LISTSERV mailing list manager LISTSERV 16.5

Help for HPS-SVN Archives


HPS-SVN Archives

HPS-SVN Archives


HPS-SVN@LISTSERV.SLAC.STANFORD.EDU


View:

Message:

[

First

|

Previous

|

Next

|

Last

]

By Topic:

[

First

|

Previous

|

Next

|

Last

]

By Author:

[

First

|

Previous

|

Next

|

Last

]

Font:

Proportional Font

LISTSERV Archives

LISTSERV Archives

HPS-SVN Home

HPS-SVN Home

HPS-SVN  April 2016

HPS-SVN April 2016

Subject:

r4346 - in /java/branches/HPSJAVA-409: ./ analysis/ analysis/src/main/java/org/hps/analysis/dataquality/ analysis/src/main/java/org/hps/analysis/ecal/ analysis/src/main/java/org/hps/analysis/ecal/cosmic/ analysis/src/main/java/org/hps/analysis/examples/ analysis/src/main/java/org/hps/analysis/plots/ analysis/src/main/java/org/hps/analysis/trigger/ analysis/src/main/java/org/hps/analysis/trigger/data/ analysis/src/main/java/org/hps/analysis/trigger/event/ analysis/src/main/java/org/hps/analysis/trigger/util/ analysis/src/test/ conditions/ conditions/src/main/java/org/hps/conditions/ conditions/src/main/java/org/hps/conditions/api/ conditions/src/main/java/org/hps/conditions/beam/ conditions/src/main/java/org/hps/conditions/cli/ conditions/src/main/java/org/hps/conditions/database/ conditions/src/main/java/org/hps/conditions/dummy/ conditions/src/main/java/org/hps/conditions/ecal/ conditions/src/main/java/org/hps/conditions/run/ conditions/src/main/java/org/hps/conditions/svt/ conditions/src/test/java/org/hps/conditions/beam/ crawler/ crawler/src/main/java/org/hps/crawler/ crawler/src/main/python/ datacat-client/ detector-data/ detector-data/detectors/HPS-EngRun2015-1_5mm-v3-4-fieldmap/ detector-data/detectors/HPS-EngRun2015-Nominal-v1-3/ detector-data/detectors/HPS-EngRun2015-Nominal-v1-4-1/ detector-data/detectors/HPS-EngRun2015-Nominal-v1-4/ detector-data/detectors/HPS-EngRun2015-Nominal-v1-5-1/ detector-data/detectors/HPS-EngRun2015-Nominal-v1-5-2/ detector-data/detectors/HPS-EngRun2015-Nominal-v3-5-0-fieldmap/ detector-data/detectors/HPS-EngRun2015-Nominal-v3-5-1-fieldmap/ detector-data/detectors/HPS-EngRun2015-Nominal-v3-5-2-fieldmap/ detector-data/detectors/HPS-EngRun2015-Nominal-v3-5-3-fieldmap/ detector-data/detectors/HPS-EngRun2015-Nominal-v4-4-fieldmap/ detector-data/detectors/HPS-EngRun2015-Nominal-v5-fieldmap/ detector-data/detectors/HPS-PhysicsRun2016-1_5mm-v4-4/ detector-data/detectors/HPS-PhysicsRun2016-2mm-v4-4/ detector-data/detectors/HPS-PhysicsRun2016-3mm-v4-4/ detector-data/detectors/HPS-PhysicsRun2016-4mm-v4-4/ detector-data/detectors/HPS-PhysicsRun2016-6pt6-v0/ detector-data/detectors/HPS-PhysicsRun2016-Nominal-v4-4-fieldmap/ detector-data/detectors/HPS-PhysicsRun2016-Nominal-v4-4/ detector-data/detectors/HPS-Proposal2014-v3-2pt2-0zOffset/ detector-data/detectors/HPS-TestRun-v5/ detector-data/detectors/HPS-TestRun-v6/ detector-data/detectors/HPS-TestRun-v7-2/ detector-data/detectors/HPS-TestRun-v7-3/ detector-data/detectors/HPS-TestRun-v7/ detector-data/detectors/HPS-TestRun-v8-4/ detector-data/detectors/HPS-TestRun-v8-5/ detector-data/detectors/HPS-TestRun-v8/ detector-data/detectors/HPSTestRunTracker2014-v0/ detector-model/ detector-model/src/main/java/org/lcsim/detector/converter/compact/ detector-model/src/main/java/org/lcsim/detector/converter/compact/subdetector/ detector-model/src/main/java/org/lcsim/detector/tracker/silicon/ detector-model/src/main/java/org/lcsim/geometry/compact/converter/ detector-model/src/main/java/org/lcsim/geometry/compact/converter/lcdd/ detector-model/src/main/java/org/lcsim/geometry/subdetector/ detector-model/src/test/java/org/hps/detector/svt/ detector-model/src/test/java/org/lcsim/detector/converter/compact/ detector-model/src/test/java/org/lcsim/geometry/compact/converter/lcdd/ detector-model/src/test/java/org/lcsim/geometry/subdetector/ detector-model/src/test/resources/org/lcsim/geometry/subdetector/ detector-model/target/ detector-model/target/antrun/ detector-model/target/classes/org/ detector-model/target/maven-archiver/ detector-model/target/maven-status/maven-compiler-plugin/compile/default-compile/ detector-model/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/ detector-model/target/test-classes/org/ distribution/ distribution/src/main/java/org/hps/ ecal-event-display/ ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/event/ ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/io/ ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/lcsim/ ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/ui/ ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/util/ ecal-readout-sim/ ecal-readout-sim/src/main/java/org/hps/readout/ecal/ ecal-recon/ ecal-recon/src/main/java/org/hps/recon/ecal/ ecal-recon/src/main/java/org/hps/recon/ecal/cluster/ evio/ evio/src/main/java/org/hps/evio/ evio/src/test/java/org/hps/evio/ integration-tests/ integration-tests/src/test/java/org/hps/test/it/ integration-tests/src/test/resources/org/hps/ecalreadoutsim/ integration-tests/src/test/resources/org/hps/steering/test/ job/ job/src/main/java/org/hps/job/ logging/ logging/src/main/resources/org/hps/logging/config/ monitoring-app/ monitoring-app/src/main/java/org/hps/monitoring/application/ monitoring-app/src/main/java/org/hps/monitoring/application/util/ monitoring-drivers/ monitoring-drivers/src/main/java/org/hps/monitoring/drivers/scalers/ monitoring-drivers/src/main/java/org/hps/monitoring/drivers/svt/ monitoring-drivers/src/main/java/org/hps/monitoring/drivers/trackrecon/ monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/ monitoring-util/ monitoring-util/src/main/java/org/hps/monitoring/plotting/ monitoring-util/src/main/java/org/hps/monitoring/subsys/et/ monitoring-util/src/main/java/org/hps/monitoring/trigger/ parent/ plugin/ recon/ recon/src/main/java/org/hps/recon/filtering/ recon/src/main/java/org/hps/recon/particle/ recon/src/main/java/org/hps/recon/utils/ recon/src/main/java/org/hps/recon/vertexing/ recon/src/test/java/org/hps/recon/particle/ record-util/ record-util/src/main/java/org/hps/job/ record-util/src/main/java/org/hps/record/ record-util/src/main/java/org/hps/record/composite/ record-util/src/main/java/org/hps/record/daqconfig/ record-util/src/main/java/org/hps/record/epics/ record-util/src/main/java/org/hps/record/evio/ record-util/src/main/java/org/hps/record/scalers/ record-util/src/main/java/org/hps/record/svt/ record-util/src/main/java/org/hps/record/triggerbank/ record-util/src/main/java/org/hps/record/util/ run-database/ run-database/src/main/java/org/hps/run/database/ run-database/src/test/java/org/hps/run/database/ steering-files/ steering-files/src/main/resources/org/hps/steering/analysis/ steering-files/src/main/resources/org/hps/steering/monitoring/ steering-files/src/main/resources/org/hps/steering/production/ steering-files/src/main/resources/org/hps/steering/readout/ steering-files/src/main/resources/org/hps/steering/recon/ steering-files/src/main/resources/org/hps/steering/users/baltzell/ steering-files/src/main/resources/org/hps/steering/users/celentan/ steering-files/src/main/resources/org/hps/steering/users/holly/ steering-files/src/main/resources/org/hps/steering/users/meeg/ steering-files/src/main/resources/org/hps/steering/users/phansson/ steering-files/src/main/resources/org/hps/steering/users/rafo/ steering-files/src/main/resources/org/hps/steering/users/spaul/ tracking/ tracking/src/main/java/org/hps/readout/svt/ tracking/src/main/java/org/hps/recon/tracking/ tracking/src/main/java/org/hps/recon/tracking/axial/ tracking/src/main/java/org/hps/recon/tracking/gbl/ tracking/src/main/java/org/hps/recon/tracking/gbl/matrix/ tracking/src/main/java/org/hps/recon/tracking/straight/ tracking/src/main/java/org/hps/svt/alignment/ tracking/src/main/resources/org/hps/recon/tracking/strategies/ tracking/src/test/java/org/hps/recon/tracking/ users/ users/src/main/java/org/hps/users/baltzell/ users/src/main/java/org/hps/users/byale/ users/src/main/java/org/hps/users/celentan/ users/src/main/java/org/hps/users/holly/ users/src/main/java/org/hps/users/jeremym/ users/src/main/java/org/hps/users/kmccarty/ users/src/main/java/org/hps/users/kmccarty/plots/ users/src/main/java/org/hps/users/kmccarty/plots/formatter/ users/src/main/java/org/hps/users/luca/ users/src/main/java/org/hps/users/meeg/ users/src/main/java/org/hps/users/mgraham/ users/src/main/java/org/hps/users/omoreno/ users/src/main/java/org/hps/users/phansson/ users/src/main/java/org/hps/users/phansson/alignment/ users/src/main/java/org/hps/users/phansson/apps/ users/src/main/java/org/hps/users/phansson/daq/ users/src/main/java/org/hps/users/phansson/gbl/ users/src/main/java/org/hps/users/phansson/testrun/ users/src/main/java/org/hps/users/phansson/tools/ users/src/main/java/org/hps/users/rafo/ users/src/main/java/org/hps/users/spaul/ users/src/main/java/org/hps/users/spaul/feecc/ users/src/main/java/org/hps/users/spaul/feecc/analysis/ users/src/main/java/org/hps/users/spaul/moller/ util/ util/src/main/java/org/hps/util/

From:

[log in to unmask]

Reply-To:

Notification of commits to the hps svn repository <[log in to unmask]>

Date:

Wed, 27 Apr 2016 18:12:13 -0000

Content-Type:

text/plain

Parts/Attachments:

Parts/Attachments

text/plain (90998 lines)

Author: [log in to unmask]
Date: Wed Apr 27 11:11:32 2016
New Revision: 4346

Log:
Merge in trunk to ecal geom dev branch so it is up to date.

Added:
    java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/dataquality/MollerMonitoring.java
      - copied unchanged from r4345, java/trunk/analysis/src/main/java/org/hps/analysis/dataquality/MollerMonitoring.java
    java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/dataquality/MuonCandidateMonitoring.java
      - copied unchanged from r4345, java/trunk/analysis/src/main/java/org/hps/analysis/dataquality/MuonCandidateMonitoring.java
    java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/examples/VertexAnalysis.java
      - copied unchanged from r4345, java/trunk/analysis/src/main/java/org/hps/analysis/examples/VertexAnalysis.java
    java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/plots/
      - copied from r4345, java/trunk/analysis/src/main/java/org/hps/analysis/plots/
    java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/ClusterDiagnosticModule.java
      - copied unchanged from r4345, java/trunk/analysis/src/main/java/org/hps/analysis/trigger/ClusterDiagnosticModule.java
    java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/DiagnosticsManagementDriver.java
      - copied unchanged from r4345, java/trunk/analysis/src/main/java/org/hps/analysis/trigger/DiagnosticsManagementDriver.java
    java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/PairTriggerDiagnosticModule.java
      - copied unchanged from r4345, java/trunk/analysis/src/main/java/org/hps/analysis/trigger/PairTriggerDiagnosticModule.java
    java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/SinglesTriggerDiagnosticModule.java
      - copied unchanged from r4345, java/trunk/analysis/src/main/java/org/hps/analysis/trigger/SinglesTriggerDiagnosticModule.java
    java/branches/HPSJAVA-409/analysis/src/test/
      - copied from r4345, java/trunk/analysis/src/test/
    java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/beam/
      - copied from r4345, java/trunk/conditions/src/main/java/org/hps/conditions/beam/
    java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/database/AbstractConditionsObjectConverter.java
      - copied unchanged from r4345, java/trunk/conditions/src/main/java/org/hps/conditions/database/AbstractConditionsObjectConverter.java
    java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/ecal/EcalTimeWalk.java
      - copied unchanged from r4345, java/trunk/conditions/src/main/java/org/hps/conditions/ecal/EcalTimeWalk.java
    java/branches/HPSJAVA-409/conditions/src/test/java/org/hps/conditions/beam/
      - copied from r4345, java/trunk/conditions/src/test/java/org/hps/conditions/beam/
    java/branches/HPSJAVA-409/crawler/src/main/java/org/hps/crawler/CrawlerFileVisitor.java
      - copied unchanged from r4345, java/trunk/crawler/src/main/java/org/hps/crawler/CrawlerFileVisitor.java
    java/branches/HPSJAVA-409/crawler/src/main/java/org/hps/crawler/DataType.java
      - copied unchanged from r4345, java/trunk/crawler/src/main/java/org/hps/crawler/DataType.java
    java/branches/HPSJAVA-409/crawler/src/main/java/org/hps/crawler/DatacatAddFile.java
      - copied unchanged from r4345, java/trunk/crawler/src/main/java/org/hps/crawler/DatacatAddFile.java
    java/branches/HPSJAVA-409/crawler/src/main/java/org/hps/crawler/DatacatHelper.java
      - copied unchanged from r4345, java/trunk/crawler/src/main/java/org/hps/crawler/DatacatHelper.java
    java/branches/HPSJAVA-409/crawler/src/main/java/org/hps/crawler/FileFormat.java
      - copied unchanged from r4345, java/trunk/crawler/src/main/java/org/hps/crawler/FileFormat.java
    java/branches/HPSJAVA-409/crawler/src/main/java/org/hps/crawler/FileUtilities.java
      - copied unchanged from r4345, java/trunk/crawler/src/main/java/org/hps/crawler/FileUtilities.java
    java/branches/HPSJAVA-409/crawler/src/main/java/org/hps/crawler/LcioReconMetadataReader.java
      - copied unchanged from r4345, java/trunk/crawler/src/main/java/org/hps/crawler/LcioReconMetadataReader.java
    java/branches/HPSJAVA-409/crawler/src/main/java/org/hps/crawler/MetadataWriter.java
      - copied unchanged from r4345, java/trunk/crawler/src/main/java/org/hps/crawler/MetadataWriter.java
    java/branches/HPSJAVA-409/crawler/src/main/java/org/hps/crawler/PathFilter.java
      - copied unchanged from r4345, java/trunk/crawler/src/main/java/org/hps/crawler/PathFilter.java
    java/branches/HPSJAVA-409/crawler/src/main/java/org/hps/crawler/Site.java
      - copied unchanged from r4345, java/trunk/crawler/src/main/java/org/hps/crawler/Site.java
    java/branches/HPSJAVA-409/crawler/src/main/python/
      - copied from r4345, java/trunk/crawler/src/main/python/
    java/branches/HPSJAVA-409/detector-data/detectors/HPS-EngRun2015-1_5mm-v3-4-fieldmap/HPS-EngRun2015-1_5mm-v3-4-fieldmap.lcdd
      - copied unchanged from r4345, java/trunk/detector-data/detectors/HPS-EngRun2015-1_5mm-v3-4-fieldmap/HPS-EngRun2015-1_5mm-v3-4-fieldmap.lcdd
    java/branches/HPSJAVA-409/detector-data/detectors/HPS-EngRun2015-Nominal-v3-5-0-fieldmap/
      - copied from r4345, java/trunk/detector-data/detectors/HPS-EngRun2015-Nominal-v3-5-0-fieldmap/
    java/branches/HPSJAVA-409/detector-data/detectors/HPS-EngRun2015-Nominal-v3-5-1-fieldmap/
      - copied from r4345, java/trunk/detector-data/detectors/HPS-EngRun2015-Nominal-v3-5-1-fieldmap/
    java/branches/HPSJAVA-409/detector-data/detectors/HPS-EngRun2015-Nominal-v3-5-2-fieldmap/
      - copied from r4345, java/trunk/detector-data/detectors/HPS-EngRun2015-Nominal-v3-5-2-fieldmap/
    java/branches/HPSJAVA-409/detector-data/detectors/HPS-EngRun2015-Nominal-v3-5-3-fieldmap/
      - copied from r4345, java/trunk/detector-data/detectors/HPS-EngRun2015-Nominal-v3-5-3-fieldmap/
    java/branches/HPSJAVA-409/detector-data/detectors/HPS-EngRun2015-Nominal-v4-4-fieldmap/
      - copied from r4345, java/trunk/detector-data/detectors/HPS-EngRun2015-Nominal-v4-4-fieldmap/
    java/branches/HPSJAVA-409/detector-data/detectors/HPS-EngRun2015-Nominal-v5-fieldmap/
      - copied from r4345, java/trunk/detector-data/detectors/HPS-EngRun2015-Nominal-v5-fieldmap/
    java/branches/HPSJAVA-409/detector-data/detectors/HPS-PhysicsRun2016-1_5mm-v4-4/
      - copied from r4345, java/trunk/detector-data/detectors/HPS-PhysicsRun2016-1_5mm-v4-4/
    java/branches/HPSJAVA-409/detector-data/detectors/HPS-PhysicsRun2016-2mm-v4-4/
      - copied from r4345, java/trunk/detector-data/detectors/HPS-PhysicsRun2016-2mm-v4-4/
    java/branches/HPSJAVA-409/detector-data/detectors/HPS-PhysicsRun2016-3mm-v4-4/
      - copied from r4345, java/trunk/detector-data/detectors/HPS-PhysicsRun2016-3mm-v4-4/
    java/branches/HPSJAVA-409/detector-data/detectors/HPS-PhysicsRun2016-4mm-v4-4/
      - copied from r4345, java/trunk/detector-data/detectors/HPS-PhysicsRun2016-4mm-v4-4/
    java/branches/HPSJAVA-409/detector-data/detectors/HPS-PhysicsRun2016-6pt6-v0/
      - copied from r4345, java/trunk/detector-data/detectors/HPS-PhysicsRun2016-6pt6-v0/
    java/branches/HPSJAVA-409/detector-data/detectors/HPS-PhysicsRun2016-Nominal-v4-4/
      - copied from r4345, java/trunk/detector-data/detectors/HPS-PhysicsRun2016-Nominal-v4-4/
    java/branches/HPSJAVA-409/detector-data/detectors/HPS-PhysicsRun2016-Nominal-v4-4-fieldmap/
      - copied from r4345, java/trunk/detector-data/detectors/HPS-PhysicsRun2016-Nominal-v4-4-fieldmap/
    java/branches/HPSJAVA-409/job/src/main/java/org/hps/job/DatabaseConditionsManagerSetup.java
      - copied unchanged from r4345, java/trunk/job/src/main/java/org/hps/job/DatabaseConditionsManagerSetup.java
    java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/svt/SVTPulseFitPlots.java
      - copied unchanged from r4345, java/trunk/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/svt/SVTPulseFitPlots.java
    java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/EcalFeeMonitor.java
      - copied unchanged from r4345, java/trunk/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/EcalFeeMonitor.java
    java/branches/HPSJAVA-409/recon/src/main/java/org/hps/recon/filtering/CosmicPMTFilter.java
      - copied unchanged from r4345, java/trunk/recon/src/main/java/org/hps/recon/filtering/CosmicPMTFilter.java
    java/branches/HPSJAVA-409/recon/src/main/java/org/hps/recon/filtering/PulserSingle0Pair0TriggerFilterDriver.java
      - copied unchanged from r4345, java/trunk/recon/src/main/java/org/hps/recon/filtering/PulserSingle0Pair0TriggerFilterDriver.java
    java/branches/HPSJAVA-409/recon/src/main/java/org/hps/recon/filtering/SvtHitMultiplicityFilter.java
      - copied unchanged from r4345, java/trunk/recon/src/main/java/org/hps/recon/filtering/SvtHitMultiplicityFilter.java
    java/branches/HPSJAVA-409/recon/src/main/java/org/hps/recon/filtering/SvtRawHitMultiplicityFilter.java
      - copied unchanged from r4345, java/trunk/recon/src/main/java/org/hps/recon/filtering/SvtRawHitMultiplicityFilter.java
    java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/AbstractLoopAdapter.java
      - copied unchanged from r4345, java/trunk/record-util/src/main/java/org/hps/record/AbstractLoopAdapter.java
    java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/AbstractRecordLoop.java
      - copied unchanged from r4345, java/trunk/record-util/src/main/java/org/hps/record/AbstractRecordLoop.java
    java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/daqconfig/TriggerConfigEvioProcessor.java
      - copied unchanged from r4345, java/trunk/record-util/src/main/java/org/hps/record/daqconfig/TriggerConfigEvioProcessor.java
    java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/epics/EpicsUtilities.java
      - copied unchanged from r4345, java/trunk/record-util/src/main/java/org/hps/record/epics/EpicsUtilities.java
    java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/evio/EventTagMask.java
      - copied unchanged from r4345, java/trunk/record-util/src/main/java/org/hps/record/evio/EventTagMask.java
    java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/svt/SvtConfigData.java
      - copied unchanged from r4345, java/trunk/record-util/src/main/java/org/hps/record/svt/SvtConfigData.java
    java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/svt/SvtConfigEvioProcessor.java
      - copied unchanged from r4345, java/trunk/record-util/src/main/java/org/hps/record/svt/SvtConfigEvioProcessor.java
    java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/triggerbank/TiTimeOffsetCalculator.java
      - copied unchanged from r4345, java/trunk/record-util/src/main/java/org/hps/record/triggerbank/TiTimeOffsetCalculator.java
    java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/triggerbank/TriggerConfigData.java
      - copied unchanged from r4345, java/trunk/record-util/src/main/java/org/hps/record/triggerbank/TriggerConfigData.java
    java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/triggerbank/TriggerType.java
      - copied unchanged from r4345, java/trunk/record-util/src/main/java/org/hps/record/triggerbank/TriggerType.java
    java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/util/
      - copied from r4345, java/trunk/record-util/src/main/java/org/hps/record/util/
    java/branches/HPSJAVA-409/run-database/src/main/java/org/hps/run/database/AbstractRunBuilder.java
      - copied unchanged from r4345, java/trunk/run-database/src/main/java/org/hps/run/database/AbstractRunBuilder.java
    java/branches/HPSJAVA-409/run-database/src/main/java/org/hps/run/database/DaoProvider.java
      - copied unchanged from r4345, java/trunk/run-database/src/main/java/org/hps/run/database/DaoProvider.java
    java/branches/HPSJAVA-409/run-database/src/main/java/org/hps/run/database/DatacatBuilder.java
      - copied unchanged from r4345, java/trunk/run-database/src/main/java/org/hps/run/database/DatacatBuilder.java
    java/branches/HPSJAVA-409/run-database/src/main/java/org/hps/run/database/DatacatUtilities.java
      - copied unchanged from r4345, java/trunk/run-database/src/main/java/org/hps/run/database/DatacatUtilities.java
    java/branches/HPSJAVA-409/run-database/src/main/java/org/hps/run/database/EvioDataBuilder.java
      - copied unchanged from r4345, java/trunk/run-database/src/main/java/org/hps/run/database/EvioDataBuilder.java
    java/branches/HPSJAVA-409/run-database/src/main/java/org/hps/run/database/LivetimeBuilder.java
      - copied unchanged from r4345, java/trunk/run-database/src/main/java/org/hps/run/database/LivetimeBuilder.java
    java/branches/HPSJAVA-409/run-database/src/main/java/org/hps/run/database/RunDatabaseBuilder.java
      - copied unchanged from r4345, java/trunk/run-database/src/main/java/org/hps/run/database/RunDatabaseBuilder.java
    java/branches/HPSJAVA-409/run-database/src/main/java/org/hps/run/database/SpreadsheetBuilder.java
      - copied unchanged from r4345, java/trunk/run-database/src/main/java/org/hps/run/database/SpreadsheetBuilder.java
    java/branches/HPSJAVA-409/run-database/src/main/java/org/hps/run/database/SvtConfigDao.java
      - copied unchanged from r4345, java/trunk/run-database/src/main/java/org/hps/run/database/SvtConfigDao.java
    java/branches/HPSJAVA-409/run-database/src/main/java/org/hps/run/database/SvtConfigDaoImpl.java
      - copied unchanged from r4345, java/trunk/run-database/src/main/java/org/hps/run/database/SvtConfigDaoImpl.java
    java/branches/HPSJAVA-409/run-database/src/main/java/org/hps/run/database/TriggerConfigBuilder.java
      - copied unchanged from r4345, java/trunk/run-database/src/main/java/org/hps/run/database/TriggerConfigBuilder.java
    java/branches/HPSJAVA-409/run-database/src/main/java/org/hps/run/database/TriggerConfigDao.java
      - copied unchanged from r4345, java/trunk/run-database/src/main/java/org/hps/run/database/TriggerConfigDao.java
    java/branches/HPSJAVA-409/run-database/src/main/java/org/hps/run/database/TriggerConfigDaoImpl.java
      - copied unchanged from r4345, java/trunk/run-database/src/main/java/org/hps/run/database/TriggerConfigDaoImpl.java
    java/branches/HPSJAVA-409/run-database/src/test/java/org/hps/run/database/RunBuilderTest.java
      - copied unchanged from r4345, java/trunk/run-database/src/test/java/org/hps/run/database/RunBuilderTest.java
    java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/production/DataQualityRecon.lcsim
      - copied unchanged from r4345, java/trunk/steering-files/src/main/resources/org/hps/steering/production/DataQualityRecon.lcsim
    java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/production/FilterHitsPerSensor.lcsim
      - copied unchanged from r4345, java/trunk/steering-files/src/main/resources/org/hps/steering/production/FilterHitsPerSensor.lcsim
    java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/readout/PhysicsRun2016TrigPair0.lcsim
      - copied unchanged from r4345, java/trunk/steering-files/src/main/resources/org/hps/steering/readout/PhysicsRun2016TrigPair0.lcsim
    java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/recon/EngineeringRun2015STRecon.lcsim
      - copied unchanged from r4345, java/trunk/steering-files/src/main/resources/org/hps/steering/recon/EngineeringRun2015STRecon.lcsim
    java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/users/baltzell/Cosmic.lcsim
      - copied unchanged from r4345, java/trunk/steering-files/src/main/resources/org/hps/steering/users/baltzell/Cosmic.lcsim
    java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/users/baltzell/EngineeringRun2015FullRecon.lcsim
      - copied unchanged from r4345, java/trunk/steering-files/src/main/resources/org/hps/steering/users/baltzell/EngineeringRun2015FullRecon.lcsim
    java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/users/celentan/LedOnlineOfflineComparison.lcsim
      - copied unchanged from r4345, java/trunk/steering-files/src/main/resources/org/hps/steering/users/celentan/LedOnlineOfflineComparison.lcsim
    java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/users/holly/EcalFeeViewer.lcsim
      - copied unchanged from r4345, java/trunk/steering-files/src/main/resources/org/hps/steering/users/holly/EcalFeeViewer.lcsim
    java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/users/holly/EngRun2015FullReconMC_FEE.lcsim
      - copied unchanged from r4345, java/trunk/steering-files/src/main/resources/org/hps/steering/users/holly/EngRun2015FullReconMC_FEE.lcsim
    java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/users/holly/EngineeringRun2015EcalRecon_noTwalk.lcsim
      - copied unchanged from r4345, java/trunk/steering-files/src/main/resources/org/hps/steering/users/holly/EngineeringRun2015EcalRecon_noTwalk.lcsim
    java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/users/holly/PhysicsRun2016_FEEIter_Filter.lcsim
      - copied unchanged from r4345, java/trunk/steering-files/src/main/resources/org/hps/steering/users/holly/PhysicsRun2016_FEEIter_Filter.lcsim
    java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/users/meeg/TridentMCSkim.lcsim
      - copied unchanged from r4345, java/trunk/steering-files/src/main/resources/org/hps/steering/users/meeg/TridentMCSkim.lcsim
    java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/users/phansson/EventInfo.lcsim
      - copied unchanged from r4345, java/trunk/steering-files/src/main/resources/org/hps/steering/users/phansson/EventInfo.lcsim
    java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/users/phansson/HPSReconNoReadout.lcsim
      - copied unchanged from r4345, java/trunk/steering-files/src/main/resources/org/hps/steering/users/phansson/HPSReconNoReadout.lcsim
    java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/users/spaul/MollerBeamtilt.lcsim
      - copied unchanged from r4345, java/trunk/steering-files/src/main/resources/org/hps/steering/users/spaul/MollerBeamtilt.lcsim
    java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/HpsHelicalTrackFit.java
      - copied unchanged from r4345, java/trunk/tracking/src/main/java/org/hps/recon/tracking/HpsHelicalTrackFit.java
    java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/SvtPlotUtils.java
      - copied unchanged from r4345, java/trunk/tracking/src/main/java/org/hps/recon/tracking/SvtPlotUtils.java
    java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/straight/
      - copied from r4345, java/trunk/tracking/src/main/java/org/hps/recon/tracking/straight/
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/byale/
      - copied from r4345, java/trunk/users/src/main/java/org/hps/users/byale/
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/celentan/LedOnlineDataDumpDriver.java
      - copied unchanged from r4345, java/trunk/users/src/main/java/org/hps/users/celentan/LedOnlineDataDumpDriver.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/celentan/LedOnlineOfflineComparisonDriver.java
      - copied unchanged from r4345, java/trunk/users/src/main/java/org/hps/users/celentan/LedOnlineOfflineComparisonDriver.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/meeg/SVTPhaseOffsetReader.java
      - copied unchanged from r4345, java/trunk/users/src/main/java/org/hps/users/meeg/SVTPhaseOffsetReader.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/meeg/TrackCleanupDriver.java
      - copied unchanged from r4345, java/trunk/users/src/main/java/org/hps/users/meeg/TrackCleanupDriver.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/phansson/GblResidualDriver.java
      - copied unchanged from r4345, java/trunk/users/src/main/java/org/hps/users/phansson/GblResidualDriver.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/phansson/PrintEventInfoDriver.java
      - copied unchanged from r4345, java/trunk/users/src/main/java/org/hps/users/phansson/PrintEventInfoDriver.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/phansson/alignment/
      - copied from r4345, java/trunk/users/src/main/java/org/hps/users/phansson/alignment/
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/phansson/apps/
      - copied from r4345, java/trunk/users/src/main/java/org/hps/users/phansson/apps/
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/phansson/daq/
      - copied from r4345, java/trunk/users/src/main/java/org/hps/users/phansson/daq/
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/phansson/gbl/
      - copied from r4345, java/trunk/users/src/main/java/org/hps/users/phansson/gbl/
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/phansson/testrun/
      - copied from r4345, java/trunk/users/src/main/java/org/hps/users/phansson/testrun/
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/phansson/tools/
      - copied from r4345, java/trunk/users/src/main/java/org/hps/users/phansson/tools/
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/spaul/FindBiasOnRange.java
      - copied unchanged from r4345, java/trunk/users/src/main/java/org/hps/users/spaul/FindBiasOnRange.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/spaul/feecc/ExtractFormFactors.java
      - copied unchanged from r4345, java/trunk/users/src/main/java/org/hps/users/spaul/feecc/ExtractFormFactors.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/spaul/feecc/FEESpectrumGenerator.java
      - copied unchanged from r4345, java/trunk/users/src/main/java/org/hps/users/spaul/feecc/FEESpectrumGenerator.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/spaul/feecc/FormFactor.java
      - copied unchanged from r4345, java/trunk/users/src/main/java/org/hps/users/spaul/feecc/FormFactor.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/spaul/feecc/MottIntegral.java
      - copied unchanged from r4345, java/trunk/users/src/main/java/org/hps/users/spaul/feecc/MottIntegral.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/spaul/feecc/MultipleScattering.java
      - copied unchanged from r4345, java/trunk/users/src/main/java/org/hps/users/spaul/feecc/MultipleScattering.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/spaul/feecc/RemoveDuplicateParticles.java
      - copied unchanged from r4345, java/trunk/users/src/main/java/org/hps/users/spaul/feecc/RemoveDuplicateParticles.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/spaul/feecc/ShowCustomBinningXY.java
      - copied unchanged from r4345, java/trunk/users/src/main/java/org/hps/users/spaul/feecc/ShowCustomBinningXY.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/spaul/moller/
      - copied from r4345, java/trunk/users/src/main/java/org/hps/users/spaul/moller/
Removed:
    java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/api/AbstractConditionsObjectConverter.java
    java/branches/HPSJAVA-409/crawler/src/main/java/org/hps/crawler/CrawlerFileUtilities.java
    java/branches/HPSJAVA-409/crawler/src/main/java/org/hps/crawler/DatacatUtilities.java
    java/branches/HPSJAVA-409/crawler/src/main/java/org/hps/crawler/FileSet.java
    java/branches/HPSJAVA-409/crawler/src/main/java/org/hps/crawler/LcioMetadataReader.java
    java/branches/HPSJAVA-409/crawler/src/main/java/org/hps/crawler/RunSummaryMap.java
    java/branches/HPSJAVA-409/datacat-client/
    java/branches/HPSJAVA-409/detector-model/target/classes/org/
    java/branches/HPSJAVA-409/detector-model/target/test-classes/org/
    java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/svt/SvtPlotUtils.java
    java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/job/
    java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/daqconfig/DAQConfigEvioProcessor.java
    java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/evio/EventCountProcessor.java
    java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/evio/EventTagBitMask.java
    java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/evio/EvioFileMetadata.java
    java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/evio/EvioFileMetadataAdapter.java
    java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/evio/EvioFileMetadataProcessor.java
    java/branches/HPSJAVA-409/run-database/src/main/java/org/hps/run/database/RunDatabaseDaoFactory.java
    java/branches/HPSJAVA-409/run-database/src/main/java/org/hps/run/database/RunProcessor.java
    java/branches/HPSJAVA-409/run-database/src/test/java/org/hps/run/database/TiTriggerOffsetTest.java
    java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/production/DataQualityRecon_Pass2.lcsim
    java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/recon/EngineeringRun2015FullReconMC_Pass2.lcsim
    java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/recon/EngineeringRun2015FullRecon_Pass2.lcsim
    java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/users/phansson/HitRecon.lcsim
    java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/HPSTrack.java
    java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/gbl/GBLDriver.java
    java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/gbl/HpsGblFitter.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/phansson/AlignmentUtils.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/phansson/BeamCurrentData.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/phansson/Count.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/phansson/DAQDeadTimeData.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/phansson/DumpAIDATextFiles.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/phansson/ECalExtrapolationDriver.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/phansson/EcalHitMapPlots.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/phansson/GlobalParameter.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/phansson/GlobalParameters.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/phansson/MPAlignmentInputCalculator.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/phansson/ModuleMPAlignmentInput.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/phansson/PolarCount.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/phansson/ROOTFlatTupleDriver.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/phansson/ReadSurveyRotations.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/phansson/RegExpMatcherTester.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/phansson/ResLimit.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/phansson/RunMPAlignment.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/phansson/STUtils.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/phansson/SimpleHPSConditions.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/phansson/StraightThroughAnalysisDriver.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/phansson/StripMPAlignmentInput.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/phansson/SvtHeaderAnalysisDriver.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/phansson/SvtHeaderMetaDataReaderDriver.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/phansson/SvtOldHeaderAnalysisDriver.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/phansson/SvtOldHeaderDataInfo.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/phansson/TestSort.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/phansson/TrackingGeometryChecker.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/phansson/TrigRateAna.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/phansson/TrigRateDriver.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/phansson/WTrack.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/phansson/dataMCPlots.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/phansson/ecalPlots.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/phansson/mergeSimpleAIDA.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/phansson/trigRate.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/spaul/feecc/analysis/
Modified:
    java/branches/HPSJAVA-409/   (props changed)
    java/branches/HPSJAVA-409/analysis/pom.xml
    java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/dataquality/DQMDatabaseManager.java
    java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/dataquality/DataQualityMonitor.java
    java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/dataquality/EcalMonitoring.java
    java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/dataquality/FinalStateMonitoring.java
    java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/dataquality/PlotAndFitUtilities.java
    java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/dataquality/SvtMonitoring.java
    java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/dataquality/TrackingMonitoring.java
    java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/dataquality/TrackingResiduals.java
    java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/dataquality/TridentMonitoring.java
    java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/dataquality/V0Monitoring.java
    java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/ecal/EcalCellIDPrintDriver.java
    java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/ecal/EcalClusterPlots.java
    java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/ecal/EcalHitPlots.java
    java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/ecal/FEEClusterPlotter.java
    java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/ecal/HPSEcalFADCPlotsDriver.java
    java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/ecal/HPSEcalTriggerPlotsDriver.java
    java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/ecal/HPSMCParticlePlotsDriver.java
    java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/ecal/cosmic/DualThresholdSignalFitDriver.java
    java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/ecal/cosmic/RawModeHitSelectionDriver.java
    java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/ecal/cosmic/RawModeSignalFitDriver.java
    java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/examples/PrintGeometryDriver.java
    java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/examples/StripGoldenEventsDriver.java
    java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/examples/StripMollerEventsDriver.java
    java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/DataTriggerSimDriver.java
    java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/SimTriggerData.java
    java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/SimTriggerModule.java
    java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/TriggerDiagnosticDriver.java
    java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/TriggerTurnOnDriver.java
    java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/data/ClusterEvent.java
    java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/data/ClusterMatchedPair.java
    java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/data/ClusterStatModule.java
    java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/data/DetailedClusterEvent.java
    java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/data/DiagnosticSnapshot.java
    java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/data/GeneralStatModule.java
    java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/data/RunDiagStats.java
    java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/data/TriggerDiagStats.java
    java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/data/TriggerEvent.java
    java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/data/TriggerStatModule.java
    java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/event/TriggerPlotsModule.java
    java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/util/ComponentUtils.java
    java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/util/OutputLogger.java
    java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/util/Pair.java
    java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/util/PairTrigger.java
    java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/util/SinglesTrigger.java
    java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/util/Trigger.java
    java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/util/TriggerDiagnosticUtil.java
    java/branches/HPSJAVA-409/conditions/   (props changed)
    java/branches/HPSJAVA-409/conditions/pom.xml
    java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/ConditionsDriver.java
    java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/api/BaseConditionsObject.java
    java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/api/BaseConditionsObjectCollection.java
    java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/api/ConditionsObjectCollection.java
    java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/api/ConditionsObjectException.java
    java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/api/ConditionsRecord.java
    java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/api/package-info.java
    java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/cli/AbstractCommand.java
    java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/cli/AddCommand.java
    java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/cli/CommandLineTool.java
    java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/cli/LoadCommand.java
    java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/cli/PrintCommand.java
    java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/cli/RunSummaryCommand.java
    java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/cli/TagCommand.java
    java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/database/ConditionsRecordConverter.java
    java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/database/ConditionsTagConverter.java
    java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/database/ConnectionParameters.java
    java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/database/Converter.java
    java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/database/ConverterRegistry.java
    java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/database/DatabaseConditionsManager.java
    java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/database/package-info.java
    java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/dummy/DummyConditionsObjectConverter.java
    java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/ecal/EcalChannel.java
    java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/ecal/EcalConditions.java
    java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/ecal/EcalConditionsConverter.java
    java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/ecal/TestRunEcalConditionsConverter.java
    java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/package-info.java
    java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/run/RunSpreadsheet.java
    java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/svt/AbstractSvtDaqMapping.java
    java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/svt/DaqMapHandler.java
    java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/svt/MotorPositionLoader.java
    java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/svt/OpeningAngleLoader.java
    java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/svt/SvtBiasConditionsLoader.java
    java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/svt/SvtConditionsLoader.java
    java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/svt/SvtDaqMapping.java
    java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/svt/SvtT0Shift.java
    java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/svt/TestRunSvtChannel.java
    java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/svt/TestRunSvtConditions.java
    java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/svt/TestRunSvtT0Shift.java
    java/branches/HPSJAVA-409/crawler/pom.xml
    java/branches/HPSJAVA-409/crawler/src/main/java/org/hps/crawler/AidaMetadataReader.java
    java/branches/HPSJAVA-409/crawler/src/main/java/org/hps/crawler/CrawlerConfig.java
    java/branches/HPSJAVA-409/crawler/src/main/java/org/hps/crawler/DatacatCrawler.java
    java/branches/HPSJAVA-409/crawler/src/main/java/org/hps/crawler/EvioMetadataReader.java
    java/branches/HPSJAVA-409/crawler/src/main/java/org/hps/crawler/FileFormatFilter.java
    java/branches/HPSJAVA-409/crawler/src/main/java/org/hps/crawler/FileMetadataReader.java
    java/branches/HPSJAVA-409/crawler/src/main/java/org/hps/crawler/RootDqmMetadataReader.java
    java/branches/HPSJAVA-409/crawler/src/main/java/org/hps/crawler/RootDstMetadataReader.java
    java/branches/HPSJAVA-409/crawler/src/main/java/org/hps/crawler/RunFilter.java
    java/branches/HPSJAVA-409/detector-data/detectors/HPS-EngRun2015-Nominal-v1-3/compact.xml
    java/branches/HPSJAVA-409/detector-data/detectors/HPS-EngRun2015-Nominal-v1-4-1/compact.xml
    java/branches/HPSJAVA-409/detector-data/detectors/HPS-EngRun2015-Nominal-v1-4-1/compact_millepede-milleBinaryISN_hps_005772.evio.0.gbl-L3_L4_L5_tu_rw_THEN_L2_tu_rw_THEN_L2_L3_L4_tu_rw_THEN_L2_L3_L5_tu_rw_THEN_L2_L3_L4_L5_excl_L3ST_tu_L4Sb_tu_THEN_L2_L4_L5_tu_rw.xml
    java/branches/HPSJAVA-409/detector-data/detectors/HPS-EngRun2015-Nominal-v1-4/compact.xml
    java/branches/HPSJAVA-409/detector-data/detectors/HPS-EngRun2015-Nominal-v1-4/compact_millepede-milleBinaryISN_hps_005772.evio.0.gbl-L2-3-4_tu_rw.xml
    java/branches/HPSJAVA-409/detector-data/detectors/HPS-EngRun2015-Nominal-v1-5-1/compact_millepede-milleBinaryISN_hps_005772.evio.0.gbl-L3_L4_L5_tu_rw_THEN_L2_tu_rw_THEN_L2_L3_L4_tu_rw_THEN_L2_L3_L5_tu_rw_THEN_L2_L3_L4_L5_excl_L3ST_tu_L4Sb_tu_THEN_L2_L4_L5_tu_rw.xml
    java/branches/HPSJAVA-409/detector-data/detectors/HPS-EngRun2015-Nominal-v1-5-2/compact_millepede-milleBinaryISN_hps_005772.evio.0.gbl-HPS-EngRun2015-Nominal-v1-4-1-100k-L456_L123_L234_L345_L123_L456_tu_rwIter0Iter1Iter2Iter3Iter4Iter5.xml
    java/branches/HPSJAVA-409/detector-data/detectors/HPS-Proposal2014-v3-2pt2-0zOffset/compact.xml
    java/branches/HPSJAVA-409/detector-data/detectors/HPS-TestRun-v5/compact.xml
    java/branches/HPSJAVA-409/detector-data/detectors/HPS-TestRun-v6/compact.xml
    java/branches/HPSJAVA-409/detector-data/detectors/HPS-TestRun-v7-2/compact.xml
    java/branches/HPSJAVA-409/detector-data/detectors/HPS-TestRun-v7-3/compact.xml
    java/branches/HPSJAVA-409/detector-data/detectors/HPS-TestRun-v7/compact.xml
    java/branches/HPSJAVA-409/detector-data/detectors/HPS-TestRun-v8-4/compact.xml
    java/branches/HPSJAVA-409/detector-data/detectors/HPS-TestRun-v8-5/compact.xml
    java/branches/HPSJAVA-409/detector-data/detectors/HPS-TestRun-v8/compact.xml
    java/branches/HPSJAVA-409/detector-data/detectors/HPSTestRunTracker2014-v0/compact.xml
    java/branches/HPSJAVA-409/detector-data/pom.xml
    java/branches/HPSJAVA-409/detector-model/pom.xml
    java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/detector/converter/compact/HPSTestRunTracker2014Converter.java
    java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/detector/converter/compact/HPSTracker2014Converter.java
    java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/detector/converter/compact/HPSTracker2014ConverterBase.java
    java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/detector/converter/compact/HPSTrackerConverter.java
    java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/detector/converter/compact/subdetector/HpsTracker2.java
    java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/detector/converter/compact/subdetector/SvtStereoLayer.java
    java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/detector/tracker/silicon/HpsSiSensor.java
    java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/detector/tracker/silicon/HpsTestRunSiSensor.java
    java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTestRunTracker2014GeometryDefinition.java
    java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTestRunTracker2014JavaBuilder.java
    java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTestRunTracker2014LCDDBuilder.java
    java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTracker2014GeometryDefinition.java
    java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTracker2014JavaBuilder.java
    java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTracker2014v1GeometryDefinition.java
    java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTrackerBuilder.java
    java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTrackerGeometryDefinition.java
    java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTrackerJavaBuilder.java
    java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTrackerLCDDBuilder.java
    java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/IHPSTrackerJavaBuilder.java
    java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/IHPSTrackerLCDDBuilder.java
    java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/JavaGhostSurveyVolume.java
    java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/JavaSurveyVolume.java
    java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/LCDDGhostSurveyVolume.java
    java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/LCDDSurveyVolume.java
    java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/MilleParameter.java
    java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/SurveyCoordinateSystem.java
    java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/SurveyVolume.java
    java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/SurveyVolumeImpl.java
    java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/SurveyVolumeVisualization.java
    java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/SvtAlignmentConstantsReader.java
    java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/lcdd/HPSMuonCalorimeter2.java
    java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/lcdd/HPSTestRunTracker2014.java
    java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/lcdd/HPSTracker.java
    java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/lcdd/HPSTracker2.java
    java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/lcdd/HPSTracker2014.java
    java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/subdetector/HPSEcal.java
    java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/subdetector/HPSEcal3.java
    java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/subdetector/HPSTestRunTracker2014.java
    java/branches/HPSJAVA-409/detector-model/src/test/java/org/hps/detector/svt/SvtDetectorSetupTest.java
    java/branches/HPSJAVA-409/detector-model/src/test/java/org/lcsim/detector/converter/compact/HPSTracker2ConverterTest.java
    java/branches/HPSJAVA-409/detector-model/src/test/java/org/lcsim/geometry/compact/converter/lcdd/HPSTestRunTracker2014LCDDTest.java
    java/branches/HPSJAVA-409/detector-model/src/test/java/org/lcsim/geometry/compact/converter/lcdd/HPSTracker2014LCDDTest.java
    java/branches/HPSJAVA-409/detector-model/src/test/java/org/lcsim/geometry/compact/converter/lcdd/HPSTracker2014v1LCDDTest.java
    java/branches/HPSJAVA-409/detector-model/src/test/java/org/lcsim/geometry/compact/converter/lcdd/HPSTracker2014v1SurveyLCDDTest.java
    java/branches/HPSJAVA-409/detector-model/src/test/java/org/lcsim/geometry/subdetector/HPSTestRunTracker2014Test.java
    java/branches/HPSJAVA-409/detector-model/src/test/resources/org/lcsim/geometry/subdetector/HPSTest.xml
    java/branches/HPSJAVA-409/detector-model/src/test/resources/org/lcsim/geometry/subdetector/HPSTestRunTracker2014.xml
    java/branches/HPSJAVA-409/detector-model/target/antrun/build-main.xml
    java/branches/HPSJAVA-409/detector-model/target/hps-detector-model-3.4.2-SNAPSHOT-bin.jar
    java/branches/HPSJAVA-409/detector-model/target/hps-detector-model-3.4.2-SNAPSHOT.jar
    java/branches/HPSJAVA-409/detector-model/target/maven-archiver/pom.properties
    java/branches/HPSJAVA-409/detector-model/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
    java/branches/HPSJAVA-409/detector-model/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
    java/branches/HPSJAVA-409/detector-model/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst
    java/branches/HPSJAVA-409/detector-model/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst
    java/branches/HPSJAVA-409/distribution/   (props changed)
    java/branches/HPSJAVA-409/distribution/pom.xml
    java/branches/HPSJAVA-409/distribution/src/main/java/org/hps/HPSJavaProperties.java
    java/branches/HPSJAVA-409/ecal-event-display/pom.xml
    java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/event/Association.java
    java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/event/Cluster.java
    java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/event/EcalHit.java
    java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/event/Event.java
    java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/io/EventManager.java
    java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/io/TextManager.java
    java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/lcsim/EventDisplayOutputDriver.java
    java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/lcsim/LCIOBridgeDriver.java
    java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/ui/ActiveViewer.java
    java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/ui/CalorimeterPanel.java
    java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/ui/DataFileViewer.java
    java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/ui/FileViewer.java
    java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/ui/PDataEventViewer.java
    java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/ui/PassiveViewer.java
    java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/ui/Viewer.java   (contents, props changed)
    java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/util/BooleanMap.java
    java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/util/ColorScale.java
    java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/util/CrystalEvent.java
    java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/util/CrystalListener.java
    java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/util/DatabaseCheck.java
    java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/util/GradientScale.java
    java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/util/MultiGradientScale.java
    java/branches/HPSJAVA-409/ecal-readout-sim/pom.xml
    java/branches/HPSJAVA-409/ecal-readout-sim/src/main/java/org/hps/readout/ecal/ClockSingleton.java
    java/branches/HPSJAVA-409/ecal-readout-sim/src/main/java/org/hps/readout/ecal/FADCEcalReadoutDriver.java
    java/branches/HPSJAVA-409/ecal-readout-sim/src/main/java/org/hps/readout/ecal/FADCPrimaryTriggerDriver.java
    java/branches/HPSJAVA-409/ecal-readout-sim/src/main/java/org/hps/readout/ecal/FADCTriggerDriver.java
    java/branches/HPSJAVA-409/ecal-readout-sim/src/main/java/org/hps/readout/ecal/FADCTriggerVariableDriver.java
    java/branches/HPSJAVA-409/ecal-readout-sim/src/main/java/org/hps/readout/ecal/MollerTriggerDriver.java
    java/branches/HPSJAVA-409/ecal-readout-sim/src/main/java/org/hps/readout/ecal/OccupancyAnalysisDriver.java
    java/branches/HPSJAVA-409/ecal-readout-sim/src/main/java/org/hps/readout/ecal/ReadoutTrigger.java
    java/branches/HPSJAVA-409/ecal-readout-sim/src/main/java/org/hps/readout/ecal/RingBuffer.java
    java/branches/HPSJAVA-409/ecal-readout-sim/src/main/java/org/hps/readout/ecal/TimeEvolutionEcalReadoutDriver.java
    java/branches/HPSJAVA-409/ecal-recon/pom.xml
    java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/EcalCalibrationsDriver.java
    java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/EcalConverterDriver.java
    java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/EcalEdepToTriggerConverterDriver.java
    java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/EcalOnlineRawConverter.java
    java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/EcalOnlineRawConverterDriver.java
    java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/EcalPedestalCalculator.java
    java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/EcalRawConverter.java
    java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/EcalRawConverterDriver.java
    java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/EcalRunningPedestalDriver.java
    java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/EcalTimeWalk.java
    java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/FADCGenericHit.java
    java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/IterateGainFactorDriver.java
    java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/AbstractClusterer.java
    java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/ClusterDriver.java
    java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/ClusterEnergyCorrection.java
    java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/ClusterPositionCorrection.java
    java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/ClusterUtilities.java
    java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/ClustererFactory.java
    java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/CopyClusterCollectionDriver.java
    java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/GTPClusterDriver.java
    java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/GTPClusterer.java
    java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/GTPOnlineClusterDriver.java
    java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/GTPOnlineClusterer.java
    java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/ReconClusterer.java
    java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/SimpleCosmicClusterer.java
    java/branches/HPSJAVA-409/evio/pom.xml
    java/branches/HPSJAVA-409/evio/src/main/java/org/hps/evio/AbstractSvtEvioReader.java
    java/branches/HPSJAVA-409/evio/src/main/java/org/hps/evio/AugmentedSvtEvioReader.java
    java/branches/HPSJAVA-409/evio/src/main/java/org/hps/evio/BasicEvioFileReader.java
    java/branches/HPSJAVA-409/evio/src/main/java/org/hps/evio/DummyEventBuilder.java
    java/branches/HPSJAVA-409/evio/src/main/java/org/hps/evio/EcalHitWriter.java
    java/branches/HPSJAVA-409/evio/src/main/java/org/hps/evio/EvioReader.java
    java/branches/HPSJAVA-409/evio/src/main/java/org/hps/evio/EvioToLcio.java
    java/branches/HPSJAVA-409/evio/src/main/java/org/hps/evio/LCSimEngRunEventBuilder.java
    java/branches/HPSJAVA-409/evio/src/main/java/org/hps/evio/RfFitFunction.java
    java/branches/HPSJAVA-409/evio/src/main/java/org/hps/evio/RfFitterDriver.java
    java/branches/HPSJAVA-409/evio/src/main/java/org/hps/evio/RfHit.java
    java/branches/HPSJAVA-409/evio/src/main/java/org/hps/evio/SvtEvioReader.java
    java/branches/HPSJAVA-409/evio/src/main/java/org/hps/evio/TestRunReconToEvio.java
    java/branches/HPSJAVA-409/evio/src/main/java/org/hps/evio/TestRunSvtEvioReader.java
    java/branches/HPSJAVA-409/evio/src/test/java/org/hps/evio/LCSimEngRunEventBuilderTest.java
    java/branches/HPSJAVA-409/evio/src/test/java/org/hps/evio/LCSimTestRunEventBuilderTest.java
    java/branches/HPSJAVA-409/evio/src/test/java/org/hps/evio/SvtEvioReaderTest.java
    java/branches/HPSJAVA-409/integration-tests/   (props changed)
    java/branches/HPSJAVA-409/integration-tests/pom.xml
    java/branches/HPSJAVA-409/integration-tests/src/test/java/org/hps/test/it/DataQualityMonitorTest.java
    java/branches/HPSJAVA-409/integration-tests/src/test/java/org/hps/test/it/EvioToLcioTest.java
    java/branches/HPSJAVA-409/integration-tests/src/test/java/org/hps/test/it/ReconSteeringTest.java
    java/branches/HPSJAVA-409/integration-tests/src/test/java/org/hps/test/it/SimpleSvtReadoutTest.java
    java/branches/HPSJAVA-409/integration-tests/src/test/resources/org/hps/ecalreadoutsim/EcalReadoutSimTest.lcsim
    java/branches/HPSJAVA-409/integration-tests/src/test/resources/org/hps/steering/test/DataQualityTest.lcsim
    java/branches/HPSJAVA-409/integration-tests/src/test/resources/org/hps/steering/test/Dummy.lcsim
    java/branches/HPSJAVA-409/integration-tests/src/test/resources/org/hps/steering/test/EcalReadoutSimTest.lcsim
    java/branches/HPSJAVA-409/job/pom.xml
    java/branches/HPSJAVA-409/job/src/main/java/org/hps/job/JobManager.java
    java/branches/HPSJAVA-409/logging/pom.xml
    java/branches/HPSJAVA-409/logging/src/main/resources/org/hps/logging/config/logging.properties
    java/branches/HPSJAVA-409/logging/src/main/resources/org/hps/logging/config/test_logging.properties
    java/branches/HPSJAVA-409/monitoring-app/   (props changed)
    java/branches/HPSJAVA-409/monitoring-app/pom.xml
    java/branches/HPSJAVA-409/monitoring-app/src/main/java/org/hps/monitoring/application/EventProcessing.java
    java/branches/HPSJAVA-409/monitoring-app/src/main/java/org/hps/monitoring/application/Main.java
    java/branches/HPSJAVA-409/monitoring-app/src/main/java/org/hps/monitoring/application/MonitoringApplication.java
    java/branches/HPSJAVA-409/monitoring-app/src/main/java/org/hps/monitoring/application/MonitoringApplicationFrame.java
    java/branches/HPSJAVA-409/monitoring-app/src/main/java/org/hps/monitoring/application/SystemStatusPanel.java
    java/branches/HPSJAVA-409/monitoring-app/src/main/java/org/hps/monitoring/application/util/TableExporter.java
    java/branches/HPSJAVA-409/monitoring-drivers/pom.xml
    java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/scalers/DeadtimePlots.java
    java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/svt/PedestalPlots.java
    java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/svt/SVTCellIDPrintDriver.java
    java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/svt/SVTHitRecoCorrelations.java
    java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/svt/SVTHitReconstructionPlots.java
    java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/svt/SampleZeroHVBiasChecker.java
    java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/svt/SensorOccupancyPlotsDriver.java
    java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/svt/SvtClusterPlots.java
    java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/svt/SvtHitPlots.java
    java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/svt/SvtTimingInPlots.java
    java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/trackrecon/PlotAndFitUtilities.java
    java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/trackrecon/SVTOpeningAlignment.java
    java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/trackrecon/TrackResiduals.java
    java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/trackrecon/TrackTimePlots.java
    java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/trackrecon/TrackingReconPlots.java
    java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/trackrecon/V0ReconPlots.java
    java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/BasicMonitoringPlotsDriver.java
    java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/EcalClusterPlots.java
    java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/EcalDaqPlots.java
    java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/EcalEventDisplay.java
    java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/EcalEventDisplayWithRawWaveform.java
    java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/EcalHitPlots.java
    java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/EcalLedSequenceMonitor.java
    java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/EcalMonitoringPlots.java
    java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/EcalPedestalViewer.java
    java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/EcalWindowPlotsXY.java
    java/branches/HPSJAVA-409/monitoring-util/pom.xml
    java/branches/HPSJAVA-409/monitoring-util/src/main/java/org/hps/monitoring/plotting/ExportPdf.java
    java/branches/HPSJAVA-409/monitoring-util/src/main/java/org/hps/monitoring/subsys/et/package-info.java
    java/branches/HPSJAVA-409/monitoring-util/src/main/java/org/hps/monitoring/trigger/AbstractTablePanel.java
    java/branches/HPSJAVA-409/monitoring-util/src/main/java/org/hps/monitoring/trigger/AbstractTriggerTablePanel.java
    java/branches/HPSJAVA-409/monitoring-util/src/main/java/org/hps/monitoring/trigger/AbstractTwoColumnTablePanel.java
    java/branches/HPSJAVA-409/monitoring-util/src/main/java/org/hps/monitoring/trigger/ClusterTablePanel.java
    java/branches/HPSJAVA-409/monitoring-util/src/main/java/org/hps/monitoring/trigger/ComponentUtils.java
    java/branches/HPSJAVA-409/monitoring-util/src/main/java/org/hps/monitoring/trigger/DiagnosticUpdatable.java
    java/branches/HPSJAVA-409/monitoring-util/src/main/java/org/hps/monitoring/trigger/EfficiencyTablePanel.java
    java/branches/HPSJAVA-409/monitoring-util/src/main/java/org/hps/monitoring/trigger/PairTablePanel.java
    java/branches/HPSJAVA-409/monitoring-util/src/main/java/org/hps/monitoring/trigger/ShifterTrigPanel.java
    java/branches/HPSJAVA-409/monitoring-util/src/main/java/org/hps/monitoring/trigger/ShifterTrigWindow.java
    java/branches/HPSJAVA-409/monitoring-util/src/main/java/org/hps/monitoring/trigger/SinglesTablePanel.java
    java/branches/HPSJAVA-409/monitoring-util/src/main/java/org/hps/monitoring/trigger/TableTextModel.java
    java/branches/HPSJAVA-409/monitoring-util/src/main/java/org/hps/monitoring/trigger/TriggerDiagnosticGUIDriver.java
    java/branches/HPSJAVA-409/parent/pom.xml
    java/branches/HPSJAVA-409/plugin/pom.xml
    java/branches/HPSJAVA-409/pom.xml
    java/branches/HPSJAVA-409/recon/pom.xml
    java/branches/HPSJAVA-409/recon/src/main/java/org/hps/recon/filtering/EcalGainCalibFilter.java
    java/branches/HPSJAVA-409/recon/src/main/java/org/hps/recon/filtering/EcalPairsFilter.java
    java/branches/HPSJAVA-409/recon/src/main/java/org/hps/recon/filtering/FEEFilterDriver.java
    java/branches/HPSJAVA-409/recon/src/main/java/org/hps/recon/filtering/MinimumHitsFilter.java
    java/branches/HPSJAVA-409/recon/src/main/java/org/hps/recon/filtering/PulserScalerAndEpicsFilter.java
    java/branches/HPSJAVA-409/recon/src/main/java/org/hps/recon/filtering/V0CandidateFilter.java
    java/branches/HPSJAVA-409/recon/src/main/java/org/hps/recon/particle/HpsReconParticleDriver.java
    java/branches/HPSJAVA-409/recon/src/main/java/org/hps/recon/particle/ReconParticleDriver.java
    java/branches/HPSJAVA-409/recon/src/main/java/org/hps/recon/particle/SimpleParticleID.java
    java/branches/HPSJAVA-409/recon/src/main/java/org/hps/recon/utils/TrackClusterMatcher.java
    java/branches/HPSJAVA-409/recon/src/main/java/org/hps/recon/vertexing/BaseSimpleVertexer.java
    java/branches/HPSJAVA-409/recon/src/main/java/org/hps/recon/vertexing/BilliorVertex.java
    java/branches/HPSJAVA-409/recon/src/main/java/org/hps/recon/vertexing/BilliorVertexer.java
    java/branches/HPSJAVA-409/recon/src/main/java/org/hps/recon/vertexing/TwoLineVertexer.java
    java/branches/HPSJAVA-409/recon/src/main/java/org/hps/recon/vertexing/TwoParticleVertexer.java
    java/branches/HPSJAVA-409/recon/src/main/java/org/hps/recon/vertexing/TwoTrackFringeVertexer.java
    java/branches/HPSJAVA-409/recon/src/test/java/org/hps/recon/particle/HpsReconParticleDriverTest.java
    java/branches/HPSJAVA-409/record-util/pom.xml
    java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/AbstractRecordProcessor.java
    java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/AbstractRecordQueue.java
    java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/RecordProcessor.java
    java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/composite/RecordProcessorAdapter.java
    java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/daqconfig/DAQConfig.java
    java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/daqconfig/DAQConfigDriver.java
    java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/daqconfig/EvioDAQParser.java
    java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/daqconfig/FADCConfig.java
    java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/daqconfig/GTPConfig.java
    java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/daqconfig/IDAQConfig.java
    java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/daqconfig/SSPConfig.java
    java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/epics/EpicsData.java
    java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/epics/EpicsEvioProcessor.java
    java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/epics/EpicsRunProcessor.java
    java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/evio/EventTagConstant.java
    java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/evio/EvioBankTag.java
    java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/evio/EvioDetectorConditionsProcessor.java
    java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/evio/EvioEventSkimmer.java
    java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/evio/EvioEventUtilities.java
    java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/evio/EvioFileProducer.java
    java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/evio/EvioFileSource.java
    java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/evio/EvioFileUtilities.java
    java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/evio/EvioLoop.java
    java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/evio/EvioLoopAdapter.java
    java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/scalers/ScalerUtilities.java
    java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/svt/SvtEvioUtils.java
    java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/triggerbank/AbstractIntData.java
    java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/triggerbank/SSPData.java
    java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/triggerbank/SSPNumberedTrigger.java
    java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/triggerbank/SSPPairTrigger.java
    java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/triggerbank/SSPSinglesTrigger.java
    java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/triggerbank/TIData.java
    java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/triggerbank/TiTimeOffsetEvioProcessor.java
    java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/triggerbank/TriggerModule.java
    java/branches/HPSJAVA-409/run-database/pom.xml
    java/branches/HPSJAVA-409/run-database/src/main/java/org/hps/run/database/EpicsDataDao.java
    java/branches/HPSJAVA-409/run-database/src/main/java/org/hps/run/database/EpicsDataDaoImpl.java
    java/branches/HPSJAVA-409/run-database/src/main/java/org/hps/run/database/EpicsType.java
    java/branches/HPSJAVA-409/run-database/src/main/java/org/hps/run/database/EpicsVariable.java
    java/branches/HPSJAVA-409/run-database/src/main/java/org/hps/run/database/RunDatabaseCommandLine.java
    java/branches/HPSJAVA-409/run-database/src/main/java/org/hps/run/database/RunManager.java
    java/branches/HPSJAVA-409/run-database/src/main/java/org/hps/run/database/RunSummary.java
    java/branches/HPSJAVA-409/run-database/src/main/java/org/hps/run/database/RunSummaryDao.java
    java/branches/HPSJAVA-409/run-database/src/main/java/org/hps/run/database/RunSummaryDaoImpl.java
    java/branches/HPSJAVA-409/run-database/src/main/java/org/hps/run/database/RunSummaryImpl.java
    java/branches/HPSJAVA-409/run-database/src/main/java/org/hps/run/database/ScalerDataDaoImpl.java
    java/branches/HPSJAVA-409/run-database/src/main/java/org/hps/run/database/package-info.java
    java/branches/HPSJAVA-409/steering-files/pom.xml
    java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/analysis/StarterAnalysis.lcsim
    java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/monitoring/EcalLedSequenceMonitoringApp.lcsim
    java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/monitoring/EcalLedSequenceStandalone.lcsim
    java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/monitoring/EcalMonitoringFinal.lcsim
    java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/monitoring/EcalMonitoringOnly.lcsim
    java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/monitoring/SvtOnlineMonitoring.lcsim
    java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/monitoring/TriggerDiagnosticsMonitoring.lcsim
    java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/production/V0CandidateFilter.lcsim
    java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/readout/CommRun2014TightPairs.lcsim
    java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/readout/EngineeringRun2014PrescaledTriggers.lcsim
    java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/readout/HPS2014ReadoutNoPileup.lcsim
    java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/readout/HPS2014ReadoutToEvio.lcsim
    java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/readout/HPS2014TruthReadoutToLcio.lcsim
    java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/readout/LcioToEvio.lcsim
    java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/readout/TestRunNoPileup.lcsim
    java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/readout/TestRunReadoutToEvio.lcsim
    java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/recon/EngineeringRun2014EcalReconMC.lcsim
    java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/recon/EngineeringRun2015FullRecon.lcsim
    java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/recon/EngineeringRun2015FullReconMC.lcsim
    java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/users/celentan/LedAnalysisFromEvio.lcsim
    java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/users/holly/ClusterRecon.lcsim
    java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/users/holly/EcalSimReadout.lcsim
    java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/users/holly/EngineeringRun2015EcalOnly.lcsim
    java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/users/holly/EngineeringRun2015_FEEIter_Filter.lcsim
    java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/users/holly/QuickEcalReadout.lcsim
    java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/users/meeg/EcalScoring.lcsim
    java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/users/meeg/HitTimes.lcsim
    java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/users/meeg/PairsSkimmer.lcsim
    java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/users/meeg/SmallHits.lcsim
    java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/users/meeg/ecal_fadc_bkgd.lcsim
    java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/users/meeg/raw_triggers.lcsim
    java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/users/phansson/EngineeringRun2015FullRecon_Pass2_Gbl.lcsim
    java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/users/phansson/TestRunOfflineRecon.lcsim
    java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/users/rafo/TestSteering.lcsim
    java/branches/HPSJAVA-409/tracking/pom.xml
    java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/readout/svt/FpgaData.java
    java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/DumbShaperFit.java
    java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/HelicalTrackHitDriver.java
    java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/HitTimeTrackCheck.java
    java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/NearestNeighborRMSClusterer.java
    java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/NoiselessReadoutChip.java
    java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/SVTBadChannelFilterDriver.java
    java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/ShaperLinearFitAlgorithm.java
    java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/StrategyType.java
    java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/TrackData.java
    java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/TrackDataDriver.java
    java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/TrackQualityData.java
    java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/TrackResidualsData.java
    java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/TrackTimeData.java
    java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/TrackUtils.java
    java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/TrackerReconDriver.java
    java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/WTrack.java
    java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/axial/HelicalTrack2DHit.java
    java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/gbl/FittedGblTrajectory.java
    java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/gbl/GBLEventData.java
    java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/gbl/GBLFileIO.java
    java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/gbl/GBLKinkData.java
    java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/gbl/GBLOutput.java
    java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/gbl/GBLOutputDriver.java
    java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/gbl/GBLRefitterDriver.java
    java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/gbl/GBLStripClusterData.java
    java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/gbl/GBLTrackData.java
    java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/gbl/GblData.java
    java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/gbl/GblPoint.java
    java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/gbl/GblTrajectory.java
    java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/gbl/GblUtils.java
    java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/gbl/HelicalTrackStripGbl.java
    java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/gbl/HpsGblRefitter.java
    java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/gbl/MakeGblTracks.java
    java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/gbl/TruthResiduals.java
    java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/gbl/matrix/Matrix.java
    java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/gbl/matrix/Vector.java
    java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/svt/alignment/BuildCompact.java
    java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/svt/alignment/BuildMillepedeCompact.java
    java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/svt/alignment/HPSStrips.java
    java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/svt/alignment/MillepedeCompactDump.java
    java/branches/HPSJAVA-409/tracking/src/main/resources/org/hps/recon/tracking/strategies/HPS-Test-All.xml
    java/branches/HPSJAVA-409/tracking/src/test/java/org/hps/recon/tracking/HelicalTrackHitDriverTest.java
    java/branches/HPSJAVA-409/tracking/src/test/java/org/hps/recon/tracking/TruthResidualTest.java
    java/branches/HPSJAVA-409/users/pom.xml
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/baltzell/RfFitFunction.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/baltzell/RfFitterDriver.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/baltzell/RfHit.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/celentan/RawPedestalComputator.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/celentan/StripChartTest.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/holly/ClusterDriver.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/holly/EcalClusterICPosition.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/holly/EcalClustererCosmics.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/holly/EcalRawConverter.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/holly/HPSEcalClusterIC.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/jeremym/EvioFileScanner.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/ClusterAnalysisDriver.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/CountTriggersDriver.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/EvioAnalysis.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/FADCAnalysisDriver.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/HPSEcalDataPlotsDriver.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/InvariantMassPairDriver.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/MTEAnalysis.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/MTETriggerPlotsFormatter.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/ParticleMCAnalysisDriver.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/PlotsFormatter.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/RafoAnalysis.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/TridentTrackDriver.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/TriggerPlotsModule.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/TriggerProcessAnalysisDriver.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/plots/AddPlots.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/plots/FormattedPlot.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/plots/FormattedPlot1D.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/plots/FormattedPlot2D.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/plots/PlotFormatModule.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/plots/PlotsFormatter.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/plots/formatter/InvariantMassPlotsFormatter.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/plots/formatter/MTEPlotFormatter.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/plots/formatter/MTETriggerPlotsFormatter.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/plots/formatter/ParticleMCAnalysisPlotsFormatter.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/plots/formatter/RafoTridentFormatter.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/plots/formatter/SingleTriggerPlotsFormatter.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/plots/formatter/TridentTrackFormatter.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/plots/formatter/TriggerPlotsFormat.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/luca/FADCVariableTriggerFEEDriver.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/luca/FEETrigger.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/luca/FEETrigger2.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/luca/LCIOReadScript.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/luca/rate.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/luca/ratesim.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/meeg/FilterMCBunches.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/meeg/HPSEcalAnalogPrintDriver.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/meeg/HPSEcalDigitalPrintDriver.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/meeg/HPSEcalRawTrackerHitPrintDriver.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/meeg/HPSGenericRawTrackerHitPrintDriver.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/meeg/LCIOTrackAnalysis.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/meeg/MergeMCBunches.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/meeg/SvtChargeIntegrator.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/meeg/TridentMCFilter.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/mgraham/ExamplePlotter.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/mgraham/HPSTrackerHit.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/mgraham/HelicalTrackHitResidualsDriver.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/mgraham/SVTRawTrackerHitThresholdDriver.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/mgraham/TrackExtrapolationAnalysis.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/mgraham/TwoTrackAnalysis.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/omoreno/EcalScoringPlaneDriver.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/omoreno/ExtrapolationAnalysis.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/omoreno/LheToStdhep.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/omoreno/PlotUtils.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/omoreno/ReconstructedParticleChecker.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/omoreno/SharedHitAnalysis.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/omoreno/SvtClusterAnalysis.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/omoreno/SvtDataRates.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/omoreno/SvtHitCorrelations.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/omoreno/SvtQA.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/omoreno/SvtTrackAnalysis.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/omoreno/SvtTrackRecoEfficiency.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/omoreno/TestRunTrackReconEfficiency.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/phansson/CmpGenToFittedTracksDriver.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/phansson/DataTrackerFakeHitDriver.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/phansson/FastTrackResidualDriver.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/phansson/ParticleHelixProducer.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/phansson/SimpleResiduals.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/phansson/TrackingReconstructionPlots.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/phansson/TriggerTurnOnAnalysis.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/phansson/TruthMomentumResolutionDriver.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/rafo/test1.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/spaul/GetChargeFromScalersMultirun.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/spaul/HitrateHistograms.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/spaul/PulserFilter.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/spaul/StyleUtil.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/spaul/SumEverything.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/spaul/feecc/BinGenerator.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/spaul/feecc/CustomBinning.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/spaul/feecc/DisplayHistograms.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/spaul/feecc/EcalUtil.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/spaul/feecc/MakeHistograms.java
    java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/spaul/feecc/ShowCustomBinning.java
    java/branches/HPSJAVA-409/util/pom.xml
    java/branches/HPSJAVA-409/util/src/main/java/org/hps/util/CalculateAcceptanceFromMadGraph.java
    java/branches/HPSJAVA-409/util/src/main/java/org/hps/util/ConvertToStdhep.java
    java/branches/HPSJAVA-409/util/src/main/java/org/hps/util/DumpLHEEventsToASCII.java
    java/branches/HPSJAVA-409/util/src/main/java/org/hps/util/LCIOFilterDriver.java
    java/branches/HPSJAVA-409/util/src/main/java/org/hps/util/MergeBunches.java

Modified: java/branches/HPSJAVA-409/analysis/pom.xml
 =============================================================================
--- java/branches/HPSJAVA-409/analysis/pom.xml	(original)
+++ java/branches/HPSJAVA-409/analysis/pom.xml	Wed Apr 27 11:11:32 2016
@@ -8,7 +8,7 @@
         <groupId>org.hps</groupId>
         <artifactId>hps-parent</artifactId>
         <relativePath>../parent/pom.xml</relativePath>
-        <version>3.4.2-SNAPSHOT</version>
+        <version>3.9-SNAPSHOT</version>
     </parent>
     <scm>
         <url>http://java.freehep.org/svn/repos/hps/list/java/trunk/analysis/</url>
@@ -21,4 +21,17 @@
             <artifactId>hps-recon</artifactId>
         </dependency>
     </dependencies>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <configuration>
+                    <excludes>
+                        <exclude>**/VertexAnalysisTest.java</exclude>
+                    </excludes>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
 </project>

Modified: java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/dataquality/DQMDatabaseManager.java
 =============================================================================
--- java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/dataquality/DQMDatabaseManager.java	(original)
+++ java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/dataquality/DQMDatabaseManager.java	Wed Apr 27 11:11:32 2016
@@ -7,10 +7,7 @@
 import java.sql.Statement;
 import java.util.ArrayList;
 import java.util.List;
-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.hps.conditions.api.TableMetaData;

Modified: java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/dataquality/DataQualityMonitor.java
 =============================================================================
--- java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/dataquality/DataQualityMonitor.java	(original)
+++ java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/dataquality/DataQualityMonitor.java	Wed Apr 27 11:11:32 2016
@@ -1,5 +1,7 @@
 package org.hps.analysis.dataquality;
 
+import java.io.FileNotFoundException;
+import java.io.PrintWriter;
 import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.util.HashMap;
@@ -7,7 +9,7 @@
 import java.util.Map;
 import java.util.logging.Level;
 import java.util.logging.Logger;
-
+import org.apache.commons.lang3.StringUtils;
 import org.hps.record.triggerbank.AbstractIntData;
 import org.hps.record.triggerbank.TIData;
 import org.lcsim.event.EventHeader;
@@ -23,8 +25,8 @@
  * calculateEndOfRunQuantities & printDQMData i.e. useful methods
  */
 public class DataQualityMonitor extends Driver {
-    
-    private static Logger LOGGER = Logger.getLogger(DataQualityMonitor.class.getPackage().getName());
+
+    private static final Logger LOGGER = Logger.getLogger(DataQualityMonitor.class.getPackage().getName());
 
     protected AIDA aida = AIDA.defaultInstance();
     protected DQMDatabaseManager manager;
@@ -38,6 +40,11 @@
     protected boolean outputPlots = false;
     protected String outputPlotDir = "DQMOutputPlots/";
 
+    protected PrintWriter tupleWriter = null;
+    protected String[] tupleVariables = {};
+    protected final Map<String, Double> tupleMap = new HashMap<String, Double>();
+    protected boolean cutTuple = false;
+
     String triggerType = "all";//allowed types are "" (blank) or "all", singles0, singles1, pairs0,pairs1
     public boolean isGBL = false;
 
@@ -58,7 +65,7 @@
     }
 
     public void setRunNumber(int run) {
-        this.runNumber = run;
+        DataQualityMonitor.runNumber = run;
     }
 
     public void setOverwriteDB(boolean overwrite) {
@@ -81,17 +88,15 @@
         this.outputPlotDir = dir;
     }
 
-    public void DataQualityMonitor() {
-
-    }
-
+    @Override
     public void endOfData() {
         calculateEndOfRunQuantities();
         fillEndOfRunPlots();
         printDQMData();
-        if (printDQMStrings)
+        if (printDQMStrings) {
             printDQMStrings();
-        LOGGER.info("Should I write to the database?  " + connectToDB);
+        }
+        LOGGER.info("Write to database =  " + connectToDB);
         if (connectToDB) {
             LOGGER.info("Connecting To Database...getting DQMDBManager");
             manager = DQMDatabaseManager.getInstance();
@@ -99,17 +104,21 @@
             boolean entryExists = false;
             try {
                 entryExists = checkRowExists();
-                if (entryExists)
+                if (entryExists) {
                     LOGGER.info("Found an existing run/reco entry in the dqm database; overwrite = " + overwriteDB);
+                }
             } catch (SQLException ex) {
                 Logger.getLogger(DataQualityMonitor.class.getName()).log(Level.SEVERE, null, ex);
             }
 
-            if (!entryExists)
+            if (!entryExists) {
                 makeNewRow();
+            }
             dumpDQMData();
         }
-
+        if (tupleWriter != null) {
+            tupleWriter.close();
+        }
     }
 
     private void makeNewRow() {
@@ -127,9 +136,7 @@
     private boolean checkRowExists() throws SQLException {
         String ins = "select * from dqm where " + getRunRecoString();
         ResultSet res = manager.selectQuery(ins);
-        if (res.next()) //this is a funny way of determining if the ResultSet has any entries
-            return true;
-        return false;
+        return res.next(); //this is a funny way of determining if the ResultSet has any entries
     }
 
     public boolean checkSelectionIsNULL(String var) throws SQLException {
@@ -137,8 +144,9 @@
         ResultSet res = manager.selectQuery(ins);
         res.next();
         double result = res.getDouble(var);
-        if (res.wasNull())
-            return true;
+        if (res.wasNull()) {
+            return true;
+        }
         LOGGER.info("checkSelectionIsNULL::" + var + " = " + result);
         return false;
     }
@@ -183,16 +191,21 @@
     }
 
     public boolean matchTriggerType(TIData triggerData) {
-        if (triggerType.contentEquals("") || triggerType.contentEquals("all"))
-            return true;
-        if (triggerData.isSingle0Trigger() && triggerType.contentEquals("singles0"))
-            return true;
-        if (triggerData.isSingle1Trigger() && triggerType.contentEquals("singles1"))
-            return true;
-        if (triggerData.isPair0Trigger() && triggerType.contentEquals("pairs0"))
-            return true;
-        if (triggerData.isPair1Trigger() && triggerType.contentEquals("pairs1"))
-            return true;
+        if (triggerType.contentEquals("") || triggerType.contentEquals("all")) {
+            return true;
+        }
+        if (triggerData.isSingle0Trigger() && triggerType.contentEquals("singles0")) {
+            return true;
+        }
+        if (triggerData.isSingle1Trigger() && triggerType.contentEquals("singles1")) {
+            return true;
+        }
+        if (triggerData.isPair0Trigger() && triggerType.contentEquals("pairs0")) {
+            return true;
+        }
+        if (triggerData.isPair1Trigger() && triggerType.contentEquals("pairs1")) {
+            return true;
+        }
         return false;
 
     }
@@ -201,14 +214,18 @@
         boolean match = true;
         if (event.hasCollection(GenericObject.class, "TriggerBank")) {
             List<GenericObject> triggerList = event.get(GenericObject.class, "TriggerBank");
-            for (GenericObject data : triggerList)
+            for (GenericObject data : triggerList) {
                 if (AbstractIntData.getTag(data) == TIData.BANK_TAG) {
                     TIData triggerData = new TIData(data);
                     if (!matchTriggerType(triggerData))//only process singles0 triggers...
+                    {
                         match = false;
+                    }
                 }
-        } else if (debug)
+            }
+        } else if (debug) {
             LOGGER.info(this.getClass().getSimpleName() + ":  No trigger bank found...running over all trigger types");
+        }
         return match;
     }
 
@@ -223,4 +240,42 @@
     public void printDQMStrings() {
     }
 
+    protected void writeTuple() {
+        for (String variable : tupleVariables) {
+            Double value = tupleMap.get(variable);
+            if (value == null) {
+                value = -9999.0;
+            }
+            if (variable.endsWith("/I") || variable.endsWith("/B")) {
+                tupleWriter.format("%d\t", Math.round(value));
+            } else {
+                tupleWriter.format("%f\t", value);
+            }
+        }
+        tupleWriter.println();
+        tupleMap.clear();
+    }
+
+    public void setTupleFile(String tupleFile) {
+        try {
+            tupleWriter = new PrintWriter(tupleFile);
+        } catch (FileNotFoundException e) {
+            tupleWriter = null;
+        }
+        tupleWriter.println(StringUtils.join(tupleVariables, ":"));
+//        for (String variable : tupleVariables) {
+//            tupleWriter.format("%s:", variable);
+//        }
+//        tupleWriter.println();
+    }
+
+    /**
+     * apply loose cuts to the tuple (cuts to be defined in the specific DQM
+     * driver)
+     *
+     * @param cutTuple
+     */
+    public void setCutTuple(boolean cutTuple) {
+        this.cutTuple = cutTuple;
+    }
 }

Modified: java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/dataquality/EcalMonitoring.java
 =============================================================================
--- java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/dataquality/EcalMonitoring.java	(original)
+++ java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/dataquality/EcalMonitoring.java	Wed Apr 27 11:11:32 2016
@@ -8,6 +8,7 @@
 import java.util.logging.Logger;
 
 import org.apache.commons.math.stat.StatUtils;
+import org.hps.conditions.beam.BeamEnergy.BeamEnergyCollection;
 import org.hps.recon.ecal.cluster.ClusterUtilities;
 import org.lcsim.event.CalorimeterHit;
 import org.lcsim.event.Cluster;
@@ -73,7 +74,11 @@
     boolean fillHitPlots = true;
     String[] ecalQuantNames = {"avg_N_hits", "avg_Hit_Energy",
         "avg_N_clusters", "avg_N_hitsPerCluster", "avg_Cluster_Energy", "avg_ClusterTime"};
-    double maxE = 1.1;
+    
+    double maxFactor = 1.5;
+    
+   
+    
     private final String plotHitsDir = "EcalHits/";
     private final String plotClustersDir = "EcalClusters/";
     private final String plotFidCutDir = "FiducialCut/";
@@ -90,44 +95,49 @@
         this.clusterCollectionName = clusterCollectionName;
     }
 
+    
     public void setFillHitPlots(boolean fill) {
         this.fillHitPlots = fill;
     }
 
     @Override
     protected void detectorChanged(Detector detector) {
+        BeamEnergyCollection beamEnergyCollection = 
+            this.getConditionsManager().getCachedConditions(BeamEnergyCollection.class, "beam_energies").getCachedData();        
+        double beamEnergy = beamEnergyCollection.get(0).getBeamEnergy();
+        //this.getConditionsManager().getCachedConditions(org.hps.conditions.EcalChannelCollection.class, "ecal_channels").
         LOGGER.info("EcalMonitoring::detectorChanged  Setting up the plotter");
         aida.tree().cd("/");
         if (fillHitPlots) {
             // Setup hit plots.
             hitCountPlot = aida.histogram1D(plotHitsDir + triggerType + "/"+ calibratedHitCollectionName + " Hit Count In Event", 40, -0.5, 39.5);
             hitTimePlot = aida.histogram1D(plotHitsDir + triggerType + "/"+calibratedHitCollectionName + " Hit Time", 50, 0 * 4.0, 50 * 4.0);
-            hitEnergyPlot = aida.histogram1D(plotHitsDir + triggerType + "/"+calibratedHitCollectionName + " Hit Energy", 100, -0.1, maxE);
+            hitEnergyPlot = aida.histogram1D(plotHitsDir + triggerType + "/"+calibratedHitCollectionName + " Hit Energy", 100, -0.1, beamEnergy*maxFactor);
             fiducialHitCountPlot = aida.histogram1D(plotHitsDir + triggerType + "/"+calibratedHitCollectionName + " Hit Count with Fiducial Cut", 10, -0.5, 9.5);
-            fiducialEnergyPlot = aida.histogram1D(plotHitsDir + triggerType + "/"+calibratedHitCollectionName + " Hit Energy with Fiducial Cut", 100, -0.1, maxE);
+            fiducialEnergyPlot = aida.histogram1D(plotHitsDir + triggerType + "/"+calibratedHitCollectionName + " Hit Energy with Fiducial Cut", 100, -0.1, beamEnergy*maxFactor);
         }
         // Setup cluster plots
         clusterCountPlot = aida.histogram1D(plotClustersDir +  triggerType + "/"+clusterCollectionName + " Cluster Count per Event", 10, -0.5, 9.5);
         clusterSizePlot = aida.histogram1D(plotClustersDir +  triggerType + "/"+clusterCollectionName + " Cluster Size", 10, -0.5, 9.5);
-        clusterEnergyPlot = aida.histogram1D(plotClustersDir +  triggerType + "/"+clusterCollectionName + " Cluster Energy", 100, -0.1, maxE);
+        clusterEnergyPlot = aida.histogram1D(plotClustersDir +  triggerType + "/"+clusterCollectionName + " Cluster Energy", 100, -0.1, beamEnergy*maxFactor);
         clusterTimes = aida.histogram1D(plotClustersDir +  triggerType + "/"+clusterCollectionName + " Cluster Seed Times", 400, 0, 4.0 * 50);
         clusterTimeMean = aida.histogram1D(plotClustersDir +  triggerType + "/"+clusterCollectionName + " Cluster Time Mean", 400, 0, 4.0 * 50);
         clusterTimeSigma = aida.histogram1D(plotClustersDir +  triggerType + "/"+clusterCollectionName + " Cluster Time Sigma", 100, 0, 10);
-        twoclusterTotEnergy = aida.histogram1D(plotClustersDir +  triggerType + "/"+clusterCollectionName + " Two Cluster Energy Sum", 100, 0, maxE);
-        twoclusterEnergyAsymmetry = aida.histogram1D(plotClustersDir +  triggerType + "/"+clusterCollectionName + " Two Cluster Energy Asymmetry", 100, 0, 1.0);
-        energyVsT = aida.histogram2D(plotClustersDir +  triggerType + "/"+clusterCollectionName + " Energy vs time", 400, 0.0, 200.0, 100, -0.1, maxE);
+        twoclusterTotEnergy = aida.histogram1D(plotClustersDir +  triggerType + "/"+clusterCollectionName + " Two Cluster Energy Sum", 100, 0, beamEnergy*maxFactor);
+        twoclusterEnergyAsymmetry = aida.histogram1D(plotClustersDir +  triggerType + "/"+clusterCollectionName + " Two Cluster Energy Asymmetry", 100, 0, beamEnergy*maxFactor);
+        energyVsT = aida.histogram2D(plotClustersDir +  triggerType + "/"+clusterCollectionName + " Energy vs time", 400, 0.0, 200.0, 100, -0.1, beamEnergy*maxFactor);
         xVsY = aida.histogram2D(plotClustersDir +  triggerType + "/"+clusterCollectionName + " X vs Y (NHits >1)", 200, -200.0, 200.0, 85, -85.0, 85.0);
-        energyVsX = aida.histogram2D(plotClustersDir +  triggerType + "/"+clusterCollectionName + " Energy vs X", 50, 0, 1.6, 50, .0, 200.0);
-        energyVsY = aida.histogram2D(plotClustersDir +  triggerType + "/"+clusterCollectionName + " Energy vs Y", 50, 0, 1.6, 50, 20.0, 85.0);
-        pairsE1vsE2 = aida.histogram2D(plotClustersDir +  triggerType + "/"+clusterCollectionName + "Pair E1 vs E2", 50, 0, 2, 50, 0, 2);
+        energyVsX = aida.histogram2D(plotClustersDir +  triggerType + "/"+clusterCollectionName + " Energy vs X", 50, 0, maxFactor*beamEnergy, 50, .0, 200.0);
+        energyVsY = aida.histogram2D(plotClustersDir +  triggerType + "/"+clusterCollectionName + " Energy vs Y", 50, 0, maxFactor*beamEnergy, 50, 20.0, 85.0);
+        pairsE1vsE2 = aida.histogram2D(plotClustersDir +  triggerType + "/"+clusterCollectionName + "Pair E1 vs E2", 50, 0, beamEnergy*maxFactor, 50, 0, beamEnergy*maxFactor);
         pairsT1vsT2 = aida.histogram2D(plotClustersDir +  triggerType + "/"+clusterCollectionName + "Pair T1 vs T2", 200, 0, 100, 200, 0, 100);
         pairsDeltaT = aida.histogram1D(plotClustersDir + triggerType + "/" + clusterCollectionName + " Pair Time Difference", 100, -20.0, 20.0);
 
         fiducialClusterCountPlot = aida.histogram1D(plotClustersDir +  triggerType + "/"+plotFidCutDir + clusterCollectionName + " Cluster Count with Fiducal Cut", 10, -0.5, 9.5);
         fiducialClusterSizePlot = aida.histogram1D(plotClustersDir+  triggerType + "/" +plotFidCutDir + clusterCollectionName + " Cluster Size with Fiducal Cut", 10, -0.5, 9.5);
-        fiducialClusterEnergyPlot = aida.histogram1D(plotClustersDir +  triggerType + "/"+plotFidCutDir  + clusterCollectionName + " Cluster Energy with Fiducal Cut", 100, -0.1, maxE);
-        fiducialenergyVsY = aida.histogram2D(plotClustersDir +  triggerType + "/"+plotFidCutDir + clusterCollectionName + " Energy vs Y with Fiducial Cuts", 50, 0, 1.6, 50, 45.0, 85.0);
-        fiducialenergyVsX = aida.histogram2D(plotClustersDir+  triggerType + "/" +plotFidCutDir + clusterCollectionName + " Energy vs X with Fiducial Cuts", 50, 0, 1.6, 50, 0.0, 200.0);
+        fiducialClusterEnergyPlot = aida.histogram1D(plotClustersDir +  triggerType + "/"+plotFidCutDir  + clusterCollectionName + " Cluster Energy with Fiducal Cut", 100, -0.1, beamEnergy*maxFactor);
+        fiducialenergyVsY = aida.histogram2D(plotClustersDir +  triggerType + "/"+plotFidCutDir + clusterCollectionName + " Energy vs Y with Fiducial Cuts", 50, 0, beamEnergy*maxFactor, 50, 45.0, 85.0);
+        fiducialenergyVsX = aida.histogram2D(plotClustersDir+  triggerType + "/" +plotFidCutDir + clusterCollectionName + " Energy vs X with Fiducial Cuts", 50, 0, beamEnergy*maxFactor, 50, 0.0, 200.0);
 
     }
 
@@ -265,5 +275,5 @@
     public void printDQMStrings() {
 
     }
-
+    
 }

Modified: java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/dataquality/FinalStateMonitoring.java
 =============================================================================
--- java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/dataquality/FinalStateMonitoring.java	(original)
+++ java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/dataquality/FinalStateMonitoring.java	Wed Apr 27 11:11:32 2016
@@ -17,6 +17,7 @@
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
+import org.hps.conditions.beam.BeamEnergy.BeamEnergyCollection;
 import org.hps.recon.ecal.cluster.ClusterUtilities;
 import org.hps.recon.tracking.TrackType;
 import org.hps.recon.tracking.TrackUtils;
@@ -60,9 +61,9 @@
     double sumdelY = 0.0;
     double sumEoverP = 0.0;
     private final String plotDir = "FinalStateParticles/";
-    double beamEnergy = 1.05; //GeV
+   // double beamEnergy = 1.05; //GeV
     double maxFactor = 1.5;
-    double feeMomentumCut = 0.8; //GeV
+    double feeMomentumCut = 0.75; //this number, multiplied by the beam energy, is the actual cut
 
     IHistogram1D elePx;
     IHistogram1D elePy;
@@ -97,12 +98,19 @@
     /* number of unassocaited tracks/event */
     IHistogram1D nUnAssTracksHisto;
     
+    
+   
     public void setFinalStateParticlesColName(String fsp) {
         this.finalStateParticlesColName = fsp;
     }
 
     @Override
     protected void detectorChanged(Detector detector) {
+        BeamEnergyCollection beamEnergyCollection = 
+            this.getConditionsManager().getCachedConditions(BeamEnergyCollection.class, "beam_energies").getCachedData();        
+        double beamEnergy = beamEnergyCollection.get(0).getBeamEnergy();
+        
+        
         LOGGER.info("Setting up the plotter");
         aida.tree().cd("/");
           String trkType="SeedTrack/";
@@ -111,24 +119,24 @@
        
         /*  Final State Particle Quantities   */
         /*  plot electron & positron momentum separately  */
-        elePx = aida.histogram1D(plotDir +trkType+ triggerType + "/" + "Electron Px (GeV)", 100, -0.1, 0.200);
-        elePy = aida.histogram1D(plotDir +trkType+ triggerType + "/" + "Electron Py (GeV)", 100, -0.1, 0.1);
+        elePx = aida.histogram1D(plotDir +trkType+ triggerType + "/" + "Electron Px (GeV)", 100, -0.1*beamEnergy, 0.200*beamEnergy);
+        elePy = aida.histogram1D(plotDir +trkType+ triggerType + "/" + "Electron Py (GeV)", 100, -0.1*beamEnergy, 0.1*beamEnergy);
         elePz = aida.histogram1D(plotDir +trkType+ triggerType + "/" + "Electron Pz (GeV)", 100, 0, beamEnergy * maxFactor);
-        elePzBeam = aida.histogram1D(plotDir +trkType+ triggerType + "/" + "Beam Electrons Total P (GeV)", 100, feeMomentumCut, beamEnergy * maxFactor);
-        elePzBeamTop = aida.histogram1D(plotDir +trkType+ triggerType + "/" + "Beam Electrons Total P (GeV):  Top", 100, feeMomentumCut, beamEnergy * maxFactor);
-        elePzBeamBottom = aida.histogram1D(plotDir +trkType+ triggerType + "/" + "Beam Electrons Total P (GeV):  Bottom", 100, feeMomentumCut, beamEnergy * maxFactor);
+        elePzBeam = aida.histogram1D(plotDir +trkType+ triggerType + "/" + "Beam Electrons Total P (GeV)", 100, feeMomentumCut*beamEnergy, beamEnergy * maxFactor);
+        elePzBeamTop = aida.histogram1D(plotDir +trkType+ triggerType + "/" + "Beam Electrons Total P (GeV):  Top", 100, feeMomentumCut*beamEnergy, beamEnergy * maxFactor);
+        elePzBeamBottom = aida.histogram1D(plotDir +trkType+ triggerType + "/" + "Beam Electrons Total P (GeV):  Bottom", 100, feeMomentumCut*beamEnergy, beamEnergy * maxFactor);
         elePTop = aida.histogram1D(plotDir +trkType+ triggerType + "/" + "Electron Total P (GeV):  Top", 100, 0, beamEnergy * maxFactor);
         elePBottom = aida.histogram1D(plotDir +trkType+ triggerType + "/" + "Electron Total P (GeV):  Bottom", 100, 0, beamEnergy * maxFactor);
 
-        posPx = aida.histogram1D(plotDir +trkType+ triggerType + "/" + "Positron Px (GeV)", 50, -0.1, 0.200);
-        posPy = aida.histogram1D(plotDir +trkType+ triggerType + "/" + "Positron Py (GeV)", 50, -0.1, 0.1);
+        posPx = aida.histogram1D(plotDir +trkType+ triggerType + "/" + "Positron Px (GeV)", 50, -0.1*beamEnergy, 0.200*beamEnergy);
+        posPy = aida.histogram1D(plotDir +trkType+ triggerType + "/" + "Positron Py (GeV)", 50, -0.1*beamEnergy, 0.1*beamEnergy);
         posPz = aida.histogram1D(plotDir +trkType+ triggerType + "/" + "Positron Pz (GeV)", 50, 0, beamEnergy * maxFactor);
         posPTop = aida.histogram1D(plotDir +trkType+ triggerType + "/" + "Positron Total P (GeV):  Top", 100, 0, beamEnergy * maxFactor);
         posPBottom = aida.histogram1D(plotDir +trkType+ triggerType + "/" + "Positron Total P (GeV):  Bottom", 100, 0, beamEnergy * maxFactor);
 
         /*  photon quanties (...right now, just unassociated clusters) */
         nPhotonsHisto = aida.histogram1D(plotDir +trkType+ triggerType + "/" + "Number of photons per event", 15, 0, 15);
-        enePhoton = aida.histogram1D(plotDir +trkType+ triggerType + "/" + "Photon Energy (GeV)", 50, 0, 2.4);
+        enePhoton = aida.histogram1D(plotDir +trkType+ triggerType + "/" + "Photon Energy (GeV)", 50, 0, 2.4*beamEnergy);
         xPhoton = aida.histogram1D(plotDir +trkType+ triggerType + "/" + "Photon X position (mm)", 50, -200, 200);
         yPhoton = aida.histogram1D(plotDir +trkType+ triggerType + "/" + "Photon Y position (mm)", 50, -100, 100);
 

Modified: java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/dataquality/PlotAndFitUtilities.java
 =============================================================================
--- java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/dataquality/PlotAndFitUtilities.java	(original)
+++ java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/dataquality/PlotAndFitUtilities.java	Wed Apr 27 11:11:32 2016
@@ -19,6 +19,7 @@
 
 import java.util.logging.Level;
 import java.util.logging.Logger;
+import org.lcsim.detector.tracker.silicon.HpsSiSensor;
 
 import org.lcsim.util.aida.AIDA;
 
@@ -29,7 +30,7 @@
 public class PlotAndFitUtilities {
 
     private static Logger LOGGER = Logger.getLogger(PlotAndFitUtilities.class.getPackage().getName());
-    
+
     static private AIDA aida = AIDA.defaultInstance();
 
     /*
@@ -37,13 +38,15 @@
      *  copied from org.hps.monitoring.drivers.ecal.EcalMonitoringUtilities.java
      */
     static IPlotter plot(IPlotterFactory plotterFactory, IBaseHistogram histogram, IPlotterStyle style, boolean show) {
-        if (style == null)
+        if (style == null) {
             style = getPlotterStyle(histogram);
+        }
         IPlotter plotter = plotterFactory.create(histogram.title());
         plotter.createRegion();
         plotter.region(0).plot(histogram, style);
-        if (show)
+        if (show) {
             plotter.show();
+        }
         return plotter;
     }
 
@@ -52,8 +55,9 @@
      *  copied from org.hps.monitoring.drivers.ecal.EcalMonitoringUtilities.java
      */
     static void plot(IPlotter plotter, IBaseHistogram histogram, IPlotterStyle style, int region) {
-        if (style == null)
+        if (style == null) {
             style = getPlotterStyle(histogram);
+        }
         LOGGER.info("Putting plot in region " + region);
         plotter.region(region).plot(histogram, style);
 
@@ -64,8 +68,9 @@
      */
 
     static void plot(IPlotter plotter, IFunction function, IPlotterStyle style, int region) {
-        if (style == null)
+        if (style == null) {
             style = getPlotterStyle(function);
+        }
         LOGGER.info("Putting function in region " + region);
         plotter.region(region).plot(function, style);
     }
@@ -78,16 +83,17 @@
         StyleRegistry styleRegistry = StyleRegistry.getStyleRegistry();
         IStyleStore store = styleRegistry.getStore("DefaultStyleStore");
         IPlotterStyle style = null;
-        if ((histogram instanceof IHistogram1D) || (histogram instanceof ICloud1D) || (histogram instanceof IProfile1D))
+        if ((histogram instanceof IHistogram1D) || (histogram instanceof ICloud1D) || (histogram instanceof IProfile1D)) {
             style = store.getStyle("DefaultHistogram1DStyle");
-        else if ((histogram instanceof IHistogram2D) || (histogram instanceof IProfile2D)) {
+        } else if ((histogram instanceof IHistogram2D) || (histogram instanceof IProfile2D)) {
             style = store.getStyle("DefaultColorMapStyle");
             style.statisticsBoxStyle().setVisible(false);
             style.setParameter("hist2DStyle", "colorMap");
             style.dataStyle().fillStyle().setParameter("colorMapScheme", "rainbow");
         }
-        if (style == null)
+        if (style == null) {
             throw new RuntimeException("A default style could not be found for " + histogram.title());
+        }
 
         //custom stuff...mg
         style.dataStyle().errorBarStyle().setVisible(false);
@@ -106,8 +112,9 @@
         IStyleStore store = styleRegistry.getStore("DefaultStyleStore");
         IPlotterStyle style = null;
         style = store.getStyle("DefaultFunctionStyle");
-        if (style == null)
+        if (style == null) {
             throw new RuntimeException("A default style could not be found for " + func.title());
+        }
         return style;
     }
 
@@ -122,10 +129,10 @@
         parameters[2] = histogram.rms();
         function.setParameters(parameters);
         IFitResult fitResult = null;
-         Logger minuitLogger = Logger.getLogger("org.freehep.math.minuit");
+        Logger minuitLogger = Logger.getLogger("org.freehep.math.minuit");
         minuitLogger.setLevel(Level.OFF);
         minuitLogger.info("minuit logger test");
-        
+
         try {
             fitResult = fitter.fit(histogram, function);
         } catch (RuntimeException e) {
@@ -142,4 +149,44 @@
         }
     }
 
+    private static final String nameStrip = "Tracker_TestRunModule_";
+
+    private static String getNiceSensorName(HpsSiSensor sensor) {
+        return sensor.getName().replaceAll(nameStrip, "")
+                .replace("module", "mod")
+                .replace("layer", "lyr")
+                .replace("sensor", "sens");
+    }
+
+    public static IHistogram1D getSensorPlot(String prefix, HpsSiSensor sensor) {
+        String hname = prefix + getNiceSensorName(sensor);
+        return aida.histogram1D(hname);
+    }
+
+//    private static IHistogram1D getSensorPlot(String prefix, String sensorName) {
+//        return aida.histogram1D(prefix + sensorName);
+//    }
+    public static IHistogram1D createSensorPlot(String prefix, HpsSiSensor sensor, int nchan, double min, double max) {
+        String hname = prefix + getNiceSensorName(sensor);
+        IHistogram1D hist = aida.histogram1D(hname, nchan, min, max);
+        hist.setTitle(getNiceSensorName(sensor));
+
+        return hist;
+    }
+
+    public static IHistogram2D getSensorPlot2D(String prefix, HpsSiSensor sensor) {
+        String hname = prefix + getNiceSensorName(sensor);
+        return aida.histogram2D(hname);
+    }
+
+    public static IHistogram2D createSensorPlot2D(String prefix, HpsSiSensor sensor, int nchanX, double minX, double maxX, int nchanY, double minY, double maxY) {
+        String hname = prefix + getNiceSensorName(sensor);
+        IHistogram2D hist = aida.histogram2D(hname, nchanX, minX, maxX, nchanY, minY, maxY);
+        hist.setTitle(sensor.getName().replaceAll(nameStrip, "")
+                .replace("module", "mod")
+                .replace("layer", "lyr")
+                .replace("sensor", "sens"));
+
+        return hist;
+    }
 }

Modified: java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/dataquality/SvtMonitoring.java
 =============================================================================
--- java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/dataquality/SvtMonitoring.java	(original)
+++ java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/dataquality/SvtMonitoring.java	Wed Apr 27 11:11:32 2016
@@ -38,7 +38,7 @@
  */
 //TODO:  add some more quantities to DQM database:  <t0> or <sigma>_t0 for intime events;  <chi^2>, <amplitude> etc
 public class SvtMonitoring extends DataQualityMonitor {
-    
+
     private static Logger LOGGER = Logger.getLogger(SvtMonitoring.class.getPackage().getName());
 
     private String rawTrackerHitCollectionName = "SVTRawTrackerHits";
@@ -90,22 +90,22 @@
         aida.tree().cd("/");
         for (HpsSiSensor sensor : sensors) {
             //IHistogram1D occupancyPlot = aida.histogram1D(sensor.getName().replaceAll("Tracker_TestRunModule_", ""), 640, 0, 639);
-            IHistogram1D occupancyPlot = createSensorPlot(plotDir + triggerType + "/"+"occupancy_", sensor, maxChannels, 0, maxChannels - 1);
-            IHistogram1D t0Plot = createSensorPlot(plotDir + triggerType + "/"+"t0Hit_", sensor, 400, -100., 100.);
-            IHistogram1D nHits = createSensorPlot(plotDir + triggerType + "/"+"nHitsPerEvent_", sensor, 100, -0.5, 99.5);
-            IHistogram1D pileup = createSensorPlot(plotDir + triggerType + "/"+"nFitsPerHit_", sensor, 3, 0.5, 3.5);
-
-            IHistogram1D amplitudePlot = createSensorPlot(plotDir + triggerType + "/"+"amplitude_", sensor, 50, 0, 4000.0);
-            IHistogram2D t0AmpPlot = createSensorPlot2D(plotDir + triggerType + "/"+"t0AmpHit_", sensor, 200, -100., 100., 50, 0, 4000.0);
-            IHistogram2D t0ChanPlot = createSensorPlot2D(plotDir + triggerType + "/"+"t0ChanBigHit_", sensor, 640, -0.5, 639.5, 200, -100., 100.);
-            IHistogram2D ampChanPlot = createSensorPlot2D(plotDir + triggerType + "/"+"ampChanHit_", sensor, 640, -0.5, 639.5, 50, 0, 4000);
-            IHistogram2D chiprobChanPlot = createSensorPlot2D(plotDir + triggerType + "/"+"chiprobChanBigHit_", sensor, 640, -0.5, 639.5, 50, 0, 1.0);
-            IHistogram2D t0TrigTimeHitPlot = createSensorPlot2D(plotDir + triggerType + "/"+"t0BigHitTrigTime_", sensor, 400, -100., 100., 6, 0, 24);
-
-            IHistogram1D chiProbPlot = createSensorPlot(plotDir + triggerType + "/"+"chiProb_", sensor, 50, 0, 1.0);
-            IHistogram1D t0ClusterPlot = createSensorPlot(plotDir + triggerType + "/"+"t0Cluster_", sensor, 400, -100., 100.);
-            IHistogram2D t0TrigTimePlot = createSensorPlot2D(plotDir + triggerType + "/"+"t0ClusterTrigTime_", sensor, 400, -100., 100., 6, 0, 24);
-            IHistogram1D dedxClusterPlot = createSensorPlot(plotDir + triggerType + "/"+"electrons_", sensor, 50, 0., 10.);
+            IHistogram1D occupancyPlot = PlotAndFitUtilities.createSensorPlot(plotDir + triggerType + "/" + "occupancy_", sensor, maxChannels, 0, maxChannels - 1);
+            IHistogram1D t0Plot = PlotAndFitUtilities.createSensorPlot(plotDir + triggerType + "/" + "t0Hit_", sensor, 400, -100., 100.);
+            IHistogram1D nHits = PlotAndFitUtilities.createSensorPlot(plotDir + triggerType + "/" + "nHitsPerEvent_", sensor, 100, -0.5, 99.5);
+            IHistogram1D pileup = PlotAndFitUtilities.createSensorPlot(plotDir + triggerType + "/" + "nFitsPerHit_", sensor, 3, 0.5, 3.5);
+
+            IHistogram1D amplitudePlot = PlotAndFitUtilities.createSensorPlot(plotDir + triggerType + "/" + "amplitude_", sensor, 50, 0, 4000.0);
+            IHistogram2D t0AmpPlot = PlotAndFitUtilities.createSensorPlot2D(plotDir + triggerType + "/" + "t0AmpHit_", sensor, 200, -100., 100., 50, 0, 4000.0);
+            IHistogram2D t0ChanPlot = PlotAndFitUtilities.createSensorPlot2D(plotDir + triggerType + "/" + "t0ChanBigHit_", sensor, 640, -0.5, 639.5, 200, -100., 100.);
+            IHistogram2D ampChanPlot = PlotAndFitUtilities.createSensorPlot2D(plotDir + triggerType + "/" + "ampChanHit_", sensor, 640, -0.5, 639.5, 50, 0, 4000);
+            IHistogram2D chiprobChanPlot = PlotAndFitUtilities.createSensorPlot2D(plotDir + triggerType + "/" + "chiprobChanBigHit_", sensor, 640, -0.5, 639.5, 50, 0, 1.0);
+            IHistogram2D t0TrigTimeHitPlot = PlotAndFitUtilities.createSensorPlot2D(plotDir + triggerType + "/" + "t0BigHitTrigTime_", sensor, 400, -100., 100., 6, 0, 24);
+
+            IHistogram1D chiProbPlot = PlotAndFitUtilities.createSensorPlot(plotDir + triggerType + "/" + "chiProb_", sensor, 50, 0, 1.0);
+            IHistogram1D t0ClusterPlot = PlotAndFitUtilities.createSensorPlot(plotDir + triggerType + "/" + "t0Cluster_", sensor, 400, -100., 100.);
+            IHistogram2D t0TrigTimePlot = PlotAndFitUtilities.createSensorPlot2D(plotDir + triggerType + "/" + "t0ClusterTrigTime_", sensor, 400, -100., 100., 6, 0, 24);
+            IHistogram1D dedxClusterPlot = PlotAndFitUtilities.createSensorPlot(plotDir + triggerType + "/" + "electrons_", sensor, 50, 0., 10.);
             occupancyPlot.reset();
         }
 
@@ -116,10 +116,11 @@
 
     public void process(EventHeader event) {
 
-          //check to see if this event is from the correct trigger (or "all");
-        if (!matchTrigger(event))
+        //check to see if this event is from the correct trigger (or "all");
+        if (!matchTrigger(event)) {
             return;
-        
+        }
+
         /*  increment the strip occupancy arrays */
         Map<String, Integer> hitsPerSensor = new HashMap<String, Integer>();
 
@@ -140,7 +141,7 @@
             ++eventCountRaw;
         }
         for (HpsSiSensor sensor : sensors) {
-            IHistogram1D sensorHist = getSensorPlot(plotDir + triggerType + "/"+"nHitsPerEvent_", sensor);
+            IHistogram1D sensorHist = PlotAndFitUtilities.getSensorPlot(plotDir + triggerType + "/" + "nHitsPerEvent_", sensor);
             Integer nHits = hitsPerSensor.get(sensor.getName());
             if (nHits == null) {
                 sensorHist.fill(0);
@@ -161,22 +162,22 @@
                 RawTrackerHit rth = (RawTrackerHit) hit.getFrom();
                 GenericObject pars = (GenericObject) hit.getTo();
 
-                String sensorName = getNiceSensorName((HpsSiSensor) rth.getDetectorElement());
+                HpsSiSensor sensor = ((HpsSiSensor) rth.getDetectorElement());
                 //this is a clever way to get the parameters we want from the generic object
                 double t0 = ShapeFitParameters.getT0(pars);
                 double amp = ShapeFitParameters.getAmp(pars);
                 double chiProb = ShapeFitParameters.getChiProb(pars);
                 int channel = rth.getIdentifierFieldValue("strip");
-                getSensorPlot(plotDir + triggerType + "/"+"nFitsPerHit_", sensorName).fill(rthtofit.allFrom(rth).size());
-                getSensorPlot(plotDir + triggerType + "/"+"t0Hit_", sensorName).fill(t0);
-                getSensorPlot(plotDir + triggerType + "/"+"amplitude_", sensorName).fill(amp);
-                getSensorPlot2D(plotDir + triggerType + "/"+"t0AmpHit_", sensorName).fill(t0, amp);
-                getSensorPlot(plotDir + triggerType + "/"+"chiProb_", sensorName).fill(chiProb);
-                getSensorPlot2D(plotDir + triggerType + "/"+"ampChanHit_", sensorName).fill(channel, amp);
+                PlotAndFitUtilities.getSensorPlot(plotDir + triggerType + "/" + "nFitsPerHit_", sensor).fill(rthtofit.allFrom(rth).size());
+                PlotAndFitUtilities.getSensorPlot(plotDir + triggerType + "/" + "t0Hit_", sensor).fill(t0);
+                PlotAndFitUtilities.getSensorPlot(plotDir + triggerType + "/" + "amplitude_", sensor).fill(amp);
+                PlotAndFitUtilities.getSensorPlot2D(plotDir + triggerType + "/" + "t0AmpHit_", sensor).fill(t0, amp);
+                PlotAndFitUtilities.getSensorPlot(plotDir + triggerType + "/" + "chiProb_", sensor).fill(chiProb);
+                PlotAndFitUtilities.getSensorPlot2D(plotDir + triggerType + "/" + "ampChanHit_", sensor).fill(channel, amp);
                 if (amp > 1000.0) {
-                    getSensorPlot2D(plotDir + triggerType + "/"+"t0ChanBigHit_", sensorName).fill(channel, t0);
-                    getSensorPlot2D(plotDir + triggerType + "/"+"chiprobChanBigHit_", sensorName).fill(channel, chiProb);
-                    getSensorPlot2D(plotDir + triggerType + "/"+"t0BigHitTrigTime_", sensorName).fill(t0, event.getTimeStamp() % 24);
+                    PlotAndFitUtilities.getSensorPlot2D(plotDir + triggerType + "/" + "t0ChanBigHit_", sensor).fill(channel, t0);
+                    PlotAndFitUtilities.getSensorPlot2D(plotDir + triggerType + "/" + "chiprobChanBigHit_", sensor).fill(channel, chiProb);
+                    PlotAndFitUtilities.getSensorPlot2D(plotDir + triggerType + "/" + "t0BigHitTrigTime_", sensor).fill(t0, event.getTimeStamp() % 24);
                 }
             }
             ++eventCountFit;
@@ -186,55 +187,15 @@
 //            LOGGER.info("Found a Si cluster collection");
             List<TrackerHit> siClusters = (List<TrackerHit>) event.get(trackerHitCollectionName);
             for (TrackerHit cluster : siClusters) {
-                String sensorName = getNiceSensorName((HpsSiSensor) ((RawTrackerHit) cluster.getRawHits().get(0)).getDetectorElement());
+                HpsSiSensor sensor = (HpsSiSensor) ((RawTrackerHit) cluster.getRawHits().get(0)).getDetectorElement();
                 double t0 = cluster.getTime();
                 double dedx = cluster.getdEdx() * 1e6;
 //                LOGGER.info("dedx = "+dedx);
-                getSensorPlot(plotDir + triggerType + "/"+"t0Cluster_", sensorName).fill(t0);
-                getSensorPlot2D(plotDir + triggerType + "/"+"t0ClusterTrigTime_", sensorName).fill(t0, event.getTimeStamp() % 24);
-                getSensorPlot(plotDir + triggerType + "/"+"electrons_", sensorName).fill(dedx);
-            }
-        }
-    }
-
-    private IHistogram1D getSensorPlot(String prefix, HpsSiSensor sensor) {
-        String hname = prefix + getNiceSensorName(sensor);
-        return aida.histogram1D(hname);
-    }
-
-    private IHistogram1D getSensorPlot(String prefix, String sensorName) {
-        return aida.histogram1D(prefix + sensorName);
-    }
-
-    private IHistogram1D createSensorPlot(String prefix, HpsSiSensor sensor, int nchan, double min, double max) {
-        String hname = prefix + getNiceSensorName(sensor);
-        IHistogram1D hist = aida.histogram1D(hname, nchan, min, max);
-        hist.setTitle(sensor.getName().replaceAll(nameStrip, "")
-                .replace("module", "mod")
-                .replace("layer", "lyr")
-                .replace("sensor", "sens"));
-
-        return hist;
-    }
-
-    private IHistogram2D getSensorPlot2D(String prefix, HpsSiSensor sensor) {
-        String hname = prefix + getNiceSensorName(sensor);
-        return aida.histogram2D(hname);
-    }
-
-    private IHistogram2D getSensorPlot2D(String prefix, String sensorName) {
-        return aida.histogram2D(prefix + sensorName);
-    }
-
-    private IHistogram2D createSensorPlot2D(String prefix, HpsSiSensor sensor, int nchanX, double minX, double maxX, int nchanY, double minY, double maxY) {
-        String hname = prefix + getNiceSensorName(sensor);
-        IHistogram2D hist = aida.histogram2D(hname, nchanX, minX, maxX, nchanY, minY, maxY);
-        hist.setTitle(sensor.getName().replaceAll(nameStrip, "")
-                .replace("module", "mod")
-                .replace("layer", "lyr")
-                .replace("sensor", "sens"));
-
-        return hist;
+                PlotAndFitUtilities.getSensorPlot(plotDir + triggerType + "/" + "t0Cluster_", sensor).fill(t0);
+                PlotAndFitUtilities.getSensorPlot2D(plotDir + triggerType + "/" + "t0ClusterTrigTime_", sensor).fill(t0, event.getTimeStamp() % 24);
+                PlotAndFitUtilities.getSensorPlot(plotDir + triggerType + "/" + "electrons_", sensor).fill(dedx);
+            }
+        }
     }
 
     private void resetOccupancyMap() {
@@ -279,7 +240,7 @@
         for (HpsSiSensor sensor : sensors) {
             Double avg = 0.0;
             //IHistogram1D sensorHist = aida.histogram1D(sensor.getName());
-            IHistogram1D sensorHist = getSensorPlot(plotDir + triggerType + "/"+"occupancy_", sensor);
+            IHistogram1D sensorHist = PlotAndFitUtilities.getSensorPlot(plotDir + triggerType + "/" + "occupancy_", sensor);
             sensorHist.reset();
             int[] strips = occupancyMap.get(sensor.getName());
             for (int i = 0; i < strips.length; i++) {
@@ -314,7 +275,7 @@
         int irTop = 0;
         int irBot = 0;
         for (HpsSiSensor sensor : sensors) {
-            IHistogram1D sensPlot = getSensorPlot(plotDir + triggerType + "/"+"t0Hit_", sensor);
+            IHistogram1D sensPlot = PlotAndFitUtilities.getSensorPlot(plotDir + triggerType + "/" + "t0Hit_", sensor);
             IFitResult result = fitGaussian(sensPlot, fitter, "range=\"(-8.0,8.0)\"");
 
             boolean isTop = sensor.isTopLayer();
@@ -362,9 +323,9 @@
     @Override
     public void printDQMData() {
         for (HpsSiSensor sensor : sensors) {
-            LOGGER.info(avgOccupancyNames.get(sensor.getName()) + "  " +triggerType+" " + avgOccupancyMap.get(sensor.getName()));
-            LOGGER.info(avgt0Names.get(sensor.getName()) + "  " +triggerType+" " + avgt0Map.get(sensor.getName()));
-            LOGGER.info(sigt0Names.get(sensor.getName()) + "  " +triggerType+" " + sigt0Map.get(sensor.getName()));
+            LOGGER.info(avgOccupancyNames.get(sensor.getName()) + "  " + triggerType + " " + avgOccupancyMap.get(sensor.getName()));
+            LOGGER.info(avgt0Names.get(sensor.getName()) + "  " + triggerType + " " + avgt0Map.get(sensor.getName()));
+            LOGGER.info(sigt0Names.get(sensor.getName()) + "  " + triggerType + " " + sigt0Map.get(sensor.getName()));
         }
     }
 

Modified: java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/dataquality/TrackingMonitoring.java
 =============================================================================
--- java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/dataquality/TrackingMonitoring.java	(original)
+++ java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/dataquality/TrackingMonitoring.java	Wed Apr 27 11:11:32 2016
@@ -8,16 +8,17 @@
 import hep.physics.vec.BasicHep3Matrix;
 import hep.physics.vec.Hep3Vector;
 import hep.physics.vec.VecOp;
-
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 import java.util.logging.Logger;
-
 import org.hps.recon.tracking.CoordinateTransformations;
 import org.hps.recon.tracking.TrackUtils;
+import org.hps.recon.tracking.gbl.GBLKinkData;
 import org.lcsim.detector.tracker.silicon.HpsSiSensor;
 import org.lcsim.event.EventHeader;
+import org.lcsim.event.GenericObject;
 import org.lcsim.event.LCRelation;
 import org.lcsim.event.RawTrackerHit;
 import org.lcsim.event.RelationalTable;
@@ -37,7 +38,7 @@
 public class TrackingMonitoring extends DataQualityMonitor {
 
     private static Logger LOGGER = Logger.getLogger(SvtMonitoring.class.getPackage().getName());
-    
+
     private String helicalTrackHitCollectionName = "HelicalTrackHits";
     private final String rotatedTrackHitCollectionName = "RotatedHelicalTrackHits";
     private final String helicalTrackHitRelationsCollectionName = "HelicalTrackHitRelations";
@@ -64,6 +65,7 @@
     private final String botDir = "Bottom/";
     private final String hthplotDir = "HelicalTrackHits/";
     private final String timeresidDir = "HitTimeResiduals/";
+    private final String kinkDir = "Kinks/";
     String[] trackingQuantNames = {"avg_N_tracks", "avg_N_hitsPerTrack", "avg_d0", "avg_z0", "avg_absslope", "avg_chi2"};
     int nmodules = 6;
     IHistogram1D[] hthTop = new IHistogram1D[nmodules];
@@ -163,7 +165,8 @@
     IHistogram2D chi2VsLambda;
     IHistogram2D chi2VsZ0;
 
-    IHistogram2D beamAngle2D;
+    IHistogram2D beamAngleXY;
+    IHistogram2D beamAngleThetaPhi;
 
     IHistogram1D L1Iso;
     IHistogram1D L12Iso;
@@ -286,7 +289,8 @@
         chi2VsLambda = aida.histogram2D(plotDir + trackCollectionName + "/" + triggerType + "/" + "chi2 vs lambda", 50, -lambdaCut, lambdaCut, 50, 0.0, 50.0);
         chi2VsZ0 = aida.histogram2D(plotDir + trackCollectionName + "/" + triggerType + "/" + "chi2 vs z0", 50, -z0Cut, z0Cut, 50, 0.0, 50.0);
 
-        beamAngle2D = aida.histogram2D(plotDir + trackCollectionName + "/" + triggerType + "/" + "angles around beam axis: theta vs phi", 100, -Math.PI, Math.PI, 100, 0, 0.25);
+        beamAngleXY = aida.histogram2D(plotDir + trackCollectionName + "/" + triggerType + "/" + "angles around beam axis: theta_y vs theta_x", 100, -0.1, 0.1, 100, -0.1, 0.1);
+        beamAngleThetaPhi = aida.histogram2D(plotDir + trackCollectionName + "/" + triggerType + "/" + "angles around beam axis: theta vs phi", 100, -Math.PI, Math.PI, 100, 0, 0.25);
 
         L1Iso = aida.histogram1D(plotDir + trackCollectionName + "/" + triggerType + "/" + "L1 isolation", 100, -5.0, 5.0);
         L12Iso = aida.histogram1D(plotDir + trackCollectionName + "/" + triggerType + "/" + "L1-2 isolation", 100, -5.0, 5.0);
@@ -300,9 +304,12 @@
         aida.tree().cd("/");
         for (HpsSiSensor sensor : sensors) {
             //IHistogram1D occupancyPlot = aida.histogram1D(sensor.getName().replaceAll("Tracker_TestRunModule_", ""), 640, 0, 639);
-            IHistogram1D hitTimeResidual = createSensorPlot(plotDir + trackCollectionName + "/" + triggerType + "/" + timeresidDir + "hitTimeResidual_", sensor, 100, -20, 20);
-        }
-
+            IHistogram1D hitTimeResidual = PlotAndFitUtilities.createSensorPlot(plotDir + trackCollectionName + "/" + triggerType + "/" + timeresidDir + "hitTimeResidual_", sensor, 100, -20, 20);
+            IHistogram1D lambdaKink = PlotAndFitUtilities.createSensorPlot(plotDir + trackCollectionName + "/" + triggerType + "/" + kinkDir + "lambdaKink_", sensor, 100, -5e-3, 5e-3);
+            IHistogram1D phiKink = PlotAndFitUtilities.createSensorPlot(plotDir + trackCollectionName + "/" + triggerType + "/" + kinkDir + "phiKink_", sensor, 100, -5e-3, 5e-3);
+            IHistogram2D lambdaKink2D = PlotAndFitUtilities.createSensorPlot2D(plotDir + trackCollectionName + "/" + triggerType + "/" + kinkDir + "lambdaKinkVsOmega_", sensor, 100, -omegaCut, omegaCut, 100, -5e-3, 5e-3);
+            IHistogram2D phiKink2D = PlotAndFitUtilities.createSensorPlot2D(plotDir + trackCollectionName + "/" + triggerType + "/" + kinkDir + "phiKinkVsOmega_", sensor, 100, -omegaCut, omegaCut, 100, -5e-3, 5e-3);
+        }
     }
 
     @Override
@@ -366,9 +373,8 @@
         int cntPos = 0;
         int cntTop = 0;
         int cntBot = 0;
-        double ecalFace = 1393.0;//mm
         for (Track trk : tracks) {
-            Hep3Vector trackPosAtEcalFace = TrackUtils.extrapolateTrack(trk, ecalFace);
+            Hep3Vector trackPosAtEcalFace = TrackUtils.getTrackPositionAtEcal(trk);
             double xAtECal = trackPosAtEcalFace.x();
             double yAtECal = trackPosAtEcalFace.y();
             if (yAtECal > 0) {
@@ -385,7 +391,7 @@
             double sinphi0 = Math.sin(trk.getTrackStates().get(0).getPhi());
             double omega = trk.getTrackStates().get(0).getOmega();
             double lambda = trk.getTrackStates().get(0).getTanLambda();
-            double z0 = trk.getTrackStates().get(0).getZ0();            
+            double z0 = trk.getTrackStates().get(0).getZ0();
             trkChi2.fill(trk.getChi2());
             nHits.fill(trk.getTrackerHits().size());
             trackNhitsVsChi2.fill(trk.getChi2(), trk.getTrackerHits().size());
@@ -418,7 +424,8 @@
             double beamPhi = Math.atan2(dirRotated.y(), dirRotated.x());
             double beamTheta = Math.acos(dirRotated.z());
 
-            beamAngle2D.fill(beamPhi, beamTheta);
+            beamAngleXY.fill(dirRotated.x(), dirRotated.y());
+            beamAngleThetaPhi.fill(beamPhi, beamTheta);
 
             Double[] isolations = TrackUtils.getIsolations(trk, hitToStrips, hitToRotated);
             double l1Iso = Double.MAX_VALUE;
@@ -447,8 +454,12 @@
             int nSeedStrips = 0;
             double meanTime = 0;
             double meanSeedTime = 0;
+
+            List<TrackerHit> stripHits = new ArrayList<TrackerHit>();
+
             for (TrackerHit hit : trk.getTrackerHits()) {
                 Collection<TrackerHit> htsList = hitToStrips.allFrom(hitToRotated.from(hit));
+                stripHits.addAll(htsList);
                 double hitTimes[] = new double[2];
                 for (TrackerHit hts : htsList) {
                     int stripLayer = ((HpsSiSensor) ((RawTrackerHit) hts.getRawHits().get(0)).getDetectorElement()).getLayerNumber();
@@ -479,18 +490,16 @@
 
             double rmsTime = 0;
             double rmsSeedTime = 0;
-            for (TrackerHit hit : trk.getTrackerHits()) {
-                Collection<TrackerHit> htsList = hitToStrips.allFrom(hitToRotated.from(hit));
-                for (TrackerHit hts : htsList) {
-                    rmsTime += Math.pow(hts.getTime() - meanTime, 2);
-                    HpsSiSensor sensor = (HpsSiSensor) ((RawTrackerHit) hts.getRawHits().get(0)).getDetectorElement();
-                    int layer = sensor.getLayerNumber();
-                    if (layer <= 6) {
-                        rmsSeedTime += Math.pow(hts.getTime() - meanSeedTime, 2);
-                    }
-                    String sensorName = getNiceSensorName(sensor);
-                    getSensorPlot(plotDir + trackCollectionName + "/" + triggerType + "/" + timeresidDir + "hitTimeResidual_", sensorName).fill((hts.getTime() - meanTime) * nStrips / (nStrips - 1)); //correct residual for bias
+
+            stripHits = TrackUtils.sortHits(stripHits);
+            for (TrackerHit hts : stripHits) {
+                rmsTime += Math.pow(hts.getTime() - meanTime, 2);
+                HpsSiSensor sensor = (HpsSiSensor) ((RawTrackerHit) hts.getRawHits().get(0)).getDetectorElement();
+                int layer = sensor.getLayerNumber();
+                if (layer <= 6) {
+                    rmsSeedTime += Math.pow(hts.getTime() - meanSeedTime, 2);
                 }
+                PlotAndFitUtilities.getSensorPlot(plotDir + trackCollectionName + "/" + triggerType + "/" + timeresidDir + "hitTimeResidual_", sensor).fill((hts.getTime() - meanTime) * nStrips / (nStrips - 1)); //correct residual for bias
             }
             rmsTime = Math.sqrt(rmsTime / nStrips);
             trackMeanTime.fill(meanTime);
@@ -501,6 +510,23 @@
 
             rmsSeedTime = Math.sqrt(rmsSeedTime / nSeedStrips);
             seedRMSTime.fill(rmsSeedTime);
+
+            GenericObject kinkData = GBLKinkData.getKinkData(event, trk);
+            if (kinkData != null) {
+                for (int i = 0; i < stripHits.size(); i++) {
+                    TrackerHit hts = stripHits.get(i);
+                    HpsSiSensor sensor = (HpsSiSensor) ((RawTrackerHit) hts.getRawHits().get(0)).getDetectorElement();
+//                    int layer = sensor.getLayerNumber();
+                    double lambdaKink = GBLKinkData.getLambdaKink(kinkData, i);
+                    double phiKink = GBLKinkData.getPhiKink(kinkData, i);
+//                    System.out.format("%d %d %f %f\n", i, layer, lambdaKink, phiKink);
+
+                    PlotAndFitUtilities.getSensorPlot(plotDir + trackCollectionName + "/" + triggerType + "/" + kinkDir + "lambdaKink_", sensor).fill(lambdaKink);
+                    PlotAndFitUtilities.getSensorPlot(plotDir + trackCollectionName + "/" + triggerType + "/" + kinkDir + "phiKink_", sensor).fill(phiKink);
+                    PlotAndFitUtilities.getSensorPlot2D(plotDir + trackCollectionName + "/" + triggerType + "/" + kinkDir + "lambdaKinkVsOmega_", sensor).fill(trk.getTrackStates().get(0).getOmega(), lambdaKink);
+                    PlotAndFitUtilities.getSensorPlot2D(plotDir + trackCollectionName + "/" + triggerType + "/" + kinkDir + "phiKinkVsOmega_", sensor).fill(trk.getTrackStates().get(0).getOmega(), phiKink);
+                }
+            }
 
             if (trk.getTrackStates().get(0).getOmega() < 0) {//positrons
                 trkChi2Pos.fill(trk.getChi2());
@@ -568,10 +594,10 @@
 
         for (HpsSiSensor sensor : sensors) {
             //IHistogram1D occupancyPlot = aida.histogram1D(sensor.getName().replaceAll("Tracker_TestRunModule_", ""), 640, 0, 639);
-            IHistogram1D hitTimeResidual = getSensorPlot(plotDir + trackCollectionName + "/" + triggerType + "/" + timeresidDir + "hitTimeResidual_", getNiceSensorName(sensor));
+            IHistogram1D hitTimeResidual = PlotAndFitUtilities.getSensorPlot(plotDir + trackCollectionName + "/" + triggerType + "/" + timeresidDir + "hitTimeResidual_", sensor);
             IFitResult result = fitGaussian(hitTimeResidual, fitter, "range=\"(-20.0,20.0)\"");
             if (result != null) {
-                LOGGER.info(String.format("%s\t%f\t%f\t%d\t%d", getNiceSensorName(sensor), result.fittedParameters()[1], result.fittedParameters()[2], sensor.getFebID(), sensor.getFebHybridID()));
+                System.out.format("%s\t%f\t%f\t%d\t%d\t%f\n", getNiceSensorName(sensor), result.fittedParameters()[1], result.fittedParameters()[2], sensor.getFebID(), sensor.getFebHybridID(), sensor.getT0Shift());
             }
         }
 
@@ -611,26 +637,6 @@
         }
     }
 
-    private IHistogram1D getSensorPlot(String prefix, HpsSiSensor sensor) {
-        String hname = prefix + getNiceSensorName(sensor);
-        return aida.histogram1D(hname);
-    }
-
-    private IHistogram1D getSensorPlot(String prefix, String sensorName) {
-        return aida.histogram1D(prefix + sensorName);
-    }
-
-    private IHistogram1D createSensorPlot(String prefix, HpsSiSensor sensor, int nchan, double min, double max) {
-        String hname = prefix + getNiceSensorName(sensor);
-        IHistogram1D hist = aida.histogram1D(hname, nchan, min, max);
-        hist.setTitle(sensor.getName().replaceAll(nameStrip, "")
-                .replace("module", "mod")
-                .replace("layer", "lyr")
-                .replace("sensor", "sens"));
-
-        return hist;
-    }
-
     private String getNiceSensorName(HpsSiSensor sensor) {
         return sensor.getName().replaceAll(nameStrip, "")
                 .replace("module", "mod")

Modified: java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/dataquality/TrackingResiduals.java
 =============================================================================
--- java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/dataquality/TrackingResiduals.java	(original)
+++ java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/dataquality/TrackingResiduals.java	Wed Apr 27 11:11:32 2016
@@ -28,8 +28,8 @@
 // TODO:  Add some quantities for DQM monitoring: 
 public class TrackingResiduals extends DataQualityMonitor {
 
-    private static Logger LOGGER = Logger.getLogger(TrackingResiduals.class.getPackage().getName());
-    
+    private static final Logger LOGGER = Logger.getLogger(TrackingResiduals.class.getPackage().getName());
+
     // Collection Names
     String trackTimeDataCollectionName = "TrackTimeData";
     String trackResidualsCollectionName = "TrackResiduals";
@@ -82,8 +82,9 @@
             yresidbot[i - 1] = aida.histogram1D(plotDir + triggerType + "/" + posresDir + "Module " + i + " Bot y Residual", 50, -getRange(i, false), getRange(i, false));
         }
 
-        for (int i = 1; i <= nmodules * 2; i++)
+        for (int i = 1; i <= nmodules * 2; i++) {
             tresid[i - 1] = aida.histogram1D(plotDir + triggerType + "/" + timeresDir + "HalfModule " + i + " t Residual", 50, -20, 20);
+        }
         for (int i = 1; i <= nsensors; i++) {
 //            IHistogram1D utopresid = aida.histogram1D(plotDir + triggerType + "/"+uresDir + "HalfModule " + i + " Top u Residual", 50, -getRange((i + 1) / 2, false), getRange((i + 1) / 2, false));
 //            IHistogram1D ubotresid = aida.histogram1D(plotDir + triggerType + "/"+uresDir + "HalfModule " + i + " Bot u Residual", 50, -getRange((i + 1) / 2, false), getRange((i + 1) / 2, false));
@@ -106,17 +107,19 @@
     @Override
     public void process(EventHeader event) {
         aida.tree().cd("/");
-        if (!event.hasCollection(GenericObject.class, trackResidualsCollectionName))
+        if (!event.hasCollection(GenericObject.class, trackResidualsCollectionName)) {
             return;
+        }
         //check to see if this event is from the correct trigger (or "all");
-        if (!matchTrigger(event))
+        if (!matchTrigger(event)) {
             return;
+        }
         nEvents++;
         List<GenericObject> trdList = event.get(GenericObject.class, trackResidualsCollectionName);
         for (GenericObject trd : trdList) {
             int nResid = trd.getNDouble();
             int isBot = trd.getIntVal(trd.getNInt() - 1);//last Int is the top/bottom flag
-            for (int i = 1; i <= nResid; i++)
+            for (int i = 1; i <= nResid; i++) {
                 if (isBot == 1) {
                     xresidbot[i - 1].fill(trd.getDoubleVal(i - 1));//x is the double value in the generic object
                     yresidbot[i - 1].fill(trd.getFloatVal(i - 1));//y is the float value in the generic object
@@ -124,19 +127,22 @@
                     xresidtop[i - 1].fill(trd.getDoubleVal(i - 1));//x is the double value in the generic object
                     yresidtop[i - 1].fill(trd.getFloatVal(i - 1));//y is the float value in the generic object                    
                 }
-        }
-
+            }
+        }
+        
         if (event.hasCollection(GenericObject.class, trackTimeDataCollectionName)) {
             List<GenericObject> ttdList = event.get(GenericObject.class, trackTimeDataCollectionName);
             for (GenericObject ttd : ttdList) {
                 int nResid = ttd.getNDouble();
-                for (int i = 1; i <= nResid; i++)
+                for (int i = 1; i <= nResid; i++) {
                     tresid[i - 1].fill(ttd.getDoubleVal(i - 1));//x is the double value in the generic object               
-            }
-        }
-
-        if (!event.hasCollection(GenericObject.class, gblStripClusterDataCollectionName))
+                }
+            }
+        }
+
+        if (!event.hasCollection(GenericObject.class, gblStripClusterDataCollectionName)) {
             return;
+        }
         List<GenericObject> gblSCDList = event.get(GenericObject.class, gblStripClusterDataCollectionName);
         for (GenericObject gblSCD : gblSCDList) {
             double umeas = gblSCD.getDoubleVal(GBLStripClusterData.GBLDOUBLE.UMEAS);//TODO:  implement generic methods into GBLStripClusterData so this isn't hard coded
@@ -146,23 +152,25 @@
             double tanlambda = gblSCD.getDoubleVal(GBLStripClusterData.GBLDOUBLE.TLAMBDA);//use the slope as a proxy for the top/bottom half of tracker
 
             int i = gblSCD.getIntVal(GBLStripClusterData.GBLINT.ID);//implement generic methods into GBLStripClusterData so this isn't hard coded
-            if (i == 666)
-                if (tanlambda > 0)
+            if (i == 666) {
+                if (tanlambda > 0) {
                     xtopresidBS.fill(resid);
-                else
+                } else {
                     xbotresidBS.fill(resid);
-            else if (i == 667)
-                if (tanlambda > 0)
+                }
+            } else if (i == 667) {
+                if (tanlambda > 0) {
                     ytopresidBS.fill(resid);
-                else
+                } else {
                     ybotresidBS.fill(resid);
-            else if (tanlambda > 0)
+                }
+            } else if (tanlambda > 0) {
                 utopresid[i - 1].fill(resid);//x is the double value in the generic object                 
-            //                aida.histogram2D(plotDir + triggerType + "/"+uresDir + "HalfModule " + i + " Top u Residual vs. u").fill(utrk,resid);//x is the double value in the generic object                 
+            } //                aida.histogram2D(plotDir + triggerType + "/"+uresDir + "HalfModule " + i + " Top u Residual vs. u").fill(utrk,resid);//x is the double value in the generic object                 
             //                aida.histogram2D(plotDir + triggerType + "/"+uresDir + "HalfModule " + i + " Top u Residual vs. v").fill(vtrk,resid);//x is the double value in the generic object                 
-            else
+            else {
                 ubotresid[i - 1].fill(resid);//x is the double value in the generic object                 
-            //                aida.histogram2D(plotDir + triggerType + "/"+uresDir + "HalfModule " + i + " Bot u Residual vs. u").fill(utrk,resid);//x is the double value in the generic object                 
+            }            //                aida.histogram2D(plotDir + triggerType + "/"+uresDir + "HalfModule " + i + " Bot u Residual vs. u").fill(utrk,resid);//x is the double value in the generic object                 
             //                aida.histogram2D(plotDir + triggerType + "/"+uresDir + "HalfModule " + i + " Bot u Residual vs. v").fill(vtrk,resid);//x is the double value in the generic object                 
         }
     }
@@ -287,20 +295,25 @@
     private String getQuantityName(int itype, int iquant, int top, int nlayer) {
         String typeString = "position_resid";
         String quantString = "mean_";
-        if (itype == 1)
+        if (itype == 1) {
             typeString = "time_resid";
-        if (iquant == 1)
+        }
+        if (iquant == 1) {
             quantString = "sigma_";
+        }
 
         String botString = "bot_";
-        if (top == 1)
+        if (top == 1) {
             botString = "top_";
-        if (top == 2)
+        }
+        if (top == 2) {
             botString = "";
+        }
 
         String layerString = "module" + nlayer;
-        if (itype == 1)
+        if (itype == 1) {
             layerString = "halfmodule" + nlayer;
+        }
 
         return typeString + quantString + botString + layerString;
     }
@@ -308,51 +321,71 @@
     @Override
     public void printDQMData() {
         LOGGER.info("TrackingResiduals::printDQMData");
-        for (Map.Entry<String, Double> entry : xposTopMeanResidMap.entrySet())
-            LOGGER.info(entry.getKey() + " = " + entry.getValue());
-        for (Map.Entry<String, Double> entry : xposBotMeanResidMap.entrySet())
-            LOGGER.info(entry.getKey() + " = " + entry.getValue());
-        for (Map.Entry<String, Double> entry : xposTopSigmaResidMap.entrySet())
-            LOGGER.info(entry.getKey() + " = " + entry.getValue());
-        for (Map.Entry<String, Double> entry : xposBotSigmaResidMap.entrySet())
-            LOGGER.info(entry.getKey() + " = " + entry.getValue());
-        for (Map.Entry<String, Double> entry : yposTopMeanResidMap.entrySet())
-            LOGGER.info(entry.getKey() + " = " + entry.getValue());
-        for (Map.Entry<String, Double> entry : yposBotMeanResidMap.entrySet())
-            LOGGER.info(entry.getKey() + " = " + entry.getValue());
-        for (Map.Entry<String, Double> entry : yposTopSigmaResidMap.entrySet())
-            LOGGER.info(entry.getKey() + " = " + entry.getValue());
-        for (Map.Entry<String, Double> entry : yposBotSigmaResidMap.entrySet())
-            LOGGER.info(entry.getKey() + " = " + entry.getValue());
-        for (Map.Entry<String, Double> entry : timeMeanResidMap.entrySet())
-            LOGGER.info(entry.getKey() + " = " + entry.getValue());
-        for (Map.Entry<String, Double> entry : timeSigmaResidMap.entrySet())
-            LOGGER.info(entry.getKey() + " = " + entry.getValue());
+        for (Map.Entry<String, Double> entry : xposTopMeanResidMap.entrySet()) {
+            LOGGER.info(entry.getKey() + " = " + entry.getValue());
+        }
+        for (Map.Entry<String, Double> entry : xposBotMeanResidMap.entrySet()) {
+            LOGGER.info(entry.getKey() + " = " + entry.getValue());
+        }
+        for (Map.Entry<String, Double> entry : xposTopSigmaResidMap.entrySet()) {
+            LOGGER.info(entry.getKey() + " = " + entry.getValue());
+        }
+        for (Map.Entry<String, Double> entry : xposBotSigmaResidMap.entrySet()) {
+            LOGGER.info(entry.getKey() + " = " + entry.getValue());
+        }
+        for (Map.Entry<String, Double> entry : yposTopMeanResidMap.entrySet()) {
+            LOGGER.info(entry.getKey() + " = " + entry.getValue());
+        }
+        for (Map.Entry<String, Double> entry : yposBotMeanResidMap.entrySet()) {
+            LOGGER.info(entry.getKey() + " = " + entry.getValue());
+        }
+        for (Map.Entry<String, Double> entry : yposTopSigmaResidMap.entrySet()) {
+            LOGGER.info(entry.getKey() + " = " + entry.getValue());
+        }
+        for (Map.Entry<String, Double> entry : yposBotSigmaResidMap.entrySet()) {
+            LOGGER.info(entry.getKey() + " = " + entry.getValue());
+        }
+        for (Map.Entry<String, Double> entry : timeMeanResidMap.entrySet()) {
+            LOGGER.info(entry.getKey() + " = " + entry.getValue());
+        }
+        for (Map.Entry<String, Double> entry : timeSigmaResidMap.entrySet()) {
+            LOGGER.info(entry.getKey() + " = " + entry.getValue());
+        }
         LOGGER.info("*******************************");
     }
 
     @Override
     public void printDQMStrings() {
-        for (Map.Entry<String, Double> entry : xposTopMeanResidMap.entrySet())
-            LOGGER.info("ALTER TABLE dqm ADD " + entry.getKey() + " double;");
-        for (Map.Entry<String, Double> entry : xposBotMeanResidMap.entrySet())
-            LOGGER.info("ALTER TABLE dqm ADD " + entry.getKey() + " double;");
-        for (Map.Entry<String, Double> entry : xposTopSigmaResidMap.entrySet())
-            LOGGER.info("ALTER TABLE dqm ADD " + entry.getKey() + " double;");
-        for (Map.Entry<String, Double> entry : xposBotSigmaResidMap.entrySet())
-            LOGGER.info("ALTER TABLE dqm ADD " + entry.getKey() + " double;");
-        for (Map.Entry<String, Double> entry : yposTopMeanResidMap.entrySet())
-            LOGGER.info("ALTER TABLE dqm ADD " + entry.getKey() + " double;");
-        for (Map.Entry<String, Double> entry : yposBotMeanResidMap.entrySet())
-            LOGGER.info("ALTER TABLE dqm ADD " + entry.getKey() + " double;");
-        for (Map.Entry<String, Double> entry : yposTopSigmaResidMap.entrySet())
-            LOGGER.info("ALTER TABLE dqm ADD " + entry.getKey() + " double;");
-        for (Map.Entry<String, Double> entry : yposBotSigmaResidMap.entrySet())
-            LOGGER.info("ALTER TABLE dqm ADD " + entry.getKey() + " double;");
-        for (Map.Entry<String, Double> entry : timeMeanResidMap.entrySet())
-            LOGGER.info("ALTER TABLE dqm ADD " + entry.getKey() + " double;");
-        for (Map.Entry<String, Double> entry : timeSigmaResidMap.entrySet())
-            LOGGER.info("ALTER TABLE dqm ADD " + entry.getKey() + " double;");
+        for (Map.Entry<String, Double> entry : xposTopMeanResidMap.entrySet()) {
+            LOGGER.info("ALTER TABLE dqm ADD " + entry.getKey() + " double;");
+        }
+        for (Map.Entry<String, Double> entry : xposBotMeanResidMap.entrySet()) {
+            LOGGER.info("ALTER TABLE dqm ADD " + entry.getKey() + " double;");
+        }
+        for (Map.Entry<String, Double> entry : xposTopSigmaResidMap.entrySet()) {
+            LOGGER.info("ALTER TABLE dqm ADD " + entry.getKey() + " double;");
+        }
+        for (Map.Entry<String, Double> entry : xposBotSigmaResidMap.entrySet()) {
+            LOGGER.info("ALTER TABLE dqm ADD " + entry.getKey() + " double;");
+        }
+        for (Map.Entry<String, Double> entry : yposTopMeanResidMap.entrySet()) {
+            LOGGER.info("ALTER TABLE dqm ADD " + entry.getKey() + " double;");
+        }
+        for (Map.Entry<String, Double> entry : yposBotMeanResidMap.entrySet()) {
+            LOGGER.info("ALTER TABLE dqm ADD " + entry.getKey() + " double;");
+        }
+        for (Map.Entry<String, Double> entry : yposTopSigmaResidMap.entrySet()) {
+            LOGGER.info("ALTER TABLE dqm ADD " + entry.getKey() + " double;");
+        }
+        for (Map.Entry<String, Double> entry : yposBotSigmaResidMap.entrySet()) {
+            LOGGER.info("ALTER TABLE dqm ADD " + entry.getKey() + " double;");
+        }
+        for (Map.Entry<String, Double> entry : timeMeanResidMap.entrySet()) {
+            LOGGER.info("ALTER TABLE dqm ADD " + entry.getKey() + " double;");
+        }
+        for (Map.Entry<String, Double> entry : timeSigmaResidMap.entrySet()) {
+            LOGGER.info("ALTER TABLE dqm ADD " + entry.getKey() + " double;");
+        }
     }
 
     private void resetOccupancyMap() {
@@ -399,31 +432,35 @@
     private double getRange(int layer, boolean isX) {
         double range = 2.5;
         if (isX) {
-            if (layer == 1)
-                return 0.2;
-            if (layer == 2)
-                return 0.5;
-            if (layer == 3)
-                return 0.5;
-            if (layer == 4)
-                return 1.0;
-            if (layer == 5)
-                return 1.0;
-            if (layer == 6)
-                return 1.0;
+            switch (layer) {
+                case 1:
+                    return 0.2;
+                case 2:
+                    return 0.5;
+                case 3:
+                    return 0.5;
+                case 4:
+                    return 1.0;
+                case 5:
+                    return 1.0;
+                case 6:
+                    return 1.0;
+            }
         } else {
-            if (layer == 1)
-                return 0.005;
-            if (layer == 2)
-                return 0.5;
-            if (layer == 3)
-                return 0.5;
-            if (layer == 4)
-                return 1.0;
-            if (layer == 5)
-                return 1.0;
-            if (layer == 6)
-                return 1.5;
+            switch (layer) {
+                case 1:
+                    return 0.005;
+                case 2:
+                    return 0.5;
+                case 3:
+                    return 0.5;
+                case 4:
+                    return 1.0;
+                case 5:
+                    return 1.0;
+                case 6:
+                    return 1.5;
+            }
         }
         return range;
 

Modified: java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/dataquality/TridentMonitoring.java
 =============================================================================
--- java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/dataquality/TridentMonitoring.java	(original)
+++ java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/dataquality/TridentMonitoring.java	Wed Apr 27 11:11:32 2016
@@ -9,17 +9,21 @@
 import hep.physics.vec.BasicHep3Matrix;
 import hep.physics.vec.Hep3Vector;
 import hep.physics.vec.VecOp;
-
 import java.util.ArrayList;
 import java.util.EnumSet;
 import java.util.List;
 import java.util.Map.Entry;
 import java.util.logging.Logger;
-
+import org.hps.conditions.beam.BeamEnergy.BeamEnergyCollection;
 import org.hps.recon.ecal.cluster.ClusterUtilities;
+import org.hps.recon.particle.HpsReconParticleDriver;
 import org.hps.recon.particle.ReconParticleDriver;
 import org.hps.recon.tracking.TrackType;
 import org.hps.recon.tracking.TrackUtils;
+import org.hps.recon.vertexing.BilliorTrack;
+import org.hps.recon.vertexing.BilliorVertex;
+import org.hps.recon.vertexing.BilliorVertexer;
+import org.lcsim.event.Cluster;
 import org.lcsim.event.EventHeader;
 import org.lcsim.event.ReconstructedParticle;
 import org.lcsim.event.RelationalTable;
@@ -72,7 +76,6 @@
 
     private final static Logger LOGGER = Logger.getLogger(TridentMonitoring.class.getPackage().getName());
 
-    private double ebeam = 1.05;
     private final BasicHep3Matrix beamAxisRotation = new BasicHep3Matrix();
 //    private static final int nCuts = 9;
 //    private final String[] cutNames = {"Trk Quality",
@@ -97,8 +100,8 @@
 
     private final String plotDir = "TridentMonitoring/";
 
-    private IHistogram2D triTrackTime2D;
-    private IHistogram1D triTrackTimeDiff;
+//    private IHistogram2D triTrackTime2D;
+//    private IHistogram1D triTrackTimeDiff;
     private IHistogram2D triMassMomentum;
     private IHistogram2D triZVsMomentum;
     private IHistogram2D triTrackMomentum2D;
@@ -108,22 +111,22 @@
     private IHistogram1D triSumP;
     private IHistogram1D triMass;
     private IHistogram2D triZVsMass;
-    private IHistogram1D triX;
-    private IHistogram1D triY;
-    private IHistogram1D triZ;
-    private IHistogram2D triZY;
-    private IHistogram2D triXY;
-    private IHistogram1D triPx;
-    private IHistogram1D triPy;
-    private IHistogram1D triPz;
-    private IHistogram2D triPxPy;
-    private IHistogram1D triU;
-    private IHistogram1D triV;
+//    private IHistogram1D triX;
+//    private IHistogram1D triY;
+//    private IHistogram1D triZ;
+//    private IHistogram2D triZY;
+//    private IHistogram2D triXY;
+//    private IHistogram1D triPx;
+//    private IHistogram1D triPy;
+//    private IHistogram1D triPz;
+//    private IHistogram2D triPxPy;
+//    private IHistogram1D triU;
+//    private IHistogram1D triV;
 
     private IHistogram2D triRadTrackTime2D;
     private IHistogram1D triRadTrackTimeDiff;
-    private IHistogram2D triRadMassMomentum;
-    private IHistogram2D triRadZVsMomentum;
+//    private IHistogram2D triRadMassMomentum;
+//    private IHistogram2D triRadZVsMomentum;
     private IHistogram2D triRadTrackMomentum2D;
     private IHistogram2D triRadPyEleVsPyPos;
     private IHistogram2D triRadPxEleVsPxPos;
@@ -131,11 +134,11 @@
     private IHistogram1D triRadSumP;
     private IHistogram1D triRadMass;
     private IHistogram2D triRadZVsMass;
-    private IHistogram1D triRadX;
-    private IHistogram1D triRadY;
-    private IHistogram1D triRadZ;
-    private IHistogram2D triRadZY;
-    private IHistogram2D triRadXY;
+//    private IHistogram1D triRadX;
+//    private IHistogram1D triRadY;
+//    private IHistogram1D triRadZ;
+//    private IHistogram2D triRadZY;
+//    private IHistogram2D triRadXY;
     private IHistogram1D triRadPx;
     private IHistogram1D triRadPy;
     private IHistogram1D triRadPz;
@@ -143,8 +146,8 @@
     private IHistogram1D triRadU;
     private IHistogram1D triRadV;
 
-    private IHistogram2D vertTrackTime2D;
-    private IHistogram1D vertTrackTimeDiff;
+//    private IHistogram2D vertTrackTime2D;
+//    private IHistogram1D vertTrackTimeDiff;
     private IHistogram2D vertMassMomentum;
     private IHistogram2D vertZVsMomentum;
     private IHistogram2D vertTrackMomentum2D;
@@ -154,17 +157,17 @@
     private IHistogram1D vertSumP;
     private IHistogram1D vertMass;
     private IHistogram2D vertZVsMass;
-    private IHistogram1D vertX;
+//    private IHistogram1D vertX;
     private IHistogram1D vertY;
-    private IHistogram1D vertZ;
+//    private IHistogram1D vertZ;
     private IHistogram2D vertZY;
     private IHistogram2D vertXY;
-    private IHistogram1D vertPx;
-    private IHistogram1D vertPy;
-    private IHistogram1D vertPz;
-    private IHistogram2D vertPxPy;
-    private IHistogram1D vertU;
-    private IHistogram1D vertV;
+//    private IHistogram1D vertPx;
+//    private IHistogram1D vertPy;
+//    private IHistogram1D vertPz;
+//    private IHistogram2D vertPxPy;
+//    private IHistogram1D vertU;
+//    private IHistogram1D vertV;
 
     private IHistogram2D vertRadTrackTime2D;
     private IHistogram1D vertRadTrackTimeDiff;
@@ -189,6 +192,8 @@
     private IHistogram1D vertRadU;
     private IHistogram1D vertRadV;
 
+    private IHistogram2D vertRadUnconBsconChi2;
+
     private IHistogram1D nTriCand;
     private IHistogram1D nVtxCand;
 //    IHistogram1D vertexW;
@@ -197,7 +202,11 @@
     private IHistogram1D maxTrkChi2;
     private IHistogram2D zVsMaxTrkChi2;
     private IHistogram1D v0Chi2;
+    private IHistogram1D bsconV0Chi2;
     private IHistogram2D zVsV0Chi2;
+    private IHistogram2D zVsBsconV0Chi2;
+    private IHistogram1D v0Chi2Diff;
+    private IHistogram2D zVsV0Chi2Diff;
     private IHistogram1D trackTimeDiff;
     private IHistogram2D zVsTrackTimeDiff;
     private IHistogram1D hitTimeStdDev;
@@ -213,55 +222,149 @@
     private final IHistogram1D[][] cutVertexZ = new IHistogram1D[Cut.nCuts][2];
     private final IHistogram2D[][] cutVertexZVsMass = new IHistogram2D[Cut.nCuts][2];
 
-    private final double plotsMinMass = 0.03 * ebeam;
-    private final double plotsMaxMass = 0.04 * ebeam;
+    private final double plotsMinMass = 0.03;
+    private final double plotsMaxMass = 0.04;
 
     //clean up event first
     private final int nTrkMax = 5;
     private final int nPosMax = 1;
 
     private final double maxChi2SeedTrack = 7.0;
-    private final double maxChi2GBLTrack = 15.0;
-    private final double maxVertChi2 = 7.0;
-
-    //v0 cuts   
-    private final double v0PzMax = 1.25 * ebeam;//GeV 
+    private double maxChi2GBLTrack = 15.0;
+    private double maxUnconVertChi2 = 7.0;
+    private double maxBsconVertChi2 = 1000.0; //disable by default
+
+    //v0 plot ranges
+    private final double v0PzMax = 1.25;//GeV 
     private final double v0PzMin = 0.1;// GeV
     private final double v0PyMax = 0.04;//GeV absolute value
     private final double v0PxMax = 0.04;//GeV absolute value
     private final double v0VzMax = 50.0;// mm from target...someday make mass dependent
-    private final double v0VyMax = 1.0;// mm from target...someday make mass dependent
+    private final double v0VyMax = 2.0;// mm from target...someday make mass dependent
     private final double v0VxMax = 2.0;// mm from target...someday make mass dependent
-    //  track quality cuts
+
+    //v0 cuts
+    private final double v0PzMaxCut = 1.25;//GeV 
+    private final double v0PzMinCut = 0.1;// GeV
+    private final double v0PyCut = 0.04;//GeV absolute value
+    private final double v0PxCut = 0.04;//GeV absolute value
+    private final double v0UnconVzCut = 50.0;// mm from target...someday make mass dependent
+    private double v0UnconVyCut = 2.0;// mm from target...someday make mass dependent
+    private double v0UnconVxCut = 2.0;// mm from target...someday make mass dependent
+    private double v0BsconVyCut = 10.0; //disable by default
+    private double v0BsconVxCut = 10.0; //disable by default
+
+//  track quality cuts
     private final double beamPCut = 0.85;
     private final double minPCut = 0.05;
 //    private double trkPyMax = 0.2;
 //    private double trkPxMax = 0.2;
-    private final double radCut = 0.8 * ebeam;
+    private final double radCut = 0.8;
     private final double trkTimeDiff = 5.0;
     private final double clusterTimeDiffCut = 2.5;
 
-    private final double l1IsoMin = 1.0;
+    private double l1IsoMin = 0.5;
+
+    private final double tupleTrkPCut = 0.9;
+    private final double tupleMaxSumCut = 1.3;
+
+    private final double[] beamSize = {0.001, 0.130, 0.050}; //rough estimate from harp scans during engineering run production running
+    private final double[] beamPos = {0.0, 0.0, 0.0};
+    private final double[] vzcBeamSize = {0.001, 100, 100};
+
 //cluster matching
 //    private boolean reqCluster = false;
 //    private int nClustMax = 3;
 //    private double eneLossFactor = 0.7; //average E/p roughly
 //    private double eneOverPCut = 0.3; //|(E/p)_meas - (E/p)_mean|<eneOverPCut
-
 //counters
     private float nEvents = 0;
     private float nRecoV0 = 0;
     private final float[] nPassCut = new float[Cut.nCuts];
 
-    public void setEbeam(double ebeam) {
-        this.ebeam = ebeam;
-    }
+    public TridentMonitoring() {
+        this.tupleVariables = new String[]{"run/I", "event/I",
+            "nTrk/I", "nPos/I",
+            "uncPX/D", "uncPY/D", "uncPZ/D", "uncP/D",
+            "uncVX/D", "uncVY/D", "uncVZ/D", "uncChisq/D", "uncM/D",
+            "bscPX/D", "bscPY/D", "bscPZ/D", "bscP/D",
+            "bscVX/D", "bscVY/D", "bscVZ/D", "bscChisq/D", "bscM/D",
+            "tarPX/D", "tarPY/D", "tarPZ/D", "tarP/D",
+            "tarVX/D", "tarVY/D", "tarVZ/D", "tarChisq/D", "tarM/D",
+            "vzcPX/D", "vzcPY/D", "vzcPZ/D", "vzcP/D",
+            "vzcVX/D", "vzcVY/D", "vzcVZ/D", "vzcChisq/D", "vzcM/D",
+            "elePX/D", "elePY/D", "elePZ/D", "eleP/D",
+            "eleTrkChisq/D", "eleTrkHits/I", "eleTrkType/I", "eleTrkT/D",
+            "eleTrkD0/D", "eleTrkZ0/D", "eleTrkEcalX/D", "eleTrkEcalY/D",
+            "eleHasL1/B", "eleHasL2/B",
+            "eleMatchChisq/D", "eleClT/D", "eleClE/D", "eleClHits/I",
+            "posPX/D", "posPY/D", "posPZ/D", "posP/D",
+            "posTrkChisq/D", "posTrkHits/I", "posTrkType/I", "posTrkT/D",
+            "posTrkD0/D", "posTrkZ0/D", "posTrkEcalX/D", "posTrkEcalY/D",
+            "posHasL1/B", "posHasL2/B",
+            "posMatchChisq/D", "posClT/D", "posClE/D", "posClHits/I",
+            "minL1Iso/D"
+        };
+    }
+
+    public void setMaxChi2GBLTrack(double maxChi2GBLTrack) {
+        this.maxChi2GBLTrack = maxChi2GBLTrack;
+    }
+
+    public void setMaxUnconVertChi2(double maxUnconVertChi2) {
+        this.maxUnconVertChi2 = maxUnconVertChi2;
+    }
+
+    public void setMaxBsconVertChi2(double maxBsconVertChi2) {
+        this.maxBsconVertChi2 = maxBsconVertChi2;
+    }
+
+    public void setV0UnconVyCut(double v0UnconVyCut) {
+        this.v0UnconVyCut = v0UnconVyCut;
+    }
+
+    public void setV0UnconVxCut(double v0UnconVxCut) {
+        this.v0UnconVxCut = v0UnconVxCut;
+    }
+
+    public void setV0BsconVyCut(double v0BsconVyCut) {
+        this.v0BsconVyCut = v0BsconVyCut;
+    }
+
+    public void setV0BsconVxCut(double v0BsconVxCut) {
+        this.v0BsconVxCut = v0BsconVxCut;
+    }
+
+    public void setL1IsoMin(double l1IsoMin) {
+        this.l1IsoMin = l1IsoMin;
+    }
+
+    public void setBeamSizeX(double beamSizeX) {
+        this.beamSize[1] = beamSizeX;
+    }
+
+    public void setBeamSizeY(double beamSizeY) {
+        this.beamSize[2] = beamSizeY;
+    }
+
+    public void setBeamPosX(double beamPosX) {
+        this.beamPos[1] = beamPosX;
+    }
+
+    public void setBeamPosY(double beamPosY) {
+        this.beamPos[2] = beamPosY;
+    }
+
+    double ebeam;
 
     @Override
     protected void detectorChanged(Detector detector) {
         LOGGER.info("TridendMonitoring::detectorChanged  Setting up the plotter");
         beamAxisRotation.setActiveEuler(Math.PI / 2, -0.0305, -Math.PI / 2);
 
+        BeamEnergyCollection beamEnergyCollection
+                = this.getConditionsManager().getCachedConditions(BeamEnergyCollection.class, "beam_energies").getCachedData();
+        ebeam = beamEnergyCollection.get(0).getBeamEnergy();
         aida.tree().cd("/");
         String trkType = "SeedTrack/";
         if (isGBL) {
@@ -284,106 +387,106 @@
 //        IHistogram1D tarconChi2 = aida.histogram1D(plotDir +  triggerType + "/"+ triggerType + "/"+"Target Constrained Chi2", 25, 0, 25);
         nTriCand = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Number of Trident Candidates", 5, 0, 4);
 
-        triTrackTimeDiff = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Trident: Track time difference", 100, -10, 10);
-        triTrackTime2D = aida.histogram2D(plotDir + trkType + triggerType + "/" + "Trident: Track time vs. track time", 100, -10, 10, 100, -10, 10);
-
-        triTrackMomentum2D = aida.histogram2D(plotDir + trkType + triggerType + "/" + "Trident: Positron vs. electron momentum", 100, 0, v0PzMax, 100, 0, v0PzMax);
-        triDeltaP = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Trident: Positron - electron momentum", 100, -1., 1.0);
-        triSumP = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Trident: Positron + electron momentum", 100, v0PzMin, v0PzMax);
-        triPyEleVsPyPos = aida.histogram2D(plotDir + trkType + triggerType + "/" + "Trident: Py(e) vs Py(p)", 50, -0.04, 0.04, 50, -0.04, 0.04);
-        triPxEleVsPxPos = aida.histogram2D(plotDir + trkType + triggerType + "/" + "Trident: Px(e) vs Px(p)", 50, -0.04, 0.04, 50, -0.04, 0.04);
-
-        triMassMomentum = aida.histogram2D(plotDir + trkType + triggerType + "/" + "Trident: Vertex mass vs. vertex momentum", 100, v0PzMin, v0PzMax, 100, 0, 0.1);
-        triZVsMomentum = aida.histogram2D(plotDir + trkType + triggerType + "/" + "Trident: Vertex Z vs. vertex momentum", 100, v0PzMin, v0PzMax, 100, -v0VzMax, v0VzMax);
-        triMass = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Trident: Vertex mass", 100, 0, 0.11);
-        triZVsMass = aida.histogram2D(plotDir + trkType + triggerType + "/" + "Trident: Vertex Z vs. mass", 100, 0, 0.11, 100, -v0VzMax, v0VzMax);
-        triX = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Trident: Vertex X", 100, -v0VxMax, v0VxMax);
-        triY = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Trident: Vertex Y", 100, -v0VyMax, v0VyMax);
-        triZ = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Trident: Vertex Z", 100, -v0VzMax, v0VzMax);
-        triXY = aida.histogram2D(plotDir + trkType + triggerType + "/" + "Trident: Vertex Y vs. X", 100, -v0VxMax, v0VxMax, 100, -v0VyMax, v0VyMax);
-        triZY = aida.histogram2D(plotDir + trkType + triggerType + "/" + "Trident: Vertex Z vs. Y", 100, -v0VyMax, v0VyMax, 100, -v0VzMax, v0VzMax);
-        triPx = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Trident: Vertex Px", 100, -v0PxMax, v0PxMax);
-        triPy = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Trident: Vertex Py", 100, -v0PyMax, v0PyMax);
-        triPz = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Trident: Vertex Pz", 100, v0PzMin, v0PzMax);
-        triPxPy = aida.histogram2D(plotDir + trkType + triggerType + "/" + "Trident: Vertex Py vs. Px", 100, -v0PxMax, v0PxMax, 100, -v0PyMax, v0PyMax);
-        triU = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Trident: Vertex Px over Ptot", 100, -0.1, 0.1);
-        triV = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Trident: Vertex Py over Ptot", 100, -0.1, 0.1);
+//        triTrackTimeDiff = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Trident: Track time difference", 100, -10, 10);
+//        triTrackTime2D = aida.histogram2D(plotDir + trkType + triggerType + "/" + "Trident: Track time vs. track time", 100, -10, 10, 100, -10, 10);
+        triTrackMomentum2D = aida.histogram2D(plotDir + trkType + triggerType + "/" + "Trident: Positron vs. electron momentum", 100, 0, v0PzMax * ebeam, 100, 0, v0PzMax * ebeam);
+        triDeltaP = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Trident: Positron - electron momentum", 100, -ebeam, ebeam);
+        triSumP = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Trident: Positron + electron momentum", 100, v0PzMin * ebeam, v0PzMax * ebeam);
+        triPyEleVsPyPos = aida.histogram2D(plotDir + trkType + triggerType + "/" + "Trident: Py(e) vs Py(p)", 50, -v0PyMax * ebeam, v0PyMax * ebeam, 50, -v0PyMax * ebeam, v0PyMax * ebeam);
+        triPxEleVsPxPos = aida.histogram2D(plotDir + trkType + triggerType + "/" + "Trident: Px(e) vs Px(p)", 50, -v0PxMax * ebeam, v0PxMax * ebeam, 50, -v0PxMax * ebeam, v0PxMax * ebeam);
+
+        triMassMomentum = aida.histogram2D(plotDir + trkType + triggerType + "/" + "Trident: Vertex mass vs. vertex momentum", 100, v0PzMin * ebeam, v0PzMax * ebeam, 100, 0, 0.1 * ebeam);
+        triZVsMomentum = aida.histogram2D(plotDir + trkType + triggerType + "/" + "Trident: Vertex Z vs. vertex momentum", 100, v0PzMin * ebeam, v0PzMax * ebeam, 100, -v0VzMax, v0VzMax);
+        triMass = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Trident: Vertex mass", 100, 0, 0.1 * ebeam);
+        triZVsMass = aida.histogram2D(plotDir + trkType + triggerType + "/" + "Trident: Vertex Z vs. mass", 100, 0, 0.1 * ebeam, 100, -v0VzMax, v0VzMax);
+//        triX = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Trident: Vertex X", 100, -v0VxMax, v0VxMax);
+//        triY = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Trident: Vertex Y", 100, -v0VyMax, v0VyMax);
+//        triZ = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Trident: Vertex Z", 100, -v0VzMax, v0VzMax);
+//        triXY = aida.histogram2D(plotDir + trkType + triggerType + "/" + "Trident: Vertex Y vs. X", 100, -v0VxMax, v0VxMax, 100, -v0VyMax, v0VyMax);
+//        triZY = aida.histogram2D(plotDir + trkType + triggerType + "/" + "Trident: Vertex Z vs. Y", 100, -v0VyMax, v0VyMax, 100, -v0VzMax, v0VzMax);
+//        triPx = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Trident: Vertex Px", 100, -v0PxMax, v0PxMax);
+//        triPy = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Trident: Vertex Py", 100, -v0PyMax, v0PyMax);
+//        triPz = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Trident: Vertex Pz", 100, v0PzMin, v0PzMax);
+//        triPxPy = aida.histogram2D(plotDir + trkType + triggerType + "/" + "Trident: Vertex Py vs. Px", 100, -v0PxMax, v0PxMax, 100, -v0PyMax, v0PyMax);
+//        triU = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Trident: Vertex Px over Ptot", 100, -0.1, 0.1);
+//        triV = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Trident: Vertex Py over Ptot", 100, -0.1, 0.1);
 
         triRadTrackTimeDiff = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Radiative trident: Track time difference", 100, -10, 10);
         triRadTrackTime2D = aida.histogram2D(plotDir + trkType + triggerType + "/" + "Radiative trident: Track time vs. track time", 100, -10, 10, 100, -10, 10);
 
-        triRadTrackMomentum2D = aida.histogram2D(plotDir + trkType + triggerType + "/" + "Radiative trident: Positron vs. electron momentum", 100, 0, v0PzMax, 100, 0, v0PzMax);
-        triRadDeltaP = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Radiative trident: Positron - electron momentum", 100, -1., 1.0);
-        triRadSumP = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Radiative trident: Positron + electron momentum", 100, v0PzMin, v0PzMax);
-        triRadPyEleVsPyPos = aida.histogram2D(plotDir + trkType + triggerType + "/" + "Radiative trident: Py(e) vs Py(p)", 50, -0.04, 0.04, 50, -0.04, 0.04);
-        triRadPxEleVsPxPos = aida.histogram2D(plotDir + trkType + triggerType + "/" + "Radiative trident: Px(e) vs Px(p)", 50, -0.04, 0.04, 50, -0.04, 0.04);
-
-        triRadMassMomentum = aida.histogram2D(plotDir + trkType + triggerType + "/" + "Radiative trident: Vertex mass vs. vertex momentum", 100, v0PzMin, v0PzMax, 100, 0, 0.1);
-        triRadZVsMomentum = aida.histogram2D(plotDir + trkType + triggerType + "/" + "Radiative trident: Vertex Z vs. vertex momentum", 100, v0PzMin, v0PzMax, 100, -v0VzMax, v0VzMax);
-        triRadMass = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Radiative trident: Vertex mass", 100, 0, 0.11);
-        triRadZVsMass = aida.histogram2D(plotDir + trkType + triggerType + "/" + "Radiative trident: Vertex Z vs. mass", 100, 0, 0.11, 100, -v0VzMax, v0VzMax);
-        triRadX = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Radiative trident: Vertex X", 100, -v0VxMax, v0VxMax);
-        triRadY = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Radiative trident: Vertex Y", 100, -v0VyMax, v0VyMax);
-        triRadZ = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Radiative trident: Vertex Z", 100, -v0VzMax, v0VzMax);
-        triRadXY = aida.histogram2D(plotDir + trkType + triggerType + "/" + "Radiative trident: Vertex Y vs. X", 100, -v0VxMax, v0VxMax, 100, -v0VyMax, v0VyMax);
-        triRadZY = aida.histogram2D(plotDir + trkType + triggerType + "/" + "Radiative trident: Vertex Z vs. Y", 100, -v0VyMax, v0VyMax, 100, -v0VzMax, v0VzMax);
-        triRadPx = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Radiative trident: Vertex Px", 100, -v0PxMax, v0PxMax);
-        triRadPy = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Radiative trident: Vertex Py", 100, -v0PyMax, v0PyMax);
-        triRadPz = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Radiative trident: Vertex Pz", 100, v0PzMin, v0PzMax);
-        triRadPxPy = aida.histogram2D(plotDir + trkType + triggerType + "/" + "Radiative trident: Vertex Py vs. Px", 100, -v0PxMax, v0PxMax, 100, -v0PyMax, v0PyMax);
+        triRadTrackMomentum2D = aida.histogram2D(plotDir + trkType + triggerType + "/" + "Radiative trident: Positron vs. electron momentum", 100, 0, v0PzMax * ebeam, 100, 0, v0PzMax * ebeam);
+        triRadDeltaP = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Radiative trident: Positron - electron momentum", 100, -ebeam, ebeam);
+        triRadSumP = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Radiative trident: Positron + electron momentum", 100, v0PzMin * ebeam, v0PzMax * ebeam);
+        triRadPyEleVsPyPos = aida.histogram2D(plotDir + trkType + triggerType + "/" + "Radiative trident: Py(e) vs Py(p)", 50, -v0PyMax * ebeam, v0PyMax * ebeam, 50, -v0PyMax * ebeam, v0PyMax * ebeam);
+        triRadPxEleVsPxPos = aida.histogram2D(plotDir + trkType + triggerType + "/" + "Radiative trident: Px(e) vs Px(p)", 50, -v0PxMax * ebeam, v0PxMax * ebeam, 50, -v0PxMax * ebeam, v0PxMax * ebeam);
+
+//        triRadMassMomentum = aida.histogram2D(plotDir + trkType + triggerType + "/" + "Radiative trident: Vertex mass vs. vertex momentum", 100, v0PzMin, v0PzMax, 100, 0, 0.1);
+//        triRadZVsMomentum = aida.histogram2D(plotDir + trkType + triggerType + "/" + "Radiative trident: Vertex Z vs. vertex momentum", 100, v0PzMin, v0PzMax, 100, -v0VzMax, v0VzMax);
+        triRadMass = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Radiative trident: Vertex mass", 100, 0, 0.1 * ebeam);
+        triRadZVsMass = aida.histogram2D(plotDir + trkType + triggerType + "/" + "Radiative trident: Vertex Z vs. mass", 100, 0, 0.1 * ebeam, 100, -v0VzMax, v0VzMax);
+//        triRadX = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Radiative trident: Vertex X", 100, -v0VxMax, v0VxMax);
+//        triRadY = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Radiative trident: Vertex Y", 100, -v0VyMax, v0VyMax);
+//        triRadZ = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Radiative trident: Vertex Z", 100, -v0VzMax, v0VzMax);
+//        triRadXY = aida.histogram2D(plotDir + trkType + triggerType + "/" + "Radiative trident: Vertex Y vs. X", 100, -v0VxMax, v0VxMax, 100, -v0VyMax, v0VyMax);
+//        triRadZY = aida.histogram2D(plotDir + trkType + triggerType + "/" + "Radiative trident: Vertex Z vs. Y", 100, -v0VyMax, v0VyMax, 100, -v0VzMax, v0VzMax);
+        triRadPx = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Radiative trident: Vertex Px", 100, -v0PxMax * ebeam, v0PxMax * ebeam);
+        triRadPy = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Radiative trident: Vertex Py", 100, -v0PyMax * ebeam, v0PyMax * ebeam);
+        triRadPz = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Radiative trident: Vertex Pz", 100, v0PzMin * ebeam, v0PzMax * ebeam);
+        triRadPxPy = aida.histogram2D(plotDir + trkType + triggerType + "/" + "Radiative trident: Vertex Py vs. Px", 100, -v0PxMax * ebeam, v0PxMax * ebeam, 100, -v0PyMax * ebeam, v0PyMax * ebeam);
         triRadU = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Radiative trident: Vertex Px over Ptot", 100, -0.1, 0.1);
         triRadV = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Radiative trident: Vertex Py over Ptot", 100, -0.1, 0.1);
 
-        vertTrackTimeDiff = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Vertex: Track time difference", 100, -10, 10);
-        vertTrackTime2D = aida.histogram2D(plotDir + trkType + triggerType + "/" + "Vertex: Track time vs. track time", 100, -10, 10, 100, -10, 10);
-
-        vertTrackMomentum2D = aida.histogram2D(plotDir + trkType + triggerType + "/" + "Vertex: Positron vs. electron momentum", 100, 0, v0PzMax, 100, 0, v0PzMax);
-        vertDeltaP = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Vertex: Positron - electron momentum", 100, -1., 1.0);
-        vertSumP = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Vertex: Positron + electron momentum", 100, v0PzMin, v0PzMax);
-        vertPyEleVsPyPos = aida.histogram2D(plotDir + trkType + triggerType + "/" + "Vertex: Py(e) vs Py(p)", 50, -0.04, 0.04, 50, -0.04, 0.04);
-        vertPxEleVsPxPos = aida.histogram2D(plotDir + trkType + triggerType + "/" + "Vertex: Px(e) vs Px(p)", 50, -0.04, 0.04, 50, -0.04, 0.04);
-
-        vertMassMomentum = aida.histogram2D(plotDir + trkType + triggerType + "/" + "Vertex: Vertex mass vs. vertex momentum", 100, v0PzMin, v0PzMax, 100, 0, 0.1);
-        vertZVsMomentum = aida.histogram2D(plotDir + trkType + triggerType + "/" + "Vertex: Vertex Z vs. vertex momentum", 100, v0PzMin, v0PzMax, 100, -v0VzMax, v0VzMax);
-        vertMass = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Vertex: Vertex mass", 100, 0, 0.11);
-        vertZVsMass = aida.histogram2D(plotDir + trkType + triggerType + "/" + "Vertex: Vertex Z vs. mass", 100, 0, 0.11, 100, -v0VzMax, v0VzMax);
-        vertX = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Vertex: Vertex X", 100, -v0VxMax, v0VxMax);
+//        vertTrackTimeDiff = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Vertex: Track time difference", 100, -10, 10);
+//        vertTrackTime2D = aida.histogram2D(plotDir + trkType + triggerType + "/" + "Vertex: Track time vs. track time", 100, -10, 10, 100, -10, 10);
+        vertTrackMomentum2D = aida.histogram2D(plotDir + trkType + triggerType + "/" + "Vertex: Positron vs. electron momentum", 100, 0, v0PzMax * ebeam, 100, 0, v0PzMax * ebeam);
+        vertDeltaP = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Vertex: Positron - electron momentum", 100, -ebeam, ebeam);
+        vertSumP = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Vertex: Positron + electron momentum", 100, v0PzMin * ebeam, v0PzMax * ebeam);
+        vertPyEleVsPyPos = aida.histogram2D(plotDir + trkType + triggerType + "/" + "Vertex: Py(e) vs Py(p)", 50, -v0PyMax * ebeam, v0PyMax * ebeam, 50, -v0PyMax * ebeam, v0PyMax * ebeam);
+        vertPxEleVsPxPos = aida.histogram2D(plotDir + trkType + triggerType + "/" + "Vertex: Px(e) vs Px(p)", 50, -v0PxMax * ebeam, v0PxMax * ebeam, 50, -v0PxMax * ebeam, v0PxMax * ebeam);
+
+        vertMassMomentum = aida.histogram2D(plotDir + trkType + triggerType + "/" + "Vertex: Vertex mass vs. vertex momentum", 100, v0PzMin * ebeam, v0PzMax * ebeam, 100, 0, 0.1 * ebeam);
+        vertZVsMomentum = aida.histogram2D(plotDir + trkType + triggerType + "/" + "Vertex: Vertex Z vs. vertex momentum", 100, v0PzMin * ebeam, v0PzMax * ebeam, 100, -v0VzMax, v0VzMax);
+        vertMass = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Vertex: Vertex mass", 100, 0, 0.1 * ebeam);
+        vertZVsMass = aida.histogram2D(plotDir + trkType + triggerType + "/" + "Vertex: Vertex Z vs. mass", 100, 0, 0.1 * ebeam, 100, -v0VzMax, v0VzMax);
+//        vertX = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Vertex: Vertex X", 100, -v0VxMax, v0VxMax);
         vertY = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Vertex: Vertex Y", 100, -v0VyMax, v0VyMax);
-        vertZ = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Vertex: Vertex Z", 100, -v0VzMax, v0VzMax);
+//        vertZ = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Vertex: Vertex Z", 100, -v0VzMax, v0VzMax);
         vertXY = aida.histogram2D(plotDir + trkType + triggerType + "/" + "Vertex: Vertex Y vs. X", 100, -v0VxMax, v0VxMax, 100, -v0VyMax, v0VyMax);
         vertZY = aida.histogram2D(plotDir + trkType + triggerType + "/" + "Vertex: Vertex Z vs. Y", 100, -v0VyMax, v0VyMax, 100, -v0VzMax, v0VzMax);
-        vertPx = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Vertex: Vertex Px", 100, -v0PxMax, v0PxMax);
-        vertPy = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Vertex: Vertex Py", 100, -v0PyMax, v0PyMax);
-        vertPz = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Vertex: Vertex Pz", 100, v0PzMin, v0PzMax);
-        vertPxPy = aida.histogram2D(plotDir + trkType + triggerType + "/" + "Vertex: Vertex Py vs. Px", 100, -v0PxMax, v0PxMax, 100, -v0PyMax, v0PyMax);
-        vertU = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Vertex: Vertex Px over Ptot", 100, -0.1, 0.1);
-        vertV = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Vertex: Vertex Py over Ptot", 100, -0.1, 0.1);
+//        vertPx = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Vertex: Vertex Px", 100, -v0PxMax, v0PxMax);
+//        vertPy = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Vertex: Vertex Py", 100, -v0PyMax, v0PyMax);
+//        vertPz = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Vertex: Vertex Pz", 100, v0PzMin, v0PzMax);
+//        vertPxPy = aida.histogram2D(plotDir + trkType + triggerType + "/" + "Vertex: Vertex Py vs. Px", 100, -v0PxMax, v0PxMax, 100, -v0PyMax, v0PyMax);
+//        vertU = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Vertex: Vertex Px over Ptot", 100, -0.1, 0.1);
+//        vertV = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Vertex: Vertex Py over Ptot", 100, -0.1, 0.1);
 
         vertRadTrackTimeDiff = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Radiative vertex: Track time difference", 100, -10, 10);
         vertRadTrackTime2D = aida.histogram2D(plotDir + trkType + triggerType + "/" + "Radiative vertex: Track time vs. track time", 100, -10, 10, 100, -10, 10);
 
-        vertRadTrackMomentum2D = aida.histogram2D(plotDir + trkType + triggerType + "/" + "Radiative vertex: Positron vs. electron momentum", 100, 0, v0PzMax, 100, 0, v0PzMax);
-        vertRadDeltaP = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Radiative vertex: Positron - electron momentum", 100, -1., 1.0);
-        vertRadSumP = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Radiative vertex: Positron + electron momentum", 100, v0PzMin, v0PzMax);
-        vertRadPyEleVsPyPos = aida.histogram2D(plotDir + trkType + triggerType + "/" + "Radiative vertex: Py(e) vs Py(p)", 50, -0.04, 0.04, 50, -0.04, 0.04);
-        vertRadPxEleVsPxPos = aida.histogram2D(plotDir + trkType + triggerType + "/" + "Radiative vertex: Px(e) vs Px(p)", 50, -0.04, 0.04, 50, -0.04, 0.04);
-
-        vertRadMassMomentum = aida.histogram2D(plotDir + trkType + triggerType + "/" + "Radiative vertex: Vertex mass vs. vertex momentum", 100, v0PzMin, v0PzMax, 100, 0, 0.1);
-        vertRadZVsMomentum = aida.histogram2D(plotDir + trkType + triggerType + "/" + "Radiative vertex: Vertex Z vs. vertex momentum", 100, v0PzMin, v0PzMax, 100, -v0VzMax, v0VzMax);
-        vertRadMass = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Radiative vertex: Vertex mass", 100, 0, 0.11);
-        vertRadZVsMass = aida.histogram2D(plotDir + trkType + triggerType + "/" + "Radiative vertex: Vertex Z vs. mass", 100, 0, 0.11, 100, -v0VzMax, v0VzMax);
+        vertRadTrackMomentum2D = aida.histogram2D(plotDir + trkType + triggerType + "/" + "Radiative vertex: Positron vs. electron momentum", 100, 0, v0PzMax * ebeam, 100, 0, v0PzMax * ebeam);
+        vertRadDeltaP = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Radiative vertex: Positron - electron momentum", 100, -ebeam, ebeam);
+        vertRadSumP = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Radiative vertex: Positron + electron momentum", 100, v0PzMin * ebeam, v0PzMax * ebeam);
+        vertRadPyEleVsPyPos = aida.histogram2D(plotDir + trkType + triggerType + "/" + "Radiative vertex: Py(e) vs Py(p)", 50, -v0PyMax * ebeam, v0PyMax * ebeam, 50, -v0PyMax * ebeam, v0PyMax * ebeam);
+        vertRadPxEleVsPxPos = aida.histogram2D(plotDir + trkType + triggerType + "/" + "Radiative vertex: Px(e) vs Px(p)", 50, -v0PxMax * ebeam, v0PxMax * ebeam, 50, -v0PxMax * ebeam, v0PxMax * ebeam);
+
+        vertRadMassMomentum = aida.histogram2D(plotDir + trkType + triggerType + "/" + "Radiative vertex: Vertex mass vs. vertex momentum", 100, v0PzMin * ebeam, v0PzMax * ebeam, 100, 0, 0.1 * ebeam);
+        vertRadZVsMomentum = aida.histogram2D(plotDir + trkType + triggerType + "/" + "Radiative vertex: Vertex Z vs. vertex momentum", 100, v0PzMin * ebeam, v0PzMax * ebeam, 100, -v0VzMax, v0VzMax);
+        vertRadMass = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Radiative vertex: Vertex mass", 100, 0, 0.1 * ebeam);
+        vertRadZVsMass = aida.histogram2D(plotDir + trkType + triggerType + "/" + "Radiative vertex: Vertex Z vs. mass", 100, 0, 0.1 * ebeam, 100, -v0VzMax, v0VzMax);
         vertRadX = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Radiative vertex: Vertex X", 100, -v0VxMax, v0VxMax);
         vertRadY = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Radiative vertex: Vertex Y", 100, -v0VyMax, v0VyMax);
         vertRadZ = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Radiative vertex: Vertex Z", 100, -v0VzMax, v0VzMax);
         vertRadXY = aida.histogram2D(plotDir + trkType + triggerType + "/" + "Radiative vertex: Vertex Y vs. X", 100, -v0VxMax, v0VxMax, 100, -v0VyMax, v0VyMax);
         vertRadZY = aida.histogram2D(plotDir + trkType + triggerType + "/" + "Radiative vertex: Vertex Z vs. Y", 100, -v0VyMax, v0VyMax, 100, -v0VzMax, v0VzMax);
-        vertRadPx = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Radiative vertex: Vertex Px", 100, -v0PxMax, v0PxMax);
-        vertRadPy = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Radiative vertex: Vertex Py", 100, -v0PyMax, v0PyMax);
-        vertRadPz = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Radiative vertex: Vertex Pz", 100, v0PzMin, v0PzMax);
-        vertRadPxPy = aida.histogram2D(plotDir + trkType + triggerType + "/" + "Radiative vertex: Vertex Py vs. Px", 100, -v0PxMax, v0PxMax, 100, -v0PyMax, v0PyMax);
+        vertRadPx = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Radiative vertex: Vertex Px", 100, -v0PxMax * ebeam, v0PxMax * ebeam);
+        vertRadPy = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Radiative vertex: Vertex Py", 100, -v0PyMax * ebeam, v0PyMax * ebeam);
+        vertRadPz = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Radiative vertex: Vertex Pz", 100, v0PzMin * ebeam, v0PzMax * ebeam);
+        vertRadPxPy = aida.histogram2D(plotDir + trkType + triggerType + "/" + "Radiative vertex: Vertex Py vs. Px", 100, -v0PxMax * ebeam, v0PxMax * ebeam, 100, -v0PyMax * ebeam, v0PyMax * ebeam);
         vertRadU = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Radiative vertex: Vertex Px over Ptot", 100, -0.1, 0.1);
         vertRadV = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Radiative vertex: Vertex Py over Ptot", 100, -0.1, 0.1);
 
+        vertRadUnconBsconChi2 = aida.histogram2D(plotDir + trkType + triggerType + "/" + "Radiative vertex: beamspot chi2 vs. uncon chi2", 100, 0, 25.0, 100, 0, 25.0);
+
         nVtxCand = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Number of Vertexing Candidates", 5, 0, 4);
 
         maxTrkChi2 = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Cut: Trk Chi2", 50, 0.0, 50.0);
@@ -391,6 +494,10 @@
 
         v0Chi2 = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Cut: V0 Chi2", 50, 0.0, 25.0);
         zVsV0Chi2 = aida.histogram2D(plotDir + trkType + triggerType + "/" + "Cut: Vz vs V0 Chi2", 50, 0.0, 25.0, 50, -v0VzMax, v0VzMax);
+        bsconV0Chi2 = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Cut: Bscon V0 Chi2", 50, 0.0, 25.0);
+        zVsBsconV0Chi2 = aida.histogram2D(plotDir + trkType + triggerType + "/" + "Cut: Vz vs Bscon V0 Chi2", 50, 0.0, 25.0, 50, -v0VzMax, v0VzMax);
+        v0Chi2Diff = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Cut: Bscon-Uncon V0 Chi2 Diff", 50, 0.0, 25.0);
+        zVsV0Chi2Diff = aida.histogram2D(plotDir + trkType + triggerType + "/" + "Cut: Vz vs Bscon-Uncon V0 Chi2 Diff", 50, 0.0, 25.0, 50, -v0VzMax, v0VzMax);
 
         trackTimeDiff = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Cut: Trk Time Diff", 50, 0.0, 10.0);
         hitTimeStdDev = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Cut: Hit Time Std Dev", 50, 0.0, 10.0);
@@ -402,16 +509,16 @@
         zVsEventTrkCount = aida.histogram2D(plotDir + trkType + triggerType + "/" + "Cut: Vz vs Num Tracks", 10, 0.5, 10.5, 50, -v0VzMax, v0VzMax);
         zVsEventPosCount = aida.histogram2D(plotDir + trkType + triggerType + "/" + "Cut: Vz vs Num Positrons", 5, 0.5, 5.5, 50, -v0VzMax, v0VzMax);
 
-        l1Iso = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Cut: L1 Isolation", 50, 0.0, 5.0);
-        zVsL1Iso = aida.histogram2D(plotDir + trkType + triggerType + "/" + "Cut: Vz vs L1 Isolation", 50, 0.0, 5.0, 50, -v0VzMax, v0VzMax);
+        l1Iso = aida.histogram1D(plotDir + trkType + triggerType + "/" + "Cut: L1 Isolation", 100, 0.0, 5.0);
+        zVsL1Iso = aida.histogram2D(plotDir + trkType + triggerType + "/" + "Cut: Vz vs L1 Isolation", 100, 0.0, 5.0, 50, -v0VzMax, v0VzMax);
 
         for (Cut cut : Cut.values()) {
             for (int i = 0; i < 2; i++) {
-                cutVertexZ[cut.ordinal()][i] = aida.histogram1D(String.format("%s%s%s/failed cut: %s/%s: Vertex Z position (mm)", plotDir, trkType, triggerType, cut.ordinal(), cut.name, i == VERTEX ? "vertex" : "trident"),
+                cutVertexZ[cut.ordinal()][i] = aida.histogram1D(String.format("%s%s%s/failed cut %d: %s/%s: Vertex Z position (mm)", plotDir, trkType, triggerType, cut.ordinal(), cut.name, i == VERTEX ? "vertex" : "trident"),
                         100, -v0VzMax, v0VzMax);
-                cutVertexMass[cut.ordinal()][i] = aida.histogram1D(String.format("%s%s%s/failed cut: %s/%s: Vertex mass (GeV)", plotDir, trkType, triggerType, cut.ordinal(), cut.name, i == VERTEX ? "vertex" : "trident"),
+                cutVertexMass[cut.ordinal()][i] = aida.histogram1D(String.format("%s%s%s/failed cut %d: %s/%s: Vertex mass (GeV)", plotDir, trkType, triggerType, cut.ordinal(), cut.name, i == VERTEX ? "vertex" : "trident"),
                         100, 0, 0.1 * ebeam);
-                cutVertexZVsMass[cut.ordinal()][i] = aida.histogram2D(String.format("%s%s%s/failed cut: %s/%s: Vertex Z vs. mass", plotDir, trkType, triggerType, cut.ordinal(), cut.name, i == VERTEX ? "vertex" : "trident"),
+                cutVertexZVsMass[cut.ordinal()][i] = aida.histogram2D(String.format("%s%s%s/failed cut %d: %s/%s: Vertex Z vs. mass", plotDir, trkType, triggerType, cut.ordinal(), cut.name, i == VERTEX ? "vertex" : "trident"),
                         100, 0, 0.1 * ebeam, 100, -v0VzMax, v0VzMax);
             }
         }
@@ -489,11 +596,9 @@
             if (tracks.size() != 2) {
                 throw new RuntimeException("expected two tracks in vertex, got " + tracks.size());
             }
-            List<Double> trackTimes = new ArrayList<Double>();
             List<Double> hitTimes = new ArrayList<Double>();
             double mean = 0;
             for (Track track : tracks) {
-                trackTimes.add(TrackUtils.getTrackTime(track, hitToStrips, hitToRotated));
                 for (TrackerHit hit : TrackUtils.getStripHits(track, hitToStrips, hitToRotated)) {
                     mean += hit.getTime();
                     hitTimes.add(hit.getTime());
@@ -516,57 +621,180 @@
                 minL1Iso = Math.min(eleL1Iso, posL1Iso);
             }
 
+            double tEle = TrackUtils.getTrackTime(electron.getTracks().get(0), hitToStrips, hitToRotated);
+            double tPos = TrackUtils.getTrackTime(positron.getTracks().get(0), hitToStrips, hitToRotated);
+            Hep3Vector pEleRot = VecOp.mult(beamAxisRotation, electron.getMomentum());
+            Hep3Vector pPosRot = VecOp.mult(beamAxisRotation, positron.getMomentum());
+
+            Hep3Vector eleAtEcal = TrackUtils.getTrackPositionAtEcal(electron.getTracks().get(0));
+            Hep3Vector posAtEcal = TrackUtils.getTrackPositionAtEcal(positron.getTracks().get(0));
+
+            BilliorVertexer vtxFitter = new BilliorVertexer(TrackUtils.getBField(event.getDetector()).y());
+            vtxFitter.setBeamSize(beamSize);
+            vtxFitter.setBeamPosition(beamPos);
+            List<BilliorTrack> billiorTracks = new ArrayList<BilliorTrack>();
+            billiorTracks.add(new BilliorTrack(electron.getTracks().get(0)));
+            billiorTracks.add(new BilliorTrack(positron.getTracks().get(0)));
+
+            vtxFitter.doBeamSpotConstraint(true);
+            BilliorVertex bsconVertex = vtxFitter.fitVertex(billiorTracks);
+            ReconstructedParticle bscV0 = HpsReconParticleDriver.makeReconstructedParticle(electron, positron, bsconVertex);
+            Hep3Vector bscMomRot = VecOp.mult(beamAxisRotation, bscV0.getMomentum());
+            Hep3Vector bscVtx = VecOp.mult(beamAxisRotation, bscV0.getStartVertex().getPosition());
+
+            vtxFitter.doTargetConstraint(true);
+            BilliorVertex tarVertex = vtxFitter.fitVertex(billiorTracks);
+            ReconstructedParticle tarV0 = HpsReconParticleDriver.makeReconstructedParticle(electron, positron, tarVertex);
+            Hep3Vector tarMomRot = VecOp.mult(beamAxisRotation, tarV0.getMomentum());
+            Hep3Vector tarVtx = VecOp.mult(beamAxisRotation, tarV0.getStartVertex().getPosition());
+
+            vtxFitter.setBeamSize(vzcBeamSize);
+            vtxFitter.doTargetConstraint(true);
+            BilliorVertex vzcVertex = vtxFitter.fitVertex(billiorTracks);
+            ReconstructedParticle vzcV0 = HpsReconParticleDriver.makeReconstructedParticle(electron, positron, vzcVertex);
+            Hep3Vector vzcMomRot = VecOp.mult(beamAxisRotation, vzcV0.getMomentum());
+            Hep3Vector vzcVtx = VecOp.mult(beamAxisRotation, vzcV0.getStartVertex().getPosition());
+
+            if (tupleWriter != null) {
+                boolean trkCut = electron.getMomentum().magnitude() < tupleTrkPCut * ebeam && positron.getMomentum().magnitude() < tupleTrkPCut * ebeam;
+                boolean sumCut = electron.getMomentum().magnitude() + positron.getMomentum().magnitude() < tupleMaxSumCut * ebeam;
+                if (!cutTuple || (trkCut && sumCut)) {
+
+                    tupleMap.put("run/I", (double) event.getRunNumber());
+                    tupleMap.put("event/I", (double) event.getEventNumber());
+
+                    tupleMap.put("uncPX/D", v0MomRot.x());
+                    tupleMap.put("uncPY/D", v0MomRot.y());
+                    tupleMap.put("uncPZ/D", v0MomRot.z());
+                    tupleMap.put("uncP/D", v0MomRot.magnitude());
+                    tupleMap.put("uncVX/D", v0Vtx.x());
+                    tupleMap.put("uncVY/D", v0Vtx.y());
+                    tupleMap.put("uncVZ/D", v0Vtx.z());
+                    tupleMap.put("uncChisq/D", uncV0.getStartVertex().getChi2());
+                    tupleMap.put("uncM/D", uncV0.getMass());
+
+                    tupleMap.put("bscPX/D", bscMomRot.x());
+                    tupleMap.put("bscPY/D", bscMomRot.y());
+                    tupleMap.put("bscPZ/D", bscMomRot.z());
+                    tupleMap.put("bscP/D", bscMomRot.magnitude());
+                    tupleMap.put("bscVX/D", bscVtx.x());
+                    tupleMap.put("bscVY/D", bscVtx.y());
+                    tupleMap.put("bscVZ/D", bscVtx.z());
+                    tupleMap.put("bscChisq/D", bscV0.getStartVertex().getChi2());
+                    tupleMap.put("bscM/D", bscV0.getMass());
+
+                    tupleMap.put("tarPX/D", tarMomRot.x());
+                    tupleMap.put("tarPY/D", tarMomRot.y());
+                    tupleMap.put("tarPZ/D", tarMomRot.z());
+                    tupleMap.put("tarP/D", tarMomRot.magnitude());
+                    tupleMap.put("tarVX/D", tarVtx.x());
+                    tupleMap.put("tarVY/D", tarVtx.y());
+                    tupleMap.put("tarVZ/D", tarVtx.z());
+                    tupleMap.put("tarChisq/D", tarV0.getStartVertex().getChi2());
+                    tupleMap.put("tarM/D", tarV0.getMass());
+
+                    tupleMap.put("vzcPX/D", vzcMomRot.x());
+                    tupleMap.put("vzcPY/D", vzcMomRot.y());
+                    tupleMap.put("vzcPZ/D", vzcMomRot.z());
+                    tupleMap.put("vzcP/D", vzcMomRot.magnitude());
+                    tupleMap.put("vzcVX/D", vzcVtx.x());
+                    tupleMap.put("vzcVY/D", vzcVtx.y());
+                    tupleMap.put("vzcVZ/D", vzcVtx.z());
+                    tupleMap.put("vzcChisq/D", vzcV0.getStartVertex().getChi2());
+                    tupleMap.put("vzcM/D", vzcV0.getMass());
+
+                    tupleMap.put("elePX/D", pEleRot.x());
+                    tupleMap.put("elePY/D", pEleRot.y());
+                    tupleMap.put("elePZ/D", pEleRot.z());
+                    tupleMap.put("eleP/D", pEleRot.magnitude());
+                    tupleMap.put("eleTrkD0/D", electron.getTracks().get(0).getTrackStates().get(0).getD0());
+                    tupleMap.put("eleTrkZ0/D", electron.getTracks().get(0).getTrackStates().get(0).getZ0());
+                    tupleMap.put("eleTrkEcalX/D", eleAtEcal.x());
+                    tupleMap.put("eleTrkEcalY/D", eleAtEcal.y());
+                    tupleMap.put("eleTrkChisq/D", electron.getTracks().get(0).getChi2());
+                    tupleMap.put("eleTrkHits/I", (double) electron.getTracks().get(0).getTrackerHits().size());
+                    tupleMap.put("eleTrkType/I", (double) electron.getType());
+                    tupleMap.put("eleTrkT/D", tEle);
+                    tupleMap.put("eleHasL1/B", eleIso[0] != null ? 1.0 : 0.0);
+                    tupleMap.put("eleHasL2/B", eleIso[2] != null ? 1.0 : 0.0);
+                    tupleMap.put("eleMatchChisq/D", electron.getGoodnessOfPID());
+                    if (!electron.getClusters().isEmpty()) {
+                        Cluster eleC = electron.getClusters().get(0);
+                        tupleMap.put("eleClT/D", ClusterUtilities.getSeedHitTime(eleC));
+                        tupleMap.put("eleClE/D", eleC.getEnergy());
+                        tupleMap.put("eleClHits/I", (double) eleC.getCalorimeterHits().size());
+                    }
+
+                    tupleMap.put("posPX/D", pPosRot.x());
+                    tupleMap.put("posPY/D", pPosRot.y());
+                    tupleMap.put("posPZ/D", pPosRot.z());
+                    tupleMap.put("posP/D", pPosRot.magnitude());
+                    tupleMap.put("posTrkD0/D", positron.getTracks().get(0).getTrackStates().get(0).getD0());
+                    tupleMap.put("posTrkZ0/D", positron.getTracks().get(0).getTrackStates().get(0).getZ0());
+                    tupleMap.put("posTrkEcalX/D", posAtEcal.x());
+                    tupleMap.put("posTrkEcalY/D", posAtEcal.y());
+                    tupleMap.put("posTrkChisq/D", positron.getTracks().get(0).getChi2());
+                    tupleMap.put("posTrkHits/I", (double) positron.getTracks().get(0).getTrackerHits().size());
+                    tupleMap.put("posTrkType/I", (double) positron.getType());
+                    tupleMap.put("posTrkT/D", tPos);
+                    tupleMap.put("posHasL1/B", posIso[0] != null ? 1.0 : 0.0);
+                    tupleMap.put("posHasL2/B", posIso[2] != null ? 1.0 : 0.0);
+                    tupleMap.put("posMatchChisq/D", positron.getGoodnessOfPID());
+                    if (!positron.getClusters().isEmpty()) {
+                        Cluster posC = positron.getClusters().get(0);
+                        tupleMap.put("posClT/D", ClusterUtilities.getSeedHitTime(posC));
+                        tupleMap.put("posClE/D", posC.getEnergy());
+                        tupleMap.put("posClHits/I", (double) posC.getCalorimeterHits().size());
+                    }
+
+                    tupleMap.put("minL1Iso/D", minL1Iso);
+
+                    tupleMap.put("nTrk/I", (double) ntrk);
+                    tupleMap.put("nPos/I", (double) npos);
+                    writeTuple();
+                }
+            }
+
             //start applying cuts
             EnumSet<Cut> bits = EnumSet.noneOf(Cut.class);
 
-            boolean trackQualityCut = Math.max(tracks.get(0).getChi2(), tracks.get(1).getChi2()) < (isGBL ? maxChi2GBLTrack : maxChi2SeedTrack);
-            maxTrkChi2.fill(Math.max(tracks.get(0).getChi2(), tracks.get(1).getChi2()));
-            zVsMaxTrkChi2.fill(Math.max(tracks.get(0).getChi2(), tracks.get(1).getChi2()), v0Vtx.z());
+            boolean trackQualityCut = Math.max(electron.getTracks().get(0).getChi2(), positron.getTracks().get(0).getChi2()) < (isGBL ? maxChi2GBLTrack : maxChi2SeedTrack);
             if (trackQualityCut) {
                 bits.add(Cut.TRK_QUALITY);
             }
 
-            boolean v0QualityCut = uncVert.getChi2() < maxVertChi2;
-            v0Chi2.fill(uncVert.getChi2());
-            zVsV0Chi2.fill(uncVert.getChi2(), v0Vtx.z());
+            boolean v0QualityCut = uncVert.getChi2() < maxUnconVertChi2 && bsconVertex.getChi2() < maxBsconVertChi2;
             if (v0QualityCut) {
                 bits.add(Cut.VTX_QUALITY);
             }
 
-            boolean vertexMomentumCut = v0MomRot.z() < v0PzMax && v0MomRot.z() > v0PzMin && Math.abs(v0MomRot.x()) < v0PxMax && Math.abs(v0MomRot.y()) < v0PyMax;
-            boolean vertexPositionCut = Math.abs(v0Vtx.x()) < v0VxMax && Math.abs(v0Vtx.y()) < v0VyMax && Math.abs(v0Vtx.z()) < v0VzMax;
+            boolean vertexMomentumCut = v0MomRot.z() < v0PzMaxCut * ebeam && v0MomRot.z() > v0PzMinCut * ebeam && Math.abs(v0MomRot.x()) < v0PxCut * ebeam && Math.abs(v0MomRot.y()) < v0PyCut * ebeam;
+            boolean vertexPositionCut = Math.abs(v0Vtx.x()) < v0UnconVxCut && Math.abs(v0Vtx.y()) < v0UnconVyCut && Math.abs(v0Vtx.z()) < v0UnconVzCut && Math.abs(bscVtx.x()) < v0BsconVxCut && Math.abs(bscVtx.y()) < v0BsconVyCut;
             if (vertexMomentumCut && vertexPositionCut) {
                 bits.add(Cut.VERTEX_CUTS);
             }
 
-            boolean trackTimeDiffCut = Math.abs(trackTimes.get(0) - trackTimes.get(1)) < trkTimeDiff;
-            trackTimeDiff.fill(Math.abs(trackTimes.get(0) - trackTimes.get(1)));
-            hitTimeStdDev.fill(stdDev);
-            zVsTrackTimeDiff.fill(Math.abs(trackTimes.get(0) - trackTimes.get(1)), v0Vtx.z());
-            zVsHitTimeStdDev.fill(stdDev, v0Vtx.z());
+            boolean trackTimeDiffCut = Math.abs(tEle - tPos) < trkTimeDiff;
             if (trackTimeDiffCut) {
                 bits.add(Cut.TIMING);
             }
 
             boolean topBottomCut = electron.getMomentum().y() * positron.getMomentum().y() < 0;
-            boolean pMinCut = electron.getMomentum().magnitude() > minPCut && positron.getMomentum().magnitude() > minPCut;
-            boolean pMaxCut = electron.getMomentum().magnitude() < beamPCut && positron.getMomentum().magnitude() < beamPCut;
+            boolean pMinCut = electron.getMomentum().magnitude() > minPCut * ebeam && positron.getMomentum().magnitude() > minPCut * ebeam;
+            boolean pMaxCut = electron.getMomentum().magnitude() < beamPCut * ebeam && positron.getMomentum().magnitude() < beamPCut * ebeam;
             if (topBottomCut && pMaxCut && pMinCut) {
                 bits.add(Cut.TRACK_CUTS);
             }
 
             boolean clusterMatchCut = !electron.getClusters().isEmpty() && !positron.getClusters().isEmpty();
             boolean clusterTimeCut = clusterMatchCut && Math.abs(ClusterUtilities.getSeedHitTime(electron.getClusters().get(0)) - ClusterUtilities.getSeedHitTime(positron.getClusters().get(0))) < clusterTimeDiffCut;
-            if (clusterMatchCut && clusterTimeCut) {
-                bits.add(Cut.CLUSTER_CUTS);
-            }
+//disable cut for now
+//            if (clusterMatchCut && clusterTimeCut) {
+            bits.add(Cut.CLUSTER_CUTS);
+//            }
 
             boolean eventTrkCountCut = ntrk >= 2 && ntrk <= nTrkMax;
             boolean eventPosCountCut = npos >= 1 && npos <= nPosMax;
-            eventTrkCount.fill(ntrk);
-            eventPosCount.fill(npos);
-            zVsEventTrkCount.fill(ntrk, v0Vtx.z());
-            zVsEventPosCount.fill(npos, v0Vtx.z());
             if (eventTrkCountCut && eventPosCountCut) {
                 bits.add(Cut.EVENT_QUALITY);
             }
@@ -576,10 +804,8 @@
                 bits.add(Cut.FRONT_HITS);
             }
 
-            l1Iso.fill(minL1Iso);
-            zVsL1Iso.fill(minL1Iso, v0Vtx.z());
             boolean isoCut = minL1Iso > l1IsoMin;
-            if (isoCut) {
+            if (!frontHitsCut || isoCut) { //diagnostic plots look better if failing the front hits cut makes you pass this one
                 bits.add(Cut.ISOLATION);
             }
 
@@ -597,22 +823,58 @@
             for (Cut cut : Cut.values()) {
                 EnumSet<Cut> allButThisCut = EnumSet.allOf(Cut.class);
                 allButThisCut.remove(cut);
-                if (bits.equals(allButThisCut)) {
-                    if (uncV0.getMass() > plotsMinMass && uncV0.getMass() < plotsMaxMass) {
-                        cutVertexZ[cut.ordinal()][VERTEX].fill(v0Vtx.z());
+                if (bits.containsAll(allButThisCut)) {
+                    if (uncV0.getMass() > plotsMinMass * ebeam && uncV0.getMass() < plotsMaxMass * ebeam && uncV0.getMomentum().magnitude() > radCut * ebeam) {
+                        switch (cut) {
+                            case ISOLATION:
+                                l1Iso.fill(minL1Iso);
+                                zVsL1Iso.fill(minL1Iso, v0Vtx.z());
+                                break;
+                            case EVENT_QUALITY:
+                                eventTrkCount.fill(ntrk);
+                                eventPosCount.fill(npos);
+                                zVsEventTrkCount.fill(ntrk, v0Vtx.z());
+                                zVsEventPosCount.fill(npos, v0Vtx.z());
+                                break;
+                            case TIMING:
+                                trackTimeDiff.fill(Math.abs(tEle - tPos));
+                                hitTimeStdDev.fill(stdDev);
+                                zVsTrackTimeDiff.fill(Math.abs(tEle - tPos), v0Vtx.z());
+                                zVsHitTimeStdDev.fill(stdDev, v0Vtx.z());
+                                break;
+                            case VTX_QUALITY:
+                                v0Chi2.fill(uncVert.getChi2());
+                                zVsV0Chi2.fill(uncVert.getChi2(), v0Vtx.z());
+                                bsconV0Chi2.fill(bsconVertex.getChi2());
+                                zVsBsconV0Chi2.fill(bsconVertex.getChi2(), v0Vtx.z());
+                                v0Chi2Diff.fill(bsconVertex.getChi2() - uncVert.getChi2());
+                                zVsV0Chi2Diff.fill(bsconVertex.getChi2() - uncVert.getChi2(), v0Vtx.z());
+                                break;
+                            case TRK_QUALITY:
+                                maxTrkChi2.fill(Math.max(tracks.get(0).getChi2(), tracks.get(1).getChi2()));
+                                zVsMaxTrkChi2.fill(Math.max(tracks.get(0).getChi2(), tracks.get(1).getChi2()), v0Vtx.z());
+                                break;
+                        }
                     }
-                    cutVertexMass[cut.ordinal()][VERTEX].fill(uncV0.getMass());
-                    cutVertexZVsMass[cut.ordinal()][VERTEX].fill(uncV0.getMass(), v0Vtx.z());
+                    if (!bits.contains(cut)) {
+                        if (uncV0.getMass() > plotsMinMass * ebeam && uncV0.getMass() < plotsMaxMass * ebeam) {
+                            cutVertexZ[cut.ordinal()][VERTEX].fill(v0Vtx.z());
+                        }
+                        cutVertexMass[cut.ordinal()][VERTEX].fill(uncV0.getMass());
+                        cutVertexZVsMass[cut.ordinal()][VERTEX].fill(uncV0.getMass(), v0Vtx.z());
+                    }
                 }
 
                 EnumSet<Cut> allTriCutsButThisCut = EnumSet.range(Cut.values()[0], Cut.values()[Cut.firstVertexingCut - 1]);
                 allTriCutsButThisCut.remove(cut);
-                if (bits.containsAll(allTriCutsButThisCut) && !bits.contains(cut)) {
-                    if (uncV0.getMass() > plotsMinMass && uncV0.getMass() < plotsMaxMass) {
-                        cutVertexZ[cut.ordinal()][TRIDENT].fill(v0Vtx.z());
+                if (bits.containsAll(allTriCutsButThisCut)) {
+                    if (!bits.contains(cut)) {
+                        if (uncV0.getMass() > plotsMinMass * ebeam && uncV0.getMass() < plotsMaxMass * ebeam) {
+                            cutVertexZ[cut.ordinal()][TRIDENT].fill(v0Vtx.z());
+                        }
+                        cutVertexMass[cut.ordinal()][TRIDENT].fill(uncV0.getMass());
+                        cutVertexZVsMass[cut.ordinal()][TRIDENT].fill(uncV0.getMass(), v0Vtx.z());
                     }
-                    cutVertexMass[cut.ordinal()][TRIDENT].fill(uncV0.getMass());
-                    cutVertexZVsMass[cut.ordinal()][TRIDENT].fill(uncV0.getMass(), v0Vtx.z());
                 }
             }
 
@@ -645,8 +907,8 @@
             Hep3Vector pPosRot = VecOp.mult(beamAxisRotation, positron.getMomentum());
             Hep3Vector v0Vtx = VecOp.mult(beamAxisRotation, bestCandidate.getStartVertex().getPosition());
 
-            triTrackTime2D.fill(tEle, tPos);
-            triTrackTimeDiff.fill(tEle - tPos);
+//            triTrackTime2D.fill(tEle, tPos);
+//            triTrackTimeDiff.fill(tEle - tPos);
             triZVsMomentum.fill(bestCandidate.getMomentum().magnitude(), v0Vtx.z());
             triMassMomentum.fill(bestCandidate.getMomentum().magnitude(), bestCandidate.getMass());
             triTrackMomentum2D.fill(electron.getMomentum().magnitude(), positron.getMomentum().magnitude());
@@ -655,24 +917,24 @@
             triSumP.fill(bestCandidate.getMomentum().magnitude());
             triDeltaP.fill(positron.getMomentum().magnitude() - electron.getMomentum().magnitude());
 
-            triPxPy.fill(pBestV0Rot.x(), pBestV0Rot.y());
+//            triPxPy.fill(pBestV0Rot.x(), pBestV0Rot.y());
             triMass.fill(bestCandidate.getMass());
             triZVsMass.fill(bestCandidate.getMass(), v0Vtx.z());
-            triX.fill(v0Vtx.x());
-            triY.fill(v0Vtx.y());
-            triZ.fill(v0Vtx.z());
-            triPx.fill(pBestV0Rot.x());
-            triPy.fill(pBestV0Rot.y());
-            triPz.fill(pBestV0Rot.z());
-            triU.fill(pBestV0Rot.x() / pBestV0Rot.magnitude());
-            triV.fill(pBestV0Rot.y() / pBestV0Rot.magnitude());
-            triXY.fill(v0Vtx.x(), v0Vtx.y());
-            triZY.fill(v0Vtx.y(), v0Vtx.z());
-            if (bestCandidate.getMomentum().magnitude() > radCut) {
+//            triX.fill(v0Vtx.x());
+//            triY.fill(v0Vtx.y());
+//            triZ.fill(v0Vtx.z());
+//            triPx.fill(pBestV0Rot.x());
+//            triPy.fill(pBestV0Rot.y());
+//            triPz.fill(pBestV0Rot.z());
+//            triU.fill(pBestV0Rot.x() / pBestV0Rot.magnitude());
+//            triV.fill(pBestV0Rot.y() / pBestV0Rot.magnitude());
+//            triXY.fill(v0Vtx.x(), v0Vtx.y());
+//            triZY.fill(v0Vtx.y(), v0Vtx.z());
+            if (bestCandidate.getMomentum().magnitude() > radCut * ebeam) {
                 triRadTrackTime2D.fill(tEle, tPos);
                 triRadTrackTimeDiff.fill(tEle - tPos);
-                triRadZVsMomentum.fill(bestCandidate.getMomentum().magnitude(), v0Vtx.z());
-                triRadMassMomentum.fill(bestCandidate.getMomentum().magnitude(), bestCandidate.getMass());
+//                triRadZVsMomentum.fill(bestCandidate.getMomentum().magnitude(), v0Vtx.z());
+//                triRadMassMomentum.fill(bestCandidate.getMomentum().magnitude(), bestCandidate.getMass());
                 triRadTrackMomentum2D.fill(electron.getMomentum().magnitude(), positron.getMomentum().magnitude());
                 triRadPyEleVsPyPos.fill(pEleRot.y(), pPosRot.y());
                 triRadPxEleVsPxPos.fill(pEleRot.x(), pPosRot.x());
@@ -682,22 +944,23 @@
                 triRadPxPy.fill(pBestV0Rot.x(), pBestV0Rot.y());
                 triRadMass.fill(bestCandidate.getMass());
                 triRadZVsMass.fill(bestCandidate.getMass(), v0Vtx.z());
-                triRadX.fill(v0Vtx.x());
-                triRadY.fill(v0Vtx.y());
-                triRadZ.fill(v0Vtx.z());
+//                triRadX.fill(v0Vtx.x());
+//                triRadY.fill(v0Vtx.y());
+//                triRadZ.fill(v0Vtx.z());
                 triRadPx.fill(pBestV0Rot.x());
                 triRadPy.fill(pBestV0Rot.y());
                 triRadPz.fill(pBestV0Rot.z());
                 triRadU.fill(pBestV0Rot.x() / pBestV0Rot.magnitude());
                 triRadV.fill(pBestV0Rot.y() / pBestV0Rot.magnitude());
-                triRadXY.fill(v0Vtx.x(), v0Vtx.y());
-                triRadZY.fill(v0Vtx.y(), v0Vtx.z());
+//                triRadXY.fill(v0Vtx.x(), v0Vtx.y());
+//                triRadZY.fill(v0Vtx.y(), v0Vtx.z());
             }
         }
 
         if (!vertCandidateList.isEmpty()) {
             // pick the best candidate...for now just pick a random one. 
             ReconstructedParticle bestCandidate = vertCandidateList.get((int) (Math.random() * vertCandidateList.size()));
+            Vertex unconVertex = bestCandidate.getStartVertex();
 
             //fill some stuff: 
             ReconstructedParticle electron = bestCandidate.getParticles().get(ReconParticleDriver.ELECTRON);
@@ -711,10 +974,10 @@
             Hep3Vector pBestV0Rot = VecOp.mult(beamAxisRotation, bestCandidate.getMomentum());
             Hep3Vector pEleRot = VecOp.mult(beamAxisRotation, electron.getMomentum());
             Hep3Vector pPosRot = VecOp.mult(beamAxisRotation, positron.getMomentum());
-            Hep3Vector v0Vtx = VecOp.mult(beamAxisRotation, bestCandidate.getStartVertex().getPosition());
-
-            vertTrackTime2D.fill(tEle, tPos);
-            vertTrackTimeDiff.fill(tEle - tPos);
+            Hep3Vector v0Vtx = VecOp.mult(beamAxisRotation, unconVertex.getPosition());
+
+//            vertTrackTime2D.fill(tEle, tPos);
+//            vertTrackTimeDiff.fill(tEle - tPos);
             vertZVsMomentum.fill(bestCandidate.getMomentum().magnitude(), v0Vtx.z());
             vertMassMomentum.fill(bestCandidate.getMomentum().magnitude(), bestCandidate.getMass());
             vertTrackMomentum2D.fill(electron.getMomentum().magnitude(), positron.getMomentum().magnitude());
@@ -723,20 +986,34 @@
             vertSumP.fill(bestCandidate.getMomentum().magnitude());
             vertDeltaP.fill(positron.getMomentum().magnitude() - electron.getMomentum().magnitude());
 
-            vertPxPy.fill(pBestV0Rot.x(), pBestV0Rot.y());
+//            vertPxPy.fill(pBestV0Rot.x(), pBestV0Rot.y());
             vertMass.fill(bestCandidate.getMass());
             vertZVsMass.fill(bestCandidate.getMass(), v0Vtx.z());
-            vertX.fill(v0Vtx.x());
+//            vertX.fill(v0Vtx.x());
             vertY.fill(v0Vtx.y());
-            vertZ.fill(v0Vtx.z());
-            vertPx.fill(pBestV0Rot.x());
-            vertPy.fill(pBestV0Rot.y());
-            vertPz.fill(pBestV0Rot.z());
-            vertU.fill(pBestV0Rot.x() / pBestV0Rot.magnitude());
-            vertV.fill(pBestV0Rot.y() / pBestV0Rot.magnitude());
+//            vertZ.fill(v0Vtx.z());
+//            vertPx.fill(pBestV0Rot.x());
+//            vertPy.fill(pBestV0Rot.y());
+//            vertPz.fill(pBestV0Rot.z());
+//            vertU.fill(pBestV0Rot.x() / pBestV0Rot.magnitude());
+//            vertV.fill(pBestV0Rot.y() / pBestV0Rot.magnitude());
             vertXY.fill(v0Vtx.x(), v0Vtx.y());
             vertZY.fill(v0Vtx.y(), v0Vtx.z());
-            if (bestCandidate.getMomentum().magnitude() > radCut) {
+            if (bestCandidate.getMomentum().magnitude() > radCut * ebeam) {
+
+                BilliorVertexer vtxFitter = new BilliorVertexer(TrackUtils.getBField(event.getDetector()).y());
+                vtxFitter.setBeamSize(beamSize);
+                vtxFitter.setBeamPosition(beamPos);
+//                vtxFitter.setDebug(false);
+                List<BilliorTrack> billiorTracks = new ArrayList<BilliorTrack>();
+                billiorTracks.add(new BilliorTrack(electron.getTracks().get(0)));
+                billiorTracks.add(new BilliorTrack(positron.getTracks().get(0)));
+                vtxFitter.doBeamSpotConstraint(true);
+                BilliorVertex bsconVertex = vtxFitter.fitVertex(billiorTracks);
+                vtxFitter.doTargetConstraint(true);
+                BilliorVertex tarconVertex = vtxFitter.fitVertex(billiorTracks);
+                vertRadUnconBsconChi2.fill(unconVertex.getChi2(), bsconVertex.getChi2());
+
                 vertRadTrackTime2D.fill(tEle, tPos);
                 vertRadTrackTimeDiff.fill(tEle - tPos);
                 vertRadZVsMomentum.fill(bestCandidate.getMomentum().magnitude(), v0Vtx.z());

Modified: java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/dataquality/V0Monitoring.java
 =============================================================================
--- java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/dataquality/V0Monitoring.java	(original)
+++ java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/dataquality/V0Monitoring.java	Wed Apr 27 11:11:32 2016
@@ -8,8 +8,8 @@
 import hep.aida.IHistogram2D;
 import hep.aida.IPlotter;
 import hep.aida.IPlotterStyle;
+import hep.physics.vec.BasicHep3Matrix;
 import hep.physics.vec.Hep3Vector;
-import hep.physics.vec.BasicHep3Matrix;
 import hep.physics.vec.VecOp;
 
 import java.io.IOException;
@@ -19,6 +19,7 @@
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
+import org.hps.conditions.beam.BeamEnergy.BeamEnergyCollection;
 import org.hps.recon.tracking.TrackType;
 import org.hps.recon.tracking.TrackUtils;
 import org.hps.recon.vertexing.BilliorTrack;
@@ -33,252 +34,493 @@
 import org.lcsim.recon.tracking.seedtracker.SeedTrack;
 
 /**
- * DQM driver V0 particles (i.e. e+e- pars) plots things like number of vertex
- * position an mass
+ * DQM driver V0 particles (i.e. e+e- pars) plots things like number of vertex position an mass
  *
  * @author mgraham on May 14, 2014
- *
  */
 public class V0Monitoring extends DataQualityMonitor {
 
     private static Logger LOGGER = Logger.getLogger(V0Monitoring.class.getPackage().getName());
-    
-    String finalStateParticlesColName = "FinalStateParticles";
-    String unconstrainedV0CandidatesColName = "UnconstrainedV0Candidates";
-    String beamConV0CandidatesColName = "BeamspotConstrainedV0Candidates";
-    String targetV0ConCandidatesColName = "TargetConstrainedV0Candidates";
-    String[] fpQuantNames = {"nV0_per_Event", "avg_BSCon_mass", "avg_BSCon_Vx", "avg_BSCon_Vy", "avg_BSCon_Vz", "sig_BSCon_Vx", "sig_BSCon_Vy", "sig_BSCon_Vz", "avg_BSCon_Chi2"};
-    //some counters
-    int nRecoEvents = 0;
-    int nTotV0 = 0;
-    int nTot2Ele = 0;
-    //some summers
-    double sumMass = 0.0;
-    double sumVx = 0.0;
-    double sumVy = 0.0;
-    double sumVz = 0.0;
-    double sumChi2 = 0.0;
-
-    /*  V0 Quantities   */
-    /*  Mass, vertex, chi^2 of fit */
-    /*  unconstrained */
-    IHistogram1D unconMass;
-    IHistogram1D unconVx;
-    IHistogram1D unconVy;
-    IHistogram1D unconVz;
-    IHistogram1D unconChi2;
-    IHistogram2D unconVzVsChi2;
-    IHistogram2D unconChi2VsTrkChi2;
+
+    private static boolean hasSharedStrips(final ReconstructedParticle fs1, final ReconstructedParticle fs2,
+            final RelationalTable hittostrip, final RelationalTable hittorotated) {
+        return TrackUtils.hasSharedStrips(fs1.getTracks().get(0), fs2.getTracks().get(0), hittostrip, hittorotated);
+    }
+
+    private final BasicHep3Matrix beamAxisRotation = new BasicHep3Matrix();
+    private final String beamConV0CandidatesColName = "BeamspotConstrainedV0Candidates";
+    private IHistogram1D bsconChi2;
+    private IHistogram2D bsconChi2VsTrkChi2;
+    private IHistogram1D bsconMass;
+    private IHistogram1D bsconVx;
+    private IHistogram1D bsconVy;
+    private IHistogram1D bsconVz;
+    private IHistogram2D bsconVzVsChi2;
+    private final String finalStateParticlesColName = "FinalStateParticles";
+    private final String[] fpQuantNames = {"nV0_per_Event", "avg_BSCon_mass", "avg_BSCon_Vx", "avg_BSCon_Vy",
+            "avg_BSCon_Vz", "sig_BSCon_Vx", "sig_BSCon_Vy", "sig_BSCon_Vz", "avg_BSCon_Chi2"};
+
+    private final double maxFactor = 1.25;
+    private IHistogram1D mollerHiP, mollerLoP, mollerEitherP, mollerPsum;
+    private IHistogram1D mollerMass;
+    private IHistogram1D mollerMassVtxCut;
+    private IHistogram1D mollerUx;
+    private IHistogram1D mollerUy;
+    private IHistogram1D mollerVx;
+
+    private IHistogram1D mollerVy;
+
+    private IHistogram1D mollerVz;
+    private IHistogram1D mollerVzVtxCut;
+    private IHistogram2D mollerXVsVtxY;
+    private IHistogram2D mollerXVsVtxZ;
+
+    private IHistogram2D mollerYVsVtxZ;
+    // some counters
+    private int nRecoEvents = 0;
+    private int nTotV0 = 0;
+    private IHistogram1D numChargeHisto;
+    private IHistogram1D nV0;
+    private IHistogram1D pEle;
+    private IHistogram2D pEleVspEle;
+    private IHistogram2D pEleVspEleBeamBeam;
+    private IHistogram2D pEleVspEleMoller;
+    private IHistogram2D pEleVspEleNoBeam;
+    private IHistogram2D pEleVspPos;
+    private IHistogram2D pEleVspPosWithCut;
+    private IHistogram2D pEleVsthetaBeamBeam;
+    private IHistogram2D pEleVsthetaMoller;
+
+    private IHistogram2D phiEleVsphiEle;
+    private final String plotDir = "V0Monitoring/";
+    private IHistogram1D pPos;
+
+    private IHistogram2D pxEleVspxEle;
+    private IHistogram2D pxEleVspxEleNoBeam;
+    private IHistogram2D pxEleVspxPos;
+
+    private IHistogram2D pyEleVspyEle;
+    private IHistogram2D pyEleVspyEleNoBeam;
+    private IHistogram2D pyEleVspyPos;
+    private IHistogram1D sumChargeHisto;
+    private double sumChi2 = 0.0;
+    // some summers
+    private double sumMass = 0.0;
+    private double sumVx = 0.0;
+    private double sumVy = 0.0;
+    private double sumVz = 0.0;
+
+    private IHistogram1D tarconChi2;
+    private IHistogram2D tarconChi2VsTrkChi2;
+
+    /* target constrained */
+    private IHistogram1D tarconMass;
+    private IHistogram1D tarconVx;
+    private IHistogram1D tarconVy;
+    private IHistogram1D tarconVz;
+    private IHistogram2D tarconVzVsChi2;
+    private final String targetV0ConCandidatesColName = "TargetConstrainedV0Candidates";
+    private IHistogram2D thetaEleVsthetaBeamBeam;
+    private IHistogram2D thetaEleVsthetaMoller;
+    private final double thetaMax = 0.06;
+    private final double thetaMin = 0.015;
+    private IHistogram1D trigTime;
+    private IHistogram2D trigTimeV0Time;
+    private IHistogram1D unconChi2;
+
+    private IHistogram2D unconChi2VsTrkChi2;
     /* beamspot constrained */
-
-    IHistogram1D nV0;
-
-    IHistogram1D v0Time;
-    IHistogram1D v0Dt;
-    IHistogram2D trigTimeV0Time;
-    IHistogram1D trigTime;
-
-    IHistogram1D bsconMass;
-    IHistogram1D bsconVx;
-    IHistogram1D bsconVy;
-    IHistogram1D bsconVz;
-    IHistogram1D bsconChi2;
-    IHistogram2D bsconVzVsChi2;
-    IHistogram2D bsconChi2VsTrkChi2;
-    /* target constrained */
-    IHistogram1D tarconMass;
-    IHistogram1D tarconVx;
-    IHistogram1D tarconVy;
-    IHistogram1D tarconVz;
-    IHistogram1D tarconChi2;
-    IHistogram2D tarconVzVsChi2;
-    IHistogram2D tarconChi2VsTrkChi2;
-
-    IHistogram2D pEleVspPos;
-    IHistogram2D pEleVspPosWithCut;
-    IHistogram2D pyEleVspyPos;
-    IHistogram2D pxEleVspxPos;
-
-    IHistogram2D VtxZVsMass;
-    IHistogram2D VtxYVsVtxZ;
-    IHistogram2D VtxXVsVtxZ;
-    IHistogram2D VtxXVsVtxY;
-    IHistogram2D VtxXVsVtxPx;
-    IHistogram2D VtxYVsVtxPy;
-    IHistogram2D VtxZVsVtxPx;
-    IHistogram2D VtxZVsVtxPy;
-    IHistogram2D VtxZVsVtxPz;
-
-    IHistogram2D VtxZVsL1Iso;
-    IHistogram2D VtxZVsTrkChi2;
-
-    IHistogram2D pEleVspEle;
-    IHistogram2D phiEleVsphiEle;
-    IHistogram2D pyEleVspyEle;
-    IHistogram2D pxEleVspxEle;
-    IHistogram2D pEleVspEleNoBeam;
-    IHistogram2D pyEleVspyEleNoBeam;
-    IHistogram2D pxEleVspxEleNoBeam;
-    IHistogram2D pEleVspEleMoller;
-    IHistogram2D pEleVsthetaMoller;
-    IHistogram2D thetaEleVsthetaMoller;
-    IHistogram2D pEleVspEleBeamBeam;
-    IHistogram2D pEleVsthetaBeamBeam;
-    IHistogram2D thetaEleVsthetaBeamBeam;
-
-    IHistogram1D mollerMass;
-    IHistogram1D mollerMassVtxCut;
-    IHistogram1D mollerVx;
-    IHistogram1D mollerVy;
-    IHistogram1D mollerVz;
-    IHistogram1D mollerVzVtxCut;
-    IHistogram2D mollerXVsVtxZ;
-    IHistogram2D mollerYVsVtxZ;
-    IHistogram2D mollerXVsVtxY;
-
-    IHistogram1D sumChargeHisto;
-    IHistogram1D numChargeHisto;
-
-    private final String plotDir = "V0Monitoring/";
-
-    double beamEnergy = 1.05; //GeV
-    private final BasicHep3Matrix beamAxisRotation = new BasicHep3Matrix();
-
-    double maxFactor = 1.25;
-    double feeMomentumCut = 0.8; //GeV
-
-    double v0ESumMinCut = 0.8 * beamEnergy;
-    double v0ESumMaxCut = 1.25 * beamEnergy;
-    double v0MaxPCut = 1.1;//GeV
-    double molPSumMin = 0.85;
-    double molPSumMax = 1.3;
-    double beambeamCut = 0.85;
-    double thetaMax = 0.06;
-    double thetaMin = 0.015;
-
+    /* V0 Quantities */
+    /* Mass, vertex, chi^2 of fit */
+    /* unconstrained */
+    private IHistogram1D unconMass;
+    private final String unconstrainedV0CandidatesColName = "UnconstrainedV0Candidates";
+    private IHistogram1D unconVx;
+    private IHistogram1D unconVy;
+    private IHistogram1D unconVz;
+    private IHistogram2D unconVzVsChi2;
+    private IHistogram1D v0Dt;
+    private double v0ESumMinCut, v0MaxPCut, v0ESumMaxCut, molPSumMin, molPSumMax, beambeamCut;
+
+    private IHistogram1D v0Time;
+    private IHistogram2D VtxXVsVtxPx;
+
+    private IHistogram2D VtxXVsVtxY;
+    private IHistogram2D VtxXVsVtxZ;
+
+    private IHistogram2D VtxYVsVtxPy;
+
+    private IHistogram2D VtxYVsVtxZ;
+
+    private IHistogram2D VtxZVsL1Iso;
+
+    private IHistogram2D VtxZVsMass;
+    private IHistogram2D VtxZVsTrkChi2;
+
+    private IHistogram2D VtxZVsVtxPx;
+
+    private IHistogram2D VtxZVsVtxPy;
+
+    private IHistogram2D VtxZVsVtxPz;
+
+    /**
+     * Calculate the averages here and fill the map
+     */
     @Override
-    protected void detectorChanged(Detector detector) {
+    public void calculateEndOfRunQuantities() {
+
+        final IAnalysisFactory analysisFactory = IAnalysisFactory.create();
+        final IFitFactory fitFactory = analysisFactory.createFitFactory();
+        final IFitter fitter = fitFactory.createFitter("chi2");
+        final double[] init = {50.0, 0.0, 0.2, 1.0, 0.0};
+        final IFitResult resVx = this.fitVertexPosition(bsconVx, fitter, init, "range=\"(-0.5,0.5)\"");
+        final double[] init2 = {50.0, 0.0, 0.04, 1.0, 0.0};
+        final IFitResult resVy = this.fitVertexPosition(bsconVy, fitter, init2, "range=\"(-0.2,0.2)\"");
+        final double[] init3 = {50.0, 0.0, 3.0, 1.0, 0.0};
+        final IFitResult resVz = this.fitVertexPosition(bsconVz, fitter, init3, "range=\"(-6,6)\"");
+
+        if (resVx != null && resVy != null & resVz != null) {
+            final double[] parsVx = resVx.fittedParameters();
+            final double[] parsVy = resVy.fittedParameters();
+            final double[] parsVz = resVz.fittedParameters();
+
+            for (int i = 0; i < 5; i++) {
+                LOGGER.info("Vertex Fit Parameters:  " + resVx.fittedParameterNames()[i] + " = " + parsVx[i] + "; "
+                        + parsVy[i] + "; " + parsVz[i]);
+            }
+
+            final IPlotter plotter = analysisFactory.createPlotterFactory().create("Vertex Position");
+            plotter.createRegions(1, 3);
+            final IPlotterStyle pstyle = plotter.style();
+            pstyle.legendBoxStyle().setVisible(false);
+            pstyle.dataStyle().fillStyle().setColor("green");
+            pstyle.dataStyle().lineStyle().setColor("black");
+            plotter.region(0).plot(bsconVx);
+            plotter.region(0).plot(resVx.fittedFunction());
+            plotter.region(1).plot(bsconVy);
+            plotter.region(1).plot(resVy.fittedFunction());
+            plotter.region(2).plot(bsconVz);
+            plotter.region(2).plot(resVz.fittedFunction());
+            if (outputPlots) {
+                try {
+                    plotter.writeToFile(outputPlotDir + "vertex.png");
+                } catch (final IOException ex) {
+                    Logger.getLogger(V0Monitoring.class.getName()).log(Level.SEVERE, null, ex);
+                }
+            }
+
+            // monitoredQuantityMap.put(fpQuantNames[2], sumVx / nTotV0);
+            // monitoredQuantityMap.put(fpQuantNames[3], sumVy / nTotV0);
+            // monitoredQuantityMap.put(fpQuantNames[4], sumVz / nTotV0);
+            monitoredQuantityMap.put(beamConV0CandidatesColName + " " + triggerType + " " + fpQuantNames[2], parsVx[1]);
+            monitoredQuantityMap.put(beamConV0CandidatesColName + " " + triggerType + " " + fpQuantNames[3], parsVy[1]);
+            monitoredQuantityMap.put(beamConV0CandidatesColName + " " + triggerType + " " + fpQuantNames[4], parsVz[1]);
+            monitoredQuantityMap.put(beamConV0CandidatesColName + " " + triggerType + " " + fpQuantNames[5], parsVx[2]);
+            monitoredQuantityMap.put(beamConV0CandidatesColName + " " + triggerType + " " + fpQuantNames[6], parsVy[2]);
+            monitoredQuantityMap.put(beamConV0CandidatesColName + " " + triggerType + " " + fpQuantNames[7], parsVz[2]);
+        }
+        monitoredQuantityMap.put(beamConV0CandidatesColName + " " + triggerType + " " + fpQuantNames[0],
+                (double) nTotV0 / nRecoEvents);
+        monitoredQuantityMap.put(beamConV0CandidatesColName + " " + triggerType + " " + fpQuantNames[1], sumMass
+                / nTotV0);
+        monitoredQuantityMap.put(beamConV0CandidatesColName + " " + triggerType + " " + fpQuantNames[8], sumChi2
+                / nTotV0);
+
+    }
+
+    @Override
+    protected void detectorChanged(final Detector detector) {
+
+        final BeamEnergyCollection beamEnergyCollection = this.getConditionsManager()
+                .getCachedConditions(BeamEnergyCollection.class, "beam_energies").getCachedData();
+        final double beamEnergy = beamEnergyCollection.get(0).getBeamEnergy();
+        v0ESumMinCut = 0.8 * beamEnergy;
+        v0ESumMaxCut = 1.25 * beamEnergy;
+
+        v0MaxPCut = 1.05 * beamEnergy;// GeV
+        molPSumMin = 0.80 * beamEnergy;
+        molPSumMax = 1.25 * beamEnergy;
+        beambeamCut = 0.80 * beamEnergy;
+
         beamAxisRotation.setActiveEuler(Math.PI / 2, -0.0305, -Math.PI / 2);
 
-        LOGGER.info("Setting up the plotter");
+        // LOGGER.info("Setting up the plotter");
         aida.tree().cd("/");
-        String xtra = "Extras";
+        final String xtra = "Extras";
         String trkType = "SeedTrack/";
-        if (isGBL)
+        if (isGBL) {
             trkType = "GBLTrack/";
-        /*  V0 Quantities   */
-        /*  Mass, vertex, chi^2 of fit */
-        /*  unconstrained */
-        unconMass = aida.histogram1D(plotDir + trkType + triggerType + "/" + unconstrainedV0CandidatesColName + "/" + "Invariant Mass (GeV)", 100, 0, 0.200);
-        unconVx = aida.histogram1D(plotDir + trkType + triggerType + "/" + unconstrainedV0CandidatesColName + "/" + "Vx (mm)", 50, -10, 10);
-        unconVy = aida.histogram1D(plotDir + trkType + triggerType + "/" + unconstrainedV0CandidatesColName + "/" + "Vy (mm)", 50, -10, 10);
-        unconVz = aida.histogram1D(plotDir + trkType + triggerType + "/" + unconstrainedV0CandidatesColName + "/" + "Vz (mm)", 50, -50, 50);
-        unconChi2 = aida.histogram1D(plotDir + trkType + triggerType + "/" + unconstrainedV0CandidatesColName + "/" + "Chi2", 25, 0, 25);
-        unconVzVsChi2 = aida.histogram2D(plotDir + trkType + triggerType + "/" + unconstrainedV0CandidatesColName + "/" + "Vz vs. Chi2", 25, 0, 25, 50, -50, 50);
-        unconChi2VsTrkChi2 = aida.histogram2D(plotDir + trkType + triggerType + "/" + unconstrainedV0CandidatesColName + "/" + "Chi2 vs. total track chi2", 50, 0, 50, 50, 0, 25);
+        }
+
+        final double maxMass = .2 * beamEnergy;
+        final double maxMassMoller = .1 * Math.sqrt(beamEnergy);
+        /* V0 Quantities */
+        /* Mass, vertex, chi^2 of fit */
+        /* unconstrained */
+        unconMass = aida.histogram1D(plotDir + trkType + triggerType + "/" + unconstrainedV0CandidatesColName + "/"
+                + "Invariant Mass (GeV)", 100, 0, maxMass);
+        unconVx = aida.histogram1D(plotDir + trkType + triggerType + "/" + unconstrainedV0CandidatesColName + "/"
+                + "Vx (mm)", 50, -10, 10);
+        unconVy = aida.histogram1D(plotDir + trkType + triggerType + "/" + unconstrainedV0CandidatesColName + "/"
+                + "Vy (mm)", 50, -10, 10);
+        unconVz = aida.histogram1D(plotDir + trkType + triggerType + "/" + unconstrainedV0CandidatesColName + "/"
+                + "Vz (mm)", 50, -50, 50);
+        unconChi2 = aida.histogram1D(plotDir + trkType + triggerType + "/" + unconstrainedV0CandidatesColName + "/"
+                + "Chi2", 25, 0, 25);
+        unconVzVsChi2 = aida.histogram2D(plotDir + trkType + triggerType + "/" + unconstrainedV0CandidatesColName + "/"
+                + "Vz vs. Chi2", 25, 0, 25, 50, -50, 50);
+        unconChi2VsTrkChi2 = aida.histogram2D(plotDir + trkType + triggerType + "/" + unconstrainedV0CandidatesColName
+                + "/" + "Chi2 vs. total track chi2", 50, 0, 50, 50, 0, 25);
         /* beamspot constrained */
-        bsconMass = aida.histogram1D(plotDir + trkType + triggerType + "/" + beamConV0CandidatesColName + "/" + "Mass (GeV)", 100, 0, 0.200);
-        bsconVx = aida.histogram1D(plotDir + trkType + triggerType + "/" + beamConV0CandidatesColName + "/" + "Vx (mm)", 50, -10, 10);
-        bsconVy = aida.histogram1D(plotDir + trkType + triggerType + "/" + beamConV0CandidatesColName + "/" + "Vy (mm)", 50, -10, 10);
-        bsconVz = aida.histogram1D(plotDir + trkType + triggerType + "/" + beamConV0CandidatesColName + "/" + "Vz (mm)", 50, -50, 50);
-        bsconChi2 = aida.histogram1D(plotDir + trkType + triggerType + "/" + beamConV0CandidatesColName + "/" + "Chi2", 25, 0, 25);
-        bsconVzVsChi2 = aida.histogram2D(plotDir + trkType + triggerType + "/" + beamConV0CandidatesColName + "/" + "Vz vs. Chi2", 25, 0, 25, 50, -50, 50);
-        bsconChi2VsTrkChi2 = aida.histogram2D(plotDir + trkType + triggerType + "/" + beamConV0CandidatesColName + "/" + "Chi2 vs. total track chi2", 50, 0, 50, 50, 0, 25);
+        bsconMass = aida.histogram1D(plotDir + trkType + triggerType + "/" + beamConV0CandidatesColName + "/"
+                + "Mass (GeV)", 100, 0, maxMass);
+        bsconVx = aida.histogram1D(
+                plotDir + trkType + triggerType + "/" + beamConV0CandidatesColName + "/" + "Vx (mm)", 50, -10, 10);
+        bsconVy = aida.histogram1D(
+                plotDir + trkType + triggerType + "/" + beamConV0CandidatesColName + "/" + "Vy (mm)", 50, -10, 10);
+        bsconVz = aida.histogram1D(
+                plotDir + trkType + triggerType + "/" + beamConV0CandidatesColName + "/" + "Vz (mm)", 50, -50, 50);
+        bsconChi2 = aida.histogram1D(plotDir + trkType + triggerType + "/" + beamConV0CandidatesColName + "/" + "Chi2",
+                25, 0, 25);
+        bsconVzVsChi2 = aida.histogram2D(plotDir + trkType + triggerType + "/" + beamConV0CandidatesColName + "/"
+                + "Vz vs. Chi2", 25, 0, 25, 50, -50, 50);
+        bsconChi2VsTrkChi2 = aida.histogram2D(plotDir + trkType + triggerType + "/" + beamConV0CandidatesColName + "/"
+                + "Chi2 vs. total track chi2", 50, 0, 50, 50, 0, 25);
         /* target constrained */
-        tarconMass = aida.histogram1D(plotDir + trkType + triggerType + "/" + targetV0ConCandidatesColName + "/" + "Mass (GeV)", 100, 0, 0.200);
-        tarconVx = aida.histogram1D(plotDir + trkType + triggerType + "/" + targetV0ConCandidatesColName + "/" + "Vx (mm)", 50, -1, 1);
-        tarconVy = aida.histogram1D(plotDir + trkType + triggerType + "/" + targetV0ConCandidatesColName + "/" + "Vy (mm)", 50, -1, 1);
-        tarconVz = aida.histogram1D(plotDir + trkType + triggerType + "/" + targetV0ConCandidatesColName + "/" + "Vz (mm)", 50, -10, 10);
-        tarconChi2 = aida.histogram1D(plotDir + trkType + triggerType + "/" + targetV0ConCandidatesColName + "/" + "Chi2", 25, 0, 25);
-        tarconVzVsChi2 = aida.histogram2D(plotDir + trkType + triggerType + "/" + targetV0ConCandidatesColName + "/" + "Vz vs. Chi2", 25, 0, 25, 50, -50, 50);
-        tarconChi2VsTrkChi2 = aida.histogram2D(plotDir + trkType + triggerType + "/" + targetV0ConCandidatesColName + "/" + "Chi2 vs. total track chi2", 50, 0, 50, 50, 0, 25);
-
-        nV0 = aida.histogram1D(plotDir + trkType + triggerType + "/" + xtra + "/" + "Number of V0 per event", 10, 0, 10);
+        tarconMass = aida.histogram1D(plotDir + trkType + triggerType + "/" + targetV0ConCandidatesColName + "/"
+                + "Mass (GeV)", 100, 0, maxMass);
+        tarconVx = aida.histogram1D(plotDir + trkType + triggerType + "/" + targetV0ConCandidatesColName + "/"
+                + "Vx (mm)", 50, -1, 1);
+        tarconVy = aida.histogram1D(plotDir + trkType + triggerType + "/" + targetV0ConCandidatesColName + "/"
+                + "Vy (mm)", 50, -1, 1);
+        tarconVz = aida.histogram1D(plotDir + trkType + triggerType + "/" + targetV0ConCandidatesColName + "/"
+                + "Vz (mm)", 50, -10, 10);
+        tarconChi2 = aida.histogram1D(plotDir + trkType + triggerType + "/" + targetV0ConCandidatesColName + "/"
+                + "Chi2", 25, 0, 25);
+        tarconVzVsChi2 = aida.histogram2D(plotDir + trkType + triggerType + "/" + targetV0ConCandidatesColName + "/"
+                + "Vz vs. Chi2", 25, 0, 25, 50, -50, 50);
+        tarconChi2VsTrkChi2 = aida.histogram2D(plotDir + trkType + triggerType + "/" + targetV0ConCandidatesColName
+                + "/" + "Chi2 vs. total track chi2", 50, 0, 50, 50, 0, 25);
+
+        nV0 = aida
+                .histogram1D(plotDir + trkType + triggerType + "/" + xtra + "/" + "Number of V0 per event", 10, 0, 10);
         v0Time = aida.histogram1D(plotDir + trkType + triggerType + "/" + xtra + "/" + "V0 mean time", 100, -25, 25);
-        v0Dt = aida.histogram1D(plotDir + trkType + triggerType + "/" + xtra + "/" + "V0 time difference", 100, -25, 25);
-        trigTimeV0Time = aida.histogram2D(plotDir + trkType + triggerType + "/" + xtra + "/" + "Trigger phase vs. V0 mean time", 100, -25, 25, 6, 0, 24);
+        v0Dt = aida
+                .histogram1D(plotDir + trkType + triggerType + "/" + xtra + "/" + "V0 time difference", 100, -25, 25);
+        trigTimeV0Time = aida.histogram2D(plotDir + trkType + triggerType + "/" + xtra + "/"
+                + "Trigger phase vs. V0 mean time", 100, -25, 25, 6, 0, 24);
         trigTime = aida.histogram1D(plotDir + trkType + triggerType + "/" + xtra + "/" + "Trigger phase", 6, 0, 24);
 
-        pEleVspPos = aida.histogram2D(plotDir + trkType + triggerType + "/" + xtra + "/" + "P(e) vs P(p)", 50, 0, beamEnergy * maxFactor, 50, 0, beamEnergy * maxFactor);
-        pEleVspPosWithCut = aida.histogram2D(plotDir + trkType + triggerType + "/" + xtra + "/" + "P(e) vs P(p): Radiative", 50, 0, beamEnergy * maxFactor, 50, 0, beamEnergy * maxFactor);
-        pyEleVspyPos = aida.histogram2D(plotDir + trkType + triggerType + "/" + xtra + "/" + "Py(e) vs Py(p)", 50, -0.04, 0.04, 50, -0.04, 0.04);
-        pxEleVspxPos = aida.histogram2D(plotDir + trkType + triggerType + "/" + xtra + "/" + "Px(e) vs Px(p)", 50, -0.04, 0.04, 50, -0.04, 0.04);
-        VtxZVsMass = aida.histogram2D(plotDir + trkType + triggerType + "/" + xtra + "/" + "Vz vs Mass", 50, 0, 0.15, 50, -50, 80);
-        VtxXVsVtxZ = aida.histogram2D(plotDir + trkType + triggerType + "/" + xtra + "/" + "Vx vs Vz", 100, -10, 10, 100, -50, 80);
-        VtxYVsVtxZ = aida.histogram2D(plotDir + trkType + triggerType + "/" + xtra + "/" + "Vy vs Vz", 100, -5, 5, 100, -50, 80);
-        VtxXVsVtxY = aida.histogram2D(plotDir + trkType + triggerType + "/" + xtra + "/" + "Vx vs Vy", 100, -10, 10, 100, -5, 5);
-        VtxXVsVtxPx = aida.histogram2D(plotDir + trkType + triggerType + "/" + xtra + "/" + "Vx vs Px", 100, -0.1, 0.1, 100, -10, 10);
-        VtxYVsVtxPy = aida.histogram2D(plotDir + trkType + triggerType + "/" + xtra + "/" + "Vy vs Py", 100, -0.1, 0.1, 100, -5, 5);
-        VtxZVsVtxPx = aida.histogram2D(plotDir + trkType + triggerType + "/" + xtra + "/" + "Vz vs Px", 100, -0.1, 0.1, 100, -50, 80);
-        VtxZVsVtxPy = aida.histogram2D(plotDir + trkType + triggerType + "/" + xtra + "/" + "Vz vs Py", 100, -0.1, 0.1, 100, -50, 80);
-        VtxZVsVtxPz = aida.histogram2D(plotDir + trkType + triggerType + "/" + xtra + "/" + "Vz vs Pz", 100, 0.0, beamEnergy * maxFactor, 100, -50, 80);
-        VtxZVsL1Iso = aida.histogram2D(plotDir + trkType + triggerType + "/" + xtra + "/" + "Vz vs L1 Isolation", 100, 0.0, 5.0, 50, -50, 80);
-        VtxZVsTrkChi2 = aida.histogram2D(plotDir + trkType + triggerType + "/" + xtra + "/" + "Vz vs Track Chi2", 50, 0, 50, 50, -50, 80);
-        pEleVspEle = aida.histogram2D(plotDir + trkType + triggerType + "/" + xtra + "/" + "2 Electron/P(e) vs P(e)", 50, 0, beamEnergy * maxFactor, 50, 0, beamEnergy * maxFactor);
-        phiEleVsphiEle = aida.histogram2D(plotDir + trkType + triggerType + "/" + xtra + "/" + "2 Electron/phi(e) vs phi(e)", 50, -Math.PI, Math.PI, 50, -Math.PI, Math.PI);
-        pyEleVspyEle = aida.histogram2D(plotDir + trkType + triggerType + "/" + xtra + "/" + "2 Electron/Py(e) vs Py(e)", 50, -0.04, 0.04, 50, -0.04, 0.04);
-        pxEleVspxEle = aida.histogram2D(plotDir + trkType + triggerType + "/" + xtra + "/" + "2 Electron/Px(e) vs Px(e)", 50, -0.02, 0.06, 50, -0.02, 0.06);
-        pEleVspEleNoBeam = aida.histogram2D(plotDir + trkType + triggerType + "/" + xtra + "/" + "2 Electron/P(e) vs P(e) NoBeam", 50, 0, beambeamCut, 50, 0, beambeamCut);
-        pEleVspEleMoller = aida.histogram2D(plotDir + trkType + triggerType + "/" + xtra + "/" + "2 Electron/P(e) vs P(e) Moller", 50, 0, beambeamCut, 50, 0, beambeamCut);
-        pEleVspEleBeamBeam = aida.histogram2D(plotDir + trkType + triggerType + "/" + xtra + "/" + "2 Electron/P(e) vs P(e) BeamBeam", 50, beambeamCut, beamEnergy * maxFactor, 50, beambeamCut, beamEnergy * maxFactor);
-        pyEleVspyEleNoBeam = aida.histogram2D(plotDir + trkType + triggerType + "/" + xtra + "/" + "2 Electron/Py(e) vs Py(e) NoBeam", 50, -0.04, 0.04, 50, -0.04, 0.04);
-        pxEleVspxEleNoBeam = aida.histogram2D(plotDir + trkType + triggerType + "/" + xtra + "/" + "2 Electron/Px(e) vs Px(e) NoBeam", 50, -0.02, 0.06, 50, -0.02, 0.06);
-        sumChargeHisto = aida.histogram1D(plotDir + trkType + triggerType + "/" + xtra + "/" + "Total Charge of  Event", 5, -2, 3);
-        numChargeHisto = aida.histogram1D(plotDir + trkType + triggerType + "/" + xtra + "/" + "Number of Charged Particles", 6, 0, 6);
-
-        pEleVsthetaMoller = aida.histogram2D(plotDir + trkType + triggerType + "/" + xtra + "/" + "2 Electron/P(e) vs Theta Moller", 50, 0, beambeamCut, 50, thetaMin, thetaMax);
-        thetaEleVsthetaMoller = aida.histogram2D(plotDir + trkType + triggerType + "/" + xtra + "/" + "2 Electron/Theta vs Theta Moller", 50, thetaMin, thetaMax, 50, thetaMin, thetaMax);
-        pEleVsthetaBeamBeam = aida.histogram2D(plotDir + trkType + triggerType + "/" + xtra + "/" + "2 Electron/P(e) vs Theta BeamBeam", 50, beambeamCut, beamEnergy * maxFactor, 50, thetaMin, thetaMax);
-        thetaEleVsthetaBeamBeam = aida.histogram2D(plotDir + trkType + triggerType + "/" + xtra + "/" + "2 Electron/Theta vs Theta BeamBeam", 50, thetaMin, thetaMax, 50, thetaMin, thetaMax);
-
-        mollerMass = aida.histogram1D(plotDir + trkType + triggerType + "/" + xtra + "/" + "2 Electron/Moller Mass (GeV)", 100, 0, 0.100);
-        mollerMassVtxCut = aida.histogram1D(plotDir + trkType + triggerType + "/" + xtra + "/" + "2 Electron/Moller Mass (GeV): VtxCut", 100, 0, 0.100);
-        mollerVx = aida.histogram1D(plotDir + trkType + triggerType + "/" + xtra + "/" + "2 Electron/Moller Vx (mm)", 50, -10, 10);
-        mollerVy = aida.histogram1D(plotDir + trkType + triggerType + "/" + xtra + "/" + "2 Electron/Moller Vy (mm)", 50, -2, 2);
-        mollerVz = aida.histogram1D(plotDir + trkType + triggerType + "/" + xtra + "/" + "2 Electron/Moller Vz (mm)", 50, -50, 50);
-        mollerVzVtxCut = aida.histogram1D(plotDir + trkType + triggerType + "/" + xtra + "/" + "2 Electron/Moller Vz (mm): VtxCut", 50, -50, 50);
-        mollerXVsVtxZ = aida.histogram2D(plotDir + trkType + triggerType + "/" + xtra + "/" + "2 Electron/Moller Vx vs Vz", 100, -5, 5, 100, -50, 50);
-        mollerYVsVtxZ = aida.histogram2D(plotDir + trkType + triggerType + "/" + xtra + "/" + "2 Electron/Moller Vy vs Vz", 100, -2, 2, 100, -50, 50);
-        mollerXVsVtxY = aida.histogram2D(plotDir + trkType + triggerType + "/" + xtra + "/" + "2 Electron/Moller Vx vs Vy", 100, -5, 5, 100, -2, 2);
+        pEleVspPos = aida.histogram2D(plotDir + trkType + triggerType + "/" + xtra + "/" + "P(e) vs P(p)", 50, 0,
+                beamEnergy * maxFactor, 50, 0, beamEnergy * maxFactor);
+
+        pEle = aida.histogram1D(plotDir + trkType + triggerType + "/" + xtra + "/" + "P(e)", 50, 0, beamEnergy
+                * maxFactor);
+        pPos = aida.histogram1D(plotDir + trkType + triggerType + "/" + xtra + "/" + "P(p)", 50, 0, beamEnergy
+                * maxFactor);
+
+        pEleVspPosWithCut = aida.histogram2D(plotDir + trkType + triggerType + "/" + xtra + "/"
+                + "P(e) vs P(p): Radiative", 50, 0, beamEnergy * maxFactor, 50, 0, beamEnergy * maxFactor);
+        pyEleVspyPos = aida.histogram2D(plotDir + trkType + triggerType + "/" + xtra + "/" + "Py(e) vs Py(p)", 50,
+                -0.04 * beamEnergy, 0.04 * beamEnergy, 50, -0.04 * beamEnergy, 0.04 * beamEnergy);
+        pxEleVspxPos = aida.histogram2D(plotDir + trkType + triggerType + "/" + xtra + "/" + "Px(e) vs Px(p)", 50,
+                -0.04 * beamEnergy, 0.04 * beamEnergy, 50, -0.04 * beamEnergy, 0.04 * beamEnergy);
+        VtxZVsMass = aida.histogram2D(plotDir + trkType + triggerType + "/" + xtra + "/" + "Vz vs Mass", 50, 0,
+                maxMass, 50, -50, 80);
+        VtxXVsVtxZ = aida.histogram2D(plotDir + trkType + triggerType + "/" + xtra + "/" + "Vx vs Vz", 100, -10, 10,
+                100, -50, 80);
+        VtxYVsVtxZ = aida.histogram2D(plotDir + trkType + triggerType + "/" + xtra + "/" + "Vy vs Vz", 100, -5, 5, 100,
+                -50, 80);
+        VtxXVsVtxY = aida.histogram2D(plotDir + trkType + triggerType + "/" + xtra + "/" + "Vx vs Vy", 100, -10, 10,
+                100, -5, 5);
+        VtxXVsVtxPx = aida.histogram2D(plotDir + trkType + triggerType + "/" + xtra + "/" + "Vx vs Px", 100, -0.1, 0.1,
+                100, -10, 10);
+        VtxYVsVtxPy = aida.histogram2D(plotDir + trkType + triggerType + "/" + xtra + "/" + "Vy vs Py", 100, -0.1, 0.1,
+                100, -5, 5);
+        VtxZVsVtxPx = aida.histogram2D(plotDir + trkType + triggerType + "/" + xtra + "/" + "Vz vs Px", 100, -0.1, 0.1,
+                100, -50, 80);
+        VtxZVsVtxPy = aida.histogram2D(plotDir + trkType + triggerType + "/" + xtra + "/" + "Vz vs Py", 100, -0.1, 0.1,
+                100, -50, 80);
+        VtxZVsVtxPz = aida.histogram2D(plotDir + trkType + triggerType + "/" + xtra + "/" + "Vz vs Pz", 100, 0.0,
+                beamEnergy * maxFactor, 100, -50, 80);
+        VtxZVsL1Iso = aida.histogram2D(plotDir + trkType + triggerType + "/" + xtra + "/" + "Vz vs L1 Isolation", 100,
+                0.0, 5.0, 50, -50, 80);
+        VtxZVsTrkChi2 = aida.histogram2D(plotDir + trkType + triggerType + "/" + xtra + "/" + "Vz vs Track Chi2", 50,
+                0, 50, 50, -50, 80);
+        phiEleVsphiEle = aida.histogram2D(plotDir + trkType + triggerType + "/" + xtra + "/"
+                + "2 Electron/phi(e) vs phi(e)", 50, -Math.PI, Math.PI, 50, -Math.PI, Math.PI);
+        pyEleVspyEle = aida.histogram2D(plotDir + trkType + triggerType + "/" + xtra + "/"
+                + "2 Electron/Py(e) vs Py(e)", 50, -0.04 * beamEnergy, 0.04 * beamEnergy, 50, -0.04 * beamEnergy,
+                0.04 * beamEnergy);
+        pxEleVspxEle = aida.histogram2D(plotDir + trkType + triggerType + "/" + xtra + "/"
+                + "2 Electron/Px(e) vs Px(e)", 50, -0.02 * beamEnergy, 0.06 * beamEnergy, 50, -0.02 * beamEnergy,
+                0.06 * beamEnergy);
+
+        // electron vs electron momentum with different cuts
+        // 1) no cut
+        // 2) cut out FEE
+        // 3) cut out FEE and also cut on momentum sum
+        // 4) cut out everything except FEE coincidentals
+        pEleVspEle = aida.histogram2D(plotDir + trkType + triggerType + "/" + xtra + "/" + "2 Electron/P(e) vs P(e)",
+                50, 0, beamEnergy * maxFactor, 50, 0, beamEnergy * maxFactor);
+        pEleVspEleNoBeam = aida.histogram2D(plotDir + trkType + triggerType + "/" + xtra + "/"
+                + "2 Electron/P(e) vs P(e) NoBeam", 50, 0, beambeamCut, 50, 0, beambeamCut);
+        pEleVspEleMoller = aida.histogram2D(plotDir + trkType + triggerType + "/" + xtra + "/"
+                + "2 Electron/P(e) vs P(e) Moller", 50, 0, beambeamCut, 50, 0, beambeamCut);
+        pEleVspEleBeamBeam = aida.histogram2D(plotDir + trkType + triggerType + "/" + xtra + "/"
+                + "2 Electron/P(e) vs P(e) BeamBeam", 50, beambeamCut, beamEnergy * maxFactor, 50, beambeamCut,
+                beamEnergy * maxFactor);
+
+        pyEleVspyEleNoBeam = aida.histogram2D(plotDir + trkType + triggerType + "/" + xtra + "/"
+                + "2 Electron/Py(e) vs Py(e) NoBeam", 50, -0.04 * beamEnergy, 0.04 * beamEnergy, 50,
+                -0.04 * beamEnergy, 0.04 * beamEnergy);
+        pxEleVspxEleNoBeam = aida.histogram2D(plotDir + trkType + triggerType + "/" + xtra + "/"
+                + "2 Electron/Px(e) vs Px(e) NoBeam", 50, -0.02 * beamEnergy, 0.06 * beamEnergy, 50,
+                -0.02 * beamEnergy, 0.06 * beamEnergy);
+        sumChargeHisto = aida.histogram1D(
+                plotDir + trkType + triggerType + "/" + xtra + "/" + "Total Charge of  Event", 5, -2, 3);
+        numChargeHisto = aida.histogram1D(plotDir + trkType + triggerType + "/" + xtra + "/"
+                + "Number of Charged Particles", 6, 0, 6);
+
+        pEleVsthetaMoller = aida.histogram2D(plotDir + trkType + triggerType + "/" + xtra + "/"
+                + "2 Electron/P(e) vs Theta Moller", 50, 0, beambeamCut, 50, thetaMin, thetaMax);
+        thetaEleVsthetaMoller = aida.histogram2D(plotDir + trkType + triggerType + "/" + xtra + "/"
+                + "2 Electron/Theta vs Theta Moller", 50, thetaMin, thetaMax, 50, thetaMin, thetaMax);
+        pEleVsthetaBeamBeam = aida.histogram2D(plotDir + trkType + triggerType + "/" + xtra + "/"
+                + "2 Electron/P(e) vs Theta BeamBeam", 50, beambeamCut, beamEnergy * maxFactor, 50, thetaMin, thetaMax);
+        thetaEleVsthetaBeamBeam = aida.histogram2D(plotDir + trkType + triggerType + "/" + xtra + "/"
+                + "2 Electron/Theta vs Theta BeamBeam", 50, thetaMin, thetaMax, 50, thetaMin, thetaMax);
+
+        mollerMass = aida.histogram1D(plotDir + trkType + triggerType + "/" + xtra + "/"
+                + "2 Electron/Moller Mass (GeV)", 100, 0, maxMassMoller);
+        mollerMassVtxCut = aida.histogram1D(plotDir + trkType + triggerType + "/" + xtra + "/"
+                + "2 Electron/Moller Mass (GeV): VtxCut", 100, 0, maxMassMoller);
+        mollerVx = aida.histogram1D(plotDir + trkType + triggerType + "/" + xtra + "/" + "2 Electron/Moller Vx (mm)",
+                50, -10, 10);
+        mollerVy = aida.histogram1D(plotDir + trkType + triggerType + "/" + xtra + "/" + "2 Electron/Moller Vy (mm)",
+                50, -2, 2);
+        mollerVz = aida.histogram1D(plotDir + trkType + triggerType + "/" + xtra + "/" + "2 Electron/Moller Vz (mm)",
+                50, -50, 50);
+        mollerVzVtxCut = aida.histogram1D(plotDir + trkType + triggerType + "/" + xtra + "/"
+                + "2 Electron/Moller Vz (mm): VtxCut", 50, -50, 50);
+        mollerXVsVtxZ = aida.histogram2D(plotDir + trkType + triggerType + "/" + xtra + "/"
+                + "2 Electron/Moller Vx vs Vz", 100, -5, 5, 100, -50, 50);
+        mollerYVsVtxZ = aida.histogram2D(plotDir + trkType + triggerType + "/" + xtra + "/"
+                + "2 Electron/Moller Vy vs Vz", 100, -2, 2, 100, -50, 50);
+        mollerXVsVtxY = aida.histogram2D(plotDir + trkType + triggerType + "/" + xtra + "/"
+                + "2 Electron/Moller Vx vs Vy", 100, -5, 5, 100, -2, 2);
+
+        mollerUx = aida.histogram1D(plotDir + trkType + triggerType + "/" + xtra + "/"
+                + "2 Electron/Moller Pair Momentum Direction Ux", 100, .015, .045);
+        mollerUy = aida.histogram1D(plotDir + trkType + triggerType + "/" + xtra + "/"
+                + "2 Electron/Moller Pair Momentum Direction Uy", 100, -.01, .01);
+
+        mollerHiP = aida.histogram1D(plotDir + trkType + triggerType + "/" + xtra + "/" + "2 Electron/P(high)", 100, 0,
+                beamEnergy * maxFactor);
+        mollerLoP = aida.histogram1D(plotDir + trkType + triggerType + "/" + xtra + "/" + "2 Electron/P(low)", 100, 0,
+                beamEnergy * maxFactor);
+
+        mollerEitherP = aida.histogram1D(plotDir + trkType + triggerType + "/" + xtra + "/" + "2 Electron/P(either)",
+                100, 0, beamEnergy * maxFactor);
+        mollerPsum = aida.histogram1D(plotDir + trkType + triggerType + "/" + xtra + "/" + "2 Electron/Psum", 100, 0,
+                beamEnergy * maxFactor);
+
     }
 
+    private BilliorVertex fitVertex(final BilliorTrack electron, final BilliorTrack positron, final double bField) {
+        // Create a vertex fitter from the magnetic field.
+        final double[] beamSize = {0.001, 0.2, 0.02};
+        final BilliorVertexer vtxFitter = new BilliorVertexer(bField);
+        // TODO: The beam size should come from the conditions database.
+        vtxFitter.setBeamSize(beamSize);
+
+        // Perform the vertexing based on the specified constraint.
+        vtxFitter.doBeamSpotConstraint(false);
+
+        // Add the electron and positron tracks to a track list for
+        // the vertex fitter.
+        final List<BilliorTrack> billiorTracks = new ArrayList<BilliorTrack>();
+
+        billiorTracks.add(electron);
+
+        billiorTracks.add(positron);
+
+        // Find and return a vertex based on the tracks.
+        return vtxFitter.fitVertex(billiorTracks);
+    }
+
+    IFitResult fitVertexPosition(final IHistogram1D h1d, final IFitter fitter, final double[] init, final String range) {
+        IFitResult ifr = null;
+        try {
+            ifr = fitter.fit(h1d, "g+p1", init, range);
+        } catch (final RuntimeException ex) {
+            LOGGER.info(this.getClass().getSimpleName() + ":  caught exception in fitGaussian");
+        }
+        return ifr;
+    }
+
     @Override
-    public void process(EventHeader event) {
-        /*  make sure everything is there */
-        if (!event.hasCollection(ReconstructedParticle.class, finalStateParticlesColName))
+    public void printDQMData() {
+        LOGGER.info("V0Monitoring::printDQMData");
+        for (final Entry<String, Double> entry : monitoredQuantityMap.entrySet()) {
+            LOGGER.info(entry.getKey() + " = " + entry.getValue());
+        }
+        LOGGER.info("*******************************");
+    }
+
+    @Override
+    public void printDQMStrings() {
+        for (int i = 0; i < 9; i++) {
+            LOGGER.info("ALTER TABLE dqm ADD " + fpQuantNames[i] + " double;");
+        }
+    }
+
+    @Override
+    public void process(final EventHeader event) {
+        /* make sure everything is there */
+        if (!event.hasCollection(ReconstructedParticle.class, finalStateParticlesColName)) {
             return;
-        if (!event.hasCollection(ReconstructedParticle.class, unconstrainedV0CandidatesColName))
+        }
+        if (!event.hasCollection(ReconstructedParticle.class, unconstrainedV0CandidatesColName)) {
             return;
-        if (!event.hasCollection(ReconstructedParticle.class, beamConV0CandidatesColName))
+        }
+        if (!event.hasCollection(ReconstructedParticle.class, beamConV0CandidatesColName)) {
             return;
-        if (!event.hasCollection(ReconstructedParticle.class, targetV0ConCandidatesColName))
+        }
+        if (!event.hasCollection(ReconstructedParticle.class, targetV0ConCandidatesColName)) {
             return;
-
-        //check to see if this event is from the correct trigger (or "all");
-        if (!matchTrigger(event))
+        }
+
+        // check to see if this event is from the correct trigger (or "all");
+        if (!this.matchTrigger(event)) {
             return;
+        }
 
         nRecoEvents++;
 
-        RelationalTable hitToStrips = TrackUtils.getHitToStripsTable(event);
-        RelationalTable hitToRotated = TrackUtils.getHitToRotatedTable(event);
-
-        List<ReconstructedParticle> unonstrainedV0List = event.get(ReconstructedParticle.class, unconstrainedV0CandidatesColName);
-        for (ReconstructedParticle uncV0 : unonstrainedV0List) {
-            if (isGBL != TrackType.isGBL(uncV0.getType()))
+        final RelationalTable<?, ?> hitToStrips = TrackUtils.getHitToStripsTable(event);
+        final RelationalTable<?, ?> hitToRotated = TrackUtils.getHitToRotatedTable(event);
+
+        final List<ReconstructedParticle> unonstrainedV0List = event.get(ReconstructedParticle.class,
+                unconstrainedV0CandidatesColName);
+        for (final ReconstructedParticle uncV0 : unonstrainedV0List) {
+            if (isGBL != TrackType.isGBL(uncV0.getType())) {
                 continue;
-            Vertex uncVert = uncV0.getStartVertex();
-            Hep3Vector pVtxRot = VecOp.mult(beamAxisRotation, uncV0.getMomentum());
-            Hep3Vector vtxPosRot = VecOp.mult(beamAxisRotation, uncVert.getPosition());
-            double theta = Math.acos(pVtxRot.z() / pVtxRot.magnitude());
-            double phi = Math.atan2(pVtxRot.y(), pVtxRot.x());
+            }
+            final Vertex uncVert = uncV0.getStartVertex();
+            final Hep3Vector pVtxRot = VecOp.mult(beamAxisRotation, uncV0.getMomentum());
+            final Hep3Vector vtxPosRot = VecOp.mult(beamAxisRotation, uncVert.getPosition());
+            final double theta = Math.acos(pVtxRot.z() / pVtxRot.magnitude());
+            final double phi = Math.atan2(pVtxRot.y(), pVtxRot.x());
             unconVx.fill(vtxPosRot.x());
             unconVy.fill(vtxPosRot.y());
             unconVz.fill(vtxPosRot.z());
             unconMass.fill(uncV0.getMass());
             unconChi2.fill(uncVert.getChi2());
             unconVzVsChi2.fill(uncVert.getChi2(), vtxPosRot.z());
-            unconChi2VsTrkChi2.fill(Math.max(uncV0.getParticles().get(0).getTracks().get(0).getChi2(), uncV0.getParticles().get(1).getTracks().get(0).getChi2()), uncVert.getChi2());
+            unconChi2VsTrkChi2.fill(
+                    Math.max(uncV0.getParticles().get(0).getTracks().get(0).getChi2(), uncV0.getParticles().get(1)
+                            .getTracks().get(0).getChi2()), uncVert.getChi2());
 
             VtxZVsMass.fill(uncV0.getMass(), vtxPosRot.z());
             VtxXVsVtxZ.fill(vtxPosRot.x(), vtxPosRot.z());
@@ -290,76 +532,90 @@
             VtxZVsVtxPy.fill(pVtxRot.y(), vtxPosRot.z());
             VtxZVsVtxPz.fill(pVtxRot.z(), vtxPosRot.z());
 
-            //this always has 2 tracks. 
-            List<ReconstructedParticle> trks = uncV0.getParticles();
-//            Track ele = trks.get(0).getTracks().get(0);
-//            Track pos = trks.get(1).getTracks().get(0);
-//            //if track #0 has charge>0 it's the electron!  This seems mixed up, but remember the track 
-//            //charge is assigned assuming a positive B-field, while ours is negative
-//            if (trks.get(0).getCharge() > 0) {
-//                pos = trks.get(0).getTracks().get(0);
-//                ele = trks.get(1).getTracks().get(0);
-//            }
-//            aida.histogram2D(plotDir + trkType + triggerType + "/" + "P(e) vs P(p)").fill(getMomentum(ele), getMomentum(pos));
-//            aida.histogram2D(plotDir + trkType + triggerType + "/" + "Px(e) vs Px(p)").fill(ele.getTrackStates().get(0).getMomentum()[1], pos.getTrackStates().get(0).getMomentum()[1]);
-//            aida.histogram2D(plotDir + trkType + triggerType + "/" + "Py(e) vs Py(p)").fill(ele.getTrackStates().get(0).getMomentum()[2], pos.getTrackStates().get(0).getMomentum()[2]);
+            // this always has 2 tracks.
+            final List<ReconstructedParticle> trks = uncV0.getParticles();
+            // Track ele = trks.get(0).getTracks().get(0);
+            // Track pos = trks.get(1).getTracks().get(0);
+            // //if track #0 has charge>0 it's the electron! This seems mixed up, but remember the track
+            // //charge is assigned assuming a positive B-field, while ours is negative
+            // if (trks.get(0).getCharge() > 0) {
+            // pos = trks.get(0).getTracks().get(0);
+            // ele = trks.get(1).getTracks().get(0);
+            // }
+            // aida.histogram2D(plotDir + trkType + triggerType + "/" + "P(e) vs P(p)").fill(getMomentum(ele),
+            // getMomentum(pos));
+            // aida.histogram2D(plotDir + trkType + triggerType + "/" +
+            // "Px(e) vs Px(p)").fill(ele.getTrackStates().get(0).getMomentum()[1],
+            // pos.getTrackStates().get(0).getMomentum()[1]);
+            // aida.histogram2D(plotDir + trkType + triggerType + "/" +
+            // "Py(e) vs Py(p)").fill(ele.getTrackStates().get(0).getMomentum()[2],
+            // pos.getTrackStates().get(0).getMomentum()[2]);
             ReconstructedParticle ele = trks.get(0);
             ReconstructedParticle pos = trks.get(1);
-            //ReconParticles have the charge correct. 
+            // ReconParticles have the charge correct.
             if (trks.get(0).getCharge() > 0) {
                 pos = trks.get(0);
                 ele = trks.get(1);
             }
             if (ele.getCharge() < 0 && pos.getCharge() > 0) {
-                VtxZVsTrkChi2.fill(Math.max(uncV0.getParticles().get(0).getTracks().get(0).getChi2(), uncV0.getParticles().get(1).getTracks().get(0).getChi2()), uncVert.getPosition().z());
-
-                Double[] eleIso = TrackUtils.getIsolations(ele.getTracks().get(0), hitToStrips, hitToRotated);
-                Double[] posIso = TrackUtils.getIsolations(pos.getTracks().get(0), hitToStrips, hitToRotated);
+                VtxZVsTrkChi2.fill(
+                        Math.max(uncV0.getParticles().get(0).getTracks().get(0).getChi2(), uncV0.getParticles().get(1)
+                                .getTracks().get(0).getChi2()), uncVert.getPosition().z());
+
+                final Double[] eleIso = TrackUtils.getIsolations(ele.getTracks().get(0), hitToStrips, hitToRotated);
+                final Double[] posIso = TrackUtils.getIsolations(pos.getTracks().get(0), hitToStrips, hitToRotated);
                 if (eleIso[0] != null && posIso[0] != null) {
-                    double eleL1Iso = Math.min(Math.abs(eleIso[0]), Math.abs(eleIso[1]));
-                    double posL1Iso = Math.min(Math.abs(posIso[0]), Math.abs(posIso[1]));
-                    double minL1Iso = Math.min(eleL1Iso, posL1Iso);
+                    final double eleL1Iso = Math.min(Math.abs(eleIso[0]), Math.abs(eleIso[1]));
+                    final double posL1Iso = Math.min(Math.abs(posIso[0]), Math.abs(posIso[1]));
+                    final double minL1Iso = Math.min(eleL1Iso, posL1Iso);
                     VtxZVsL1Iso.fill(minL1Iso, uncVert.getPosition().z());
                 }
 
-                double pe = ele.getMomentum().magnitude();
-                double pp = pos.getMomentum().magnitude();
-                Hep3Vector pEleRot = VecOp.mult(beamAxisRotation, ele.getMomentum());
-                Hep3Vector pPosRot = VecOp.mult(beamAxisRotation, pos.getMomentum());
+                final double pe = ele.getMomentum().magnitude();
+                final double pp = pos.getMomentum().magnitude();
+                final Hep3Vector pEleRot = VecOp.mult(beamAxisRotation, ele.getMomentum());
+                final Hep3Vector pPosRot = VecOp.mult(beamAxisRotation, pos.getMomentum());
 
                 pEleVspPos.fill(pe, pp);
+                pEle.fill(pe);
+                pPos.fill(pp);
+
                 pxEleVspxPos.fill(pEleRot.x(), pPosRot.x());
                 pyEleVspyPos.fill(pEleRot.y(), pPosRot.y());
-                if (pe < v0MaxPCut && pp < v0MaxPCut && (pe + pp) > v0ESumMinCut && (pe + pp) < v0ESumMaxCut)//enrich radiative-like events
-                
+                if (pe < v0MaxPCut && pp < v0MaxPCut && pe + pp > v0ESumMinCut && pe + pp < v0ESumMaxCut) {
                     pEleVspPosWithCut.fill(pe, pp);
-            }
-
-            double eleT = TrackUtils.getTrackTime(ele.getTracks().get(0), hitToStrips, hitToRotated);
-            double posT = TrackUtils.getTrackTime(pos.getTracks().get(0), hitToStrips, hitToRotated);
-            double meanT = (eleT + posT) / 2.0;
+                }
+            }
+
+            final double eleT = TrackUtils.getTrackTime(ele.getTracks().get(0), hitToStrips, hitToRotated);
+            final double posT = TrackUtils.getTrackTime(pos.getTracks().get(0), hitToStrips, hitToRotated);
+            final double meanT = (eleT + posT) / 2.0;
             v0Time.fill(meanT);
             v0Dt.fill(eleT - posT);
             trigTimeV0Time.fill(meanT, event.getTimeStamp() % 24);
             trigTime.fill(event.getTimeStamp() % 24);
         }
 
-        List<ReconstructedParticle> beamConstrainedV0List = event.get(ReconstructedParticle.class, beamConV0CandidatesColName);
+        final List<ReconstructedParticle> beamConstrainedV0List = event.get(ReconstructedParticle.class,
+                beamConV0CandidatesColName);
         nV0.fill(beamConstrainedV0List.size());
-        for (ReconstructedParticle bsV0 : beamConstrainedV0List) {
-
-            if (isGBL != TrackType.isGBL(bsV0.getType()))
+        for (final ReconstructedParticle bsV0 : beamConstrainedV0List) {
+
+            if (isGBL != TrackType.isGBL(bsV0.getType())) {
                 continue;
+            }
             nTotV0++;
-            Vertex bsVert = bsV0.getStartVertex();
-            Hep3Vector vtxPosRot = VecOp.mult(beamAxisRotation, bsVert.getPosition());
+            final Vertex bsVert = bsV0.getStartVertex();
+            final Hep3Vector vtxPosRot = VecOp.mult(beamAxisRotation, bsVert.getPosition());
             bsconVx.fill(vtxPosRot.x());
             bsconVy.fill(vtxPosRot.y());
             bsconVz.fill(vtxPosRot.z());
             bsconMass.fill(bsV0.getMass());
             bsconChi2.fill(bsVert.getChi2());
             bsconVzVsChi2.fill(bsVert.getChi2(), vtxPosRot.z());
-            bsconChi2VsTrkChi2.fill(Math.max(bsV0.getParticles().get(0).getTracks().get(0).getChi2(), bsV0.getParticles().get(1).getTracks().get(0).getChi2()), bsVert.getChi2());
+            bsconChi2VsTrkChi2.fill(
+                    Math.max(bsV0.getParticles().get(0).getTracks().get(0).getChi2(), bsV0.getParticles().get(1)
+                            .getTracks().get(0).getChi2()), bsVert.getChi2());
             sumMass += bsV0.getMass();
             sumVx += vtxPosRot.x();
             sumVy += vtxPosRot.y();
@@ -367,71 +623,82 @@
             sumChi2 += bsVert.getChi2();
         }
 
-        List<ReconstructedParticle> targetConstrainedV0List = event.get(ReconstructedParticle.class, targetV0ConCandidatesColName);
-        for (ReconstructedParticle tarV0 : targetConstrainedV0List) {
-
-            if (isGBL != TrackType.isGBL(tarV0.getType()))
+        final List<ReconstructedParticle> targetConstrainedV0List = event.get(ReconstructedParticle.class,
+                targetV0ConCandidatesColName);
+        for (final ReconstructedParticle tarV0 : targetConstrainedV0List) {
+
+            if (isGBL != TrackType.isGBL(tarV0.getType())) {
                 continue;
-
-            Vertex tarVert = tarV0.getStartVertex();
-            Hep3Vector vtxPosRot = VecOp.mult(beamAxisRotation, tarVert.getPosition());
+            }
+
+            final Vertex tarVert = tarV0.getStartVertex();
+            final Hep3Vector vtxPosRot = VecOp.mult(beamAxisRotation, tarVert.getPosition());
             tarconVx.fill(vtxPosRot.x());
             tarconVy.fill(vtxPosRot.y());
             tarconVz.fill(vtxPosRot.z());
             tarconMass.fill(tarV0.getMass());
             tarconChi2.fill(tarVert.getChi2());
             tarconVzVsChi2.fill(tarVert.getChi2(), vtxPosRot.z());
-            tarconChi2VsTrkChi2.fill(Math.max(tarV0.getParticles().get(0).getTracks().get(0).getChi2(), tarV0.getParticles().get(1).getTracks().get(0).getChi2()), tarVert.getChi2());
-        }
-        List<ReconstructedParticle> finalStateParticles = event.get(ReconstructedParticle.class, finalStateParticlesColName);
-        if (debug)
+            tarconChi2VsTrkChi2.fill(
+                    Math.max(tarV0.getParticles().get(0).getTracks().get(0).getChi2(), tarV0.getParticles().get(1)
+                            .getTracks().get(0).getChi2()), tarVert.getChi2());
+        }
+        final List<ReconstructedParticle> finalStateParticles = event.get(ReconstructedParticle.class,
+                finalStateParticlesColName);
+        if (debug) {
             LOGGER.info("This events has " + finalStateParticles.size() + " final state particles");
+        }
 
         ReconstructedParticle ele1 = null;
         ReconstructedParticle ele2 = null;
         int sumCharge = 0;
         int numChargedParticles = 0;
-        for (ReconstructedParticle fsPart : finalStateParticles) {
-            if (isGBL != TrackType.isGBL(fsPart.getType()))
+        for (final ReconstructedParticle fsPart : finalStateParticles) {
+            if (isGBL != TrackType.isGBL(fsPart.getType())) {
                 continue;
-            if (debug)
-                LOGGER.info("PDGID = " + fsPart.getParticleIDUsed() + "; charge = " + fsPart.getCharge() + "; pz = " + fsPart.getMomentum().x());
-            double charge = fsPart.getCharge();
+            }
+            if (debug) {
+                LOGGER.info("PDGID = " + fsPart.getParticleIDUsed() + "; charge = " + fsPart.getCharge() + "; pz = "
+                        + fsPart.getMomentum().x());
+            }
+            final double charge = fsPart.getCharge();
             sumCharge += charge;
             if (charge != 0) {
                 numChargedParticles++;
-                if (charge < 1)
-                    if (ele1 == null)
+                if (charge < 1) {
+                    if (ele1 == null) {
                         ele1 = fsPart;
-                    else if (!hasSharedStrips(ele1, fsPart, hitToStrips, hitToRotated))
+                    } else if (!hasSharedStrips(ele1, fsPart, hitToStrips, hitToRotated)) {
                         ele2 = fsPart;
+                    }
+                }
             }
         }
         sumChargeHisto.fill(sumCharge);
         numChargeHisto.fill(numChargedParticles);
 
         if (ele1 != null && ele2 != null) {
-            Hep3Vector p1 = VecOp.mult(beamAxisRotation, ele1.getMomentum());
-            Hep3Vector p2 = VecOp.mult(beamAxisRotation, ele2.getMomentum());
-//            Hep3Vector beamAxis = new BasicHep3Vector(Math.sin(0.0305), 0, Math.cos(0.0305));
-//            LOGGER.info(p1);
-//            LOGGER.info(VecOp.mult(rot, p1));
-
-            double theta1 = Math.acos(p1.z() / p1.magnitude());
-            double theta2 = Math.acos(p2.z() / p2.magnitude());
-            double phi1 = Math.atan2(p1.y(), p1.x());
-            double phi2 = Math.atan2(p2.y(), p2.x());
+            final Hep3Vector p1 = VecOp.mult(beamAxisRotation, ele1.getMomentum());
+            final Hep3Vector p2 = VecOp.mult(beamAxisRotation, ele2.getMomentum());
+            // Hep3Vector beamAxis = new BasicHep3Vector(Math.sin(0.0305), 0, Math.cos(0.0305));
+            // LOGGER.info(p1);
+            // LOGGER.info(VecOp.mult(rot, p1));
+
+            final double theta1 = Math.acos(p1.z() / p1.magnitude());
+            final double theta2 = Math.acos(p2.z() / p2.magnitude());
+            final double phi1 = Math.atan2(p1.y(), p1.x());
+            final double phi2 = Math.atan2(p2.y(), p2.x());
             phiEleVsphiEle.fill(phi1, phi2);
             pEleVspEle.fill(ele1.getMomentum().magnitude(), ele2.getMomentum().magnitude());
             pyEleVspyEle.fill(ele1.getMomentum().y(), ele2.getMomentum().y());
             pxEleVspxEle.fill(ele1.getMomentum().x(), ele2.getMomentum().x());
-            //remove beam electrons
+            // remove beam electrons
             if (ele1.getMomentum().magnitude() < beambeamCut && ele2.getMomentum().magnitude() < beambeamCut) {
                 pEleVspEleNoBeam.fill(ele1.getMomentum().magnitude(), ele2.getMomentum().magnitude());
                 pyEleVspyEleNoBeam.fill(ele1.getMomentum().y(), ele2.getMomentum().y());
                 pxEleVspxEleNoBeam.fill(ele1.getMomentum().x(), ele2.getMomentum().x());
             }
-            //look at beam-beam events
+            // look at beam-beam events
             if (ele1.getMomentum().magnitude() > beambeamCut && ele2.getMomentum().magnitude() > beambeamCut) {
                 pEleVspEleBeamBeam.fill(ele1.getMomentum().magnitude(), ele2.getMomentum().magnitude());
                 pEleVsthetaBeamBeam.fill(p1.magnitude(), theta1);
@@ -439,29 +706,51 @@
                 thetaEleVsthetaBeamBeam.fill(theta1, theta2);
             }
 
-            //look at "Moller" events (if that's what they really are
+            // look at "Moller" events (if that's what they really are
             if (ele1.getMomentum().magnitude() + ele2.getMomentum().magnitude() > molPSumMin
                     && ele1.getMomentum().magnitude() + ele2.getMomentum().magnitude() < molPSumMax
-                    && (p1.magnitude() < beambeamCut && p2.magnitude() < beambeamCut)) {
-
-                Track ele1trk = ele1.getTracks().get(0);
-                Track ele2trk = ele2.getTracks().get(0);
-                SeedTrack stEle1 = TrackUtils.makeSeedTrackFromBaseTrack(ele1trk);
-                SeedTrack stEle2 = TrackUtils.makeSeedTrackFromBaseTrack(ele2trk);
-                BilliorTrack btEle1 = new BilliorTrack(stEle1.getSeedCandidate().getHelix());
-                BilliorTrack btEle2 = new BilliorTrack(stEle2.getSeedCandidate().getHelix());
-                BilliorVertex bv = fitVertex(btEle1, btEle2);
-//                LOGGER.info("ee vertex: "+bv.toString());
-                mollerMass.fill(bv.getParameters().get("invMass"));
+                    && p1.magnitude() < beambeamCut && p2.magnitude() < beambeamCut) {
+
+                final Track ele1trk = ele1.getTracks().get(0);
+                final Track ele2trk = ele2.getTracks().get(0);
+                final SeedTrack stEle1 = TrackUtils.makeSeedTrackFromBaseTrack(ele1trk);
+                final SeedTrack stEle2 = TrackUtils.makeSeedTrackFromBaseTrack(ele2trk);
+                final BilliorTrack btEle1 = new BilliorTrack(stEle1.getSeedCandidate().getHelix());
+                final BilliorTrack btEle2 = new BilliorTrack(stEle2.getSeedCandidate().getHelix());
+                final BilliorVertex bv = this.fitVertex(btEle1, btEle2, TrackUtils.getBField(event.getDetector())
+                        .magnitude());
+                // LOGGER.info("ee vertex: "+bv.toString());
+                final double invMass = bv.getParameters().get("invMass");
+                mollerMass.fill(invMass);
                 mollerVx.fill(bv.getPosition().x());
                 mollerVy.fill(bv.getPosition().y());
                 mollerVz.fill(bv.getPosition().z());
                 mollerXVsVtxZ.fill(bv.getPosition().x(), bv.getPosition().z());
                 mollerYVsVtxZ.fill(bv.getPosition().y(), bv.getPosition().z());
                 mollerXVsVtxY.fill(bv.getPosition().x(), bv.getPosition().y());
-                if (Math.abs(bv.getPosition().x()) < 2
-                        && Math.abs(bv.getPosition().y()) < 0.5) {
-                    mollerMassVtxCut.fill(bv.getParameters().get("invMass"));
+
+                final double ux = (ele1.getMomentum().x() + ele2.getMomentum().x())
+                        / (ele1.getMomentum().z() + ele2.getMomentum().z());
+                final double uy = (ele1.getMomentum().y() + ele2.getMomentum().y())
+                        / (ele1.getMomentum().z() + ele2.getMomentum().z());
+                mollerUx.fill(ux);
+                mollerUy.fill(uy);
+
+                // higher and lower energy electrons in moller pair
+                final double pt1 = ele1.getMomentum().magnitude();
+                final double pt2 = ele2.getMomentum().magnitude();
+                final double ph = pt1 > pt2 ? pt1 : pt2;
+                final double pl = pt1 > pt2 ? pt2 : pt1;
+
+                mollerHiP.fill(ph);
+                mollerLoP.fill(pl);
+
+                mollerEitherP.fill(ph);
+                mollerEitherP.fill(pl);
+                mollerPsum.fill(pt1 + pt2);
+
+                if (Math.abs(bv.getPosition().x()) < 2 && Math.abs(bv.getPosition().y()) < 0.5) {
+                    mollerMassVtxCut.fill(invMass);
                     mollerVzVtxCut.fill(bv.getPosition().z());
                 }
                 pEleVspEleMoller.fill(p1.magnitude(), p2.magnitude());
@@ -471,119 +760,4 @@
             }
         }
     }
-
-    @Override
-    public void printDQMData() {
-        LOGGER.info("V0Monitoring::printDQMData");
-        for (Entry<String, Double> entry : monitoredQuantityMap.entrySet())
-            LOGGER.info(entry.getKey() + " = " + entry.getValue());
-        LOGGER.info("*******************************");
-    }
-
-    /**
-     * Calculate the averages here and fill the map
-     */
-    @Override
-    public void calculateEndOfRunQuantities() {
-
-        IAnalysisFactory analysisFactory = IAnalysisFactory.create();
-        IFitFactory fitFactory = analysisFactory.createFitFactory();
-        IFitter fitter = fitFactory.createFitter("chi2");
-        double[] init = {50.0, 0.0, 0.2, 1.0, 0.0};
-        IFitResult resVx = fitVertexPosition(bsconVx, fitter, init, "range=\"(-0.5,0.5)\"");
-        double[] init2 = {50.0, 0.0, 0.04, 1.0, 0.0};
-        IFitResult resVy = fitVertexPosition(bsconVy, fitter, init2, "range=\"(-0.2,0.2)\"");
-        double[] init3 = {50.0, 0.0, 3.0, 1.0, 0.0};
-        IFitResult resVz = fitVertexPosition(bsconVz, fitter, init3, "range=\"(-6,6)\"");
-
-        if (resVx != null && resVy != null & resVz != null) {
-            double[] parsVx = resVx.fittedParameters();
-            double[] parsVy = resVy.fittedParameters();
-            double[] parsVz = resVz.fittedParameters();
-
-            for (int i = 0; i < 5; i++)
-                LOGGER.info("Vertex Fit Parameters:  " + resVx.fittedParameterNames()[i] + " = " + parsVx[i] + "; " + parsVy[i] + "; " + parsVz[i]);
-
-            IPlotter plotter = analysisFactory.createPlotterFactory().create("Vertex Position");
-            plotter.createRegions(1, 3);
-            IPlotterStyle pstyle = plotter.style();
-            pstyle.legendBoxStyle().setVisible(false);
-            pstyle.dataStyle().fillStyle().setColor("green");
-            pstyle.dataStyle().lineStyle().setColor("black");
-            plotter.region(0).plot(bsconVx);
-            plotter.region(0).plot(resVx.fittedFunction());
-            plotter.region(1).plot(bsconVy);
-            plotter.region(1).plot(resVy.fittedFunction());
-            plotter.region(2).plot(bsconVz);
-            plotter.region(2).plot(resVz.fittedFunction());
-            if (outputPlots)
-                try {
-                    plotter.writeToFile(outputPlotDir + "vertex.png");
-                } catch (IOException ex) {
-                    Logger.getLogger(V0Monitoring.class.getName()).log(Level.SEVERE, null, ex);
-                }
-
-//        monitoredQuantityMap.put(fpQuantNames[2], sumVx / nTotV0);
-//        monitoredQuantityMap.put(fpQuantNames[3], sumVy / nTotV0);
-//        monitoredQuantityMap.put(fpQuantNames[4], sumVz / nTotV0);
-            monitoredQuantityMap.put(beamConV0CandidatesColName + " " + triggerType + " " + fpQuantNames[2], parsVx[1]);
-            monitoredQuantityMap.put(beamConV0CandidatesColName + " " + triggerType + " " + fpQuantNames[3], parsVy[1]);
-            monitoredQuantityMap.put(beamConV0CandidatesColName + " " + triggerType + " " + fpQuantNames[4], parsVz[1]);
-            monitoredQuantityMap.put(beamConV0CandidatesColName + " " + triggerType + " " + fpQuantNames[5], parsVx[2]);
-            monitoredQuantityMap.put(beamConV0CandidatesColName + " " + triggerType + " " + fpQuantNames[6], parsVy[2]);
-            monitoredQuantityMap.put(beamConV0CandidatesColName + " " + triggerType + " " + fpQuantNames[7], parsVz[2]);
-        }
-        monitoredQuantityMap.put(beamConV0CandidatesColName + " " + triggerType + " " + fpQuantNames[0], (double) nTotV0 / nRecoEvents);
-        monitoredQuantityMap.put(beamConV0CandidatesColName + " " + triggerType + " " + fpQuantNames[1], sumMass / nTotV0);
-        monitoredQuantityMap.put(beamConV0CandidatesColName + " " + triggerType + " " + fpQuantNames[8], sumChi2 / nTotV0);
-
-    }
-
-    @Override
-    public void printDQMStrings() {
-        for (int i = 0; i < 9; i++)//TODO:  do this in a smarter way...loop over the map
-            LOGGER.info("ALTER TABLE dqm ADD " + fpQuantNames[i] + " double;");
-    }
-
-    IFitResult fitVertexPosition(IHistogram1D h1d, IFitter fitter, double[] init, String range
-    ) {
-        IFitResult ifr = null;
-        try {
-            ifr = fitter.fit(h1d, "g+p1", init, range);
-        } catch (RuntimeException ex) {
-            LOGGER.info(this.getClass().getSimpleName() + ":  caught exception in fitGaussian");
-        }
-        return ifr;
-    }
-
-    private BilliorVertex fitVertex(BilliorTrack electron, BilliorTrack positron) {
-        // Create a vertex fitter from the magnetic field.
-        double bField = 0.24;
-        double[] beamSize = {0.001, 0.2, 0.02};
-        BilliorVertexer vtxFitter = new BilliorVertexer(bField);
-        // TODO: The beam size should come from the conditions database.
-        vtxFitter.setBeamSize(beamSize);
-
-        // Perform the vertexing based on the specified constraint.
-        vtxFitter.doBeamSpotConstraint(false);
-
-        // Add the electron and positron tracks to a track list for
-        // the vertex fitter.
-        List<BilliorTrack> billiorTracks = new ArrayList<BilliorTrack>();
-
-        billiorTracks.add(electron);
-
-        billiorTracks.add(positron);
-
-        // Find and return a vertex based on the tracks.
-        return vtxFitter.fitVertex(billiorTracks);
-    }
-
-    private static boolean hasSharedStrips(ReconstructedParticle vertex, RelationalTable hittostrip, RelationalTable hittorotated) {
-        return hasSharedStrips(vertex.getParticles().get(0), vertex.getParticles().get(1), hittostrip, hittorotated);
-    }
-
-    private static boolean hasSharedStrips(ReconstructedParticle fs1, ReconstructedParticle fs2, RelationalTable hittostrip, RelationalTable hittorotated) {
-        return TrackUtils.hasSharedStrips(fs1.getTracks().get(0), fs2.getTracks().get(0), hittostrip, hittorotated);
-    }
 }

Modified: java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/ecal/EcalCellIDPrintDriver.java
 =============================================================================
--- java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/ecal/EcalCellIDPrintDriver.java	(original)
+++ java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/ecal/EcalCellIDPrintDriver.java	Wed Apr 27 11:11:32 2016
@@ -19,63 +19,63 @@
  */
 public class EcalCellIDPrintDriver extends Driver {
 
-	Subdetector ecal;
-	IDDecoder dec;
-	String ecalName = "Ecal";
-	String ecalCollectionName = "EcalReadoutHits";
-	String outputFileName;
-	PrintWriter outputStream = null;
+    Subdetector ecal;
+    IDDecoder dec;
+    String ecalName = "Ecal";
+    String ecalCollectionName = "EcalReadoutHits";
+    String outputFileName;
+    PrintWriter outputStream = null;
 
-	public EcalCellIDPrintDriver() {
-	}
+    public EcalCellIDPrintDriver() {
+    }
 
-	public void setEcalCollectionName(String ecalCollectionName) {
-		this.ecalCollectionName = ecalCollectionName;
-	}
+    public void setEcalCollectionName(String ecalCollectionName) {
+        this.ecalCollectionName = ecalCollectionName;
+    }
 
-	public void setEcalName(String ecalName) {
-		this.ecalName = ecalName;
-	}
+    public void setEcalName(String ecalName) {
+        this.ecalName = ecalName;
+    }
 
-	public void setOutputFileName(String outputFileName) {
-		this.outputFileName = outputFileName;
-	}
+    public void setOutputFileName(String outputFileName) {
+        this.outputFileName = outputFileName;
+    }
 
-	public void startOfData() {
-		if (outputFileName != null) {
-			try {
-				outputStream = new PrintWriter(outputFileName);
-			} catch (IOException ex) {
-				throw new RuntimeException("Invalid outputFilePath!");
-			}
-		} else {
-			outputStream = new PrintWriter(System.out, true);
-		}
-	}
+    public void startOfData() {
+        if (outputFileName != null) {
+            try {
+                outputStream = new PrintWriter(outputFileName);
+            } catch (IOException ex) {
+                throw new RuntimeException("Invalid outputFilePath!");
+            }
+        } else {
+            outputStream = new PrintWriter(System.out, true);
+        }
+    }
 
-	public void detectorChanged(Detector detector) {
-		// Get the Subdetector.
-		ecal = (Subdetector) detector.getSubdetector(ecalName);
-		dec = ecal.getIDDecoder();
-	}
+    public void detectorChanged(Detector detector) {
+        // Get the Subdetector.
+        ecal = (Subdetector) detector.getSubdetector(ecalName);
+        dec = ecal.getIDDecoder();
+    }
 
-	public void process(EventHeader event) {
-		// Get the list of ECal hits.
-		if (event.hasCollection(RawCalorimeterHit.class, ecalCollectionName)) {
-			List<RawCalorimeterHit> hits = event.get(RawCalorimeterHit.class, ecalCollectionName);
-			//outputStream.println("Reading RawCalorimeterHit from event " + event.getEventNumber());
-			for (RawCalorimeterHit hit : hits) {
-				dec.setID(hit.getCellID());
-				outputStream.printf("x=%d\ty=%d\n", dec.getValue("ix"), dec.getValue("iy"));
-			}
-		}
-		if (event.hasCollection(RawTrackerHit.class, ecalCollectionName)) {
-			List<RawTrackerHit> hits = event.get(RawTrackerHit.class, ecalCollectionName);
-			//outputStream.println("Reading RawCalorimeterHit from event " + event.getEventNumber());
-			for (RawTrackerHit hit : hits) {
-				dec.setID(hit.getCellID());
-				outputStream.printf("x=%d\ty=%d\n", dec.getValue("ix"), dec.getValue("iy"));
-			}
-		}
-	}
+    public void process(EventHeader event) {
+        // Get the list of ECal hits.
+        if (event.hasCollection(RawCalorimeterHit.class, ecalCollectionName)) {
+            List<RawCalorimeterHit> hits = event.get(RawCalorimeterHit.class, ecalCollectionName);
+            //outputStream.println("Reading RawCalorimeterHit from event " + event.getEventNumber());
+            for (RawCalorimeterHit hit : hits) {
+                dec.setID(hit.getCellID());
+                outputStream.printf("x=%d\ty=%d\n", dec.getValue("ix"), dec.getValue("iy"));
+            }
+        }
+        if (event.hasCollection(RawTrackerHit.class, ecalCollectionName)) {
+            List<RawTrackerHit> hits = event.get(RawTrackerHit.class, ecalCollectionName);
+            //outputStream.println("Reading RawCalorimeterHit from event " + event.getEventNumber());
+            for (RawTrackerHit hit : hits) {
+                dec.setID(hit.getCellID());
+                outputStream.printf("x=%d\ty=%d\n", dec.getValue("ix"), dec.getValue("iy"));
+            }
+        }
+    }
 }

Modified: java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/ecal/EcalClusterPlots.java
 =============================================================================
--- java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/ecal/EcalClusterPlots.java	(original)
+++ java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/ecal/EcalClusterPlots.java	Wed Apr 27 11:11:32 2016
@@ -17,7 +17,7 @@
 
 public class EcalClusterPlots extends Driver {
 
-	//AIDAFrame plotterFrame;
+    //AIDAFrame plotterFrame;
     String inputCollection = "EcalClusters";
     AIDA aida = AIDA.defaultInstance();
     IPlotter plotter, plotter2, plotter3, plotter4;
@@ -47,7 +47,7 @@
     @Override
     protected void detectorChanged(Detector detector) {
 
-    	//plotterFrame = new AIDAFrame();
+        //plotterFrame = new AIDAFrame();
         //plotterFrame.setTitle("HPS ECal Cluster Plots");
 
         // Setup the plotter.
@@ -172,6 +172,6 @@
 
     @Override
     public void endOfData() {
-    	//plotterFrame.dispose();
+        //plotterFrame.dispose();
     }
 }

Modified: java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/ecal/EcalHitPlots.java
 =============================================================================
--- java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/ecal/EcalHitPlots.java	(original)
+++ java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/ecal/EcalHitPlots.java	Wed Apr 27 11:11:32 2016
@@ -192,8 +192,8 @@
                 } else if (AbstractIntData.getTag(data) == SSPData.BANK_TAG) {
                     //SSPData triggerData = new SSPData(data);
                     // TODO: TOP, BOTTOM, AND, and OR trigger are test
-                	// run-specific parameters and are not supported by
-                	// SSPData.
+                    // run-specific parameters and are not supported by
+                    // SSPData.
                     int orTrig = 0; //triggerData.getOrTrig();
                     if(orTrig != 0) {
                         for (int i = 0; i < 32; i++) {
@@ -237,7 +237,7 @@
             double botTime = Double.POSITIVE_INFINITY;
             double orTime = Double.POSITIVE_INFINITY;
             for (CalorimeterHit hit : hits) {
-            	/*
+                /*
                 if (hit.getIdentifierFieldValue("iy") > 0) {
                     topX.fill(hit.getIdentifierFieldValue("ix"),hit.getPosition()[0]);
                     topY.fill(hit.getIdentifierFieldValue("iy"),hit.getPosition()[1]);

Modified: java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/ecal/FEEClusterPlotter.java
 =============================================================================
--- java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/ecal/FEEClusterPlotter.java	(original)
+++ java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/ecal/FEEClusterPlotter.java	Wed Apr 27 11:11:32 2016
@@ -28,8 +28,8 @@
 */
 
 public class FEEClusterPlotter extends Driver {
-	
-	//private AIDAFrame plotterFrame;
+    
+    //private AIDAFrame plotterFrame;
     private AIDA aida = AIDA.defaultInstance();
     IPlotter plotter;
     IAnalysisFactory fac = aida.analysisFactory();
@@ -43,6 +43,28 @@
     private String histoNameFormat = "%3d";
     
     private String outputPlots = null;
+    
+    //Set min energy in histo
+    private double minHistoE = 0.5;
+    
+    //Set max energy in histo
+    private double maxHistoE = 1.3;
+    
+    /**
+     * Set the minimum histogram energy
+     * @param minHistoE
+     */
+    public void setMinHistoE(double minHistoE) {
+        this.minHistoE = minHistoE;
+    }
+    
+    /**
+     * Set the maximum histogram energy
+     * @param maxHistoE
+     */
+    public void setMaxHistoE(double maxHistoE) {
+        this.maxHistoE = maxHistoE;
+    }
     
     @Override
     protected void detectorChanged(Detector detector) {
@@ -52,7 +74,7 @@
         
         aida.tree().cd("/");
         for (EcalChannel cc : ecalConditions.getChannelCollection()) {
-            aida.histogram1D(getHistoName(cc),200,0.5,1.3);
+            aida.histogram1D(getHistoName(cc),200,minHistoE,maxHistoE);
         }
 
     }
@@ -61,43 +83,121 @@
         return String.format(histoNameFormat,cc.getChannelId());
     }
     
+    
+    //Set min seed energy value, default to 2015 run
+    private double seedCut = 0.4;
+    
+    //set min cluster time in window, default to 2015 run
+    private double minTime = 30;
+    
+    //set max cluster time in window, default to 2015 run
+    private double maxTime = 70;
+    
+  //set min number of hits in a cluster in row 1, default to 2015 run
+    private int hitCut = 5;
+    
+    //hit cut is only used in 2016 data, not 2015
+    private boolean useHitCut = false;
+    
+    
+    /**
+     * Set the cut value for seed energy in GeV
+     * @param seedCut
+     */
+    public void setSeedCut(double seedCut) {
+        this.seedCut = seedCut;
+    }
+    
+    /**
+     * Set the min time in window to look for cluster
+     * @param minTime
+     */
+    public void setMinTime(double minTime) {
+        this.minTime = minTime;
+    }
+    
+    /**
+     * Set the max time in window to look for cluster
+     * @param maxTime
+     */
+    public void setMaxTime(double maxTime) {
+        this.maxTime = maxTime;
+    }
+    
+    /**
+     * Set the hit cut value for hits in cluster
+     * This cut is used in 2016 running (not 2015)
+     * @param hitCut
+     */
+    public void setHitCut(int hitCut) {
+        this.hitCut = hitCut;
+    }
+    
+    /**
+     * Set the hit cut value for hits in cluster
+     * This cut is used in 2016 running (not 2015)
+     * @param hitCut
+     */
+    public void setUseHitCut(boolean useHitCut) {
+        this.useHitCut = useHitCut;
+    }
+    
     public void process(EventHeader event) {
         aida.tree().cd("/");
 
         //only keep singles triggers:
         if (!event.hasCollection(GenericObject.class,"TriggerBank"))
-        	throw new Driver.NextEventException();
+            throw new Driver.NextEventException();
         boolean isSingles=false;
         for (GenericObject gob : event.get(GenericObject.class,"TriggerBank"))
-        {	
-        	if (!(AbstractIntData.getTag(gob) == TIData.BANK_TAG)) continue;
-        	TIData tid = new TIData(gob);
-        	if (tid.isSingle0Trigger()  || tid.isSingle1Trigger())
-        	{
-        		isSingles=true;
-        		break;
-        	}
+        {   
+            if (!(AbstractIntData.getTag(gob) == TIData.BANK_TAG)) continue;
+            TIData tid = new TIData(gob);
+            if (tid.isSingle0Trigger()  || tid.isSingle1Trigger())
+            {
+                isSingles=true;
+                break;
+            }
         }
         
         if (isSingles){
-        	List<Cluster> clusters = event.get(Cluster.class, inputCollection);
-        	for (Cluster clus : clusters) {
-        		List<CalorimeterHit> hits = clus.getCalorimeterHits();
-        		CalorimeterHit seed = hits.get(0);
-        	
-        		double seedE = seed.getCorrectedEnergy();
-        		double clusE = clus.getEnergy();
-        		double time = seed.getTime();
-        			
-        		if ((seedE/clusE > 0.6) && seedE >0.45 && time>30 && time <70){
-        	
-        			EcalChannel cc = findChannel(seed);
-        			aida.histogram1D(getHistoName(cc)).fill(clusE);
-        		}
-        	}
-        }
-    }
-	
+            List<Cluster> clusters = event.get(Cluster.class, inputCollection);
+            for (Cluster clus : clusters) {
+                List<CalorimeterHit> hits = clus.getCalorimeterHits();
+                CalorimeterHit seed = hits.get(0);
+            
+                double seedE = seed.getCorrectedEnergy();
+                double clusE = clus.getEnergy();
+                double time = seed.getTime();
+                
+                //in 2015, not hit count cut used at all
+                if (useHitCut){
+                    if (Math.abs(seed.getIdentifierFieldValue("iy"))==1 && (seedE/clusE > 0.6) && seedE >seedCut 
+                        && time>minTime && time <maxTime && hits.size()>(hitCut+2) ){
+            
+                        EcalChannel cc = findChannel(seed);
+                        aida.histogram1D(getHistoName(cc)).fill(clusE);
+                    }
+                    else if (Math.abs(seed.getIdentifierFieldValue("iy"))>1 && (seedE/clusE > 0.6) && seedE >seedCut 
+                        && time>minTime && time <maxTime && hits.size()>(hitCut) ){
+                        
+                        EcalChannel cc = findChannel(seed);
+                        aida.histogram1D(getHistoName(cc)).fill(clusE);
+                    }
+                }
+                else {
+                    if ((seedE/clusE > 0.6) && seedE >seedCut 
+                            && time>minTime && time <maxTime ){
+                
+                            EcalChannel cc = findChannel(seed);
+                            aida.histogram1D(getHistoName(cc)).fill(clusE);
+                         
+                    }   
+                }   
+            }
+        }
+    }
+    
     public void setOutputPlots(String output) {
         this.outputPlots = output;
     }
@@ -119,5 +219,5 @@
                 Logger.getLogger(FEEClusterPlotter.class.getName()).log(Level.SEVERE, null, ex);
             }
         }
-    }	
+    }   
 }

Modified: java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/ecal/HPSEcalFADCPlotsDriver.java
 =============================================================================
--- java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/ecal/HPSEcalFADCPlotsDriver.java	(original)
+++ java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/ecal/HPSEcalFADCPlotsDriver.java	Wed Apr 27 11:11:32 2016
@@ -20,90 +20,90 @@
  */
 public class HPSEcalFADCPlotsDriver extends Driver {
 
-	String edepCollectionName = "EcalHits";
-	String rawCollectionName = null;
-	String ecalCollectionName = null;
-	String clusterCollectionName = "EcalClusters";
-	AIDA aida = AIDA.defaultInstance();
-	IHistogram1D edepE;
-	IHistogram1D rawE;
-	IHistogram1D ecalE;
-	IHistogram1D clusterE;
-	ICloud2D window_E;
-	double edepThreshold = 0.05;
+    String edepCollectionName = "EcalHits";
+    String rawCollectionName = null;
+    String ecalCollectionName = null;
+    String clusterCollectionName = "EcalClusters";
+    AIDA aida = AIDA.defaultInstance();
+    IHistogram1D edepE;
+    IHistogram1D rawE;
+    IHistogram1D ecalE;
+    IHistogram1D clusterE;
+    ICloud2D window_E;
+    double edepThreshold = 0.05;
 
-	public void setEdepThreshold(double edepThreshold) {
-		this.edepThreshold = edepThreshold;
-	}
+    public void setEdepThreshold(double edepThreshold) {
+        this.edepThreshold = edepThreshold;
+    }
 
-	public void setRawCollectionName(String rawCollectionName) {
-		this.rawCollectionName = rawCollectionName;
-	}
+    public void setRawCollectionName(String rawCollectionName) {
+        this.rawCollectionName = rawCollectionName;
+    }
 
-	public void setEcalCollectionName(String ecalCollectionName) {
-		this.ecalCollectionName = ecalCollectionName;
-	}
+    public void setEcalCollectionName(String ecalCollectionName) {
+        this.ecalCollectionName = ecalCollectionName;
+    }
 
-	public void setClusterCollectionName(String clusterCollectionName) {
-		this.clusterCollectionName = clusterCollectionName;
-	}
+    public void setClusterCollectionName(String clusterCollectionName) {
+        this.clusterCollectionName = clusterCollectionName;
+    }
 
-	public void startOfData() {
-		edepE = aida.histogram1D(
-				"FADC plots: " + edepCollectionName + " : Hits",
-				500, 0.0, 5.0);
-		if (rawCollectionName != null) {
-			rawE = aida.histogram1D(
-					"FADC plots: " + rawCollectionName + " : Hits",
-					500, 0.0, 500.0);
-			window_E = aida.cloud2D("FADC plots: " + rawCollectionName + " : Window vs. E");
-		}
-		if (ecalCollectionName != null) {
-			ecalE = aida.histogram1D(
-					"FADC plots: " + ecalCollectionName + " : Hits",
-					500, 0.0, 5.0);
-		}
-		clusterE = aida.histogram1D(
-				"FADC plots: " + clusterCollectionName + " : Clusters",
-				500, 0.0, 5.0);
-	}
+    public void startOfData() {
+        edepE = aida.histogram1D(
+                "FADC plots: " + edepCollectionName + " : Hits",
+                500, 0.0, 5.0);
+        if (rawCollectionName != null) {
+            rawE = aida.histogram1D(
+                    "FADC plots: " + rawCollectionName + " : Hits",
+                    500, 0.0, 500.0);
+            window_E = aida.cloud2D("FADC plots: " + rawCollectionName + " : Window vs. E");
+        }
+        if (ecalCollectionName != null) {
+            ecalE = aida.histogram1D(
+                    "FADC plots: " + ecalCollectionName + " : Hits",
+                    500, 0.0, 5.0);
+        }
+        clusterE = aida.histogram1D(
+                "FADC plots: " + clusterCollectionName + " : Clusters",
+                500, 0.0, 5.0);
+    }
 
-	public void process(EventHeader event) {
-		List<Cluster> clusters = event.get(Cluster.class, clusterCollectionName);
-		if (clusters == null)
-			throw new RuntimeException("Missing cluster collection!");
+    public void process(EventHeader event) {
+        List<Cluster> clusters = event.get(Cluster.class, clusterCollectionName);
+        if (clusters == null)
+            throw new RuntimeException("Missing cluster collection!");
 
-		List<CalorimeterHit> edepHits = event.get(CalorimeterHit.class, edepCollectionName);
-		if (edepHits == null)
-			throw new RuntimeException("Missing hit collection!");
+        List<CalorimeterHit> edepHits = event.get(CalorimeterHit.class, edepCollectionName);
+        if (edepHits == null)
+            throw new RuntimeException("Missing hit collection!");
 
-		if (rawCollectionName != null) {
-			List<RawCalorimeterHit> rawHits = event.get(RawCalorimeterHit.class, rawCollectionName);
-			if (rawHits == null)
-				throw new RuntimeException("Missing hit collection!");
+        if (rawCollectionName != null) {
+            List<RawCalorimeterHit> rawHits = event.get(RawCalorimeterHit.class, rawCollectionName);
+            if (rawHits == null)
+                throw new RuntimeException("Missing hit collection!");
 
-			for (RawCalorimeterHit hit : rawHits) {
-				rawE.fill(hit.getAmplitude());
-				//window_E.fill(hit.getAmplitude(),hit.getWindowSize());
-			}
-		}
+            for (RawCalorimeterHit hit : rawHits) {
+                rawE.fill(hit.getAmplitude());
+                //window_E.fill(hit.getAmplitude(),hit.getWindowSize());
+            }
+        }
 
-		if (ecalCollectionName != null) {
-			List<CalorimeterHit> ecalHits = event.get(CalorimeterHit.class, ecalCollectionName);
-			if (ecalHits == null)
-				throw new RuntimeException("Missing hit collection!");
+        if (ecalCollectionName != null) {
+            List<CalorimeterHit> ecalHits = event.get(CalorimeterHit.class, ecalCollectionName);
+            if (ecalHits == null)
+                throw new RuntimeException("Missing hit collection!");
 
-			for (CalorimeterHit hit : ecalHits) {
-				ecalE.fill(hit.getRawEnergy());
-			}
-		}
+            for (CalorimeterHit hit : ecalHits) {
+                ecalE.fill(hit.getRawEnergy());
+            }
+        }
 
-		for (CalorimeterHit hit : edepHits) {
-			if (hit.getRawEnergy() > edepThreshold)
-				edepE.fill(hit.getRawEnergy());
-		}
-		for (Cluster cluster : clusters) {
-			clusterE.fill(cluster.getEnergy());
-		}
-	}
+        for (CalorimeterHit hit : edepHits) {
+            if (hit.getRawEnergy() > edepThreshold)
+                edepE.fill(hit.getRawEnergy());
+        }
+        for (Cluster cluster : clusters) {
+            clusterE.fill(cluster.getEnergy());
+        }
+    }
 }

Modified: java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/ecal/HPSEcalTriggerPlotsDriver.java
 =============================================================================
--- java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/ecal/HPSEcalTriggerPlotsDriver.java	(original)
+++ java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/ecal/HPSEcalTriggerPlotsDriver.java	Wed Apr 27 11:11:32 2016
@@ -23,7 +23,7 @@
  * Exp $
  */
 public class HPSEcalTriggerPlotsDriver extends Driver {
-	// LCSim collection names.
+    // LCSim collection names.
     String ecalCollectionName = "EcalHits";
     String clusterCollectionName = "EcalClusters";
     
@@ -55,46 +55,46 @@
     }
     
     public void startOfData() {
-    	// Initialize a hit histogram for each declared energy.
-    	for(int e = 0; e < energyCut.length; e++) {
-    		hitXYPlot[e] = aida.histogram2D("Trigger Plots: " + ecalCollectionName +
-    				" : Hits above " + energyCut[e] + " MeV", 46, -23, 23, 11, -5.5, 5.5);
-    	}
-    	// Initialize the remaining plots.
+        // Initialize a hit histogram for each declared energy.
+        for(int e = 0; e < energyCut.length; e++) {
+            hitXYPlot[e] = aida.histogram2D("Trigger Plots: " + ecalCollectionName +
+                    " : Hits above " + energyCut[e] + " MeV", 46, -23, 23, 11, -5.5, 5.5);
+        }
+        // Initialize the remaining plots.
         crystalDeadTime = aida.histogram2D("Trigger Plots: " + ecalCollectionName +
-        		" : Crystal dead time", 46, -23, 23, 11, -5.5, 5.5);
+                " : Crystal dead time", 46, -23, 23, 11, -5.5, 5.5);
         clusterHitXYPlot = aida.histogram2D("Trigger Plots: " + clusterCollectionName +
-        		" : Crystals in clusters", 47, -23.5, 23.5, 11, -5.5, 5.5);
+                " : Crystals in clusters", 47, -23.5, 23.5, 11, -5.5, 5.5);
         seedHitXYPlot = aida.histogram2D("Trigger Plots: " + clusterCollectionName +
-        		" : Seed hits", 47, -23.5, 23.5, 11, -5.5, 5.5);
+                " : Seed hits", 47, -23.5, 23.5, 11, -5.5, 5.5);
         triggerClusterHitXYPlot = aida.histogram2D("Trigger Plots: " + clusterCollectionName +
                 " : Crystals in clusters, with trigger", 47, -23.5, 23.5, 11, -5.5, 5.5);
         triggerSeedHitXYPlot = aida.histogram2D("Trigger Plots: " + clusterCollectionName +
-        		" : Seed hits, with trigger", 47, -23.5, 23.5, 11, -5.5, 5.5);
+                " : Seed hits, with trigger", 47, -23.5, 23.5, 11, -5.5, 5.5);
     }
     
     public void process(EventHeader event) {
-    	// If the current event has the indicated hit collection,
-    	// use it as the hit list.
-    	List<CalorimeterHit> hits;
-    	if(event.hasCollection(CalorimeterHit.class, ecalCollectionName)) {
-    		hits = event.get(CalorimeterHit.class, ecalCollectionName);
-    	}
-    	// If it does not, then use an empty list to avoid crashing.
-    	else { hits = new ArrayList<CalorimeterHit>(0); }
-    	
-    	// If the current event has the indicated cluster collection,
-    	// use it as the cluster list.
-    	List<Cluster> clusters;
-    	if(event.hasCollection(Cluster.class, clusterCollectionName)) {
-    		clusters = event.get(Cluster.class, clusterCollectionName);
-    	}
-    	// If it does not, then use an empty list to avoid crashing.
-    	else { clusters = new ArrayList<Cluster>(0); }
+        // If the current event has the indicated hit collection,
+        // use it as the hit list.
+        List<CalorimeterHit> hits;
+        if(event.hasCollection(CalorimeterHit.class, ecalCollectionName)) {
+            hits = event.get(CalorimeterHit.class, ecalCollectionName);
+        }
+        // If it does not, then use an empty list to avoid crashing.
+        else { hits = new ArrayList<CalorimeterHit>(0); }
+        
+        // If the current event has the indicated cluster collection,
+        // use it as the cluster list.
+        List<Cluster> clusters;
+        if(event.hasCollection(Cluster.class, clusterCollectionName)) {
+            clusters = event.get(Cluster.class, clusterCollectionName);
+        }
+        // If it does not, then use an empty list to avoid crashing.
+        else { clusters = new ArrayList<Cluster>(0); }
         
         // Populate hit plots.
         for (CalorimeterHit hit : hits) {
-        	// Get the hit crystal position.
+            // Get the hit crystal position.
             int ix = hit.getIdentifierFieldValue("ix");
             int iy = hit.getIdentifierFieldValue("iy");
             double energy = hit.getRawEnergy();
@@ -102,9 +102,9 @@
             // Loop through the energy plots and fill them if the hit
             // is over the current energy threshold/
             for(int e = 0; e < energyCut.length; e++) {
-            	if(energy > energyCut[e] * EcalUtils.MeV) {
-            		hitXYPlot[e].fill(ix - 0.5 * Math.signum(ix), iy);
-            	}
+                if(energy > energyCut[e] * EcalUtils.MeV) {
+                    hitXYPlot[e].fill(ix - 0.5 * Math.signum(ix), iy);
+                }
             }
             
             // Generate the dead time plot.
@@ -121,8 +121,8 @@
         
         // Populate cluster based plots.
         for (Cluster cluster : clusters) {
-        	// Get the cluster's seed hit position.
-        	CalorimeterHit seed = cluster.getCalorimeterHits().get(0);
+            // Get the cluster's seed hit position.
+            CalorimeterHit seed = cluster.getCalorimeterHits().get(0);
             int ix = seed.getIdentifierFieldValue("ix");
             int iy = seed.getIdentifierFieldValue("iy");
             
@@ -135,7 +135,7 @@
             
             // Populate the component hit histogram.
             for (CalorimeterHit hit : cluster.getCalorimeterHits()) {
-            	// Get the component hit location.
+                // Get the component hit location.
                 ix = hit.getIdentifierFieldValue("ix");
                 iy = hit.getIdentifierFieldValue("iy");
                 

Modified: java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/ecal/HPSMCParticlePlotsDriver.java
 =============================================================================
--- java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/ecal/HPSMCParticlePlotsDriver.java	(original)
+++ java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/ecal/HPSMCParticlePlotsDriver.java	Wed Apr 27 11:11:32 2016
@@ -25,138 +25,138 @@
  */
 public class HPSMCParticlePlotsDriver extends Driver {
 
-	AIDA aida = AIDA.defaultInstance();
+    AIDA aida = AIDA.defaultInstance();
         //private AIDAFrame pFrame;
         IAnalysisFactory af = aida.analysisFactory();
         public boolean _hideFrame = false;
         // MCParticle plots.
-	ICloud1D primaryEPlot;
-	ICloud1D fsCountPlot;
-	IHistogram1D fsCountVsEventPlot;
-	ICloud1D fsCountTypePlot;
-	ICloud1D fsCountEventTypePlot;
-	ICloud1D fsCountEventTypePlot2;
-	ICloud1D fsCountTypePlot500;
-	IHistogram1D fsEPlot;
-	IHistogram1D fsGammaEPlot;
-	IHistogram1D fsElectronEPlot;
-	IHistogram1D fsPositronEPlot;
-	IHistogram1D fsThetayPlot;
-	ICloud1D fsGammaThetaPlot;
-	IHistogram1D fsGammaThetayPlot;
-	IHistogram1D fsGammaThetayTrigPlot;
-	ICloud2D fsGammaThetayEPlot;
-	ICloud1D fsElectronThetaPlot;
-	IHistogram1D fsElectronThetayPlot;
-	IHistogram1D fsElectronThetayTrigPlot;
-	ICloud2D fsElectronThetayEPlot;
-	ICloud1D fsPositronThetaPlot;
-	IHistogram1D fsPositronThetayPlot;
-	IHistogram1D fsPositronThetayTrigPlot;
-	ICloud2D fsPositronThetayEPlot;
+    ICloud1D primaryEPlot;
+    ICloud1D fsCountPlot;
+    IHistogram1D fsCountVsEventPlot;
+    ICloud1D fsCountTypePlot;
+    ICloud1D fsCountEventTypePlot;
+    ICloud1D fsCountEventTypePlot2;
+    ICloud1D fsCountTypePlot500;
+    IHistogram1D fsEPlot;
+    IHistogram1D fsGammaEPlot;
+    IHistogram1D fsElectronEPlot;
+    IHistogram1D fsPositronEPlot;
+    IHistogram1D fsThetayPlot;
+    ICloud1D fsGammaThetaPlot;
+    IHistogram1D fsGammaThetayPlot;
+    IHistogram1D fsGammaThetayTrigPlot;
+    ICloud2D fsGammaThetayEPlot;
+    ICloud1D fsElectronThetaPlot;
+    IHistogram1D fsElectronThetayPlot;
+    IHistogram1D fsElectronThetayTrigPlot;
+    ICloud2D fsElectronThetayEPlot;
+    ICloud1D fsPositronThetaPlot;
+    IHistogram1D fsPositronThetayPlot;
+    IHistogram1D fsPositronThetayTrigPlot;
+    ICloud2D fsPositronThetayEPlot;
         ICloud1D eventEPlot;
 
-	class MCParticleEComparator implements Comparator<MCParticle> {
-
-		public int compare(MCParticle p1, MCParticle p2) {
-			double e1 = p1.getEnergy();
-			double e2 = p2.getEnergy();
-			if (e1 < e2) {
-				return -1;
-			} else if (e1 == e2) {
-				return 0;
-			} else {
-				return 1;
-			}
-		}
-	}
+    class MCParticleEComparator implements Comparator<MCParticle> {
+
+        public int compare(MCParticle p1, MCParticle p2) {
+            double e1 = p1.getEnergy();
+            double e2 = p2.getEnergy();
+            if (e1 < e2) {
+                return -1;
+            } else if (e1 == e2) {
+                return 0;
+            } else {
+                return 1;
+            }
+        }
+    }
 
         public void setHideFrame(boolean hideFrame) {
             this._hideFrame = hideFrame;
         }
         
         
-	@Override
-	public void startOfData() {
-		fsCountPlot = aida.cloud1D("MCParticle: Number of Final State Particles");
-		fsCountPlot.annotation().addItem("xAxisLabel", "Number of FS Particles");
+    @Override
+    public void startOfData() {
+        fsCountPlot = aida.cloud1D("MCParticle: Number of Final State Particles");
+        fsCountPlot.annotation().addItem("xAxisLabel", "Number of FS Particles");
                 
                 fsCountVsEventPlot = aida.histogram1D("MCParticle: Number of Final State Particles vs Event Nr", 501, -0.5, 500.5);
-		fsCountVsEventPlot.annotation().addItem("xAxisLabel", "Event Number");
+        fsCountVsEventPlot.annotation().addItem("xAxisLabel", "Event Number");
 
                 fsCountTypePlot = aida.cloud1D("MCParticle: Number of Final State Particles Type");
-		fsCountTypePlot.annotation().addItem("xAxisLabel", "Number of FS Particles of Type");
+        fsCountTypePlot.annotation().addItem("xAxisLabel", "Number of FS Particles of Type");
 
                 fsCountTypePlot500 = aida.cloud1D("MCParticle: Number of Final State Particles Type E>0.5GeV");
-		fsCountTypePlot500.annotation().addItem("xAxisLabel", "Number of FS Particles of Type E>0.5GeV");
+        fsCountTypePlot500.annotation().addItem("xAxisLabel", "Number of FS Particles of Type E>0.5GeV");
 
                 fsCountEventTypePlot = aida.cloud1D("MCParticle: Number of Final State Types");
-		fsCountEventTypePlot.annotation().addItem("xAxisLabel", "Number of FS Types");
+        fsCountEventTypePlot.annotation().addItem("xAxisLabel", "Number of FS Types");
 
                 fsCountEventTypePlot2 = aida.cloud1D("MCParticle: Number of Final State Types Gamma E>500");
-		fsCountEventTypePlot2.annotation().addItem("xAxisLabel", "Number of FS Types Gamma E>500");                
-                
-		fsEPlot = aida.histogram1D("MCParticle: FS Particle E",100,0,3);
-		fsEPlot.annotation().addItem("xAxisLabel", "Particle E [GeV]");
-
-		fsGammaEPlot = aida.histogram1D("MCParticle: FS Gamma E",100,0,3);
-		fsGammaEPlot.annotation().addItem("xAxisLabel", "Particle E [GeV]");
-
-		fsElectronEPlot = aida.histogram1D("MCParticle: FS Electron E",100,0,3);
-		fsElectronEPlot.annotation().addItem("xAxisLabel", "Particle E [GeV]");
-
-		fsPositronEPlot = aida.histogram1D("MCParticle: FS Positron E",100,0,3);
-		fsPositronEPlot.annotation().addItem("xAxisLabel", "Particle E [GeV]");
-
-		fsGammaThetaPlot = aida.cloud1D("MCParticle: FS Gamma Theta");
-		fsGammaThetaPlot.annotation().addItem("xAxisLabel", "Particle angle [rad]");
+        fsCountEventTypePlot2.annotation().addItem("xAxisLabel", "Number of FS Types Gamma E>500");                
+                
+        fsEPlot = aida.histogram1D("MCParticle: FS Particle E",100,0,3);
+        fsEPlot.annotation().addItem("xAxisLabel", "Particle E [GeV]");
+
+        fsGammaEPlot = aida.histogram1D("MCParticle: FS Gamma E",100,0,3);
+        fsGammaEPlot.annotation().addItem("xAxisLabel", "Particle E [GeV]");
+
+        fsElectronEPlot = aida.histogram1D("MCParticle: FS Electron E",100,0,3);
+        fsElectronEPlot.annotation().addItem("xAxisLabel", "Particle E [GeV]");
+
+        fsPositronEPlot = aida.histogram1D("MCParticle: FS Positron E",100,0,3);
+        fsPositronEPlot.annotation().addItem("xAxisLabel", "Particle E [GeV]");
+
+        fsGammaThetaPlot = aida.cloud1D("MCParticle: FS Gamma Theta");
+        fsGammaThetaPlot.annotation().addItem("xAxisLabel", "Particle angle [rad]");
 
                 fsThetayPlot = aida.histogram1D("MCParticle: FS Particle Thetay",100,0,0.1);
-		fsThetayPlot.annotation().addItem("xAxisLabel", "Particle Thetay angle [rad]");
+        fsThetayPlot.annotation().addItem("xAxisLabel", "Particle Thetay angle [rad]");
 
                 
                 fsGammaThetayPlot = aida.histogram1D("MCParticle: FS Gamma Thetay",100,0,0.1);
-		fsGammaThetayPlot.annotation().addItem("xAxisLabel", "Particle Thetay angle [rad]");
+        fsGammaThetayPlot.annotation().addItem("xAxisLabel", "Particle Thetay angle [rad]");
 
                 fsGammaThetayTrigPlot = aida.histogram1D("MCParticle: FS Gamma Thetay Trig",100,0,0.1);
-		fsGammaThetayTrigPlot.annotation().addItem("xAxisLabel", "Particle Thetay angle [rad]");
+        fsGammaThetayTrigPlot.annotation().addItem("xAxisLabel", "Particle Thetay angle [rad]");
              
                 fsGammaThetayEPlot = aida.cloud2D("MCParticle: FS Gamma Thetay vs E");
-		fsGammaThetayEPlot.annotation().addItem("xAxisLabel", "Particle Thetay angle [rad]");
-		fsGammaThetayEPlot.annotation().addItem("yAxisLabel", "Particle Energy [GeV]");
-                
-		fsElectronThetaPlot = aida.cloud1D("MCParticle: FS Electron Theta");
-		fsElectronThetaPlot.annotation().addItem("xAxisLabel", "Particle angle [rad]");
+        fsGammaThetayEPlot.annotation().addItem("xAxisLabel", "Particle Thetay angle [rad]");
+        fsGammaThetayEPlot.annotation().addItem("yAxisLabel", "Particle Energy [GeV]");
+                
+        fsElectronThetaPlot = aida.cloud1D("MCParticle: FS Electron Theta");
+        fsElectronThetaPlot.annotation().addItem("xAxisLabel", "Particle angle [rad]");
 
                 fsElectronThetayPlot = aida.histogram1D("MCParticle: FS Electron Thetay",100,0,0.1);
-		fsElectronThetayPlot.annotation().addItem("xAxisLabel", "Particle Thetay angle [rad]");
+        fsElectronThetayPlot.annotation().addItem("xAxisLabel", "Particle Thetay angle [rad]");
 
                 fsElectronThetayTrigPlot = aida.histogram1D("MCParticle: FS Electron Thetay Trig",100,0,0.1);
-		fsElectronThetayTrigPlot.annotation().addItem("xAxisLabel", "Particle Thetay angle [rad]");
+        fsElectronThetayTrigPlot.annotation().addItem("xAxisLabel", "Particle Thetay angle [rad]");
 
                 fsElectronThetayEPlot = aida.cloud2D("MCParticle: FS Electron Thetay vs E");
-		fsElectronThetayEPlot.annotation().addItem("xAxisLabel", "Particle Thetay angle [rad]");
-		fsElectronThetayEPlot.annotation().addItem("yAxisLabel", "Particle Energy [GeV]");
-
-		fsPositronThetaPlot = aida.cloud1D("MCParticle: FS Positron Theta");
-		fsPositronThetaPlot.annotation().addItem("xAxisLabel", "Particle angle [rad]");
+        fsElectronThetayEPlot.annotation().addItem("xAxisLabel", "Particle Thetay angle [rad]");
+        fsElectronThetayEPlot.annotation().addItem("yAxisLabel", "Particle Energy [GeV]");
+
+        fsPositronThetaPlot = aida.cloud1D("MCParticle: FS Positron Theta");
+        fsPositronThetaPlot.annotation().addItem("xAxisLabel", "Particle angle [rad]");
 
                 fsPositronThetayPlot = aida.histogram1D("MCParticle: FS Positron Thetay",100,0,0.1);
-		fsPositronThetayPlot.annotation().addItem("xAxisLabel", "Particle Thetay angle [rad]");
+        fsPositronThetayPlot.annotation().addItem("xAxisLabel", "Particle Thetay angle [rad]");
 
                 fsPositronThetayTrigPlot = aida.histogram1D("MCParticle: FS Positron Thetay Trig",100,0,0.1);
-		fsPositronThetayTrigPlot.annotation().addItem("xAxisLabel", "Particle Thetay angle [rad]");
+        fsPositronThetayTrigPlot.annotation().addItem("xAxisLabel", "Particle Thetay angle [rad]");
 
                 fsPositronThetayEPlot = aida.cloud2D("MCParticle: FS Positron Thetay vs E");
-		fsPositronThetayEPlot.annotation().addItem("xAxisLabel", "Particle Thetay angle [rad]");
-		fsPositronThetayEPlot.annotation().addItem("yAxisLabel", "Particle Energy [GeV]");
-
-                
-		primaryEPlot = aida.cloud1D("MCParticle: Highest Primary E in Event");
-		primaryEPlot.annotation().addItem("xAxisLabel", "E [GeV]");
-
-		eventEPlot = aida.cloud1D("MCParticle: Total Gen FS Electron E in Event");
-		eventEPlot.annotation().addItem("xAxisLabel", "E [GeV]");
+        fsPositronThetayEPlot.annotation().addItem("xAxisLabel", "Particle Thetay angle [rad]");
+        fsPositronThetayEPlot.annotation().addItem("yAxisLabel", "Particle Energy [GeV]");
+
+                
+        primaryEPlot = aida.cloud1D("MCParticle: Highest Primary E in Event");
+        primaryEPlot.annotation().addItem("xAxisLabel", "E [GeV]");
+
+        eventEPlot = aida.cloud1D("MCParticle: Total Gen FS Electron E in Event");
+        eventEPlot.annotation().addItem("xAxisLabel", "E [GeV]");
 
                 
                 //pFrame = new AIDAFrame();
@@ -205,19 +205,19 @@
                 
                 
                 
-	}
-
-	@Override
-	public void process(EventHeader event) {
-
-		// MCParticles
-		List<MCParticle> mcparticles = event.get(MCParticle.class).get(0);
-
-		// Final State particles.
-		List<MCParticle> fsParticles = makeGenFSParticleList(mcparticles);
-
-		//System.out.println("fsParticles="+fsParticles.size());
-		fsCountPlot.fill(fsParticles.size());
+    }
+
+    @Override
+    public void process(EventHeader event) {
+
+        // MCParticles
+        List<MCParticle> mcparticles = event.get(MCParticle.class).get(0);
+
+        // Final State particles.
+        List<MCParticle> fsParticles = makeGenFSParticleList(mcparticles);
+
+        //System.out.println("fsParticles="+fsParticles.size());
+        fsCountPlot.fill(fsParticles.size());
                 
                 for (int i=0;i<fsParticles.size();++i) fsCountVsEventPlot.fill(event.getEventNumber());
                 
@@ -229,69 +229,69 @@
                 int[] ngammas = {0,0};
                 int count = 0;
                 double trigThr = 0.2;
-		for (MCParticle fs : fsParticles) {
+        for (MCParticle fs : fsParticles) {
                         //System.out.println("Index " + count);
 
-			double fsE = fs.getEnergy();
-			double theta = Math.atan2(Math.sqrt(fs.getPX() * fs.getPX() + fs.getPY() * fs.getPY()), fs.getPZ());
-			double thetay = Math.atan2(fs.getPY(), fs.getPZ());
-			int fsPdg = fs.getPDGID();
-			fsEPlot.fill(fsE);
+            double fsE = fs.getEnergy();
+            double theta = Math.atan2(Math.sqrt(fs.getPX() * fs.getPX() + fs.getPY() * fs.getPY()), fs.getPZ());
+            double thetay = Math.atan2(fs.getPY(), fs.getPZ());
+            int fsPdg = fs.getPDGID();
+            fsEPlot.fill(fsE);
                         this.fsThetayPlot.fill(Math.abs(thetay));
                         fsCountTypePlot.fill(fsPdg);
                         if(fsE>0.5) fsCountTypePlot500.fill(fsPdg);
-			if (ParticleTypeClassifier.isElectron(fsPdg)) {
-				fsElectronEPlot.fill(fsE);
-				fsElectronThetaPlot.fill(theta);
-				fsElectronThetayPlot.fill(Math.abs(thetay));
-				if(fsE>trigThr) fsElectronThetayTrigPlot.fill(Math.abs(thetay));
-				fsElectronThetayEPlot.fill(Math.abs(thetay),fsE);
+            if (ParticleTypeClassifier.isElectron(fsPdg)) {
+                fsElectronEPlot.fill(fsE);
+                fsElectronThetaPlot.fill(theta);
+                fsElectronThetayPlot.fill(Math.abs(thetay));
+                if(fsE>trigThr) fsElectronThetayTrigPlot.fill(Math.abs(thetay));
+                fsElectronThetayEPlot.fill(Math.abs(thetay),fsE);
                                 nelectrons[0]++;
                                 if(fsGammaEmax>0.5) nelectrons[1]++; 
-			} else if (ParticleTypeClassifier.isPositron(fsPdg)) {
-				fsPositronEPlot.fill(fsE);
-				fsPositronThetaPlot.fill(theta);
-				fsPositronThetayPlot.fill(Math.abs(thetay));
-				if(fsE>trigThr) fsPositronThetayTrigPlot.fill(Math.abs(thetay));
-				fsPositronThetayEPlot.fill(Math.abs(thetay),fsE);
+            } else if (ParticleTypeClassifier.isPositron(fsPdg)) {
+                fsPositronEPlot.fill(fsE);
+                fsPositronThetaPlot.fill(theta);
+                fsPositronThetayPlot.fill(Math.abs(thetay));
+                if(fsE>trigThr) fsPositronThetayTrigPlot.fill(Math.abs(thetay));
+                fsPositronThetayEPlot.fill(Math.abs(thetay),fsE);
                                 npositrons[0]++;
                                 if(fsGammaEmax>0.5) npositrons[1]++; 
-			} else if (ParticleTypeClassifier.isPhoton(fsPdg)) {
-				fsGammaEPlot.fill(fsE);
-				fsGammaThetaPlot.fill(theta);
-				fsGammaThetayPlot.fill(Math.abs(thetay));
-				if(fsE>trigThr) fsGammaThetayTrigPlot.fill(Math.abs(thetay));
-				fsGammaThetayEPlot.fill(Math.abs(thetay),fsE);
+            } else if (ParticleTypeClassifier.isPhoton(fsPdg)) {
+                fsGammaEPlot.fill(fsE);
+                fsGammaThetaPlot.fill(theta);
+                fsGammaThetayPlot.fill(Math.abs(thetay));
+                if(fsE>trigThr) fsGammaThetayTrigPlot.fill(Math.abs(thetay));
+                fsGammaThetayEPlot.fill(Math.abs(thetay),fsE);
                                 ngammas[0]++;
                                 if(fsGammaEmax>0.5) {
                                     ngammas[1]++;
                                     //System.out.println("Counting high E gamma at count "+ count);
                                 } 
-			}
-		}
+            }
+        }
 
                 fsCountEventTypePlot.fill(getEventTypeId(nelectrons[0],npositrons[0],ngammas[0]));
                 fsCountEventTypePlot2.fill(getEventTypeId(nelectrons[1],npositrons[1],ngammas[1]));
 
-		// Sort MCParticles on energy.
-		//Collections.sort(fsParticles, new MCParticleEComparator());
-
-		// Energy of top two FS particles.
-		//double e2 = fsParticles.get(0).getEnergy() + fsParticles.get(1).getEnergy();
-
-		// Energy of top three FS particles.
-		//double e3 = e2 + fsParticles.get(2).getEnergy();
-
-		if (!fsParticles.isEmpty()) {
-			// primary particle with most E
-			double primaryE = getPrimary(fsParticles).getEnergy();
-			primaryEPlot.fill(primaryE);
-		}
-
-		// event electron energy
-		double eventE = getPrimaryElectronE(fsParticles);
-		eventEPlot.fill(eventE);
-	}
+        // Sort MCParticles on energy.
+        //Collections.sort(fsParticles, new MCParticleEComparator());
+
+        // Energy of top two FS particles.
+        //double e2 = fsParticles.get(0).getEnergy() + fsParticles.get(1).getEnergy();
+
+        // Energy of top three FS particles.
+        //double e3 = e2 + fsParticles.get(2).getEnergy();
+
+        if (!fsParticles.isEmpty()) {
+            // primary particle with most E
+            double primaryE = getPrimary(fsParticles).getEnergy();
+            primaryEPlot.fill(primaryE);
+        }
+
+        // event electron energy
+        double eventE = getPrimaryElectronE(fsParticles);
+        eventEPlot.fill(eventE);
+    }
 
         
         public int getEventTypeId(int ne, int np, int ng) {
@@ -314,57 +314,57 @@
             return 0;
         }
         
-	public double getHighestPhotonE(List<MCParticle> particles) {
-		double Emax = -1;
+    public double getHighestPhotonE(List<MCParticle> particles) {
+        double Emax = -1;
                 double E=0;
                 int count = 0;
-		for (MCParticle particle : particles) {
-			if (ParticleTypeClassifier.isPhoton(particle.getPDGID())) {
-				E = particle.getEnergy();
+        for (MCParticle particle : particles) {
+            if (ParticleTypeClassifier.isPhoton(particle.getPDGID())) {
+                E = particle.getEnergy();
                                 if(E>Emax) {
                                     Emax = E;
                                     //System.out.println("Emax from photon with index " + count);
                                 }
-			count++;
+            count++;
                         }
-		}
-		return Emax;
-	}
+        }
+        return Emax;
+    }
 
         private double getPrimaryElectronE(List<MCParticle> particles) {
-		double totalE = 0;
-		for (MCParticle particle : particles) {
-			if (Math.abs(particle.getPDGID()) == 11) {
-				totalE += particle.getEnergy();
-			}
-		}
-		return totalE;
-	}
-
-	private MCParticle getPrimary(List<MCParticle> particles) {
-		double maxE = 0;
-		MCParticle primary = null;
-		for (MCParticle particle : particles) {
-			if (particle.getEnergy() > maxE) {
-				maxE = particle.getEnergy();
-				primary = particle;
-			}
-		}
-		return primary;
-	}
-
-	public static List<MCParticle> makeGenFSParticleList(List<MCParticle> mcparticles) {
-		List<MCParticle> fsParticles = new ArrayList<MCParticle>();
-		for (MCParticle mcparticle : mcparticles) {
-			if (mcparticle.getGeneratorStatus() == MCParticle.FINAL_STATE) {
-				double theta = Math.atan2(Math.sqrt(mcparticle.getPX() * mcparticle.getPX() + mcparticle.getPY() * mcparticle.getPY()), mcparticle.getPZ());
-				if (theta > 1e-3) {
-					fsParticles.add(mcparticle);
-				}
-			}
-		}
-		return fsParticles;
-	}
+        double totalE = 0;
+        for (MCParticle particle : particles) {
+            if (Math.abs(particle.getPDGID()) == 11) {
+                totalE += particle.getEnergy();
+            }
+        }
+        return totalE;
+    }
+
+    private MCParticle getPrimary(List<MCParticle> particles) {
+        double maxE = 0;
+        MCParticle primary = null;
+        for (MCParticle particle : particles) {
+            if (particle.getEnergy() > maxE) {
+                maxE = particle.getEnergy();
+                primary = particle;
+            }
+        }
+        return primary;
+    }
+
+    public static List<MCParticle> makeGenFSParticleList(List<MCParticle> mcparticles) {
+        List<MCParticle> fsParticles = new ArrayList<MCParticle>();
+        for (MCParticle mcparticle : mcparticles) {
+            if (mcparticle.getGeneratorStatus() == MCParticle.FINAL_STATE) {
+                double theta = Math.atan2(Math.sqrt(mcparticle.getPX() * mcparticle.getPX() + mcparticle.getPY() * mcparticle.getPY()), mcparticle.getPZ());
+                if (theta > 1e-3) {
+                    fsParticles.add(mcparticle);
+                }
+            }
+        }
+        return fsParticles;
+    }
         
         
         public void endOfData() {

Modified: java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/ecal/cosmic/DualThresholdSignalFitDriver.java
 =============================================================================
--- java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/ecal/cosmic/DualThresholdSignalFitDriver.java	(original)
+++ java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/ecal/cosmic/DualThresholdSignalFitDriver.java	Wed Apr 27 11:11:32 2016
@@ -182,7 +182,7 @@
      * Process the event, performing a signal fit for every raw data hit in the input collection.
      * The hits that pass the sigma selection cut are added to a new hits collection, which can be
      * converted to a CalorimeterHit collection and then clustered.
-     * @throw NextEventException if there are not enough hits that pass the selection cut.
+     * @throws NextEventException if there are not enough hits that pass the selection cut.
      */
     public void process(EventHeader event) {
         if (event.hasCollection(RawTrackerHit.class, inputHitsCollectionName)) {

Modified: java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/ecal/cosmic/RawModeHitSelectionDriver.java
 =============================================================================
--- java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/ecal/cosmic/RawModeHitSelectionDriver.java	(original)
+++ java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/ecal/cosmic/RawModeHitSelectionDriver.java	Wed Apr 27 11:11:32 2016
@@ -54,7 +54,7 @@
 
     /**
      * Set the number of ADC samples in a row which must be above the threshold.
-     * @param selectedHits The minimum number of samples above threshold.
+     * @param minimumSelectedSamples The minimum number of samples above threshold.
      */
     public void setMinimumSelectedSamples(int minimumSelectedSamples) {
         this.minimumSelectedSamples = minimumSelectedSamples;

Modified: java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/ecal/cosmic/RawModeSignalFitDriver.java
 =============================================================================
--- java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/ecal/cosmic/RawModeSignalFitDriver.java	(original)
+++ java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/ecal/cosmic/RawModeSignalFitDriver.java	Wed Apr 27 11:11:32 2016
@@ -168,7 +168,7 @@
      * Process the event, performing a signal fit for every raw data hit in the input collection.
      * The hits that pass the sigma selection cut are added to a new hits collection, which can be
      * converted to a CalorimeterHit collection and then clustered.
-     * @throw NextEventException if there are not enough hits that pass the selection cut.
+     * @throws NextEventException if there are not enough hits that pass the selection cut.
      */
     public void process(EventHeader event) {
         if (event.hasCollection(RawTrackerHit.class, inputHitsCollectionName)) {

Modified: java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/examples/PrintGeometryDriver.java
 =============================================================================
--- java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/examples/PrintGeometryDriver.java	(original)
+++ java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/examples/PrintGeometryDriver.java	Wed Apr 27 11:11:32 2016
@@ -2,8 +2,9 @@
 
 import hep.physics.vec.BasicHep3Vector;
 import hep.physics.vec.Hep3Vector;
-import java.util.ArrayList;
+
 import java.util.List;
+
 import org.lcsim.detector.IDetectorElement;
 import org.lcsim.detector.ITransform3D;
 import org.lcsim.detector.Transform3D;
@@ -13,13 +14,7 @@
 import org.lcsim.detector.tracker.silicon.SiSensor;
 import org.lcsim.detector.tracker.silicon.SiSensorElectrodes;
 import org.lcsim.detector.tracker.silicon.SiTrackerIdentifierHelper;
-import org.lcsim.event.RawTrackerHit;
-import org.lcsim.event.SimTrackerHit;
-import org.lcsim.event.base.BaseRawTrackerHit;
 import org.lcsim.geometry.Detector;
-import org.hps.recon.tracking.MaterialSupervisor;
-import org.hps.recon.tracking.TrackerHitUtils;
-import org.lcsim.recon.tracking.digitization.sisim.TrackerHitType;
 import org.lcsim.util.Driver;
 
 /**

Modified: java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/examples/StripGoldenEventsDriver.java
 =============================================================================
--- java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/examples/StripGoldenEventsDriver.java	(original)
+++ java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/examples/StripGoldenEventsDriver.java	Wed Apr 27 11:11:32 2016
@@ -1,11 +1,11 @@
 package org.hps.analysis.examples;
 
 import java.util.List;
+
 import org.lcsim.event.Cluster;
 import org.lcsim.event.EventHeader;
 import org.lcsim.event.ReconstructedParticle;
 import org.lcsim.event.Track;
-import org.lcsim.event.Vertex;
 import org.lcsim.util.Driver;
 
 /**
@@ -27,7 +27,7 @@
         boolean skipEvent = false;
         if (event.hasCollection(ReconstructedParticle.class, "UnconstrainedV0Candidates")) {
             List<ReconstructedParticle> vertices = event.get(ReconstructedParticle.class, "UnconstrainedV0Candidates");
-	    //System.out.println("Thete are: "+vertices.size()+" Unconstrained V0 candidates");
+        //System.out.println("Thete are: "+vertices.size()+" Unconstrained V0 candidates");
             if (vertices.size() > 1 || vertices.isEmpty()) {
                 skipEvent = true;
             } else {
@@ -38,14 +38,14 @@
                     List<Track> trks = rp.getTracks();
                     // require each track to have six hits
                     if (trks.get(0).getTrackerHits().size() != 6) {
-			//System.out.println("Thete are: "+trks.get(0).getTrackerHits().size()+" hits on Track");
+            //System.out.println("Thete are: "+trks.get(0).getTrackerHits().size()+" hits on Track");
                         skipEvent = true;
                     }
                 }
                 // require no other tracks in the event
                 if (event.get(Track.class, "MatchedTracks").size() > 2) {
                     skipEvent = true;
-		    //System.out.println("Thete are: "+event.get(Track.class, "MatchedTracks").size()+" Matched tracks");
+            //System.out.println("Thete are: "+event.get(Track.class, "MatchedTracks").size()+" Matched tracks");
                 }
                 // require no other clusters in the event
                 if (event.get(Cluster.class, "EcalClustersGTP").size() > 2) {

Modified: java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/examples/StripMollerEventsDriver.java
 =============================================================================
--- java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/examples/StripMollerEventsDriver.java	(original)
+++ java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/examples/StripMollerEventsDriver.java	Wed Apr 27 11:11:32 2016
@@ -94,7 +94,7 @@
                             skipEvent = false;
                         }
                     }
-		    //System.out.println("Thete are: "+event.get(Track.class, "MatchedTracks").size()+" Matched tracks");
+            //System.out.println("Thete are: "+event.get(Track.class, "MatchedTracks").size()+" Matched tracks");
                 }
             }
         }

Modified: java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/DataTriggerSimDriver.java
 =============================================================================
--- java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/DataTriggerSimDriver.java	(original)
+++ java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/DataTriggerSimDriver.java	Wed Apr 27 11:11:32 2016
@@ -48,454 +48,454 @@
  * output object is not persisted into LCIO after runtime.
  * 
  * @author Kyle McCarty <[log in to unmask]>
- * @see DAQConfigDriver
- * @see EcalOnlineRawConverterDriver
- * @see GTPOnlineClusterDriver
+ * @see org.hps.record.daqconfig.DAQConfigDriver
+ * @see org.hps.recon.ecal.EcalOnlineRawConverterDriver
+ * @see org.hps.recon.ecal.cluster.GTPOnlineClusterDriver
  * @see SimTriggerData
  */
 public class DataTriggerSimDriver extends Driver {
-	// Store the LCIO collection names for the needed objects.
-	private boolean filterUnverifiable = false;
-	private String bankCollectionName = "TriggerBank";
-	private String clusterCollectionName = "EcalClusters";
-	private String simTriggerCollectionName = "SimTriggers";
-	
-	// Store the SSP bank.
-	private SSPData sspBank = null;
-	
-	// Store cluster verifiability parameters.
-	private int nsa = 0;
-	private int nsb = 0;
-	private int windowWidth = 0;
-	
-	// Define trigger simulation modules.
-	private boolean[] pairTriggerEnabled = new boolean[2];
-	private boolean[] singlesTriggerEnabled = new boolean[2];
-	private boolean[][] pairCutsEnabled = new boolean[2][7];
-	private boolean[][] singlesCutsEnabled = new boolean[2][3];
-	private TriggerModule[] pairsTrigger = new TriggerModule[2];
-	private TriggerModule[] singlesTrigger = new TriggerModule[2];
-	
-	// Reference variables.
-	private static final int ENERGY_MIN   = TriggerDiagnosticUtil.SINGLES_ENERGY_MIN;
-	private static final int ENERGY_MAX   = TriggerDiagnosticUtil.SINGLES_ENERGY_MAX;
-	private static final int HIT_COUNT    = TriggerDiagnosticUtil.SINGLES_HIT_COUNT;
-	private static final int ENERGY_SUM   = TriggerDiagnosticUtil.PAIR_ENERGY_SUM;
-	private static final int ENERGY_DIFF  = TriggerDiagnosticUtil.PAIR_ENERGY_DIFF;
-	private static final int ENERGY_SLOPE = TriggerDiagnosticUtil.PAIR_ENERGY_SLOPE;
-	private static final int COPLANARITY  = TriggerDiagnosticUtil.PAIR_COPLANARITY;
-	
-	/**
-	 * Connects the driver to the the <code>ConfigurationManager</code>
-	 * in order to obtain the correct trigger information. Trigger
-	 * settings are stored in the <code>TriggerModule</code> objects.
-	 */
-	@Override
-	public void startOfData() {
-		// Define the first singles trigger.
-		singlesTrigger[0] = new TriggerModule();
-		singlesTrigger[0].setCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_LOW, 0.500);
-		singlesTrigger[0].setCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_HIGH, 8.191);
-		singlesTrigger[0].setCutValue(TriggerModule.CLUSTER_HIT_COUNT_LOW, 0);
-		
-		// Define the second singles trigger.
-		singlesTrigger[1] = new TriggerModule();
-		singlesTrigger[1].setCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_LOW, 0.000);
-		singlesTrigger[1].setCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_HIGH, 8.191);
-		singlesTrigger[1].setCutValue(TriggerModule.CLUSTER_HIT_COUNT_LOW, 0);
-		
-		// Define the first pairs trigger.
-		pairsTrigger[0] = new TriggerModule();
-		pairsTrigger[0].setCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_LOW, 0.000);
-		pairsTrigger[0].setCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_HIGH, 8.191);
-		pairsTrigger[0].setCutValue(TriggerModule.CLUSTER_HIT_COUNT_LOW, 0);
-		pairsTrigger[0].setCutValue(TriggerModule.PAIR_ENERGY_SUM_LOW, 0.000);
-		pairsTrigger[0].setCutValue(TriggerModule.PAIR_ENERGY_SUM_HIGH, 8.191);
-		pairsTrigger[0].setCutValue(TriggerModule.PAIR_ENERGY_DIFFERENCE_HIGH, 8.191);
-		pairsTrigger[0].setCutValue(TriggerModule.PAIR_ENERGY_SLOPE_LOW, 0.000);
-		pairsTrigger[0].setCutValue(TriggerModule.PAIR_ENERGY_SLOPE_F, 0.001);
-		pairsTrigger[0].setCutValue(TriggerModule.PAIR_COPLANARITY_HIGH, 180);
-		pairsTrigger[0].setCutValue(TriggerModule.PAIR_TIME_COINCIDENCE, 8);
-		
-		// Define the second pairs trigger.
-		pairsTrigger[1] = new TriggerModule();
-		pairsTrigger[1].setCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_LOW, 0.000);
-		pairsTrigger[1].setCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_HIGH, 8.191);
-		pairsTrigger[1].setCutValue(TriggerModule.CLUSTER_HIT_COUNT_LOW, 0);
-		pairsTrigger[1].setCutValue(TriggerModule.PAIR_ENERGY_SUM_LOW, 0.000);
-		pairsTrigger[1].setCutValue(TriggerModule.PAIR_ENERGY_SUM_HIGH, 8.191);
-		pairsTrigger[1].setCutValue(TriggerModule.PAIR_ENERGY_DIFFERENCE_HIGH, 8.191);
-		pairsTrigger[1].setCutValue(TriggerModule.PAIR_ENERGY_SLOPE_LOW, 0.000);
-		pairsTrigger[1].setCutValue(TriggerModule.PAIR_ENERGY_SLOPE_F, 0.001);
-		pairsTrigger[1].setCutValue(TriggerModule.PAIR_COPLANARITY_HIGH, 180);
-		pairsTrigger[1].setCutValue(TriggerModule.PAIR_TIME_COINCIDENCE, 8);
-		
-		// Listen for the configuration manager to provide the real
-		// trigger settings.
-		ConfigurationManager.addActionListener(new ActionListener() {
-			@Override
-			public void actionPerformed(ActionEvent e) {
-				// Get the DAQ configuration.
-				DAQConfig daq = ConfigurationManager.getInstance();
-				
-				// Get cluster verifiability parameters.
-				nsa = daq.getFADCConfig().getNSA();
-				nsb = daq.getFADCConfig().getNSB();
-				windowWidth = daq.getFADCConfig().getWindowWidth();
-				
-				// Load the DAQ settings from the configuration manager.
-				singlesTrigger[0].loadDAQConfiguration(daq.getSSPConfig().getSingles1Config());
-				singlesTrigger[1].loadDAQConfiguration(daq.getSSPConfig().getSingles2Config());
-				pairsTrigger[0].loadDAQConfiguration(daq.getSSPConfig().getPair1Config());
-				pairsTrigger[1].loadDAQConfiguration(daq.getSSPConfig().getPair2Config());
-				
-				// Get the trigger configurations from the DAQ.
-				SinglesTriggerConfig[] singles = { daq.getSSPConfig().getSingles1Config(),
-						daq.getSSPConfig().getSingles2Config() };
-				PairTriggerConfig[] pairs = { daq.getSSPConfig().getPair1Config(),
-						daq.getSSPConfig().getPair2Config() };
-				
-				// Update the enabled/disabled statuses.
-				for(int i = 0; i < 2; i++) {
-					// Set the trigger enabled status.
-					pairTriggerEnabled[i] = pairs[i].isEnabled();
-					singlesTriggerEnabled[i] = singles[i].isEnabled();
-					
-					// Set the singles cut statuses.
-					singlesCutsEnabled[i][ENERGY_MIN] = singles[i].getEnergyMinCutConfig().isEnabled();
-					singlesCutsEnabled[i][ENERGY_MAX] = singles[i].getEnergyMaxCutConfig().isEnabled();
-					singlesCutsEnabled[i][HIT_COUNT] = singles[i].getHitCountCutConfig().isEnabled();
-					
-					// Set the pair cut statuses.
-					pairCutsEnabled[i][ENERGY_MIN] = pairs[i].getEnergyMinCutConfig().isEnabled();
-					pairCutsEnabled[i][ENERGY_MAX] = pairs[i].getEnergyMaxCutConfig().isEnabled();
-					pairCutsEnabled[i][HIT_COUNT] = pairs[i].getHitCountCutConfig().isEnabled();
-					pairCutsEnabled[i][3 + ENERGY_SUM] = pairs[i].getEnergySumCutConfig().isEnabled();
-					pairCutsEnabled[i][3 + ENERGY_DIFF] = pairs[i].getEnergyDifferenceCutConfig().isEnabled();
-					pairCutsEnabled[i][3 + ENERGY_SLOPE] = pairs[i].getEnergySlopeCutConfig().isEnabled();
-					pairCutsEnabled[i][3 + COPLANARITY] = pairs[i].getCoplanarityCutConfig().isEnabled();
-				}
-			}
-		});
-	}
-	
-	/**
-	 * Processes an LCIO event and simulates triggers in the same manner
-	 * as the hardware for both <code>SSPCluster</code> objects as well
-	 * as <code>Cluster</code> objects reconstructed from FADC hits.
-	 * Triggers are then output to the data stream.
-	 * @param event - The <code>EventHeader</code> object representing
-	 * the current LCIO event.
-	 */
-	@Override
-	public void process(EventHeader event) {
-		// If the DAQ configuration manager has not been initialized,
-		// then no action can be performed.
-		if(!ConfigurationManager.isInitialized()) {
-			// Put an empty trigger results module into the data stream.
-			SimTriggerData triggerData = new SimTriggerData();
-			List<SimTriggerData> dataList = new ArrayList<SimTriggerData>(1);
-			dataList.add(triggerData);
-			event.put(simTriggerCollectionName, dataList, SimTriggerData.class, 0);
-			
-			// Nothing further can be done, since trigger settings are
-			// not yet defined.
-			return;
-		}
-		
-		// Get the SSP bank.
-		if(event.hasCollection(GenericObject.class, bankCollectionName)) {
-			// Get the bank list.
-			List<GenericObject> bankList = event.get(GenericObject.class, bankCollectionName);
-			
-			// Search through the banks and get the SSP and TI banks.
-			for(GenericObject obj : bankList) {
-				// If this is an SSP bank, parse it.
-				if(AbstractIntData.getTag(obj) == SSPData.BANK_TAG) {
-					sspBank = new SSPData(obj);
-				}
-			}
-		}
-		
-		// Get a list of SSPClusters.
-		List<SSPCluster> sspClusters = null;
-		if(sspBank != null) { sspClusters = sspBank.getClusters(); }
-		else { sspClusters = new ArrayList<SSPCluster>(0); }
-		
-		// Get reconstructed clusters.
-		List<Cluster> reconClusters = null;
-		if(event.hasCollection(Cluster.class, clusterCollectionName)) {
-			reconClusters = event.get(Cluster.class, clusterCollectionName);
-		}
-		else { reconClusters = new ArrayList<Cluster>(0); }
-		
-		// If only "verifiable" clusters should be used, test all the
-		// reconstructed clusters for verifiability.
-		if(filterUnverifiable) {
-			// Create a list to store the verifiable clusters.
-			List<Cluster> goodClusters = new ArrayList<Cluster>();
-			
-			// Iterate over all the clusters and test them to see if
-			// they are verifiable.
-			for(Cluster cluster : reconClusters) {
-				if(TriggerDiagnosticUtil.isVerifiable(cluster, nsa, nsb, windowWidth)) {
-					goodClusters.add(cluster);
-				}
-			}
-			
-			// Replace the old cluster list with the new one.
-			reconClusters = goodClusters;
-		}
-		
-		// Generate simulated triggers.
-		SimTriggerModule<Cluster> reconModule = constructTriggers(reconClusters, Cluster.class);
-		SimTriggerModule<SSPCluster> sspModule = constructTriggers(sspClusters, SSPCluster.class);
-		
-		// Insert the trigger results in the data stream.
-		SimTriggerData triggerData = new SimTriggerData(reconModule, sspModule);
-		List<SimTriggerData> dataList = new ArrayList<SimTriggerData>(1);
-		dataList.add(triggerData);
-		event.put(simTriggerCollectionName, dataList, SimTriggerData.class, 0);
-	}
-	
-	/**
-	 * Constructs simulated triggers in the same manner as the hardware.
-	 * Method can accept either <code>Cluster</code> objects, any object
-	 * that is a subclass of <code>Cluster</code>, or objects of type
-	 * <code>SSPCluster</code>.
-	 * @param clusters - A <code>List</code> collection of the cluster
-	 * objects from which triggers are to be derived.
-	 * @param clusterType - The class of the cluster objects from which
-	 * triggers are to be derived. This can be <code>Cluster</code>,
-	 * <code>SSPCluster</code>, or a subclass thereof.
-	 * @return Returns a <code>SimTriggerModule</code> object containing
-	 * the simulated trigger results.
-	 * @throws IllegalArgumentException Occurs if the class of the
-	 * cluster objects is not of a supported type.
-	 * 
-	 */
-	private <E> SimTriggerModule<E> constructTriggers(List<E> clusters, Class<E> clusterType) throws IllegalArgumentException {
-		// Verify that the cluster type is supported.
-		if(!clusterType.equals(Cluster.class) && !clusterType.equals(SSPCluster.class)) {
-			throw new IllegalArgumentException("Class \"" + clusterType.getSimpleName() + "\" is not a supported cluster type.");
-		}
-		
-		// Store the singles and pair triggers.
-		List<List<PairTrigger<E[]>>> pairTriggers = new ArrayList<List<PairTrigger<E[]>>>(2);
-		pairTriggers.add(new ArrayList<PairTrigger<E[]>>());
-		pairTriggers.add(new ArrayList<PairTrigger<E[]>>());
-		List<List<SinglesTrigger<E>>> singlesTriggers = new ArrayList<List<SinglesTrigger<E>>>(2);
-		singlesTriggers.add(new ArrayList<SinglesTrigger<E>>());
-		singlesTriggers.add(new ArrayList<SinglesTrigger<E>>());
-		
-		// Run the clusters through the singles trigger to determine
-		// whether or not they pass it.
-		for(E cluster : clusters) {
-			// Simulate each of the cluster singles triggers.
-			triggerLoop:
-			for(int triggerNum = 0; triggerNum < 2; triggerNum++) {
-				// Track whether the cluster passed each singles cut.
-				boolean passSeedLow = true;
-				boolean passSeedHigh = true;
-				boolean passClusterLow = false;
-				boolean passClusterHigh = false;
-				boolean passHitCount = false;
-				
-				// Perform the trigger cuts appropriately for the type
-				// of cluster.
-				if(cluster instanceof Cluster) {
-					// Cast the cluster to the appropriate type.
-					Cluster c = (Cluster) cluster;
-					
-					// Perform each trigger cut.
-					passClusterLow = singlesTrigger[triggerNum].clusterTotalEnergyCutLow(c);
-					passClusterHigh = singlesTrigger[triggerNum].clusterTotalEnergyCutHigh(c);
-					passHitCount = singlesTrigger[triggerNum].clusterHitCountCut(c);
-				} else if(cluster instanceof SSPCluster) {
-					// Cast the cluster to the appropriate type.
-					SSPCluster c = (SSPCluster) cluster;
-					
-					// Perform each trigger cut.
-					passClusterLow = singlesTrigger[triggerNum].clusterTotalEnergyCutLow(c);
-					passClusterHigh = singlesTrigger[triggerNum].clusterTotalEnergyCutHigh(c);
-					passHitCount = singlesTrigger[triggerNum].clusterHitCountCut(c);
-				}
-				
-				// Make a trigger to store the results.
-				SinglesTrigger<E> trigger = new SinglesTrigger<E>(cluster, triggerNum);
-				trigger.setStateSeedEnergyLow(passSeedLow);
-				trigger.setStateSeedEnergyHigh(passSeedHigh);
-				trigger.setStateClusterEnergyLow(passClusterLow);
-				trigger.setStateClusterEnergyHigh(passClusterHigh);
-				trigger.setStateHitCount(passHitCount);
-				
-				// A trigger will only be reported by the SSP if it
-				// passes all of the enabled cuts for that trigger.
-				// Check whether this trigger meets these conditions.
-				if(singlesCutsEnabled[triggerNum][ENERGY_MIN] && !trigger.getStateClusterEnergyLow()) {
-					continue triggerLoop;
-				} if(singlesCutsEnabled[triggerNum][ENERGY_MAX] && !trigger.getStateClusterEnergyHigh()) {
-					continue triggerLoop;
-				} if(singlesCutsEnabled[triggerNum][HIT_COUNT] && !trigger.getStateHitCount()) {
-					continue triggerLoop;
-				}
-				
-				// Store the trigger.
-				singlesTriggers.get(triggerNum).add(trigger);
-			}
-		}
-		
-		// Store cluster pairs.
-		List<E[]> pairs = TriggerModule.getTopBottomPairs(clusters, clusterType);
-		
-		// Simulate the pair triggers and record the results.
-		for(E[] pair : pairs) {
-			// Simulate each of the cluster pair triggers.
-			pairTriggerLoop:
-			for(int triggerIndex = 0; triggerIndex < 2; triggerIndex++) {
-				// Track whether the cluster passed each singles cut.
-				boolean passSeedLow = true;
-				boolean passSeedHigh = true;
-				boolean passClusterLow = false;
-				boolean passClusterHigh = false;
-				boolean passHitCount = false;
-				boolean passPairEnergySumLow = false;
-				boolean passPairEnergySumHigh = false;
-				boolean passPairEnergyDifference = false;
-				boolean passPairEnergySlope = false;
-				boolean passPairCoplanarity = false;
-				boolean passTimeCoincidence = false;
-				
-				// Apply the trigger cuts appropriately according to the
-				// cluster type.
-				if(clusterType.equals(Cluster.class)) {
-					// Cast the cluster object.
-					Cluster[] reconPair = { (Cluster) pair[0], (Cluster) pair[1] };
-					
-					// Check that the pair passes the time coincidence cut.
-					// If it does not, it is not a valid pair and should be
-					// destroyed.
-					if(!pairsTrigger[triggerIndex].pairTimeCoincidenceCut(reconPair)) {
-						continue pairTriggerLoop;
-					}
-					
-					passClusterLow = pairsTrigger[triggerIndex].clusterTotalEnergyCutLow(reconPair[0])
-							&& pairsTrigger[triggerIndex].clusterTotalEnergyCutLow(reconPair[1]);
-					passClusterHigh = pairsTrigger[triggerIndex].clusterTotalEnergyCutHigh(reconPair[0])
-							&& pairsTrigger[triggerIndex].clusterTotalEnergyCutHigh(reconPair[1]);
-					passHitCount = pairsTrigger[triggerIndex].clusterHitCountCut(reconPair[0])
-							&& pairsTrigger[triggerIndex].clusterHitCountCut(reconPair[1]);
-					passPairEnergySumLow = pairsTrigger[triggerIndex].pairEnergySumCutLow(reconPair);
-					passPairEnergySumHigh = pairsTrigger[triggerIndex].pairEnergySumCutHigh(reconPair);
-					passPairEnergyDifference = pairsTrigger[triggerIndex].pairEnergyDifferenceCut(reconPair);
-					passPairEnergySlope = pairsTrigger[triggerIndex].pairEnergySlopeCut(reconPair);
-					passPairCoplanarity = pairsTrigger[triggerIndex].pairCoplanarityCut(reconPair);
-					passTimeCoincidence = pairsTrigger[triggerIndex].pairTimeCoincidenceCut(reconPair);
-				} else if(clusterType.equals(SSPCluster.class)) {
-					// Cast the cluster object.
-					SSPCluster[] sspPair = { (SSPCluster) pair[0], (SSPCluster) pair[1] };
-					
-					// Check that the pair passes the time coincidence cut.
-					// If it does not, it is not a valid pair and should be
-					// destroyed.
-					if(!pairsTrigger[triggerIndex].pairTimeCoincidenceCut(sspPair)) {
-						continue pairTriggerLoop;
-					}
-					
-					// Perform each trigger cut.
-					passClusterLow = pairsTrigger[triggerIndex].clusterTotalEnergyCutLow(sspPair[0])
-							&& pairsTrigger[triggerIndex].clusterTotalEnergyCutLow(sspPair[1]);
-					passClusterHigh = pairsTrigger[triggerIndex].clusterTotalEnergyCutHigh(sspPair[0])
-							&& pairsTrigger[triggerIndex].clusterTotalEnergyCutHigh(sspPair[1]);
-					passHitCount = pairsTrigger[triggerIndex].clusterHitCountCut(sspPair[0])
-							&& pairsTrigger[triggerIndex].clusterHitCountCut(sspPair[1]);
-					passPairEnergySumLow = pairsTrigger[triggerIndex].pairEnergySumCutLow(sspPair);
-					passPairEnergySumHigh = pairsTrigger[triggerIndex].pairEnergySumCutHigh(sspPair);
-					passPairEnergyDifference = pairsTrigger[triggerIndex].pairEnergyDifferenceCut(sspPair);
-					passPairEnergySlope = pairsTrigger[triggerIndex].pairEnergySlopeCut(sspPair);
-					passPairCoplanarity = pairsTrigger[triggerIndex].pairCoplanarityCut(sspPair);
-					passTimeCoincidence = pairsTrigger[triggerIndex].pairTimeCoincidenceCut(sspPair);
-				}
-				
-				// Create a trigger from the results.
-				PairTrigger<E[]> trigger = new PairTrigger<E[]>(pair, triggerIndex);
-				trigger.setStateSeedEnergyLow(passSeedLow);
-				trigger.setStateSeedEnergyHigh(passSeedHigh);
-				trigger.setStateClusterEnergyLow(passClusterLow);
-				trigger.setStateClusterEnergyHigh(passClusterHigh);
-				trigger.setStateHitCount(passHitCount);
-				trigger.setStateEnergySumLow(passPairEnergySumLow);
-				trigger.setStateEnergySumHigh(passPairEnergySumHigh);
-				trigger.setStateEnergyDifference(passPairEnergyDifference);
-				trigger.setStateEnergySlope(passPairEnergySlope);
-				trigger.setStateCoplanarity(passPairCoplanarity);
-				trigger.setStateTimeCoincidence(passTimeCoincidence);
-				
-				// A trigger will only be reported by the SSP if it
-				// passes all of the enabled cuts for that trigger.
-				// Check whether this trigger meets these conditions.
-				if(pairCutsEnabled[triggerIndex][ENERGY_MIN] && !trigger.getStateClusterEnergyLow()) {
-					continue pairTriggerLoop;
-				} if(pairCutsEnabled[triggerIndex][ENERGY_MAX] && !trigger.getStateClusterEnergyHigh()) {
-					continue pairTriggerLoop;
-				} if(pairCutsEnabled[triggerIndex][HIT_COUNT] && !trigger.getStateHitCount()) {
-					continue pairTriggerLoop;
-				} if(pairCutsEnabled[triggerIndex][3 + ENERGY_SUM] && !trigger.getStateEnergySum()) {
-					continue pairTriggerLoop;
-				} if(pairCutsEnabled[triggerIndex][3 + ENERGY_DIFF] && !trigger.getStateEnergyDifference()) {
-					continue pairTriggerLoop;
-				} if(pairCutsEnabled[triggerIndex][3 + ENERGY_SLOPE] && !trigger.getStateEnergySlope()) {
-					continue pairTriggerLoop;
-				} if(pairCutsEnabled[triggerIndex][3 + COPLANARITY] && !trigger.getStateCoplanarity()) {
-					continue pairTriggerLoop;
-				}
-				
-				// Add the trigger to the list.
-				pairTriggers.get(triggerIndex).add(trigger);
-			}
-		}
-		
-		// Create a new simulated trigger module to contain the results.
-		return new SimTriggerModule<E>(singlesTriggers.get(0), singlesTriggers.get(1),
-				pairTriggers.get(0), pairTriggers.get(1));
-	}
-	
-	/**
-	 * Sets the name of the LCIO collection containing the TI and SSP
-	 * banks.
-	 * @param bankCollectionName - The bank collection name.
-	 */
-	public void setBankCollectionName(String bankCollectionName) {
-		this.bankCollectionName = bankCollectionName;
-	}
-	
-	/**
-	 * Sets the name of the LCIO collection containing the simulated
-	 * reconstructed clusters.
-	 * @param clusterCollectionName - The cluster collection name.
-	 */
-	public void setClusterCollectionName(String clusterCollectionName) {
-		this.clusterCollectionName = clusterCollectionName;
-	}
-	
-	/**
-	 * Sets whether or not triggers should be formed using all clusters,
-	 * or only those that where the integration window for the cluster
-	 * is completely within the bounds of the event window.
-	 * @param state - <code>true</code> means that only clusters where
-	 * the entire cluster integration window is within the event time
-	 * window will be used, while <code>false</code> means that all
-	 * clusters will be used.
-	 */
-	public void setFilterUnverifiableClusters(boolean state) {
-		this.filterUnverifiable = state;
-	}
-	
-	/**
-	 * Sets the name of the LCIO collection containing simulated triggers.
-	 * @param triggerCollection - The trigger collection name.
-	 */
-	public void setTriggerCollectionName(String triggerCollection) {
-		this.simTriggerCollectionName = triggerCollection;
-	}
+    // Store the LCIO collection names for the needed objects.
+    private boolean filterUnverifiable = false;
+    private String bankCollectionName = "TriggerBank";
+    private String clusterCollectionName = "EcalClusters";
+    private String simTriggerCollectionName = "SimTriggers";
+    
+    // Store the SSP bank.
+    private SSPData sspBank = null;
+    
+    // Store cluster verifiability parameters.
+    private int nsa = 0;
+    private int nsb = 0;
+    private int windowWidth = 0;
+    
+    // Define trigger simulation modules.
+    private boolean[] pairTriggerEnabled = new boolean[2];
+    private boolean[] singlesTriggerEnabled = new boolean[2];
+    private boolean[][] pairCutsEnabled = new boolean[2][7];
+    private boolean[][] singlesCutsEnabled = new boolean[2][3];
+    private TriggerModule[] pairsTrigger = new TriggerModule[2];
+    private TriggerModule[] singlesTrigger = new TriggerModule[2];
+    
+    // Reference variables.
+    private static final int ENERGY_MIN   = TriggerDiagnosticUtil.SINGLES_ENERGY_MIN;
+    private static final int ENERGY_MAX   = TriggerDiagnosticUtil.SINGLES_ENERGY_MAX;
+    private static final int HIT_COUNT    = TriggerDiagnosticUtil.SINGLES_HIT_COUNT;
+    private static final int ENERGY_SUM   = TriggerDiagnosticUtil.PAIR_ENERGY_SUM;
+    private static final int ENERGY_DIFF  = TriggerDiagnosticUtil.PAIR_ENERGY_DIFF;
+    private static final int ENERGY_SLOPE = TriggerDiagnosticUtil.PAIR_ENERGY_SLOPE;
+    private static final int COPLANARITY  = TriggerDiagnosticUtil.PAIR_COPLANARITY;
+    
+    /**
+     * Connects the driver to the the <code>ConfigurationManager</code>
+     * in order to obtain the correct trigger information. Trigger
+     * settings are stored in the <code>TriggerModule</code> objects.
+     */
+    @Override
+    public void startOfData() {
+        // Define the first singles trigger.
+        singlesTrigger[0] = new TriggerModule();
+        singlesTrigger[0].setCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_LOW, 0.500);
+        singlesTrigger[0].setCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_HIGH, 8.191);
+        singlesTrigger[0].setCutValue(TriggerModule.CLUSTER_HIT_COUNT_LOW, 0);
+        
+        // Define the second singles trigger.
+        singlesTrigger[1] = new TriggerModule();
+        singlesTrigger[1].setCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_LOW, 0.000);
+        singlesTrigger[1].setCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_HIGH, 8.191);
+        singlesTrigger[1].setCutValue(TriggerModule.CLUSTER_HIT_COUNT_LOW, 0);
+        
+        // Define the first pairs trigger.
+        pairsTrigger[0] = new TriggerModule();
+        pairsTrigger[0].setCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_LOW, 0.000);
+        pairsTrigger[0].setCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_HIGH, 8.191);
+        pairsTrigger[0].setCutValue(TriggerModule.CLUSTER_HIT_COUNT_LOW, 0);
+        pairsTrigger[0].setCutValue(TriggerModule.PAIR_ENERGY_SUM_LOW, 0.000);
+        pairsTrigger[0].setCutValue(TriggerModule.PAIR_ENERGY_SUM_HIGH, 8.191);
+        pairsTrigger[0].setCutValue(TriggerModule.PAIR_ENERGY_DIFFERENCE_HIGH, 8.191);
+        pairsTrigger[0].setCutValue(TriggerModule.PAIR_ENERGY_SLOPE_LOW, 0.000);
+        pairsTrigger[0].setCutValue(TriggerModule.PAIR_ENERGY_SLOPE_F, 0.001);
+        pairsTrigger[0].setCutValue(TriggerModule.PAIR_COPLANARITY_HIGH, 180);
+        pairsTrigger[0].setCutValue(TriggerModule.PAIR_TIME_COINCIDENCE, 8);
+        
+        // Define the second pairs trigger.
+        pairsTrigger[1] = new TriggerModule();
+        pairsTrigger[1].setCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_LOW, 0.000);
+        pairsTrigger[1].setCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_HIGH, 8.191);
+        pairsTrigger[1].setCutValue(TriggerModule.CLUSTER_HIT_COUNT_LOW, 0);
+        pairsTrigger[1].setCutValue(TriggerModule.PAIR_ENERGY_SUM_LOW, 0.000);
+        pairsTrigger[1].setCutValue(TriggerModule.PAIR_ENERGY_SUM_HIGH, 8.191);
+        pairsTrigger[1].setCutValue(TriggerModule.PAIR_ENERGY_DIFFERENCE_HIGH, 8.191);
+        pairsTrigger[1].setCutValue(TriggerModule.PAIR_ENERGY_SLOPE_LOW, 0.000);
+        pairsTrigger[1].setCutValue(TriggerModule.PAIR_ENERGY_SLOPE_F, 0.001);
+        pairsTrigger[1].setCutValue(TriggerModule.PAIR_COPLANARITY_HIGH, 180);
+        pairsTrigger[1].setCutValue(TriggerModule.PAIR_TIME_COINCIDENCE, 8);
+        
+        // Listen for the configuration manager to provide the real
+        // trigger settings.
+        ConfigurationManager.addActionListener(new ActionListener() {
+            @Override
+            public void actionPerformed(ActionEvent e) {
+                // Get the DAQ configuration.
+                DAQConfig daq = ConfigurationManager.getInstance();
+                
+                // Get cluster verifiability parameters.
+                nsa = daq.getFADCConfig().getNSA();
+                nsb = daq.getFADCConfig().getNSB();
+                windowWidth = daq.getFADCConfig().getWindowWidth();
+                
+                // Load the DAQ settings from the configuration manager.
+                singlesTrigger[0].loadDAQConfiguration(daq.getSSPConfig().getSingles1Config());
+                singlesTrigger[1].loadDAQConfiguration(daq.getSSPConfig().getSingles2Config());
+                pairsTrigger[0].loadDAQConfiguration(daq.getSSPConfig().getPair1Config());
+                pairsTrigger[1].loadDAQConfiguration(daq.getSSPConfig().getPair2Config());
+                
+                // Get the trigger configurations from the DAQ.
+                SinglesTriggerConfig[] singles = { daq.getSSPConfig().getSingles1Config(),
+                        daq.getSSPConfig().getSingles2Config() };
+                PairTriggerConfig[] pairs = { daq.getSSPConfig().getPair1Config(),
+                        daq.getSSPConfig().getPair2Config() };
+                
+                // Update the enabled/disabled statuses.
+                for(int i = 0; i < 2; i++) {
+                    // Set the trigger enabled status.
+                    pairTriggerEnabled[i] = pairs[i].isEnabled();
+                    singlesTriggerEnabled[i] = singles[i].isEnabled();
+                    
+                    // Set the singles cut statuses.
+                    singlesCutsEnabled[i][ENERGY_MIN] = singles[i].getEnergyMinCutConfig().isEnabled();
+                    singlesCutsEnabled[i][ENERGY_MAX] = singles[i].getEnergyMaxCutConfig().isEnabled();
+                    singlesCutsEnabled[i][HIT_COUNT] = singles[i].getHitCountCutConfig().isEnabled();
+                    
+                    // Set the pair cut statuses.
+                    pairCutsEnabled[i][ENERGY_MIN] = pairs[i].getEnergyMinCutConfig().isEnabled();
+                    pairCutsEnabled[i][ENERGY_MAX] = pairs[i].getEnergyMaxCutConfig().isEnabled();
+                    pairCutsEnabled[i][HIT_COUNT] = pairs[i].getHitCountCutConfig().isEnabled();
+                    pairCutsEnabled[i][3 + ENERGY_SUM] = pairs[i].getEnergySumCutConfig().isEnabled();
+                    pairCutsEnabled[i][3 + ENERGY_DIFF] = pairs[i].getEnergyDifferenceCutConfig().isEnabled();
+                    pairCutsEnabled[i][3 + ENERGY_SLOPE] = pairs[i].getEnergySlopeCutConfig().isEnabled();
+                    pairCutsEnabled[i][3 + COPLANARITY] = pairs[i].getCoplanarityCutConfig().isEnabled();
+                }
+            }
+        });
+    }
+    
+    /**
+     * Processes an LCIO event and simulates triggers in the same manner
+     * as the hardware for both <code>SSPCluster</code> objects as well
+     * as <code>Cluster</code> objects reconstructed from FADC hits.
+     * Triggers are then output to the data stream.
+     * @param event - The <code>EventHeader</code> object representing
+     * the current LCIO event.
+     */
+    @Override
+    public void process(EventHeader event) {
+        // If the DAQ configuration manager has not been initialized,
+        // then no action can be performed.
+        if(!ConfigurationManager.isInitialized()) {
+            // Put an empty trigger results module into the data stream.
+            SimTriggerData triggerData = new SimTriggerData();
+            List<SimTriggerData> dataList = new ArrayList<SimTriggerData>(1);
+            dataList.add(triggerData);
+            event.put(simTriggerCollectionName, dataList, SimTriggerData.class, 0);
+            
+            // Nothing further can be done, since trigger settings are
+            // not yet defined.
+            return;
+        }
+        
+        // Get the SSP bank.
+        if(event.hasCollection(GenericObject.class, bankCollectionName)) {
+            // Get the bank list.
+            List<GenericObject> bankList = event.get(GenericObject.class, bankCollectionName);
+            
+            // Search through the banks and get the SSP and TI banks.
+            for(GenericObject obj : bankList) {
+                // If this is an SSP bank, parse it.
+                if(AbstractIntData.getTag(obj) == SSPData.BANK_TAG) {
+                    sspBank = new SSPData(obj);
+                }
+            }
+        }
+        
+        // Get a list of SSPClusters.
+        List<SSPCluster> sspClusters = null;
+        if(sspBank != null) { sspClusters = sspBank.getClusters(); }
+        else { sspClusters = new ArrayList<SSPCluster>(0); }
+        
+        // Get reconstructed clusters.
+        List<Cluster> reconClusters = null;
+        if(event.hasCollection(Cluster.class, clusterCollectionName)) {
+            reconClusters = event.get(Cluster.class, clusterCollectionName);
+        }
+        else { reconClusters = new ArrayList<Cluster>(0); }
+        
+        // If only "verifiable" clusters should be used, test all the
+        // reconstructed clusters for verifiability.
+        if(filterUnverifiable) {
+            // Create a list to store the verifiable clusters.
+            List<Cluster> goodClusters = new ArrayList<Cluster>();
+            
+            // Iterate over all the clusters and test them to see if
+            // they are verifiable.
+            for(Cluster cluster : reconClusters) {
+                if(TriggerDiagnosticUtil.isVerifiable(cluster, nsa, nsb, windowWidth)) {
+                    goodClusters.add(cluster);
+                }
+            }
+            
+            // Replace the old cluster list with the new one.
+            reconClusters = goodClusters;
+        }
+        
+        // Generate simulated triggers.
+        SimTriggerModule<Cluster> reconModule = constructTriggers(reconClusters, Cluster.class);
+        SimTriggerModule<SSPCluster> sspModule = constructTriggers(sspClusters, SSPCluster.class);
+        
+        // Insert the trigger results in the data stream.
+        SimTriggerData triggerData = new SimTriggerData(reconModule, sspModule);
+        List<SimTriggerData> dataList = new ArrayList<SimTriggerData>(1);
+        dataList.add(triggerData);
+        event.put(simTriggerCollectionName, dataList, SimTriggerData.class, 0);
+    }
+    
+    /**
+     * Constructs simulated triggers in the same manner as the hardware.
+     * Method can accept either <code>Cluster</code> objects, any object
+     * that is a subclass of <code>Cluster</code>, or objects of type
+     * <code>SSPCluster</code>.
+     * @param clusters - A <code>List</code> collection of the cluster
+     * objects from which triggers are to be derived.
+     * @param clusterType - The class of the cluster objects from which
+     * triggers are to be derived. This can be <code>Cluster</code>,
+     * <code>SSPCluster</code>, or a subclass thereof.
+     * @return Returns a <code>SimTriggerModule</code> object containing
+     * the simulated trigger results.
+     * @throws IllegalArgumentException Occurs if the class of the
+     * cluster objects is not of a supported type.
+     * 
+     */
+    private <E> SimTriggerModule<E> constructTriggers(List<E> clusters, Class<E> clusterType) throws IllegalArgumentException {
+        // Verify that the cluster type is supported.
+        if(!clusterType.equals(Cluster.class) && !clusterType.equals(SSPCluster.class)) {
+            throw new IllegalArgumentException("Class \"" + clusterType.getSimpleName() + "\" is not a supported cluster type.");
+        }
+        
+        // Store the singles and pair triggers.
+        List<List<PairTrigger<E[]>>> pairTriggers = new ArrayList<List<PairTrigger<E[]>>>(2);
+        pairTriggers.add(new ArrayList<PairTrigger<E[]>>());
+        pairTriggers.add(new ArrayList<PairTrigger<E[]>>());
+        List<List<SinglesTrigger<E>>> singlesTriggers = new ArrayList<List<SinglesTrigger<E>>>(2);
+        singlesTriggers.add(new ArrayList<SinglesTrigger<E>>());
+        singlesTriggers.add(new ArrayList<SinglesTrigger<E>>());
+        
+        // Run the clusters through the singles trigger to determine
+        // whether or not they pass it.
+        for(E cluster : clusters) {
+            // Simulate each of the cluster singles triggers.
+            triggerLoop:
+            for(int triggerNum = 0; triggerNum < 2; triggerNum++) {
+                // Track whether the cluster passed each singles cut.
+                boolean passSeedLow = true;
+                boolean passSeedHigh = true;
+                boolean passClusterLow = false;
+                boolean passClusterHigh = false;
+                boolean passHitCount = false;
+                
+                // Perform the trigger cuts appropriately for the type
+                // of cluster.
+                if(cluster instanceof Cluster) {
+                    // Cast the cluster to the appropriate type.
+                    Cluster c = (Cluster) cluster;
+                    
+                    // Perform each trigger cut.
+                    passClusterLow = singlesTrigger[triggerNum].clusterTotalEnergyCutLow(c);
+                    passClusterHigh = singlesTrigger[triggerNum].clusterTotalEnergyCutHigh(c);
+                    passHitCount = singlesTrigger[triggerNum].clusterHitCountCut(c);
+                } else if(cluster instanceof SSPCluster) {
+                    // Cast the cluster to the appropriate type.
+                    SSPCluster c = (SSPCluster) cluster;
+                    
+                    // Perform each trigger cut.
+                    passClusterLow = singlesTrigger[triggerNum].clusterTotalEnergyCutLow(c);
+                    passClusterHigh = singlesTrigger[triggerNum].clusterTotalEnergyCutHigh(c);
+                    passHitCount = singlesTrigger[triggerNum].clusterHitCountCut(c);
+                }
+                
+                // Make a trigger to store the results.
+                SinglesTrigger<E> trigger = new SinglesTrigger<E>(cluster, triggerNum);
+                trigger.setStateSeedEnergyLow(passSeedLow);
+                trigger.setStateSeedEnergyHigh(passSeedHigh);
+                trigger.setStateClusterEnergyLow(passClusterLow);
+                trigger.setStateClusterEnergyHigh(passClusterHigh);
+                trigger.setStateHitCount(passHitCount);
+                
+                // A trigger will only be reported by the SSP if it
+                // passes all of the enabled cuts for that trigger.
+                // Check whether this trigger meets these conditions.
+                if(singlesCutsEnabled[triggerNum][ENERGY_MIN] && !trigger.getStateClusterEnergyLow()) {
+                    continue triggerLoop;
+                } if(singlesCutsEnabled[triggerNum][ENERGY_MAX] && !trigger.getStateClusterEnergyHigh()) {
+                    continue triggerLoop;
+                } if(singlesCutsEnabled[triggerNum][HIT_COUNT] && !trigger.getStateHitCount()) {
+                    continue triggerLoop;
+                }
+                
+                // Store the trigger.
+                singlesTriggers.get(triggerNum).add(trigger);
+            }
+        }
+        
+        // Store cluster pairs.
+        List<E[]> pairs = TriggerModule.getTopBottomPairs(clusters, clusterType);
+        
+        // Simulate the pair triggers and record the results.
+        for(E[] pair : pairs) {
+            // Simulate each of the cluster pair triggers.
+            pairTriggerLoop:
+            for(int triggerIndex = 0; triggerIndex < 2; triggerIndex++) {
+                // Track whether the cluster passed each singles cut.
+                boolean passSeedLow = true;
+                boolean passSeedHigh = true;
+                boolean passClusterLow = false;
+                boolean passClusterHigh = false;
+                boolean passHitCount = false;
+                boolean passPairEnergySumLow = false;
+                boolean passPairEnergySumHigh = false;
+                boolean passPairEnergyDifference = false;
+                boolean passPairEnergySlope = false;
+                boolean passPairCoplanarity = false;
+                boolean passTimeCoincidence = false;
+                
+                // Apply the trigger cuts appropriately according to the
+                // cluster type.
+                if(clusterType.equals(Cluster.class)) {
+                    // Cast the cluster object.
+                    Cluster[] reconPair = { (Cluster) pair[0], (Cluster) pair[1] };
+                    
+                    // Check that the pair passes the time coincidence cut.
+                    // If it does not, it is not a valid pair and should be
+                    // destroyed.
+                    if(!pairsTrigger[triggerIndex].pairTimeCoincidenceCut(reconPair)) {
+                        continue pairTriggerLoop;
+                    }
+                    
+                    passClusterLow = pairsTrigger[triggerIndex].clusterTotalEnergyCutLow(reconPair[0])
+                            && pairsTrigger[triggerIndex].clusterTotalEnergyCutLow(reconPair[1]);
+                    passClusterHigh = pairsTrigger[triggerIndex].clusterTotalEnergyCutHigh(reconPair[0])
+                            && pairsTrigger[triggerIndex].clusterTotalEnergyCutHigh(reconPair[1]);
+                    passHitCount = pairsTrigger[triggerIndex].clusterHitCountCut(reconPair[0])
+                            && pairsTrigger[triggerIndex].clusterHitCountCut(reconPair[1]);
+                    passPairEnergySumLow = pairsTrigger[triggerIndex].pairEnergySumCutLow(reconPair);
+                    passPairEnergySumHigh = pairsTrigger[triggerIndex].pairEnergySumCutHigh(reconPair);
+                    passPairEnergyDifference = pairsTrigger[triggerIndex].pairEnergyDifferenceCut(reconPair);
+                    passPairEnergySlope = pairsTrigger[triggerIndex].pairEnergySlopeCut(reconPair);
+                    passPairCoplanarity = pairsTrigger[triggerIndex].pairCoplanarityCut(reconPair);
+                    passTimeCoincidence = pairsTrigger[triggerIndex].pairTimeCoincidenceCut(reconPair);
+                } else if(clusterType.equals(SSPCluster.class)) {
+                    // Cast the cluster object.
+                    SSPCluster[] sspPair = { (SSPCluster) pair[0], (SSPCluster) pair[1] };
+                    
+                    // Check that the pair passes the time coincidence cut.
+                    // If it does not, it is not a valid pair and should be
+                    // destroyed.
+                    if(!pairsTrigger[triggerIndex].pairTimeCoincidenceCut(sspPair)) {
+                        continue pairTriggerLoop;
+                    }
+                    
+                    // Perform each trigger cut.
+                    passClusterLow = pairsTrigger[triggerIndex].clusterTotalEnergyCutLow(sspPair[0])
+                            && pairsTrigger[triggerIndex].clusterTotalEnergyCutLow(sspPair[1]);
+                    passClusterHigh = pairsTrigger[triggerIndex].clusterTotalEnergyCutHigh(sspPair[0])
+                            && pairsTrigger[triggerIndex].clusterTotalEnergyCutHigh(sspPair[1]);
+                    passHitCount = pairsTrigger[triggerIndex].clusterHitCountCut(sspPair[0])
+                            && pairsTrigger[triggerIndex].clusterHitCountCut(sspPair[1]);
+                    passPairEnergySumLow = pairsTrigger[triggerIndex].pairEnergySumCutLow(sspPair);
+                    passPairEnergySumHigh = pairsTrigger[triggerIndex].pairEnergySumCutHigh(sspPair);
+                    passPairEnergyDifference = pairsTrigger[triggerIndex].pairEnergyDifferenceCut(sspPair);
+                    passPairEnergySlope = pairsTrigger[triggerIndex].pairEnergySlopeCut(sspPair);
+                    passPairCoplanarity = pairsTrigger[triggerIndex].pairCoplanarityCut(sspPair);
+                    passTimeCoincidence = pairsTrigger[triggerIndex].pairTimeCoincidenceCut(sspPair);
+                }
+                
+                // Create a trigger from the results.
+                PairTrigger<E[]> trigger = new PairTrigger<E[]>(pair, triggerIndex);
+                trigger.setStateSeedEnergyLow(passSeedLow);
+                trigger.setStateSeedEnergyHigh(passSeedHigh);
+                trigger.setStateClusterEnergyLow(passClusterLow);
+                trigger.setStateClusterEnergyHigh(passClusterHigh);
+                trigger.setStateHitCount(passHitCount);
+                trigger.setStateEnergySumLow(passPairEnergySumLow);
+                trigger.setStateEnergySumHigh(passPairEnergySumHigh);
+                trigger.setStateEnergyDifference(passPairEnergyDifference);
+                trigger.setStateEnergySlope(passPairEnergySlope);
+                trigger.setStateCoplanarity(passPairCoplanarity);
+                trigger.setStateTimeCoincidence(passTimeCoincidence);
+                
+                // A trigger will only be reported by the SSP if it
+                // passes all of the enabled cuts for that trigger.
+                // Check whether this trigger meets these conditions.
+                if(pairCutsEnabled[triggerIndex][ENERGY_MIN] && !trigger.getStateClusterEnergyLow()) {
+                    continue pairTriggerLoop;
+                } if(pairCutsEnabled[triggerIndex][ENERGY_MAX] && !trigger.getStateClusterEnergyHigh()) {
+                    continue pairTriggerLoop;
+                } if(pairCutsEnabled[triggerIndex][HIT_COUNT] && !trigger.getStateHitCount()) {
+                    continue pairTriggerLoop;
+                } if(pairCutsEnabled[triggerIndex][3 + ENERGY_SUM] && !trigger.getStateEnergySum()) {
+                    continue pairTriggerLoop;
+                } if(pairCutsEnabled[triggerIndex][3 + ENERGY_DIFF] && !trigger.getStateEnergyDifference()) {
+                    continue pairTriggerLoop;
+                } if(pairCutsEnabled[triggerIndex][3 + ENERGY_SLOPE] && !trigger.getStateEnergySlope()) {
+                    continue pairTriggerLoop;
+                } if(pairCutsEnabled[triggerIndex][3 + COPLANARITY] && !trigger.getStateCoplanarity()) {
+                    continue pairTriggerLoop;
+                }
+                
+                // Add the trigger to the list.
+                pairTriggers.get(triggerIndex).add(trigger);
+            }
+        }
+        
+        // Create a new simulated trigger module to contain the results.
+        return new SimTriggerModule<E>(singlesTriggers.get(0), singlesTriggers.get(1),
+                pairTriggers.get(0), pairTriggers.get(1));
+    }
+    
+    /**
+     * Sets the name of the LCIO collection containing the TI and SSP
+     * banks.
+     * @param bankCollectionName - The bank collection name.
+     */
+    public void setBankCollectionName(String bankCollectionName) {
+        this.bankCollectionName = bankCollectionName;
+    }
+    
+    /**
+     * Sets the name of the LCIO collection containing the simulated
+     * reconstructed clusters.
+     * @param clusterCollectionName - The cluster collection name.
+     */
+    public void setClusterCollectionName(String clusterCollectionName) {
+        this.clusterCollectionName = clusterCollectionName;
+    }
+    
+    /**
+     * Sets whether or not triggers should be formed using all clusters,
+     * or only those that where the integration window for the cluster
+     * is completely within the bounds of the event window.
+     * @param state - <code>true</code> means that only clusters where
+     * the entire cluster integration window is within the event time
+     * window will be used, while <code>false</code> means that all
+     * clusters will be used.
+     */
+    public void setFilterUnverifiableClusters(boolean state) {
+        this.filterUnverifiable = state;
+    }
+    
+    /**
+     * Sets the name of the LCIO collection containing simulated triggers.
+     * @param triggerCollection - The trigger collection name.
+     */
+    public void setTriggerCollectionName(String triggerCollection) {
+        this.simTriggerCollectionName = triggerCollection;
+    }
 }

Modified: java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/SimTriggerData.java
 =============================================================================
--- java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/SimTriggerData.java	(original)
+++ java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/SimTriggerData.java	Wed Apr 27 11:11:32 2016
@@ -7,53 +7,76 @@
  * Class <code>SimTriggerData</code> is a container class that holds
  * simulated trigger data modules. It is intended to be placed in the
  * LCIO data stream by the <code>DataTriggerSimDriver</code> to allow
- * other classes to access triggers simulated from SSP and reconstructed
+ * other classes to access triggers simulated from hardware and software
  * cluster data.
  * 
  * @author Kyle McCarty <[log in to unmask]>
  */
 public class SimTriggerData {
-	private final SimTriggerModule<Cluster> reconTriggers;
-	private final SimTriggerModule<SSPCluster> sspTriggers;
-	
-	/**
-	 * Instantiates a new <code>SimTriggerData</code> object with empty
-	 * trigger results modules.
-	 */
-	SimTriggerData() {
-		reconTriggers = new SimTriggerModule<Cluster>();
-		sspTriggers = new SimTriggerModule<SSPCluster>();
-	}
-	
-	/**
-	 * Instantiates a new <code>SimTriggerData</code> object that will
-	 * contain the argument trigger modules.
-	 * @param reconTriggers - The simulated reconstructed cluster
-	 * triggers module.
-	 * @param sspTriggers - The simulated SSP cluster triggers module.
-	 */
-	SimTriggerData(SimTriggerModule<Cluster> reconTriggers, SimTriggerModule<SSPCluster> sspTriggers) {
-		this.reconTriggers = reconTriggers;
-		this.sspTriggers = sspTriggers;
-	}
-	
-	/**
-	 * Gets the module containing all simulated SSP trigger data for
-	 * each of the four primary triggers.
-	 * @return Returns the trigger data in a <code>SimTriggerModule</code>
-	 * object.
-	 */
-	public SimTriggerModule<SSPCluster> getSimSSPTriggers() {
-		return sspTriggers;
-	}
-	
-	/**
-	 * Gets the module containing all simulated LCSim trigger data for
-	 * each of the four primary triggers.
-	 * @return Returns the trigger data in a <code>SimTriggerModule</code>
-	 * object.
-	 */
-	public SimTriggerModule<Cluster> getSimReconTriggers() {
-		return reconTriggers;
-	}
+    private final SimTriggerModule<Cluster> softwareClusterTriggers;
+    private final SimTriggerModule<SSPCluster> hardwareClusterTriggers;
+    
+    /**
+     * Instantiates a new <code>SimTriggerData</code> object with empty
+     * trigger results modules.
+     */
+    SimTriggerData() {
+        softwareClusterTriggers = new SimTriggerModule<Cluster>();
+        hardwareClusterTriggers = new SimTriggerModule<SSPCluster>();
+    }
+    
+    /**
+     * Instantiates a new <code>SimTriggerData</code> object that will
+     * contain the argument trigger modules.
+     * @param softwareClusterTriggers - The module containing triggers
+     * simulated from software simulated clusters.
+     * @param hardwareClusterTriggers - The module containing triggers
+     * simulated from hardware reported clusters.
+     */
+    SimTriggerData(SimTriggerModule<Cluster> softwareClusterTriggers, SimTriggerModule<SSPCluster> hardwareClusterTriggers) {
+        this.softwareClusterTriggers = softwareClusterTriggers;
+        this.hardwareClusterTriggers = hardwareClusterTriggers;
+    }
+    
+    /**
+     * Gets the module containing all simulated SSP trigger data for
+     * each of the four primary triggers.
+     * @return Returns the trigger data in a <code>SimTriggerModule</code>
+     * object.
+     */
+    @Deprecated
+    public SimTriggerModule<SSPCluster> getSimSSPTriggers() {
+        return hardwareClusterTriggers;
+    }
+    
+    /**
+     * Gets the module containing all simulated LCSim trigger data for
+     * each of the four primary triggers.
+     * @return Returns the trigger data in a <code>SimTriggerModule</code>
+     * object.
+     */
+    @Deprecated
+    public SimTriggerModule<Cluster> getSimReconTriggers() {
+        return softwareClusterTriggers;
+    }
+    
+    /**
+     * Gets the module containing all triggers simulated from hardware
+     * reported clusters for each of the four production triggers.
+     * @return Returns the trigger data in a <code>SimTriggerModule</code>
+     * object.
+     */
+    public SimTriggerModule<SSPCluster> getSimHardwareClusterTriggers() {
+        return hardwareClusterTriggers;
+    }
+    
+    /**
+     * Gets the module containing all triggers simulated from software
+     * simulated clusters for each of the four production triggers.
+     * @return Returns the trigger data in a <code>SimTriggerModule</code>
+     * object.
+     */
+    public SimTriggerModule<Cluster> getSimSoftwareClusterTriggers() {
+        return softwareClusterTriggers;
+    }
 }

Modified: java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/SimTriggerModule.java
 =============================================================================
--- java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/SimTriggerModule.java	(original)
+++ java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/SimTriggerModule.java	Wed Apr 27 11:11:32 2016
@@ -18,71 +18,115 @@
  * @see DataTriggerSimDriver
  */
 public class SimTriggerModule<E> {
-	private final List<SinglesTrigger<E>> singles0;
-	private final List<SinglesTrigger<E>> singles1;
-	private final List<PairTrigger<E[]>> pair0;
-	private final List<PairTrigger<E[]>> pair1;
-	
-	/**
-	 * Constructs a new <code>SimTriggerModule</code> with the no
-	 * triggers results for any triggers.
-	 */
-	SimTriggerModule() {
-		singles0 = new ArrayList<SinglesTrigger<E>>(0);
-		singles1 = new ArrayList<SinglesTrigger<E>>(0);
-		pair0    = new ArrayList<PairTrigger<E[]>>(0);
-		pair1    = new ArrayList<PairTrigger<E[]>>(0);
-	}
-	
-	/**
-	 * Constructs a new <code>SimTriggerModule</code> with the specified
-	 * trigger results for each of the four primary triggers.
-	 * @param singles0Triggers - The results for the singles 0 trigger.
-	 * @param singles1Triggers - The results for the singles 1 trigger.
-	 * @param pair0Triggers - The results for the pair 0 trigger.
-	 * @param pair1Triggers - The results for the pair 1 trigger.
-	 */
-	SimTriggerModule(List<SinglesTrigger<E>> singles0Triggers, List<SinglesTrigger<E>> singles1Triggers,
-			List<PairTrigger<E[]>> pair0Triggers, List<PairTrigger<E[]>> pair1Triggers) {
-		this.singles0 = singles0Triggers;
-		this.singles1 = singles1Triggers;
-		this.pair0    = pair0Triggers;
-		this.pair1    = pair1Triggers;
-	}
-	
-	/**
-	 * Gets the simulated trigger results for the singles 0 trigger.
-	 * @return Returns the trigger results as a <code>List</code> of
-	 * <code>SinglesTrigger</code> objects.
-	 */
-	public List<SinglesTrigger<E>> getSingles0Triggers() {
-		return singles0;
-	}
-	
-	/**
-	 * Gets the simulated trigger results for the singles 1 trigger.
-	 * @return Returns the trigger results as a <code>List</code> of
-	 * <code>SinglesTrigger</code> objects.
-	 */
-	public List<SinglesTrigger<E>> getSingles1Triggers() {
-		return singles1;
-	}
-	
-	/**
-	 * Gets the simulated trigger results for the pair 0 trigger.
-	 * @return Returns the trigger results as a <code>List</code> of
-	 * <code>PairTrigger</code> objects.
-	 */
-	public List<PairTrigger<E[]>> getPair0Triggers() {
-		return pair0;
-	}
-	
-	/**
-	 * Gets the simulated trigger results for the pair 1 trigger.
-	 * @return Returns the trigger results as a <code>List</code> of
-	 * <code>PairTrigger</code> objects.
-	 */
-	public List<PairTrigger<E[]>> getPair1Triggers() {
-		return pair1;
-	}
-}
+    private final List<SinglesTrigger<E>> singles0;
+    private final List<SinglesTrigger<E>> singles1;
+    private final List<PairTrigger<E[]>> pair0;
+    private final List<PairTrigger<E[]>> pair1;
+    
+    /**
+     * Constructs a new <code>SimTriggerModule</code> with the no
+     * triggers results for any triggers.
+     */
+    SimTriggerModule() {
+        singles0 = new ArrayList<SinglesTrigger<E>>(0);
+        singles1 = new ArrayList<SinglesTrigger<E>>(0);
+        pair0    = new ArrayList<PairTrigger<E[]>>(0);
+        pair1    = new ArrayList<PairTrigger<E[]>>(0);
+    }
+    
+    /**
+     * Constructs a new <code>SimTriggerModule</code> with the specified
+     * trigger results for each of the four primary triggers.
+     * @param singles0Triggers - The results for the singles 0 trigger.
+     * @param singles1Triggers - The results for the singles 1 trigger.
+     * @param pair0Triggers - The results for the pair 0 trigger.
+     * @param pair1Triggers - The results for the pair 1 trigger.
+     */
+    SimTriggerModule(List<SinglesTrigger<E>> singles0Triggers, List<SinglesTrigger<E>> singles1Triggers,
+            List<PairTrigger<E[]>> pair0Triggers, List<PairTrigger<E[]>> pair1Triggers) {
+        this.singles0 = singles0Triggers;
+        this.singles1 = singles1Triggers;
+        this.pair0    = pair0Triggers;
+        this.pair1    = pair1Triggers;
+    }
+    
+    /**
+     * Gets the simulated trigger results for the indicated singles
+     * trigger. Note that only inputs of <code>0</code> and <code>1</code>
+     * are allowed.
+     * @param triggerNumber - A value of either <code>0</code>, to
+     * obtain the singles 0 trigger results, or <code>1</code>, to
+     * obtain the singles 1 trigger results.
+     * @return Returns the trigger results as a <code>List</code> of
+     * <code>SinglesTrigger</code> objects.
+     * @throws IllegalArgumentException Occurs if the input argument
+     * is not either <code>0</code> or <code>1</code>.
+     */
+    public List<SinglesTrigger<E>> getSinglesTriggers(int triggerNumber) {
+        // Return the appropriate trigger list.
+        if(triggerNumber == 0) { return getSingles0Triggers(); }
+        else if(triggerNumber == 1) { return getSingles1Triggers(); }
+        
+        // Any other trigger number is not valid and should produce an
+        // exception.
+        throw new IllegalArgumentException("Trigger number " + triggerNumber + " is not valid.");
+    }
+    
+    /**
+     * Gets the simulated trigger results for the singles 0 trigger.
+     * @return Returns the trigger results as a <code>List</code> of
+     * <code>SinglesTrigger</code> objects.
+     */
+    public List<SinglesTrigger<E>> getSingles0Triggers() {
+        return singles0;
+    }
+    
+    /**
+     * Gets the simulated trigger results for the singles 1 trigger.
+     * @return Returns the trigger results as a <code>List</code> of
+     * <code>SinglesTrigger</code> objects.
+     */
+    public List<SinglesTrigger<E>> getSingles1Triggers() {
+        return singles1;
+    }
+    
+    /**
+     * Gets the simulated trigger results for the indicated pair trigger.
+     * Note that only inputs of <code>0</code> and <code>1</code> are
+     * allowed.
+     * @param triggerNumber - A value of either <code>0</code>, to
+     * obtain the pair 0 trigger results, or <code>1</code>, to obtain
+     * the pair 1 trigger results.
+     * @return Returns the trigger results as a <code>List</code> of
+     * <code>PairTrigger</code> objects.
+     * @throws IllegalArgumentException Occurs if the input argument
+     * is not either <code>0</code> or <code>1</code>.
+     */
+    public List<PairTrigger<E[]>> getPairTriggers(int triggerNumber) {
+        // Return the appropriate trigger list.
+        if(triggerNumber == 0) { return getPair0Triggers(); }
+        else if(triggerNumber == 1) { return getPair1Triggers(); }
+        
+        // Any other trigger number is not valid and should produce an
+        // exception.
+        throw new IllegalArgumentException("Trigger number " + triggerNumber + " is not valid.");
+    }
+    
+    /**
+     * Gets the simulated trigger results for the pair 0 trigger.
+     * @return Returns the trigger results as a <code>List</code> of
+     * <code>PairTrigger</code> objects.
+     */
+    public List<PairTrigger<E[]>> getPair0Triggers() {
+        return pair0;
+    }
+    
+    /**
+     * Gets the simulated trigger results for the pair 1 trigger.
+     * @return Returns the trigger results as a <code>List</code> of
+     * <code>PairTrigger</code> objects.
+     */
+    public List<PairTrigger<E[]>> getPair1Triggers() {
+        return pair1;
+    }
+}

Modified: java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/TriggerDiagnosticDriver.java
 =============================================================================
--- java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/TriggerDiagnosticDriver.java	(original)
+++ java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/TriggerDiagnosticDriver.java	Wed Apr 27 11:11:32 2016
@@ -52,54 +52,54 @@
 import org.lcsim.util.aida.AIDA;
 
 public class TriggerDiagnosticDriver extends Driver {
-	// Store the LCIO collection names for the needed objects.
-	private String hitCollectionName = "EcalCalHits";
-	private String bankCollectionName = "TriggerBank";
-	private String clusterCollectionName = "EcalClusters";
-	private String diagnosticCollectionName = "DiagnosticSnapshot";
-	private static final int clusterCollectionFlag = 1 << LCIOConstants.CLBIT_HITS;
-	private String[] singlesCandidateCollectionName = { "Singles0TriggerCandidates", "Singles1TriggerCandidates" };
-	private String[] pairCandidateCollectionName = { "Pair0TriggerCandidates", "Pair1TriggerCandidates" };
-	
-	// Store the lists of parsed objects.
-	private TIData tiBank;
-	private SSPData sspBank;
-	private List<SSPCluster> sspClusters;
-	private List<Cluster> reconClusters = new ArrayList<Cluster>();
-	private SimTriggerData triggerData = null;
-	
-	// Trigger modules for performing trigger analysis.
-	//private int activeTrigger = -1;
-	private boolean[] tiFlags = new boolean[6];
-	private TriggerModule[] singlesTrigger = new TriggerModule[2];
-	private TriggerModule[] pairsTrigger = new TriggerModule[2];
-	private boolean[][] singlesCutsEnabled = new boolean[2][3];
-	private boolean[][] pairCutsEnabled = new boolean[2][7];
-	private boolean[] singlesTriggerEnabled = new boolean[2];
-	private boolean[] pairTriggerEnabled = new boolean[2];
-	
-	// Verification settings.
-	private int nsa = 100;
-	private int nsb = 20;
-	private int windowWidth = 200;
-	private int hitAcceptance = 1;
-	private int noiseThreshold = 50;
-	private double energyAcceptance = 0.003;
-	private boolean readDAQConfig = false;
-	private int localWindowThreshold = 1000000000;
-	private boolean performClusterVerification = true;
-	private boolean performSinglesTriggerVerification = true;
-	private boolean performPairTriggerVerification = true;
-	private boolean enforceTimeCompliance = false;
-	
-	// Efficiency tracking variables.
-	private RunDiagStats localStats = new RunDiagStats();
-	private RunDiagStats globalStats = new RunDiagStats();
-    
-	// Track which clusters/pairs are trigger candidates.
-	private List<List<Cluster>> singlesCandidates = new ArrayList<List<Cluster>>(2);
-	private List<List<LCRelation>> pairCandidates = new ArrayList<List<LCRelation>>(2);
-	
+    // Store the LCIO collection names for the needed objects.
+    private String hitCollectionName = "EcalCalHits";
+    private String bankCollectionName = "TriggerBank";
+    private String clusterCollectionName = "EcalClusters";
+    private String diagnosticCollectionName = "DiagnosticSnapshot";
+    private static final int clusterCollectionFlag = 1 << LCIOConstants.CLBIT_HITS;
+    private String[] singlesCandidateCollectionName = { "Singles0TriggerCandidates", "Singles1TriggerCandidates" };
+    private String[] pairCandidateCollectionName = { "Pair0TriggerCandidates", "Pair1TriggerCandidates" };
+    
+    // Store the lists of parsed objects.
+    private TIData tiBank;
+    private SSPData sspBank;
+    private List<SSPCluster> sspClusters;
+    private List<Cluster> reconClusters = new ArrayList<Cluster>();
+    private SimTriggerData triggerData = null;
+    
+    // Trigger modules for performing trigger analysis.
+    //private int activeTrigger = -1;
+    private boolean[] tiFlags = new boolean[6];
+    private TriggerModule[] singlesTrigger = new TriggerModule[2];
+    private TriggerModule[] pairsTrigger = new TriggerModule[2];
+    private boolean[][] singlesCutsEnabled = new boolean[2][3];
+    private boolean[][] pairCutsEnabled = new boolean[2][7];
+    private boolean[] singlesTriggerEnabled = new boolean[2];
+    private boolean[] pairTriggerEnabled = new boolean[2];
+    
+    // Verification settings.
+    private int nsa = 100;
+    private int nsb = 20;
+    private int windowWidth = 200;
+    private int hitAcceptance = 1;
+    private int noiseThreshold = 50;
+    private double energyAcceptance = 0.003;
+    private boolean readDAQConfig = false;
+    private int localWindowThreshold = 1000000000;
+    private boolean performClusterVerification = true;
+    private boolean performSinglesTriggerVerification = true;
+    private boolean performPairTriggerVerification = true;
+    private boolean enforceTimeCompliance = false;
+    
+    // Efficiency tracking variables.
+    private RunDiagStats localStats = new RunDiagStats();
+    private RunDiagStats globalStats = new RunDiagStats();
+    
+    // Track which clusters/pairs are trigger candidates.
+    private List<List<Cluster>> singlesCandidates = new ArrayList<List<Cluster>>(2);
+    private List<List<LCRelation>> pairCandidates = new ArrayList<List<LCRelation>>(2);
+    
     // Verbose settings.
     private boolean clusterFail = false;
     private boolean singlesEfficiencyFail = false;
@@ -115,2125 +115,2125 @@
     private int     statPrintInterval = Integer.MAX_VALUE;
 
     // Cut index arrays for trigger verification.
-	private static final int ENERGY_MIN   = TriggerDiagnosticUtil.SINGLES_ENERGY_MIN;
-	private static final int ENERGY_MAX   = TriggerDiagnosticUtil.SINGLES_ENERGY_MAX;
-	private static final int HIT_COUNT    = TriggerDiagnosticUtil.SINGLES_HIT_COUNT;
-	private static final int ENERGY_SUM   = TriggerDiagnosticUtil.PAIR_ENERGY_SUM;
-	private static final int ENERGY_DIFF  = TriggerDiagnosticUtil.PAIR_ENERGY_DIFF;
-	private static final int ENERGY_SLOPE = TriggerDiagnosticUtil.PAIR_ENERGY_SLOPE;
-	private static final int COPLANARITY  = TriggerDiagnosticUtil.PAIR_COPLANARITY;
-    
-	// Track the total run time.
-	private long startTime = -1;
-	private long endTime = -1;
-	
-	// Cut names for logging.
-	private static final String[][] cutNames = {
-			{ "E_min", "E_max", "hit count", "null" },
-			{ "E_sum", "E_diff", "E_slope", "coplanar" }
-	};
-	
-	// Temporary AIDA Plots
-	private TriggerPlotsModule globalTriggerPlots = new TriggerPlotsModule(0, 0);
-	private static final int RECON   = 0;
-	private static final int SSP     = 1;
-	private static final int ALL     = 0;
-	private static final int MATCHED = 1;
-	private static final int FAILED  = 2;
-	private AIDA aida = AIDA.defaultInstance();
-	private IHistogram1D[][] clusterHitPlot = {
-			{
-				aida.histogram1D("Clustering/Recon Cluster Hit Count (All)",     9, 0.5, 9.5),
-				aida.histogram1D("Clustering/Recon Cluster Hit Count (Matched)", 9, 0.5, 9.5),
-				aida.histogram1D("Clustering/Recon Cluster Hit Count (Failed)",  9, 0.5, 9.5)
-			},
-			{
-				aida.histogram1D("Clustering/SSP Cluster Hit Count (All)",     9, 0.5, 9.5),
-				aida.histogram1D("Clustering/SSP Cluster Hit Count (Matched)", 9, 0.5, 9.5),
-				aida.histogram1D("Clustering/SSP Cluster Hit Count (Failed)",  9, 0.5, 9.5)
-			}
-	};
-	private IHistogram1D[][] clusterEnergyPlot = {
-			{
-				aida.histogram1D("Clustering/Recon Cluster Energy (All)",     300, 0.0, 3.0),
-				aida.histogram1D("Clustering/Recon Cluster Energy (Matched)", 300, 0.0, 3.0),
-				aida.histogram1D("Clustering/Recon Cluster Energy (Failed)",  300, 0.0, 3.0)
-			},
-			{
-				aida.histogram1D("Clustering/SSP Cluster Energy (All)",     300, 0.0, 3.0),
-				aida.histogram1D("Clustering/SSP Cluster Energy (Matched)", 300, 0.0, 3.0),
-				aida.histogram1D("Clustering/SSP Cluster Energy (Failed)",  300, 0.0, 3.0)
-			}
-	};
-	private IHistogram1D[][] clusterTimePlot = {
-			{
-				aida.histogram1D("Clustering/Recon Cluster Time (All)",     115, 0, 460),
-				aida.histogram1D("Clustering/Recon Cluster Time (Matched)", 115, 0, 460),
-				aida.histogram1D("Clustering/Recon Cluster Time (Failed)",  115, 0, 460)
-			},
-			{
-				aida.histogram1D("Clustering/SSP Cluster Time (All)",     115, 0, 460),
-				aida.histogram1D("Clustering/SSP Cluster Time (Matched)", 115, 0, 460),
-				aida.histogram1D("Clustering/SSP Cluster Time (Failed)",  115, 0, 460)
-			}
-	};
-	private IHistogram2D[][] clusterPositionPlot = {
-			{
-				aida.histogram2D("Clustering/Recon Cluster Position (All)",     47, -23.5, 23.5, 11, -5.5, 5.5),
-				aida.histogram2D("Clustering/Recon Cluster Position (Matched)", 47, -23.5, 23.5, 11, -5.5, 5.5),
-				aida.histogram2D("Clustering/Recon Cluster Position (Failed)",  47, -23.5, 23.5, 11, -5.5, 5.5)
-			},
-			{
-				aida.histogram2D("Clustering/SSP Cluster Position (All)",     47, -23.5, 23.5, 11, -5.5, 5.5),
-				aida.histogram2D("Clustering/SSP Cluster Position (Matched)", 47, -23.5, 23.5, 11, -5.5, 5.5),
-				aida.histogram2D("Clustering/SSP Cluster Position (Failed)",  47, -23.5, 23.5, 11, -5.5, 5.5)
-			}
-	};
-	private IHistogram2D[] energyhitDiffPlot = {
-		aida.histogram2D("Clustering/Recon-SSP Energy-Hit Difference (All)",     21, -0.010, 0.010, 6, -3, 3),
-		aida.histogram2D("Clustering/Recon-SSP Energy-Hit Difference (Matched)", 21, -0.010, 0.010, 6, -3, 3),
-		aida.histogram2D("Clustering/Recon-SSP Energy-Hit Difference (Failed)",  21, -0.010, 0.010, 6, -3, 3)
-	};
-	private ICloud2D[] efficiencyTimeHist = {
-			aida.cloud2D("Clustering/Cluster Efficiency vs. Time"),
-			aida.cloud2D("Singles Trigger 0/Cluster Efficiency vs. Time"),
-			aida.cloud2D("Singles Trigger 1/Cluster Efficiency vs. Time"),
-			aida.cloud2D("Pair Trigger 0/Cluster Efficiency vs. Time"),
-			aida.cloud2D("Pair Trigger 1/Cluster Efficiency vs. Time")
-	};
-	
-	/**
-	 * Define the trigger modules. This should be replaced by parsing
-	 * the DAQ configuration at some point.
-	 */
-	@Override
-	public void startOfData() {
-		// By default, all triggers and cuts are enabled.
-		for(int i = 0; i < 2; i++) {
-			// Enable the triggers.
-			pairTriggerEnabled[i] = true;
-			singlesTriggerEnabled[i] = true;
-			
-			// Enable the singles cuts.
-			for(int j = 0; j < singlesCutsEnabled.length; j++) {
-				singlesCutsEnabled[i][j] = true;
-			}
-			
-			// Enable the pair cuts.
-			for(int j = 0; j < pairCutsEnabled.length; j++) {
-				pairCutsEnabled[i][j] = true;
-			}
-		}
-		
-		// If the DAQ configuration should be read, attach a listener
-		// to track when it updates.
-		if(readDAQConfig) {
-			ConfigurationManager.addActionListener(new ActionListener() {
-				@Override
-				public void actionPerformed(ActionEvent e) {
-					// Get the DAQ configuration.
-					DAQConfig daq = ConfigurationManager.getInstance();
-					
-					// Update the plotting energy slope values.
-					globalTriggerPlots.setEnergySlopeParamF(0, daq.getSSPConfig().getPair1Config().getEnergySlopeCutConfig().getParameterF());
-					globalTriggerPlots.setEnergySlopeParamF(1, daq.getSSPConfig().getPair2Config().getEnergySlopeCutConfig().getParameterF());
-					
-					// Load the DAQ settings from the configuration manager.
-					singlesTrigger[0].loadDAQConfiguration(daq.getSSPConfig().getSingles1Config());
-					singlesTrigger[1].loadDAQConfiguration(daq.getSSPConfig().getSingles2Config());
-					pairsTrigger[0].loadDAQConfiguration(daq.getSSPConfig().getPair1Config());
-					pairsTrigger[1].loadDAQConfiguration(daq.getSSPConfig().getPair2Config());
-					nsa = daq.getFADCConfig().getNSA();
-					nsb = daq.getFADCConfig().getNSB();
-					windowWidth = daq.getFADCConfig().getWindowWidth();
-					
-					// Get the trigger configurations from the DAQ.
-					SinglesTriggerConfig[] singles = { daq.getSSPConfig().getSingles1Config(),
-							daq.getSSPConfig().getSingles2Config() };
-					PairTriggerConfig[] pairs = { daq.getSSPConfig().getPair1Config(),
-							daq.getSSPConfig().getPair2Config() };
-					
-					// Update the enabled/disabled statuses.
-					for(int i = 0; i < 2; i++) {
-						// Set the trigger enabled status.
-						pairTriggerEnabled[i] = pairs[i].isEnabled();
-						singlesTriggerEnabled[i] = singles[i].isEnabled();
-						
-						// Set the singles cut statuses.
-						singlesCutsEnabled[i][ENERGY_MIN] = singles[i].getEnergyMinCutConfig().isEnabled();
-						singlesCutsEnabled[i][ENERGY_MAX] = singles[i].getEnergyMaxCutConfig().isEnabled();
-						singlesCutsEnabled[i][HIT_COUNT] = singles[i].getHitCountCutConfig().isEnabled();
-						
-						// Set the pair cut statuses.
-						pairCutsEnabled[i][ENERGY_MIN] = pairs[i].getEnergyMinCutConfig().isEnabled();
-						pairCutsEnabled[i][ENERGY_MAX] = pairs[i].getEnergyMaxCutConfig().isEnabled();
-						pairCutsEnabled[i][HIT_COUNT] = pairs[i].getHitCountCutConfig().isEnabled();
-						pairCutsEnabled[i][3 + ENERGY_SUM] = pairs[i].getEnergySumCutConfig().isEnabled();
-						pairCutsEnabled[i][3 + ENERGY_DIFF] = pairs[i].getEnergyDifferenceCutConfig().isEnabled();
-						pairCutsEnabled[i][3 + ENERGY_SLOPE] = pairs[i].getEnergySlopeCutConfig().isEnabled();
-						pairCutsEnabled[i][3 + COPLANARITY] = pairs[i].getCoplanarityCutConfig().isEnabled();
-					}
-					
-					// Update the trigger plots values.
-					globalTriggerPlots.setEnergySlopeParamF(0, daq.getSSPConfig().getPair1Config().getEnergySlopeCutConfig().getParameterF());
-					globalTriggerPlots.setEnergySlopeParamF(1, daq.getSSPConfig().getPair2Config().getEnergySlopeCutConfig().getParameterF());
-					
-					// Print a DAQ configuration settings header.
-					System.out.println();
-					System.out.println();
-					System.out.println("======================================================================");
-					System.out.println("=== DAQ Configuration Settings =======================================");
-					System.out.println("======================================================================");
-					logSettings();
-				}
-			});
-		}
-		
-		// Print the cluster verification header.
-		System.out.println();
-		System.out.println();
-		System.out.println("======================================================================");
-		System.out.println("=== Cluster/Trigger Verification Settings ============================");
-		System.out.println("======================================================================");
-		
-		// Define the first singles trigger.
-		singlesTrigger[0] = new TriggerModule();
-		singlesTrigger[0].setCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_LOW, 0.500);
-		singlesTrigger[0].setCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_HIGH, 8.191);
-		singlesTrigger[0].setCutValue(TriggerModule.CLUSTER_HIT_COUNT_LOW, 0);
-		
-		// Define the second singles trigger.
-		singlesTrigger[1] = new TriggerModule();
-		singlesTrigger[1].setCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_LOW, 0.000);
-		singlesTrigger[1].setCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_HIGH, 8.191);
-		singlesTrigger[1].setCutValue(TriggerModule.CLUSTER_HIT_COUNT_LOW, 0);
-		
-		// Define the first pairs trigger.
-		pairsTrigger[0] = new TriggerModule();
-		pairsTrigger[0].setCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_LOW, 0.000);
-		pairsTrigger[0].setCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_HIGH, 8.191);
-		pairsTrigger[0].setCutValue(TriggerModule.CLUSTER_HIT_COUNT_LOW, 0);
-		pairsTrigger[0].setCutValue(TriggerModule.PAIR_ENERGY_SUM_LOW, 0.000);
-		pairsTrigger[0].setCutValue(TriggerModule.PAIR_ENERGY_SUM_HIGH, 8.191);
-		pairsTrigger[0].setCutValue(TriggerModule.PAIR_ENERGY_DIFFERENCE_HIGH, 8.191);
-		pairsTrigger[0].setCutValue(TriggerModule.PAIR_ENERGY_SLOPE_LOW, 0.000);
-		pairsTrigger[0].setCutValue(TriggerModule.PAIR_ENERGY_SLOPE_F, 0.001);
-		pairsTrigger[0].setCutValue(TriggerModule.PAIR_COPLANARITY_HIGH, 180);
-		pairsTrigger[0].setCutValue(TriggerModule.PAIR_TIME_COINCIDENCE, 8);
-		
-		// Define the second pairs trigger.
-		pairsTrigger[1] = new TriggerModule();
-		pairsTrigger[1].setCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_LOW, 0.000);
-		pairsTrigger[1].setCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_HIGH, 8.191);
-		pairsTrigger[1].setCutValue(TriggerModule.CLUSTER_HIT_COUNT_LOW, 0);
-		pairsTrigger[1].setCutValue(TriggerModule.PAIR_ENERGY_SUM_LOW, 0.000);
-		pairsTrigger[1].setCutValue(TriggerModule.PAIR_ENERGY_SUM_HIGH, 8.191);
-		pairsTrigger[1].setCutValue(TriggerModule.PAIR_ENERGY_DIFFERENCE_HIGH, 8.191);
-		pairsTrigger[1].setCutValue(TriggerModule.PAIR_ENERGY_SLOPE_LOW, 0.000);
-		pairsTrigger[1].setCutValue(TriggerModule.PAIR_ENERGY_SLOPE_F, 0.001);
-		pairsTrigger[1].setCutValue(TriggerModule.PAIR_COPLANARITY_HIGH, 180);
-		pairsTrigger[1].setCutValue(TriggerModule.PAIR_TIME_COINCIDENCE, 8);
-		
-		// Print the initial settings.
-		logSettings();
-	}
-	
-	/**
-	 * Prints the total run statistics.
-	 */
-	@Override
-	public void endOfData() {
-		// Output the statistics.
-		logStatistics();
-		
-		/*
-		// Calculate the values needed for the efficiency histogram.
-		long totalTime = entryList.get(entryList.size()).time / 1000000000;
-		int entries = (int) (totalTime / (localWindowThreshold / 1000000000)) + 1;
-		
-		// Generate a histogram containing the efficiencies.
-		IHistogram1D[] efficiencyHist = new IHistogram1D[5];
-		for(int i = 0; i < 5; i++) {
-			efficiencyHist[i] = aida.histogram1D("Efficiency " + i, entries, 0.0, totalTime + (localWindowThreshold / 1000000000));
-		}
-		
-		// Input the efficiencies.
-		for(EfficiencyEntry entry : entryList) {
-			for(int i = 0; i < 5; i++) {
-				efficiencyHist[i].fill(entry.time / 1000000000, entry.efficiency[i]);
-			}
-		}
-		*/
-	}
-	
-	/**
-	 * Gets the banks and clusters from the event.
-	 */
-	@Override
-	public void process(EventHeader event) {
-		// ==========================================================
-		// ==== Event Pre-Initialization ============================
-		// ==========================================================
-        
-		// If DAQ settings are to be used, check if they are initialized
-		// yet. If not, skip the event.
-		if(readDAQConfig) {
-			if(!ConfigurationManager.isInitialized()) {
-				return;
-			}
-		}
-		
-		// Reset the candidate cluster lists.
-		singlesCandidates.clear();
-		singlesCandidates.add(new ArrayList<Cluster>());
-		singlesCandidates.add(new ArrayList<Cluster>());
-		pairCandidates.clear();
-		pairCandidates.add(new ArrayList<LCRelation>());
-		pairCandidates.add(new ArrayList<LCRelation>());
-		
-		// Increment the total event count.
-		localStats.sawEvent(event.getTimeStamp());
-		globalStats.sawEvent(event.getTimeStamp());
-		
-		// Print the statistics every so often during a run.
-		if(globalStats.getEventCount() % statPrintInterval == 0) {
-			logStatistics();
-		}
-		
-		// Reset the output buffer and print flags.
-		clusterFail = false;
-		singlesInternalFail = false;
-		singlesEfficiencyFail = false;
-		pairInternalFail = false;
-		pairEfficiencyFail = false;
-		OutputLogger.clearLog();
-		
-		// Track the times.
-		if(startTime == -1) { startTime = event.getTimeStamp(); }
-		else { endTime = event.getTimeStamp(); }
-		
-		
-		
-		// ==========================================================
-		// ==== Output GTP Information ==============================
-		// ==========================================================
-		
+    private static final int ENERGY_MIN   = TriggerDiagnosticUtil.SINGLES_ENERGY_MIN;
+    private static final int ENERGY_MAX   = TriggerDiagnosticUtil.SINGLES_ENERGY_MAX;
+    private static final int HIT_COUNT    = TriggerDiagnosticUtil.SINGLES_HIT_COUNT;
+    private static final int ENERGY_SUM   = TriggerDiagnosticUtil.PAIR_ENERGY_SUM;
+    private static final int ENERGY_DIFF  = TriggerDiagnosticUtil.PAIR_ENERGY_DIFF;
+    private static final int ENERGY_SLOPE = TriggerDiagnosticUtil.PAIR_ENERGY_SLOPE;
+    private static final int COPLANARITY  = TriggerDiagnosticUtil.PAIR_COPLANARITY;
+    
+    // Track the total run time.
+    private long startTime = -1;
+    private long endTime = -1;
+    
+    // Cut names for logging.
+    private static final String[][] cutNames = {
+            { "E_min", "E_max", "hit count", "null" },
+            { "E_sum", "E_diff", "E_slope", "coplanar" }
+    };
+    
+    // Temporary AIDA Plots
+    private TriggerPlotsModule globalTriggerPlots = new TriggerPlotsModule(0, 0);
+    private static final int RECON   = 0;
+    private static final int SSP     = 1;
+    private static final int ALL     = 0;
+    private static final int MATCHED = 1;
+    private static final int FAILED  = 2;
+    private AIDA aida = AIDA.defaultInstance();
+    private IHistogram1D[][] clusterHitPlot = {
+            {
+                aida.histogram1D("Clustering/Recon Cluster Hit Count (All)",     9, 0.5, 9.5),
+                aida.histogram1D("Clustering/Recon Cluster Hit Count (Matched)", 9, 0.5, 9.5),
+                aida.histogram1D("Clustering/Recon Cluster Hit Count (Failed)",  9, 0.5, 9.5)
+            },
+            {
+                aida.histogram1D("Clustering/SSP Cluster Hit Count (All)",     9, 0.5, 9.5),
+                aida.histogram1D("Clustering/SSP Cluster Hit Count (Matched)", 9, 0.5, 9.5),
+                aida.histogram1D("Clustering/SSP Cluster Hit Count (Failed)",  9, 0.5, 9.5)
+            }
+    };
+    private IHistogram1D[][] clusterEnergyPlot = {
+            {
+                aida.histogram1D("Clustering/Recon Cluster Energy (All)",     300, 0.0, 3.0),
+                aida.histogram1D("Clustering/Recon Cluster Energy (Matched)", 300, 0.0, 3.0),
+                aida.histogram1D("Clustering/Recon Cluster Energy (Failed)",  300, 0.0, 3.0)
+            },
+            {
+                aida.histogram1D("Clustering/SSP Cluster Energy (All)",     300, 0.0, 3.0),
+                aida.histogram1D("Clustering/SSP Cluster Energy (Matched)", 300, 0.0, 3.0),
+                aida.histogram1D("Clustering/SSP Cluster Energy (Failed)",  300, 0.0, 3.0)
+            }
+    };
+    private IHistogram1D[][] clusterTimePlot = {
+            {
+                aida.histogram1D("Clustering/Recon Cluster Time (All)",     115, 0, 460),
+                aida.histogram1D("Clustering/Recon Cluster Time (Matched)", 115, 0, 460),
+                aida.histogram1D("Clustering/Recon Cluster Time (Failed)",  115, 0, 460)
+            },
+            {
+                aida.histogram1D("Clustering/SSP Cluster Time (All)",     115, 0, 460),
+                aida.histogram1D("Clustering/SSP Cluster Time (Matched)", 115, 0, 460),
+                aida.histogram1D("Clustering/SSP Cluster Time (Failed)",  115, 0, 460)
+            }
+    };
+    private IHistogram2D[][] clusterPositionPlot = {
+            {
+                aida.histogram2D("Clustering/Recon Cluster Position (All)",     47, -23.5, 23.5, 11, -5.5, 5.5),
+                aida.histogram2D("Clustering/Recon Cluster Position (Matched)", 47, -23.5, 23.5, 11, -5.5, 5.5),
+                aida.histogram2D("Clustering/Recon Cluster Position (Failed)",  47, -23.5, 23.5, 11, -5.5, 5.5)
+            },
+            {
+                aida.histogram2D("Clustering/SSP Cluster Position (All)",     47, -23.5, 23.5, 11, -5.5, 5.5),
+                aida.histogram2D("Clustering/SSP Cluster Position (Matched)", 47, -23.5, 23.5, 11, -5.5, 5.5),
+                aida.histogram2D("Clustering/SSP Cluster Position (Failed)",  47, -23.5, 23.5, 11, -5.5, 5.5)
+            }
+    };
+    private IHistogram2D[] energyhitDiffPlot = {
+        aida.histogram2D("Clustering/Recon-SSP Energy-Hit Difference (All)",     21, -0.010, 0.010, 6, -3, 3),
+        aida.histogram2D("Clustering/Recon-SSP Energy-Hit Difference (Matched)", 21, -0.010, 0.010, 6, -3, 3),
+        aida.histogram2D("Clustering/Recon-SSP Energy-Hit Difference (Failed)",  21, -0.010, 0.010, 6, -3, 3)
+    };
+    private ICloud2D[] efficiencyTimeHist = {
+            aida.cloud2D("Clustering/Cluster Efficiency vs. Time"),
+            aida.cloud2D("Singles Trigger 0/Cluster Efficiency vs. Time"),
+            aida.cloud2D("Singles Trigger 1/Cluster Efficiency vs. Time"),
+            aida.cloud2D("Pair Trigger 0/Cluster Efficiency vs. Time"),
+            aida.cloud2D("Pair Trigger 1/Cluster Efficiency vs. Time")
+    };
+    
+    /**
+     * Define the trigger modules. This should be replaced by parsing
+     * the DAQ configuration at some point.
+     */
+    @Override
+    public void startOfData() {
+        // By default, all triggers and cuts are enabled.
+        for(int i = 0; i < 2; i++) {
+            // Enable the triggers.
+            pairTriggerEnabled[i] = true;
+            singlesTriggerEnabled[i] = true;
+            
+            // Enable the singles cuts.
+            for(int j = 0; j < singlesCutsEnabled.length; j++) {
+                singlesCutsEnabled[i][j] = true;
+            }
+            
+            // Enable the pair cuts.
+            for(int j = 0; j < pairCutsEnabled.length; j++) {
+                pairCutsEnabled[i][j] = true;
+            }
+        }
+        
+        // If the DAQ configuration should be read, attach a listener
+        // to track when it updates.
+        if(readDAQConfig) {
+            ConfigurationManager.addActionListener(new ActionListener() {
+                @Override
+                public void actionPerformed(ActionEvent e) {
+                    // Get the DAQ configuration.
+                    DAQConfig daq = ConfigurationManager.getInstance();
+                    
+                    // Update the plotting energy slope values.
+                    globalTriggerPlots.setEnergySlopeParamF(0, daq.getSSPConfig().getPair1Config().getEnergySlopeCutConfig().getParameterF());
+                    globalTriggerPlots.setEnergySlopeParamF(1, daq.getSSPConfig().getPair2Config().getEnergySlopeCutConfig().getParameterF());
+                    
+                    // Load the DAQ settings from the configuration manager.
+                    singlesTrigger[0].loadDAQConfiguration(daq.getSSPConfig().getSingles1Config());
+                    singlesTrigger[1].loadDAQConfiguration(daq.getSSPConfig().getSingles2Config());
+                    pairsTrigger[0].loadDAQConfiguration(daq.getSSPConfig().getPair1Config());
+                    pairsTrigger[1].loadDAQConfiguration(daq.getSSPConfig().getPair2Config());
+                    nsa = daq.getFADCConfig().getNSA();
+                    nsb = daq.getFADCConfig().getNSB();
+                    windowWidth = daq.getFADCConfig().getWindowWidth();
+                    
+                    // Get the trigger configurations from the DAQ.
+                    SinglesTriggerConfig[] singles = { daq.getSSPConfig().getSingles1Config(),
+                            daq.getSSPConfig().getSingles2Config() };
+                    PairTriggerConfig[] pairs = { daq.getSSPConfig().getPair1Config(),
+                            daq.getSSPConfig().getPair2Config() };
+                    
+                    // Update the enabled/disabled statuses.
+                    for(int i = 0; i < 2; i++) {
+                        // Set the trigger enabled status.
+                        pairTriggerEnabled[i] = pairs[i].isEnabled();
+                        singlesTriggerEnabled[i] = singles[i].isEnabled();
+                        
+                        // Set the singles cut statuses.
+                        singlesCutsEnabled[i][ENERGY_MIN] = singles[i].getEnergyMinCutConfig().isEnabled();
+                        singlesCutsEnabled[i][ENERGY_MAX] = singles[i].getEnergyMaxCutConfig().isEnabled();
+                        singlesCutsEnabled[i][HIT_COUNT] = singles[i].getHitCountCutConfig().isEnabled();
+                        
+                        // Set the pair cut statuses.
+                        pairCutsEnabled[i][ENERGY_MIN] = pairs[i].getEnergyMinCutConfig().isEnabled();
+                        pairCutsEnabled[i][ENERGY_MAX] = pairs[i].getEnergyMaxCutConfig().isEnabled();
+                        pairCutsEnabled[i][HIT_COUNT] = pairs[i].getHitCountCutConfig().isEnabled();
+                        pairCutsEnabled[i][3 + ENERGY_SUM] = pairs[i].getEnergySumCutConfig().isEnabled();
+                        pairCutsEnabled[i][3 + ENERGY_DIFF] = pairs[i].getEnergyDifferenceCutConfig().isEnabled();
+                        pairCutsEnabled[i][3 + ENERGY_SLOPE] = pairs[i].getEnergySlopeCutConfig().isEnabled();
+                        pairCutsEnabled[i][3 + COPLANARITY] = pairs[i].getCoplanarityCutConfig().isEnabled();
+                    }
+                    
+                    // Update the trigger plots values.
+                    globalTriggerPlots.setEnergySlopeParamF(0, daq.getSSPConfig().getPair1Config().getEnergySlopeCutConfig().getParameterF());
+                    globalTriggerPlots.setEnergySlopeParamF(1, daq.getSSPConfig().getPair2Config().getEnergySlopeCutConfig().getParameterF());
+                    
+                    // Print a DAQ configuration settings header.
+                    System.out.println();
+                    System.out.println();
+                    System.out.println("======================================================================");
+                    System.out.println("=== DAQ Configuration Settings =======================================");
+                    System.out.println("======================================================================");
+                    logSettings();
+                }
+            });
+        }
+        
+        // Print the cluster verification header.
+        System.out.println();
+        System.out.println();
+        System.out.println("======================================================================");
+        System.out.println("=== Cluster/Trigger Verification Settings ============================");
+        System.out.println("======================================================================");
+        
+        // Define the first singles trigger.
+        singlesTrigger[0] = new TriggerModule();
+        singlesTrigger[0].setCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_LOW, 0.500);
+        singlesTrigger[0].setCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_HIGH, 8.191);
+        singlesTrigger[0].setCutValue(TriggerModule.CLUSTER_HIT_COUNT_LOW, 0);
+        
+        // Define the second singles trigger.
+        singlesTrigger[1] = new TriggerModule();
+        singlesTrigger[1].setCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_LOW, 0.000);
+        singlesTrigger[1].setCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_HIGH, 8.191);
+        singlesTrigger[1].setCutValue(TriggerModule.CLUSTER_HIT_COUNT_LOW, 0);
+        
+        // Define the first pairs trigger.
+        pairsTrigger[0] = new TriggerModule();
+        pairsTrigger[0].setCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_LOW, 0.000);
+        pairsTrigger[0].setCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_HIGH, 8.191);
+        pairsTrigger[0].setCutValue(TriggerModule.CLUSTER_HIT_COUNT_LOW, 0);
+        pairsTrigger[0].setCutValue(TriggerModule.PAIR_ENERGY_SUM_LOW, 0.000);
+        pairsTrigger[0].setCutValue(TriggerModule.PAIR_ENERGY_SUM_HIGH, 8.191);
+        pairsTrigger[0].setCutValue(TriggerModule.PAIR_ENERGY_DIFFERENCE_HIGH, 8.191);
+        pairsTrigger[0].setCutValue(TriggerModule.PAIR_ENERGY_SLOPE_LOW, 0.000);
+        pairsTrigger[0].setCutValue(TriggerModule.PAIR_ENERGY_SLOPE_F, 0.001);
+        pairsTrigger[0].setCutValue(TriggerModule.PAIR_COPLANARITY_HIGH, 180);
+        pairsTrigger[0].setCutValue(TriggerModule.PAIR_TIME_COINCIDENCE, 8);
+        
+        // Define the second pairs trigger.
+        pairsTrigger[1] = new TriggerModule();
+        pairsTrigger[1].setCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_LOW, 0.000);
+        pairsTrigger[1].setCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_HIGH, 8.191);
+        pairsTrigger[1].setCutValue(TriggerModule.CLUSTER_HIT_COUNT_LOW, 0);
+        pairsTrigger[1].setCutValue(TriggerModule.PAIR_ENERGY_SUM_LOW, 0.000);
+        pairsTrigger[1].setCutValue(TriggerModule.PAIR_ENERGY_SUM_HIGH, 8.191);
+        pairsTrigger[1].setCutValue(TriggerModule.PAIR_ENERGY_DIFFERENCE_HIGH, 8.191);
+        pairsTrigger[1].setCutValue(TriggerModule.PAIR_ENERGY_SLOPE_LOW, 0.000);
+        pairsTrigger[1].setCutValue(TriggerModule.PAIR_ENERGY_SLOPE_F, 0.001);
+        pairsTrigger[1].setCutValue(TriggerModule.PAIR_COPLANARITY_HIGH, 180);
+        pairsTrigger[1].setCutValue(TriggerModule.PAIR_TIME_COINCIDENCE, 8);
+        
+        // Print the initial settings.
+        logSettings();
+    }
+    
+    /**
+     * Prints the total run statistics.
+     */
+    @Override
+    public void endOfData() {
+        // Output the statistics.
+        logStatistics();
+        
+        /*
+        // Calculate the values needed for the efficiency histogram.
+        long totalTime = entryList.get(entryList.size()).time / 1000000000;
+        int entries = (int) (totalTime / (localWindowThreshold / 1000000000)) + 1;
+        
+        // Generate a histogram containing the efficiencies.
+        IHistogram1D[] efficiencyHist = new IHistogram1D[5];
+        for(int i = 0; i < 5; i++) {
+            efficiencyHist[i] = aida.histogram1D("Efficiency " + i, entries, 0.0, totalTime + (localWindowThreshold / 1000000000));
+        }
+        
+        // Input the efficiencies.
+        for(EfficiencyEntry entry : entryList) {
+            for(int i = 0; i < 5; i++) {
+                efficiencyHist[i].fill(entry.time / 1000000000, entry.efficiency[i]);
+            }
+        }
+        */
+    }
+    
+    /**
+     * Gets the banks and clusters from the event.
+     */
+    @Override
+    public void process(EventHeader event) {
+        // ==========================================================
+        // ==== Event Pre-Initialization ============================
+        // ==========================================================
+        
+        // If DAQ settings are to be used, check if they are initialized
+        // yet. If not, skip the event.
+        if(readDAQConfig) {
+            if(!ConfigurationManager.isInitialized()) {
+                return;
+            }
+        }
+        
+        // Reset the candidate cluster lists.
+        singlesCandidates.clear();
+        singlesCandidates.add(new ArrayList<Cluster>());
+        singlesCandidates.add(new ArrayList<Cluster>());
+        pairCandidates.clear();
+        pairCandidates.add(new ArrayList<LCRelation>());
+        pairCandidates.add(new ArrayList<LCRelation>());
+        
+        // Increment the total event count.
+        localStats.sawEvent(event.getTimeStamp());
+        globalStats.sawEvent(event.getTimeStamp());
+        
+        // Print the statistics every so often during a run.
+        if(globalStats.getEventCount() % statPrintInterval == 0) {
+            logStatistics();
+        }
+        
+        // Reset the output buffer and print flags.
+        clusterFail = false;
+        singlesInternalFail = false;
+        singlesEfficiencyFail = false;
+        pairInternalFail = false;
+        pairEfficiencyFail = false;
+        OutputLogger.clearLog();
+        
+        // Track the times.
+        if(startTime == -1) { startTime = event.getTimeStamp(); }
+        else { endTime = event.getTimeStamp(); }
+        
+        
+        
+        // ==========================================================
+        // ==== Output GTP Information ==============================
+        // ==========================================================
+        
         // Print the verification header.
-		OutputLogger.printNewLine(2);
-		OutputLogger.println("======================================================================");
-		OutputLogger.println("==== FADC/GTP Readout ================================================");
-		OutputLogger.println("======================================================================");
-		
-		OutputLogger.println("FADC Hits:");
-		for(CalorimeterHit hit : event.get(CalorimeterHit.class, "EcalCalHits")) {
-			int ix = hit.getIdentifierFieldValue("ix");
-			int iy = hit.getIdentifierFieldValue("iy");
-			OutputLogger.printf("\tHit at (%3d, %3d) with %7.3f GeV at time %3.0f ns%n", ix, iy, hit.getCorrectedEnergy(), hit.getTime());
-		}
-		OutputLogger.printNewLine(2);
-		OutputLogger.println("GTP Clusters:");
-		for(Cluster cluster : event.get(Cluster.class, clusterCollectionName)) {
-			OutputLogger.printf("\t%s%n", TriggerDiagnosticUtil.clusterToString(cluster));
-			for(CalorimeterHit hit : cluster.getCalorimeterHits()) {
-				int ix = hit.getIdentifierFieldValue("ix");
-				int iy = hit.getIdentifierFieldValue("iy");
-				OutputLogger.printf("\t\t> (%3d, %3d) :: %7.3f GeV%n", ix, iy, hit.getCorrectedEnergy());
-			}
-		}
-		
-		
-		
-		// ==========================================================
-		// ==== Initialize the Event ================================
-		// ==========================================================
-		
+        OutputLogger.printNewLine(2);
+        OutputLogger.println("======================================================================");
+        OutputLogger.println("==== FADC/GTP Readout ================================================");
+        OutputLogger.println("======================================================================");
+        
+        OutputLogger.println("FADC Hits:");
+        for(CalorimeterHit hit : event.get(CalorimeterHit.class, "EcalCalHits")) {
+            int ix = hit.getIdentifierFieldValue("ix");
+            int iy = hit.getIdentifierFieldValue("iy");
+            OutputLogger.printf("\tHit at (%3d, %3d) with %7.3f GeV at time %3.0f ns%n", ix, iy, hit.getCorrectedEnergy(), hit.getTime());
+        }
+        OutputLogger.printNewLine(2);
+        OutputLogger.println("GTP Clusters:");
+        for(Cluster cluster : event.get(Cluster.class, clusterCollectionName)) {
+            OutputLogger.printf("\t%s%n", TriggerDiagnosticUtil.clusterToString(cluster));
+            for(CalorimeterHit hit : cluster.getCalorimeterHits()) {
+                int ix = hit.getIdentifierFieldValue("ix");
+                int iy = hit.getIdentifierFieldValue("iy");
+                OutputLogger.printf("\t\t> (%3d, %3d) :: %7.3f GeV%n", ix, iy, hit.getCorrectedEnergy());
+            }
+        }
+        
+        
+        
+        // ==========================================================
+        // ==== Initialize the Event ================================
+        // ==========================================================
+        
         // Print the verification header.
-		OutputLogger.printNewLine(2);
-		OutputLogger.println("======================================================================");
-		OutputLogger.println("==== Cluster/Trigger Verification ====================================");
-		OutputLogger.println("======================================================================");
-		
-		
-		
-		// ==========================================================
-		// ==== Obtain SSP and TI Banks =============================
-		// ==========================================================
-		
-		// Get the SSP clusters.
-		if(event.hasCollection(GenericObject.class, bankCollectionName)) {
-			// Get the bank list.
-			List<GenericObject> bankList = event.get(GenericObject.class, bankCollectionName);
-			
-			// Search through the banks and get the SSP and TI banks.
-			for(GenericObject obj : bankList) {
-				// If this is an SSP bank, parse it.
-				if(AbstractIntData.getTag(obj) == SSPData.BANK_TAG) {
-					sspBank = new SSPData(obj);
-				}
-				
-				// Otherwise, if this is a TI bank, parse it.
-				else if(AbstractIntData.getTag(obj) == TIData.BANK_TAG) {
-					tiBank = new TIData(obj);
-					
-					tiFlags = new boolean[6];
-					if(tiBank.isPulserTrigger()) {
-						OutputLogger.println("Trigger type :: Pulser");
-						tiFlags[TriggerDiagStats.PULSER] = true;
-					} else if(tiBank.isSingle0Trigger()) {
-						OutputLogger.println("Trigger type :: Singles 1");
-						tiFlags[TriggerDiagStats.SINGLES0] = true;
-					} else if(tiBank.isSingle1Trigger()) {
-						OutputLogger.println("Trigger type :: Singles 2");
-						tiFlags[TriggerDiagStats.SINGLES1] = true;
-					} else if(tiBank.isPair0Trigger()) {
-						OutputLogger.println("Trigger type :: Pair 1");
-						tiFlags[TriggerDiagStats.PAIR0] = true;
-					} else if(tiBank.isPair1Trigger()) {
-						OutputLogger.println("Trigger type :: Pair 2");
-						tiFlags[TriggerDiagStats.PAIR1] = true;
-					} else if(tiBank.isCalibTrigger()) {
-						OutputLogger.println("Trigger type :: Cosmic");
-						tiFlags[TriggerDiagStats.COSMIC] = true;
-					} else {
-						System.err.println("TriggerDiagnosticDriver: Skipping event; no TI trigger source found.");
-						return;
-					}
-					
-					// Pass the TI triggers to the run statistical data
-					// manager object.
-					localStats.getTriggerStats().sawTITriggers(tiFlags);
-					globalStats.getTriggerStats().sawTITriggers(tiFlags);
-				}
-			}
-			
-			// If there is an SSP bank, get the list of SSP clusters.
-			if(sspBank != null) {
-				sspClusters = sspBank.getClusters();
-				if(sspClusters.size() == 1) {
-					OutputLogger.println("1 SSP cluster found.");
-				} else {
-					OutputLogger.printf("%d SSP clusters found.%n", sspClusters.size());
-				}
-			}
-		}
-		
-		// Make sure that both an SSP bank and a TI bank were found.
-		if(tiBank == null || sspBank == null) {
-			System.err.println("TriggerDiagnosticDriver :: SEVERE WARNING :: TI bank or SSP bank missing from event!");
-			return;
-		}
-		
-		// Output the event number and information.
-		OutputLogger.printf("Event Number %d (%d)%n", sspBank.getEventNumber(), event.getEventNumber());
-		
-		
-		
-		// ==========================================================
-		// ==== Establish Event Integrity ===========================
-		// ==========================================================
-		
-		// Check that all of the required objects are present.
-		if(sspBank == null) {
-			OutputLogger.println("No SSP bank found for this event. No verification will be performed.");
-			if(verbose) { OutputLogger.printLog(); }
-			return;
-		} if(tiBank == null) {
-			OutputLogger.println("No TI bank found for this event. No verification will be performed.");
-			if(verbose) { OutputLogger.printLog(); }
-			return;
-		}
-		
-		
-		
-		// ==========================================================
-		// ==== Check the Noise Level ===============================
-		// ==========================================================
-		
-		// Check if there are hits.
-		if(event.hasCollection(CalorimeterHit.class, hitCollectionName)) {
-			// Check if there are more hits than the noise threshold.
-			if(event.get(CalorimeterHit.class, hitCollectionName).size() >= noiseThreshold) {
-				localStats.sawNoiseEvent();
-				globalStats.sawNoiseEvent();
-				OutputLogger.println("Noise event detected. Skipping event...");
-				if(verbose) { OutputLogger.printLog(); }
-				return;
-			}
-		}
-        
-        
-        
-		// ==========================================================
-		// ==== Obtain Reconstructed Clusters =======================
-		// ==========================================================
-		
-		// Get the reconstructed clusters.
-		if(event.hasCollection(Cluster.class, clusterCollectionName)) {
-			// Get the reconstructed clusters.
-			List<Cluster> allClusters = event.get(Cluster.class, clusterCollectionName);
-			
-			// Keep only the clusters that can be verified.
-			OutputLogger.println();
-			OutputLogger.println("Process cluster for verifiability:");
-			reconClusters.clear();
-			for(Cluster reconCluster : allClusters) {
-				// Check that the cluster is within the safe region of the
-				// FADC readout window. If it is not, it will likely have
-				// inaccurate energy or hit values and may not produce the
-				// expected results.
-				OutputLogger.printf("\t%s", TriggerDiagnosticUtil.clusterToString(reconCluster));
-				if(isVerifiable(reconCluster)) {
-					reconClusters.add(reconCluster);
-					OutputLogger.println(" [  verifiable  ]");
-				} else { OutputLogger.println(" [ unverifiable ]"); }
-			}
-			
-			// Output the number of verifiable clusters found.
-			if(reconClusters.size() == 1) { OutputLogger.println("1 verifiable reconstructed cluster found."); }
-			else { OutputLogger.printf("%d verifiable reconstructed clusters found.%n", reconClusters.size()); }
-			
-			// Output the number of unverifiable clusters found.
-			int unverifiableClusters = allClusters.size() - reconClusters.size();
-			if(unverifiableClusters == 1) { OutputLogger.println("1 unverifiable reconstructed cluster found."); }
-			else { OutputLogger.printf("%d unverifiable reconstructed clusters found.%n", unverifiableClusters); }
-		} else {
-			reconClusters = new ArrayList<Cluster>(0);
-			OutputLogger.printf("No reconstructed clusters were found for collection \"%s\" in this event.%n", clusterCollectionName);
-		}
-		
-		
-		
-		// ==========================================================
-		// ==== Perform Event Verification ==========================
-		// ==========================================================
-		
-		// Perform the cluster verification step.
-		if(performClusterVerification) { clusterVerification(); }
-		
-		// Get the simulated triggers.
-		if(event.hasCollection(SimTriggerData.class, "SimTriggers")) {
-			List<SimTriggerData> stdList = event.get(SimTriggerData.class, "SimTriggers");
-			triggerData = stdList.get(0);
-		}
-		
-		// Construct lists of triggers for the SSP clusters and the
-		// reconstructed clusters.
-		if(performSinglesTriggerVerification) {
-			singlesTriggerVerification();
-		}
-		if(performPairTriggerVerification) {
-			pairTriggerVerification();
-		}
-		
-		// Track how many events failed due to each type of verification.
-		if(clusterFail) {
-			localStats.failedClusterEvent();
-			globalStats.failedClusterEvent();
-		} if(pairInternalFail || pairEfficiencyFail) {
-			localStats.failedPairEvent();
-			globalStats.failedPairEvent();
-		} if(singlesInternalFail || singlesEfficiencyFail) {
-			localStats.failedSinglesEvent();
-			globalStats.failedSinglesEvent();
-		}
-		
-		
-		
-		// ==========================================================
-		// ==== Perform Event Write-Out =============================
-		// ==========================================================
-		
-		if(verbose ||(clusterFail && printClusterFail) ||
-				(singlesInternalFail && printSinglesTriggerInternalFail) ||
-				(singlesEfficiencyFail && printSinglesTriggerEfficiencyFail) ||
-				(pairInternalFail && printPairTriggerInternalFail) ||
-				(pairEfficiencyFail && printPairTriggerEfficiencyFail)) {
-			OutputLogger.printLog();
-		}	
-		
-		
-				
-		// ==========================================================
-		// ==== Process Local Tracked Variables =====================
-		// ==========================================================
-		if(localStats.getDuration() > localWindowThreshold) {
-			// Write a snapshot of the driver to the event stream.
-			List<DiagnosticSnapshot> snapshotList = new ArrayList<DiagnosticSnapshot>(2);
-			snapshotList.add(localStats.getSnapshot());
-			snapshotList.add(globalStats.getSnapshot());
-			
-			// Push the snapshot to the data stream.
-			event.put(diagnosticCollectionName, snapshotList);
-			
-			// Store values needed to calculate efficiency.
-			int[] matched = {
-					localStats.getClusterStats().getMatches(),
-					localStats.getTriggerStats().getSingles0Stats().getMatchedReconSimulatedTriggers(),
-					localStats.getTriggerStats().getSingles1Stats().getMatchedReconSimulatedTriggers(),
-					localStats.getTriggerStats().getPair0Stats().getMatchedReconSimulatedTriggers(),
-					localStats.getTriggerStats().getPair1Stats().getMatchedReconSimulatedTriggers()
-			};
-			int[] total = {
-					localStats.getClusterStats().getReconClusterCount(),
-					localStats.getTriggerStats().getSingles0Stats().getReconSimulatedTriggers(),
-					localStats.getTriggerStats().getSingles1Stats().getReconSimulatedTriggers(),
-					localStats.getTriggerStats().getPair0Stats().getReconSimulatedTriggers(),
-					localStats.getTriggerStats().getPair1Stats().getReconSimulatedTriggers()
-			};
-			
-			// Calculate the efficiencies and upper/lower errors.
-			double[] efficiency = new double[5];
-			for(int i = 0; i < 5; i++) {
-				efficiency[i] = 1.0 * matched[i] / total[i];
-			}
-			
-			// Get the time for the current snapshot. This is the total
-			// run time before the snapshot plus half of the snapshot.
-			long time = globalStats.getDuration() - (localStats.getDuration() / 2);
-			
-			// Add them to the appropriate cloud plot.
-			for(int i = 0; i < 5; i++) { efficiencyTimeHist[i].fill(time, efficiency[i]); }
-			
-			// Clear the local statistical data.
-			localStats.clear();
-		}
-		
-		
-		
-		// ==========================================================
-		// ==== Write the Candidate Triggers ========================
-		// ==========================================================
-		
-		// Write the candidates to a collection.
-		event.put(pairCandidateCollectionName[0], pairCandidates.get(0), LCRelation.class, 0);
-		event.put(pairCandidateCollectionName[1], pairCandidates.get(1), LCRelation.class, 0);
-		event.put(singlesCandidateCollectionName[0], singlesCandidates.get(0), Cluster.class, clusterCollectionFlag);
-		event.put(singlesCandidateCollectionName[1], singlesCandidates.get(1), Cluster.class, clusterCollectionFlag);
-	}
+        OutputLogger.printNewLine(2);
+        OutputLogger.println("======================================================================");
+        OutputLogger.println("==== Cluster/Trigger Verification ====================================");
+        OutputLogger.println("======================================================================");
+        
+        
+        
+        // ==========================================================
+        // ==== Obtain SSP and TI Banks =============================
+        // ==========================================================
+        
+        // Get the SSP clusters.
+        if(event.hasCollection(GenericObject.class, bankCollectionName)) {
+            // Get the bank list.
+            List<GenericObject> bankList = event.get(GenericObject.class, bankCollectionName);
+            
+            // Search through the banks and get the SSP and TI banks.
+            for(GenericObject obj : bankList) {
+                // If this is an SSP bank, parse it.
+                if(AbstractIntData.getTag(obj) == SSPData.BANK_TAG) {
+                    sspBank = new SSPData(obj);
+                }
+                
+                // Otherwise, if this is a TI bank, parse it.
+                else if(AbstractIntData.getTag(obj) == TIData.BANK_TAG) {
+                    tiBank = new TIData(obj);
+                    
+                    tiFlags = new boolean[6];
+                    if(tiBank.isPulserTrigger()) {
+                        OutputLogger.println("Trigger type :: Pulser");
+                        tiFlags[TriggerDiagStats.PULSER] = true;
+                    } else if(tiBank.isSingle0Trigger()) {
+                        OutputLogger.println("Trigger type :: Singles 1");
+                        tiFlags[TriggerDiagStats.SINGLES0] = true;
+                    } else if(tiBank.isSingle1Trigger()) {
+                        OutputLogger.println("Trigger type :: Singles 2");
+                        tiFlags[TriggerDiagStats.SINGLES1] = true;
+                    } else if(tiBank.isPair0Trigger()) {
+                        OutputLogger.println("Trigger type :: Pair 1");
+                        tiFlags[TriggerDiagStats.PAIR0] = true;
+                    } else if(tiBank.isPair1Trigger()) {
+                        OutputLogger.println("Trigger type :: Pair 2");
+                        tiFlags[TriggerDiagStats.PAIR1] = true;
+                    } else if(tiBank.isCalibTrigger()) {
+                        OutputLogger.println("Trigger type :: Cosmic");
+                        tiFlags[TriggerDiagStats.COSMIC] = true;
+                    } else {
+                        System.err.println("TriggerDiagnosticDriver: Skipping event; no TI trigger source found.");
+                        return;
+                    }
+                    
+                    // Pass the TI triggers to the run statistical data
+                    // manager object.
+                    localStats.getTriggerStats().sawTITriggers(tiFlags);
+                    globalStats.getTriggerStats().sawTITriggers(tiFlags);
+                }
+            }
+            
+            // If there is an SSP bank, get the list of SSP clusters.
+            if(sspBank != null) {
+                sspClusters = sspBank.getClusters();
+                if(sspClusters.size() == 1) {
+                    OutputLogger.println("1 SSP cluster found.");
+                } else {
+                    OutputLogger.printf("%d SSP clusters found.%n", sspClusters.size());
+                }
+            }
+        }
+        
+        // Make sure that both an SSP bank and a TI bank were found.
+        if(tiBank == null || sspBank == null) {
+            System.err.println("TriggerDiagnosticDriver :: SEVERE WARNING :: TI bank or SSP bank missing from event!");
+            return;
+        }
+        
+        // Output the event number and information.
+        OutputLogger.printf("Event Number %d (%d)%n", sspBank.getEventNumber(), event.getEventNumber());
+        
+        
+        
+        // ==========================================================
+        // ==== Establish Event Integrity ===========================
+        // ==========================================================
+        
+        // Check that all of the required objects are present.
+        if(sspBank == null) {
+            OutputLogger.println("No SSP bank found for this event. No verification will be performed.");
+            if(verbose) { OutputLogger.printLog(); }
+            return;
+        } if(tiBank == null) {
+            OutputLogger.println("No TI bank found for this event. No verification will be performed.");
+            if(verbose) { OutputLogger.printLog(); }
+            return;
+        }
+        
+        
+        
+        // ==========================================================
+        // ==== Check the Noise Level ===============================
+        // ==========================================================
+        
+        // Check if there are hits.
+        if(event.hasCollection(CalorimeterHit.class, hitCollectionName)) {
+            // Check if there are more hits than the noise threshold.
+            if(event.get(CalorimeterHit.class, hitCollectionName).size() >= noiseThreshold) {
+                localStats.sawNoiseEvent();
+                globalStats.sawNoiseEvent();
+                OutputLogger.println("Noise event detected. Skipping event...");
+                if(verbose) { OutputLogger.printLog(); }
+                return;
+            }
+        }
+        
+        
+        
+        // ==========================================================
+        // ==== Obtain Reconstructed Clusters =======================
+        // ==========================================================
+        
+        // Get the reconstructed clusters.
+        if(event.hasCollection(Cluster.class, clusterCollectionName)) {
+            // Get the reconstructed clusters.
+            List<Cluster> allClusters = event.get(Cluster.class, clusterCollectionName);
+            
+            // Keep only the clusters that can be verified.
+            OutputLogger.println();
+            OutputLogger.println("Process cluster for verifiability:");
+            reconClusters.clear();
+            for(Cluster reconCluster : allClusters) {
+                // Check that the cluster is within the safe region of the
+                // FADC readout window. If it is not, it will likely have
+                // inaccurate energy or hit values and may not produce the
+                // expected results.
+                OutputLogger.printf("\t%s", TriggerDiagnosticUtil.clusterToString(reconCluster));
+                if(isVerifiable(reconCluster)) {
+                    reconClusters.add(reconCluster);
+                    OutputLogger.println(" [  verifiable  ]");
+                } else { OutputLogger.println(" [ unverifiable ]"); }
+            }
+            
+            // Output the number of verifiable clusters found.
+            if(reconClusters.size() == 1) { OutputLogger.println("1 verifiable reconstructed cluster found."); }
+            else { OutputLogger.printf("%d verifiable reconstructed clusters found.%n", reconClusters.size()); }
+            
+            // Output the number of unverifiable clusters found.
+            int unverifiableClusters = allClusters.size() - reconClusters.size();
+            if(unverifiableClusters == 1) { OutputLogger.println("1 unverifiable reconstructed cluster found."); }
+            else { OutputLogger.printf("%d unverifiable reconstructed clusters found.%n", unverifiableClusters); }
+        } else {
+            reconClusters = new ArrayList<Cluster>(0);
+            OutputLogger.printf("No reconstructed clusters were found for collection \"%s\" in this event.%n", clusterCollectionName);
+        }
+        
+        
+        
+        // ==========================================================
+        // ==== Perform Event Verification ==========================
+        // ==========================================================
+        
+        // Perform the cluster verification step.
+        if(performClusterVerification) { clusterVerification(); }
+        
+        // Get the simulated triggers.
+        if(event.hasCollection(SimTriggerData.class, "SimTriggers")) {
+            List<SimTriggerData> stdList = event.get(SimTriggerData.class, "SimTriggers");
+            triggerData = stdList.get(0);
+        }
+        
+        // Construct lists of triggers for the SSP clusters and the
+        // reconstructed clusters.
+        if(performSinglesTriggerVerification) {
+            singlesTriggerVerification();
+        }
+        if(performPairTriggerVerification) {
+            pairTriggerVerification();
+        }
+        
+        // Track how many events failed due to each type of verification.
+        if(clusterFail) {
+            localStats.failedClusterEvent();
+            globalStats.failedClusterEvent();
+        } if(pairInternalFail || pairEfficiencyFail) {
+            localStats.failedPairEvent();
+            globalStats.failedPairEvent();
+        } if(singlesInternalFail || singlesEfficiencyFail) {
+            localStats.failedSinglesEvent();
+            globalStats.failedSinglesEvent();
+        }
+        
+        
+        
+        // ==========================================================
+        // ==== Perform Event Write-Out =============================
+        // ==========================================================
+        
+        if(verbose ||(clusterFail && printClusterFail) ||
+                (singlesInternalFail && printSinglesTriggerInternalFail) ||
+                (singlesEfficiencyFail && printSinglesTriggerEfficiencyFail) ||
+                (pairInternalFail && printPairTriggerInternalFail) ||
+                (pairEfficiencyFail && printPairTriggerEfficiencyFail)) {
+            OutputLogger.printLog();
+        }   
+        
+        
+                
+        // ==========================================================
+        // ==== Process Local Tracked Variables =====================
+        // ==========================================================
+        if(localStats.getDuration() > localWindowThreshold) {
+            // Write a snapshot of the driver to the event stream.
+            List<DiagnosticSnapshot> snapshotList = new ArrayList<DiagnosticSnapshot>(2);
+            snapshotList.add(localStats.getSnapshot());
+            snapshotList.add(globalStats.getSnapshot());
+            
+            // Push the snapshot to the data stream.
+            event.put(diagnosticCollectionName, snapshotList);
+            
+            // Store values needed to calculate efficiency.
+            int[] matched = {
+                    localStats.getClusterStats().getMatches(),
+                    localStats.getTriggerStats().getSingles0Stats().getMatchedReconSimulatedTriggers(),
+                    localStats.getTriggerStats().getSingles1Stats().getMatchedReconSimulatedTriggers(),
+                    localStats.getTriggerStats().getPair0Stats().getMatchedReconSimulatedTriggers(),
+                    localStats.getTriggerStats().getPair1Stats().getMatchedReconSimulatedTriggers()
+            };
+            int[] total = {
+                    localStats.getClusterStats().getReconClusterCount(),
+                    localStats.getTriggerStats().getSingles0Stats().getReconSimulatedTriggers(),
+                    localStats.getTriggerStats().getSingles1Stats().getReconSimulatedTriggers(),
+                    localStats.getTriggerStats().getPair0Stats().getReconSimulatedTriggers(),
+                    localStats.getTriggerStats().getPair1Stats().getReconSimulatedTriggers()
+            };
+            
+            // Calculate the efficiencies and upper/lower errors.
+            double[] efficiency = new double[5];
+            for(int i = 0; i < 5; i++) {
+                efficiency[i] = 1.0 * matched[i] / total[i];
+            }
+            
+            // Get the time for the current snapshot. This is the total
+            // run time before the snapshot plus half of the snapshot.
+            long time = globalStats.getDuration() - (localStats.getDuration() / 2);
+            
+            // Add them to the appropriate cloud plot.
+            for(int i = 0; i < 5; i++) { efficiencyTimeHist[i].fill(time, efficiency[i]); }
+            
+            // Clear the local statistical data.
+            localStats.clear();
+        }
+        
+        
+        
+        // ==========================================================
+        // ==== Write the Candidate Triggers ========================
+        // ==========================================================
+        
+        // Write the candidates to a collection.
+        event.put(pairCandidateCollectionName[0], pairCandidates.get(0), LCRelation.class, 0);
+        event.put(pairCandidateCollectionName[1], pairCandidates.get(1), LCRelation.class, 0);
+        event.put(singlesCandidateCollectionName[0], singlesCandidates.get(0), Cluster.class, clusterCollectionFlag);
+        event.put(singlesCandidateCollectionName[1], singlesCandidates.get(1), Cluster.class, clusterCollectionFlag);
+    }
 
-	public void setPrintResultsEveryNEvents(int n) {
-		statPrintInterval = n;
-	}
-	
-	public void setPrintOnClusterFailure(boolean state) {
-		printClusterFail = state;
-	}
-	
-	public void setPrintOnSinglesEfficiencyFailure(boolean state) {
-		printSinglesTriggerEfficiencyFail = state;
-	}
-	
-	public void setPrintOnSinglesSSPFailure(boolean state) {
-		printSinglesTriggerInternalFail = state;
-	}
-	
-	public void setPrintOnPairEfficiencyFailure(boolean state) {
-		printPairTriggerEfficiencyFail = state;
-	}
-	
-	public void setPrintOnPairSSPFailure(boolean state) {
-		printPairTriggerInternalFail = state;
-	}
-	
-	public void setVerbose(boolean state) {
-		verbose = state;
-	}
-	
-	public void setHitCollectionName(String hitCollectionName) {
-		this.hitCollectionName = hitCollectionName;
-	}
-	
-	public void setClusterCollectionName(String clusterCollectionName) {
-		this.clusterCollectionName = clusterCollectionName;
-	}
-	
-	public void setBankCollectionName(String bankCollectionName) {
-		this.bankCollectionName = bankCollectionName;
-	}
-	
-	public void setNoiseThresholdCount(int noiseHits) {
-		noiseThreshold = noiseHits;
-	}
-	
-	public void setHitAcceptanceWindow(int window) {
-		hitAcceptance = window;
-	}
-	
-	public void setEnergyAcceptanceWindow(double window) {
-		energyAcceptance = window;
-	}
-	
-	public void setEnforceStrictTimeCompliance(boolean state) {
-		enforceTimeCompliance = state;
-	}
-	
-	public void setReadDAQConfig(boolean state) {
-		readDAQConfig = state;
-	}
-	
-	public void setLocalWindowThresholdMilliseconds(int localWindowThreshold) {
-	    this.localWindowThreshold = localWindowThreshold;
-	}
-	
-	/**
-	 * Attempts to match all reconstructed clusters that are safely
-	 * within the integration window with clusters reported by the SSP.
-	 * Method also tracks the ratio of valid reconstructed clusters to
-	 * matches found.<br/>
-	 * <br/>
-	 * Note that unmatched SSP clusters are ignored. Since these may
-	 * or may not correspond to reconstructed clusters that occur in
-	 * the forbidden time region, it is impossible to say whether or
-	 * not these legitimately failed to match or not.
-	 */
-	private void clusterVerification() {
-		// ==========================================================
-		// ==== Initialize Cluster Verification =====================
-		// ==========================================================
-		
-		// Print the cluster verification header.
-		OutputLogger.printNewLine(2);
-		OutputLogger.println("======================================================================");
-		OutputLogger.println("=== Cluster Verification =============================================");
-		OutputLogger.println("======================================================================");
-		
-		
-		
-		// ==========================================================
-		// ==== Perform Cluster Matching ============================
-		// ==========================================================
-		
-		// Track the number of cluster pairs that were matched and that
-		// failed by failure type.
-		DetailedClusterEvent event;
-		
-		if(enforceTimeCompliance) {
-			event = matchClustersTimeCompliant(reconClusters, sspClusters, energyAcceptance, hitAcceptance);
-		} else {
-			event = matchClusters(reconClusters, sspClusters, energyAcceptance, hitAcceptance);
-		}
-		
-		// Add the event results to the global results.
-		localStats.getClusterStats().addEvent(event);
-		globalStats.getClusterStats().addEvent(event);
-		localStats.getClusterStats().sawSSPClusters(sspClusters.size());
-		globalStats.getClusterStats().sawSSPClusters(sspClusters.size());
-		localStats.getClusterStats().sawReconClusters(reconClusters.size());
-		globalStats.getClusterStats().sawReconClusters(reconClusters.size());
-		
-		
-		
-		// ==========================================================
-		// ==== Output Event Summary ================================
-		// ==========================================================
-		
-		// Print the valid reconstructed clusters and populate their
-		// distribution graphs.
-		OutputLogger.println();
-		OutputLogger.println("Verified Reconstructed Clusters:");
-		if(!reconClusters.isEmpty()) {
-			for(Cluster reconCluster : reconClusters) {
-				OutputLogger.printf("\t%s%n", TriggerDiagnosticUtil.clusterToString(reconCluster));
-			}
-		} else { OutputLogger.println("\tNone"); }
-		
-		// Print the SSP clusters and populate their distribution graphs.
-		OutputLogger.println("SSP Clusters:");
-		if(!sspClusters.isEmpty()) {
-			for(SSPCluster sspCluster : sspClusters) {
-				OutputLogger.printf("\t%s%n", TriggerDiagnosticUtil.clusterToString(sspCluster));
-			}
-		} else { OutputLogger.println("\tNone"); }
-		
-		// Print the matched clusters.
-		OutputLogger.println("Matched Clusters:");
-		if(event.getMatches() != 0) {
-			// Iterate over the matched pairs.
-			for(ClusterMatchedPair pair : event.getClusterPairs()) {
-				// If the pair is a match, print it out.
-				if(pair.isMatch()) {
-					OutputLogger.printf("\t%s --> %s%n",
-							TriggerDiagnosticUtil.clusterToString(pair.getReconstructedCluster()),
-							TriggerDiagnosticUtil.clusterToString(pair.getSSPCluster()));
-				}
-			}
-		}
-		 else { OutputLogger.println("\tNone"); }
-		
-		// Print event statistics.
-		OutputLogger.println();
-		OutputLogger.println("Event Statistics:");
-		OutputLogger.printf("\tRecon Clusters     :: %d%n", reconClusters.size());
-		OutputLogger.printf("\tClusters Matched   :: %d%n", event.getMatches());
-		OutputLogger.printf("\tFailed (Position)  :: %d%n", event.getPositionFailures());
-		OutputLogger.printf("\tFailed (Time)      :: %d%n", event.getTimeFailures());
-		OutputLogger.printf("\tFailed (Energy)    :: %d%n", event.getEnergyFailures());
-		OutputLogger.printf("\tFailed (Hit Count) :: %d%n", event.getHitCountFailures());
-		OutputLogger.printf("\tCluster Efficiency :: %3.0f%%%n", 100.0 * event.getMatches() / reconClusters.size());
-		
-		// Note whether there was a cluster match failure.
-		if(event.isFailState() || event.getMatches() - reconClusters.size() != 0) {
-			clusterFail = true;
-		}
-		
-		
-		
-		// TEMP :: Populate the cluster diagnostic plots.
-		
-		// Populate the ALL cluster plots.
-		for(Cluster cluster : reconClusters) {
-			clusterHitPlot[RECON][ALL].fill(cluster.getCalorimeterHits().size());
-			clusterEnergyPlot[RECON][ALL].fill(cluster.getEnergy());
-			clusterTimePlot[RECON][ALL].fill(cluster.getCalorimeterHits().get(0).getTime());
-			Point position = TriggerDiagnosticUtil.getClusterPosition(cluster);
-			clusterPositionPlot[RECON][ALL].fill(position.x, position.y);
-		}
-		for(SSPCluster cluster : sspClusters) {
-			clusterHitPlot[SSP][ALL].fill(cluster.getHitCount());
-			clusterEnergyPlot[SSP][ALL].fill(cluster.getEnergy());
-			clusterTimePlot[SSP][ALL].fill(cluster.getTime());
-			clusterPositionPlot[SSP][ALL].fill(cluster.getXIndex(), cluster.getYIndex());
-		}
-		
-		// Populate the matched and failed plots.
-		for(ClusterMatchedPair pair : event.getClusterPairs()) {
-			 if(pair.getFirstElement() != null && pair.getSecondElement() != null) {
-				double energyDiff = pair.getSecondElement().getEnergy() - pair.getFirstElement().getEnergy();
-				int hitDiff = pair.getSecondElement().getHitCount() - pair.getFirstElement().getCalorimeterHits().size();
-				energyhitDiffPlot[ALL].fill(energyDiff, hitDiff);
-			 }
-			
-			if(pair.isMatch()) {
-				if(pair.getFirstElement() != null) {
-					clusterHitPlot[RECON][MATCHED].fill(pair.getFirstElement().getCalorimeterHits().size());
-					clusterEnergyPlot[RECON][MATCHED].fill(pair.getFirstElement().getEnergy());
-					clusterTimePlot[RECON][MATCHED].fill(pair.getFirstElement().getCalorimeterHits().get(0).getTime());
-					Point position = TriggerDiagnosticUtil.getClusterPosition(pair.getFirstElement());
-					clusterPositionPlot[RECON][MATCHED].fill(position.x, position.y);
-				} if(pair.getSecondElement() != null) {
-					clusterHitPlot[SSP][MATCHED].fill(pair.getSecondElement().getHitCount());
-					clusterEnergyPlot[SSP][MATCHED].fill(pair.getSecondElement().getEnergy());
-					clusterTimePlot[SSP][MATCHED].fill(pair.getSecondElement().getTime());
-					clusterPositionPlot[SSP][MATCHED].fill(pair.getSecondElement().getXIndex(), pair.getSecondElement().getYIndex());
-				} if(pair.getFirstElement() != null && pair.getSecondElement() != null) {
-					double energyDiff = pair.getSecondElement().getEnergy() - pair.getFirstElement().getEnergy();
-					int hitDiff = pair.getSecondElement().getHitCount() - pair.getFirstElement().getCalorimeterHits().size();
-					energyhitDiffPlot[MATCHED].fill(energyDiff, hitDiff);
-				}
-			} else {
-				if(pair.getFirstElement() != null) {
-					clusterHitPlot[RECON][FAILED].fill(pair.getFirstElement().getCalorimeterHits().size());
-					clusterEnergyPlot[RECON][FAILED].fill(pair.getFirstElement().getEnergy());
-					clusterTimePlot[RECON][FAILED].fill(pair.getFirstElement().getCalorimeterHits().get(0).getTime());
-					Point position = TriggerDiagnosticUtil.getClusterPosition(pair.getFirstElement());
-					clusterPositionPlot[RECON][FAILED].fill(position.x, position.y);
-				} if(pair.getSecondElement() != null) {
-					clusterHitPlot[SSP][FAILED].fill(pair.getSecondElement().getHitCount());
-					clusterEnergyPlot[SSP][FAILED].fill(pair.getSecondElement().getEnergy());
-					clusterTimePlot[SSP][FAILED].fill(pair.getSecondElement().getTime());
-					clusterPositionPlot[SSP][FAILED].fill(pair.getSecondElement().getXIndex(), pair.getSecondElement().getYIndex());
-				} if(pair.getFirstElement() != null && pair.getSecondElement() != null) {
-					double energyDiff = pair.getSecondElement().getEnergy() - pair.getFirstElement().getEnergy();
-					int hitDiff = pair.getSecondElement().getHitCount() - pair.getFirstElement().getCalorimeterHits().size();
-					energyhitDiffPlot[FAILED].fill(energyDiff, hitDiff);
-				}
-			}
-		}
-	}
-	
-	/**
+    public void setPrintResultsEveryNEvents(int n) {
+        statPrintInterval = n;
+    }
+    
+    public void setPrintOnClusterFailure(boolean state) {
+        printClusterFail = state;
+    }
+    
+    public void setPrintOnSinglesEfficiencyFailure(boolean state) {
+        printSinglesTriggerEfficiencyFail = state;
+    }
+    
+    public void setPrintOnSinglesSSPFailure(boolean state) {
+        printSinglesTriggerInternalFail = state;
+    }
+    
+    public void setPrintOnPairEfficiencyFailure(boolean state) {
+        printPairTriggerEfficiencyFail = state;
+    }
+    
+    public void setPrintOnPairSSPFailure(boolean state) {
+        printPairTriggerInternalFail = state;
+    }
+    
+    public void setVerbose(boolean state) {
+        verbose = state;
+    }
+    
+    public void setHitCollectionName(String hitCollectionName) {
+        this.hitCollectionName = hitCollectionName;
+    }
+    
+    public void setClusterCollectionName(String clusterCollectionName) {
+        this.clusterCollectionName = clusterCollectionName;
+    }
+    
+    public void setBankCollectionName(String bankCollectionName) {
+        this.bankCollectionName = bankCollectionName;
+    }
+    
+    public void setNoiseThresholdCount(int noiseHits) {
+        noiseThreshold = noiseHits;
+    }
+    
+    public void setHitAcceptanceWindow(int window) {
+        hitAcceptance = window;
+    }
+    
+    public void setEnergyAcceptanceWindow(double window) {
+        energyAcceptance = window;
+    }
+    
+    public void setEnforceStrictTimeCompliance(boolean state) {
+        enforceTimeCompliance = state;
+    }
+    
+    public void setReadDAQConfig(boolean state) {
+        readDAQConfig = state;
+    }
+    
+    public void setLocalWindowThresholdMilliseconds(int localWindowThreshold) {
+        this.localWindowThreshold = localWindowThreshold;
+    }
+    
+    /**
+     * Attempts to match all reconstructed clusters that are safely
+     * within the integration window with clusters reported by the SSP.
+     * Method also tracks the ratio of valid reconstructed clusters to
+     * matches found.<br/>
+     * <br/>
+     * Note that unmatched SSP clusters are ignored. Since these may
+     * or may not correspond to reconstructed clusters that occur in
+     * the forbidden time region, it is impossible to say whether or
+     * not these legitimately failed to match or not.
+     */
+    private void clusterVerification() {
+        // ==========================================================
+        // ==== Initialize Cluster Verification =====================
+        // ==========================================================
+        
+        // Print the cluster verification header.
+        OutputLogger.printNewLine(2);
+        OutputLogger.println("======================================================================");
+        OutputLogger.println("=== Cluster Verification =============================================");
+        OutputLogger.println("======================================================================");
+        
+        
+        
+        // ==========================================================
+        // ==== Perform Cluster Matching ============================
+        // ==========================================================
+        
+        // Track the number of cluster pairs that were matched and that
+        // failed by failure type.
+        DetailedClusterEvent event;
+        
+        if(enforceTimeCompliance) {
+            event = matchClustersTimeCompliant(reconClusters, sspClusters, energyAcceptance, hitAcceptance);
+        } else {
+            event = matchClusters(reconClusters, sspClusters, energyAcceptance, hitAcceptance);
+        }
+        
+        // Add the event results to the global results.
+        localStats.getClusterStats().addEvent(event);
+        globalStats.getClusterStats().addEvent(event);
+        localStats.getClusterStats().sawSSPClusters(sspClusters.size());
+        globalStats.getClusterStats().sawSSPClusters(sspClusters.size());
+        localStats.getClusterStats().sawReconClusters(reconClusters.size());
+        globalStats.getClusterStats().sawReconClusters(reconClusters.size());
+        
+        
+        
+        // ==========================================================
+        // ==== Output Event Summary ================================
+        // ==========================================================
+        
+        // Print the valid reconstructed clusters and populate their
+        // distribution graphs.
+        OutputLogger.println();
+        OutputLogger.println("Verified Reconstructed Clusters:");
+        if(!reconClusters.isEmpty()) {
+            for(Cluster reconCluster : reconClusters) {
+                OutputLogger.printf("\t%s%n", TriggerDiagnosticUtil.clusterToString(reconCluster));
+            }
+        } else { OutputLogger.println("\tNone"); }
+        
+        // Print the SSP clusters and populate their distribution graphs.
+        OutputLogger.println("SSP Clusters:");
+        if(!sspClusters.isEmpty()) {
+            for(SSPCluster sspCluster : sspClusters) {
+                OutputLogger.printf("\t%s%n", TriggerDiagnosticUtil.clusterToString(sspCluster));
+            }
+        } else { OutputLogger.println("\tNone"); }
+        
+        // Print the matched clusters.
+        OutputLogger.println("Matched Clusters:");
+        if(event.getMatches() != 0) {
+            // Iterate over the matched pairs.
+            for(ClusterMatchedPair pair : event.getClusterPairs()) {
+                // If the pair is a match, print it out.
+                if(pair.isMatch()) {
+                    OutputLogger.printf("\t%s --> %s%n",
+                            TriggerDiagnosticUtil.clusterToString(pair.getReconstructedCluster()),
+                            TriggerDiagnosticUtil.clusterToString(pair.getSSPCluster()));
+                }
+            }
+        }
+         else { OutputLogger.println("\tNone"); }
+        
+        // Print event statistics.
+        OutputLogger.println();
+        OutputLogger.println("Event Statistics:");
+        OutputLogger.printf("\tRecon Clusters     :: %d%n", reconClusters.size());
+        OutputLogger.printf("\tClusters Matched   :: %d%n", event.getMatches());
+        OutputLogger.printf("\tFailed (Position)  :: %d%n", event.getPositionFailures());
+        OutputLogger.printf("\tFailed (Time)      :: %d%n", event.getTimeFailures());
+        OutputLogger.printf("\tFailed (Energy)    :: %d%n", event.getEnergyFailures());
+        OutputLogger.printf("\tFailed (Hit Count) :: %d%n", event.getHitCountFailures());
+        OutputLogger.printf("\tCluster Efficiency :: %3.0f%%%n", 100.0 * event.getMatches() / reconClusters.size());
+        
+        // Note whether there was a cluster match failure.
+        if(event.isFailState() || event.getMatches() - reconClusters.size() != 0) {
+            clusterFail = true;
+        }
+        
+        
+        
+        // TEMP :: Populate the cluster diagnostic plots.
+        
+        // Populate the ALL cluster plots.
+        for(Cluster cluster : reconClusters) {
+            clusterHitPlot[RECON][ALL].fill(cluster.getCalorimeterHits().size());
+            clusterEnergyPlot[RECON][ALL].fill(cluster.getEnergy());
+            clusterTimePlot[RECON][ALL].fill(cluster.getCalorimeterHits().get(0).getTime());
+            Point position = TriggerDiagnosticUtil.getClusterPosition(cluster);
+            clusterPositionPlot[RECON][ALL].fill(position.x, position.y);
+        }
+        for(SSPCluster cluster : sspClusters) {
+            clusterHitPlot[SSP][ALL].fill(cluster.getHitCount());
+            clusterEnergyPlot[SSP][ALL].fill(cluster.getEnergy());
+            clusterTimePlot[SSP][ALL].fill(cluster.getTime());
+            clusterPositionPlot[SSP][ALL].fill(cluster.getXIndex(), cluster.getYIndex());
+        }
+        
+        // Populate the matched and failed plots.
+        for(ClusterMatchedPair pair : event.getClusterPairs()) {
+             if(pair.getFirstElement() != null && pair.getSecondElement() != null) {
+                double energyDiff = pair.getSecondElement().getEnergy() - pair.getFirstElement().getEnergy();
+                int hitDiff = pair.getSecondElement().getHitCount() - pair.getFirstElement().getCalorimeterHits().size();
+                energyhitDiffPlot[ALL].fill(energyDiff, hitDiff);
+             }
+            
+            if(pair.isMatch()) {
+                if(pair.getFirstElement() != null) {
+                    clusterHitPlot[RECON][MATCHED].fill(pair.getFirstElement().getCalorimeterHits().size());
+                    clusterEnergyPlot[RECON][MATCHED].fill(pair.getFirstElement().getEnergy());
+                    clusterTimePlot[RECON][MATCHED].fill(pair.getFirstElement().getCalorimeterHits().get(0).getTime());
+                    Point position = TriggerDiagnosticUtil.getClusterPosition(pair.getFirstElement());
+                    clusterPositionPlot[RECON][MATCHED].fill(position.x, position.y);
+                } if(pair.getSecondElement() != null) {
+                    clusterHitPlot[SSP][MATCHED].fill(pair.getSecondElement().getHitCount());
+                    clusterEnergyPlot[SSP][MATCHED].fill(pair.getSecondElement().getEnergy());
+                    clusterTimePlot[SSP][MATCHED].fill(pair.getSecondElement().getTime());
+                    clusterPositionPlot[SSP][MATCHED].fill(pair.getSecondElement().getXIndex(), pair.getSecondElement().getYIndex());
+                } if(pair.getFirstElement() != null && pair.getSecondElement() != null) {
+                    double energyDiff = pair.getSecondElement().getEnergy() - pair.getFirstElement().getEnergy();
+                    int hitDiff = pair.getSecondElement().getHitCount() - pair.getFirstElement().getCalorimeterHits().size();
+                    energyhitDiffPlot[MATCHED].fill(energyDiff, hitDiff);
+                }
+            } else {
+                if(pair.getFirstElement() != null) {
+                    clusterHitPlot[RECON][FAILED].fill(pair.getFirstElement().getCalorimeterHits().size());
+                    clusterEnergyPlot[RECON][FAILED].fill(pair.getFirstElement().getEnergy());
+                    clusterTimePlot[RECON][FAILED].fill(pair.getFirstElement().getCalorimeterHits().get(0).getTime());
+                    Point position = TriggerDiagnosticUtil.getClusterPosition(pair.getFirstElement());
+                    clusterPositionPlot[RECON][FAILED].fill(position.x, position.y);
+                } if(pair.getSecondElement() != null) {
+                    clusterHitPlot[SSP][FAILED].fill(pair.getSecondElement().getHitCount());
+                    clusterEnergyPlot[SSP][FAILED].fill(pair.getSecondElement().getEnergy());
+                    clusterTimePlot[SSP][FAILED].fill(pair.getSecondElement().getTime());
+                    clusterPositionPlot[SSP][FAILED].fill(pair.getSecondElement().getXIndex(), pair.getSecondElement().getYIndex());
+                } if(pair.getFirstElement() != null && pair.getSecondElement() != null) {
+                    double energyDiff = pair.getSecondElement().getEnergy() - pair.getFirstElement().getEnergy();
+                    int hitDiff = pair.getSecondElement().getHitCount() - pair.getFirstElement().getCalorimeterHits().size();
+                    energyhitDiffPlot[FAILED].fill(energyDiff, hitDiff);
+                }
+            }
+        }
+    }
+    
+    /**
      * Performs cluster matching between a collection of reconstructed
-	 * clusters and a collection of SSP clusters with an algorithm that
-	 * ignores the times reported for each cluster.
-	 * @param reconClusters - A collection of reconstructed clusters.
-	 * @param sspClusters - A collection of SSP clusters.
-	 * @param energyWindow - The window of allowed deviation between
-	 * the reconstructed cluster and SSP cluster energies.
-	 * @param hitWindow - The window of allowed deviation between
-	 * the reconstructed cluster and SSP cluster hit counts.
-	 * @return Returns the cluster matching results stored inside a
-	 * <code>clusterMatchEvent</code> object.
-	 */
-	private static final DetailedClusterEvent matchClusters(Collection<Cluster> reconClusters,
-			Collection<SSPCluster> sspClusters, double energyWindow, int hitWindow) {
-		// Track the number of cluster pairs that were matched and that
-		// failed by failure type.
-		DetailedClusterEvent event = new DetailedClusterEvent();
-		
-		// Create maps to link cluster position to the list of clusters
-		// that were found at that location.
-		Map<Point, List<Cluster>> reconClusterMap = new HashMap<Point, List<Cluster>>(reconClusters.size());
-		Map<Point, List<SSPCluster>> sspClusterMap = new HashMap<Point, List<SSPCluster>>(reconClusters.size());
-		
-		// Populate the reconstructed cluster map.
-		for(Cluster reconCluster : reconClusters) {
-			// Get the cluster position.
-			Point position = new Point(TriggerDiagnosticUtil.getXIndex(reconCluster),
-					TriggerDiagnosticUtil.getYIndex(reconCluster));
-			
-			// Get the list for this cluster position.
-			List<Cluster> reconList = reconClusterMap.get(position);
-			if(reconList == null) {
-				reconList = new ArrayList<Cluster>();
-				reconClusterMap.put(position, reconList);
-			}
-			
-			// Add the cluster to the list.
-			reconList.add(reconCluster);
-		}
-		
-		// Populate the SSP cluster map.
-		for(SSPCluster sspCluster : sspClusters) {
-			// Get the cluster position.
-			Point position = new Point(sspCluster.getXIndex(), sspCluster.getYIndex());
-			
-			// Get the list for this cluster position.
-			List<SSPCluster> sspList = sspClusterMap.get(position);
-			if(sspList == null) {
-				sspList = new ArrayList<SSPCluster>();
-				sspClusterMap.put(position, sspList);
-			}
-			
-			// Add the cluster to the list.
-			sspList.add(sspCluster);
-		}
-		
-		// For each reconstructed cluster, attempt to match the clusters
-		// with SSP clusters at the same position.
-		positionLoop:
-		for(Entry<Point, List<Cluster>> clusterSet : reconClusterMap.entrySet()) {
-			// Get the reconstructed and SSP clusters at this position.
-			List<Cluster> reconList = clusterSet.getValue();
-			List<SSPCluster> sspList = sspClusterMap.get(clusterSet.getKey());
-			
-			// Print the crystal position header.
-			OutputLogger.println();
-			OutputLogger.printf("Considering clusters at (%3d, %3d)%n", clusterSet.getKey().x, clusterSet.getKey().y);
-			
-			// If there are no SSP clusters, then matching fails by
-			// reason of position. The remainder of the loop may be
-			// skipped, since there is nothing to check.
-			if(sspList == null || sspList.isEmpty()) {
-				event.pairFailPosition(reconList.size());
-				continue positionLoop;
-			}
-			
-			// Get all possible permutations of SSP clusters.
-			List<List<Pair<Cluster, SSPCluster>>> permutations = getPermutations(reconList, sspList);
-			
-			// Print the information for this crystal position.
-			OutputLogger.printf("\tRecon Clusters :: %d%n", reconList.size());
-			OutputLogger.printf("\tSSP Clusters   :: %d%n", sspList.size());
-			OutputLogger.printf("\tPermutations   :: %d%n", permutations.size());
-			
-			// Track the plotted values for the current best permutation.
-			DetailedClusterEvent bestPerm = null;
-			
-			// Iterate over the permutations and find the permutation
-			// that produces the best possible result when compared to
-			// the reconstructed clusters.
-			int permIndex = 0;
-			for(List<Pair<Cluster, SSPCluster>> pairs : permutations) {
-				// Update the current permutation number.
-				permIndex++;
-				
-				// Track the plot values for this permutation.
-				DetailedClusterEvent perm = new DetailedClusterEvent();
-				
-				// Try to match each pair.
-				pairLoop:
-				for(Pair<Cluster, SSPCluster> pair : pairs) {
-					// Print the current reconstructed/SSP cluster pair.
-					OutputLogger.printf("\tP%d :: %s --> %s", permIndex,
-							pair.getFirstElement() == null ? "None" : TriggerDiagnosticUtil.clusterToString(pair.getFirstElement()),
-							pair.getSecondElement() == null ? "None" : TriggerDiagnosticUtil.clusterToString(pair.getSecondElement()));
-					
-					// If either cluster in the pair is null, there
-					// are not enough clusters to perform this match.
-					if(pair.getFirstElement() == null || pair.getSecondElement() == null) {
-						// Log the result.
-						OutputLogger.printf(" [ %18s ]%n", "failure: unpaired");
-						
-						// An unpaired SSP cluster does not necessarily
-						// represent a problem. Often, this just means
-						// that the SSP cluster's matching reconstructed
-						// cluster is outside the verification window.
-						if(pair.getSecondElement() == null) {
-							perm.pairFailPosition(pair.getFirstElement(), pair.getSecondElement());
-						}
-						
-						// Skip the rest of the checks.
-						continue pairLoop;
-					}
-					
-					// Check if the reconstructed cluster has an energy
-					// within the allotted threshold of the SSP cluster.
-					if(pair.getSecondElement().getEnergy() >= pair.getFirstElement().getEnergy() - energyWindow &&
-							pair.getSecondElement().getEnergy() <= pair.getFirstElement().getEnergy() + energyWindow) {
-						
-						// Check that the hit count of the reconstructed
-						// is within the allotted threshold of the SSP
-						// cluster.
-						if(pair.getSecondElement().getHitCount() >= pair.getFirstElement().getCalorimeterHits().size() - hitWindow &&
-								pair.getSecondElement().getHitCount() <= pair.getFirstElement().getCalorimeterHits().size() + hitWindow) {
-							// Designate the pair as a match.
-							perm.pairMatch(pair.getFirstElement(), pair.getSecondElement());
-							OutputLogger.printf(" [ %18s ]%n", "success: matched");
-						} else {
-							perm.pairFailHitCount(pair.getFirstElement(), pair.getSecondElement());
-							OutputLogger.printf(" [ %18s ]%n", "failure: hit count");
-						} // End hit count check.
-					} else {
-						perm.pairFailEnergy(pair.getFirstElement(), pair.getSecondElement());
-						OutputLogger.printf(" [ %18s ]%n", "failure: energy");
-					} // End energy check.
-				} // End Pair Loop
-				
-				// Print the results of the permutation.
-				OutputLogger.printf("\t\tPermutation Matched   :: %d%n", perm.getMatches());
-				OutputLogger.printf("\t\tPermutation Energy    :: %d%n", perm.getEnergyFailures());
-				OutputLogger.printf("\t\tPermutation Hit Count :: %d%n", perm.getHitCountFailures());
-				
-				// Check whether the results from this permutation
-				// exceed the quality of the last best results. A
-				// greater number of matches is always better. If the
-				// matches are the same, select the one with fewer
-				// failures due to energy.
-				bestPerm = getBestPermutation(bestPerm, perm);
-			} // End Permutation Loop
-			
-			// Print the final results for the position.
-			OutputLogger.printf("\tPosition Matched   :: %d%n", bestPerm.getMatches());
-			OutputLogger.printf("\tPosition Energy    :: %d%n", bestPerm.getEnergyFailures());
-			OutputLogger.printf("\tPosition Hit Count :: %d%n", bestPerm.getHitCountFailures());
-			
-			// Add the results from the best-matched permutation
-			// to the event efficiency results.
-			event.addEvent(bestPerm);
-		} // End Crystal Position Loop
-		
-		// Return the cluster match summary.
-		return event;
-	}
-	
-	/**
-	 * Performs cluster matching between a collection of reconstructed
-	 * clusters and a collection of SSP clusters using the strictly
-	 * time-compliant algorithm.
-	 * @param reconClusters - A collection of reconstructed clusters.
-	 * @param sspClusters - A collection of SSP clusters.
-	 * @param energyWindow - The window of allowed deviation between
-	 * the reconstructed cluster and SSP cluster energies.
-	 * @param hitWindow - The window of allowed deviation between
-	 * the reconstructed cluster and SSP cluster hit counts.
-	 * @return Returns the cluster matching results stored inside a
-	 * <code>clusterMatchEvent</code> object.
-	 */
-	private static final DetailedClusterEvent matchClustersTimeCompliant(Collection<Cluster> reconClusters,
-			Collection<SSPCluster> sspClusters, double energyWindow, int hitWindow) {
-		// Track the number of cluster pairs that were matched and that
-		// failed by failure type.
-		DetailedClusterEvent event = new DetailedClusterEvent();
-		
-		// Store the clusters which have been successfully paired.
-		Set<SSPCluster> sspMatched = new HashSet<SSPCluster>(sspClusters.size());
-		
-		// Find reconstructed/SSP cluster matched pairs.
-		reconLoop:
-		for(Cluster reconCluster : reconClusters) {
-			// Track whether a position-matched cluster was found.
-			boolean matchedPosition = false;
-			
-			// VERBOSE :: Output the cluster being matched.
-			OutputLogger.printf("Considering %s%n", TriggerDiagnosticUtil.clusterToString(reconCluster));
-			
-			// Search through the SSP clusters for a matching cluster.
-			sspLoop:
-			for(SSPCluster sspCluster : sspClusters) {
-				// VERBOSE :: Output the SSP cluster being considered.
-				OutputLogger.printf("\t%s ", TriggerDiagnosticUtil.clusterToString(sspCluster));
-				
-				// If this cluster has been paired, skip it.
-				if(sspMatched.contains(sspCluster)) {
-					OutputLogger.printf("[ %7s; %9s ]%n", "fail", "matched");
-					continue sspLoop;
-				}
-				
-				// Matched clusters must have the same position.
-				if(TriggerDiagnosticUtil.getXIndex(reconCluster) != sspCluster.getXIndex()
-						|| TriggerDiagnosticUtil.getYIndex(reconCluster) != sspCluster.getYIndex()) {
-					OutputLogger.printf("[ %7s; %9s ]%n", "fail", "position");
-					continue sspLoop;
-				}
-				
-				// Note that a cluster was found at this position.
-				matchedPosition = true;
-				
-				// Matched clusters must have the same time-stamp.
-				if(reconCluster.getCalorimeterHits().get(0).getTime() != sspCluster.getTime()) {
-					OutputLogger.printf("[ %7s; %9s ]%n", "fail", "time");
-					continue sspLoop;
-				}
-				
-				// Clusters that pass all of the above checks are the
-				// same cluster.
-				sspMatched.add(sspCluster);
-				
-				// Check that the clusters are sufficiently close in
-				// energy to one another.
-				if(sspCluster.getEnergy() >= reconCluster.getEnergy() - energyWindow
-						&& sspCluster.getEnergy() <= reconCluster.getEnergy() + energyWindow) {
-					// If a cluster matches in energy, check that it
-					// is also sufficiently close in hit count.
-					if(sspCluster.getHitCount() >= reconCluster.getCalorimeterHits().size() - hitWindow &&
-							sspCluster.getHitCount() <= reconCluster.getCalorimeterHits().size() + hitWindow) {
-						// The cluster is a match.
-						event.pairMatch(reconCluster, sspCluster);
-						OutputLogger.printf("[ %7s; %9s ]%n", "success", "matched");
-						continue reconLoop;
-					} else {
-						event.pairFailHitCount(reconCluster, sspCluster);
-						OutputLogger.printf("[ %7s; %9s ]%n", "fail", "hit count");
-						continue reconLoop;
-					} // End hit count check.
-				} else {
-					event.pairFailEnergy(reconCluster, sspCluster);
-					OutputLogger.printf("[ %7s; %9s ]%n", "fail", "energy");
-					continue reconLoop;
-				} // End energy check.
-			}// End SSP loop.
-			
-			// If the reconstructed cluster has not been matched, check
-			// if a cluster was found at the same position. If not, then
-			// the cluster fails by reason of position.
-			if(!matchedPosition) {
-				event.pairFailPosition(reconCluster, null);
-			}
-			
-			// Otherwise, the cluster had a potential matched, but the
-			// time-stamps were off. The cluster fails by reason of time.
-			else {
-				event.pairFailTime(reconCluster, null);
-			}
-		} // End recon loop.
-		
-		// Return the populated match event.
-		return event;
-	}
-	
-	/**
-	 * Checks triggers simulated on SSP clusters against the SSP bank's
-	 * reported triggers to verify that the trigger is correctly applying
-	 * cuts to the clusters it sees. Additionally compares triggers
-	 * simulated on reconstructed clusters to measure trigger efficiency.
-	 */
-	private void singlesTriggerVerification() {
-		// Create lists of generic triggers.
-		List<List<? extends Trigger<?>>> sspTriggerList = new ArrayList<List<? extends Trigger<?>>>(2);
-		List<List<? extends Trigger<?>>> reconTriggerList = new ArrayList<List<? extends Trigger<?>>>(2);
-		
-		// Convert the simulated triggers to generic versions and add
-		// them to the generic list.
-		sspTriggerList.add(triggerData.getSimSSPTriggers().getSingles0Triggers());
-		sspTriggerList.add(triggerData.getSimSSPTriggers().getSingles1Triggers());
-		reconTriggerList.add(triggerData.getSimReconTriggers().getSingles0Triggers());
-		reconTriggerList.add(triggerData.getSimReconTriggers().getSingles1Triggers());
-		
-		// Run generic trigger verification.
-		triggerVerification(sspTriggerList, reconTriggerList, true);
-	}
-	
-	/**
-	 * Checks triggers simulated on SSP clusters against the SSP bank's
-	 * reported triggers to verify that the trigger is correctly applying
-	 * cuts to the clusters it sees. Additionally compares triggers
-	 * simulated on reconstructed clusters to measure trigger efficiency.
-	 */
-	private void pairTriggerVerification() {
-		// Create lists of generic triggers.
-		List<List<? extends Trigger<?>>> sspTriggerList = new ArrayList<List<? extends Trigger<?>>>(2);
-		List<List<? extends Trigger<?>>> reconTriggerList = new ArrayList<List<? extends Trigger<?>>>(2);
-		
-		// Convert the simulated triggers to generic versions and add
-		// them to the generic list.
-		sspTriggerList.add(triggerData.getSimSSPTriggers().getPair0Triggers());
-		sspTriggerList.add(triggerData.getSimSSPTriggers().getPair1Triggers());
-		reconTriggerList.add(triggerData.getSimReconTriggers().getPair0Triggers());
-		reconTriggerList.add(triggerData.getSimReconTriggers().getPair1Triggers());
-		
-		// Run generic trigger verification.
-		triggerVerification(sspTriggerList, reconTriggerList, false);
-	}
-	
-	/**
-	 * Performs trigger verification for both trigger types.
-	 * @param sspTriggerList - The list of SSP triggers.
-	 * @param reconTriggerList - The list of reconstructed triggers.
-	 * @param isSingles - Whether or not this is a singles trigger
-	 * verification.
-	 */
-	private void triggerVerification(List<List<? extends Trigger<?>>> sspTriggerList, 
-			List<List<? extends Trigger<?>>> reconTriggerList, boolean isSingles) {
-		
-		// ==========================================================
-		// ==== Initialize Trigger Verification =====================
-		// ==========================================================
-		
-		// Print the cluster verification header.
-		OutputLogger.println();
-		OutputLogger.println();
-		OutputLogger.println("======================================================================");
-		if(isSingles) { OutputLogger.println("=== Singles Trigger Verification ====================================="); }
-		else { OutputLogger.println("=== Pair Trigger Verification ========================================"); }
-		OutputLogger.println("======================================================================");
-		
-		// Track the number of triggers seen and the number found.
-		TriggerEvent[] triggerEvent = { new TriggerEvent(), new TriggerEvent() };
-		
-		// ==========================================================
-		// ==== Output Event Summary ================================
-		// ==========================================================
-		
-		// Get the list of triggers reported by the SSP.
-		List<? extends SSPNumberedTrigger> sspTriggers;
-		if(isSingles) { sspTriggers = sspBank.getSinglesTriggers(); }
-		else { sspTriggers = sspBank.getPairTriggers(); }
-		
-		// Output the SSP cluster triggers.
-		OutputLogger.println();
-		OutputLogger.println("SSP Cluster " + (isSingles ? "Singles" : "Pair") + " Triggers");
-		for(int triggerNum = 0; triggerNum < 2; triggerNum++) {
-			for(Trigger<?> simTrigger : sspTriggerList.get(triggerNum)) {
-				OutputLogger.printf("\tTrigger %d :: %s :: %3.0f :: %s%n",
-						(triggerNum + 1), triggerPositionString(simTrigger),
-						getTriggerTime(simTrigger), simTrigger.toString());
-			}
-		}
-		if(sspTriggerList.get(0).size() + sspTriggerList.get(1).size() == 0) {
-			OutputLogger.println("\tNone");
-		}
-		
-		// Output the reconstructed cluster singles triggers.
-		OutputLogger.println("Reconstructed Cluster " + (isSingles ? "Singles" : "Pair") + " Triggers");
-		for(int triggerNum = 0; triggerNum < 2; triggerNum++) {
-			for(Trigger<?> simTrigger : reconTriggerList.get(triggerNum)) {
-				OutputLogger.printf("\tTrigger %d :: %s :: %3.0f :: %s%n",
-						(triggerNum + 1), triggerPositionString(simTrigger),
-						getTriggerTime(simTrigger), simTrigger.toString());
-			}
-		}
-		if(reconTriggerList.get(0).size() + reconTriggerList.get(1).size() == 0) {
-			OutputLogger.println("\tNone");
-		}
-		
-		// Output the SSP reported triggers.
-		OutputLogger.println("SSP Reported " + (isSingles ? "Singles" : "Pair") + " Triggers");
-		for(SSPTrigger sspTrigger : sspTriggers) {
-			OutputLogger.printf("\t%s%n", sspTrigger.toString());
-		}
-		if(sspTriggers.size() == 0) { OutputLogger.println("\tNone"); }
-		
-		// Update the trigger event with the counts for each type of
-		// simulated trigger. Reported triggers are counted later when
-		// already iterating over them.
-		for(int triggerNum = 0; triggerNum < 2; triggerNum++) {
-			triggerEvent[triggerNum].sawSSPSimulatedTriggers(tiFlags, sspTriggerList.get(triggerNum).size());
-			triggerEvent[triggerNum].sawReconSimulatedTriggers(tiFlags, reconTriggerList.get(triggerNum).size());
-		}
-		
-		
-		
-		// ==========================================================
-		// ==== SSP Internal Logic Verification =====================
-		// ==========================================================
-		
-		// Track which SSP triggers have been matched to avoid matching
-		// multiple reconstructed SSP cluster triggers to the same SSP
-		// trigger.
-		Set<SSPNumberedTrigger> sspTriggerSet = new HashSet<SSPNumberedTrigger>();
-		Set<Trigger<?>> simTriggerSet = new HashSet<Trigger<?>>();
-		
-		// Track the number of SSP reported triggers that are found in
-		// excess of the SSP simulated triggers.
-		int sspReportedExtras = sspTriggers.size() - (sspTriggerList.get(0).size() + sspTriggerList.get(1).size());
-		if(sspReportedExtras > 0) {
-			if(isSingles) { singlesInternalFail = true; }
-			else { pairInternalFail = true; }
-		} else { sspReportedExtras = 0; }
-		
-		// Iterate over the triggers.
-		OutputLogger.println();
-		OutputLogger.println("Matching SSP Reported Triggers to SSP Simulated Triggers:");
-		for(SSPNumberedTrigger sspTrigger : sspTriggers) {
-			// Get the trigger information.
-			int triggerNum = sspTrigger.isFirstTrigger() ? 0 : 1;
-			OutputLogger.printf("\t%s%n", sspTrigger.toString());
-			
-			// Note that a bank trigger was seen.
-			triggerEvent[triggerNum].sawReportedTrigger();
-			
-			// Iterate over the SSP cluster simulated triggers and
-			// look for a trigger that matches.
-			matchLoop:
-			for(Trigger<?> simTrigger : sspTriggerList.get(triggerNum)) {
-				// VERBOSE :: Output the trigger being considered for
-				//            matching.
-				OutputLogger.printf("\t\tTrigger %d :: %s :: %3.0f :: %s ",
-						(triggerNum + 1), triggerPositionString(simTrigger),
-						getTriggerTime(simTrigger), simTrigger.toString());
-				
-				// If the current SSP trigger has already been matched,
-				// skip it.
-				if(simTriggerSet.contains(simTrigger)) {
-					OutputLogger.printf("[ %-15s ]%n", "failed; matched");
-					continue matchLoop;
-				}
-				
-				// Check that the triggers have the same time. Triggers
-				// generated from SSP bank clusters should always align
-				// in time.
-				if(sspTrigger.getTime() != getTriggerTime(simTrigger)) {
-					OutputLogger.printf("[ %-15s ]%n", "failed; time");
-					continue matchLoop;
-				}
-				
-				// Check whether the trigger cuts match.
-				boolean[] matchedCuts = triggerCutMatch(simTrigger, sspTrigger);
-				for(int i = 0; i < matchedCuts.length; i++) {
-					if(!matchedCuts[i]) {
-						int typeIndex = isSingles ? 0 : 1;
-						OutputLogger.printf("[ %-15s ]%n", String.format("failed; %s", cutNames[typeIndex][i]));
-						continue matchLoop;
-					}
-				}
-				
-				// If all the cuts match, along with the time and the
-				// trigger number, than these triggers are a match.
-				sspTriggerSet.add(sspTrigger);
-				simTriggerSet.add(simTrigger);
-				triggerEvent[triggerNum].matchedSSPTrigger(tiFlags);
-				OutputLogger.printf("[ %-15s ]%n", "success");
-				break matchLoop;
-			}
-		}
-		
-		for(int triggerNum = 0; triggerNum < 2; triggerNum++) {
-			for(Trigger<?> simTrigger : sspTriggerList.get(triggerNum)) {
-				globalTriggerPlots.sawTrigger(simTrigger);
-				if(simTriggerSet.contains(simTrigger)) {
-					globalTriggerPlots.matchedTrigger(simTrigger);
-				} else {
-					globalTriggerPlots.failedTrigger(simTrigger);
-				}
-			}
-		}
-		
-		// Iterate over the unmatched simulated triggers again and the
-		// unmatched SSP reported trigger that most closely matches it.
-		OutputLogger.println();
-		OutputLogger.println("Matching Failed SSP Reported Triggers to Remaining SSP Simulated Triggers:");
-		for(int triggerNum = 0; triggerNum < 2; triggerNum++) {
-			simLoop:
-			for(Trigger<?> simTrigger : sspTriggerList.get(triggerNum)) {
-				OutputLogger.printf("\tTrigger %d :: %s :: %3.0f :: %s%n",
-						(triggerNum + 1), triggerPositionString(simTrigger),
-						getTriggerTime(simTrigger), simTrigger.toString());
-				
-				// Check whether this trigger has already been matched
-				// or not. If it has been matched, skip it.
-				if(simTriggerSet.contains(simTrigger)) {
-					OutputLogger.println("\t\tSkipping; already matched successfully");
-					continue simLoop;
-				}
-				
-				// Get the trigger time for the simulated trigger.
-				double simTime = getTriggerTime(simTrigger);
-				
-				// Track the match statistics for each reported trigger
-				// so that the closest match may be found.
-				int numMatched = -1;
-				boolean[] matchedCut = null;
-				SSPNumberedTrigger bestMatch = null;
-				
-				// Store the readout for the best match.
-				String bestMatchText = null;
-				
-				// Iterate over the reported triggers to find a match.
-				reportedLoop:
-				for(SSPNumberedTrigger sspTrigger : sspTriggers) {
-					OutputLogger.printf("\t\t%s ", sspTrigger.toString());
-					
-					// If the two triggers have different times, this
-					// trigger should be skipped.
-					if(sspTrigger.getTime() != simTime) {
-						OutputLogger.printf("[ %-15s ]%n", "failed; time");
-						continue reportedLoop;
-					}
-					
-					// If this reported trigger has been matched then
-					// it should be skipped.
-					if(sspTriggerSet.contains(sspTrigger)) {
-						OutputLogger.printf("[ %-15s ]%n", "failed; matched");
-						continue reportedLoop;
-					}
-					
-					// Check each of the cuts.
-					boolean[] tempMatchedCut = triggerCutMatch(simTrigger, sspTrigger);
-					
-					// Check each cut and see if this is a closer match
-					// than the previous best match.
-					int tempNumMatched = 0;
-					for(boolean passed : tempMatchedCut) { if(passed) { tempNumMatched++; } }
-					OutputLogger.printf("[ %-15s ]%n", String.format("maybe; %d failed", tempNumMatched));
-					
-					// If the number of matched cuts exceeds the old
-					// best result, this becomes the new best result.
-					if(tempNumMatched > numMatched) {
-						numMatched = tempNumMatched;
-						matchedCut = tempMatchedCut;
-						bestMatch = sspTrigger;
-						bestMatchText = String.format("%s%n", sspTrigger.toString());
-					}
-				}
-				
-				// If there was no match found, it means that there were
-				// no triggers that were both unmatched and at the same
-				// time as this simulated trigger.
-				if(bestMatch == null) {
-					if(isSingles) { singlesInternalFail = true; }
-					else { pairInternalFail = true; }
-					triggerEvent[triggerNum].failedSSPTrigger();
-					OutputLogger.printf("\t\tTrigger %d :: %s :: %3.0f :: %s",
-							(triggerNum + 1), triggerPositionString(simTrigger),
-							getTriggerTime(simTrigger), simTrigger.toString());
-					OutputLogger.println(" --> No Valid Match Found");
-				} else {
-					triggerEvent[triggerNum].matchedSSPTrigger(tiFlags, matchedCut);
-					OutputLogger.printf("\t\tTrigger %d :: %s :: %3.0f :: %s",
-							(triggerNum + 1), triggerPositionString(simTrigger),
-							getTriggerTime(simTrigger), simTrigger.toString());
-					OutputLogger.println(" --> " + bestMatchText);
-				}
-			}
-		}
-		
-		
-		
-		// ==========================================================
-		// ==== Trigger Efficiency ==================================
-		// ==========================================================
-		
-		// Reset the SSP matched trigger set.
-		sspTriggerSet.clear();
-		
-		// Iterate over the reconstructed cluster singles triggers.
-		OutputLogger.println();
-		OutputLogger.println("Recon Cluster Trigger --> SSP Reported Trigger Match Status");
-		for(int triggerNum = 0; triggerNum < 2; triggerNum++) {
-			for(Trigger<?> simTrigger : reconTriggerList.get(triggerNum)) {
-				OutputLogger.printf("\tTrigger %d :: %s :: %s%n", (triggerNum + 1),
-						triggerPositionString(simTrigger), simTrigger.toString());
-				
-				// TEMP :: Populate the recon ALL pairs plots.
-				globalTriggerPlots.sawTrigger(simTrigger);
-				
-				// Iterate over the SSP reported triggers and compare
-				// them to the reconstructed cluster simulated trigger.
-				boolean matched = false;
-				matchLoop:
-				for(SSPNumberedTrigger sspTrigger : sspTriggers) {
-					OutputLogger.printf("\t\t\t%s", sspTrigger.toString());
-					
-					// Only compare triggers if they are from the
-					// same trigger source.
-					if((triggerNum == 0 && sspTrigger.isSecondTrigger())
-							|| (triggerNum == 1 && sspTrigger.isFirstTrigger())) {
-						OutputLogger.print(" [ fail; source    ]%n");
-						continue matchLoop;
-					}
-					
-					// Only compare the singles trigger if it was
-					// not already matched to another trigger.
-					if(sspTriggerSet.contains(sspTrigger)) {
-						OutputLogger.print(" [ fail; matched   ]%n");
-						continue matchLoop;
-					}
-					
-					// Test each cut.
-					int typeIndex = isSingles ? 0 : 1;
-					boolean[] matchedCuts = triggerCutMatch(simTrigger, sspTrigger);
-					for(int cutIndex = 0; cutIndex < matchedCuts.length; cutIndex++) {
-						if(!matchedCuts[cutIndex]) {
-							OutputLogger.printf(" [ fail; %-9s ]%n", cutNames[typeIndex][cutIndex]);
-							continue matchLoop;
-						}
-					}
-					
-					// If all the trigger flags match, then the
-					// triggers are a match.
-					sspTriggerSet.add(sspTrigger);
-					triggerEvent[triggerNum].matchedReconTrigger(tiFlags);
-					OutputLogger.print(" [ success         ]%n");
-					globalTriggerPlots.matchedTrigger(simTrigger);
-					matched = true;
-					break matchLoop;
-				}
-				
-				if(!matched) { globalTriggerPlots.failedTrigger(simTrigger); }
-			}
-		}
-		
-		
-		
-		// ==========================================================
-		// ==== Output Event Results ================================
-		// ==========================================================
-		
-		// Get the number of SSP and reconstructed cluster simulated
-		// triggers.
-		int sspSimTriggers = sspTriggerList.get(0).size() + sspTriggerList.get(1).size();
-		int reconSimTriggers = reconTriggerList.get(0).size() + reconTriggerList.get(1).size();
-		int[] sspTriggerCount = { sspTriggerList.get(0).size(), sspTriggerList.get(1).size() };
-		
-		// Print event statistics.
-		OutputLogger.println();
-		OutputLogger.println("Event Statistics:");
-		OutputLogger.printf("\tSSP Cluster Sim Triggers   :: %d%n", sspSimTriggers);
-		OutputLogger.printf("\tRecon Cluster Sim Triggers :: %d%n", reconSimTriggers);
-		OutputLogger.printf("\tSSP Reported Triggers      :: %d%n", sspTriggers.size());
-		
-		int matchedSSPTriggers = triggerEvent[0].getMatchedSSPSimulatedTriggers() + triggerEvent[1].getMatchedSSPSimulatedTriggers();
-		OutputLogger.printf("\tInternal Efficiency        :: %d / %d ", matchedSSPTriggers, sspSimTriggers);
-		if(sspSimTriggers == 0) { OutputLogger.printf("(N/A)%n"); }
-		else { OutputLogger.printf("(%3.0f%%)%n", (100.0 * matchedSSPTriggers / sspSimTriggers)); }
-		
-		int matchedReconTriggers = triggerEvent[0].getMatchedReconSimulatedTriggers() + triggerEvent[1].getMatchedReconSimulatedTriggers();
-		OutputLogger.printf("\tTrigger Efficiency         :: %d / %d", matchedReconTriggers, reconSimTriggers);
-		if(reconSimTriggers == 0) { OutputLogger.printf("(N/A)%n"); }
-		else { OutputLogger.printf("(%3.0f%%)%n", (100.0 * matchedReconTriggers / reconSimTriggers)); }
-		
-		// Print the individual cut performances.
-		if(isSingles) {
-			OutputLogger.println();
-			for(int triggerNum = 0; triggerNum < 2; triggerNum++) {
-				OutputLogger.printf("Trigger %d Individual Cut Failure Rate:%n", (triggerNum + 1));
-				if(sspSimTriggers == 0) {
-					OutputLogger.printf("\tCluster Energy Lower Bound :: %d / %d%n", triggerEvent[triggerNum].getSSPCutFailures(ENERGY_MIN), sspTriggerCount[triggerNum]);
-					OutputLogger.printf("\tCluster Energy Upper Bound :: %d / %d%n", triggerEvent[triggerNum].getSSPCutFailures(ENERGY_MAX), sspTriggerCount[triggerNum]);
-					OutputLogger.printf("\tCluster Hit Count          :: %d / %d%n", triggerEvent[triggerNum].getSSPCutFailures(HIT_COUNT), sspTriggerCount[triggerNum]);
-				} else {
-					OutputLogger.printf("\tCluster Energy Lower Bound :: %d / %d (%3.0f%%)%n",
-							triggerEvent[triggerNum].getSSPCutFailures(ENERGY_MIN), sspTriggerCount[triggerNum],
-							(100.0 * triggerEvent[triggerNum].getSSPCutFailures(ENERGY_MIN) / sspTriggerCount[triggerNum]));
-					OutputLogger.printf("\tCluster Energy Upper Bound :: %d / %d (%3.0f%%)%n",
-							triggerEvent[triggerNum].getSSPCutFailures(ENERGY_MAX), sspTriggerCount[triggerNum],
-							(100.0 * triggerEvent[triggerNum].getSSPCutFailures(ENERGY_MAX) / sspTriggerCount[triggerNum]));
-					OutputLogger.printf("\tCluster Hit Count          :: %d / %d (%3.0f%%)%n",
-							triggerEvent[triggerNum].getSSPCutFailures(HIT_COUNT), sspTriggerCount[triggerNum],
-							(100.0 * triggerEvent[triggerNum].getSSPCutFailures(HIT_COUNT) / sspTriggerCount[triggerNum]));
-				}
-			}
-			
-			// Update the global trigger tracking variables.
-			localStats.getTriggerStats().getSingles0Stats().addEvent(triggerEvent[0]);
-			localStats.getTriggerStats().getSingles1Stats().addEvent(triggerEvent[1]);
-			globalStats.getTriggerStats().getSingles0Stats().addEvent(triggerEvent[0]);
-			globalStats.getTriggerStats().getSingles1Stats().addEvent(triggerEvent[1]);
-		} else {
-			for(int triggerNum = 0; triggerNum < 2; triggerNum++) {
-				OutputLogger.println();
-				OutputLogger.printf("Trigger %d Individual Cut Failure Rate:%n", (triggerNum + 1));
-				if(sspTriggerCount[triggerNum] == 0) {
-					OutputLogger.printf("\tPair Energy Sum            :: %d / %d%n", triggerEvent[triggerNum].getSSPCutFailures(ENERGY_SUM), sspTriggerCount[triggerNum]);
-					OutputLogger.printf("\tPair Energy Difference     :: %d / %d%n", triggerEvent[triggerNum].getSSPCutFailures(ENERGY_DIFF), sspTriggerCount[triggerNum]);
-					OutputLogger.printf("\tPair Energy Slope          :: %d / %d%n", triggerEvent[triggerNum].getSSPCutFailures(ENERGY_SLOPE), sspTriggerCount[triggerNum]);
-					OutputLogger.printf("\tPair Coplanarity           :: %d / %d%n", triggerEvent[triggerNum].getSSPCutFailures(COPLANARITY), sspTriggerCount[triggerNum]);
-				} else {
-					OutputLogger.printf("\tPair Energy Sum            :: %d / %d (%3.0f%%)%n",
-							triggerEvent[triggerNum].getSSPCutFailures(ENERGY_SUM), sspTriggerCount[triggerNum],
-							(100.0 * triggerEvent[triggerNum].getSSPCutFailures(ENERGY_SUM) / sspTriggerCount[triggerNum]));
-					OutputLogger.printf("\tPair Energy Difference     :: %d / %d (%3.0f%%)%n",
-							triggerEvent[triggerNum].getSSPCutFailures(ENERGY_DIFF), sspTriggerCount[triggerNum],
-							(100.0 * triggerEvent[triggerNum].getSSPCutFailures(ENERGY_DIFF) / sspTriggerCount[triggerNum]));
-					OutputLogger.printf("\tPair Energy Slope          :: %d / %d (%3.0f%%)%n",
-							triggerEvent[triggerNum].getSSPCutFailures(ENERGY_SLOPE), sspTriggerCount[triggerNum],
-							(100.0 * triggerEvent[triggerNum].getSSPCutFailures(ENERGY_SLOPE) / sspTriggerCount[triggerNum]));
-					OutputLogger.printf("\tPair Coplanarity           :: %d / %d (%3.0f%%)%n",
-							triggerEvent[triggerNum].getSSPCutFailures(COPLANARITY), sspTriggerCount[triggerNum],
-							(100.0 * triggerEvent[triggerNum].getSSPCutFailures(COPLANARITY) / sspTriggerCount[triggerNum]));
-				}
-			}
-			
-			// Update the global trigger tracking variables.
-			localStats.getTriggerStats().getPair0Stats().addEvent(triggerEvent[0]);
-			localStats.getTriggerStats().getPair1Stats().addEvent(triggerEvent[1]);
-			globalStats.getTriggerStats().getPair0Stats().addEvent(triggerEvent[0]);
-			globalStats.getTriggerStats().getPair1Stats().addEvent(triggerEvent[1]);
-		}
-		
-		// Note whether the was a trigger match failure.
-		if(triggerEvent[0].getFailedReconSimulatedTriggers() != 0 && triggerEvent[1].getFailedReconSimulatedTriggers() != 0) {
-			if(isSingles) { singlesEfficiencyFail = true; }
-			else { pairEfficiencyFail = true; }
-		} if(triggerEvent[0].getFailedSSPSimulatedTriggers() != 0 && triggerEvent[1].getFailedSSPSimulatedTriggers() != 0) {
-			if(isSingles) { singlesInternalFail = true; }
-			else { pairInternalFail = true; }
-		}
-	}
-	
-	/**
-	 * Outputs all of the verification parameters currently in use by
-	 * the software. A warning will be issued if the values for NSA and
-	 * NSB, along with the FADC window, preclude clusters from being
-	 * verified.
-	 */
-	private void logSettings() {
-		// Output general settings.
-		System.out.println("Cluster Verification Settings");
-		System.out.printf("\tHit Threshold          :: %1d hit(s)%n", hitAcceptance);
-		System.out.printf("\tEnergy Threshold       :: %5.3f GeV%n",  energyAcceptance);
-		System.out.println();
-		
-		// Output window settings.
-		System.out.println("FADC Timing Window Settings");
-		System.out.printf("\tNSB                    :: %3d ns%n", nsb);
-		System.out.printf("\tNSA                    :: %3d ns%n", nsa);
-		System.out.printf("\tFADC Window            :: %3d ns%n", windowWidth);
-		
-		// Calculate the valid clustering window.
-		int start = nsb;
-		int end = windowWidth - nsa;
-		if(start < end) {
-			System.out.printf("\tValid Cluster Window   :: [ %3d ns, %3d ns ]%n", start, end);
-			performClusterVerification = true;
-		} else {
-			System.out.println("\tNSB, NSA, and FADC window preclude a valid cluster verification window.");
-			System.out.println("\tCluster verification will not be performed!");
-			performClusterVerification = false;
-		}
-		System.out.println();
-		
-		// Output the singles trigger settings.
-		for(int i = 0; i < 2; i++) {
-			// Print the settings.
-			System.out.printf("Singles Trigger %d Settings%23s[%5b]%n", (i + 1), "", singlesTriggerEnabled[i]);
-			System.out.printf("\tCluster Energy Low     :: %.3f GeV      [%5b]%n",
-					singlesTrigger[i].getCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_LOW), singlesCutsEnabled[i][0]);
-			System.out.printf("\tCluster Energy High    :: %.3f GeV      [%5b]%n",
-					singlesTrigger[i].getCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_HIGH), singlesCutsEnabled[i][1]);
-			System.out.printf("\tCluster Hit Count      :: %.0f hit(s)       [%5b]%n",
-					singlesTrigger[i].getCutValue(TriggerModule.CLUSTER_HIT_COUNT_LOW), singlesCutsEnabled[i][2]);
-			System.out.println();
-		}
-		
-		// Output the pair trigger settings.
-		for(int i = 0; i < 2; i++) {
-			System.out.printf("Pairs Trigger %d Settings%25s[%5b]%n", (i + 1), "", pairTriggerEnabled[i]);
-			System.out.printf("\tCluster Energy Low     :: %.3f GeV      [%5b]%n",
-					pairsTrigger[i].getCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_LOW), pairCutsEnabled[i][0]);
-			System.out.printf("\tCluster Energy High    :: %.3f GeV      [%5b]%n",
-					pairsTrigger[i].getCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_HIGH), pairCutsEnabled[i][1]);
-			System.out.printf("\tCluster Hit Count      :: %.0f hit(s)       [%5b]%n",
-					pairsTrigger[i].getCutValue(TriggerModule.CLUSTER_HIT_COUNT_LOW), pairCutsEnabled[i][2]);
-			System.out.printf("\tPair Energy Sum Low    :: %.3f GeV      [%5b]%n",
-					pairsTrigger[i].getCutValue(TriggerModule.PAIR_ENERGY_SUM_LOW), pairCutsEnabled[i][3]);
-			System.out.printf("\tPair Energy Sum High   :: %.3f GeV      [%5b]%n",
-					pairsTrigger[i].getCutValue(TriggerModule.PAIR_ENERGY_SUM_HIGH), pairCutsEnabled[i][3]);
-			System.out.printf("\tPair Energy Difference :: %.3f GeV      [%5b]%n",
-					pairsTrigger[i].getCutValue(TriggerModule.PAIR_ENERGY_DIFFERENCE_HIGH), pairCutsEnabled[i][4]);
-			System.out.printf("\tPair Energy Slope      :: %.3f GeV      [%5b]%n",
-					pairsTrigger[i].getCutValue(TriggerModule.PAIR_ENERGY_SLOPE_LOW), pairCutsEnabled[i][5]);
-			System.out.printf("\tPair Energy Slope F    :: %.4f GeV / mm%n",
-					pairsTrigger[i].getCutValue(TriggerModule.PAIR_ENERGY_SLOPE_F));
-			System.out.printf("\tPair Coplanarity       :: %3.0f Degrees    [%5b]%n",
-					pairsTrigger[i].getCutValue(TriggerModule.PAIR_COPLANARITY_HIGH), pairCutsEnabled[i][6]);
-			System.out.printf("\tPair Time Coincidence  :: %2.0f ns          [%5b]%n",
-					pairsTrigger[i].getCutValue(TriggerModule.PAIR_TIME_COINCIDENCE), true);
-			System.out.println();
-		}
-	}
-	
-	/**
-	 * Summarizes the global run statistics in a log to the terminal.
-	 */
-	private void logStatistics() {
-		// Print the cluster/trigger verification header.
-		System.out.println();
-		System.out.println();
-		System.out.println("======================================================================");
-		System.out.println("=== Cluster/Trigger Verification Results =============================");
-		System.out.println("======================================================================");
-		
-		// Print the general event failure rate.
-		int headSpaces = getPrintSpaces(globalStats.getEventCount());
-		System.out.println("General Event Statistics:");
-		System.out.printf("\tEvent Start Time      :: %.3f s%n", (startTime / Math.pow(10, 9)));
-		System.out.printf("\tEvent End Time        :: %.3f%n", (endTime / Math.pow(10, 9)));
-		System.out.printf("\tEvent Run Time        :: %.3f%n", ((endTime - startTime) / Math.pow(10, 9)));
-		System.out.printf("\tNoise Events          :: %" + headSpaces + "d / %" + headSpaces + "d (%7.3f%%)%n",
-				globalStats.getNoiseEvents(), globalStats.getEventCount(), (100.0 * globalStats.getNoiseEvents() / globalStats.getEventCount()));
-		System.out.printf("\tCluster Events Failed :: %" + headSpaces + "d / %" + headSpaces + "d (%7.3f%%)%n",
-				globalStats.getFailedClusterEventCount(), globalStats.getEventCount(), (100.0 * globalStats.getFailedClusterEventCount() / globalStats.getEventCount()));
-		System.out.printf("\tSingles Events Failed :: %" + headSpaces + "d / %" + headSpaces + "d (%7.3f%%)%n",
-				globalStats.getFailedSinglesEventCount(), globalStats.getEventCount(), (100.0 * globalStats.getFailedSinglesEventCount() / globalStats.getEventCount()));
-		System.out.printf("\tPair Events Failed    :: %" + headSpaces + "d / %" + headSpaces + "d (%7.3f%%)%n",
-				globalStats.getFailedPairEventCount(), globalStats.getEventCount(), (100.0 * globalStats.getFailedPairEventCount() / globalStats.getEventCount()));
-		
-		// Print out how many events reported a given TI type, both in
-		// total and hierarchically.
-		System.out.println();
-		System.out.println("Event Triggering Type Verification:");
-		System.out.printf("\t%15s\t%15s\t%15s%n", "Trigger", "Total", "Hierarchical");
-		System.out.printf("\t%15s\t%15s\t%15s%n", "Pulser", globalStats.getTriggerStats().getTITriggers(TriggerDiagStats.PULSER, false),
-				globalStats.getTriggerStats().getTITriggers(TriggerDiagStats.PULSER, true));
-		System.out.printf("\t%15s\t%15s\t%15s%n", "Cosmic", globalStats.getTriggerStats().getTITriggers(TriggerDiagStats.COSMIC, false),
-				globalStats.getTriggerStats().getTITriggers(TriggerDiagStats.COSMIC, true));
-		System.out.printf("\t%15s\t%15s\t%15s%n", "Singles 1", globalStats.getTriggerStats().getTITriggers(TriggerDiagStats.SINGLES0, false),
-				globalStats.getTriggerStats().getTITriggers(TriggerDiagStats.SINGLES0, true));
-		System.out.printf("\t%15s\t%15s\t%15s%n", "Singles 2", globalStats.getTriggerStats().getTITriggers(TriggerDiagStats.SINGLES1, false),
-				globalStats.getTriggerStats().getTITriggers(TriggerDiagStats.SINGLES1, true));
-		System.out.printf("\t%15s\t%15s\t%15s%n", "Pair 1", globalStats.getTriggerStats().getTITriggers(TriggerDiagStats.PAIR0, false),
-				globalStats.getTriggerStats().getTITriggers(TriggerDiagStats.PAIR0, true));
-		System.out.printf("\t%15s\t%15s\t%15s%n", "Pair 2", globalStats.getTriggerStats().getTITriggers(TriggerDiagStats.PAIR1, false),
-				globalStats.getTriggerStats().getTITriggers(TriggerDiagStats.PAIR1, true));
-		
-		// Print the cluster verification data.
-		System.out.println();
-		System.out.println("Cluster Verification:");
-		System.out.printf("\tRecon Clusters        :: %d%n", globalStats.getClusterStats().getReconClusterCount());
-		System.out.printf("\tSSP Clusters          :: %d%n", globalStats.getClusterStats().getSSPClusterCount());
-		System.out.printf("\tClusters Matched      :: %d%n", globalStats.getClusterStats().getMatches());
-		System.out.printf("\tFailed (Position)     :: %d%n", globalStats.getClusterStats().getPositionFailures());
-		System.out.printf("\tFailed (Energy)       :: %d%n", globalStats.getClusterStats().getEnergyFailures());
-		System.out.printf("\tFailed (Hit Count)    :: %d%n", globalStats.getClusterStats().getHitCountFailures());
-		if(globalStats.getClusterStats().getReconClusterCount() == 0) {
-			System.out.printf("\tCluster Efficiency    :: N/A%n");
-		} else {
-			System.out.printf("\tCluster Efficiency    :: %7.3f%%%n",
-					100.0 * globalStats.getClusterStats().getMatches() / globalStats.getClusterStats().getReconClusterCount());
-		}
-		
-		// Print the trigger verification data.
-		for(int triggerType = 0; triggerType < 2; triggerType++) {
-			// Get the trigger data. Type 0 represents singles triggers.
-			TriggerEvent[] triggerData = new TriggerEvent[2];
-			if(triggerType == 0) {
-				triggerData[0] = globalStats.getTriggerStats().getSingles0Stats();
-				triggerData[1] = globalStats.getTriggerStats().getSingles1Stats();
-			} else {
-				triggerData[0] = globalStats.getTriggerStats().getPair0Stats();
-				triggerData[1] = globalStats.getTriggerStats().getPair1Stats();
-			}
-			
-			// Get the basic trigger data.
-			int sspSimTriggers = triggerData[0].getSSPSimulatedTriggers() + triggerData[1].getSSPSimulatedTriggers();
-			int reconSimTriggers = triggerData[0].getReconSimulatedTriggers() + triggerData[1].getReconSimulatedTriggers();
-			int sspReportedTriggers = triggerData[0].getReportedTriggers() + triggerData[1].getReportedTriggers();
-			int sspMatchedTriggers = triggerData[0].getMatchedSSPSimulatedTriggers() + triggerData[1].getMatchedSSPSimulatedTriggers();
-			int reconMatchedTriggers = triggerData[0].getMatchedReconSimulatedTriggers() + triggerData[1].getMatchedReconSimulatedTriggers();
-			
-			// Print the basic trigger statistics.
-			int spaces = getPrintSpaces(sspSimTriggers, reconSimTriggers, sspReportedTriggers);
-			System.out.println();
-			if(triggerType == 0) { System.out.println("Singles Trigger Verification:"); }
-			else { System.out.println("Pair Trigger Verification:"); }
-			System.out.printf("\tSSP Cluster Sim Triggers   :: %" + spaces + "d%n", sspSimTriggers);
-			System.out.printf("\tRecon Cluster Sim Triggers :: %" + spaces + "d%n", reconSimTriggers);
-			System.out.printf("\tSSP Reported Triggers      :: %" + spaces + "d%n", sspReportedTriggers);
-			
-			System.out.printf("\tInternal Efficiency        :: %" + spaces + "d / %" + spaces + "d ", sspMatchedTriggers, sspSimTriggers);
-			if(sspSimTriggers == 0) { System.out.printf("(N/A)%n"); }
-			else { System.out.printf("(%7.3f%%)%n", (100.0 * sspMatchedTriggers / sspSimTriggers)); }
-			
-			System.out.printf("\tTrigger Efficiency         :: %" + spaces + "d / %" + spaces + "d ", reconMatchedTriggers, reconSimTriggers);
-			if(reconSimTriggers == 0) { System.out.printf("(N/A)%n"); }
-			else { System.out.printf("(%7.3f%%)%n" , (100.0 * reconMatchedTriggers / reconSimTriggers)); }
-			
-			// Print the individual cut performances.
-			if(triggerType == 0) {
-				for(int triggerNum = 0; triggerNum < 2; triggerNum++) {
-					// Get the appropriate trigger statistics module.
-					TriggerEvent triggerStats;
-					if(triggerNum == 0) { triggerStats = globalStats.getTriggerStats().getSingles0Stats(); }
-					else { triggerStats = globalStats.getTriggerStats().getSingles1Stats(); }
-					
-					// Get the number of SSP triggers for this trigger number.
-					int sspTriggerCount = triggerStats.getSSPSimulatedTriggers();
-					//int sspTriggerCount = triggerRunStats[0].getTotalSSPTriggers(triggerNum);
-				
-					System.out.println();
-					System.out.printf("\tTrigger %d Individual Cut Failure Rate:%n", (triggerNum + 1));
-					System.out.printf("\t\tUmatched Triggers          :: %" + spaces + "d%n", triggerStats.getUnmatchedSSPSimulatedTriggers());
-					//System.out.printf("\t\tUmatched Triggers          :: %" + spaces + "d%n", triggerRunStats[0].getUnmatchedTriggers(triggerNum));
-					if(sspTriggerCount == 0) {
-						System.out.printf("\t\tCluster Energy Lower Bound :: %" + spaces + "d / %" + spaces + "d%n",
-								triggerStats.getSSPCutFailures(ENERGY_MIN), sspTriggerCount);
-						System.out.printf("\t\tCluster Energy Upper Bound :: %" + spaces + "d / %" + spaces + "d%n",
-								triggerStats.getSSPCutFailures(ENERGY_MAX), sspTriggerCount);
-						System.out.printf("\t\tCluster Hit Count          :: %" + spaces + "d / %" + spaces + "d%n",
-								triggerStats.getSSPCutFailures(HIT_COUNT), sspTriggerCount);
-					} else {
-						System.out.printf("\t\tCluster Energy Lower Bound :: %" + spaces + "d / %" + spaces + "d (%7.3f%%)%n",
-								triggerStats.getSSPCutFailures(ENERGY_MIN), sspTriggerCount,
-								(100.0 * triggerStats.getSSPCutFailures(ENERGY_MIN) / sspTriggerCount));
-						System.out.printf("\t\tCluster Energy Upper Bound :: %" + spaces + "d / %" + spaces + "d (%7.3f%%)%n",
-								triggerStats.getSSPCutFailures(ENERGY_MAX), sspTriggerCount,
-								(100.0 * triggerStats.getSSPCutFailures(ENERGY_MAX) / sspTriggerCount));
-						System.out.printf("\t\tCluster Hit Count          :: %" + spaces + "d / %" + spaces + "d (%7.3f%%)%n",
-								triggerStats.getSSPCutFailures(HIT_COUNT), sspTriggerCount,
-								(100.0 * triggerStats.getSSPCutFailures(HIT_COUNT) / sspTriggerCount));
-					}
-				}
-			} else {
-				for(int triggerNum = 0; triggerNum < 2; triggerNum++) {
-					// Get the appropriate trigger statistics module.
-					TriggerEvent triggerStats;
-					if(triggerNum == 0) { triggerStats = globalStats.getTriggerStats().getPair0Stats(); }
-					else { triggerStats = globalStats.getTriggerStats().getPair1Stats(); }
-					
-					// Get the number of SSP triggers for this trigger number.
-					int sspTriggerCount = triggerStats.getSSPSimulatedTriggers();
-					
-					System.out.println();
-					System.out.printf("\tTrigger %d Individual Cut Failure Rate:%n", (triggerNum + 1));
-					System.out.printf("\t\tUmatched Triggers          :: %" + spaces + "d%n", triggerStats.getUnmatchedSSPSimulatedTriggers());
-					if(sspTriggerCount == 0) {
-						System.out.printf("\t\tPair Energy Sum            :: %" + spaces + "d / %" + spaces + "d%n",
-								triggerStats.getSSPCutFailures(ENERGY_SUM), sspTriggerCount);
-						System.out.printf("\t\tPair Energy Difference     :: %" + spaces + "d / %" + spaces + "d%n",
-								triggerStats.getSSPCutFailures(ENERGY_DIFF), sspTriggerCount);
-						System.out.printf("\t\tPair Energy Slope          :: %" + spaces + "d / %" + spaces + "d%n",
-								triggerStats.getSSPCutFailures(ENERGY_SLOPE), sspTriggerCount);
-						System.out.printf("\t\tPair Coplanarity           :: %" + spaces + "d / %" + spaces + "d%n",
-								triggerStats.getSSPCutFailures(COPLANARITY), sspTriggerCount);
-					} else {
-						System.out.printf("\t\tPair Energy Sum            :: %" + spaces + "d / %" + spaces + "d (%7.3f%%)%n",
-								triggerStats.getSSPCutFailures(ENERGY_SUM), sspTriggerCount,
-								(100.0 * triggerStats.getSSPCutFailures(ENERGY_SUM) / sspTriggerCount));
-						System.out.printf("\t\tPair Energy Difference     :: %" + spaces + "d / %" + spaces + "d (%7.3f%%)%n",
-								triggerStats.getSSPCutFailures(ENERGY_DIFF), sspTriggerCount,
-								(100.0 * triggerStats.getSSPCutFailures(ENERGY_DIFF) / sspTriggerCount));
-						System.out.printf("\t\tPair Energy Slope          :: %" + spaces + "d / %" + spaces + "d (%7.3f%%)%n",
-								triggerStats.getSSPCutFailures(ENERGY_SLOPE), sspTriggerCount,
-								(100.0 * triggerStats.getSSPCutFailures(ENERGY_SLOPE) / sspTriggerCount));
-						System.out.printf("\t\tPair Coplanarity           :: %" + spaces + "d / %" + spaces + "d (%7.3f%%)%n",
-								triggerStats.getSSPCutFailures(COPLANARITY), sspTriggerCount,
-								(100.0 * triggerStats.getSSPCutFailures(COPLANARITY) / sspTriggerCount));
-					}
-				}
-			}
-		}
-		
-		// Print out the trigger efficiency table.
-		System.out.println();
-		globalStats.getTriggerStats().printEfficiencyTable();
-	}
-	
-	/**
-	 * Checks whether all of the hits in a cluster are within the safe
-	 * region of the FADC output window.
-	 * @param reconCluster - The cluster to check.
-	 * @return Returns <code>true</code> if the cluster is safe and
-	 * returns <code>false</code> otherwise.
-	 */
-	private final boolean isVerifiable(Cluster reconCluster) {
-		return TriggerDiagnosticUtil.isVerifiable(reconCluster, nsa, nsb, windowWidth);
-	}
-	
-	/**
-	 * Generates a <code>List</code> collection that contains a set
-	 * of <code>ArrayList</code> collections representing a unique
-	 * permutation of the entries in the argument.
-	 * @param values - A collection of the entries to be permuted.
-	 * @return Returns a list of lists representing the permutations.
-	 */
-	private static final List<List<Pair<Cluster, SSPCluster>>> getPermutations(List<Cluster> reconClusters, List<SSPCluster> sspClusters) {
-		// Store the SSP cluster permutations.
-		List<List<SSPCluster>> permList = new ArrayList<List<SSPCluster>>();
-		
-		// Make sure that the two lists are the same size.
-		int reconSize = reconClusters.size();
-		int sspSize = sspClusters.size();
-		while(sspClusters.size() < reconClusters.size()) {
-			sspClusters.add(null);
-		}
-		while(reconClusters.size() < sspClusters.size()) {
-			reconClusters.add(null);
-		}
-		
-		// Get the SSP cluster permutations.
-		permute(new ArrayList<SSPCluster>(0), sspClusters, permList);
-		
-		// Create pairs from the permutations.
-		List<List<Pair<Cluster, SSPCluster>>> pairList = new ArrayList<List<Pair<Cluster, SSPCluster>>>();
-		for(List<SSPCluster> permutation : permList) {
-			List<Pair<Cluster, SSPCluster>> pairs = new ArrayList<Pair<Cluster, SSPCluster>>(reconClusters.size());
-			
-			for(int clusterIndex = 0; (clusterIndex < reconClusters.size() && clusterIndex < permutation.size()); clusterIndex++) {
-				pairs.add(new Pair<Cluster, SSPCluster>(reconClusters.get(clusterIndex), permutation.get(clusterIndex)));
-			}
-			
-			pairList.add(pairs);
-		}
-		
-		// Remove the extra values.
-		for(int i = sspClusters.size() - 1; i >= sspSize; i--) { sspClusters.remove(i); }
-		for(int i = reconClusters.size() - 1; i >= reconSize; i--) { reconClusters.remove(i); }
-		
-		// Return the pairs.
-		return pairList;
-	}
-	
-	/**
-	 * Recursive method for permuting all entries in the argument
-	 * collection <code>remainingValues</code> into the argument
-	 * <code>permutedValues</code> values. Completed permutations are
-	 * placed in the argument <code>permList</code>.
-	 * @param permutedValues - List to store entries that have already
-	 * been permuted.
-	 * @param remainingValues - List to store  entries that need to be
-	 * permuted.
-	 * @param permList - List to store completed permutations.
-	 */
-	private static final void permute(List<SSPCluster> permutedValues, List<SSPCluster> remainingValues, List<List<SSPCluster>> permList) {
-		// If the list of entries that still need to be sorted is empty,
-		// then there is nothing to sort. Just return and empty list.
-		if(remainingValues.isEmpty()) { return; }
-		
-		// If there is only one value left in the list of entries that
-		// still need to be sorted, then just add it to the permutation
-		// list and return it.
-		else if(remainingValues.size() <= 1) {
-			// Add the last entry.
-			permutedValues.add(remainingValues.get(0));
-			
-			// Add the permutation to the list of completed permutations.
-			permList.add(permutedValues);
-		}
-		
-		// Otherwise, continue to get all possible permutations.
-		else {
-			// Iterate over the entries that have not been permuted.
-			for(int i = 0; i < remainingValues.size(); i++) {
-				// Make new lists to contain the permutations.
-				List<SSPCluster> newPermList = new ArrayList<SSPCluster>(permutedValues.size() + 1);
-				List<SSPCluster> newRemainList = new ArrayList<SSPCluster>(remainingValues.size());
-				
-				// Copy the current permuted entries to the new list
-				// and one value from the list of entries that have
-				// not been permuted yet.
-				newPermList.addAll(permutedValues);
-				newPermList.add(remainingValues.get(i));
-				
-				// The new list of entries that have not been permuted
-				// should be identical, except it should now be missing
-				// the entry that was moved.
-				for(int index = 0; index < remainingValues.size(); index++) {
-					if(index != i) { newRemainList.add(remainingValues.get(index)); }
-				}
-				
-				// Repeat the process with the new lists.
-				permute(newPermList, newRemainList, permList);
-			}
-		}
-	}
-	
-	/**
-	 * Compares two cluster matching events and finds the one that has
-	 * the better results. Note that this will only return results that
-	 * make sense if both of the events represent different permutations
-	 * of the same set of clusters. Comparing events with different sets
-	 * of clusters will produce meaningless results.
-	 * @param firstEvent - The first cluster matching event,
-	 * @param secondEvent - The second cluster matching event.
-	 * @return Returns the cluster matching event that is better.
-	 */
-	private static final DetailedClusterEvent getBestPermutation(DetailedClusterEvent firstEvent, DetailedClusterEvent secondEvent) {
-		// If both permutations are null, return that.
-		if(firstEvent == null && secondEvent == null) {
-			return null;
-		}
-		
-		// If one permutation is null, it is not the best.
-		if(firstEvent == null) { return secondEvent; }
-		else if(secondEvent == null) { return firstEvent; }
-		
-		// A permutation is better if it has more matches.
-		if(firstEvent.getMatches() > secondEvent.getMatches()) { return firstEvent; }
-		else if(secondEvent.getMatches() > firstEvent.getMatches()) { return secondEvent; }
-		
-		// Otherwise, the permutation with the least energy failures is
-		// the better permutation.
-		if(firstEvent.getEnergyFailures() < secondEvent.getEnergyFailures()) { return firstEvent; }
-		else if(secondEvent.getEnergyFailures() < firstEvent.getEnergyFailures()) { return secondEvent; }
-		
-		// If both these values are the same, then the events are identical.
-		return firstEvent;
-	}
-	
-	/**
-	 * Determines the number of spaces needed to render the longest of
-	 * a series of integers as a string.
-	 * @param vals - The series of integers.
-	 * @return Returns the number of spaces needed to render the longest
-	 * integer as a base-10 string.
-	 */
-	private static final int getPrintSpaces(int... vals) {
-		// Track the largest value.
-		int largest = 0;
-		
-		// Iterate over the arguments and find the largest.
-		for(int val : vals) {
-			// Get the length of the string.
-			int length = TriggerDiagnosticUtil.getDigits(val);
-			
-			// If it is larger, track it.
-			if(length > largest) { largest = length; }
-		}
-		
-		// Return the longer one.
-		return largest;
-	}
-	
-	/**
-	 * Gets the position of the source of a <code>Trigger</code> object
-	 * as text. This method only supports trigger sources of the types
-	 * <code>SSPCluster</code>, <code>Cluster</code>, and arrays of size
-	 * two of either type.
-	 * @param trigger - The trigger from which to obtain the source.
-	 * @return Returns the source of the trigger as a <code>String</code>
-	 * object.
-	 * @throws IllegalArgumentException Occurs if the source of the
-	 * trigger is not any of the supported types.
-	 */
-	private static final String triggerPositionString(Trigger<?> trigger) throws IllegalArgumentException {
-		// Get the trigger source.
-		Object source = trigger.getTriggerSource();
-		
-		// Handle valid trigger sources.
-		if(source instanceof SSPCluster) {
-			return TriggerDiagnosticUtil.clusterPositionString((SSPCluster) source);
-		} else if(source instanceof Cluster) {
-			return TriggerDiagnosticUtil.clusterPositionString((Cluster) source);
-		} else if(source instanceof SSPCluster[]) {
-			SSPCluster[] sourcePair = (SSPCluster[]) source;
-			if(sourcePair.length == 2) {
-				return String.format("%s, %s", TriggerDiagnosticUtil.clusterPositionString(sourcePair[0]),
-						TriggerDiagnosticUtil.clusterPositionString(sourcePair[1]));
-			}
-		} else if(source instanceof Cluster[]) {
-			Cluster[] sourcePair = (Cluster[]) source;
-			if(sourcePair.length == 2) {
-				return String.format("%s, %s", TriggerDiagnosticUtil.clusterPositionString(sourcePair[0]),
-						TriggerDiagnosticUtil.clusterPositionString(sourcePair[1]));
-			}
-		}
-		
-		// Otherwise, the source type is unrecognized. Throw an error.
-		throw new IllegalArgumentException(String.format("Trigger source type \"%s\" is not supported.",
-				trigger.getTriggerSource().getClass().getSimpleName()));
-	}
-	
-	/**
-	 * Gets the time of a simulated trigger object. Method supports
-	 * triggers with source objects of type <code>SSPCluster</code>,
-	 * <code>Cluster</code>, and arrays of size two composed of either
-	 * object type.
-	 * @param trigger - The trigger.
-	 * @return Returns the time at which the trigger occurred.
-	 * @throws IllegalArgumentException Occurs if the trigger source
-	 * is not a supported type.
-	 */
-	private static final double getTriggerTime(Trigger<?> trigger) throws IllegalArgumentException {
-		// Get the trigger source.
-		Object source = trigger.getTriggerSource();
-		
-		// Get the trigger time for supported trigger types.
-		if(source instanceof SSPCluster) {
-			return ((SSPCluster) source).getTime();
-		} else if(source instanceof Cluster) {
-			return TriggerDiagnosticUtil.getClusterTime((Cluster) source);
-		} else if(source instanceof SSPCluster[]) {
-			// Get the pair.
-			SSPCluster[] sourcePair = (SSPCluster[]) source;
-			
-			// Get the time of the bottom cluster.
-			if(sourcePair.length == 2) {
-				if(sourcePair[0].getYIndex() < 0) { return sourcePair[0].getTime(); }
-				else if(sourcePair[1].getYIndex() < 0) { return sourcePair[1].getTime(); }
-				else { throw new IllegalArgumentException("Cluster pairs must be formed of a top/bottom pair."); }
-			}
-			else { throw new IllegalArgumentException("Cluster pairs must be of size 2."); }
-		} else if(source instanceof Cluster[]) {
-			// Get the pair.
-			Cluster[] sourcePair = (Cluster[]) source;
-			int[] iy = {
-				TriggerDiagnosticUtil.getYIndex(sourcePair[0]),
-				TriggerDiagnosticUtil.getYIndex(sourcePair[1])
-			};
-			
-			// Get the time of the bottom cluster.
-			if(sourcePair.length == 2) {
-				if(iy[0] < 0) { return TriggerDiagnosticUtil.getClusterTime(sourcePair[0]); }
-				else if(iy[1] < 0) { return TriggerDiagnosticUtil.getClusterTime(sourcePair[1]); }
-				else { throw new IllegalArgumentException("Cluster pairs must be formed of a top/bottom pair."); }
-			}
-			else { throw new IllegalArgumentException("Cluster pairs must be of size 2."); }
-		}
-		
-		// If the source type is unrecognized, throw an exception.
-		throw new IllegalArgumentException(String.format("Trigger source type \"%\" is not supported.",
-				source.getClass().getSimpleName()));
-	}
-	
-	/**
-	 * Checks if a simulated trigger and an SSP trigger match. Note
-	 * that only certain types can be compared. These are:
-	 * <ul><li><code>SinglesTrigger<?> --> SSPSinglesTrigger</code></li>
-	 * <li><code>PairTrigger<?> --> SSPPairTrigger</code></li></ul>
-	 * @param simTrigger - The simulated trigger.
-	 * @param sspTrigger - The SSP bank trigger.
-	 * @return Returns an array of <code>boolean</code> primitives that
-	 * indicate which cuts passed and which failed.
-	 */
-	private static final boolean[] triggerCutMatch(Trigger<?> simTrigger, SSPTrigger sspTrigger) {
-		// Check that the cuts match for supported trigger types.
-		if(simTrigger instanceof SinglesTrigger && sspTrigger instanceof SSPSinglesTrigger) {
-			// Create an array to store the cut checks.
-			boolean[] cutMatch = new boolean[3];
-			
-			// Cast the triggers.
-			SinglesTrigger<?> simSingles = (SinglesTrigger<?>) simTrigger;
-			SSPSinglesTrigger sspSingles = (SSPSinglesTrigger) sspTrigger;
-			
-			// Perform the check.
-			cutMatch[ENERGY_MIN] = (simSingles.getStateClusterEnergyLow()  == sspSingles.passCutEnergyMin());
-			cutMatch[ENERGY_MAX] = (simSingles.getStateClusterEnergyHigh() == sspSingles.passCutEnergyMax());
-			cutMatch[HIT_COUNT] = (simSingles.getStateHitCount()          == sspSingles.passCutHitCount());
-			
-			// Return the match array.
-			return cutMatch;
-		} else if(simTrigger instanceof PairTrigger && sspTrigger instanceof SSPPairTrigger) {
-			// Create an array to store the cut checks.
-			boolean[] cutMatch = new boolean[4];
-			
-			// Cast the triggers.
-			PairTrigger<?> simPair = (PairTrigger<?>) simTrigger;
-			SSPPairTrigger sspPair = (SSPPairTrigger) sspTrigger;
-			
-			// Perform the check.
-			cutMatch[ENERGY_SUM] = (simPair.getStateEnergySum()        == sspPair.passCutEnergySum());
-			cutMatch[ENERGY_DIFF] = (simPair.getStateEnergyDifference() == sspPair.passCutEnergyDifference());
-			cutMatch[ENERGY_SLOPE] = (simPair.getStateEnergySlope()      == sspPair.passCutEnergySlope());
-			cutMatch[COPLANARITY] = (simPair.getStateCoplanarity()      == sspPair.passCutCoplanarity());
-			
-			// Return the match array.
-			return cutMatch;
-		}
-		
-		// If this point is reached, the triggers are not of a supported
-		// type for cut comparison. Produce an exception.
-		throw new IllegalArgumentException(String.format("Triggers of type \"%s\" can not be cut-matched with triggers of type \"%s\".",
-				simTrigger.getClass().getSimpleName(), sspTrigger.getClass().getSimpleName()));
-	}
+     * clusters and a collection of SSP clusters with an algorithm that
+     * ignores the times reported for each cluster.
+     * @param reconClusters - A collection of reconstructed clusters.
+     * @param sspClusters - A collection of SSP clusters.
+     * @param energyWindow - The window of allowed deviation between
+     * the reconstructed cluster and SSP cluster energies.
+     * @param hitWindow - The window of allowed deviation between
+     * the reconstructed cluster and SSP cluster hit counts.
+     * @return Returns the cluster matching results stored inside a
+     * <code>clusterMatchEvent</code> object.
+     */
+    private static final DetailedClusterEvent matchClusters(Collection<Cluster> reconClusters,
+            Collection<SSPCluster> sspClusters, double energyWindow, int hitWindow) {
+        // Track the number of cluster pairs that were matched and that
+        // failed by failure type.
+        DetailedClusterEvent event = new DetailedClusterEvent();
+        
+        // Create maps to link cluster position to the list of clusters
+        // that were found at that location.
+        Map<Point, List<Cluster>> reconClusterMap = new HashMap<Point, List<Cluster>>(reconClusters.size());
+        Map<Point, List<SSPCluster>> sspClusterMap = new HashMap<Point, List<SSPCluster>>(reconClusters.size());
+        
+        // Populate the reconstructed cluster map.
+        for(Cluster reconCluster : reconClusters) {
+            // Get the cluster position.
+            Point position = new Point(TriggerDiagnosticUtil.getXIndex(reconCluster),
+                    TriggerDiagnosticUtil.getYIndex(reconCluster));
+            
+            // Get the list for this cluster position.
+            List<Cluster> reconList = reconClusterMap.get(position);
+            if(reconList == null) {
+                reconList = new ArrayList<Cluster>();
+                reconClusterMap.put(position, reconList);
+            }
+            
+            // Add the cluster to the list.
+            reconList.add(reconCluster);
+        }
+        
+        // Populate the SSP cluster map.
+        for(SSPCluster sspCluster : sspClusters) {
+            // Get the cluster position.
+            Point position = new Point(sspCluster.getXIndex(), sspCluster.getYIndex());
+            
+            // Get the list for this cluster position.
+            List<SSPCluster> sspList = sspClusterMap.get(position);
+            if(sspList == null) {
+                sspList = new ArrayList<SSPCluster>();
+                sspClusterMap.put(position, sspList);
+            }
+            
+            // Add the cluster to the list.
+            sspList.add(sspCluster);
+        }
+        
+        // For each reconstructed cluster, attempt to match the clusters
+        // with SSP clusters at the same position.
+        positionLoop:
+        for(Entry<Point, List<Cluster>> clusterSet : reconClusterMap.entrySet()) {
+            // Get the reconstructed and SSP clusters at this position.
+            List<Cluster> reconList = clusterSet.getValue();
+            List<SSPCluster> sspList = sspClusterMap.get(clusterSet.getKey());
+            
+            // Print the crystal position header.
+            OutputLogger.println();
+            OutputLogger.printf("Considering clusters at (%3d, %3d)%n", clusterSet.getKey().x, clusterSet.getKey().y);
+            
+            // If there are no SSP clusters, then matching fails by
+            // reason of position. The remainder of the loop may be
+            // skipped, since there is nothing to check.
+            if(sspList == null || sspList.isEmpty()) {
+                event.pairFailPosition(reconList.size());
+                continue positionLoop;
+            }
+            
+            // Get all possible permutations of SSP clusters.
+            List<List<Pair<Cluster, SSPCluster>>> permutations = getPermutations(reconList, sspList);
+            
+            // Print the information for this crystal position.
+            OutputLogger.printf("\tRecon Clusters :: %d%n", reconList.size());
+            OutputLogger.printf("\tSSP Clusters   :: %d%n", sspList.size());
+            OutputLogger.printf("\tPermutations   :: %d%n", permutations.size());
+            
+            // Track the plotted values for the current best permutation.
+            DetailedClusterEvent bestPerm = null;
+            
+            // Iterate over the permutations and find the permutation
+            // that produces the best possible result when compared to
+            // the reconstructed clusters.
+            int permIndex = 0;
+            for(List<Pair<Cluster, SSPCluster>> pairs : permutations) {
+                // Update the current permutation number.
+                permIndex++;
+                
+                // Track the plot values for this permutation.
+                DetailedClusterEvent perm = new DetailedClusterEvent();
+                
+                // Try to match each pair.
+                pairLoop:
+                for(Pair<Cluster, SSPCluster> pair : pairs) {
+                    // Print the current reconstructed/SSP cluster pair.
+                    OutputLogger.printf("\tP%d :: %s --> %s", permIndex,
+                            pair.getFirstElement() == null ? "None" : TriggerDiagnosticUtil.clusterToString(pair.getFirstElement()),
+                            pair.getSecondElement() == null ? "None" : TriggerDiagnosticUtil.clusterToString(pair.getSecondElement()));
+                    
+                    // If either cluster in the pair is null, there
+                    // are not enough clusters to perform this match.
+                    if(pair.getFirstElement() == null || pair.getSecondElement() == null) {
+                        // Log the result.
+                        OutputLogger.printf(" [ %18s ]%n", "failure: unpaired");
+                        
+                        // An unpaired SSP cluster does not necessarily
+                        // represent a problem. Often, this just means
+                        // that the SSP cluster's matching reconstructed
+                        // cluster is outside the verification window.
+                        if(pair.getSecondElement() == null) {
+                            perm.pairFailPosition(pair.getFirstElement(), pair.getSecondElement());
+                        }
+                        
+                        // Skip the rest of the checks.
+                        continue pairLoop;
+                    }
+                    
+                    // Check if the reconstructed cluster has an energy
+                    // within the allotted threshold of the SSP cluster.
+                    if(pair.getSecondElement().getEnergy() >= pair.getFirstElement().getEnergy() - energyWindow &&
+                            pair.getSecondElement().getEnergy() <= pair.getFirstElement().getEnergy() + energyWindow) {
+                        
+                        // Check that the hit count of the reconstructed
+                        // is within the allotted threshold of the SSP
+                        // cluster.
+                        if(pair.getSecondElement().getHitCount() >= pair.getFirstElement().getCalorimeterHits().size() - hitWindow &&
+                                pair.getSecondElement().getHitCount() <= pair.getFirstElement().getCalorimeterHits().size() + hitWindow) {
+                            // Designate the pair as a match.
+                            perm.pairMatch(pair.getFirstElement(), pair.getSecondElement());
+                            OutputLogger.printf(" [ %18s ]%n", "success: matched");
+                        } else {
+                            perm.pairFailHitCount(pair.getFirstElement(), pair.getSecondElement());
+                            OutputLogger.printf(" [ %18s ]%n", "failure: hit count");
+                        } // End hit count check.
+                    } else {
+                        perm.pairFailEnergy(pair.getFirstElement(), pair.getSecondElement());
+                        OutputLogger.printf(" [ %18s ]%n", "failure: energy");
+                    } // End energy check.
+                } // End Pair Loop
+                
+                // Print the results of the permutation.
+                OutputLogger.printf("\t\tPermutation Matched   :: %d%n", perm.getMatches());
+                OutputLogger.printf("\t\tPermutation Energy    :: %d%n", perm.getEnergyFailures());
+                OutputLogger.printf("\t\tPermutation Hit Count :: %d%n", perm.getHitCountFailures());
+                
+                // Check whether the results from this permutation
+                // exceed the quality of the last best results. A
+                // greater number of matches is always better. If the
+                // matches are the same, select the one with fewer
+                // failures due to energy.
+                bestPerm = getBestPermutation(bestPerm, perm);
+            } // End Permutation Loop
+            
+            // Print the final results for the position.
+            OutputLogger.printf("\tPosition Matched   :: %d%n", bestPerm.getMatches());
+            OutputLogger.printf("\tPosition Energy    :: %d%n", bestPerm.getEnergyFailures());
+            OutputLogger.printf("\tPosition Hit Count :: %d%n", bestPerm.getHitCountFailures());
+            
+            // Add the results from the best-matched permutation
+            // to the event efficiency results.
+            event.addEvent(bestPerm);
+        } // End Crystal Position Loop
+        
+        // Return the cluster match summary.
+        return event;
+    }
+    
+    /**
+     * Performs cluster matching between a collection of reconstructed
+     * clusters and a collection of SSP clusters using the strictly
+     * time-compliant algorithm.
+     * @param reconClusters - A collection of reconstructed clusters.
+     * @param sspClusters - A collection of SSP clusters.
+     * @param energyWindow - The window of allowed deviation between
+     * the reconstructed cluster and SSP cluster energies.
+     * @param hitWindow - The window of allowed deviation between
+     * the reconstructed cluster and SSP cluster hit counts.
+     * @return Returns the cluster matching results stored inside a
+     * <code>clusterMatchEvent</code> object.
+     */
+    private static final DetailedClusterEvent matchClustersTimeCompliant(Collection<Cluster> reconClusters,
+            Collection<SSPCluster> sspClusters, double energyWindow, int hitWindow) {
+        // Track the number of cluster pairs that were matched and that
+        // failed by failure type.
+        DetailedClusterEvent event = new DetailedClusterEvent();
+        
+        // Store the clusters which have been successfully paired.
+        Set<SSPCluster> sspMatched = new HashSet<SSPCluster>(sspClusters.size());
+        
+        // Find reconstructed/SSP cluster matched pairs.
+        reconLoop:
+        for(Cluster reconCluster : reconClusters) {
+            // Track whether a position-matched cluster was found.
+            boolean matchedPosition = false;
+            
+            // VERBOSE :: Output the cluster being matched.
+            OutputLogger.printf("Considering %s%n", TriggerDiagnosticUtil.clusterToString(reconCluster));
+            
+            // Search through the SSP clusters for a matching cluster.
+            sspLoop:
+            for(SSPCluster sspCluster : sspClusters) {
+                // VERBOSE :: Output the SSP cluster being considered.
+                OutputLogger.printf("\t%s ", TriggerDiagnosticUtil.clusterToString(sspCluster));
+                
+                // If this cluster has been paired, skip it.
+                if(sspMatched.contains(sspCluster)) {
+                    OutputLogger.printf("[ %7s; %9s ]%n", "fail", "matched");
+                    continue sspLoop;
+                }
+                
+                // Matched clusters must have the same position.
+                if(TriggerDiagnosticUtil.getXIndex(reconCluster) != sspCluster.getXIndex()
+                        || TriggerDiagnosticUtil.getYIndex(reconCluster) != sspCluster.getYIndex()) {
+                    OutputLogger.printf("[ %7s; %9s ]%n", "fail", "position");
+                    continue sspLoop;
+                }
+                
+                // Note that a cluster was found at this position.
+                matchedPosition = true;
+                
+                // Matched clusters must have the same time-stamp.
+                if(reconCluster.getCalorimeterHits().get(0).getTime() != sspCluster.getTime()) {
+                    OutputLogger.printf("[ %7s; %9s ]%n", "fail", "time");
+                    continue sspLoop;
+                }
+                
+                // Clusters that pass all of the above checks are the
+                // same cluster.
+                sspMatched.add(sspCluster);
+                
+                // Check that the clusters are sufficiently close in
+                // energy to one another.
+                if(sspCluster.getEnergy() >= reconCluster.getEnergy() - energyWindow
+                        && sspCluster.getEnergy() <= reconCluster.getEnergy() + energyWindow) {
+                    // If a cluster matches in energy, check that it
+                    // is also sufficiently close in hit count.
+                    if(sspCluster.getHitCount() >= reconCluster.getCalorimeterHits().size() - hitWindow &&
+                            sspCluster.getHitCount() <= reconCluster.getCalorimeterHits().size() + hitWindow) {
+                        // The cluster is a match.
+                        event.pairMatch(reconCluster, sspCluster);
+                        OutputLogger.printf("[ %7s; %9s ]%n", "success", "matched");
+                        continue reconLoop;
+                    } else {
+                        event.pairFailHitCount(reconCluster, sspCluster);
+                        OutputLogger.printf("[ %7s; %9s ]%n", "fail", "hit count");
+                        continue reconLoop;
+                    } // End hit count check.
+                } else {
+                    event.pairFailEnergy(reconCluster, sspCluster);
+                    OutputLogger.printf("[ %7s; %9s ]%n", "fail", "energy");
+                    continue reconLoop;
+                } // End energy check.
+            }// End SSP loop.
+            
+            // If the reconstructed cluster has not been matched, check
+            // if a cluster was found at the same position. If not, then
+            // the cluster fails by reason of position.
+            if(!matchedPosition) {
+                event.pairFailPosition(reconCluster, null);
+            }
+            
+            // Otherwise, the cluster had a potential matched, but the
+            // time-stamps were off. The cluster fails by reason of time.
+            else {
+                event.pairFailTime(reconCluster, null);
+            }
+        } // End recon loop.
+        
+        // Return the populated match event.
+        return event;
+    }
+    
+    /**
+     * Checks triggers simulated on SSP clusters against the SSP bank's
+     * reported triggers to verify that the trigger is correctly applying
+     * cuts to the clusters it sees. Additionally compares triggers
+     * simulated on reconstructed clusters to measure trigger efficiency.
+     */
+    private void singlesTriggerVerification() {
+        // Create lists of generic triggers.
+        List<List<? extends Trigger<?>>> sspTriggerList = new ArrayList<List<? extends Trigger<?>>>(2);
+        List<List<? extends Trigger<?>>> reconTriggerList = new ArrayList<List<? extends Trigger<?>>>(2);
+        
+        // Convert the simulated triggers to generic versions and add
+        // them to the generic list.
+        sspTriggerList.add(triggerData.getSimSSPTriggers().getSingles0Triggers());
+        sspTriggerList.add(triggerData.getSimSSPTriggers().getSingles1Triggers());
+        reconTriggerList.add(triggerData.getSimReconTriggers().getSingles0Triggers());
+        reconTriggerList.add(triggerData.getSimReconTriggers().getSingles1Triggers());
+        
+        // Run generic trigger verification.
+        triggerVerification(sspTriggerList, reconTriggerList, true);
+    }
+    
+    /**
+     * Checks triggers simulated on SSP clusters against the SSP bank's
+     * reported triggers to verify that the trigger is correctly applying
+     * cuts to the clusters it sees. Additionally compares triggers
+     * simulated on reconstructed clusters to measure trigger efficiency.
+     */
+    private void pairTriggerVerification() {
+        // Create lists of generic triggers.
+        List<List<? extends Trigger<?>>> sspTriggerList = new ArrayList<List<? extends Trigger<?>>>(2);
+        List<List<? extends Trigger<?>>> reconTriggerList = new ArrayList<List<? extends Trigger<?>>>(2);
+        
+        // Convert the simulated triggers to generic versions and add
+        // them to the generic list.
+        sspTriggerList.add(triggerData.getSimSSPTriggers().getPair0Triggers());
+        sspTriggerList.add(triggerData.getSimSSPTriggers().getPair1Triggers());
+        reconTriggerList.add(triggerData.getSimReconTriggers().getPair0Triggers());
+        reconTriggerList.add(triggerData.getSimReconTriggers().getPair1Triggers());
+        
+        // Run generic trigger verification.
+        triggerVerification(sspTriggerList, reconTriggerList, false);
+    }
+    
+    /**
+     * Performs trigger verification for both trigger types.
+     * @param sspTriggerList - The list of SSP triggers.
+     * @param reconTriggerList - The list of reconstructed triggers.
+     * @param isSingles - Whether or not this is a singles trigger
+     * verification.
+     */
+    private void triggerVerification(List<List<? extends Trigger<?>>> sspTriggerList, 
+            List<List<? extends Trigger<?>>> reconTriggerList, boolean isSingles) {
+        
+        // ==========================================================
+        // ==== Initialize Trigger Verification =====================
+        // ==========================================================
+        
+        // Print the cluster verification header.
+        OutputLogger.println();
+        OutputLogger.println();
+        OutputLogger.println("======================================================================");
+        if(isSingles) { OutputLogger.println("=== Singles Trigger Verification ====================================="); }
+        else { OutputLogger.println("=== Pair Trigger Verification ========================================"); }
+        OutputLogger.println("======================================================================");
+        
+        // Track the number of triggers seen and the number found.
+        TriggerEvent[] triggerEvent = { new TriggerEvent(), new TriggerEvent() };
+        
+        // ==========================================================
+        // ==== Output Event Summary ================================
+        // ==========================================================
+        
+        // Get the list of triggers reported by the SSP.
+        List<? extends SSPNumberedTrigger> sspTriggers;
+        if(isSingles) { sspTriggers = sspBank.getSinglesTriggers(); }
+        else { sspTriggers = sspBank.getPairTriggers(); }
+        
+        // Output the SSP cluster triggers.
+        OutputLogger.println();
+        OutputLogger.println("SSP Cluster " + (isSingles ? "Singles" : "Pair") + " Triggers");
+        for(int triggerNum = 0; triggerNum < 2; triggerNum++) {
+            for(Trigger<?> simTrigger : sspTriggerList.get(triggerNum)) {
+                OutputLogger.printf("\tTrigger %d :: %s :: %3.0f :: %s%n",
+                        (triggerNum + 1), triggerPositionString(simTrigger),
+                        getTriggerTime(simTrigger), simTrigger.toString());
+            }
+        }
+        if(sspTriggerList.get(0).size() + sspTriggerList.get(1).size() == 0) {
+            OutputLogger.println("\tNone");
+        }
+        
+        // Output the reconstructed cluster singles triggers.
+        OutputLogger.println("Reconstructed Cluster " + (isSingles ? "Singles" : "Pair") + " Triggers");
+        for(int triggerNum = 0; triggerNum < 2; triggerNum++) {
+            for(Trigger<?> simTrigger : reconTriggerList.get(triggerNum)) {
+                OutputLogger.printf("\tTrigger %d :: %s :: %3.0f :: %s%n",
+                        (triggerNum + 1), triggerPositionString(simTrigger),
+                        getTriggerTime(simTrigger), simTrigger.toString());
+            }
+        }
+        if(reconTriggerList.get(0).size() + reconTriggerList.get(1).size() == 0) {
+            OutputLogger.println("\tNone");
+        }
+        
+        // Output the SSP reported triggers.
+        OutputLogger.println("SSP Reported " + (isSingles ? "Singles" : "Pair") + " Triggers");
+        for(SSPTrigger sspTrigger : sspTriggers) {
+            OutputLogger.printf("\t%s%n", sspTrigger.toString());
+        }
+        if(sspTriggers.size() == 0) { OutputLogger.println("\tNone"); }
+        
+        // Update the trigger event with the counts for each type of
+        // simulated trigger. Reported triggers are counted later when
+        // already iterating over them.
+        for(int triggerNum = 0; triggerNum < 2; triggerNum++) {
+            triggerEvent[triggerNum].sawSSPSimulatedTriggers(tiFlags, sspTriggerList.get(triggerNum).size());
+            triggerEvent[triggerNum].sawReconSimulatedTriggers(tiFlags, reconTriggerList.get(triggerNum).size());
+        }
+        
+        
+        
+        // ==========================================================
+        // ==== SSP Internal Logic Verification =====================
+        // ==========================================================
+        
+        // Track which SSP triggers have been matched to avoid matching
+        // multiple reconstructed SSP cluster triggers to the same SSP
+        // trigger.
+        Set<SSPNumberedTrigger> sspTriggerSet = new HashSet<SSPNumberedTrigger>();
+        Set<Trigger<?>> simTriggerSet = new HashSet<Trigger<?>>();
+        
+        // Track the number of SSP reported triggers that are found in
+        // excess of the SSP simulated triggers.
+        int sspReportedExtras = sspTriggers.size() - (sspTriggerList.get(0).size() + sspTriggerList.get(1).size());
+        if(sspReportedExtras > 0) {
+            if(isSingles) { singlesInternalFail = true; }
+            else { pairInternalFail = true; }
+        } else { sspReportedExtras = 0; }
+        
+        // Iterate over the triggers.
+        OutputLogger.println();
+        OutputLogger.println("Matching SSP Reported Triggers to SSP Simulated Triggers:");
+        for(SSPNumberedTrigger sspTrigger : sspTriggers) {
+            // Get the trigger information.
+            int triggerNum = sspTrigger.isFirstTrigger() ? 0 : 1;
+            OutputLogger.printf("\t%s%n", sspTrigger.toString());
+            
+            // Note that a bank trigger was seen.
+            triggerEvent[triggerNum].sawReportedTrigger();
+            
+            // Iterate over the SSP cluster simulated triggers and
+            // look for a trigger that matches.
+            matchLoop:
+            for(Trigger<?> simTrigger : sspTriggerList.get(triggerNum)) {
+                // VERBOSE :: Output the trigger being considered for
+                //            matching.
+                OutputLogger.printf("\t\tTrigger %d :: %s :: %3.0f :: %s ",
+                        (triggerNum + 1), triggerPositionString(simTrigger),
+                        getTriggerTime(simTrigger), simTrigger.toString());
+                
+                // If the current SSP trigger has already been matched,
+                // skip it.
+                if(simTriggerSet.contains(simTrigger)) {
+                    OutputLogger.printf("[ %-15s ]%n", "failed; matched");
+                    continue matchLoop;
+                }
+                
+                // Check that the triggers have the same time. Triggers
+                // generated from SSP bank clusters should always align
+                // in time.
+                if(sspTrigger.getTime() != getTriggerTime(simTrigger)) {
+                    OutputLogger.printf("[ %-15s ]%n", "failed; time");
+                    continue matchLoop;
+                }
+                
+                // Check whether the trigger cuts match.
+                boolean[] matchedCuts = triggerCutMatch(simTrigger, sspTrigger);
+                for(int i = 0; i < matchedCuts.length; i++) {
+                    if(!matchedCuts[i]) {
+                        int typeIndex = isSingles ? 0 : 1;
+                        OutputLogger.printf("[ %-15s ]%n", String.format("failed; %s", cutNames[typeIndex][i]));
+                        continue matchLoop;
+                    }
+                }
+                
+                // If all the cuts match, along with the time and the
+                // trigger number, than these triggers are a match.
+                sspTriggerSet.add(sspTrigger);
+                simTriggerSet.add(simTrigger);
+                triggerEvent[triggerNum].matchedSSPTrigger(tiFlags);
+                OutputLogger.printf("[ %-15s ]%n", "success");
+                break matchLoop;
+            }
+        }
+        
+        for(int triggerNum = 0; triggerNum < 2; triggerNum++) {
+            for(Trigger<?> simTrigger : sspTriggerList.get(triggerNum)) {
+                globalTriggerPlots.sawTrigger(simTrigger);
+                if(simTriggerSet.contains(simTrigger)) {
+                    globalTriggerPlots.matchedTrigger(simTrigger);
+                } else {
+                    globalTriggerPlots.failedTrigger(simTrigger);
+                }
+            }
+        }
+        
+        // Iterate over the unmatched simulated triggers again and the
+        // unmatched SSP reported trigger that most closely matches it.
+        OutputLogger.println();
+        OutputLogger.println("Matching Failed SSP Reported Triggers to Remaining SSP Simulated Triggers:");
+        for(int triggerNum = 0; triggerNum < 2; triggerNum++) {
+            simLoop:
+            for(Trigger<?> simTrigger : sspTriggerList.get(triggerNum)) {
+                OutputLogger.printf("\tTrigger %d :: %s :: %3.0f :: %s%n",
+                        (triggerNum + 1), triggerPositionString(simTrigger),
+                        getTriggerTime(simTrigger), simTrigger.toString());
+                
+                // Check whether this trigger has already been matched
+                // or not. If it has been matched, skip it.
+                if(simTriggerSet.contains(simTrigger)) {
+                    OutputLogger.println("\t\tSkipping; already matched successfully");
+                    continue simLoop;
+                }
+                
+                // Get the trigger time for the simulated trigger.
+                double simTime = getTriggerTime(simTrigger);
+                
+                // Track the match statistics for each reported trigger
+                // so that the closest match may be found.
+                int numMatched = -1;
+                boolean[] matchedCut = null;
+                SSPNumberedTrigger bestMatch = null;
+                
+                // Store the readout for the best match.
+                String bestMatchText = null;
+                
+                // Iterate over the reported triggers to find a match.
+                reportedLoop:
+                for(SSPNumberedTrigger sspTrigger : sspTriggers) {
+                    OutputLogger.printf("\t\t%s ", sspTrigger.toString());
+                    
+                    // If the two triggers have different times, this
+                    // trigger should be skipped.
+                    if(sspTrigger.getTime() != simTime) {
+                        OutputLogger.printf("[ %-15s ]%n", "failed; time");
+                        continue reportedLoop;
+                    }
+                    
+                    // If this reported trigger has been matched then
+                    // it should be skipped.
+                    if(sspTriggerSet.contains(sspTrigger)) {
+                        OutputLogger.printf("[ %-15s ]%n", "failed; matched");
+                        continue reportedLoop;
+                    }
+                    
+                    // Check each of the cuts.
+                    boolean[] tempMatchedCut = triggerCutMatch(simTrigger, sspTrigger);
+                    
+                    // Check each cut and see if this is a closer match
+                    // than the previous best match.
+                    int tempNumMatched = 0;
+                    for(boolean passed : tempMatchedCut) { if(passed) { tempNumMatched++; } }
+                    OutputLogger.printf("[ %-15s ]%n", String.format("maybe; %d failed", tempNumMatched));
+                    
+                    // If the number of matched cuts exceeds the old
+                    // best result, this becomes the new best result.
+                    if(tempNumMatched > numMatched) {
+                        numMatched = tempNumMatched;
+                        matchedCut = tempMatchedCut;
+                        bestMatch = sspTrigger;
+                        bestMatchText = String.format("%s%n", sspTrigger.toString());
+                    }
+                }
+                
+                // If there was no match found, it means that there were
+                // no triggers that were both unmatched and at the same
+                // time as this simulated trigger.
+                if(bestMatch == null) {
+                    if(isSingles) { singlesInternalFail = true; }
+                    else { pairInternalFail = true; }
+                    triggerEvent[triggerNum].failedSSPTrigger();
+                    OutputLogger.printf("\t\tTrigger %d :: %s :: %3.0f :: %s",
+                            (triggerNum + 1), triggerPositionString(simTrigger),
+                            getTriggerTime(simTrigger), simTrigger.toString());
+                    OutputLogger.println(" --> No Valid Match Found");
+                } else {
+                    triggerEvent[triggerNum].matchedSSPTrigger(tiFlags, matchedCut);
+                    OutputLogger.printf("\t\tTrigger %d :: %s :: %3.0f :: %s",
+                            (triggerNum + 1), triggerPositionString(simTrigger),
+                            getTriggerTime(simTrigger), simTrigger.toString());
+                    OutputLogger.println(" --> " + bestMatchText);
+                }
+            }
+        }
+        
+        
+        
+        // ==========================================================
+        // ==== Trigger Efficiency ==================================
+        // ==========================================================
+        
+        // Reset the SSP matched trigger set.
+        sspTriggerSet.clear();
+        
+        // Iterate over the reconstructed cluster singles triggers.
+        OutputLogger.println();
+        OutputLogger.println("Recon Cluster Trigger --> SSP Reported Trigger Match Status");
+        for(int triggerNum = 0; triggerNum < 2; triggerNum++) {
+            for(Trigger<?> simTrigger : reconTriggerList.get(triggerNum)) {
+                OutputLogger.printf("\tTrigger %d :: %s :: %s%n", (triggerNum + 1),
+                        triggerPositionString(simTrigger), simTrigger.toString());
+                
+                // TEMP :: Populate the recon ALL pairs plots.
+                globalTriggerPlots.sawTrigger(simTrigger);
+                
+                // Iterate over the SSP reported triggers and compare
+                // them to the reconstructed cluster simulated trigger.
+                boolean matched = false;
+                matchLoop:
+                for(SSPNumberedTrigger sspTrigger : sspTriggers) {
+                    OutputLogger.printf("\t\t\t%s", sspTrigger.toString());
+                    
+                    // Only compare triggers if they are from the
+                    // same trigger source.
+                    if((triggerNum == 0 && sspTrigger.isSecondTrigger())
+                            || (triggerNum == 1 && sspTrigger.isFirstTrigger())) {
+                        OutputLogger.print(" [ fail; source    ]%n");
+                        continue matchLoop;
+                    }
+                    
+                    // Only compare the singles trigger if it was
+                    // not already matched to another trigger.
+                    if(sspTriggerSet.contains(sspTrigger)) {
+                        OutputLogger.print(" [ fail; matched   ]%n");
+                        continue matchLoop;
+                    }
+                    
+                    // Test each cut.
+                    int typeIndex = isSingles ? 0 : 1;
+                    boolean[] matchedCuts = triggerCutMatch(simTrigger, sspTrigger);
+                    for(int cutIndex = 0; cutIndex < matchedCuts.length; cutIndex++) {
+                        if(!matchedCuts[cutIndex]) {
+                            OutputLogger.printf(" [ fail; %-9s ]%n", cutNames[typeIndex][cutIndex]);
+                            continue matchLoop;
+                        }
+                    }
+                    
+                    // If all the trigger flags match, then the
+                    // triggers are a match.
+                    sspTriggerSet.add(sspTrigger);
+                    triggerEvent[triggerNum].matchedReconTrigger(tiFlags);
+                    OutputLogger.print(" [ success         ]%n");
+                    globalTriggerPlots.matchedTrigger(simTrigger);
+                    matched = true;
+                    break matchLoop;
+                }
+                
+                if(!matched) { globalTriggerPlots.failedTrigger(simTrigger); }
+            }
+        }
+        
+        
+        
+        // ==========================================================
+        // ==== Output Event Results ================================
+        // ==========================================================
+        
+        // Get the number of SSP and reconstructed cluster simulated
+        // triggers.
+        int sspSimTriggers = sspTriggerList.get(0).size() + sspTriggerList.get(1).size();
+        int reconSimTriggers = reconTriggerList.get(0).size() + reconTriggerList.get(1).size();
+        int[] sspTriggerCount = { sspTriggerList.get(0).size(), sspTriggerList.get(1).size() };
+        
+        // Print event statistics.
+        OutputLogger.println();
+        OutputLogger.println("Event Statistics:");
+        OutputLogger.printf("\tSSP Cluster Sim Triggers   :: %d%n", sspSimTriggers);
+        OutputLogger.printf("\tRecon Cluster Sim Triggers :: %d%n", reconSimTriggers);
+        OutputLogger.printf("\tSSP Reported Triggers      :: %d%n", sspTriggers.size());
+        
+        int matchedSSPTriggers = triggerEvent[0].getMatchedSSPSimulatedTriggers() + triggerEvent[1].getMatchedSSPSimulatedTriggers();
+        OutputLogger.printf("\tInternal Efficiency        :: %d / %d ", matchedSSPTriggers, sspSimTriggers);
+        if(sspSimTriggers == 0) { OutputLogger.printf("(N/A)%n"); }
+        else { OutputLogger.printf("(%3.0f%%)%n", (100.0 * matchedSSPTriggers / sspSimTriggers)); }
+        
+        int matchedReconTriggers = triggerEvent[0].getMatchedReconSimulatedTriggers() + triggerEvent[1].getMatchedReconSimulatedTriggers();
+        OutputLogger.printf("\tTrigger Efficiency         :: %d / %d", matchedReconTriggers, reconSimTriggers);
+        if(reconSimTriggers == 0) { OutputLogger.printf("(N/A)%n"); }
+        else { OutputLogger.printf("(%3.0f%%)%n", (100.0 * matchedReconTriggers / reconSimTriggers)); }
+        
+        // Print the individual cut performances.
+        if(isSingles) {
+            OutputLogger.println();
+            for(int triggerNum = 0; triggerNum < 2; triggerNum++) {
+                OutputLogger.printf("Trigger %d Individual Cut Failure Rate:%n", (triggerNum + 1));
+                if(sspSimTriggers == 0) {
+                    OutputLogger.printf("\tCluster Energy Lower Bound :: %d / %d%n", triggerEvent[triggerNum].getSSPCutFailures(ENERGY_MIN), sspTriggerCount[triggerNum]);
+                    OutputLogger.printf("\tCluster Energy Upper Bound :: %d / %d%n", triggerEvent[triggerNum].getSSPCutFailures(ENERGY_MAX), sspTriggerCount[triggerNum]);
+                    OutputLogger.printf("\tCluster Hit Count          :: %d / %d%n", triggerEvent[triggerNum].getSSPCutFailures(HIT_COUNT), sspTriggerCount[triggerNum]);
+                } else {
+                    OutputLogger.printf("\tCluster Energy Lower Bound :: %d / %d (%3.0f%%)%n",
+                            triggerEvent[triggerNum].getSSPCutFailures(ENERGY_MIN), sspTriggerCount[triggerNum],
+                            (100.0 * triggerEvent[triggerNum].getSSPCutFailures(ENERGY_MIN) / sspTriggerCount[triggerNum]));
+                    OutputLogger.printf("\tCluster Energy Upper Bound :: %d / %d (%3.0f%%)%n",
+                            triggerEvent[triggerNum].getSSPCutFailures(ENERGY_MAX), sspTriggerCount[triggerNum],
+                            (100.0 * triggerEvent[triggerNum].getSSPCutFailures(ENERGY_MAX) / sspTriggerCount[triggerNum]));
+                    OutputLogger.printf("\tCluster Hit Count          :: %d / %d (%3.0f%%)%n",
+                            triggerEvent[triggerNum].getSSPCutFailures(HIT_COUNT), sspTriggerCount[triggerNum],
+                            (100.0 * triggerEvent[triggerNum].getSSPCutFailures(HIT_COUNT) / sspTriggerCount[triggerNum]));
+                }
+            }
+            
+            // Update the global trigger tracking variables.
+            localStats.getTriggerStats().getSingles0Stats().addEvent(triggerEvent[0]);
+            localStats.getTriggerStats().getSingles1Stats().addEvent(triggerEvent[1]);
+            globalStats.getTriggerStats().getSingles0Stats().addEvent(triggerEvent[0]);
+            globalStats.getTriggerStats().getSingles1Stats().addEvent(triggerEvent[1]);
+        } else {
+            for(int triggerNum = 0; triggerNum < 2; triggerNum++) {
+                OutputLogger.println();
+                OutputLogger.printf("Trigger %d Individual Cut Failure Rate:%n", (triggerNum + 1));
+                if(sspTriggerCount[triggerNum] == 0) {
+                    OutputLogger.printf("\tPair Energy Sum            :: %d / %d%n", triggerEvent[triggerNum].getSSPCutFailures(ENERGY_SUM), sspTriggerCount[triggerNum]);
+                    OutputLogger.printf("\tPair Energy Difference     :: %d / %d%n", triggerEvent[triggerNum].getSSPCutFailures(ENERGY_DIFF), sspTriggerCount[triggerNum]);
+                    OutputLogger.printf("\tPair Energy Slope          :: %d / %d%n", triggerEvent[triggerNum].getSSPCutFailures(ENERGY_SLOPE), sspTriggerCount[triggerNum]);
+                    OutputLogger.printf("\tPair Coplanarity           :: %d / %d%n", triggerEvent[triggerNum].getSSPCutFailures(COPLANARITY), sspTriggerCount[triggerNum]);
+                } else {
+                    OutputLogger.printf("\tPair Energy Sum            :: %d / %d (%3.0f%%)%n",
+                            triggerEvent[triggerNum].getSSPCutFailures(ENERGY_SUM), sspTriggerCount[triggerNum],
+                            (100.0 * triggerEvent[triggerNum].getSSPCutFailures(ENERGY_SUM) / sspTriggerCount[triggerNum]));
+                    OutputLogger.printf("\tPair Energy Difference     :: %d / %d (%3.0f%%)%n",
+                            triggerEvent[triggerNum].getSSPCutFailures(ENERGY_DIFF), sspTriggerCount[triggerNum],
+                            (100.0 * triggerEvent[triggerNum].getSSPCutFailures(ENERGY_DIFF) / sspTriggerCount[triggerNum]));
+                    OutputLogger.printf("\tPair Energy Slope          :: %d / %d (%3.0f%%)%n",
+                            triggerEvent[triggerNum].getSSPCutFailures(ENERGY_SLOPE), sspTriggerCount[triggerNum],
+                            (100.0 * triggerEvent[triggerNum].getSSPCutFailures(ENERGY_SLOPE) / sspTriggerCount[triggerNum]));
+                    OutputLogger.printf("\tPair Coplanarity           :: %d / %d (%3.0f%%)%n",
+                            triggerEvent[triggerNum].getSSPCutFailures(COPLANARITY), sspTriggerCount[triggerNum],
+                            (100.0 * triggerEvent[triggerNum].getSSPCutFailures(COPLANARITY) / sspTriggerCount[triggerNum]));
+                }
+            }
+            
+            // Update the global trigger tracking variables.
+            localStats.getTriggerStats().getPair0Stats().addEvent(triggerEvent[0]);
+            localStats.getTriggerStats().getPair1Stats().addEvent(triggerEvent[1]);
+            globalStats.getTriggerStats().getPair0Stats().addEvent(triggerEvent[0]);
+            globalStats.getTriggerStats().getPair1Stats().addEvent(triggerEvent[1]);
+        }
+        
+        // Note whether the was a trigger match failure.
+        if(triggerEvent[0].getFailedReconSimulatedTriggers() != 0 && triggerEvent[1].getFailedReconSimulatedTriggers() != 0) {
+            if(isSingles) { singlesEfficiencyFail = true; }
+            else { pairEfficiencyFail = true; }
+        } if(triggerEvent[0].getFailedSSPSimulatedTriggers() != 0 && triggerEvent[1].getFailedSSPSimulatedTriggers() != 0) {
+            if(isSingles) { singlesInternalFail = true; }
+            else { pairInternalFail = true; }
+        }
+    }
+    
+    /**
+     * Outputs all of the verification parameters currently in use by
+     * the software. A warning will be issued if the values for NSA and
+     * NSB, along with the FADC window, preclude clusters from being
+     * verified.
+     */
+    private void logSettings() {
+        // Output general settings.
+        System.out.println("Cluster Verification Settings");
+        System.out.printf("\tHit Threshold          :: %1d hit(s)%n", hitAcceptance);
+        System.out.printf("\tEnergy Threshold       :: %5.3f GeV%n",  energyAcceptance);
+        System.out.println();
+        
+        // Output window settings.
+        System.out.println("FADC Timing Window Settings");
+        System.out.printf("\tNSB                    :: %3d ns%n", nsb);
+        System.out.printf("\tNSA                    :: %3d ns%n", nsa);
+        System.out.printf("\tFADC Window            :: %3d ns%n", windowWidth);
+        
+        // Calculate the valid clustering window.
+        int start = nsb;
+        int end = windowWidth - nsa;
+        if(start < end) {
+            System.out.printf("\tValid Cluster Window   :: [ %3d ns, %3d ns ]%n", start, end);
+            performClusterVerification = true;
+        } else {
+            System.out.println("\tNSB, NSA, and FADC window preclude a valid cluster verification window.");
+            System.out.println("\tCluster verification will not be performed!");
+            performClusterVerification = false;
+        }
+        System.out.println();
+        
+        // Output the singles trigger settings.
+        for(int i = 0; i < 2; i++) {
+            // Print the settings.
+            System.out.printf("Singles Trigger %d Settings%23s[%5b]%n", (i + 1), "", singlesTriggerEnabled[i]);
+            System.out.printf("\tCluster Energy Low     :: %.3f GeV      [%5b]%n",
+                    singlesTrigger[i].getCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_LOW), singlesCutsEnabled[i][0]);
+            System.out.printf("\tCluster Energy High    :: %.3f GeV      [%5b]%n",
+                    singlesTrigger[i].getCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_HIGH), singlesCutsEnabled[i][1]);
+            System.out.printf("\tCluster Hit Count      :: %.0f hit(s)       [%5b]%n",
+                    singlesTrigger[i].getCutValue(TriggerModule.CLUSTER_HIT_COUNT_LOW), singlesCutsEnabled[i][2]);
+            System.out.println();
+        }
+        
+        // Output the pair trigger settings.
+        for(int i = 0; i < 2; i++) {
+            System.out.printf("Pairs Trigger %d Settings%25s[%5b]%n", (i + 1), "", pairTriggerEnabled[i]);
+            System.out.printf("\tCluster Energy Low     :: %.3f GeV      [%5b]%n",
+                    pairsTrigger[i].getCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_LOW), pairCutsEnabled[i][0]);
+            System.out.printf("\tCluster Energy High    :: %.3f GeV      [%5b]%n",
+                    pairsTrigger[i].getCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_HIGH), pairCutsEnabled[i][1]);
+            System.out.printf("\tCluster Hit Count      :: %.0f hit(s)       [%5b]%n",
+                    pairsTrigger[i].getCutValue(TriggerModule.CLUSTER_HIT_COUNT_LOW), pairCutsEnabled[i][2]);
+            System.out.printf("\tPair Energy Sum Low    :: %.3f GeV      [%5b]%n",
+                    pairsTrigger[i].getCutValue(TriggerModule.PAIR_ENERGY_SUM_LOW), pairCutsEnabled[i][3]);
+            System.out.printf("\tPair Energy Sum High   :: %.3f GeV      [%5b]%n",
+                    pairsTrigger[i].getCutValue(TriggerModule.PAIR_ENERGY_SUM_HIGH), pairCutsEnabled[i][3]);
+            System.out.printf("\tPair Energy Difference :: %.3f GeV      [%5b]%n",
+                    pairsTrigger[i].getCutValue(TriggerModule.PAIR_ENERGY_DIFFERENCE_HIGH), pairCutsEnabled[i][4]);
+            System.out.printf("\tPair Energy Slope      :: %.3f GeV      [%5b]%n",
+                    pairsTrigger[i].getCutValue(TriggerModule.PAIR_ENERGY_SLOPE_LOW), pairCutsEnabled[i][5]);
+            System.out.printf("\tPair Energy Slope F    :: %.4f GeV / mm%n",
+                    pairsTrigger[i].getCutValue(TriggerModule.PAIR_ENERGY_SLOPE_F));
+            System.out.printf("\tPair Coplanarity       :: %3.0f Degrees    [%5b]%n",
+                    pairsTrigger[i].getCutValue(TriggerModule.PAIR_COPLANARITY_HIGH), pairCutsEnabled[i][6]);
+            System.out.printf("\tPair Time Coincidence  :: %2.0f ns          [%5b]%n",
+                    pairsTrigger[i].getCutValue(TriggerModule.PAIR_TIME_COINCIDENCE), true);
+            System.out.println();
+        }
+    }
+    
+    /**
+     * Summarizes the global run statistics in a log to the terminal.
+     */
+    private void logStatistics() {
+        // Print the cluster/trigger verification header.
+        System.out.println();
+        System.out.println();
+        System.out.println("======================================================================");
+        System.out.println("=== Cluster/Trigger Verification Results =============================");
+        System.out.println("======================================================================");
+        
+        // Print the general event failure rate.
+        int headSpaces = getPrintSpaces(globalStats.getEventCount());
+        System.out.println("General Event Statistics:");
+        System.out.printf("\tEvent Start Time      :: %.3f s%n", (startTime / Math.pow(10, 9)));
+        System.out.printf("\tEvent End Time        :: %.3f%n", (endTime / Math.pow(10, 9)));
+        System.out.printf("\tEvent Run Time        :: %.3f%n", ((endTime - startTime) / Math.pow(10, 9)));
+        System.out.printf("\tNoise Events          :: %" + headSpaces + "d / %" + headSpaces + "d (%7.3f%%)%n",
+                globalStats.getNoiseEvents(), globalStats.getEventCount(), (100.0 * globalStats.getNoiseEvents() / globalStats.getEventCount()));
+        System.out.printf("\tCluster Events Failed :: %" + headSpaces + "d / %" + headSpaces + "d (%7.3f%%)%n",
+                globalStats.getFailedClusterEventCount(), globalStats.getEventCount(), (100.0 * globalStats.getFailedClusterEventCount() / globalStats.getEventCount()));
+        System.out.printf("\tSingles Events Failed :: %" + headSpaces + "d / %" + headSpaces + "d (%7.3f%%)%n",
+                globalStats.getFailedSinglesEventCount(), globalStats.getEventCount(), (100.0 * globalStats.getFailedSinglesEventCount() / globalStats.getEventCount()));
+        System.out.printf("\tPair Events Failed    :: %" + headSpaces + "d / %" + headSpaces + "d (%7.3f%%)%n",
+                globalStats.getFailedPairEventCount(), globalStats.getEventCount(), (100.0 * globalStats.getFailedPairEventCount() / globalStats.getEventCount()));
+        
+        // Print out how many events reported a given TI type, both in
+        // total and hierarchically.
+        System.out.println();
+        System.out.println("Event Triggering Type Verification:");
+        System.out.printf("\t%15s\t%15s\t%15s%n", "Trigger", "Total", "Hierarchical");
+        System.out.printf("\t%15s\t%15s\t%15s%n", "Pulser", globalStats.getTriggerStats().getTITriggers(TriggerDiagStats.PULSER, false),
+                globalStats.getTriggerStats().getTITriggers(TriggerDiagStats.PULSER, true));
+        System.out.printf("\t%15s\t%15s\t%15s%n", "Cosmic", globalStats.getTriggerStats().getTITriggers(TriggerDiagStats.COSMIC, false),
+                globalStats.getTriggerStats().getTITriggers(TriggerDiagStats.COSMIC, true));
+        System.out.printf("\t%15s\t%15s\t%15s%n", "Singles 1", globalStats.getTriggerStats().getTITriggers(TriggerDiagStats.SINGLES0, false),
+                globalStats.getTriggerStats().getTITriggers(TriggerDiagStats.SINGLES0, true));
+        System.out.printf("\t%15s\t%15s\t%15s%n", "Singles 2", globalStats.getTriggerStats().getTITriggers(TriggerDiagStats.SINGLES1, false),
+                globalStats.getTriggerStats().getTITriggers(TriggerDiagStats.SINGLES1, true));
+        System.out.printf("\t%15s\t%15s\t%15s%n", "Pair 1", globalStats.getTriggerStats().getTITriggers(TriggerDiagStats.PAIR0, false),
+                globalStats.getTriggerStats().getTITriggers(TriggerDiagStats.PAIR0, true));
+        System.out.printf("\t%15s\t%15s\t%15s%n", "Pair 2", globalStats.getTriggerStats().getTITriggers(TriggerDiagStats.PAIR1, false),
+                globalStats.getTriggerStats().getTITriggers(TriggerDiagStats.PAIR1, true));
+        
+        // Print the cluster verification data.
+        System.out.println();
+        System.out.println("Cluster Verification:");
+        System.out.printf("\tRecon Clusters        :: %d%n", globalStats.getClusterStats().getReconClusterCount());
+        System.out.printf("\tSSP Clusters          :: %d%n", globalStats.getClusterStats().getSSPClusterCount());
+        System.out.printf("\tClusters Matched      :: %d%n", globalStats.getClusterStats().getMatches());
+        System.out.printf("\tFailed (Position)     :: %d%n", globalStats.getClusterStats().getPositionFailures());
+        System.out.printf("\tFailed (Energy)       :: %d%n", globalStats.getClusterStats().getEnergyFailures());
+        System.out.printf("\tFailed (Hit Count)    :: %d%n", globalStats.getClusterStats().getHitCountFailures());
+        if(globalStats.getClusterStats().getReconClusterCount() == 0) {
+            System.out.printf("\tCluster Efficiency    :: N/A%n");
+        } else {
+            System.out.printf("\tCluster Efficiency    :: %7.3f%%%n",
+                    100.0 * globalStats.getClusterStats().getMatches() / globalStats.getClusterStats().getReconClusterCount());
+        }
+        
+        // Print the trigger verification data.
+        for(int triggerType = 0; triggerType < 2; triggerType++) {
+            // Get the trigger data. Type 0 represents singles triggers.
+            TriggerEvent[] triggerData = new TriggerEvent[2];
+            if(triggerType == 0) {
+                triggerData[0] = globalStats.getTriggerStats().getSingles0Stats();
+                triggerData[1] = globalStats.getTriggerStats().getSingles1Stats();
+            } else {
+                triggerData[0] = globalStats.getTriggerStats().getPair0Stats();
+                triggerData[1] = globalStats.getTriggerStats().getPair1Stats();
+            }
+            
+            // Get the basic trigger data.
+            int sspSimTriggers = triggerData[0].getSSPSimulatedTriggers() + triggerData[1].getSSPSimulatedTriggers();
+            int reconSimTriggers = triggerData[0].getReconSimulatedTriggers() + triggerData[1].getReconSimulatedTriggers();
+            int sspReportedTriggers = triggerData[0].getReportedTriggers() + triggerData[1].getReportedTriggers();
+            int sspMatchedTriggers = triggerData[0].getMatchedSSPSimulatedTriggers() + triggerData[1].getMatchedSSPSimulatedTriggers();
+            int reconMatchedTriggers = triggerData[0].getMatchedReconSimulatedTriggers() + triggerData[1].getMatchedReconSimulatedTriggers();
+            
+            // Print the basic trigger statistics.
+            int spaces = getPrintSpaces(sspSimTriggers, reconSimTriggers, sspReportedTriggers);
+            System.out.println();
+            if(triggerType == 0) { System.out.println("Singles Trigger Verification:"); }
+            else { System.out.println("Pair Trigger Verification:"); }
+            System.out.printf("\tSSP Cluster Sim Triggers   :: %" + spaces + "d%n", sspSimTriggers);
+            System.out.printf("\tRecon Cluster Sim Triggers :: %" + spaces + "d%n", reconSimTriggers);
+            System.out.printf("\tSSP Reported Triggers      :: %" + spaces + "d%n", sspReportedTriggers);
+            
+            System.out.printf("\tInternal Efficiency        :: %" + spaces + "d / %" + spaces + "d ", sspMatchedTriggers, sspSimTriggers);
+            if(sspSimTriggers == 0) { System.out.printf("(N/A)%n"); }
+            else { System.out.printf("(%7.3f%%)%n", (100.0 * sspMatchedTriggers / sspSimTriggers)); }
+            
+            System.out.printf("\tTrigger Efficiency         :: %" + spaces + "d / %" + spaces + "d ", reconMatchedTriggers, reconSimTriggers);
+            if(reconSimTriggers == 0) { System.out.printf("(N/A)%n"); }
+            else { System.out.printf("(%7.3f%%)%n" , (100.0 * reconMatchedTriggers / reconSimTriggers)); }
+            
+            // Print the individual cut performances.
+            if(triggerType == 0) {
+                for(int triggerNum = 0; triggerNum < 2; triggerNum++) {
+                    // Get the appropriate trigger statistics module.
+                    TriggerEvent triggerStats;
+                    if(triggerNum == 0) { triggerStats = globalStats.getTriggerStats().getSingles0Stats(); }
+                    else { triggerStats = globalStats.getTriggerStats().getSingles1Stats(); }
+                    
+                    // Get the number of SSP triggers for this trigger number.
+                    int sspTriggerCount = triggerStats.getSSPSimulatedTriggers();
+                    //int sspTriggerCount = triggerRunStats[0].getTotalSSPTriggers(triggerNum);
+                
+                    System.out.println();
+                    System.out.printf("\tTrigger %d Individual Cut Failure Rate:%n", (triggerNum + 1));
+                    System.out.printf("\t\tUmatched Triggers          :: %" + spaces + "d%n", triggerStats.getUnmatchedSSPSimulatedTriggers());
+                    //System.out.printf("\t\tUmatched Triggers          :: %" + spaces + "d%n", triggerRunStats[0].getUnmatchedTriggers(triggerNum));
+                    if(sspTriggerCount == 0) {
+                        System.out.printf("\t\tCluster Energy Lower Bound :: %" + spaces + "d / %" + spaces + "d%n",
+                                triggerStats.getSSPCutFailures(ENERGY_MIN), sspTriggerCount);
+                        System.out.printf("\t\tCluster Energy Upper Bound :: %" + spaces + "d / %" + spaces + "d%n",
+                                triggerStats.getSSPCutFailures(ENERGY_MAX), sspTriggerCount);
+                        System.out.printf("\t\tCluster Hit Count          :: %" + spaces + "d / %" + spaces + "d%n",
+                                triggerStats.getSSPCutFailures(HIT_COUNT), sspTriggerCount);
+                    } else {
+                        System.out.printf("\t\tCluster Energy Lower Bound :: %" + spaces + "d / %" + spaces + "d (%7.3f%%)%n",
+                                triggerStats.getSSPCutFailures(ENERGY_MIN), sspTriggerCount,
+                                (100.0 * triggerStats.getSSPCutFailures(ENERGY_MIN) / sspTriggerCount));
+                        System.out.printf("\t\tCluster Energy Upper Bound :: %" + spaces + "d / %" + spaces + "d (%7.3f%%)%n",
+                                triggerStats.getSSPCutFailures(ENERGY_MAX), sspTriggerCount,
+                                (100.0 * triggerStats.getSSPCutFailures(ENERGY_MAX) / sspTriggerCount));
+                        System.out.printf("\t\tCluster Hit Count          :: %" + spaces + "d / %" + spaces + "d (%7.3f%%)%n",
+                                triggerStats.getSSPCutFailures(HIT_COUNT), sspTriggerCount,
+                                (100.0 * triggerStats.getSSPCutFailures(HIT_COUNT) / sspTriggerCount));
+                    }
+                }
+            } else {
+                for(int triggerNum = 0; triggerNum < 2; triggerNum++) {
+                    // Get the appropriate trigger statistics module.
+                    TriggerEvent triggerStats;
+                    if(triggerNum == 0) { triggerStats = globalStats.getTriggerStats().getPair0Stats(); }
+                    else { triggerStats = globalStats.getTriggerStats().getPair1Stats(); }
+                    
+                    // Get the number of SSP triggers for this trigger number.
+                    int sspTriggerCount = triggerStats.getSSPSimulatedTriggers();
+                    
+                    System.out.println();
+                    System.out.printf("\tTrigger %d Individual Cut Failure Rate:%n", (triggerNum + 1));
+                    System.out.printf("\t\tUmatched Triggers          :: %" + spaces + "d%n", triggerStats.getUnmatchedSSPSimulatedTriggers());
+                    if(sspTriggerCount == 0) {
+                        System.out.printf("\t\tPair Energy Sum            :: %" + spaces + "d / %" + spaces + "d%n",
+                                triggerStats.getSSPCutFailures(ENERGY_SUM), sspTriggerCount);
+                        System.out.printf("\t\tPair Energy Difference     :: %" + spaces + "d / %" + spaces + "d%n",
+                                triggerStats.getSSPCutFailures(ENERGY_DIFF), sspTriggerCount);
+                        System.out.printf("\t\tPair Energy Slope          :: %" + spaces + "d / %" + spaces + "d%n",
+                                triggerStats.getSSPCutFailures(ENERGY_SLOPE), sspTriggerCount);
+                        System.out.printf("\t\tPair Coplanarity           :: %" + spaces + "d / %" + spaces + "d%n",
+                                triggerStats.getSSPCutFailures(COPLANARITY), sspTriggerCount);
+                    } else {
+                        System.out.printf("\t\tPair Energy Sum            :: %" + spaces + "d / %" + spaces + "d (%7.3f%%)%n",
+                                triggerStats.getSSPCutFailures(ENERGY_SUM), sspTriggerCount,
+                                (100.0 * triggerStats.getSSPCutFailures(ENERGY_SUM) / sspTriggerCount));
+                        System.out.printf("\t\tPair Energy Difference     :: %" + spaces + "d / %" + spaces + "d (%7.3f%%)%n",
+                                triggerStats.getSSPCutFailures(ENERGY_DIFF), sspTriggerCount,
+                                (100.0 * triggerStats.getSSPCutFailures(ENERGY_DIFF) / sspTriggerCount));
+                        System.out.printf("\t\tPair Energy Slope          :: %" + spaces + "d / %" + spaces + "d (%7.3f%%)%n",
+                                triggerStats.getSSPCutFailures(ENERGY_SLOPE), sspTriggerCount,
+                                (100.0 * triggerStats.getSSPCutFailures(ENERGY_SLOPE) / sspTriggerCount));
+                        System.out.printf("\t\tPair Coplanarity           :: %" + spaces + "d / %" + spaces + "d (%7.3f%%)%n",
+                                triggerStats.getSSPCutFailures(COPLANARITY), sspTriggerCount,
+                                (100.0 * triggerStats.getSSPCutFailures(COPLANARITY) / sspTriggerCount));
+                    }
+                }
+            }
+        }
+        
+        // Print out the trigger efficiency table.
+        System.out.println();
+        globalStats.getTriggerStats().printEfficiencyTable();
+    }
+    
+    /**
+     * Checks whether all of the hits in a cluster are within the safe
+     * region of the FADC output window.
+     * @param reconCluster - The cluster to check.
+     * @return Returns <code>true</code> if the cluster is safe and
+     * returns <code>false</code> otherwise.
+     */
+    private final boolean isVerifiable(Cluster reconCluster) {
+        return TriggerDiagnosticUtil.isVerifiable(reconCluster, nsa, nsb, windowWidth);
+    }
+    
+    /**
+     * Generates a <code>List</code> collection that contains a set
+     * of <code>ArrayList</code> collections representing a unique
+     * permutation of the entries in the argument.
+     * @param values - A collection of the entries to be permuted.
+     * @return Returns a list of lists representing the permutations.
+     */
+    private static final List<List<Pair<Cluster, SSPCluster>>> getPermutations(List<Cluster> reconClusters, List<SSPCluster> sspClusters) {
+        // Store the SSP cluster permutations.
+        List<List<SSPCluster>> permList = new ArrayList<List<SSPCluster>>();
+        
+        // Make sure that the two lists are the same size.
+        int reconSize = reconClusters.size();
+        int sspSize = sspClusters.size();
+        while(sspClusters.size() < reconClusters.size()) {
+            sspClusters.add(null);
+        }
+        while(reconClusters.size() < sspClusters.size()) {
+            reconClusters.add(null);
+        }
+        
+        // Get the SSP cluster permutations.
+        permute(new ArrayList<SSPCluster>(0), sspClusters, permList);
+        
+        // Create pairs from the permutations.
+        List<List<Pair<Cluster, SSPCluster>>> pairList = new ArrayList<List<Pair<Cluster, SSPCluster>>>();
+        for(List<SSPCluster> permutation : permList) {
+            List<Pair<Cluster, SSPCluster>> pairs = new ArrayList<Pair<Cluster, SSPCluster>>(reconClusters.size());
+            
+            for(int clusterIndex = 0; (clusterIndex < reconClusters.size() && clusterIndex < permutation.size()); clusterIndex++) {
+                pairs.add(new Pair<Cluster, SSPCluster>(reconClusters.get(clusterIndex), permutation.get(clusterIndex)));
+            }
+            
+            pairList.add(pairs);
+        }
+        
+        // Remove the extra values.
+        for(int i = sspClusters.size() - 1; i >= sspSize; i--) { sspClusters.remove(i); }
+        for(int i = reconClusters.size() - 1; i >= reconSize; i--) { reconClusters.remove(i); }
+        
+        // Return the pairs.
+        return pairList;
+    }
+    
+    /**
+     * Recursive method for permuting all entries in the argument
+     * collection <code>remainingValues</code> into the argument
+     * <code>permutedValues</code> values. Completed permutations are
+     * placed in the argument <code>permList</code>.
+     * @param permutedValues - List to store entries that have already
+     * been permuted.
+     * @param remainingValues - List to store  entries that need to be
+     * permuted.
+     * @param permList - List to store completed permutations.
+     */
+    private static final void permute(List<SSPCluster> permutedValues, List<SSPCluster> remainingValues, List<List<SSPCluster>> permList) {
+        // If the list of entries that still need to be sorted is empty,
+        // then there is nothing to sort. Just return and empty list.
+        if(remainingValues.isEmpty()) { return; }
+        
+        // If there is only one value left in the list of entries that
+        // still need to be sorted, then just add it to the permutation
+        // list and return it.
+        else if(remainingValues.size() <= 1) {
+            // Add the last entry.
+            permutedValues.add(remainingValues.get(0));
+            
+            // Add the permutation to the list of completed permutations.
+            permList.add(permutedValues);
+        }
+        
+        // Otherwise, continue to get all possible permutations.
+        else {
+            // Iterate over the entries that have not been permuted.
+            for(int i = 0; i < remainingValues.size(); i++) {
+                // Make new lists to contain the permutations.
+                List<SSPCluster> newPermList = new ArrayList<SSPCluster>(permutedValues.size() + 1);
+                List<SSPCluster> newRemainList = new ArrayList<SSPCluster>(remainingValues.size());
+                
+                // Copy the current permuted entries to the new list
+                // and one value from the list of entries that have
+                // not been permuted yet.
+                newPermList.addAll(permutedValues);
+                newPermList.add(remainingValues.get(i));
+                
+                // The new list of entries that have not been permuted
+                // should be identical, except it should now be missing
+                // the entry that was moved.
+                for(int index = 0; index < remainingValues.size(); index++) {
+                    if(index != i) { newRemainList.add(remainingValues.get(index)); }
+                }
+                
+                // Repeat the process with the new lists.
+                permute(newPermList, newRemainList, permList);
+            }
+        }
+    }
+    
+    /**
+     * Compares two cluster matching events and finds the one that has
+     * the better results. Note that this will only return results that
+     * make sense if both of the events represent different permutations
+     * of the same set of clusters. Comparing events with different sets
+     * of clusters will produce meaningless results.
+     * @param firstEvent - The first cluster matching event,
+     * @param secondEvent - The second cluster matching event.
+     * @return Returns the cluster matching event that is better.
+     */
+    private static final DetailedClusterEvent getBestPermutation(DetailedClusterEvent firstEvent, DetailedClusterEvent secondEvent) {
+        // If both permutations are null, return that.
+        if(firstEvent == null && secondEvent == null) {
+            return null;
+        }
+        
+        // If one permutation is null, it is not the best.
+        if(firstEvent == null) { return secondEvent; }
+        else if(secondEvent == null) { return firstEvent; }
+        
+        // A permutation is better if it has more matches.
+        if(firstEvent.getMatches() > secondEvent.getMatches()) { return firstEvent; }
+        else if(secondEvent.getMatches() > firstEvent.getMatches()) { return secondEvent; }
+        
+        // Otherwise, the permutation with the least energy failures is
+        // the better permutation.
+        if(firstEvent.getEnergyFailures() < secondEvent.getEnergyFailures()) { return firstEvent; }
+        else if(secondEvent.getEnergyFailures() < firstEvent.getEnergyFailures()) { return secondEvent; }
+        
+        // If both these values are the same, then the events are identical.
+        return firstEvent;
+    }
+    
+    /**
+     * Determines the number of spaces needed to render the longest of
+     * a series of integers as a string.
+     * @param vals - The series of integers.
+     * @return Returns the number of spaces needed to render the longest
+     * integer as a base-10 string.
+     */
+    private static final int getPrintSpaces(int... vals) {
+        // Track the largest value.
+        int largest = 0;
+        
+        // Iterate over the arguments and find the largest.
+        for(int val : vals) {
+            // Get the length of the string.
+            int length = TriggerDiagnosticUtil.getDigits(val);
+            
+            // If it is larger, track it.
+            if(length > largest) { largest = length; }
+        }
+        
+        // Return the longer one.
+        return largest;
+    }
+    
+    /**
+     * Gets the position of the source of a <code>Trigger</code> object
+     * as text. This method only supports trigger sources of the types
+     * <code>SSPCluster</code>, <code>Cluster</code>, and arrays of size
+     * two of either type.
+     * @param trigger - The trigger from which to obtain the source.
+     * @return Returns the source of the trigger as a <code>String</code>
+     * object.
+     * @throws IllegalArgumentException Occurs if the source of the
+     * trigger is not any of the supported types.
+     */
+    private static final String triggerPositionString(Trigger<?> trigger) throws IllegalArgumentException {
+        // Get the trigger source.
+        Object source = trigger.getTriggerSource();
+        
+        // Handle valid trigger sources.
+        if(source instanceof SSPCluster) {
+            return TriggerDiagnosticUtil.clusterPositionString((SSPCluster) source);
+        } else if(source instanceof Cluster) {
+            return TriggerDiagnosticUtil.clusterPositionString((Cluster) source);
+        } else if(source instanceof SSPCluster[]) {
+            SSPCluster[] sourcePair = (SSPCluster[]) source;
+            if(sourcePair.length == 2) {
+                return String.format("%s, %s", TriggerDiagnosticUtil.clusterPositionString(sourcePair[0]),
+                        TriggerDiagnosticUtil.clusterPositionString(sourcePair[1]));
+            }
+        } else if(source instanceof Cluster[]) {
+            Cluster[] sourcePair = (Cluster[]) source;
+            if(sourcePair.length == 2) {
+                return String.format("%s, %s", TriggerDiagnosticUtil.clusterPositionString(sourcePair[0]),
+                        TriggerDiagnosticUtil.clusterPositionString(sourcePair[1]));
+            }
+        }
+        
+        // Otherwise, the source type is unrecognized. Throw an error.
+        throw new IllegalArgumentException(String.format("Trigger source type \"%s\" is not supported.",
+                trigger.getTriggerSource().getClass().getSimpleName()));
+    }
+    
+    /**
+     * Gets the time of a simulated trigger object. Method supports
+     * triggers with source objects of type <code>SSPCluster</code>,
+     * <code>Cluster</code>, and arrays of size two composed of either
+     * object type.
+     * @param trigger - The trigger.
+     * @return Returns the time at which the trigger occurred.
+     * @throws IllegalArgumentException Occurs if the trigger source
+     * is not a supported type.
+     */
+    private static final double getTriggerTime(Trigger<?> trigger) throws IllegalArgumentException {
+        // Get the trigger source.
+        Object source = trigger.getTriggerSource();
+        
+        // Get the trigger time for supported trigger types.
+        if(source instanceof SSPCluster) {
+            return ((SSPCluster) source).getTime();
+        } else if(source instanceof Cluster) {
+            return TriggerDiagnosticUtil.getClusterTime((Cluster) source);
+        } else if(source instanceof SSPCluster[]) {
+            // Get the pair.
+            SSPCluster[] sourcePair = (SSPCluster[]) source;
+            
+            // Get the time of the bottom cluster.
+            if(sourcePair.length == 2) {
+                if(sourcePair[0].getYIndex() < 0) { return sourcePair[0].getTime(); }
+                else if(sourcePair[1].getYIndex() < 0) { return sourcePair[1].getTime(); }
+                else { throw new IllegalArgumentException("Cluster pairs must be formed of a top/bottom pair."); }
+            }
+            else { throw new IllegalArgumentException("Cluster pairs must be of size 2."); }
+        } else if(source instanceof Cluster[]) {
+            // Get the pair.
+            Cluster[] sourcePair = (Cluster[]) source;
+            int[] iy = {
+                TriggerDiagnosticUtil.getYIndex(sourcePair[0]),
+                TriggerDiagnosticUtil.getYIndex(sourcePair[1])
+            };
+            
+            // Get the time of the bottom cluster.
+            if(sourcePair.length == 2) {
+                if(iy[0] < 0) { return TriggerDiagnosticUtil.getClusterTime(sourcePair[0]); }
+                else if(iy[1] < 0) { return TriggerDiagnosticUtil.getClusterTime(sourcePair[1]); }
+                else { throw new IllegalArgumentException("Cluster pairs must be formed of a top/bottom pair."); }
+            }
+            else { throw new IllegalArgumentException("Cluster pairs must be of size 2."); }
+        }
+        
+        // If the source type is unrecognized, throw an exception.
+        throw new IllegalArgumentException(String.format("Trigger source type \"%\" is not supported.",
+                source.getClass().getSimpleName()));
+    }
+    
+    /**
+     * Checks if a simulated trigger and an SSP trigger match. Note
+     * that only certain types can be compared. These are:
+     * <ul><li><code>SinglesTrigger<?> --> SSPSinglesTrigger</code></li>
+     * <li><code>PairTrigger<?> --> SSPPairTrigger</code></li></ul>
+     * @param simTrigger - The simulated trigger.
+     * @param sspTrigger - The SSP bank trigger.
+     * @return Returns an array of <code>boolean</code> primitives that
+     * indicate which cuts passed and which failed.
+     */
+    private static final boolean[] triggerCutMatch(Trigger<?> simTrigger, SSPTrigger sspTrigger) {
+        // Check that the cuts match for supported trigger types.
+        if(simTrigger instanceof SinglesTrigger && sspTrigger instanceof SSPSinglesTrigger) {
+            // Create an array to store the cut checks.
+            boolean[] cutMatch = new boolean[3];
+            
+            // Cast the triggers.
+            SinglesTrigger<?> simSingles = (SinglesTrigger<?>) simTrigger;
+            SSPSinglesTrigger sspSingles = (SSPSinglesTrigger) sspTrigger;
+            
+            // Perform the check.
+            cutMatch[ENERGY_MIN] = (simSingles.getStateClusterEnergyLow()  == sspSingles.passCutEnergyMin());
+            cutMatch[ENERGY_MAX] = (simSingles.getStateClusterEnergyHigh() == sspSingles.passCutEnergyMax());
+            cutMatch[HIT_COUNT] = (simSingles.getStateHitCount()          == sspSingles.passCutHitCount());
+            
+            // Return the match array.
+            return cutMatch;
+        } else if(simTrigger instanceof PairTrigger && sspTrigger instanceof SSPPairTrigger) {
+            // Create an array to store the cut checks.
+            boolean[] cutMatch = new boolean[4];
+            
+            // Cast the triggers.
+            PairTrigger<?> simPair = (PairTrigger<?>) simTrigger;
+            SSPPairTrigger sspPair = (SSPPairTrigger) sspTrigger;
+            
+            // Perform the check.
+            cutMatch[ENERGY_SUM] = (simPair.getStateEnergySum()        == sspPair.passCutEnergySum());
+            cutMatch[ENERGY_DIFF] = (simPair.getStateEnergyDifference() == sspPair.passCutEnergyDifference());
+            cutMatch[ENERGY_SLOPE] = (simPair.getStateEnergySlope()      == sspPair.passCutEnergySlope());
+            cutMatch[COPLANARITY] = (simPair.getStateCoplanarity()      == sspPair.passCutCoplanarity());
+            
+            // Return the match array.
+            return cutMatch;
+        }
+        
+        // If this point is reached, the triggers are not of a supported
+        // type for cut comparison. Produce an exception.
+        throw new IllegalArgumentException(String.format("Triggers of type \"%s\" can not be cut-matched with triggers of type \"%s\".",
+                simTrigger.getClass().getSimpleName(), sspTrigger.getClass().getSimpleName()));
+    }
 }

Modified: java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/TriggerTurnOnDriver.java
 =============================================================================
--- java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/TriggerTurnOnDriver.java	(original)
+++ java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/TriggerTurnOnDriver.java	Wed Apr 27 11:11:32 2016
@@ -70,9 +70,9 @@
     public TriggerTurnOnDriver() {
     }
     
-	public void setShowPlots(boolean showPlots) {
-		this.showPlots = showPlots;
-	}
+    public void setShowPlots(boolean showPlots) {
+        this.showPlots = showPlots;
+    }
 
     @Override
     protected void detectorChanged(Detector detector) {

Modified: java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/data/ClusterEvent.java
 =============================================================================
--- java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/data/ClusterEvent.java	(original)
+++ java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/data/ClusterEvent.java	Wed Apr 27 11:11:32 2016
@@ -9,104 +9,104 @@
  * @author Kyle McCarty <[log in to unmask]>
  */
 public class ClusterEvent extends ClusterStatModule {
-	/**
-	 * Fuses another <code>ClusterEvent</code> with this object. The
-	 * other event's cluster pairs and states will be added to those
-	 * already in this event.
-	 * @param event - The event to fuse.
-	 */
-	public void addEvent(ClusterEvent event) {
-		// If the event is null, do nothing.
-		if(event == null) { return; }
-		
-		// Add the values stored in the argument event to the counters
-		// in this event.
-		sspClusters   += event.sspClusters;
-		reconClusters += event.reconClusters;
-		matches       += event.matches;
-		failEnergy    += event.failEnergy;
-		failPosition  += event.failPosition;
-		failHitCount  += event.failHitCount;
-	}
-	
-	/**
-	 * Indicates whether at least one cluster pair in the event created
-	 * a fail state.
-	 * @return Returns <code>true</code> if not all clusters matched and
-	 * <code>false</code> otherwise.
-	 */
-	public boolean isFailState() {
-		return (failEnergy > 0) || (failHitCount > 0) || (failTime > 0) || (failPosition > 0);
-	}
-	
-	/**
-	 * Notes that a reconstructed cluster and SSP cluster pair failed
-	 * due to energy.
-	 */
-	public void pairFailEnergy() {
-		failEnergy++;
-	}
-	
-	/**
-	 * Notes that a reconstructed cluster and SSP cluster pair failed
-	 * due to hit count.
-	 */
-	public void pairFailHitCount() {
-		failHitCount++;
-	}
-	
-	/**
-	 * Notes that a reconstructed cluster and SSP cluster pair failed
-	 * due to position.
-	 */
-	public void pairFailPosition() {
-		failPosition++;
-	}
-	
-	/**
-	 * Notes that one or more reconstructed cluster and SSP cluster pair
-	 * failed due to position.
-	 * @param count - The number of events that failed in this manner.
-	 */
-	public void pairFailPosition(int count) {
-		// negative values are non-physical.
-		if(count < 0) {
-			throw new IllegalArgumentException("Cluster failure counts must be non-negative.");
-		}
-		
-		// Increment the count.
-		failPosition += count;
-	}
-	
-	/**
-	 * Notes that a reconstructed cluster and SSP cluster pair failed
-	 * due to time.
-	 */
-	public void pairFailTime() {
-		failTime++;
-	}
-	
-	/**
-	 * Notes that a reconstructed cluster and SSP cluster pair was
-	 * successfully matched.
-	 */
-	public void pairMatch() {
-		matches++;
-	}
-	
-	/**
-	 * Increments the number of reconstructed FADC clusters seen.
-	 * @param count - The number of clusters seen.
-	 */
-	public void sawReconClusters(int count) {
-		reconClusters += count;
-	}
-	
-	/**
-	 * Increments the number of SSP bank clusters seen.
-	 * @param count - The number of clusters seen.
-	 */
-	public void sawSSPClusters(int count) {
-		sspClusters += count;
-	}
+    /**
+     * Fuses another <code>ClusterEvent</code> with this object. The
+     * other event's cluster pairs and states will be added to those
+     * already in this event.
+     * @param event - The event to fuse.
+     */
+    public void addEvent(ClusterEvent event) {
+        // If the event is null, do nothing.
+        if(event == null) { return; }
+        
+        // Add the values stored in the argument event to the counters
+        // in this event.
+        sspClusters   += event.sspClusters;
+        reconClusters += event.reconClusters;
+        matches       += event.matches;
+        failEnergy    += event.failEnergy;
+        failPosition  += event.failPosition;
+        failHitCount  += event.failHitCount;
+    }
+    
+    /**
+     * Indicates whether at least one cluster pair in the event created
+     * a fail state.
+     * @return Returns <code>true</code> if not all clusters matched and
+     * <code>false</code> otherwise.
+     */
+    public boolean isFailState() {
+        return (failEnergy > 0) || (failHitCount > 0) || (failTime > 0) || (failPosition > 0);
+    }
+    
+    /**
+     * Notes that a reconstructed cluster and SSP cluster pair failed
+     * due to energy.
+     */
+    public void pairFailEnergy() {
+        failEnergy++;
+    }
+    
+    /**
+     * Notes that a reconstructed cluster and SSP cluster pair failed
+     * due to hit count.
+     */
+    public void pairFailHitCount() {
+        failHitCount++;
+    }
+    
+    /**
+     * Notes that a reconstructed cluster and SSP cluster pair failed
+     * due to position.
+     */
+    public void pairFailPosition() {
+        failPosition++;
+    }
+    
+    /**
+     * Notes that one or more reconstructed cluster and SSP cluster pair
+     * failed due to position.
+     * @param count - The number of events that failed in this manner.
+     */
+    public void pairFailPosition(int count) {
+        // negative values are non-physical.
+        if(count < 0) {
+            throw new IllegalArgumentException("Cluster failure counts must be non-negative.");
+        }
+        
+        // Increment the count.
+        failPosition += count;
+    }
+    
+    /**
+     * Notes that a reconstructed cluster and SSP cluster pair failed
+     * due to time.
+     */
+    public void pairFailTime() {
+        failTime++;
+    }
+    
+    /**
+     * Notes that a reconstructed cluster and SSP cluster pair was
+     * successfully matched.
+     */
+    public void pairMatch() {
+        matches++;
+    }
+    
+    /**
+     * Increments the number of reconstructed FADC clusters seen.
+     * @param count - The number of clusters seen.
+     */
+    public void sawReconClusters(int count) {
+        reconClusters += count;
+    }
+    
+    /**
+     * Increments the number of SSP bank clusters seen.
+     * @param count - The number of clusters seen.
+     */
+    public void sawSSPClusters(int count) {
+        sspClusters += count;
+    }
 }

Modified: java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/data/ClusterMatchedPair.java
 =============================================================================
--- java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/data/ClusterMatchedPair.java	(original)
+++ java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/data/ClusterMatchedPair.java	Wed Apr 27 11:11:32 2016
@@ -14,114 +14,114 @@
  * @author Kyle McCarty <[log in to unmask]>
  */
 public class ClusterMatchedPair extends Pair<Cluster, SSPCluster> {
-	// CLass variables.
-	private final byte state;
-	
-	/**
-	 * Instantiates a new <code>ClusterMatchedPair</code> object from
-	 * the two indicated clusters and marks their match state.
-	 * @param reconCluster - The reconstructed cluster.
-	 * @param sspCluster - The SSP cluster.
-	 * @param state - The pair match state.
-	 */
-	public ClusterMatchedPair(Cluster reconCluster, SSPCluster sspCluster, byte state) {
-		// Set the cluster pairs.
-		super(reconCluster, sspCluster);
-		
-		// If the state is defined, set it. Otherwise, it is unknown.
-		if(state == TriggerDiagnosticUtil.CLUSTER_STATE_MATCHED
-				|| state == TriggerDiagnosticUtil.CLUSTER_STATE_FAIL_POSITION
-				|| state == TriggerDiagnosticUtil.CLUSTER_STATE_FAIL_ENERGY
-				|| state == TriggerDiagnosticUtil.CLUSTER_STATE_FAIL_HIT_COUNT) {
-			this.state = state;
-		} else {
-			this.state = TriggerDiagnosticUtil.CLUSTER_STATE_FAIL_UNKNOWN;
-		}
-	}
-	
-	/**
-	 * Gets the reconstructed cluster of the pair.
-	 * @return Returns the reconstructed cluster a <code>Cluster</cod>
-	 * object.
-	 */
-	public Cluster getReconstructedCluster() {
-		return getFirstElement();
-	}
-	
-	/**
-	 * Gets the SSP cluster of the pair.
-	 * @return Returns the SSP cluster as an <code>SSPCluster</code>
-	 * object.
-	 */
-	public SSPCluster getSSPCluster() {
-		return getSecondElement();
-	}
-	
-	/**
-	 * Gets the raw state identifier.
-	 * @return Returns the state identifier as a <code>byte</code>
-	 * primitive. Valid identifiers are defined in the class
-	 * <code>TriggerDiagnosticUtil</code>.
-	 */
-	public byte getState() {
-		return state;
-	}
-	
-	/**
-	 * Indicates whether the recon/SSP pair failed to not being close
-	 * enough in energy.
-	 * @return Returns <code>true</code> if the pair match state is an
-	 * energy fail state and <code>false</code> otherwise.
-	 */
-	public boolean isEnergyFailState() {
-		return (state == TriggerDiagnosticUtil.CLUSTER_STATE_FAIL_ENERGY);
-	}
-	
-	/**
-	 * Indicates whether the recon/SSP pair failed to match due to not
-	 * being close enough in hit count.
-	 * @return Returns <code>true</code> if the pair match state is a
-	 * hit count fail state and <code>false</code> otherwise.
-	 */
-	public boolean isHitCountFailState() {
-		return (state == TriggerDiagnosticUtil.CLUSTER_STATE_FAIL_HIT_COUNT);
-	}
-	
-	/**
-	 * Indicates whether the recon/SSP pair matched.
-	 * @return Returns <code>true</code> if the pair match state is a
-	 * match state and <code>false</code> otherwise.
-	 */
-	public boolean isMatch() {
-		return (state == TriggerDiagnosticUtil.CLUSTER_STATE_MATCHED);
-	}
-	
-	/**
-	 * Indicates whether the recon/SSP pair failed to match due to the
-	 * cluster positions not aligning.
-	 * @return Returns <code>true</code> if the pair match state is a
-	 * position fail state and <code>false</code> otherwise.
-	 */
-	public boolean isPositionFailState() {
-		return (state == TriggerDiagnosticUtil.CLUSTER_STATE_FAIL_POSITION);
-	}
-	
-	/**
-	 * Indicates whether the recon/SSP pair failed to match due to the
-	 * cluster time-stamps not aligning.
-	 * @return Returns <code>true</code> if the pair match state is a
-	 * time fail state and <code>false</code> otherwise.
-	 */
-	public boolean isTimeFailState() {
-		return (state == TriggerDiagnosticUtil.CLUSTER_STATE_FAIL_TIME);
-	}
-	
-	/**
-	 * Indicates whether the recon/SSP pair has no known match state.
-	 * @return Returns <code>true</code> if the pair match state is
-	 * unknown and <code>false</code> otherwise.
-	 */
-	public boolean isUnknownState() {
-		return (state == TriggerDiagnosticUtil.CLUSTER_STATE_FAIL_UNKNOWN);
-	}
+    // CLass variables.
+    private final byte state;
+    
+    /**
+     * Instantiates a new <code>ClusterMatchedPair</code> object from
+     * the two indicated clusters and marks their match state.
+     * @param reconCluster - The reconstructed cluster.
+     * @param sspCluster - The SSP cluster.
+     * @param state - The pair match state.
+     */
+    public ClusterMatchedPair(Cluster reconCluster, SSPCluster sspCluster, byte state) {
+        // Set the cluster pairs.
+        super(reconCluster, sspCluster);
+        
+        // If the state is defined, set it. Otherwise, it is unknown.
+        if(state == TriggerDiagnosticUtil.CLUSTER_STATE_MATCHED
+                || state == TriggerDiagnosticUtil.CLUSTER_STATE_FAIL_POSITION
+                || state == TriggerDiagnosticUtil.CLUSTER_STATE_FAIL_ENERGY
+                || state == TriggerDiagnosticUtil.CLUSTER_STATE_FAIL_HIT_COUNT) {
+            this.state = state;
+        } else {
+            this.state = TriggerDiagnosticUtil.CLUSTER_STATE_FAIL_UNKNOWN;
+        }
+    }
+    
+    /**
+     * Gets the reconstructed cluster of the pair.
+     * @return Returns the reconstructed cluster a <code>Cluster</cod>
+     * object.
+     */
+    public Cluster getReconstructedCluster() {
+        return getFirstElement();
+    }
+    
+    /**
+     * Gets the SSP cluster of the pair.
+     * @return Returns the SSP cluster as an <code>SSPCluster</code>
+     * object.
+     */
+    public SSPCluster getSSPCluster() {
+        return getSecondElement();
+    }
+    
+    /**
+     * Gets the raw state identifier.
+     * @return Returns the state identifier as a <code>byte</code>
+     * primitive. Valid identifiers are defined in the class
+     * <code>TriggerDiagnosticUtil</code>.
+     */
+    public byte getState() {
+        return state;
+    }
+    
+    /**
+     * Indicates whether the recon/SSP pair failed to not being close
+     * enough in energy.
+     * @return Returns <code>true</code> if the pair match state is an
+     * energy fail state and <code>false</code> otherwise.
+     */
+    public boolean isEnergyFailState() {
+        return (state == TriggerDiagnosticUtil.CLUSTER_STATE_FAIL_ENERGY);
+    }
+    
+    /**
+     * Indicates whether the recon/SSP pair failed to match due to not
+     * being close enough in hit count.
+     * @return Returns <code>true</code> if the pair match state is a
+     * hit count fail state and <code>false</code> otherwise.
+     */
+    public boolean isHitCountFailState() {
+        return (state == TriggerDiagnosticUtil.CLUSTER_STATE_FAIL_HIT_COUNT);
+    }
+    
+    /**
+     * Indicates whether the recon/SSP pair matched.
+     * @return Returns <code>true</code> if the pair match state is a
+     * match state and <code>false</code> otherwise.
+     */
+    public boolean isMatch() {
+        return (state == TriggerDiagnosticUtil.CLUSTER_STATE_MATCHED);
+    }
+    
+    /**
+     * Indicates whether the recon/SSP pair failed to match due to the
+     * cluster positions not aligning.
+     * @return Returns <code>true</code> if the pair match state is a
+     * position fail state and <code>false</code> otherwise.
+     */
+    public boolean isPositionFailState() {
+        return (state == TriggerDiagnosticUtil.CLUSTER_STATE_FAIL_POSITION);
+    }
+    
+    /**
+     * Indicates whether the recon/SSP pair failed to match due to the
+     * cluster time-stamps not aligning.
+     * @return Returns <code>true</code> if the pair match state is a
+     * time fail state and <code>false</code> otherwise.
+     */
+    public boolean isTimeFailState() {
+        return (state == TriggerDiagnosticUtil.CLUSTER_STATE_FAIL_TIME);
+    }
+    
+    /**
+     * Indicates whether the recon/SSP pair has no known match state.
+     * @return Returns <code>true</code> if the pair match state is
+     * unknown and <code>false</code> otherwise.
+     */
+    public boolean isUnknownState() {
+        return (state == TriggerDiagnosticUtil.CLUSTER_STATE_FAIL_UNKNOWN);
+    }
 }

Modified: java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/data/ClusterStatModule.java
 =============================================================================
--- java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/data/ClusterStatModule.java	(original)
+++ java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/data/ClusterStatModule.java	Wed Apr 27 11:11:32 2016
@@ -7,100 +7,100 @@
  * @author Kyle McCarty <[log in to unmask]>
  */
 public class ClusterStatModule {
-	// Track cluster statistics.
-	protected int sspClusters   = 0;
-	protected int reconClusters = 0;
-	protected int matches       = 0;
-	protected int failEnergy    = 0;
-	protected int failPosition  = 0;
-	protected int failHitCount  = 0;
-	protected int failTime      = 0;
-	
-	/**
-	 * Instantiates a <code>ClusterStatModule</code> with no statistics
-	 * stored.
-	 */
-	ClusterStatModule() {  }
-	
-	/**
-	 * Clears all statistical information and resets the object of its
-	 * default, empty state.
-	 */
-	void clear() {
-		sspClusters   = 0;
-		reconClusters = 0;
-		matches       = 0;
-		failEnergy    = 0;
-		failPosition  = 0;
-		failHitCount  = 0;
-		failTime      = 0;
-	}
-	
-	@Override
-	public ClusterStatModule clone() {
-		// Create a clone.
-		ClusterStatModule clone = new ClusterStatModule();
-		
-		// Copy the statistical values to the clone.
-		clone.sspClusters   = sspClusters;
-		clone.reconClusters = reconClusters;
-		clone.matches       = matches;
-		clone.failEnergy    = failEnergy;
-		clone.failPosition  = failPosition;
-		clone.failHitCount  = failHitCount;
-		clone.failTime      = failTime;
-		
-		// Return the clone.
-		return clone;
-	}
-	
-	/**
-	 * Gets the number of cluster pairs stored in this event that are
-	 * marked with energy fail states.
-	 * @return Returns the number of instances of this state as an
-	 * <code>int</code> primitive.
-	 */
-	public int getEnergyFailures() {
-		return failEnergy;
-	}
-	
-	/**
-	 * Gets the number of cluster pairs stored in this event that are
-	 * marked with hit count fail states.
-	 * @return Returns the number of instances of this state as an
-	 * <code>int</code> primitive.
-	 */
-	public int getHitCountFailures() {
-		return failHitCount;
-	}
-	
-	/**
-	 * Gets the number of cluster pairs stored in this event that are
-	 * marked with position fail states.
-	 * @return Returns the number of instances of this state as an
-	 * <code>int</code> primitive.
-	 */
-	public int getMatches() {
-		return matches;
-	}
-	
-	/**
-	 * Gets the number of cluster pairs stored in this event that are
-	 * marked with position fail states.
-	 * @return Returns the number of instances of this state as an
-	 * <code>int</code> primitive.
-	 */
-	public int getPositionFailures() {
-		return failPosition;
-	}
-	
-	/**
-	 * Gets the total number of verifiable reconstructed clusters seen.
+    // Track cluster statistics.
+    protected int sspClusters   = 0;
+    protected int reconClusters = 0;
+    protected int matches       = 0;
+    protected int failEnergy    = 0;
+    protected int failPosition  = 0;
+    protected int failHitCount  = 0;
+    protected int failTime      = 0;
+    
+    /**
+     * Instantiates a <code>ClusterStatModule</code> with no statistics
+     * stored.
+     */
+    ClusterStatModule() {  }
+    
+    /**
+     * Clears all statistical information and resets the object of its
+     * default, empty state.
+     */
+    void clear() {
+        sspClusters   = 0;
+        reconClusters = 0;
+        matches       = 0;
+        failEnergy    = 0;
+        failPosition  = 0;
+        failHitCount  = 0;
+        failTime      = 0;
+    }
+    
+    @Override
+    public ClusterStatModule clone() {
+        // Create a clone.
+        ClusterStatModule clone = new ClusterStatModule();
+        
+        // Copy the statistical values to the clone.
+        clone.sspClusters   = sspClusters;
+        clone.reconClusters = reconClusters;
+        clone.matches       = matches;
+        clone.failEnergy    = failEnergy;
+        clone.failPosition  = failPosition;
+        clone.failHitCount  = failHitCount;
+        clone.failTime      = failTime;
+        
+        // Return the clone.
+        return clone;
+    }
+    
+    /**
+     * Gets the number of cluster pairs stored in this event that are
+     * marked with energy fail states.
+     * @return Returns the number of instances of this state as an
+     * <code>int</code> primitive.
+     */
+    public int getEnergyFailures() {
+        return failEnergy;
+    }
+    
+    /**
+     * Gets the number of cluster pairs stored in this event that are
+     * marked with hit count fail states.
+     * @return Returns the number of instances of this state as an
+     * <code>int</code> primitive.
+     */
+    public int getHitCountFailures() {
+        return failHitCount;
+    }
+    
+    /**
+     * Gets the number of cluster pairs stored in this event that are
+     * marked with position fail states.
+     * @return Returns the number of instances of this state as an
+     * <code>int</code> primitive.
+     */
+    public int getMatches() {
+        return matches;
+    }
+    
+    /**
+     * Gets the number of cluster pairs stored in this event that are
+     * marked with position fail states.
+     * @return Returns the number of instances of this state as an
+     * <code>int</code> primitive.
+     */
+    public int getPositionFailures() {
+        return failPosition;
+    }
+    
+    /**
+     * Gets the total number of verifiable reconstructed clusters seen.
      * @return Returns the cluster count as an <code>int</code>
      * primitive.
-	 */
+     */
     public int getReconClusterCount() {
-    	return reconClusters;
+        return reconClusters;
     }
     
     /**
@@ -109,16 +109,16 @@
      * primitive.
      */
     public int getSSPClusterCount() {
-    	return sspClusters;
+        return sspClusters;
     }
-	
-	/**
-	 * Gets the number of cluster pairs stored in this event that are
-	 * marked with time fail states.
-	 * @return Returns the number of instances of this state as an
-	 * <code>int</code> primitive.
-	 */
-	public int getTimeFailures() {
-		return failTime;
-	}
+    
+    /**
+     * Gets the number of cluster pairs stored in this event that are
+     * marked with time fail states.
+     * @return Returns the number of instances of this state as an
+     * <code>int</code> primitive.
+     */
+    public int getTimeFailures() {
+        return failTime;
+    }
 }

Modified: java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/data/DetailedClusterEvent.java
 =============================================================================
--- java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/data/DetailedClusterEvent.java	(original)
+++ java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/data/DetailedClusterEvent.java	Wed Apr 27 11:11:32 2016
@@ -8,89 +8,89 @@
 import org.lcsim.event.Cluster;
 
 public class DetailedClusterEvent extends ClusterEvent {
-	// Store all of the pairs.
-	private List<ClusterMatchedPair> pairList = new ArrayList<ClusterMatchedPair>();
-	
-	/**
-	 * Fuses another <code>ClusterEvent</code> with this object. The
-	 * other event's cluster pairs and states will be added to those
-	 * already in this event.
-	 * @param event - The event to fuse.
-	 */
-	public void addEvent(ClusterEvent event) {
-		// Run the superclass method.
-		super.addEvent(event);
-		
-		// If the event is null, do nothing.
-		if(event == null) { return; }
-		
-		// Merge the list of cluster pairs, if applicable.
-		if(event instanceof DetailedClusterEvent) {
-			pairList.addAll(((DetailedClusterEvent) event).pairList);
-		}
-	}
-	
-	/**
-	 * Adds a reconstructed/SSP cluster pair and marks it as having an
-	 * energy fail state.
-	 * @param reconCluster - The reconstructed cluster.
-	 * @param sspCluster - The SSP cluster.
-	 */
-	public void pairFailEnergy(Cluster reconCluster, SSPCluster sspCluster) {
-		pairFailEnergy();
-		pairList.add(new ClusterMatchedPair(reconCluster, sspCluster, TriggerDiagnosticUtil.CLUSTER_STATE_FAIL_ENERGY));
-	}
-	
-	/**
-	 * Adds a reconstructed/SSP cluster pair and marks it as having a
-	 * hit count fail state.
-	 * @param reconCluster - The reconstructed cluster.
-	 * @param sspCluster - The SSP cluster.
-	 */
-	public void pairFailHitCount(Cluster reconCluster, SSPCluster sspCluster) {
-		pairFailHitCount();
-		pairList.add(new ClusterMatchedPair(reconCluster, sspCluster, TriggerDiagnosticUtil.CLUSTER_STATE_FAIL_HIT_COUNT));
-	}
-	
-	/**
-	 * Adds a reconstructed/SSP cluster pair and marks it as having a
-	 * position fail state.
-	 * @param reconCluster - The reconstructed cluster.
-	 * @param sspCluster - The SSP cluster.
-	 */
-	public void pairFailPosition(Cluster reconCluster, SSPCluster sspCluster) {
-		pairFailPosition();
-		pairList.add(new ClusterMatchedPair(reconCluster, sspCluster, TriggerDiagnosticUtil.CLUSTER_STATE_FAIL_POSITION));
-	}
-	
-	/**
-	 * Adds a reconstructed/SSP cluster pair and marks it as having a
-	 * time fail state.
-	 * @param reconCluster - The reconstructed cluster.
-	 * @param sspCluster - The SSP cluster.
-	 */
-	public void pairFailTime(Cluster reconCluster, SSPCluster sspCluster) {
-		pairFailTime();
-		pairList.add(new ClusterMatchedPair(reconCluster, sspCluster, TriggerDiagnosticUtil.CLUSTER_STATE_FAIL_TIME));
-	}
-	
-	/**
-	 * Adds a reconstructed/SSP cluster pair and marks it as having a
-	 * match state.
-	 * @param reconCluster - The reconstructed cluster.
-	 * @param sspCluster - The SSP cluster.
-	 */
-	public void pairMatch(Cluster reconCluster, SSPCluster sspCluster) {
-		pairMatch();
-		pairList.add(new ClusterMatchedPair(reconCluster, sspCluster, TriggerDiagnosticUtil.CLUSTER_STATE_MATCHED));
-	}
-	
-	/**
-	 * Gets a list of all matched cluster pairs and their match states.
-	 * @return Returns the matched cluster pairs as a <code>List</code>
-	 * of <code>ClusterMatchedPair</code> objects.
-	 */
-	public List<ClusterMatchedPair> getClusterPairs() {
-		return pairList;
-	}
+    // Store all of the pairs.
+    private List<ClusterMatchedPair> pairList = new ArrayList<ClusterMatchedPair>();
+    
+    /**
+     * Fuses another <code>ClusterEvent</code> with this object. The
+     * other event's cluster pairs and states will be added to those
+     * already in this event.
+     * @param event - The event to fuse.
+     */
+    public void addEvent(ClusterEvent event) {
+        // Run the superclass method.
+        super.addEvent(event);
+        
+        // If the event is null, do nothing.
+        if(event == null) { return; }
+        
+        // Merge the list of cluster pairs, if applicable.
+        if(event instanceof DetailedClusterEvent) {
+            pairList.addAll(((DetailedClusterEvent) event).pairList);
+        }
+    }
+    
+    /**
+     * Adds a reconstructed/SSP cluster pair and marks it as having an
+     * energy fail state.
+     * @param reconCluster - The reconstructed cluster.
+     * @param sspCluster - The SSP cluster.
+     */
+    public void pairFailEnergy(Cluster reconCluster, SSPCluster sspCluster) {
+        pairFailEnergy();
+        pairList.add(new ClusterMatchedPair(reconCluster, sspCluster, TriggerDiagnosticUtil.CLUSTER_STATE_FAIL_ENERGY));
+    }
+    
+    /**
+     * Adds a reconstructed/SSP cluster pair and marks it as having a
+     * hit count fail state.
+     * @param reconCluster - The reconstructed cluster.
+     * @param sspCluster - The SSP cluster.
+     */
+    public void pairFailHitCount(Cluster reconCluster, SSPCluster sspCluster) {
+        pairFailHitCount();
+        pairList.add(new ClusterMatchedPair(reconCluster, sspCluster, TriggerDiagnosticUtil.CLUSTER_STATE_FAIL_HIT_COUNT));
+    }
+    
+    /**
+     * Adds a reconstructed/SSP cluster pair and marks it as having a
+     * position fail state.
+     * @param reconCluster - The reconstructed cluster.
+     * @param sspCluster - The SSP cluster.
+     */
+    public void pairFailPosition(Cluster reconCluster, SSPCluster sspCluster) {
+        pairFailPosition();
+        pairList.add(new ClusterMatchedPair(reconCluster, sspCluster, TriggerDiagnosticUtil.CLUSTER_STATE_FAIL_POSITION));
+    }
+    
+    /**
+     * Adds a reconstructed/SSP cluster pair and marks it as having a
+     * time fail state.
+     * @param reconCluster - The reconstructed cluster.
+     * @param sspCluster - The SSP cluster.
+     */
+    public void pairFailTime(Cluster reconCluster, SSPCluster sspCluster) {
+        pairFailTime();
+        pairList.add(new ClusterMatchedPair(reconCluster, sspCluster, TriggerDiagnosticUtil.CLUSTER_STATE_FAIL_TIME));
+    }
+    
+    /**
+     * Adds a reconstructed/SSP cluster pair and marks it as having a
+     * match state.
+     * @param reconCluster - The reconstructed cluster.
+     * @param sspCluster - The SSP cluster.
+     */
+    public void pairMatch(Cluster reconCluster, SSPCluster sspCluster) {
+        pairMatch();
+        pairList.add(new ClusterMatchedPair(reconCluster, sspCluster, TriggerDiagnosticUtil.CLUSTER_STATE_MATCHED));
+    }
+    
+    /**
+     * Gets a list of all matched cluster pairs and their match states.
+     * @return Returns the matched cluster pairs as a <code>List</code>
+     * of <code>ClusterMatchedPair</code> objects.
+     */
+    public List<ClusterMatchedPair> getClusterPairs() {
+        return pairList;
+    }
 }

Modified: java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/data/DiagnosticSnapshot.java
 =============================================================================
--- java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/data/DiagnosticSnapshot.java	(original)
+++ java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/data/DiagnosticSnapshot.java	Wed Apr 27 11:11:32 2016
@@ -8,117 +8,117 @@
  * @author Kyle McCarty <[log in to unmask]>
  */
 public class DiagnosticSnapshot {
-	// Store the TI trigger information.
-	private int[] tiSeenAll = new int[6];
-	private int[] tiSeenHierarchical = new int[6];
-	
-	// Store the statistical modules.
-	private final GeneralStatModule generalStats;
-	private final ClusterStatModule clusterStats;
-	private final TriggerStatModule[] triggerStats = new TriggerStatModule[4];
-	
-	/**
-	 * Creates a snapshot of the trigger diagnostic results.
-	 * @param stats - The run statistical object.
-	 */
-	DiagnosticSnapshot(RunDiagStats stats) {
-		// Store the statistical modules.
-		generalStats = stats.clone();
-		clusterStats = stats.getClusterStats().clone();
-		triggerStats[0] = stats.getTriggerStats().getSingles0Stats().clone();
-		triggerStats[1] = stats.getTriggerStats().getSingles1Stats().clone();
-		triggerStats[2] = stats.getTriggerStats().getPair0Stats().clone();
-		triggerStats[3] = stats.getTriggerStats().getPair1Stats().clone();
-		
-		// Copy the TI trigger data.
-		for(int triggerType = 0; triggerType < 6; triggerType++) {
-			tiSeenAll[triggerType] = stats.getTriggerStats().getTITriggers(triggerType, false);
-			tiSeenHierarchical[triggerType] = stats.getTriggerStats().getTITriggers(triggerType, true);
-		}
-	}
-	
-	/**
-	 * Gets the general run statistics.
-	 * @return Returns a <code>GeneralStatModule</code> object that
-	 * contains the statistics.
-	 */
-	public GeneralStatModule getGeneralStats() {
-		return generalStats;
-	}
-	
-	/**
-	 * Gets the cluster statistics.
-	 * @return Returns a <code>ClusterStatModule</code> object that
-	 * contains the statistics.
-	 */
-	public ClusterStatModule getClusterStats() {
-		return clusterStats;
-	}
-	
-	/**
-	 * Gets the singles 0 trigger statistics.
-	 * @return Returns a <code>TriggerStatModule</code> object that
-	 * contains the statistics.
-	 */
-	public TriggerStatModule getSingles0Stats() {
-		return triggerStats[0];
-	}
-	
-	/**
-	 * Gets the singles 1 trigger statistics.
-	 * @return Returns a <code>TriggerStatModule</code> object that
-	 * contains the statistics.
-	 */
-	public TriggerStatModule getSingles1Stats() {
-		return triggerStats[1];
-	}
-	
-	/**
-	 * Gets the pair 0 trigger statistics.
-	 * @return Returns a <code>TriggerStatModule</code> object that
-	 * contains the statistics.
-	 */
-	public TriggerStatModule getPair0Stats() {
-		return triggerStats[2];
-	}
-	
-	/**
-	 * Gets the pair 1 trigger statistics.
-	 * @return Returns a <code>TriggerStatModule</code> object that
-	 * contains the statistics.
-	 */
-	public TriggerStatModule getPair1Stats() {
-		return triggerStats[3];
-	}
-	
-	/**
-	 * Gets the total number of events where the TI reported a trigger
-	 * of the specified type.
-	 * @param triggerID - The identifier for the type of trigger.
-	 * @param unique - <code>true</code> returns only the number of
-	 * events where this trigger type was the <i>only</i> type seen by
-	 * the TI while <code>false</code> returns the number of events
-	 * that saw this trigger type without regards for other trigger
-	 * flags.
-	 * @return Returns the count as an <code>int</code>.
-	 */
-	public int getTITriggers(int triggerID, boolean hierarchical) {
-		// Verify the trigger type.
-		validateTriggerType(triggerID);
-		
-		// Increment the counters.
-		if(hierarchical) { return tiSeenHierarchical[triggerID]; }
-		else { return tiSeenAll[triggerID]; }
-	}
-	
-	/**
-	 * Produces an exception if the argument trigger type is not of a
-	 * supported type.
-	 * @param triggerType - The trigger type to verify.
-	 */
-	private static final void validateTriggerType(int triggerType) {
-		if(triggerType < 0 || triggerType > 5) {
-			throw new IndexOutOfBoundsException(String.format("Trigger type \"%d\" is not supported.", triggerType));
-		}
-	}
+    // Store the TI trigger information.
+    private int[] tiSeenAll = new int[6];
+    private int[] tiSeenHierarchical = new int[6];
+    
+    // Store the statistical modules.
+    private final GeneralStatModule generalStats;
+    private final ClusterStatModule clusterStats;
+    private final TriggerStatModule[] triggerStats = new TriggerStatModule[4];
+    
+    /**
+     * Creates a snapshot of the trigger diagnostic results.
+     * @param stats - The run statistical object.
+     */
+    DiagnosticSnapshot(RunDiagStats stats) {
+        // Store the statistical modules.
+        generalStats = stats.clone();
+        clusterStats = stats.getClusterStats().clone();
+        triggerStats[0] = stats.getTriggerStats().getSingles0Stats().clone();
+        triggerStats[1] = stats.getTriggerStats().getSingles1Stats().clone();
+        triggerStats[2] = stats.getTriggerStats().getPair0Stats().clone();
+        triggerStats[3] = stats.getTriggerStats().getPair1Stats().clone();
+        
+        // Copy the TI trigger data.
+        for(int triggerType = 0; triggerType < 6; triggerType++) {
+            tiSeenAll[triggerType] = stats.getTriggerStats().getTITriggers(triggerType, false);
+            tiSeenHierarchical[triggerType] = stats.getTriggerStats().getTITriggers(triggerType, true);
+        }
+    }
+    
+    /**
+     * Gets the general run statistics.
+     * @return Returns a <code>GeneralStatModule</code> object that
+     * contains the statistics.
+     */
+    public GeneralStatModule getGeneralStats() {
+        return generalStats;
+    }
+    
+    /**
+     * Gets the cluster statistics.
+     * @return Returns a <code>ClusterStatModule</code> object that
+     * contains the statistics.
+     */
+    public ClusterStatModule getClusterStats() {
+        return clusterStats;
+    }
+    
+    /**
+     * Gets the singles 0 trigger statistics.
+     * @return Returns a <code>TriggerStatModule</code> object that
+     * contains the statistics.
+     */
+    public TriggerStatModule getSingles0Stats() {
+        return triggerStats[0];
+    }
+    
+    /**
+     * Gets the singles 1 trigger statistics.
+     * @return Returns a <code>TriggerStatModule</code> object that
+     * contains the statistics.
+     */
+    public TriggerStatModule getSingles1Stats() {
+        return triggerStats[1];
+    }
+    
+    /**
+     * Gets the pair 0 trigger statistics.
+     * @return Returns a <code>TriggerStatModule</code> object that
+     * contains the statistics.
+     */
+    public TriggerStatModule getPair0Stats() {
+        return triggerStats[2];
+    }
+    
+    /**
+     * Gets the pair 1 trigger statistics.
+     * @return Returns a <code>TriggerStatModule</code> object that
+     * contains the statistics.
+     */
+    public TriggerStatModule getPair1Stats() {
+        return triggerStats[3];
+    }
+    
+    /**
+     * Gets the total number of events where the TI reported a trigger
+     * of the specified type.
+     * @param triggerID - The identifier for the type of trigger.
+     * @param hierarchical - <code>true</code> returns only the number of
+     * events where this trigger type was the <i>only</i> type seen by
+     * the TI while <code>false</code> returns the number of events
+     * that saw this trigger type without regards for other trigger
+     * flags.
+     * @return Returns the count as an <code>int</code>.
+     */
+    public int getTITriggers(int triggerID, boolean hierarchical) {
+        // Verify the trigger type.
+        validateTriggerType(triggerID);
+        
+        // Increment the counters.
+        if(hierarchical) { return tiSeenHierarchical[triggerID]; }
+        else { return tiSeenAll[triggerID]; }
+    }
+    
+    /**
+     * Produces an exception if the argument trigger type is not of a
+     * supported type.
+     * @param triggerType - The trigger type to verify.
+     */
+    private static final void validateTriggerType(int triggerType) {
+        if(triggerType < 0 || triggerType > 5) {
+            throw new IndexOutOfBoundsException(String.format("Trigger type \"%d\" is not supported.", triggerType));
+        }
+    }
 }

Modified: java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/data/GeneralStatModule.java
 =============================================================================
--- java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/data/GeneralStatModule.java	(original)
+++ java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/data/GeneralStatModule.java	Wed Apr 27 11:11:32 2016
@@ -7,97 +7,97 @@
  * @author Kyle McCarty <[log in to unmask]>
  */
 public class GeneralStatModule {
-	// Store general run statistics.
-	protected long endTime = -1;
-	protected long startTime = -1;
-	protected int totalEvents = 0;
-	protected int noiseEvents = 0;
-	protected int failedPairEvents = 0;
-	protected int failedClusterEvents = 0;
-	protected int failedSinglesEvents = 0;
-	
-	/**
-	 * Clears all of the statistical counters in the object.
-	 */
-	void clear() {
-		endTime = -1;
-		startTime = -1;
-		totalEvents = 0;
-		noiseEvents = 0;
-		failedPairEvents = 0;
-		failedClusterEvents = 0;
-		failedSinglesEvents = 0;
-	}
-	
-	@Override
-	public GeneralStatModule clone() {
-		// Create the a cloned object.
-		GeneralStatModule clone = new GeneralStatModule();
-		
-		// Copy the tracked statistical data to the clone.
-		clone.endTime             = endTime;
-		clone.startTime           = startTime;
-		clone.totalEvents         = totalEvents;
-		clone.noiseEvents         = noiseEvents;
-		clone.failedPairEvents    = failedPairEvents;
-		clone.failedClusterEvents = failedClusterEvents;
-		clone.failedSinglesEvents = failedSinglesEvents;
-		
-		// Return the clone.
-		return clone;
-	}
-	
-	/**
-	 * Gets the length of time, in nanoseconds, over which the events
-	 * represented by this object occurred.
-	 * @return Returns the length of time as a <code>long</code>.
-	 */
-	public long getDuration() {
-		return endTime - startTime;
-	}
-	
-	/**
-	 * Gets the number of events seen.
-	 * @return Returns the number of events as an <code>int</code>.
-	 */
-	public int getEventCount() {
-		return totalEvents;
-	}
-	
-	/**
-	 * Gets the number of events in which at least one cluster was
-	 * not matched.
-	 * @return Returns the number of events as an <code>int</code>.
-	 */
-	public int getFailedClusterEventCount() {
-		return failedClusterEvents;
-	}
-	
-	/**
-	 * Gets the number of events in which at least one pair trigger
-	 * was not matched.
-	 * @return Returns the number of events as an <code>int</code>.
-	 */
-	public int getFailedPairEventCount() {
-		return failedPairEvents;
-	}
+    // Store general run statistics.
+    protected long endTime = -1;
+    protected long startTime = -1;
+    protected int totalEvents = 0;
+    protected int noiseEvents = 0;
+    protected int failedPairEvents = 0;
+    protected int failedClusterEvents = 0;
+    protected int failedSinglesEvents = 0;
+    
+    /**
+     * Clears all of the statistical counters in the object.
+     */
+    void clear() {
+        endTime = -1;
+        startTime = -1;
+        totalEvents = 0;
+        noiseEvents = 0;
+        failedPairEvents = 0;
+        failedClusterEvents = 0;
+        failedSinglesEvents = 0;
+    }
+    
+    @Override
+    public GeneralStatModule clone() {
+        // Create the a cloned object.
+        GeneralStatModule clone = new GeneralStatModule();
+        
+        // Copy the tracked statistical data to the clone.
+        clone.endTime             = endTime;
+        clone.startTime           = startTime;
+        clone.totalEvents         = totalEvents;
+        clone.noiseEvents         = noiseEvents;
+        clone.failedPairEvents    = failedPairEvents;
+        clone.failedClusterEvents = failedClusterEvents;
+        clone.failedSinglesEvents = failedSinglesEvents;
+        
+        // Return the clone.
+        return clone;
+    }
+    
+    /**
+     * Gets the length of time, in nanoseconds, over which the events
+     * represented by this object occurred.
+     * @return Returns the length of time as a <code>long</code>.
+     */
+    public long getDuration() {
+        return endTime - startTime;
+    }
+    
+    /**
+     * Gets the number of events seen.
+     * @return Returns the number of events as an <code>int</code>.
+     */
+    public int getEventCount() {
+        return totalEvents;
+    }
+    
+    /**
+     * Gets the number of events in which at least one cluster was
+     * not matched.
+     * @return Returns the number of events as an <code>int</code>.
+     */
+    public int getFailedClusterEventCount() {
+        return failedClusterEvents;
+    }
+    
+    /**
+     * Gets the number of events in which at least one pair trigger
+     * was not matched.
+     * @return Returns the number of events as an <code>int</code>.
+     */
+    public int getFailedPairEventCount() {
+        return failedPairEvents;
+    }
 
-	/**
-	 * Gets the number of events in which at least one singles trigger
-	 * was not matched.
-	 * @return Returns the number of events as an <code>int</code>.
-	 */
-	public int getFailedSinglesEventCount() {
-		return failedSinglesEvents;
-	}
-	
-	/**
-	 * Gets the number of events which were ignored due to having too
-	 * many hits in them.
-	 * @return Returns the number of events as an <code>int</code>.
-	 */
-	public int getNoiseEvents() {
-		return noiseEvents;
-	}
+    /**
+     * Gets the number of events in which at least one singles trigger
+     * was not matched.
+     * @return Returns the number of events as an <code>int</code>.
+     */
+    public int getFailedSinglesEventCount() {
+        return failedSinglesEvents;
+    }
+    
+    /**
+     * Gets the number of events which were ignored due to having too
+     * many hits in them.
+     * @return Returns the number of events as an <code>int</code>.
+     */
+    public int getNoiseEvents() {
+        return noiseEvents;
+    }
 
 }

Modified: java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/data/RunDiagStats.java
 =============================================================================
--- java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/data/RunDiagStats.java	(original)
+++ java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/data/RunDiagStats.java	Wed Apr 27 11:11:32 2016
@@ -9,89 +9,89 @@
  * @author Kyle McCarty <[log in to unmask]>
  */
 public class RunDiagStats extends GeneralStatModule {
-	// Store the statistics for trigger matching.
-	private TriggerDiagStats triggerStats = new TriggerDiagStats();
-	
-	// Store the statistics for cluster matching.
-	private ClusterEvent clusterStats = new ClusterEvent();
-	
-	/**
-	 * Clears all of the statistical counters in the object.
-	 */
-	public void clear() {
-		super.clear();
-		clusterStats.clear();
-		triggerStats.clear();
-	}
-	
-	/**
-	 * Notes that an event failed to match all clusters.
-	 */
-	public void failedClusterEvent() {
-		failedClusterEvents++;
-	}
-	
-	/**
-	 * Notes that an event failed to match all pair triggers.
-	 */
-	public void failedPairEvent() {
-		failedPairEvents++;
-	}
+    // Store the statistics for trigger matching.
+    private TriggerDiagStats triggerStats = new TriggerDiagStats();
+    
+    // Store the statistics for cluster matching.
+    private ClusterEvent clusterStats = new ClusterEvent();
+    
+    /**
+     * Clears all of the statistical counters in the object.
+     */
+    public void clear() {
+        super.clear();
+        clusterStats.clear();
+        triggerStats.clear();
+    }
+    
+    /**
+     * Notes that an event failed to match all clusters.
+     */
+    public void failedClusterEvent() {
+        failedClusterEvents++;
+    }
+    
+    /**
+     * Notes that an event failed to match all pair triggers.
+     */
+    public void failedPairEvent() {
+        failedPairEvents++;
+    }
 
-	/**
-	 * Notes that an event failed to match all singles triggers.
-	 */
-	public void failedSinglesEvent() {
-		failedSinglesEvents++;
-	}
-	
-	/**
-	 * Gets the cluster data.
-	 * @return Returns the <code>ClusterEvent</code> object that holds
-	 * the cluster data.
-	 */
-	public ClusterEvent getClusterStats() {
-		return clusterStats;
-	}
-	
-	/**
-	 * Gets a snapshot of the statistical data at the present time. The
-	 * snapshot will remain static and unchanged even if the generating
-	 * object itself is updated.
-	 * @return Returns a snapshot as a <code>DiagnosticSnapshot</code>
-	 * object.
-	 */
-	public DiagnosticSnapshot getSnapshot() {
-		return new DiagnosticSnapshot(this);
-	}
-	
-	/**
-	 * Gets the trigger data.
-	 * @return Returns the <code>TriggerDiagStats</code> object that holds
-	 * the cluster data.
-	 */
-	public TriggerDiagStats getTriggerStats() {
-		return triggerStats;
-	}
-	
-	/**
-	 * Notes that an event occurred.
-	 */
-	public void sawEvent(long eventTime) {
-		// Increment the event count.
-		totalEvents++;
-		
-		// If the start time is not defined, use this as the start time.
-		if(startTime == -1) { startTime = eventTime; }
-		
-		// The end time should always match the most recent event.
-		endTime = eventTime;
-	}
+    /**
+     * Notes that an event failed to match all singles triggers.
+     */
+    public void failedSinglesEvent() {
+        failedSinglesEvents++;
+    }
+    
+    /**
+     * Gets the cluster data.
+     * @return Returns the <code>ClusterEvent</code> object that holds
+     * the cluster data.
+     */
+    public ClusterEvent getClusterStats() {
+        return clusterStats;
+    }
+    
+    /**
+     * Gets a snapshot of the statistical data at the present time. The
+     * snapshot will remain static and unchanged even if the generating
+     * object itself is updated.
+     * @return Returns a snapshot as a <code>DiagnosticSnapshot</code>
+     * object.
+     */
+    public DiagnosticSnapshot getSnapshot() {
+        return new DiagnosticSnapshot(this);
+    }
+    
+    /**
+     * Gets the trigger data.
+     * @return Returns the <code>TriggerDiagStats</code> object that holds
+     * the cluster data.
+     */
+    public TriggerDiagStats getTriggerStats() {
+        return triggerStats;
+    }
+    
+    /**
+     * Notes that an event occurred.
+     */
+    public void sawEvent(long eventTime) {
+        // Increment the event count.
+        totalEvents++;
+        
+        // If the start time is not defined, use this as the start time.
+        if(startTime == -1) { startTime = eventTime; }
+        
+        // The end time should always match the most recent event.
+        endTime = eventTime;
+    }
 
-	/**
-	 * Notes that an event was labeled as noise.
-	 */
-	public void sawNoiseEvent() {
-		noiseEvents++;
-	}
+    /**
+     * Notes that an event was labeled as noise.
+     */
+    public void sawNoiseEvent() {
+        noiseEvents++;
+    }
 }

Modified: java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/data/TriggerDiagStats.java
 =============================================================================
--- java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/data/TriggerDiagStats.java	(original)
+++ java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/data/TriggerDiagStats.java	Wed Apr 27 11:11:32 2016
@@ -4,304 +4,304 @@
 import org.hps.analysis.trigger.util.TriggerDiagnosticUtil;
 
 public class TriggerDiagStats {
-	// Define TI trigger type identifiers.
-	public static final int SINGLES0 = TriggerStatModule.SINGLES_0;
-	public static final int SINGLES1 = TriggerStatModule.SINGLES_1;
-	public static final int PAIR0    = TriggerStatModule.PAIR_0;
-	public static final int PAIR1    = TriggerStatModule.PAIR_1;
-	public static final int PULSER   = TriggerStatModule.PULSER;
-	public static final int COSMIC   = TriggerStatModule.COSMIC;
-	
-	// Tracks the number of TI triggers seen across all events for only
-	// the TI trigger with the highest priority in the event.
-	private int[] tiSeenHierarchical = new int[6];
-	
-	// Tracks the number of TI triggers across all events.
-	private int[] tiSeenAll = new int[6];
-	
-	// Store the statistics modules for each of the regular triggers.
-	private TriggerEvent[] triggerStats = new TriggerEvent[4];
-	
-	/**
-	 * Instantiates a new <code>TriggerDiagStats</code> object.
-	 */
-	public TriggerDiagStats() {
-		// Instantiate a trigger statistics module for each of the
-		// triggers for which statistics are supported.
-		for(int triggerType = 0; triggerType < 4; triggerType++) {
-			triggerStats[triggerType] = new TriggerEvent();
-		}
-	}
-	
-	/**
-	 * Clears all of the statistical counters in the object.
-	 */
-	void clear() {
-		// Clear the tracked TI trigger data.
-		for(int tiType = 0; tiType < 6; tiType++) {
-			tiSeenAll[tiType] = 0;
-			tiSeenHierarchical[tiType] = 0;
-		}
-		
-		// Clear the trigger statistical modules.
-		for(int triggerType = 0; triggerType < 4; triggerType++) {
-			triggerStats[triggerType].clear();
-		}
-	}
-	
-	/**
-	 * Gets the trigger data for the pair 0 trigger.
-	 * @return Returns the <code>TriggerEvent</code> object that holds
-	 * the trigger data for the pair 0 trigger.
-	 */
-	public TriggerEvent getPair0Stats() {
-		return triggerStats[PAIR0];
-	}
-	
-	/**
-	 * Gets the trigger data for the pair 1 trigger.
-	 * @return Returns the <code>TriggerEvent</code> object that holds
-	 * the trigger data for the pair 1 trigger.
-	 */
-	public TriggerEvent getPair1Stats() {
-		return triggerStats[PAIR1];
-	}
-	
-	/**
-	 * Gets the trigger data for the singles 0 trigger.
-	 * @return Returns the <code>TriggerEvent</code> object that holds
-	 * the trigger data for the singles 0 trigger.
-	 */
-	public TriggerEvent getSingles0Stats() {
-		return triggerStats[SINGLES0];
-	}
-	
-	/**
-	 * Gets the trigger data for the singles 1 trigger.
-	 * @return Returns the <code>TriggerEvent</code> object that holds
-	 * the trigger data for the singles 1 trigger.
-	 */
-	public TriggerEvent getSingles1Stats() {
-		return triggerStats[SINGLES1];
-	}
-	
-	/**
-	 * Gets the total number of events where the TI reported a trigger
-	 * of the specified type.
-	 * @param triggerID - The identifier for the type of trigger.
-	 * @param unique - <code>true</code> returns only the number of
-	 * events where this trigger type was the <i>only</i> type seen by
-	 * the TI while <code>false</code> returns the number of events
-	 * that saw this trigger type without regards for other trigger
-	 * flags.
-	 * @return Returns the count as an <code>int</code>.
-	 */
-	public int getTITriggers(int triggerID, boolean hierarchical) {
-		// Verify the trigger type.
-		validateTriggerType(triggerID);
-		
-		// Increment the counters.
-		if(hierarchical) { return tiSeenHierarchical[triggerID]; }
-		else { return tiSeenAll[triggerID]; }
-	}
-	
-	/**
-	 * Increments the counts tracking the number of TI flags seen.
-	 * @param flags - An array of <code>boolean</code> values of size
-	 * six. This represents one flag for each possible TI trigger type.
-	 */
-	public void sawTITriggers(boolean[] flags) {
-		// There must be six trigger flags and the array must not be
-		// null.
-		if(flags == null) {
-			throw new NullPointerException("TI trigger flags can not be null.");
-		} if(flags.length != 6) {
-			throw new IllegalArgumentException("TI trigger flags must be of size six.");
-		}
-		
-		// Check each TI flag in the order of the flag hierarchy. The
-		// first flag in the hierarchy that is true is recorded in the
-		// hierarchical count. All flags are recorded in the all count.
-		boolean foundHierarchical = false;
-		if(flags[PAIR1]) {
-			tiSeenAll[PAIR1]++;
-			if(!foundHierarchical) {
-				tiSeenHierarchical[PAIR1]++;
-				foundHierarchical = true;
-			}
-		} if(flags[PAIR0]) {
-			tiSeenAll[PAIR0]++;
-			if(!foundHierarchical) {
-				tiSeenHierarchical[PAIR0]++;
-				foundHierarchical = true;
-			}
-		} if(flags[SINGLES1]) {
-			tiSeenAll[SINGLES1]++;
-			if(!foundHierarchical) {
-				tiSeenHierarchical[SINGLES1]++;
-				foundHierarchical = true;
-			}
-		} if(flags[SINGLES0]) {
-			tiSeenAll[SINGLES0]++;
-			if(!foundHierarchical) {
-				tiSeenHierarchical[SINGLES0]++;
-				foundHierarchical = true;
-			}
-		} if(flags[PULSER]) {
-			tiSeenAll[PULSER]++;
-			if(!foundHierarchical) {
-				tiSeenHierarchical[PULSER]++;
-				foundHierarchical = true;
-			}
-		} if(flags[COSMIC]) {
-			tiSeenAll[COSMIC]++;
-			if(!foundHierarchical) {
-				tiSeenHierarchical[COSMIC]++;
-				foundHierarchical = true;
-			}
-		}
-	}
-	
-	/**
-	 * Prints the trigger statistics to the terminal as a table.
-	 */
-	public void printEfficiencyTable() {
-		// Get the trigger statistics tables.
-		int[][] seenStats = new int[6][4];
-		int[][] matchedStats = new int[6][4];
-		TriggerEvent[] triggerEvents = { getSingles0Stats(), getSingles1Stats(), getPair0Stats(), getPair1Stats() };
-		for(int i = 0; i < 4; i++) {
-			for(int j = 0; j < 6; j++) {
-				seenStats[j][i] = triggerEvents[i].getReconSimulatedTriggers(j);
-				matchedStats[j][i] = triggerEvents[i].getMatchedReconSimulatedTriggers(j);
-			}
-		}
-		
-		// Define constant spacing variables.
-		int columnSpacing = 3;
-		
-		// Define table headers.
-		String sourceName = "Source";
-		String seenName = "Trigger Efficiency";
-		
-		// Get the longest column header name.
-		int longestHeader = -1;
-		String[] headerNames = {
-				TriggerDiagnosticUtil.TRIGGER_NAME[0],
-				TriggerDiagnosticUtil.TRIGGER_NAME[1],
-				TriggerDiagnosticUtil.TRIGGER_NAME[2],
-				TriggerDiagnosticUtil.TRIGGER_NAME[3],
-				"TI Highest Type"
-		};
-		for(String triggerName : headerNames) {
-			longestHeader = ComponentUtils.max(longestHeader, triggerName.length());
-		}
-		longestHeader = ComponentUtils.max(longestHeader, sourceName.length());
-		
-		// Determine the spacing needed to display the largest numerical
-		// cell value.
-		int numWidth = -1;
-		int longestCell = -1;
-		for(int eventTriggerID = 0; eventTriggerID < 6; eventTriggerID++) {
-			for(int seenTriggerID = 0; seenTriggerID < 4; seenTriggerID++) {
-				int valueSize = ComponentUtils.getDigits(seenStats[eventTriggerID][seenTriggerID]);
-				int cellSize = valueSize * 2 + 13;
-				if(cellSize > longestCell) {
-					longestCell = cellSize;
-					numWidth = valueSize;
-				}
-			}
-		}
-		
-		// The total column width can then be calculated from the
-		// longer of the header and cell values.
-		int columnWidth = ComponentUtils.max(longestCell, longestHeader);
-		int sourceWidth = ComponentUtils.max(
-				TriggerDiagnosticUtil.TRIGGER_NAME[0].length(), TriggerDiagnosticUtil.TRIGGER_NAME[1].length(),
-				TriggerDiagnosticUtil.TRIGGER_NAME[2].length(), TriggerDiagnosticUtil.TRIGGER_NAME[3].length(),
-				TriggerDiagnosticUtil.TRIGGER_NAME[4].length(), TriggerDiagnosticUtil.TRIGGER_NAME[5].length(),
-				sourceName.length() );
-		
-		// Calculate the total width of the table value header columns.
-		int headerTotalWidth = (headerNames.length * columnWidth)
-				+ ((headerNames.length - 1) * columnSpacing);
-		
-		// Write the table header.
-		String spacingText = ComponentUtils.getChars(' ', columnSpacing);
-		System.out.println(ComponentUtils.getChars(' ', sourceWidth) + spacingText
-				+ getCenteredString(seenName, headerTotalWidth));
-		
-		// Create the format strings for the cell values.
-		String headerFormat = "%-" + sourceWidth + "s" + spacingText;
-		String cellFormat = "%" + numWidth + "d / %" + numWidth + "d (%7.3f)";
-		String nullText = getCenteredString(ComponentUtils.getChars('-', numWidth) + " / "
-				+ ComponentUtils.getChars('-', numWidth) + " (  N/A  )", columnWidth) + spacingText;
-		
-		// Print the column headers.
-		System.out.printf(headerFormat, sourceName);
-		for(String header : headerNames) {
-			System.out.print(getCenteredString(header, columnWidth) + spacingText);
-		}
-		System.out.println();
-		
-		// Write out the value columns.
-		for(int eventTriggerID = 0; eventTriggerID < 6; eventTriggerID++) {
-			// Print out the row header.
-			System.out.printf(headerFormat, TriggerDiagnosticUtil.TRIGGER_NAME[eventTriggerID]);
-			
-			// Print the cell values.
-			for(int seenTriggerID = 0; seenTriggerID < 4; seenTriggerID++) {
-				if(seenTriggerID == eventTriggerID) { System.out.print(nullText); }
-				else {
-					String cellText = String.format(cellFormat, matchedStats[eventTriggerID][seenTriggerID],
-							seenStats[eventTriggerID][seenTriggerID],
-							(100.0 * matchedStats[eventTriggerID][seenTriggerID] / seenStats[eventTriggerID][seenTriggerID]));
-					System.out.print(getCenteredString(cellText, columnWidth) + spacingText);
-				}
-			}
-			
-			// Output the number of events that had only the trigger
-			// type ID for the current trigger type flagged by the TI.
-			System.out.print(getCenteredString("" + getTITriggers(eventTriggerID, true), columnWidth) + spacingText);
-			
-			// Start a new line.
-			System.out.println();
-		}
-	}
-	
-	/**
-	 * Produces a <code>String</code> of the indicated length with the
-	 * text <code>value</code> centered in the middle. Extra length is
-	 * filled through spaces before and after the text.
-	 * @param value - The text to display.
-	 * @param width - The number of spaces to include.
-	 * @return Returns a <code>String</code> of the specified length,
-	 * or the argument text if it is longer.
-	 */
-	private static final String getCenteredString(String value, int width) {
-		// The method can not perform as intended if the argument text
-		// exceeds the requested string length. Just return the text.
-		if(width <= value.length()) {
-			return value;
-		}
-		
-		// Otherwise, get the amount of buffering needed to center the
-		// text and add it around the text to produce the string.
-		else {
-			int buffer = (width - value.length()) / 2;
-			return ComponentUtils.getChars(' ', buffer) + value
-					+ ComponentUtils.getChars(' ', width - buffer - value.length());
-		}
-	}
-	
-	/**
-	 * Produces an exception if the argument trigger type is not of a
-	 * supported type.
-	 * @param triggerType - The trigger type to verify.
-	 */
-	private static final void validateTriggerType(int triggerType) {
-		if(triggerType < 0 || triggerType > 5) {
-			throw new IndexOutOfBoundsException(String.format("Trigger type \"%d\" is not supported.", triggerType));
-		}
-	}
+    // Define TI trigger type identifiers.
+    public static final int SINGLES0 = TriggerStatModule.SINGLES_0;
+    public static final int SINGLES1 = TriggerStatModule.SINGLES_1;
+    public static final int PAIR0    = TriggerStatModule.PAIR_0;
+    public static final int PAIR1    = TriggerStatModule.PAIR_1;
+    public static final int PULSER   = TriggerStatModule.PULSER;
+    public static final int COSMIC   = TriggerStatModule.COSMIC;
+    
+    // Tracks the number of TI triggers seen across all events for only
+    // the TI trigger with the highest priority in the event.
+    private int[] tiSeenHierarchical = new int[6];
+    
+    // Tracks the number of TI triggers across all events.
+    private int[] tiSeenAll = new int[6];
+    
+    // Store the statistics modules for each of the regular triggers.
+    private TriggerEvent[] triggerStats = new TriggerEvent[4];
+    
+    /**
+     * Instantiates a new <code>TriggerDiagStats</code> object.
+     */
+    public TriggerDiagStats() {
+        // Instantiate a trigger statistics module for each of the
+        // triggers for which statistics are supported.
+        for(int triggerType = 0; triggerType < 4; triggerType++) {
+            triggerStats[triggerType] = new TriggerEvent();
+        }
+    }
+    
+    /**
+     * Clears all of the statistical counters in the object.
+     */
+    void clear() {
+        // Clear the tracked TI trigger data.
+        for(int tiType = 0; tiType < 6; tiType++) {
+            tiSeenAll[tiType] = 0;
+            tiSeenHierarchical[tiType] = 0;
+        }
+        
+        // Clear the trigger statistical modules.
+        for(int triggerType = 0; triggerType < 4; triggerType++) {
+            triggerStats[triggerType].clear();
+        }
+    }
+    
+    /**
+     * Gets the trigger data for the pair 0 trigger.
+     * @return Returns the <code>TriggerEvent</code> object that holds
+     * the trigger data for the pair 0 trigger.
+     */
+    public TriggerEvent getPair0Stats() {
+        return triggerStats[PAIR0];
+    }
+    
+    /**
+     * Gets the trigger data for the pair 1 trigger.
+     * @return Returns the <code>TriggerEvent</code> object that holds
+     * the trigger data for the pair 1 trigger.
+     */
+    public TriggerEvent getPair1Stats() {
+        return triggerStats[PAIR1];
+    }
+    
+    /**
+     * Gets the trigger data for the singles 0 trigger.
+     * @return Returns the <code>TriggerEvent</code> object that holds
+     * the trigger data for the singles 0 trigger.
+     */
+    public TriggerEvent getSingles0Stats() {
+        return triggerStats[SINGLES0];
+    }
+    
+    /**
+     * Gets the trigger data for the singles 1 trigger.
+     * @return Returns the <code>TriggerEvent</code> object that holds
+     * the trigger data for the singles 1 trigger.
+     */
+    public TriggerEvent getSingles1Stats() {
+        return triggerStats[SINGLES1];
+    }
+    
+    /**
+     * Gets the total number of events where the TI reported a trigger
+     * of the specified type.
+     * @param triggerID - The identifier for the type of trigger.
+     * @param hierarchical - <code>true</code> returns only the number of
+     * events where this trigger type was the <i>only</i> type seen by
+     * the TI while <code>false</code> returns the number of events
+     * that saw this trigger type without regards for other trigger
+     * flags.
+     * @return Returns the count as an <code>int</code>.
+     */
+    public int getTITriggers(int triggerID, boolean hierarchical) {
+        // Verify the trigger type.
+        validateTriggerType(triggerID);
+        
+        // Increment the counters.
+        if(hierarchical) { return tiSeenHierarchical[triggerID]; }
+        else { return tiSeenAll[triggerID]; }
+    }
+    
+    /**
+     * Increments the counts tracking the number of TI flags seen.
+     * @param flags - An array of <code>boolean</code> values of size
+     * six. This represents one flag for each possible TI trigger type.
+     */
+    public void sawTITriggers(boolean[] flags) {
+        // There must be six trigger flags and the array must not be
+        // null.
+        if(flags == null) {
+            throw new NullPointerException("TI trigger flags can not be null.");
+        } if(flags.length != 6) {
+            throw new IllegalArgumentException("TI trigger flags must be of size six.");
+        }
+        
+        // Check each TI flag in the order of the flag hierarchy. The
+        // first flag in the hierarchy that is true is recorded in the
+        // hierarchical count. All flags are recorded in the all count.
+        boolean foundHierarchical = false;
+        if(flags[PAIR1]) {
+            tiSeenAll[PAIR1]++;
+            if(!foundHierarchical) {
+                tiSeenHierarchical[PAIR1]++;
+                foundHierarchical = true;
+            }
+        } if(flags[PAIR0]) {
+            tiSeenAll[PAIR0]++;
+            if(!foundHierarchical) {
+                tiSeenHierarchical[PAIR0]++;
+                foundHierarchical = true;
+            }
+        } if(flags[SINGLES1]) {
+            tiSeenAll[SINGLES1]++;
+            if(!foundHierarchical) {
+                tiSeenHierarchical[SINGLES1]++;
+                foundHierarchical = true;
+            }
+        } if(flags[SINGLES0]) {
+            tiSeenAll[SINGLES0]++;
+            if(!foundHierarchical) {
+                tiSeenHierarchical[SINGLES0]++;
+                foundHierarchical = true;
+            }
+        } if(flags[PULSER]) {
+            tiSeenAll[PULSER]++;
+            if(!foundHierarchical) {
+                tiSeenHierarchical[PULSER]++;
+                foundHierarchical = true;
+            }
+        } if(flags[COSMIC]) {
+            tiSeenAll[COSMIC]++;
+            if(!foundHierarchical) {
+                tiSeenHierarchical[COSMIC]++;
+                foundHierarchical = true;
+            }
+        }
+    }
+    
+    /**
+     * Prints the trigger statistics to the terminal as a table.
+     */
+    public void printEfficiencyTable() {
+        // Get the trigger statistics tables.
+        int[][] seenStats = new int[6][4];
+        int[][] matchedStats = new int[6][4];
+        TriggerEvent[] triggerEvents = { getSingles0Stats(), getSingles1Stats(), getPair0Stats(), getPair1Stats() };
+        for(int i = 0; i < 4; i++) {
+            for(int j = 0; j < 6; j++) {
+                seenStats[j][i] = triggerEvents[i].getReconSimulatedTriggers(j);
+                matchedStats[j][i] = triggerEvents[i].getMatchedReconSimulatedTriggers(j);
+            }
+        }
+        
+        // Define constant spacing variables.
+        int columnSpacing = 3;
+        
+        // Define table headers.
+        String sourceName = "Source";
+        String seenName = "Trigger Efficiency";
+        
+        // Get the longest column header name.
+        int longestHeader = -1;
+        String[] headerNames = {
+                TriggerDiagnosticUtil.TRIGGER_NAME[0],
+                TriggerDiagnosticUtil.TRIGGER_NAME[1],
+                TriggerDiagnosticUtil.TRIGGER_NAME[2],
+                TriggerDiagnosticUtil.TRIGGER_NAME[3],
+                "TI Highest Type"
+        };
+        for(String triggerName : headerNames) {
+            longestHeader = ComponentUtils.max(longestHeader, triggerName.length());
+        }
+        longestHeader = ComponentUtils.max(longestHeader, sourceName.length());
+        
+        // Determine the spacing needed to display the largest numerical
+        // cell value.
+        int numWidth = -1;
+        int longestCell = -1;
+        for(int eventTriggerID = 0; eventTriggerID < 6; eventTriggerID++) {
+            for(int seenTriggerID = 0; seenTriggerID < 4; seenTriggerID++) {
+                int valueSize = ComponentUtils.getDigits(seenStats[eventTriggerID][seenTriggerID]);
+                int cellSize = valueSize * 2 + 13;
+                if(cellSize > longestCell) {
+                    longestCell = cellSize;
+                    numWidth = valueSize;
+                }
+            }
+        }
+        
+        // The total column width can then be calculated from the
+        // longer of the header and cell values.
+        int columnWidth = ComponentUtils.max(longestCell, longestHeader);
+        int sourceWidth = ComponentUtils.max(
+                TriggerDiagnosticUtil.TRIGGER_NAME[0].length(), TriggerDiagnosticUtil.TRIGGER_NAME[1].length(),
+                TriggerDiagnosticUtil.TRIGGER_NAME[2].length(), TriggerDiagnosticUtil.TRIGGER_NAME[3].length(),
+                TriggerDiagnosticUtil.TRIGGER_NAME[4].length(), TriggerDiagnosticUtil.TRIGGER_NAME[5].length(),
+                sourceName.length() );
+        
+        // Calculate the total width of the table value header columns.
+        int headerTotalWidth = (headerNames.length * columnWidth)
+                + ((headerNames.length - 1) * columnSpacing);
+        
+        // Write the table header.
+        String spacingText = ComponentUtils.getChars(' ', columnSpacing);
+        System.out.println(ComponentUtils.getChars(' ', sourceWidth) + spacingText
+                + getCenteredString(seenName, headerTotalWidth));
+        
+        // Create the format strings for the cell values.
+        String headerFormat = "%-" + sourceWidth + "s" + spacingText;
+        String cellFormat = "%" + numWidth + "d / %" + numWidth + "d (%7.3f)";
+        String nullText = getCenteredString(ComponentUtils.getChars('-', numWidth) + " / "
+                + ComponentUtils.getChars('-', numWidth) + " (  N/A  )", columnWidth) + spacingText;
+        
+        // Print the column headers.
+        System.out.printf(headerFormat, sourceName);
+        for(String header : headerNames) {
+            System.out.print(getCenteredString(header, columnWidth) + spacingText);
+        }
+        System.out.println();
+        
+        // Write out the value columns.
+        for(int eventTriggerID = 0; eventTriggerID < 6; eventTriggerID++) {
+            // Print out the row header.
+            System.out.printf(headerFormat, TriggerDiagnosticUtil.TRIGGER_NAME[eventTriggerID]);
+            
+            // Print the cell values.
+            for(int seenTriggerID = 0; seenTriggerID < 4; seenTriggerID++) {
+                if(seenTriggerID == eventTriggerID) { System.out.print(nullText); }
+                else {
+                    String cellText = String.format(cellFormat, matchedStats[eventTriggerID][seenTriggerID],
+                            seenStats[eventTriggerID][seenTriggerID],
+                            (100.0 * matchedStats[eventTriggerID][seenTriggerID] / seenStats[eventTriggerID][seenTriggerID]));
+                    System.out.print(getCenteredString(cellText, columnWidth) + spacingText);
+                }
+            }
+            
+            // Output the number of events that had only the trigger
+            // type ID for the current trigger type flagged by the TI.
+            System.out.print(getCenteredString("" + getTITriggers(eventTriggerID, true), columnWidth) + spacingText);
+            
+            // Start a new line.
+            System.out.println();
+        }
+    }
+    
+    /**
+     * Produces a <code>String</code> of the indicated length with the
+     * text <code>value</code> centered in the middle. Extra length is
+     * filled through spaces before and after the text.
+     * @param value - The text to display.
+     * @param width - The number of spaces to include.
+     * @return Returns a <code>String</code> of the specified length,
+     * or the argument text if it is longer.
+     */
+    private static final String getCenteredString(String value, int width) {
+        // The method can not perform as intended if the argument text
+        // exceeds the requested string length. Just return the text.
+        if(width <= value.length()) {
+            return value;
+        }
+        
+        // Otherwise, get the amount of buffering needed to center the
+        // text and add it around the text to produce the string.
+        else {
+            int buffer = (width - value.length()) / 2;
+            return ComponentUtils.getChars(' ', buffer) + value
+                    + ComponentUtils.getChars(' ', width - buffer - value.length());
+        }
+    }
+    
+    /**
+     * Produces an exception if the argument trigger type is not of a
+     * supported type.
+     * @param triggerType - The trigger type to verify.
+     */
+    private static final void validateTriggerType(int triggerType) {
+        if(triggerType < 0 || triggerType > 5) {
+            throw new IndexOutOfBoundsException(String.format("Trigger type \"%d\" is not supported.", triggerType));
+        }
+    }
 }

Modified: java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/data/TriggerEvent.java
 =============================================================================
--- java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/data/TriggerEvent.java	(original)
+++ java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/data/TriggerEvent.java	Wed Apr 27 11:11:32 2016
@@ -9,263 +9,255 @@
  * @author Kyle McCarty <[log in to unmask]>
  */
 public class TriggerEvent extends TriggerStatModule {
-	/**
-	 * Adds the statistics from one event object into this one.
-	 * @param event - The event data to add.
-	 */
-	public void addEvent(TriggerStatModule event) {
-		// Merge the values that do not depend on trigger source type.
-		reportedTriggers += event.reportedTriggers;
-		
-		// Merge each value that depends on the trigger source type.
-		for(int sourceType = 0; sourceType < 2; sourceType++) {
-			simTriggers[sourceType] += event.simTriggers[sourceType];
-			matchedTriggers[sourceType] += event.matchedTriggers[sourceType];
-			unmatchedTriggers[sourceType] += event.unmatchedTriggers[sourceType];
-			
-			// Merge the number of times each cut failed.
-			for(int cutID = 0; cutID < 4; cutID++) {
-				failedCuts[sourceType][cutID] += event.failedCuts[sourceType][cutID];
-			}
-			
-			// Copy the values for the TI flag trigger counters.
-			for(int tiType = 0; tiType < 6; tiType++) {
-				tiTriggersSeen[sourceType][tiType] += event.tiTriggersSeen[sourceType][tiType];
-				tiTriggersMatched[sourceType][tiType] += event.tiTriggersMatched[sourceType][tiType];
-			}
-		}
-	}
-	
-	/**
-	 * Indicates that a reconstructed trigger could not be matched, even
-	 * partially, to an SSP bank trigger.
-	 */
-	public void failedReconTrigger() {
-		unmatchedTriggers[RECON]++;
-	}
-	
-	/**
-	 * Indicates that an SSP simulated trigger could not be matched, even
-	 * partially, to an SSP bank trigger.
-	 */
-	public void failedSSPTrigger() {
-		unmatchedTriggers[SSP]++;
-	}
+    /**
+     * Adds the statistics from one event object into this one.
+     * @param event - The event data to add.
+     */
+    public void addEvent(TriggerStatModule event) {
+        // Merge the values that do not depend on trigger source type.
+        reportedTriggers += event.reportedTriggers;
+        
+        // Merge each value that depends on the trigger source type.
+        for(int sourceType = 0; sourceType < 2; sourceType++) {
+            simTriggers[sourceType] += event.simTriggers[sourceType];
+            matchedTriggers[sourceType] += event.matchedTriggers[sourceType];
+            unmatchedTriggers[sourceType] += event.unmatchedTriggers[sourceType];
+            
+            // Merge the number of times each cut failed.
+            for(int cutID = 0; cutID < 4; cutID++) {
+                failedCuts[sourceType][cutID] += event.failedCuts[sourceType][cutID];
+            }
+            
+            // Copy the values for the TI flag trigger counters.
+            for(int tiType = 0; tiType < 6; tiType++) {
+                tiTriggersSeen[sourceType][tiType] += event.tiTriggersSeen[sourceType][tiType];
+                tiTriggersMatched[sourceType][tiType] += event.tiTriggersMatched[sourceType][tiType];
+            }
+        }
+    }
+    
+    /**
+     * Indicates that a reconstructed trigger could not be matched, even
+     * partially, to an SSP bank trigger.
+     */
+    public void failedReconTrigger() {
+        unmatchedTriggers[RECON]++;
+    }
+    
+    /**
+     * Indicates that an SSP simulated trigger could not be matched, even
+     * partially, to an SSP bank trigger.
+     */
+    public void failedSSPTrigger() {
+        unmatchedTriggers[SSP]++;
+    }
 
-	/**
-	 * Indicates that a trigger simulated from a reconstructed cluster
-	 * was successfully matched to a trigger in the SSP bank.
-	 * @param tiFlags - An array of size 6 indicating which TI bank
-	 * flags are active and which are not.
-	 * @param triggerTypeID - An identifier indicating the type of
-	 * trigger that was matched.
-	 */
-	public void matchedReconTrigger(boolean[] tiFlags) {
-		matchedTriggers(tiFlags, RECON);
-	}
-	
-	/**
-	 * Indicates that a trigger simulated from a reconstructed cluster
-	 * was partially matched to a trigger in the SSP bank, and notes
-	 * which cuts did and did not match.
-	 * @param tiFlags - An array of size 6 indicating which TI bank
-	 * flags are active and which are not.
-	 * @param triggerTypeID - An identifier indicating the type of
-	 * trigger that was matched.
-	 * @param matchedCuts - An array of size 3 or 4 indicating which
-	 * cuts did and did not align between the triggers.
-	 */
-	public void matchedReconTrigger(boolean[] tiFlags, boolean[] matchedCuts) {
-		matchedTriggers(tiFlags, matchedCuts, RECON);
-	}
-	
-	/**
-	 * Indicates that a trigger simulated from an SSP bank cluster was
-	 * successfully matched to a trigger in the SSP bank.
-	 * @param tiFlags - An array of size 6 indicating which TI bank
-	 * flags are active and which are not.
-	 * @param triggerTypeID - An identifier indicating the type of
-	 * trigger that was matched.
-	 */
-	public void matchedSSPTrigger(boolean[] tiFlags) {
-		matchedTriggers(tiFlags, SSP);
-	}
-	
-	/**
-	 * Indicates that a trigger simulated from an SSP bank cluster was
-	 * partially matched to a trigger in the SSP bank, and notes which
-	 * cuts did and did not match.
-	 * @param tiFlags - An array of size 6 indicating which TI bank
-	 * flags are active and which are not.
-	 * @param triggerTypeID - An identifier indicating the type of
-	 * trigger that was matched.
-	 * @param matchedCuts - An array of size 3 or 4 indicating which
-	 * cuts did and did not align between the triggers.
-	 */
-	public void matchedSSPTrigger(boolean[] tiFlags, boolean[] matchedCuts) {
-		matchedTriggers(tiFlags, matchedCuts, SSP);
-	}
-	
-	/**
-	 * Indicates that a trigger simulated from a reconstructed cluster
-	 * was seen and increments the count for this type of trigger by one.
-	 * @param tiFlags - Whether or not each of the TI bank flags is
-	 * active or not.
-	 */
-	public void sawReconSimulatedTrigger(boolean[] tiFlags) {
-		sawReconSimulatedTriggers(tiFlags, 1);
-	}
-	
-	/**
-	 * Indicates that a number triggers simulated from reconstructed
-	 * clusters were seen and increments the count for this type of
-	 * trigger by the indicated number.
-	 * @param tiFlags - Whether or not each of the TI bank flags is
-	 * active or not.
-	 * @param count - The number of simulated triggers seen.
-	 */
-	public void sawReconSimulatedTriggers(boolean[] tiFlags, int count) {
-		// Increment the total count.
-		simTriggers[RECON] += count;
-		
-		// Increment the TI flag counters.
-		for(int tiType = 0; tiType < 6; tiType++) {
-			if(tiFlags[tiType]) {
-				tiTriggersSeen[RECON][tiType] += count;
-			}
-		}
-	}
-	
-	/**
-	 * Indicates that a trigger from the SSP trigger bank was seen and
-	 * increments the count for this type of trigger by one.
-	 */
-	public void sawReportedTrigger() {
-		sawReportedTriggers(1);
-	}
-	
-	/**
-	 * Indicates that a number triggers from the SSP trigger bank were
-	 * seen and increments the count for this type of trigger by the
-	 * indicated number.
-	 * @param count - The number of simulated triggers seen.
-	 */
-	public void sawReportedTriggers(int count) {
-		reportedTriggers += count;
-	}
-	
-	/**
-	 * Indicates that a trigger simulated from an SSP bank cluster was
-	 * seen and increments the count for this type of trigger by one.
-	 * @param tiFlags - Whether or not each of the TI bank flags is
-	 * active or not.
-	 */
-	public void sawSSPSimulatedTrigger(boolean[] tiFlags) {
-		sawSSPSimulatedTriggers(tiFlags, 1);
-	}
-	
-	/**
-	 * Indicates that a number triggers simulated from SSP bank clusters
-	 * were seen and increments the count for this type of trigger by
-	 * the indicated number.
-	 * @param tiFlags - Whether or not each of the TI bank flags is
-	 * active or not.
-	 * @param count - The number of simulated triggers seen.
-	 */
-	public void sawSSPSimulatedTriggers(boolean[] tiFlags, int count) {
-		// Increment the total count.
-		simTriggers[SSP] += count;
-		
-		// Increment the TI flag counters.
-		for(int tiType = 0; tiType < 6; tiType++) {
-			if(tiFlags[tiType]) {
-				tiTriggersSeen[SSP][tiType] += count;
-			}
-		}
-	}
-	
-	/**
-	 * Indicates that a simulated trigger was successfully matched to
-	 * an SSP bank trigger.
-	 * @param tiFlags - An array of size 6 indicating which TI bank
-	 * flags are active and which are not.
-	 * @param sourceType - Uses <code>SSP</code> for triggers simulated
-	 * from an SSP bank cluster and <code>RECON</code> for triggers that
-	 * were simulated from a reconstructed cluster.
-	 */
-	private final void matchedTriggers(boolean[] tiFlags, int sourceType) {
-		// Increment the total triggers matched.
-		matchedTriggers[sourceType]++;
-		
-		// Increment the triggers matched for this type for each if
-		// the active TI bank flags.
-		for(int tiType = 0; tiType < 6; tiType++) {
-			if(tiFlags[tiType]) {
-				tiTriggersMatched[sourceType][tiType]++;
-			}
-		}
-	}
-	
-	/**
-	 * Indicates that a simulated trigger was partially matched to a
-	 * trigger in the SSP bank, and notes which cuts did and did not
-	 * match.
-	 * @param tiFlags - An array of size 6 indicating which TI bank
-	 * flags are active and which are not.
-	 * @param sourceType - Uses <code>SSP</code> for triggers simulated
-	 * from an SSP bank cluster and <code>RECON</code> for triggers that
-	 * were simulated from a reconstructed cluster.
-	 */
-	private void matchedTriggers(boolean[] tiFlags, boolean[] matchedCuts, int sourceType) {
-		// The matched cuts must be defined.
-		if(matchedCuts == null) {
-			throw new NullPointerException("The matched cuts array must be defined.");
-		}
-		
-		// The matched cuts array must be of either size 3 or 4.
-		if(matchedCuts.length != 3 && matchedCuts.length != 4) {
-			throw new IllegalArgumentException("All triggers must use either three or four cuts.");
-		}
-		
-		// Increment the counters for each cut that was no matched. Also
-		// track whether or not a cut actually failed.
-		boolean cutFailed = false;
-		for(int cutIndex = 0; cutIndex < matchedCuts.length; cutIndex++) {
-			if(!matchedCuts[cutIndex]) {
-				failedCuts[sourceType][cutIndex]++;
-				cutFailed = true;
-			}
-		}
-		
-		// If no cut failed, this is actually a match. Increment the
-		// appropriate counters.
-		if(!cutFailed) {
-			matchedTriggers(tiFlags, sourceType);
-		}
-	}
-	
-	@Deprecated
-	public String getPrintData() {
-		StringBuffer out = new StringBuffer();
+    /**
+     * Indicates that a trigger simulated from a reconstructed cluster
+     * was successfully matched to a trigger in the SSP bank.
+     * @param tiFlags - An array of size 6 indicating which TI bank
+     * flags are active and which are not.
+     */
+    public void matchedReconTrigger(boolean[] tiFlags) {
+        matchedTriggers(tiFlags, RECON);
+    }
+    
+    /**
+     * Indicates that a trigger simulated from a reconstructed cluster
+     * was partially matched to a trigger in the SSP bank, and notes
+     * which cuts did and did not match.
+     * @param tiFlags - An array of size 6 indicating which TI bank
+     * flags are active and which are not.
+     * @param matchedCuts - An array of size 3 or 4 indicating which
+     * cuts did and did not align between the triggers.
+     */
+    public void matchedReconTrigger(boolean[] tiFlags, boolean[] matchedCuts) {
+        matchedTriggers(tiFlags, matchedCuts, RECON);
+    }
+    
+    /**
+     * Indicates that a trigger simulated from an SSP bank cluster was
+     * successfully matched to a trigger in the SSP bank.
+     * @param tiFlags - An array of size 6 indicating which TI bank
+     * flags are active and which are not.
+     */
+    public void matchedSSPTrigger(boolean[] tiFlags) {
+        matchedTriggers(tiFlags, SSP);
+    }
+    
+    /**
+     * Indicates that a trigger simulated from an SSP bank cluster was
+     * partially matched to a trigger in the SSP bank, and notes which
+     * cuts did and did not match.
+     * @param tiFlags - An array of size 6 indicating which TI bank
+     * flags are active and which are not.
+     * @param matchedCuts - An array of size 3 or 4 indicating which
+     * cuts did and did not align between the triggers.
+     */
+    public void matchedSSPTrigger(boolean[] tiFlags, boolean[] matchedCuts) {
+        matchedTriggers(tiFlags, matchedCuts, SSP);
+    }
+    
+    /**
+     * Indicates that a trigger simulated from a reconstructed cluster
+     * was seen and increments the count for this type of trigger by one.
+     * @param tiFlags - Whether or not each of the TI bank flags is
+     * active or not.
+     */
+    public void sawReconSimulatedTrigger(boolean[] tiFlags) {
+        sawReconSimulatedTriggers(tiFlags, 1);
+    }
+    
+    /**
+     * Indicates that a number triggers simulated from reconstructed
+     * clusters were seen and increments the count for this type of
+     * trigger by the indicated number.
+     * @param tiFlags - Whether or not each of the TI bank flags is
+     * active or not.
+     * @param count - The number of simulated triggers seen.
+     */
+    public void sawReconSimulatedTriggers(boolean[] tiFlags, int count) {
+        // Increment the total count.
+        simTriggers[RECON] += count;
+        
+        // Increment the TI flag counters.
+        for(int tiType = 0; tiType < 6; tiType++) {
+            if(tiFlags[tiType]) {
+                tiTriggersSeen[RECON][tiType] += count;
+            }
+        }
+    }
+    
+    /**
+     * Indicates that a trigger from the SSP trigger bank was seen and
+     * increments the count for this type of trigger by one.
+     */
+    public void sawReportedTrigger() {
+        sawReportedTriggers(1);
+    }
+    
+    /**
+     * Indicates that a number triggers from the SSP trigger bank were
+     * seen and increments the count for this type of trigger by the
+     * indicated number.
+     * @param count - The number of simulated triggers seen.
+     */
+    public void sawReportedTriggers(int count) {
+        reportedTriggers += count;
+    }
+    
+    /**
+     * Indicates that a trigger simulated from an SSP bank cluster was
+     * seen and increments the count for this type of trigger by one.
+     * @param tiFlags - Whether or not each of the TI bank flags is
+     * active or not.
+     */
+    public void sawSSPSimulatedTrigger(boolean[] tiFlags) {
+        sawSSPSimulatedTriggers(tiFlags, 1);
+    }
+    
+    /**
+     * Indicates that a number triggers simulated from SSP bank clusters
+     * were seen and increments the count for this type of trigger by
+     * the indicated number.
+     * @param tiFlags - Whether or not each of the TI bank flags is
+     * active or not.
+     * @param count - The number of simulated triggers seen.
+     */
+    public void sawSSPSimulatedTriggers(boolean[] tiFlags, int count) {
+        // Increment the total count.
+        simTriggers[SSP] += count;
+        
+        // Increment the TI flag counters.
+        for(int tiType = 0; tiType < 6; tiType++) {
+            if(tiFlags[tiType]) {
+                tiTriggersSeen[SSP][tiType] += count;
+            }
+        }
+    }
+    
+    /**
+     * Indicates that a simulated trigger was successfully matched to
+     * an SSP bank trigger.
+     * @param tiFlags - An array of size 6 indicating which TI bank
+     * flags are active and which are not.
+     * @param sourceType - Uses <code>SSP</code> for triggers simulated
+     * from an SSP bank cluster and <code>RECON</code> for triggers that
+     * were simulated from a reconstructed cluster.
+     */
+    private final void matchedTriggers(boolean[] tiFlags, int sourceType) {
+        // Increment the total triggers matched.
+        matchedTriggers[sourceType]++;
+        
+        // Increment the triggers matched for this type for each if
+        // the active TI bank flags.
+        for(int tiType = 0; tiType < 6; tiType++) {
+            if(tiFlags[tiType]) {
+                tiTriggersMatched[sourceType][tiType]++;
+            }
+        }
+    }
+    
+    /**
+     * Indicates that a simulated trigger was partially matched to a
+     * trigger in the SSP bank, and notes which cuts did and did not
+     * match.
+     * @param tiFlags - An array of size 6 indicating which TI bank
+     * flags are active and which are not.
+     * @param sourceType - Uses <code>SSP</code> for triggers simulated
+     * from an SSP bank cluster and <code>RECON</code> for triggers that
+     * were simulated from a reconstructed cluster.
+     */
+    private void matchedTriggers(boolean[] tiFlags, boolean[] matchedCuts, int sourceType) {
+        // The matched cuts must be defined.
+        if(matchedCuts == null) {
+            throw new NullPointerException("The matched cuts array must be defined.");
+        }
+        
+        // The matched cuts array must be of either size 3 or 4.
+        if(matchedCuts.length != 3 && matchedCuts.length != 4) {
+            throw new IllegalArgumentException("All triggers must use either three or four cuts.");
+        }
+        
+        // Increment the counters for each cut that was no matched. Also
+        // track whether or not a cut actually failed.
+        boolean cutFailed = false;
+        for(int cutIndex = 0; cutIndex < matchedCuts.length; cutIndex++) {
+            if(!matchedCuts[cutIndex]) {
+                failedCuts[sourceType][cutIndex]++;
+                cutFailed = true;
+            }
+        }
+        
+        // If no cut failed, this is actually a match. Increment the
+        // appropriate counters.
+        if(!cutFailed) {
+            matchedTriggers(tiFlags, sourceType);
+        }
+    }
+    
+    @Deprecated
+    public String getPrintData() {
+        StringBuffer out = new StringBuffer();
 
-		out.append("\n");
-		out.append("Trigger Result\n");
-		out.append("SSP Sim Triggers    :: " + simTriggers[SSP] + "\n");
-		out.append("Recon Sim Triggers  :: " + simTriggers[RECON] + "\n");
-		out.append("Reported Triggers   :: " + reportedTriggers + "\n");
-		out.append(String.format("Internal Efficiency :: %d / %d (%7.3f)%n", matchedTriggers[SSP], simTriggers[SSP],
-				(100.0 * matchedTriggers[SSP] / simTriggers[SSP])));
-		out.append(String.format("Trigger Efficiency  :: %d / %d (%7.3f)%n", matchedTriggers[RECON], simTriggers[RECON],
-				(100.0 * matchedTriggers[RECON] / simTriggers[RECON])));
-		
-		out.append("\n");
-		out.append("Individual Cut Failure Rates\n");
-		out.append("Unmatched Triggers   :: " + unmatchedTriggers[SSP] + "\n");
-		for(int i = 0; i < 4; i++) {
-			out.append(String.format("\tCut %d :: %d / %d (%7.3f)%n", i, failedCuts[SSP][i], simTriggers[SSP],
-					(100.0 * failedCuts[SSP][i] / simTriggers[SSP])));
-		}
-		
-		return out.toString();
-	}
+        out.append("\n");
+        out.append("Trigger Result\n");
+        out.append("SSP Sim Triggers    :: " + simTriggers[SSP] + "\n");
+        out.append("Recon Sim Triggers  :: " + simTriggers[RECON] + "\n");
+        out.append("Reported Triggers   :: " + reportedTriggers + "\n");
+        out.append(String.format("Internal Efficiency :: %d / %d (%7.3f)%n", matchedTriggers[SSP], simTriggers[SSP],
+                (100.0 * matchedTriggers[SSP] / simTriggers[SSP])));
+        out.append(String.format("Trigger Efficiency  :: %d / %d (%7.3f)%n", matchedTriggers[RECON], simTriggers[RECON],
+                (100.0 * matchedTriggers[RECON] / simTriggers[RECON])));
+        
+        out.append("\n");
+        out.append("Individual Cut Failure Rates\n");
+        out.append("Unmatched Triggers   :: " + unmatchedTriggers[SSP] + "\n");
+        for(int i = 0; i < 4; i++) {
+            out.append(String.format("\tCut %d :: %d / %d (%7.3f)%n", i, failedCuts[SSP][i], simTriggers[SSP],
+                    (100.0 * failedCuts[SSP][i] / simTriggers[SSP])));
+        }
+        
+        return out.toString();
+    }
 }

Modified: java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/data/TriggerStatModule.java
 =============================================================================
--- java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/data/TriggerStatModule.java	(original)
+++ java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/data/TriggerStatModule.java	Wed Apr 27 11:11:32 2016
@@ -10,285 +10,281 @@
  * @author Kyle McCarty <[log in to unmask]>
  */
 public class TriggerStatModule {
-	// Store the reference index for SSP simulated triggers and recon
-	// simulated triggers.
-	protected static final int SSP = 0;
-	protected static final int RECON = 1;
-	
-	// Define TI trigger type identifiers.
-	public static final int SINGLES_0 = 0;
-	public static final int SINGLES_1 = 1;
-	public static final int PAIR_0    = 2;
-	public static final int PAIR_1    = 3;
-	public static final int PULSER    = 4;
-	public static final int COSMIC    = 5;
-	
-	// Track the number of simulated triggers seen for each source type.
-	// SSP simulated triggers from the SSP bank clusters. Reconstructed
-	// simulated triggers come from clusters built from FADC data.
-	protected int[] simTriggers = new int[2];
-	
-	// Also track the number of triggers reported by the SSP bank.
-	protected int reportedTriggers = 0;
-	
-	// Track the number of simulated triggers of each type that were
-	// successfully matched.
-	protected int[] matchedTriggers = new int[2];
-	
-	// Track the number of simulated triggers that could not be matched
-	// at all.
-	protected int[] unmatchedTriggers = new int[2];
-	
-	// Track which cuts succeeded and which cuts failed for each type.
-	// Note that this is currently only tracked for SSP cluster triggers.
-	protected int[][] failedCuts = new int[2][4];
-	
-	// Store the number of trigger matches seen over all events that
-	// contain a given TI flag.
-	protected int[][] tiTriggersSeen = new int[2][6];
-	protected int[][] tiTriggersMatched = new int[2][6];
-	
-	/**
-	 * Clears all of the statistical counters in the object.
-	 */
-	void clear() {
-		// Clear all values.
-		for(int sourceType = 0; sourceType < 2; sourceType++) {
-			// Clear the general statistics.
-			simTriggers[sourceType]       = 0;
-			matchedTriggers[sourceType]   = 0;
-			unmatchedTriggers[sourceType] = 0;
-			
-			// Clear the cut failure statistics.
-			for(int cutID = 0; cutID < 4; cutID++) {
-				failedCuts[sourceType][cutID] = 0;
-			}
-			
-			// Clear the TI flag statistics.
-			for(int tiType = 0; tiType < 6; tiType++) {
-				tiTriggersSeen[sourceType][tiType]    = 0;
-				tiTriggersMatched[sourceType][tiType] = 0;
-			}
-		}
-	}
-	
-	@Override
-	public TriggerStatModule clone() {
-		// Make a new statistics module.
-		TriggerStatModule clone = new TriggerStatModule();
-		
-		// Copy the values that do not depend on trigger source type.
-		clone.reportedTriggers = reportedTriggers;
-		
-		// Set each value that depends on the trigger source type.
-		for(int sourceType = 0; sourceType < 2; sourceType++) {
-			clone.simTriggers[sourceType] = simTriggers[sourceType];
-			clone.matchedTriggers[sourceType] = matchedTriggers[sourceType];
-			clone.unmatchedTriggers[sourceType] = unmatchedTriggers[sourceType];
-			
-			// Set the number of times each cut failed.
-			for(int cutID = 0; cutID < 4; cutID++) {
-				clone.failedCuts[sourceType][cutID] = failedCuts[sourceType][cutID];
-			}
-			
-			// Copy the values for the TI flag trigger counters.
-			for(int tiType = 0; tiType < 6; tiType++) {
-				clone.tiTriggersSeen[sourceType][tiType] = tiTriggersSeen[sourceType][tiType];
-				clone.tiTriggersMatched[sourceType][tiType] = tiTriggersMatched[sourceType][tiType];
-			}
-		}
-		
-		// Return the copied clone.
-		return clone;
-	}
-	
-	/**
-	 * Gets the number of simulated triggers from reconstructed clusters
-	 * that were not matched.
-	 * @return Returns the number of triggers as an <code>int</code>.
-	 */
-	public int getFailedReconSimulatedTriggers() {
-		return simTriggers[RECON] - matchedTriggers[RECON];
-	}
-	
-	/**
-	 * Gets the number of simulated triggers from SSP bank clusters
-	 * that were not matched.
-	 * @return Returns the number of triggers as an <code>int</code>.
-	 */
-	public int getFailedSSPSimulatedTriggers() {
-		return simTriggers[SSP] - matchedTriggers[SSP];
-	}
-	
-	/**
-	 * Gets the number of simulated triggers from reconstructed clusters
-	 * that were matched.
-	 * @return Returns the number of triggers as an <code>int</code>.
-	 */
-	public int getMatchedReconSimulatedTriggers() {
-		return matchedTriggers[RECON];
-	}
-	
-	/**
-	 * Gets the number of simulated triggers from reconstructed clusters
-	 * that were matched for a given type of trigger when a given TI
-	 * bank flag was active.
-	 * @param tiTypeID - The identifier for the type of TI bank trigger
-	 * that should be active.
-	 * @param triggerTypeID - The identifier for the type of trigger.
-	 * @return Returns the number of triggers as an <code>int</code>.
-	 */
-	public int getMatchedReconSimulatedTriggers(int tiTypeID) {
-		return tiTriggersMatched[RECON][tiTypeID];
-	}
-	
-	/**
-	 * Gets the number of simulated triggers from SSP bank clusters
-	 * that were matched.
-	 * @return Returns the number of triggers as an <code>int</code>.
-	 */
-	public int getMatchedSSPSimulatedTriggers() {
-		return matchedTriggers[SSP];
-	}
-	
-	/**
-	 * Gets the number of simulated triggers from SSP bank clusters
-	 * that were matched for a given type of trigger when a given TI
-	 * bank flag was active.
-	 * @param tiTypeID - The identifier for the type of TI bank trigger
-	 * that should be active.
-	 * @param triggerTypeID - The identifier for the type of trigger.
-	 * @return Returns the number of triggers as an <code>int</code>.
-	 */
-	public int getMatchedSSPSimulatedTriggers(int tiTypeID) {
-		return tiTriggersMatched[SSP][tiTypeID];
-	}
-	
-	/**
-	 * Gets the number of simulated triggers from reconstructed clusters
-	 * that were matched, but did not see full cut alignment.
-	 * @return Returns the number of triggers as an <code>int</code>.
-	 */
-	public int getPartiallyMatchedReconSimulatedTriggers() {
-		return simTriggers[RECON] - (matchedTriggers[RECON] + unmatchedTriggers[RECON]);
-	}
-	
-	/**
-	 * Gets the number of simulated triggers from SSP bank clusters
-	 * that were matched, but did not see full cut alignment.
-	 * @return Returns the number of triggers as an <code>int</code>.
-	 */
-	public int getPartiallyMatchedSSPSimulatedTriggers() {
-		return simTriggers[SSP] - (matchedTriggers[SSP] + unmatchedTriggers[SSP]);
-	}
-	
-	/**
-	 * Gets the number of times the specified cut failed for triggers
-	 * that were partially matched for triggers simulated from FADC
-	 * reconstructed clusters.
-	 * @param cutIndex - The numerical cut identifier.
-	 * @return Returns the number of triggers as an <code>int</code>.
-	 */
-	public int getReconCutFailures(int cutIndex) {
-		return getCutFailures(RECON, cutIndex);
-	}
-	
-	/**
-	 * Gets the number of simulated triggers from reconstructed clusters
-	 * that were seen.
-	 * @return Returns the number of triggers as an <code>int</code>.
-	 */
-	public int getReconSimulatedTriggers() {
-		return simTriggers[RECON];
-	}
-	
-	/**
-	 * Gets the number of simulated triggers from reconstructed clusters
-	 * that were seen for a given trigger type when a given TI bank
-	 * flag was active.
-	 * @param tiTypeID - The identifier for the type of TI bank trigger
-	 * that should be active.
-	 * @param triggerTypeID - The identifier for the type of trigger.
-	 * @return Returns the number of triggers as an <code>int</code>.
-	 */
-	public int getReconSimulatedTriggers(int tiTypeID) {
-		return tiTriggersSeen[RECON][tiTypeID];
-	}
-	
-	/**
-	 * Gets the number of triggers reported by the SSP bank.
-	 * @return Returns the number of triggers as an <code>int</code>.
-	 */
-	public int getReportedTriggers() {
-		return reportedTriggers;
-	}
-	
-	/**
-	 * Gets the number of times the specified cut failed for triggers
-	 * that were partially matched for triggers simulated from SSP
-	 * bank clusters.
-	 * @param cutIndex - The numerical cut identifier.
-	 * @return Returns the number of triggers as an <code>int</code>.
-	 */
-	public int getSSPCutFailures(int cutIndex) {
-		return getCutFailures(SSP, cutIndex);
-	}
-	
-	/**
-	 * Gets the number of simulated triggers from SSP bank clusters
-	 * that were seen.
-	 * @return Returns the number of triggers as an <code>int</code>.
-	 */
-	public int getSSPSimulatedTriggers() {
-		return simTriggers[SSP];
-	}
-	
-	/**
-	 * Gets the number of simulated triggers from SSP bank clusters
-	 * that were seen for a given trigger type when a given TI bank
-	 * flag was active.
-	 * @param tiTypeID - The identifier for the type of TI bank trigger
-	 * that should be active.
-	 * @param triggerTypeID - The identifier for the type of trigger.
-	 * @return Returns the number of triggers as an <code>int</code>.
-	 */
-	public int getSSPSimulatedTriggers(int tiTypeID) {
-		return tiTriggersSeen[SSP][tiTypeID];
-	}
-	
-	/**
-	 * Gets the number of simulated triggers from reconstructed clusters
-	 * that were completely unmatched.
-	 * @return Returns the number of triggers as an <code>int</code>.
-	 */
-	public int getUnmatchedReconSimulatedTriggers() {
-		return unmatchedTriggers[RECON];
-	}
-	
-	/**
-	 * Gets the number of simulated triggers from SSP bank clusters
-	 * that were completely unmatched.
-	 * @return Returns the number of triggers as an <code>int</code>.
-	 */
-	public int getUnmatchedSSPSimulatedTriggers() {
-		return unmatchedTriggers[SSP];
-	}
-	
-	/**
-	 * Gets the number of times the specified cut failed for triggers
-	 * that were partially matched for triggers simulated from the type
-	 * of cluster indicated.
-	 * @param type - Either <code>SSP</code> or <code>RECON</code>.
-	 * @param cutIndex - The numerical cut identifier.
-	 * @return Returns the number of triggers as an <code>int</code>.
-	 */
-	private int getCutFailures(int type, int cutIndex) {
-		// Ensure that the cut index is valid.
-		if(cutIndex < 0 || cutIndex >= 4) {
-			throw new IndexOutOfBoundsException(String.format("Cut index \"%d\" is not recognized.", cutIndex));
-		}
-		
-		// Return the cut failures.
-		return failedCuts[type][cutIndex];
-	}
+    // Store the reference index for SSP simulated triggers and recon
+    // simulated triggers.
+    protected static final int SSP = 0;
+    protected static final int RECON = 1;
+    
+    // Define TI trigger type identifiers.
+    public static final int SINGLES_0 = 0;
+    public static final int SINGLES_1 = 1;
+    public static final int PAIR_0    = 2;
+    public static final int PAIR_1    = 3;
+    public static final int PULSER    = 4;
+    public static final int COSMIC    = 5;
+    
+    // Track the number of simulated triggers seen for each source type.
+    // SSP simulated triggers from the SSP bank clusters. Reconstructed
+    // simulated triggers come from clusters built from FADC data.
+    protected int[] simTriggers = new int[2];
+    
+    // Also track the number of triggers reported by the SSP bank.
+    protected int reportedTriggers = 0;
+    
+    // Track the number of simulated triggers of each type that were
+    // successfully matched.
+    protected int[] matchedTriggers = new int[2];
+    
+    // Track the number of simulated triggers that could not be matched
+    // at all.
+    protected int[] unmatchedTriggers = new int[2];
+    
+    // Track which cuts succeeded and which cuts failed for each type.
+    // Note that this is currently only tracked for SSP cluster triggers.
+    protected int[][] failedCuts = new int[2][4];
+    
+    // Store the number of trigger matches seen over all events that
+    // contain a given TI flag.
+    protected int[][] tiTriggersSeen = new int[2][6];
+    protected int[][] tiTriggersMatched = new int[2][6];
+    
+    /**
+     * Clears all of the statistical counters in the object.
+     */
+    void clear() {
+        // Clear all values.
+        for(int sourceType = 0; sourceType < 2; sourceType++) {
+            // Clear the general statistics.
+            simTriggers[sourceType]       = 0;
+            matchedTriggers[sourceType]   = 0;
+            unmatchedTriggers[sourceType] = 0;
+            
+            // Clear the cut failure statistics.
+            for(int cutID = 0; cutID < 4; cutID++) {
+                failedCuts[sourceType][cutID] = 0;
+            }
+            
+            // Clear the TI flag statistics.
+            for(int tiType = 0; tiType < 6; tiType++) {
+                tiTriggersSeen[sourceType][tiType]    = 0;
+                tiTriggersMatched[sourceType][tiType] = 0;
+            }
+        }
+    }
+    
+    @Override
+    public TriggerStatModule clone() {
+        // Make a new statistics module.
+        TriggerStatModule clone = new TriggerStatModule();
+        
+        // Copy the values that do not depend on trigger source type.
+        clone.reportedTriggers = reportedTriggers;
+        
+        // Set each value that depends on the trigger source type.
+        for(int sourceType = 0; sourceType < 2; sourceType++) {
+            clone.simTriggers[sourceType] = simTriggers[sourceType];
+            clone.matchedTriggers[sourceType] = matchedTriggers[sourceType];
+            clone.unmatchedTriggers[sourceType] = unmatchedTriggers[sourceType];
+            
+            // Set the number of times each cut failed.
+            for(int cutID = 0; cutID < 4; cutID++) {
+                clone.failedCuts[sourceType][cutID] = failedCuts[sourceType][cutID];
+            }
+            
+            // Copy the values for the TI flag trigger counters.
+            for(int tiType = 0; tiType < 6; tiType++) {
+                clone.tiTriggersSeen[sourceType][tiType] = tiTriggersSeen[sourceType][tiType];
+                clone.tiTriggersMatched[sourceType][tiType] = tiTriggersMatched[sourceType][tiType];
+            }
+        }
+        
+        // Return the copied clone.
+        return clone;
+    }
+    
+    /**
+     * Gets the number of simulated triggers from reconstructed clusters
+     * that were not matched.
+     * @return Returns the number of triggers as an <code>int</code>.
+     */
+    public int getFailedReconSimulatedTriggers() {
+        return simTriggers[RECON] - matchedTriggers[RECON];
+    }
+    
+    /**
+     * Gets the number of simulated triggers from SSP bank clusters
+     * that were not matched.
+     * @return Returns the number of triggers as an <code>int</code>.
+     */
+    public int getFailedSSPSimulatedTriggers() {
+        return simTriggers[SSP] - matchedTriggers[SSP];
+    }
+    
+    /**
+     * Gets the number of simulated triggers from reconstructed clusters
+     * that were matched.
+     * @return Returns the number of triggers as an <code>int</code>.
+     */
+    public int getMatchedReconSimulatedTriggers() {
+        return matchedTriggers[RECON];
+    }
+    
+    /**
+     * Gets the number of simulated triggers from reconstructed clusters
+     * that were matched for a given type of trigger when a given TI
+     * bank flag was active.
+     * @param tiTypeID - The identifier for the type of TI bank trigger
+     * that should be active.
+     * @return Returns the number of triggers as an <code>int</code>.
+     */
+    public int getMatchedReconSimulatedTriggers(int tiTypeID) {
+        return tiTriggersMatched[RECON][tiTypeID];
+    }
+    
+    /**
+     * Gets the number of simulated triggers from SSP bank clusters
+     * that were matched.
+     * @return Returns the number of triggers as an <code>int</code>.
+     */
+    public int getMatchedSSPSimulatedTriggers() {
+        return matchedTriggers[SSP];
+    }
+    
+    /**
+     * Gets the number of simulated triggers from SSP bank clusters
+     * that were matched for a given type of trigger when a given TI
+     * bank flag was active.
+     * @param tiTypeID - The identifier for the type of TI bank trigger
+     * that should be active.
+     * @return Returns the number of triggers as an <code>int</code>.
+     */
+    public int getMatchedSSPSimulatedTriggers(int tiTypeID) {
+        return tiTriggersMatched[SSP][tiTypeID];
+    }
+    
+    /**
+     * Gets the number of simulated triggers from reconstructed clusters
+     * that were matched, but did not see full cut alignment.
+     * @return Returns the number of triggers as an <code>int</code>.
+     */
+    public int getPartiallyMatchedReconSimulatedTriggers() {
+        return simTriggers[RECON] - (matchedTriggers[RECON] + unmatchedTriggers[RECON]);
+    }
+    
+    /**
+     * Gets the number of simulated triggers from SSP bank clusters
+     * that were matched, but did not see full cut alignment.
+     * @return Returns the number of triggers as an <code>int</code>.
+     */
+    public int getPartiallyMatchedSSPSimulatedTriggers() {
+        return simTriggers[SSP] - (matchedTriggers[SSP] + unmatchedTriggers[SSP]);
+    }
+    
+    /**
+     * Gets the number of times the specified cut failed for triggers
+     * that were partially matched for triggers simulated from FADC
+     * reconstructed clusters.
+     * @param cutIndex - The numerical cut identifier.
+     * @return Returns the number of triggers as an <code>int</code>.
+     */
+    public int getReconCutFailures(int cutIndex) {
+        return getCutFailures(RECON, cutIndex);
+    }
+    
+    /**
+     * Gets the number of simulated triggers from reconstructed clusters
+     * that were seen.
+     * @return Returns the number of triggers as an <code>int</code>.
+     */
+    public int getReconSimulatedTriggers() {
+        return simTriggers[RECON];
+    }
+    
+    /**
+     * Gets the number of simulated triggers from reconstructed clusters
+     * that were seen for a given trigger type when a given TI bank
+     * flag was active.
+     * @param tiTypeID - The identifier for the type of TI bank trigger
+     * that should be active.
+     * @return Returns the number of triggers as an <code>int</code>.
+     */
+    public int getReconSimulatedTriggers(int tiTypeID) {
+        return tiTriggersSeen[RECON][tiTypeID];
+    }
+    
+    /**
+     * Gets the number of triggers reported by the SSP bank.
+     * @return Returns the number of triggers as an <code>int</code>.
+     */
+    public int getReportedTriggers() {
+        return reportedTriggers;
+    }
+    
+    /**
+     * Gets the number of times the specified cut failed for triggers
+     * that were partially matched for triggers simulated from SSP
+     * bank clusters.
+     * @param cutIndex - The numerical cut identifier.
+     * @return Returns the number of triggers as an <code>int</code>.
+     */
+    public int getSSPCutFailures(int cutIndex) {
+        return getCutFailures(SSP, cutIndex);
+    }
+    
+    /**
+     * Gets the number of simulated triggers from SSP bank clusters
+     * that were seen.
+     * @return Returns the number of triggers as an <code>int</code>.
+     */
+    public int getSSPSimulatedTriggers() {
+        return simTriggers[SSP];
+    }
+    
+    /**
+     * Gets the number of simulated triggers from SSP bank clusters
+     * that were seen for a given trigger type when a given TI bank
+     * flag was active.
+     * @param tiTypeID - The identifier for the type of TI bank trigger
+     * that should be active.
+     * @return Returns the number of triggers as an <code>int</code>.
+     */
+    public int getSSPSimulatedTriggers(int tiTypeID) {
+        return tiTriggersSeen[SSP][tiTypeID];
+    }
+    
+    /**
+     * Gets the number of simulated triggers from reconstructed clusters
+     * that were completely unmatched.
+     * @return Returns the number of triggers as an <code>int</code>.
+     */
+    public int getUnmatchedReconSimulatedTriggers() {
+        return unmatchedTriggers[RECON];
+    }
+    
+    /**
+     * Gets the number of simulated triggers from SSP bank clusters
+     * that were completely unmatched.
+     * @return Returns the number of triggers as an <code>int</code>.
+     */
+    public int getUnmatchedSSPSimulatedTriggers() {
+        return unmatchedTriggers[SSP];
+    }
+    
+    /**
+     * Gets the number of times the specified cut failed for triggers
+     * that were partially matched for triggers simulated from the type
+     * of cluster indicated.
+     * @param type - Either <code>SSP</code> or <code>RECON</code>.
+     * @param cutIndex - The numerical cut identifier.
+     * @return Returns the number of triggers as an <code>int</code>.
+     */
+    private int getCutFailures(int type, int cutIndex) {
+        // Ensure that the cut index is valid.
+        if(cutIndex < 0 || cutIndex >= 4) {
+            throw new IndexOutOfBoundsException(String.format("Cut index \"%d\" is not recognized.", cutIndex));
+        }
+        
+        // Return the cut failures.
+        return failedCuts[type][cutIndex];
+    }
 }

Modified: java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/event/TriggerPlotsModule.java
 =============================================================================
--- java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/event/TriggerPlotsModule.java	(original)
+++ java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/event/TriggerPlotsModule.java	Wed Apr 27 11:11:32 2016
@@ -16,383 +16,383 @@
  * @author Kyle McCarty
  */
 public class TriggerPlotsModule {
-	// Reference variables.
-	private static final int RECON     = 0;
-	private static final int SSP       = 1;
-	private static final int ALL       = 0;
-	private static final int MATCHED   = 1;
-	private static final int FAILED    = 2;
-	private static final int TRIGGERED = 3;
-	private static final int NO_CUTS   = 4;
-	
-	// Class variables.
-	private final double[] energySlopeParamF;
-	private static final double MØLLER_SUM_THRESHOLD = 0.750;
-	
-	// Plots.
-	private AIDA aida = AIDA.defaultInstance();
-	private IHistogram1D[][][] singlesClusterEnergyPlot = new IHistogram1D[2][2][5];
-	private IHistogram1D[][][] singlesHitCountPlot = new IHistogram1D[2][2][5];
-	private IHistogram1D[][][] singlesTriggerTimePlot = new IHistogram1D[2][2][5];
-	
-	private IHistogram1D[][][] pairClusterEnergyPlot = new IHistogram1D[2][2][5];
-	private IHistogram1D[][][] pairHitCountPlot = new IHistogram1D[2][2][5];
-	private IHistogram1D[][][] pairTimePlot = new IHistogram1D[2][2][5];
-	private IHistogram1D[][][] pairSumPlot = new IHistogram1D[2][2][5];
+    // Reference variables.
+    private static final int RECON     = 0;
+    private static final int SSP       = 1;
+    private static final int ALL       = 0;
+    private static final int MATCHED   = 1;
+    private static final int FAILED    = 2;
+    private static final int TRIGGERED = 3;
+    private static final int NO_CUTS   = 4;
+    
+    // Class variables.
+    private final double[] energySlopeParamF;
+    private static final double MØLLER_SUM_THRESHOLD = 0.750;
+    
+    // Plots.
+    private AIDA aida = AIDA.defaultInstance();
+    private IHistogram1D[][][] singlesClusterEnergyPlot = new IHistogram1D[2][2][5];
+    private IHistogram1D[][][] singlesHitCountPlot = new IHistogram1D[2][2][5];
+    private IHistogram1D[][][] singlesTriggerTimePlot = new IHistogram1D[2][2][5];
+    
+    private IHistogram1D[][][] pairClusterEnergyPlot = new IHistogram1D[2][2][5];
+    private IHistogram1D[][][] pairHitCountPlot = new IHistogram1D[2][2][5];
+    private IHistogram1D[][][] pairTimePlot = new IHistogram1D[2][2][5];
+    private IHistogram1D[][][] pairSumPlot = new IHistogram1D[2][2][5];
     private IHistogram2D[][][] pairSumEnergiesPlot = new IHistogram2D[2][2][5];
-	private IHistogram1D[][][] pairDiffPlot = new IHistogram1D[2][2][5];
-	private IHistogram1D[][][] pairSlopePlot = new IHistogram1D[2][2][5];
-	private IHistogram1D[][][] pairCoplanarityPlot = new IHistogram1D[2][2][5];
-	private IHistogram1D[][][] pairTriggerTimePlot = new IHistogram1D[2][2][5];
-	
-	private IHistogram1D[] møllerClusterEnergyPlot = new IHistogram1D[2];
-	private IHistogram1D[] møllerHitCountPlot = new IHistogram1D[2];
-	private IHistogram1D[] møllerTimePlot = new IHistogram1D[2];
-	private IHistogram1D[] møllerSumPlot = new IHistogram1D[2];
+    private IHistogram1D[][][] pairDiffPlot = new IHistogram1D[2][2][5];
+    private IHistogram1D[][][] pairSlopePlot = new IHistogram1D[2][2][5];
+    private IHistogram1D[][][] pairCoplanarityPlot = new IHistogram1D[2][2][5];
+    private IHistogram1D[][][] pairTriggerTimePlot = new IHistogram1D[2][2][5];
+    
+    private IHistogram1D[] møllerClusterEnergyPlot = new IHistogram1D[2];
+    private IHistogram1D[] møllerHitCountPlot = new IHistogram1D[2];
+    private IHistogram1D[] møllerTimePlot = new IHistogram1D[2];
+    private IHistogram1D[] møllerSumPlot = new IHistogram1D[2];
     private IHistogram2D[] møllerSumEnergiesPlot = new IHistogram2D[2];
-	private IHistogram1D[] møllerDiffPlot = new IHistogram1D[2];
-	private IHistogram1D[] møllerSlopePlot = new IHistogram1D[2];
-	private IHistogram1D[] møllerCoplanarityPlot = new IHistogram1D[2];
-	private IHistogram1D[] møllerTriggerTimePlot = new IHistogram1D[2];
+    private IHistogram1D[] møllerDiffPlot = new IHistogram1D[2];
+    private IHistogram1D[] møllerSlopePlot = new IHistogram1D[2];
+    private IHistogram1D[] møllerCoplanarityPlot = new IHistogram1D[2];
+    private IHistogram1D[] møllerTriggerTimePlot = new IHistogram1D[2];
     private IHistogram2D[] møllerPositionPlot = new IHistogram2D[2];
-	
-	private IHistogram1D[] tridentClusterEnergyPlot = new IHistogram1D[2];
-	private IHistogram1D[] tridentHitCountPlot = new IHistogram1D[2];
+    
+    private IHistogram1D[] tridentClusterEnergyPlot = new IHistogram1D[2];
+    private IHistogram1D[] tridentHitCountPlot = new IHistogram1D[2];
     private IHistogram2D[] tridentPositionPlot = new IHistogram2D[2];
-	
-	/**
-	 * Instantiates a new <code>TriggerPlotsModule</code> that will use
-	 * the indicated values for the energy slope conversion factor when
-	 * plotting energy slope values. Plots will be attached to the
-	 * default AIDA instance.
-	 * @param trigger0F - The energy slope conversion factor for the
-	 * first trigger.
-	 * @param trigger1F - The energy slope conversion factor for the
-	 * second trigger.
-	 */
-	public TriggerPlotsModule(double trigger0F, double trigger1F) {
-		// Store the energy slope parameter.
-		energySlopeParamF = new double[2];
-		energySlopeParamF[0] = trigger0F;
-		energySlopeParamF[1] = trigger1F;
-		
-		// Define type string values.
-		String[] sourceType = { "Recon", "SSP" };
-		String[] resultType = { "All", "Matched", "Failed", "Triggered", "No Cuts" };
-		
-		// Instantiate the trigger result plots for each trigger.
-		for(int triggerNum = 0; triggerNum < 2; triggerNum++) {
-			// Get the directory for the current triggers.
-			String pairDir = "Pair Trigger " + triggerNum;
-			String singlesDir = "Singles Trigger " + triggerNum;
-			
-			// Instantiate the trigger result plots for each type of
-			// trigger source object.
-			for(int source = 0; source < 2; source++) {
-				// Instantiate the trigger result plots for each type
-				// of trigger match result.
-				for(int result = 0; result < 5; result++) {
-					// Instantiate the singles trigger plots.
-					singlesClusterEnergyPlot[triggerNum][source][result] = aida.histogram1D(String.format("%s/%s/Singles Cluster Energy (%s)",
-							singlesDir, sourceType[source], resultType[result]), 300, 0.0, 3.0);
-					singlesHitCountPlot[triggerNum][source][result] = aida.histogram1D(String.format("%s/%s/Singles Hit Count (%s)",
-							singlesDir, sourceType[source], resultType[result]), 9, 0.5, 9.5);
-					singlesTriggerTimePlot[triggerNum][source][result] = aida.histogram1D(String.format("%s/%s/Singles Trigger Time (%s)",
-							singlesDir, sourceType[source], resultType[result]), 100, 0, 400);
-					
-					// Instantiate the pair trigger plots.
-					pairHitCountPlot[triggerNum][source][result] = aida.histogram1D(String.format("%s/%s/Pair Hit Count (%s)",
-							pairDir, sourceType[source], resultType[result]), 9, 0.5, 9.5);
-					pairClusterEnergyPlot[triggerNum][source][result] = aida.histogram1D(String.format("%s/%s/Pair Cluster Energy (%s)",
-							pairDir, sourceType[source], resultType[result]), 300, 0.0, 3.0);
-					pairTimePlot[triggerNum][source][result] = aida.histogram1D(String.format("%s/%s/Pair Time Coincidence (%s)",
-							pairDir, sourceType[source], resultType[result]), 8, 0, 32);
-					pairSumPlot[triggerNum][source][result] = aida.histogram1D(String.format("%s/%s/Pair Energy Sum (%s)",
-							pairDir, sourceType[source], resultType[result]), 300, 0.0, 3.0);
+    
+    /**
+     * Instantiates a new <code>TriggerPlotsModule</code> that will use
+     * the indicated values for the energy slope conversion factor when
+     * plotting energy slope values. Plots will be attached to the
+     * default AIDA instance.
+     * @param trigger0F - The energy slope conversion factor for the
+     * first trigger.
+     * @param trigger1F - The energy slope conversion factor for the
+     * second trigger.
+     */
+    public TriggerPlotsModule(double trigger0F, double trigger1F) {
+        // Store the energy slope parameter.
+        energySlopeParamF = new double[2];
+        energySlopeParamF[0] = trigger0F;
+        energySlopeParamF[1] = trigger1F;
+        
+        // Define type string values.
+        String[] sourceType = { "Recon", "SSP" };
+        String[] resultType = { "All", "Matched", "Failed", "Triggered", "No Cuts" };
+        
+        // Instantiate the trigger result plots for each trigger.
+        for(int triggerNum = 0; triggerNum < 2; triggerNum++) {
+            // Get the directory for the current triggers.
+            String pairDir = "Pair Trigger " + triggerNum;
+            String singlesDir = "Singles Trigger " + triggerNum;
+            
+            // Instantiate the trigger result plots for each type of
+            // trigger source object.
+            for(int source = 0; source < 2; source++) {
+                // Instantiate the trigger result plots for each type
+                // of trigger match result.
+                for(int result = 0; result < 5; result++) {
+                    // Instantiate the singles trigger plots.
+                    singlesClusterEnergyPlot[triggerNum][source][result] = aida.histogram1D(String.format("%s/%s/Singles Cluster Energy (%s)",
+                            singlesDir, sourceType[source], resultType[result]), 300, 0.0, 3.0);
+                    singlesHitCountPlot[triggerNum][source][result] = aida.histogram1D(String.format("%s/%s/Singles Hit Count (%s)",
+                            singlesDir, sourceType[source], resultType[result]), 9, 0.5, 9.5);
+                    singlesTriggerTimePlot[triggerNum][source][result] = aida.histogram1D(String.format("%s/%s/Singles Trigger Time (%s)",
+                            singlesDir, sourceType[source], resultType[result]), 100, 0, 400);
+                    
+                    // Instantiate the pair trigger plots.
+                    pairHitCountPlot[triggerNum][source][result] = aida.histogram1D(String.format("%s/%s/Pair Hit Count (%s)",
+                            pairDir, sourceType[source], resultType[result]), 9, 0.5, 9.5);
+                    pairClusterEnergyPlot[triggerNum][source][result] = aida.histogram1D(String.format("%s/%s/Pair Cluster Energy (%s)",
+                            pairDir, sourceType[source], resultType[result]), 300, 0.0, 3.0);
+                    pairTimePlot[triggerNum][source][result] = aida.histogram1D(String.format("%s/%s/Pair Time Coincidence (%s)",
+                            pairDir, sourceType[source], resultType[result]), 8, 0, 32);
+                    pairSumPlot[triggerNum][source][result] = aida.histogram1D(String.format("%s/%s/Pair Energy Sum (%s)",
+                            pairDir, sourceType[source], resultType[result]), 300, 0.0, 3.0);
                                         pairSumEnergiesPlot[triggerNum][source][result] = aida.histogram2D(String.format("%s/%s/Pair 2D Energy Sum (%s)",
                                                         pairDir, sourceType[source], resultType[result]), 300, 0.0, 3.0, 300, 0.0, 3.0);
-					pairDiffPlot[triggerNum][source][result] = aida.histogram1D(String.format("%s/%s/Pair Energy Difference (%s)",
-							pairDir, sourceType[source], resultType[result]), 300, 0.0, 3.0);
-					pairSlopePlot[triggerNum][source][result] = aida.histogram1D(String.format("%s/%s/Pair Energy Slope (%s)",
-							pairDir, sourceType[source], resultType[result]), 300, 0.0, 3.0);
-					pairCoplanarityPlot[triggerNum][source][result] = aida.histogram1D(String.format("%s/%s/Pair Coplanarity (%s)",
-							pairDir, sourceType[source], resultType[result]), 180, 0, 180);
-					pairTriggerTimePlot[triggerNum][source][result] = aida.histogram1D(String.format("%s/%s/Pair Trigger Time (%s)",
-							pairDir, sourceType[source], resultType[result]), 100, 0, 400);
-				}
-			}
-			
-			// Instantiate the Møller plots.
-			møllerHitCountPlot[triggerNum] = aida.histogram1D(String.format("%s/Møller/Møller-like Pair Hit Count",
-					pairDir), 9, 0.5, 9.5);
-			møllerClusterEnergyPlot[triggerNum] = aida.histogram1D(String.format("%s/Møller/Møller-like Pair Cluster Energy",
-					pairDir), 300, 0.0, 3.0);
-			møllerTimePlot[triggerNum] = aida.histogram1D(String.format("%s/Møller/Møller-like Pair Time Coincidence",
-					pairDir), 8, 0, 32);
-			møllerSumPlot[triggerNum] = aida.histogram1D(String.format("%s/Møller/Møller-like Pair Energy Sum",
-					pairDir), 300, 0.0, 3.0);
-			møllerSumEnergiesPlot[triggerNum] = aida.histogram2D(String.format("%s/Møller/Møller-like Pair 2D Energy Sum",
+                    pairDiffPlot[triggerNum][source][result] = aida.histogram1D(String.format("%s/%s/Pair Energy Difference (%s)",
+                            pairDir, sourceType[source], resultType[result]), 300, 0.0, 3.0);
+                    pairSlopePlot[triggerNum][source][result] = aida.histogram1D(String.format("%s/%s/Pair Energy Slope (%s)",
+                            pairDir, sourceType[source], resultType[result]), 300, 0.0, 3.0);
+                    pairCoplanarityPlot[triggerNum][source][result] = aida.histogram1D(String.format("%s/%s/Pair Coplanarity (%s)",
+                            pairDir, sourceType[source], resultType[result]), 180, 0, 180);
+                    pairTriggerTimePlot[triggerNum][source][result] = aida.histogram1D(String.format("%s/%s/Pair Trigger Time (%s)",
+                            pairDir, sourceType[source], resultType[result]), 100, 0, 400);
+                }
+            }
+            
+            // Instantiate the Møller plots.
+            møllerHitCountPlot[triggerNum] = aida.histogram1D(String.format("%s/Møller/Møller-like Pair Hit Count",
+                    pairDir), 9, 0.5, 9.5);
+            møllerClusterEnergyPlot[triggerNum] = aida.histogram1D(String.format("%s/Møller/Møller-like Pair Cluster Energy",
+                    pairDir), 300, 0.0, 3.0);
+            møllerTimePlot[triggerNum] = aida.histogram1D(String.format("%s/Møller/Møller-like Pair Time Coincidence",
+                    pairDir), 8, 0, 32);
+            møllerSumPlot[triggerNum] = aida.histogram1D(String.format("%s/Møller/Møller-like Pair Energy Sum",
+                    pairDir), 300, 0.0, 3.0);
+            møllerSumEnergiesPlot[triggerNum] = aida.histogram2D(String.format("%s/Møller/Møller-like Pair 2D Energy Sum",
                     pairDir), 300, 0.0, 3.0, 300, 0.0, 3.0);
             møllerDiffPlot[triggerNum] = aida.histogram1D(String.format("%s/Møller/Møller-like Pair Energy Difference",
-					pairDir), 300, 0.0, 3.0);
+                    pairDir), 300, 0.0, 3.0);
             møllerSlopePlot[triggerNum] = aida.histogram1D(String.format("%s/Møller/Møller-like Pair Energy Slope",
-					pairDir), 300, 0.0, 3.0);
+                    pairDir), 300, 0.0, 3.0);
             møllerCoplanarityPlot[triggerNum] = aida.histogram1D(String.format("%s/Møller/Møller-like Pair Coplanarity",
-					pairDir), 180, 0, 180);
+                    pairDir), 180, 0, 180);
             møllerTriggerTimePlot[triggerNum] = aida.histogram1D(String.format("%s/Møller/Møller-like Pair Trigger Time",
-					pairDir), 100, 0, 400);
+                    pairDir), 100, 0, 400);
             møllerPositionPlot[triggerNum] = aida.histogram2D(String.format("%s/Møller/Møller-like Pair Position",
-					pairDir), 46, -23, 23, 11, -5.5, 5.5);
+                    pairDir), 46, -23, 23, 11, -5.5, 5.5);
             
             // Instantiate the trident plots.
             tridentHitCountPlot[triggerNum] = aida.histogram1D(String.format("%s/Trident/Trident-like Pair Hit Count",
-            		singlesDir), 9, 0.5, 9.5);
-			tridentClusterEnergyPlot[triggerNum] = aida.histogram1D(String.format("%s/Trident/Trident-like Pair Cluster Energy",
-					singlesDir), 300, 0.0, 3.0);
+                    singlesDir), 9, 0.5, 9.5);
+            tridentClusterEnergyPlot[triggerNum] = aida.histogram1D(String.format("%s/Trident/Trident-like Pair Cluster Energy",
+                    singlesDir), 300, 0.0, 3.0);
             tridentPositionPlot[triggerNum] = aida.histogram2D(String.format("%s/Trident/Trident-like Pair Position",
-            		singlesDir), 46, -23, 23, 11, -5.5, 5.5);
-		}
-	}
-	
-	/**
-	 * Populates the "failed" plots of the appropriate type with the
-	 * cut results from the argument trigger.
-	 * @param trigger - The trigger from which to populate the plots.
-	 */
-	public void failedTrigger(Trigger<?> trigger) {
-		processTrigger(trigger, FAILED);
-	}
-	
-	/**
-	 * Populates the "matched" plots of the appropriate type with the
-	 * cut results from the argument trigger.
-	 * @param trigger - The trigger from which to populate the plots.
-	 */
-	public void matchedTrigger(Trigger<?> trigger) {
-		processTrigger(trigger, MATCHED);
-	}
-	
-	/**
-	 * Populates the "triggered" plots of the appropriate type with the
-	 * cut results from the argument trigger.
-	 * @param trigger - The trigger from which to populate the plots.
-	 */
-	public void passedTrigger(Trigger<?> trigger) {
-		processTrigger(trigger, TRIGGERED);
-	}
-	
-	/**
-	 * Indicates that a cluster was seen by a trigger and adds it to
-	 * the "no cuts" plots.
-	 * @param triggerNum - The number of the trigger.
-	 * @param cluster - The cluster that was seen.
-	 */
-	public void sawCluster(int triggerNum, Cluster cluster) {
-		processSingles(triggerNum, NO_CUTS, cluster);
-	}
-	
-	/**
-	 * Indicates that a cluster was seen by a trigger and adds it to
-	 * the "no cuts" plots.
-	 * @param triggerNum - The number of the trigger.
-	 * @param cluster - The cluster that was seen.
-	 */
-	public void sawCluster(int triggerNum, SSPCluster cluster) {
-		processSingles(triggerNum, NO_CUTS, cluster);
-	}
-	
-	/**
-	 * Indicates that a cluster pair was seen by a trigger and adds it
-	 * to the "no cuts" plots.
-	 * @param triggerNum - The number of the trigger.
-	 * @param pair - The cluster pair that was seen.
-	 */
-	public void sawPair(int triggerNum, Cluster[] pair) {
-		processPair(triggerNum, NO_CUTS, pair);
-	}
-	
-	/**
-	 * Indicates that a cluster pair was seen by a trigger and adds it
-	 * to the "no cuts" plots.
-	 * @param triggerNum - The number of the trigger.
-	 * @param pair - The cluster pair that was seen.
-	 */
-	public void sawPair(int triggerNum, SSPCluster[] pair) {
-		processPair(triggerNum, NO_CUTS, pair);
-	}
-	
-	/**
-	 * Populates the "all" plots of the appropriate type with the cut
-	 * results from the argument trigger.
-	 * @param trigger - The trigger from which to populate the plots.
-	 */
-	public void sawTrigger(Trigger<?> trigger) {
-		processTrigger(trigger, ALL);
-	}
-	
-	/**
-	 * Sets the energy slope conversion factor to be used to calculate
-	 * the energy slope value for plots.
-	 * @param triggerNum - The trigger for which the conversion factor
-	 * should be used.
-	 * @param value - The conversion factor in units of GeV/mm.
-	 */
-	public void setEnergySlopeParamF(int triggerNum, double value) {
-		// Make sure that the trigger number is valid.
-		if(triggerNum < 0 || triggerNum > 1) {
-			throw new IllegalArgumentException(String.format("Trigger number %d is not valid.", triggerNum));
-		}
-		
-		// Set the parameter.
-		energySlopeParamF[triggerNum] = value;
-	}
-	
-	/**
-	 * Populates the indicated type of plots of the appropriate type
-	 * for the argument trigger.
-	 * @param trigger - The trigger from which to populate the plots.
-	 * @param plotType - The type of plot to populate. This must be one
-	 * of <code>ALL</code>, <code>MATCHED</code>, or <code>FAILED</code>.
-	 */
-	private void processTrigger(Trigger<?> trigger, int plotType) {
-		// Get the trigger number and source.
-		Object source = trigger.getTriggerSource();
-		int triggerNum = trigger.getTriggerNumber();
-		
-		// Populate the plots using the appropriate method.
-		if(source instanceof Cluster) {
-			processSingles(triggerNum, plotType, (Cluster) source);
-		}
-		else if(source instanceof SSPCluster) {
-			processSingles(triggerNum, plotType, (SSPCluster) source);
-		}
-		else if(source instanceof Cluster[]) {
-			processPair(triggerNum, plotType, (Cluster[]) source);
-		}
-		else if(source instanceof SSPCluster[]) {
-			processPair(triggerNum, plotType, (SSPCluster[]) source);
-		}
-		
-		// If the trigger source is unsupported, produce an error.
-		else {
-			throw new IllegalArgumentException(String.format("Trigger source \"%s\" is not supported.", source.getClass().getSimpleName()));
-		}
-	}
-	
-	/**
-	 * Populates the trigger singles plots for the indicated type for
-	 * reconstructed clusters.
-	 * @param triggerNum - The trigger number of the source trigger.
-	 * @param plotType - The type of plot to populate. This must be one
-	 * of <code>ALL</code>, <code>MATCHED</code>, or <code>FAILED</code>.
-	 * @param pair - The triggering cluster.
-	 */
-	private void processSingles(int triggerNum, int plotType, Cluster cluster) {
-		// Fill the cluster singles plots.
-		singlesHitCountPlot[triggerNum][RECON][plotType].fill(TriggerModule.getValueClusterHitCount(cluster));
-		singlesClusterEnergyPlot[triggerNum][RECON][plotType].fill(TriggerModule.getValueClusterTotalEnergy(cluster));
-		singlesTriggerTimePlot[triggerNum][RECON][plotType].fill(cluster.getCalorimeterHits().get(0).getTime());
-	}
-	
-	/**
-	 * Populates the trigger singles plots for the indicated type for SSP
-	 * clusters.
-	 * @param triggerNum - The trigger number of the source trigger.
-	 * @param plotType - The type of plot to populate. This must be one
-	 * of <code>ALL</code>, <code>MATCHED</code>, or <code>FAILED</code>.
-	 * @param pair - The triggering cluster.
-	 */
-	private void processSingles(int triggerNum, int plotType, SSPCluster cluster) {
-		// Fill the cluster singles plots.
-		singlesHitCountPlot[triggerNum][SSP][plotType].fill(TriggerModule.getValueClusterHitCount(cluster));
-		singlesClusterEnergyPlot[triggerNum][SSP][plotType].fill(TriggerModule.getValueClusterTotalEnergy(cluster));
-		singlesTriggerTimePlot[triggerNum][SSP][plotType].fill(cluster.getTime());
-		
-		// Check if this cluster is "trident-like."
-		// TODO: Define "trident-like."
-		boolean processTrident = false;
-		
-		// If this is a trident-like event, add it to the trident plots.
-		if(processTrident) {
-			tridentHitCountPlot[triggerNum].fill(TriggerModule.getValueClusterHitCount(cluster));
-			tridentClusterEnergyPlot[triggerNum].fill(TriggerModule.getValueClusterTotalEnergy(cluster));
-			tridentPositionPlot[triggerNum].fill(cluster.getXIndex() > 0 ? cluster.getXIndex() - 1 : cluster.getXIndex(), cluster.getYIndex());
-		}
-	}
-	
-	/**
-	 * Populates the trigger pair plots for the indicated type for
-	 * reconstructed cluster pairs.
-	 * @param triggerNum - The trigger number of the source trigger.
-	 * @param plotType - The type of plot to populate. This must be one
-	 * of <code>ALL</code>, <code>MATCHED</code>, or <code>FAILED</code>.
-	 * @param pair - The triggering pair.
-	 */
-	private void processPair(int triggerNum, int plotType, Cluster[] pair) {
-		// Fill the cluster singles plots.
-		pairHitCountPlot[triggerNum][RECON][plotType].fill(TriggerModule.getValueClusterHitCount(pair[0]));
-		pairHitCountPlot[triggerNum][RECON][plotType].fill(TriggerModule.getValueClusterHitCount(pair[1]));
-		pairClusterEnergyPlot[triggerNum][RECON][plotType].fill(TriggerModule.getValueClusterTotalEnergy(pair[0]));
-		pairClusterEnergyPlot[triggerNum][RECON][plotType].fill(TriggerModule.getValueClusterTotalEnergy(pair[1]));
-		pairTriggerTimePlot[triggerNum][RECON][plotType].fill(pair[0].getCalorimeterHits().get(0).getTime());
-		pairTriggerTimePlot[triggerNum][RECON][plotType].fill(pair[1].getCalorimeterHits().get(0).getTime());
-		
-		// Fill the cluster pair plots.
-		pairTimePlot[triggerNum][RECON][plotType].fill(TriggerModule.getValueTimeCoincidence(pair));
-		pairSumPlot[triggerNum][RECON][plotType].fill(TriggerModule.getValueEnergySum(pair));
+                    singlesDir), 46, -23, 23, 11, -5.5, 5.5);
+        }
+    }
+    
+    /**
+     * Populates the "failed" plots of the appropriate type with the
+     * cut results from the argument trigger.
+     * @param trigger - The trigger from which to populate the plots.
+     */
+    public void failedTrigger(Trigger<?> trigger) {
+        processTrigger(trigger, FAILED);
+    }
+    
+    /**
+     * Populates the "matched" plots of the appropriate type with the
+     * cut results from the argument trigger.
+     * @param trigger - The trigger from which to populate the plots.
+     */
+    public void matchedTrigger(Trigger<?> trigger) {
+        processTrigger(trigger, MATCHED);
+    }
+    
+    /**
+     * Populates the "triggered" plots of the appropriate type with the
+     * cut results from the argument trigger.
+     * @param trigger - The trigger from which to populate the plots.
+     */
+    public void passedTrigger(Trigger<?> trigger) {
+        processTrigger(trigger, TRIGGERED);
+    }
+    
+    /**
+     * Indicates that a cluster was seen by a trigger and adds it to
+     * the "no cuts" plots.
+     * @param triggerNum - The number of the trigger.
+     * @param cluster - The cluster that was seen.
+     */
+    public void sawCluster(int triggerNum, Cluster cluster) {
+        processSingles(triggerNum, NO_CUTS, cluster);
+    }
+    
+    /**
+     * Indicates that a cluster was seen by a trigger and adds it to
+     * the "no cuts" plots.
+     * @param triggerNum - The number of the trigger.
+     * @param cluster - The cluster that was seen.
+     */
+    public void sawCluster(int triggerNum, SSPCluster cluster) {
+        processSingles(triggerNum, NO_CUTS, cluster);
+    }
+    
+    /**
+     * Indicates that a cluster pair was seen by a trigger and adds it
+     * to the "no cuts" plots.
+     * @param triggerNum - The number of the trigger.
+     * @param pair - The cluster pair that was seen.
+     */
+    public void sawPair(int triggerNum, Cluster[] pair) {
+        processPair(triggerNum, NO_CUTS, pair);
+    }
+    
+    /**
+     * Indicates that a cluster pair was seen by a trigger and adds it
+     * to the "no cuts" plots.
+     * @param triggerNum - The number of the trigger.
+     * @param pair - The cluster pair that was seen.
+     */
+    public void sawPair(int triggerNum, SSPCluster[] pair) {
+        processPair(triggerNum, NO_CUTS, pair);
+    }
+    
+    /**
+     * Populates the "all" plots of the appropriate type with the cut
+     * results from the argument trigger.
+     * @param trigger - The trigger from which to populate the plots.
+     */
+    public void sawTrigger(Trigger<?> trigger) {
+        processTrigger(trigger, ALL);
+    }
+    
+    /**
+     * Sets the energy slope conversion factor to be used to calculate
+     * the energy slope value for plots.
+     * @param triggerNum - The trigger for which the conversion factor
+     * should be used.
+     * @param value - The conversion factor in units of GeV/mm.
+     */
+    public void setEnergySlopeParamF(int triggerNum, double value) {
+        // Make sure that the trigger number is valid.
+        if(triggerNum < 0 || triggerNum > 1) {
+            throw new IllegalArgumentException(String.format("Trigger number %d is not valid.", triggerNum));
+        }
+        
+        // Set the parameter.
+        energySlopeParamF[triggerNum] = value;
+    }
+    
+    /**
+     * Populates the indicated type of plots of the appropriate type
+     * for the argument trigger.
+     * @param trigger - The trigger from which to populate the plots.
+     * @param plotType - The type of plot to populate. This must be one
+     * of <code>ALL</code>, <code>MATCHED</code>, or <code>FAILED</code>.
+     */
+    private void processTrigger(Trigger<?> trigger, int plotType) {
+        // Get the trigger number and source.
+        Object source = trigger.getTriggerSource();
+        int triggerNum = trigger.getTriggerNumber();
+        
+        // Populate the plots using the appropriate method.
+        if(source instanceof Cluster) {
+            processSingles(triggerNum, plotType, (Cluster) source);
+        }
+        else if(source instanceof SSPCluster) {
+            processSingles(triggerNum, plotType, (SSPCluster) source);
+        }
+        else if(source instanceof Cluster[]) {
+            processPair(triggerNum, plotType, (Cluster[]) source);
+        }
+        else if(source instanceof SSPCluster[]) {
+            processPair(triggerNum, plotType, (SSPCluster[]) source);
+        }
+        
+        // If the trigger source is unsupported, produce an error.
+        else {
+            throw new IllegalArgumentException(String.format("Trigger source \"%s\" is not supported.", source.getClass().getSimpleName()));
+        }
+    }
+    
+    /**
+     * Populates the trigger singles plots for the indicated type for
+     * reconstructed clusters.
+     * @param triggerNum - The trigger number of the source trigger.
+     * @param plotType - The type of plot to populate. This must be one
+     * of <code>ALL</code>, <code>MATCHED</code>, or <code>FAILED</code>.
+     * @param pair - The triggering cluster.
+     */
+    private void processSingles(int triggerNum, int plotType, Cluster cluster) {
+        // Fill the cluster singles plots.
+        singlesHitCountPlot[triggerNum][RECON][plotType].fill(TriggerModule.getValueClusterHitCount(cluster));
+        singlesClusterEnergyPlot[triggerNum][RECON][plotType].fill(TriggerModule.getValueClusterTotalEnergy(cluster));
+        singlesTriggerTimePlot[triggerNum][RECON][plotType].fill(cluster.getCalorimeterHits().get(0).getTime());
+    }
+    
+    /**
+     * Populates the trigger singles plots for the indicated type for SSP
+     * clusters.
+     * @param triggerNum - The trigger number of the source trigger.
+     * @param plotType - The type of plot to populate. This must be one
+     * of <code>ALL</code>, <code>MATCHED</code>, or <code>FAILED</code>.
+     * @param pair - The triggering cluster.
+     */
+    private void processSingles(int triggerNum, int plotType, SSPCluster cluster) {
+        // Fill the cluster singles plots.
+        singlesHitCountPlot[triggerNum][SSP][plotType].fill(TriggerModule.getValueClusterHitCount(cluster));
+        singlesClusterEnergyPlot[triggerNum][SSP][plotType].fill(TriggerModule.getValueClusterTotalEnergy(cluster));
+        singlesTriggerTimePlot[triggerNum][SSP][plotType].fill(cluster.getTime());
+        
+        // Check if this cluster is "trident-like."
+        // TODO: Define "trident-like."
+        boolean processTrident = false;
+        
+        // If this is a trident-like event, add it to the trident plots.
+        if(processTrident) {
+            tridentHitCountPlot[triggerNum].fill(TriggerModule.getValueClusterHitCount(cluster));
+            tridentClusterEnergyPlot[triggerNum].fill(TriggerModule.getValueClusterTotalEnergy(cluster));
+            tridentPositionPlot[triggerNum].fill(cluster.getXIndex() > 0 ? cluster.getXIndex() - 1 : cluster.getXIndex(), cluster.getYIndex());
+        }
+    }
+    
+    /**
+     * Populates the trigger pair plots for the indicated type for
+     * reconstructed cluster pairs.
+     * @param triggerNum - The trigger number of the source trigger.
+     * @param plotType - The type of plot to populate. This must be one
+     * of <code>ALL</code>, <code>MATCHED</code>, or <code>FAILED</code>.
+     * @param pair - The triggering pair.
+     */
+    private void processPair(int triggerNum, int plotType, Cluster[] pair) {
+        // Fill the cluster singles plots.
+        pairHitCountPlot[triggerNum][RECON][plotType].fill(TriggerModule.getValueClusterHitCount(pair[0]));
+        pairHitCountPlot[triggerNum][RECON][plotType].fill(TriggerModule.getValueClusterHitCount(pair[1]));
+        pairClusterEnergyPlot[triggerNum][RECON][plotType].fill(TriggerModule.getValueClusterTotalEnergy(pair[0]));
+        pairClusterEnergyPlot[triggerNum][RECON][plotType].fill(TriggerModule.getValueClusterTotalEnergy(pair[1]));
+        pairTriggerTimePlot[triggerNum][RECON][plotType].fill(pair[0].getCalorimeterHits().get(0).getTime());
+        pairTriggerTimePlot[triggerNum][RECON][plotType].fill(pair[1].getCalorimeterHits().get(0).getTime());
+        
+        // Fill the cluster pair plots.
+        pairTimePlot[triggerNum][RECON][plotType].fill(TriggerModule.getValueTimeCoincidence(pair));
+        pairSumPlot[triggerNum][RECON][plotType].fill(TriggerModule.getValueEnergySum(pair));
                 pairSumEnergiesPlot[triggerNum][RECON][plotType].fill(pair[0].getEnergy(), pair[1].getEnergy());
-		pairDiffPlot[triggerNum][RECON][plotType].fill(TriggerModule.getValueEnergyDifference(pair));
-		pairSlopePlot[triggerNum][RECON][plotType].fill(TriggerModule.getValueEnergySlope(pair, energySlopeParamF[triggerNum]));
-		pairCoplanarityPlot[triggerNum][RECON][plotType].fill(TriggerModule.getValueCoplanarity(pair));
-	}
-	
-	/**
-	 * Populates the trigger pair plots for the indicated type for SSP
-	 * cluster pairs.
-	 * @param triggerNum - The trigger number of the source trigger.
-	 * @param plotType - The type of plot to populate. This must be one
-	 * of <code>ALL</code>, <code>MATCHED</code>, or <code>FAILED</code>.
-	 * @param pair - The triggering pair.
-	 */
-	private void processPair(int triggerNum, int plotType, SSPCluster[] pair) {
-		// Fill the cluster singles plots.
-		pairHitCountPlot[triggerNum][SSP][plotType].fill(TriggerModule.getValueClusterHitCount(pair[0]));
-		pairHitCountPlot[triggerNum][SSP][plotType].fill(TriggerModule.getValueClusterHitCount(pair[1]));
-		pairClusterEnergyPlot[triggerNum][SSP][plotType].fill(TriggerModule.getValueClusterTotalEnergy(pair[0]));
-		pairClusterEnergyPlot[triggerNum][SSP][plotType].fill(TriggerModule.getValueClusterTotalEnergy(pair[1]));
-		pairTriggerTimePlot[triggerNum][SSP][plotType].fill(pair[0].getTime());
-		pairTriggerTimePlot[triggerNum][SSP][plotType].fill(pair[1].getTime());
-		
-		// Fill the cluster pair plots.
-		pairTimePlot[triggerNum][SSP][plotType].fill(TriggerModule.getValueTimeCoincidence(pair));
-		pairSumPlot[triggerNum][SSP][plotType].fill(TriggerModule.getValueEnergySum(pair));
+        pairDiffPlot[triggerNum][RECON][plotType].fill(TriggerModule.getValueEnergyDifference(pair));
+        pairSlopePlot[triggerNum][RECON][plotType].fill(TriggerModule.getValueEnergySlope(pair, energySlopeParamF[triggerNum]));
+        pairCoplanarityPlot[triggerNum][RECON][plotType].fill(TriggerModule.getValueCoplanarity(pair));
+    }
+    
+    /**
+     * Populates the trigger pair plots for the indicated type for SSP
+     * cluster pairs.
+     * @param triggerNum - The trigger number of the source trigger.
+     * @param plotType - The type of plot to populate. This must be one
+     * of <code>ALL</code>, <code>MATCHED</code>, or <code>FAILED</code>.
+     * @param pair - The triggering pair.
+     */
+    private void processPair(int triggerNum, int plotType, SSPCluster[] pair) {
+        // Fill the cluster singles plots.
+        pairHitCountPlot[triggerNum][SSP][plotType].fill(TriggerModule.getValueClusterHitCount(pair[0]));
+        pairHitCountPlot[triggerNum][SSP][plotType].fill(TriggerModule.getValueClusterHitCount(pair[1]));
+        pairClusterEnergyPlot[triggerNum][SSP][plotType].fill(TriggerModule.getValueClusterTotalEnergy(pair[0]));
+        pairClusterEnergyPlot[triggerNum][SSP][plotType].fill(TriggerModule.getValueClusterTotalEnergy(pair[1]));
+        pairTriggerTimePlot[triggerNum][SSP][plotType].fill(pair[0].getTime());
+        pairTriggerTimePlot[triggerNum][SSP][plotType].fill(pair[1].getTime());
+        
+        // Fill the cluster pair plots.
+        pairTimePlot[triggerNum][SSP][plotType].fill(TriggerModule.getValueTimeCoincidence(pair));
+        pairSumPlot[triggerNum][SSP][plotType].fill(TriggerModule.getValueEnergySum(pair));
         pairSumEnergiesPlot[triggerNum][SSP][plotType].fill(pair[0].getEnergy(), pair[1].getEnergy());
-		pairDiffPlot[triggerNum][SSP][plotType].fill(TriggerModule.getValueEnergyDifference(pair));
-		pairSlopePlot[triggerNum][SSP][plotType].fill(TriggerModule.getValueEnergySlope(pair, energySlopeParamF[triggerNum]));
-		pairCoplanarityPlot[triggerNum][SSP][plotType].fill(TriggerModule.getValueCoplanarity(pair));
-		
-		// Check if this pair is "Møller-like."
-		boolean processMøller = TriggerModule.getValueEnergySum(pair) >= MØLLER_SUM_THRESHOLD;
-		
-		// If the pair is Møller-like, populate the Møller plots.
-		if(processMøller) {
-			// Fill the cluster singles plots.
-			møllerHitCountPlot[triggerNum].fill(TriggerModule.getValueClusterHitCount(pair[0]));
-			møllerHitCountPlot[triggerNum].fill(TriggerModule.getValueClusterHitCount(pair[1]));
-			møllerClusterEnergyPlot[triggerNum].fill(TriggerModule.getValueClusterTotalEnergy(pair[0]));
-			møllerClusterEnergyPlot[triggerNum].fill(TriggerModule.getValueClusterTotalEnergy(pair[1]));
-			møllerTriggerTimePlot[triggerNum].fill(pair[0].getTime());
-			møllerTriggerTimePlot[triggerNum].fill(pair[1].getTime());
-			møllerPositionPlot[triggerNum].fill(pair[0].getXIndex() > 0 ? pair[0].getXIndex() - 1 : pair[0].getXIndex(), pair[0].getYIndex());
-			møllerPositionPlot[triggerNum].fill(pair[1].getXIndex() > 0 ? pair[1].getXIndex() - 1 : pair[1].getXIndex(), pair[1].getYIndex());
-			
-			// Fill the cluster pair plots.
-			møllerTimePlot[triggerNum].fill(TriggerModule.getValueTimeCoincidence(pair));
-			møllerSumPlot[triggerNum].fill(TriggerModule.getValueEnergySum(pair));
-			møllerSumEnergiesPlot[triggerNum].fill(pair[0].getEnergy(), pair[1].getEnergy());
-	        møllerDiffPlot[triggerNum].fill(TriggerModule.getValueEnergyDifference(pair));
-	        møllerSlopePlot[triggerNum].fill(TriggerModule.getValueEnergySlope(pair, energySlopeParamF[triggerNum]));
-	        møllerCoplanarityPlot[triggerNum].fill(TriggerModule.getValueCoplanarity(pair));
-		}
-	}
+        pairDiffPlot[triggerNum][SSP][plotType].fill(TriggerModule.getValueEnergyDifference(pair));
+        pairSlopePlot[triggerNum][SSP][plotType].fill(TriggerModule.getValueEnergySlope(pair, energySlopeParamF[triggerNum]));
+        pairCoplanarityPlot[triggerNum][SSP][plotType].fill(TriggerModule.getValueCoplanarity(pair));
+        
+        // Check if this pair is "Møller-like."
+        boolean processMøller = TriggerModule.getValueEnergySum(pair) >= MØLLER_SUM_THRESHOLD;
+        
+        // If the pair is Møller-like, populate the Møller plots.
+        if(processMøller) {
+            // Fill the cluster singles plots.
+            møllerHitCountPlot[triggerNum].fill(TriggerModule.getValueClusterHitCount(pair[0]));
+            møllerHitCountPlot[triggerNum].fill(TriggerModule.getValueClusterHitCount(pair[1]));
+            møllerClusterEnergyPlot[triggerNum].fill(TriggerModule.getValueClusterTotalEnergy(pair[0]));
+            møllerClusterEnergyPlot[triggerNum].fill(TriggerModule.getValueClusterTotalEnergy(pair[1]));
+            møllerTriggerTimePlot[triggerNum].fill(pair[0].getTime());
+            møllerTriggerTimePlot[triggerNum].fill(pair[1].getTime());
+            møllerPositionPlot[triggerNum].fill(pair[0].getXIndex() > 0 ? pair[0].getXIndex() - 1 : pair[0].getXIndex(), pair[0].getYIndex());
+            møllerPositionPlot[triggerNum].fill(pair[1].getXIndex() > 0 ? pair[1].getXIndex() - 1 : pair[1].getXIndex(), pair[1].getYIndex());
+            
+            // Fill the cluster pair plots.
+            møllerTimePlot[triggerNum].fill(TriggerModule.getValueTimeCoincidence(pair));
+            møllerSumPlot[triggerNum].fill(TriggerModule.getValueEnergySum(pair));
+            møllerSumEnergiesPlot[triggerNum].fill(pair[0].getEnergy(), pair[1].getEnergy());
+            møllerDiffPlot[triggerNum].fill(TriggerModule.getValueEnergyDifference(pair));
+            møllerSlopePlot[triggerNum].fill(TriggerModule.getValueEnergySlope(pair, energySlopeParamF[triggerNum]));
+            møllerCoplanarityPlot[triggerNum].fill(TriggerModule.getValueCoplanarity(pair));
+        }
+    }
 }

Modified: java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/util/ComponentUtils.java
 =============================================================================
--- java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/util/ComponentUtils.java	(original)
+++ java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/util/ComponentUtils.java	Wed Apr 27 11:11:32 2016
@@ -1,8 +1,6 @@
 package org.hps.analysis.trigger.util;
 
 import java.awt.Component;
-
-import org.hps.analysis.trigger.util.TriggerDiagnosticUtil;
 
 /**
  * Class <code>ComponentUtils</code> is a list of utility methods used
@@ -11,116 +9,116 @@
  * @author Kyle McCarty <[log in to unmask]>
  */
 public class ComponentUtils {
-	/** The default spacing used between a horizontal edge of one
-	 * component and the horizontal edge of another. */
-	public static final int hinternal = 10;
-	/** The default spacing used between a vertical edge of one
-	 * component and the vertical edge of another. */
-	public static final int vinternal = 10;
-	/** The default spacing used between a horizontal edge of one
-	 * component and the edge of its parent component. */
-	public static final int hexternal = 0;
-	/** The default spacing used between a vertical edge of one
-	 * component and the edge of its parent component. */
-	public static final int vexternal = 0;
-	
-	/**
-	 * Gets a <code>String</code> composed of a number of instances of
-	 * character <code>c</code> equal to <code>number</code>.
-	 * @param c - The character to repeat.
-	 * @param number - The number of repetitions.
-	 * @return Returns the repeated character as a <code>String</code>.
-	 */
-	public static final String getChars(char c, int number) {
-		// Create a buffer to store the characters in.
-		StringBuffer s = new StringBuffer();
-		
-		// Add the indicated number of instances.
-		for(int i = 0; i < number; i++) {
-			s.append(c);
-		}
-		
-		// Return the string.
-		return s.toString();
-	}
-	
-	/**
-	 * Gets the number of digits in the base-10 String representation
-	 * of an integer primitive. Negative signs are not included in the
-	 * digit count.
-	 * @param value - The value of which to obtain the length.
-	 * @return Returns the number of digits in the String representation
-	 * of the argument value.
-	 */
-	public static final int getDigits(int value) {
-		return TriggerDiagnosticUtil.getDigits(value);
-	}
-	
-	/**
-	 * Gets the maximum value from a list of values.
-	 * @param values - The values to compare.
-	 * @return Returns the largest of the argument values.
-	 * @throws IllegalArgumentException Occurs if no values are given.
-	 */
-	public static final int max(int... values) throws IllegalArgumentException {
-		// Throw an error if no arguments are provided.
-		if(values == null || values.length == 0) {
-			throw new IllegalArgumentException("Can not determine maximum value from a list of 0 values.");
-		}
-		
-		// If there is only one value, return it.
-		if(values.length == 1) { return values[0]; }
-		
-		// Otherwise, get the largest value.
-		int largest = Integer.MIN_VALUE;
-		for(int value : values) {
-			if(value > largest) { largest = value; }
-		}
-		
-		// Return the result.
-		return largest;
-	}
-	
-	/**
-	 * Gets the x-coordinate immediately to the right of the given
-	 * component.
-	 * @param c - The component of which to find the edge.
-	 * @return Returns the x-coordinate as an <code>int</code> value.
-	 */
-	public static final int getNextX(Component c) {
-		return getNextX(c, 0);
-	}
-	
-	/**
-	 * Gets the x-coordinate a given distance to the right edge of the
-	 * argument component.
-	 * @param c - The component of which to find the edge.
-	 * @param spacing - The additional spacing past the edge of the
-	 * component to add.
-	 * @return Returns the x-coordinate as an <code>int</code> value.
-	 */
-	public static final int getNextX(Component c, int spacing) {
-		return c.getX() + c.getWidth() + spacing;
-	}
-	
-	/**
-	 * Gets the y-coordinate immediately below the given component.
-	 * @param c - The component of which to find the edge.
-	 * @return Returns the y-coordinate as an <code>int</code> value.
-	 */
-	public static final int getNextY(Component c) {
-		return getNextY(c, 0);
-	}
-	
-	/**
-	 * Gets the y-coordinate a given distance below the bottom edge
-	 * of the argument component.
-	 * @param c - The component of which to find the edge.
-	 * @param spacing - The additional spacing past the edge of the
-	 * component to add.
-	 * @return Returns the y-coordinate as an <code>int</code> value.
-	 */
-	public static final int getNextY(Component c, int spacing) {
-		return c.getY() + c.getHeight() + spacing;
-	}
+    /** The default spacing used between a horizontal edge of one
+     * component and the horizontal edge of another. */
+    public static final int hinternal = 10;
+    /** The default spacing used between a vertical edge of one
+     * component and the vertical edge of another. */
+    public static final int vinternal = 10;
+    /** The default spacing used between a horizontal edge of one
+     * component and the edge of its parent component. */
+    public static final int hexternal = 0;
+    /** The default spacing used between a vertical edge of one
+     * component and the edge of its parent component. */
+    public static final int vexternal = 0;
+    
+    /**
+     * Gets a <code>String</code> composed of a number of instances of
+     * character <code>c</code> equal to <code>number</code>.
+     * @param c - The character to repeat.
+     * @param number - The number of repetitions.
+     * @return Returns the repeated character as a <code>String</code>.
+     */
+    public static final String getChars(char c, int number) {
+        // Create a buffer to store the characters in.
+        StringBuffer s = new StringBuffer();
+        
+        // Add the indicated number of instances.
+        for(int i = 0; i < number; i++) {
+            s.append(c);
+        }
+        
+        // Return the string.
+        return s.toString();
+    }
+    
+    /**
+     * Gets the number of digits in the base-10 String representation
+     * of an integer primitive. Negative signs are not included in the
+     * digit count.
+     * @param value - The value of which to obtain the length.
+     * @return Returns the number of digits in the String representation
+     * of the argument value.
+     */
+    public static final int getDigits(int value) {
+        return TriggerDiagnosticUtil.getDigits(value);
+    }
+    
+    /**
+     * Gets the maximum value from a list of values.
+     * @param values - The values to compare.
+     * @return Returns the largest of the argument values.
+     * @throws IllegalArgumentException Occurs if no values are given.
+     */
+    public static final int max(int... values) throws IllegalArgumentException {
+        // Throw an error if no arguments are provided.
+        if(values == null || values.length == 0) {
+            throw new IllegalArgumentException("Can not determine maximum value from a list of 0 values.");
+        }
+        
+        // If there is only one value, return it.
+        if(values.length == 1) { return values[0]; }
+        
+        // Otherwise, get the largest value.
+        int largest = Integer.MIN_VALUE;
+        for(int value : values) {
+            if(value > largest) { largest = value; }
+        }
+        
+        // Return the result.
+        return largest;
+    }
+    
+    /**
+     * Gets the x-coordinate immediately to the right of the given
+     * component.
+     * @param c - The component of which to find the edge.
+     * @return Returns the x-coordinate as an <code>int</code> value.
+     */
+    public static final int getNextX(Component c) {
+        return getNextX(c, 0);
+    }
+    
+    /**
+     * Gets the x-coordinate a given distance to the right edge of the
+     * argument component.
+     * @param c - The component of which to find the edge.
+     * @param spacing - The additional spacing past the edge of the
+     * component to add.
+     * @return Returns the x-coordinate as an <code>int</code> value.
+     */
+    public static final int getNextX(Component c, int spacing) {
+        return c.getX() + c.getWidth() + spacing;
+    }
+    
+    /**
+     * Gets the y-coordinate immediately below the given component.
+     * @param c - The component of which to find the edge.
+     * @return Returns the y-coordinate as an <code>int</code> value.
+     */
+    public static final int getNextY(Component c) {
+        return getNextY(c, 0);
+    }
+    
+    /**
+     * Gets the y-coordinate a given distance below the bottom edge
+     * of the argument component.
+     * @param c - The component of which to find the edge.
+     * @param spacing - The additional spacing past the edge of the
+     * component to add.
+     * @return Returns the y-coordinate as an <code>int</code> value.
+     */
+    public static final int getNextY(Component c, int spacing) {
+        return c.getY() + c.getHeight() + spacing;
+    }
 }

Modified: java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/util/OutputLogger.java
 =============================================================================
--- java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/util/OutputLogger.java	(original)
+++ java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/util/OutputLogger.java	Wed Apr 27 11:11:32 2016
@@ -3,28 +3,28 @@
 public class OutputLogger {
     private static StringBuffer outputBuffer = new StringBuffer();
     
-	public static final void printf(String text, Object... args) {
-		outputBuffer.append(String.format(text, args));
-	}
-	
-	public static final void println() { printf(String.format("%n")); }
-	
-	public static final void println(String text) { printf(String.format("%s%n", text)); }
-	
-	public static final void print(String text) { printf(text); }
-	
-	public static final void printLog() {
-		System.out.println(outputBuffer.toString());
-		clearLog();
-	}
-	
-	public static final void printNewLine() { println(); }
-	
-	public static final void printNewLine(int quantity) {
-		for(int i = 0; i < quantity; i++) { println(); }
-	}
-	
-	public static final void clearLog() {
-		outputBuffer = new StringBuffer();
-	}
+    public static final void printf(String text, Object... args) {
+        outputBuffer.append(String.format(text, args));
+    }
+    
+    public static final void println() { printf(String.format("%n")); }
+    
+    public static final void println(String text) { printf(String.format("%s%n", text)); }
+    
+    public static final void print(String text) { printf(text); }
+    
+    public static final void printLog() {
+        System.out.println(outputBuffer.toString());
+        clearLog();
+    }
+    
+    public static final void printNewLine() { println(); }
+    
+    public static final void printNewLine(int quantity) {
+        for(int i = 0; i < quantity; i++) { println(); }
+    }
+    
+    public static final void clearLog() {
+        outputBuffer = new StringBuffer();
+    }
 }

Modified: java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/util/Pair.java
 =============================================================================
--- java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/util/Pair.java	(original)
+++ java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/util/Pair.java	Wed Apr 27 11:11:32 2016
@@ -8,32 +8,32 @@
  * @param <F> - The object type of the second element in the pair.
  */
 public class Pair<E, F> {
-	private final E firstObject;
-	private final F secondObject;
-	
-	/**
-	 * Creates a pair of the two indicated objects.
-	 * @param firstObject - The first object.
-	 * @param secondObject - The second object.
-	 */
-	public Pair(E firstElement, F secondElement) {
-		this.firstObject = firstElement;
-		this.secondObject = secondElement;
-	}
-	
-	/**
-	 * Gets the first element of the pair.
-	 * @return Returns the first element.
-	 */
-	public E getFirstElement() {
-		return firstObject;
-	}
-	
-	/**
-	 * Gets the second element of the pair.
-	 * @return Returns the second element.
-	 */
-	public F getSecondElement() {
-		return secondObject;
-	}
+    private final E firstObject;
+    private final F secondObject;
+    
+    /**
+     * Creates a pair of the two indicated objects.
+     * @param firstElement - The first object.
+     * @param secondElement - The second object.
+     */
+    public Pair(E firstElement, F secondElement) {
+        this.firstObject = firstElement;
+        this.secondObject = secondElement;
+    }
+    
+    /**
+     * Gets the first element of the pair.
+     * @return Returns the first element.
+     */
+    public E getFirstElement() {
+        return firstObject;
+    }
+    
+    /**
+     * Gets the second element of the pair.
+     * @return Returns the second element.
+     */
+    public F getSecondElement() {
+        return secondObject;
+    }
 }

Modified: java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/util/PairTrigger.java
 =============================================================================
--- java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/util/PairTrigger.java	(original)
+++ java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/util/PairTrigger.java	Wed Apr 27 11:11:32 2016
@@ -3,164 +3,164 @@
 import org.hps.record.triggerbank.TriggerModule;
 
 public class PairTrigger<E> extends SinglesTrigger<E> {
-	// Define the supported trigger cuts.
-	private static final String PAIR_ENERGY_SUM_LOW = TriggerModule.PAIR_ENERGY_SUM_LOW;
-	private static final String PAIR_ENERGY_SUM_HIGH = TriggerModule.PAIR_ENERGY_SUM_HIGH;
-	private static final String PAIR_ENERGY_DIFFERENCE_HIGH = TriggerModule.PAIR_ENERGY_DIFFERENCE_HIGH;
-	private static final String PAIR_ENERGY_SLOPE_LOW = TriggerModule.PAIR_ENERGY_SLOPE_LOW;
-	private static final String PAIR_COPLANARITY_HIGH = TriggerModule.PAIR_COPLANARITY_HIGH;
+    // Define the supported trigger cuts.
+    private static final String PAIR_ENERGY_SUM_LOW = TriggerModule.PAIR_ENERGY_SUM_LOW;
+    private static final String PAIR_ENERGY_SUM_HIGH = TriggerModule.PAIR_ENERGY_SUM_HIGH;
+    private static final String PAIR_ENERGY_DIFFERENCE_HIGH = TriggerModule.PAIR_ENERGY_DIFFERENCE_HIGH;
+    private static final String PAIR_ENERGY_SLOPE_LOW = TriggerModule.PAIR_ENERGY_SLOPE_LOW;
+    private static final String PAIR_COPLANARITY_HIGH = TriggerModule.PAIR_COPLANARITY_HIGH;
     private static final String PAIR_TIME_COINCIDENCE = "pairTimeCoincidence";
-	
-	/**
-	 * Instantiates a new <code>PairTrigger</code> with all cut
-	 * states set to <code>false</code> and with the trigger source
-	 * defined according to the specified object.
-	 * @param source - The object from which the trigger cut states
-	 * are derived.
-	 */
-	public PairTrigger(E source, int triggerNum) {
-		// Instantiate the superclass.
-		super(source, triggerNum);
-		
-		// Add the supported cuts types.
-		addValidCut(PAIR_ENERGY_SUM_LOW);
-		addValidCut(PAIR_ENERGY_SUM_HIGH);
-		addValidCut(PAIR_ENERGY_DIFFERENCE_HIGH);
-		addValidCut(PAIR_ENERGY_SLOPE_LOW);
-		addValidCut(PAIR_COPLANARITY_HIGH);
-		addValidCut(PAIR_TIME_COINCIDENCE);
-	}
-	
-	/**
-	 * Gets whether the pair energy sum lower bound cut was met.
-	 * @return Returns <code>true</code> if the cut was met and
-	 * <code>false</code> otherwise.
-	 */
-	public boolean getStateEnergySumLow() {
-		return getCutState(PAIR_ENERGY_SUM_LOW);
-	}
-	
-	/**
-	 * Gets whether the pair energy sum upper bound cut was met.
-	 * @return Returns <code>true</code> if the cut was met and
-	 * <code>false</code> otherwise.
-	 */
-	public boolean getStateEnergySumHigh() {
-		return getCutState(PAIR_ENERGY_SUM_HIGH);
-	}
-	
-	/**
-	 * Gets whether both the pair energy sum upper and lower bound cuts
-	 * were met.
-	 * @return Returns <code>true</code> if the cuts were met and
-	 * <code>false</code> otherwise.
-	 */
-	public boolean getStateEnergySum() {
-		return getCutState(PAIR_ENERGY_SUM_HIGH);
-	}
-	
-	/**
-	 * Gets whether the pair energy difference cut was met.
-	 * @return Returns <code>true</code> if the cut was met and
-	 * <code>false</code> otherwise.
-	 */
-	public boolean getStateEnergyDifference() {
-		return getCutState(PAIR_ENERGY_DIFFERENCE_HIGH);
-	}
-	
-	/**
-	 * Gets whether the pair energy slope cut was met.
-	 * @return Returns <code>true</code> if the cut was met and
-	 * <code>false</code> otherwise.
-	 */
-	public boolean getStateEnergySlope() {
-		return getCutState(PAIR_ENERGY_SLOPE_LOW);
-	}
-	
-	/**
-	 * Gets whether the pair coplanarity cut was met.
-	 * @return Returns <code>true</code> if the cut was met and
-	 * <code>false</code> otherwise.
-	 */
-	public boolean getStateCoplanarity() {
-		return getCutState(PAIR_COPLANARITY_HIGH);
-	}
-	
-	/**
-	 * Gets whether the time coincidence cut was met.
-	 * @return Returns <code>true</code> if the cut was met and
-	 * <code>false</code> otherwise.
-	 */
-	public boolean getStateTimeCoincidence() {
-		return getCutState(PAIR_TIME_COINCIDENCE);
-	}
-	
-	/**
-	 * Sets whether the conditions for the pair energy sum lower bound
-	 * cut were met.
-	 * @param state - <code>true</code> indicates that the cut conditions
-	 * were met and <code>false</code> that they were not.
-	 */
-	public void setStateEnergySumLow(boolean state) {
-		setCutState(PAIR_ENERGY_SUM_LOW, state);
-	}
-	
-	/**
-	 * Sets whether the conditions for the pair energy sum upper bound
-	 * cut were met.
-	 * @param state - <code>true</code> indicates that the cut conditions
-	 * were met and <code>false</code> that they were not.
-	 */
-	public void setStateEnergySumHigh(boolean state) {
-		setCutState(PAIR_ENERGY_SUM_HIGH, state);
-	}
-	
-	/**
-	 * Sets whether the conditions for the pair energy difference cut
-	 * were met.
-	 * @param state - <code>true</code> indicates that the cut conditions
-	 * were met and <code>false</code> that they were not.
-	 */
-	public void setStateEnergyDifference(boolean state) {
-		setCutState(PAIR_ENERGY_DIFFERENCE_HIGH, state);
-	}
-	
-	/**
-	 * Sets whether the conditions for the pair energy slope cut were
-	 * met.
-	 * @param state - <code>true</code> indicates that the cut conditions
-	 * were met and <code>false</code> that they were not.
-	 */
-	public void setStateEnergySlope(boolean state) {
-		setCutState(PAIR_ENERGY_SLOPE_LOW, state);
-	}
-	
-	/**
-	 * Sets whether the conditions for the pair coplanarity cut were
-	 * met.
-	 * @param state - <code>true</code> indicates that the cut conditions
-	 * were met and <code>false</code> that they were not.
-	 */
-	public void setStateCoplanarity(boolean state) {
-		setCutState(PAIR_COPLANARITY_HIGH, state);
-	}
-	
-	/**
-	 * Sets whether the conditions for the time coincidence cut were
-	 * met.
-	 * @param state - <code>true</code> indicates that the cut conditions
-	 * were met and <code>false</code> that they were not.
-	 */
-	public void setStateTimeCoincidence(boolean state) {
-		setCutState(PAIR_TIME_COINCIDENCE, state);
-	}
-	
-	@Override
-	public String toString() {
-		return String.format("EClusterLow: %d; EClusterHigh %d; HitCount: %d; ESumLow: %d, ESumHigh: %d, EDiff: %d, ESlope: %d, Coplanarity: %d",
-				getStateClusterEnergyLow() ? 1 : 0, getStateClusterEnergyHigh() ? 1 : 0,
-				getStateHitCount() ? 1 : 0, getStateEnergySumLow() ? 1 : 0,
-				getStateEnergySumHigh() ? 1 : 0, getStateEnergyDifference() ? 1 : 0,
-				getStateEnergySlope() ? 1 : 0, getStateCoplanarity() ? 1 : 0);
-	}
-}
+    
+    /**
+     * Instantiates a new <code>PairTrigger</code> with all cut
+     * states set to <code>false</code> and with the trigger source
+     * defined according to the specified object.
+     * @param source - The object from which the trigger cut states
+     * are derived.
+     */
+    public PairTrigger(E source, int triggerNum) {
+        // Instantiate the superclass.
+        super(source, triggerNum);
+        
+        // Add the supported cuts types.
+        addValidCut(PAIR_ENERGY_SUM_LOW);
+        addValidCut(PAIR_ENERGY_SUM_HIGH);
+        addValidCut(PAIR_ENERGY_DIFFERENCE_HIGH);
+        addValidCut(PAIR_ENERGY_SLOPE_LOW);
+        addValidCut(PAIR_COPLANARITY_HIGH);
+        addValidCut(PAIR_TIME_COINCIDENCE);
+    }
+    
+    /**
+     * Gets whether the pair energy sum lower bound cut was met.
+     * @return Returns <code>true</code> if the cut was met and
+     * <code>false</code> otherwise.
+     */
+    public boolean getStateEnergySumLow() {
+        return getCutState(PAIR_ENERGY_SUM_LOW);
+    }
+    
+    /**
+     * Gets whether the pair energy sum upper bound cut was met.
+     * @return Returns <code>true</code> if the cut was met and
+     * <code>false</code> otherwise.
+     */
+    public boolean getStateEnergySumHigh() {
+        return getCutState(PAIR_ENERGY_SUM_HIGH);
+    }
+    
+    /**
+     * Gets whether both the pair energy sum upper and lower bound cuts
+     * were met.
+     * @return Returns <code>true</code> if the cuts were met and
+     * <code>false</code> otherwise.
+     */
+    public boolean getStateEnergySum() {
+        return getCutState(PAIR_ENERGY_SUM_HIGH);
+    }
+    
+    /**
+     * Gets whether the pair energy difference cut was met.
+     * @return Returns <code>true</code> if the cut was met and
+     * <code>false</code> otherwise.
+     */
+    public boolean getStateEnergyDifference() {
+        return getCutState(PAIR_ENERGY_DIFFERENCE_HIGH);
+    }
+    
+    /**
+     * Gets whether the pair energy slope cut was met.
+     * @return Returns <code>true</code> if the cut was met and
+     * <code>false</code> otherwise.
+     */
+    public boolean getStateEnergySlope() {
+        return getCutState(PAIR_ENERGY_SLOPE_LOW);
+    }
+    
+    /**
+     * Gets whether the pair coplanarity cut was met.
+     * @return Returns <code>true</code> if the cut was met and
+     * <code>false</code> otherwise.
+     */
+    public boolean getStateCoplanarity() {
+        return getCutState(PAIR_COPLANARITY_HIGH);
+    }
+    
+    /**
+     * Gets whether the time coincidence cut was met.
+     * @return Returns <code>true</code> if the cut was met and
+     * <code>false</code> otherwise.
+     */
+    public boolean getStateTimeCoincidence() {
+        return getCutState(PAIR_TIME_COINCIDENCE);
+    }
+    
+    /**
+     * Sets whether the conditions for the pair energy sum lower bound
+     * cut were met.
+     * @param state - <code>true</code> indicates that the cut conditions
+     * were met and <code>false</code> that they were not.
+     */
+    public void setStateEnergySumLow(boolean state) {
+        setCutState(PAIR_ENERGY_SUM_LOW, state);
+    }
+    
+    /**
+     * Sets whether the conditions for the pair energy sum upper bound
+     * cut were met.
+     * @param state - <code>true</code> indicates that the cut conditions
+     * were met and <code>false</code> that they were not.
+     */
+    public void setStateEnergySumHigh(boolean state) {
+        setCutState(PAIR_ENERGY_SUM_HIGH, state);
+    }
+    
+    /**
+     * Sets whether the conditions for the pair energy difference cut
+     * were met.
+     * @param state - <code>true</code> indicates that the cut conditions
+     * were met and <code>false</code> that they were not.
+     */
+    public void setStateEnergyDifference(boolean state) {
+        setCutState(PAIR_ENERGY_DIFFERENCE_HIGH, state);
+    }
+    
+    /**
+     * Sets whether the conditions for the pair energy slope cut were
+     * met.
+     * @param state - <code>true</code> indicates that the cut conditions
+     * were met and <code>false</code> that they were not.
+     */
+    public void setStateEnergySlope(boolean state) {
+        setCutState(PAIR_ENERGY_SLOPE_LOW, state);
+    }
+    
+    /**
+     * Sets whether the conditions for the pair coplanarity cut were
+     * met.
+     * @param state - <code>true</code> indicates that the cut conditions
+     * were met and <code>false</code> that they were not.
+     */
+    public void setStateCoplanarity(boolean state) {
+        setCutState(PAIR_COPLANARITY_HIGH, state);
+    }
+    
+    /**
+     * Sets whether the conditions for the time coincidence cut were
+     * met.
+     * @param state - <code>true</code> indicates that the cut conditions
+     * were met and <code>false</code> that they were not.
+     */
+    public void setStateTimeCoincidence(boolean state) {
+        setCutState(PAIR_TIME_COINCIDENCE, state);
+    }
+    
+    @Override
+    public String toString() {
+        return String.format("EClusterLow: %d; EClusterHigh %d; HitCount: %d; ESumLow: %d, ESumHigh: %d, EDiff: %d, ESlope: %d, Coplanarity: %d",
+                getStateClusterEnergyLow() ? 1 : 0, getStateClusterEnergyHigh() ? 1 : 0,
+                getStateHitCount() ? 1 : 0, getStateEnergySumLow() ? 1 : 0,
+                getStateEnergySumHigh() ? 1 : 0, getStateEnergyDifference() ? 1 : 0,
+                getStateEnergySlope() ? 1 : 0, getStateCoplanarity() ? 1 : 0);
+    }
+}

Modified: java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/util/SinglesTrigger.java
 =============================================================================
--- java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/util/SinglesTrigger.java	(original)
+++ java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/util/SinglesTrigger.java	Wed Apr 27 11:11:32 2016
@@ -3,151 +3,151 @@
 import org.hps.record.triggerbank.TriggerModule;
 
 public class SinglesTrigger<E> extends Trigger<E> {
-	// Define the supported trigger cuts.
-	private static final String CLUSTER_HIT_COUNT_LOW = TriggerModule.CLUSTER_HIT_COUNT_LOW;
-	private static final String CLUSTER_SEED_ENERGY_LOW = TriggerModule.CLUSTER_SEED_ENERGY_LOW;
-	private static final String CLUSTER_SEED_ENERGY_HIGH = TriggerModule.CLUSTER_SEED_ENERGY_HIGH;
-	private static final String CLUSTER_TOTAL_ENERGY_LOW = TriggerModule.CLUSTER_TOTAL_ENERGY_LOW;
-	private static final String CLUSTER_TOTAL_ENERGY_HIGH = TriggerModule.CLUSTER_TOTAL_ENERGY_HIGH;
-	
-	/**
-	 * Instantiates a new <code>SinglesTrigger</code> with all cut
-	 * states set to <code>false</code> and with the trigger source
-	 * defined according to the specified object.
-	 * @param source - The object from which the trigger cut states
-	 * are derived.
-	 */
-	public SinglesTrigger(E source, int triggerNum) {
-		// Instantiate the superclass.
-		super(source, triggerNum);
-		
-		// Add the supported cuts types.
-		addValidCut(CLUSTER_HIT_COUNT_LOW);
-		addValidCut(CLUSTER_SEED_ENERGY_LOW);
-		addValidCut(CLUSTER_SEED_ENERGY_HIGH);
-		addValidCut(CLUSTER_TOTAL_ENERGY_LOW);
-		addValidCut(CLUSTER_TOTAL_ENERGY_HIGH);
-	}
-	
-	/**
-	 * Gets whether the cluster hit count cut was met.
-	 * @return Returns <code>true</code> if the cut was met and
-	 * <code>false</code> otherwise.
-	 */
-	public boolean getStateHitCount() {
-		return getCutState(CLUSTER_HIT_COUNT_LOW);
-	}
-	
-	/**
-	 * Gets whether the cluster seed energy lower bound cut was met.
-	 * @return Returns <code>true</code> if the cut was met and
-	 * <code>false</code> otherwise.
-	 */
-	public boolean getStateSeedEnergyLow() {
-		return getCutState(CLUSTER_SEED_ENERGY_LOW);
-	}
-	
-	/**
-	 * Gets whether the cluster seed energy upper bound cut was met.
-	 * @return Returns <code>true</code> if the cut was met and
-	 * <code>false</code> otherwise.
-	 */
-	public boolean getStateSeedEnergyHigh() {
-		return getCutState(CLUSTER_SEED_ENERGY_HIGH);
-	}
-	
-	/**
-	 * Gets whether both the cluster seed energy upper and lower bound
-	 * cuts were met.
-	 * @return Returns <code>true</code> if the cuts were met and
-	 * <code>false</code> otherwise.
-	 */
-	public boolean getStateSeedEnergy() {
-		return getCutState(CLUSTER_SEED_ENERGY_LOW) && getCutState(CLUSTER_SEED_ENERGY_HIGH);
-	}
-	
-	/**
-	 * Gets whether the cluster total energy lower bound cut was met.
-	 * @return Returns <code>true</code> if the cut was met and
-	 * <code>false</code> otherwise.
-	 */
-	public boolean getStateClusterEnergyLow() {
-		return getCutState(CLUSTER_TOTAL_ENERGY_LOW);
-	}
-	
-	/**
-	 * Gets whether the cluster total energy upper bound cut was met.
-	 * @return Returns <code>true</code> if the cut was met and
-	 * <code>false</code> otherwise.
-	 */
-	public boolean getStateClusterEnergyHigh() {
-		return getCutState(CLUSTER_TOTAL_ENERGY_HIGH);
-	}
-	
-	/**
-	 * Gets whether both the cluster total energy upper and lower bound
-	 * cuts were met.
-	 * @return Returns <code>true</code> if the cuts were met and
-	 * <code>false</code> otherwise.
-	 */
-	public boolean getStateClusterEnergy() {
-		return getCutState(CLUSTER_TOTAL_ENERGY_LOW) && getCutState(CLUSTER_TOTAL_ENERGY_HIGH);
-	}
-	
-	/**
-	 * Sets whether the conditions for the cluster hit count cut were
-	 * met.
-	 * @param state - <code>true</code> indicates that the cut conditions
-	 * were met and <code>false</code> that they were not.
-	 */
-	public void setStateHitCount(boolean state) {
-		setCutState(CLUSTER_HIT_COUNT_LOW, state);
-	}
-	
-	/**
-	 * Sets whether the conditions for the cluster seed energy lower
-	 * bound cut were met.
-	 * @param state - <code>true</code> indicates that the cut conditions
-	 * were met and <code>false</code> that they were not.
-	 */
-	public void setStateSeedEnergyLow(boolean state) {
-		setCutState(CLUSTER_SEED_ENERGY_LOW, state);
-	}
-	
-	/**
-	 * Sets whether the conditions for the cluster seed energy upper
-	 * bound cut were met.
-	 * @param state - <code>true</code> indicates that the cut conditions
-	 * were met and <code>false</code> that they were not.
-	 */
-	public void setStateSeedEnergyHigh(boolean state) {
-		setCutState(CLUSTER_SEED_ENERGY_HIGH, state);
-	}
-	
-	/**
-	 * Sets whether the conditions for the cluster total energy lower
-	 * bound cut were met.
-	 * @param state - <code>true</code> indicates that the cut conditions
-	 * were met and <code>false</code> that they were not.
-	 */
-	public void setStateClusterEnergyLow(boolean state) {
-		setCutState(CLUSTER_TOTAL_ENERGY_LOW, state);
-	}
-	
-	/**
-	 * Sets whether the conditions for the cluster total energy upper
-	 * bound cut were met.
-	 * @param state - <code>true</code> indicates that the cut conditions
-	 * were met and <code>false</code> that they were not.
-	 */
-	public void setStateClusterEnergyHigh(boolean state) {
-		setCutState(CLUSTER_TOTAL_ENERGY_HIGH, state);
-	}
-	
-	@Override
-	public String toString() {
-		return String.format("EClusterLow: %d; EClusterHigh %d; HitCount: %d",
-				getStateClusterEnergyLow() ? 1 : 0, getStateClusterEnergyHigh() ? 1 : 0,
-				getStateHitCount() ? 1 : 0);
-	}
-}
+    // Define the supported trigger cuts.
+    private static final String CLUSTER_HIT_COUNT_LOW = TriggerModule.CLUSTER_HIT_COUNT_LOW;
+    private static final String CLUSTER_SEED_ENERGY_LOW = TriggerModule.CLUSTER_SEED_ENERGY_LOW;
+    private static final String CLUSTER_SEED_ENERGY_HIGH = TriggerModule.CLUSTER_SEED_ENERGY_HIGH;
+    private static final String CLUSTER_TOTAL_ENERGY_LOW = TriggerModule.CLUSTER_TOTAL_ENERGY_LOW;
+    private static final String CLUSTER_TOTAL_ENERGY_HIGH = TriggerModule.CLUSTER_TOTAL_ENERGY_HIGH;
+    
+    /**
+     * Instantiates a new <code>SinglesTrigger</code> with all cut
+     * states set to <code>false</code> and with the trigger source
+     * defined according to the specified object.
+     * @param source - The object from which the trigger cut states
+     * are derived.
+     */
+    public SinglesTrigger(E source, int triggerNum) {
+        // Instantiate the superclass.
+        super(source, triggerNum);
+        
+        // Add the supported cuts types.
+        addValidCut(CLUSTER_HIT_COUNT_LOW);
+        addValidCut(CLUSTER_SEED_ENERGY_LOW);
+        addValidCut(CLUSTER_SEED_ENERGY_HIGH);
+        addValidCut(CLUSTER_TOTAL_ENERGY_LOW);
+        addValidCut(CLUSTER_TOTAL_ENERGY_HIGH);
+    }
+    
+    /**
+     * Gets whether the cluster hit count cut was met.
+     * @return Returns <code>true</code> if the cut was met and
+     * <code>false</code> otherwise.
+     */
+    public boolean getStateHitCount() {
+        return getCutState(CLUSTER_HIT_COUNT_LOW);
+    }
+    
+    /**
+     * Gets whether the cluster seed energy lower bound cut was met.
+     * @return Returns <code>true</code> if the cut was met and
+     * <code>false</code> otherwise.
+     */
+    public boolean getStateSeedEnergyLow() {
+        return getCutState(CLUSTER_SEED_ENERGY_LOW);
+    }
+    
+    /**
+     * Gets whether the cluster seed energy upper bound cut was met.
+     * @return Returns <code>true</code> if the cut was met and
+     * <code>false</code> otherwise.
+     */
+    public boolean getStateSeedEnergyHigh() {
+        return getCutState(CLUSTER_SEED_ENERGY_HIGH);
+    }
+    
+    /**
+     * Gets whether both the cluster seed energy upper and lower bound
+     * cuts were met.
+     * @return Returns <code>true</code> if the cuts were met and
+     * <code>false</code> otherwise.
+     */
+    public boolean getStateSeedEnergy() {
+        return getCutState(CLUSTER_SEED_ENERGY_LOW) && getCutState(CLUSTER_SEED_ENERGY_HIGH);
+    }
+    
+    /**
+     * Gets whether the cluster total energy lower bound cut was met.
+     * @return Returns <code>true</code> if the cut was met and
+     * <code>false</code> otherwise.
+     */
+    public boolean getStateClusterEnergyLow() {
+        return getCutState(CLUSTER_TOTAL_ENERGY_LOW);
+    }
+    
+    /**
+     * Gets whether the cluster total energy upper bound cut was met.
+     * @return Returns <code>true</code> if the cut was met and
+     * <code>false</code> otherwise.
+     */
+    public boolean getStateClusterEnergyHigh() {
+        return getCutState(CLUSTER_TOTAL_ENERGY_HIGH);
+    }
+    
+    /**
+     * Gets whether both the cluster total energy upper and lower bound
+     * cuts were met.
+     * @return Returns <code>true</code> if the cuts were met and
+     * <code>false</code> otherwise.
+     */
+    public boolean getStateClusterEnergy() {
+        return getCutState(CLUSTER_TOTAL_ENERGY_LOW) && getCutState(CLUSTER_TOTAL_ENERGY_HIGH);
+    }
+    
+    /**
+     * Sets whether the conditions for the cluster hit count cut were
+     * met.
+     * @param state - <code>true</code> indicates that the cut conditions
+     * were met and <code>false</code> that they were not.
+     */
+    public void setStateHitCount(boolean state) {
+        setCutState(CLUSTER_HIT_COUNT_LOW, state);
+    }
+    
+    /**
+     * Sets whether the conditions for the cluster seed energy lower
+     * bound cut were met.
+     * @param state - <code>true</code> indicates that the cut conditions
+     * were met and <code>false</code> that they were not.
+     */
+    public void setStateSeedEnergyLow(boolean state) {
+        setCutState(CLUSTER_SEED_ENERGY_LOW, state);
+    }
+    
+    /**
+     * Sets whether the conditions for the cluster seed energy upper
+     * bound cut were met.
+     * @param state - <code>true</code> indicates that the cut conditions
+     * were met and <code>false</code> that they were not.
+     */
+    public void setStateSeedEnergyHigh(boolean state) {
+        setCutState(CLUSTER_SEED_ENERGY_HIGH, state);
+    }
+    
+    /**
+     * Sets whether the conditions for the cluster total energy lower
+     * bound cut were met.
+     * @param state - <code>true</code> indicates that the cut conditions
+     * were met and <code>false</code> that they were not.
+     */
+    public void setStateClusterEnergyLow(boolean state) {
+        setCutState(CLUSTER_TOTAL_ENERGY_LOW, state);
+    }
+    
+    /**
+     * Sets whether the conditions for the cluster total energy upper
+     * bound cut were met.
+     * @param state - <code>true</code> indicates that the cut conditions
+     * were met and <code>false</code> that they were not.
+     */
+    public void setStateClusterEnergyHigh(boolean state) {
+        setCutState(CLUSTER_TOTAL_ENERGY_HIGH, state);
+    }
+    
+    @Override
+    public String toString() {
+        return String.format("EClusterLow: %d; EClusterHigh %d; HitCount: %d",
+                getStateClusterEnergyLow() ? 1 : 0, getStateClusterEnergyHigh() ? 1 : 0,
+                getStateHitCount() ? 1 : 0);
+    }
+}

Modified: java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/util/Trigger.java
 =============================================================================
--- java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/util/Trigger.java	(original)
+++ java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/util/Trigger.java	Wed Apr 27 11:11:32 2016
@@ -14,139 +14,139 @@
  * @author Kyle McCarty <[log in to unmask]>
  */
 public abstract class Trigger<E> {
-	// Track whether the trigger conditions were met.
-	private boolean passTrigger = false;
-	// Store the cut condition states.
-	private Map<String, Boolean> passMap = new HashMap<String, Boolean>();
-	// Store the cluster associated with the trigger.
-	private final E source;
-	// Store the trigger number.
-	private final int triggerNum;
-	
-	/**
-	 * Creates a new <code>Trigger</code> object with the argument
-	 * specifying the object from whence the trigger state is derived.
-	 * @param source - The trigger source object.
-	 */
-	protected Trigger(E source) {
-		this(source, -1);
-	}
-	
-	/**
-	 * Creates a new <code>Trigger</code> object with the argument
-	 * specifying the object from whence the trigger state is derived.
-	 * @param source - The trigger source object.
-	 * @param triggerNum - The number of the trigger.
-	 */
-	protected Trigger(E source, int triggerNum) {
-		this.source = source;
-		this.triggerNum = triggerNum;
-	}
-	
-	/**
-	 * Adds a cut to the set of cuts tracked by this trigger.
-	 * @param cut - The identifier for the cut.
-	 */
-	protected void addValidCut(String cut) {
-		passMap.put(cut, new Boolean(false));
-	}
-	
-	/**
-	 * Gets the state of the specified cut.
-	 * @param cut - The identifier for the cut.
-	 * @return Returns <code>true</code> if the conditions for the
-	 * specified cut were met and <code>false</code> otherwise.
-	 * @throws IllegalArgumentException Occurs if the specified cut
-	 * is not supported by the object.
-	 */
-	protected boolean getCutState(String cut) throws IllegalArgumentException {
-		if(passMap.containsKey(cut)) {
-			return passMap.get(cut);
-		} else {
-			throw new IllegalArgumentException(String.format("Trigger cut \"%s\" is not a supported trigger cut.", cut));
-		}
-	}
-	
-	/**
-	 * Gets the number of the trigger. If the trigger has no number,
-	 * it will return <code>-1</code>.
-	 * @return Returns the trigger number as an <code>int</code>.
-	 */
-	public int getTriggerNumber() {
-		return triggerNum;
-	}
-	
-	/**
-	 * Gets the object to which the trigger cuts are applied.
-	 * @return Returns the trigger source object.
-	 */
-	public E getTriggerSource() { return source; }
-	
-	/**
-	 * Gets whether the conditions for the trigger were met.
-	 * @return Returns <code>true</code> if the conditions for the
-	 * trigger were met and <code>false</code> if they were not.
-	 */
-	public boolean getTriggerState() {
-		return passTrigger;
-	}
-	
-	/**
-	 * Removes a cut from the set of cuts tracked by the trigger.
-	 * @param cut - The identifier for the cut.
-	 */
-	protected void removeValidCut(String cut) {
-		passMap.remove(cut);
-	}
-	
-	/**
-	 * Checks whether the all of the trigger cut conditions were met.
-	 * @return Returns <code>true</code> if all of the cut conditions
-	 * were met and <code>false</code> otherwise.
-	 */
-	private boolean isValidTrigger() {
-		// Iterate over all of the cuts and look for any that have not
-		// been met.
-		for(Entry<String, Boolean> cut : passMap.entrySet()) {
-			if(!cut.getValue()) { return false; }
-		}
-		
-		// If there are no cut conditions that have not been met, then
-		// the trigger is valid.
-		return true;
-	}
-	
-	/**
-	 * Sets whether the conditions for the specified cut were met.
-	 * @param cut - The identifier for the cut.
-	 * @param state - <code>true</code> indicates that the conditions
-	 * for the cut were met and <code>false</code> that they were not.
-	 * @throws IllegalArgumentException Occurs if the specified cut
-	 * is not supported by the object.
-	 */
-	protected void setCutState(String cut, boolean state) throws IllegalArgumentException {
-		if(passMap.containsKey(cut)) {
-			// Set the cut state.
-			passMap.put(cut, state);
-			
-			// If the cut state is true, then all cut conditions may have
-			// been met. Check whether this is true and, if so, set the
-			// trigger state accordingly.
-			if(state && isValidTrigger()) { passTrigger = true; }
-			else { passTrigger = false; }
-		} else {
-			throw new IllegalArgumentException(String.format("Trigger cut \"%s\" is not a supported trigger cut.", cut));
-		}
-	}
-	
-	/**
-	 * Indicates whether the specified cut state is tracked by this
-	 * object or not.
-	 * @param cut - The identifier for the cut.
-	 * @return Returns <code>true</code> if the cut state is tracked
-	 * by this object and <code>false</code> otherwise.
-	 */
-	protected boolean supportsCut(String cut) {
-		return passMap.containsKey(cut);
-	}
-}
+    // Track whether the trigger conditions were met.
+    private boolean passTrigger = false;
+    // Store the cut condition states.
+    private Map<String, Boolean> passMap = new HashMap<String, Boolean>();
+    // Store the cluster associated with the trigger.
+    private final E source;
+    // Store the trigger number.
+    private final int triggerNum;
+    
+    /**
+     * Creates a new <code>Trigger</code> object with the argument
+     * specifying the object from whence the trigger state is derived.
+     * @param source - The trigger source object.
+     */
+    protected Trigger(E source) {
+        this(source, -1);
+    }
+    
+    /**
+     * Creates a new <code>Trigger</code> object with the argument
+     * specifying the object from whence the trigger state is derived.
+     * @param source - The trigger source object.
+     * @param triggerNum - The number of the trigger.
+     */
+    protected Trigger(E source, int triggerNum) {
+        this.source = source;
+        this.triggerNum = triggerNum;
+    }
+    
+    /**
+     * Adds a cut to the set of cuts tracked by this trigger.
+     * @param cut - The identifier for the cut.
+     */
+    protected void addValidCut(String cut) {
+        passMap.put(cut, new Boolean(false));
+    }
+    
+    /**
+     * Gets the state of the specified cut.
+     * @param cut - The identifier for the cut.
+     * @return Returns <code>true</code> if the conditions for the
+     * specified cut were met and <code>false</code> otherwise.
+     * @throws IllegalArgumentException Occurs if the specified cut
+     * is not supported by the object.
+     */
+    protected boolean getCutState(String cut) throws IllegalArgumentException {
+        if(passMap.containsKey(cut)) {
+            return passMap.get(cut);
+        } else {
+            throw new IllegalArgumentException(String.format("Trigger cut \"%s\" is not a supported trigger cut.", cut));
+        }
+    }
+    
+    /**
+     * Gets the number of the trigger. If the trigger has no number,
+     * it will return <code>-1</code>.
+     * @return Returns the trigger number as an <code>int</code>.
+     */
+    public int getTriggerNumber() {
+        return triggerNum;
+    }
+    
+    /**
+     * Gets the object to which the trigger cuts are applied.
+     * @return Returns the trigger source object.
+     */
+    public E getTriggerSource() { return source; }
+    
+    /**
+     * Gets whether the conditions for the trigger were met.
+     * @return Returns <code>true</code> if the conditions for the
+     * trigger were met and <code>false</code> if they were not.
+     */
+    public boolean getTriggerState() {
+        return passTrigger;
+    }
+    
+    /**
+     * Removes a cut from the set of cuts tracked by the trigger.
+     * @param cut - The identifier for the cut.
+     */
+    protected void removeValidCut(String cut) {
+        passMap.remove(cut);
+    }
+    
+    /**
+     * Checks whether the all of the trigger cut conditions were met.
+     * @return Returns <code>true</code> if all of the cut conditions
+     * were met and <code>false</code> otherwise.
+     */
+    private boolean isValidTrigger() {
+        // Iterate over all of the cuts and look for any that have not
+        // been met.
+        for(Entry<String, Boolean> cut : passMap.entrySet()) {
+            if(!cut.getValue()) { return false; }
+        }
+        
+        // If there are no cut conditions that have not been met, then
+        // the trigger is valid.
+        return true;
+    }
+    
+    /**
+     * Sets whether the conditions for the specified cut were met.
+     * @param cut - The identifier for the cut.
+     * @param state - <code>true</code> indicates that the conditions
+     * for the cut were met and <code>false</code> that they were not.
+     * @throws IllegalArgumentException Occurs if the specified cut
+     * is not supported by the object.
+     */
+    protected void setCutState(String cut, boolean state) throws IllegalArgumentException {
+        if(passMap.containsKey(cut)) {
+            // Set the cut state.
+            passMap.put(cut, state);
+            
+            // If the cut state is true, then all cut conditions may have
+            // been met. Check whether this is true and, if so, set the
+            // trigger state accordingly.
+            if(state && isValidTrigger()) { passTrigger = true; }
+            else { passTrigger = false; }
+        } else {
+            throw new IllegalArgumentException(String.format("Trigger cut \"%s\" is not a supported trigger cut.", cut));
+        }
+    }
+    
+    /**
+     * Indicates whether the specified cut state is tracked by this
+     * object or not.
+     * @param cut - The identifier for the cut.
+     * @return Returns <code>true</code> if the cut state is tracked
+     * by this object and <code>false</code> otherwise.
+     */
+    protected boolean supportsCut(String cut) {
+        return passMap.containsKey(cut);
+    }
+}

Modified: java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/util/TriggerDiagnosticUtil.java
 =============================================================================
--- java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/util/TriggerDiagnosticUtil.java	(original)
+++ java/branches/HPSJAVA-409/analysis/src/main/java/org/hps/analysis/trigger/util/TriggerDiagnosticUtil.java	Wed Apr 27 11:11:32 2016
@@ -15,208 +15,208 @@
  * @author Kyle McCarty <[log in to unmask]>
  */
 public class TriggerDiagnosticUtil {
-	// Cluster match state variables.
-	public static final byte CLUSTER_STATE_MATCHED        = 0;
-	public static final byte CLUSTER_STATE_FAIL_POSITION  = 1;
-	public static final byte CLUSTER_STATE_FAIL_ENERGY    = 2;
-	public static final byte CLUSTER_STATE_FAIL_HIT_COUNT = 3;
-	public static final byte CLUSTER_STATE_FAIL_TIME      = 4;
-	public static final byte CLUSTER_STATE_FAIL_UNKNOWN   = 5;
-	
-	// Trigger match cut IDs.
-	public static final int SINGLES_ENERGY_MIN = 0;
-	public static final int SINGLES_ENERGY_MAX = 1;
-	public static final int SINGLES_HIT_COUNT = 2;
-	public static final int PAIR_ENERGY_SUM = 0;
-	public static final int PAIR_ENERGY_DIFF = 1;
-	public static final int PAIR_ENERGY_SLOPE = 2;
-	public static final int PAIR_COPLANARITY = 3;
-	
-	// Trigger type variables.
-	public static final int TRIGGER_PULSER    = TriggerStatModule.PULSER;
-	public static final int TRIGGER_COSMIC    = TriggerStatModule.COSMIC;
-	public static final int TRIGGER_SINGLES_0 = TriggerStatModule.SINGLES_0;
-	public static final int TRIGGER_SINGLES_1 = TriggerStatModule.SINGLES_1;
-	public static final int TRIGGER_PAIR_0    = TriggerStatModule.PAIR_0;
-	public static final int TRIGGER_PAIR_1    = TriggerStatModule.PAIR_1;
-	public static final String[] TRIGGER_NAME = { "Singles 0", "Singles 1", "Pair 0", "Pair 1", "Pulser", "Cosmic" };
-	
-	/**
-	 * Convenience method that writes the position of a cluster in the
-	 * form (ix, iy).
-	 * @param cluster - The cluster.
-	 * @return Returns the cluster position as a <code>String</code>.
-	 */
-	public static final String clusterPositionString(Cluster cluster) {
-		return String.format("(%3d, %3d)",
-				cluster.getCalorimeterHits().get(0).getIdentifierFieldValue("ix"),
-				cluster.getCalorimeterHits().get(0).getIdentifierFieldValue("iy"));
-	}
-	
-	/**
-	 * Convenience method that writes the position of a cluster in the
-	 * form (ix, iy).
-	 * @param cluster - The cluster.
-	 * @return Returns the cluster position as a <code>String</code>.
-	 */
-	public static final String clusterPositionString(SSPCluster cluster) {
-		return String.format("(%3d, %3d)", cluster.getXIndex(), cluster.getYIndex());
-	}
-	
-	/**
-	 * Convenience method that writes the information in a cluster to
-	 * a <code>String</code>.
-	 * @param cluster - The cluster.
-	 * @return Returns the cluster information as a <code>String</code>.
-	 */
-	public static final String clusterToString(Cluster cluster) {
-		return String.format("Cluster at (%3d, %3d) with %.3f GeV and %d hits at %4.0f ns.",
-				cluster.getCalorimeterHits().get(0).getIdentifierFieldValue("ix"),
-				cluster.getCalorimeterHits().get(0).getIdentifierFieldValue("iy"),
-				cluster.getEnergy(), cluster.getCalorimeterHits().size(),
-				cluster.getCalorimeterHits().get(0).getTime());
-	}
-	
-	/**
-	 * Convenience method that writes the information in a cluster to
-	 * a <code>String</code>.
-	 * @param cluster - The cluster.
-	 * @return Returns the cluster information as a <code>String</code>.
-	 */
-	public static final String clusterToString(SSPCluster cluster) {
-		return String.format("Cluster at (%3d, %3d) with %.3f GeV and %d hits at %4d ns.",
-				cluster.getXIndex(), cluster.getYIndex(), cluster.getEnergy(),
-				cluster.getHitCount(), cluster.getTime());
-	}
-	
-	/**
-	 * Gets the x/y-indices of the cluster.
-	 * @param cluster -  The cluster of which to obtain the indices.
-	 * @return Returns the indices as a <code>Point</code> object.
-	 */
-	public static final Point getClusterPosition(Cluster cluster) {
-		return new Point(getXIndex(cluster), getYIndex(cluster));
-	}
-	
-	/**
-	 * Gets the x/y-indices of the cluster.
-	 * @param cluster -  The cluster of which to obtain the indices.
-	 * @return Returns the indices as a <code>Point</code> object.
-	 */
-	public static final Point getClusterPosition(SSPCluster cluster) {
-		return new Point(cluster.getXIndex(), cluster.getYIndex());
-	}
-	
-	/**
-	 * Gets the time stamp of the cluster in nanoseconds.
-	 * @param cluster - The cluster.
-	 * @return Returns the time-stamp.
-	 */
-	public static final double getClusterTime(Cluster cluster) {
-		return cluster.getCalorimeterHits().get(0).getTime();
-	}
-	
-	/**
-	 * Gets the time stamp of the cluster in nanoseconds.
-	 * @param cluster - The cluster.
-	 * @return Returns the time-stamp.
-	 */
-	public static final int getClusterTime(SSPCluster cluster) {
-		return cluster.getTime();
-	}
-	
-	/**
-	 * Gets the number of digits in the base-10 String representation
-	 * of an integer primitive. Negative signs are not included in the
-	 * digit count.
-	 * @param value - The value of which to obtain the length.
-	 * @return Returns the number of digits in the String representation
-	 * of the argument value.
-	 */
-	public static final int getDigits(int value) {
-		if(value < 0) { return Integer.toString(value).length() - 1; }
-		else { return Integer.toString(value).length(); }
-	}
-	
-	/**
-	 * Gets the number of hits in a cluster.
-	 * @param cluster - The cluster.
-	 * @return Returns the number of hits in the cluster.
-	 */
-	public static final int getHitCount(Cluster cluster) {
-		return cluster.getCalorimeterHits().size();
-	}
-	
-	/**
-	 * Gets the number of hits in a cluster.
-	 * @param cluster - The cluster.
-	 * @return Returns the number of hits in the cluster.
-	 */
-	public static final int getHitCount(SSPCluster cluster) {
-		return cluster.getHitCount();
-	}
-	
-	/**
-	 * Gets the x-index of the cluster's seed hit.
-	 * @param cluster - The cluster.
-	 * @return Returns the x-index.
-	 */
-	public static final int getXIndex(Cluster cluster) {
-		return cluster.getCalorimeterHits().get(0).getIdentifierFieldValue("ix");
-	}
-	
-	/**
-	 * Gets the x-index of the cluster's seed hit.
-	 * @param cluster - The cluster.
-	 * @return Returns the x-index.
-	 */
-	public static final int getXIndex(SSPCluster cluster) {
-		return cluster.getXIndex();
-	}
-	
-	/**
-	 * Gets the y-index of the cluster's seed hit.
-	 * @param cluster - The cluster.
-	 * @return Returns the y-index.
-	 */
-	public static final int getYIndex(Cluster cluster) {
-		return cluster.getCalorimeterHits().get(0).getIdentifierFieldValue("iy");
-	}
-	
-	/**
-	 * Gets the y-index of the cluster's seed hit.
-	 * @param cluster - The cluster.
-	 * @return Returns the y-index.
-	 */
-	public static final int getYIndex(SSPCluster cluster) {
-		return cluster.getYIndex();
-	}
-	
-	/**
-	 * Checks whether all of the hits in a cluster are within the safe
-	 * region of the FADC output window.
-	 * @param reconCluster - The cluster to check.
-	 * @return Returns <code>true</code> if the cluster is safe and
-	 * returns <code>false</code> otherwise.
-	 */
-	public static final boolean isVerifiable(Cluster reconCluster, int nsa, int nsb, int windowWidth) {
-		// Iterate over the hits in the cluster.
-		for(CalorimeterHit hit : reconCluster.getCalorimeterHits()) {
-			// Check that none of the hits are within the disallowed
-			// region of the FADC readout window.
-			if(hit.getTime() <= nsb || hit.getTime() >= (windowWidth - nsa)) {
-				return false;
-			}
-			
-			// Also check to make sure that the cluster does not have
-			// any negative energy hits. These are, obviously, wrong.
-			if(hit.getCorrectedEnergy() < 0.0) {
-				return false;
-			}
-		}
-		
-		// If all of the cluster hits pass the time cut, the cluster
-		// is valid.
-		return true;
-	}
+    // Cluster match state variables.
+    public static final byte CLUSTER_STATE_MATCHED        = 0;
+    public static final byte CLUSTER_STATE_FAIL_POSITION  = 1;
+    public static final byte CLUSTER_STATE_FAIL_ENERGY    = 2;
+    public static final byte CLUSTER_STATE_FAIL_HIT_COUNT = 3;
+    public static final byte CLUSTER_STATE_FAIL_TIME      = 4;
+    public static final byte CLUSTER_STATE_FAIL_UNKNOWN   = 5;
+    
+    // Trigger match cut IDs.
+    public static final int SINGLES_ENERGY_MIN = 0;
+    public static final int SINGLES_ENERGY_MAX = 1;
+    public static final int SINGLES_HIT_COUNT = 2;
+    public static final int PAIR_ENERGY_SUM = 0;
+    public static final int PAIR_ENERGY_DIFF = 1;
+    public static final int PAIR_ENERGY_SLOPE = 2;
+    public static final int PAIR_COPLANARITY = 3;
+    
+    // Trigger type variables.
+    public static final int TRIGGER_PULSER    = TriggerStatModule.PULSER;
+    public static final int TRIGGER_COSMIC    = TriggerStatModule.COSMIC;
+    public static final int TRIGGER_SINGLES_0 = TriggerStatModule.SINGLES_0;
+    public static final int TRIGGER_SINGLES_1 = TriggerStatModule.SINGLES_1;
+    public static final int TRIGGER_PAIR_0    = TriggerStatModule.PAIR_0;
+    public static final int TRIGGER_PAIR_1    = TriggerStatModule.PAIR_1;
+    public static final String[] TRIGGER_NAME = { "Singles 0", "Singles 1", "Pair 0", "Pair 1", "Pulser", "Cosmic" };
+    
+    /**
+     * Convenience method that writes the position of a cluster in the
+     * form (ix, iy).
+     * @param cluster - The cluster.
+     * @return Returns the cluster position as a <code>String</code>.
+     */
+    public static final String clusterPositionString(Cluster cluster) {
+        return String.format("(%3d, %3d)",
+                cluster.getCalorimeterHits().get(0).getIdentifierFieldValue("ix"),
+                cluster.getCalorimeterHits().get(0).getIdentifierFieldValue("iy"));
+    }
+    
+    /**
+     * Convenience method that writes the position of a cluster in the
+     * form (ix, iy).
+     * @param cluster - The cluster.
+     * @return Returns the cluster position as a <code>String</code>.
+     */
+    public static final String clusterPositionString(SSPCluster cluster) {
+        return String.format("(%3d, %3d)", cluster.getXIndex(), cluster.getYIndex());
+    }
+    
+    /**
+     * Convenience method that writes the information in a cluster to
+     * a <code>String</code>.
+     * @param cluster - The cluster.
+     * @return Returns the cluster information as a <code>String</code>.
+     */
+    public static final String clusterToString(Cluster cluster) {
+        return String.format("Cluster at (%3d, %3d) with %.3f GeV and %d hits at %4.0f ns.",
+                cluster.getCalorimeterHits().get(0).getIdentifierFieldValue("ix"),
+                cluster.getCalorimeterHits().get(0).getIdentifierFieldValue("iy"),
+                cluster.getEnergy(), cluster.getCalorimeterHits().size(),
+                cluster.getCalorimeterHits().get(0).getTime());
+    }
+    
+    /**
+     * Convenience method that writes the information in a cluster to
+     * a <code>String</code>.
+     * @param cluster - The cluster.
+     * @return Returns the cluster information as a <code>String</code>.
+     */
+    public static final String clusterToString(SSPCluster cluster) {
+        return String.format("Cluster at (%3d, %3d) with %.3f GeV and %d hits at %4d ns.",
+                cluster.getXIndex(), cluster.getYIndex(), cluster.getEnergy(),
+                cluster.getHitCount(), cluster.getTime());
+    }
+    
+    /**
+     * Gets the x/y-indices of the cluster.
+     * @param cluster -  The cluster of which to obtain the indices.
+     * @return Returns the indices as a <code>Point</code> object.
+     */
+    public static final Point getClusterPosition(Cluster cluster) {
+        return new Point(getXIndex(cluster), getYIndex(cluster));
+    }
+    
+    /**
+     * Gets the x/y-indices of the cluster.
+     * @param cluster -  The cluster of which to obtain the indices.
+     * @return Returns the indices as a <code>Point</code> object.
+     */
+    public static final Point getClusterPosition(SSPCluster cluster) {
+        return new Point(cluster.getXIndex(), cluster.getYIndex());
+    }
+    
+    /**
+     * Gets the time stamp of the cluster in nanoseconds.
+     * @param cluster - The cluster.
+     * @return Returns the time-stamp.
+     */
+    public static final double getClusterTime(Cluster cluster) {
+        return cluster.getCalorimeterHits().get(0).getTime();
+    }
+    
+    /**
+     * Gets the time stamp of the cluster in nanoseconds.
+     * @param cluster - The cluster.
+     * @return Returns the time-stamp.
+     */
+    public static final int getClusterTime(SSPCluster cluster) {
+        return cluster.getTime();
+    }
+    
+    /**
+     * Gets the number of digits in the base-10 String representation
+     * of an integer primitive. Negative signs are not included in the
+     * digit count.
+     * @param value - The value of which to obtain the length.
+     * @return Returns the number of digits in the String representation
+     * of the argument value.
+     */
+    public static final int getDigits(int value) {
+        if(value < 0) { return Integer.toString(value).length() - 1; }
+        else { return Integer.toString(value).length(); }
+    }
+    
+    /**
+     * Gets the number of hits in a cluster.
+     * @param cluster - The cluster.
+     * @return Returns the number of hits in the cluster.
+     */
+    public static final int getHitCount(Cluster cluster) {
+        return cluster.getCalorimeterHits().size();
+    }
+    
+    /**
+     * Gets the number of hits in a cluster.
+     * @param cluster - The cluster.
+     * @return Returns the number of hits in the cluster.
+     */
+    public static final int getHitCount(SSPCluster cluster) {
+        return cluster.getHitCount();
+    }
+    
+    /**
+     * Gets the x-index of the cluster's seed hit.
+     * @param cluster - The cluster.
+     * @return Returns the x-index.
+     */
+    public static final int getXIndex(Cluster cluster) {
+        return cluster.getCalorimeterHits().get(0).getIdentifierFieldValue("ix");
+    }
+    
+    /**
+     * Gets the x-index of the cluster's seed hit.
+     * @param cluster - The cluster.
+     * @return Returns the x-index.
+     */
+    public static final int getXIndex(SSPCluster cluster) {
+        return cluster.getXIndex();
+    }
+    
+    /**
+     * Gets the y-index of the cluster's seed hit.
+     * @param cluster - The cluster.
+     * @return Returns the y-index.
+     */
+    public static final int getYIndex(Cluster cluster) {
+        return cluster.getCalorimeterHits().get(0).getIdentifierFieldValue("iy");
+    }
+    
+    /**
+     * Gets the y-index of the cluster's seed hit.
+     * @param cluster - The cluster.
+     * @return Returns the y-index.
+     */
+    public static final int getYIndex(SSPCluster cluster) {
+        return cluster.getYIndex();
+    }
+    
+    /**
+     * Checks whether all of the hits in a cluster are within the safe
+     * region of the FADC output window.
+     * @param reconCluster - The cluster to check.
+     * @return Returns <code>true</code> if the cluster is safe and
+     * returns <code>false</code> otherwise.
+     */
+    public static final boolean isVerifiable(Cluster reconCluster, int nsa, int nsb, int windowWidth) {
+        // Iterate over the hits in the cluster.
+        for(CalorimeterHit hit : reconCluster.getCalorimeterHits()) {
+            // Check that none of the hits are within the disallowed
+            // region of the FADC readout window.
+            if(hit.getTime() <= nsb || hit.getTime() >= (windowWidth - nsa)) {
+                return false;
+            }
+            
+            // Also check to make sure that the cluster does not have
+            // any negative energy hits. These are, obviously, wrong.
+            if(hit.getCorrectedEnergy() < 0.0) {
+                return false;
+            }
+        }
+        
+        // If all of the cluster hits pass the time cut, the cluster
+        // is valid.
+        return true;
+    }
 }

Modified: java/branches/HPSJAVA-409/conditions/pom.xml
 =============================================================================
--- java/branches/HPSJAVA-409/conditions/pom.xml	(original)
+++ java/branches/HPSJAVA-409/conditions/pom.xml	Wed Apr 27 11:11:32 2016
@@ -8,7 +8,7 @@
         <groupId>org.hps</groupId>
         <artifactId>hps-parent</artifactId>
         <relativePath>../parent/pom.xml</relativePath>
-        <version>3.4.2-SNAPSHOT</version>
+        <version>3.9-SNAPSHOT</version>
     </parent>
     <scm>
         <url>http://java.freehep.org/svn/repos/hps/list/java/trunk/conditions/</url>
@@ -37,6 +37,7 @@
                         <exclude>org/hps/conditions/api/ConditionsTagTest.java</exclude>
                         <exclude>org/hps/conditions/HPSJAVA_529_Test.java</exclude>
                         <exclude>org/hps/conditions/dummy/**.java</exclude>
+                        <exclude>org/hps/conditions/beam/BeamEnergyTest.java</exclude>
                     </excludes>
                 </configuration>
             </plugin>

Modified: java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/ConditionsDriver.java
 =============================================================================
--- java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/ConditionsDriver.java	(original)
+++ java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/ConditionsDriver.java	Wed Apr 27 11:11:32 2016
@@ -28,12 +28,15 @@
  * This is a "special" Driver which must have its initialization occur at the right time. It has a custom initialization
  * method {@link #initialize()} which should be called after all Driver setup has occurred, but before the job actually
  * begins. This is so the conditions system functions properly, including the activation of registered listeners. The
- * setup is performed by in the class {@link org.hps.job.JobManager}, which is used in the default command line front
- * end of the hps-distribution. If that class is not being used, then the method must be executed manually at the right
+ * setup is performed by the <code>JobManager</code>, which is used in the default command line front end of the 
+ * hps-distribution. If that class is not being used, then the method must be executed manually at the right
  * time to achieve the proper behavior.
  *
  * @author Jeremy McCormick, SLAC
+ * 
+ * @deprecated Use built-in options of job manager.
  */
+@Deprecated
 public class ConditionsDriver extends Driver {
 
     /** The name of the detector model. */
@@ -142,4 +145,12 @@
     public final void setXmlConfigResource(final String xmlConfigResource) {
         this.xmlConfigResource = xmlConfigResource;
     }
+
+    public int getRunNumber() {
+        return this.runNumber;
+    }
+
+    public String getDetectorName() {
+        return this.detectorName;
+    }
 }

Modified: java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/api/BaseConditionsObject.java
 =============================================================================
--- java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/api/BaseConditionsObject.java	(original)
+++ java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/api/BaseConditionsObject.java	Wed Apr 27 11:11:32 2016
@@ -15,7 +15,7 @@
  *
  * @author Jeremy McCormick, SLAC
  */
-public class BaseConditionsObject implements ConditionsObject {
+public abstract class BaseConditionsObject implements ConditionsObject {
 
     /**
      * Field name for collection ID.
@@ -206,8 +206,8 @@
      * Get a field value.
      *
      * @param name the field name
-     * @param T the field value
-     * @param <T> the implicit return return
+     * @param <T> the implicit return type
+     * @return the value of field cast to given type
      */
     @Override
     public <T> T getFieldValue(final String name) {
@@ -247,7 +247,7 @@
     /**
      * Return <code>true</code> if collection ID is valid.
      *
-     * @param <code>true</code> if collection ID is valid
+     * @return <code>true</code> if collection ID is valid
      */
     @Override
     public boolean hasValidCollectionId() {
@@ -440,4 +440,22 @@
         }
         return rowsUpdated != 0;
     }
+    
+    public boolean equals(Object object) {
+        // Is it the same object?
+        if (object == this) {
+            return true;
+        }
+        // Are these objects the same class?
+        if (object.getClass().equals(this.getClass())) {
+            BaseConditionsObject otherObject = BaseConditionsObject.class.cast(object);
+            // Do the row IDs and database table name match?
+            if (otherObject.getTableMetaData().getTableName().equals(this.getTableMetaData().getTableName()) &&
+                    this.getRowId() == otherObject.getRowId()) {
+                // These are considered the same object (same database table and row ID).
+                return true;
+            }
+        }
+        return false;
+    }
 }

Modified: java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/api/BaseConditionsObjectCollection.java
 =============================================================================
--- java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/api/BaseConditionsObjectCollection.java	(original)
+++ java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/api/BaseConditionsObjectCollection.java	Wed Apr 27 11:11:32 2016
@@ -102,6 +102,15 @@
         if (object == null) {
             throw new IllegalArgumentException("The object argument is null.");
         }
+        //checkCollectionId(object);
+        final boolean added = this.objects.add(object);
+        if (!added) {
+            throw new RuntimeException("Failed to add object.");
+        }
+        return added;
+    }
+
+    private void checkCollectionId(final ObjectType object) {
         // Does this collection have a valid ID yet?
         if (this.getCollectionId() != BaseConditionsObject.UNSET_COLLECTION_ID) {
             // Does the object that is being added have a collection ID?
@@ -122,11 +131,6 @@
                 }
             }
         }
-        final boolean added = this.objects.add(object);
-        if (!added) {
-            throw new RuntimeException("Failed to add object.");
-        }
-        return added;
     }
 
     /**
@@ -344,7 +348,7 @@
         } else {
             // If the collection already exists in the database with this ID then it cannot be inserted.
             if (this.exists()) {
-                throw new DatabaseObjectException("The collection " + this.collectionId
+                throw new DatabaseObjectException("The collection ID " + this.collectionId
                         + " cannot be inserted because it already exists in the " + this.tableMetaData.getTableName()
                         + " table.", this);
             }
@@ -605,7 +609,7 @@
     /**
      * Set the table meta data of the collection.
      *
-     * @param the table meta data of the collection
+     * @param tableMetaData the table meta data of the collection
      * @see TableMetaData
      */
     @Override
@@ -703,7 +707,6 @@
     public void writeCsv(final File file) throws IOException {
         FileWriter fileWriter = null;
         CSVPrinter csvFilePrinter = null;
-
         try {
             fileWriter = new FileWriter(file);
             csvFilePrinter = new CSVPrinter(fileWriter, CSVFormat.DEFAULT);

Modified: java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/api/ConditionsObjectCollection.java
 =============================================================================
--- java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/api/ConditionsObjectCollection.java	(original)
+++ java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/api/ConditionsObjectCollection.java	Wed Apr 27 11:11:32 2016
@@ -64,7 +64,6 @@
      * Load collection from a CSV file.
      *
      * @param file the input CSV file
-     * @param delimiter the field delimiter (leave blank for default which is comma-delimited)
      * @throws IOException if there is an error closing the reader
      * @throws FileNotFoundException if the input file does not exist
      * @throws ConditionsObjectException if there is an error creating a conditions object
@@ -104,7 +103,6 @@
      * Write the collection contents to a text file.
      *
      * @param file the output text file
-     * @param delimiter the field delimiter (leave blank for default which is comma-delimited)
      */
     void writeCsv(File file) throws IOException;
 }

Modified: java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/api/ConditionsObjectException.java
 =============================================================================
--- java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/api/ConditionsObjectException.java	(original)
+++ java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/api/ConditionsObjectException.java	Wed Apr 27 11:11:32 2016
@@ -16,7 +16,7 @@
     /**
      * Error with a message.
      *
-     * @param message the error message
+     * @param e the original exception
      */
     public ConditionsObjectException(Exception e) {
         super(e);

Modified: java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/api/ConditionsRecord.java
 =============================================================================
--- java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/api/ConditionsRecord.java	(original)
+++ java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/api/ConditionsRecord.java	Wed Apr 27 11:11:32 2016
@@ -8,6 +8,7 @@
 import org.hps.conditions.database.ConditionsRecordConverter;
 import org.hps.conditions.database.Converter;
 import org.hps.conditions.database.Field;
+import org.hps.conditions.database.MultipleCollectionsAction;
 import org.hps.conditions.database.Table;
 
 /**
@@ -233,6 +234,33 @@
         public final ConditionsRecordCollection sortedByUpdated() {
             return (ConditionsRecordCollection) this.sorted(new UpdatedComparator());
         }
+        
+        /**
+         * Find a unique record using the selected action for disambiguating conditions with the same key.
+         * @param key the name of the key
+         * @param action the disambiguation action
+         * @return the unique conditions record or <code>null</code> if does not exist
+         */
+        public ConditionsRecord findUniqueRecord(String key, MultipleCollectionsAction action) {
+            ConditionsRecord record = null;
+            ConditionsRecordCollection keyRecords = this.findByKey(key);
+            if (keyRecords.size() > 0) {
+                if (keyRecords.size() == 1) {
+                    record = keyRecords.get(0);
+                } else {
+                    if (action.equals(MultipleCollectionsAction.LAST_UPDATED)) {
+                        record = keyRecords.sortedByUpdated().get(keyRecords.size() - 1);
+                    } else if (action.equals(MultipleCollectionsAction.LAST_CREATED)) {
+                        record = keyRecords.sortedByCreated().get(keyRecords.size() - 1);
+                    } else if (action.equals(MultipleCollectionsAction.LATEST_RUN_START)) {
+                        record = keyRecords.sortedByRunStart().get(keyRecords.size() - 1);
+                    } else if (action.equals(MultipleCollectionsAction.ERROR)) {
+                        throw new RuntimeException("Multiple ConditionsRecord object found for conditions key " + key + ".");
+                    }
+                }
+            }
+            return record;
+        }
     }
 
     /**

Modified: java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/api/package-info.java
 =============================================================================
--- java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/api/package-info.java	(original)
+++ java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/api/package-info.java	Wed Apr 27 11:11:32 2016
@@ -1,11 +1,13 @@
 /**
- * User interface to the database conditions system
+ * User API to the database conditions system
  *
  * @author Jeremy McCormick, SLAC
- * @see ConditionsObject
- * @see ConditionsObjectCollection
- * @see ConditionsSeries
- * @see ConditionsRecord
+ * 
+ * @see org.hps.conditions.api.ConditionsObject
+ * @see org.hps.conditions.api.ConditionsObjectCollection
+ * @see org.hps.conditions.api.ConditionsSeries
+ * @see org.hps.conditions.api.ConditionsRecord
+ * @see org.hps.conditions.api.ConditionsTag
  */
 package org.hps.conditions.api;
 

Modified: java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/cli/AbstractCommand.java
 =============================================================================
--- java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/cli/AbstractCommand.java	(original)
+++ java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/cli/AbstractCommand.java	Wed Apr 27 11:11:32 2016
@@ -1,7 +1,7 @@
 package org.hps.conditions.cli;
 
 import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.DefaultParser;
+import org.apache.commons.cli.PosixParser;
 import org.apache.commons.cli.HelpFormatter;
 import org.apache.commons.cli.Options;
 import org.apache.commons.cli.ParseException;
@@ -32,7 +32,7 @@
     /**
      * The parser for the options.
      */
-    private final DefaultParser parser = new DefaultParser();
+    private final PosixParser parser = new PosixParser();
 
     /**
      * Class constructor.

Modified: java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/cli/AddCommand.java
 =============================================================================
--- java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/cli/AddCommand.java	(original)
+++ java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/cli/AddCommand.java	Wed Apr 27 11:11:32 2016
@@ -32,16 +32,13 @@
      */
     private static final Options OPTIONS = new Options();
     static {
-        OPTIONS.addOption(new Option("h", false, "print help for add command"));
-        OPTIONS.addOption("r", true, "starting run number (required)");
-        OPTIONS.getOption("r").setRequired(true);
-        OPTIONS.addOption("e", true, "ending run number (default is starting run number)");
-        OPTIONS.addOption("t", true, "table name (required)");
-        OPTIONS.getOption("t").setRequired(true);
-        OPTIONS.addOption("c", true, "collection ID (required)");
-        OPTIONS.getOption("c").setRequired(true);
-        OPTIONS.addOption("u", true, "user name (optional)");
-        OPTIONS.addOption("m", true, "notes about this conditions set (optional)");
+        OPTIONS.addOption(new Option("h", "help", false, "print help for add command"));
+        OPTIONS.addOption("r", "run-start", true, "starting run number (required)");
+        OPTIONS.addOption("e", "run-end", true, "ending run number (default is starting run number)");
+        OPTIONS.addOption("t", "table", true, "table name (required)");
+        OPTIONS.addOption("c", "collection", true, "collection ID (required)");
+        OPTIONS.addOption("u", "user", true, "user name (optional)");
+        OPTIONS.addOption("m", "notes", true, "notes about this conditions set (optional)");
     }
 
     /**

Modified: java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/cli/CommandLineTool.java
 =============================================================================
--- java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/cli/CommandLineTool.java	(original)
+++ java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/cli/CommandLineTool.java	Wed Apr 27 11:11:32 2016
@@ -11,7 +11,7 @@
 import org.apache.commons.cli.Option;
 import org.apache.commons.cli.Options;
 import org.apache.commons.cli.ParseException;
-import org.apache.commons.cli.DefaultParser;
+import org.apache.commons.cli.PosixParser;
 import org.hps.conditions.database.DatabaseConditionsManager;
 import org.lcsim.conditions.ConditionsManager.ConditionsNotFoundException;
 
@@ -34,13 +34,12 @@
     private static Options OPTIONS = new Options();
 
     static {
-        OPTIONS.addOption(new Option("h", false, "print help"));
-        OPTIONS.addOption(new Option("d", true, "detector name"));
-        OPTIONS.addOption(new Option("r", true, "run number"));
-        OPTIONS.addOption(new Option("p", true, "database connection properties file"));
-        OPTIONS.addOption(new Option("x", true, "conditions XML configuration file"));
-        OPTIONS.addOption(new Option("t", true, "conditions tag to use for filtering records"));
-        OPTIONS.addOption(new Option("l", true, "log level of the conditions manager (INFO, FINE, etc.)"));
+        OPTIONS.addOption(new Option("h", "help", false, "print help"));
+        OPTIONS.addOption(new Option("d", "detector", true, "detector name"));
+        OPTIONS.addOption(new Option("r", "run", true, "run number"));
+        OPTIONS.addOption(new Option("p", "connection", true, "database connection properties file"));
+        OPTIONS.addOption(new Option("x", "xml", true, "conditions XML configuration file"));
+        OPTIONS.addOption(new Option("t", "tag", true, "conditions tag to use for filtering records"));
     }
 
     /**
@@ -80,7 +79,7 @@
     /**
      * The options parser.
      */
-    private final DefaultParser parser = new DefaultParser();
+    private final PosixParser parser = new PosixParser();
 
     /**
      * Exit with the given status.
@@ -176,13 +175,6 @@
 
         // Create new manager.
         this.conditionsManager = DatabaseConditionsManager.getInstance();
-
-        // Set the conditions manager log level (does not affect logger of this class or sub-commands).
-        if (commandLine.hasOption("l")) {
-            final Level newLevel = Level.parse(commandLine.getOptionValue("l"));
-            Logger.getLogger(DatabaseConditionsManager.class.getPackage().getName()).setLevel(newLevel);
-            LOGGER.config("conditions manager log level will be set to " + newLevel.toString());
-        }
 
         // Connection properties.
         if (commandLine.hasOption("p")) {

Modified: java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/cli/LoadCommand.java
 =============================================================================
--- java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/cli/LoadCommand.java	(original)
+++ java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/cli/LoadCommand.java	Wed Apr 27 11:11:32 2016
@@ -33,12 +33,10 @@
      */
     private static final Options OPTIONS = new Options();
     static {
-        OPTIONS.addOption(new Option("h", false, "print help for load command"));
-        OPTIONS.addOption(new Option("t", true, "name of the target table (required)"));
-        OPTIONS.getOption("t").setRequired(true);
-        OPTIONS.addOption(new Option("f", true, "input data file path (required)"));
-        OPTIONS.getOption("f").setRequired(true);
-        OPTIONS.addOption(new Option("d", true, "description for the collection log"));
+        OPTIONS.addOption(new Option("h", "help", false, "print help for load command"));
+        OPTIONS.addOption(new Option("t", "table", true, "name of the target table (required)"));
+        OPTIONS.addOption(new Option("f", "file", true, "input data file path (required)"));
+        OPTIONS.addOption(new Option("d", "description", true, "description for the collection log"));
     }
 
     /**

Modified: java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/cli/PrintCommand.java
 =============================================================================
--- java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/cli/PrintCommand.java	(original)
+++ java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/cli/PrintCommand.java	Wed Apr 27 11:11:32 2016
@@ -38,18 +38,17 @@
     static Options options = new Options();
 
     static {
-        options.addOption(new Option("h", false, "print help for print command"));
-        options.addOption(new Option("t", true, "table name"));
-        options.addOption(new Option("i", false, "print the ID for the records (off by default)"));
-        options.addOption(new Option("f", true, "write print output to a file (must be used with -t option)"));
-        options.addOption(new Option("H", false, "suppress printing of conditions record and table info"));
-        options.addOption(new Option("d", false, "use tabs for field delimiter instead of spaces"));
+        options.addOption(new Option("h", "help", false, "print help for print command"));
+        options.addOption(new Option("t", "table", true, "table name"));
+        options.addOption(new Option("i", "print-id", false, "include the row IDs in printouts"));
+        options.addOption(new Option("f", "file", true, "write output to a file (requires -t option)"));
+        options.addOption(new Option("H", "no-header", false, "suppress printing of conditions record and table info"));
     }
 
     /**
      * The field delimiter for print output.
      */
-    private char fieldDelimiter = ' ';
+    private static final char DELIMITER = ',';    
 
     /**
      * Output file if printing to a file.
@@ -125,11 +124,6 @@
         // Print header info. Option turns this off.
         if (commandLine.hasOption("h")) {
             this.printHeaders = false;
-        }
-
-        // Use tabs instead of spaces for field delimiter.
-        if (commandLine.hasOption("d")) {
-            this.fieldDelimiter = '\t';
         }
 
         // List of conditions records to print.
@@ -173,7 +167,7 @@
             for (final String columnName : collection.getTableMetaData().getFieldNames()) {
                 if (!"collection_id".equals(columnName)) {
                     buffer.append(((ConditionsObject) object).getFieldValue(columnName));
-                    buffer.append(this.fieldDelimiter);
+                    buffer.append(DELIMITER);
                 }
             }
             buffer.setLength(buffer.length() - 1);
@@ -221,15 +215,17 @@
     private void printColumnNames(final TableMetaData tableMetaData) {
         if (this.printIDs) {
             this.ps.print("id");
-            this.ps.print(this.fieldDelimiter);
-        }
+            this.ps.print(DELIMITER);
+        }
+        StringBuffer sb = new StringBuffer();
         for (final String columnName : tableMetaData.getFieldNames()) {
             if (!"collection_id".equals(columnName)) {
-                this.ps.print(columnName);
-                this.ps.print(this.fieldDelimiter);
-            }
-        }
-        this.ps.println();
+                sb.append(columnName);
+                sb.append(DELIMITER);
+            }
+        }
+        sb.setLength(sb.length() - 1);
+        this.ps.println(sb.toString());
     }
 
     /**

Modified: java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/cli/RunSummaryCommand.java
 =============================================================================
--- java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/cli/RunSummaryCommand.java	(original)
+++ java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/cli/RunSummaryCommand.java	Wed Apr 27 11:11:32 2016
@@ -35,8 +35,8 @@
      */
     static Options options = new Options();
     static {
-        options.addOption(new Option("h", false, "Show help for run-summary command"));
-        options.addOption(new Option("a", false, "Print all collections found for the run"));
+        options.addOption(new Option("h", "help", false, "Show help for run-summary command"));
+        options.addOption(new Option("a", "all", false, "Print all collections found for the run"));
     }
 
     /**

Modified: java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/cli/TagCommand.java
 =============================================================================
--- java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/cli/TagCommand.java	(original)
+++ java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/cli/TagCommand.java	Wed Apr 27 11:11:32 2016
@@ -1,10 +1,9 @@
 package org.hps.conditions.cli;
 
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
 import java.sql.SQLException;
-import java.util.logging.Level;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.TreeSet;
 import java.util.logging.Logger;
 
 import org.apache.commons.cli.CommandLine;
@@ -16,17 +15,16 @@
 import org.hps.conditions.api.ConditionsTag;
 import org.hps.conditions.api.ConditionsTag.ConditionsTagCollection;
 import org.hps.conditions.api.DatabaseObjectException;
-import org.hps.conditions.api.TableMetaData;
 import org.hps.conditions.api.TableRegistry;
+import org.hps.conditions.database.DatabaseConditionsManager;
 import org.hps.conditions.database.MultipleCollectionsAction;
+import org.lcsim.conditions.ConditionsManager.ConditionsNotFoundException;
 
 /**
  * Create a conditions system tag.
  * <p>
  * The tag groups together conditions records from the <i>conditions</i> database table with a run validity range that 
  * is between a specified starting and ending run.
- * <p>
- * Tagging will not disambiguate overlapping conditions, which is done at run-time based on the current run number.
  *
  * @author Jeremy McCormick, SLAC
  */
@@ -41,20 +39,29 @@
      * Defines command options.
      */
     private static Options OPTIONS = new Options();
+    
+    private MultipleCollectionsAction multipleCollectionsAction = MultipleCollectionsAction.LAST_CREATED; 
+    
+    private static String getMultipleCollectionsActionString() {
+        StringBuffer sb = new StringBuffer();
+        for (MultipleCollectionsAction action : MultipleCollectionsAction.values()) {
+            sb.append(action.name() + " ");
+        }
+        sb.setLength(sb.length() - 1);
+        return sb.toString();
+    }
 
     /**
      * Define all command options.
      */
     static {
-        OPTIONS.addOption(new Option("h", false, "Show help for tag command"));
-        OPTIONS.addOption(new Option("t", true, "Conditions tag name"));
-        OPTIONS.addOption(new Option("s", true, "Starting run number (required)"));
-        OPTIONS.getOption("s").setRequired(true);
-        OPTIONS.addOption(new Option("e", true, "Ending run number (default is unlimited)"));
-        OPTIONS.getOption("t").setRequired(true);
-        OPTIONS.addOption(new Option("m", true,
-                "MultipleCollectionsAction to use for disambiguation (default is LAST_CREATED)"));
-        OPTIONS.addOption(new Option("d", false, "Don't prompt before making tag (be careful!)"));
+        OPTIONS.addOption(new Option("h", "help", false, "Show help for tag command"));
+        OPTIONS.addOption(new Option("t", "tag", true, "Conditions tag name"));
+        OPTIONS.addOption(new Option("s", "run-start", true, "Starting run number (required)"));
+        OPTIONS.addOption(new Option("e", "run-end", true, "Ending run number (required)"));
+        OPTIONS.addOption(new Option("m", "multiple", true, 
+                "set run overlap handling (" + getMultipleCollectionsActionString() + ")"));
+        OPTIONS.addOption(new Option("D", "dont-prompt", false, "Don't prompt before making tag (careful!)"));
     }
 
     /**
@@ -103,6 +110,11 @@
         } else {
             throw new RuntimeException("Missing required -t argument with the tag name.");
         }
+        
+        // Check if tag exists already.
+        if (getManager().getAvailableTags().contains(tagName)) {
+            throw new RuntimeException("The tag '" + tagName + "' already exists in the database.");
+        }
 
         // Starting run number (required).
         int runStart = -1;
@@ -110,19 +122,16 @@
             runStart = Integer.parseInt(commandLine.getOptionValue("s"));
             LOGGER.config("run start set to " + runStart);
         } else {
-            throw new RuntimeException("missing require -s argument with starting run number");
-        }
-
-        // Ending run number (max integer is default).
-        int runEnd = Integer.MAX_VALUE;
+            throw new RuntimeException("Missing required -s argument with starting run number.");
+        }
+
+        // Ending run number (required).
+        int runEnd = -1;
         if (commandLine.hasOption("e")) {
             runEnd = Integer.parseInt(commandLine.getOptionValue("e"));
             LOGGER.config("run end set to " + runEnd);
-        }
-
-        // Run end must be greater than or equal to run start.
-        if (runEnd < runStart) {
-            throw new IllegalArgumentException("runEnd < runStart");
+        } else {
+            throw new RuntimeException("Missing required -e argument with starting run number.");
         }
 
         // Action for disambiguating overlapping collections (default is to use the most recent creation date).
@@ -131,20 +140,24 @@
             multipleCollectionsAction = MultipleCollectionsAction
                     .valueOf(commandLine.getOptionValue("m").toUpperCase());
         }
-        LOGGER.config("multiple collections action set tco " + multipleCollectionsAction);
+        LOGGER.config("run overlaps will be disambiguated using " + multipleCollectionsAction);
 
         // Whether to prompt before tagging (default is yes).
         boolean promptBeforeTagging = true;
         if (commandLine.hasOption("d")) {
             promptBeforeTagging = false;
         }
-        LOGGER.config("prompt before tagging: " + promptBeforeTagging);
+        LOGGER.config("prompt before tagging = " + promptBeforeTagging);
 
         // Conditions system configuration.
         this.getManager().setXmlConfig("/org/hps/conditions/config/conditions_database_no_svt.xml");
 
         // Find all the applicable conditions records by their run number ranges.
         ConditionsRecordCollection tagConditionsRecordCollection = this.findConditionsRecords(runStart, runEnd);
+        
+        if (tagConditionsRecordCollection.size() == 0) {
+            throw new RuntimeException("No records found for tag.");
+        }
 
         LOGGER.info("found " + tagConditionsRecordCollection.size() + " conditions records for the tag");
 
@@ -152,8 +165,8 @@
         final ConditionsTagCollection conditionsTagCollection = this.createConditionsTagCollection(
                 tagConditionsRecordCollection, tagName);
 
-        LOGGER.info("created " + conditionsTagCollection.size() + " tag records ..." + '\n' + conditionsTagCollection);
-
+        printConditionsRecords(tagConditionsRecordCollection);
+        
         // Prompt user to verify tag creation.
         boolean createTag = true;
         if (promptBeforeTagging) {
@@ -178,68 +191,85 @@
 
         LOGGER.info("done!");
     }
-   
-    /**
-     * Find all the conditions records that are applicable for the given run range.
-     * <p>
-     * Overlapping run numbers in conditions with the same key are not disambiguated.
-     * This must be done in the user's job at runtime; usually the most recently created 
-     * conditions record will be used if multiple one's are applicable to the current run.
-     *
-     * @param runStart the start run
-     * @param runEnd the end run (must be greater than or equal to <code>runStart</code>)
-     * @return the conditions records that fall in the run range
+    
+    /**
+     * Print information about conditions records in the tag to the log.
+     * 
+     * @param collection the conditions tag collection
+     */
+    private void printConditionsRecords(ConditionsRecordCollection records) {
+        StringBuffer sb = new StringBuffer();
+        Set<String> keys = new TreeSet<String>(records.getConditionsKeys());
+        for (String key : keys) {
+            ConditionsRecordCollection keyRecords = records.findByKey(key);
+            keyRecords.sortByKey();
+            for (ConditionsRecord record : keyRecords) {
+                sb.append("conditions_id: " + record.getRowId() + ", name: " + record.getName() + ", collection_id: "
+                        + record.getCollectionId() + ", run_start: " + record.getRunStart() 
+                        + ", run_end: " + record.getRunEnd() + ", notes: " + record.getNotes() + '\n');
+                
+            }
+        }        
+        LOGGER.info("including " + records.size() + " records in tag ..." + '\n' + sb.toString());
+    }
+     
+    /**
+     * Scan through a run range to find conditions records for the tag.
+     * 
+     * @param runStart the starting run number
+     * @param runEnd the ending run number
+     * @return the conditions records for the tag
      */
     private ConditionsRecordCollection findConditionsRecords(final int runStart, final int runEnd) {
-        if (runStart > runEnd) {
-            throw new IllegalArgumentException("runStart > runEnd");
-        }
-        if (runStart < 0) {
-            throw new IllegalArgumentException("invalid runStart: " + runStart);
-        }
-        if (runEnd < 0) {
-            throw new IllegalArgumentException("invalid runEnd: " + runEnd);
-        }
-        final Connection connection = this.getManager().getConnection();
-        final ConditionsRecordCollection conditionsRecordCollection = new ConditionsRecordCollection();
-        final TableMetaData tableMetaData = TableRegistry.getTableRegistry().findByTableName("conditions");
-        PreparedStatement statement = null;
-        try {
-            /*
-             * SQL statement handles 3 cases: 
-             * 1) condition's run_start in range 
-             * 2) condition's run_end in range 
-             * 3) condition's run_start and run_end enclose the range
-             */
-            statement = connection
-                    .prepareStatement("SELECT id FROM conditions WHERE (run_start >= ? and run_start <= ?) or (run_end >= ? and run_end <= ?)"
-                            + " or (run_start <= ? and run_end >= ?)");
-            statement.setInt(1, runStart);
-            statement.setInt(2, runEnd);
-            statement.setInt(3, runStart);
-            statement.setInt(4, runEnd);
-            statement.setInt(5, runStart);
-            statement.setInt(6, runEnd);
-
-            final ResultSet resultSet = statement.executeQuery();
-            while (resultSet.next()) {
-                final ConditionsRecord record = new ConditionsRecord();
-                record.setConnection(connection);
-                record.setTableMetaData(tableMetaData);
-                record.select(resultSet.getInt(1));
-                conditionsRecordCollection.add(record);
-            }
-        } catch (DatabaseObjectException | ConditionsObjectException | SQLException e) {
-            throw new RuntimeException(e);
-        } finally {
+        if (runStart < 0 ) {
+            throw new IllegalArgumentException("The run start " + runStart + " is invalid.");
+        }
+        if (runEnd < 0 ) {
+            throw new IllegalArgumentException("The run end " + runEnd + " is invalid.");
+        }
+        if (runStart > runEnd ) {
+            throw new IllegalArgumentException("The run start is greater than the run end.");
+        }
+        DatabaseConditionsManager dbManager = this.getManager();
+        if (dbManager.isFrozen()) {
+            dbManager.unfreeze();
+        }
+        if (!dbManager.getActiveTags().isEmpty()) {
+            dbManager.clearTags();
+        }
+        final String detectorName = "HPS-dummy-detector";
+        ConditionsRecordCollection tagRecords = new ConditionsRecordCollection();
+        Set<Integer> ids = new HashSet<Integer>();
+        for (int run = runStart; run <= runEnd; run++) {
+            LOGGER.info("loading run " + run);
             try {
-                if (statement != null) {
-                    statement.close();
+                dbManager.setDetector(detectorName, run);
+            } catch (ConditionsNotFoundException e) {
+                throw new RuntimeException(e);
+            }
+            ConditionsRecordCollection runRecords = dbManager.getConditionsRecords();
+            Set<String> keys = runRecords.getConditionsKeys();
+            LOGGER.fine("run has " + runRecords.size() + " conditions records");
+            for (String key : keys) {
+                ConditionsRecord record = runRecords.findUniqueRecord(key, this.multipleCollectionsAction);
+                if (record == null) {
+                    throw new RuntimeException("Missing expected unique condition record for " + key + ".");
                 }
-            } catch (final SQLException e) {
-                e.printStackTrace();
-            }
-        }
-        return conditionsRecordCollection;
+                if (!ids.contains(record.getRowId())) {
+                    try {
+                        LOGGER.fine("adding conditions to tag ..." + '\n' + record.toString());
+                        tagRecords.add(record);
+                        ids.add(record.getRowId());
+                    } catch (ConditionsObjectException e) {
+                        throw new RuntimeException(e);
+                    }
+                } else {
+                    LOGGER.fine("Conditions record with row id " + record.getRowId() + " is already in the tag.");
+                }
+            }
+            LOGGER.info("done processing run " + run);
+        }
+        LOGGER.info("Found " + tagRecords.size() + " conditions records for tag.");
+        return tagRecords;
     }
 }

Modified: java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/database/ConditionsRecordConverter.java
 =============================================================================
--- java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/database/ConditionsRecordConverter.java	(original)
+++ java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/database/ConditionsRecordConverter.java	Wed Apr 27 11:11:32 2016
@@ -3,7 +3,6 @@
 import java.sql.ResultSet;
 import java.sql.SQLException;
 
-import org.hps.conditions.api.AbstractConditionsObjectConverter;
 import org.hps.conditions.api.ConditionsObject;
 import org.hps.conditions.api.ConditionsObjectCollection;
 import org.hps.conditions.api.ConditionsObjectException;

Modified: java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/database/ConditionsTagConverter.java
 =============================================================================
--- java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/database/ConditionsTagConverter.java	(original)
+++ java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/database/ConditionsTagConverter.java	Wed Apr 27 11:11:32 2016
@@ -5,7 +5,6 @@
 import java.sql.ResultSet;
 import java.sql.SQLException;
 
-import org.hps.conditions.api.AbstractConditionsObjectConverter;
 import org.hps.conditions.api.ConditionsObjectException;
 import org.hps.conditions.api.ConditionsTag;
 import org.hps.conditions.api.ConditionsTag.ConditionsTagCollection;
@@ -24,14 +23,13 @@
     private static final String SELECT_SQL = "SELECT conditions_id, tag from conditions_tags where tag = ?";
    
     /**
-     * Get a {@link org.hps.conditions.api.ConditionsTagCollection} which specifies a group of collections
-     * that are tagged in the <i>conditions_tags</i> table in the database.
-     * <p>
-     * The run number is not used, and the <code>name</code> argument specifies the tag name.
+     * Get a {@link org.hps.conditions.api.ConditionsTag.ConditionsTagCollection} which specifies a group of 
+     * collections that are tagged in the <i>conditions_tags</i> table in the database.  The <code>name</code> 
+     * argument is the tag name.
      *
-     * @param manager The current conditions manager.
-     * @param name The name of the conditions set.
-     * @return The matching ConditionsRecords.
+     * @param manager the current conditions manager
+     * @param name the name of the conditions set
+     * @return the matching <code>ConditionsRecord</code> objects
      */
     @Override
     public ConditionsTagCollection getData(final ConditionsManager manager, final String name) {

Modified: java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/database/ConnectionParameters.java
 =============================================================================
--- java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/database/ConnectionParameters.java	(original)
+++ java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/database/ConnectionParameters.java	Wed Apr 27 11:11:32 2016
@@ -13,7 +13,8 @@
 import java.util.logging.Logger;
 
 /**
- * This class encapsulates the parameters for connecting to a database, including host name, port, user and password.
+ * This class encapsulates the parameters for connecting to a database,
+ * including host name, port, user and password.
  *
  * @author Jeremy McCormick, SLAC
  */
@@ -28,6 +29,12 @@
      * Number of connection retries allowed.
      */
     private static final int MAX_ATTEMPTS = 10;
+    
+    /**
+     * Wait time (in millis) for the first retry. The nth retry waits for
+     * n*RETRY_WAIT millis.
+     */
+    private static final int RETRY_WAIT = 5000;
 
     /**
      * Configure the connection parameters from a properties file.
@@ -46,7 +53,8 @@
     }
 
     /**
-     * Configure the connection parameters from an <code>InputStream</code> of properties.
+     * Configure the connection parameters from an <code>InputStream</code> of
+     * properties.
      *
      * @param in the InputStream of the properties
      * @return the connection parameters
@@ -71,7 +79,8 @@
     }
 
     /**
-     * Configure the connection parameters from an embedded classpath resource which should be a properties file.
+     * Configure the connection parameters from an embedded classpath resource
+     * which should be a properties file.
      *
      * @param resource the resource path
      * @return the connection parameters
@@ -146,8 +155,8 @@
     }
 
     /**
-     * Create a database connection from these parameters. The caller becomes the "owner" and is responsible for closing
-     * it when finished.
+     * Create a database connection from these parameters. The caller becomes
+     * the "owner" and is responsible for closing it when finished.
      *
      * @return the new <code>Connection</code> object
      */
@@ -166,7 +175,7 @@
                     throw new RuntimeException("Failed to connect to database after " + attempt + " attempts: " + this.getConnectionString(), x);
                 }
                 try {
-                    Thread.sleep(attempt * 1000);
+                    Thread.sleep(attempt * RETRY_WAIT);
                 } catch (InterruptedException ex) {
                     Logger.getLogger(ConnectionParameters.class.getName()).log(Level.SEVERE, null, ex);
                 }
@@ -247,13 +256,13 @@
     String getUser() {
         return this.user;
     }
-    
+
     /**
      * Convert to human readable string.
-     * 
+     *
      * @return this object converted to a string
      */
-    public String toString() {                        
+    public String toString() {
         return "ConnectionParameters { database: " + database + ", hostname: " + hostname + ", password: " + password
                 + ", port: " + port + ", user: " + user + " }";
     }

Modified: java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/database/Converter.java
 =============================================================================
--- java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/database/Converter.java	(original)
+++ java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/database/Converter.java	Wed Apr 27 11:11:32 2016
@@ -4,8 +4,6 @@
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
-
-import org.hps.conditions.api.AbstractConditionsObjectConverter;
 
 /**
  * This is an annotation for providing converter configuration for {@link org.hps.conditions.api.ConditionsObject}

Modified: java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/database/ConverterRegistry.java
 =============================================================================
--- java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/database/ConverterRegistry.java	(original)
+++ java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/database/ConverterRegistry.java	Wed Apr 27 11:11:32 2016
@@ -6,7 +6,6 @@
 
 import javassist.Modifier;
 
-import org.hps.conditions.api.AbstractConditionsObjectConverter;
 import org.hps.conditions.api.BaseConditionsObjectCollection;
 import org.hps.conditions.api.ConditionsObject;
 import org.hps.conditions.api.TableRegistry;

Modified: java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/database/DatabaseConditionsManager.java
 =============================================================================
--- java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/database/DatabaseConditionsManager.java	(original)
+++ java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/database/DatabaseConditionsManager.java	Wed Apr 27 11:11:32 2016
@@ -20,7 +20,6 @@
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
-import org.hps.conditions.api.AbstractConditionsObjectConverter;
 import org.hps.conditions.api.ConditionsObject;
 import org.hps.conditions.api.ConditionsObjectCollection;
 import org.hps.conditions.api.ConditionsRecord.ConditionsRecordCollection;
@@ -338,7 +337,7 @@
     }
 
     /**
-     * Clear the tags used to filter the {@link org.hps.conditons.api.ConditionsRecord}s.
+     * Clear the tags used to filter the {@link org.hps.conditions.api.ConditionsRecord}s.
      */
     public void clearTags() {
         this.tags.clear();
@@ -505,9 +504,8 @@
 
     /**
      * Add a row for a new collection and return the new collection ID assigned to it.
-     *
-     * @param tableName the name of the table
-     * @param comment an optional comment about this new collection
+     * @param collection the conditions object collection
+     * @param description text description for the new collection ID record in the database
      * @return the collection's ID
      * @throws SQLException
      */

Modified: java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/database/package-info.java
 =============================================================================
--- java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/database/package-info.java	(original)
+++ java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/database/package-info.java	Wed Apr 27 11:11:32 2016
@@ -1,5 +1,10 @@
 /**
- * Implementation of database API to detector conditions
+ * Implementation of database API for detector conditions
+ * <p>
+ * The {@link org.hps.conditions.database.DatabaseConditionsManager} has a set of converters for handling the 
+ * conversion of conditions table data to typed collections.  The converters are created automatically using 
+ * introspection of {@link org.hps.conditions.api.ConditionsObject} classes that have the
+ * {@link org.hps.conditions.database.Table} and {@link org.hps.conditions.database.Field} annotations.
  *
  * @author Jeremy McCormick, SLAC
  */

Modified: java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/dummy/DummyConditionsObjectConverter.java
 =============================================================================
--- java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/dummy/DummyConditionsObjectConverter.java	(original)
+++ java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/dummy/DummyConditionsObjectConverter.java	Wed Apr 27 11:11:32 2016
@@ -1,6 +1,6 @@
 package org.hps.conditions.dummy;
 
-import org.hps.conditions.api.AbstractConditionsObjectConverter;
+import org.hps.conditions.database.AbstractConditionsObjectConverter;
 import org.hps.conditions.dummy.DummyConditionsObject.DummyConditionsObjectCollection;
 
 /**

Modified: java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/ecal/EcalChannel.java
 =============================================================================
--- java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/ecal/EcalChannel.java	(original)
+++ java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/ecal/EcalChannel.java	Wed Apr 27 11:11:32 2016
@@ -4,12 +4,12 @@
 import java.util.HashMap;
 import java.util.Map;
 
-import org.hps.conditions.api.AbstractConditionsObjectConverter;
 import org.hps.conditions.api.AbstractIdentifier;
 import org.hps.conditions.api.BaseConditionsObject;
 import org.hps.conditions.api.BaseConditionsObjectCollection;
 import org.hps.conditions.api.ConditionsObjectCollection;
 import org.hps.conditions.api.ConditionsObjectException;
+import org.hps.conditions.database.AbstractConditionsObjectConverter;
 import org.hps.conditions.database.Converter;
 import org.hps.conditions.database.DatabaseConditionsManager;
 import org.hps.conditions.database.Field;
@@ -290,11 +290,16 @@
         public EcalChannelCollection getData(final ConditionsManager conditionsManager, final String name) {
             final EcalChannelCollection collection = super.getData(conditionsManager, name);
             final Subdetector ecal = DatabaseConditionsManager.getInstance().getEcalSubdetector();
-            if (ecal.getDetectorElement() != null) {
-                collection.buildGeometryMap(ecal.getDetectorElement().getIdentifierHelper(), ecal.getSystemID());
+            if (ecal != null) {
+                if (ecal.getDetectorElement() != null) {
+                    collection.buildGeometryMap(ecal.getDetectorElement().getIdentifierHelper(), ecal.getSystemID());
+                } else {
+                    // This can happen when not running with the detector-framework jar in the classpath.
+                    throw new IllegalStateException("The ECal subdetector's detector element is not setup.");
+                }
             } else {
-                // This can happen when not running with the detector-framework jar in the classpath.
-                throw new IllegalStateException("The ECal subdetector's detector element is not setup.");
+                // Bad detector or conditions system not initialized properly.
+                throw new IllegalStateException("The ECal subdetector object is null.");
             }
             return collection;
         }

Modified: java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/ecal/EcalConditions.java
 =============================================================================
--- java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/ecal/EcalConditions.java	(original)
+++ java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/ecal/EcalConditions.java	Wed Apr 27 11:11:32 2016
@@ -11,7 +11,7 @@
  * settings, per crystal.
  * <p>
  * Unlike most conditions data types, it does not extend {@link org.hps.conditions.api.ConditionsObject}, because it is
- * a composite object containing data assembled from many other {@link org.hps.conditions.ConditionsObjects} and has a
+ * a composite object containing data assembled from many other {@link org.hps.conditions.api.ConditionsObject} and has a
  * special data converter {@link EcalConditionsConverter}.
  *
  * @author Jeremy McCormick, SLAC

Modified: java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/ecal/EcalConditionsConverter.java
 =============================================================================
--- java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/ecal/EcalConditionsConverter.java	(original)
+++ java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/ecal/EcalConditionsConverter.java	Wed Apr 27 11:11:32 2016
@@ -22,6 +22,7 @@
  *
  * @author Jeremy McCormick, SLAC
  * @author Omar Moreno, UCSC
+ * 
  * @see EcalConditions
  * @see EcalChannel
  * @see EcalGain
@@ -38,8 +39,7 @@
        
     /**
      * Create combined ECAL conditions object containing all data for the current run.
-     *
-     * @param manager the conditions manager
+     * 
      * @param name the conditions set name (unused but must satisfy conditions API)
      */
     @Override
@@ -129,7 +129,6 @@
     /**
      * Get the default collections of {@link EcalBadChannel} objects.
      *
-     * @param manager the conditions manager
      * @return the collections of ECAL bad channel objects
      */
     protected ConditionsSeries<EcalBadChannel, EcalBadChannelCollection> getEcalBadChannelSeries() {
@@ -139,7 +138,6 @@
     /**
      * Get the default {@link EcalCalibration} collection.
      *
-     * @param manager the conditions manager
      * @return the collection of ECAL channel calibration objects
      */
     protected EcalCalibrationCollection getEcalCalibrationCollection() {
@@ -149,7 +147,6 @@
     /**
      * Get the default {@link EcalChannel} collection.
      *
-     * @param manager the conditions manager
      * @return the default ECAL channel object collection
      */
     protected EcalChannelCollection getEcalChannelCollection() {
@@ -159,7 +156,6 @@
     /**
      * Get the default {@link EcalGain} collection.
      *
-     * @param manager the conditions manager
      * @return the ECAL channel gain collection
      */
     protected EcalGainCollection getEcalGainCollection() {
@@ -169,7 +165,6 @@
     /**
      * Get the default {@link EcalTimeShift} collection.
      *
-     * @param manager the conditions manager
      * @return the collection of ECAL time shift objects
      */
     protected EcalTimeShiftCollection getEcalTimeShiftCollection() {
@@ -177,9 +172,8 @@
     }
     
     /**
-     * Get the default {@link EcalPulseWith} collection.
-     *
-     * @param manager the conditions manager
+     * Get the default {@link EcalPulseWidth} collection.
+     *
      * @return the collection of ECAL pulse widths
      */
     protected EcalPulseWidthCollection getEcalPulseWidthCollection() {

Modified: java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/ecal/TestRunEcalConditionsConverter.java
 =============================================================================
--- java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/ecal/TestRunEcalConditionsConverter.java	(original)
+++ java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/ecal/TestRunEcalConditionsConverter.java	Wed Apr 27 11:11:32 2016
@@ -20,7 +20,6 @@
     /**
      * Get the collections of {@link EcalBadChannel} objects for Test Run.
      *
-     * @param manager the conditions manager
      * @return the Test Run bad channel collections
      */
     @Override
@@ -31,7 +30,6 @@
     /**
      * Get the {@link EcalCalibration} collection for Test Run.
      *
-     * @param manager the conditions manager
      * @return the Test Run ECAL calibration collection
      */
     @Override
@@ -43,7 +41,6 @@
     /**
      * Get the {@link EcalChannel} collection for Test Run.
      *
-     * @param manager the conditions manager
      * @return the Test Run ECAL channel collection
      */
     @Override
@@ -54,7 +51,6 @@
     /**
      * Get the {@link EcalGain} collection for Test Run.
      *
-     * @param manager the conditions manager
      * @return the Test Run ECAL gain collection
      */
     @Override
@@ -65,7 +61,6 @@
     /**
      * Get the {@link EcalTimeShift} collection for Test Run.
      *
-     * @param manager the conditions manager
      * @return the Test Run ECAL time shift collection
      */
     @Override

Modified: java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/package-info.java
 =============================================================================
--- java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/package-info.java	(original)
+++ java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/package-info.java	Wed Apr 27 11:11:32 2016
@@ -2,8 +2,7 @@
  * Database conditions system
  * <p>
  * The HPS conditions module provides facilities for accessing time dependent conditions for a detector at runtime using
- * a framework built on the LCSim conditions system. The {@link DatabaseConditionsReader} has a set of converters for
- * reading data from tables using SQL queries and creating appropriate, typed objects for them.
+ * a framework built on the LCSim conditions system. 
  *
  * @author Jeremy McCormick, SLAC
  * @see org.hps.conditions.api

Modified: java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/run/RunSpreadsheet.java
 =============================================================================
--- java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/run/RunSpreadsheet.java	(original)
+++ java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/run/RunSpreadsheet.java	Wed Apr 27 11:11:32 2016
@@ -25,7 +25,7 @@
  * The rows are accessible as raw CSV data through the Apache Commons CSV library, and this data must be manually cleaned up and converted 
  * to the correct data type before being inserted into the conditions database.
  *
- * @author Jeremy McCormick
+ * @author Jeremy McCormick, SLAC
  */
 public final class RunSpreadsheet {
 
@@ -38,23 +38,23 @@
         "start_time", 
         "end_time", 
         "to_tape", 
-        "n_events", 
+        "events",
         "files",
         "trigger_rate", 
         "target", 
         "beam_current",
         "beam_x", 
-        "beam_y", 
-        "trigger_config",
-        /*
-        "ecal_fadc_mode", 
+        "beam_y",
+        "trigger_config", 
+        /* Next 7 are actually hidden in the spreadsheet! */
+        "ecal_fadc_mode",
         "ecal_fadc_thresh", 
         "ecal_fadc_window", 
         "ecal_cluster_thresh_seed", 
         "ecal_cluster_thresh_cluster",
         "ecal_cluster_window_hits", 
-        "ecal_cluster_window_pairs",
-        */ 
+        "ecal_cluster_window_pairs", 
+        /* End hidden fields. */
         "ecal_scalers_fadc", 
         "ecal_scalers_dsc", 
         "svt_y_position", 
@@ -62,8 +62,7 @@
         "svt_offset_time",
         "ecal_temp", 
         "ecal_lv_current", 
-        "notes"
-    };
+        "notes"};
 
     /**
      * Read the CSV file from the command line and print the data to the terminal (just a basic test).
@@ -100,11 +99,14 @@
      * @param file the CSV file
      */
     public RunSpreadsheet(final File file) {
+        if (file == null) {
+            throw new IllegalArgumentException("The file argument is null.");
+        }
         this.file = file;
         try {
             this.fromCsv(this.file);
         } catch (final Exception e) {
-            throw new RuntimeException();
+            throw new RuntimeException("Failed to parse run spreadsheet.", e);
         }
     }
 
@@ -161,14 +163,15 @@
         return records;
     }
     
-    public static final AnotherSimpleDateFormat DATE_FORMAT = new AnotherSimpleDateFormat("MM/dd/yyyy H:mm"); 
+    public static final RunSpreadsheetDateFormat DATE_FORMAT = new RunSpreadsheetDateFormat("MM/dd/yyyy H:mm"); 
     private static final TimeZone TIME_ZONE =  TimeZone.getTimeZone("EST");
     
     
     @SuppressWarnings("serial")
     public
-    static class AnotherSimpleDateFormat extends SimpleDateFormat {
-        public AnotherSimpleDateFormat(String formatstring) {
+    static class RunSpreadsheetDateFormat extends SimpleDateFormat {
+        
+        public RunSpreadsheetDateFormat(String formatstring) {
             super(formatstring);
             //Calendar c = Calendar.getInstance(TIME_ZONE,Locale.US);
             //setTimeZone(TIME_ZONE);
@@ -264,7 +267,7 @@
                 try {
                     addRunData(new RunData(record));
                 } catch (NumberFormatException e) {
-                    e.printStackTrace();
+                    //e.printStackTrace();
                 }
             }
         }

Modified: java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/svt/AbstractSvtDaqMapping.java
 =============================================================================
--- java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/svt/AbstractSvtDaqMapping.java	(original)
+++ java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/svt/AbstractSvtDaqMapping.java	Wed Apr 27 11:11:32 2016
@@ -20,7 +20,7 @@
     @SuppressWarnings("serial")
     public static abstract class AbstractSvtDaqMappingCollection<T extends AbstractSvtDaqMapping> extends
             BaseConditionsObjectCollection<T> {
-      
+
         /**
          * Get the orientation of a sensor.
          *
@@ -65,8 +65,8 @@
     /**
      * Get the orientation of an SVT sensor (AXIAL or STEREO).
      *
-     * @see AXIAL
-     * @see STEREO
+     * @see #AXIAL
+     * @see #STEREO
      * @return the orientation of the SVT sensor
      */
     @Field(names = {"orientation"})
@@ -87,7 +87,7 @@
     /**
      * Set the SVT sensor layer number (1-10 for test run and 1-12 for engineering run).
      *
-     * @param layer : SVT sensor layer number
+     * @param layer SVT sensor layer number
      */
     public final void setLayerNumber(final int layer) {
         this.setFieldValue("layer", layer);
@@ -109,8 +109,8 @@
      * Set the SVT half that the sensor belongs to.
      *
      * @param svtHalf the SVT half (TOP or BOTTOM)
-     * @see TOP_HALF
-     * @see BOTTOM_HALF
+     * @see #TOP_HALF
+     * @see #BOTTOM_HALF
      */
     public final void setSvtHalf(final String svtHalf) {
         if (!svtHalf.equals(AbstractSvtDaqMapping.TOP_HALF) && !svtHalf.equals(AbstractSvtDaqMapping.BOTTOM_HALF)) {

Modified: java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/svt/DaqMapHandler.java
 =============================================================================
--- java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/svt/DaqMapHandler.java	(original)
+++ java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/svt/DaqMapHandler.java	Wed Apr 27 11:11:32 2016
@@ -96,7 +96,7 @@
      * Method that is triggered when the end of a tag is encountered.
      *
      * @param uri the Namespace URI.
-     * @param locaName the local name (without prefix)
+     * @param localName the local name (without prefix)
      * @param qName the qualified name (with prefix)
      * @throws SAXException if there is an error processing the element
      */

Modified: java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/svt/MotorPositionLoader.java
 =============================================================================
--- java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/svt/MotorPositionLoader.java	(original)
+++ java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/svt/MotorPositionLoader.java	Wed Apr 27 11:11:32 2016
@@ -16,7 +16,7 @@
 import org.apache.commons.cli.CommandLine;
 import org.apache.commons.cli.HelpFormatter;
 import org.apache.commons.cli.Options;
-import org.apache.commons.cli.DefaultParser;
+import org.apache.commons.cli.PosixParser;
 
 /**
  * Load SVT motor positions from a MYA dump, figure out time ranges (same position for > 10 seconds), and then convert
@@ -195,7 +195,7 @@
      */
     void run(final String args[]) {
 
-        final DefaultParser parser = new DefaultParser();
+        final PosixParser parser = new PosixParser();
 
         CommandLine cl = null;
         try {

Modified: java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/svt/OpeningAngleLoader.java
 =============================================================================
--- java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/svt/OpeningAngleLoader.java	(original)
+++ java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/svt/OpeningAngleLoader.java	Wed Apr 27 11:11:32 2016
@@ -30,7 +30,7 @@
      * Check if the run record looks good.
      *
      * @param data
-     * @return
+     * @return whether to accept the run or not
      */
     private static boolean acceptRun(final RunData data) {
         return !data.getRecord().get("to_tape").equals("JUNK")

Modified: java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/svt/SvtBiasConditionsLoader.java
 =============================================================================
--- java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/svt/SvtBiasConditionsLoader.java	(original)
+++ java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/svt/SvtBiasConditionsLoader.java	Wed Apr 27 11:11:32 2016
@@ -23,7 +23,7 @@
 import org.apache.commons.cli.Option;
 import org.apache.commons.cli.Options;
 import org.apache.commons.cli.ParseException;
-import org.apache.commons.cli.DefaultParser;
+import org.apache.commons.cli.PosixParser;
 import org.hps.conditions.api.ConditionsRecord;
 import org.hps.conditions.database.DatabaseConditionsManager;
 import org.hps.conditions.run.RunRange;
@@ -176,7 +176,7 @@
 //        options.addOption(new Option("b", true, "beam current file"));
         options.addOption(new Option("s", false, "Show plots"));
 
-        final CommandLineParser parser = new DefaultParser();
+        final CommandLineParser parser = new PosixParser();
         CommandLine cl = null;
         try {
             cl = parser.parse(options, args);

Modified: java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/svt/SvtConditionsLoader.java
 =============================================================================
--- java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/svt/SvtConditionsLoader.java	(original)
+++ java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/svt/SvtConditionsLoader.java	Wed Apr 27 11:11:32 2016
@@ -8,7 +8,7 @@
 import org.apache.commons.cli.Option;
 import org.apache.commons.cli.Options;
 import org.apache.commons.cli.ParseException;
-import org.apache.commons.cli.DefaultParser;
+import org.apache.commons.cli.PosixParser;
 import org.hps.conditions.api.ConditionsRecord;
 import org.hps.conditions.api.TableMetaData;
 import org.hps.conditions.database.DatabaseConditionsManager;
@@ -60,7 +60,7 @@
         final Options options = setupCommandLineOptions();
 
         // Parse the command line arguments
-        final CommandLineParser parser = new DefaultParser();
+        final CommandLineParser parser = new PosixParser();
         final CommandLine commandLine;
         try {
             commandLine = parser.parse(options, args);

Modified: java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/svt/SvtDaqMapping.java
 =============================================================================
--- java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/svt/SvtDaqMapping.java	(original)
+++ java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/svt/SvtDaqMapping.java	Wed Apr 27 11:11:32 2016
@@ -129,8 +129,8 @@
     /**
      * Get the side of the sensor (ELECTRON or POSITRON).
      *
-     * @see ELECTRON
-     * @see POSITRON
+     * @see #ELECTRON
+     * @see #POSITRON
      * @return sensor side (ELECTRON or POSITRON)
      */
     @Field(names = {"side"})
@@ -160,8 +160,8 @@
      * Set the side of the sensor (ELECTRON or POSITRON).
      *
      * @param side the sensor side (ELECTRON or POSITRON)
-     * @see {@link #ELECTRON}
-     * @see {@link #POSITRON}
+     * @see #ELECTRON
+     * @see #POSITRON
      */
     public final void setSide(final String side) {
         if (!side.equals(SvtDaqMapping.ELECTRON) && !side.equals(SvtDaqMapping.POSITRON)) {

Modified: java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/svt/SvtT0Shift.java
 =============================================================================
--- java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/svt/SvtT0Shift.java	(original)
+++ java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/svt/SvtT0Shift.java	Wed Apr 27 11:11:32 2016
@@ -23,7 +23,7 @@
         /**
          * Get the {@link SvtT0Shift} associated with a given DAQ pair.
          *
-         * @param DAQ pair for a given sensor
+         * @param pair DAQ pair for a given sensor
          * @return the {@link SvtT0Shift} associated with the DAQ pair or null if does not exist
          */
         @Override

Modified: java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/svt/TestRunSvtChannel.java
 =============================================================================
--- java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/svt/TestRunSvtChannel.java	(original)
+++ java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/svt/TestRunSvtChannel.java	Wed Apr 27 11:11:32 2016
@@ -26,7 +26,7 @@
         /**
          * Find a collection of channels by their DAQ pair assignment.
          *
-         * @param the DAQ pair (FEB ID and FEB Hybrid ID)
+         * @param pair the DAQ pair (FEB ID and FEB Hybrid ID)
          * @return the collection of channels
          */
         @Override

Modified: java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/svt/TestRunSvtConditions.java
 =============================================================================
--- java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/svt/TestRunSvtConditions.java	(original)
+++ java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/svt/TestRunSvtConditions.java	Wed Apr 27 11:11:32 2016
@@ -10,7 +10,7 @@
 
 /**
  * This class contains all test run SVT conditions data by readout channel. {@link TestRunSvtChannel} objects from the
- * SVT channel map should be used to lookup the conditions using the {@link #getChannelConstants(TestRunSvtChannel)}
+ * SVT channel map should be used to lookup the conditions using the {@link #getChannelConstants(AbstractSvtChannel)}
  * method.
  *
  * @author Jeremy McCormick, SLAC

Modified: java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/svt/TestRunSvtT0Shift.java
 =============================================================================
--- java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/svt/TestRunSvtT0Shift.java	(original)
+++ java/branches/HPSJAVA-409/conditions/src/main/java/org/hps/conditions/svt/TestRunSvtT0Shift.java	Wed Apr 27 11:11:32 2016
@@ -22,7 +22,7 @@
         /**
          * Get the {@link TestRunSvtT0Shift} associated with a given DAQ pair
          *
-         * @param DAQ pair for a given sensor
+         * @param pair DAQ pair for a given sensor
          * @return the {@link TestRunSvtT0Shift} associated with the DAQ pair or null if does not exist
          */
         @Override

Modified: java/branches/HPSJAVA-409/crawler/pom.xml
 =============================================================================
--- java/branches/HPSJAVA-409/crawler/pom.xml	(original)
+++ java/branches/HPSJAVA-409/crawler/pom.xml	Wed Apr 27 11:11:32 2016
@@ -7,7 +7,7 @@
         <groupId>org.hps</groupId>
         <artifactId>hps-parent</artifactId>
         <relativePath>../parent/pom.xml</relativePath>
-        <version>3.4.2-SNAPSHOT</version>
+        <version>3.9-SNAPSHOT</version>
     </parent>
     <scm>
         <url>http://java.freehep.org/svn/repos/hps/list/java/trunk/crawler/</url>
@@ -17,7 +17,11 @@
     <dependencies>
         <dependency>
             <groupId>org.hps</groupId>
-            <artifactId>hps-run-database</artifactId>
+            <artifactId>hps-record-util</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>srs</groupId>
+            <artifactId>org-srs-datacat-client</artifactId>
         </dependency>
     </dependencies>
 </project>

Modified: java/branches/HPSJAVA-409/crawler/src/main/java/org/hps/crawler/AidaMetadataReader.java
 =============================================================================
--- java/branches/HPSJAVA-409/crawler/src/main/java/org/hps/crawler/AidaMetadataReader.java	(original)
+++ java/branches/HPSJAVA-409/crawler/src/main/java/org/hps/crawler/AidaMetadataReader.java	Wed Apr 27 11:11:32 2016
@@ -12,7 +12,7 @@
  *
  * @author Jeremy McCormick, SLAC
  */
-public class AidaMetadataReader implements FileMetadataReader {
+final class AidaMetadataReader implements FileMetadataReader {
 
     /**
      * Get the metadata for a ROOT DQM file.
@@ -22,7 +22,7 @@
     @Override
     public Map<String, Object> getMetadata(final File file) throws IOException {
         final Map<String, Object> metadata = new HashMap<String, Object>();
-        final int run = CrawlerFileUtilities.getRunFromFileName(file);
+        final Long run = FileUtilities.getRunFromFileName(file);
         metadata.put("runMin", run);
         metadata.put("runMax", run);
         return metadata;

Modified: java/branches/HPSJAVA-409/crawler/src/main/java/org/hps/crawler/CrawlerConfig.java
 =============================================================================
--- java/branches/HPSJAVA-409/crawler/src/main/java/org/hps/crawler/CrawlerConfig.java	(original)
+++ java/branches/HPSJAVA-409/crawler/src/main/java/org/hps/crawler/CrawlerConfig.java	Wed Apr 27 11:11:32 2016
@@ -11,13 +11,9 @@
 import java.util.Set;
 
 import org.hps.conditions.database.ConnectionParameters;
-import org.hps.datacat.client.DatasetFileFormat;
-import org.hps.datacat.client.DatasetSite;
 
 /**
  * Full configuration information for the {@link Crawler} class.
- * <p>
- * Method chaining of setters is supported.
  *
  * @author Jeremy McCormick, SLAC
  */
@@ -41,20 +37,13 @@
 
     /**
      * The name of the folder in the data catalog for inserting data (under "/HPS" root folder).
-     * <p>
-     * Default provided for Eng Run 2015 data.
      */
     private String datacatFolder = null;
 
     /**
-     * Set whether extraction of metadata from files is enabled.
-     */
-    private boolean enableMetadata;
-
-    /**
-     * Set of file formats for filtering files.
-     */
-    Set<DatasetFileFormat> formats = new HashSet<DatasetFileFormat>();
+     * Set of accepted file formats.
+     */
+    private Set<FileFormat> formats = new HashSet<FileFormat>();
 
     /**
      * The maximum depth to crawl.
@@ -69,7 +58,7 @@
     /**
      * The dataset site for the datacat.
      */
-    private DatasetSite site;
+    private Site site = Site.JLAB;
 
     /**
      * A timestamp to use for filtering input files on their creation date.
@@ -80,6 +69,21 @@
      * A file to use for getting the timestamp date.
      */
     private File timestampFile = null;
+    
+    /**
+     * Dry run for not actually executing updates.
+     */
+    private boolean dryRun = false;
+    
+    /**
+     * Base URL of datacat client.
+     */
+    private String baseUrl = DatacatHelper.DATACAT_URL;
+        
+    /**
+     * Set of paths used for filtering files (file's path must match one of these).
+     */
+    private Set<String> paths = new HashSet<String>();
 
     /**
      * Get the set of runs that will be accepted for the job.
@@ -94,7 +98,7 @@
      * Add the default file formats.
      */
     CrawlerConfig addDefaultFileFormats() {
-        final List<DatasetFileFormat> defaultFormats = Arrays.asList(DatasetFileFormat.values());
+        final List<FileFormat> defaultFormats = Arrays.asList(FileFormat.values());
         this.formats.addAll(defaultFormats);
         return this;
     }
@@ -104,9 +108,8 @@
      *
      * @param format the file format
      */
-    CrawlerConfig addFileFormat(final DatasetFileFormat format) {
+    void addFileFormat(final FileFormat format) {
         this.formats.add(format);
-        return this;
     }
 
     /**
@@ -123,7 +126,7 @@
      *
      * @return the data catalog folder
      */
-    String datacatFolder() {
+    String folder() {
         return this.datacatFolder;
     }
 
@@ -132,25 +135,16 @@
      *
      * @return the dataset site
      */
-    DatasetSite datasetSite() {
+    Site site() {
         return this.site;
     }
 
     /**
-     * Return <code>true</code> if metadata extraction from files is enabled.
-     *
-     * @return <code>true</code> if metadata extraction is enabled
-     */
-    boolean enableMetaData() {
-        return this.enableMetadata;
-    }
-
-    /**
      * Get the file formats for filtering.
      *
      * @return the file formats for filtering
      */
-    Set<DatasetFileFormat> getFileFormats() {
+    Set<FileFormat> getFileFormats() {
         return this.formats;
     }
 
@@ -164,7 +158,7 @@
     }
 
     /**
-     * Get the root directory for the file search.
+     * Get the root directory in the file catalog.
      *
      * @return the root directory for the file search
      */
@@ -178,9 +172,8 @@
      * @param acceptRuns the list of acceptable run numbers
      * @return this object
      */
-    CrawlerConfig setAcceptRuns(final Set<Integer> acceptRuns) {
+    void setAcceptRuns(final Set<Integer> acceptRuns) {
         this.acceptRuns = acceptRuns;
-        return this;
     }
 
     /**
@@ -189,9 +182,8 @@
      * @param connectionParameters the database connection parameters
      * @return this object
      */
-    CrawlerConfig setConnection(final ConnectionParameters connectionParameters) {
+    void setConnection(final ConnectionParameters connectionParameters) {
         this.connectionParameters = connectionParameters;
-        return this;
     }
 
     /**
@@ -199,9 +191,8 @@
      *
      * @param datacatFolder the data catalog folder
      */
-    CrawlerConfig setDatacatFolder(final String datacatFolder) {
+    void setDatacatFolder(final String datacatFolder) {
         this.datacatFolder = datacatFolder;
-        return this;
     }
 
     /**
@@ -209,29 +200,28 @@
      *
      * @return this object
      */
-    void setDatasetSite(final DatasetSite site) {
+    void setSite(final Site site) {
         this.site = site;
     }
-
-    /**
-     * Set whether metadata extraction is enabled.
-     *
-     * @param enableMetadata <code>true</code> to enable metadata
-     * @return this object
-     */
-    CrawlerConfig setEnableMetadata(final boolean enableMetadata) {
-        this.enableMetadata = enableMetadata;
-        return this;
-    }
+    
+    /**
+     * Enable dry run.
+     * 
+     * @param dryRun set to <code>true</code> to enable dry run
+     * @return this object
+     */
+    void setDryRun(boolean dryRun) {
+        this.dryRun = dryRun;
+    }
+    
 
     /**
      * Set the max depth.
      *
      * @param maxDepth the max depth
      */
-    CrawlerConfig setMaxDepth(final Integer maxDepth) {
+    void setMaxDepth(final Integer maxDepth) {
         this.maxDepth = maxDepth;
-        return this;
     }
 
     /**
@@ -240,9 +230,8 @@
      * @param rootDir the root directory for the file search
      * @return this object
      */
-    CrawlerConfig setRootDir(final File rootDir) {
+    void setRootDir(final File rootDir) {
         this.rootDir = rootDir;
-        return this;
     }
 
     /**
@@ -253,9 +242,8 @@
      * @param timestamp the date for filtering files
      * @return this object
      */
-    CrawlerConfig setTimestamp(final Date timestamp) {
+    void setTimestamp(final Date timestamp) {
         this.timestamp = timestamp;
-        return this;
     }
 
     /**
@@ -267,9 +255,8 @@
      * @param timestamp the date string for filtering files
      * @return this object
      */
-    CrawlerConfig setTimestamp(final String timestampString) throws ParseException {
+    void setTimestamp(final String timestampString) throws ParseException {
         TIMESTAMP_FORMAT.parse(timestampString);
-        return this;
     }
 
     /**
@@ -278,9 +265,8 @@
      * @param timestampFile the timestamp file for date filtering
      * @return this object
      */
-    CrawlerConfig setTimestampFile(final File timestampFile) {
+    void setTimestampFile(final File timestampFile) {
         this.timestampFile = timestampFile;
-        return this;
     }
 
     /**
@@ -302,4 +288,49 @@
     File timestampFile() {
         return timestampFile;
     }
+    
+    /**
+     * Returns <code>true</code> if dry run which means no updates will occur.
+     * 
+     * @return <code>true</code> if dry run
+     */
+    boolean dryRun() {
+        return this.dryRun;
+    }
+    
+    /**
+     * Set the data catalog URL.
+     * 
+     * @param baseUrl the data catalog URL
+     */
+    void setDatacatUrl(String baseUrl) {
+        this.baseUrl = baseUrl;        
+    }
+    
+    /**
+     * Get the data catalog URL.
+     * 
+     * @return the data catalog URL
+     */
+    String datacatUrl() {
+        return this.baseUrl;
+    }
+        
+    /**
+     * Add a path for filtering files.
+     * 
+     * @param path the path for filtering
+     */
+    void addPath(String path) {
+        this.paths.add(path);
+    }
+    
+    /**
+     * Get the list of paths for filtering. 
+     * 
+     * @return the list of paths for filtering
+     */
+    Set<String> paths() {
+        return this.paths;
+    }
 }

Modified: java/branches/HPSJAVA-409/crawler/src/main/java/org/hps/crawler/DatacatCrawler.java
 =============================================================================
--- java/branches/HPSJAVA-409/crawler/src/main/java/org/hps/crawler/DatacatCrawler.java	(original)
+++ java/branches/HPSJAVA-409/crawler/src/main/java/org/hps/crawler/DatacatCrawler.java	Wed Apr 27 11:11:32 2016
@@ -1,112 +1,30 @@
 package org.hps.crawler;
 
 import java.io.File;
-import java.io.FileFilter;
 import java.io.IOException;
 import java.nio.file.FileVisitOption;
-import java.nio.file.FileVisitResult;
 import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.SimpleFileVisitor;
 import java.nio.file.attribute.BasicFileAttributes;
-import java.util.ArrayList;
 import java.util.Date;
 import java.util.EnumSet;
-import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
-import java.util.Map;
 import java.util.Set;
-import java.util.logging.Level;
 import java.util.logging.Logger;
 
 import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.PosixParser;
 import org.apache.commons.cli.HelpFormatter;
 import org.apache.commons.cli.Options;
 import org.apache.commons.cli.ParseException;
-import org.apache.commons.cli.DefaultParser;
-import org.hps.datacat.client.DatacatClient;
-import org.hps.datacat.client.DatacatClientFactory;
-import org.hps.datacat.client.DatasetFileFormat;
+import org.srs.datacat.model.DatasetModel;
 
 /**
  * Command line file crawler for populating the data catalog.
  *
  * @author Jeremy McCormick, SLAC
  */
-public class DatacatCrawler {
-
-    /**
-     * Visitor which creates a {@link FileSet} from walking a directory tree.
-     * <p>
-     * Any number of {@link java.io.FileFilter} objects can be registered with this visitor to restrict which files are
-     * accepted.
-     *
-     * @author Jeremy McCormick, SLAC
-     */
-    final class DatacatFileVisitor extends SimpleFileVisitor<Path> {
-
-        /**
-         * The run log containing information about files from each run.
-         */
-        private final FileSet fileSet = new FileSet();
-
-        /**
-         * A list of file filters to apply.
-         */
-        private final List<FileFilter> filters = new ArrayList<FileFilter>();
-
-        /**
-         * Run the filters on the file to tell whether it should be accepted or not.
-         *
-         * @param file the EVIO file
-         * @return <code>true</code> if file should be accepted
-         */
-        private boolean accept(final File file) {
-            boolean accept = true;
-            for (final FileFilter filter : this.filters) {
-                accept = filter.accept(file);
-                if (!accept) {
-                    break;
-                }
-            }
-            return accept;
-        }
-
-        /**
-         * Add a file filter.
-         *
-         * @param filter the file filter
-         */
-        void addFilter(final FileFilter filter) {
-            this.filters.add(filter);
-        }
-
-        /**
-         * Get the file set created by visiting the directory tree.
-         *
-         * @return the file set from visiting the directory tree
-         */
-        FileSet getFileSet() {
-            return this.fileSet;
-        }
-
-        /**
-         * Visit a single file.
-         *
-         * @param path the file to visit
-         * @param attrs the file attributes
-         */
-        @Override
-        public FileVisitResult visitFile(final Path path, final BasicFileAttributes attrs) {
-            final File file = path.toFile();
-            if (this.accept(file)) {
-                final DatasetFileFormat format = DatacatUtilities.getFileFormat(file);
-                fileSet.addFile(format, file);
-            }
-            return FileVisitResult.CONTINUE;
-        }
-    }
+public final class DatacatCrawler {
 
     /**
      * Make a list of available file formats for printing help.
@@ -117,14 +35,14 @@
      * Setup the logger.
      */
     private static final Logger LOGGER = Logger.getLogger(DatacatCrawler.class.getPackage().getName());
-
+    
     /**
      * Command line options for the crawler.
      */
     private static final Options OPTIONS = new Options();
     static {
         final StringBuffer buffer = new StringBuffer();
-        for (final DatasetFileFormat format : DatasetFileFormat.values()) {
+        for (final FileFormat format : FileFormat.values()) {
             buffer.append(format.name() + " ");
         }
         buffer.setLength(buffer.length() - 1);
@@ -135,17 +53,17 @@
      * Statically define the command options.
      */
     static {
-        OPTIONS.addOption("L", "log-level", true, "set the log level (INFO, FINE, etc.)");
         OPTIONS.addOption("b", "min-date", true, "min date for a file (example \"2015-03-26 11:28:59\")");
         OPTIONS.addOption("d", "directory", true, "root directory to crawl");
         OPTIONS.addOption("f", "folder", true, "datacat folder");
         OPTIONS.addOption("h", "help", false, "print help and exit (overrides all other arguments)");
         OPTIONS.addOption("o", "format", true, "add a file format for filtering: " + AVAILABLE_FORMATS);
-        OPTIONS.addOption("m", "metadata", false, "create metadata for datasets");
         OPTIONS.addOption("r", "run", true, "add a run number to accept");
         OPTIONS.addOption("s", "site", true, "datacat site");
         OPTIONS.addOption("t", "timestamp-file", true, "existing or new timestamp file name");
         OPTIONS.addOption("x", "max-depth", true, "max depth to crawl");
+        OPTIONS.addOption("D", "dry-run", false, "dry run which will not update the datacat");
+        OPTIONS.addOption("u", "base-url", true, "provide a base URL of the datacat server");
     }
 
     /**
@@ -165,33 +83,16 @@
     /**
      * The options parser.
      */
-    private final DefaultParser parser = new DefaultParser();
-
-    /**
-     * Throw an exception if the path doesn't exist in the data catalog or it is not a folder.
-     *
-     * @param folder the folder in the datacat
-     * @throws RuntimeException if the given path does not exist or it is not a folder
-     */
-    void checkFolder(final String folder) {
-        final DatacatClient datacatClient = new DatacatClientFactory().createClient();
-        if (!datacatClient.exists(folder)) {
-            throw new RuntimeException("The folder " + folder + " does not exist in the data catalog.");
-        }
-        if (!datacatClient.isFolder(folder)) {
-            throw new RuntimeException("The path " + folder + " is not a folder.");
-        }
-    }
-
+    private final PosixParser parser = new PosixParser();
+    
     /**
      * Parse command line options.
      *
      * @param args the command line arguments
      * @return this object (for method chaining)
      */
-    public DatacatCrawler parse(final String[] args) {
-        config = new CrawlerConfig();
-
+    private DatacatCrawler parse(final String[] args) {
+        
         LOGGER.config("parsing command line options");
 
         this.config = new CrawlerConfig();
@@ -202,13 +103,6 @@
             // Print help.
             if (cl.hasOption("h") || args.length == 0) {
                 this.printUsage();
-            }
-
-            // Log level.
-            if (cl.hasOption("L")) {
-                final Level level = Level.parse(cl.getOptionValue("L"));
-                LOGGER.config("setting log level to " + level);
-                LOGGER.setLevel(level);
             }
 
             // Root directory for file crawling.
@@ -221,7 +115,7 @@
                     throw new IllegalArgumentException("The specified path is not a directory.");
                 }
                 config.setRootDir(rootDir);
-                LOGGER.config("root dir set to " + config.rootDir());
+                LOGGER.config("root dir " + config.rootDir());
             }
 
             // Timestamp file for date filtering.
@@ -278,9 +172,9 @@
             // Configure enabled file formats.
             if (cl.hasOption("o")) {
                 for (final String arg : cl.getOptionValues("o")) {
-                    DatasetFileFormat format = null;
+                    FileFormat format = null;
                     try {
-                        format = DatasetFileFormat.valueOf(arg);
+                        format = FileFormat.valueOf(arg);
                     } catch (IllegalArgumentException | NullPointerException e) {
                         throw new IllegalArgumentException("The format " + arg + " is not valid.", e);
                     }
@@ -288,19 +182,22 @@
                     this.config.addFileFormat(format);
                 }
             } else {
-                throw new RuntimeException("The -o argument with data format must be supplied at least once.");
-            }
-
-            // Enable metadata extraction from files.
-            if (cl.hasOption("m")) {
-                config.setEnableMetadata(true);
-                LOGGER.config("metadata extraction enabled");
+                for (FileFormat format : FileFormat.values()) {
+                    this.config.addFileFormat(format);
+                    LOGGER.config("adding default format " + format);
+                }
+            }
+            
+            // Enable the default set of file formats.
+            if (this.config.getFileFormats().isEmpty()) {
+                LOGGER.config("enabling default file formats");
+                this.config.addDefaultFileFormats();
             }
 
             // Datacat folder.
             if (cl.hasOption("f")) {
                 config.setDatacatFolder(cl.getOptionValue("f"));
-                LOGGER.config("set datacat folder to " + config.datacatFolder());
+                LOGGER.config("set datacat folder to " + config.folder());
             } else {
                 throw new RuntimeException("The -f argument with the datacat folder is required.");
             }
@@ -313,20 +210,43 @@
                 }
                 config.setAcceptRuns(acceptRuns);
             }
+                                    
+            // Dry run.
+            if (cl.hasOption("D")) {
+                config.setDryRun(true);
+            }
+                        
+            // List of paths.
+            if (!cl.getArgList().isEmpty()) {
+                for (String arg : cl.getArgList()) {
+                    config.addPath(arg);
+                }
+            }
+            
+            // Dataset site (defaults to JLAB).
+            Site site = Site.JLAB;
+            if (cl.hasOption("s")) {
+                site = Site.valueOf(cl.getOptionValue("s"));
+            }
+            LOGGER.config("dataset site " + site);
+            config.setSite(site);
+            
+            // Data catalog URL.
+            if (cl.hasOption("u")) {
+                config.setDatacatUrl(cl.getOptionValue("u"));
+                LOGGER.config("datacat URL " + config.datacatUrl());
+            }
 
         } catch (final ParseException e) {
             throw new RuntimeException("Error parsing options.", e);
         }
 
-        // Check the datacat folder which must already exist.
-        this.checkFolder(config.datacatFolder());
-
         // Check that there is at least one file format enabled for filtering.
         if (this.config.getFileFormats().isEmpty()) {
-            throw new IllegalStateException("At least one file format must be provided with the -f switch.");
-        }
-
-        LOGGER.info("done parsing command line options");
+            throw new IllegalStateException("At least one file format must be provided with the -o switch.");
+        }
+
+        LOGGER.info("Done parsing command line options.");
 
         return this;
     }
@@ -336,72 +256,65 @@
      */
     private void printUsage() {
         final HelpFormatter help = new HelpFormatter();
-        help.printHelp(70, "DatacatCrawler [options]", "", OPTIONS, "");
+        help.printHelp(70, "DatacatCrawler [options] path ...", "", OPTIONS, "");
         System.exit(0);
     }
 
     /**
      * Run the crawler job.
      */
-    void run() {
-
+    private void run() {
+                
         // Create the file visitor for crawling the root directory with the given date filter.
-        final DatacatFileVisitor visitor = new DatacatFileVisitor();
+        final CrawlerFileVisitor visitor = new CrawlerFileVisitor();
 
         // Add date filter if timestamp is supplied.
         if (config.timestamp() != null) {
             visitor.addFilter(new DateFileFilter(config.timestamp()));
+            LOGGER.config("added timestamp filter " + config.timestamp());
+        }
+        
+        // Add path filter.
+        if (!config.paths().isEmpty()) {
+            visitor.addFilter(new PathFilter(config.paths()));
+            StringBuffer sb = new StringBuffer();
+            for (String path : config.paths()) {
+                sb.append(path + ":");
+            }
+            sb.setLength(sb.length() - 1);
+            LOGGER.config("added paths " + sb.toString());
         }
 
         // Add file format filter.
-        for (final DatasetFileFormat fileFormat : config.getFileFormats()) {
-            LOGGER.info("adding file format filter for " + fileFormat.name());
-        }
         visitor.addFilter(new FileFormatFilter(config.getFileFormats()));
 
-        // Run number filter.
+        // Add run number filter.
         if (!config.acceptRuns().isEmpty()) {
             visitor.addFilter(new RunFilter(config.acceptRuns()));
         }
 
-        // Walk the file tree using the visitor.
+        // Walk the file tree and get list of files.
         this.walk(visitor);
-
-        // Update the data catalog.
-        this.updateDatacat(visitor.getFileSet());
-    }
-
-    /**
-     * Update the data catalog.
-     *
-     * @param runMap the map of run information including the EVIO file list
-     */
-    private void updateDatacat(final FileSet fileSet) {
-        final DatacatClient datacatClient = new DatacatClientFactory().createClient();
-        for (final DatasetFileFormat fileFormat : config.getFileFormats()) {
-            LOGGER.info("adding files to datacat with format " + fileFormat.name());
-            for (final File file : fileSet.get(fileFormat)) {
-
-                LOGGER.info("adding file " + file.getAbsolutePath() + " to datacat");
-
-                // Create metadata if this is enabled (takes awhile).
-                Map<String, Object> metadata = new HashMap<String, Object>();
-                if (config.enableMetaData()) {
-                    metadata = DatacatUtilities.createMetadata(file);
-                }
-
-                // Register file in the catalog.
-                DatacatUtilities.addFile(datacatClient, config.datacatFolder(), file, metadata);
-            }
-        }
-    }
-
-    /**
-     * Walk the directory tree to find EVIO files for the runs that are being processed in the job.
+                
+        // Insert datasets if files were found.
+        if (!visitor.getFiles().isEmpty()) {
+            List<DatasetModel> datasets = DatacatHelper.createDatasets(visitor.getFiles(), config.folder(), config.site().toString());
+            LOGGER.info("built " + datasets.size() + " datasets");
+            DatacatHelper.addDatasets(datasets, config.folder(), config.datacatUrl());
+            LOGGER.info("added datasets to datacat");
+        } else {
+            LOGGER.warning("No files were found by the crawler.");
+        }
+        
+        LOGGER.info("Done!");
+    }
+                         
+    /**
+     * Walk the directory tree to find files for the runs that are being processed in the job.
      *
      * @param visitor the file visitor
      */
-    private void walk(final DatacatFileVisitor visitor) {
+    private void walk(final CrawlerFileVisitor visitor) {
         try {
             // Walk the file tree from the root directory.
             final EnumSet<FileVisitOption> options = EnumSet.noneOf(FileVisitOption.class);

Modified: java/branches/HPSJAVA-409/crawler/src/main/java/org/hps/crawler/EvioMetadataReader.java
 =============================================================================
--- java/branches/HPSJAVA-409/crawler/src/main/java/org/hps/crawler/EvioMetadataReader.java	(original)
+++ java/branches/HPSJAVA-409/crawler/src/main/java/org/hps/crawler/EvioMetadataReader.java	Wed Apr 27 11:11:32 2016
@@ -2,147 +2,330 @@
 
 import java.io.File;
 import java.io.IOException;
-import java.util.Date;
-import java.util.HashMap;
+import java.math.RoundingMode;
+import java.text.DecimalFormat;
+import java.util.LinkedHashMap;
 import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.logging.Level;
 import java.util.logging.Logger;
 
 import org.hps.record.evio.EventTagConstant;
 import org.hps.record.evio.EvioEventUtilities;
 import org.hps.record.evio.EvioFileUtilities;
+import org.hps.record.triggerbank.AbstractIntData.IntBankDefinition;
+import org.hps.record.triggerbank.HeadBankData;
+import org.hps.record.triggerbank.TiTimeOffsetEvioProcessor;
+import org.hps.record.triggerbank.TriggerType;
+import org.jlab.coda.jevio.BaseStructure;
 import org.jlab.coda.jevio.EvioEvent;
 import org.jlab.coda.jevio.EvioException;
 import org.jlab.coda.jevio.EvioReader;
 
 /**
- * Reads metadata from EVIO files.
- *
+ * Creates detailed metadata for the datacat from an EVIO input file.
+ * 
  * @author Jeremy McCormick, SLAC
  */
-public class EvioMetadataReader implements FileMetadataReader {
+final class EvioMetadataReader implements FileMetadataReader {
 
     /**
-     * Initialize the logger.
+     * Initialize the package logger.
      */
     private static Logger LOGGER = Logger.getLogger(EvioMetadataReader.class.getPackage().getName());
 
     /**
+     * Head bank definition.
+     */
+    private static IntBankDefinition HEAD_BANK = new IntBankDefinition(HeadBankData.class, new int[] {0x2e, 0xe10f});
+
+    /**
      * Get the EVIO file metadata.
-     *
+     * 
      * @param file the EVIO file
      * @return the metadata map of key and value pairs
      */
     @Override
     public Map<String, Object> getMetadata(final File file) throws IOException {
-
-        Date startDate = null;
-        Date endDate = null;
-        int badEventCount = 0;
-        int eventCount = 0;
-        int byteCount = 0;
-        boolean hasPrestart = false;
-        boolean hasEnd = false;
-        int[] eventIdData = null;
-        Integer run = null;
-        Integer endEvent = null;
-        Integer startEvent = null;
-        Long lastTimestamp = null;
+        
+        long totalEvents = 0;
+        int physicsEvents = 0;
+        int badEvents = 0;
+        int blinded = 0;
+        Long run = null;
+        Integer firstHeadTimestamp = null;
+        Integer lastHeadTimestamp = null;
+        Integer lastPhysicsEvent = null;
+        Integer firstPhysicsEvent = null;
+        Integer prestartTimestamp = null;
+        Integer endTimestamp = null;
+        Integer goTimestamp = null;
+        Double triggerRate = null;
+        
+        // Processor for calculating TI time offsets.
+        TiTimeOffsetEvioProcessor tiProcessor = new TiTimeOffsetEvioProcessor();
+
+        // Create map for counting trigger types.
+        Map<TriggerType, Integer> triggerCounts = new LinkedHashMap<TriggerType, Integer>();
+        for (TriggerType triggerType : TriggerType.values()) {
+            triggerCounts.put(triggerType, 0);
+        }
+
+        // Get the file number from the name.
+        final int fileNumber = EvioFileUtilities.getSequenceFromName(file);
+
+        // File numbers indivisible by 10 are blinded (Eng Run 2015 scheme).
+        if (!(fileNumber % 10 == 0)) {
+            blinded = 1;
+        }
+        
+        // Get file size.
+        long size = 0;
+        File cacheFile = file;
+        if (FileUtilities.isMssFile(file)) {
+            cacheFile = FileUtilities.getCachedFile(file);
+        }
+        size = cacheFile.length();
+        
+        // Compute MD5 checksum string.
+        String checksum = FileUtilities.createMD5Checksum(cacheFile);
 
         EvioReader evioReader = null;
         try {
-            evioReader = EvioFileUtilities.open(file, false);
+            // Open file in sequential mode.
+            evioReader = EvioFileUtilities.open(file, true);
+            EvioEvent evioEvent = null;
+
+            // Event read loop.
+            eventLoop: while (true) {
+                try {
+                    // Parse next event.
+                    evioEvent = evioReader.parseNextEvent();
+
+                    // End of file.
+                    if (evioEvent == null) {
+                        LOGGER.fine("EOF after " + totalEvents + " events.");
+                        break eventLoop;
+                    }
+                    
+                    // Increment event count (doesn't count events that can't be parsed).
+                    ++totalEvents;
+
+                    // Debug print event number and tag.
+                    LOGGER.finest("Parsed event " + evioEvent.getEventNumber() + " with tag 0x"
+                            + String.format("%08x", evioEvent.getHeader().getTag()));
+
+                    // Get head bank.
+                    BaseStructure headBank = HEAD_BANK.findBank(evioEvent);
+
+                    // Current timestamp.
+                    int thisTimestamp = 0;
+
+                    // Process head bank if not null.
+                    if (headBank != null) {
+                        if (headBank != null) {
+                            final int[] headBankData = headBank.getIntData();
+                            thisTimestamp = headBankData[3];
+                            if (thisTimestamp != 0) {
+                                // First header timestamp.
+                                if (firstHeadTimestamp == null) {
+                                    firstHeadTimestamp = thisTimestamp;
+                                    LOGGER.finer("First head timestamp " + firstHeadTimestamp + " from event "
+                                            + evioEvent.getEventNumber());
+                                }
+
+                                // Last header timestamp.
+                                lastHeadTimestamp = thisTimestamp;
+                            }
+
+                            // Run number.
+                            if (run == null) {
+                                if (headBankData[1] != 0) {
+                                    run = (long) headBankData[1];
+                                    LOGGER.finer("Run number " + run + " from event " + evioEvent.getEventNumber());
+                                }
+                            }
+                        }
+                    }
+                    
+                    if (EvioEventUtilities.isPhysicsEvent(evioEvent)) {
+                                                
+                        final int[] eventIdData = EvioEventUtilities.getEventIdData(evioEvent);
+                        
+                        if (eventIdData != null) {
+                        
+                            // Set the last physics event.
+                            lastPhysicsEvent = eventIdData[0];
+
+                            // Set the first physics event.
+                            if (firstPhysicsEvent == null) {
+                                firstPhysicsEvent = eventIdData[0];
+                                LOGGER.finer("Set first physics event " + firstPhysicsEvent);
+                            }
+                        }
+                        
+                        ++physicsEvents;
+                    } else if (EvioEventUtilities.isControlEvent(evioEvent)) {
+                        int[] controlData = EvioEventUtilities.getControlEventData(evioEvent);
+                        if (controlData[0] != 0) {
+                            if (EventTagConstant.PRESTART.isEventTag(evioEvent)) {
+                                prestartTimestamp = controlData[0];
+                            }                        
+                            if (EventTagConstant.GO.isEventTag(evioEvent)) {
+                                goTimestamp = controlData[0];
+                            }
+                            if (EventTagConstant.END.isEventTag(evioEvent)) {
+                                endTimestamp = controlData[0];
+                            }
+                        }
+                    }
+
+                    // Count trigger types for this event.
+                    Set<TriggerType> triggerTypes = TriggerType.getTriggerTypes(evioEvent);
+                    for (TriggerType mask : triggerTypes) {
+                        int count = triggerCounts.get(mask) + 1;
+                        triggerCounts.put(mask, count);
+                        LOGGER.finest("Incremented " + mask.name() + " to " + count);
+                    }
+                    
+                    // Activate TI time offset processor.
+                    tiProcessor.process(evioEvent);
+                    
+                } catch (Exception e) {  
+                    // Trap all event processing errors.
+                    badEvents++;
+                    LOGGER.warning("Error processing EVIO event " + evioEvent.getEventNumber());
+                }
+            }
         } catch (final EvioException e) {
-            throw new IOException(e);
-        }
-
-        final int fileNumber = EvioFileUtilities.getSequenceFromName(file);
-
-        EvioEvent evioEvent = null;
-
-        while (true) {
-            try {
-                evioEvent = evioReader.parseNextEvent();
-            } catch (IOException | EvioException e) {
-                ++badEventCount;
-                continue;
+            // Error reading the EVIO file.
+            throw new IOException("Error reading EVIO file.", e);
+        } finally {
+            // Close the reader.
+            if (evioReader != null) {
+                try {
+                    evioReader.close();
+                } catch (IOException e) {
+                    LOGGER.log(Level.WARNING, "Error closing EVIO reader", e);
+                }
             }
-            if (evioEvent == null) {
-                break;
+        }
+
+        LOGGER.info("Done reading " + totalEvents + " events from " + file.getPath());
+
+        // Rough trigger rate calculation.
+        try {
+            if (firstHeadTimestamp != null && lastHeadTimestamp != null && totalEvents > 0 
+                    && (firstHeadTimestamp - lastHeadTimestamp != 0)) {
+                triggerRate = calculateTriggerRate(firstHeadTimestamp, lastHeadTimestamp, totalEvents);
+            } else {
+                LOGGER.log(Level.WARNING, "Missing information for calculating trigger rate.");
             }
-            byteCount += evioEvent.getTotalBytes();
-            if (EventTagConstant.PRESTART.equals(evioEvent)) {
-                LOGGER.info("found PRESTART");
-                hasPrestart = true;
-                final int[] controlEventData = EvioEventUtilities.getControlEventData(evioEvent);
-                final long timestamp = controlEventData[0] * 1000L;
-                startDate = new Date(timestamp);
-                LOGGER.info("set start date to " + startDate + " from PRESTART");
-                if (run == null) {
-                    run = controlEventData[1];
-                    LOGGER.info("set run to " + run);
-                }
-            } else if (EventTagConstant.END.equals(evioEvent)) {
-                LOGGER.info("found END event");
-                hasEnd = true;
-                final int[] controlEventData = EvioEventUtilities.getControlEventData(evioEvent);
-                final long timestamp = controlEventData[0] * 1000L;
-                endDate = new Date(timestamp);
-                LOGGER.info("set end date to " + endDate);
-                if (run == null) {
-                    run = controlEventData[1];
-                    LOGGER.info("set run to " + run);
-                }
-            } else if (EvioEventUtilities.isPhysicsEvent(evioEvent)) {
-                final int[] headBankData = EvioEventUtilities.getHeadBankData(evioEvent);
-                if (startDate == null) {
-                    if (headBankData[3] != 0) {
-                        startDate = new Date(headBankData[3] * 1000L);
-                        LOGGER.info("set start date to " + startDate + " from physics event");
-                    }
-                }
-                if (run == null) {
-                    run = headBankData[1];
-                    LOGGER.info("set run to " + run + " from physics event");
-                }
-                eventIdData = EvioEventUtilities.getEventIdData(evioEvent);
-                if (startEvent == null) {
-                    startEvent = eventIdData[0];
-                    LOGGER.info("set start event " + startEvent);
-                }
-                if (headBankData[3] != 0) {
-                    lastTimestamp = headBankData[3] * 1000L;
-                }
-                ++eventCount;
+        } catch (Exception e) {
+            LOGGER.log(Level.WARNING, "Error calculating the trigger rate.", e);
+        }
+
+        // Create and fill the metadata map.
+        final Map<String, Object> metadataMap = new LinkedHashMap<String, Object>();
+
+        try {
+            if (run == null) {
+                run = new Long(EvioFileUtilities.getRunFromName(file));
             }
-        }
-
-        // Set end date from last valid timestamp.
-        if (endDate == null) {
-            endDate = new Date(lastTimestamp);
-            LOGGER.info("set end date to " + endDate + " from last timestamp " + lastTimestamp);
-        }
-
-        // Set end event number.
-        if (eventIdData != null) {
-            endEvent = eventIdData[0];
-            LOGGER.info("set end event " + endEvent);
-        }
-
-        final Map<String, Object> metaDataMap = new HashMap<String, Object>();
-
-        metaDataMap.put("runMin", run);
-        metaDataMap.put("runMax", run);
-        metaDataMap.put("eventCount", eventCount);
-        metaDataMap.put("size", byteCount);
-        metaDataMap.put("fileNumber", fileNumber);
-        metaDataMap.put("badEventCount", badEventCount);
-        metaDataMap.put("endTimestamp", endDate.getTime());
-        metaDataMap.put("startTimestamp", startDate.getTime());
-        metaDataMap.put("startEvent", startEvent);
-        metaDataMap.put("endEvent", endEvent);
-        metaDataMap.put("hasEnd", hasEnd ? 1 : 0);
-        metaDataMap.put("hasPrestart", hasPrestart ? 1 : 0);
-
-        return metaDataMap;
+        } catch (Exception e) {
+            throw new RuntimeException("Failed to get run number from event data or file name.", e);
+        }
+
+        // Set locationExtras metadata.
+        metadataMap.put("runMin", run);
+        metadataMap.put("runMax", run);
+        metadataMap.put("eventCount", totalEvents);
+        metadataMap.put("size", size);
+        metadataMap.put("checksum", checksum);     
+        
+        // File sequence number.
+        metadataMap.put("FILE", fileNumber);
+
+        // Blinded flag.
+        metadataMap.put("BLINDED", blinded);
+
+        // First and last timestamps which may come from control or physics events.
+        if (firstHeadTimestamp != null) {
+            metadataMap.put("FIRST_HEAD_TIMESTAMP", firstHeadTimestamp);
+        } 
+        
+        if (lastHeadTimestamp != null) {
+            metadataMap.put("LAST_HEAD_TIMESTAMP", lastHeadTimestamp);
+        } 
+
+        // First and last physics event numbers.
+        if (firstPhysicsEvent != null) {
+            metadataMap.put("FIRST_PHYSICS_EVENT", firstPhysicsEvent);
+        } 
+        
+        if (lastPhysicsEvent != null) {
+            metadataMap.put("LAST_PHYSICS_EVENT", lastPhysicsEvent);
+        }
+        
+        // Timestamps which are only set if the corresponding control events were found in the file.
+        if (prestartTimestamp != null) {
+            metadataMap.put("PRESTART_TIMESTAMP", prestartTimestamp);
+        }
+        if (endTimestamp != null) {
+            metadataMap.put("END_TIMESTAMP", endTimestamp);
+        }
+        if (goTimestamp != null) {
+            metadataMap.put("GO_TIMESTAMP", goTimestamp);
+        }
+
+        // TI times and offset.
+        metadataMap.put("TI_TIME_MIN_OFFSET", new Long(tiProcessor.getMinOffset()).toString());
+        metadataMap.put("TI_TIME_MAX_OFFSET", new Long(tiProcessor.getMaxOffset()).toString());
+        metadataMap.put("TI_TIME_N_OUTLIERS", tiProcessor.getNumOutliers());
+        
+        // Event counts.
+        metadataMap.put("BAD_EVENTS", badEvents);
+        
+        // Physics event count.
+        metadataMap.put("PHYSICS_EVENTS", physicsEvents);
+        
+        // Rough trigger rate.
+        if (triggerRate != null && !Double.isInfinite(triggerRate) && !Double.isNaN(triggerRate)) {
+            DecimalFormat df = new DecimalFormat("#.##");
+            df.setRoundingMode(RoundingMode.CEILING);
+            LOGGER.info("Setting trigger rate to " + triggerRate + " Hz.");
+            metadataMap.put("TRIGGER_RATE", Double.parseDouble(df.format(triggerRate)));
+        } else {
+            LOGGER.warning("Failed to calculate trigger rate.");
+        }        
+
+        // Trigger type counts.
+        for (Entry<TriggerType, Integer> entry : triggerCounts.entrySet()) {
+            metadataMap.put(entry.getKey().name(), entry.getValue());
+        }
+
+        // Print the file metadata to log.
+        StringBuffer sb = new StringBuffer();
+        sb.append('\n');
+        for (Entry<String, Object> entry : metadataMap.entrySet()) {
+            sb.append("  " + entry.getKey() + " = " + entry.getValue() + '\n');
+        }
+        LOGGER.info("File metadata ..." + '\n' + sb.toString());
+
+        // Return the completed metadata map.
+        return metadataMap;
+    }
+         
+    /**
+     * Calculate the trigger rate in Hz.
+     * 
+     * @param firstTimestamp the first physics timestamp
+     * @param lastTimestamp the last physics timestamp
+     * @param events the number of physics events
+     * @return the trigger rate calculation in KHz
+     */
+    private double calculateTriggerRate(Integer firstTimestamp, Integer lastTimestamp, long events) {
+        return ((double) events / ((double) lastTimestamp - (double) firstTimestamp));
     }
 }

Modified: java/branches/HPSJAVA-409/crawler/src/main/java/org/hps/crawler/FileFormatFilter.java
 =============================================================================
--- java/branches/HPSJAVA-409/crawler/src/main/java/org/hps/crawler/FileFormatFilter.java	(original)
+++ java/branches/HPSJAVA-409/crawler/src/main/java/org/hps/crawler/FileFormatFilter.java	Wed Apr 27 11:11:32 2016
@@ -3,9 +3,6 @@
 import java.io.File;
 import java.io.FileFilter;
 import java.util.Set;
-import java.util.logging.Logger;
-
-import org.hps.datacat.client.DatasetFileFormat;
 
 /**
  * Filter files on their format.
@@ -17,21 +14,16 @@
 public class FileFormatFilter implements FileFilter {
 
     /**
-     * Initialize the logger.
-     */
-    private static final Logger LOGGER = Logger.getLogger(FileFormatFilter.class.getPackage().getName());
-
-    /**
      * The file format.
      */
-    private final Set<DatasetFileFormat> formats;
+    private final Set<FileFormat> formats;
 
     /**
      * Create a new filter with the given format.
      *
      * @param format the file format
      */
-    FileFormatFilter(final Set<DatasetFileFormat> formats) {
+    FileFormatFilter(final Set<FileFormat> formats) {
         if (formats == null) {
             throw new IllegalArgumentException("The formats collection is null.");
         }
@@ -48,13 +40,10 @@
      */
     @Override
     public boolean accept(final File pathname) {
-        LOGGER.info(pathname.getPath());
-        final DatasetFileFormat fileFormat = DatacatUtilities.getFileFormat(pathname);
+        final FileFormat fileFormat = DatacatHelper.getFileFormat(pathname);
         if (fileFormat != null) {
-            LOGGER.info("file " + pathname.getPath() + " has format " + fileFormat.name());
             return formats.contains(fileFormat);
         } else {
-            LOGGER.info("rejected file " + pathname.getPath() + " with unknown format");
             return false;
         }
     }

Modified: java/branches/HPSJAVA-409/crawler/src/main/java/org/hps/crawler/FileMetadataReader.java
 =============================================================================
--- java/branches/HPSJAVA-409/crawler/src/main/java/org/hps/crawler/FileMetadataReader.java	(original)
+++ java/branches/HPSJAVA-409/crawler/src/main/java/org/hps/crawler/FileMetadataReader.java	Wed Apr 27 11:11:32 2016
@@ -4,8 +4,19 @@
 import java.io.IOException;
 import java.util.Map;
 
-
+/**
+ * Interface for reading metadata for the datacat from files.
+ * 
+ * @author Jeremy McCormick, SLAC
+ */
 public interface FileMetadataReader {   
     
-    public Map<String, Object> getMetadata(File file) throws IOException;
+    /**
+     * Create a metadata map with keys and values from the contents of a file.
+     * 
+     * @param file the input file from which to extract metadata
+     * @return the metadata map of field names to values
+     * @throws IOException if there is an error reading the file
+     */
+    Map<String, Object> getMetadata(File file) throws IOException;
 }

Modified: java/branches/HPSJAVA-409/crawler/src/main/java/org/hps/crawler/RootDqmMetadataReader.java
 =============================================================================
--- java/branches/HPSJAVA-409/crawler/src/main/java/org/hps/crawler/RootDqmMetadataReader.java	(original)
+++ java/branches/HPSJAVA-409/crawler/src/main/java/org/hps/crawler/RootDqmMetadataReader.java	Wed Apr 27 11:11:32 2016
@@ -22,7 +22,7 @@
     @Override
     public Map<String, Object> getMetadata(final File file) throws IOException {
         final Map<String, Object> metadata = new HashMap<String, Object>();
-        final int run = CrawlerFileUtilities.getRunFromFileName(file);
+        final Long run = FileUtilities.getRunFromFileName(file);
         metadata.put("runMin", run);
         metadata.put("runMax", run);
         return metadata;

Modified: java/branches/HPSJAVA-409/crawler/src/main/java/org/hps/crawler/RootDstMetadataReader.java
 =============================================================================
--- java/branches/HPSJAVA-409/crawler/src/main/java/org/hps/crawler/RootDstMetadataReader.java	(original)
+++ java/branches/HPSJAVA-409/crawler/src/main/java/org/hps/crawler/RootDstMetadataReader.java	Wed Apr 27 11:11:32 2016
@@ -1,10 +1,10 @@
 package org.hps.crawler;
 
-import hep.io.root.RootClassNotFound;
-import hep.io.root.RootFileReader;
-import hep.io.root.interfaces.TLeafElement;
-import hep.io.root.interfaces.TObjArray;
-import hep.io.root.interfaces.TTree;
+//import hep.io.root.RootClassNotFound;
+//import hep.io.root.RootFileReader;
+//import hep.io.root.interfaces.TLeafElement;
+//import hep.io.root.interfaces.TObjArray;
+//import hep.io.root.interfaces.TTree;
 
 import java.io.File;
 import java.io.IOException;
@@ -28,6 +28,10 @@
     @Override
     public Map<String, Object> getMetadata(final File file) throws IOException {
         final Map<String, Object> metadata = new HashMap<String, Object>();
+        Long run = FileUtilities.getRunFromFileName(file);
+        metadata.put("runMin", run);
+        metadata.put("runMax", run);
+        /*
         RootFileReader rootReader = null;
         long eventCount = 0;
         int runMin = 0;
@@ -60,6 +64,7 @@
         metadata.put("runMin", runMin);
         metadata.put("runMax", runMax);
         metadata.put("size", size);
+        */
         return metadata;
     }
 }

Modified: java/branches/HPSJAVA-409/crawler/src/main/java/org/hps/crawler/RunFilter.java
 =============================================================================
--- java/branches/HPSJAVA-409/crawler/src/main/java/org/hps/crawler/RunFilter.java	(original)
+++ java/branches/HPSJAVA-409/crawler/src/main/java/org/hps/crawler/RunFilter.java	Wed Apr 27 11:11:32 2016
@@ -3,8 +3,6 @@
 import java.io.File;
 import java.io.FileFilter;
 import java.util.Set;
-
-import org.hps.record.evio.EvioFileUtilities;
 
 /**
  * A filter which rejects files with run numbers not in a specified set.
@@ -25,7 +23,7 @@
      */
     RunFilter(final Set<Integer> acceptRuns) {
         if (acceptRuns.isEmpty()) {
-            throw new IllegalArgumentException("the acceptRuns collection is empty");
+            throw new IllegalArgumentException("The acceptRuns collection is empty.");
         }
         this.acceptRuns = acceptRuns;
     }
@@ -38,6 +36,11 @@
      */
     @Override
     public boolean accept(final File file) {
-        return this.acceptRuns.contains(EvioFileUtilities.getRunFromName(file));
+        try {
+            int run = Integer.parseInt(file.getName().substring(5, 10));
+            return this.acceptRuns.contains(run);
+        } catch (Exception e) {
+            return false;
+        }
     }
 }

Modified: java/branches/HPSJAVA-409/detector-data/detectors/HPS-EngRun2015-Nominal-v1-3/compact.xml
 =============================================================================
--- java/branches/HPSJAVA-409/detector-data/detectors/HPS-EngRun2015-Nominal-v1-3/compact.xml	(original)
+++ java/branches/HPSJAVA-409/detector-data/detectors/HPS-EngRun2015-Nominal-v1-3/compact.xml	Wed Apr 27 11:11:32 2016
@@ -9,8 +9,8 @@
                1) float L2_tu, 2) float L2_tu, L4_tu, L5_tu
                2nd: round
                1) float L2_tu, L4_tu, L5_tu
-	       3rd: round
-	       1) float L2_tu_rw, L4_tu_rw, L5_tu_rw
+           3rd: round
+           1) float L2_tu_rw, L4_tu_rw, L5_tu_rw
         </comment>
     </info>
     

Modified: java/branches/HPSJAVA-409/detector-data/detectors/HPS-EngRun2015-Nominal-v1-4-1/compact.xml
 =============================================================================
--- java/branches/HPSJAVA-409/detector-data/detectors/HPS-EngRun2015-Nominal-v1-4-1/compact.xml	(original)
+++ java/branches/HPSJAVA-409/detector-data/detectors/HPS-EngRun2015-Nominal-v1-4-1/compact.xml	Wed Apr 27 11:11:32 2016
@@ -9,8 +9,8 @@
                1) float L2_tu, 2) float L2_tu, L4_tu, L5_tu
                2nd: round
                1) float L2_tu, L4_tu, L5_tu
-	       3rd: round
-	       1) float L2_tu_rw, L4_tu_rw, L5_tu_rw
+           3rd: round
+           1) float L2_tu_rw, L4_tu_rw, L5_tu_rw
            4th: round start with v1-3
            L3_L4_L5_tu_rw_THEN_L2_tu_rw_THEN_L2_L3_L4_tu_rw_THEN_L2_L3_L5_tu_rw_THEN_L2_L3_L4_L5_excl_L3ST_tu_L4Sb_tu_THEN_L2_L4_L5_tu_rw
         </comment>

Modified: java/branches/HPSJAVA-409/detector-data/detectors/HPS-EngRun2015-Nominal-v1-4-1/compact_millepede-milleBinaryISN_hps_005772.evio.0.gbl-L3_L4_L5_tu_rw_THEN_L2_tu_rw_THEN_L2_L3_L4_tu_rw_THEN_L2_L3_L5_tu_rw_THEN_L2_L3_L4_L5_excl_L3ST_tu_L4Sb_tu_THEN_L2_L4_L5_tu_rw.xml
 =============================================================================
--- java/branches/HPSJAVA-409/detector-data/detectors/HPS-EngRun2015-Nominal-v1-4-1/compact_millepede-milleBinaryISN_hps_005772.evio.0.gbl-L3_L4_L5_tu_rw_THEN_L2_tu_rw_THEN_L2_L3_L4_tu_rw_THEN_L2_L3_L5_tu_rw_THEN_L2_L3_L4_L5_excl_L3ST_tu_L4Sb_tu_THEN_L2_L4_L5_tu_rw.xml	(original)
+++ java/branches/HPSJAVA-409/detector-data/detectors/HPS-EngRun2015-Nominal-v1-4-1/compact_millepede-milleBinaryISN_hps_005772.evio.0.gbl-L3_L4_L5_tu_rw_THEN_L2_tu_rw_THEN_L2_L3_L4_tu_rw_THEN_L2_L3_L5_tu_rw_THEN_L2_L3_L4_L5_excl_L3ST_tu_L4Sb_tu_THEN_L2_L4_L5_tu_rw.xml	Wed Apr 27 11:11:32 2016
@@ -9,8 +9,8 @@
                1) float L2_tu, 2) float L2_tu, L4_tu, L5_tu
                2nd: round
                1) float L2_tu, L4_tu, L5_tu
-	       3rd: round
-	       1) float L2_tu_rw, L4_tu_rw, L5_tu_rw
+           3rd: round
+           1) float L2_tu_rw, L4_tu_rw, L5_tu_rw
         </comment>
     </info>
     

Modified: java/branches/HPSJAVA-409/detector-data/detectors/HPS-EngRun2015-Nominal-v1-4/compact.xml
 =============================================================================
--- java/branches/HPSJAVA-409/detector-data/detectors/HPS-EngRun2015-Nominal-v1-4/compact.xml	(original)
+++ java/branches/HPSJAVA-409/detector-data/detectors/HPS-EngRun2015-Nominal-v1-4/compact.xml	Wed Apr 27 11:11:32 2016
@@ -9,8 +9,8 @@
                1) float L2_tu, 2) float L2_tu, L4_tu, L5_tu
                2nd: round
                1) float L2_tu, L4_tu, L5_tu
-	       3rd: round
-	       1) float L2_tu_rw, L4_tu_rw, L5_tu_rw
+           3rd: round
+           1) float L2_tu_rw, L4_tu_rw, L5_tu_rw
            4th: round start with v1-3
            1) float L2_tu_rw, L3_tu_rw, L4_tu_rw
         </comment>

Modified: java/branches/HPSJAVA-409/detector-data/detectors/HPS-EngRun2015-Nominal-v1-4/compact_millepede-milleBinaryISN_hps_005772.evio.0.gbl-L2-3-4_tu_rw.xml
 =============================================================================
--- java/branches/HPSJAVA-409/detector-data/detectors/HPS-EngRun2015-Nominal-v1-4/compact_millepede-milleBinaryISN_hps_005772.evio.0.gbl-L2-3-4_tu_rw.xml	(original)
+++ java/branches/HPSJAVA-409/detector-data/detectors/HPS-EngRun2015-Nominal-v1-4/compact_millepede-milleBinaryISN_hps_005772.evio.0.gbl-L2-3-4_tu_rw.xml	Wed Apr 27 11:11:32 2016
@@ -9,8 +9,8 @@
                1) float L2_tu, 2) float L2_tu, L4_tu, L5_tu
                2nd: round
                1) float L2_tu, L4_tu, L5_tu
-	       3rd: round
-	       1) float L2_tu_rw, L4_tu_rw, L5_tu_rw
+           3rd: round
+           1) float L2_tu_rw, L4_tu_rw, L5_tu_rw
         </comment>
     </info>
     

Modified: java/branches/HPSJAVA-409/detector-data/detectors/HPS-EngRun2015-Nominal-v1-5-1/compact_millepede-milleBinaryISN_hps_005772.evio.0.gbl-L3_L4_L5_tu_rw_THEN_L2_tu_rw_THEN_L2_L3_L4_tu_rw_THEN_L2_L3_L5_tu_rw_THEN_L2_L3_L4_L5_excl_L3ST_tu_L4Sb_tu_THEN_L2_L4_L5_tu_rw.xml
 =============================================================================
--- java/branches/HPSJAVA-409/detector-data/detectors/HPS-EngRun2015-Nominal-v1-5-1/compact_millepede-milleBinaryISN_hps_005772.evio.0.gbl-L3_L4_L5_tu_rw_THEN_L2_tu_rw_THEN_L2_L3_L4_tu_rw_THEN_L2_L3_L5_tu_rw_THEN_L2_L3_L4_L5_excl_L3ST_tu_L4Sb_tu_THEN_L2_L4_L5_tu_rw.xml	(original)
+++ java/branches/HPSJAVA-409/detector-data/detectors/HPS-EngRun2015-Nominal-v1-5-1/compact_millepede-milleBinaryISN_hps_005772.evio.0.gbl-L3_L4_L5_tu_rw_THEN_L2_tu_rw_THEN_L2_L3_L4_tu_rw_THEN_L2_L3_L5_tu_rw_THEN_L2_L3_L4_L5_excl_L3ST_tu_L4Sb_tu_THEN_L2_L4_L5_tu_rw.xml	Wed Apr 27 11:11:32 2016
@@ -9,8 +9,8 @@
                1) float L2_tu, 2) float L2_tu, L4_tu, L5_tu
                2nd: round
                1) float L2_tu, L4_tu, L5_tu
-	       3rd: round
-	       1) float L2_tu_rw, L4_tu_rw, L5_tu_rw
+           3rd: round
+           1) float L2_tu_rw, L4_tu_rw, L5_tu_rw
         </comment>
     </info>
     

Modified: java/branches/HPSJAVA-409/detector-data/detectors/HPS-EngRun2015-Nominal-v1-5-2/compact_millepede-milleBinaryISN_hps_005772.evio.0.gbl-HPS-EngRun2015-Nominal-v1-4-1-100k-L456_L123_L234_L345_L123_L456_tu_rwIter0Iter1Iter2Iter3Iter4Iter5.xml
 =============================================================================
--- java/branches/HPSJAVA-409/detector-data/detectors/HPS-EngRun2015-Nominal-v1-5-2/compact_millepede-milleBinaryISN_hps_005772.evio.0.gbl-HPS-EngRun2015-Nominal-v1-4-1-100k-L456_L123_L234_L345_L123_L456_tu_rwIter0Iter1Iter2Iter3Iter4Iter5.xml	(original)
+++ java/branches/HPSJAVA-409/detector-data/detectors/HPS-EngRun2015-Nominal-v1-5-2/compact_millepede-milleBinaryISN_hps_005772.evio.0.gbl-HPS-EngRun2015-Nominal-v1-4-1-100k-L456_L123_L234_L345_L123_L456_tu_rwIter0Iter1Iter2Iter3Iter4Iter5.xml	Wed Apr 27 11:11:32 2016
@@ -9,8 +9,8 @@
                1) float L2_tu, 2) float L2_tu, L4_tu, L5_tu
                2nd: round
                1) float L2_tu, L4_tu, L5_tu
-	       3rd: round
-	       1) float L2_tu_rw, L4_tu_rw, L5_tu_rw
+           3rd: round
+           1) float L2_tu_rw, L4_tu_rw, L5_tu_rw
            4th: round start with v1-3
            L3_L4_L5_tu_rw_THEN_L2_tu_rw_THEN_L2_L3_L4_tu_rw_THEN_L2_L3_L5_tu_rw_THEN_L2_L3_L4_L5_excl_L3ST_tu_L4Sb_tu_THEN_L2_L4_L5_tu_rw
         </comment>

Modified: java/branches/HPSJAVA-409/detector-data/detectors/HPS-Proposal2014-v3-2pt2-0zOffset/compact.xml
 =============================================================================
--- java/branches/HPSJAVA-409/detector-data/detectors/HPS-Proposal2014-v3-2pt2-0zOffset/compact.xml	(original)
+++ java/branches/HPSJAVA-409/detector-data/detectors/HPS-Proposal2014-v3-2pt2-0zOffset/compact.xml	Wed Apr 27 11:11:32 2016
@@ -305,7 +305,7 @@
             </layer>
             <layer id="2">
                 <module_placement name="TestRunModuleFieldDef" id="0" x="0" y="0" z="endOfFieldZ" rx="0" ry="0" rz="-PI/2"/>
-			</layer>
+            </layer>
             
            
         </detector>     

Modified: java/branches/HPSJAVA-409/detector-data/detectors/HPS-TestRun-v5/compact.xml
 =============================================================================
--- java/branches/HPSJAVA-409/detector-data/detectors/HPS-TestRun-v5/compact.xml	(original)
+++ java/branches/HPSJAVA-409/detector-data/detectors/HPS-TestRun-v5/compact.xml	Wed Apr 27 11:11:32 2016
@@ -488,7 +488,7 @@
     </define>
     
     <materials>      
-    	<!-- Set the world material to vacuum. -->
+        <!-- Set the world material to vacuum. -->
         <material name="WorldMaterial">
             <D type="density" unit="g/cm3" value="0.0000000000000001"/>
             <fraction n="1.0" ref="Vacuum" />
@@ -578,7 +578,7 @@
             </layer>
             <layer id="2">
                 <module_placement name="TestRunModuleFieldDef" id="0" x="0" y="0" z="endOfFieldZ" rx="0" ry="0" rz="-PI/2"/>
-			</layer>
+            </layer>
         </detector>     
         
         <detector id="13" name="Ecal" type="HPSEcal3" insideTrackingVolume="false" readout="EcalHits" vis="ECALVis">

Modified: java/branches/HPSJAVA-409/detector-data/detectors/HPS-TestRun-v6/compact.xml
 =============================================================================
--- java/branches/HPSJAVA-409/detector-data/detectors/HPS-TestRun-v6/compact.xml	(original)
+++ java/branches/HPSJAVA-409/detector-data/detectors/HPS-TestRun-v6/compact.xml	Wed Apr 27 11:11:32 2016
@@ -488,7 +488,7 @@
     </define>
     
     <materials>      
-    	<!-- Set the world material to vacuum. -->
+        <!-- Set the world material to vacuum. -->
         <material name="WorldMaterial">
             <D type="density" unit="g/cm3" value="0.0000000000000001"/>
             <fraction n="1.0" ref="Vacuum" />
@@ -578,7 +578,7 @@
             </layer>
             <layer id="2">
                 <module_placement name="TestRunModuleFieldDef" id="0" x="0" y="0" z="endOfFieldZ" rx="0" ry="0" rz="-PI/2"/>
-			</layer>
+            </layer>
         </detector>     
         
         <detector id="13" name="Ecal" type="HPSEcal3" insideTrackingVolume="false" readout="EcalHits" vis="ECALVis">

Modified: java/branches/HPSJAVA-409/detector-data/detectors/HPS-TestRun-v7-2/compact.xml
 =============================================================================
--- java/branches/HPSJAVA-409/detector-data/detectors/HPS-TestRun-v7-2/compact.xml	(original)
+++ java/branches/HPSJAVA-409/detector-data/detectors/HPS-TestRun-v7-2/compact.xml	Wed Apr 27 11:11:32 2016
@@ -86,127 +86,127 @@
         <constant name="y9b_misalign" value="0.0"/>
         <constant name="y10b_misalign" value="0.0"/>
 
-		<!-- alignment corrections -->
-	<constant name="x1t_align" value="0.000000"/>
-	<constant name="x2t_align" value="0.000000"/>
-	<constant name="x3t_align" value="0.000000"/>
-	<constant name="x4t_align" value="0.000000"/>
-	<constant name="x5t_align" value="0.000000"/>
-	<constant name="x6t_align" value="0.000000"/>
-	<constant name="x7t_align" value="0.000000"/>
-	<constant name="x8t_align" value="0.000000"/>
-	<constant name="x9t_align" value="0.000000"/>
-	<constant name="x10t_align" value="0.000000"/>
-	<constant name="y1t_align" value="0.000000"/>
-	<constant name="y2t_align" value="0.000000"/>
-	<constant name="y3t_align" value="0.0"/>
-	<constant name="y4t_align" value="0.0"/>
-	<constant name="y5t_align" value="0.000000"/>
-	<constant name="y6t_align" value="0.000000"/>
-	<constant name="y7t_align" value="0.000000"/>
-	<constant name="y8t_align" value="0.000000"/>
-	<constant name="y9t_align" value="0.000000"/>
-	<constant name="y10t_align" value="0.000000"/>
-	<constant name="z1t_align" value="0.000000"/>
-	<constant name="z2t_align" value="0.000000"/>
-	<constant name="z3t_align" value="0.000000"/>
-	<constant name="z4t_align" value="0.000000"/>
-	<constant name="z5t_align" value="0.000000"/>
-	<constant name="z6t_align" value="0.000000"/>
-	<constant name="z7t_align" value="0.000000"/>
-	<constant name="z8t_align" value="0.000000"/>
-	<constant name="z9t_align" value="0.000000"/>
-	<constant name="z10t_align" value="0.000000"/>
-	<constant name="rx1t_align" value="0.000000"/>
-	<constant name="rx2t_align" value="0.000000"/>
-	<constant name="rx3t_align" value="0.000000"/>
-	<constant name="rx4t_align" value="0.000000"/>
-	<constant name="rx5t_align" value="0.000000"/>
-	<constant name="rx6t_align" value="0.000000"/>
-	<constant name="rx7t_align" value="0.000000"/>
-	<constant name="rx8t_align" value="0.000000"/>
-	<constant name="rx9t_align" value="0.000000"/>
-	<constant name="rx10t_align" value="0.000000"/>
-	<constant name="ry1t_align" value="0.000000"/>
-	<constant name="ry2t_align" value="0.000000"/>
-	<constant name="ry3t_align" value="0.000000"/>
-	<constant name="ry4t_align" value="0.000000"/>
-	<constant name="ry5t_align" value="0.000000"/>
-	<constant name="ry6t_align" value="0.000000"/>
-	<constant name="ry7t_align" value="0.000000"/>
-	<constant name="ry8t_align" value="0.000000"/>
-	<constant name="ry9t_align" value="0.000000"/>
-	<constant name="ry10t_align" value="0.000000"/>
-	<constant name="rz1t_align" value="0.000000"/>
-	<constant name="rz2t_align" value="0.000000"/>
-	<constant name="rz3t_align" value="0.000000"/>
-	<constant name="rz4t_align" value="0.000000"/>
-	<constant name="rz5t_align" value="0.000000"/>
-	<constant name="rz6t_align" value="0.000000"/>
-	<constant name="rz7t_align" value="0.000000"/>
-	<constant name="rz8t_align" value="0.000000"/>
-	<constant name="rz9t_align" value="0.000000"/>
-	<constant name="rz10t_align" value="0.000000"/>
-	<constant name="x1b_align" value="0.000000"/>
-	<constant name="x2b_align" value="0.000000"/>
-	<constant name="x3b_align" value="0.000000"/>
-	<constant name="x4b_align" value="0.000000"/>
-	<constant name="x5b_align" value="0.000000"/>
-	<constant name="x6b_align" value="0.00000"/>
-	<constant name="x7b_align" value="0.000000"/>
-	<constant name="x8b_align" value="0.000000"/>
-	<constant name="x9b_align" value="0.000000"/>
-	<constant name="x10b_align" value="0.000000"/>
-	<constant name="y1b_align" value="0.000000"/>
-	<constant name="y2b_align" value="0.000000"/>
-	<constant name="y3b_align" value="0.000000"/>
-	<constant name="y4b_align" value="0.000000"/>
-	<constant name="y5b_align" value="0.0"/>
-	<constant name="y6b_align" value="0.0"/>
-	<constant name="y7b_align" value="0.000000"/>
-	<constant name="y8b_align" value="0.000000"/>
-	<constant name="y9b_align" value="0.000000"/>
-	<constant name="y10b_align" value="0.000000"/>
-	<constant name="z1b_align" value="0.000000"/>
-	<constant name="z2b_align" value="0.000000"/>
-	<constant name="z3b_align" value="0.000000"/>
-	<constant name="z4b_align" value="0.000000"/>
-	<constant name="z5b_align" value="0.000000"/>
-	<constant name="z6b_align" value="0.000000"/>
-	<constant name="z7b_align" value="0.000000"/>
-	<constant name="z8b_align" value="0.000000"/>
-	<constant name="z9b_align" value="0.000000"/>
-	<constant name="z10b_align" value="0.000000"/>
-	<constant name="rx1b_align" value="0.000000"/>
-	<constant name="rx2b_align" value="0.000000"/>
-	<constant name="rx3b_align" value="0.000000"/>
-	<constant name="rx4b_align" value="0.000000"/>
-	<constant name="rx5b_align" value="0.000000"/>
-	<constant name="rx6b_align" value="0.000000"/>
-	<constant name="rx7b_align" value="0.000000"/>
-	<constant name="rx8b_align" value="0.000000"/>
-	<constant name="rx9b_align" value="0.000000"/>
-	<constant name="rx10b_align" value="0.000000"/>
-	<constant name="ry1b_align" value="0.000000"/>
-	<constant name="ry2b_align" value="0.000000"/>
-	<constant name="ry3b_align" value="0.000000"/>
-	<constant name="ry4b_align" value="0.000000"/>
-	<constant name="ry5b_align" value="0.000000"/>
-	<constant name="ry6b_align" value="0.000000"/>
-	<constant name="ry7b_align" value="0.000000"/>
-	<constant name="ry8b_align" value="0.000000"/>
-	<constant name="ry9b_align" value="0.000000"/>
-	<constant name="ry10b_align" value="0.000000"/>
-	<constant name="rz1b_align" value="0.000000"/>
-	<constant name="rz2b_align" value="0.000000"/>
-	<constant name="rz3b_align" value="0.000000"/>
-	<constant name="rz4b_align" value="0.000000"/>
-	<constant name="rz5b_align" value="0.000000"/>
-	<constant name="rz6b_align" value="0.000000"/>
-	<constant name="rz7b_align" value="0.000000"/>
-	<constant name="rz8b_align" value="0.000000"/>
-	<constant name="rz9b_align" value="0.000000"/>
-	<constant name="rz10b_align" value="0.000000"/>
+        <!-- alignment corrections -->
+    <constant name="x1t_align" value="0.000000"/>
+    <constant name="x2t_align" value="0.000000"/>
+    <constant name="x3t_align" value="0.000000"/>
+    <constant name="x4t_align" value="0.000000"/>
+    <constant name="x5t_align" value="0.000000"/>
+    <constant name="x6t_align" value="0.000000"/>
+    <constant name="x7t_align" value="0.000000"/>
+    <constant name="x8t_align" value="0.000000"/>
+    <constant name="x9t_align" value="0.000000"/>
+    <constant name="x10t_align" value="0.000000"/>
+    <constant name="y1t_align" value="0.000000"/>
+    <constant name="y2t_align" value="0.000000"/>
+    <constant name="y3t_align" value="0.0"/>
+    <constant name="y4t_align" value="0.0"/>
+    <constant name="y5t_align" value="0.000000"/>
+    <constant name="y6t_align" value="0.000000"/>
+    <constant name="y7t_align" value="0.000000"/>
+    <constant name="y8t_align" value="0.000000"/>
+    <constant name="y9t_align" value="0.000000"/>
+    <constant name="y10t_align" value="0.000000"/>
+    <constant name="z1t_align" value="0.000000"/>
+    <constant name="z2t_align" value="0.000000"/>
+    <constant name="z3t_align" value="0.000000"/>
+    <constant name="z4t_align" value="0.000000"/>
+    <constant name="z5t_align" value="0.000000"/>
+    <constant name="z6t_align" value="0.000000"/>
+    <constant name="z7t_align" value="0.000000"/>
+    <constant name="z8t_align" value="0.000000"/>
+    <constant name="z9t_align" value="0.000000"/>
+    <constant name="z10t_align" value="0.000000"/>
+    <constant name="rx1t_align" value="0.000000"/>
+    <constant name="rx2t_align" value="0.000000"/>
+    <constant name="rx3t_align" value="0.000000"/>
+    <constant name="rx4t_align" value="0.000000"/>
+    <constant name="rx5t_align" value="0.000000"/>
+    <constant name="rx6t_align" value="0.000000"/>
+    <constant name="rx7t_align" value="0.000000"/>
+    <constant name="rx8t_align" value="0.000000"/>
+    <constant name="rx9t_align" value="0.000000"/>
+    <constant name="rx10t_align" value="0.000000"/>
+    <constant name="ry1t_align" value="0.000000"/>
+    <constant name="ry2t_align" value="0.000000"/>
+    <constant name="ry3t_align" value="0.000000"/>
+    <constant name="ry4t_align" value="0.000000"/>
+    <constant name="ry5t_align" value="0.000000"/>
+    <constant name="ry6t_align" value="0.000000"/>
+    <constant name="ry7t_align" value="0.000000"/>
+    <constant name="ry8t_align" value="0.000000"/>
+    <constant name="ry9t_align" value="0.000000"/>
+    <constant name="ry10t_align" value="0.000000"/>
+    <constant name="rz1t_align" value="0.000000"/>
+    <constant name="rz2t_align" value="0.000000"/>
+    <constant name="rz3t_align" value="0.000000"/>
+    <constant name="rz4t_align" value="0.000000"/>
+    <constant name="rz5t_align" value="0.000000"/>
+    <constant name="rz6t_align" value="0.000000"/>
+    <constant name="rz7t_align" value="0.000000"/>
+    <constant name="rz8t_align" value="0.000000"/>
+    <constant name="rz9t_align" value="0.000000"/>
+    <constant name="rz10t_align" value="0.000000"/>
+    <constant name="x1b_align" value="0.000000"/>
+    <constant name="x2b_align" value="0.000000"/>
+    <constant name="x3b_align" value="0.000000"/>
+    <constant name="x4b_align" value="0.000000"/>
+    <constant name="x5b_align" value="0.000000"/>
+    <constant name="x6b_align" value="0.00000"/>
+    <constant name="x7b_align" value="0.000000"/>
+    <constant name="x8b_align" value="0.000000"/>
+    <constant name="x9b_align" value="0.000000"/>
+    <constant name="x10b_align" value="0.000000"/>
+    <constant name="y1b_align" value="0.000000"/>
+    <constant name="y2b_align" value="0.000000"/>
+    <constant name="y3b_align" value="0.000000"/>
+    <constant name="y4b_align" value="0.000000"/>
+    <constant name="y5b_align" value="0.0"/>
+    <constant name="y6b_align" value="0.0"/>
+    <constant name="y7b_align" value="0.000000"/>
+    <constant name="y8b_align" value="0.000000"/>
+    <constant name="y9b_align" value="0.000000"/>
+    <constant name="y10b_align" value="0.000000"/>
+    <constant name="z1b_align" value="0.000000"/>
+    <constant name="z2b_align" value="0.000000"/>
+    <constant name="z3b_align" value="0.000000"/>
+    <constant name="z4b_align" value="0.000000"/>
+    <constant name="z5b_align" value="0.000000"/>
+    <constant name="z6b_align" value="0.000000"/>
+    <constant name="z7b_align" value="0.000000"/>
+    <constant name="z8b_align" value="0.000000"/>
+    <constant name="z9b_align" value="0.000000"/>
+    <constant name="z10b_align" value="0.000000"/>
+    <constant name="rx1b_align" value="0.000000"/>
+    <constant name="rx2b_align" value="0.000000"/>
+    <constant name="rx3b_align" value="0.000000"/>
+    <constant name="rx4b_align" value="0.000000"/>
+    <constant name="rx5b_align" value="0.000000"/>
+    <constant name="rx6b_align" value="0.000000"/>
+    <constant name="rx7b_align" value="0.000000"/>
+    <constant name="rx8b_align" value="0.000000"/>
+    <constant name="rx9b_align" value="0.000000"/>
+    <constant name="rx10b_align" value="0.000000"/>
+    <constant name="ry1b_align" value="0.000000"/>
+    <constant name="ry2b_align" value="0.000000"/>
+    <constant name="ry3b_align" value="0.000000"/>
+    <constant name="ry4b_align" value="0.000000"/>
+    <constant name="ry5b_align" value="0.000000"/>
+    <constant name="ry6b_align" value="0.000000"/>
+    <constant name="ry7b_align" value="0.000000"/>
+    <constant name="ry8b_align" value="0.000000"/>
+    <constant name="ry9b_align" value="0.000000"/>
+    <constant name="ry10b_align" value="0.000000"/>
+    <constant name="rz1b_align" value="0.000000"/>
+    <constant name="rz2b_align" value="0.000000"/>
+    <constant name="rz3b_align" value="0.000000"/>
+    <constant name="rz4b_align" value="0.000000"/>
+    <constant name="rz5b_align" value="0.000000"/>
+    <constant name="rz6b_align" value="0.000000"/>
+    <constant name="rz7b_align" value="0.000000"/>
+    <constant name="rz8b_align" value="0.000000"/>
+    <constant name="rz9b_align" value="0.000000"/>
+    <constant name="rz10b_align" value="0.000000"/>
 
         <!-- Positions of sensor centers above/below nominal beam -->
         <constant name="y1t" value="36.894" />
@@ -606,134 +606,134 @@
         <constant name="mod2_rx10b" value="mod_rx10b"/>
         <constant name="mod2_ry10b" value="mod_ry10b+y_rot_bot_pivot"/>
         <constant name="mod2_rz10b" value="mod_rz10b"/>
-    	
-    	<!-- final constants -->
-	<constant name="final_x1t" value="mod2_x1t+x1t_align"/>
-	<constant name="final_x2t" value="mod2_x2t+x2t_align"/>
-	<constant name="final_x3t" value="mod2_x3t+x3t_align"/>
-	<constant name="final_x4t" value="mod2_x4t+x4t_align"/>
-	<constant name="final_x5t" value="mod2_x5t+x5t_align"/>
-	<constant name="final_x6t" value="mod2_x6t+x6t_align"/>
-	<constant name="final_x7t" value="mod2_x7t+x7t_align"/>
-	<constant name="final_x8t" value="mod2_x8t+x8t_align"/>
-	<constant name="final_x9t" value="mod2_x9t+x9t_align"/>
-	<constant name="final_x10t" value="mod2_x10t+x10t_align"/>
-	<constant name="final_y1t" value="mod2_y1t+y1t_align"/>
-	<constant name="final_y2t" value="mod2_y2t+y2t_align"/>
-	<constant name="final_y3t" value="mod2_y3t+y3t_align"/>
-	<constant name="final_y4t" value="mod2_y4t+y4t_align"/>
-	<constant name="final_y5t" value="mod2_y5t+y5t_align"/>
-	<constant name="final_y6t" value="mod2_y6t+y6t_align"/>
-	<constant name="final_y7t" value="mod2_y7t+y7t_align"/>
-	<constant name="final_y8t" value="mod2_y8t+y8t_align"/>
-	<constant name="final_y9t" value="mod2_y9t+y9t_align"/>
-	<constant name="final_y10t" value="mod2_y10t+y10t_align"/>
-	<constant name="final_z1t" value="mod2_z1t+z1t_align"/>
-	<constant name="final_z2t" value="mod2_z2t+z2t_align"/>
-	<constant name="final_z3t" value="mod2_z3t+z3t_align"/>
-	<constant name="final_z4t" value="mod2_z4t+z4t_align"/>
-	<constant name="final_z5t" value="mod2_z5t+z5t_align"/>
-	<constant name="final_z6t" value="mod2_z6t+z6t_align"/>
-	<constant name="final_z7t" value="mod2_z7t+z7t_align"/>
-	<constant name="final_z8t" value="mod2_z8t+z8t_align"/>
-	<constant name="final_z9t" value="mod2_z9t+z9t_align"/>
-	<constant name="final_z10t" value="mod2_z10t+z10t_align"/>
-	<constant name="final_rx1t" value="mod2_rx1t+rx1t_align"/>
-	<constant name="final_rx2t" value="mod2_rx2t+rx2t_align"/>
-	<constant name="final_rx3t" value="mod2_rx3t+rx3t_align"/>
-	<constant name="final_rx4t" value="mod2_rx4t+rx4t_align"/>
-	<constant name="final_rx5t" value="mod2_rx5t+rx5t_align"/>
-	<constant name="final_rx6t" value="mod2_rx6t+rx6t_align"/>
-	<constant name="final_rx7t" value="mod2_rx7t+rx7t_align"/>
-	<constant name="final_rx8t" value="mod2_rx8t+rx8t_align"/>
-	<constant name="final_rx9t" value="mod2_rx9t+rx9t_align"/>
-	<constant name="final_rx10t" value="mod2_rx10t+rx10t_align"/>
-	<constant name="final_ry1t" value="mod2_ry1t+ry1t_align"/>
-	<constant name="final_ry2t" value="mod2_ry2t+ry2t_align"/>
-	<constant name="final_ry3t" value="mod2_ry3t+ry3t_align"/>
-	<constant name="final_ry4t" value="mod2_ry4t+ry4t_align"/>
-	<constant name="final_ry5t" value="mod2_ry5t+ry5t_align"/>
-	<constant name="final_ry6t" value="mod2_ry6t+ry6t_align"/>
-	<constant name="final_ry7t" value="mod2_ry7t+ry7t_align"/>
-	<constant name="final_ry8t" value="mod2_ry8t+ry8t_align"/>
-	<constant name="final_ry9t" value="mod2_ry9t+ry9t_align"/>
-	<constant name="final_ry10t" value="mod2_ry10t+ry10t_align"/>
-	<constant name="final_rz1t" value="mod2_rz1t+rz1t_align"/>
-	<constant name="final_rz2t" value="mod2_rz2t+rz2t_align"/>
-	<constant name="final_rz3t" value="mod2_rz3t+rz3t_align"/>
-	<constant name="final_rz4t" value="mod2_rz4t+rz4t_align"/>
-	<constant name="final_rz5t" value="mod2_rz5t+rz5t_align"/>
-	<constant name="final_rz6t" value="mod2_rz6t+rz6t_align"/>
-	<constant name="final_rz7t" value="mod2_rz7t+rz7t_align"/>
-	<constant name="final_rz8t" value="mod2_rz8t+rz8t_align"/>
-	<constant name="final_rz9t" value="mod2_rz9t+rz9t_align"/>
-	<constant name="final_rz10t" value="mod2_rz10t+rz10t_align"/>
-	<constant name="final_x1b" value="mod2_x1b+x1b_align"/>
-	<constant name="final_x2b" value="mod2_x2b+x2b_align"/>
-	<constant name="final_x3b" value="mod2_x3b+x3b_align"/>
-	<constant name="final_x4b" value="mod2_x4b+x4b_align"/>
-	<constant name="final_x5b" value="mod2_x5b+x5b_align"/>
-	<constant name="final_x6b" value="mod2_x6b+x6b_align"/>
-	<constant name="final_x7b" value="mod2_x7b+x7b_align"/>
-	<constant name="final_x8b" value="mod2_x8b+x8b_align"/>
-	<constant name="final_x9b" value="mod2_x9b+x9b_align"/>
-	<constant name="final_x10b" value="mod2_x10b+x10b_align"/>
-	<constant name="final_y1b" value="mod2_y1b+y1b_align"/>
-	<constant name="final_y2b" value="mod2_y2b+y2b_align"/>
-	<constant name="final_y3b" value="mod2_y3b+y3b_align"/>
-	<constant name="final_y4b" value="mod2_y4b+y4b_align"/>
-	<constant name="final_y5b" value="mod2_y5b+y5b_align"/>
-	<constant name="final_y6b" value="mod2_y6b+y6b_align"/>
-	<constant name="final_y7b" value="mod2_y7b+y7b_align"/>
-	<constant name="final_y8b" value="mod2_y8b+y8b_align"/>
-	<constant name="final_y9b" value="mod2_y9b+y9b_align"/>
-	<constant name="final_y10b" value="mod2_y10b+y10b_align"/>
-	<constant name="final_z1b" value="mod2_z1b+z1b_align"/>
-	<constant name="final_z2b" value="mod2_z2b+z2b_align"/>
-	<constant name="final_z3b" value="mod2_z3b+z3b_align"/>
-	<constant name="final_z4b" value="mod2_z4b+z4b_align"/>
-	<constant name="final_z5b" value="mod2_z5b+z5b_align"/>
-	<constant name="final_z6b" value="mod2_z6b+z6b_align"/>
-	<constant name="final_z7b" value="mod2_z7b+z7b_align"/>
-	<constant name="final_z8b" value="mod2_z8b+z8b_align"/>
-	<constant name="final_z9b" value="mod2_z9b+z9b_align"/>
-	<constant name="final_z10b" value="mod2_z10b+z10b_align"/>
-	<constant name="final_rx1b" value="mod2_rx1b+rx1b_align"/>
-	<constant name="final_rx2b" value="mod2_rx2b+rx2b_align"/>
-	<constant name="final_rx3b" value="mod2_rx3b+rx3b_align"/>
-	<constant name="final_rx4b" value="mod2_rx4b+rx4b_align"/>
-	<constant name="final_rx5b" value="mod2_rx5b+rx5b_align"/>
-	<constant name="final_rx6b" value="mod2_rx6b+rx6b_align"/>
-	<constant name="final_rx7b" value="mod2_rx7b+rx7b_align"/>
-	<constant name="final_rx8b" value="mod2_rx8b+rx8b_align"/>
-	<constant name="final_rx9b" value="mod2_rx9b+rx9b_align"/>
-	<constant name="final_rx10b" value="mod2_rx10b+rx10b_align"/>
-	<constant name="final_ry1b" value="mod2_ry1b+ry1b_align"/>
-	<constant name="final_ry2b" value="mod2_ry2b+ry2b_align"/>
-	<constant name="final_ry3b" value="mod2_ry3b+ry3b_align"/>
-	<constant name="final_ry4b" value="mod2_ry4b+ry4b_align"/>
-	<constant name="final_ry5b" value="mod2_ry5b+ry5b_align"/>
-	<constant name="final_ry6b" value="mod2_ry6b+ry6b_align"/>
-	<constant name="final_ry7b" value="mod2_ry7b+ry7b_align"/>
-	<constant name="final_ry8b" value="mod2_ry8b+ry8b_align"/>
-	<constant name="final_ry9b" value="mod2_ry9b+ry9b_align"/>
-	<constant name="final_ry10b" value="mod2_ry10b+ry10b_align"/>
-	<constant name="final_rz1b" value="mod2_rz1b+rz1b_align"/>
-	<constant name="final_rz2b" value="mod2_rz2b+rz2b_align"/>
-	<constant name="final_rz3b" value="mod2_rz3b+rz3b_align"/>
-	<constant name="final_rz4b" value="mod2_rz4b+rz4b_align"/>
-	<constant name="final_rz5b" value="mod2_rz5b+rz5b_align"/>
-	<constant name="final_rz6b" value="mod2_rz6b+rz6b_align"/>
-	<constant name="final_rz7b" value="mod2_rz7b+rz7b_align"/>
-	<constant name="final_rz8b" value="mod2_rz8b+rz8b_align"/>
-	<constant name="final_rz9b" value="mod2_rz9b+rz9b_align"/>
-	<constant name="final_rz10b" value="mod2_rz10b+rz10b_align"/>
-    	
-    	
+        
+        <!-- final constants -->
+    <constant name="final_x1t" value="mod2_x1t+x1t_align"/>
+    <constant name="final_x2t" value="mod2_x2t+x2t_align"/>
+    <constant name="final_x3t" value="mod2_x3t+x3t_align"/>
+    <constant name="final_x4t" value="mod2_x4t+x4t_align"/>
+    <constant name="final_x5t" value="mod2_x5t+x5t_align"/>
+    <constant name="final_x6t" value="mod2_x6t+x6t_align"/>
+    <constant name="final_x7t" value="mod2_x7t+x7t_align"/>
+    <constant name="final_x8t" value="mod2_x8t+x8t_align"/>
+    <constant name="final_x9t" value="mod2_x9t+x9t_align"/>
+    <constant name="final_x10t" value="mod2_x10t+x10t_align"/>
+    <constant name="final_y1t" value="mod2_y1t+y1t_align"/>
+    <constant name="final_y2t" value="mod2_y2t+y2t_align"/>
+    <constant name="final_y3t" value="mod2_y3t+y3t_align"/>
+    <constant name="final_y4t" value="mod2_y4t+y4t_align"/>
+    <constant name="final_y5t" value="mod2_y5t+y5t_align"/>
+    <constant name="final_y6t" value="mod2_y6t+y6t_align"/>
+    <constant name="final_y7t" value="mod2_y7t+y7t_align"/>
+    <constant name="final_y8t" value="mod2_y8t+y8t_align"/>
+    <constant name="final_y9t" value="mod2_y9t+y9t_align"/>
+    <constant name="final_y10t" value="mod2_y10t+y10t_align"/>
+    <constant name="final_z1t" value="mod2_z1t+z1t_align"/>
+    <constant name="final_z2t" value="mod2_z2t+z2t_align"/>
+    <constant name="final_z3t" value="mod2_z3t+z3t_align"/>
+    <constant name="final_z4t" value="mod2_z4t+z4t_align"/>
+    <constant name="final_z5t" value="mod2_z5t+z5t_align"/>
+    <constant name="final_z6t" value="mod2_z6t+z6t_align"/>
+    <constant name="final_z7t" value="mod2_z7t+z7t_align"/>
+    <constant name="final_z8t" value="mod2_z8t+z8t_align"/>
+    <constant name="final_z9t" value="mod2_z9t+z9t_align"/>
+    <constant name="final_z10t" value="mod2_z10t+z10t_align"/>
+    <constant name="final_rx1t" value="mod2_rx1t+rx1t_align"/>
+    <constant name="final_rx2t" value="mod2_rx2t+rx2t_align"/>
+    <constant name="final_rx3t" value="mod2_rx3t+rx3t_align"/>
+    <constant name="final_rx4t" value="mod2_rx4t+rx4t_align"/>
+    <constant name="final_rx5t" value="mod2_rx5t+rx5t_align"/>
+    <constant name="final_rx6t" value="mod2_rx6t+rx6t_align"/>
+    <constant name="final_rx7t" value="mod2_rx7t+rx7t_align"/>
+    <constant name="final_rx8t" value="mod2_rx8t+rx8t_align"/>
+    <constant name="final_rx9t" value="mod2_rx9t+rx9t_align"/>
+    <constant name="final_rx10t" value="mod2_rx10t+rx10t_align"/>
+    <constant name="final_ry1t" value="mod2_ry1t+ry1t_align"/>
+    <constant name="final_ry2t" value="mod2_ry2t+ry2t_align"/>
+    <constant name="final_ry3t" value="mod2_ry3t+ry3t_align"/>
+    <constant name="final_ry4t" value="mod2_ry4t+ry4t_align"/>
+    <constant name="final_ry5t" value="mod2_ry5t+ry5t_align"/>
+    <constant name="final_ry6t" value="mod2_ry6t+ry6t_align"/>
+    <constant name="final_ry7t" value="mod2_ry7t+ry7t_align"/>
+    <constant name="final_ry8t" value="mod2_ry8t+ry8t_align"/>
+    <constant name="final_ry9t" value="mod2_ry9t+ry9t_align"/>
+    <constant name="final_ry10t" value="mod2_ry10t+ry10t_align"/>
+    <constant name="final_rz1t" value="mod2_rz1t+rz1t_align"/>
+    <constant name="final_rz2t" value="mod2_rz2t+rz2t_align"/>
+    <constant name="final_rz3t" value="mod2_rz3t+rz3t_align"/>
+    <constant name="final_rz4t" value="mod2_rz4t+rz4t_align"/>
+    <constant name="final_rz5t" value="mod2_rz5t+rz5t_align"/>
+    <constant name="final_rz6t" value="mod2_rz6t+rz6t_align"/>
+    <constant name="final_rz7t" value="mod2_rz7t+rz7t_align"/>
+    <constant name="final_rz8t" value="mod2_rz8t+rz8t_align"/>
+    <constant name="final_rz9t" value="mod2_rz9t+rz9t_align"/>
+    <constant name="final_rz10t" value="mod2_rz10t+rz10t_align"/>
+    <constant name="final_x1b" value="mod2_x1b+x1b_align"/>
+    <constant name="final_x2b" value="mod2_x2b+x2b_align"/>
+    <constant name="final_x3b" value="mod2_x3b+x3b_align"/>
+    <constant name="final_x4b" value="mod2_x4b+x4b_align"/>
+    <constant name="final_x5b" value="mod2_x5b+x5b_align"/>
+    <constant name="final_x6b" value="mod2_x6b+x6b_align"/>
+    <constant name="final_x7b" value="mod2_x7b+x7b_align"/>
+    <constant name="final_x8b" value="mod2_x8b+x8b_align"/>
+    <constant name="final_x9b" value="mod2_x9b+x9b_align"/>
+    <constant name="final_x10b" value="mod2_x10b+x10b_align"/>
+    <constant name="final_y1b" value="mod2_y1b+y1b_align"/>
+    <constant name="final_y2b" value="mod2_y2b+y2b_align"/>
+    <constant name="final_y3b" value="mod2_y3b+y3b_align"/>
+    <constant name="final_y4b" value="mod2_y4b+y4b_align"/>
+    <constant name="final_y5b" value="mod2_y5b+y5b_align"/>
+    <constant name="final_y6b" value="mod2_y6b+y6b_align"/>
+    <constant name="final_y7b" value="mod2_y7b+y7b_align"/>
+    <constant name="final_y8b" value="mod2_y8b+y8b_align"/>
+    <constant name="final_y9b" value="mod2_y9b+y9b_align"/>
+    <constant name="final_y10b" value="mod2_y10b+y10b_align"/>
+    <constant name="final_z1b" value="mod2_z1b+z1b_align"/>
+    <constant name="final_z2b" value="mod2_z2b+z2b_align"/>
+    <constant name="final_z3b" value="mod2_z3b+z3b_align"/>
+    <constant name="final_z4b" value="mod2_z4b+z4b_align"/>
+    <constant name="final_z5b" value="mod2_z5b+z5b_align"/>
+    <constant name="final_z6b" value="mod2_z6b+z6b_align"/>
+    <constant name="final_z7b" value="mod2_z7b+z7b_align"/>
+    <constant name="final_z8b" value="mod2_z8b+z8b_align"/>
+    <constant name="final_z9b" value="mod2_z9b+z9b_align"/>
+    <constant name="final_z10b" value="mod2_z10b+z10b_align"/>
+    <constant name="final_rx1b" value="mod2_rx1b+rx1b_align"/>
+    <constant name="final_rx2b" value="mod2_rx2b+rx2b_align"/>
+    <constant name="final_rx3b" value="mod2_rx3b+rx3b_align"/>
+    <constant name="final_rx4b" value="mod2_rx4b+rx4b_align"/>
+    <constant name="final_rx5b" value="mod2_rx5b+rx5b_align"/>
+    <constant name="final_rx6b" value="mod2_rx6b+rx6b_align"/>
+    <constant name="final_rx7b" value="mod2_rx7b+rx7b_align"/>
+    <constant name="final_rx8b" value="mod2_rx8b+rx8b_align"/>
+    <constant name="final_rx9b" value="mod2_rx9b+rx9b_align"/>
+    <constant name="final_rx10b" value="mod2_rx10b+rx10b_align"/>
+    <constant name="final_ry1b" value="mod2_ry1b+ry1b_align"/>
+    <constant name="final_ry2b" value="mod2_ry2b+ry2b_align"/>
+    <constant name="final_ry3b" value="mod2_ry3b+ry3b_align"/>
+    <constant name="final_ry4b" value="mod2_ry4b+ry4b_align"/>
+    <constant name="final_ry5b" value="mod2_ry5b+ry5b_align"/>
+    <constant name="final_ry6b" value="mod2_ry6b+ry6b_align"/>
+    <constant name="final_ry7b" value="mod2_ry7b+ry7b_align"/>
+    <constant name="final_ry8b" value="mod2_ry8b+ry8b_align"/>
+    <constant name="final_ry9b" value="mod2_ry9b+ry9b_align"/>
+    <constant name="final_ry10b" value="mod2_ry10b+ry10b_align"/>
+    <constant name="final_rz1b" value="mod2_rz1b+rz1b_align"/>
+    <constant name="final_rz2b" value="mod2_rz2b+rz2b_align"/>
+    <constant name="final_rz3b" value="mod2_rz3b+rz3b_align"/>
+    <constant name="final_rz4b" value="mod2_rz4b+rz4b_align"/>
+    <constant name="final_rz5b" value="mod2_rz5b+rz5b_align"/>
+    <constant name="final_rz6b" value="mod2_rz6b+rz6b_align"/>
+    <constant name="final_rz7b" value="mod2_rz7b+rz7b_align"/>
+    <constant name="final_rz8b" value="mod2_rz8b+rz8b_align"/>
+    <constant name="final_rz9b" value="mod2_rz9b+rz9b_align"/>
+    <constant name="final_rz10b" value="mod2_rz10b+rz10b_align"/>
+        
+        
     </define>
     
     <materials>      
-    	<!-- Set the world material to vacuum. -->
+        <!-- Set the world material to vacuum. -->
         <material name="WorldMaterial">
             <D type="density" unit="g/cm3" value="0.0000000000000001"/>
             <fraction n="1.0" ref="Vacuum" />
@@ -822,7 +822,7 @@
             </layer>
             <layer id="2">
                 <module_placement name="TestRunModuleFieldDef" id="0" x="0" y="0" z="dipoleMagnetPositionZ+dipoleMagnetLength/2" rx="0" ry="0" rz="-PI/2"/>
-			</layer>
+            </layer>
         </detector>     
         
         <detector id="13" name="Ecal" type="HPSEcal3" insideTrackingVolume="false" readout="EcalHits" vis="ECALVis">

Modified: java/branches/HPSJAVA-409/detector-data/detectors/HPS-TestRun-v7-3/compact.xml
 =============================================================================
--- java/branches/HPSJAVA-409/detector-data/detectors/HPS-TestRun-v7-3/compact.xml	(original)
+++ java/branches/HPSJAVA-409/detector-data/detectors/HPS-TestRun-v7-3/compact.xml	Wed Apr 27 11:11:32 2016
@@ -84,127 +84,127 @@
         <constant name="y9b_misalign" value="0.0" />
         <constant name="y10b_misalign" value="0.0" />
 
-		<!-- alignment corrections -->
-	<constant name="x1t_align" value="0.000000" />
-	<constant name="x2t_align" value="-0.000000" />
-	<constant name="x3t_align" value="-0.000012" />
-	<constant name="x4t_align" value="-0.017488" />
-	<constant name="x5t_align" value="-0.000064" />
-	<constant name="x6t_align" value="-0.000141" />
-	<constant name="x7t_align" value="0.000002" />
-	<constant name="x8t_align" value="0.000573" />
-	<constant name="x9t_align" value="0.000000" />
-	<constant name="x10t_align" value="-0.000000" />
-	<constant name="y1t_align" value="0.000000" />
-	<constant name="y2t_align" value="0.000000" />
-	<constant name="y3t_align" value="-0.094679" />
-	<constant name="y4t_align" value="-0.174440" />
-	<constant name="y5t_align" value="0.118670" />
-	<constant name="y6t_align" value="-0.001400" />
-	<constant name="y7t_align" value="0.047526" />
-	<constant name="y8t_align" value="0.011511" />
-	<constant name="y9t_align" value="0.000000" />
-	<constant name="y10t_align" value="0.000000" />
-	<constant name="z1t_align" value="0.000000" />
-	<constant name="z2t_align" value="0.000000" />
-	<constant name="z3t_align" value="-0.002463" />
-	<constant name="z4t_align" value="-0.003986" />
-	<constant name="z5t_align" value="0.003089" />
-	<constant name="z6t_align" value="-0.000032" />
-	<constant name="z7t_align" value="0.001236" />
-	<constant name="z8t_align" value="0.000281" />
-	<constant name="z9t_align" value="0.000000" />
-	<constant name="z10t_align" value="0.000000" />
-	<constant name="rx1t_align" value="0.000000" />
-	<constant name="rx2t_align" value="-0.000000" />
-	<constant name="rx3t_align" value="0.000000" />
-	<constant name="rx4t_align" value="-0.000000" />
-	<constant name="rx5t_align" value="0.000000" />
-	<constant name="rx6t_align" value="-0.000000" />
-	<constant name="rx7t_align" value="0.000000" />
-	<constant name="rx8t_align" value="-0.000000" />
-	<constant name="rx9t_align" value="0.000000" />
-	<constant name="rx10t_align" value="-0.000000" />
-	<constant name="ry1t_align" value="0.000000" />
-	<constant name="ry2t_align" value="0.000000" />
-	<constant name="ry3t_align" value="0.000000" />
-	<constant name="ry4t_align" value="0.000000" />
-	<constant name="ry5t_align" value="0.000000" />
-	<constant name="ry6t_align" value="0.000000" />
-	<constant name="ry7t_align" value="0.000000" />
-	<constant name="ry8t_align" value="0.000000" />
-	<constant name="ry9t_align" value="0.000000" />
-	<constant name="ry10t_align" value="0.000000" />
-	<constant name="rz1t_align" value="0.000000" />
-	<constant name="rz2t_align" value="0.000000" />
-	<constant name="rz3t_align" value="0.000000" />
-	<constant name="rz4t_align" value="0.000000" />
-	<constant name="rz5t_align" value="0.000000" />
-	<constant name="rz6t_align" value="0.000000" />
-	<constant name="rz7t_align" value="0.000000" />
-	<constant name="rz8t_align" value="0.000000" />
-	<constant name="rz9t_align" value="0.000000" />
-	<constant name="rz10t_align" value="0.000000" />
-	<constant name="x1b_align" value="0.000000" />
-	<constant name="x2b_align" value="-0.000000" />
-	<constant name="x3b_align" value="-0.068351" />
-	<constant name="x4b_align" value="0.000012" />
-	<constant name="x5b_align" value="-0.100385" />
-	<constant name="x6b_align" value="0.000012" />
-	<constant name="x7b_align" value="-0.025606" />
-	<constant name="x8b_align" value="0.000007" />
-	<constant name="x9b_align" value="0.000000" />
-	<constant name="x10b_align" value="-0.000000" />
-	<constant name="y1b_align" value="0.000000" />
-	<constant name="y2b_align" value="0.000000" />
-	<constant name="y3b_align" value="0.681109" />
-	<constant name="y4b_align" value="0.061551" />
-	<constant name="y5b_align" value="1.004204" />
-	<constant name="y6b_align" value="0.037831" />
-	<constant name="y7b_align" value="0.506463" />
-	<constant name="y8b_align" value="0.015775" />
-	<constant name="y9b_align" value="0.000000" />
-	<constant name="y10b_align" value="0.000000" />
-	<constant name="z1b_align" value="0.000000" />
-	<constant name="z2b_align" value="0.000000" />
-	<constant name="z3b_align" value="-0.013322" />
-	<constant name="z4b_align" value="-0.001371" />
-	<constant name="z5b_align" value="-0.019651" />
-	<constant name="z6b_align" value="-0.000843" />
-	<constant name="z7b_align" value="-0.010587" />
-	<constant name="z8b_align" value="-0.000352" />
-	<constant name="z9b_align" value="0.000000" />
-	<constant name="z10b_align" value="0.000000" />
-	<constant name="rx1b_align" value="0.000000" />
-	<constant name="rx2b_align" value="-0.000000" />
-	<constant name="rx3b_align" value="0.000000" />
-	<constant name="rx4b_align" value="-0.000000" />
-	<constant name="rx5b_align" value="0.000000" />
-	<constant name="rx6b_align" value="-0.000000" />
-	<constant name="rx7b_align" value="0.000000" />
-	<constant name="rx8b_align" value="-0.000000" />
-	<constant name="rx9b_align" value="0.000000" />
-	<constant name="rx10b_align" value="-0.000000" />
-	<constant name="ry1b_align" value="0.000000" />
-	<constant name="ry2b_align" value="0.000000" />
-	<constant name="ry3b_align" value="0.000000" />
-	<constant name="ry4b_align" value="0.000000" />
-	<constant name="ry5b_align" value="0.000000" />
-	<constant name="ry6b_align" value="0.000000" />
-	<constant name="ry7b_align" value="0.000000" />
-	<constant name="ry8b_align" value="0.000000" />
-	<constant name="ry9b_align" value="0.000000" />
-	<constant name="ry10b_align" value="0.000000" />
-	<constant name="rz1b_align" value="0.000000" />
-	<constant name="rz2b_align" value="0.000000" />
-	<constant name="rz3b_align" value="0.000000" />
-	<constant name="rz4b_align" value="0.000000" />
-	<constant name="rz5b_align" value="0.000000" />
-	<constant name="rz6b_align" value="0.000000" />
-	<constant name="rz7b_align" value="0.000000" />
-	<constant name="rz8b_align" value="0.000000" />
-	<constant name="rz9b_align" value="0.000000" />
-	<constant name="rz10b_align" value="0.000000" />
+        <!-- alignment corrections -->
+    <constant name="x1t_align" value="0.000000" />
+    <constant name="x2t_align" value="-0.000000" />
+    <constant name="x3t_align" value="-0.000012" />
+    <constant name="x4t_align" value="-0.017488" />
+    <constant name="x5t_align" value="-0.000064" />
+    <constant name="x6t_align" value="-0.000141" />
+    <constant name="x7t_align" value="0.000002" />
+    <constant name="x8t_align" value="0.000573" />
+    <constant name="x9t_align" value="0.000000" />
+    <constant name="x10t_align" value="-0.000000" />
+    <constant name="y1t_align" value="0.000000" />
+    <constant name="y2t_align" value="0.000000" />
+    <constant name="y3t_align" value="-0.094679" />
+    <constant name="y4t_align" value="-0.174440" />
+    <constant name="y5t_align" value="0.118670" />
+    <constant name="y6t_align" value="-0.001400" />
+    <constant name="y7t_align" value="0.047526" />
+    <constant name="y8t_align" value="0.011511" />
+    <constant name="y9t_align" value="0.000000" />
+    <constant name="y10t_align" value="0.000000" />
+    <constant name="z1t_align" value="0.000000" />
+    <constant name="z2t_align" value="0.000000" />
+    <constant name="z3t_align" value="-0.002463" />
+    <constant name="z4t_align" value="-0.003986" />
+    <constant name="z5t_align" value="0.003089" />
+    <constant name="z6t_align" value="-0.000032" />
+    <constant name="z7t_align" value="0.001236" />
+    <constant name="z8t_align" value="0.000281" />
+    <constant name="z9t_align" value="0.000000" />
+    <constant name="z10t_align" value="0.000000" />
+    <constant name="rx1t_align" value="0.000000" />
+    <constant name="rx2t_align" value="-0.000000" />
+    <constant name="rx3t_align" value="0.000000" />
+    <constant name="rx4t_align" value="-0.000000" />
+    <constant name="rx5t_align" value="0.000000" />
+    <constant name="rx6t_align" value="-0.000000" />
+    <constant name="rx7t_align" value="0.000000" />
+    <constant name="rx8t_align" value="-0.000000" />
+    <constant name="rx9t_align" value="0.000000" />
+    <constant name="rx10t_align" value="-0.000000" />
+    <constant name="ry1t_align" value="0.000000" />
+    <constant name="ry2t_align" value="0.000000" />
+    <constant name="ry3t_align" value="0.000000" />
+    <constant name="ry4t_align" value="0.000000" />
+    <constant name="ry5t_align" value="0.000000" />
+    <constant name="ry6t_align" value="0.000000" />
+    <constant name="ry7t_align" value="0.000000" />
+    <constant name="ry8t_align" value="0.000000" />
+    <constant name="ry9t_align" value="0.000000" />
+    <constant name="ry10t_align" value="0.000000" />
+    <constant name="rz1t_align" value="0.000000" />
+    <constant name="rz2t_align" value="0.000000" />
+    <constant name="rz3t_align" value="0.000000" />
+    <constant name="rz4t_align" value="0.000000" />
+    <constant name="rz5t_align" value="0.000000" />
+    <constant name="rz6t_align" value="0.000000" />
+    <constant name="rz7t_align" value="0.000000" />
+    <constant name="rz8t_align" value="0.000000" />
+    <constant name="rz9t_align" value="0.000000" />
+    <constant name="rz10t_align" value="0.000000" />
+    <constant name="x1b_align" value="0.000000" />
+    <constant name="x2b_align" value="-0.000000" />
+    <constant name="x3b_align" value="-0.068351" />
+    <constant name="x4b_align" value="0.000012" />
+    <constant name="x5b_align" value="-0.100385" />
+    <constant name="x6b_align" value="0.000012" />
+    <constant name="x7b_align" value="-0.025606" />
+    <constant name="x8b_align" value="0.000007" />
+    <constant name="x9b_align" value="0.000000" />
+    <constant name="x10b_align" value="-0.000000" />
+    <constant name="y1b_align" value="0.000000" />
+    <constant name="y2b_align" value="0.000000" />
+    <constant name="y3b_align" value="0.681109" />
+    <constant name="y4b_align" value="0.061551" />
+    <constant name="y5b_align" value="1.004204" />
+    <constant name="y6b_align" value="0.037831" />
+    <constant name="y7b_align" value="0.506463" />
+    <constant name="y8b_align" value="0.015775" />
+    <constant name="y9b_align" value="0.000000" />
+    <constant name="y10b_align" value="0.000000" />
+    <constant name="z1b_align" value="0.000000" />
+    <constant name="z2b_align" value="0.000000" />
+    <constant name="z3b_align" value="-0.013322" />
+    <constant name="z4b_align" value="-0.001371" />
+    <constant name="z5b_align" value="-0.019651" />
+    <constant name="z6b_align" value="-0.000843" />
+    <constant name="z7b_align" value="-0.010587" />
+    <constant name="z8b_align" value="-0.000352" />
+    <constant name="z9b_align" value="0.000000" />
+    <constant name="z10b_align" value="0.000000" />
+    <constant name="rx1b_align" value="0.000000" />
+    <constant name="rx2b_align" value="-0.000000" />
+    <constant name="rx3b_align" value="0.000000" />
+    <constant name="rx4b_align" value="-0.000000" />
+    <constant name="rx5b_align" value="0.000000" />
+    <constant name="rx6b_align" value="-0.000000" />
+    <constant name="rx7b_align" value="0.000000" />
+    <constant name="rx8b_align" value="-0.000000" />
+    <constant name="rx9b_align" value="0.000000" />
+    <constant name="rx10b_align" value="-0.000000" />
+    <constant name="ry1b_align" value="0.000000" />
+    <constant name="ry2b_align" value="0.000000" />
+    <constant name="ry3b_align" value="0.000000" />
+    <constant name="ry4b_align" value="0.000000" />
+    <constant name="ry5b_align" value="0.000000" />
+    <constant name="ry6b_align" value="0.000000" />
+    <constant name="ry7b_align" value="0.000000" />
+    <constant name="ry8b_align" value="0.000000" />
+    <constant name="ry9b_align" value="0.000000" />
+    <constant name="ry10b_align" value="0.000000" />
+    <constant name="rz1b_align" value="0.000000" />
+    <constant name="rz2b_align" value="0.000000" />
+    <constant name="rz3b_align" value="0.000000" />
+    <constant name="rz4b_align" value="0.000000" />
+    <constant name="rz5b_align" value="0.000000" />
+    <constant name="rz6b_align" value="0.000000" />
+    <constant name="rz7b_align" value="0.000000" />
+    <constant name="rz8b_align" value="0.000000" />
+    <constant name="rz9b_align" value="0.000000" />
+    <constant name="rz10b_align" value="0.000000" />
 
         <!-- Positions of sensor centers above/below nominal beam -->
         <constant name="y1t" value="36.894" />
@@ -604,134 +604,134 @@
         <constant name="mod2_rx10b" value="mod_rx10b" />
         <constant name="mod2_ry10b" value="mod_ry10b+y_rot_bot_pivot" />
         <constant name="mod2_rz10b" value="mod_rz10b" />
-    	
-    	<!-- final constants -->
-	<constant name="final_x1t" value="mod2_x1t+x1t_align" />
-	<constant name="final_x2t" value="mod2_x2t+x2t_align" />
-	<constant name="final_x3t" value="mod2_x3t+x3t_align" />
-	<constant name="final_x4t" value="mod2_x4t+x4t_align" />
-	<constant name="final_x5t" value="mod2_x5t+x5t_align" />
-	<constant name="final_x6t" value="mod2_x6t+x6t_align" />
-	<constant name="final_x7t" value="mod2_x7t+x7t_align" />
-	<constant name="final_x8t" value="mod2_x8t+x8t_align" />
-	<constant name="final_x9t" value="mod2_x9t+x9t_align" />
-	<constant name="final_x10t" value="mod2_x10t+x10t_align" />
-	<constant name="final_y1t" value="mod2_y1t+y1t_align" />
-	<constant name="final_y2t" value="mod2_y2t+y2t_align" />
-	<constant name="final_y3t" value="mod2_y3t+y3t_align" />
-	<constant name="final_y4t" value="mod2_y4t+y4t_align" />
-	<constant name="final_y5t" value="mod2_y5t+y5t_align" />
-	<constant name="final_y6t" value="mod2_y6t+y6t_align" />
-	<constant name="final_y7t" value="mod2_y7t+y7t_align" />
-	<constant name="final_y8t" value="mod2_y8t+y8t_align" />
-	<constant name="final_y9t" value="mod2_y9t+y9t_align" />
-	<constant name="final_y10t" value="mod2_y10t+y10t_align" />
-	<constant name="final_z1t" value="mod2_z1t+z1t_align" />
-	<constant name="final_z2t" value="mod2_z2t+z2t_align" />
-	<constant name="final_z3t" value="mod2_z3t+z3t_align" />
-	<constant name="final_z4t" value="mod2_z4t+z4t_align" />
-	<constant name="final_z5t" value="mod2_z5t+z5t_align" />
-	<constant name="final_z6t" value="mod2_z6t+z6t_align" />
-	<constant name="final_z7t" value="mod2_z7t+z7t_align" />
-	<constant name="final_z8t" value="mod2_z8t+z8t_align" />
-	<constant name="final_z9t" value="mod2_z9t+z9t_align" />
-	<constant name="final_z10t" value="mod2_z10t+z10t_align" />
-	<constant name="final_rx1t" value="mod2_rx1t+rx1t_align" />
-	<constant name="final_rx2t" value="mod2_rx2t+rx2t_align" />
-	<constant name="final_rx3t" value="mod2_rx3t+rx3t_align" />
-	<constant name="final_rx4t" value="mod2_rx4t+rx4t_align" />
-	<constant name="final_rx5t" value="mod2_rx5t+rx5t_align" />
-	<constant name="final_rx6t" value="mod2_rx6t+rx6t_align" />
-	<constant name="final_rx7t" value="mod2_rx7t+rx7t_align" />
-	<constant name="final_rx8t" value="mod2_rx8t+rx8t_align" />
-	<constant name="final_rx9t" value="mod2_rx9t+rx9t_align" />
-	<constant name="final_rx10t" value="mod2_rx10t+rx10t_align" />
-	<constant name="final_ry1t" value="mod2_ry1t+ry1t_align" />
-	<constant name="final_ry2t" value="mod2_ry2t+ry2t_align" />
-	<constant name="final_ry3t" value="mod2_ry3t+ry3t_align" />
-	<constant name="final_ry4t" value="mod2_ry4t+ry4t_align" />
-	<constant name="final_ry5t" value="mod2_ry5t+ry5t_align" />
-	<constant name="final_ry6t" value="mod2_ry6t+ry6t_align" />
-	<constant name="final_ry7t" value="mod2_ry7t+ry7t_align" />
-	<constant name="final_ry8t" value="mod2_ry8t+ry8t_align" />
-	<constant name="final_ry9t" value="mod2_ry9t+ry9t_align" />
-	<constant name="final_ry10t" value="mod2_ry10t+ry10t_align" />
-	<constant name="final_rz1t" value="mod2_rz1t+rz1t_align" />
-	<constant name="final_rz2t" value="mod2_rz2t+rz2t_align" />
-	<constant name="final_rz3t" value="mod2_rz3t+rz3t_align" />
-	<constant name="final_rz4t" value="mod2_rz4t+rz4t_align" />
-	<constant name="final_rz5t" value="mod2_rz5t+rz5t_align" />
-	<constant name="final_rz6t" value="mod2_rz6t+rz6t_align" />
-	<constant name="final_rz7t" value="mod2_rz7t+rz7t_align" />
-	<constant name="final_rz8t" value="mod2_rz8t+rz8t_align" />
-	<constant name="final_rz9t" value="mod2_rz9t+rz9t_align" />
-	<constant name="final_rz10t" value="mod2_rz10t+rz10t_align" />
-	<constant name="final_x1b" value="mod2_x1b+x1b_align" />
-	<constant name="final_x2b" value="mod2_x2b+x2b_align" />
-	<constant name="final_x3b" value="mod2_x3b+x3b_align" />
-	<constant name="final_x4b" value="mod2_x4b+x4b_align" />
-	<constant name="final_x5b" value="mod2_x5b+x5b_align" />
-	<constant name="final_x6b" value="mod2_x6b+x6b_align" />
-	<constant name="final_x7b" value="mod2_x7b+x7b_align" />
-	<constant name="final_x8b" value="mod2_x8b+x8b_align" />
-	<constant name="final_x9b" value="mod2_x9b+x9b_align" />
-	<constant name="final_x10b" value="mod2_x10b+x10b_align" />
-	<constant name="final_y1b" value="mod2_y1b+y1b_align" />
-	<constant name="final_y2b" value="mod2_y2b+y2b_align" />
-	<constant name="final_y3b" value="mod2_y3b+y3b_align" />
-	<constant name="final_y4b" value="mod2_y4b+y4b_align" />
-	<constant name="final_y5b" value="mod2_y5b+y5b_align" />
-	<constant name="final_y6b" value="mod2_y6b+y6b_align" />
-	<constant name="final_y7b" value="mod2_y7b+y7b_align" />
-	<constant name="final_y8b" value="mod2_y8b+y8b_align" />
-	<constant name="final_y9b" value="mod2_y9b+y9b_align" />
-	<constant name="final_y10b" value="mod2_y10b+y10b_align" />
-	<constant name="final_z1b" value="mod2_z1b+z1b_align" />
-	<constant name="final_z2b" value="mod2_z2b+z2b_align" />
-	<constant name="final_z3b" value="mod2_z3b+z3b_align" />
-	<constant name="final_z4b" value="mod2_z4b+z4b_align" />
-	<constant name="final_z5b" value="mod2_z5b+z5b_align" />
-	<constant name="final_z6b" value="mod2_z6b+z6b_align" />
-	<constant name="final_z7b" value="mod2_z7b+z7b_align" />
-	<constant name="final_z8b" value="mod2_z8b+z8b_align" />
-	<constant name="final_z9b" value="mod2_z9b+z9b_align" />
-	<constant name="final_z10b" value="mod2_z10b+z10b_align" />
-	<constant name="final_rx1b" value="mod2_rx1b+rx1b_align" />
-	<constant name="final_rx2b" value="mod2_rx2b+rx2b_align" />
-	<constant name="final_rx3b" value="mod2_rx3b+rx3b_align" />
-	<constant name="final_rx4b" value="mod2_rx4b+rx4b_align" />
-	<constant name="final_rx5b" value="mod2_rx5b+rx5b_align" />
-	<constant name="final_rx6b" value="mod2_rx6b+rx6b_align" />
-	<constant name="final_rx7b" value="mod2_rx7b+rx7b_align" />
-	<constant name="final_rx8b" value="mod2_rx8b+rx8b_align" />
-	<constant name="final_rx9b" value="mod2_rx9b+rx9b_align" />
-	<constant name="final_rx10b" value="mod2_rx10b+rx10b_align" />
-	<constant name="final_ry1b" value="mod2_ry1b+ry1b_align" />
-	<constant name="final_ry2b" value="mod2_ry2b+ry2b_align" />
-	<constant name="final_ry3b" value="mod2_ry3b+ry3b_align" />
-	<constant name="final_ry4b" value="mod2_ry4b+ry4b_align" />
-	<constant name="final_ry5b" value="mod2_ry5b+ry5b_align" />
-	<constant name="final_ry6b" value="mod2_ry6b+ry6b_align" />
-	<constant name="final_ry7b" value="mod2_ry7b+ry7b_align" />
-	<constant name="final_ry8b" value="mod2_ry8b+ry8b_align" />
-	<constant name="final_ry9b" value="mod2_ry9b+ry9b_align" />
-	<constant name="final_ry10b" value="mod2_ry10b+ry10b_align" />
-	<constant name="final_rz1b" value="mod2_rz1b+rz1b_align" />
-	<constant name="final_rz2b" value="mod2_rz2b+rz2b_align" />
-	<constant name="final_rz3b" value="mod2_rz3b+rz3b_align" />
-	<constant name="final_rz4b" value="mod2_rz4b+rz4b_align" />
-	<constant name="final_rz5b" value="mod2_rz5b+rz5b_align" />
-	<constant name="final_rz6b" value="mod2_rz6b+rz6b_align" />
-	<constant name="final_rz7b" value="mod2_rz7b+rz7b_align" />
-	<constant name="final_rz8b" value="mod2_rz8b+rz8b_align" />
-	<constant name="final_rz9b" value="mod2_rz9b+rz9b_align" />
-	<constant name="final_rz10b" value="mod2_rz10b+rz10b_align" />
-    	
-    	
+        
+        <!-- final constants -->
+    <constant name="final_x1t" value="mod2_x1t+x1t_align" />
+    <constant name="final_x2t" value="mod2_x2t+x2t_align" />
+    <constant name="final_x3t" value="mod2_x3t+x3t_align" />
+    <constant name="final_x4t" value="mod2_x4t+x4t_align" />
+    <constant name="final_x5t" value="mod2_x5t+x5t_align" />
+    <constant name="final_x6t" value="mod2_x6t+x6t_align" />
+    <constant name="final_x7t" value="mod2_x7t+x7t_align" />
+    <constant name="final_x8t" value="mod2_x8t+x8t_align" />
+    <constant name="final_x9t" value="mod2_x9t+x9t_align" />
+    <constant name="final_x10t" value="mod2_x10t+x10t_align" />
+    <constant name="final_y1t" value="mod2_y1t+y1t_align" />
+    <constant name="final_y2t" value="mod2_y2t+y2t_align" />
+    <constant name="final_y3t" value="mod2_y3t+y3t_align" />
+    <constant name="final_y4t" value="mod2_y4t+y4t_align" />
+    <constant name="final_y5t" value="mod2_y5t+y5t_align" />
+    <constant name="final_y6t" value="mod2_y6t+y6t_align" />
+    <constant name="final_y7t" value="mod2_y7t+y7t_align" />
+    <constant name="final_y8t" value="mod2_y8t+y8t_align" />
+    <constant name="final_y9t" value="mod2_y9t+y9t_align" />
+    <constant name="final_y10t" value="mod2_y10t+y10t_align" />
+    <constant name="final_z1t" value="mod2_z1t+z1t_align" />
+    <constant name="final_z2t" value="mod2_z2t+z2t_align" />
+    <constant name="final_z3t" value="mod2_z3t+z3t_align" />
+    <constant name="final_z4t" value="mod2_z4t+z4t_align" />
+    <constant name="final_z5t" value="mod2_z5t+z5t_align" />
+    <constant name="final_z6t" value="mod2_z6t+z6t_align" />
+    <constant name="final_z7t" value="mod2_z7t+z7t_align" />
+    <constant name="final_z8t" value="mod2_z8t+z8t_align" />
+    <constant name="final_z9t" value="mod2_z9t+z9t_align" />
+    <constant name="final_z10t" value="mod2_z10t+z10t_align" />
+    <constant name="final_rx1t" value="mod2_rx1t+rx1t_align" />
+    <constant name="final_rx2t" value="mod2_rx2t+rx2t_align" />
+    <constant name="final_rx3t" value="mod2_rx3t+rx3t_align" />
+    <constant name="final_rx4t" value="mod2_rx4t+rx4t_align" />
+    <constant name="final_rx5t" value="mod2_rx5t+rx5t_align" />
+    <constant name="final_rx6t" value="mod2_rx6t+rx6t_align" />
+    <constant name="final_rx7t" value="mod2_rx7t+rx7t_align" />
+    <constant name="final_rx8t" value="mod2_rx8t+rx8t_align" />
+    <constant name="final_rx9t" value="mod2_rx9t+rx9t_align" />
+    <constant name="final_rx10t" value="mod2_rx10t+rx10t_align" />
+    <constant name="final_ry1t" value="mod2_ry1t+ry1t_align" />
+    <constant name="final_ry2t" value="mod2_ry2t+ry2t_align" />
+    <constant name="final_ry3t" value="mod2_ry3t+ry3t_align" />
+    <constant name="final_ry4t" value="mod2_ry4t+ry4t_align" />
+    <constant name="final_ry5t" value="mod2_ry5t+ry5t_align" />
+    <constant name="final_ry6t" value="mod2_ry6t+ry6t_align" />
+    <constant name="final_ry7t" value="mod2_ry7t+ry7t_align" />
+    <constant name="final_ry8t" value="mod2_ry8t+ry8t_align" />
+    <constant name="final_ry9t" value="mod2_ry9t+ry9t_align" />
+    <constant name="final_ry10t" value="mod2_ry10t+ry10t_align" />
+    <constant name="final_rz1t" value="mod2_rz1t+rz1t_align" />
+    <constant name="final_rz2t" value="mod2_rz2t+rz2t_align" />
+    <constant name="final_rz3t" value="mod2_rz3t+rz3t_align" />
+    <constant name="final_rz4t" value="mod2_rz4t+rz4t_align" />
+    <constant name="final_rz5t" value="mod2_rz5t+rz5t_align" />
+    <constant name="final_rz6t" value="mod2_rz6t+rz6t_align" />
+    <constant name="final_rz7t" value="mod2_rz7t+rz7t_align" />
+    <constant name="final_rz8t" value="mod2_rz8t+rz8t_align" />
+    <constant name="final_rz9t" value="mod2_rz9t+rz9t_align" />
+    <constant name="final_rz10t" value="mod2_rz10t+rz10t_align" />
+    <constant name="final_x1b" value="mod2_x1b+x1b_align" />
+    <constant name="final_x2b" value="mod2_x2b+x2b_align" />
+    <constant name="final_x3b" value="mod2_x3b+x3b_align" />
+    <constant name="final_x4b" value="mod2_x4b+x4b_align" />
+    <constant name="final_x5b" value="mod2_x5b+x5b_align" />
+    <constant name="final_x6b" value="mod2_x6b+x6b_align" />
+    <constant name="final_x7b" value="mod2_x7b+x7b_align" />
+    <constant name="final_x8b" value="mod2_x8b+x8b_align" />
+    <constant name="final_x9b" value="mod2_x9b+x9b_align" />
+    <constant name="final_x10b" value="mod2_x10b+x10b_align" />
+    <constant name="final_y1b" value="mod2_y1b+y1b_align" />
+    <constant name="final_y2b" value="mod2_y2b+y2b_align" />
+    <constant name="final_y3b" value="mod2_y3b+y3b_align" />
+    <constant name="final_y4b" value="mod2_y4b+y4b_align" />
+    <constant name="final_y5b" value="mod2_y5b+y5b_align" />
+    <constant name="final_y6b" value="mod2_y6b+y6b_align" />
+    <constant name="final_y7b" value="mod2_y7b+y7b_align" />
+    <constant name="final_y8b" value="mod2_y8b+y8b_align" />
+    <constant name="final_y9b" value="mod2_y9b+y9b_align" />
+    <constant name="final_y10b" value="mod2_y10b+y10b_align" />
+    <constant name="final_z1b" value="mod2_z1b+z1b_align" />
+    <constant name="final_z2b" value="mod2_z2b+z2b_align" />
+    <constant name="final_z3b" value="mod2_z3b+z3b_align" />
+    <constant name="final_z4b" value="mod2_z4b+z4b_align" />
+    <constant name="final_z5b" value="mod2_z5b+z5b_align" />
+    <constant name="final_z6b" value="mod2_z6b+z6b_align" />
+    <constant name="final_z7b" value="mod2_z7b+z7b_align" />
+    <constant name="final_z8b" value="mod2_z8b+z8b_align" />
+    <constant name="final_z9b" value="mod2_z9b+z9b_align" />
+    <constant name="final_z10b" value="mod2_z10b+z10b_align" />
+    <constant name="final_rx1b" value="mod2_rx1b+rx1b_align" />
+    <constant name="final_rx2b" value="mod2_rx2b+rx2b_align" />
+    <constant name="final_rx3b" value="mod2_rx3b+rx3b_align" />
+    <constant name="final_rx4b" value="mod2_rx4b+rx4b_align" />
+    <constant name="final_rx5b" value="mod2_rx5b+rx5b_align" />
+    <constant name="final_rx6b" value="mod2_rx6b+rx6b_align" />
+    <constant name="final_rx7b" value="mod2_rx7b+rx7b_align" />
+    <constant name="final_rx8b" value="mod2_rx8b+rx8b_align" />
+    <constant name="final_rx9b" value="mod2_rx9b+rx9b_align" />
+    <constant name="final_rx10b" value="mod2_rx10b+rx10b_align" />
+    <constant name="final_ry1b" value="mod2_ry1b+ry1b_align" />
+    <constant name="final_ry2b" value="mod2_ry2b+ry2b_align" />
+    <constant name="final_ry3b" value="mod2_ry3b+ry3b_align" />
+    <constant name="final_ry4b" value="mod2_ry4b+ry4b_align" />
+    <constant name="final_ry5b" value="mod2_ry5b+ry5b_align" />
+    <constant name="final_ry6b" value="mod2_ry6b+ry6b_align" />
+    <constant name="final_ry7b" value="mod2_ry7b+ry7b_align" />
+    <constant name="final_ry8b" value="mod2_ry8b+ry8b_align" />
+    <constant name="final_ry9b" value="mod2_ry9b+ry9b_align" />
+    <constant name="final_ry10b" value="mod2_ry10b+ry10b_align" />
+    <constant name="final_rz1b" value="mod2_rz1b+rz1b_align" />
+    <constant name="final_rz2b" value="mod2_rz2b+rz2b_align" />
+    <constant name="final_rz3b" value="mod2_rz3b+rz3b_align" />
+    <constant name="final_rz4b" value="mod2_rz4b+rz4b_align" />
+    <constant name="final_rz5b" value="mod2_rz5b+rz5b_align" />
+    <constant name="final_rz6b" value="mod2_rz6b+rz6b_align" />
+    <constant name="final_rz7b" value="mod2_rz7b+rz7b_align" />
+    <constant name="final_rz8b" value="mod2_rz8b+rz8b_align" />
+    <constant name="final_rz9b" value="mod2_rz9b+rz9b_align" />
+    <constant name="final_rz10b" value="mod2_rz10b+rz10b_align" />
+        
+        
     </define>
     
     <materials>      
-    	<!-- Set the world material to vacuum. -->
+        <!-- Set the world material to vacuum. -->
         <material name="WorldMaterial">
             <D type="density" unit="g/cm3" value="0.0000000000000001" />
             <fraction n="1.0" ref="Vacuum" />
@@ -820,7 +820,7 @@
             </layer>
             <layer id="2">
                 <module_placement name="TestRunModuleFieldDef" id="0" x="0" y="0" z="dipoleMagnetPositionZ+dipoleMagnetLength/2" rx="0" ry="0" rz="-PI/2" />
-			</layer>
+            </layer>
         </detector>     
         
         <detector id="13" name="Ecal" type="HPSEcal3" insideTrackingVolume="false" readout="EcalHits" vis="ECALVis">

Modified: java/branches/HPSJAVA-409/detector-data/detectors/HPS-TestRun-v7/compact.xml
 =============================================================================
--- java/branches/HPSJAVA-409/detector-data/detectors/HPS-TestRun-v7/compact.xml	(original)
+++ java/branches/HPSJAVA-409/detector-data/detectors/HPS-TestRun-v7/compact.xml	Wed Apr 27 11:11:32 2016
@@ -488,7 +488,7 @@
     </define>
     
     <materials>      
-    	<!-- Set the world material to vacuum. -->
+        <!-- Set the world material to vacuum. -->
         <material name="WorldMaterial">
             <D type="density" unit="g/cm3" value="0.0000000000000001"/>
             <fraction n="1.0" ref="Vacuum" />
@@ -577,7 +577,7 @@
             </layer>
             <layer id="2">
                 <module_placement name="TestRunModuleFieldDef" id="0" x="0" y="0" z="dipoleMagnetPositionZ+dipoleMagnetLength/2" rx="0" ry="0" rz="-PI/2"/>
-			</layer>
+            </layer>
         </detector>     
         
         <detector id="13" name="Ecal" type="HPSEcal3" insideTrackingVolume="false" readout="EcalHits" vis="ECALVis">

Modified: java/branches/HPSJAVA-409/detector-data/detectors/HPS-TestRun-v8-4/compact.xml
 =============================================================================
--- java/branches/HPSJAVA-409/detector-data/detectors/HPS-TestRun-v8-4/compact.xml	(original)
+++ java/branches/HPSJAVA-409/detector-data/detectors/HPS-TestRun-v8-4/compact.xml	Wed Apr 27 11:11:32 2016
@@ -3,9 +3,9 @@
     
     <info name="HPS-TestRun-v8-4">
         <comment>
-		  HPS JLab Test Run detector with dipole field starting at z=0
-		  Alignment based on millepede: compact-u3-6-float-1351-v8-10k.xml
-		</comment>
+          HPS JLab Test Run detector with dipole field starting at z=0
+          Alignment based on millepede: compact-u3-6-float-1351-v8-10k.xml
+        </comment>
     </info>
 
     <define>
@@ -65,127 +65,127 @@
 <!--        <constant name="x_off" value = "-15.0"/> -->
         <constant name="x_off" value="0.0" /> 
 
-		<!-- alignment corrections -->
-	<constant name="x1t_align" value="0.000000" />
-	<constant name="x2t_align" value="0.000000" />
-	<constant name="x3t_align" value="0.000014" />
-	<constant name="x4t_align" value="0.015024" />
-	<constant name="x5t_align" value="0.000045" />
-	<constant name="x6t_align" value="-0.003411" />
-	<constant name="x7t_align" value="0.000000" />
-	<constant name="x8t_align" value="0.000000" />
-	<constant name="x9t_align" value="0.000000" />
-	<constant name="x10t_align" value="0.000000" />
-	<constant name="y1t_align" value="0.000000" />
-	<constant name="y2t_align" value="0.000000" />
-	<constant name="y3t_align" value="0.112932" />
-	<constant name="y4t_align" value="0.149860" />
-	<constant name="y5t_align" value="-0.082467" />
-	<constant name="y6t_align" value="-0.033966" />
-	<constant name="y7t_align" value="0.000000" />
-	<constant name="y8t_align" value="0.000000" />
-	<constant name="y9t_align" value="0.000000" />
-	<constant name="y10t_align" value="0.000000" />
-	<constant name="z1t_align" value="-0.000000" />
-	<constant name="z2t_align" value="0.000000" />
-	<constant name="z3t_align" value="0.002938" />
-	<constant name="z4t_align" value="0.003424" />
-	<constant name="z5t_align" value="-0.002147" />
-	<constant name="z6t_align" value="-0.000776" />
-	<constant name="z7t_align" value="-0.000000" />
-	<constant name="z8t_align" value="0.000000" />
-	<constant name="z9t_align" value="-0.000000" />
-	<constant name="z10t_align" value="0.000000" />
-	<constant name="rx1t_align" value="0.000000" />
-	<constant name="rx2t_align" value="0.000000" />
-	<constant name="rx3t_align" value="0.000000" />
-	<constant name="rx4t_align" value="0.000000" />
-	<constant name="rx5t_align" value="0.000000" />
-	<constant name="rx6t_align" value="0.000000" />
-	<constant name="rx7t_align" value="0.000000" />
-	<constant name="rx8t_align" value="0.000000" />
-	<constant name="rx9t_align" value="0.000000" />
-	<constant name="rx10t_align" value="0.000000" />
-	<constant name="ry1t_align" value="0.000000" />
-	<constant name="ry2t_align" value="0.000000" />
-	<constant name="ry3t_align" value="0.000000" />
-	<constant name="ry4t_align" value="0.000000" />
-	<constant name="ry5t_align" value="0.000000" />
-	<constant name="ry6t_align" value="0.000000" />
-	<constant name="ry7t_align" value="0.000000" />
-	<constant name="ry8t_align" value="0.000000" />
-	<constant name="ry9t_align" value="0.000000" />
-	<constant name="ry10t_align" value="0.000000" />
-	<constant name="rz1t_align" value="-0.000000" />
-	<constant name="rz2t_align" value="0.000000" />
-	<constant name="rz3t_align" value="-0.000000" />
-	<constant name="rz4t_align" value="0.000000" />
-	<constant name="rz5t_align" value="-0.000000" />
-	<constant name="rz6t_align" value="0.000000" />
-	<constant name="rz7t_align" value="-0.000000" />
-	<constant name="rz8t_align" value="0.000000" />
-	<constant name="rz9t_align" value="-0.000000" />
-	<constant name="rz10t_align" value="0.000000" />
-	<constant name="x1b_align" value="0.000000" />
-	<constant name="x2b_align" value="0.000000" />
-	<constant name="x3b_align" value="0.008443" />
-	<constant name="x4b_align" value="-0.000012" />
-	<constant name="x5b_align" value="0.004437" />
-	<constant name="x6b_align" value="-0.000010" />
-	<constant name="x7b_align" value="0.000000" />
-	<constant name="x8b_align" value="0.000000" />
-	<constant name="x9b_align" value="0.000000" />
-	<constant name="x10b_align" value="0.000000" />
-	<constant name="y1b_align" value="0.000000" />
-	<constant name="y2b_align" value="0.000000" />
-	<constant name="y3b_align" value="-0.084138" />
-	<constant name="y4b_align" value="-0.061835" />
-	<constant name="y5b_align" value="-0.044388" />
-	<constant name="y6b_align" value="-0.032317" />
-	<constant name="y7b_align" value="0.000000" />
-	<constant name="y8b_align" value="0.000000" />
-	<constant name="y9b_align" value="0.000000" />
-	<constant name="y10b_align" value="0.000000" />
-	<constant name="z1b_align" value="0.000000" />
-	<constant name="z2b_align" value="0.000000" />
-	<constant name="z3b_align" value="0.001646" />
-	<constant name="z4b_align" value="0.001377" />
-	<constant name="z5b_align" value="0.000869" />
-	<constant name="z6b_align" value="0.000720" />
-	<constant name="z7b_align" value="0.000000" />
-	<constant name="z8b_align" value="0.000000" />
-	<constant name="z9b_align" value="0.000000" />
-	<constant name="z10b_align" value="0.000000" />
-	<constant name="rx1b_align" value="0.000000" />
-	<constant name="rx2b_align" value="0.000000" />
-	<constant name="rx3b_align" value="0.000000" />
-	<constant name="rx4b_align" value="0.000000" />
-	<constant name="rx5b_align" value="0.000000" />
-	<constant name="rx6b_align" value="0.000000" />
-	<constant name="rx7b_align" value="0.000000" />
-	<constant name="rx8b_align" value="0.000000" />
-	<constant name="rx9b_align" value="0.000000" />
-	<constant name="rx10b_align" value="0.000000" />
-	<constant name="ry1b_align" value="0.000000" />
-	<constant name="ry2b_align" value="0.000000" />
-	<constant name="ry3b_align" value="0.000000" />
-	<constant name="ry4b_align" value="0.000000" />
-	<constant name="ry5b_align" value="0.000000" />
-	<constant name="ry6b_align" value="0.000000" />
-	<constant name="ry7b_align" value="0.000000" />
-	<constant name="ry8b_align" value="0.000000" />
-	<constant name="ry9b_align" value="0.000000" />
-	<constant name="ry10b_align" value="0.000000" />
-	<constant name="rz1b_align" value="0.000000" />
-	<constant name="rz2b_align" value="0.000000" />
-	<constant name="rz3b_align" value="0.000000" />
-	<constant name="rz4b_align" value="0.000000" />
-	<constant name="rz5b_align" value="0.000000" />
-	<constant name="rz6b_align" value="0.000000" />
-	<constant name="rz7b_align" value="0.000000" />
-	<constant name="rz8b_align" value="0.000000" />
-	<constant name="rz9b_align" value="0.000000" />
-	<constant name="rz10b_align" value="0.000000" />
+        <!-- alignment corrections -->
+    <constant name="x1t_align" value="0.000000" />
+    <constant name="x2t_align" value="0.000000" />
+    <constant name="x3t_align" value="0.000014" />
+    <constant name="x4t_align" value="0.015024" />
+    <constant name="x5t_align" value="0.000045" />
+    <constant name="x6t_align" value="-0.003411" />
+    <constant name="x7t_align" value="0.000000" />
+    <constant name="x8t_align" value="0.000000" />
+    <constant name="x9t_align" value="0.000000" />
+    <constant name="x10t_align" value="0.000000" />
+    <constant name="y1t_align" value="0.000000" />
+    <constant name="y2t_align" value="0.000000" />
+    <constant name="y3t_align" value="0.112932" />
+    <constant name="y4t_align" value="0.149860" />
+    <constant name="y5t_align" value="-0.082467" />
+    <constant name="y6t_align" value="-0.033966" />
+    <constant name="y7t_align" value="0.000000" />
+    <constant name="y8t_align" value="0.000000" />
+    <constant name="y9t_align" value="0.000000" />
+    <constant name="y10t_align" value="0.000000" />
+    <constant name="z1t_align" value="-0.000000" />
+    <constant name="z2t_align" value="0.000000" />
+    <constant name="z3t_align" value="0.002938" />
+    <constant name="z4t_align" value="0.003424" />
+    <constant name="z5t_align" value="-0.002147" />
+    <constant name="z6t_align" value="-0.000776" />
+    <constant name="z7t_align" value="-0.000000" />
+    <constant name="z8t_align" value="0.000000" />
+    <constant name="z9t_align" value="-0.000000" />
+    <constant name="z10t_align" value="0.000000" />
+    <constant name="rx1t_align" value="0.000000" />
+    <constant name="rx2t_align" value="0.000000" />
+    <constant name="rx3t_align" value="0.000000" />
+    <constant name="rx4t_align" value="0.000000" />
+    <constant name="rx5t_align" value="0.000000" />
+    <constant name="rx6t_align" value="0.000000" />
+    <constant name="rx7t_align" value="0.000000" />
+    <constant name="rx8t_align" value="0.000000" />
+    <constant name="rx9t_align" value="0.000000" />
+    <constant name="rx10t_align" value="0.000000" />
+    <constant name="ry1t_align" value="0.000000" />
+    <constant name="ry2t_align" value="0.000000" />
+    <constant name="ry3t_align" value="0.000000" />
+    <constant name="ry4t_align" value="0.000000" />
+    <constant name="ry5t_align" value="0.000000" />
+    <constant name="ry6t_align" value="0.000000" />
+    <constant name="ry7t_align" value="0.000000" />
+    <constant name="ry8t_align" value="0.000000" />
+    <constant name="ry9t_align" value="0.000000" />
+    <constant name="ry10t_align" value="0.000000" />
+    <constant name="rz1t_align" value="-0.000000" />
+    <constant name="rz2t_align" value="0.000000" />
+    <constant name="rz3t_align" value="-0.000000" />
+    <constant name="rz4t_align" value="0.000000" />
+    <constant name="rz5t_align" value="-0.000000" />
+    <constant name="rz6t_align" value="0.000000" />
+    <constant name="rz7t_align" value="-0.000000" />
+    <constant name="rz8t_align" value="0.000000" />
+    <constant name="rz9t_align" value="-0.000000" />
+    <constant name="rz10t_align" value="0.000000" />
+    <constant name="x1b_align" value="0.000000" />
+    <constant name="x2b_align" value="0.000000" />
+    <constant name="x3b_align" value="0.008443" />
+    <constant name="x4b_align" value="-0.000012" />
+    <constant name="x5b_align" value="0.004437" />
+    <constant name="x6b_align" value="-0.000010" />
+    <constant name="x7b_align" value="0.000000" />
+    <constant name="x8b_align" value="0.000000" />
+    <constant name="x9b_align" value="0.000000" />
+    <constant name="x10b_align" value="0.000000" />
+    <constant name="y1b_align" value="0.000000" />
+    <constant name="y2b_align" value="0.000000" />
+    <constant name="y3b_align" value="-0.084138" />
+    <constant name="y4b_align" value="-0.061835" />
+    <constant name="y5b_align" value="-0.044388" />
+    <constant name="y6b_align" value="-0.032317" />
+    <constant name="y7b_align" value="0.000000" />
+    <constant name="y8b_align" value="0.000000" />
+    <constant name="y9b_align" value="0.000000" />
+    <constant name="y10b_align" value="0.000000" />
+    <constant name="z1b_align" value="0.000000" />
+    <constant name="z2b_align" value="0.000000" />
+    <constant name="z3b_align" value="0.001646" />
+    <constant name="z4b_align" value="0.001377" />
+    <constant name="z5b_align" value="0.000869" />
+    <constant name="z6b_align" value="0.000720" />
+    <constant name="z7b_align" value="0.000000" />
+    <constant name="z8b_align" value="0.000000" />
+    <constant name="z9b_align" value="0.000000" />
+    <constant name="z10b_align" value="0.000000" />
+    <constant name="rx1b_align" value="0.000000" />
+    <constant name="rx2b_align" value="0.000000" />
+    <constant name="rx3b_align" value="0.000000" />
+    <constant name="rx4b_align" value="0.000000" />
+    <constant name="rx5b_align" value="0.000000" />
+    <constant name="rx6b_align" value="0.000000" />
+    <constant name="rx7b_align" value="0.000000" />
+    <constant name="rx8b_align" value="0.000000" />
+    <constant name="rx9b_align" value="0.000000" />
+    <constant name="rx10b_align" value="0.000000" />
+    <constant name="ry1b_align" value="0.000000" />
+    <constant name="ry2b_align" value="0.000000" />
+    <constant name="ry3b_align" value="0.000000" />
+    <constant name="ry4b_align" value="0.000000" />
+    <constant name="ry5b_align" value="0.000000" />
+    <constant name="ry6b_align" value="0.000000" />
+    <constant name="ry7b_align" value="0.000000" />
+    <constant name="ry8b_align" value="0.000000" />
+    <constant name="ry9b_align" value="0.000000" />
+    <constant name="ry10b_align" value="0.000000" />
+    <constant name="rz1b_align" value="0.000000" />
+    <constant name="rz2b_align" value="0.000000" />
+    <constant name="rz3b_align" value="0.000000" />
+    <constant name="rz4b_align" value="0.000000" />
+    <constant name="rz5b_align" value="0.000000" />
+    <constant name="rz6b_align" value="0.000000" />
+    <constant name="rz7b_align" value="0.000000" />
+    <constant name="rz8b_align" value="0.000000" />
+    <constant name="rz9b_align" value="0.000000" />
+    <constant name="rz10b_align" value="0.000000" />
 
         <!-- Positions of sensor centers above/below nominal beam -->
         <constant name="y1t" value="36.894" />
@@ -585,134 +585,134 @@
         <constant name="mod2_rx10b" value="mod_rx10b" />
         <constant name="mod2_ry10b" value="mod_ry10b+y_rot_bot_pivot" />
         <constant name="mod2_rz10b" value="mod_rz10b" />
-    	
-    	<!-- final constants -->
-	<constant name="final_x1t" value="mod2_x1t+x1t_align" />
-	<constant name="final_x2t" value="mod2_x2t+x2t_align" />
-	<constant name="final_x3t" value="mod2_x3t+x3t_align" />
-	<constant name="final_x4t" value="mod2_x4t+x4t_align" />
-	<constant name="final_x5t" value="mod2_x5t+x5t_align" />
-	<constant name="final_x6t" value="mod2_x6t+x6t_align" />
-	<constant name="final_x7t" value="mod2_x7t+x7t_align" />
-	<constant name="final_x8t" value="mod2_x8t+x8t_align" />
-	<constant name="final_x9t" value="mod2_x9t+x9t_align" />
-	<constant name="final_x10t" value="mod2_x10t+x10t_align" />
-	<constant name="final_y1t" value="mod2_y1t+y1t_align" />
-	<constant name="final_y2t" value="mod2_y2t+y2t_align" />
-	<constant name="final_y3t" value="mod2_y3t+y3t_align" />
-	<constant name="final_y4t" value="mod2_y4t+y4t_align" />
-	<constant name="final_y5t" value="mod2_y5t+y5t_align" />
-	<constant name="final_y6t" value="mod2_y6t+y6t_align" />
-	<constant name="final_y7t" value="mod2_y7t+y7t_align" />
-	<constant name="final_y8t" value="mod2_y8t+y8t_align" />
-	<constant name="final_y9t" value="mod2_y9t+y9t_align" />
-	<constant name="final_y10t" value="mod2_y10t+y10t_align" />
-	<constant name="final_z1t" value="mod2_z1t+z1t_align" />
-	<constant name="final_z2t" value="mod2_z2t+z2t_align" />
-	<constant name="final_z3t" value="mod2_z3t+z3t_align" />
-	<constant name="final_z4t" value="mod2_z4t+z4t_align" />
-	<constant name="final_z5t" value="mod2_z5t+z5t_align" />
-	<constant name="final_z6t" value="mod2_z6t+z6t_align" />
-	<constant name="final_z7t" value="mod2_z7t+z7t_align" />
-	<constant name="final_z8t" value="mod2_z8t+z8t_align" />
-	<constant name="final_z9t" value="mod2_z9t+z9t_align" />
-	<constant name="final_z10t" value="mod2_z10t+z10t_align" />
-	<constant name="final_rx1t" value="mod2_rx1t+rx1t_align" />
-	<constant name="final_rx2t" value="mod2_rx2t+rx2t_align" />
-	<constant name="final_rx3t" value="mod2_rx3t+rx3t_align" />
-	<constant name="final_rx4t" value="mod2_rx4t+rx4t_align" />
-	<constant name="final_rx5t" value="mod2_rx5t+rx5t_align" />
-	<constant name="final_rx6t" value="mod2_rx6t+rx6t_align" />
-	<constant name="final_rx7t" value="mod2_rx7t+rx7t_align" />
-	<constant name="final_rx8t" value="mod2_rx8t+rx8t_align" />
-	<constant name="final_rx9t" value="mod2_rx9t+rx9t_align" />
-	<constant name="final_rx10t" value="mod2_rx10t+rx10t_align" />
-	<constant name="final_ry1t" value="mod2_ry1t+ry1t_align" />
-	<constant name="final_ry2t" value="mod2_ry2t+ry2t_align" />
-	<constant name="final_ry3t" value="mod2_ry3t+ry3t_align" />
-	<constant name="final_ry4t" value="mod2_ry4t+ry4t_align" />
-	<constant name="final_ry5t" value="mod2_ry5t+ry5t_align" />
-	<constant name="final_ry6t" value="mod2_ry6t+ry6t_align" />
-	<constant name="final_ry7t" value="mod2_ry7t+ry7t_align" />
-	<constant name="final_ry8t" value="mod2_ry8t+ry8t_align" />
-	<constant name="final_ry9t" value="mod2_ry9t+ry9t_align" />
-	<constant name="final_ry10t" value="mod2_ry10t+ry10t_align" />
-	<constant name="final_rz1t" value="mod2_rz1t+rz1t_align" />
-	<constant name="final_rz2t" value="mod2_rz2t+rz2t_align" />
-	<constant name="final_rz3t" value="mod2_rz3t+rz3t_align" />
-	<constant name="final_rz4t" value="mod2_rz4t+rz4t_align" />
-	<constant name="final_rz5t" value="mod2_rz5t+rz5t_align" />
-	<constant name="final_rz6t" value="mod2_rz6t+rz6t_align" />
-	<constant name="final_rz7t" value="mod2_rz7t+rz7t_align" />
-	<constant name="final_rz8t" value="mod2_rz8t+rz8t_align" />
-	<constant name="final_rz9t" value="mod2_rz9t+rz9t_align" />
-	<constant name="final_rz10t" value="mod2_rz10t+rz10t_align" />
-	<constant name="final_x1b" value="mod2_x1b+x1b_align" />
-	<constant name="final_x2b" value="mod2_x2b+x2b_align" />
-	<constant name="final_x3b" value="mod2_x3b+x3b_align" />
-	<constant name="final_x4b" value="mod2_x4b+x4b_align" />
-	<constant name="final_x5b" value="mod2_x5b+x5b_align" />
-	<constant name="final_x6b" value="mod2_x6b+x6b_align" />
-	<constant name="final_x7b" value="mod2_x7b+x7b_align" />
-	<constant name="final_x8b" value="mod2_x8b+x8b_align" />
-	<constant name="final_x9b" value="mod2_x9b+x9b_align" />
-	<constant name="final_x10b" value="mod2_x10b+x10b_align" />
-	<constant name="final_y1b" value="mod2_y1b+y1b_align" />
-	<constant name="final_y2b" value="mod2_y2b+y2b_align" />
-	<constant name="final_y3b" value="mod2_y3b+y3b_align" />
-	<constant name="final_y4b" value="mod2_y4b+y4b_align" />
-	<constant name="final_y5b" value="mod2_y5b+y5b_align" />
-	<constant name="final_y6b" value="mod2_y6b+y6b_align" />
-	<constant name="final_y7b" value="mod2_y7b+y7b_align" />
-	<constant name="final_y8b" value="mod2_y8b+y8b_align" />
-	<constant name="final_y9b" value="mod2_y9b+y9b_align" />
-	<constant name="final_y10b" value="mod2_y10b+y10b_align" />
-	<constant name="final_z1b" value="mod2_z1b+z1b_align" />
-	<constant name="final_z2b" value="mod2_z2b+z2b_align" />
-	<constant name="final_z3b" value="mod2_z3b+z3b_align" />
-	<constant name="final_z4b" value="mod2_z4b+z4b_align" />
-	<constant name="final_z5b" value="mod2_z5b+z5b_align" />
-	<constant name="final_z6b" value="mod2_z6b+z6b_align" />
-	<constant name="final_z7b" value="mod2_z7b+z7b_align" />
-	<constant name="final_z8b" value="mod2_z8b+z8b_align" />
-	<constant name="final_z9b" value="mod2_z9b+z9b_align" />
-	<constant name="final_z10b" value="mod2_z10b+z10b_align" />
-	<constant name="final_rx1b" value="mod2_rx1b+rx1b_align" />
-	<constant name="final_rx2b" value="mod2_rx2b+rx2b_align" />
-	<constant name="final_rx3b" value="mod2_rx3b+rx3b_align" />
-	<constant name="final_rx4b" value="mod2_rx4b+rx4b_align" />
-	<constant name="final_rx5b" value="mod2_rx5b+rx5b_align" />
-	<constant name="final_rx6b" value="mod2_rx6b+rx6b_align" />
-	<constant name="final_rx7b" value="mod2_rx7b+rx7b_align" />
-	<constant name="final_rx8b" value="mod2_rx8b+rx8b_align" />
-	<constant name="final_rx9b" value="mod2_rx9b+rx9b_align" />
-	<constant name="final_rx10b" value="mod2_rx10b+rx10b_align" />
-	<constant name="final_ry1b" value="mod2_ry1b+ry1b_align" />
-	<constant name="final_ry2b" value="mod2_ry2b+ry2b_align" />
-	<constant name="final_ry3b" value="mod2_ry3b+ry3b_align" />
-	<constant name="final_ry4b" value="mod2_ry4b+ry4b_align" />
-	<constant name="final_ry5b" value="mod2_ry5b+ry5b_align" />
-	<constant name="final_ry6b" value="mod2_ry6b+ry6b_align" />
-	<constant name="final_ry7b" value="mod2_ry7b+ry7b_align" />
-	<constant name="final_ry8b" value="mod2_ry8b+ry8b_align" />
-	<constant name="final_ry9b" value="mod2_ry9b+ry9b_align" />
-	<constant name="final_ry10b" value="mod2_ry10b+ry10b_align" />
-	<constant name="final_rz1b" value="mod2_rz1b+rz1b_align" />
-	<constant name="final_rz2b" value="mod2_rz2b+rz2b_align" />
-	<constant name="final_rz3b" value="mod2_rz3b+rz3b_align" />
-	<constant name="final_rz4b" value="mod2_rz4b+rz4b_align" />
-	<constant name="final_rz5b" value="mod2_rz5b+rz5b_align" />
-	<constant name="final_rz6b" value="mod2_rz6b+rz6b_align" />
-	<constant name="final_rz7b" value="mod2_rz7b+rz7b_align" />
-	<constant name="final_rz8b" value="mod2_rz8b+rz8b_align" />
-	<constant name="final_rz9b" value="mod2_rz9b+rz9b_align" />
-	<constant name="final_rz10b" value="mod2_rz10b+rz10b_align" />
-    	
-    	
+        
+        <!-- final constants -->
+    <constant name="final_x1t" value="mod2_x1t+x1t_align" />
+    <constant name="final_x2t" value="mod2_x2t+x2t_align" />
+    <constant name="final_x3t" value="mod2_x3t+x3t_align" />
+    <constant name="final_x4t" value="mod2_x4t+x4t_align" />
+    <constant name="final_x5t" value="mod2_x5t+x5t_align" />
+    <constant name="final_x6t" value="mod2_x6t+x6t_align" />
+    <constant name="final_x7t" value="mod2_x7t+x7t_align" />
+    <constant name="final_x8t" value="mod2_x8t+x8t_align" />
+    <constant name="final_x9t" value="mod2_x9t+x9t_align" />
+    <constant name="final_x10t" value="mod2_x10t+x10t_align" />
+    <constant name="final_y1t" value="mod2_y1t+y1t_align" />
+    <constant name="final_y2t" value="mod2_y2t+y2t_align" />
+    <constant name="final_y3t" value="mod2_y3t+y3t_align" />
+    <constant name="final_y4t" value="mod2_y4t+y4t_align" />
+    <constant name="final_y5t" value="mod2_y5t+y5t_align" />
+    <constant name="final_y6t" value="mod2_y6t+y6t_align" />
+    <constant name="final_y7t" value="mod2_y7t+y7t_align" />
+    <constant name="final_y8t" value="mod2_y8t+y8t_align" />
+    <constant name="final_y9t" value="mod2_y9t+y9t_align" />
+    <constant name="final_y10t" value="mod2_y10t+y10t_align" />
+    <constant name="final_z1t" value="mod2_z1t+z1t_align" />
+    <constant name="final_z2t" value="mod2_z2t+z2t_align" />
+    <constant name="final_z3t" value="mod2_z3t+z3t_align" />
+    <constant name="final_z4t" value="mod2_z4t+z4t_align" />
+    <constant name="final_z5t" value="mod2_z5t+z5t_align" />
+    <constant name="final_z6t" value="mod2_z6t+z6t_align" />
+    <constant name="final_z7t" value="mod2_z7t+z7t_align" />
+    <constant name="final_z8t" value="mod2_z8t+z8t_align" />
+    <constant name="final_z9t" value="mod2_z9t+z9t_align" />
+    <constant name="final_z10t" value="mod2_z10t+z10t_align" />
+    <constant name="final_rx1t" value="mod2_rx1t+rx1t_align" />
+    <constant name="final_rx2t" value="mod2_rx2t+rx2t_align" />
+    <constant name="final_rx3t" value="mod2_rx3t+rx3t_align" />
+    <constant name="final_rx4t" value="mod2_rx4t+rx4t_align" />
+    <constant name="final_rx5t" value="mod2_rx5t+rx5t_align" />
+    <constant name="final_rx6t" value="mod2_rx6t+rx6t_align" />
+    <constant name="final_rx7t" value="mod2_rx7t+rx7t_align" />
+    <constant name="final_rx8t" value="mod2_rx8t+rx8t_align" />
+    <constant name="final_rx9t" value="mod2_rx9t+rx9t_align" />
+    <constant name="final_rx10t" value="mod2_rx10t+rx10t_align" />
+    <constant name="final_ry1t" value="mod2_ry1t+ry1t_align" />
+    <constant name="final_ry2t" value="mod2_ry2t+ry2t_align" />
+    <constant name="final_ry3t" value="mod2_ry3t+ry3t_align" />
+    <constant name="final_ry4t" value="mod2_ry4t+ry4t_align" />
+    <constant name="final_ry5t" value="mod2_ry5t+ry5t_align" />
+    <constant name="final_ry6t" value="mod2_ry6t+ry6t_align" />
+    <constant name="final_ry7t" value="mod2_ry7t+ry7t_align" />
+    <constant name="final_ry8t" value="mod2_ry8t+ry8t_align" />
+    <constant name="final_ry9t" value="mod2_ry9t+ry9t_align" />
+    <constant name="final_ry10t" value="mod2_ry10t+ry10t_align" />
+    <constant name="final_rz1t" value="mod2_rz1t+rz1t_align" />
+    <constant name="final_rz2t" value="mod2_rz2t+rz2t_align" />
+    <constant name="final_rz3t" value="mod2_rz3t+rz3t_align" />
+    <constant name="final_rz4t" value="mod2_rz4t+rz4t_align" />
+    <constant name="final_rz5t" value="mod2_rz5t+rz5t_align" />
+    <constant name="final_rz6t" value="mod2_rz6t+rz6t_align" />
+    <constant name="final_rz7t" value="mod2_rz7t+rz7t_align" />
+    <constant name="final_rz8t" value="mod2_rz8t+rz8t_align" />
+    <constant name="final_rz9t" value="mod2_rz9t+rz9t_align" />
+    <constant name="final_rz10t" value="mod2_rz10t+rz10t_align" />
+    <constant name="final_x1b" value="mod2_x1b+x1b_align" />
+    <constant name="final_x2b" value="mod2_x2b+x2b_align" />
+    <constant name="final_x3b" value="mod2_x3b+x3b_align" />
+    <constant name="final_x4b" value="mod2_x4b+x4b_align" />
+    <constant name="final_x5b" value="mod2_x5b+x5b_align" />
+    <constant name="final_x6b" value="mod2_x6b+x6b_align" />
+    <constant name="final_x7b" value="mod2_x7b+x7b_align" />
+    <constant name="final_x8b" value="mod2_x8b+x8b_align" />
+    <constant name="final_x9b" value="mod2_x9b+x9b_align" />
+    <constant name="final_x10b" value="mod2_x10b+x10b_align" />
+    <constant name="final_y1b" value="mod2_y1b+y1b_align" />
+    <constant name="final_y2b" value="mod2_y2b+y2b_align" />
+    <constant name="final_y3b" value="mod2_y3b+y3b_align" />
+    <constant name="final_y4b" value="mod2_y4b+y4b_align" />
+    <constant name="final_y5b" value="mod2_y5b+y5b_align" />
+    <constant name="final_y6b" value="mod2_y6b+y6b_align" />
+    <constant name="final_y7b" value="mod2_y7b+y7b_align" />
+    <constant name="final_y8b" value="mod2_y8b+y8b_align" />
+    <constant name="final_y9b" value="mod2_y9b+y9b_align" />
+    <constant name="final_y10b" value="mod2_y10b+y10b_align" />
+    <constant name="final_z1b" value="mod2_z1b+z1b_align" />
+    <constant name="final_z2b" value="mod2_z2b+z2b_align" />
+    <constant name="final_z3b" value="mod2_z3b+z3b_align" />
+    <constant name="final_z4b" value="mod2_z4b+z4b_align" />
+    <constant name="final_z5b" value="mod2_z5b+z5b_align" />
+    <constant name="final_z6b" value="mod2_z6b+z6b_align" />
+    <constant name="final_z7b" value="mod2_z7b+z7b_align" />
+    <constant name="final_z8b" value="mod2_z8b+z8b_align" />
+    <constant name="final_z9b" value="mod2_z9b+z9b_align" />
+    <constant name="final_z10b" value="mod2_z10b+z10b_align" />
+    <constant name="final_rx1b" value="mod2_rx1b+rx1b_align" />
+    <constant name="final_rx2b" value="mod2_rx2b+rx2b_align" />
+    <constant name="final_rx3b" value="mod2_rx3b+rx3b_align" />
+    <constant name="final_rx4b" value="mod2_rx4b+rx4b_align" />
+    <constant name="final_rx5b" value="mod2_rx5b+rx5b_align" />
+    <constant name="final_rx6b" value="mod2_rx6b+rx6b_align" />
+    <constant name="final_rx7b" value="mod2_rx7b+rx7b_align" />
+    <constant name="final_rx8b" value="mod2_rx8b+rx8b_align" />
+    <constant name="final_rx9b" value="mod2_rx9b+rx9b_align" />
+    <constant name="final_rx10b" value="mod2_rx10b+rx10b_align" />
+    <constant name="final_ry1b" value="mod2_ry1b+ry1b_align" />
+    <constant name="final_ry2b" value="mod2_ry2b+ry2b_align" />
+    <constant name="final_ry3b" value="mod2_ry3b+ry3b_align" />
+    <constant name="final_ry4b" value="mod2_ry4b+ry4b_align" />
+    <constant name="final_ry5b" value="mod2_ry5b+ry5b_align" />
+    <constant name="final_ry6b" value="mod2_ry6b+ry6b_align" />
+    <constant name="final_ry7b" value="mod2_ry7b+ry7b_align" />
+    <constant name="final_ry8b" value="mod2_ry8b+ry8b_align" />
+    <constant name="final_ry9b" value="mod2_ry9b+ry9b_align" />
+    <constant name="final_ry10b" value="mod2_ry10b+ry10b_align" />
+    <constant name="final_rz1b" value="mod2_rz1b+rz1b_align" />
+    <constant name="final_rz2b" value="mod2_rz2b+rz2b_align" />
+    <constant name="final_rz3b" value="mod2_rz3b+rz3b_align" />
+    <constant name="final_rz4b" value="mod2_rz4b+rz4b_align" />
+    <constant name="final_rz5b" value="mod2_rz5b+rz5b_align" />
+    <constant name="final_rz6b" value="mod2_rz6b+rz6b_align" />
+    <constant name="final_rz7b" value="mod2_rz7b+rz7b_align" />
+    <constant name="final_rz8b" value="mod2_rz8b+rz8b_align" />
+    <constant name="final_rz9b" value="mod2_rz9b+rz9b_align" />
+    <constant name="final_rz10b" value="mod2_rz10b+rz10b_align" />
+        
+        
     </define>
     
     <materials>      
-    	<!-- Set the world material to vacuum. -->
+        <!-- Set the world material to vacuum. -->
         <material name="WorldMaterial">
             <D type="density" unit="g/cm3" value="0.0000000000000001" />
             <fraction n="1.0" ref="Vacuum" />
@@ -801,7 +801,7 @@
             </layer>
             <layer id="2">
                 <module_placement name="TestRunModuleFieldDef" id="0" x="0" y="0" z="dipoleMagnetPositionZ+dipoleMagnetLength/2" rx="0" ry="0" rz="-PI/2" />
-			</layer>
+            </layer>
         </detector>     
         
         <detector id="13" name="Ecal" type="HPSEcal3" insideTrackingVolume="false" readout="EcalHits" vis="ECALVis">

Modified: java/branches/HPSJAVA-409/detector-data/detectors/HPS-TestRun-v8-5/compact.xml
 =============================================================================
--- java/branches/HPSJAVA-409/detector-data/detectors/HPS-TestRun-v8-5/compact.xml	(original)
+++ java/branches/HPSJAVA-409/detector-data/detectors/HPS-TestRun-v8-5/compact.xml	Wed Apr 27 11:11:32 2016
@@ -3,9 +3,9 @@
     
     <info name="HPS-TestRun-v8-5">
         <comment>
-	  HPS JLab Test Run detector with dipole field starting at z=0
-	  Based on millepede-u3-6-float-then-u7-8float-then-u3-6-float-then-u1-2-float-then-u3-6-float-then-u9-10-float-then-u7-10-float-then-u3-6-float-then-u1-4-float-then-u9-10-float-1351-v8-10k.res.txt
-	</comment>
+      HPS JLab Test Run detector with dipole field starting at z=0
+      Based on millepede-u3-6-float-then-u7-8float-then-u3-6-float-then-u1-2-float-then-u3-6-float-then-u9-10-float-then-u7-10-float-then-u3-6-float-then-u1-4-float-then-u9-10-float-1351-v8-10k.res.txt
+    </comment>
     </info>
 
     <define>
@@ -65,127 +65,127 @@
 <!--        <constant name="x_off" value = "-15.0"/> -->
         <constant name="x_off" value="0.0" /> 
 
-		<!-- alignment corrections -->
-	<constant name="x1t_align" value="0.000000" />
-	<constant name="x2t_align" value="0.000338" />
-	<constant name="x3t_align" value="0.000013" />
-	<constant name="x4t_align" value="0.014360" />
-	<constant name="x5t_align" value="0.000051" />
-	<constant name="x6t_align" value="-0.004610" />
-	<constant name="x7t_align" value="-0.000000" />
-	<constant name="x8t_align" value="-0.000200" />
-	<constant name="x9t_align" value="0.000023" />
-	<constant name="x10t_align" value="0.003314" />
-	<constant name="y1t_align" value="0.003643" />
-	<constant name="y2t_align" value="0.003372" />
-	<constant name="y3t_align" value="0.106214" />
-	<constant name="y4t_align" value="0.143235" />
-	<constant name="y5t_align" value="-0.094779" />
-	<constant name="y6t_align" value="-0.045906" />
-	<constant name="y7t_align" value="-0.004270" />
-	<constant name="y8t_align" value="-0.004014" />
-	<constant name="y9t_align" value="0.069062" />
-	<constant name="y10t_align" value="0.066775" />
-	<constant name="z1t_align" value="0.000095" />
-	<constant name="z2t_align" value="0.000077" />
-	<constant name="z3t_align" value="0.002763" />
-	<constant name="z4t_align" value="0.003273" />
-	<constant name="z5t_align" value="-0.002467" />
-	<constant name="z6t_align" value="-0.001049" />
-	<constant name="z7t_align" value="-0.000111" />
-	<constant name="z8t_align" value="-0.000098" />
-	<constant name="z9t_align" value="0.001796" />
-	<constant name="z10t_align" value="0.001633" />
-	<constant name="rx1t_align" value="0.000000" />
-	<constant name="rx2t_align" value="0.000000" />
-	<constant name="rx3t_align" value="0.000000" />
-	<constant name="rx4t_align" value="0.000000" />
-	<constant name="rx5t_align" value="0.000000" />
-	<constant name="rx6t_align" value="0.000000" />
-	<constant name="rx7t_align" value="0.000000" />
-	<constant name="rx8t_align" value="0.000000" />
-	<constant name="rx9t_align" value="0.000000" />
-	<constant name="rx10t_align" value="0.000000" />
-	<constant name="ry1t_align" value="0.000000" />
-	<constant name="ry2t_align" value="0.000000" />
-	<constant name="ry3t_align" value="0.000000" />
-	<constant name="ry4t_align" value="0.000000" />
-	<constant name="ry5t_align" value="0.000000" />
-	<constant name="ry6t_align" value="0.000000" />
-	<constant name="ry7t_align" value="0.000000" />
-	<constant name="ry8t_align" value="0.000000" />
-	<constant name="ry9t_align" value="0.000000" />
-	<constant name="ry10t_align" value="0.000000" />
-	<constant name="rz1t_align" value="-0.000000" />
-	<constant name="rz2t_align" value="0.000000" />
-	<constant name="rz3t_align" value="-0.000000" />
-	<constant name="rz4t_align" value="0.000000" />
-	<constant name="rz5t_align" value="-0.000000" />
-	<constant name="rz6t_align" value="0.000000" />
-	<constant name="rz7t_align" value="-0.000000" />
-	<constant name="rz8t_align" value="0.000000" />
-	<constant name="rz9t_align" value="-0.000000" />
-	<constant name="rz10t_align" value="0.000000" />
-	<constant name="x1b_align" value="-0.000240" />
-	<constant name="x2b_align" value="0.000001" />
-	<constant name="x3b_align" value="0.008881" />
-	<constant name="x4b_align" value="-0.000013" />
-	<constant name="x5b_align" value="0.005242" />
-	<constant name="x6b_align" value="-0.000013" />
-	<constant name="x7b_align" value="0.000171" />
-	<constant name="x8b_align" value="-0.000002" />
-	<constant name="x9b_align" value="-0.002390" />
-	<constant name="x10b_align" value="0.000002" />
-	<constant name="y1b_align" value="0.002386" />
-	<constant name="y2b_align" value="0.002507" />
-	<constant name="y3b_align" value="-0.088503" />
-	<constant name="y4b_align" value="-0.066488" />
-	<constant name="y5b_align" value="-0.052443" />
-	<constant name="y6b_align" value="-0.040809" />
-	<constant name="y7b_align" value="-0.003389" />
-	<constant name="y8b_align" value="-0.003634" />
-	<constant name="y9b_align" value="0.047254" />
-	<constant name="y10b_align" value="0.047194" />
-	<constant name="z1b_align" value="-0.000047" />
-	<constant name="z2b_align" value="-0.000056" />
-	<constant name="z3b_align" value="0.001731" />
-	<constant name="z4b_align" value="0.001481" />
-	<constant name="z5b_align" value="0.001026" />
-	<constant name="z6b_align" value="0.000909" />
-	<constant name="z7b_align" value="0.000071" />
-	<constant name="z8b_align" value="0.000081" />
-	<constant name="z9b_align" value="-0.000988" />
-	<constant name="z10b_align" value="-0.001051" />
-	<constant name="rx1b_align" value="0.000000" />
-	<constant name="rx2b_align" value="0.000000" />
-	<constant name="rx3b_align" value="0.000000" />
-	<constant name="rx4b_align" value="0.000000" />
-	<constant name="rx5b_align" value="0.000000" />
-	<constant name="rx6b_align" value="0.000000" />
-	<constant name="rx7b_align" value="0.000000" />
-	<constant name="rx8b_align" value="0.000000" />
-	<constant name="rx9b_align" value="0.000000" />
-	<constant name="rx10b_align" value="0.000000" />
-	<constant name="ry1b_align" value="0.000000" />
-	<constant name="ry2b_align" value="0.000000" />
-	<constant name="ry3b_align" value="0.000000" />
-	<constant name="ry4b_align" value="0.000000" />
-	<constant name="ry5b_align" value="0.000000" />
-	<constant name="ry6b_align" value="0.000000" />
-	<constant name="ry7b_align" value="0.000000" />
-	<constant name="ry8b_align" value="0.000000" />
-	<constant name="ry9b_align" value="0.000000" />
-	<constant name="ry10b_align" value="0.000000" />
-	<constant name="rz1b_align" value="0.000000" />
-	<constant name="rz2b_align" value="0.000000" />
-	<constant name="rz3b_align" value="0.000000" />
-	<constant name="rz4b_align" value="0.000000" />
-	<constant name="rz5b_align" value="0.000000" />
-	<constant name="rz6b_align" value="0.000000" />
-	<constant name="rz7b_align" value="0.000000" />
-	<constant name="rz8b_align" value="0.000000" />
-	<constant name="rz9b_align" value="0.000000" />
-	<constant name="rz10b_align" value="0.000000" />
+        <!-- alignment corrections -->
+    <constant name="x1t_align" value="0.000000" />
+    <constant name="x2t_align" value="0.000338" />
+    <constant name="x3t_align" value="0.000013" />
+    <constant name="x4t_align" value="0.014360" />
+    <constant name="x5t_align" value="0.000051" />
+    <constant name="x6t_align" value="-0.004610" />
+    <constant name="x7t_align" value="-0.000000" />
+    <constant name="x8t_align" value="-0.000200" />
+    <constant name="x9t_align" value="0.000023" />
+    <constant name="x10t_align" value="0.003314" />
+    <constant name="y1t_align" value="0.003643" />
+    <constant name="y2t_align" value="0.003372" />
+    <constant name="y3t_align" value="0.106214" />
+    <constant name="y4t_align" value="0.143235" />
+    <constant name="y5t_align" value="-0.094779" />
+    <constant name="y6t_align" value="-0.045906" />
+    <constant name="y7t_align" value="-0.004270" />
+    <constant name="y8t_align" value="-0.004014" />
+    <constant name="y9t_align" value="0.069062" />
+    <constant name="y10t_align" value="0.066775" />
+    <constant name="z1t_align" value="0.000095" />
+    <constant name="z2t_align" value="0.000077" />
+    <constant name="z3t_align" value="0.002763" />
+    <constant name="z4t_align" value="0.003273" />
+    <constant name="z5t_align" value="-0.002467" />
+    <constant name="z6t_align" value="-0.001049" />
+    <constant name="z7t_align" value="-0.000111" />
+    <constant name="z8t_align" value="-0.000098" />
+    <constant name="z9t_align" value="0.001796" />
+    <constant name="z10t_align" value="0.001633" />
+    <constant name="rx1t_align" value="0.000000" />
+    <constant name="rx2t_align" value="0.000000" />
+    <constant name="rx3t_align" value="0.000000" />
+    <constant name="rx4t_align" value="0.000000" />
+    <constant name="rx5t_align" value="0.000000" />
+    <constant name="rx6t_align" value="0.000000" />
+    <constant name="rx7t_align" value="0.000000" />
+    <constant name="rx8t_align" value="0.000000" />
+    <constant name="rx9t_align" value="0.000000" />
+    <constant name="rx10t_align" value="0.000000" />
+    <constant name="ry1t_align" value="0.000000" />
+    <constant name="ry2t_align" value="0.000000" />
+    <constant name="ry3t_align" value="0.000000" />
+    <constant name="ry4t_align" value="0.000000" />
+    <constant name="ry5t_align" value="0.000000" />
+    <constant name="ry6t_align" value="0.000000" />
+    <constant name="ry7t_align" value="0.000000" />
+    <constant name="ry8t_align" value="0.000000" />
+    <constant name="ry9t_align" value="0.000000" />
+    <constant name="ry10t_align" value="0.000000" />
+    <constant name="rz1t_align" value="-0.000000" />
+    <constant name="rz2t_align" value="0.000000" />
+    <constant name="rz3t_align" value="-0.000000" />
+    <constant name="rz4t_align" value="0.000000" />
+    <constant name="rz5t_align" value="-0.000000" />
+    <constant name="rz6t_align" value="0.000000" />
+    <constant name="rz7t_align" value="-0.000000" />
+    <constant name="rz8t_align" value="0.000000" />
+    <constant name="rz9t_align" value="-0.000000" />
+    <constant name="rz10t_align" value="0.000000" />
+    <constant name="x1b_align" value="-0.000240" />
+    <constant name="x2b_align" value="0.000001" />
+    <constant name="x3b_align" value="0.008881" />
+    <constant name="x4b_align" value="-0.000013" />
+    <constant name="x5b_align" value="0.005242" />
+    <constant name="x6b_align" value="-0.000013" />
+    <constant name="x7b_align" value="0.000171" />
+    <constant name="x8b_align" value="-0.000002" />
+    <constant name="x9b_align" value="-0.002390" />
+    <constant name="x10b_align" value="0.000002" />
+    <constant name="y1b_align" value="0.002386" />
+    <constant name="y2b_align" value="0.002507" />
+    <constant name="y3b_align" value="-0.088503" />
+    <constant name="y4b_align" value="-0.066488" />
+    <constant name="y5b_align" value="-0.052443" />
+    <constant name="y6b_align" value="-0.040809" />
+    <constant name="y7b_align" value="-0.003389" />
+    <constant name="y8b_align" value="-0.003634" />
+    <constant name="y9b_align" value="0.047254" />
+    <constant name="y10b_align" value="0.047194" />
+    <constant name="z1b_align" value="-0.000047" />
+    <constant name="z2b_align" value="-0.000056" />
+    <constant name="z3b_align" value="0.001731" />
+    <constant name="z4b_align" value="0.001481" />
+    <constant name="z5b_align" value="0.001026" />
+    <constant name="z6b_align" value="0.000909" />
+    <constant name="z7b_align" value="0.000071" />
+    <constant name="z8b_align" value="0.000081" />
+    <constant name="z9b_align" value="-0.000988" />
+    <constant name="z10b_align" value="-0.001051" />
+    <constant name="rx1b_align" value="0.000000" />
+    <constant name="rx2b_align" value="0.000000" />
+    <constant name="rx3b_align" value="0.000000" />
+    <constant name="rx4b_align" value="0.000000" />
+    <constant name="rx5b_align" value="0.000000" />
+    <constant name="rx6b_align" value="0.000000" />
+    <constant name="rx7b_align" value="0.000000" />
+    <constant name="rx8b_align" value="0.000000" />
+    <constant name="rx9b_align" value="0.000000" />
+    <constant name="rx10b_align" value="0.000000" />
+    <constant name="ry1b_align" value="0.000000" />
+    <constant name="ry2b_align" value="0.000000" />
+    <constant name="ry3b_align" value="0.000000" />
+    <constant name="ry4b_align" value="0.000000" />
+    <constant name="ry5b_align" value="0.000000" />
+    <constant name="ry6b_align" value="0.000000" />
+    <constant name="ry7b_align" value="0.000000" />
+    <constant name="ry8b_align" value="0.000000" />
+    <constant name="ry9b_align" value="0.000000" />
+    <constant name="ry10b_align" value="0.000000" />
+    <constant name="rz1b_align" value="0.000000" />
+    <constant name="rz2b_align" value="0.000000" />
+    <constant name="rz3b_align" value="0.000000" />
+    <constant name="rz4b_align" value="0.000000" />
+    <constant name="rz5b_align" value="0.000000" />
+    <constant name="rz6b_align" value="0.000000" />
+    <constant name="rz7b_align" value="0.000000" />
+    <constant name="rz8b_align" value="0.000000" />
+    <constant name="rz9b_align" value="0.000000" />
+    <constant name="rz10b_align" value="0.000000" />
 
         <!-- Positions of sensor centers above/below nominal beam -->
         <constant name="y1t" value="36.894" />
@@ -585,134 +585,134 @@
         <constant name="mod2_rx10b" value="mod_rx10b" />
         <constant name="mod2_ry10b" value="mod_ry10b+y_rot_bot_pivot" />
         <constant name="mod2_rz10b" value="mod_rz10b" />
-    	
-    	<!-- final constants -->
-	<constant name="final_x1t" value="mod2_x1t+x1t_align" />
-	<constant name="final_x2t" value="mod2_x2t+x2t_align" />
-	<constant name="final_x3t" value="mod2_x3t+x3t_align" />
-	<constant name="final_x4t" value="mod2_x4t+x4t_align" />
-	<constant name="final_x5t" value="mod2_x5t+x5t_align" />
-	<constant name="final_x6t" value="mod2_x6t+x6t_align" />
-	<constant name="final_x7t" value="mod2_x7t+x7t_align" />
-	<constant name="final_x8t" value="mod2_x8t+x8t_align" />
-	<constant name="final_x9t" value="mod2_x9t+x9t_align" />
-	<constant name="final_x10t" value="mod2_x10t+x10t_align" />
-	<constant name="final_y1t" value="mod2_y1t+y1t_align" />
-	<constant name="final_y2t" value="mod2_y2t+y2t_align" />
-	<constant name="final_y3t" value="mod2_y3t+y3t_align" />
-	<constant name="final_y4t" value="mod2_y4t+y4t_align" />
-	<constant name="final_y5t" value="mod2_y5t+y5t_align" />
-	<constant name="final_y6t" value="mod2_y6t+y6t_align" />
-	<constant name="final_y7t" value="mod2_y7t+y7t_align" />
-	<constant name="final_y8t" value="mod2_y8t+y8t_align" />
-	<constant name="final_y9t" value="mod2_y9t+y9t_align" />
-	<constant name="final_y10t" value="mod2_y10t+y10t_align" />
-	<constant name="final_z1t" value="mod2_z1t+z1t_align" />
-	<constant name="final_z2t" value="mod2_z2t+z2t_align" />
-	<constant name="final_z3t" value="mod2_z3t+z3t_align" />
-	<constant name="final_z4t" value="mod2_z4t+z4t_align" />
-	<constant name="final_z5t" value="mod2_z5t+z5t_align" />
-	<constant name="final_z6t" value="mod2_z6t+z6t_align" />
-	<constant name="final_z7t" value="mod2_z7t+z7t_align" />
-	<constant name="final_z8t" value="mod2_z8t+z8t_align" />
-	<constant name="final_z9t" value="mod2_z9t+z9t_align" />
-	<constant name="final_z10t" value="mod2_z10t+z10t_align" />
-	<constant name="final_rx1t" value="mod2_rx1t+rx1t_align" />
-	<constant name="final_rx2t" value="mod2_rx2t+rx2t_align" />
-	<constant name="final_rx3t" value="mod2_rx3t+rx3t_align" />
-	<constant name="final_rx4t" value="mod2_rx4t+rx4t_align" />
-	<constant name="final_rx5t" value="mod2_rx5t+rx5t_align" />
-	<constant name="final_rx6t" value="mod2_rx6t+rx6t_align" />
-	<constant name="final_rx7t" value="mod2_rx7t+rx7t_align" />
-	<constant name="final_rx8t" value="mod2_rx8t+rx8t_align" />
-	<constant name="final_rx9t" value="mod2_rx9t+rx9t_align" />
-	<constant name="final_rx10t" value="mod2_rx10t+rx10t_align" />
-	<constant name="final_ry1t" value="mod2_ry1t+ry1t_align" />
-	<constant name="final_ry2t" value="mod2_ry2t+ry2t_align" />
-	<constant name="final_ry3t" value="mod2_ry3t+ry3t_align" />
-	<constant name="final_ry4t" value="mod2_ry4t+ry4t_align" />
-	<constant name="final_ry5t" value="mod2_ry5t+ry5t_align" />
-	<constant name="final_ry6t" value="mod2_ry6t+ry6t_align" />
-	<constant name="final_ry7t" value="mod2_ry7t+ry7t_align" />
-	<constant name="final_ry8t" value="mod2_ry8t+ry8t_align" />
-	<constant name="final_ry9t" value="mod2_ry9t+ry9t_align" />
-	<constant name="final_ry10t" value="mod2_ry10t+ry10t_align" />
-	<constant name="final_rz1t" value="mod2_rz1t+rz1t_align" />
-	<constant name="final_rz2t" value="mod2_rz2t+rz2t_align" />
-	<constant name="final_rz3t" value="mod2_rz3t+rz3t_align" />
-	<constant name="final_rz4t" value="mod2_rz4t+rz4t_align" />
-	<constant name="final_rz5t" value="mod2_rz5t+rz5t_align" />
-	<constant name="final_rz6t" value="mod2_rz6t+rz6t_align" />
-	<constant name="final_rz7t" value="mod2_rz7t+rz7t_align" />
-	<constant name="final_rz8t" value="mod2_rz8t+rz8t_align" />
-	<constant name="final_rz9t" value="mod2_rz9t+rz9t_align" />
-	<constant name="final_rz10t" value="mod2_rz10t+rz10t_align" />
-	<constant name="final_x1b" value="mod2_x1b+x1b_align" />
-	<constant name="final_x2b" value="mod2_x2b+x2b_align" />
-	<constant name="final_x3b" value="mod2_x3b+x3b_align" />
-	<constant name="final_x4b" value="mod2_x4b+x4b_align" />
-	<constant name="final_x5b" value="mod2_x5b+x5b_align" />
-	<constant name="final_x6b" value="mod2_x6b+x6b_align" />
-	<constant name="final_x7b" value="mod2_x7b+x7b_align" />
-	<constant name="final_x8b" value="mod2_x8b+x8b_align" />
-	<constant name="final_x9b" value="mod2_x9b+x9b_align" />
-	<constant name="final_x10b" value="mod2_x10b+x10b_align" />
-	<constant name="final_y1b" value="mod2_y1b+y1b_align" />
-	<constant name="final_y2b" value="mod2_y2b+y2b_align" />
-	<constant name="final_y3b" value="mod2_y3b+y3b_align" />
-	<constant name="final_y4b" value="mod2_y4b+y4b_align" />
-	<constant name="final_y5b" value="mod2_y5b+y5b_align" />
-	<constant name="final_y6b" value="mod2_y6b+y6b_align" />
-	<constant name="final_y7b" value="mod2_y7b+y7b_align" />
-	<constant name="final_y8b" value="mod2_y8b+y8b_align" />
-	<constant name="final_y9b" value="mod2_y9b+y9b_align" />
-	<constant name="final_y10b" value="mod2_y10b+y10b_align" />
-	<constant name="final_z1b" value="mod2_z1b+z1b_align" />
-	<constant name="final_z2b" value="mod2_z2b+z2b_align" />
-	<constant name="final_z3b" value="mod2_z3b+z3b_align" />
-	<constant name="final_z4b" value="mod2_z4b+z4b_align" />
-	<constant name="final_z5b" value="mod2_z5b+z5b_align" />
-	<constant name="final_z6b" value="mod2_z6b+z6b_align" />
-	<constant name="final_z7b" value="mod2_z7b+z7b_align" />
-	<constant name="final_z8b" value="mod2_z8b+z8b_align" />
-	<constant name="final_z9b" value="mod2_z9b+z9b_align" />
-	<constant name="final_z10b" value="mod2_z10b+z10b_align" />
-	<constant name="final_rx1b" value="mod2_rx1b+rx1b_align" />
-	<constant name="final_rx2b" value="mod2_rx2b+rx2b_align" />
-	<constant name="final_rx3b" value="mod2_rx3b+rx3b_align" />
-	<constant name="final_rx4b" value="mod2_rx4b+rx4b_align" />
-	<constant name="final_rx5b" value="mod2_rx5b+rx5b_align" />
-	<constant name="final_rx6b" value="mod2_rx6b+rx6b_align" />
-	<constant name="final_rx7b" value="mod2_rx7b+rx7b_align" />
-	<constant name="final_rx8b" value="mod2_rx8b+rx8b_align" />
-	<constant name="final_rx9b" value="mod2_rx9b+rx9b_align" />
-	<constant name="final_rx10b" value="mod2_rx10b+rx10b_align" />
-	<constant name="final_ry1b" value="mod2_ry1b+ry1b_align" />
-	<constant name="final_ry2b" value="mod2_ry2b+ry2b_align" />
-	<constant name="final_ry3b" value="mod2_ry3b+ry3b_align" />
-	<constant name="final_ry4b" value="mod2_ry4b+ry4b_align" />
-	<constant name="final_ry5b" value="mod2_ry5b+ry5b_align" />
-	<constant name="final_ry6b" value="mod2_ry6b+ry6b_align" />
-	<constant name="final_ry7b" value="mod2_ry7b+ry7b_align" />
-	<constant name="final_ry8b" value="mod2_ry8b+ry8b_align" />
-	<constant name="final_ry9b" value="mod2_ry9b+ry9b_align" />
-	<constant name="final_ry10b" value="mod2_ry10b+ry10b_align" />
-	<constant name="final_rz1b" value="mod2_rz1b+rz1b_align" />
-	<constant name="final_rz2b" value="mod2_rz2b+rz2b_align" />
-	<constant name="final_rz3b" value="mod2_rz3b+rz3b_align" />
-	<constant name="final_rz4b" value="mod2_rz4b+rz4b_align" />
-	<constant name="final_rz5b" value="mod2_rz5b+rz5b_align" />
-	<constant name="final_rz6b" value="mod2_rz6b+rz6b_align" />
-	<constant name="final_rz7b" value="mod2_rz7b+rz7b_align" />
-	<constant name="final_rz8b" value="mod2_rz8b+rz8b_align" />
-	<constant name="final_rz9b" value="mod2_rz9b+rz9b_align" />
-	<constant name="final_rz10b" value="mod2_rz10b+rz10b_align" />
-    	
-    	
+        
+        <!-- final constants -->
+    <constant name="final_x1t" value="mod2_x1t+x1t_align" />
+    <constant name="final_x2t" value="mod2_x2t+x2t_align" />
+    <constant name="final_x3t" value="mod2_x3t+x3t_align" />
+    <constant name="final_x4t" value="mod2_x4t+x4t_align" />
+    <constant name="final_x5t" value="mod2_x5t+x5t_align" />
+    <constant name="final_x6t" value="mod2_x6t+x6t_align" />
+    <constant name="final_x7t" value="mod2_x7t+x7t_align" />
+    <constant name="final_x8t" value="mod2_x8t+x8t_align" />
+    <constant name="final_x9t" value="mod2_x9t+x9t_align" />
+    <constant name="final_x10t" value="mod2_x10t+x10t_align" />
+    <constant name="final_y1t" value="mod2_y1t+y1t_align" />
+    <constant name="final_y2t" value="mod2_y2t+y2t_align" />
+    <constant name="final_y3t" value="mod2_y3t+y3t_align" />
+    <constant name="final_y4t" value="mod2_y4t+y4t_align" />
+    <constant name="final_y5t" value="mod2_y5t+y5t_align" />
+    <constant name="final_y6t" value="mod2_y6t+y6t_align" />
+    <constant name="final_y7t" value="mod2_y7t+y7t_align" />
+    <constant name="final_y8t" value="mod2_y8t+y8t_align" />
+    <constant name="final_y9t" value="mod2_y9t+y9t_align" />
+    <constant name="final_y10t" value="mod2_y10t+y10t_align" />
+    <constant name="final_z1t" value="mod2_z1t+z1t_align" />
+    <constant name="final_z2t" value="mod2_z2t+z2t_align" />
+    <constant name="final_z3t" value="mod2_z3t+z3t_align" />
+    <constant name="final_z4t" value="mod2_z4t+z4t_align" />
+    <constant name="final_z5t" value="mod2_z5t+z5t_align" />
+    <constant name="final_z6t" value="mod2_z6t+z6t_align" />
+    <constant name="final_z7t" value="mod2_z7t+z7t_align" />
+    <constant name="final_z8t" value="mod2_z8t+z8t_align" />
+    <constant name="final_z9t" value="mod2_z9t+z9t_align" />
+    <constant name="final_z10t" value="mod2_z10t+z10t_align" />
+    <constant name="final_rx1t" value="mod2_rx1t+rx1t_align" />
+    <constant name="final_rx2t" value="mod2_rx2t+rx2t_align" />
+    <constant name="final_rx3t" value="mod2_rx3t+rx3t_align" />
+    <constant name="final_rx4t" value="mod2_rx4t+rx4t_align" />
+    <constant name="final_rx5t" value="mod2_rx5t+rx5t_align" />
+    <constant name="final_rx6t" value="mod2_rx6t+rx6t_align" />
+    <constant name="final_rx7t" value="mod2_rx7t+rx7t_align" />
+    <constant name="final_rx8t" value="mod2_rx8t+rx8t_align" />
+    <constant name="final_rx9t" value="mod2_rx9t+rx9t_align" />
+    <constant name="final_rx10t" value="mod2_rx10t+rx10t_align" />
+    <constant name="final_ry1t" value="mod2_ry1t+ry1t_align" />
+    <constant name="final_ry2t" value="mod2_ry2t+ry2t_align" />
+    <constant name="final_ry3t" value="mod2_ry3t+ry3t_align" />
+    <constant name="final_ry4t" value="mod2_ry4t+ry4t_align" />
+    <constant name="final_ry5t" value="mod2_ry5t+ry5t_align" />
+    <constant name="final_ry6t" value="mod2_ry6t+ry6t_align" />
+    <constant name="final_ry7t" value="mod2_ry7t+ry7t_align" />
+    <constant name="final_ry8t" value="mod2_ry8t+ry8t_align" />
+    <constant name="final_ry9t" value="mod2_ry9t+ry9t_align" />
+    <constant name="final_ry10t" value="mod2_ry10t+ry10t_align" />
+    <constant name="final_rz1t" value="mod2_rz1t+rz1t_align" />
+    <constant name="final_rz2t" value="mod2_rz2t+rz2t_align" />
+    <constant name="final_rz3t" value="mod2_rz3t+rz3t_align" />
+    <constant name="final_rz4t" value="mod2_rz4t+rz4t_align" />
+    <constant name="final_rz5t" value="mod2_rz5t+rz5t_align" />
+    <constant name="final_rz6t" value="mod2_rz6t+rz6t_align" />
+    <constant name="final_rz7t" value="mod2_rz7t+rz7t_align" />
+    <constant name="final_rz8t" value="mod2_rz8t+rz8t_align" />
+    <constant name="final_rz9t" value="mod2_rz9t+rz9t_align" />
+    <constant name="final_rz10t" value="mod2_rz10t+rz10t_align" />
+    <constant name="final_x1b" value="mod2_x1b+x1b_align" />
+    <constant name="final_x2b" value="mod2_x2b+x2b_align" />
+    <constant name="final_x3b" value="mod2_x3b+x3b_align" />
+    <constant name="final_x4b" value="mod2_x4b+x4b_align" />
+    <constant name="final_x5b" value="mod2_x5b+x5b_align" />
+    <constant name="final_x6b" value="mod2_x6b+x6b_align" />
+    <constant name="final_x7b" value="mod2_x7b+x7b_align" />
+    <constant name="final_x8b" value="mod2_x8b+x8b_align" />
+    <constant name="final_x9b" value="mod2_x9b+x9b_align" />
+    <constant name="final_x10b" value="mod2_x10b+x10b_align" />
+    <constant name="final_y1b" value="mod2_y1b+y1b_align" />
+    <constant name="final_y2b" value="mod2_y2b+y2b_align" />
+    <constant name="final_y3b" value="mod2_y3b+y3b_align" />
+    <constant name="final_y4b" value="mod2_y4b+y4b_align" />
+    <constant name="final_y5b" value="mod2_y5b+y5b_align" />
+    <constant name="final_y6b" value="mod2_y6b+y6b_align" />
+    <constant name="final_y7b" value="mod2_y7b+y7b_align" />
+    <constant name="final_y8b" value="mod2_y8b+y8b_align" />
+    <constant name="final_y9b" value="mod2_y9b+y9b_align" />
+    <constant name="final_y10b" value="mod2_y10b+y10b_align" />
+    <constant name="final_z1b" value="mod2_z1b+z1b_align" />
+    <constant name="final_z2b" value="mod2_z2b+z2b_align" />
+    <constant name="final_z3b" value="mod2_z3b+z3b_align" />
+    <constant name="final_z4b" value="mod2_z4b+z4b_align" />
+    <constant name="final_z5b" value="mod2_z5b+z5b_align" />
+    <constant name="final_z6b" value="mod2_z6b+z6b_align" />
+    <constant name="final_z7b" value="mod2_z7b+z7b_align" />
+    <constant name="final_z8b" value="mod2_z8b+z8b_align" />
+    <constant name="final_z9b" value="mod2_z9b+z9b_align" />
+    <constant name="final_z10b" value="mod2_z10b+z10b_align" />
+    <constant name="final_rx1b" value="mod2_rx1b+rx1b_align" />
+    <constant name="final_rx2b" value="mod2_rx2b+rx2b_align" />
+    <constant name="final_rx3b" value="mod2_rx3b+rx3b_align" />
+    <constant name="final_rx4b" value="mod2_rx4b+rx4b_align" />
+    <constant name="final_rx5b" value="mod2_rx5b+rx5b_align" />
+    <constant name="final_rx6b" value="mod2_rx6b+rx6b_align" />
+    <constant name="final_rx7b" value="mod2_rx7b+rx7b_align" />
+    <constant name="final_rx8b" value="mod2_rx8b+rx8b_align" />
+    <constant name="final_rx9b" value="mod2_rx9b+rx9b_align" />
+    <constant name="final_rx10b" value="mod2_rx10b+rx10b_align" />
+    <constant name="final_ry1b" value="mod2_ry1b+ry1b_align" />
+    <constant name="final_ry2b" value="mod2_ry2b+ry2b_align" />
+    <constant name="final_ry3b" value="mod2_ry3b+ry3b_align" />
+    <constant name="final_ry4b" value="mod2_ry4b+ry4b_align" />
+    <constant name="final_ry5b" value="mod2_ry5b+ry5b_align" />
+    <constant name="final_ry6b" value="mod2_ry6b+ry6b_align" />
+    <constant name="final_ry7b" value="mod2_ry7b+ry7b_align" />
+    <constant name="final_ry8b" value="mod2_ry8b+ry8b_align" />
+    <constant name="final_ry9b" value="mod2_ry9b+ry9b_align" />
+    <constant name="final_ry10b" value="mod2_ry10b+ry10b_align" />
+    <constant name="final_rz1b" value="mod2_rz1b+rz1b_align" />
+    <constant name="final_rz2b" value="mod2_rz2b+rz2b_align" />
+    <constant name="final_rz3b" value="mod2_rz3b+rz3b_align" />
+    <constant name="final_rz4b" value="mod2_rz4b+rz4b_align" />
+    <constant name="final_rz5b" value="mod2_rz5b+rz5b_align" />
+    <constant name="final_rz6b" value="mod2_rz6b+rz6b_align" />
+    <constant name="final_rz7b" value="mod2_rz7b+rz7b_align" />
+    <constant name="final_rz8b" value="mod2_rz8b+rz8b_align" />
+    <constant name="final_rz9b" value="mod2_rz9b+rz9b_align" />
+    <constant name="final_rz10b" value="mod2_rz10b+rz10b_align" />
+        
+        
     </define>
     
     <materials>      
-    	<!-- Set the world material to vacuum. -->
+        <!-- Set the world material to vacuum. -->
         <material name="WorldMaterial">
             <D type="density" unit="g/cm3" value="0.0000000000000001" />
             <fraction n="1.0" ref="Vacuum" />
@@ -801,7 +801,7 @@
             </layer>
             <layer id="2">
                 <module_placement name="TestRunModuleFieldDef" id="0" x="0" y="0" z="dipoleMagnetPositionZ+dipoleMagnetLength/2" rx="0" ry="0" rz="-PI/2" />
-			</layer>
+            </layer>
         </detector>     
         
         <detector id="13" name="Ecal" type="HPSEcal3" insideTrackingVolume="false" readout="EcalHits" vis="ECALVis">

Modified: java/branches/HPSJAVA-409/detector-data/detectors/HPS-TestRun-v8/compact.xml
 =============================================================================
--- java/branches/HPSJAVA-409/detector-data/detectors/HPS-TestRun-v8/compact.xml	(original)
+++ java/branches/HPSJAVA-409/detector-data/detectors/HPS-TestRun-v8/compact.xml	Wed Apr 27 11:11:32 2016
@@ -64,127 +64,127 @@
 <!--        <constant name="x_off" value = "-15.0"/> -->
         <constant name="x_off" value = "0.0"/> 
 
-		<!-- alignment corrections -->
-	<constant name="x1t_align" value="0.000000"/>
-	<constant name="x2t_align" value="0.000000"/>
-	<constant name="x3t_align" value="0.000000"/>
-	<constant name="x4t_align" value="0.000000"/>
-	<constant name="x5t_align" value="0.000000"/>
-	<constant name="x6t_align" value="0.000000"/>
-	<constant name="x7t_align" value="0.000000"/>
-	<constant name="x8t_align" value="0.000000"/>
-	<constant name="x9t_align" value="0.000000"/>
-	<constant name="x10t_align" value="0.000000"/>
-	<constant name="y1t_align" value="0.000000"/>
-	<constant name="y2t_align" value="0.000000"/>
-	<constant name="y3t_align" value="0.000000"/>
-	<constant name="y4t_align" value="0.000000"/>
-	<constant name="y5t_align" value="0.000000"/>
-	<constant name="y6t_align" value="0.000000"/>
-	<constant name="y7t_align" value="0.000000"/>
-	<constant name="y8t_align" value="0.000000"/>
-	<constant name="y9t_align" value="0.000000"/>
-	<constant name="y10t_align" value="0.000000"/>
-	<constant name="z1t_align" value="0.000000"/>
-	<constant name="z2t_align" value="0.000000"/>
-	<constant name="z3t_align" value="0.000000"/>
-	<constant name="z4t_align" value="0.000000"/>
-	<constant name="z5t_align" value="0.000000"/>
-	<constant name="z6t_align" value="0.000000"/>
-	<constant name="z7t_align" value="0.000000"/>
-	<constant name="z8t_align" value="0.000000"/>
-	<constant name="z9t_align" value="0.000000"/>
-	<constant name="z10t_align" value="0.000000"/>
-	<constant name="rx1t_align" value="0.000000"/>
-	<constant name="rx2t_align" value="0.000000"/>
-	<constant name="rx3t_align" value="0.000000"/>
-	<constant name="rx4t_align" value="0.000000"/>
-	<constant name="rx5t_align" value="0.000000"/>
-	<constant name="rx6t_align" value="0.000000"/>
-	<constant name="rx7t_align" value="0.000000"/>
-	<constant name="rx8t_align" value="0.000000"/>
-	<constant name="rx9t_align" value="0.000000"/>
-	<constant name="rx10t_align" value="0.000000"/>
-	<constant name="ry1t_align" value="0.000000"/>
-	<constant name="ry2t_align" value="0.000000"/>
-	<constant name="ry3t_align" value="0.000000"/>
-	<constant name="ry4t_align" value="0.000000"/>
-	<constant name="ry5t_align" value="0.000000"/>
-	<constant name="ry6t_align" value="0.000000"/>
-	<constant name="ry7t_align" value="0.000000"/>
-	<constant name="ry8t_align" value="0.000000"/>
-	<constant name="ry9t_align" value="0.000000"/>
-	<constant name="ry10t_align" value="0.000000"/>
-	<constant name="rz1t_align" value="0.000000"/>
-	<constant name="rz2t_align" value="0.000000"/>
-	<constant name="rz3t_align" value="0.000000"/>
-	<constant name="rz4t_align" value="0.000000"/>
-	<constant name="rz5t_align" value="0.000000"/>
-	<constant name="rz6t_align" value="0.000000"/>
-	<constant name="rz7t_align" value="0.000000"/>
-	<constant name="rz8t_align" value="0.000000"/>
-	<constant name="rz9t_align" value="0.000000"/>
-	<constant name="rz10t_align" value="0.000000"/>
-	<constant name="x1b_align" value="0.000000"/>
-	<constant name="x2b_align" value="0.000000"/>
-	<constant name="x3b_align" value="0.000000"/>
-	<constant name="x4b_align" value="0.000000"/>
-	<constant name="x5b_align" value="0.000000"/>
-	<constant name="x6b_align" value="0.000000"/>
-	<constant name="x7b_align" value="0.000000"/>
-	<constant name="x8b_align" value="0.000000"/>
-	<constant name="x9b_align" value="0.000000"/>
-	<constant name="x10b_align" value="0.000000"/>
-	<constant name="y1b_align" value="0.000000"/>
-	<constant name="y2b_align" value="0.000000"/>
-	<constant name="y3b_align" value="0.000000"/>
-	<constant name="y4b_align" value="0.000000"/>
-	<constant name="y5b_align" value="0.000000"/>
-	<constant name="y6b_align" value="0.000000"/>
-	<constant name="y7b_align" value="0.000000"/>
-	<constant name="y8b_align" value="0.000000"/>
-	<constant name="y9b_align" value="0.000000"/>
-	<constant name="y10b_align" value="0.000000"/>
-	<constant name="z1b_align" value="0.000000"/>
-	<constant name="z2b_align" value="0.000000"/>
-	<constant name="z3b_align" value="0.000000"/>
-	<constant name="z4b_align" value="0.000000"/>
-	<constant name="z5b_align" value="0.000000"/>
-	<constant name="z6b_align" value="0.000000"/>
-	<constant name="z7b_align" value="0.000000"/>
-	<constant name="z8b_align" value="0.000000"/>
-	<constant name="z9b_align" value="0.000000"/>
-	<constant name="z10b_align" value="0.000000"/>
-	<constant name="rx1b_align" value="0.000000"/>
-	<constant name="rx2b_align" value="0.000000"/>
-	<constant name="rx3b_align" value="0.000000"/>
-	<constant name="rx4b_align" value="0.000000"/>
-	<constant name="rx5b_align" value="0.000000"/>
-	<constant name="rx6b_align" value="0.000000"/>
-	<constant name="rx7b_align" value="0.000000"/>
-	<constant name="rx8b_align" value="0.000000"/>
-	<constant name="rx9b_align" value="0.000000"/>
-	<constant name="rx10b_align" value="0.000000"/>
-	<constant name="ry1b_align" value="0.000000"/>
-	<constant name="ry2b_align" value="0.000000"/>
-	<constant name="ry3b_align" value="0.000000"/>
-	<constant name="ry4b_align" value="0.000000"/>
-	<constant name="ry5b_align" value="0.000000"/>
-	<constant name="ry6b_align" value="0.000000"/>
-	<constant name="ry7b_align" value="0.000000"/>
-	<constant name="ry8b_align" value="0.000000"/>
-	<constant name="ry9b_align" value="0.000000"/>
-	<constant name="ry10b_align" value="0.000000"/>
-	<constant name="rz1b_align" value="0.000000"/>
-	<constant name="rz2b_align" value="0.000000"/>
-	<constant name="rz3b_align" value="0.000000"/>
-	<constant name="rz4b_align" value="0.000000"/>
-	<constant name="rz5b_align" value="0.000000"/>
-	<constant name="rz6b_align" value="0.000000"/>
-	<constant name="rz7b_align" value="0.000000"/>
-	<constant name="rz8b_align" value="0.000000"/>
-	<constant name="rz9b_align" value="0.000000"/>
-	<constant name="rz10b_align" value="0.000000"/>
+        <!-- alignment corrections -->
+    <constant name="x1t_align" value="0.000000"/>
+    <constant name="x2t_align" value="0.000000"/>
+    <constant name="x3t_align" value="0.000000"/>
+    <constant name="x4t_align" value="0.000000"/>
+    <constant name="x5t_align" value="0.000000"/>
+    <constant name="x6t_align" value="0.000000"/>
+    <constant name="x7t_align" value="0.000000"/>
+    <constant name="x8t_align" value="0.000000"/>
+    <constant name="x9t_align" value="0.000000"/>
+    <constant name="x10t_align" value="0.000000"/>
+    <constant name="y1t_align" value="0.000000"/>
+    <constant name="y2t_align" value="0.000000"/>
+    <constant name="y3t_align" value="0.000000"/>
+    <constant name="y4t_align" value="0.000000"/>
+    <constant name="y5t_align" value="0.000000"/>
+    <constant name="y6t_align" value="0.000000"/>
+    <constant name="y7t_align" value="0.000000"/>
+    <constant name="y8t_align" value="0.000000"/>
+    <constant name="y9t_align" value="0.000000"/>
+    <constant name="y10t_align" value="0.000000"/>
+    <constant name="z1t_align" value="0.000000"/>
+    <constant name="z2t_align" value="0.000000"/>
+    <constant name="z3t_align" value="0.000000"/>
+    <constant name="z4t_align" value="0.000000"/>
+    <constant name="z5t_align" value="0.000000"/>
+    <constant name="z6t_align" value="0.000000"/>
+    <constant name="z7t_align" value="0.000000"/>
+    <constant name="z8t_align" value="0.000000"/>
+    <constant name="z9t_align" value="0.000000"/>
+    <constant name="z10t_align" value="0.000000"/>
+    <constant name="rx1t_align" value="0.000000"/>
+    <constant name="rx2t_align" value="0.000000"/>
+    <constant name="rx3t_align" value="0.000000"/>
+    <constant name="rx4t_align" value="0.000000"/>
+    <constant name="rx5t_align" value="0.000000"/>
+    <constant name="rx6t_align" value="0.000000"/>
+    <constant name="rx7t_align" value="0.000000"/>
+    <constant name="rx8t_align" value="0.000000"/>
+    <constant name="rx9t_align" value="0.000000"/>
+    <constant name="rx10t_align" value="0.000000"/>
+    <constant name="ry1t_align" value="0.000000"/>
+    <constant name="ry2t_align" value="0.000000"/>
+    <constant name="ry3t_align" value="0.000000"/>
+    <constant name="ry4t_align" value="0.000000"/>
+    <constant name="ry5t_align" value="0.000000"/>
+    <constant name="ry6t_align" value="0.000000"/>
+    <constant name="ry7t_align" value="0.000000"/>
+    <constant name="ry8t_align" value="0.000000"/>
+    <constant name="ry9t_align" value="0.000000"/>
+    <constant name="ry10t_align" value="0.000000"/>
+    <constant name="rz1t_align" value="0.000000"/>
+    <constant name="rz2t_align" value="0.000000"/>
+    <constant name="rz3t_align" value="0.000000"/>
+    <constant name="rz4t_align" value="0.000000"/>
+    <constant name="rz5t_align" value="0.000000"/>
+    <constant name="rz6t_align" value="0.000000"/>
+    <constant name="rz7t_align" value="0.000000"/>
+    <constant name="rz8t_align" value="0.000000"/>
+    <constant name="rz9t_align" value="0.000000"/>
+    <constant name="rz10t_align" value="0.000000"/>
+    <constant name="x1b_align" value="0.000000"/>
+    <constant name="x2b_align" value="0.000000"/>
+    <constant name="x3b_align" value="0.000000"/>
+    <constant name="x4b_align" value="0.000000"/>
+    <constant name="x5b_align" value="0.000000"/>
+    <constant name="x6b_align" value="0.000000"/>
+    <constant name="x7b_align" value="0.000000"/>
+    <constant name="x8b_align" value="0.000000"/>
+    <constant name="x9b_align" value="0.000000"/>
+    <constant name="x10b_align" value="0.000000"/>
+    <constant name="y1b_align" value="0.000000"/>
+    <constant name="y2b_align" value="0.000000"/>
+    <constant name="y3b_align" value="0.000000"/>
+    <constant name="y4b_align" value="0.000000"/>
+    <constant name="y5b_align" value="0.000000"/>
+    <constant name="y6b_align" value="0.000000"/>
+    <constant name="y7b_align" value="0.000000"/>
+    <constant name="y8b_align" value="0.000000"/>
+    <constant name="y9b_align" value="0.000000"/>
+    <constant name="y10b_align" value="0.000000"/>
+    <constant name="z1b_align" value="0.000000"/>
+    <constant name="z2b_align" value="0.000000"/>
+    <constant name="z3b_align" value="0.000000"/>
+    <constant name="z4b_align" value="0.000000"/>
+    <constant name="z5b_align" value="0.000000"/>
+    <constant name="z6b_align" value="0.000000"/>
+    <constant name="z7b_align" value="0.000000"/>
+    <constant name="z8b_align" value="0.000000"/>
+    <constant name="z9b_align" value="0.000000"/>
+    <constant name="z10b_align" value="0.000000"/>
+    <constant name="rx1b_align" value="0.000000"/>
+    <constant name="rx2b_align" value="0.000000"/>
+    <constant name="rx3b_align" value="0.000000"/>
+    <constant name="rx4b_align" value="0.000000"/>
+    <constant name="rx5b_align" value="0.000000"/>
+    <constant name="rx6b_align" value="0.000000"/>
+    <constant name="rx7b_align" value="0.000000"/>
+    <constant name="rx8b_align" value="0.000000"/>
+    <constant name="rx9b_align" value="0.000000"/>
+    <constant name="rx10b_align" value="0.000000"/>
+    <constant name="ry1b_align" value="0.000000"/>
+    <constant name="ry2b_align" value="0.000000"/>
+    <constant name="ry3b_align" value="0.000000"/>
+    <constant name="ry4b_align" value="0.000000"/>
+    <constant name="ry5b_align" value="0.000000"/>
+    <constant name="ry6b_align" value="0.000000"/>
+    <constant name="ry7b_align" value="0.000000"/>
+    <constant name="ry8b_align" value="0.000000"/>
+    <constant name="ry9b_align" value="0.000000"/>
+    <constant name="ry10b_align" value="0.000000"/>
+    <constant name="rz1b_align" value="0.000000"/>
+    <constant name="rz2b_align" value="0.000000"/>
+    <constant name="rz3b_align" value="0.000000"/>
+    <constant name="rz4b_align" value="0.000000"/>
+    <constant name="rz5b_align" value="0.000000"/>
+    <constant name="rz6b_align" value="0.000000"/>
+    <constant name="rz7b_align" value="0.000000"/>
+    <constant name="rz8b_align" value="0.000000"/>
+    <constant name="rz9b_align" value="0.000000"/>
+    <constant name="rz10b_align" value="0.000000"/>
 
         <!-- Positions of sensor centers above/below nominal beam -->
         <constant name="y1t" value="36.894" />
@@ -584,134 +584,134 @@
         <constant name="mod2_rx10b" value="mod_rx10b"/>
         <constant name="mod2_ry10b" value="mod_ry10b+y_rot_bot_pivot"/>
         <constant name="mod2_rz10b" value="mod_rz10b"/>
-    	
-    	<!-- final constants -->
-	<constant name="final_x1t" value="mod2_x1t+x1t_align"/>
-	<constant name="final_x2t" value="mod2_x2t+x2t_align"/>
-	<constant name="final_x3t" value="mod2_x3t+x3t_align"/>
-	<constant name="final_x4t" value="mod2_x4t+x4t_align"/>
-	<constant name="final_x5t" value="mod2_x5t+x5t_align"/>
-	<constant name="final_x6t" value="mod2_x6t+x6t_align"/>
-	<constant name="final_x7t" value="mod2_x7t+x7t_align"/>
-	<constant name="final_x8t" value="mod2_x8t+x8t_align"/>
-	<constant name="final_x9t" value="mod2_x9t+x9t_align"/>
-	<constant name="final_x10t" value="mod2_x10t+x10t_align"/>
-	<constant name="final_y1t" value="mod2_y1t+y1t_align"/>
-	<constant name="final_y2t" value="mod2_y2t+y2t_align"/>
-	<constant name="final_y3t" value="mod2_y3t+y3t_align"/>
-	<constant name="final_y4t" value="mod2_y4t+y4t_align"/>
-	<constant name="final_y5t" value="mod2_y5t+y5t_align"/>
-	<constant name="final_y6t" value="mod2_y6t+y6t_align"/>
-	<constant name="final_y7t" value="mod2_y7t+y7t_align"/>
-	<constant name="final_y8t" value="mod2_y8t+y8t_align"/>
-	<constant name="final_y9t" value="mod2_y9t+y9t_align"/>
-	<constant name="final_y10t" value="mod2_y10t+y10t_align"/>
-	<constant name="final_z1t" value="mod2_z1t+z1t_align"/>
-	<constant name="final_z2t" value="mod2_z2t+z2t_align"/>
-	<constant name="final_z3t" value="mod2_z3t+z3t_align"/>
-	<constant name="final_z4t" value="mod2_z4t+z4t_align"/>
-	<constant name="final_z5t" value="mod2_z5t+z5t_align"/>
-	<constant name="final_z6t" value="mod2_z6t+z6t_align"/>
-	<constant name="final_z7t" value="mod2_z7t+z7t_align"/>
-	<constant name="final_z8t" value="mod2_z8t+z8t_align"/>
-	<constant name="final_z9t" value="mod2_z9t+z9t_align"/>
-	<constant name="final_z10t" value="mod2_z10t+z10t_align"/>
-	<constant name="final_rx1t" value="mod2_rx1t+rx1t_align"/>
-	<constant name="final_rx2t" value="mod2_rx2t+rx2t_align"/>
-	<constant name="final_rx3t" value="mod2_rx3t+rx3t_align"/>
-	<constant name="final_rx4t" value="mod2_rx4t+rx4t_align"/>
-	<constant name="final_rx5t" value="mod2_rx5t+rx5t_align"/>
-	<constant name="final_rx6t" value="mod2_rx6t+rx6t_align"/>
-	<constant name="final_rx7t" value="mod2_rx7t+rx7t_align"/>
-	<constant name="final_rx8t" value="mod2_rx8t+rx8t_align"/>
-	<constant name="final_rx9t" value="mod2_rx9t+rx9t_align"/>
-	<constant name="final_rx10t" value="mod2_rx10t+rx10t_align"/>
-	<constant name="final_ry1t" value="mod2_ry1t+ry1t_align"/>
-	<constant name="final_ry2t" value="mod2_ry2t+ry2t_align"/>
-	<constant name="final_ry3t" value="mod2_ry3t+ry3t_align"/>
-	<constant name="final_ry4t" value="mod2_ry4t+ry4t_align"/>
-	<constant name="final_ry5t" value="mod2_ry5t+ry5t_align"/>
-	<constant name="final_ry6t" value="mod2_ry6t+ry6t_align"/>
-	<constant name="final_ry7t" value="mod2_ry7t+ry7t_align"/>
-	<constant name="final_ry8t" value="mod2_ry8t+ry8t_align"/>
-	<constant name="final_ry9t" value="mod2_ry9t+ry9t_align"/>
-	<constant name="final_ry10t" value="mod2_ry10t+ry10t_align"/>
-	<constant name="final_rz1t" value="mod2_rz1t+rz1t_align"/>
-	<constant name="final_rz2t" value="mod2_rz2t+rz2t_align"/>
-	<constant name="final_rz3t" value="mod2_rz3t+rz3t_align"/>
-	<constant name="final_rz4t" value="mod2_rz4t+rz4t_align"/>
-	<constant name="final_rz5t" value="mod2_rz5t+rz5t_align"/>
-	<constant name="final_rz6t" value="mod2_rz6t+rz6t_align"/>
-	<constant name="final_rz7t" value="mod2_rz7t+rz7t_align"/>
-	<constant name="final_rz8t" value="mod2_rz8t+rz8t_align"/>
-	<constant name="final_rz9t" value="mod2_rz9t+rz9t_align"/>
-	<constant name="final_rz10t" value="mod2_rz10t+rz10t_align"/>
-	<constant name="final_x1b" value="mod2_x1b+x1b_align"/>
-	<constant name="final_x2b" value="mod2_x2b+x2b_align"/>
-	<constant name="final_x3b" value="mod2_x3b+x3b_align"/>
-	<constant name="final_x4b" value="mod2_x4b+x4b_align"/>
-	<constant name="final_x5b" value="mod2_x5b+x5b_align"/>
-	<constant name="final_x6b" value="mod2_x6b+x6b_align"/>
-	<constant name="final_x7b" value="mod2_x7b+x7b_align"/>
-	<constant name="final_x8b" value="mod2_x8b+x8b_align"/>
-	<constant name="final_x9b" value="mod2_x9b+x9b_align"/>
-	<constant name="final_x10b" value="mod2_x10b+x10b_align"/>
-	<constant name="final_y1b" value="mod2_y1b+y1b_align"/>
-	<constant name="final_y2b" value="mod2_y2b+y2b_align"/>
-	<constant name="final_y3b" value="mod2_y3b+y3b_align"/>
-	<constant name="final_y4b" value="mod2_y4b+y4b_align"/>
-	<constant name="final_y5b" value="mod2_y5b+y5b_align"/>
-	<constant name="final_y6b" value="mod2_y6b+y6b_align"/>
-	<constant name="final_y7b" value="mod2_y7b+y7b_align"/>
-	<constant name="final_y8b" value="mod2_y8b+y8b_align"/>
-	<constant name="final_y9b" value="mod2_y9b+y9b_align"/>
-	<constant name="final_y10b" value="mod2_y10b+y10b_align"/>
-	<constant name="final_z1b" value="mod2_z1b+z1b_align"/>
-	<constant name="final_z2b" value="mod2_z2b+z2b_align"/>
-	<constant name="final_z3b" value="mod2_z3b+z3b_align"/>
-	<constant name="final_z4b" value="mod2_z4b+z4b_align"/>
-	<constant name="final_z5b" value="mod2_z5b+z5b_align"/>
-	<constant name="final_z6b" value="mod2_z6b+z6b_align"/>
-	<constant name="final_z7b" value="mod2_z7b+z7b_align"/>
-	<constant name="final_z8b" value="mod2_z8b+z8b_align"/>
-	<constant name="final_z9b" value="mod2_z9b+z9b_align"/>
-	<constant name="final_z10b" value="mod2_z10b+z10b_align"/>
-	<constant name="final_rx1b" value="mod2_rx1b+rx1b_align"/>
-	<constant name="final_rx2b" value="mod2_rx2b+rx2b_align"/>
-	<constant name="final_rx3b" value="mod2_rx3b+rx3b_align"/>
-	<constant name="final_rx4b" value="mod2_rx4b+rx4b_align"/>
-	<constant name="final_rx5b" value="mod2_rx5b+rx5b_align"/>
-	<constant name="final_rx6b" value="mod2_rx6b+rx6b_align"/>
-	<constant name="final_rx7b" value="mod2_rx7b+rx7b_align"/>
-	<constant name="final_rx8b" value="mod2_rx8b+rx8b_align"/>
-	<constant name="final_rx9b" value="mod2_rx9b+rx9b_align"/>
-	<constant name="final_rx10b" value="mod2_rx10b+rx10b_align"/>
-	<constant name="final_ry1b" value="mod2_ry1b+ry1b_align"/>
-	<constant name="final_ry2b" value="mod2_ry2b+ry2b_align"/>
-	<constant name="final_ry3b" value="mod2_ry3b+ry3b_align"/>
-	<constant name="final_ry4b" value="mod2_ry4b+ry4b_align"/>
-	<constant name="final_ry5b" value="mod2_ry5b+ry5b_align"/>
-	<constant name="final_ry6b" value="mod2_ry6b+ry6b_align"/>
-	<constant name="final_ry7b" value="mod2_ry7b+ry7b_align"/>
-	<constant name="final_ry8b" value="mod2_ry8b+ry8b_align"/>
-	<constant name="final_ry9b" value="mod2_ry9b+ry9b_align"/>
-	<constant name="final_ry10b" value="mod2_ry10b+ry10b_align"/>
-	<constant name="final_rz1b" value="mod2_rz1b+rz1b_align"/>
-	<constant name="final_rz2b" value="mod2_rz2b+rz2b_align"/>
-	<constant name="final_rz3b" value="mod2_rz3b+rz3b_align"/>
-	<constant name="final_rz4b" value="mod2_rz4b+rz4b_align"/>
-	<constant name="final_rz5b" value="mod2_rz5b+rz5b_align"/>
-	<constant name="final_rz6b" value="mod2_rz6b+rz6b_align"/>
-	<constant name="final_rz7b" value="mod2_rz7b+rz7b_align"/>
-	<constant name="final_rz8b" value="mod2_rz8b+rz8b_align"/>
-	<constant name="final_rz9b" value="mod2_rz9b+rz9b_align"/>
-	<constant name="final_rz10b" value="mod2_rz10b+rz10b_align"/>
-    	
-    	
+        
+        <!-- final constants -->
+    <constant name="final_x1t" value="mod2_x1t+x1t_align"/>
+    <constant name="final_x2t" value="mod2_x2t+x2t_align"/>
+    <constant name="final_x3t" value="mod2_x3t+x3t_align"/>
+    <constant name="final_x4t" value="mod2_x4t+x4t_align"/>
+    <constant name="final_x5t" value="mod2_x5t+x5t_align"/>
+    <constant name="final_x6t" value="mod2_x6t+x6t_align"/>
+    <constant name="final_x7t" value="mod2_x7t+x7t_align"/>
+    <constant name="final_x8t" value="mod2_x8t+x8t_align"/>
+    <constant name="final_x9t" value="mod2_x9t+x9t_align"/>
+    <constant name="final_x10t" value="mod2_x10t+x10t_align"/>
+    <constant name="final_y1t" value="mod2_y1t+y1t_align"/>
+    <constant name="final_y2t" value="mod2_y2t+y2t_align"/>
+    <constant name="final_y3t" value="mod2_y3t+y3t_align"/>
+    <constant name="final_y4t" value="mod2_y4t+y4t_align"/>
+    <constant name="final_y5t" value="mod2_y5t+y5t_align"/>
+    <constant name="final_y6t" value="mod2_y6t+y6t_align"/>
+    <constant name="final_y7t" value="mod2_y7t+y7t_align"/>
+    <constant name="final_y8t" value="mod2_y8t+y8t_align"/>
+    <constant name="final_y9t" value="mod2_y9t+y9t_align"/>
+    <constant name="final_y10t" value="mod2_y10t+y10t_align"/>
+    <constant name="final_z1t" value="mod2_z1t+z1t_align"/>
+    <constant name="final_z2t" value="mod2_z2t+z2t_align"/>
+    <constant name="final_z3t" value="mod2_z3t+z3t_align"/>
+    <constant name="final_z4t" value="mod2_z4t+z4t_align"/>
+    <constant name="final_z5t" value="mod2_z5t+z5t_align"/>
+    <constant name="final_z6t" value="mod2_z6t+z6t_align"/>
+    <constant name="final_z7t" value="mod2_z7t+z7t_align"/>
+    <constant name="final_z8t" value="mod2_z8t+z8t_align"/>
+    <constant name="final_z9t" value="mod2_z9t+z9t_align"/>
+    <constant name="final_z10t" value="mod2_z10t+z10t_align"/>
+    <constant name="final_rx1t" value="mod2_rx1t+rx1t_align"/>
+    <constant name="final_rx2t" value="mod2_rx2t+rx2t_align"/>
+    <constant name="final_rx3t" value="mod2_rx3t+rx3t_align"/>
+    <constant name="final_rx4t" value="mod2_rx4t+rx4t_align"/>
+    <constant name="final_rx5t" value="mod2_rx5t+rx5t_align"/>
+    <constant name="final_rx6t" value="mod2_rx6t+rx6t_align"/>
+    <constant name="final_rx7t" value="mod2_rx7t+rx7t_align"/>
+    <constant name="final_rx8t" value="mod2_rx8t+rx8t_align"/>
+    <constant name="final_rx9t" value="mod2_rx9t+rx9t_align"/>
+    <constant name="final_rx10t" value="mod2_rx10t+rx10t_align"/>
+    <constant name="final_ry1t" value="mod2_ry1t+ry1t_align"/>
+    <constant name="final_ry2t" value="mod2_ry2t+ry2t_align"/>
+    <constant name="final_ry3t" value="mod2_ry3t+ry3t_align"/>
+    <constant name="final_ry4t" value="mod2_ry4t+ry4t_align"/>
+    <constant name="final_ry5t" value="mod2_ry5t+ry5t_align"/>
+    <constant name="final_ry6t" value="mod2_ry6t+ry6t_align"/>
+    <constant name="final_ry7t" value="mod2_ry7t+ry7t_align"/>
+    <constant name="final_ry8t" value="mod2_ry8t+ry8t_align"/>
+    <constant name="final_ry9t" value="mod2_ry9t+ry9t_align"/>
+    <constant name="final_ry10t" value="mod2_ry10t+ry10t_align"/>
+    <constant name="final_rz1t" value="mod2_rz1t+rz1t_align"/>
+    <constant name="final_rz2t" value="mod2_rz2t+rz2t_align"/>
+    <constant name="final_rz3t" value="mod2_rz3t+rz3t_align"/>
+    <constant name="final_rz4t" value="mod2_rz4t+rz4t_align"/>
+    <constant name="final_rz5t" value="mod2_rz5t+rz5t_align"/>
+    <constant name="final_rz6t" value="mod2_rz6t+rz6t_align"/>
+    <constant name="final_rz7t" value="mod2_rz7t+rz7t_align"/>
+    <constant name="final_rz8t" value="mod2_rz8t+rz8t_align"/>
+    <constant name="final_rz9t" value="mod2_rz9t+rz9t_align"/>
+    <constant name="final_rz10t" value="mod2_rz10t+rz10t_align"/>
+    <constant name="final_x1b" value="mod2_x1b+x1b_align"/>
+    <constant name="final_x2b" value="mod2_x2b+x2b_align"/>
+    <constant name="final_x3b" value="mod2_x3b+x3b_align"/>
+    <constant name="final_x4b" value="mod2_x4b+x4b_align"/>
+    <constant name="final_x5b" value="mod2_x5b+x5b_align"/>
+    <constant name="final_x6b" value="mod2_x6b+x6b_align"/>
+    <constant name="final_x7b" value="mod2_x7b+x7b_align"/>
+    <constant name="final_x8b" value="mod2_x8b+x8b_align"/>
+    <constant name="final_x9b" value="mod2_x9b+x9b_align"/>
+    <constant name="final_x10b" value="mod2_x10b+x10b_align"/>
+    <constant name="final_y1b" value="mod2_y1b+y1b_align"/>
+    <constant name="final_y2b" value="mod2_y2b+y2b_align"/>
+    <constant name="final_y3b" value="mod2_y3b+y3b_align"/>
+    <constant name="final_y4b" value="mod2_y4b+y4b_align"/>
+    <constant name="final_y5b" value="mod2_y5b+y5b_align"/>
+    <constant name="final_y6b" value="mod2_y6b+y6b_align"/>
+    <constant name="final_y7b" value="mod2_y7b+y7b_align"/>
+    <constant name="final_y8b" value="mod2_y8b+y8b_align"/>
+    <constant name="final_y9b" value="mod2_y9b+y9b_align"/>
+    <constant name="final_y10b" value="mod2_y10b+y10b_align"/>
+    <constant name="final_z1b" value="mod2_z1b+z1b_align"/>
+    <constant name="final_z2b" value="mod2_z2b+z2b_align"/>
+    <constant name="final_z3b" value="mod2_z3b+z3b_align"/>
+    <constant name="final_z4b" value="mod2_z4b+z4b_align"/>
+    <constant name="final_z5b" value="mod2_z5b+z5b_align"/>
+    <constant name="final_z6b" value="mod2_z6b+z6b_align"/>
+    <constant name="final_z7b" value="mod2_z7b+z7b_align"/>
+    <constant name="final_z8b" value="mod2_z8b+z8b_align"/>
+    <constant name="final_z9b" value="mod2_z9b+z9b_align"/>
+    <constant name="final_z10b" value="mod2_z10b+z10b_align"/>
+    <constant name="final_rx1b" value="mod2_rx1b+rx1b_align"/>
+    <constant name="final_rx2b" value="mod2_rx2b+rx2b_align"/>
+    <constant name="final_rx3b" value="mod2_rx3b+rx3b_align"/>
+    <constant name="final_rx4b" value="mod2_rx4b+rx4b_align"/>
+    <constant name="final_rx5b" value="mod2_rx5b+rx5b_align"/>
+    <constant name="final_rx6b" value="mod2_rx6b+rx6b_align"/>
+    <constant name="final_rx7b" value="mod2_rx7b+rx7b_align"/>
+    <constant name="final_rx8b" value="mod2_rx8b+rx8b_align"/>
+    <constant name="final_rx9b" value="mod2_rx9b+rx9b_align"/>
+    <constant name="final_rx10b" value="mod2_rx10b+rx10b_align"/>
+    <constant name="final_ry1b" value="mod2_ry1b+ry1b_align"/>
+    <constant name="final_ry2b" value="mod2_ry2b+ry2b_align"/>
+    <constant name="final_ry3b" value="mod2_ry3b+ry3b_align"/>
+    <constant name="final_ry4b" value="mod2_ry4b+ry4b_align"/>
+    <constant name="final_ry5b" value="mod2_ry5b+ry5b_align"/>
+    <constant name="final_ry6b" value="mod2_ry6b+ry6b_align"/>
+    <constant name="final_ry7b" value="mod2_ry7b+ry7b_align"/>
+    <constant name="final_ry8b" value="mod2_ry8b+ry8b_align"/>
+    <constant name="final_ry9b" value="mod2_ry9b+ry9b_align"/>
+    <constant name="final_ry10b" value="mod2_ry10b+ry10b_align"/>
+    <constant name="final_rz1b" value="mod2_rz1b+rz1b_align"/>
+    <constant name="final_rz2b" value="mod2_rz2b+rz2b_align"/>
+    <constant name="final_rz3b" value="mod2_rz3b+rz3b_align"/>
+    <constant name="final_rz4b" value="mod2_rz4b+rz4b_align"/>
+    <constant name="final_rz5b" value="mod2_rz5b+rz5b_align"/>
+    <constant name="final_rz6b" value="mod2_rz6b+rz6b_align"/>
+    <constant name="final_rz7b" value="mod2_rz7b+rz7b_align"/>
+    <constant name="final_rz8b" value="mod2_rz8b+rz8b_align"/>
+    <constant name="final_rz9b" value="mod2_rz9b+rz9b_align"/>
+    <constant name="final_rz10b" value="mod2_rz10b+rz10b_align"/>
+        
+        
     </define>
     
     <materials>      
-    	<!-- Set the world material to vacuum. -->
+        <!-- Set the world material to vacuum. -->
         <material name="WorldMaterial">
             <D type="density" unit="g/cm3" value="0.0000000000000001"/>
             <fraction n="1.0" ref="Vacuum" />
@@ -800,7 +800,7 @@
             </layer>
             <layer id="2">
                 <module_placement name="TestRunModuleFieldDef" id="0" x="0" y="0" z="dipoleMagnetPositionZ+dipoleMagnetLength/2" rx="0" ry="0" rz="-PI/2"/>
-			</layer>
+            </layer>
         </detector>     
         
         <detector id="13" name="Ecal" type="HPSEcal3" insideTrackingVolume="false" readout="EcalHits" vis="ECALVis">

Modified: java/branches/HPSJAVA-409/detector-data/detectors/HPSTestRunTracker2014-v0/compact.xml
 =============================================================================
--- java/branches/HPSJAVA-409/detector-data/detectors/HPSTestRunTracker2014-v0/compact.xml	(original)
+++ java/branches/HPSJAVA-409/detector-data/detectors/HPSTestRunTracker2014-v0/compact.xml	Wed Apr 27 11:11:32 2016
@@ -7,9 +7,9 @@
   </info> 
   
   <define>
-	<!-- units -->
-	<constant name="mm" value="0.1*cm"/>
-	<constant name="inch" value="25.4*mm"/>
+    <!-- units -->
+    <constant name="mm" value="0.1*cm"/>
+    <constant name="inch" value="25.4*mm"/>
 
     <!-- world -->
     <constant name="world_side" value="500.0*cm" />
@@ -17,48 +17,48 @@
     <constant name="world_y" value="world_side" />
     <constant name="world_z" value="world_side" />
   
- 	 <!-- tracking region -->
- 	<constant name="tracking_region_radius" value="200.0*cm"/>
+     <!-- tracking region -->
+    <constant name="tracking_region_radius" value="200.0*cm"/>
     <constant name="tracking_region_min" value="5.0*cm"/>
     <constant name="tracking_region_zmax" value="131.8*cm"/>
     
      <!--  dipole magnet and  B-field -->
-	<constant name="dipoleMagnetPositionZ" value="45.72*cm" />
-	<constant name="dipoleMagnetHeight" value="17.78*cm" />
-	<constant name="dipoleMagnetWidth" value="41.6052*cm" />
-	<constant name="dipoleMagnetLength" value="dipoleMagnetPositionZ*2.0" />
-	<constant name="constBFieldY" value="-0.491" />
+    <constant name="dipoleMagnetPositionZ" value="45.72*cm" />
+    <constant name="dipoleMagnetHeight" value="17.78*cm" />
+    <constant name="dipoleMagnetWidth" value="41.6052*cm" />
+    <constant name="dipoleMagnetLength" value="dipoleMagnetPositionZ*2.0" />
+    <constant name="constBFieldY" value="-0.491" />
  
-	<!-- ECAL -->
+    <!-- ECAL -->
     <constant name="ecal_front" value="13.3/2*mm" />
-	<constant name="ecal_back" value="16/2*mm" />
-	<constant name="ecal_z" value="160/2*mm" />
-   	<constant name="ecal_dx" value="41.27*mm" />
+    <constant name="ecal_back" value="16/2*mm" />
+    <constant name="ecal_z" value="160/2*mm" />
+    <constant name="ecal_dx" value="41.27*mm" />
  
   </define>
   
   <materials>
-  	<!-- Set the world material to vacuum. -->
+    <!-- Set the world material to vacuum. -->
     <material name="WorldMaterial">
-    	<D type="density" unit="g/cm3" value="0.0000000000000001"/>
-    	<fraction n="1.0" ref="Vacuum" />
+        <D type="density" unit="g/cm3" value="0.0000000000000001"/>
+        <fraction n="1.0" ref="Vacuum" />
     </material>
     <!-- Set tracking material to vacuum. -->
     <material name="TrackingMaterial">
       <D type="density" unit="g/cm3" value="0.0000000000000001" />
       <fraction n="1.0" ref="Vacuum" />
     </material>
-	<!-- ECal crystal material. -->
-	<material name="LeadTungstate">
-		<D value="8.28" unit="g/cm3" />
-		<composite n="1" ref="Pb" />
-		<composite n="1" ref="W" />
-		<composite n="4" ref="O" />
-	</material>
+    <!-- ECal crystal material. -->
+    <material name="LeadTungstate">
+        <D value="8.28" unit="g/cm3" />
+        <composite n="1" ref="Pb" />
+        <composite n="1" ref="W" />
+        <composite n="4" ref="O" />
+    </material>
   </materials>
   
   <display>
-	
+    
     <vis name="SensorVis" alpha="1.0" r="1.0" g="0.0" b="0.0" drawingStyle="wireframe" lineStyle="unbroken" showDaughters="true" visible="true"/>
     <vis name="ActiveSensorVis" alpha="1.0" r="1.0" g="0.0" b="0.0" drawingStyle="solid" lineStyle="unbroken" showDaughters="true" visible="true"/>
     <vis name="CarbonFiberVis" alpha="1.0" r="0.88" g="0.88" b="0.88" drawingStyle="solid" lineStyle="unbroken" showDaughters="true" visible="true"/>
@@ -72,14 +72,14 @@
     <vis name="BasePlateVis" alpha="1.0" r="0.35" g="0.35" b="0.35" drawingStyle="solid" lineStyle="dashed" showDaughters="true" visible="true"/>
     <vis name="LayerVis" alpha="0.0" r="0.0" g="0.0" b="1.0" drawingStyle="wireframe" showDaughters="true" visible="false"/>
     <vis name="ComponentVis" alpha="0.0" r="0.0" g="0.2" b="0.4" drawingStyle="solid" showDaughters="false" visible="false"/>
-	<vis name="BeamPlaneVis" alpha="1.0" r="1.0" g="1.0" b="1.0" drawingStyle="solid" lineStyle="unbroken" showDaughters="false" visible="true"/>
+    <vis name="BeamPlaneVis" alpha="1.0" r="1.0" g="1.0" b="1.0" drawingStyle="solid" lineStyle="unbroken" showDaughters="false" visible="true"/>
 
     <vis name="ECALVis" r="0.8" g="0.5" b="0.1" />
   </display>
   
   <detectors>
     <detector id="1" name="Tracker" type="HPSTestRunTracker2014" readout="TrackerHits">
-	   <millepede_constants>
+       <millepede_constants>
             <!-- top translations -->
             <millepede_constant name="11101" value="0.0"/>
             <millepede_constant name="11102" value="0.0"/>
@@ -234,43 +234,43 @@
      
     </detector>
 
-	<detector id="30" name="TrackerFieldDef" type="HPSTracker2"
-		readout="TrackerHitsThin">
-		<comment>The Silicon Vertex Tracker</comment>
-		<module name="TestRunModuleFieldDef">
-			<box x="dipoleMagnetWidth*4+1" y="dipoleMagnetHeight*4+1" />
-			<module_component thickness="0.000000001*cm"
-				material="Vacuum" sensitive="true">
-				<dimensions x="dipoleMagnetWidth*4" y="dipoleMagnetHeight*4" />
-			</module_component>
-		</module>
-		<layer id="1">
-			<module_placement name="TestRunModuleFieldDef" id="0"
-				x="0" y="0" z="dipoleMagnetPositionZ-dipoleMagnetLength/2" rx="0"
-				ry="0" rz="-PI/2" />
-		</layer>
-		<layer id="2">
-			<module_placement name="TestRunModuleFieldDef" id="0"
-				x="0" y="0" z="dipoleMagnetPositionZ+dipoleMagnetLength/2" rx="0"
-				ry="0" rz="-PI/2" />
-		</layer>
-	</detector>
-
-	<detector id="13" name="Ecal" type="HPSEcal3"
-		insideTrackingVolume="false" readout="EcalHits" vis="ECALVis">
-		<comment>The crystal ECal</comment>
-		<material name="LeadTungstate" />
-		<dimensions x1="ecal_front" y1="ecal_front" x2="ecal_back"
-			y2="ecal_back" z="ecal_z" />
-		<!-- Measurements as found in installation by Stepan -->
-		<!-- Moving ecal halves out by 6.5mm from SVT ecal-track matching - Pelle -->
-		<!-- Moving ecal face to reflect latest survey calculation 2/17/14 - Pelle -->
-		<layout beamgap="43.5*mm" nx="46" ny="5" dface="147.0*cm">
-			<remove ixmin="-10" ixmax="-2" iymin="-1" iymax="1" />
-			<top dx="ecal_dx" dy="0." dz="0." />
-			<bottom dx="ecal_dx" dy="0." dz="0." />
-		</layout>
-	</detector>
+    <detector id="30" name="TrackerFieldDef" type="HPSTracker2"
+        readout="TrackerHitsThin">
+        <comment>The Silicon Vertex Tracker</comment>
+        <module name="TestRunModuleFieldDef">
+            <box x="dipoleMagnetWidth*4+1" y="dipoleMagnetHeight*4+1" />
+            <module_component thickness="0.000000001*cm"
+                material="Vacuum" sensitive="true">
+                <dimensions x="dipoleMagnetWidth*4" y="dipoleMagnetHeight*4" />
+            </module_component>
+        </module>
+        <layer id="1">
+            <module_placement name="TestRunModuleFieldDef" id="0"
+                x="0" y="0" z="dipoleMagnetPositionZ-dipoleMagnetLength/2" rx="0"
+                ry="0" rz="-PI/2" />
+        </layer>
+        <layer id="2">
+            <module_placement name="TestRunModuleFieldDef" id="0"
+                x="0" y="0" z="dipoleMagnetPositionZ+dipoleMagnetLength/2" rx="0"
+                ry="0" rz="-PI/2" />
+        </layer>
+    </detector>
+
+    <detector id="13" name="Ecal" type="HPSEcal3"
+        insideTrackingVolume="false" readout="EcalHits" vis="ECALVis">
+        <comment>The crystal ECal</comment>
+        <material name="LeadTungstate" />
+        <dimensions x1="ecal_front" y1="ecal_front" x2="ecal_back"
+            y2="ecal_back" z="ecal_z" />
+        <!-- Measurements as found in installation by Stepan -->
+        <!-- Moving ecal halves out by 6.5mm from SVT ecal-track matching - Pelle -->
+        <!-- Moving ecal face to reflect latest survey calculation 2/17/14 - Pelle -->
+        <layout beamgap="43.5*mm" nx="46" ny="5" dface="147.0*cm">
+            <remove ixmin="-10" ixmax="-2" iymin="-1" iymax="1" />
+            <top dx="ecal_dx" dy="0." dz="0." />
+            <bottom dx="ecal_dx" dy="0." dz="0." />
+        </layout>
+    </detector>
     
      
     
@@ -279,28 +279,28 @@
     <readout name="TrackerHits">
       <id>system:6,barrel:3,layer:4,module:12,sensor:1,side:32:-2,strip:12</id>
     </readout>
-	<readout name="TrackerHitsThin">
-		<id>system:6,barrel:3,layer:4,module:12,sensor:1,side:32:-2,strip:12</id>
-	</readout>
-
-	<readout name="EcalHits">
-		<segmentation type="GridXYZ" gridSizeX="0.0" gridSizeY="0.0"
-			gridSizeZ="0.0" />
-		<id>system:6,layer:2,ix:-8,iy:-6</id>
-	</readout>
+    <readout name="TrackerHitsThin">
+        <id>system:6,barrel:3,layer:4,module:12,sensor:1,side:32:-2,strip:12</id>
+    </readout>
+
+    <readout name="EcalHits">
+        <segmentation type="GridXYZ" gridSizeX="0.0" gridSizeY="0.0"
+            gridSizeZ="0.0" />
+        <id>system:6,layer:2,ix:-8,iy:-6</id>
+    </readout>
   </readouts>
 
-	<fields>
-		<field type="BoxDipole" name="AnalyzingDipole" x="0*cm" y="0*cm"
-			z="dipoleMagnetPositionZ" dx="dipoleMagnetWidth/2.0" dy="dipoleMagnetHeight/2.0"
-			dz="dipoleMagnetLength/2.0" bx="0.0" by="constBFieldY" bz="0.0" />
-	</fields>
+    <fields>
+        <field type="BoxDipole" name="AnalyzingDipole" x="0*cm" y="0*cm"
+            z="dipoleMagnetPositionZ" dx="dipoleMagnetWidth/2.0" dy="dipoleMagnetHeight/2.0"
+            dz="dipoleMagnetLength/2.0" bx="0.0" by="constBFieldY" bz="0.0" />
+    </fields>
 
 <!-- 
-	<includes>
-		<gdmlFile
-			ref="http://www.lcsim.org/test/gdml/testRunDownstreamVacuumFlange.gdml" />
-	</includes>
+    <includes>
+        <gdmlFile
+            ref="http://www.lcsim.org/test/gdml/testRunDownstreamVacuumFlange.gdml" />
+    </includes>
     -->
  
 </lccdd>

Modified: java/branches/HPSJAVA-409/detector-data/pom.xml
 =============================================================================
--- java/branches/HPSJAVA-409/detector-data/pom.xml	(original)
+++ java/branches/HPSJAVA-409/detector-data/pom.xml	Wed Apr 27 11:11:32 2016
@@ -8,7 +8,7 @@
         <groupId>org.hps</groupId>
         <artifactId>hps-parent</artifactId>
         <relativePath>../parent/pom.xml</relativePath>
-        <version>3.4.2-SNAPSHOT</version>
+        <version>3.9-SNAPSHOT</version>
     </parent>
     <scm>
         <url>http://java.freehep.org/svn/repos/hps/list/java/trunk/detector-data/</url>

Modified: java/branches/HPSJAVA-409/detector-model/pom.xml
 =============================================================================
--- java/branches/HPSJAVA-409/detector-model/pom.xml	(original)
+++ java/branches/HPSJAVA-409/detector-model/pom.xml	Wed Apr 27 11:11:32 2016
@@ -8,7 +8,7 @@
         <groupId>org.hps</groupId>
         <artifactId>hps-parent</artifactId>
         <relativePath>../parent/pom.xml</relativePath>
-        <version>3.4.2-SNAPSHOT</version>
+        <version>3.9-SNAPSHOT</version>
     </parent>
     <build>
         <plugins>

Modified: java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/detector/converter/compact/HPSTestRunTracker2014Converter.java
 =============================================================================
--- java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/detector/converter/compact/HPSTestRunTracker2014Converter.java	(original)
+++ java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/detector/converter/compact/HPSTestRunTracker2014Converter.java	Wed Apr 27 11:11:32 2016
@@ -11,7 +11,6 @@
 import org.lcsim.geometry.compact.converter.HPSTestRunTracker2014JavaBuilder;
 import org.lcsim.geometry.compact.converter.HPSTrackerBuilder;
 import org.lcsim.geometry.compact.converter.HPSTrackerJavaBuilder;
-import org.lcsim.geometry.compact.converter.JavaSurveyVolume;
 import org.lcsim.geometry.subdetector.HPSTestRunTracker2014;
 
 /**
@@ -21,21 +20,21 @@
  */
 public class HPSTestRunTracker2014Converter extends HPSTracker2014ConverterBase {
 
-	public HPSTestRunTracker2014Converter() {
-		super();
-	}
-	
-	/* (non-Javadoc)
-	 * @see org.lcsim.detector.converter.compact.HPSTracker2014ConverterBase#initializeBuilder(org.jdom.Element)
-	 */
-	protected HPSTrackerJavaBuilder initializeBuilder(Element node) {
-	     return new HPSTestRunTracker2014JavaBuilder(_debug,node);
-	 }
+    public HPSTestRunTracker2014Converter() {
+        super();
+    }
     
-	/* (non-Javadoc)
-	 * @see org.lcsim.detector.converter.compact.AbstractSubdetectorConverter#getSubdetectorType()
-	 */
-	public Class getSubdetectorType() {
+    /* (non-Javadoc)
+     * @see org.lcsim.detector.converter.compact.HPSTracker2014ConverterBase#initializeBuilder(org.jdom.Element)
+     */
+    protected HPSTrackerJavaBuilder initializeBuilder(Element node) {
+         return new HPSTestRunTracker2014JavaBuilder(_debug,node);
+     }
+    
+    /* (non-Javadoc)
+     * @see org.lcsim.detector.converter.compact.AbstractSubdetectorConverter#getSubdetectorType()
+     */
+    public Class getSubdetectorType() {
         return HPSTestRunTracker2014.class;
     }
 
@@ -53,5 +52,5 @@
     protected int getModuleNumber(String surveyVolume) {
         return HPSTrackerBuilder.getHalfFromName(surveyVolume).equals("top") ? 0 : 1;
     }
-	
+    
 }

Modified: java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/detector/converter/compact/HPSTracker2014Converter.java
 =============================================================================
--- java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/detector/converter/compact/HPSTracker2014Converter.java	(original)
+++ java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/detector/converter/compact/HPSTracker2014Converter.java	Wed Apr 27 11:11:32 2016
@@ -7,7 +7,6 @@
 import org.lcsim.geometry.compact.converter.HPSTracker2014JavaBuilder;
 import org.lcsim.geometry.compact.converter.HPSTrackerBuilder;
 import org.lcsim.geometry.compact.converter.HPSTrackerJavaBuilder;
-import org.lcsim.geometry.compact.converter.JavaSurveyVolume;
 import org.lcsim.geometry.subdetector.HPSTracker2014;
 
 

Modified: java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/detector/converter/compact/HPSTracker2014ConverterBase.java
 =============================================================================
--- java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/detector/converter/compact/HPSTracker2014ConverterBase.java	(original)
+++ java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/detector/converter/compact/HPSTracker2014ConverterBase.java	Wed Apr 27 11:11:32 2016
@@ -71,7 +71,7 @@
      * @see org.lcsim.detector.converter.compact.AbstractSubdetectorConverter#makeIdentifierHelper(org.lcsim.geometry.compact.Subdetector, org.lcsim.detector.DetectorIdentifierHelper.SystemMap)
      */
     public IIdentifierHelper makeIdentifierHelper(Subdetector subdetector, SystemMap systemMap) {
-    	return new SiTrackerIdentifierHelper(subdetector.getDetectorElement(), makeIdentifierDictionary(subdetector), systemMap);
+        return new SiTrackerIdentifierHelper(subdetector.getDetectorElement(), makeIdentifierDictionary(subdetector), systemMap);
     }
 
     

Modified: java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/detector/converter/compact/HPSTrackerConverter.java
 =============================================================================
--- java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/detector/converter/compact/HPSTrackerConverter.java	(original)
+++ java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/detector/converter/compact/HPSTrackerConverter.java	Wed Apr 27 11:11:32 2016
@@ -1,8 +1,4 @@
 package org.lcsim.detector.converter.compact;
-
-import hep.physics.matrix.BasicMatrix;
-import hep.physics.vec.BasicHep3Vector;
-import hep.physics.vec.VecOp;
 
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -16,15 +12,11 @@
 import org.lcsim.detector.DetectorIdentifierHelper;
 import org.lcsim.detector.DetectorIdentifierHelper.SystemMap;
 import org.lcsim.detector.IDetectorElement;
-
 import org.lcsim.detector.IPhysicalVolume;
 import org.lcsim.detector.IPhysicalVolumePath;
-import org.lcsim.detector.IRotation3D;
-import org.lcsim.detector.ITranslation3D;
 import org.lcsim.detector.LogicalVolume;
 import org.lcsim.detector.PhysicalVolume;
 import org.lcsim.detector.RotationGeant;
-import org.lcsim.detector.RotationPassiveXYZ;
 import org.lcsim.detector.Transform3D;
 import org.lcsim.detector.Translation3D;
 import org.lcsim.detector.identifier.ExpandedIdentifier;
@@ -35,10 +27,7 @@
 import org.lcsim.detector.material.IMaterial;
 import org.lcsim.detector.material.MaterialStore;
 import org.lcsim.detector.solids.Box;
-import org.lcsim.detector.solids.Polygon3D;
-import org.lcsim.detector.tracker.silicon.ChargeCarrier;
 import org.lcsim.detector.tracker.silicon.SiSensor;
-import org.lcsim.detector.tracker.silicon.SiStrips;
 import org.lcsim.detector.tracker.silicon.SiTrackerIdentifierHelper;
 import org.lcsim.detector.tracker.silicon.SiTrackerModule;
 import org.lcsim.geometry.compact.Detector;
@@ -238,7 +227,7 @@
     {
         //double moduleX = moduleParameters.getDimension(0);
         //double moduleY = moduleParameters.getDimension(1);        
-    	double moduleY = moduleParameters.getDimension(0);
+        double moduleY = moduleParameters.getDimension(0);
         double moduleX = moduleParameters.getDimension(1);
         Box box = (Box)moduleVolume.getSolid();
         double moduleZ = box.getZHalfLength() * 2;                        
@@ -375,7 +364,7 @@
     /*
     private void configSensor(SiSensor sensor)
     {
-    	//
+        //
         Box sensorSolid = (Box) sensor.getGeometry().getLogicalVolume().getSolid();                                                        
         
         Polygon3D pside = sensorSolid.getFacesNormalTo(new BasicHep3Vector(0, 0, 1)).get(0);

Modified: java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/detector/converter/compact/subdetector/HpsTracker2.java
 =============================================================================
--- java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/detector/converter/compact/subdetector/HpsTracker2.java	(original)
+++ java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/detector/converter/compact/subdetector/HpsTracker2.java	Wed Apr 27 11:11:32 2016
@@ -8,7 +8,7 @@
 import org.lcsim.detector.converter.compact.SubdetectorDetectorElement;
 import org.lcsim.detector.tracker.silicon.HpsSiSensor;
 /**
- * Class describing an {@link HPSTracker2} subdetector. 
+ * Detector element for <code>HPSTracker2</code> type.
  * 
  * @author Omar Moreno <[log in to unmask]>
  * @author Jeremy McCormick <[log in to unmask]>
@@ -19,89 +19,89 @@
     private boolean debug = false;
     
     // List of stereo layers composing the SVT
-	List<SvtStereoLayer> stereoPairs = new ArrayList<SvtStereoLayer>(); 
-	
-	public HpsTracker2(String name, IDetectorElement parent) {
-		super(name, parent);
-	}
-	
-	/**
-	 * Get a collection of stereo pairs ({@link SvtStereoLayer}) composing the SVT.
-	 * 
-	 * @return List of stereo pairs
-	 */
-	public List<SvtStereoLayer> getStereoPairs(){
-	    return Collections.unmodifiableList(stereoPairs);
-	}
+    List<SvtStereoLayer> stereoPairs = new ArrayList<SvtStereoLayer>(); 
+    
+    public HpsTracker2(String name, IDetectorElement parent) {
+        super(name, parent);
+    }
+    
+    /**
+     * Get a collection of stereo pairs ({@link SvtStereoLayer}) composing the SVT.
+     * 
+     * @return List of stereo pairs
+     */
+    public List<SvtStereoLayer> getStereoPairs(){
+        return Collections.unmodifiableList(stereoPairs);
+    }
 
-	/**
-	 * Get the collection of {@link HpsSiSensor} composing the SVT. 
-	 * 
-	 * @return List of sensors
-	 */
-	public List<HpsSiSensor> getSensors(){
-	    List<HpsSiSensor> list = this.findDescendants(HpsSiSensor.class);
-	    if(debug) {
-	        System.out.printf("%s: found %d HpsSiSensors\n",getClass().getSimpleName(), list.size());
-	        System.out.printf("%s: %45s %5s %5s\n",getClass().getSimpleName(), "<name>", "<layerID>", "<moduleID>");
-	        for(HpsSiSensor sensor : list) {
-	            System.out.printf("%s: %45s %5d %5d\n",getClass().getSimpleName(), sensor.getName(), sensor.getLayerNumber(), sensor.getModuleNumber());
-	        }
-	    }
-	    return list;
-	}
-	
-	/**
-	 * Get a {@link HpsSiSensor} by layer and module number.
-	 * 
-	 * @param layer The SVT layer number
-	 * @param module The SVT module number
-	 * @return Corresponding sensor
-	 */
-	public HpsSiSensor getSensor(int layer, int module){
-	    for(HpsSiSensor sensor : this.getSensors()){
-	        if(sensor.getLayerNumber() == layer && sensor.getModuleNumber() == module) 
-	            return sensor; 
-	    }
-	    return null;
-	}
-	
-	/**
-	 * Get the maximum layer number present in the collection of {@link HpsSiSensor}.
-	 * 
-	 * @return maximum layer number
-	 */
-	private int getMaxLayerNumber(){
-	    int maxLayerNumber = 0;
-	    for(HpsSiSensor sensor : this.getSensors()){
-	       if(sensor.getLayerNumber() > maxLayerNumber) maxLayerNumber = sensor.getLayerNumber();
-	    }
-	    return maxLayerNumber; 
-	}
+    /**
+     * Get the collection of {@link HpsSiSensor} composing the SVT. 
+     * 
+     * @return List of sensors
+     */
+    public List<HpsSiSensor> getSensors(){
+        List<HpsSiSensor> list = this.findDescendants(HpsSiSensor.class);
+        if(debug) {
+            System.out.printf("%s: found %d HpsSiSensors\n",getClass().getSimpleName(), list.size());
+            System.out.printf("%s: %45s %5s %5s\n",getClass().getSimpleName(), "<name>", "<layerID>", "<moduleID>");
+            for(HpsSiSensor sensor : list) {
+                System.out.printf("%s: %45s %5d %5d\n",getClass().getSimpleName(), sensor.getName(), sensor.getLayerNumber(), sensor.getModuleNumber());
+            }
+        }
+        return list;
+    }
+    
+    /**
+     * Get a {@link HpsSiSensor} by layer and module number.
+     * 
+     * @param layer The SVT layer number
+     * @param module The SVT module number
+     * @return Corresponding sensor
+     */
+    public HpsSiSensor getSensor(int layer, int module){
+        for(HpsSiSensor sensor : this.getSensors()){
+            if(sensor.getLayerNumber() == layer && sensor.getModuleNumber() == module) 
+                return sensor; 
+        }
+        return null;
+    }
+    
+    /**
+     * Get the maximum layer number present in the collection of {@link HpsSiSensor}.
+     * 
+     * @return maximum layer number
+     */
+    private int getMaxLayerNumber(){
+        int maxLayerNumber = 0;
+        for(HpsSiSensor sensor : this.getSensors()){
+           if(sensor.getLayerNumber() > maxLayerNumber) maxLayerNumber = sensor.getLayerNumber();
+        }
+        return maxLayerNumber; 
+    }
 
-	/**
-	 * Get the maximum module number present in the collection of {@link HpsSiSensor}.
-	 * 
-	 * @return maximum module number
-	 */
-	private int getMaxModuleNumber(){
-	    int maxModuleID = 0; 
-	    for(HpsSiSensor sensor : this.getSensors()){
-	       if(sensor.getModuleNumber() > maxModuleID) maxModuleID = sensor.getModuleNumber();
-	    }
-	    return maxModuleID; 
-	}
-	
-	/**
-	 * Method that loops through the collection of {@link HpsSiSensor} and creates 
-	 * stereo layers. A stereo layer is composed of two adjacent sensors (stereo and axial)
-	 * with the same module number.
-	 */
-	public void createStereoLayers(){
+    /**
+     * Get the maximum module number present in the collection of {@link HpsSiSensor}.
+     * 
+     * @return maximum module number
+     */
+    private int getMaxModuleNumber(){
+        int maxModuleID = 0; 
+        for(HpsSiSensor sensor : this.getSensors()){
+           if(sensor.getModuleNumber() > maxModuleID) maxModuleID = sensor.getModuleNumber();
+        }
+        return maxModuleID; 
+    }
+    
+    /**
+     * Method that loops through the collection of {@link HpsSiSensor} and creates 
+     * stereo layers. A stereo layer is composed of two adjacent sensors (stereo and axial)
+     * with the same module number.
+     */
+    public void createStereoLayers(){
 
-	    //System.out.printf("%s: create stereo layers\n",getClass().getSimpleName());
+        //System.out.printf("%s: create stereo layers\n",getClass().getSimpleName());
         
-	    HpsSiSensor firstSensor = null;
+        HpsSiSensor firstSensor = null;
         HpsSiSensor secondSensor = null;
 
         //System.out.printf("%s: %10s %10s %42s %42s\n",getClass().getSimpleName(), "layerID/moduleID", "layerID/moduleID", "sensor1", "sensor2");

Modified: java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/detector/converter/compact/subdetector/SvtStereoLayer.java
 =============================================================================
--- java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/detector/converter/compact/subdetector/SvtStereoLayer.java	(original)
+++ java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/detector/converter/compact/subdetector/SvtStereoLayer.java	Wed Apr 27 11:11:32 2016
@@ -9,76 +9,76 @@
  */
 public class SvtStereoLayer {
 
-	
-	// Layer number to which the stereo pair belongs to
-	private int stereoLayerNumber = 0; 
-	
-	// The axial and stereo sensors
-	private HpsSiSensor axialSensor = null; 
-	private HpsSiSensor stereoSensor = null;
-	
-	
-	/**
-	 * Ctor
-	 * 
-	 * @param layerNumber  Layer number to which the stereo pair belongs to
-	 * @param firstSensor  The first sensor in the stereo layer 
-	 * @param secondSensor The second sensor in the stereo layer
-	 */
-	public SvtStereoLayer(int stereoLayerNumber, HpsSiSensor firstSensor, HpsSiSensor secondSensor){
-		this.stereoLayerNumber = stereoLayerNumber;
-		if(firstSensor.isAxial()){
-		    this.axialSensor = firstSensor; 
-		    this.stereoSensor = secondSensor; 
-		} else { 
-		    this.axialSensor = secondSensor; 
-		    this.stereoSensor = firstSensor; 
-		}
-	}
-	
-	
-	/**
-	 * Get the axial sensor of the stereo pair
-	 * 
-	 * @return Axial sensor. Returns null if it hasn't been set yet.
-	 */
-	public HpsSiSensor getAxialSensor(){
-		return axialSensor; 
-	}
-	
-	/**
-	 * Get the stereo sensor of the stereo pair
-	 * 
-	 * @return Stereo sensor. Returns null if it hasn't been set yet.
-	 */
-	public HpsSiSensor getStereoSensor(){
-		return stereoSensor; 
-	}
+    
+    // Layer number to which the stereo pair belongs to
+    private int stereoLayerNumber = 0; 
+    
+    // The axial and stereo sensors
+    private HpsSiSensor axialSensor = null; 
+    private HpsSiSensor stereoSensor = null;
+    
+    
+    /**
+     * Ctor
+     * 
+     * @param stereoLayerNumber  Layer number to which the stereo pair belongs
+     * @param firstSensor  The first sensor in the stereo layer 
+     * @param secondSensor The second sensor in the stereo layer
+     */
+    public SvtStereoLayer(int stereoLayerNumber, HpsSiSensor firstSensor, HpsSiSensor secondSensor){
+        this.stereoLayerNumber = stereoLayerNumber;
+        if(firstSensor.isAxial()){
+            this.axialSensor = firstSensor; 
+            this.stereoSensor = secondSensor; 
+        } else { 
+            this.axialSensor = secondSensor; 
+            this.stereoSensor = firstSensor; 
+        }
+    }
+    
+    
+    /**
+     * Get the axial sensor of the stereo pair
+     * 
+     * @return Axial sensor. Returns null if it hasn't been set yet.
+     */
+    public HpsSiSensor getAxialSensor(){
+        return axialSensor; 
+    }
+    
+    /**
+     * Get the stereo sensor of the stereo pair
+     * 
+     * @return Stereo sensor. Returns null if it hasn't been set yet.
+     */
+    public HpsSiSensor getStereoSensor(){
+        return stereoSensor; 
+    }
 
-	/**
-	 * Get the layer number to which the stereo pair belongs to.
-	 * 
-	 * @return stereo layer number
-	 */
-	public int getLayerNumber(){
-		return stereoLayerNumber; 
-	}
-	
-	/**
-	 * Return a string describing the stereo pair
-	 * 
-	 * @return stereo pair description
-	 */
-	@Override
-	public String toString(){
-	    StringBuffer buffer = new StringBuffer();
-	    buffer.append("[ Stereo Pair ]: Layer number: " + this.getLayerNumber() + "\n");
-	    buffer.append("\t\tAxial Sensor: ");
-	    buffer.append(axialSensor == null ? "None" : axialSensor.getName());
-	    buffer.append("\tStereo Sensor: ");
-		buffer.append(stereoSensor == null ? "None" : stereoSensor.getName());
-		return buffer.toString(); 
-	}
+    /**
+     * Get the layer number to which the stereo pair belongs to.
+     * 
+     * @return stereo layer number
+     */
+    public int getLayerNumber(){
+        return stereoLayerNumber; 
+    }
+    
+    /**
+     * Return a string describing the stereo pair
+     * 
+     * @return stereo pair description
+     */
+    @Override
+    public String toString(){
+        StringBuffer buffer = new StringBuffer();
+        buffer.append("[ Stereo Pair ]: Layer number: " + this.getLayerNumber() + "\n");
+        buffer.append("\t\tAxial Sensor: ");
+        buffer.append(axialSensor == null ? "None" : axialSensor.getName());
+        buffer.append("\tStereo Sensor: ");
+        buffer.append(stereoSensor == null ? "None" : stereoSensor.getName());
+        return buffer.toString(); 
+    }
 
 }
 

Modified: java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/detector/tracker/silicon/HpsSiSensor.java
 =============================================================================
--- java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/detector/tracker/silicon/HpsSiSensor.java	(original)
+++ java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/detector/tracker/silicon/HpsSiSensor.java	Wed Apr 27 11:11:32 2016
@@ -303,9 +303,8 @@
     /**
      * Generate an ID for a channel (strip) on a sensor.
      *
-     * @param sensor
      * @param channel : Physical channel number
-     * @return ID
+     * @return the channel ID
      */
     public long makeChannelID(final int channel) {
         final int sideNumber = this.hasElectrodesOnSide(ChargeCarrier.HOLE) ? ChargeCarrier.HOLE.charge()
@@ -385,7 +384,7 @@
     /**
      * Set the front end board (FEB) ID of the sensor.
      * 
-     * @param FEB ID The FEB ID of the sensor.
+     * @param febID FEB ID The FEB ID of the sensor.
      */
     public void setFebID(final int febID) {
         this.febID = febID;
@@ -394,7 +393,7 @@
     /**
      * Set the FEB hybrid ID of the sensor.
      * 
-     * @param FEB hybrid ID The FEB hybrid ID.
+     * @param febHybridID FEB hybrid ID The FEB hybrid ID.
      */
     public void setFebHybridID(final int febHybridID) {
         this.febHybridID = febHybridID;
@@ -412,7 +411,7 @@
     /**
      * Flag the sensor as being axial.
      * 
-     * @param true if the sensor is Axial, false otherwise
+     * @param isAxial true if the sensor is Axial, false otherwise
      */
     public void setAxial(final boolean isAxial) {
         this.isAxial = isAxial;
@@ -421,7 +420,7 @@
     /**
      * Flag the sensor as being stereo
      * 
-     * @param true is the sensor is stereo, false otherwise
+     * @param isStereo true is the sensor is stereo, false otherwise
      */
     public void setStereo(final boolean isStereo) {
         this.isStereo = isStereo;
@@ -449,6 +448,8 @@
         buffer.append("\n");
         buffer.append("----------------------------------");
         buffer.append("\n");
+        buffer.append("Feb ID: " + this.getFebID() + "\n");
+        buffer.append("Feb Hybrid ID: " + this.getFebHybridID() + "\n");
         buffer.append("Layer: " + this.getLayerNumber() + "\n");
         buffer.append("Module: " + this.getModuleNumber() + "\n");
         buffer.append("Number of readout strips: " + this.getReadoutElectrodes(ChargeCarrier.HOLE).getNCells() + "\n");

Modified: java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/detector/tracker/silicon/HpsTestRunSiSensor.java
 =============================================================================
--- java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/detector/tracker/silicon/HpsTestRunSiSensor.java	(original)
+++ java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/detector/tracker/silicon/HpsTestRunSiSensor.java	Wed Apr 27 11:11:32 2016
@@ -14,85 +14,85 @@
  * @author Omar Moreno <[log in to unmask]>
  */
 public class HpsTestRunSiSensor extends HpsSiSensor {
-	
-	
-	protected int fpgaID;
-	protected int hybridID;
-			
-	
-	/**
-	 * This class constructor matches the signature of <code>SiSensor</code>.
-	 * @param sensorid The sensor ID.
-	 * @param name The name of the sensor.
-	 * @param parent The parent DetectorElement.
-	 * @param support The physical support path.
-	 * @param id The identifier of the sensor.
-	 */
-	public HpsTestRunSiSensor(
+    
+    
+    protected int fpgaID;
+    protected int hybridID;
+            
+    
+    /**
+     * This class constructor matches the signature of <code>SiSensor</code>.
+     * @param sensorid The sensor ID.
+     * @param name The name of the sensor.
+     * @param parent The parent DetectorElement.
+     * @param support The physical support path.
+     * @param id The identifier of the sensor.
+     */
+    public HpsTestRunSiSensor(
             int sensorid,
             String name,
             IDetectorElement parent,
             String support,
             IIdentifier id)
     {
-		super(sensorid, name, parent, support, id);
+        super(sensorid, name, parent, support, id);
     }
-	
-	
+    
+    
 
-	/**
-	 * Get the FPGA ID associated with this sensor.
-	 * 
-	 * @return The FPGA ID
-	 */
-	public int getFpgaID() {
-		return fpgaID;
-	}
+    /**
+     * Get the FPGA ID associated with this sensor.
+     * 
+     * @return The FPGA ID
+     */
+    public int getFpgaID() {
+        return fpgaID;
+    }
 
-	/**
-	 * Get the hybrid ID associated with this sensor.
-	 * 
-	 * @return The hybrid ID
-	 */
-	public int getHybridID() {
-		return hybridID;
-	}
+    /**
+     * Get the hybrid ID associated with this sensor.
+     * 
+     * @return The hybrid ID
+     */
+    public int getHybridID() {
+        return hybridID;
+    }
 
-	@Override
-	public int getFebID(){
-	    throw new RuntimeException("This method is not supported for the HpsTestRunSiSensor.");
-	}
-	
-	@Override
-	public int getFebHybridID(){
-	    throw new RuntimeException("This method is not supported for the HpsTestRunSiSensor.");
-	}
+    @Override
+    public int getFebID(){
+        throw new RuntimeException("This method is not supported for the HpsTestRunSiSensor.");
+    }
+    
+    @Override
+    public int getFebHybridID(){
+        throw new RuntimeException("This method is not supported for the HpsTestRunSiSensor.");
+    }
 
-	/**
-	 * Set the FPGA ID associated with this sensor.
-	 * 
-	 * @param The FPGA ID
-	 */
-	public void setFpgaID(int fpgaID) {
-		this.fpgaID = fpgaID;
-	}
+    /**
+     * Set the FPGA ID associated with this sensor.
+     * 
+     * @param fpgaID The FPGA ID
+     */
+    public void setFpgaID(int fpgaID) {
+        this.fpgaID = fpgaID;
+    }
 
-	/**
-	 * Set the hybrid ID associated with this sensor.
-	 * 
-	 * @param The hybrid ID.
-	 */
-	public void setHybridID(int hybridID) {
-		this.hybridID = hybridID;
-	}
-	
-	@Override
-	public void setFebID(int febID) {
-	    throw new RuntimeException("This method is not supported for the HpsTestRunSiSensor.");
-	}
-	
-	@Override
-	public void setFebHybridID(int febHybridID) {
-	    throw new RuntimeException("This method is not supported for the HpsTestRunSiSensor.");
-	}
+    /**
+     * Set the hybrid ID associated with this sensor.
+     * 
+     * @param hybridID The hybrid ID.
+     */
+    public void setHybridID(int hybridID) {
+        this.hybridID = hybridID;
+    }
+    
+    @Override
+    public void setFebID(int febID) {
+        throw new RuntimeException("This method is not supported for the HpsTestRunSiSensor.");
+    }
+    
+    @Override
+    public void setFebHybridID(int febHybridID) {
+        throw new RuntimeException("This method is not supported for the HpsTestRunSiSensor.");
+    }
 }

Modified: java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTestRunTracker2014GeometryDefinition.java
 =============================================================================
--- java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTestRunTracker2014GeometryDefinition.java	(original)
+++ java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTestRunTracker2014GeometryDefinition.java	Wed Apr 27 11:11:32 2016
@@ -29,7 +29,7 @@
     protected static final boolean use30mradRotation = true;
     protected static final boolean useFakeHalfModuleAxialPos = false;
 
-    // Global position references	
+    // Global position references   
     protected static final double target_pos_wrt_base_plate_x = 162.3; //from Marco's 3D model
     protected static final double target_pos_wrt_base_plate_y = 80.55; //from Tim's sketchup //68.75; //from Marco's 3D model
     protected static final double target_pos_wrt_base_plate_z = 926.59; //from Marco's 3D model
@@ -208,7 +208,7 @@
         protected void setPos() {
             final double ball_pos_base_x = -1.0*target_pos_wrt_base_plate_x;
             final double ball_pos_base_y = -1.0*target_pos_wrt_base_plate_y;
-            final double ball_pos_base_z = target_pos_wrt_base_plate_z;		
+            final double ball_pos_base_z = target_pos_wrt_base_plate_z;     
             final double vee_pos_base_x = ball_pos_base_x + BasePlate.base_plate_width;
             final double vee_pos_base_y = ball_pos_base_y;
             final double vee_pos_base_z = ball_pos_base_z;
@@ -230,7 +230,7 @@
 
 
     public static class BasePlate extends SurveyVolume {
-        // Base plate references	
+        // Base plate references    
         public static final double base_plate_thickness = 0.25*inch;
         public static final double base_plate_width = 385.00;
         public static final double base_plate_length = 1216.00;
@@ -281,7 +281,7 @@
         public CSupport(String name, SurveyVolume mother) {
             super(name,mother, null);
             init();
-        }			
+        }           
         private void calcAndSetFlatPos() {
             if(use30mradRotation) {
                 // find the rotation to place the flat point
@@ -462,7 +462,7 @@
         // this is referenced to the pin position of the c-support
         private static final double ball_pos_csup_bearings_bottom_x = 240.0 - 265.0 + 14.0;
         private static final double ball_pos_csup_bearings_bottom_y = (-6.0 + 22.0);
-        private static final double ball_pos_csup_bearings_bottom_z = 14.7;		
+        private static final double ball_pos_csup_bearings_bottom_z = 14.7;     
         private static final double vee_pos_csup_bearings_bottom_x = 240.0- 129.0;
         private static final double vee_pos_csup_bearings_bottom_y = (-6.0 + 22.0);
         private static final double vee_pos_csup_bearings_bottom_z = 14.7;
@@ -499,12 +499,12 @@
 
             // make vectors
             setBallPos(ball_pos_csup_bearings_bottom_x,ball_pos_csup_bearings_bottom_y,ball_pos_csup_bearings_bottom_z);
-            setVeePos(vee_pos_csup_bearings_bottom_x,vee_pos_csup_bearings_bottom_y,vee_pos_csup_bearings_bottom_z);	
+            setVeePos(vee_pos_csup_bearings_bottom_x,vee_pos_csup_bearings_bottom_y,vee_pos_csup_bearings_bottom_z);    
             setFlatPos(flat_pos_csup_bearings_bottom_x,flat_pos_csup_bearings_bottom_y,flat_pos_csup_bearings_bottom_z);
 
 
             // create the coordinate system of the c-support bearings
-            //HPSTestRunTracker2014GeomDef.Coord csup_bearings_bottom_coord = new HPSTestRunTracker2014GeomDef.Coord(ball_pos_csup_bearings_bottom, vee_pos_csup_bearings_bottom, flat_pos_csup_bearings_bottom);		
+            //HPSTestRunTracker2014GeomDef.Coord csup_bearings_bottom_coord = new HPSTestRunTracker2014GeomDef.Coord(ball_pos_csup_bearings_bottom, vee_pos_csup_bearings_bottom, flat_pos_csup_bearings_bottom);       
 
             // since we don't care (no volume is built) about the local position of the bearings in the pin coord system we'll get rid of it
             // and find the bearings position in the base coordinate system directly
@@ -579,11 +579,11 @@
 
         public SupportPlateBottom(String name, SurveyVolume mother, SurveyVolume referenceGeom, String material) {
             super(mother, referenceGeom, name, material);
-            init();				
+            init();             
         }
         public SupportPlateBottom(String name, SurveyVolume mother, List<SurveyVolume> referenceGeom, String material) {
             super(mother, referenceGeom, name, material);
-            init();				
+            init();             
         }
         protected void setPos() {
             if(debug) System.out.printf("%s: setPos for %s\n",this.getClass().getSimpleName(),getName());
@@ -755,11 +755,11 @@
         public TestRunModule(String name, SurveyVolume mother, int layer, String half) {
             super(name, mother,null,layer, half);
             init();
-        }			
+        }           
         public TestRunModule(String name, SurveyVolume mother, SurveyVolume ref, int layer, String half) {
             super(name, mother,null,ref,layer, half);
             init();
-        }			
+        }           
         protected abstract double getColdBlockThickness();
         protected abstract double getModuleBoxLength();
         protected abstract double getModuleBoxWidth();
@@ -771,7 +771,7 @@
         }
         protected void setCenter() {
             setCenter(getModuleBoxLength()/2.0-5.0, 0.0, getModuleBoxWidth()/2.0-box_extra_width/5.0); 
-        }			
+        }           
         protected void setPos() {
 
             if(debug) System.out.printf("%s: setPos for %s\n",this.getClass().getSimpleName(),getName());
@@ -787,7 +787,7 @@
                 case 2:
                     ballPos = new BasicHep3Vector(25.0, 561.1, SupportPlateBottom.pedestal_height_L2-SupportPlateBottom.support_plate_pocket_depth);
                     veePos = new BasicHep3Vector(95.0, 561.1, SupportPlateBottom.pedestal_height_L2-SupportPlateBottom.support_plate_pocket_depth);
-                    flatPos = new BasicHep3Vector(60.0, 567.10, SupportPlateBottom.pedestal_height_L2-SupportPlateBottom.support_plate_pocket_depth);	
+                    flatPos = new BasicHep3Vector(60.0, 567.10, SupportPlateBottom.pedestal_height_L2-SupportPlateBottom.support_plate_pocket_depth);   
                     break;
                 case 3:
                     ballPos = new BasicHep3Vector(25.0, 461.1, SupportPlateBottom.pedestal_height_L3-SupportPlateBottom.support_plate_pocket_depth);
@@ -938,7 +938,7 @@
         // Distance from CF edge to screw hole: 30mm
         // Distance from screw hole to edge of cold block: 33.75mm
         // Distance from edge of cold block to hole/ball position: 5mm
-        protected static final double dist_sensor_center_to_coldblock_hole_vdir = (180.0 - 30.0 + (33.75 - 5.0)) - Sensor.length/2.0;	
+        protected static final double dist_sensor_center_to_coldblock_hole_vdir = (180.0 - 30.0 + (33.75 - 5.0)) - Sensor.length/2.0;   
         protected static final double half_module_thickness = TestRunHalfModule.getHybridThickness() + TestRunHalfModule.getCFThickness() + HalfModuleLamination.thickness;
         protected static final double half_module_length = TestRunHalfModule.getCFLength();
         protected static final double half_module_width = 6.83 + Sensor.width;
@@ -1038,7 +1038,7 @@
             if(useFakeHalfModuleAxialPos) {
                 ball_pos_halfmod_local_x = ball_pos_halfmod_local_x*2.0;
                 ball_pos_halfmod_local_y = -2.0*ball_pos_halfmod_local_y;
-            }				
+            }               
             final double ball_pos_halfmod_local_z =  dist_lower_sensor_edge_to_cold_block_mounting_surface + Sensor.width/2.0;
             
             
@@ -1118,7 +1118,7 @@
 //            final double vee_pos_halfmod_local_z =  ball_pos_halfmod_local_z;
 //            final double flat_pos_halfmod_local_x =  ball_pos_halfmod_local_x;
 //            final double flat_pos_halfmod_local_y =  ball_pos_halfmod_local_y + Sensor.getSensorThickness()/2.0;
-//            final double flat_pos_halfmod_local_z =  ball_pos_halfmod_local_z;		
+//            final double flat_pos_halfmod_local_z =  ball_pos_halfmod_local_z;        
 //            ballPos = new BasicHep3Vector(ball_pos_halfmod_local_x, ball_pos_halfmod_local_y, ball_pos_halfmod_local_z);
 //            veePos = new BasicHep3Vector(vee_pos_halfmod_local_x, vee_pos_halfmod_local_y,vee_pos_halfmod_local_z);
 //            flatPos = new BasicHep3Vector(flat_pos_halfmod_local_x, flat_pos_halfmod_local_y,flat_pos_halfmod_local_z);
@@ -1235,7 +1235,7 @@
 
     }
 
-    public static abstract class TestRunColdBlock extends SurveyVolume {		
+    public static abstract class TestRunColdBlock extends SurveyVolume {        
         private int layer;
         public TestRunColdBlock(String name, SurveyVolume mother, int layer) {
             super(name, mother, null);
@@ -1284,7 +1284,7 @@
         }
     }
 
-    public static class TestRunColdBlockL13 extends TestRunColdBlock {			
+    public static class TestRunColdBlockL13 extends TestRunColdBlock {          
         protected static final double coldblock_L13_length = 82.00;
         protected static final double coldblock_L13_width = 52.50;
         protected static final double coldblock_L13_thickness = 6.00;
@@ -1306,7 +1306,7 @@
         }
     }
 
-    public static class TestRunColdBlockL45 extends TestRunColdBlock {			
+    public static class TestRunColdBlockL45 extends TestRunColdBlock {          
         protected static final double coldblock_L45_length = 82.00;
         protected static final double coldblock_L45_width = 51.00;
         protected static final double coldblock_L45_thickness = 6.00;
@@ -1358,7 +1358,7 @@
 //            if(useSiStripsConvention) {
 //                setBallPos(0,0,0);
 //                setVeePos(ballPos.x(), ballPos.y(), ballPos.z() + getSensorWidth()/2.0);
-//                setFlatPos(ballPos.x() + getSensorLength()/2.0,ballPos.y(), ballPos.z());					
+//                setFlatPos(ballPos.x() + getSensorLength()/2.0,ballPos.y(), ballPos.z());                 
 //            } else {
 //                setBallPos(0,0,0);
 //                setVeePos(ballPos.x() + getSensorLength()/2.0, ballPos.y(), ballPos.z());
@@ -1392,7 +1392,7 @@
         }
         protected double getLength() {
             return length;
-        }			
+        }           
     }
 
     /**

Modified: java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTestRunTracker2014JavaBuilder.java
 =============================================================================
--- java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTestRunTracker2014JavaBuilder.java	(original)
+++ java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTestRunTracker2014JavaBuilder.java	Wed Apr 27 11:11:32 2016
@@ -28,175 +28,175 @@
  */
 public class HPSTestRunTracker2014JavaBuilder extends HPSTrackerJavaBuilder {
 
-	
-	
-	/**
-	 * Default constructor
-	 * @param node 
-	 */
-	public HPSTestRunTracker2014JavaBuilder(boolean debugFlag, Element node) {
-		super(debugFlag, node);
-	}
-	
-	
-	
-	/**
-	 * Build the JAVA geometry objects from the geometry definition.
-	 * @param trackingVolume - the reference volume.
-	 */
-	public void build(ILogicalVolume trackingVolume) {
-
-		// build geometry
+    
+    
+    /**
+     * Default constructor
+     * @param node 
+     */
+    public HPSTestRunTracker2014JavaBuilder(boolean debugFlag, Element node) {
+        super(debugFlag, node);
+    }
+    
+    
+    
+    /**
+     * Build the JAVA geometry objects from the geometry definition.
+     * @param trackingVolume - the reference volume.
+     */
+    public void build(ILogicalVolume trackingVolume) {
+
+        // build geometry
         setBuilder(createGeometryDefinition(_debug, node));
-		
-		if(_builder==null) throw new RuntimeException("need to set builder class before calling build!");
-
-		if(isDebug()) System.out.printf("%s: build the base geometry objects\n", getClass().getSimpleName());
-		
-		_builder.build();
-
-		if(isDebug()) System.out.printf("%s: DONE build the base geometry objects\n", getClass().getSimpleName());
-
-		if(isDebug()) System.out.printf("%s: build the JAVA geometry objects\n", getClass().getSimpleName());
-		
-		// initialize the list to store a reference to each object
-		javaSurveyVolumes = new ArrayList<JavaSurveyVolume>();
-
-		// Go through the list of volumes to build that is created in the generic builder class
-		JavaSurveyVolume trackingGeometry = new JavaSurveyVolume(_builder.getSurveyVolume(org.lcsim.geometry.compact.converter.HPSTrackerGeometryDefinition.TrackingVolume.class), trackingVolume);
-		add(trackingGeometry);
-		//setBaseTrackerGeometry(new GhostJavaBaseGeom(_builder.getBaseGeometry(Base.class), trackingGeometry));
+        
+        if(_builder==null) throw new RuntimeException("need to set builder class before calling build!");
+
+        if(isDebug()) System.out.printf("%s: build the base geometry objects\n", getClass().getSimpleName());
+        
+        _builder.build();
+
+        if(isDebug()) System.out.printf("%s: DONE build the base geometry objects\n", getClass().getSimpleName());
+
+        if(isDebug()) System.out.printf("%s: build the JAVA geometry objects\n", getClass().getSimpleName());
+        
+        // initialize the list to store a reference to each object
+        javaSurveyVolumes = new ArrayList<JavaSurveyVolume>();
+
+        // Go through the list of volumes to build that is created in the generic builder class
+        JavaSurveyVolume trackingGeometry = new JavaSurveyVolume(_builder.getSurveyVolume(org.lcsim.geometry.compact.converter.HPSTrackerGeometryDefinition.TrackingVolume.class), trackingVolume);
+        add(trackingGeometry);
+        //setBaseTrackerGeometry(new GhostJavaBaseGeom(_builder.getBaseGeometry(Base.class), trackingGeometry));
         setBaseTrackerGeometry(new JavaSurveyVolume(_builder.getSurveyVolume(TrackerEnvelope.class), trackingGeometry,1));
         add(getBaseTrackerGeometry());
-		JavaSurveyVolume basePlateGeometry = new JavaGhostSurveyVolume(_builder.getSurveyVolume(BasePlate.class), getBaseTrackerGeometry());
-		add(basePlateGeometry);
-		// skip the c-support, this is purely a reference volume in the builder so should have no use here!?
-		//JavaBaseGeometry cSupportGeometry = new GhostJavaBaseGeom(_builder.getBaseGeometry(CSupport.class), baseTrackerGeometry);
-		//add(cSupportGeometry);
-		JavaSurveyVolume supportBottomGeometry = new JavaGhostSurveyVolume(_builder.getSurveyVolume(SupportBottom.class), getBaseTrackerGeometry());
-		add(supportBottomGeometry);
-		JavaSurveyVolume supportPlateBottomGeometry = new JavaGhostSurveyVolume(_builder.getSurveyVolume(SupportPlateBottom.class), getBaseTrackerGeometry());
-		add(supportPlateBottomGeometry);
-		JavaSurveyVolume supportTopGeometry = new JavaGhostSurveyVolume(_builder.getSurveyVolume(SupportTop.class), getBaseTrackerGeometry());
-		add(supportTopGeometry);
-		JavaSurveyVolume supportPlateTopGeometry = new JavaGhostSurveyVolume(_builder.getSurveyVolume(SupportPlateTop.class), getBaseTrackerGeometry());
-		add(supportPlateTopGeometry);
-
-		// build modules	
-		
-		if(isDebug()) System.out.printf("%s: build JAVA modules\n", getClass().getSimpleName());
-
-		// Loop over all modules created
-		for(BaseModuleBundle mod : _builder.modules) {
-			TestRunModuleBundle m = (TestRunModuleBundle) mod;
-		    if(isDebug()) { 
-				System.out.printf("%s: build module %s (layer %d half %s)\n", getClass().getSimpleName(),m.module.getName(),m.getLayer(),m.getHalf());
-				m.print();
-			}
-
-			// Find the mother among the objects using its name, should probably have a better way...
-			String name_mother = m.getMother().getName();
-			JavaSurveyVolume mother = null;
-			for(JavaSurveyVolume g : javaSurveyVolumes) {
-				if(g.getName().equals(name_mother)) {
-					mother = g;
-					break;
-				}
-			}
-			// Check that it had a mother
-			if(mother==null) throw new RuntimeException("Cound't find mother to module " + m.module.getName());
-
-			if(isDebug()) System.out.printf("%s: found mother %s to module %s\n", getClass().getSimpleName(),mother.getName(),m.module.getName());
-			
-			// put the module in the list of objects that will be added to LCDD
-			addTestRunModule(m, mother);
-			
-			if(isDebug()) System.out.printf("%s: DONE build module %s\n", getClass().getSimpleName(), m.module.getName());
-
-			
-		}
-		
-		if(isDebug()) System.out.printf("%s: DONE build JAVA modules\n", getClass().getSimpleName());
-
-		
-		if(isDebug()) System.out.printf("%s: DONE building the JAVA geometry objects\n", getClass().getSimpleName());
-		if(isDebug()) {
-		    System.out.printf("%s: DONE building the JAVA geometry objects\n", getClass().getSimpleName());
-		    System.out.printf("%s: List of all the JAVA geometry objects built\n", this.getClass().getSimpleName());
-		    for(JavaSurveyVolume bg : javaSurveyVolumes) {
-		        System.out.printf("-------\n%s\n", bg.toString());
-		    }
-		}
-
-
-		// Set visualization features
-		//setVis();
-
-
-	}
-
-	/**
-	 * Rules for adding the JAVA module geometry.
-	 * @param bundle - module to be added
-	 * @param mother - mother JAVA geometry object
-	 */
-	protected void addTestRunModule(TestRunModuleBundle bundle, JavaSurveyVolume mother) {
-		
-		if(isDebug()) {
-			System.out.printf("%s: addModule %s containing:\n",this.getClass().getSimpleName(), bundle.module.getName());
-			bundle.print();
-		}
-		
-		// Create the module
-		JavaSurveyVolume lcddM = new JavaGhostSurveyVolume(bundle.module, mother);
-		add(lcddM);
-		
-		// add half modules
-		if(bundle.halfModuleAxial!=null)  addHalfModule((TestRunHalfModuleBundle)bundle.halfModuleAxial,lcddM);     
+        JavaSurveyVolume basePlateGeometry = new JavaGhostSurveyVolume(_builder.getSurveyVolume(BasePlate.class), getBaseTrackerGeometry());
+        add(basePlateGeometry);
+        // skip the c-support, this is purely a reference volume in the builder so should have no use here!?
+        //JavaBaseGeometry cSupportGeometry = new GhostJavaBaseGeom(_builder.getBaseGeometry(CSupport.class), baseTrackerGeometry);
+        //add(cSupportGeometry);
+        JavaSurveyVolume supportBottomGeometry = new JavaGhostSurveyVolume(_builder.getSurveyVolume(SupportBottom.class), getBaseTrackerGeometry());
+        add(supportBottomGeometry);
+        JavaSurveyVolume supportPlateBottomGeometry = new JavaGhostSurveyVolume(_builder.getSurveyVolume(SupportPlateBottom.class), getBaseTrackerGeometry());
+        add(supportPlateBottomGeometry);
+        JavaSurveyVolume supportTopGeometry = new JavaGhostSurveyVolume(_builder.getSurveyVolume(SupportTop.class), getBaseTrackerGeometry());
+        add(supportTopGeometry);
+        JavaSurveyVolume supportPlateTopGeometry = new JavaGhostSurveyVolume(_builder.getSurveyVolume(SupportPlateTop.class), getBaseTrackerGeometry());
+        add(supportPlateTopGeometry);
+
+        // build modules    
+        
+        if(isDebug()) System.out.printf("%s: build JAVA modules\n", getClass().getSimpleName());
+
+        // Loop over all modules created
+        for(BaseModuleBundle mod : _builder.modules) {
+            TestRunModuleBundle m = (TestRunModuleBundle) mod;
+            if(isDebug()) { 
+                System.out.printf("%s: build module %s (layer %d half %s)\n", getClass().getSimpleName(),m.module.getName(),m.getLayer(),m.getHalf());
+                m.print();
+            }
+
+            // Find the mother among the objects using its name, should probably have a better way...
+            String name_mother = m.getMother().getName();
+            JavaSurveyVolume mother = null;
+            for(JavaSurveyVolume g : javaSurveyVolumes) {
+                if(g.getName().equals(name_mother)) {
+                    mother = g;
+                    break;
+                }
+            }
+            // Check that it had a mother
+            if(mother==null) throw new RuntimeException("Cound't find mother to module " + m.module.getName());
+
+            if(isDebug()) System.out.printf("%s: found mother %s to module %s\n", getClass().getSimpleName(),mother.getName(),m.module.getName());
+            
+            // put the module in the list of objects that will be added to LCDD
+            addTestRunModule(m, mother);
+            
+            if(isDebug()) System.out.printf("%s: DONE build module %s\n", getClass().getSimpleName(), m.module.getName());
+
+            
+        }
+        
+        if(isDebug()) System.out.printf("%s: DONE build JAVA modules\n", getClass().getSimpleName());
+
+        
+        if(isDebug()) System.out.printf("%s: DONE building the JAVA geometry objects\n", getClass().getSimpleName());
+        if(isDebug()) {
+            System.out.printf("%s: DONE building the JAVA geometry objects\n", getClass().getSimpleName());
+            System.out.printf("%s: List of all the JAVA geometry objects built\n", this.getClass().getSimpleName());
+            for(JavaSurveyVolume bg : javaSurveyVolumes) {
+                System.out.printf("-------\n%s\n", bg.toString());
+            }
+        }
+
+
+        // Set visualization features
+        //setVis();
+
+
+    }
+
+    /**
+     * Rules for adding the JAVA module geometry.
+     * @param bundle - module to be added
+     * @param mother - mother JAVA geometry object
+     */
+    protected void addTestRunModule(TestRunModuleBundle bundle, JavaSurveyVolume mother) {
+        
+        if(isDebug()) {
+            System.out.printf("%s: addModule %s containing:\n",this.getClass().getSimpleName(), bundle.module.getName());
+            bundle.print();
+        }
+        
+        // Create the module
+        JavaSurveyVolume lcddM = new JavaGhostSurveyVolume(bundle.module, mother);
+        add(lcddM);
+        
+        // add half modules
+        if(bundle.halfModuleAxial!=null)  addHalfModule((TestRunHalfModuleBundle)bundle.halfModuleAxial,lcddM);     
         if(bundle.halfModuleStereo!=null) addHalfModule((TestRunHalfModuleBundle)bundle.halfModuleStereo,lcddM);
-		
-		
-		if(isDebug()) {
-			System.out.printf("%s: DONE addModule %s \n",this.getClass().getSimpleName(), bundle.module.getName());
-		}
-		
-	}
-	
-	
-	/**
-	 * Rules for adding the JAVA half module geometry.
-	 * @param bundle - module to be added
-	 * @param mother - mother JAVA geometry object
-	 */
-	private void addHalfModule(TestRunHalfModuleBundle bundle, JavaSurveyVolume mother) {
-		// Create the half-module
-		// This is not a ghost element but reflects the module 
-		// concept in the old compact description
-		// TODO fix the layer IDs
-		int oldCompactModuleId = 0;
-		JavaSurveyVolume lcddHM = new JavaSurveyVolume(bundle.halfModule, mother,oldCompactModuleId);
-		add(lcddHM);
-		
-		// ComponentNumber is taken from old geometry where it is simply a counter when adding the xml daughters to the TestRunModule.
-		// It is simply 0 for sensor and 1 for carbon fiber in the old geometry 
-		int componentNumber = ((Sensor)bundle.sensor).getId();
-
-		// create the sensor
-		JavaSurveyVolume lcddS = new JavaSurveyVolume(bundle.sensor, lcddHM, componentNumber);
-		add(lcddS);
-
-		// create the active sensor
-		JavaSurveyVolume lcddAS = new JavaSurveyVolume(bundle.activeSensor, lcddS, componentNumber);
-		add(lcddAS);
-		
-//		if(isDebug()) {
-//			System.out.printf("%s: added sensor %s \n",this.getClass().getSimpleName(), lcddS.getName());
-//			System.out.printf("%s: local coordinate system\n%s\n",this.getClass().getSimpleName(), bundle.sensor.getCoord().toString());
-//			dsd
-//		}
-		
-		
-	}
+        
+        
+        if(isDebug()) {
+            System.out.printf("%s: DONE addModule %s \n",this.getClass().getSimpleName(), bundle.module.getName());
+        }
+        
+    }
+    
+    
+    /**
+     * Rules for adding the JAVA half module geometry.
+     * @param bundle - module to be added
+     * @param mother - mother JAVA geometry object
+     */
+    private void addHalfModule(TestRunHalfModuleBundle bundle, JavaSurveyVolume mother) {
+        // Create the half-module
+        // This is not a ghost element but reflects the module 
+        // concept in the old compact description
+        // TODO fix the layer IDs
+        int oldCompactModuleId = 0;
+        JavaSurveyVolume lcddHM = new JavaSurveyVolume(bundle.halfModule, mother,oldCompactModuleId);
+        add(lcddHM);
+        
+        // ComponentNumber is taken from old geometry where it is simply a counter when adding the xml daughters to the TestRunModule.
+        // It is simply 0 for sensor and 1 for carbon fiber in the old geometry 
+        int componentNumber = ((Sensor)bundle.sensor).getId();
+
+        // create the sensor
+        JavaSurveyVolume lcddS = new JavaSurveyVolume(bundle.sensor, lcddHM, componentNumber);
+        add(lcddS);
+
+        // create the active sensor
+        JavaSurveyVolume lcddAS = new JavaSurveyVolume(bundle.activeSensor, lcddS, componentNumber);
+        add(lcddAS);
+        
+//      if(isDebug()) {
+//          System.out.printf("%s: added sensor %s \n",this.getClass().getSimpleName(), lcddS.getName());
+//          System.out.printf("%s: local coordinate system\n%s\n",this.getClass().getSimpleName(), bundle.sensor.getCoord().toString());
+//          dsd
+//      }
+        
+        
+    }
 
 
 
@@ -206,8 +206,8 @@
     }
 
 
-	
-	
-	
+    
+    
+    
 
 }

Modified: java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTestRunTracker2014LCDDBuilder.java
 =============================================================================
--- java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTestRunTracker2014LCDDBuilder.java	(original)
+++ java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTestRunTracker2014LCDDBuilder.java	Wed Apr 27 11:11:32 2016
@@ -26,157 +26,157 @@
 public class HPSTestRunTracker2014LCDDBuilder extends HPSTrackerLCDDBuilder {
 
 
-	public HPSTestRunTracker2014LCDDBuilder(boolean debugFlag, Element node, LCDD lcdd, SensitiveDetector sens) {
-		super(debugFlag, node, lcdd, sens);
-	}
+    public HPSTestRunTracker2014LCDDBuilder(boolean debugFlag, Element node, LCDD lcdd, SensitiveDetector sens) {
+        super(debugFlag, node, lcdd, sens);
+    }
 
-	
-	public void setBuilder() {
-	    setBuilder();
-	}
-	
-	public void build(Volume worldVolume) {
-		
-		// set and build geometry
+    
+    public void setBuilder() {
+        setBuilder();
+    }
+    
+    public void build(Volume worldVolume) {
+        
+        // set and build geometry
         setBuilder(createGeometryDefinition(_debug, node));
         
-		if(_builder==null) throw new RuntimeException("need to set builder class before calling build!");
+        if(_builder==null) throw new RuntimeException("need to set builder class before calling build!");
 
-		if(isDebug()) System.out.printf("%s: build the base geometry objects\n", getClass().getSimpleName());
+        if(isDebug()) System.out.printf("%s: build the base geometry objects\n", getClass().getSimpleName());
 
-		_builder.build();
+        _builder.build();
 
-		if(isDebug()) System.out.printf("%s: DONE build the base geometry objects\n", getClass().getSimpleName());
+        if(isDebug()) System.out.printf("%s: DONE build the base geometry objects\n", getClass().getSimpleName());
 
 
-		if(isDebug()) System.out.printf("%s: build the LCDD geometry objects\n", getClass().getSimpleName());
+        if(isDebug()) System.out.printf("%s: build the LCDD geometry objects\n", getClass().getSimpleName());
 
-		
-		// Go through the list of volumes to build that is created in the generic builder class
-		// TODO this is manual now since I don't have a way of knowing in the generic builder class what is a ghost volume at this point.
-		LCDDSurveyVolume trackingGeometry = new LCDDSurveyVolume(_builder.getSurveyVolume(org.lcsim.geometry.compact.converter.HPSTrackerGeometryDefinition.TrackingVolume.class), worldVolume);
-		add(trackingGeometry);
-		baseSurveyVolume = new LCDDSurveyVolume(_builder.getSurveyVolume(TrackerEnvelope.class), lcdd, trackingGeometry);
-		add(baseSurveyVolume);
-		LCDDSurveyVolume basePlateGeometry = new LCDDSurveyVolume(_builder.getSurveyVolume(BasePlate.class), lcdd, baseSurveyVolume);
-		add(basePlateGeometry);
-		// TODO I don't think this c-support has any use at all since the coordinates of it has been already used in the builder. Should remove?
-		LCDDSurveyVolume cSupportGeometry = new LCDDGhostSurveyVolume(_builder.getSurveyVolume(CSupport.class), baseSurveyVolume);
-		add(cSupportGeometry);
-		LCDDSurveyVolume supportBottomGeometry = new LCDDGhostSurveyVolume(_builder.getSurveyVolume(SupportBottom.class), baseSurveyVolume);
-		add(supportBottomGeometry);
-		LCDDSurveyVolume supportPlateBottomGeometry = new LCDDSurveyVolume(_builder.getSurveyVolume(SupportPlateBottom.class), lcdd, baseSurveyVolume);
-		add(supportPlateBottomGeometry);
-		LCDDSurveyVolume supportTopGeometry = new LCDDGhostSurveyVolume(_builder.getSurveyVolume(SupportTop.class), baseSurveyVolume);
-		add(supportTopGeometry);
-		LCDDSurveyVolume supportPlateTopGeometry = new LCDDSurveyVolume(_builder.getSurveyVolume(SupportPlateTop.class), lcdd, baseSurveyVolume);
-		add(supportPlateTopGeometry);
+        
+        // Go through the list of volumes to build that is created in the generic builder class
+        // TODO this is manual now since I don't have a way of knowing in the generic builder class what is a ghost volume at this point.
+        LCDDSurveyVolume trackingGeometry = new LCDDSurveyVolume(_builder.getSurveyVolume(org.lcsim.geometry.compact.converter.HPSTrackerGeometryDefinition.TrackingVolume.class), worldVolume);
+        add(trackingGeometry);
+        baseSurveyVolume = new LCDDSurveyVolume(_builder.getSurveyVolume(TrackerEnvelope.class), lcdd, trackingGeometry);
+        add(baseSurveyVolume);
+        LCDDSurveyVolume basePlateGeometry = new LCDDSurveyVolume(_builder.getSurveyVolume(BasePlate.class), lcdd, baseSurveyVolume);
+        add(basePlateGeometry);
+        // TODO I don't think this c-support has any use at all since the coordinates of it has been already used in the builder. Should remove?
+        LCDDSurveyVolume cSupportGeometry = new LCDDGhostSurveyVolume(_builder.getSurveyVolume(CSupport.class), baseSurveyVolume);
+        add(cSupportGeometry);
+        LCDDSurveyVolume supportBottomGeometry = new LCDDGhostSurveyVolume(_builder.getSurveyVolume(SupportBottom.class), baseSurveyVolume);
+        add(supportBottomGeometry);
+        LCDDSurveyVolume supportPlateBottomGeometry = new LCDDSurveyVolume(_builder.getSurveyVolume(SupportPlateBottom.class), lcdd, baseSurveyVolume);
+        add(supportPlateBottomGeometry);
+        LCDDSurveyVolume supportTopGeometry = new LCDDGhostSurveyVolume(_builder.getSurveyVolume(SupportTop.class), baseSurveyVolume);
+        add(supportTopGeometry);
+        LCDDSurveyVolume supportPlateTopGeometry = new LCDDSurveyVolume(_builder.getSurveyVolume(SupportPlateTop.class), lcdd, baseSurveyVolume);
+        add(supportPlateTopGeometry);
 
-		// build modules	
+        // build modules    
 
-		if(isDebug()) System.out.printf("%s: build modules\n", getClass().getSimpleName());
+        if(isDebug()) System.out.printf("%s: build modules\n", getClass().getSimpleName());
 
-		// Loop over all modules created
-		for(BaseModuleBundle mod : _builder.modules) {
-		    TestRunModuleBundle m = (TestRunModuleBundle) mod;
-			if(isDebug()) { 
-				System.out.printf("%s: module layer %d half %s\n", getClass().getSimpleName(),m.getLayer(),m.getHalf());
-				m.print();
-			}
+        // Loop over all modules created
+        for(BaseModuleBundle mod : _builder.modules) {
+            TestRunModuleBundle m = (TestRunModuleBundle) mod;
+            if(isDebug()) { 
+                System.out.printf("%s: module layer %d half %s\n", getClass().getSimpleName(),m.getLayer(),m.getHalf());
+                m.print();
+            }
 
-			// Find the mother among the LCDD objects using its name, should probably have a better way...
-			String name_mother = m.getMother().getName();
-			LCDDSurveyVolume mother = null;
-			for(LCDDSurveyVolume g : lcddSurveyVolumes) {
-				if(g.getName().equals(name_mother)) {
-					mother = g;
-					break;
-				}
-			}
-			// Check that it had a mother
-			if(mother==null) throw new RuntimeException("Cound't find mother to module layer " + m.getLayer() + " half "+ m.getHalf());
+            // Find the mother among the LCDD objects using its name, should probably have a better way...
+            String name_mother = m.getMother().getName();
+            LCDDSurveyVolume mother = null;
+            for(LCDDSurveyVolume g : lcddSurveyVolumes) {
+                if(g.getName().equals(name_mother)) {
+                    mother = g;
+                    break;
+                }
+            }
+            // Check that it had a mother
+            if(mother==null) throw new RuntimeException("Cound't find mother to module layer " + m.getLayer() + " half "+ m.getHalf());
 
-			if(isDebug()) System.out.printf("%s: found mother %s for module layer %d half %s\n", getClass().getSimpleName(),mother.getName(),m.getLayer(),m.getHalf());
+            if(isDebug()) System.out.printf("%s: found mother %s for module layer %d half %s\n", getClass().getSimpleName(),mother.getName(),m.getLayer(),m.getHalf());
 
-			// add the module to the list of objects that will be added to LCDD
-			addTestRunModule(m, mother);
+            // add the module to the list of objects that will be added to LCDD
+            addTestRunModule(m, mother);
 
-		}
+        }
 
 
 
-		if(isDebug()) {
-		    System.out.printf("%s: DONE building the LCDD geometry objects\n", getClass().getSimpleName());
-		    System.out.printf("%s: List of all %d LCDD geometry objects built\n", this.getClass().getSimpleName(), lcddSurveyVolumes.size());
-		    for(SurveyVolumeImpl bg : lcddSurveyVolumes) {
-		        System.out.printf("-------\n%s\n", bg.toString());
-		    }
-		}
+        if(isDebug()) {
+            System.out.printf("%s: DONE building the LCDD geometry objects\n", getClass().getSimpleName());
+            System.out.printf("%s: List of all %d LCDD geometry objects built\n", this.getClass().getSimpleName(), lcddSurveyVolumes.size());
+            for(SurveyVolumeImpl bg : lcddSurveyVolumes) {
+                System.out.printf("-------\n%s\n", bg.toString());
+            }
+        }
 
 
 
-		// Set visualization features
-		setVisualization();
+        // Set visualization features
+        setVisualization();
 
 
-	}
+    }
 
 
-	/**
-	 * Rules for adding the LCDD module geometry.
-	 * @param bundle - module to be added
-	 * @param mother - mother LCDD geometry object
-	 */
-	protected void addTestRunModule(TestRunModuleBundle bundle, LCDDSurveyVolume mother) {
-		// This could perhaps be fixed if there is a relation with daughters in geometry definition?
-		// create the module
-		LCDDSurveyVolume lcddM = new LCDDSurveyVolume(bundle.module, lcdd, mother);
-		add(lcddM);
-		if(bundle.halfModuleAxial!=null)  addTestRunHalfModule(bundle.halfModuleAxial,lcddM);
-		if(bundle.coldBlock!=null)        add(new LCDDSurveyVolume(bundle.coldBlock, lcdd, lcddM));		
-		if(bundle.halfModuleStereo!=null) addTestRunHalfModule((TestRunHalfModuleBundle)bundle.halfModuleStereo,lcddM);
+    /**
+     * Rules for adding the LCDD module geometry.
+     * @param bundle - module to be added
+     * @param mother - mother LCDD geometry object
+     */
+    protected void addTestRunModule(TestRunModuleBundle bundle, LCDDSurveyVolume mother) {
+        // This could perhaps be fixed if there is a relation with daughters in geometry definition?
+        // create the module
+        LCDDSurveyVolume lcddM = new LCDDSurveyVolume(bundle.module, lcdd, mother);
+        add(lcddM);
+        if(bundle.halfModuleAxial!=null)  addTestRunHalfModule(bundle.halfModuleAxial,lcddM);
+        if(bundle.coldBlock!=null)        add(new LCDDSurveyVolume(bundle.coldBlock, lcdd, lcddM));     
+        if(bundle.halfModuleStereo!=null) addTestRunHalfModule((TestRunHalfModuleBundle)bundle.halfModuleStereo,lcddM);
 //        if(bundle.halfModuleAxial!=null)  addHalfModule((TestRunHalfModuleBundle)bundle.halfModuleAxial,lcddM);
 //        if(bundle.coldBlock!=null)        add(new LCDDSurveyVolume(bundle.coldBlock, lcdd, lcddM));     
 //        if(bundle.halfModuleStereo!=null) addHalfModule((TestRunHalfModuleBundle)bundle.halfModuleStereo,lcddM);
 
-	}
+    }
 
-	/**
-	 * Rules for adding the LCDD half module geometry.
-	 * @param bundle - module to be added
-	 * @param mother - mother LCDD geometry object
-	 */
-	protected void addTestRunHalfModule(HalfModuleBundle bundle2, LCDDSurveyVolume mother) {
-		// This could perhaps be fixed if there is a relation with daughters in geometry definition?
-	    TestRunHalfModuleBundle bundle = (TestRunHalfModuleBundle) bundle2;
-	    
-	    // create the half-module
-		LCDDSurveyVolume lcddHM = new LCDDSurveyVolume(bundle.halfModule, lcdd, mother);
-		add(lcddHM);
-		// create the sensor
-		LCDDSurveyVolume lcddS = new LCDDSurveyVolume(bundle.sensor, lcdd, lcddHM);
-		add(lcddS);
-		// create the active sensor
-		LCDDSurveyVolume lcddAS = new LCDDSurveyVolume(bundle.activeSensor, lcdd, lcddS);
-		add(lcddAS);
-		// create the lamination
-		LCDDSurveyVolume lcddL = new LCDDSurveyVolume(bundle.lamination, lcdd, lcddHM);
-		add(lcddL);
-		// create the carbon fiber frame
-		LCDDSurveyVolume lcddCF = new LCDDSurveyVolume(bundle.carbonFiber, lcdd, lcddHM);
-		add(lcddCF);
-		// create the hybrid frame
-		LCDDSurveyVolume lcddH = new LCDDSurveyVolume(bundle.hybrid, lcdd, lcddHM);
-		add(lcddH);
+    /**
+     * Rules for adding the LCDD half module geometry.
+     * @param bundle2 - module to be added
+     * @param mother - mother LCDD geometry object
+     */
+    protected void addTestRunHalfModule(HalfModuleBundle bundle2, LCDDSurveyVolume mother) {
+        // This could perhaps be fixed if there is a relation with daughters in geometry definition?
+        TestRunHalfModuleBundle bundle = (TestRunHalfModuleBundle) bundle2;
+        
+        // create the half-module
+        LCDDSurveyVolume lcddHM = new LCDDSurveyVolume(bundle.halfModule, lcdd, mother);
+        add(lcddHM);
+        // create the sensor
+        LCDDSurveyVolume lcddS = new LCDDSurveyVolume(bundle.sensor, lcdd, lcddHM);
+        add(lcddS);
+        // create the active sensor
+        LCDDSurveyVolume lcddAS = new LCDDSurveyVolume(bundle.activeSensor, lcdd, lcddS);
+        add(lcddAS);
+        // create the lamination
+        LCDDSurveyVolume lcddL = new LCDDSurveyVolume(bundle.lamination, lcdd, lcddHM);
+        add(lcddL);
+        // create the carbon fiber frame
+        LCDDSurveyVolume lcddCF = new LCDDSurveyVolume(bundle.carbonFiber, lcdd, lcddHM);
+        add(lcddCF);
+        // create the hybrid frame
+        LCDDSurveyVolume lcddH = new LCDDSurveyVolume(bundle.hybrid, lcdd, lcddHM);
+        add(lcddH);
 
-	}
+    }
 
 
     @Override
     public HPSTrackerGeometryDefinition createGeometryDefinition(boolean debug,
             Element node) {
         return new HPSTestRunTracker2014GeometryDefinition(_debug, node);
-    }	
+    }   
 
 
 }

Modified: java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTracker2014GeometryDefinition.java
 =============================================================================
--- java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTracker2014GeometryDefinition.java	(original)
+++ java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTracker2014GeometryDefinition.java	Wed Apr 27 11:11:32 2016
@@ -27,8 +27,8 @@
  *
  */
  public class HPSTracker2014GeometryDefinition extends HPSTrackerGeometryDefinition {
-
-     private static final Logger LOGGER = Logger.getLogger(HPSTracker2014GeometryDefinition.class.getPackage().getName());
+    
+    private static final Logger LOGGER = Logger.getLogger(HPSTracker2014GeometryDefinition.class.getPackage().getName());
 
     public HPSTracker2014GeometryDefinition(boolean debug, Element node) {
         super(debug, node);
@@ -38,8 +38,7 @@
         doBottom = true;
         doTop = true;
         layerBitMask = 0x3F;
-    }
-
+     }
 
     /* (non-Javadoc)
      * @see org.lcsim.geometry.compact.converter.HPSTrackerBuilder#build()
@@ -47,12 +46,11 @@
     public void build() {
 
         if(isDebug()) System.out.printf("%s: constructing the geometry objects\n", this.getClass().getSimpleName());
-
         
         // Create alignment correction objects
         // THis is really a ugly approach with MP corrections initialized before and 
         // the survey corrections based on the XML node
-        // FIX THIS! //TODO
+        // TODO: FIX THIS!
         AlignmentCorrection alignmentCorrections = new AlignmentCorrection();
         alignmentCorrections.setNode(node);
         AlignmentCorrection supBotCorr = getL13UChannelAlignmentCorrection(false);
@@ -74,25 +72,19 @@
 
         SvtBoxBasePlate svtBoxBasePlate = new SvtBoxBasePlate("base_plate",svtBox,null);
         surveyVolumes.add(svtBoxBasePlate);
-                
-        
-        
+                             
         SupportRingL13BottomKinMount supportRingKinL13Bottom = new SupportRingL13BottomKinMount("c_support_kin_L13b", svtBox, supBotCorr); 
-        surveyVolumes.add(supportRingKinL13Bottom);
-        
+        surveyVolumes.add(supportRingKinL13Bottom);        
         
         UChannelL13 uChannelL13Bottom = new UChannelL13Bottom("support_bottom_L13", svtBox, alignmentCorrections, supportRingKinL13Bottom); 
         surveyVolumes.add(uChannelL13Bottom);
         
         UChannelL13Plate uChannelL13BottomPlate = new UChannelL13BottomPlate("support_plate_bottom_L13", svtBox, null, uChannelL13Bottom); 
         surveyVolumes.add(uChannelL13BottomPlate);
-
         
         SupportRingL13TopKinMount supportRingKinL13Top = new SupportRingL13TopKinMount("c_support_kin_L13t", svtBox, supTopCorr); 
         surveyVolumes.add(supportRingKinL13Top);
-
-        
-        
+                
         UChannelL13Top uChannelL13Top = new UChannelL13Top("support_top_L13", svtBox, alignmentCorrections, supportRingKinL13Top); 
         surveyVolumes.add(uChannelL13Top);
         
@@ -110,7 +102,6 @@
         
         UChannelL46Plate uChannelL46TopPlate = new UChannelL46TopPlate("support_plate_top_L46", svtBox, null, uChannelL46Top);
         surveyVolumes.add(uChannelL46TopPlate);
-
         
         for(int l=1; l<=6;++l) {
             if(doLayer(l)) {
@@ -135,30 +126,20 @@
                 bundle.print();
             }
         }
-        
-        
-        
-        
-
-    }
-
+    }
     
     /**
      * {@link SurveyVolume} volume defining the pair spectrometer (PS) vacuum chamber
      * Reference: tracking volume coordinate system
      * Origin: same as reference
      * Orientation:  u - points in x direction (towards positron side), v - points upstream
-     * 
-     * @author Per Hansson Adrian <[log in to unmask]>
-     *
      */
     public static class PSVacuumChamber extends SurveyVolume {
+        
         public static final double height = PS_vac_box_inner_height; 
         public static final double width = PS_vac_box_inner_width;
         public static final double length = PS_vac_box_inner_length;
-        
-        
-        
+                       
         public PSVacuumChamber(String name, SurveyVolume mother, AlignmentCorrection alignmentCorrection) {
             super(name, mother, alignmentCorrection);
             init();
@@ -184,9 +165,6 @@
      * Reference: PS vacuum chamber coordinate system. Note that the PS vacuum chamber box is placed w.r.t. this box and the target positions.
      * Origin: intersection of midplanes vertically and horizontally
      * Orientation: same as reference
-     * 
-     * @author Per Hansson Adrian <[log in to unmask]>
-     *
      */
     public static class SvtBox extends SurveyVolume {
         public static final double height = 6.740*inch;
@@ -198,10 +176,7 @@
         public static final double center_to_target_z = 13.777*inch;
         public static final double center_to_target_x = 0.84*inch;
         public static final double center_to_target_y = 0.0;
-        
-        
-        
-        
+                               
         public SvtBox(String name, SurveyVolume mother, AlignmentCorrection alignmentCorrection) {
             super(name, mother, alignmentCorrection);
             init();
@@ -217,8 +192,7 @@
             
             ballPos = new BasicHep3Vector(0, 0, 0);
             veePos = new BasicHep3Vector(ballPos.x()+1, ballPos.y(), ballPos.z());
-            flatPos = new BasicHep3Vector(ballPos.x(), ballPos.y()+1, ballPos.z());
-            
+            flatPos = new BasicHep3Vector(ballPos.x(), ballPos.y()+1, ballPos.z());            
         }
     }
     
@@ -228,9 +202,6 @@
      * Reference: {@link SvtBox}  coordinate system.
      * Origin: surface of base plate intersection with center of hole for adjustment screw on positron side
      * Orientation: same as reference
-     * 
-     * @author Per Hansson Adrian <[log in to unmask]>
-     *
      */
     public static class SvtBoxBasePlate extends SurveyVolume {
         public static final double length = 50.5*inch;
@@ -268,16 +239,11 @@
         
     }
     
-    
-    
-    
     /**
      * {@link SurveyVolume} volume defining the coordinate system of the support ring
      *  Reference: @SvtBoxBasePlate
      *  Origin: pin position of support ring (electron side)
      *  Orientation: slot position is vee position (positron side) i.e u points towards the positron side and v in the upstream beam direction
-     *  
-     * @author Per Hansson Adrian <[log in to unmask]>
      *
      */
     public static class SupportRing extends SurveyVolume {
@@ -315,14 +281,9 @@
             flatPos = VecOp.add(ballPos, vPrime);
         }
     }
-   
-    
-    
+        
     /**
      * Abstract {@link SurveyVolume} volume defining a coordinate system from the kinematic mount positions for support channels
-     *  
-     * @author Per Hansson Adrian <[log in to unmask]>
-     *
      */
     public abstract static class SupportRingL13KinMount extends SurveyVolume {
 
@@ -360,9 +321,6 @@
      *  Reference: {@link SvtBox} coordinate system
      *  Origin: cone mount (it's on the electron side)
      *  Orientation: ball is cone mount, slot mount is vee position and flat is along beam line pointing upstream
-     *  
-     * @author Per Hansson Adrian <[log in to unmask]>
-     *
      */
     public static class SupportRingL13BottomKinMount extends SupportRingL13KinMount {
 
@@ -385,9 +343,6 @@
      *  Reference: @SupportRing coordinate system
      *  Origin: cone mount (it's on the electron side)
      *  Orientation: ball is cone mount, slot mount is vee position and flat is along beamline pointing upstream
-     *  
-     * @author Per Hansson Adrian <[log in to unmask]>
-     *
      */
     public static class SupportRingL13TopKinMount extends SupportRingL13KinMount {
         //public static final double mount_surface_wrt_baseplate_vertically = 5.388*inch;
@@ -420,12 +375,9 @@
 //            flatPos = new BasicHep3Vector(flat_pos_x,flat_pos_y,flat_pos_z);
 //        }
     }
-    
-    
-    /**
-     * Abstract {@link SurveyVolume} volume defining the coordinate system of the L1-3 u-channels 
-     *  
-     *  @author Per Hansson Adrian <[log in to unmask]>
+        
+    /**
+     * Abstract {@link SurveyVolume} volume defining the coordinate system of the L1-3 u-channels
      */
     public abstract static class UChannelL13 extends SurveyVolume {
         public final static double length = UChannelL13Plate.length;
@@ -457,9 +409,6 @@
      *  Reference: {@link SupportRingL13BottomKinMount} coordinate system
      *  Origin: midpoint between upstream survey cones
      *  Orientation: u - width pointing towards electron side, v - pointing along the U-channel in the beam direction
-     *  
-     *  @author Per Hansson Adrian <[log in to unmask]>
-     *
      */
     public static class UChannelL13Bottom extends UChannelL13 {
         private final static double cone_to_edge_of_plate_y = 12.25*inch; 
@@ -489,14 +438,9 @@
         }
     }
     
-    
-    
     /**
      * Position of the center of the survey balls when engaging the cones in the side plates of the U-channel. 
      * This is at nominal position.
-     * 
-     * @author Per Hansson Adrian <[log in to unmask]>
-     *
      */
     private static class UChannelL13BottomSurveyBalls  {
         
@@ -523,18 +467,12 @@
         }
     }
     
-    
-  
-    
     /**
      * {@link SurveyVolume} volume defining the coordinate system of the top L1-3 u-channel 
      *  Reference: SupportRingL13TopKinMount coordinate system
      *  Origin: midpoint between upstream survey cones
      *  Orientation: u - width pointing towards positron side, v - pointing along the U-channel in the beam direction
      *  Note that this is flipped w.r.t. bottom support.
-     *  
-     *  @author Per Hansson Adrian <[log in to unmask]>
-     *
      */
     public static class UChannelL13Top extends UChannelL13 {
         private final static Hep3Vector ball_kinMount = new BasicHep3Vector(SupportRingL13TopKinMount.kin_mount_pos_x,SupportRingL13TopKinMount.kin_mount_pos_y,SupportRingL13TopKinMount.kin_mount_pos_z);
@@ -567,15 +505,10 @@
            return length;
         }
     }
-
-    
-    
+       
     /**
      * Position of the center of the survey balls when engaging the cones in the side plates of the U-channel. 
      * This is at nominal position.
-     * 
-     * @author Per Hansson Adrian <[log in to unmask]>
-     *
      */
     private static class UChannelL13TopSurveyBalls  {
         
@@ -602,16 +535,8 @@
         }
     }
     
-    
-    
-    
-    
-
     /**
      * Abstract {@link SurveyVolume} volume defining the coordinate system of the u-channel plate
-
-     * @author Per Hansson Adrian <[log in to unmask]>
-     *
      */
     public abstract static class UChannelPlate extends SurveyVolume {
         public UChannelPlate(String name, SurveyVolume m,
@@ -626,9 +551,6 @@
 
     /**
      * Abstract {@link SurveyVolume} volume defining the coordinate system of the u-channel plate
-
-     * @author Per Hansson Adrian <[log in to unmask]>
-     *
      */
     public abstract static class UChannelL13Plate extends UChannelPlate {
         private final static double pocket_depth_L1 = 0.025;
@@ -689,9 +611,6 @@
      * Reference:  @UChannelL13Bottom coordinate system
      * Origin:  same as reference
      * Orientation: same as reference
-     *
-     * @author Per Hansson Adrian <[log in to unmask]>
-     *
      */
     public static class UChannelL13BottomPlate extends UChannelL13Plate {
         protected final static double L1_module_pin_to_edge_of_plate = (16.0-4.126)*inch;
@@ -715,10 +634,7 @@
      * {@link SurveyVolume} volume defining the coordinate system of the bottom u-channel plate
      * Reference:  @UChannelL13Bottom coordinate system
      * Origin:  same as reference
-     * Orientation: same as reference
-     *
-     * @author Per Hansson Adrian <[log in to unmask]>
-     *
+     * Orientation: same as reference     
      */
     public static class UChannelL13TopPlate extends UChannelL13Plate {
         protected final static double L1_module_pin_to_edge_of_plate = (16.0-2.75)*inch;
@@ -737,12 +653,9 @@
         }
        
     }
-    
-    
+        
     /**
      * Abstract {@link SurveyVolume} volume defining the L4-6 u-channel volume
-     * 
-     *  @author Per Hansson Adrian <[log in to unmask]>
      */
     public abstract static class UChannelL46 extends SurveyVolume {
 
@@ -760,26 +673,18 @@
 
         protected void setBoxDim() {
             setBoxDim(width,length,height);
-        }
-        
-    }
-    
-    
-   
-   
-    
+        }        
+    }
+                 
     /**
      * {@link SurveyVolume} volume defining the coordinate system of the u-channel 
      *  Reference: SVTBox coordinate system
      *  Origin: midpoint between upstream survey cones
      *  Orientation: u - width pointing towards electron side, v - pointing along the U-channel in the beam direction
-     *  
-     *  @author Per Hansson Adrian <[log in to unmask]>
      *
      */
     public static class UChannelL46Bottom extends UChannelL46 {
-        
-        
+                
         protected static final double cone_to_edge_of_plate_y = 2.75*inch;
 
         public UChannelL46Bottom(String name, SurveyVolume m, AlignmentCorrection alignmentCorrection) {
@@ -803,15 +708,12 @@
     
     /**
      * Position of the center of the survey balls when engaging the cones in the side plates of the U-channel.
-     * 
-     * @author Per Hansson Adrian <[log in to unmask]>
      *
      */
     private static class UChannelL46BottomSurveyBalls  {
         
-     // Shawn's calculated point at midpoint between two forward survey balls
+        // Shawn's calculated point at midpoint between two forward survey balls
         protected final static Hep3Vector ball_pos = new BasicHep3Vector(-5.857, -157.776, -8.423);
-
         
         private static final double cone_fwd_right_x = -7.019*inch;
         private static final double cone_fwd_right_y = -6.419*inch;
@@ -841,22 +743,14 @@
             return VecOp.sub(bwd_left, fwd_left);
         }
     }
-    
-    
-    
   
-    
     /**
      * {@link SurveyVolume} volume defining the coordinate system of the u-channel 
-     *  Reference: {@link SVTBox} coordinate system
-     *  Origin: midpoint between upstream survey cones
-     *  Orientation: u - width pointing towards electron side, v - pointing along the U-channel in the beam direction
-     *  
-     *  @author Per Hansson Adrian <[log in to unmask]>
-     *
+     * Reference: {@link HPSTracker2014GeometryDefinition.SVTBox} coordinate system
+     * Origin: midpoint between upstream survey cones
+     * Orientation: u - width pointing towards electron side, v - pointing along the U-channel in the beam direction
      */
     public static class UChannelL46Top extends UChannelL46 {
-
         
         private static final double cone_to_side_plate_pin_y = (0.875-0.25)*inch;
         private static final double side_plate_pin_to_edge_of_plate_y = 1.5*inch;
@@ -886,8 +780,7 @@
             //flatPos = new BasicHep3Vector(ballPos.x(), ballPos.y()-1, ballPos.z()); // random offset
         }
     }
-    
-    
+        
     /**
      * Position of the center of the survey balls when engaging the cones in the side plates of the U-channel.
      * 
@@ -899,7 +792,6 @@
         // Shawn's calculated point at midpoint between two forward survey balls
         protected final static Hep3Vector ball_pos = new BasicHep3Vector(-6.341, -141.909, 8.423);
 
-
         protected static final double cone_fwd_right_x = -7.038*inch;
         protected static final double cone_fwd_right_y = -5.794*inch;
         protected static final double cone_fwd_right_z = 0.332*inch;
@@ -928,14 +820,9 @@
             return VecOp.sub(bwd_right, fwd_right);
         }
     }
-
-
-    
-    /**
-     * Abstract {@link SurveyVolume}  defining the coordinate system of the u-channel plates
-
-     * @author Per Hansson Adrian <[log in to unmask]>
-     *
+    
+    /**
+     * Abstract {@link SurveyVolume}  defining the coordinate system of the u-channel plates     
      */
     public abstract static class UChannelL46Plate extends UChannelPlate {
         public final static double pocket_depth_L4 = 0.1;
@@ -1043,16 +930,12 @@
         }
        
     }
-
-    
-
+  
     /**
      * {@link SurveyVolume} volume defining the coordinate system of module L1-3
      * Reference:  @UChannelL13Bottom coordinate system
      * Origin:  hole position on mounting surface (on electron side)
      * Orientation: u - is normal to the surface pointing vertically down, v - points along module away from hybrid side (i.e. positron direction).
-     * 
-     * @author Per Hansson Adrian <[log in to unmask]>
      *
      */
     public abstract static class ModuleL13 extends BaseModule {
@@ -1119,8 +1002,7 @@
         protected double getHoleModuleCenterOffset() {
             return UChannelL13Bottom.cone_to_edge_of_plate_y - UChannelL13BottomPlate.L1_module_pin_to_edge_of_plate;
         }
-    }
-    
+    }    
     
     public static class ModuleL1Bot extends ModuleL13Bot {
 
@@ -1136,8 +1018,7 @@
             return new BasicHep3Vector(x, y, z);
         }
         
-    }
-    
+    }    
    
     public static class ModuleL1Top extends ModuleL13Top {
 
@@ -1155,9 +1036,7 @@
         }
         
     }
-    
-    
-    
+        
     public static class ModuleL2Bot extends ModuleL13Bot {
 
         public ModuleL2Bot(String name, SurveyVolume mother,
@@ -1190,10 +1069,7 @@
         }
         
     }
-    
-    
-    
-    
+        
     public static class ModuleL3Bot extends ModuleL13Bot {
 
         public ModuleL3Bot(String name, SurveyVolume mother,
@@ -1226,11 +1102,7 @@
         }
         
     }
-    
-    
-    
-   
-    
+                
     /**
      * Abstract {@link SurveyVolume} volume defining the coordinate system of module L4-6
      * 
@@ -1628,8 +1500,6 @@
      * Reference:  @ModuleL13Bot coordinate system
      * Origin:  sensor center
      * Orientation: w - is normal to the surface pointing from p-side to n-side, v - points along strips away from signal bond pads
-     * 
-     * @author Per Hansson Adrian <[log in to unmask]>
      *
      */
     public static class HalfModuleAxial extends HPSTestRunTracker2014GeometryDefinition.TestRunHalfModule {
@@ -1668,8 +1538,6 @@
      * Reference:  @ModuleL13Bot coordinate system
      * Origin:  sensor center
      * Orientation: same as axial - the module is rotated later.
-     * 
-     * @author Per Hansson Adrian <[log in to unmask]>
      *
      */
     public static class HalfModuleStereo extends HPSTestRunTracker2014GeometryDefinition.TestRunHalfModule {
@@ -1873,23 +1741,21 @@
 
     }
 
-
-
-
-
-    /**
-     * @author Per Hansson Adrian <[log in to unmask]>
-     *
+    /**
+     *    
      */
     public static class LongModuleBundle extends BaseModuleBundle {
+        
         public HalfModuleBundle halfModuleAxialHole = null;
         public HalfModuleBundle halfModuleStereoHole = null;
         public HalfModuleBundle halfModuleAxialSlot = null;
         public HalfModuleBundle halfModuleStereoSlot = null;
         protected SurveyVolume coldBlock = null;
+        
         public LongModuleBundle(BaseModule m) {
             super(m);
         }
+        
         public void print() {
             if(module!=null) System.out.printf("%s: %s\n", this.getClass().getSimpleName(),module.toString());
             if(halfModuleAxialHole!=null) halfModuleAxialHole.print();
@@ -1897,13 +1763,11 @@
             if(coldBlock!=null)System.out.printf("%s: %s\n", this.getClass().getSimpleName(),coldBlock.getName());
             if(halfModuleStereoHole!=null) halfModuleStereoHole.print();
             if(halfModuleStereoSlot!=null) halfModuleStereoSlot.print();
-            }
-        }
-
-
-    /**
-     * @author Per Hansson Adrian <[log in to unmask]>
-     *
+        }
+    }
+
+    /**
+     *     
      */
     public static class LongHalfModuleBundle extends HalfModuleBundle {
         public LongHalfModuleBundle() {
@@ -1913,9 +1777,7 @@
             super(hm);
         }
     }
-    
-    
-    
+        
     /**
      * Create the half-module.
      * @param side - stereo or axial
@@ -1955,9 +1817,6 @@
         //TestRunModuleBundle bundle  = (TestRunModuleBundle)getModuleBundle(mother);
         //TestRunHalfModuleBundle halfModuleBundle;
         LongModuleBundle bundle  = (LongModuleBundle)getModuleBundle(mother);
-        
-       
-        
         
         // Build the half-module bundle and half-module
         //TODO clean this up to a separate method
@@ -1983,9 +1842,6 @@
             }
         } 
         halfModuleBundle.halfModule = halfModule;
-        
-        
-    
     
         // create the half module components 
         makeHalfModuleComponentSensor(halfModule);
@@ -1994,13 +1850,8 @@
 
         //makeHalfModuleComponentCF(halfModule);
     
-        //makeHalfModuleComponentHybrid(halfModule);
-    
-    
-    
-    
-    }
-
+        //makeHalfModuleComponentHybrid(halfModule);    
+    }
 
     protected void makeLongHalfModuleComponentKapton(BaseModule mother) {
         
@@ -2022,10 +1873,6 @@
     
     }
 
-    
-    
-    
-    
     protected HPSTestRunTracker2014GeometryDefinition.TestRunHalfModule createTestRunHalfModuleAxial(String volName,
             BaseModule mother, AlignmentCorrection alignmentCorrection,
             int layer, String half) {
@@ -2047,7 +1894,6 @@
      * @param alignmentCorrection
      * @param layer
      * @param half
-     * @return
      */
     protected LongHalfModule createLongAxialSlotHalfModule(String name, SurveyVolume mother,
             AlignmentCorrection alignmentCorrection, int layer,
@@ -2062,16 +1908,13 @@
      * @param alignmentCorrection
      * @param layer
      * @param half
-     * @return
      */
     protected LongHalfModule createLongStereoSlotHalfModule(String name, SurveyVolume mother,
             AlignmentCorrection alignmentCorrection, int layer,
             String half) {
         return new LongStereoSlotHalfModule(name, mother, alignmentCorrection, layer, half);
     }
-    
-    
-    
+
     /* (non-Javadoc)
      * @see org.lcsim.geometry.compact.converter.HPSTrackerGeometryDefinition#getHalfModuleBundle(org.lcsim.geometry.compact.converter.HPSTestRunTracker2014GeometryDefinition.BaseModule, java.lang.String)
      */
@@ -2121,9 +1964,6 @@
         }
         return hm;
     }
-
-
-    
     
     /* (non-Javadoc)
      * @see org.lcsim.geometry.compact.converter.HPSTrackerBuilder#getMillepedeLayer(java.lang.String)
@@ -2149,8 +1989,6 @@
         return  getMillepedeLayer(isTopLayer, layer, isAxial, isHole);
 
     }
-    
-    
 
     /**
      * Definition relating the sensors and layer number used in millepede for this detector.
@@ -2158,7 +1996,6 @@
      * @param layer
      * @param isAxial
      * @param isHole
-     * @return
      */
     public int getMillepedeLayer(boolean isTopLayer, int layer, boolean isAxial, boolean isHole) {
         int l = -1;
@@ -2208,16 +2045,7 @@
         if(l<0) throw new RuntimeException("Error getting the millepede layer.");
         
         if(isDebug()) System.out.printf("%s: %s %d %s %s -> MP layer %d\n",getClass().getSimpleName(),isTopLayer?"top":"bottom", layer, isAxial?"axial":"stereo", isHole?"hole":"slot", l);
-
         
         return l;
     }
-
-
-   
-
 }
-
-
-
-

Modified: java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTracker2014JavaBuilder.java
 =============================================================================
--- java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTracker2014JavaBuilder.java	(original)
+++ java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTracker2014JavaBuilder.java	Wed Apr 27 11:11:32 2016
@@ -28,122 +28,122 @@
  */
 public class HPSTracker2014JavaBuilder extends HPSTestRunTracker2014JavaBuilder {
 
-	
-	
-	/**
-	 * Default constructor
-	 * @param node 
-	 */
-	public HPSTracker2014JavaBuilder(boolean debugFlag, Element node) {
-		super(debugFlag, node);
-	}
-	
-	
-	
-	
-	/**
-	 * Build the JAVA geometry objects from the geometry definition.
-	 * @param trackingVolume - the reference volume.
-	 */
-	public void build(ILogicalVolume trackingVolume) {
-
-		// build geometry
+    
+    
+    /**
+     * Default constructor
+     * @param node 
+     */
+    public HPSTracker2014JavaBuilder(boolean debugFlag, Element node) {
+        super(debugFlag, node);
+    }
+    
+    
+    
+    
+    /**
+     * Build the JAVA geometry objects from the geometry definition.
+     * @param trackingVolume - the reference volume.
+     */
+    public void build(ILogicalVolume trackingVolume) {
+
+        // build geometry
         setBuilder(createGeometryDefinition(this._debug, node));
-		
-		if(_builder==null) throw new RuntimeException("need to set builder class before calling build!");
-
-		if(isDebug()) System.out.printf("%s: build the base geometry objects\n", getClass().getSimpleName());
-		
-		_builder.build();
-
-		if(isDebug()) System.out.printf("%s: DONE build the base geometry objects\n", getClass().getSimpleName());
-
-		if(isDebug()) System.out.printf("%s: build the JAVA geometry objects\n", getClass().getSimpleName());
-		
-		// initialize the list to store a reference to each object
-		javaSurveyVolumes = new ArrayList<JavaSurveyVolume>();
-
-		// Go through the list of volumes to build that is created in the generic builder class
-		JavaSurveyVolume tracking = new JavaSurveyVolume(_builder.getSurveyVolume(TrackingVolume.class), trackingVolume);
-		add(tracking);
-		JavaSurveyVolume chamber = new JavaGhostSurveyVolume(_builder.getSurveyVolume(PSVacuumChamber.class), tracking);
-		add(chamber);
-		setBaseTrackerGeometry(new JavaSurveyVolume(_builder.getSurveyVolume(SvtBox.class), chamber,1));
-		add(getBaseTrackerGeometry());
-		JavaSurveyVolume svtBoxBasePlate = new JavaGhostSurveyVolume(_builder.getSurveyVolume(SvtBoxBasePlate.class), getBaseTrackerGeometry());
-		add(svtBoxBasePlate);
-
-		
-		// build modules	
-		
-		if(isDebug()) System.out.printf("%s: build JAVA modules\n", getClass().getSimpleName());
-
-		// Loop over all modules created
-		for(BaseModuleBundle mod : _builder.modules) {
-			BaseModuleBundle m = mod;
-		    if(isDebug()) { 
-				System.out.printf("%s: build module %s (layer %d half %s)\n", getClass().getSimpleName(),m.module.getName(),m.getLayer(),m.getHalf());
-				m.print();
-			}
-
-			// Find the mother among the objects using its name, should probably have a better way...
-			String name_mother = m.getMother().getName();
-			JavaSurveyVolume mother = null;
-			for(JavaSurveyVolume g : javaSurveyVolumes) {
-				if(g.getName().equals(name_mother)) {
-					mother = g;
-					break;
-				}
-			}
-			// Check that it had a mother
-			if(mother==null) throw new RuntimeException("Cound't find mother to module " + m.module.getName());
-
-			if(isDebug()) System.out.printf("%s: found mother %s to module %s\n", getClass().getSimpleName(),mother.getName(),m.module.getName());
-			
-			// put the module in the list of objects that will be added to LCDD
-			addModule(m, mother);
-			
-			if(isDebug()) System.out.printf("%s: DONE build module %s\n", getClass().getSimpleName(), m.module.getName());
-
-			
-		}
-		
-		if(isDebug()) System.out.printf("%s: DONE build JAVA modules\n", getClass().getSimpleName());
-
-		
-		//System.out.printf("%s: Built %d JAVA geometry objects\n", getClass().getSimpleName(),javaSurveyVolumes.size());
-		
-		if(isDebug()) {
-		    System.out.printf("%s: DONE building the JAVA geometry objects\n", getClass().getSimpleName());
-		    System.out.printf("%s: List of all the JAVA geometry objects built\n", this.getClass().getSimpleName());
-		    for(JavaSurveyVolume bg : javaSurveyVolumes) {
-		        System.out.printf("-------\n%s\n", bg.toString());
-		    }
-		}
-
-
-		// Set visualization features
-		//setVis();
-
-
-	}
-
-	/**
-	 * Rules for adding the JAVA module geometry.
-	 * @param bundle - module to be added
-	 * @param mother - mother JAVA geometry object
-	 */
-	private void addModule(BaseModuleBundle bundle, JavaSurveyVolume mother) {
-	    if(bundle instanceof TestRunModuleBundle) {
-	           addTestRunModule((TestRunModuleBundle) bundle, mother);
-	       } else if(bundle instanceof LongModuleBundle) {
-	           addLongModule((LongModuleBundle) bundle, mother);
-	       } else {
-	           throw new RuntimeException("The bundle is of unknown class type!");
-	       }
-	}
-	
-	/**
+        
+        if(_builder==null) throw new RuntimeException("need to set builder class before calling build!");
+
+        if(isDebug()) System.out.printf("%s: build the base geometry objects\n", getClass().getSimpleName());
+        
+        _builder.build();
+
+        if(isDebug()) System.out.printf("%s: DONE build the base geometry objects\n", getClass().getSimpleName());
+
+        if(isDebug()) System.out.printf("%s: build the JAVA geometry objects\n", getClass().getSimpleName());
+        
+        // initialize the list to store a reference to each object
+        javaSurveyVolumes = new ArrayList<JavaSurveyVolume>();
+
+        // Go through the list of volumes to build that is created in the generic builder class
+        JavaSurveyVolume tracking = new JavaSurveyVolume(_builder.getSurveyVolume(TrackingVolume.class), trackingVolume);
+        add(tracking);
+        JavaSurveyVolume chamber = new JavaGhostSurveyVolume(_builder.getSurveyVolume(PSVacuumChamber.class), tracking);
+        add(chamber);
+        setBaseTrackerGeometry(new JavaSurveyVolume(_builder.getSurveyVolume(SvtBox.class), chamber,1));
+        add(getBaseTrackerGeometry());
+        JavaSurveyVolume svtBoxBasePlate = new JavaGhostSurveyVolume(_builder.getSurveyVolume(SvtBoxBasePlate.class), getBaseTrackerGeometry());
+        add(svtBoxBasePlate);
+
+        
+        // build modules    
+        
+        if(isDebug()) System.out.printf("%s: build JAVA modules\n", getClass().getSimpleName());
+
+        // Loop over all modules created
+        for(BaseModuleBundle mod : _builder.modules) {
+            BaseModuleBundle m = mod;
+            if(isDebug()) { 
+                System.out.printf("%s: build module %s (layer %d half %s)\n", getClass().getSimpleName(),m.module.getName(),m.getLayer(),m.getHalf());
+                m.print();
+            }
+
+            // Find the mother among the objects using its name, should probably have a better way...
+            String name_mother = m.getMother().getName();
+            JavaSurveyVolume mother = null;
+            for(JavaSurveyVolume g : javaSurveyVolumes) {
+                if(g.getName().equals(name_mother)) {
+                    mother = g;
+                    break;
+                }
+            }
+            // Check that it had a mother
+            if(mother==null) throw new RuntimeException("Cound't find mother to module " + m.module.getName());
+
+            if(isDebug()) System.out.printf("%s: found mother %s to module %s\n", getClass().getSimpleName(),mother.getName(),m.module.getName());
+            
+            // put the module in the list of objects that will be added to LCDD
+            addModule(m, mother);
+            
+            if(isDebug()) System.out.printf("%s: DONE build module %s\n", getClass().getSimpleName(), m.module.getName());
+
+            
+        }
+        
+        if(isDebug()) System.out.printf("%s: DONE build JAVA modules\n", getClass().getSimpleName());
+
+        
+        //System.out.printf("%s: Built %d JAVA geometry objects\n", getClass().getSimpleName(),javaSurveyVolumes.size());
+        
+        if(isDebug()) {
+            System.out.printf("%s: DONE building the JAVA geometry objects\n", getClass().getSimpleName());
+            System.out.printf("%s: List of all the JAVA geometry objects built\n", this.getClass().getSimpleName());
+            for(JavaSurveyVolume bg : javaSurveyVolumes) {
+                System.out.printf("-------\n%s\n", bg.toString());
+            }
+        }
+
+
+        // Set visualization features
+        //setVis();
+
+
+    }
+
+    /**
+     * Rules for adding the JAVA module geometry.
+     * @param bundle - module to be added
+     * @param mother - mother JAVA geometry object
+     */
+    private void addModule(BaseModuleBundle bundle, JavaSurveyVolume mother) {
+        if(bundle instanceof TestRunModuleBundle) {
+               addTestRunModule((TestRunModuleBundle) bundle, mother);
+           } else if(bundle instanceof LongModuleBundle) {
+               addLongModule((LongModuleBundle) bundle, mother);
+           } else {
+               throw new RuntimeException("The bundle is of unknown class type!");
+           }
+    }
+    
+    /**
      * Rules for adding the LCDD module geometry.
      * @param bundle - module to be added
      * @param mother - mother LCDD geometry object
@@ -191,12 +191,12 @@
         
         
     }
-	
+    
     @Override
     public HPSTrackerGeometryDefinition createGeometryDefinition(boolean debug, Element node) {
         return new HPSTracker2014GeometryDefinition(debug, node);
     }
-	
-	
+    
+    
 
 }

Modified: java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTracker2014v1GeometryDefinition.java
 =============================================================================
--- java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTracker2014v1GeometryDefinition.java	(original)
+++ java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTracker2014v1GeometryDefinition.java	Wed Apr 27 11:11:32 2016
@@ -7,7 +7,7 @@
 /**
  * 
  * Updated geometry information for the HPS tracker 2014
-
+ * 
  * @author Per Hansson Adrian <[log in to unmask]>
  *
  */
@@ -93,8 +93,7 @@
 
     
     /**
-     * PI rotation around generic z-axis
-     * @return
+     * PI rotation around generic z-axis 
      */
     private static Rotation getSlotRotation() {
         return new Rotation(new Vector3D(0,0,1),Math.PI);

Modified: java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTrackerBuilder.java
 =============================================================================
--- java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTrackerBuilder.java	(original)
+++ java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTrackerBuilder.java	Wed Apr 27 11:11:32 2016
@@ -632,7 +632,7 @@
     /**
      * Get hole or slot key name from string
      * 
-     * @param name.
+     * @param name "hole" or "slot"
      * @return hole or not boolean
      */
     public static boolean isHoleFromName(String name) {
@@ -649,10 +649,7 @@
     /**
      * Extract old definition of Test Run sensor number.
      * 
-     * @param isTopLayer - top or bottom layer
-     * @param l - layer
-     * @param isAxial - axial or stereo sensor
-     * @return
+     * @return the geometric layer according to Test Run definition
      */
     public int getOldGeomDefLayerFromVolumeName(String name) {
 
@@ -672,8 +669,7 @@
     /**
      * Get the layer number consistent with the old geometry definition.
      * 
-     * @param module name that contains layer and half information.
-     * @return the layer.
+     * @return the older layer definition
      */
     public int getOldLayerDefinition(boolean isTopLayer, int l, boolean isAxial) {
         int layer = -1;

Modified: java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTrackerGeometryDefinition.java
 =============================================================================
--- java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTrackerGeometryDefinition.java	(original)
+++ java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTrackerGeometryDefinition.java	Wed Apr 27 11:11:32 2016
@@ -41,7 +41,7 @@
     protected static final boolean use30mradRotation = true;
     protected static final boolean useFakeHalfModuleAxialPos = false;
 
-    // Global position references	
+    // Global position references   
     protected static final double target_pos_wrt_base_plate_x = 162.3; //from Marco's 3D model
     protected static final double target_pos_wrt_base_plate_y = 80.55; //from Tim's sketchup //68.75; //from Marco's 3D model
     protected static final double target_pos_wrt_base_plate_z = 926.59; //from Marco's 3D model

Modified: java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTrackerJavaBuilder.java
 =============================================================================
--- java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTrackerJavaBuilder.java	(original)
+++ java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTrackerJavaBuilder.java	Wed Apr 27 11:11:32 2016
@@ -15,158 +15,158 @@
 
 public abstract class HPSTrackerJavaBuilder implements IHPSTrackerJavaBuilder {
 
-	protected boolean _debug = false;
-	private JavaSurveyVolume baseSurveyVolume;
-	protected List<JavaSurveyVolume> javaSurveyVolumes = new ArrayList<JavaSurveyVolume>();
-	protected DetectorIdentifierHelper detectorIdentifierHelper;
-	protected IIdentifierDictionary identifierDictionary;
-	protected Subdetector subdet;
-	protected List<IDetectorElement> layerDetectorElements = new ArrayList<IDetectorElement>();
-	protected List<IDetectorElement> moduleDetectorElements = new ArrayList<IDetectorElement>();
-	protected IDetectorElement baseDetectorElement = null;
-	public HPSTrackerBuilder _builder = null;
+    protected boolean _debug = false;
+    private JavaSurveyVolume baseSurveyVolume;
+    protected List<JavaSurveyVolume> javaSurveyVolumes = new ArrayList<JavaSurveyVolume>();
+    protected DetectorIdentifierHelper detectorIdentifierHelper;
+    protected IIdentifierDictionary identifierDictionary;
+    protected Subdetector subdet;
+    protected List<IDetectorElement> layerDetectorElements = new ArrayList<IDetectorElement>();
+    protected List<IDetectorElement> moduleDetectorElements = new ArrayList<IDetectorElement>();
+    protected IDetectorElement baseDetectorElement = null;
+    public HPSTrackerBuilder _builder = null;
     protected Element node = null;
-	
-	public HPSTrackerJavaBuilder(boolean debugFlag, Element node) {
-		this._debug=debugFlag;
-		this.node  = node;
-	}	
-	
-	public abstract void build(ILogicalVolume trackingVolume);
-	public abstract HPSTrackerGeometryDefinition createGeometryDefinition(boolean debug, Element node);
+    
+    public HPSTrackerJavaBuilder(boolean debugFlag, Element node) {
+        this._debug=debugFlag;
+        this.node  = node;
+    }   
+    
+    public abstract void build(ILogicalVolume trackingVolume);
+    public abstract HPSTrackerGeometryDefinition createGeometryDefinition(boolean debug, Element node);
 
-	
-	/**
-	 * Add to list of objects.
-	 * @param geom - object to add.
-	 */
-	public void add(JavaSurveyVolume geom) {
-		javaSurveyVolumes.add(geom);
-	}
-	
-	public void setBuilder(HPSTrackerBuilder b) {
-		_builder = b;
-	}
-	
-	public void build() {
-		_builder.build();
-	}
-	
-	public void setDebug(boolean debug) {
-		_debug = debug;
-	}
-	
-	public boolean isDebug() {
-		return _debug;
-	}
+    
+    /**
+     * Add to list of objects.
+     * @param geom - object to add.
+     */
+    public void add(JavaSurveyVolume geom) {
+        javaSurveyVolumes.add(geom);
+    }
+    
+    public void setBuilder(HPSTrackerBuilder b) {
+        _builder = b;
+    }
+    
+    public void build() {
+        _builder.build();
+    }
+    
+    public void setDebug(boolean debug) {
+        _debug = debug;
+    }
+    
+    public boolean isDebug() {
+        return _debug;
+    }
 
 
-	public DetectorIdentifierHelper getDetectorIdentifierHelper() {
-		return detectorIdentifierHelper;
-	}
+    public DetectorIdentifierHelper getDetectorIdentifierHelper() {
+        return detectorIdentifierHelper;
+    }
 
-	public void setDetectorIdentifierHelper(
-			DetectorIdentifierHelper detectorIdentifierHelper) {
-		this.detectorIdentifierHelper = detectorIdentifierHelper;
-	}
+    public void setDetectorIdentifierHelper(
+            DetectorIdentifierHelper detectorIdentifierHelper) {
+        this.detectorIdentifierHelper = detectorIdentifierHelper;
+    }
 
-	public IIdentifierDictionary getIdentifierDictionary() {
-		return identifierDictionary;
-	}
+    public IIdentifierDictionary getIdentifierDictionary() {
+        return identifierDictionary;
+    }
 
-	public void setIdentifierDictionary(
-			IIdentifierDictionary identifierDictionary) {
-		this.identifierDictionary = identifierDictionary;
-	}
+    public void setIdentifierDictionary(
+            IIdentifierDictionary identifierDictionary) {
+        this.identifierDictionary = identifierDictionary;
+    }
 
 
-	public void setSubdetector(Subdetector subdet) {
-		this.subdet = subdet;
-	}
+    public void setSubdetector(Subdetector subdet) {
+        this.subdet = subdet;
+    }
 
-	public Subdetector getSubdetector() {
-		return this.subdet;
-	}
+    public Subdetector getSubdetector() {
+        return this.subdet;
+    }
 
-	
+    
 
-	
+    
 
-	// This finds specific type. I would like to use the ID for this but can't, I think.
-	// TODO there must be a factory instance to do this
-	public SiTrackerModule getModuleDetectorElement(SiTrackerModule testElement) {
-		if(isDebug()) System.out.printf("%s: getModuleDetectorElement for module  %s path: \"%s\"\n", this.getClass().getSimpleName(),testElement.getName(),testElement.getGeometry().getPathString());
-		SiTrackerModule element = null;
-		for(IDetectorElement e : moduleDetectorElements) {
-			SiTrackerModule m = (SiTrackerModule) e;
-			if(isDebug()) System.out.printf("%s: compare with module  %s path: %s\"%s\" \n", this.getClass().getSimpleName(),m.getName(),m.getGeometry().getPathString());
-			if(m.getGeometry().getPathString().equals(testElement.getGeometry().getPathString())) {
-				if(element!=null) throw new RuntimeException("two DE sharing extended ID?");
-				if(isDebug()) System.out.printf("%s: found it\n", this.getClass().getSimpleName());
-				element = m;
-			}
-		}
-		return element;
-	}
+    // This finds specific type. I would like to use the ID for this but can't, I think.
+    // TODO there must be a factory instance to do this
+    public SiTrackerModule getModuleDetectorElement(SiTrackerModule testElement) {
+        if(isDebug()) System.out.printf("%s: getModuleDetectorElement for module  %s path: \"%s\"\n", this.getClass().getSimpleName(),testElement.getName(),testElement.getGeometry().getPathString());
+        SiTrackerModule element = null;
+        for(IDetectorElement e : moduleDetectorElements) {
+            SiTrackerModule m = (SiTrackerModule) e;
+            if(isDebug()) System.out.printf("%s: compare with module  %s path: %s\"%s\" \n", this.getClass().getSimpleName(),m.getName(),m.getGeometry().getPathString());
+            if(m.getGeometry().getPathString().equals(testElement.getGeometry().getPathString())) {
+                if(element!=null) throw new RuntimeException("two DE sharing extended ID?");
+                if(isDebug()) System.out.printf("%s: found it\n", this.getClass().getSimpleName());
+                element = m;
+            }
+        }
+        return element;
+    }
 
-	
-	// Find detector elements
-	// TODO This should be using some global geometry code like DetectorElementStore?
-	public IDetectorElement getLayerDetectorElement(IExpandedIdentifier expId) {
-		IDetectorElement element = null;
-		if(isDebug()) System.out.printf("%s: search among %d layer DEs\n", this.getClass().getSimpleName(), layerDetectorElements.size());
-		for(IDetectorElement e : layerDetectorElements) {
-			if(isDebug()) System.out.printf("%s: test %s\n", this.getClass().getSimpleName(),e.getName());
-			ExpandedIdentifier eId = (ExpandedIdentifier) e.getExpandedIdentifier();
-			if(eId.equals(expId)) { // TODO order matters as expId is an interface without that function!?
-				//check that only one was found
-				if(element!=null) throw new RuntimeException("two DE sharing extended ID?");
-				if(isDebug()) System.out.printf("%s: found it\n", this.getClass().getSimpleName());
-				element = e;
-			}
+    
+    // Find detector elements
+    // TODO This should be using some global geometry code like DetectorElementStore?
+    public IDetectorElement getLayerDetectorElement(IExpandedIdentifier expId) {
+        IDetectorElement element = null;
+        if(isDebug()) System.out.printf("%s: search among %d layer DEs\n", this.getClass().getSimpleName(), layerDetectorElements.size());
+        for(IDetectorElement e : layerDetectorElements) {
+            if(isDebug()) System.out.printf("%s: test %s\n", this.getClass().getSimpleName(),e.getName());
+            ExpandedIdentifier eId = (ExpandedIdentifier) e.getExpandedIdentifier();
+            if(eId.equals(expId)) { // TODO order matters as expId is an interface without that function!?
+                //check that only one was found
+                if(element!=null) throw new RuntimeException("two DE sharing extended ID?");
+                if(isDebug()) System.out.printf("%s: found it\n", this.getClass().getSimpleName());
+                element = e;
+            }
 
-		}
-		return element;
-	}
+        }
+        return element;
+    }
 
 
-	public void addLayerDetectorElement(IDetectorElement e) {
-		IExpandedIdentifier expId = e.getExpandedIdentifier();
-		if(getLayerDetectorElement(expId) != null) 
-			throw new RuntimeException("Trying to add an existing layer detector element.");
-		layerDetectorElements.add(e);
-	}
+    public void addLayerDetectorElement(IDetectorElement e) {
+        IExpandedIdentifier expId = e.getExpandedIdentifier();
+        if(getLayerDetectorElement(expId) != null) 
+            throw new RuntimeException("Trying to add an existing layer detector element.");
+        layerDetectorElements.add(e);
+    }
 
-	public void addBaseDetectorElement(IDetectorElement e) {
-	    baseDetectorElement = e;
-	}
+    public void addBaseDetectorElement(IDetectorElement e) {
+        baseDetectorElement = e;
+    }
 
-	public IDetectorElement getBaseDetectorElement() {
-	    return baseDetectorElement;
-	}
+    public IDetectorElement getBaseDetectorElement() {
+        return baseDetectorElement;
+    }
 
-	public void addModuleDetectorElement(IDetectorElement e) {
-		if(!(e instanceof SiTrackerModule)) 
-			throw new RuntimeException("Trying to add an existing module of wrong type.");
-		if(getModuleDetectorElement((SiTrackerModule) e) != null) 
-			throw new RuntimeException("Trying to add an already existing module detector element.");
-		layerDetectorElements.add(e);
-	}
-	
+    public void addModuleDetectorElement(IDetectorElement e) {
+        if(!(e instanceof SiTrackerModule)) 
+            throw new RuntimeException("Trying to add an existing module of wrong type.");
+        if(getModuleDetectorElement((SiTrackerModule) e) != null) 
+            throw new RuntimeException("Trying to add an already existing module detector element.");
+        layerDetectorElements.add(e);
+    }
+    
 
-	/**
-	 * @return the baseTrackerGeometry
-	 */
-	public JavaSurveyVolume getBaseTrackerGeometry() {
-		return baseSurveyVolume;
-	}
+    /**
+     * @return the baseTrackerGeometry
+     */
+    public JavaSurveyVolume getBaseTrackerGeometry() {
+        return baseSurveyVolume;
+    }
 
-	/**
-	 * @param baseTrackerGeometry the baseTrackerGeometry to set
-	 */
-	public void setBaseTrackerGeometry(JavaSurveyVolume baseTrackerGeometry) {
-		this.baseSurveyVolume = baseTrackerGeometry;
-	}
+    /**
+     * @param baseTrackerGeometry the baseTrackerGeometry to set
+     */
+    public void setBaseTrackerGeometry(JavaSurveyVolume baseTrackerGeometry) {
+        this.baseSurveyVolume = baseTrackerGeometry;
+    }
 
 
 }

Modified: java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTrackerLCDDBuilder.java
 =============================================================================
--- java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTrackerLCDDBuilder.java	(original)
+++ java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTrackerLCDDBuilder.java	Wed Apr 27 11:11:32 2016
@@ -10,24 +10,24 @@
 
 public abstract class HPSTrackerLCDDBuilder  implements IHPSTrackerLCDDBuilder {
 
-	public boolean _debug = false;
-	protected LCDD lcdd = null;
-	protected LCDDSurveyVolume baseSurveyVolume;
-	protected List<LCDDSurveyVolume> lcddSurveyVolumes = new ArrayList<LCDDSurveyVolume>();
-	private SensitiveDetector sensitiveDetector;
-	public HPSTrackerBuilder _builder = null;
+    public boolean _debug = false;
+    protected LCDD lcdd = null;
+    protected LCDDSurveyVolume baseSurveyVolume;
+    protected List<LCDDSurveyVolume> lcddSurveyVolumes = new ArrayList<LCDDSurveyVolume>();
+    private SensitiveDetector sensitiveDetector;
+    public HPSTrackerBuilder _builder = null;
     protected Element node;
 
-	
-	
-	public HPSTrackerLCDDBuilder(boolean debugFlag, Element node, LCDD lcdd2, SensitiveDetector sens) {
-		setDebug(debugFlag);
-		setLCDD(lcdd2);
-		setSensitiveDetector(sens);
-		setNode(node);
-	}
-	
-	/**
+    
+    
+    public HPSTrackerLCDDBuilder(boolean debugFlag, Element node, LCDD lcdd2, SensitiveDetector sens) {
+        setDebug(debugFlag);
+        setLCDD(lcdd2);
+        setSensitiveDetector(sens);
+        setNode(node);
+    }
+    
+    /**
      * Build the LCDD geometry objects.
      * @param worldVolume - the reference volume.
      */
@@ -37,93 +37,93 @@
     public abstract void setBuilder();
     
     public abstract HPSTrackerGeometryDefinition createGeometryDefinition(boolean debug, Element node);
-	
+    
 
-	public void setNode(Element node) {
+    public void setNode(Element node) {
         this.node = node;
-	}
-	
+    }
+    
     public void setSensitiveDetector(SensitiveDetector sens) {
-		this.sensitiveDetector = sens;
-	}
+        this.sensitiveDetector = sens;
+    }
 
-	public SensitiveDetector getSensitiveDetector() {
-		return this.sensitiveDetector;
-	}
+    public SensitiveDetector getSensitiveDetector() {
+        return this.sensitiveDetector;
+    }
 
-	public void setBuilder(HPSTrackerBuilder b) {
-		_builder = b;
-	}
-	
-	public HPSTrackerBuilder getBuilder() {
-	    return _builder;
-	}
-	
-	public void build() {
-		_builder.build();
-	}
-	
-	public void setDebug(boolean debug) {
-		_debug = debug;
-	}
-	
-	public boolean isDebug() {
-		return _debug;
-	}
-	
-	/**
-	 * Add to list of objects.
-	 * @param geom - object to add.
-	 */
-	public void add(LCDDSurveyVolume geom) {
-		lcddSurveyVolumes.add(geom);
-	}
+    public void setBuilder(HPSTrackerBuilder b) {
+        _builder = b;
+    }
+    
+    public HPSTrackerBuilder getBuilder() {
+        return _builder;
+    }
+    
+    public void build() {
+        _builder.build();
+    }
+    
+    public void setDebug(boolean debug) {
+        _debug = debug;
+    }
+    
+    public boolean isDebug() {
+        return _debug;
+    }
+    
+    /**
+     * Add to list of objects.
+     * @param geom - object to add.
+     */
+    public void add(LCDDSurveyVolume geom) {
+        lcddSurveyVolumes.add(geom);
+    }
 
-	
-	
+    
+    
 
-	public void setLCDD(LCDD lcdd) {
-		this.lcdd = lcdd;
-	}
+    public void setLCDD(LCDD lcdd) {
+        this.lcdd = lcdd;
+    }
 
-	public LCDD getLCDD() {
-		return lcdd;
-	}
+    public LCDD getLCDD() {
+        return lcdd;
+    }
 
-	public LCDDSurveyVolume getBaseLCDD() {
-		return baseSurveyVolume;
-	}
+    public LCDDSurveyVolume getBaseLCDD() {
+        return baseSurveyVolume;
+    }
 
-	public void setVisualization() {
-	
-		if(isDebug()) System.out.printf("%s: Set LCDD visualization for %d LCDD geometry objects \n", getClass().getSimpleName(), lcddSurveyVolumes.size());
-		for(SurveyVolumeImpl g : lcddSurveyVolumes) {
-		    String name = g.getName();
-			if(isDebug()) System.out.printf("%s: Set LCDD vis for %s \n", getClass().getSimpleName(), name);			
-			if(name.contains("base_plate")) g.setVisName("BasePlateVis");
+    public void setVisualization() {
+    
+        if(isDebug()) System.out.printf("%s: Set LCDD visualization for %d LCDD geometry objects \n", getClass().getSimpleName(), lcddSurveyVolumes.size());
+        for(SurveyVolumeImpl g : lcddSurveyVolumes) {
+            String name = g.getName();
+            if(isDebug()) System.out.printf("%s: Set LCDD vis for %s \n", getClass().getSimpleName(), name);            
+            if(name.contains("base_plate")) g.setVisName("BasePlateVis");
             else if(name.equals("base")) g.setVisName("SvtBoxVis");
-			else if(name.contains("chamber")) g.setVisName("ChamberVis");
-			else if(name.contains("support_bottom") || name.contains("support_top")) g.setVisName("SupportVolumeVis");
-			else if(name.contains("support_plate")) g.setVisName("SupportPlateVis");
-			else if(name.startsWith("module_")) {
-			    if(name.endsWith("halfmodule_axial") || name.endsWith("halfmodule_stereo")) g.setVisName("HalfModuleVis");
-			    else if(name.endsWith("cold")) g.setVisName("ColdBlockVis");
-			    else if(name.endsWith("lamination")) g.setVisName("KaptonVis");
-			    else if(name.endsWith("sensor")) g.setVisName("SensorVis");
-			    else if(name.endsWith("sensor_active")) g.setVisName("SensorVis");
-			    else if(name.endsWith("cf")) g.setVisName("CarbonFiberVis");
-			    else if(name.endsWith("hybrid")) g.setVisName("HybridVis");
-			    else {
-			        //this must be a module then?
-			        g.setVisName("ModuleVis");
-			    }
-			}
-			else {
-				if(isDebug()) System.out.printf("%s: No LCDD vis for %s \n", getClass().getSimpleName(), name);
-			}
-		}
-		if(isDebug()) System.out.printf("%s: DONE Set LCDD vis \n", getClass().getSimpleName());
-	}
-	
+            else if(name.contains("chamber")) g.setVisName("ChamberVis");
+            else if(name.contains("support_bottom") || name.contains("support_top")) g.setVisName("SupportVolumeVis");
+            else if(name.contains("support_plate")) g.setVisName("SupportPlateVis");
+            else if(name.startsWith("module_")) {
+                if(name.endsWith("halfmodule_axial") || name.endsWith("halfmodule_stereo")) g.setVisName("HalfModuleVis");
+                else if(name.endsWith("cold")) g.setVisName("ColdBlockVis");
+                else if(name.endsWith("lamination")) g.setVisName("KaptonVis");
+                else if(name.endsWith("sensor")) g.setVisName("SensorVis");
+                else if(name.endsWith("sensor_active")) g.setVisName("SensorVis");
+                else if(name.endsWith("cf")) g.setVisName("CarbonFiberVis");
+                else if(name.endsWith("hybrid")) g.setVisName("HybridVis");
+                else {
+                    //this must be a module then?
+                    g.setVisName("ModuleVis");
+                }
+            }
+            else {
+                if(isDebug()) System.out.printf("%s: No LCDD vis for %s \n", getClass().getSimpleName(), name);
+            }
+        }
+        if(isDebug()) System.out.printf("%s: DONE Set LCDD vis \n", getClass().getSimpleName());
+    }
+    
 
 }

Modified: java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/IHPSTrackerJavaBuilder.java
 =============================================================================
--- java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/IHPSTrackerJavaBuilder.java	(original)
+++ java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/IHPSTrackerJavaBuilder.java	Wed Apr 27 11:11:32 2016
@@ -7,25 +7,25 @@
 
 public interface IHPSTrackerJavaBuilder {
 
-	/**
-	 * Build the JAVA geometry objects from the geometry definition.
-	 * @param trackingVolume - the reference volume.
-	 */
-	public void build(ILogicalVolume trackingVolume);
-	
-	public DetectorIdentifierHelper getDetectorIdentifierHelper();
+    /**
+     * Build the JAVA geometry objects from the geometry definition.
+     * @param trackingVolume - the reference volume.
+     */
+    public void build(ILogicalVolume trackingVolume);
+    
+    public DetectorIdentifierHelper getDetectorIdentifierHelper();
 
-	public void setDetectorIdentifierHelper(
-			DetectorIdentifierHelper detectorIdentifierHelper);
+    public void setDetectorIdentifierHelper(
+            DetectorIdentifierHelper detectorIdentifierHelper);
 
-	public IIdentifierDictionary getIdentifierDictionary();
+    public IIdentifierDictionary getIdentifierDictionary();
 
-	public void setIdentifierDictionary(
-			IIdentifierDictionary identifierDictionary);
+    public void setIdentifierDictionary(
+            IIdentifierDictionary identifierDictionary);
 
 
-	public void setSubdetector(Subdetector subdet);
+    public void setSubdetector(Subdetector subdet);
 
-	public Subdetector getSubdetector();
-	
+    public Subdetector getSubdetector();
+    
 }

Modified: java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/IHPSTrackerLCDDBuilder.java
 =============================================================================
--- java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/IHPSTrackerLCDDBuilder.java	(original)
+++ java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/IHPSTrackerLCDDBuilder.java	Wed Apr 27 11:11:32 2016
@@ -5,11 +5,11 @@
 
 public interface IHPSTrackerLCDDBuilder {
 
-	public  void setSensitiveDetector(SensitiveDetector sens);
+    public  void setSensitiveDetector(SensitiveDetector sens);
 
-	public  SensitiveDetector getSensitiveDetector();
-	
-	public void build(Volume worldVolume);
+    public  SensitiveDetector getSensitiveDetector();
+    
+    public void build(Volume worldVolume);
 
-	public void setVisualization();
+    public void setVisualization();
 }

Modified: java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/JavaGhostSurveyVolume.java
 =============================================================================
--- java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/JavaGhostSurveyVolume.java	(original)
+++ java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/JavaGhostSurveyVolume.java	Wed Apr 27 11:11:32 2016
@@ -7,22 +7,22 @@
  * @author Per Hansson Adrian <[log in to unmask]>
  */
 public class JavaGhostSurveyVolume extends JavaSurveyVolume {
-	
-	/**
-	 * Initialize with base and mother. This is typically for a reference geometry object 
-	 * that is used for referencing coordinate systems but that doesn't have a volume itself.
-	 * @param surveyVolume - object used to get geometry definitions
-	 * @param mother - mother object
-	 */
-	public JavaGhostSurveyVolume(SurveyVolume surveyVolume, JavaSurveyVolume mother) {
-		super(surveyVolume);
-		if(isDebug()) System.out.printf("%s: constructing JAVA ghost object %s with mother %s\n", this.getClass().getSimpleName(),surveyVolume.getName(),mother==null?"null":mother.getName());
-		setMother(mother);
-		mother.addDaughter(this);
-		setPositionAndRotation(surveyVolume);
-		if(isDebug()) System.out.printf("%s: DONE constructing JAVA object %s\n", this.getClass().getSimpleName(),surveyVolume.getName());
-	}
-	
+    
+    /**
+     * Initialize with base and mother. This is typically for a reference geometry object 
+     * that is used for referencing coordinate systems but that doesn't have a volume itself.
+     * @param surveyVolume - object used to get geometry definitions
+     * @param mother - mother object
+     */
+    public JavaGhostSurveyVolume(SurveyVolume surveyVolume, JavaSurveyVolume mother) {
+        super(surveyVolume);
+        if(isDebug()) System.out.printf("%s: constructing JAVA ghost object %s with mother %s\n", this.getClass().getSimpleName(),surveyVolume.getName(),mother==null?"null":mother.getName());
+        setMother(mother);
+        mother.addDaughter(this);
+        setPositionAndRotation(surveyVolume);
+        if(isDebug()) System.out.printf("%s: DONE constructing JAVA object %s\n", this.getClass().getSimpleName(),surveyVolume.getName());
+    }
+    
 
 
 }

Modified: java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/JavaSurveyVolume.java
 =============================================================================
--- java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/JavaSurveyVolume.java	(original)
+++ java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/JavaSurveyVolume.java	Wed Apr 27 11:11:32 2016
@@ -16,7 +16,6 @@
 import org.lcsim.detector.RotationGeant;
 import org.lcsim.detector.Transform3D;
 import org.lcsim.detector.Translation3D;
-import org.lcsim.detector.material.IMaterial;
 import org.lcsim.detector.material.MaterialStore;
 import org.lcsim.detector.solids.Box;
 import org.lcsim.geometry.util.TransformationUtils;
@@ -26,120 +25,120 @@
  * @author Per Hansson Adrian <[log in to unmask]>
  */
 public class JavaSurveyVolume extends SurveyVolumeImpl {
-	private Box box= null;
-	private ILogicalVolume volume = null;
-	private ITranslation3D pos = null;
-	private IRotation3D rot = null;
-	private IPhysicalVolume physVolume = null;
-	private JavaSurveyVolume mother = null;
-	public List<JavaSurveyVolume> daughters = new ArrayList<JavaSurveyVolume>();
-	private int componentId = -1;
-	
-	/**
-	 *  Default constructor
-	 */
-	public JavaSurveyVolume(SurveyVolume surveyVolume) {
-	    super(surveyVolume);
-	}
-
-	/**
-	 * Construct a JAVA geometry object from its geometry definition and an already built logical volume. 
-	 * This is typically used by the tracking volume.
-	 * @param surveyVolume - input geometry definition
-	 * @param vol - logical volume
-	 */
-	public JavaSurveyVolume(SurveyVolume surveyVolume, ILogicalVolume vol) {
-	    super(surveyVolume);
-		if(isDebug()) System.out.printf("%s: JavaBaseGeometry %s (given logical volume %s)\n", this.getClass().getSimpleName(),surveyVolume.getName(),vol.getName());
-		// this must be tracking volume. May change in the future and is probably weird to make this requirement here. 
-		if(!surveyVolume.getName().contains("tracking")) throw new RuntimeException("this constructor is only used with the tracking volume!?");
-		setVolume(vol);
-		// since it's tracking volume, set the pos and rotation trivially
-		Hep3Vector lcdd_rot_angles = TransformationUtils.getCardanAngles(surveyVolume.getCoord().v(), surveyVolume.getCoord().w(), new BasicHep3Vector(0,1,0),new BasicHep3Vector(0,0,1));
-		setPos(new Translation3D(0,0,0));
-		setRot(new RotationGeant(lcdd_rot_angles.x(), lcdd_rot_angles.y(), lcdd_rot_angles.z()));
-		if(isDebug()) System.out.printf("%s: DONE JavaBaseGeometry %s\n", this.getClass().getSimpleName(),surveyVolume.getName());
-	}
-	
-	/**
-	 * Construct a JAVA geometry object from its geometry definition. 
-	 * @param surveyVolume - input geometry definition
-	 * @param mother - reference to mother JAVA definition
-	 * @param volumeId - component id number 
-	 */
-	public JavaSurveyVolume(SurveyVolume surveyVolume, JavaSurveyVolume mother, int volumeId) {
-	    super(surveyVolume);
+    private Box box= null;
+    private ILogicalVolume volume = null;
+    private ITranslation3D pos = null;
+    private IRotation3D rot = null;
+    private IPhysicalVolume physVolume = null;
+    private JavaSurveyVolume mother = null;
+    public List<JavaSurveyVolume> daughters = new ArrayList<JavaSurveyVolume>();
+    private int componentId = -1;
+    
+    /**
+     *  Default constructor
+     */
+    public JavaSurveyVolume(SurveyVolume surveyVolume) {
+        super(surveyVolume);
+    }
+
+    /**
+     * Construct a JAVA geometry object from its geometry definition and an already built logical volume. 
+     * This is typically used by the tracking volume.
+     * @param surveyVolume - input geometry definition
+     * @param vol - logical volume
+     */
+    public JavaSurveyVolume(SurveyVolume surveyVolume, ILogicalVolume vol) {
+        super(surveyVolume);
+        if(isDebug()) System.out.printf("%s: JavaBaseGeometry %s (given logical volume %s)\n", this.getClass().getSimpleName(),surveyVolume.getName(),vol.getName());
+        // this must be tracking volume. May change in the future and is probably weird to make this requirement here. 
+        if(!surveyVolume.getName().contains("tracking")) throw new RuntimeException("this constructor is only used with the tracking volume!?");
+        setVolume(vol);
+        // since it's tracking volume, set the pos and rotation trivially
+        Hep3Vector lcdd_rot_angles = TransformationUtils.getCardanAngles(surveyVolume.getCoord().v(), surveyVolume.getCoord().w(), new BasicHep3Vector(0,1,0),new BasicHep3Vector(0,0,1));
+        setPos(new Translation3D(0,0,0));
+        setRot(new RotationGeant(lcdd_rot_angles.x(), lcdd_rot_angles.y(), lcdd_rot_angles.z()));
+        if(isDebug()) System.out.printf("%s: DONE JavaBaseGeometry %s\n", this.getClass().getSimpleName(),surveyVolume.getName());
+    }
+    
+    /**
+     * Construct a JAVA geometry object from its geometry definition. 
+     * @param surveyVolume - input geometry definition
+     * @param mother - reference to mother JAVA definition
+     * @param volumeId - component id number 
+     */
+    public JavaSurveyVolume(SurveyVolume surveyVolume, JavaSurveyVolume mother, int volumeId) {
+        super(surveyVolume);
         if(isDebug()) System.out.printf("%s: JavaBaseGeometry %s (volumeID %d, mother %s)\n", this.getClass().getSimpleName(),surveyVolume.getName(),volumeId,mother==null?"null":mother.getName());
-		setComponentId(volumeId);
-		setMother(mother);
-		mother.addDaughter(this);
-		buildBox();
-		buildVolume();
-		setPositionAndRotation(surveyVolume);
-		if(isDebug()) System.out.printf("%s: DONE JavaBaseGeometry %s\n", this.getClass().getSimpleName(),surveyVolume.getName());
-	}
-
-	protected boolean hasCoordinateSystemInfo() {
-		return pos!=null && rot!=null;
-	}
-	
-	
-	public void buildPhysVolume() {
-		if(isDebug()) System.out.printf("%s: build phys volume for %s with mother %s and physical mother %s\n", this.getClass().getSimpleName(),getName(),getMother().getName(),getPhysMother().getName());
-		JavaSurveyVolume physMother =  getPhysMother();
-		setPhysVolume(new PhysicalVolume(new Transform3D(getPos(), getRot()), getName(), volume, physMother.getVolume(),getComponentId()));
-	}
-	
-	public void buildBox() {
-		Hep3Vector b = VecOp.mult(0.5,getBoxDim());
-		if(isDebug()) System.out.printf("%s: build box for %s with dimensions %s \n", this.getClass().getSimpleName(),getName(), b);
-		setBox(new Box(getName() + "Box", b.x(), b.y(), b.z())); 
-	}
-	public void buildVolume() {
-		if(isDebug()) System.out.printf("%s: build volume for %s with material %s\n", this.getClass().getSimpleName(),getName(), MaterialStore.getInstance().get(getMaterial()));
-			setVolume(new LogicalVolume(getName() + "_volume", box, MaterialStore.getInstance().get(getMaterial())));
-		
-	}
-	public void setPositionAndRotation(SurveyVolume base) {
-		if(isDebug()) System.out.printf("%s: set position and rotation for volume %s\n", this.getClass().getSimpleName(),getName());
-		
-		// no mother, this must be the world/tracking volume!?
-		if(base.getMother()==null) throw new RuntimeException("trying to set coordinates w/o mother defined for "+base.getName());
-		
-		// Vector from origin to center of box locally 
-		Hep3Vector box_center_base_local = base.getCenter();
-		
-		// find the physical mother i.e. not a ghost volume and compound transformations to it
-		JavaSurveyVolume physMother =  getPhysMother();
-		if(isDebug()) System.out.printf("%s: physical mother to transform to is %s; find the transform to it\n", this.getClass().getSimpleName(),physMother.getName());
-		Transform3D trf = HPSTrackerBuilder.getTransform(base.getCoord().getTransformation(),base.getMother(),physMother.getName()); 
-		if(isDebug()) System.out.printf("%s: found transform to physical mother \n%s\n\n", this.getClass().getSimpleName(),trf.toString());
-		
-		// find the position of the center in the physical mother coord
-		Hep3Vector box_center_base = trf.transformed(box_center_base_local);
-		
-		// find the position of the center of the box in the mother coordinate system, make sure to use the physical mother coordinates
-		if(isDebug()) System.out.printf("%s: find center of box in physical mother coord %s \n", this.getClass().getSimpleName(),physMother.getName());
-		// hack since my getTransform function needs a mother TODO Fix this!
-		SurveyVolume gm = base;
-		if(isDebug()) System.out.printf("%s: look for physical mother %s starting from mother %s \n", this.getClass().getSimpleName(),physMother.getName(),gm.getMother()!=null?gm.getMother().getName():"-- no mother --");
-		while((gm=gm.getMother()).getName()!=physMother.getName()) {
-			if(isDebug()) System.out.printf("%s: gm is %s \n", this.getClass().getSimpleName(),gm.getName());
-			//gm = gm.getMother();
-		}
-		if(isDebug()) System.out.printf("%s: found physical mother %s with center at %s \n", this.getClass().getSimpleName(),gm.getName(), gm.getCenter());
-		
-		Hep3Vector mother_center = gm.getCenter();
-
-		// now calculate the position of this box center in the mother LCDD coordinates
-		Hep3Vector box_center = VecOp.sub(box_center_base, mother_center);
-
-		//Find LCDD Euler rotation angles from coordinate system unit vectors
-		//Note that this has to be rotation wrt to physical mother and not just mother as normally is the case
-		//Use apache lib to get angles, but in principle I should already have it from the trf above
-		//Hep3Vector lcdd_rot_angles = HPSTestRunTracker2014.getEulerAngles(base.getCoord().v(), base.getCoord().w(), new BasicHep3Vector(0,1,0),new BasicHep3Vector(0,0,1));
-		if(isDebug()) System.out.printf("%s: find LCDD Cardan rotation angles - need to find mother to physical mother transform \n", this.getClass().getSimpleName(),physMother.getName());
-		Hep3Vector base_u = base.getCoord().u();
+        setComponentId(volumeId);
+        setMother(mother);
+        mother.addDaughter(this);
+        buildBox();
+        buildVolume();
+        setPositionAndRotation(surveyVolume);
+        if(isDebug()) System.out.printf("%s: DONE JavaBaseGeometry %s\n", this.getClass().getSimpleName(),surveyVolume.getName());
+    }
+
+    protected boolean hasCoordinateSystemInfo() {
+        return pos!=null && rot!=null;
+    }
+    
+    
+    public void buildPhysVolume() {
+        if(isDebug()) System.out.printf("%s: build phys volume for %s with mother %s and physical mother %s\n", this.getClass().getSimpleName(),getName(),getMother().getName(),getPhysMother().getName());
+        JavaSurveyVolume physMother =  getPhysMother();
+        setPhysVolume(new PhysicalVolume(new Transform3D(getPos(), getRot()), getName(), volume, physMother.getVolume(),getComponentId()));
+    }
+    
+    public void buildBox() {
+        Hep3Vector b = VecOp.mult(0.5,getBoxDim());
+        if(isDebug()) System.out.printf("%s: build box for %s with dimensions %s \n", this.getClass().getSimpleName(),getName(), b);
+        setBox(new Box(getName() + "Box", b.x(), b.y(), b.z())); 
+    }
+    public void buildVolume() {
+        if(isDebug()) System.out.printf("%s: build volume for %s with material %s\n", this.getClass().getSimpleName(),getName(), MaterialStore.getInstance().get(getMaterial()));
+            setVolume(new LogicalVolume(getName() + "_volume", box, MaterialStore.getInstance().get(getMaterial())));
+        
+    }
+    public void setPositionAndRotation(SurveyVolume base) {
+        if(isDebug()) System.out.printf("%s: set position and rotation for volume %s\n", this.getClass().getSimpleName(),getName());
+        
+        // no mother, this must be the world/tracking volume!?
+        if(base.getMother()==null) throw new RuntimeException("trying to set coordinates w/o mother defined for "+base.getName());
+        
+        // Vector from origin to center of box locally 
+        Hep3Vector box_center_base_local = base.getCenter();
+        
+        // find the physical mother i.e. not a ghost volume and compound transformations to it
+        JavaSurveyVolume physMother =  getPhysMother();
+        if(isDebug()) System.out.printf("%s: physical mother to transform to is %s; find the transform to it\n", this.getClass().getSimpleName(),physMother.getName());
+        Transform3D trf = HPSTrackerBuilder.getTransform(base.getCoord().getTransformation(),base.getMother(),physMother.getName()); 
+        if(isDebug()) System.out.printf("%s: found transform to physical mother \n%s\n\n", this.getClass().getSimpleName(),trf.toString());
+        
+        // find the position of the center in the physical mother coord
+        Hep3Vector box_center_base = trf.transformed(box_center_base_local);
+        
+        // find the position of the center of the box in the mother coordinate system, make sure to use the physical mother coordinates
+        if(isDebug()) System.out.printf("%s: find center of box in physical mother coord %s \n", this.getClass().getSimpleName(),physMother.getName());
+        // hack since my getTransform function needs a mother TODO Fix this!
+        SurveyVolume gm = base;
+        if(isDebug()) System.out.printf("%s: look for physical mother %s starting from mother %s \n", this.getClass().getSimpleName(),physMother.getName(),gm.getMother()!=null?gm.getMother().getName():"-- no mother --");
+        while((gm=gm.getMother()).getName()!=physMother.getName()) {
+            if(isDebug()) System.out.printf("%s: gm is %s \n", this.getClass().getSimpleName(),gm.getName());
+            //gm = gm.getMother();
+        }
+        if(isDebug()) System.out.printf("%s: found physical mother %s with center at %s \n", this.getClass().getSimpleName(),gm.getName(), gm.getCenter());
+        
+        Hep3Vector mother_center = gm.getCenter();
+
+        // now calculate the position of this box center in the mother LCDD coordinates
+        Hep3Vector box_center = VecOp.sub(box_center_base, mother_center);
+
+        //Find LCDD Euler rotation angles from coordinate system unit vectors
+        //Note that this has to be rotation wrt to physical mother and not just mother as normally is the case
+        //Use apache lib to get angles, but in principle I should already have it from the trf above
+        //Hep3Vector lcdd_rot_angles = HPSTestRunTracker2014.getEulerAngles(base.getCoord().v(), base.getCoord().w(), new BasicHep3Vector(0,1,0),new BasicHep3Vector(0,0,1));
+        if(isDebug()) System.out.printf("%s: find LCDD Cardan rotation angles - need to find mother to physical mother transform \n", this.getClass().getSimpleName(),physMother.getName());
+        Hep3Vector base_u = base.getCoord().u();
         Hep3Vector base_v = base.getCoord().v();
         Hep3Vector base_w = base.getCoord().w();
         if(isDebug()) System.out.printf("%s: unit vectors in mother coord: %s, %s, %s\n", this.getClass().getSimpleName(),base_u.toString(),base_v.toString(),base_w.toString());
@@ -169,22 +168,22 @@
             //System.out.printf("%s: unit vectors u %s v %s w %s\n", this.getClass().getSimpleName(),base.getCoord().u().toString(),base.getCoord().v().toString(),base.getCoord().w().toString());
         }
         
-		Hep3Vector lcdd_rot_angles = TransformationUtils.getCardanAngles(base_u, base_v, base_w, unit_u, unit_v, unit_w);
-
-
-		// Create the LCDD position
-		setPos(new Translation3D(box_center.x(), box_center.y(), box_center.z()));
-		setRot(new RotationGeant(lcdd_rot_angles.x(), lcdd_rot_angles.y(), lcdd_rot_angles.z()));
-		
-		if(isDebug()) {
-			
-		    System.out.printf("%s: SurveyVolume information for %s:\n", this.getClass().getSimpleName(), base.getName());
+        Hep3Vector lcdd_rot_angles = TransformationUtils.getCardanAngles(base_u, base_v, base_w, unit_u, unit_v, unit_w);
+
+
+        // Create the LCDD position
+        setPos(new Translation3D(box_center.x(), box_center.y(), box_center.z()));
+        setRot(new RotationGeant(lcdd_rot_angles.x(), lcdd_rot_angles.y(), lcdd_rot_angles.z()));
+        
+        if(isDebug()) {
+            
+            System.out.printf("%s: SurveyVolume information for %s:\n", this.getClass().getSimpleName(), base.getName());
             System.out.printf("%s: box_center_base_local       %s\n", this.getClass().getSimpleName(), box_center_base_local.toString());
-			System.out.printf("%s: box_center_base             %s\n", this.getClass().getSimpleName(), box_center_base.toString());
-			System.out.printf("%s: mother center               %s\n", this.getClass().getSimpleName(), base.getMother()==null?" <no mother> ":mother_center.toString());
-			System.out.printf("%s: box_center                  %s\n", this.getClass().getSimpleName(), box_center.toString());
-			System.out.printf("%s: pos                         %s\n", this.getClass().getSimpleName(), getPos().toString());
-			Hep3Vector box_center_tracking_xcheck = HPSTrackerBuilder.transformToTracking(box_center_base_local, base);
+            System.out.printf("%s: box_center_base             %s\n", this.getClass().getSimpleName(), box_center_base.toString());
+            System.out.printf("%s: mother center               %s\n", this.getClass().getSimpleName(), base.getMother()==null?" <no mother> ":mother_center.toString());
+            System.out.printf("%s: box_center                  %s\n", this.getClass().getSimpleName(), box_center.toString());
+            System.out.printf("%s: pos                         %s\n", this.getClass().getSimpleName(), getPos().toString());
+            Hep3Vector box_center_tracking_xcheck = HPSTrackerBuilder.transformToTracking(box_center_base_local, base);
             System.out.printf("%s: box_center_tracking_xcheck  %s (for %s)\n", this.getClass().getSimpleName(), box_center_tracking_xcheck==null ? " <null> " : box_center_tracking_xcheck.toString(),base.getName());
             Hep3Vector box_center_envelope_xcheck2 = HPSTrackerBuilder.transformToParent(box_center_base_local, base, "base");
             System.out.printf("%s: box_center_base_xcheck2     %s (for %s)\n", this.getClass().getSimpleName(), box_center_envelope_xcheck2==null ? " <null> " : box_center_envelope_xcheck2.toString(),base.getName());
@@ -203,90 +202,90 @@
                 System.out.printf("%s: origin_base_in          %s\n", this.getClass().getSimpleName(), origin_base_in==null ? " <null> " : origin_base_in.toString());
             }
             System.out.printf("%s: euler                       %s\n", this.getClass().getSimpleName(), lcdd_rot_angles.toString());
-			System.out.printf("%s: rot                         %s\n", this.getClass().getSimpleName(), getRot().toString());
-			
-		}
-		
-	}
-
-	/**
-	 * Find the first non-ghost volume among parents.  
-	 * @return mother object
-	 */
-	public JavaSurveyVolume getPhysMother() {
-		//if(isDebug()) System.out.printf("%s: finding physical mother to %s\n", this.getClass().getSimpleName(), getName());
-		if(mother==null) throw new RuntimeException("Trying to get phys mother but there is no mother!");
-		if(mother instanceof JavaGhostSurveyVolume) {
-			return mother.getPhysMother();
-		} else {
-			//if(isDebug()) System.out.printf("%s: found a non-ghost volume: %s\n", this.getClass().getSimpleName(), mother.getName());
-			return mother;
-		}
-	}
-	
-	
-	public ILogicalVolume getVolume() {
-		return volume;
-	}
-	protected void setVolume(ILogicalVolume volume) {
-		this.volume = volume;
-	}
-	protected Box getBox() {
-		return box;
-	}
-	protected void setBox(Box b) {
-		box = b;
-	}	
-	protected ITranslation3D getPos() {
-		return pos;
-	}
-	protected void setPos(ITranslation3D iTranslation3D) {
-		this.pos = iTranslation3D;
-	}
-	protected IRotation3D getRot() {
-		return rot;
-	}
-	protected void setRot(IRotation3D iRotation3D) {
-		this.rot = iRotation3D;
-	}
-	public JavaSurveyVolume getMother() {
-		return mother;
-	}
-	protected void setMother(JavaSurveyVolume mother) {
-		this.mother = mother;
-	}
-	public IPhysicalVolume getPhysVolume() {
-		return physVolume;
-	}
-	protected void setPhysVolume(PhysicalVolume physVolume) {
-		this.physVolume = physVolume;
-	}
-
-	public List<JavaSurveyVolume> getDaughters() {
-		return daughters;
-	}
-
-	protected void addDaughter(JavaSurveyVolume o) {
-		getDaughters().add(o);
-	}
-
-	public int getComponentId() {
-		return componentId;
-	}
-
-	public void setComponentId(int componentId) {
-		this.componentId = componentId;
-	}
-	
-	public String toString() {
-		String s = "JavaBaseGeometry " + getName() + "\n";
-		if(getPos()!=null && getRot()!=null) {
-			s += "Position: "  + getPos().toString() + "\n";
-			s += "Rotation: " + getRot().toString() + "\n";
-		} else {
-			s+= " - no position/rotation info -\n";
-		}
-		return s;
-	}
+            System.out.printf("%s: rot                         %s\n", this.getClass().getSimpleName(), getRot().toString());
+            
+        }
+        
+    }
+
+    /**
+     * Find the first non-ghost volume among parents.  
+     * @return mother object
+     */
+    public JavaSurveyVolume getPhysMother() {
+        //if(isDebug()) System.out.printf("%s: finding physical mother to %s\n", this.getClass().getSimpleName(), getName());
+        if(mother==null) throw new RuntimeException("Trying to get phys mother but there is no mother!");
+        if(mother instanceof JavaGhostSurveyVolume) {
+            return mother.getPhysMother();
+        } else {
+            //if(isDebug()) System.out.printf("%s: found a non-ghost volume: %s\n", this.getClass().getSimpleName(), mother.getName());
+            return mother;
+        }
+    }
+    
+    
+    public ILogicalVolume getVolume() {
+        return volume;
+    }
+    protected void setVolume(ILogicalVolume volume) {
+        this.volume = volume;
+    }
+    protected Box getBox() {
+        return box;
+    }
+    protected void setBox(Box b) {
+        box = b;
+    }   
+    protected ITranslation3D getPos() {
+        return pos;
+    }
+    protected void setPos(ITranslation3D iTranslation3D) {
+        this.pos = iTranslation3D;
+    }
+    protected IRotation3D getRot() {
+        return rot;
+    }
+    protected void setRot(IRotation3D iRotation3D) {
+        this.rot = iRotation3D;
+    }
+    public JavaSurveyVolume getMother() {
+        return mother;
+    }
+    protected void setMother(JavaSurveyVolume mother) {
+        this.mother = mother;
+    }
+    public IPhysicalVolume getPhysVolume() {
+        return physVolume;
+    }
+    protected void setPhysVolume(PhysicalVolume physVolume) {
+        this.physVolume = physVolume;
+    }
+
+    public List<JavaSurveyVolume> getDaughters() {
+        return daughters;
+    }
+
+    protected void addDaughter(JavaSurveyVolume o) {
+        getDaughters().add(o);
+    }
+
+    public int getComponentId() {
+        return componentId;
+    }
+
+    public void setComponentId(int componentId) {
+        this.componentId = componentId;
+    }
+    
+    public String toString() {
+        String s = "JavaBaseGeometry " + getName() + "\n";
+        if(getPos()!=null && getRot()!=null) {
+            s += "Position: "  + getPos().toString() + "\n";
+            s += "Rotation: " + getRot().toString() + "\n";
+        } else {
+            s+= " - no position/rotation info -\n";
+        }
+        return s;
+    }
 
 }

Modified: java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/LCDDGhostSurveyVolume.java
 =============================================================================
--- java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/LCDDGhostSurveyVolume.java	(original)
+++ java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/LCDDGhostSurveyVolume.java	Wed Apr 27 11:11:32 2016
@@ -10,20 +10,20 @@
  */
 public class LCDDGhostSurveyVolume extends LCDDSurveyVolume {
 
-	
-	
-	/**
-	 * Initialize with base and mother. This is typically for a reference geometry object 
-	 * that is used for referencing coordinate systems but that doesn't have a volume itself.
-	 * @param base - object used to get geometry definitions
-	 * @param mother - mother LCDD object
-	 */
-	public LCDDGhostSurveyVolume(SurveyVolume base, LCDDSurveyVolume mother) {
-		super(base);
-		if(isDebug()) System.out.printf("%s: constructing LCDD ghost object %s with mother %s\n", this.getClass().getSimpleName(),base.getName(),mother==null?"null":mother.getName());
-		setMother(mother);
-		mother.addDaughter(this);
-		if(isDebug()) System.out.printf("%s: DONE constructing LCDD object %s\n", this.getClass().getSimpleName(),base.getName());
-	}
-	
+    
+    
+    /**
+     * Initialize with base and mother. This is typically for a reference geometry object 
+     * that is used for referencing coordinate systems but that doesn't have a volume itself.
+     * @param base - object used to get geometry definitions
+     * @param mother - mother LCDD object
+     */
+    public LCDDGhostSurveyVolume(SurveyVolume base, LCDDSurveyVolume mother) {
+        super(base);
+        if(isDebug()) System.out.printf("%s: constructing LCDD ghost object %s with mother %s\n", this.getClass().getSimpleName(),base.getName(),mother==null?"null":mother.getName());
+        setMother(mother);
+        mother.addDaughter(this);
+        if(isDebug()) System.out.printf("%s: DONE constructing LCDD object %s\n", this.getClass().getSimpleName(),base.getName());
+    }
+    
 }

Modified: java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/LCDDSurveyVolume.java
 =============================================================================
--- java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/LCDDSurveyVolume.java	(original)
+++ java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/LCDDSurveyVolume.java	Wed Apr 27 11:11:32 2016
@@ -25,233 +25,233 @@
  * @author Per Hansson Adrian <[log in to unmask]>
  */
 public class LCDDSurveyVolume extends SurveyVolumeImpl  {
-	Box box= null;
-	Volume volume = null;
-	private Position pos = null;
-	private Rotation rot = null;
-	private PhysVol physVolume = null;
-	LCDD lcdd = null;
-	private LCDDSurveyVolume mother = null;
-	protected Map<String,Integer> physVolId = null;
-	public List<LCDDSurveyVolume> daughters = new ArrayList<LCDDSurveyVolume>();
-	/**
-	 *  Default constructor
-	 *  @param surveyVolume - core geometry definitions
-	 */
-	public LCDDSurveyVolume(SurveyVolume surveyVolume) {
-	   super(surveyVolume);
-	}
-	
-	/**
-	 * Initialize this object with a known volume and no mother. Typically the world volume would use this.
-	 * @param surveyVolume - core geometry definitions
-	 * @param vol - given volume
-	 */
-	public LCDDSurveyVolume(SurveyVolume surveyVolume, Volume volume) {
-		super(surveyVolume);
-		if(isDebug()) System.out.printf("%s: constructing LCDD object %s with volume name %s\n", this.getClass().getSimpleName(),surveyVolume.getName(),volume.getName());
-		setVolume(volume);
-		if(isDebug()) System.out.printf("%s: DONE constructing LCDD object %s\n", this.getClass().getSimpleName(),surveyVolume.getName());
-		Hep3Vector lcdd_rot_angles = TransformationUtils.getCardanAngles(surveyVolume.getCoord().v(), surveyVolume.getCoord().w(), new BasicHep3Vector(0,1,0),new BasicHep3Vector(0,0,1));
-		setPos(new Position(getName() + "_position", 0, 0, 0));
-		setRot(new Rotation(getName() + "_rotation",lcdd_rot_angles.x(), lcdd_rot_angles.y(), lcdd_rot_angles.z()));
-		if(isDebug()) System.out.printf("%s: DONE  %s\n", this.getClass().getSimpleName(),surveyVolume.getName());
-	}
-	
-	/**
-	 * Interface to the LCDD converter geometry for the geometry definition. 
-	 * @param surveyVolume - core geometry definition
-	 * @param lcdd - lcdd file 
-	 * @param mother - reference to mother LCDD definition
-	 */
-	public LCDDSurveyVolume(SurveyVolume surveyVolume, LCDD lcdd, LCDDSurveyVolume mother) {
-	    super(surveyVolume);
-	    if(isDebug()) System.out.printf("%s: constructing LCDD object %s with mother %s\n", this.getClass().getSimpleName(),surveyVolume.getName(),mother==null?"null":mother.getName());
-		this.lcdd = lcdd;
-		setMother(mother);
-		mother.addDaughter(this);
-		buildBox();
-		buildVolume();
-		setPositionAndRotation(surveyVolume);
-		//buildPhysVolume(mother);
-		if(isDebug()) System.out.printf("%s: DONE constructing LCDD object %s\n", this.getClass().getSimpleName(),surveyVolume.getName());
-	}
-
-	
-	public void buildPhysVolume() {
-
-	    if(isDebug()) System.out.printf("%s: build phys volume for %s with mother %s and physical mother %s\n", this.getClass().getSimpleName(),getName(),getMother().getName(),getPhysMother().getName());
-	    LCDDSurveyVolume physMother =  getPhysMother();
-	    setPhysVolume(new PhysVol(volume, physMother.getVolume(), getPos(), getRot()));
-	    //if(isDebug()) System.out.printf("%s: build phys volume for %s\n", this.getClass().getSimpleName(),getName());
-		//setPhysVolume(new PhysVol(volume, getMother().getVolume(), getPos(), getRot()));
-	}
-	public void buildBox() {
-		if(isDebug()) System.out.printf("%s: build box for %s\n", getClass().getSimpleName(),getName());
-		setBox(new Box(getName() + "Box", getBoxDim().x(), getBoxDim().y(), getBoxDim().z())); 
-	}
-	public void buildVolume() {
-		if(isDebug()) System.out.printf("%s: build volume for %s with material %s\n", this.getClass().getSimpleName(),getName(),getMaterial());
-		try {
-			Material mat = lcdd.getMaterial(getMaterial());
-			setVolume(new Volume(getName() + "_volume", box, mat));
-		} catch (JDOMException e) {
-			e.printStackTrace();
-		}
-	}
-	
-	
-	public void setPositionAndRotation(SurveyVolume base) {
-		if(isDebug()) System.out.printf("%s: set position and rotation for volume %s\n", this.getClass().getSimpleName(),getName());
-		
-		// NOTE:
-		// This sets position and reference w.r.t. mother coordinate system. 
-		// If I'm not building that volume this will be wrong. 
-		// TODO Similar to in the JAVA converter this should be something like the physical mother.
-		
-		if(base.getMother()==null) throw new RuntimeException("trying to set coordinates w/o mother defined for "+base.getName());
-		
-		// Vector from origin to center of box locally 
-		Hep3Vector box_center_base_local = base.getCenter();
-		
-		//translate to the mother coordinate system
-		LCDDSurveyVolume physMother = getPhysMother();
-		if(isDebug()) System.out.printf("%s: physical mother to transform to is %s; find the transform to it\n", this.getClass().getSimpleName(),physMother.getName());
-		Transform3D trf = HPSTrackerBuilder.getTransform(base.getCoord().getTransformation(),base.getMother(),physMother.getName()); 
-		if(isDebug()) System.out.printf("%s: found transform to physical mother \n%s\n\n", this.getClass().getSimpleName(),trf.toString());
-		
-		// find the position of the center in the physical mother coord
-		Hep3Vector box_center_base = trf.transformed(box_center_base_local);
-		
-		// find the position of the center of the box in the mother coordinate system, make sure to use the physical mother coordinates
-		if(isDebug()) System.out.printf("%s: find center of box in physical mother coord %s \n", this.getClass().getSimpleName(),physMother.getName());
-		// hack since my getTransform function needs a mother TODO Fix this!
-		SurveyVolume gm = base;
-		if(isDebug()) System.out.printf("%s: look for physical mother %s starting from mother %s \n", this.getClass().getSimpleName(),physMother.getName(),gm.getMother()!=null?gm.getMother().getName():"-- no mother --");
-		while((gm=gm.getMother()).getName()!=physMother.getName()) {
-			if(isDebug()) System.out.printf("%s: gm is %s \n", this.getClass().getSimpleName(),gm.getName());
-			//gm = gm.getMother();
-		}
-		if(isDebug()) System.out.printf("%s: found physical mother %s with center at %s \n", this.getClass().getSimpleName(),gm.getName(), gm.getCenter());
-
-		Hep3Vector mother_center = gm.getCenter();
-		
-		// find the position of the center in the mother coord
-		Hep3Vector box_center = VecOp.sub(box_center_base, mother_center);
-		
-		//Find LCDD Euler rotation angles from coordinate system unit vectors
-		//Note that this has to be rotation wrt to physical mother and not just mother as normally is the case
-		if(isDebug()) System.out.printf("%s: find LCDD Cardan rotation angles - need to find mother to physical mother transform \n", this.getClass().getSimpleName(),physMother.getName());
-		Hep3Vector base_u = base.getCoord().u();
-		Hep3Vector base_v = base.getCoord().v();
-		Hep3Vector base_w = base.getCoord().w();
+    Box box= null;
+    Volume volume = null;
+    private Position pos = null;
+    private Rotation rot = null;
+    private PhysVol physVolume = null;
+    LCDD lcdd = null;
+    private LCDDSurveyVolume mother = null;
+    protected Map<String,Integer> physVolId = null;
+    public List<LCDDSurveyVolume> daughters = new ArrayList<LCDDSurveyVolume>();
+    /**
+     *  Default constructor
+     *  @param surveyVolume - core geometry definitions
+     */
+    public LCDDSurveyVolume(SurveyVolume surveyVolume) {
+       super(surveyVolume);
+    }
+    
+    /**
+     * Initialize this object with a known volume and no mother. Typically the world volume would use this.
+     * @param surveyVolume - core geometry definitions
+     * @param volume - given volume
+     */
+    public LCDDSurveyVolume(SurveyVolume surveyVolume, Volume volume) {
+        super(surveyVolume);
+        if(isDebug()) System.out.printf("%s: constructing LCDD object %s with volume name %s\n", this.getClass().getSimpleName(),surveyVolume.getName(),volume.getName());
+        setVolume(volume);
+        if(isDebug()) System.out.printf("%s: DONE constructing LCDD object %s\n", this.getClass().getSimpleName(),surveyVolume.getName());
+        Hep3Vector lcdd_rot_angles = TransformationUtils.getCardanAngles(surveyVolume.getCoord().v(), surveyVolume.getCoord().w(), new BasicHep3Vector(0,1,0),new BasicHep3Vector(0,0,1));
+        setPos(new Position(getName() + "_position", 0, 0, 0));
+        setRot(new Rotation(getName() + "_rotation",lcdd_rot_angles.x(), lcdd_rot_angles.y(), lcdd_rot_angles.z()));
+        if(isDebug()) System.out.printf("%s: DONE  %s\n", this.getClass().getSimpleName(),surveyVolume.getName());
+    }
+    
+    /**
+     * Interface to the LCDD converter geometry for the geometry definition. 
+     * @param surveyVolume - core geometry definition
+     * @param lcdd - lcdd file 
+     * @param mother - reference to mother LCDD definition
+     */
+    public LCDDSurveyVolume(SurveyVolume surveyVolume, LCDD lcdd, LCDDSurveyVolume mother) {
+        super(surveyVolume);
+        if(isDebug()) System.out.printf("%s: constructing LCDD object %s with mother %s\n", this.getClass().getSimpleName(),surveyVolume.getName(),mother==null?"null":mother.getName());
+        this.lcdd = lcdd;
+        setMother(mother);
+        mother.addDaughter(this);
+        buildBox();
+        buildVolume();
+        setPositionAndRotation(surveyVolume);
+        //buildPhysVolume(mother);
+        if(isDebug()) System.out.printf("%s: DONE constructing LCDD object %s\n", this.getClass().getSimpleName(),surveyVolume.getName());
+    }
+
+    
+    public void buildPhysVolume() {
+
+        if(isDebug()) System.out.printf("%s: build phys volume for %s with mother %s and physical mother %s\n", this.getClass().getSimpleName(),getName(),getMother().getName(),getPhysMother().getName());
+        LCDDSurveyVolume physMother =  getPhysMother();
+        setPhysVolume(new PhysVol(volume, physMother.getVolume(), getPos(), getRot()));
+        //if(isDebug()) System.out.printf("%s: build phys volume for %s\n", this.getClass().getSimpleName(),getName());
+        //setPhysVolume(new PhysVol(volume, getMother().getVolume(), getPos(), getRot()));
+    }
+    public void buildBox() {
+        if(isDebug()) System.out.printf("%s: build box for %s\n", getClass().getSimpleName(),getName());
+        setBox(new Box(getName() + "Box", getBoxDim().x(), getBoxDim().y(), getBoxDim().z())); 
+    }
+    public void buildVolume() {
+        if(isDebug()) System.out.printf("%s: build volume for %s with material %s\n", this.getClass().getSimpleName(),getName(),getMaterial());
+        try {
+            Material mat = lcdd.getMaterial(getMaterial());
+            setVolume(new Volume(getName() + "_volume", box, mat));
+        } catch (JDOMException e) {
+            e.printStackTrace();
+        }
+    }
+    
+    
+    public void setPositionAndRotation(SurveyVolume base) {
+        if(isDebug()) System.out.printf("%s: set position and rotation for volume %s\n", this.getClass().getSimpleName(),getName());
+        
+        // NOTE:
+        // This sets position and reference w.r.t. mother coordinate system. 
+        // If I'm not building that volume this will be wrong. 
+        // TODO Similar to in the JAVA converter this should be something like the physical mother.
+        
+        if(base.getMother()==null) throw new RuntimeException("trying to set coordinates w/o mother defined for "+base.getName());
+        
+        // Vector from origin to center of box locally 
+        Hep3Vector box_center_base_local = base.getCenter();
+        
+        //translate to the mother coordinate system
+        LCDDSurveyVolume physMother = getPhysMother();
+        if(isDebug()) System.out.printf("%s: physical mother to transform to is %s; find the transform to it\n", this.getClass().getSimpleName(),physMother.getName());
+        Transform3D trf = HPSTrackerBuilder.getTransform(base.getCoord().getTransformation(),base.getMother(),physMother.getName()); 
+        if(isDebug()) System.out.printf("%s: found transform to physical mother \n%s\n\n", this.getClass().getSimpleName(),trf.toString());
+        
+        // find the position of the center in the physical mother coord
+        Hep3Vector box_center_base = trf.transformed(box_center_base_local);
+        
+        // find the position of the center of the box in the mother coordinate system, make sure to use the physical mother coordinates
+        if(isDebug()) System.out.printf("%s: find center of box in physical mother coord %s \n", this.getClass().getSimpleName(),physMother.getName());
+        // hack since my getTransform function needs a mother TODO Fix this!
+        SurveyVolume gm = base;
+        if(isDebug()) System.out.printf("%s: look for physical mother %s starting from mother %s \n", this.getClass().getSimpleName(),physMother.getName(),gm.getMother()!=null?gm.getMother().getName():"-- no mother --");
+        while((gm=gm.getMother()).getName()!=physMother.getName()) {
+            if(isDebug()) System.out.printf("%s: gm is %s \n", this.getClass().getSimpleName(),gm.getName());
+            //gm = gm.getMother();
+        }
+        if(isDebug()) System.out.printf("%s: found physical mother %s with center at %s \n", this.getClass().getSimpleName(),gm.getName(), gm.getCenter());
+
+        Hep3Vector mother_center = gm.getCenter();
+        
+        // find the position of the center in the mother coord
+        Hep3Vector box_center = VecOp.sub(box_center_base, mother_center);
+        
+        //Find LCDD Euler rotation angles from coordinate system unit vectors
+        //Note that this has to be rotation wrt to physical mother and not just mother as normally is the case
+        if(isDebug()) System.out.printf("%s: find LCDD Cardan rotation angles - need to find mother to physical mother transform \n", this.getClass().getSimpleName(),physMother.getName());
+        Hep3Vector base_u = base.getCoord().u();
+        Hep3Vector base_v = base.getCoord().v();
+        Hep3Vector base_w = base.getCoord().w();
         if(isDebug()) System.out.printf("%s: unit vectors in mother coord: %s, %s, %s\n", this.getClass().getSimpleName(),base_u.toString(),base_v.toString(),base_w.toString());
-		Hep3Vector unit_u = new BasicHep3Vector(1,0,0);
-		Hep3Vector unit_v = new BasicHep3Vector(0,1,0);
-		Hep3Vector unit_w = new BasicHep3Vector(0,0,1);
-		if(!base.getMother().getName().equals(physMother.getName())) {
-		    if(isDebug()) System.out.printf("%s: Need to get unit vectors in physical mother %s coord system\n", this.getClass().getSimpleName(),physMother.getName());
+        Hep3Vector unit_u = new BasicHep3Vector(1,0,0);
+        Hep3Vector unit_v = new BasicHep3Vector(0,1,0);
+        Hep3Vector unit_w = new BasicHep3Vector(0,0,1);
+        if(!base.getMother().getName().equals(physMother.getName())) {
+            if(isDebug()) System.out.printf("%s: Need to get unit vectors in physical mother %s coord system\n", this.getClass().getSimpleName(),physMother.getName());
             Transform3D trf_mother = HPSTrackerBuilder.getTransform(base.getMother().getCoord().getTransformation(),base.getMother().getMother(),physMother.getName()); 
             if(isDebug()) System.out.printf("%s: found transform from mother to physical mother \n%s\n", this.getClass().getSimpleName(),trf_mother.toString());
-			//unit_u = VecOp.unit(trf_mother.rotated(unit_u));
-			//unit_v = VecOp.unit(trf_mother.rotated(unit_v));
-			//unit_w = VecOp.unit(trf_mother.rotated(unit_w));
-			base_u = VecOp.unit(trf_mother.rotated(base_u));
+            //unit_u = VecOp.unit(trf_mother.rotated(unit_u));
+            //unit_v = VecOp.unit(trf_mother.rotated(unit_v));
+            //unit_w = VecOp.unit(trf_mother.rotated(unit_w));
+            base_u = VecOp.unit(trf_mother.rotated(base_u));
             base_v = VecOp.unit(trf_mother.rotated(base_v));
             base_w = VecOp.unit(trf_mother.rotated(base_w));
             
-		} else {
-			if(isDebug()) System.out.printf("%s: mother and physical mother is the same so unit vectors didn't change\n",getClass().getSimpleName());
-		}
-		
-		if(isDebug()) {
-		    if(isDebug()) System.out.printf("%s: final unit vectors to get Cardan angles from : \n%s, %s, %s -> %s, %s, %s \n", 
-		                                    this.getClass().getSimpleName(),
-		                                    base_u.toString(),base_v.toString(),base_w.toString(),	            
-		                                    unit_u.toString(),unit_v.toString(),unit_w.toString());
-			//System.out.printf("%s: unit vectors u %s v %s w %s\n", this.getClass().getSimpleName(),base.getCoord().u().toString(),base.getCoord().v().toString(),base.getCoord().w().toString());
-		}
+        } else {
+            if(isDebug()) System.out.printf("%s: mother and physical mother is the same so unit vectors didn't change\n",getClass().getSimpleName());
+        }
+        
+        if(isDebug()) {
+            if(isDebug()) System.out.printf("%s: final unit vectors to get Cardan angles from : \n%s, %s, %s -> %s, %s, %s \n", 
+                                            this.getClass().getSimpleName(),
+                                            base_u.toString(),base_v.toString(),base_w.toString(),              
+                                            unit_u.toString(),unit_v.toString(),unit_w.toString());
+            //System.out.printf("%s: unit vectors u %s v %s w %s\n", this.getClass().getSimpleName(),base.getCoord().u().toString(),base.getCoord().v().toString(),base.getCoord().w().toString());
+        }
         Hep3Vector lcdd_rot_angles = TransformationUtils.getCardanAngles(base_u, base_v, base_w, unit_u, unit_v, unit_w);
         
-		
-		// Create the LCDD position and rotation
-		setPos(new Position(getName() + "_position",box_center.x(), box_center.y(), box_center.z()));
-		setRot(new Rotation(getName() + "_rotation",lcdd_rot_angles.x(), lcdd_rot_angles.y(), lcdd_rot_angles.z()));
-		
-		if(isDebug()) {
-		    System.out.printf("%s: SurveyVolume information for %s:\n", this.getClass().getSimpleName(), base.getName());
+        
+        // Create the LCDD position and rotation
+        setPos(new Position(getName() + "_position",box_center.x(), box_center.y(), box_center.z()));
+        setRot(new Rotation(getName() + "_rotation",lcdd_rot_angles.x(), lcdd_rot_angles.y(), lcdd_rot_angles.z()));
+        
+        if(isDebug()) {
+            System.out.printf("%s: SurveyVolume information for %s:\n", this.getClass().getSimpleName(), base.getName());
             System.out.printf("%s: box_center_base_local  %s\n", this.getClass().getSimpleName(), box_center_base_local.toString());
-			System.out.printf("%s: box_center_base        %s\n", this.getClass().getSimpleName(), box_center_base.toString());
-			System.out.printf("%s: mother center          %s\n", this.getClass().getSimpleName(), mother_center.toString());
-			System.out.printf("%s: box_center             %s\n", this.getClass().getSimpleName(), box_center.toString());
-			System.out.printf("%s: pos                    %s\n", this.getClass().getSimpleName(), getPos().toString());
-			System.out.printf("%s: euler                  %s\n", this.getClass().getSimpleName(), lcdd_rot_angles.toString());
+            System.out.printf("%s: box_center_base        %s\n", this.getClass().getSimpleName(), box_center_base.toString());
+            System.out.printf("%s: mother center          %s\n", this.getClass().getSimpleName(), mother_center.toString());
+            System.out.printf("%s: box_center             %s\n", this.getClass().getSimpleName(), box_center.toString());
+            System.out.printf("%s: pos                    %s\n", this.getClass().getSimpleName(), getPos().toString());
+            System.out.printf("%s: euler                  %s\n", this.getClass().getSimpleName(), lcdd_rot_angles.toString());
             System.out.printf("%s: rot                    %s\n", this.getClass().getSimpleName(), getRot().toString());
-			
-			//calculate the position in tracking volume separately as a xcheck
-			Hep3Vector box_center_tracking_xcheck = HPSTrackerBuilder.transformToTracking(box_center_base_local, base);
-			System.out.printf("%s: box_center_tracking_xcheck  %s (for %s)\n", this.getClass().getSimpleName(), box_center_tracking_xcheck.toString(), base.getName());
-		}
-		
-	}
-	/**
-	 * Find the first non-ghost volume among parents.  
-	 * @return mother object
-	 */
-	public LCDDSurveyVolume getPhysMother() {
-		//if(isDebug()) System.out.printf("%s: finding physical mother to %s\n", this.getClass().getSimpleName(), getName());
-		if(mother==null) throw new RuntimeException("Trying to get phys mother but there is no mother!");
-		if(mother instanceof LCDDGhostSurveyVolume) {
-			return mother.getPhysMother();
-		} else {
-			//if(isDebug()) System.out.printf("%s: found a non-ghost volume: %s\n", this.getClass().getSimpleName(), mother.getName());
-			return mother;
-		}
-	}
-	
-	public Volume getVolume() {
-		return volume;
-	}
-	public void setVolume(Volume volume) {
-		this.volume = volume;
-	}
-	public Box getBox() {
-		return box;
-	}
-	public void setBox(Box b) {
-		box = b;
-	}	
-	public Position getPos() {
-		return pos;
-	}
-	public void setPos(Position pos) {
-		this.pos = pos;
-	}
-	public Rotation getRot() {
-		return rot;
-	}
-	public void setRot(Rotation rot) {
-		this.rot = rot;
-	}
-	public LCDDSurveyVolume getMother() {
-		return mother;
-	}
-	public void setMother(LCDDSurveyVolume mother) {
-		this.mother = mother;
-	}
-	public PhysVol getPhysVolume() {
-		return physVolume;
-	}
-	public void setPhysVolume(PhysVol physVolume) {
-		this.physVolume = physVolume;
-	}
-	public List<LCDDSurveyVolume> getDaughters() {
-		return daughters;
-	}
-	public void addDaughter(LCDDSurveyVolume o) {
-		getDaughters().add(o);
-	}
-	 public String toString() {
+            
+            //calculate the position in tracking volume separately as a xcheck
+            Hep3Vector box_center_tracking_xcheck = HPSTrackerBuilder.transformToTracking(box_center_base_local, base);
+            System.out.printf("%s: box_center_tracking_xcheck  %s (for %s)\n", this.getClass().getSimpleName(), box_center_tracking_xcheck.toString(), base.getName());
+        }
+        
+    }
+    /**
+     * Find the first non-ghost volume among parents.  
+     * @return mother object
+     */
+    public LCDDSurveyVolume getPhysMother() {
+        //if(isDebug()) System.out.printf("%s: finding physical mother to %s\n", this.getClass().getSimpleName(), getName());
+        if(mother==null) throw new RuntimeException("Trying to get phys mother but there is no mother!");
+        if(mother instanceof LCDDGhostSurveyVolume) {
+            return mother.getPhysMother();
+        } else {
+            //if(isDebug()) System.out.printf("%s: found a non-ghost volume: %s\n", this.getClass().getSimpleName(), mother.getName());
+            return mother;
+        }
+    }
+    
+    public Volume getVolume() {
+        return volume;
+    }
+    public void setVolume(Volume volume) {
+        this.volume = volume;
+    }
+    public Box getBox() {
+        return box;
+    }
+    public void setBox(Box b) {
+        box = b;
+    }   
+    public Position getPos() {
+        return pos;
+    }
+    public void setPos(Position pos) {
+        this.pos = pos;
+    }
+    public Rotation getRot() {
+        return rot;
+    }
+    public void setRot(Rotation rot) {
+        this.rot = rot;
+    }
+    public LCDDSurveyVolume getMother() {
+        return mother;
+    }
+    public void setMother(LCDDSurveyVolume mother) {
+        this.mother = mother;
+    }
+    public PhysVol getPhysVolume() {
+        return physVolume;
+    }
+    public void setPhysVolume(PhysVol physVolume) {
+        this.physVolume = physVolume;
+    }
+    public List<LCDDSurveyVolume> getDaughters() {
+        return daughters;
+    }
+    public void addDaughter(LCDDSurveyVolume o) {
+        getDaughters().add(o);
+    }
+     public String toString() {
         String s = getClass().getSimpleName() +": " + getName() + "\n";
         if(getPos()!=null && getRot()!=null)    {
             double x = Double.valueOf(getPos().getAttributeValue("x"));

Modified: java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/MilleParameter.java
 =============================================================================
--- java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/MilleParameter.java	(original)
+++ java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/MilleParameter.java	Wed Apr 27 11:11:32 2016
@@ -9,113 +9,113 @@
 
 public class MilleParameter {
     private static double corrScaleFactor = -1.;
-	private int id;
-	private double value; 
-	private double presigma;
-	private static final Map<Integer,String> dMap;
-	private static final Map<Integer,String> tMap;
-	private static final Map<Integer,String> hMap;
-	static {
-		dMap = new HashMap<Integer,String>();
-		dMap.put(1, "x");dMap.put(2, "y"); dMap.put(3, "z");
-		tMap = new HashMap<Integer,String>();
-		tMap.put(1, "");tMap.put(2, "r");
-		hMap = new HashMap<Integer,String>();
-		hMap.put(1, "t");hMap.put(2, "b");
-		}
-	public static final int half_offset = 10000;
-	public static final int type_offset = 1000; 
-	public static final int dimension_offset = 100;
-	public static enum Type {
-	    TRANSLATION(1), ROTATION(2);
-	    private int value;
-	    private Type(int value) {this.value = value;}
-	    public int getType() {return this.value;}
-	};
-	
-	public MilleParameter(String line) {
-		String[] vals = StringUtils.split(line);// line.split("\\s+");
-		if(vals.length <3) {
-			System.out.println("this line is ill-formatted (" + vals.length + ")");
-			System.out.println(line);
-			System.exit(1);
-		}
-		try {
-		//for(String v : vals) System.out.println("\"" + v + "\"");
-		setId(Integer.parseInt(vals[0]));
-		setValue( corrScaleFactor * Double.parseDouble(vals[1]) );
-		setPresigma(Double.parseDouble(vals[2]));
-		
-		} catch (NumberFormatException e) {
-			System.out.println(vals[0] + " " + vals[1] + " " + vals[2]);
-			throw new RuntimeException("problem parsing string ", e);
-		}
-	}
-	
-	public MilleParameter(int id, double value, double presigma) {
-	    setId(id);
-	    setValue(value);
-	    setPresigma(presigma);
-	}
-	
-	public String getXMLName() {
-		String d = dMap.get(getDim());
-		String t = tMap.get(getType());
-		String h = hMap.get(getHalf());
-		int s = getSensor();
-		return String.format("%s%s%d%s_align", t,d,s,h);
-		
-	}
+    private int id;
+    private double value; 
+    private double presigma;
+    private static final Map<Integer,String> dMap;
+    private static final Map<Integer,String> tMap;
+    private static final Map<Integer,String> hMap;
+    static {
+        dMap = new HashMap<Integer,String>();
+        dMap.put(1, "x");dMap.put(2, "y"); dMap.put(3, "z");
+        tMap = new HashMap<Integer,String>();
+        tMap.put(1, "");tMap.put(2, "r");
+        hMap = new HashMap<Integer,String>();
+        hMap.put(1, "t");hMap.put(2, "b");
+        }
+    public static final int half_offset = 10000;
+    public static final int type_offset = 1000; 
+    public static final int dimension_offset = 100;
+    public static enum Type {
+        TRANSLATION(1), ROTATION(2);
+        private int value;
+        private Type(int value) {this.value = value;}
+        public int getType() {return this.value;}
+    };
+    
+    public MilleParameter(String line) {
+        String[] vals = StringUtils.split(line);// line.split("\\s+");
+        if(vals.length <3) {
+            System.out.println("this line is ill-formatted (" + vals.length + ")");
+            System.out.println(line);
+            System.exit(1);
+        }
+        try {
+        //for(String v : vals) System.out.println("\"" + v + "\"");
+        setId(Integer.parseInt(vals[0]));
+        setValue( corrScaleFactor * Double.parseDouble(vals[1]) );
+        setPresigma(Double.parseDouble(vals[2]));
+        
+        } catch (NumberFormatException e) {
+            System.out.println(vals[0] + " " + vals[1] + " " + vals[2]);
+            throw new RuntimeException("problem parsing string ", e);
+        }
+    }
+    
+    public MilleParameter(int id, double value, double presigma) {
+        setId(id);
+        setValue(value);
+        setPresigma(presigma);
+    }
+    
+    public String getXMLName() {
+        String d = dMap.get(getDim());
+        String t = tMap.get(getType());
+        String h = hMap.get(getHalf());
+        int s = getSensor();
+        return String.format("%s%s%d%s_align", t,d,s,h);
+        
+    }
 
-	public int getDim() {
-		int h = (int) (getHalf() * half_offset);
-		int t = (int) (getType() * type_offset);
-		return (int) Math.floor((id- h -t)/(double)dimension_offset);
-	}
-	
-	public int getSensor() {
-		int h = (int) (getHalf() * half_offset);
-		int t = (int) (getType() * type_offset);
-		int d = (int) (getDim() * dimension_offset);
-		return (id - h - t -d);
-	}
+    public int getDim() {
+        int h = (int) (getHalf() * half_offset);
+        int t = (int) (getType() * type_offset);
+        return (int) Math.floor((id- h -t)/(double)dimension_offset);
+    }
+    
+    public int getSensor() {
+        int h = (int) (getHalf() * half_offset);
+        int t = (int) (getType() * type_offset);
+        int d = (int) (getDim() * dimension_offset);
+        return (id - h - t -d);
+    }
 
-	public int getType() {
-		int h = (int) (getHalf() * half_offset);
-		return (int) Math.floor((id -h)/(double)type_offset);
-	}
+    public int getType() {
+        int h = (int) (getHalf() * half_offset);
+        return (int) Math.floor((id -h)/(double)type_offset);
+    }
 
-	public int getHalf() {
-		return (int)Math.floor(id/(double)half_offset);
-	}
+    public int getHalf() {
+        return (int)Math.floor(id/(double)half_offset);
+    }
 
-	public int getId() {
-		return id;
-	}
+    public int getId() {
+        return id;
+    }
 
-	public void setId(int id) {
-		this.id = id;
-	}
+    public void setId(int id) {
+        this.id = id;
+    }
 
-	public double getValue() {
-		return value;
-	}
+    public double getValue() {
+        return value;
+    }
 
-	public void setValue(double value) {
-		this.value = value;
-	}
+    public void setValue(double value) {
+        this.value = value;
+    }
 
-	public double getPresigma() {
-		return presigma;
-	}
+    public double getPresigma() {
+        return presigma;
+    }
 
-	public void setPresigma(double presigma) {
-		this.presigma = presigma;
-	}
-	
-	public String toString() {
-	    return String.format("Milleparameter id=%d half=%d type=%d dim=%d sensor=%d value=%f", this.getId(), this.getHalf(), this.getType(), this.getDim(), this.getSensor(), this.getValue());
-	}
+    public void setPresigma(double presigma) {
+        this.presigma = presigma;
+    }
+    
+    public String toString() {
+        return String.format("Milleparameter id=%d half=%d type=%d dim=%d sensor=%d value=%f", this.getId(), this.getHalf(), this.getType(), this.getDim(), this.getSensor(), this.getValue());
+    }
 
 
 }

Modified: java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/SurveyCoordinateSystem.java
 =============================================================================
--- java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/SurveyCoordinateSystem.java	(original)
+++ java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/SurveyCoordinateSystem.java	Wed Apr 27 11:11:32 2016
@@ -13,26 +13,26 @@
 import org.lcsim.detector.Translation3D;
 
      /**
-	 * Class describing a simple coordinate system used to define the {@link SurveyVolume}.
-	 * 
-	 *    @author Per Hansson Adrian <[log in to unmask]>
-	 */
-	public class SurveyCoordinateSystem {
-	    private final boolean debug = false;
-		private Hep3Vector origin;
-		private Hep3Vector u;
-		private Hep3Vector v;
-		private Hep3Vector w;
+     * Class describing a simple coordinate system used to define the {@link SurveyVolume}.
+     * 
+     *    @author Per Hansson Adrian <[log in to unmask]>
+     */
+    public class SurveyCoordinateSystem {
+        private final boolean debug = false;
+        private Hep3Vector origin;
+        private Hep3Vector u;
+        private Hep3Vector v;
+        private Hep3Vector w;
 
-//		public SurveyCoordinateSystem(Hep3Vector org, Hep3Vector unit_x, Hep3Vector unit_y, Hep3Vector unit_z) {
-//			origin = org;
-//			u = unit_x;
-//			v = unit_y;
-//			w = unit_z;
-//		}
+//      public SurveyCoordinateSystem(Hep3Vector org, Hep3Vector unit_x, Hep3Vector unit_y, Hep3Vector unit_z) {
+//          origin = org;
+//          u = unit_x;
+//          v = unit_y;
+//          w = unit_z;
+//      }
 
-		
-		public SurveyCoordinateSystem(Hep3Vector ball, Hep3Vector vee, Hep3Vector flat) {
+        
+        public SurveyCoordinateSystem(Hep3Vector ball, Hep3Vector vee, Hep3Vector flat) {
             origin = ball;
             Hep3Vector ball_to_vee = VecOp.sub(vee, ball);
             u = VecOp.unit(ball_to_vee);
@@ -41,61 +41,61 @@
             v = VecOp.cross(w, u);
             check();
         }
-		
-		private void check() {
-		    checkUnitLength();
-		    checkAngles();
-		}
+        
+        private void check() {
+            checkUnitLength();
+            checkAngles();
+        }
 
-		private void checkUnitLength() {
-		    if(u.magnitude()-1>0.00001 || v.magnitude()-1>0.00001 || v.magnitude()-1>0.00001) {
-		        throw new RuntimeException("Error: the unit vectors of the  coordinate system is ill-defined " + toString());
-		    }
-		}
+        private void checkUnitLength() {
+            if(u.magnitude()-1>0.00001 || v.magnitude()-1>0.00001 || v.magnitude()-1>0.00001) {
+                throw new RuntimeException("Error: the unit vectors of the  coordinate system is ill-defined " + toString());
+            }
+        }
 
-		private void checkAngles() {
-		    if( (VecOp.dot(u, v)-1)>0.00001 ||  (VecOp.dot(u, w)-1)>0.00001 ||  (VecOp.dot(v, w)-1)>0.00001 ) {
-		        throw new RuntimeException("Error: the angles in coordinate system is ill-defined " + toString());
-		    }
-		}
-		
-		
-		/**
-		 * Transform this coordinate system to another one.
-		 * @param t
-		 */
-		public void transform(Transform3D t) {
-		    Transform3D t_this = getTransformation();
-		    Hep3Vector v = t_this.getTranslation().getTranslationVector();
-		    Hep3Vector vrot = t.rotated(v);
-		    Hep3Vector vrottrans = t.translated(vrot);
-		    origin = vrottrans;
+        private void checkAngles() {
+            if( (VecOp.dot(u, v)-1)>0.00001 ||  (VecOp.dot(u, w)-1)>0.00001 ||  (VecOp.dot(v, w)-1)>0.00001 ) {
+                throw new RuntimeException("Error: the angles in coordinate system is ill-defined " + toString());
+            }
+        }
+        
+        
+        /**
+         * Transform this coordinate system to another one.
+         * @param t
+         */
+        public void transform(Transform3D t) {
+            Transform3D t_this = getTransformation();
+            Hep3Vector v = t_this.getTranslation().getTranslationVector();
+            Hep3Vector vrot = t.rotated(v);
+            Hep3Vector vrottrans = t.translated(vrot);
+            origin = vrottrans;
             rotate(t.getRotation());
             //System.out.printf("monkey transform\n"); 
             //System.out.printf("v %s\n",v.toString());
             //System.out.printf("vrot %s\n",vrot.toString());
             //System.out.printf("vrottrans %s\n",vrottrans.toString());
-		    check();
-		}
-		
-		public void rotate(IRotation3D r) {
-			r.rotate(u);
-			r.rotate(v);
-			r.rotate(w);
-		}
+            check();
+        }
+        
+        public void rotate(IRotation3D r) {
+            r.rotate(u);
+            r.rotate(v);
+            r.rotate(w);
+        }
 
-		public void translate(Hep3Vector translation) {
-			// update origin with local translation in u,v,w
-		    //origin = VecOp.add(origin, translation);
-		    translate(new Translation3D(translation));
-		}
+        public void translate(Hep3Vector translation) {
+            // update origin with local translation in u,v,w
+            //origin = VecOp.add(origin, translation);
+            translate(new Translation3D(translation));
+        }
 
-		public void translate(Translation3D t) {
-		    origin = t.translated(getTransformation().getTranslation().getTranslationVector());
-		}
+        public void translate(Translation3D t) {
+            origin = t.translated(getTransformation().getTranslation().getTranslationVector());
+        }
 
-		
-		public void rotateApache(Rotation r) {
+        
+        public void rotateApache(Rotation r) {
             if(debug) System.out.printf("%s: apply apache rotation to this coord system\n%s\n", getClass().getSimpleName(),toString());
             this.u = new BasicHep3Vector(r.applyTo(new Vector3D(u.v())).toArray());
             this.v = new BasicHep3Vector(r.applyTo(new Vector3D(v.v())).toArray());
@@ -104,52 +104,52 @@
         }
         
         public Hep3Vector origin() {
-			return origin;
-		}
-		public Hep3Vector u() {
-			return u;
-		}
-		public Hep3Vector v() {
-			return v;
-		}
-		public Hep3Vector w() {
-			return w;
-		}
-		public void u(Hep3Vector vec) {
+            return origin;
+        }
+        public Hep3Vector u() {
+            return u;
+        }
+        public Hep3Vector v() {
+            return v;
+        }
+        public Hep3Vector w() {
+            return w;
+        }
+        public void u(Hep3Vector vec) {
             u = vec;
-		}
+        }
         public void v(Hep3Vector vec) {
             v = vec;
         }
         public void w(Hep3Vector vec) {
             w = vec;
         }
-		
+        
         public String toString() {
-			String str = "origin " + origin.toString() + "\nu " + u.toString() + "\nv " + v.toString() + "\nw " + w.toString();
-			return str;
+            String str = "origin " + origin.toString() + "\nu " + u.toString() + "\nv " + v.toString() + "\nw " + w.toString();
+            return str;
         }
-	
-		
-		/**
-		 * Find @ITransform3D to the coordinate system defined by the input. 
-		 * @return resulting 3D transform 
-		 */
-		public Transform3D getTransformation() {
-			// Find the transform between the two frames - use transform classes here (not really needed)
-			Translation3D translation = new Translation3D(origin.x(), origin.y(), origin.z());
-			//RotationGeant trackingToEnvelopeRotation = new RotationGeant(0, 0, 0);
-			Rotation3D rotation = new Rotation3D(
-					new BasicHep3Matrix(
-							u.x(),v.x(),w.x(),
-							u.y(),v.y(),w.y(),
-							u.z(),v.z(),w.z()
-							));
-			Transform3D envelopeToSupportTransform = new Transform3D(translation, rotation);
-			return envelopeToSupportTransform;
-		}
-		
-		
-		
-		
-	}
+    
+        
+        /**
+         * Find @ITransform3D to the coordinate system defined by the input. 
+         * @return resulting 3D transform 
+         */
+        public Transform3D getTransformation() {
+            // Find the transform between the two frames - use transform classes here (not really needed)
+            Translation3D translation = new Translation3D(origin.x(), origin.y(), origin.z());
+            //RotationGeant trackingToEnvelopeRotation = new RotationGeant(0, 0, 0);
+            Rotation3D rotation = new Rotation3D(
+                    new BasicHep3Matrix(
+                            u.x(),v.x(),w.x(),
+                            u.y(),v.y(),w.y(),
+                            u.z(),v.z(),w.z()
+                            ));
+            Transform3D envelopeToSupportTransform = new Transform3D(translation, rotation);
+            return envelopeToSupportTransform;
+        }
+        
+        
+        
+        
+    }

Modified: java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/SurveyVolume.java
 =============================================================================
--- java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/SurveyVolume.java	(original)
+++ java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/SurveyVolume.java	Wed Apr 27 11:11:32 2016
@@ -20,66 +20,66 @@
  * 
  */
 public abstract class SurveyVolume {
-	protected boolean debug = false;
-	private String name;
-	private String material = "Vacuum";
-	private SurveyVolume mother = null;
-	protected List<SurveyVolume> referenceGeom = null;
-	private SurveyCoordinateSystem coord;
-	protected  Hep3Vector ballPos;
-	protected  Hep3Vector veePos;
-	protected  Hep3Vector flatPos;
-	private Hep3Vector center;
-	private Hep3Vector boxDim;
-	private AlignmentCorrection alignmentCorrections;
-	
-	public SurveyVolume(String name, SurveyVolume m, AlignmentCorrection alignmentCorrection) {
-		setName(name);
-		setMother(m);
-		setAlignmentCorrection(alignmentCorrection);
-	}
-	
-	public SurveyVolume(String name, SurveyVolume m, AlignmentCorrection alignmentCorrection, SurveyVolume ref) {
-		setName(name);
-		setMother(m);
-		setAlignmentCorrection(alignmentCorrection);
-		addReferenceGeom(ref);
-	}
-	
-	public SurveyVolume(String name, SurveyVolume m, AlignmentCorrection alignmentCorrection, List<SurveyVolume> ref) {
-		setName(name);
-		setMother(m);
-		setAlignmentCorrection(alignmentCorrection);
-		addReferenceGeom(ref);
-	}
-	
-	protected abstract void setPos();
-	protected abstract void setCenter();
-	protected abstract void setBoxDim();
-
-	/**
-	 * 
-	 * Initialize the volume. 
-	 * This needs to be called at the top level implementation of the {@link SurveyVolume} to properly setup
-	 * the coordinate systems. It takes care of applying user supplied custom transformations and alignment corrections
-	 * in the order given in the function below. That order must be preserved to get a uniform behavior. 
-	 * 
-	 */
-	protected void init() {
-	    if(debug) System.out.printf("%s: init SurveyVolume %s\n",this.getClass().getSimpleName(),getName());
+    protected boolean debug = false;
+    private String name;
+    private String material = "Vacuum";
+    private SurveyVolume mother = null;
+    protected List<SurveyVolume> referenceGeom = null;
+    private SurveyCoordinateSystem coord;
+    protected  Hep3Vector ballPos;
+    protected  Hep3Vector veePos;
+    protected  Hep3Vector flatPos;
+    private Hep3Vector center;
+    private Hep3Vector boxDim;
+    private AlignmentCorrection alignmentCorrections;
+    
+    public SurveyVolume(String name, SurveyVolume m, AlignmentCorrection alignmentCorrection) {
+        setName(name);
+        setMother(m);
+        setAlignmentCorrection(alignmentCorrection);
+    }
+    
+    public SurveyVolume(String name, SurveyVolume m, AlignmentCorrection alignmentCorrection, SurveyVolume ref) {
+        setName(name);
+        setMother(m);
+        setAlignmentCorrection(alignmentCorrection);
+        addReferenceGeom(ref);
+    }
+    
+    public SurveyVolume(String name, SurveyVolume m, AlignmentCorrection alignmentCorrection, List<SurveyVolume> ref) {
+        setName(name);
+        setMother(m);
+        setAlignmentCorrection(alignmentCorrection);
+        addReferenceGeom(ref);
+    }
+    
+    protected abstract void setPos();
+    protected abstract void setCenter();
+    protected abstract void setBoxDim();
+
+    /**
+     * 
+     * Initialize the volume. 
+     * This needs to be called at the top level implementation of the {@link SurveyVolume} to properly setup
+     * the coordinate systems. It takes care of applying user supplied custom transformations and alignment corrections
+     * in the order given in the function below. That order must be preserved to get a uniform behavior. 
+     * 
+     */
+    protected void init() {
+        if(debug) System.out.printf("%s: init SurveyVolume %s\n",this.getClass().getSimpleName(),getName());
         setPos();
-		setCoord();
-		applyReferenceTransformation();
-		setCenter();
-		setBoxDim();
-		applyGenericCoordinateSystemCorrections();
-		applyLocalAlignmentCorrections();
-		if(debug) {
-		    //printCoordInfo();
-		    System.out.printf("%s: init of SurveyVolume %s DONE\n",this.getClass().getSimpleName(),getName());            
-		}
-	}
-	
+        setCoord();
+        applyReferenceTransformation();
+        setCenter();
+        setBoxDim();
+        applyGenericCoordinateSystemCorrections();
+        applyLocalAlignmentCorrections();
+        if(debug) {
+            //printCoordInfo();
+            System.out.printf("%s: init of SurveyVolume %s DONE\n",this.getClass().getSimpleName(),getName());            
+        }
+    }
+    
 
     private void applySurvey(Element node) {
 
@@ -378,254 +378,254 @@
      * Apply a generic correction to the coordinate system of this volume. 
      */
     protected void applyGenericCoordinateSystemCorrections() {
-	    //do nothing here unless overridden
-	   
-	}
-    
-	/**
-	 * Applies a user supplied reference transformation to the module. 
-	 * This is convenient as it allows for intermediary "virtual" mother volumes to be used 
-	 * in referencing a volume to it's physcial mother volume.
-	 */
-	protected void applyReferenceTransformation() {
-
-	        	    
-	    if(referenceGeom!=null) {
-	        
-	        if(debug) System.out.printf("%s: apply reference transformation for %s\n",this.getClass().getSimpleName(),getName());
-	        
-
-	        if(debug) System.out.printf("%s: coord system before %d ref transformations:\n%s\n",this.getClass().getSimpleName(),referenceGeom.size(),getCoord().toString());
-	        
-	        for(SurveyVolume ref : referenceGeom) {
-
-	            if(debug) {
-	                System.out.printf("%s: coord system before ref %s transform:\n%s\n",this.getClass().getSimpleName(),ref.getName(),getCoord().toString());
-	                System.out.printf("%s: Ref %s coord\n%s\n",this.getClass().getSimpleName(), ref.getName(),ref.getCoord().toString());
-	            }
-	            
-	            getCoord().transform(ref.getCoord().getTransformation());
-
-	            if(debug) System.out.printf("%s: coord system after ref %s transform:\n%s\n",this.getClass().getSimpleName(),ref.getName(),getCoord().toString());
-	            
-	        }
-
-	        if(debug) System.out.printf("%s: coord system after ref transformations:\n%s\n",this.getClass().getSimpleName(),getCoord().toString());
-	        
-	    } else {
-	        
-	        if(debug) System.out.printf("%s: no reference transformation exists for %s\n",this.getClass().getSimpleName(),getName());
-	        
-	    }
-
-	}
-	
-	/**
-	 * Apply @link AlignmentCorrection to the volume if they are supplied. 
-	 * 
-	 */
-	private void applyLocalAlignmentCorrections() {
-	    
-	    // Apply alignment corrections to local coordinate system that is already built
-	    boolean debug_local = false;
-	    if(this.coord==null) 
-	        throw new RuntimeException("no coordinate system was set before trying to apply alignment corrections.");
-
-	    if(alignmentCorrections!=null) {
-
-	        
-	        if(alignmentCorrections.getNode()!=null) {
-	            
-	            if(debug_local || debug) System.out.printf("%s: Apply survey results to %s\n",this.getClass().getSimpleName(),this.getName());
-	            
-	            applySurvey(alignmentCorrections.getNode());
-
-	            if(debug_local || debug) System.out.printf("%s: DONE Apply survey results to %s\n",this.getClass().getSimpleName(),this.getName());
-                
-	        }
-	        
-	        
-	        
-	        
-	        
-	        if(debug_local || debug) System.out.printf("%s: Apply alignment corrections to %s\n",this.getClass().getSimpleName(),this.getName());
-
-	        // translate
-	        if(alignmentCorrections.getTranslation()!=null) {			    
-
-	            if(debug_local || debug) System.out.printf("%s: Apply local translation %s\n", this.getClass().getSimpleName(),alignmentCorrections.getTranslation().toString());			    
-	            
-	            // rotate into mother coordinate system
-	            Hep3Vector translation_mother = getCoord().getTransformation().rotated(alignmentCorrections.getTranslation());
-	            
-	            if(debug_local || debug) System.out.printf("%s: after rotation apply translation %s to coordinate system\n", this.getClass().getSimpleName(),translation_mother.toString());
-	            
-	            //apply translation
-	            getCoord().translate(translation_mother);
-
-	        } else {
-	            if(debug_local || debug) System.out.printf("%s: No translation to coordinate system\n", this.getClass().getSimpleName());
-	        }
-
-	        // rotate
-	        if(alignmentCorrections.getRotation()!=null) {  
-	            
+        //do nothing here unless overridden
+       
+    }
+    
+    /**
+     * Applies a user supplied reference transformation to the module. 
+     * This is convenient as it allows for intermediary "virtual" mother volumes to be used 
+     * in referencing a volume to it's physcial mother volume.
+     */
+    protected void applyReferenceTransformation() {
+
+                    
+        if(referenceGeom!=null) {
+            
+            if(debug) System.out.printf("%s: apply reference transformation for %s\n",this.getClass().getSimpleName(),getName());
+            
+
+            if(debug) System.out.printf("%s: coord system before %d ref transformations:\n%s\n",this.getClass().getSimpleName(),referenceGeom.size(),getCoord().toString());
+            
+            for(SurveyVolume ref : referenceGeom) {
+
+                if(debug) {
+                    System.out.printf("%s: coord system before ref %s transform:\n%s\n",this.getClass().getSimpleName(),ref.getName(),getCoord().toString());
+                    System.out.printf("%s: Ref %s coord\n%s\n",this.getClass().getSimpleName(), ref.getName(),ref.getCoord().toString());
+                }
+                
+                getCoord().transform(ref.getCoord().getTransformation());
+
+                if(debug) System.out.printf("%s: coord system after ref %s transform:\n%s\n",this.getClass().getSimpleName(),ref.getName(),getCoord().toString());
+                
+            }
+
+            if(debug) System.out.printf("%s: coord system after ref transformations:\n%s\n",this.getClass().getSimpleName(),getCoord().toString());
+            
+        } else {
+            
+            if(debug) System.out.printf("%s: no reference transformation exists for %s\n",this.getClass().getSimpleName(),getName());
+            
+        }
+
+    }
+    
+    /**
+     * Apply @link AlignmentCorrection to the volume if they are supplied. 
+     * 
+     */
+    private void applyLocalAlignmentCorrections() {
+        
+        // Apply alignment corrections to local coordinate system that is already built
+        boolean debug_local = false;
+        if(this.coord==null) 
+            throw new RuntimeException("no coordinate system was set before trying to apply alignment corrections.");
+
+        if(alignmentCorrections!=null) {
+
+            
+            if(alignmentCorrections.getNode()!=null) {
+                
+                if(debug_local || debug) System.out.printf("%s: Apply survey results to %s\n",this.getClass().getSimpleName(),this.getName());
+                
+                applySurvey(alignmentCorrections.getNode());
+
+                if(debug_local || debug) System.out.printf("%s: DONE Apply survey results to %s\n",this.getClass().getSimpleName(),this.getName());
+                
+            }
+            
+            
+            
+            
+            
+            if(debug_local || debug) System.out.printf("%s: Apply alignment corrections to %s\n",this.getClass().getSimpleName(),this.getName());
+
+            // translate
+            if(alignmentCorrections.getTranslation()!=null) {               
+
+                if(debug_local || debug) System.out.printf("%s: Apply local translation %s\n", this.getClass().getSimpleName(),alignmentCorrections.getTranslation().toString());               
+                
+                // rotate into mother coordinate system
+                Hep3Vector translation_mother = getCoord().getTransformation().rotated(alignmentCorrections.getTranslation());
+                
+                if(debug_local || debug) System.out.printf("%s: after rotation apply translation %s to coordinate system\n", this.getClass().getSimpleName(),translation_mother.toString());
+                
+                //apply translation
+                getCoord().translate(translation_mother);
+
+            } else {
+                if(debug_local || debug) System.out.printf("%s: No translation to coordinate system\n", this.getClass().getSimpleName());
+            }
+
+            // rotate
+            if(alignmentCorrections.getRotation()!=null) {  
+                
                 if(debug_local || debug) {
                     System.out.printf("%s: Apply rotation matrix:\n", this.getClass().getSimpleName());   
                     TransformationUtils.printMatrix(alignmentCorrections.getRotation().getMatrix());
                     System.out.printf("%s: coord system before:\n%s\n", this.getClass().getSimpleName(),getCoord().toString());   
                 }
 
-	            
-	            // correct rotation of the local unit vectors
-	            Vector3D u_rot_local = alignmentCorrections.getRotation().applyTo(new Vector3D(1,0,0));
-	            Vector3D v_rot_local = alignmentCorrections.getRotation().applyTo(new Vector3D(0,1,0));
-	            Vector3D w_rot_local = alignmentCorrections.getRotation().applyTo(new Vector3D(0,0,1));
-
-	            // rotate the local unit vectors to the mother coordinates
-	            
-	            Hep3Vector u_rot = getCoord().getTransformation().getRotation().rotated(new BasicHep3Vector(u_rot_local.toArray()));
-	            Hep3Vector v_rot = getCoord().getTransformation().getRotation().rotated(new BasicHep3Vector(v_rot_local.toArray()));
-	            Hep3Vector w_rot = getCoord().getTransformation().getRotation().rotated(new BasicHep3Vector(w_rot_local.toArray()));
+                
+                // correct rotation of the local unit vectors
+                Vector3D u_rot_local = alignmentCorrections.getRotation().applyTo(new Vector3D(1,0,0));
+                Vector3D v_rot_local = alignmentCorrections.getRotation().applyTo(new Vector3D(0,1,0));
+                Vector3D w_rot_local = alignmentCorrections.getRotation().applyTo(new Vector3D(0,0,1));
+
+                // rotate the local unit vectors to the mother coordinates
+                
+                Hep3Vector u_rot = getCoord().getTransformation().getRotation().rotated(new BasicHep3Vector(u_rot_local.toArray()));
+                Hep3Vector v_rot = getCoord().getTransformation().getRotation().rotated(new BasicHep3Vector(v_rot_local.toArray()));
+                Hep3Vector w_rot = getCoord().getTransformation().getRotation().rotated(new BasicHep3Vector(w_rot_local.toArray()));
                
-	            getCoord().u(u_rot);
-	            getCoord().v(v_rot);
-	            getCoord().w(w_rot);
+                getCoord().u(u_rot);
+                getCoord().v(v_rot);
+                getCoord().w(w_rot);
 
                 if(debug_local || debug) {
                     System.out.printf("%s: coord system after:\n%s\n", this.getClass().getSimpleName(),getCoord().toString());   
                 }
 
-	            
-	            
-
-	        } else {
-	            if(debug_local || debug) System.out.printf("%s: No rotation to coordinate system\n", this.getClass().getSimpleName());
-	        }
-
-	        if(debug_local || debug) System.out.printf("%s: coordinate system after alignment corrections:\n%s\n",this.getClass().getSimpleName(),getCoord().toString());
-
-	    } else {
+                
+                
+
+            } else {
+                if(debug_local || debug) System.out.printf("%s: No rotation to coordinate system\n", this.getClass().getSimpleName());
+            }
+
+            if(debug_local || debug) System.out.printf("%s: coordinate system after alignment corrections:\n%s\n",this.getClass().getSimpleName(),getCoord().toString());
+
+        } else {
             if(debug_local || debug) System.out.printf("%s: no alignment corrections exist for %s\n",this.getClass().getSimpleName(),this.getName());
-	    }
-
-	}
-	
-	private void setAlignmentCorrection(AlignmentCorrection alignmentCorrection) {
+        }
+
+    }
+    
+    private void setAlignmentCorrection(AlignmentCorrection alignmentCorrection) {
         this.alignmentCorrections = alignmentCorrection;
     }
     public  void setBallPos(double x, double y, double z) {
-		ballPos = new BasicHep3Vector(x,y,z);
-	}
-	public  void setVeePos(double x, double y, double z) {
-		veePos = new BasicHep3Vector(x,y,z);
-	}
-	public  void setFlatPos(double x, double y, double z) {
-		flatPos = new BasicHep3Vector(x,y,z);
-	}
-	public  Hep3Vector getBallPos() {
-		return ballPos;
-	}
-	public  Hep3Vector getVeePos() {
-		return veePos;
-	}
-	public  Hep3Vector getFlatPos() {
-		return flatPos;
-	}
-	public void setCoord() {
-		if(ballPos==null || veePos==null || flatPos==null) {
-			throw new RuntimeException("Need to set ball, vee and flat before building coord system!");
-		}
-		
-		coord = new SurveyCoordinateSystem(ballPos, veePos, flatPos);					
-		
-		if(this.debug) {
-		    System.out.printf("%s: setCoord \n%s\n", this.getClass().getSimpleName(), coord.toString());
-		}
-	}
-	public SurveyCoordinateSystem getCoord() {
-		if(coord == null) {
-			throw new RuntimeException("Need to setCoord!");
-		}
-		return coord;
-	}
-	public String getName() {
-		return name;
-	}
-	public void setName(String name) {
-		this.name = name;
-	}
-	public Hep3Vector getCenter() {
-		return center;
-	}
-	public void setCenter(Hep3Vector center) {
-		this.center = center;
-	}
-	public void setCenter(double x, double y, double z) {
-		this.center = new BasicHep3Vector(x,y,z);
-	}
-	public Hep3Vector getBoxDim() {
-		return boxDim;
-	}
-	public void setBoxDim(double x, double y, double z) {
-		this.boxDim = new BasicHep3Vector(x,y,z);
-	}
-	public SurveyVolume getMother() {
-		return mother;
-	}
-	public void setMother(SurveyVolume mother) {
-		this.mother = mother;
-	}
-	public void addReferenceGeom(SurveyVolume refGeom) {
-	    if(refGeom!=null) { // check that it's not a dummy call
-	        if(referenceGeom == null) {
-	            referenceGeom = new ArrayList<SurveyVolume>();
-	        }
-	        referenceGeom.add(refGeom);
-	    }
-	}
-	public void addReferenceGeom(List<SurveyVolume> refGeomList) {
-		if(referenceGeom == null) {
-			referenceGeom = new ArrayList<SurveyVolume>();
-		}
-		referenceGeom.addAll(refGeomList);
-	}
-	public void printSurveyPos() {
-	    if(debug) {
-	        System.out.printf("%s: Survey pos for %s:\n",getClass().getSimpleName(),getName());
-	        System.out.printf("%s: ballPos   %s\n",getClass().getSimpleName(), ballPos.toString());
-	        System.out.printf("%s: veePos    %s\n",getClass().getSimpleName(), veePos.toString());
-	        System.out.printf("%s: flatPos   %s\n",getClass().getSimpleName(), flatPos.toString());
-	    }
-	}
-	public String getMaterial() {
-		return material;
-	}
-	public void setMaterial(String material) {
-		this.material = material;
-	}
-	public String toString() {
-		String s = "==\n" + getName() + " with mother " + (getMother()==null?"<no mother>":getMother().getName()) + ":\n";
-		if( getCenter()!=null) s += "Center of box: " + getCenter().toString() + "\n";
+        ballPos = new BasicHep3Vector(x,y,z);
+    }
+    public  void setVeePos(double x, double y, double z) {
+        veePos = new BasicHep3Vector(x,y,z);
+    }
+    public  void setFlatPos(double x, double y, double z) {
+        flatPos = new BasicHep3Vector(x,y,z);
+    }
+    public  Hep3Vector getBallPos() {
+        return ballPos;
+    }
+    public  Hep3Vector getVeePos() {
+        return veePos;
+    }
+    public  Hep3Vector getFlatPos() {
+        return flatPos;
+    }
+    public void setCoord() {
+        if(ballPos==null || veePos==null || flatPos==null) {
+            throw new RuntimeException("Need to set ball, vee and flat before building coord system!");
+        }
+        
+        coord = new SurveyCoordinateSystem(ballPos, veePos, flatPos);                   
+        
+        if(this.debug) {
+            System.out.printf("%s: setCoord \n%s\n", this.getClass().getSimpleName(), coord.toString());
+        }
+    }
+    public SurveyCoordinateSystem getCoord() {
+        if(coord == null) {
+            throw new RuntimeException("Need to setCoord!");
+        }
+        return coord;
+    }
+    public String getName() {
+        return name;
+    }
+    public void setName(String name) {
+        this.name = name;
+    }
+    public Hep3Vector getCenter() {
+        return center;
+    }
+    public void setCenter(Hep3Vector center) {
+        this.center = center;
+    }
+    public void setCenter(double x, double y, double z) {
+        this.center = new BasicHep3Vector(x,y,z);
+    }
+    public Hep3Vector getBoxDim() {
+        return boxDim;
+    }
+    public void setBoxDim(double x, double y, double z) {
+        this.boxDim = new BasicHep3Vector(x,y,z);
+    }
+    public SurveyVolume getMother() {
+        return mother;
+    }
+    public void setMother(SurveyVolume mother) {
+        this.mother = mother;
+    }
+    public void addReferenceGeom(SurveyVolume refGeom) {
+        if(refGeom!=null) { // check that it's not a dummy call
+            if(referenceGeom == null) {
+                referenceGeom = new ArrayList<SurveyVolume>();
+            }
+            referenceGeom.add(refGeom);
+        }
+    }
+    public void addReferenceGeom(List<SurveyVolume> refGeomList) {
+        if(referenceGeom == null) {
+            referenceGeom = new ArrayList<SurveyVolume>();
+        }
+        referenceGeom.addAll(refGeomList);
+    }
+    public void printSurveyPos() {
+        if(debug) {
+            System.out.printf("%s: Survey pos for %s:\n",getClass().getSimpleName(),getName());
+            System.out.printf("%s: ballPos   %s\n",getClass().getSimpleName(), ballPos.toString());
+            System.out.printf("%s: veePos    %s\n",getClass().getSimpleName(), veePos.toString());
+            System.out.printf("%s: flatPos   %s\n",getClass().getSimpleName(), flatPos.toString());
+        }
+    }
+    public String getMaterial() {
+        return material;
+    }
+    public void setMaterial(String material) {
+        this.material = material;
+    }
+    public String toString() {
+        String s = "==\n" + getName() + " with mother " + (getMother()==null?"<no mother>":getMother().getName()) + ":\n";
+        if( getCenter()!=null) s += "Center of box: " + getCenter().toString() + "\n";
         if( getBoxDim()!=null) s += "Box dimensions: " + getBoxDim().toString() + "\n";
-		if(this.coord==null)   s += " No coord system \n";
-		else {
-		    s += getName() + " origin " + getCoord().origin() + " u " + getCoord().u()+ " v " + getCoord().v()+ " w " + getCoord().w();
-		}
+        if(this.coord==null)   s += " No coord system \n";
+        else {
+            s += getName() + " origin " + getCoord().origin() + " u " + getCoord().u()+ " v " + getCoord().v()+ " w " + getCoord().w();
+        }
         s += "AlignmentCorrections: \n";
-		if(this.alignmentCorrections!=null) {
-		    s += "Milleparameters: ";
-		    if(this.alignmentCorrections.getMilleParameters()!=null) {
-		        for(MilleParameter mp : this.alignmentCorrections.getMilleParameters()) s += mp.getId() + " ";
-		    } else {
-		        s += "no MP params associated.";
-		    }
-		    s +=  "(" + this.getName() + ")" + " \n";
-		} else {
-		    s+= " no alignment corrections associated.\n";
-		}
-		SurveyVolume m = getMother();
-		while(m!=null) {    
+        if(this.alignmentCorrections!=null) {
+            s += "Milleparameters: ";
+            if(this.alignmentCorrections.getMilleParameters()!=null) {
+                for(MilleParameter mp : this.alignmentCorrections.getMilleParameters()) s += mp.getId() + " ";
+            } else {
+                s += "no MP params associated.";
+            }
+            s +=  "(" + this.getName() + ")" + " \n";
+        } else {
+            s+= " no alignment corrections associated.\n";
+        }
+        SurveyVolume m = getMother();
+        while(m!=null) {    
             Hep3Vector origin_m = HPSTrackerBuilder.transformToParent(new BasicHep3Vector(0, 0, 0), this, m.getName());
             String unitVecStr = "";
             if(getCoord()!=null) {
@@ -638,12 +638,12 @@
             //origin_m = VecOp.mult(0.0393701, origin_m);
             //s += String.format("%s origin in %s : (%.4f %.4f %.4f) (inch)\n",getName(), m.getName(), origin_m.x(),origin_m.y(),origin_m.z());            
             m = m.getMother();
-		}
-		
-		
-		return s;
-	}
-	
-
-	
+        }
+        
+        
+        return s;
+    }
+    
+
+    
 }

Modified: java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/SurveyVolumeImpl.java
 =============================================================================
--- java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/SurveyVolumeImpl.java	(original)
+++ java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/SurveyVolumeImpl.java	Wed Apr 27 11:11:32 2016
@@ -21,7 +21,7 @@
     public abstract void setPositionAndRotation(SurveyVolume base);
 
     public String getName() {
-    	return surveyVolume.getName();
+        return surveyVolume.getName();
     }
     
     protected Hep3Vector getBoxDim() {
@@ -33,7 +33,7 @@
     }
 
     public boolean isDebug() {
-    	return debug;
+        return debug;
     }
 
     public abstract String toString();

Modified: java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/SurveyVolumeVisualization.java
 =============================================================================
--- java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/SurveyVolumeVisualization.java	(original)
+++ java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/SurveyVolumeVisualization.java	Wed Apr 27 11:11:32 2016
@@ -7,14 +7,14 @@
  * @author Per Hansson Adrian <[log in to unmask]>
  */
 public class SurveyVolumeVisualization {
-	protected String visName = "";
-	public SurveyVolumeVisualization() {}
-	public String getVisName() {
-		return visName;
-	}
-	protected void setVisName(String visName) {
-		this.visName = visName;
-	}
-	
-	
+    protected String visName = "";
+    public SurveyVolumeVisualization() {}
+    public String getVisName() {
+        return visName;
+    }
+    protected void setVisName(String visName) {
+        this.visName = visName;
+    }
+    
+    
 }

Modified: java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/SvtAlignmentConstantsReader.java
 =============================================================================
--- java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/SvtAlignmentConstantsReader.java	(original)
+++ java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/SvtAlignmentConstantsReader.java	Wed Apr 27 11:11:32 2016
@@ -14,16 +14,16 @@
  * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
  */
 public class SvtAlignmentConstantsReader {
-	
-	private SvtAlignmentConstantsReader() {
-	}
+    
+    private SvtAlignmentConstantsReader() {
+    }
 
-	/**
-	 * Read SVT alignment constants from the conditions database table <i>svt_alignments</i> and create a list of 
-	 * <code>MilleParameter</code> objects from it.
-	 * 
-	 * @return the Millepede parameter list
-	 */
+    /**
+     * Read SVT alignment constants from the conditions database table <i>svt_alignments</i> and create a list of 
+     * <code>MilleParameter</code> objects from it.
+     * 
+     * @return the Millepede parameter list
+     */
     static List<MilleParameter> readMilleParameters() {
 
         final DatabaseConditionsManager manager = DatabaseConditionsManager.getInstance();

Modified: java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/lcdd/HPSMuonCalorimeter2.java
 =============================================================================
--- java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/lcdd/HPSMuonCalorimeter2.java	(original)
+++ java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/lcdd/HPSMuonCalorimeter2.java	Wed Apr 27 11:11:32 2016
@@ -8,13 +8,13 @@
 
 public class HPSMuonCalorimeter2 extends LCDDSubdetector
 {
-	HPSMuonCalorimeter2(Element e) throws JDOMException 
-	{
-		super(e);
-	}
+    HPSMuonCalorimeter2(Element e) throws JDOMException 
+    {
+        super(e);
+    }
 
-	void addToLCDD(LCDD lcdd, SensitiveDetector sens) throws JDOMException 
-	{
+    void addToLCDD(LCDD lcdd, SensitiveDetector sens) throws JDOMException 
+    {
         String name = node.getAttributeValue("name");
         System.out.println("HPSMuonCalorimeter2.addToLCDD - " + name);
         int id = node.getAttribute("id").getIntValue();
@@ -22,7 +22,7 @@
         
         Element parameters = node.getChild("parameters");
         if (parameters == null) {
-        	throw new RuntimeException("parameters element missing");
+            throw new RuntimeException("parameters element missing");
         }
                 
         double frontFaceToTarget = parameters.getAttribute("front_face_to_target").getDoubleValue();
@@ -40,16 +40,16 @@
         System.out.println("stripSpacingZ = " + stripSpacingZ);
         
         for (Object layerObject : node.getChildren("layer")) {
-        	Element layerElement = (Element)layerObject;
-        	int layerId = layerElement.getAttribute("id").getIntValue();
-        	System.out.println("layer = " + layerId);
-        	for (Object sliceObject : layerElement.getChildren("slice")) {
-        		Element sliceElement = (Element)sliceObject;
-        		if (sliceElement.getAttribute("thickness") != null) {
-        			double thickness = sliceElement.getAttribute("thickness").getDoubleValue();
-        			System.out.println("slice thickness = " + thickness);
-        		}
-        	}
+            Element layerElement = (Element)layerObject;
+            int layerId = layerElement.getAttribute("id").getIntValue();
+            System.out.println("layer = " + layerId);
+            for (Object sliceObject : layerElement.getChildren("slice")) {
+                Element sliceElement = (Element)sliceObject;
+                if (sliceElement.getAttribute("thickness") != null) {
+                    double thickness = sliceElement.getAttribute("thickness").getDoubleValue();
+                    System.out.println("slice thickness = " + thickness);
+                }
+            }
         }
-	}
+    }
 }

Modified: java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/lcdd/HPSTestRunTracker2014.java
 =============================================================================
--- java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/lcdd/HPSTestRunTracker2014.java	(original)
+++ java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/lcdd/HPSTestRunTracker2014.java	Wed Apr 27 11:11:32 2016
@@ -9,7 +9,6 @@
 import org.lcsim.geometry.compact.converter.HPSTestRunTracker2014GeometryDefinition;
 import org.lcsim.geometry.compact.converter.HPSTestRunTracker2014LCDDBuilder;
 import org.lcsim.geometry.compact.converter.HPSTrackerBuilder;
-import org.lcsim.geometry.compact.converter.HPSTrackerGeometryDefinition;
 import org.lcsim.geometry.compact.converter.HPSTrackerLCDDBuilder;
 import org.lcsim.geometry.compact.converter.lcdd.util.Box;
 import org.lcsim.geometry.compact.converter.lcdd.util.LCDD;
@@ -30,58 +29,58 @@
  */
 public class HPSTestRunTracker2014 extends HPSTracker2014Base
 {
-	public HPSTestRunTracker2014(Element node) throws JDOMException
-	{
-		super(node);
-	}
-
-	/* (non-Javadoc)
-	 * @see org.lcsim.geometry.compact.converter.lcdd.HPSTracker2014Base#initializeBuilder(org.lcsim.geometry.compact.converter.lcdd.util.LCDD, org.lcsim.geometry.compact.converter.lcdd.util.SensitiveDetector)
-	 */
-	protected HPSTrackerLCDDBuilder initializeBuilder(LCDD lcdd, SensitiveDetector sens) {
-	    HPSTrackerLCDDBuilder b = new HPSTestRunTracker2014LCDDBuilder(_debug,node,lcdd,sens);
-	    return b;
-	}
-	
-	
-
-	/* (non-Javadoc)
+    public HPSTestRunTracker2014(Element node) throws JDOMException
+    {
+        super(node);
+    }
+
+    /* (non-Javadoc)
+     * @see org.lcsim.geometry.compact.converter.lcdd.HPSTracker2014Base#initializeBuilder(org.lcsim.geometry.compact.converter.lcdd.util.LCDD, org.lcsim.geometry.compact.converter.lcdd.util.SensitiveDetector)
+     */
+    protected HPSTrackerLCDDBuilder initializeBuilder(LCDD lcdd, SensitiveDetector sens) {
+        HPSTrackerLCDDBuilder b = new HPSTestRunTracker2014LCDDBuilder(_debug,node,lcdd,sens);
+        return b;
+    }
+    
+    
+
+    /* (non-Javadoc)
      * @see org.lcsim.detector.converter.compact.HPSTracker2014ConverterBase#getModuleNumber(org.lcsim.geometry.compact.converter.JavaSurveyVolume)
      */
     protected int getModuleNumber(String surveyVolume) {
         return HPSTrackerBuilder.getHalfFromName(surveyVolume).equals("top") ? 0 : 1;
     }
-	
-	
-	
-	
-	
-	
-	
-	
-	
-
-	
-	
-	
-	private void makeExample(LCDD lcdd, SensitiveDetector sens) throws JDOMException {
-	
-	
-	if(_debug) {
-		System.out.println("--- makeExample ----");
-		
-	}
-
-	
-	
-	String volName = "example";
-	Box box = new Box(volName + "Box", HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width, HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length , HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/4.0);
-	lcdd.add(box);
-	Volume volume = new Volume(volName + "_volume", box, lcdd.getMaterial("Vacuum"));
-	
-	
-	
-	 org.apache.commons.math3.geometry.euclidean.threed.Vector3D axisX = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(1., 0., 0.);
+    
+    
+    
+    
+    
+    
+    
+    
+    
+
+    
+    
+    
+    private void makeExample(LCDD lcdd, SensitiveDetector sens) throws JDOMException {
+    
+    
+    if(_debug) {
+        System.out.println("--- makeExample ----");
+        
+    }
+
+    
+    
+    String volName = "example";
+    Box box = new Box(volName + "Box", HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width, HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length , HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/4.0);
+    lcdd.add(box);
+    Volume volume = new Volume(volName + "_volume", box, lcdd.getMaterial("Vacuum"));
+    
+    
+    
+     org.apache.commons.math3.geometry.euclidean.threed.Vector3D axisX = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(1., 0., 0.);
      org.apache.commons.math3.geometry.euclidean.threed.Vector3D axisY = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(0., 1., 0.);
      org.apache.commons.math3.geometry.euclidean.threed.Vector3D axisZ = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(0., 0., 1.);
 
@@ -131,11 +130,11 @@
      Rotation rot = new Rotation(volName + "_rotation",0,0,0);
      lcdd.add(pos);
      lcdd.add(rot);
-	
-	
+    
+    
      PhysVol basePV = new PhysVol(volume, lcdd.pickMotherVolume(this), pos, rot);
      if(_debug) {
-    	 System.out.println("Created physical vomume " + basePV.getName());
+         System.out.println("Created physical vomume " + basePV.getName());
      }
      
      
@@ -151,153 +150,153 @@
      lcdd.add(subRot);
      PhysVol subBasePV = new PhysVol(volumeSub, volume, subPos, subRot);
      if(_debug) {
-    	 System.out.println("Created physical vomume " + subBasePV.getName());
+         System.out.println("Created physical vomume " + subBasePV.getName());
      }
-	
+    
      lcdd.add(volumeSub);
      volumeSub.setVisAttributes(lcdd.getVisAttributes("SensorVis"));
 
-	
+    
      lcdd.add(volume);
-	
-	
-	
-	
-	}
-	
-	
-	private void makeExample2(LCDD lcdd, SensitiveDetector sens) throws JDOMException {
-		
-		
-		if(_debug) {
-			System.out.println("--- makeExample2 ----");
-			
-		}
-		
-		String volName = "example2";
-		Box box = new Box(volName + "Box", HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width, HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length , HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/4.0);
-		lcdd.add(box);
-		Volume volume = new Volume(volName + "_volume", box, lcdd.getMaterial("Vacuum"));
-	    
-
-		
-		 org.apache.commons.math3.geometry.euclidean.threed.Vector3D axisX = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(1., 0., 0.);
-	     org.apache.commons.math3.geometry.euclidean.threed.Vector3D axisY = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(0., 1., 0.);
-	     org.apache.commons.math3.geometry.euclidean.threed.Vector3D axisZ = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(0., 0., 1.);
-
-	     double alpha1 = PI / 4.;
-	     double alpha2 = PI / 4.;
-	     double alpha3 = -PI / 4.;
-
-	     org.apache.commons.math3.geometry.euclidean.threed.Rotation r123 = 
-	    		 new org.apache.commons.math3.geometry.euclidean.threed.Rotation(org.apache.commons.math3.geometry.euclidean.threed.RotationOrder.XYZ, 
-	    				 alpha1, 
-	    				 alpha2, 
-	    				 alpha3);
-	     
-	     org.apache.commons.math3.geometry.euclidean.threed.Vector3D axisXPrime = r123.applyTo(axisX);
-	     org.apache.commons.math3.geometry.euclidean.threed.Vector3D axisYPrime = r123.applyTo(axisY);
-	     org.apache.commons.math3.geometry.euclidean.threed.Vector3D axisZPrime = r123.applyTo(axisZ);
-
-	     //if(_debug) System.out.println("axisYPrime: " + axisYPrime);
-	     //if(_debug) System.out.println("axisZPrime: " + axisZPrime);
-
-	     
-	     
-	     //double [] rotations = r123.getAngles(org.apache.commons.math3.geometry.euclidean.threed.RotationOrder.XYZ);
-	     
-	     
-	     //double [] rotations = r12.getAngles(org.apache.commons.math3.geometry.euclidean.threed.RotationOrder.XYZ);
-	     double [] rotations = r123.getAngles(org.apache.commons.math3.geometry.euclidean.threed.RotationOrder.XYZ);
-	     
-	     Position pos = new Position(volName + "_position",HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width*1.5,0,0);
-	     Rotation rot = new Rotation(volName + "_rotation",rotations[0],rotations[1],rotations[2]);
-	     lcdd.add(pos);
-	     lcdd.add(rot);
-		
-		
-	     PhysVol basePV = new PhysVol(volume, lcdd.pickMotherVolume(this), pos, rot);
-	     if(_debug) {
-	    	 System.out.println("Created physical vomume " + basePV.getName());
-	     }
-		
-	     
-	     
-	     volName = volName + "_sub";
-	     Box boxSub = new Box(volName + "Box", HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width, HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/4.0 , HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/8.0);
-	     lcdd.add(boxSub);
-	     Volume volumeSub = new Volume(volName + "_volume", boxSub, lcdd.getMaterial("Vacuum"));
-	     Position subPos = new Position(volName + "_position",0,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/4.0*2-HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/8.0,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/16.0);
-	     Rotation subRot = new Rotation(volName + "_rotation",0,0,0);
-	     lcdd.add(subPos);
-	     lcdd.add(subRot);
-	     PhysVol subBasePV = new PhysVol(volumeSub, volume, subPos, subRot);
-	     if(_debug) {
-	    	 System.out.println("Created physical vomume " + subBasePV.getName());
-	     }
-		
-	     lcdd.add(volumeSub);
-	     volumeSub.setVisAttributes(lcdd.getVisAttributes("SensorVis"));
-	     
-	     lcdd.add(volume);
-
-		
-		
-		
-		}
-		
-		
-		
-	private void makeExample3(LCDD lcdd, SensitiveDetector sens) throws JDOMException {
-		
-		
-		if(_debug) {
-			System.out.println("--- makeExample3 ----");
-			
-		}
-		
-		String volName = "example3";
-		Box box = new Box(volName + "Box", HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width, HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length , HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/4.0);
-		lcdd.add(box);
-		Volume volume = new Volume(volName + "_volume", box, lcdd.getMaterial("Vacuum"));
-		
-		/*
-		
-		TestRunModuleL13: survey positions before ref support_plate_top transform
-		Survey pos for module_L1t:
-		ballPos   [      25.000,      676.10,     -4.3500]
-		veePos    [      95.000,      676.10,     -4.3500]
-		flatPos   [      60.000,      670.10,     -4.3500]
-		TestRunModuleL13: Ref support_plate_top coord
-		Coordinate system: 
-		origin [      40.314,      142.71,      138.40]
-		u [     0.99955,    0.030000,      0.0000]
-		v [   -0.030000,     0.99955,      0.0000]
-		w [      0.0000,     -0.0000,      1.0000]
-		TestRunModuleL13: survey positions after ref support_plate_top transform
-		Survey pos for module_L1t:
-		ballPos   [      45.020,      819.25,      134.05]
-		veePos    [      114.99,      821.35,      134.05]
-		flatPos   [      80.184,      814.31,      134.05]
-		TestRunModuleL13: coordinate system:
-		Coordinate system: 
-		origin [      45.020,      819.25,      134.05]
-		u [     0.99955,    0.030000,      0.0000]
-		v [    0.030000,    -0.99955,      0.0000]
-		w [      0.0000,      0.0000,     -1.0000]
-		TestRunModuleL13: translation:
-		[      45.020,      819.25,      134.05]
-		TestRunModuleL13: rotation:
-		[
-		0.999549894704642 0.030000133265350216 0.0
-		0.030000133265350216 -0.999549894704642 0.0
-		0.0 0.0 -1.0
-
-		]
-		
-		
-		
-		LCDDBaseGeom: set position and rotation for volume module_L1t
+    
+    
+    
+    
+    }
+    
+    
+    private void makeExample2(LCDD lcdd, SensitiveDetector sens) throws JDOMException {
+        
+        
+        if(_debug) {
+            System.out.println("--- makeExample2 ----");
+            
+        }
+        
+        String volName = "example2";
+        Box box = new Box(volName + "Box", HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width, HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length , HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/4.0);
+        lcdd.add(box);
+        Volume volume = new Volume(volName + "_volume", box, lcdd.getMaterial("Vacuum"));
+        
+
+        
+         org.apache.commons.math3.geometry.euclidean.threed.Vector3D axisX = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(1., 0., 0.);
+         org.apache.commons.math3.geometry.euclidean.threed.Vector3D axisY = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(0., 1., 0.);
+         org.apache.commons.math3.geometry.euclidean.threed.Vector3D axisZ = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(0., 0., 1.);
+
+         double alpha1 = PI / 4.;
+         double alpha2 = PI / 4.;
+         double alpha3 = -PI / 4.;
+
+         org.apache.commons.math3.geometry.euclidean.threed.Rotation r123 = 
+                 new org.apache.commons.math3.geometry.euclidean.threed.Rotation(org.apache.commons.math3.geometry.euclidean.threed.RotationOrder.XYZ, 
+                         alpha1, 
+                         alpha2, 
+                         alpha3);
+         
+         org.apache.commons.math3.geometry.euclidean.threed.Vector3D axisXPrime = r123.applyTo(axisX);
+         org.apache.commons.math3.geometry.euclidean.threed.Vector3D axisYPrime = r123.applyTo(axisY);
+         org.apache.commons.math3.geometry.euclidean.threed.Vector3D axisZPrime = r123.applyTo(axisZ);
+
+         //if(_debug) System.out.println("axisYPrime: " + axisYPrime);
+         //if(_debug) System.out.println("axisZPrime: " + axisZPrime);
+
+         
+         
+         //double [] rotations = r123.getAngles(org.apache.commons.math3.geometry.euclidean.threed.RotationOrder.XYZ);
+         
+         
+         //double [] rotations = r12.getAngles(org.apache.commons.math3.geometry.euclidean.threed.RotationOrder.XYZ);
+         double [] rotations = r123.getAngles(org.apache.commons.math3.geometry.euclidean.threed.RotationOrder.XYZ);
+         
+         Position pos = new Position(volName + "_position",HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width*1.5,0,0);
+         Rotation rot = new Rotation(volName + "_rotation",rotations[0],rotations[1],rotations[2]);
+         lcdd.add(pos);
+         lcdd.add(rot);
+        
+        
+         PhysVol basePV = new PhysVol(volume, lcdd.pickMotherVolume(this), pos, rot);
+         if(_debug) {
+             System.out.println("Created physical vomume " + basePV.getName());
+         }
+        
+         
+         
+         volName = volName + "_sub";
+         Box boxSub = new Box(volName + "Box", HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width, HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/4.0 , HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/8.0);
+         lcdd.add(boxSub);
+         Volume volumeSub = new Volume(volName + "_volume", boxSub, lcdd.getMaterial("Vacuum"));
+         Position subPos = new Position(volName + "_position",0,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/4.0*2-HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/8.0,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/16.0);
+         Rotation subRot = new Rotation(volName + "_rotation",0,0,0);
+         lcdd.add(subPos);
+         lcdd.add(subRot);
+         PhysVol subBasePV = new PhysVol(volumeSub, volume, subPos, subRot);
+         if(_debug) {
+             System.out.println("Created physical vomume " + subBasePV.getName());
+         }
+        
+         lcdd.add(volumeSub);
+         volumeSub.setVisAttributes(lcdd.getVisAttributes("SensorVis"));
+         
+         lcdd.add(volume);
+
+        
+        
+        
+        }
+        
+        
+        
+    private void makeExample3(LCDD lcdd, SensitiveDetector sens) throws JDOMException {
+        
+        
+        if(_debug) {
+            System.out.println("--- makeExample3 ----");
+            
+        }
+        
+        String volName = "example3";
+        Box box = new Box(volName + "Box", HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width, HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length , HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/4.0);
+        lcdd.add(box);
+        Volume volume = new Volume(volName + "_volume", box, lcdd.getMaterial("Vacuum"));
+        
+        /*
+        
+        TestRunModuleL13: survey positions before ref support_plate_top transform
+        Survey pos for module_L1t:
+        ballPos   [      25.000,      676.10,     -4.3500]
+        veePos    [      95.000,      676.10,     -4.3500]
+        flatPos   [      60.000,      670.10,     -4.3500]
+        TestRunModuleL13: Ref support_plate_top coord
+        Coordinate system: 
+        origin [      40.314,      142.71,      138.40]
+        u [     0.99955,    0.030000,      0.0000]
+        v [   -0.030000,     0.99955,      0.0000]
+        w [      0.0000,     -0.0000,      1.0000]
+        TestRunModuleL13: survey positions after ref support_plate_top transform
+        Survey pos for module_L1t:
+        ballPos   [      45.020,      819.25,      134.05]
+        veePos    [      114.99,      821.35,      134.05]
+        flatPos   [      80.184,      814.31,      134.05]
+        TestRunModuleL13: coordinate system:
+        Coordinate system: 
+        origin [      45.020,      819.25,      134.05]
+        u [     0.99955,    0.030000,      0.0000]
+        v [    0.030000,    -0.99955,      0.0000]
+        w [      0.0000,      0.0000,     -1.0000]
+        TestRunModuleL13: translation:
+        [      45.020,      819.25,      134.05]
+        TestRunModuleL13: rotation:
+        [
+        0.999549894704642 0.030000133265350216 0.0
+        0.030000133265350216 -0.999549894704642 0.0
+        0.0 0.0 -1.0
+
+        ]
+        
+        
+        
+        LCDDBaseGeom: set position and rotation for volume module_L1t
 getEulerAngles: u [    0.030000,    -0.99955,      0.0000] v[      0.0000,      0.0000,     -1.0000] -> [      0.0000,      1.0000,      0.0000] [      0.0000,      0.0000,      1.0000]
 Input: u {0.03; -1; 0} v {0; 0; -1} u' {0; 1; 0} v' {0; 0; 1}
 rot matrix:
@@ -314,388 +313,388 @@
 LCDDBaseGeom: rot                    [Element: <rotation/>]
 LCDDBaseGeom: DONE constructing LCDD object module_L1t
 
-		
-
-		*/
-
-		Hep3Vector u = new BasicHep3Vector(1,0,0);
-		Hep3Vector v = new BasicHep3Vector(0,1,0);
-		Hep3Vector w = new BasicHep3Vector(0,0,1);
-		
-		Hep3Vector u_L1 = new BasicHep3Vector(0.99955,    0.030000,      0.0000);
-		Hep3Vector v_L1 = new BasicHep3Vector(0.030000,    -0.99955,      0.0000);
-		Hep3Vector w_L1 = new BasicHep3Vector(0.0000,      0.0000,     -1.0000);
-		
-		
-		
-		org.apache.commons.math3.geometry.euclidean.threed.Vector3D u_3D_L1 = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(u_L1.v());
-		org.apache.commons.math3.geometry.euclidean.threed.Vector3D v_3D_L1 = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(v_L1.v());
-		org.apache.commons.math3.geometry.euclidean.threed.Vector3D w_3D_L1 = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(w_L1.v());
-
-		org.apache.commons.math3.geometry.euclidean.threed.Vector3D u_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(u.v());
-		org.apache.commons.math3.geometry.euclidean.threed.Vector3D v_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(v.v());
-		org.apache.commons.math3.geometry.euclidean.threed.Vector3D w_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(w.v());
-		
-		Hep3Vector euler_angles = TransformationUtils.getCardanAngles(v_L1, w_L1, v, w);
-		
-		//Get the generic rotation
-		org.apache.commons.math3.geometry.euclidean.threed.Rotation r = new org.apache.commons.math3.geometry.euclidean.threed.Rotation(v_3D_L1,w_3D_L1,v_3D, w_3D);
-		//Get the angles
-		double rotations[] = r.getAngles(org.apache.commons.math3.geometry.euclidean.threed.RotationOrder.XYZ);
-		
-		if(_debug) {
-			System.out.println("getEulerAngles gives euler_angles: " + euler_angles.toString());
-			System.out.println("manual          gives euler_angles: (" + rotations[0] + "," + rotations[1] + "," + rotations[2] + ")");
-		}
-			  
-		if((rotations[0]-euler_angles.x())>0.00001 || (rotations[1]-euler_angles.y())>0.00001 || (rotations[2]-euler_angles.z())>0.00001) {
-			//System.("closing the loop in apache rotation didn't work!");
-			//throw new RuntimeException("closing the loop in apache rotation didn't work!");
-		}
-		
-		   
-		
-		
-	     Position pos = new Position(volName + "_position",HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width*1.5*4,0,0);
-	     Rotation rot = new Rotation(volName + "_rotation",rotations[0],rotations[1],rotations[2]);
-	     lcdd.add(pos);
-	     lcdd.add(rot);
-		
-		
-	     PhysVol basePV = new PhysVol(volume, lcdd.pickMotherVolume(this), pos, rot);
-	     if(_debug) {
-	    	 System.out.println("Created physical vomume " + basePV.getName());
-	     }
-		
-	     
-	     
-	     volName = volName + "_sub";
-	     Box boxSub = new Box(volName + "Box", HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width, HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/4.0 , HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/8.0);
-	     lcdd.add(boxSub);
-	     Volume volumeSub = new Volume(volName + "_volume", boxSub, lcdd.getMaterial("Vacuum"));
-	     Position subPos = new Position(volName + "_position",0,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/4.0*2-HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/8.0,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/16.0);
-	     Rotation subRot = new Rotation(volName + "_rotation",0,0,0);
-	     lcdd.add(subPos);
-	     lcdd.add(subRot);
-	     PhysVol subBasePV = new PhysVol(volumeSub, volume, subPos, subRot);
-	     if(_debug) {
-	    	 System.out.println("Created physical vomume " + subBasePV.getName());
-	     }
-		
-	     lcdd.add(volumeSub);
-	     volumeSub.setVisAttributes(lcdd.getVisAttributes("HybridVis"));
-
-	     lcdd.add(volume);
-		
-		
-		
-		
-		}
-		
-	
-		private void makeExample4(LCDD lcdd, SensitiveDetector sens) throws JDOMException {
-		
-		
-		if(_debug) {
-			System.out.println("--- makeExample4 ----");
-			
-		}
-		
-		String volName = "example4";
-		Box box = new Box(volName + "Box", HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width, HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length , HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/4.0);
-		lcdd.add(box);
-		Volume volume = new Volume(volName + "_volume", box, lcdd.getMaterial("Vacuum"));
-	
-		 
-
-		Hep3Vector u = new BasicHep3Vector(1,0,0);
-		Hep3Vector v = new BasicHep3Vector(0,1,0);
-		Hep3Vector w = new BasicHep3Vector(0,0,1);
-	
-		org.apache.commons.math3.geometry.euclidean.threed.Vector3D u_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(u.v());
-		org.apache.commons.math3.geometry.euclidean.threed.Vector3D v_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(v.v());
-		org.apache.commons.math3.geometry.euclidean.threed.Vector3D w_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(w.v());
-		
-		
-		
-		//set up a rotation about the X axis
-	    org.apache.commons.math3.geometry.euclidean.threed.Rotation r1 = new org.apache.commons.math3.geometry.euclidean.threed.Rotation(u_3D, -1.0*Math.PI);
-	     
-	    // find y' and z'
-	    org.apache.commons.math3.geometry.euclidean.threed.Vector3D u_3D_p = r1.applyTo(u_3D);
-	    org.apache.commons.math3.geometry.euclidean.threed.Vector3D v_3D_p = r1.applyTo(v_3D);
-	    org.apache.commons.math3.geometry.euclidean.threed.Vector3D w_3D_p = r1.applyTo(w_3D);
-	    
-	    
-	    double [] rotations = r1.getAngles(org.apache.commons.math3.geometry.euclidean.threed.RotationOrder.XYZ);
-	    
-	    
-	    if(_debug) {
-	    	System.out.println("u_3D:       " + u_3D.toString());
-			System.out.println("v_3D:       " + v_3D.toString());
-			System.out.println("w_3D:       " + w_3D.toString());
-			r1.toString();
-			System.out.println("u_3D_p: " + u_3D_p.toString());
-			System.out.println("v_3D_p: " + v_3D_p.toString());
-			System.out.println("w_3D_p: " + w_3D_p.toString());
-			
-			System.out.println("gives euler_angles: (" + rotations[0] + "," + rotations[1] + "," + rotations[2] + ")");
-
-	    }
-	    
-	 	 
-		
-		//apply to unit vector
-		
-	     Position pos = new Position(volName + "_position",HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width*1.5*2,0,0);
-	     Rotation rot = new Rotation(volName + "_rotation",rotations[0],rotations[1],rotations[2]);
-	     lcdd.add(pos);
-	     lcdd.add(rot);
-		
-		
-	     PhysVol basePV = new PhysVol(volume, lcdd.pickMotherVolume(this), pos, rot);
-	     if(_debug) {
-	    	 System.out.println("Created physical vomume " + basePV.getName());
-	     }
-		
-	     
-	     
-	     
-	     volName = volName + "_sub";
-	     Box boxSub = new Box(volName + "Box", HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width, HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/4.0 , HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/8.0);
-	     lcdd.add(boxSub);
-	     Volume volumeSub = new Volume(volName + "_volume", boxSub, lcdd.getMaterial("Vacuum"));
-	     Position subPos = new Position(volName + "_position",0,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/4.0*2-HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/8.0,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/16.0);
-	     Rotation subRot = new Rotation(volName + "_rotation",0,0,0);
-	     lcdd.add(subPos);
-	     lcdd.add(subRot);
-	     PhysVol subBasePV = new PhysVol(volumeSub, volume, subPos, subRot);
-	     if(_debug) {
-	    	 System.out.println("Created physical vomume " + subBasePV.getName());
-	     }
-		
-	     lcdd.add(volumeSub);
-	     volumeSub.setVisAttributes(lcdd.getVisAttributes("SensorVis"));
-
-	     lcdd.add(volume);
-		
-		
-		
-		
-		}
-		
-	
-		private void makeExample5(LCDD lcdd, SensitiveDetector sens) throws JDOMException {
-			
-			
-			if(_debug) {
-				System.out.println("--- makeExample5 ----");
-				
-			}
-			
-			String volName = "example5";
-			Box box = new Box(volName + "Box", HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width, HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length , HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/4.0);
-			lcdd.add(box);
-			Volume volume = new Volume(volName + "_volume", box, lcdd.getMaterial("Vacuum"));
-		
-			 
-
-			Hep3Vector u = new BasicHep3Vector(1,0,0);
-			Hep3Vector v = new BasicHep3Vector(0,1,0);
-			Hep3Vector w = new BasicHep3Vector(0,0,1);
-		
-			org.apache.commons.math3.geometry.euclidean.threed.Vector3D u_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(u.v());
-			org.apache.commons.math3.geometry.euclidean.threed.Vector3D v_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(v.v());
-			org.apache.commons.math3.geometry.euclidean.threed.Vector3D w_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(w.v());
-			
-			
-			
-			//set up a rotation about the X axis
-		    org.apache.commons.math3.geometry.euclidean.threed.Rotation r1 = new org.apache.commons.math3.geometry.euclidean.threed.Rotation(u_3D, -1.0*Math.PI);
-		     
-		    // find y' and z'
-		    org.apache.commons.math3.geometry.euclidean.threed.Vector3D u_3D_p = r1.applyTo(u_3D);
-		    org.apache.commons.math3.geometry.euclidean.threed.Vector3D v_3D_p = r1.applyTo(v_3D);
-		    org.apache.commons.math3.geometry.euclidean.threed.Vector3D w_3D_p = r1.applyTo(w_3D);
-		    
-		    // set up a rotation about the Z axis
-		    org.apache.commons.math3.geometry.euclidean.threed.Rotation r3 = new org.apache.commons.math3.geometry.euclidean.threed.Rotation(w_3D_p, -0.03);
-		    org.apache.commons.math3.geometry.euclidean.threed.Rotation r13 = r3.applyTo(r1);
-		    
-		    
-		    // find y' and z'
-		    org.apache.commons.math3.geometry.euclidean.threed.Vector3D u_3D_pp = r13.applyTo(u_3D);
-		    org.apache.commons.math3.geometry.euclidean.threed.Vector3D v_3D_pp = r13.applyTo(v_3D);
-		    org.apache.commons.math3.geometry.euclidean.threed.Vector3D w_3D_pp = r13.applyTo(w_3D);
-		    //org.apache.commons.math3.geometry.euclidean.threed.Vector3D u_3D_pp = r13.applyTo(u_3D_p);
-		    //org.apache.commons.math3.geometry.euclidean.threed.Vector3D v_3D_pp = r13.applyTo(v_3D_p);
-		    //org.apache.commons.math3.geometry.euclidean.threed.Vector3D w_3D_pp = r13.applyTo(w_3D_p);
-		    
-		    double [] rotations = r13.getAngles(org.apache.commons.math3.geometry.euclidean.threed.RotationOrder.XYZ);
-		    
-		    
-		    if(_debug) {
-		    	System.out.println("u_3D:       " + u_3D.toString());
-				System.out.println("v_3D:       " + v_3D.toString());
-				System.out.println("w_3D:       " + w_3D.toString());
-				r1.toString();
-				System.out.println("u_3D_p: " + u_3D_p.toString());
-				System.out.println("v_3D_p: " + v_3D_p.toString());
-				System.out.println("w_3D_p: " + w_3D_p.toString());
-				r13.toString();
-				System.out.println("u_3D_pp: " + u_3D_pp.toString());
-				System.out.println("v_3D_pp: " + v_3D_pp.toString());
-				System.out.println("w_3D_pp: " + w_3D_pp.toString());
-				System.out.println("gives euler_angles: (" + rotations[0] + "," + rotations[1] + "," + rotations[2] + ")");
-
-		    }
-		    
-		 	 
-			
-			//apply to unit vector
-			
-		     Position pos = new Position(volName + "_position",HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width*1.5*3,0,0);
-		     Rotation rot = new Rotation(volName + "_rotation",rotations[0],rotations[1],rotations[2]);
-		     lcdd.add(pos);
-		     lcdd.add(rot);
-			
-			
-		     PhysVol basePV = new PhysVol(volume, lcdd.pickMotherVolume(this), pos, rot);
-		     if(_debug) {
-		    	 System.out.println("Created physical vomume " + basePV.getName());
-		     }
-			
-		     
-		     volName = volName + "_sub";
-		     Box boxSub = new Box(volName + "Box", HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width, HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/4.0 , HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/8.0);
-		     lcdd.add(boxSub);
-		     Volume volumeSub = new Volume(volName + "_volume", boxSub, lcdd.getMaterial("Vacuum"));
-		     Position subPos = new Position(volName + "_position",0,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/4.0*2-HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/8.0,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/16.0);
-		     Rotation subRot = new Rotation(volName + "_rotation",0,0,0);
-		     lcdd.add(subPos);
-		     lcdd.add(subRot);
-		     PhysVol subBasePV = new PhysVol(volumeSub, volume, subPos, subRot);
-		     if(_debug) {
-		    	 System.out.println("Created physical vomume " + subBasePV.getName());
-		     }
-			
-		     lcdd.add(volumeSub);
-		     volumeSub.setVisAttributes(lcdd.getVisAttributes("SensorVis"));
-
-		     lcdd.add(volume);
-			
-			
-			
-			
-			}
-			
-		
-		
-
-		private void makeExample5b(LCDD lcdd, SensitiveDetector sens) throws JDOMException {
-			
-			
-			if(_debug) {
-				System.out.println("--- makeExample5b ----");
-				
-			}
-			
-			String volName = "example5b";
-			Box box = new Box(volName + "Box", HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width, HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length , HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/4.0);
-			lcdd.add(box);
-			Volume volume = new Volume(volName + "_volume", box, lcdd.getMaterial("Vacuum"));
-		
-			 
-
-			Hep3Vector u = new BasicHep3Vector(1,0,0);
-			Hep3Vector v = new BasicHep3Vector(0,1,0);
-			Hep3Vector w = new BasicHep3Vector(0,0,1);
-		
-			org.apache.commons.math3.geometry.euclidean.threed.Vector3D u_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(u.v());
-			org.apache.commons.math3.geometry.euclidean.threed.Vector3D v_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(v.v());
-			org.apache.commons.math3.geometry.euclidean.threed.Vector3D w_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(w.v());
-			
-			
-			 // set up a rotation about the Z axis
-		    org.apache.commons.math3.geometry.euclidean.threed.Rotation r3 = new org.apache.commons.math3.geometry.euclidean.threed.Rotation(w_3D, -0.03);
-		     
-		    // find y' and z'
-		    org.apache.commons.math3.geometry.euclidean.threed.Vector3D u_3D_p = r3.applyTo(u_3D);
-		    org.apache.commons.math3.geometry.euclidean.threed.Vector3D v_3D_p = r3.applyTo(v_3D);
-		    org.apache.commons.math3.geometry.euclidean.threed.Vector3D w_3D_p = r3.applyTo(w_3D);
-		    
-		   
-		    
-		    double [] rotations = r3.getAngles(org.apache.commons.math3.geometry.euclidean.threed.RotationOrder.XYZ);
-		    
-		    
-		    if(_debug) {
-		    	System.out.println("u_3D:       " + u_3D.toString());
-				System.out.println("v_3D:       " + v_3D.toString());
-				System.out.println("w_3D:       " + w_3D.toString());
-				r3.toString();
-				System.out.println("u_3D_p: " + u_3D_p.toString());
-				System.out.println("v_3D_p: " + v_3D_p.toString());
-				System.out.println("w_3D_p: " + w_3D_p.toString());
-				System.out.println("gives euler_angles: (" + rotations[0] + "," + rotations[1] + "," + rotations[2] + ")");
-
-		    }
-		    
-		 	 
-			
-			//apply to unit vector
-			
-		     Position pos = new Position(volName + "_position",HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width*1.5*3,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length*-1.5,0);
-		     Rotation rot = new Rotation(volName + "_rotation",rotations[0],rotations[1],rotations[2]);
-		     lcdd.add(pos);
-		     lcdd.add(rot);
-			
-			
-		     PhysVol basePV = new PhysVol(volume, lcdd.pickMotherVolume(this), pos, rot);
-		     if(_debug) {
-		    	 System.out.println("Created physical vomume " + basePV.getName());
-		     }
-			
-		     
-		     volName = volName + "_sub";
-		     Box boxSub = new Box(volName + "Box", HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width, HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/4.0 , HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/8.0);
-		     lcdd.add(boxSub);
-		     Volume volumeSub = new Volume(volName + "_volume", boxSub, lcdd.getMaterial("Vacuum"));
-		     Position subPos = new Position(volName + "_position",0,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/4.0*2-HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/8.0,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/16.0);
-		     Rotation subRot = new Rotation(volName + "_rotation",0,0,0);
-		     lcdd.add(subPos);
-		     lcdd.add(subRot);
-		     PhysVol subBasePV = new PhysVol(volumeSub, volume, subPos, subRot);
-		     if(_debug) {
-		    	 System.out.println("Created physical vomume " + subBasePV.getName());
-		     }
-			
-		     lcdd.add(volumeSub);
-		     volumeSub.setVisAttributes(lcdd.getVisAttributes("SensorVis"));
-
-		     lcdd.add(volume);
-			
-			
-			
-			
-			}
-			
-		private void makeExample3b(LCDD lcdd, SensitiveDetector sens) throws JDOMException {
-			
-			
-			if(_debug) {
-				System.out.println("--- makeExample3b ----");
-				
-			}
-			
-			String volName = "example3b";
-			Box box = new Box(volName + "Box", HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width, HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length , HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/4.0);
-			lcdd.add(box);
-			Volume volume = new Volume(volName + "_volume", box, lcdd.getMaterial("Vacuum"));
-			
-			/*
-			
-			TestRunModuleL13: survey positions
+        
+
+        */
+
+        Hep3Vector u = new BasicHep3Vector(1,0,0);
+        Hep3Vector v = new BasicHep3Vector(0,1,0);
+        Hep3Vector w = new BasicHep3Vector(0,0,1);
+        
+        Hep3Vector u_L1 = new BasicHep3Vector(0.99955,    0.030000,      0.0000);
+        Hep3Vector v_L1 = new BasicHep3Vector(0.030000,    -0.99955,      0.0000);
+        Hep3Vector w_L1 = new BasicHep3Vector(0.0000,      0.0000,     -1.0000);
+        
+        
+        
+        org.apache.commons.math3.geometry.euclidean.threed.Vector3D u_3D_L1 = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(u_L1.v());
+        org.apache.commons.math3.geometry.euclidean.threed.Vector3D v_3D_L1 = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(v_L1.v());
+        org.apache.commons.math3.geometry.euclidean.threed.Vector3D w_3D_L1 = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(w_L1.v());
+
+        org.apache.commons.math3.geometry.euclidean.threed.Vector3D u_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(u.v());
+        org.apache.commons.math3.geometry.euclidean.threed.Vector3D v_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(v.v());
+        org.apache.commons.math3.geometry.euclidean.threed.Vector3D w_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(w.v());
+        
+        Hep3Vector euler_angles = TransformationUtils.getCardanAngles(v_L1, w_L1, v, w);
+        
+        //Get the generic rotation
+        org.apache.commons.math3.geometry.euclidean.threed.Rotation r = new org.apache.commons.math3.geometry.euclidean.threed.Rotation(v_3D_L1,w_3D_L1,v_3D, w_3D);
+        //Get the angles
+        double rotations[] = r.getAngles(org.apache.commons.math3.geometry.euclidean.threed.RotationOrder.XYZ);
+        
+        if(_debug) {
+            System.out.println("getEulerAngles gives euler_angles: " + euler_angles.toString());
+            System.out.println("manual          gives euler_angles: (" + rotations[0] + "," + rotations[1] + "," + rotations[2] + ")");
+        }
+              
+        if((rotations[0]-euler_angles.x())>0.00001 || (rotations[1]-euler_angles.y())>0.00001 || (rotations[2]-euler_angles.z())>0.00001) {
+            //System.("closing the loop in apache rotation didn't work!");
+            //throw new RuntimeException("closing the loop in apache rotation didn't work!");
+        }
+        
+           
+        
+        
+         Position pos = new Position(volName + "_position",HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width*1.5*4,0,0);
+         Rotation rot = new Rotation(volName + "_rotation",rotations[0],rotations[1],rotations[2]);
+         lcdd.add(pos);
+         lcdd.add(rot);
+        
+        
+         PhysVol basePV = new PhysVol(volume, lcdd.pickMotherVolume(this), pos, rot);
+         if(_debug) {
+             System.out.println("Created physical vomume " + basePV.getName());
+         }
+        
+         
+         
+         volName = volName + "_sub";
+         Box boxSub = new Box(volName + "Box", HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width, HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/4.0 , HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/8.0);
+         lcdd.add(boxSub);
+         Volume volumeSub = new Volume(volName + "_volume", boxSub, lcdd.getMaterial("Vacuum"));
+         Position subPos = new Position(volName + "_position",0,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/4.0*2-HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/8.0,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/16.0);
+         Rotation subRot = new Rotation(volName + "_rotation",0,0,0);
+         lcdd.add(subPos);
+         lcdd.add(subRot);
+         PhysVol subBasePV = new PhysVol(volumeSub, volume, subPos, subRot);
+         if(_debug) {
+             System.out.println("Created physical vomume " + subBasePV.getName());
+         }
+        
+         lcdd.add(volumeSub);
+         volumeSub.setVisAttributes(lcdd.getVisAttributes("HybridVis"));
+
+         lcdd.add(volume);
+        
+        
+        
+        
+        }
+        
+    
+        private void makeExample4(LCDD lcdd, SensitiveDetector sens) throws JDOMException {
+        
+        
+        if(_debug) {
+            System.out.println("--- makeExample4 ----");
+            
+        }
+        
+        String volName = "example4";
+        Box box = new Box(volName + "Box", HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width, HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length , HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/4.0);
+        lcdd.add(box);
+        Volume volume = new Volume(volName + "_volume", box, lcdd.getMaterial("Vacuum"));
+    
+         
+
+        Hep3Vector u = new BasicHep3Vector(1,0,0);
+        Hep3Vector v = new BasicHep3Vector(0,1,0);
+        Hep3Vector w = new BasicHep3Vector(0,0,1);
+    
+        org.apache.commons.math3.geometry.euclidean.threed.Vector3D u_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(u.v());
+        org.apache.commons.math3.geometry.euclidean.threed.Vector3D v_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(v.v());
+        org.apache.commons.math3.geometry.euclidean.threed.Vector3D w_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(w.v());
+        
+        
+        
+        //set up a rotation about the X axis
+        org.apache.commons.math3.geometry.euclidean.threed.Rotation r1 = new org.apache.commons.math3.geometry.euclidean.threed.Rotation(u_3D, -1.0*Math.PI);
+         
+        // find y' and z'
+        org.apache.commons.math3.geometry.euclidean.threed.Vector3D u_3D_p = r1.applyTo(u_3D);
+        org.apache.commons.math3.geometry.euclidean.threed.Vector3D v_3D_p = r1.applyTo(v_3D);
+        org.apache.commons.math3.geometry.euclidean.threed.Vector3D w_3D_p = r1.applyTo(w_3D);
+        
+        
+        double [] rotations = r1.getAngles(org.apache.commons.math3.geometry.euclidean.threed.RotationOrder.XYZ);
+        
+        
+        if(_debug) {
+            System.out.println("u_3D:       " + u_3D.toString());
+            System.out.println("v_3D:       " + v_3D.toString());
+            System.out.println("w_3D:       " + w_3D.toString());
+            r1.toString();
+            System.out.println("u_3D_p: " + u_3D_p.toString());
+            System.out.println("v_3D_p: " + v_3D_p.toString());
+            System.out.println("w_3D_p: " + w_3D_p.toString());
+            
+            System.out.println("gives euler_angles: (" + rotations[0] + "," + rotations[1] + "," + rotations[2] + ")");
+
+        }
+        
+         
+        
+        //apply to unit vector
+        
+         Position pos = new Position(volName + "_position",HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width*1.5*2,0,0);
+         Rotation rot = new Rotation(volName + "_rotation",rotations[0],rotations[1],rotations[2]);
+         lcdd.add(pos);
+         lcdd.add(rot);
+        
+        
+         PhysVol basePV = new PhysVol(volume, lcdd.pickMotherVolume(this), pos, rot);
+         if(_debug) {
+             System.out.println("Created physical vomume " + basePV.getName());
+         }
+        
+         
+         
+         
+         volName = volName + "_sub";
+         Box boxSub = new Box(volName + "Box", HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width, HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/4.0 , HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/8.0);
+         lcdd.add(boxSub);
+         Volume volumeSub = new Volume(volName + "_volume", boxSub, lcdd.getMaterial("Vacuum"));
+         Position subPos = new Position(volName + "_position",0,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/4.0*2-HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/8.0,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/16.0);
+         Rotation subRot = new Rotation(volName + "_rotation",0,0,0);
+         lcdd.add(subPos);
+         lcdd.add(subRot);
+         PhysVol subBasePV = new PhysVol(volumeSub, volume, subPos, subRot);
+         if(_debug) {
+             System.out.println("Created physical vomume " + subBasePV.getName());
+         }
+        
+         lcdd.add(volumeSub);
+         volumeSub.setVisAttributes(lcdd.getVisAttributes("SensorVis"));
+
+         lcdd.add(volume);
+        
+        
+        
+        
+        }
+        
+    
+        private void makeExample5(LCDD lcdd, SensitiveDetector sens) throws JDOMException {
+            
+            
+            if(_debug) {
+                System.out.println("--- makeExample5 ----");
+                
+            }
+            
+            String volName = "example5";
+            Box box = new Box(volName + "Box", HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width, HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length , HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/4.0);
+            lcdd.add(box);
+            Volume volume = new Volume(volName + "_volume", box, lcdd.getMaterial("Vacuum"));
+        
+             
+
+            Hep3Vector u = new BasicHep3Vector(1,0,0);
+            Hep3Vector v = new BasicHep3Vector(0,1,0);
+            Hep3Vector w = new BasicHep3Vector(0,0,1);
+        
+            org.apache.commons.math3.geometry.euclidean.threed.Vector3D u_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(u.v());
+            org.apache.commons.math3.geometry.euclidean.threed.Vector3D v_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(v.v());
+            org.apache.commons.math3.geometry.euclidean.threed.Vector3D w_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(w.v());
+            
+            
+            
+            //set up a rotation about the X axis
+            org.apache.commons.math3.geometry.euclidean.threed.Rotation r1 = new org.apache.commons.math3.geometry.euclidean.threed.Rotation(u_3D, -1.0*Math.PI);
+             
+            // find y' and z'
+            org.apache.commons.math3.geometry.euclidean.threed.Vector3D u_3D_p = r1.applyTo(u_3D);
+            org.apache.commons.math3.geometry.euclidean.threed.Vector3D v_3D_p = r1.applyTo(v_3D);
+            org.apache.commons.math3.geometry.euclidean.threed.Vector3D w_3D_p = r1.applyTo(w_3D);
+            
+            // set up a rotation about the Z axis
+            org.apache.commons.math3.geometry.euclidean.threed.Rotation r3 = new org.apache.commons.math3.geometry.euclidean.threed.Rotation(w_3D_p, -0.03);
+            org.apache.commons.math3.geometry.euclidean.threed.Rotation r13 = r3.applyTo(r1);
+            
+            
+            // find y' and z'
+            org.apache.commons.math3.geometry.euclidean.threed.Vector3D u_3D_pp = r13.applyTo(u_3D);
+            org.apache.commons.math3.geometry.euclidean.threed.Vector3D v_3D_pp = r13.applyTo(v_3D);
+            org.apache.commons.math3.geometry.euclidean.threed.Vector3D w_3D_pp = r13.applyTo(w_3D);
+            //org.apache.commons.math3.geometry.euclidean.threed.Vector3D u_3D_pp = r13.applyTo(u_3D_p);
+            //org.apache.commons.math3.geometry.euclidean.threed.Vector3D v_3D_pp = r13.applyTo(v_3D_p);
+            //org.apache.commons.math3.geometry.euclidean.threed.Vector3D w_3D_pp = r13.applyTo(w_3D_p);
+            
+            double [] rotations = r13.getAngles(org.apache.commons.math3.geometry.euclidean.threed.RotationOrder.XYZ);
+            
+            
+            if(_debug) {
+                System.out.println("u_3D:       " + u_3D.toString());
+                System.out.println("v_3D:       " + v_3D.toString());
+                System.out.println("w_3D:       " + w_3D.toString());
+                r1.toString();
+                System.out.println("u_3D_p: " + u_3D_p.toString());
+                System.out.println("v_3D_p: " + v_3D_p.toString());
+                System.out.println("w_3D_p: " + w_3D_p.toString());
+                r13.toString();
+                System.out.println("u_3D_pp: " + u_3D_pp.toString());
+                System.out.println("v_3D_pp: " + v_3D_pp.toString());
+                System.out.println("w_3D_pp: " + w_3D_pp.toString());
+                System.out.println("gives euler_angles: (" + rotations[0] + "," + rotations[1] + "," + rotations[2] + ")");
+
+            }
+            
+             
+            
+            //apply to unit vector
+            
+             Position pos = new Position(volName + "_position",HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width*1.5*3,0,0);
+             Rotation rot = new Rotation(volName + "_rotation",rotations[0],rotations[1],rotations[2]);
+             lcdd.add(pos);
+             lcdd.add(rot);
+            
+            
+             PhysVol basePV = new PhysVol(volume, lcdd.pickMotherVolume(this), pos, rot);
+             if(_debug) {
+                 System.out.println("Created physical vomume " + basePV.getName());
+             }
+            
+             
+             volName = volName + "_sub";
+             Box boxSub = new Box(volName + "Box", HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width, HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/4.0 , HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/8.0);
+             lcdd.add(boxSub);
+             Volume volumeSub = new Volume(volName + "_volume", boxSub, lcdd.getMaterial("Vacuum"));
+             Position subPos = new Position(volName + "_position",0,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/4.0*2-HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/8.0,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/16.0);
+             Rotation subRot = new Rotation(volName + "_rotation",0,0,0);
+             lcdd.add(subPos);
+             lcdd.add(subRot);
+             PhysVol subBasePV = new PhysVol(volumeSub, volume, subPos, subRot);
+             if(_debug) {
+                 System.out.println("Created physical vomume " + subBasePV.getName());
+             }
+            
+             lcdd.add(volumeSub);
+             volumeSub.setVisAttributes(lcdd.getVisAttributes("SensorVis"));
+
+             lcdd.add(volume);
+            
+            
+            
+            
+            }
+            
+        
+        
+
+        private void makeExample5b(LCDD lcdd, SensitiveDetector sens) throws JDOMException {
+            
+            
+            if(_debug) {
+                System.out.println("--- makeExample5b ----");
+                
+            }
+            
+            String volName = "example5b";
+            Box box = new Box(volName + "Box", HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width, HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length , HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/4.0);
+            lcdd.add(box);
+            Volume volume = new Volume(volName + "_volume", box, lcdd.getMaterial("Vacuum"));
+        
+             
+
+            Hep3Vector u = new BasicHep3Vector(1,0,0);
+            Hep3Vector v = new BasicHep3Vector(0,1,0);
+            Hep3Vector w = new BasicHep3Vector(0,0,1);
+        
+            org.apache.commons.math3.geometry.euclidean.threed.Vector3D u_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(u.v());
+            org.apache.commons.math3.geometry.euclidean.threed.Vector3D v_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(v.v());
+            org.apache.commons.math3.geometry.euclidean.threed.Vector3D w_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(w.v());
+            
+            
+             // set up a rotation about the Z axis
+            org.apache.commons.math3.geometry.euclidean.threed.Rotation r3 = new org.apache.commons.math3.geometry.euclidean.threed.Rotation(w_3D, -0.03);
+             
+            // find y' and z'
+            org.apache.commons.math3.geometry.euclidean.threed.Vector3D u_3D_p = r3.applyTo(u_3D);
+            org.apache.commons.math3.geometry.euclidean.threed.Vector3D v_3D_p = r3.applyTo(v_3D);
+            org.apache.commons.math3.geometry.euclidean.threed.Vector3D w_3D_p = r3.applyTo(w_3D);
+            
+           
+            
+            double [] rotations = r3.getAngles(org.apache.commons.math3.geometry.euclidean.threed.RotationOrder.XYZ);
+            
+            
+            if(_debug) {
+                System.out.println("u_3D:       " + u_3D.toString());
+                System.out.println("v_3D:       " + v_3D.toString());
+                System.out.println("w_3D:       " + w_3D.toString());
+                r3.toString();
+                System.out.println("u_3D_p: " + u_3D_p.toString());
+                System.out.println("v_3D_p: " + v_3D_p.toString());
+                System.out.println("w_3D_p: " + w_3D_p.toString());
+                System.out.println("gives euler_angles: (" + rotations[0] + "," + rotations[1] + "," + rotations[2] + ")");
+
+            }
+            
+             
+            
+            //apply to unit vector
+            
+             Position pos = new Position(volName + "_position",HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width*1.5*3,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length*-1.5,0);
+             Rotation rot = new Rotation(volName + "_rotation",rotations[0],rotations[1],rotations[2]);
+             lcdd.add(pos);
+             lcdd.add(rot);
+            
+            
+             PhysVol basePV = new PhysVol(volume, lcdd.pickMotherVolume(this), pos, rot);
+             if(_debug) {
+                 System.out.println("Created physical vomume " + basePV.getName());
+             }
+            
+             
+             volName = volName + "_sub";
+             Box boxSub = new Box(volName + "Box", HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width, HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/4.0 , HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/8.0);
+             lcdd.add(boxSub);
+             Volume volumeSub = new Volume(volName + "_volume", boxSub, lcdd.getMaterial("Vacuum"));
+             Position subPos = new Position(volName + "_position",0,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/4.0*2-HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/8.0,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/16.0);
+             Rotation subRot = new Rotation(volName + "_rotation",0,0,0);
+             lcdd.add(subPos);
+             lcdd.add(subRot);
+             PhysVol subBasePV = new PhysVol(volumeSub, volume, subPos, subRot);
+             if(_debug) {
+                 System.out.println("Created physical vomume " + subBasePV.getName());
+             }
+            
+             lcdd.add(volumeSub);
+             volumeSub.setVisAttributes(lcdd.getVisAttributes("SensorVis"));
+
+             lcdd.add(volume);
+            
+            
+            
+            
+            }
+            
+        private void makeExample3b(LCDD lcdd, SensitiveDetector sens) throws JDOMException {
+            
+            
+            if(_debug) {
+                System.out.println("--- makeExample3b ----");
+                
+            }
+            
+            String volName = "example3b";
+            Box box = new Box(volName + "Box", HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width, HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length , HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/4.0);
+            lcdd.add(box);
+            Volume volume = new Volume(volName + "_volume", box, lcdd.getMaterial("Vacuum"));
+            
+            /*
+            
+            TestRunModuleL13: survey positions
 Survey pos for module_L1b:
 ballPos   [      25.000,      661.10,      4.3500]
 veePos    [      95.000,      661.10,      4.3500]
@@ -732,11 +731,11 @@
 
 ]
 
-			
-			
-			
-			
-			LCDDBaseGeom: set position and rotation for volume module_L1b
+            
+            
+            
+            
+            LCDDBaseGeom: set position and rotation for volume module_L1b
 getEulerAngles: u [   -0.030000,     0.99955,      0.0000] v[      0.0000,      0.0000,      1.0000] -> [      0.0000,      1.0000,      0.0000] [      0.0000,      0.0000,      1.0000]
 Input: u {-0.03; 1; 0} v {0; 0; 1} u' {0; 1; 0} v' {0; 0; 1}
 rot matrix:
@@ -753,484 +752,484 @@
 LCDDBaseGeom: rot                    [Element: <rotation/>]
 LCDDBaseGeom: DONE constructing LCDD object module_L1b
 
-		
-
-			
-
-			*/
-
-			Hep3Vector u = new BasicHep3Vector(1,0,0);
-			Hep3Vector v = new BasicHep3Vector(0,1,0);
-			Hep3Vector w = new BasicHep3Vector(0,0,1);
-			
-			Hep3Vector u_L1 = new BasicHep3Vector(0.99955,    0.030000,      0.0000);
-			Hep3Vector v_L1 = new BasicHep3Vector(-0.030000,     0.99955,      0.0000);
-			Hep3Vector w_L1 = new BasicHep3Vector(0.0000,      0.0000,     1.0000);
-			
-			
-			
-			org.apache.commons.math3.geometry.euclidean.threed.Vector3D u_3D_L1 = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(u_L1.v());
-			org.apache.commons.math3.geometry.euclidean.threed.Vector3D v_3D_L1 = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(v_L1.v());
-			org.apache.commons.math3.geometry.euclidean.threed.Vector3D w_3D_L1 = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(w_L1.v());
-
-			org.apache.commons.math3.geometry.euclidean.threed.Vector3D u_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(u.v());
-			org.apache.commons.math3.geometry.euclidean.threed.Vector3D v_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(v.v());
-			org.apache.commons.math3.geometry.euclidean.threed.Vector3D w_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(w.v());
-			
-			Hep3Vector euler_angles = TransformationUtils.getCardanAngles(v_L1, w_L1, v, w);
-			
-			//Get the generic rotation
-			org.apache.commons.math3.geometry.euclidean.threed.Rotation r = new org.apache.commons.math3.geometry.euclidean.threed.Rotation(v_3D_L1,w_3D_L1,v_3D, w_3D);
-			//Get the angles
-			double rotations[] = r.getAngles(org.apache.commons.math3.geometry.euclidean.threed.RotationOrder.XYZ);
-			
-			if(_debug) {
-				System.out.println("getEulerAngles gives euler_angles: " + euler_angles.toString());
-				System.out.println("manual          gives euler_angles: (" + rotations[0] + "," + rotations[1] + "," + rotations[2] + ")");
-			}
-				  
-			if((rotations[0]-euler_angles.x())>0.00001 || (rotations[1]-euler_angles.y())>0.00001 || (rotations[2]-euler_angles.z())>0.00001) {
-				//throw new RuntimeException("closing the loop in apache rotation didn't work!");
-			}
-			
-			   
-			
-			
-		     Position pos = new Position(volName + "_position",HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width*1.5*4,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length*-1.5,0);
-		     Rotation rot = new Rotation(volName + "_rotation",rotations[0],rotations[1],rotations[2]);
-		     lcdd.add(pos);
-		     lcdd.add(rot);
-			
-			
-		     PhysVol basePV = new PhysVol(volume, lcdd.pickMotherVolume(this), pos, rot);
-		     if(_debug) {
-		    	 System.out.println("Created physical vomume " + basePV.getName());
-		     }
-			
-		     
-		     
-		     volName = volName + "_sub";
-		     Box boxSub = new Box(volName + "Box", HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width, HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/4.0 , HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/8.0);
-		     lcdd.add(boxSub);
-		     Volume volumeSub = new Volume(volName + "_volume", boxSub, lcdd.getMaterial("Vacuum"));
-		     Position subPos = new Position(volName + "_position",0,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/4.0*2-HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/8.0,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/16.0);
-		     Rotation subRot = new Rotation(volName + "_rotation",0,0,0);
-		     lcdd.add(subPos);
-		     lcdd.add(subRot);
-		     PhysVol subBasePV = new PhysVol(volumeSub, volume, subPos, subRot);
-		     if(_debug) {
-		    	 System.out.println("Created physical vomume " + subBasePV.getName());
-		     }
-			
-		     lcdd.add(volumeSub);
-		     volumeSub.setVisAttributes(lcdd.getVisAttributes("HybridVis"));
-
-		     lcdd.add(volume);
-			
-			
-			
-			
-			}
-			
-
-		private void makeExample6(LCDD lcdd, SensitiveDetector sens) throws JDOMException {
-		
-		
-		if(_debug) {
-			System.out.println("--- makeExample6 ----");
-			
-		}
-		
-		String volName = "example6";
-		Box box = new Box(volName + "Box", HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width, HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length , HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/4.0);
-		lcdd.add(box);
-		Volume volume = new Volume(volName + "_volume", box, lcdd.getMaterial("Vacuum"));
-	    
-	    double [] rotations = {-0.5*Math.PI,0,0};
-	    
-	    
-	    if(_debug) {
-	
-			
-			System.out.println("manual set lcdd angles: (" + rotations[0] + "," + rotations[1] + "," + rotations[2] + ")");
-
-	    }
-	    
-	 	 
-		
-		//apply to unit vector
-		
-	     Position pos = new Position(volName + "_position",HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width*1.5*-2,0,0);
-	     Rotation rot = new Rotation(volName + "_rotation",rotations[0],rotations[1],rotations[2]);
-	     lcdd.add(pos);
-	     lcdd.add(rot);
-		
-		
-	     PhysVol basePV = new PhysVol(volume, lcdd.pickMotherVolume(this), pos, rot);
-	     if(_debug) {
-	    	 System.out.println("Created physical vomume " + basePV.getName());
-	     }
-		
-	     
-	     
-	     
-	     volName = volName + "_sub";
-	     Box boxSub = new Box(volName + "Box", HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width, HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/4.0 , HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/8.0);
-	     lcdd.add(boxSub);
-	     Volume volumeSub = new Volume(volName + "_volume", boxSub, lcdd.getMaterial("Vacuum"));
-	     Position subPos = new Position(volName + "_position",0,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/4.0*2-HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/8.0,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/16.0);
-	     Rotation subRot = new Rotation(volName + "_rotation",0,0,0);
-	     lcdd.add(subPos);
-	     lcdd.add(subRot);
-	     PhysVol subBasePV = new PhysVol(volumeSub, volume, subPos, subRot);
-	     if(_debug) {
-	    	 System.out.println("Created physical vomume " + subBasePV.getName());
-	     }
-		
-	     lcdd.add(volumeSub);
-	     volumeSub.setVisAttributes(lcdd.getVisAttributes("SensorVis"));
-
-	     lcdd.add(volume);
-		
-		
-		
-		
-		}
-		
-		
-		
-		private void makeExample66(LCDD lcdd, SensitiveDetector sens) throws JDOMException {
-			
-			
-			if(_debug) {
-				System.out.println("--- makeExample66 ----");
-				
-			}
-			
-			String volName = "example66";
-			Box box = new Box(volName + "Box", HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width, HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length , HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/4.0);
-			lcdd.add(box);
-			Volume volume = new Volume(volName + "_volume", box, lcdd.getMaterial("Vacuum"));
-		
-			 
-
-			Hep3Vector u = new BasicHep3Vector(1,0,0);
-			Hep3Vector v = new BasicHep3Vector(0,1,0);
-			Hep3Vector w = new BasicHep3Vector(0,0,1);
-		
-			org.apache.commons.math3.geometry.euclidean.threed.Vector3D u_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(u.v());
-			org.apache.commons.math3.geometry.euclidean.threed.Vector3D v_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(v.v());
-			org.apache.commons.math3.geometry.euclidean.threed.Vector3D w_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(w.v());
-			
-			
-			
-			//set up a rotation about the X axis
-		    org.apache.commons.math3.geometry.euclidean.threed.Rotation r1 = new org.apache.commons.math3.geometry.euclidean.threed.Rotation(u_3D, -0.5*Math.PI);
-		     
-		    // find y' and z'
-		    org.apache.commons.math3.geometry.euclidean.threed.Vector3D u_3D_p = r1.applyTo(u_3D);
-		    org.apache.commons.math3.geometry.euclidean.threed.Vector3D v_3D_p = r1.applyTo(v_3D);
-		    org.apache.commons.math3.geometry.euclidean.threed.Vector3D w_3D_p = r1.applyTo(w_3D);
-		    
-		    
-		    double [] rotations = r1.getAngles(org.apache.commons.math3.geometry.euclidean.threed.RotationOrder.XYZ);
-		    
-		    
-		    if(_debug) {
-		    	System.out.println("u_3D:       " + u_3D.toString());
-				System.out.println("v_3D:       " + v_3D.toString());
-				System.out.println("w_3D:       " + w_3D.toString());
-				r1.toString();
-				System.out.println("u_3D_p: " + u_3D_p.toString());
-				System.out.println("v_3D_p: " + v_3D_p.toString());
-				System.out.println("w_3D_p: " + w_3D_p.toString());
-				
-				System.out.println("gives euler_angles: (" + rotations[0] + "," + rotations[1] + "," + rotations[2] + ")");
-
-		    }
-		    
-		 	 
-			
-			//apply to unit vector
-			
-		     Position pos = new Position(volName + "_position",HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width*1.5*-4,0,0);
-		     Rotation rot = new Rotation(volName + "_rotation",rotations[0],rotations[1],rotations[2]);
-		     lcdd.add(pos);
-		     lcdd.add(rot);
-			
-			
-		     PhysVol basePV = new PhysVol(volume, lcdd.pickMotherVolume(this), pos, rot);
-		     if(_debug) {
-		    	 System.out.println("Created physical vomume " + basePV.getName());
-		     }
-			
-		     
-		     
-		     
-		     volName = volName + "_sub";
-		     Box boxSub = new Box(volName + "Box", HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width, HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/4.0 , HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/8.0);
-		     lcdd.add(boxSub);
-		     Volume volumeSub = new Volume(volName + "_volume", boxSub, lcdd.getMaterial("Vacuum"));
-		     Position subPos = new Position(volName + "_position",0,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/4.0*2-HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/8.0,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/16.0);
-		     Rotation subRot = new Rotation(volName + "_rotation",0,0,0);
-		     lcdd.add(subPos);
-		     lcdd.add(subRot);
-		     PhysVol subBasePV = new PhysVol(volumeSub, volume, subPos, subRot);
-		     if(_debug) {
-		    	 System.out.println("Created physical vomume " + subBasePV.getName());
-		     }
-			
-		     lcdd.add(volumeSub);
-		     volumeSub.setVisAttributes(lcdd.getVisAttributes("SensorVis"));
-
-		     lcdd.add(volume);
-			
-			
-			
-			
-			}
-		
-		
-		
-		
-		
-
-		private void makeExample7(LCDD lcdd, SensitiveDetector sens) throws JDOMException {
-		
-		
-		if(_debug) {
-			System.out.println("--- makeExample7 ----");
-			
-		}
-		
-		String volName = "example7";
-		Box box = new Box(volName + "Box", HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width, HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length , HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/4.0);
-		lcdd.add(box);
-		Volume volume = new Volume(volName + "_volume", box, lcdd.getMaterial("Vacuum"));
-	    
-	    double [] rotations = {-0.5*Math.PI,0,-0.25*Math.PI};
-	    
-	    
-	    if(_debug) {
-	
-			
-			System.out.println("manual set lcdd angles: (" + rotations[0] + "," + rotations[1] + "," + rotations[2] + ")");
-
-	    }
-	    
-	 	 
-		
-		//apply to unit vector
-		
-	     Position pos = new Position(volName + "_position",HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width*1.5*-2,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length*-1,0);
-	     Rotation rot = new Rotation(volName + "_rotation",rotations[0],rotations[1],rotations[2]);
-	     lcdd.add(pos);
-	     lcdd.add(rot);
-		
-		
-	     PhysVol basePV = new PhysVol(volume, lcdd.pickMotherVolume(this), pos, rot);
-	     if(_debug) {
-	    	 System.out.println("Created physical vomume " + basePV.getName());
-	     }
-		
-	     
-	     
-	     
-	     volName = volName + "_sub";
-	     Box boxSub = new Box(volName + "Box", HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width, HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/4.0 , HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/8.0);
-	     lcdd.add(boxSub);
-	     Volume volumeSub = new Volume(volName + "_volume", boxSub, lcdd.getMaterial("Vacuum"));
-	     Position subPos = new Position(volName + "_position",0,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/4.0*2-HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/8.0,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/16.0);
-	     Rotation subRot = new Rotation(volName + "_rotation",0,0,0);
-	     lcdd.add(subPos);
-	     lcdd.add(subRot);
-	     PhysVol subBasePV = new PhysVol(volumeSub, volume, subPos, subRot);
-	     if(_debug) {
-	    	 System.out.println("Created physical vomume " + subBasePV.getName());
-	     }
-		
-	     lcdd.add(volumeSub);
-	     volumeSub.setVisAttributes(lcdd.getVisAttributes("SensorVis"));
-
-	     lcdd.add(volume);
-		
-		
-		
-		
-		}
-		
-		
-		
-	private void makeExample77(LCDD lcdd, SensitiveDetector sens) throws JDOMException {
-			
-			
-			if(_debug) {
-				System.out.println("--- makeExample77 ----");
-				
-			}
-			
-			String volName = "example77";
-			Box box = new Box(volName + "Box", HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width, HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length , HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/4.0);
-			lcdd.add(box);
-			Volume volume = new Volume(volName + "_volume", box, lcdd.getMaterial("Vacuum"));
-		
-			 
-
-			Hep3Vector u = new BasicHep3Vector(1,0,0);
-			Hep3Vector v = new BasicHep3Vector(0,1,0);
-			Hep3Vector w = new BasicHep3Vector(0,0,1);
-		
-			org.apache.commons.math3.geometry.euclidean.threed.Vector3D u_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(u.v());
-			org.apache.commons.math3.geometry.euclidean.threed.Vector3D v_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(v.v());
-			org.apache.commons.math3.geometry.euclidean.threed.Vector3D w_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(w.v());
-			
-			
-			
-			//set up a rotation about the X axis
-		    org.apache.commons.math3.geometry.euclidean.threed.Rotation r1 = new org.apache.commons.math3.geometry.euclidean.threed.Rotation(u_3D, -0.5*Math.PI);
-		     
-		    // find y' and z'
-		    org.apache.commons.math3.geometry.euclidean.threed.Vector3D u_3D_p = r1.applyTo(u_3D);
-		    org.apache.commons.math3.geometry.euclidean.threed.Vector3D v_3D_p = r1.applyTo(v_3D);
-		    org.apache.commons.math3.geometry.euclidean.threed.Vector3D w_3D_p = r1.applyTo(w_3D);
-		    
-		    
-		  //set up a rotation about the Z xis
-		   org.apache.commons.math3.geometry.euclidean.threed.Rotation r3 = new org.apache.commons.math3.geometry.euclidean.threed.Rotation(w_3D_p, -0.25*Math.PI);
-		   
-		   org.apache.commons.math3.geometry.euclidean.threed.Rotation r13 = r3.applyTo(r1);
-		   
-		   // find y'' and z''
-		   org.apache.commons.math3.geometry.euclidean.threed.Vector3D u_3D_pp = r13.applyTo(u_3D);
-		   org.apache.commons.math3.geometry.euclidean.threed.Vector3D v_3D_pp = r13.applyTo(v_3D);
-		   org.apache.commons.math3.geometry.euclidean.threed.Vector3D w_3D_pp = r13.applyTo(w_3D);
-		    
-		   // find y'' and z'' (cross-check)
-		   org.apache.commons.math3.geometry.euclidean.threed.Vector3D u_3D_pp_2 = r3.applyTo(u_3D_p);
-		   org.apache.commons.math3.geometry.euclidean.threed.Vector3D v_3D_pp_2 = r3.applyTo(v_3D_p);
-		   org.apache.commons.math3.geometry.euclidean.threed.Vector3D w_3D_pp_2 = r3.applyTo(w_3D_p);
-		    
-		    
-		    double [] rotations = r13.getAngles(org.apache.commons.math3.geometry.euclidean.threed.RotationOrder.XYZ);
-		    
-		    
-		    if(_debug) {
-		    	System.out.println("u_3D:       " + u_3D.toString());
-				System.out.println("v_3D:       " + v_3D.toString());
-				System.out.println("w_3D:       " + w_3D.toString());
-				r1.toString();
-				System.out.println("u_3D_p: " + u_3D_p.toString());
-				System.out.println("v_3D_p: " + v_3D_p.toString());
-				System.out.println("w_3D_p: " + w_3D_p.toString());
-				r13.toString();
-				System.out.println("u_3D_pp: " + u_3D_pp.toString());
-				System.out.println("v_3D_pp: " + v_3D_pp.toString());
-				System.out.println("w_3D_pp: " + w_3D_pp.toString());
-				
-				System.out.println("gives euler_angles: (" + rotations[0] + "," + rotations[1] + "," + rotations[2] + ")");
-				
-				System.out.println("u_3D_pp_2: " + u_3D_pp_2.toString());
-				System.out.println("v_3D_pp_2: " + v_3D_pp_2.toString());
-				System.out.println("w_3D_pp_2: " + w_3D_pp_2.toString());
-		    }
-		    
-		 	 
-			
-			//apply to unit vector
-			
-		     Position pos = new Position(volName + "_position",HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width*1.5*-4,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length*-1,0);
-		     Rotation rot = new Rotation(volName + "_rotation",rotations[0],rotations[1],rotations[2]);
-		     lcdd.add(pos);
-		     lcdd.add(rot);
-			
-			
-		     PhysVol basePV = new PhysVol(volume, lcdd.pickMotherVolume(this), pos, rot);
-		     if(_debug) {
-		    	 System.out.println("Created physical vomume " + basePV.getName());
-		     }
-			
-		     
-		     
-		     
-		     volName = volName + "_sub";
-		     Box boxSub = new Box(volName + "Box", HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width, HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/4.0 , HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/8.0);
-		     lcdd.add(boxSub);
-		     Volume volumeSub = new Volume(volName + "_volume", boxSub, lcdd.getMaterial("Vacuum"));
-		     Position subPos = new Position(volName + "_position",0,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/4.0*2-HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/8.0,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/16.0);
-		     Rotation subRot = new Rotation(volName + "_rotation",0,0,0);
-		     lcdd.add(subPos);
-		     lcdd.add(subRot);
-		     PhysVol subBasePV = new PhysVol(volumeSub, volume, subPos, subRot);
-		     if(_debug) {
-		    	 System.out.println("Created physical vomume " + subBasePV.getName());
-		     }
-			
-		     lcdd.add(volumeSub);
-		     volumeSub.setVisAttributes(lcdd.getVisAttributes("SensorVis"));
-
-		     lcdd.add(volume);
-			
-			
-			
-			
-			}
-		
-		
-		
-
-	private void makeExample8(LCDD lcdd, SensitiveDetector sens) throws JDOMException {
-	
-	
-	if(_debug) {
-		System.out.println("--- makeExample8 ----");
-		
-	}
-	
-	String volName = "example8";
-	Box box = new Box(volName + "Box", HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width, HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length , HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/4.0);
-	lcdd.add(box);
-	Volume volume = new Volume(volName + "_volume", box, lcdd.getMaterial("Vacuum"));
-    
-	
-	Hep3Vector u = new BasicHep3Vector(1,0,0);
-	Hep3Vector v = new BasicHep3Vector(0,1,0);
-	Hep3Vector w = new BasicHep3Vector(0,0,1);
-
-	org.apache.commons.math3.geometry.euclidean.threed.Vector3D u_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(u.v());
-	org.apache.commons.math3.geometry.euclidean.threed.Vector3D v_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(v.v());
-	org.apache.commons.math3.geometry.euclidean.threed.Vector3D w_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(w.v());
-	
-	Hep3Vector u_L1 = new BasicHep3Vector(1/Math.sqrt(2),0,1/Math.sqrt(2));
-	Hep3Vector v_L1 = new BasicHep3Vector(-1/Math.sqrt(2),0,1/Math.sqrt(2));
-	Hep3Vector w_L1 = new BasicHep3Vector(0,-1,0);
-	
-	Hep3Vector euler_angles = TransformationUtils.getCardanAngles(u_L1, v_L1, u, v);
-	
-	
+        
+
+            
+
+            */
+
+            Hep3Vector u = new BasicHep3Vector(1,0,0);
+            Hep3Vector v = new BasicHep3Vector(0,1,0);
+            Hep3Vector w = new BasicHep3Vector(0,0,1);
+            
+            Hep3Vector u_L1 = new BasicHep3Vector(0.99955,    0.030000,      0.0000);
+            Hep3Vector v_L1 = new BasicHep3Vector(-0.030000,     0.99955,      0.0000);
+            Hep3Vector w_L1 = new BasicHep3Vector(0.0000,      0.0000,     1.0000);
+            
+            
+            
+            org.apache.commons.math3.geometry.euclidean.threed.Vector3D u_3D_L1 = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(u_L1.v());
+            org.apache.commons.math3.geometry.euclidean.threed.Vector3D v_3D_L1 = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(v_L1.v());
+            org.apache.commons.math3.geometry.euclidean.threed.Vector3D w_3D_L1 = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(w_L1.v());
+
+            org.apache.commons.math3.geometry.euclidean.threed.Vector3D u_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(u.v());
+            org.apache.commons.math3.geometry.euclidean.threed.Vector3D v_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(v.v());
+            org.apache.commons.math3.geometry.euclidean.threed.Vector3D w_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(w.v());
+            
+            Hep3Vector euler_angles = TransformationUtils.getCardanAngles(v_L1, w_L1, v, w);
+            
+            //Get the generic rotation
+            org.apache.commons.math3.geometry.euclidean.threed.Rotation r = new org.apache.commons.math3.geometry.euclidean.threed.Rotation(v_3D_L1,w_3D_L1,v_3D, w_3D);
+            //Get the angles
+            double rotations[] = r.getAngles(org.apache.commons.math3.geometry.euclidean.threed.RotationOrder.XYZ);
+            
+            if(_debug) {
+                System.out.println("getEulerAngles gives euler_angles: " + euler_angles.toString());
+                System.out.println("manual          gives euler_angles: (" + rotations[0] + "," + rotations[1] + "," + rotations[2] + ")");
+            }
+                  
+            if((rotations[0]-euler_angles.x())>0.00001 || (rotations[1]-euler_angles.y())>0.00001 || (rotations[2]-euler_angles.z())>0.00001) {
+                //throw new RuntimeException("closing the loop in apache rotation didn't work!");
+            }
+            
+               
+            
+            
+             Position pos = new Position(volName + "_position",HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width*1.5*4,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length*-1.5,0);
+             Rotation rot = new Rotation(volName + "_rotation",rotations[0],rotations[1],rotations[2]);
+             lcdd.add(pos);
+             lcdd.add(rot);
+            
+            
+             PhysVol basePV = new PhysVol(volume, lcdd.pickMotherVolume(this), pos, rot);
+             if(_debug) {
+                 System.out.println("Created physical vomume " + basePV.getName());
+             }
+            
+             
+             
+             volName = volName + "_sub";
+             Box boxSub = new Box(volName + "Box", HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width, HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/4.0 , HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/8.0);
+             lcdd.add(boxSub);
+             Volume volumeSub = new Volume(volName + "_volume", boxSub, lcdd.getMaterial("Vacuum"));
+             Position subPos = new Position(volName + "_position",0,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/4.0*2-HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/8.0,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/16.0);
+             Rotation subRot = new Rotation(volName + "_rotation",0,0,0);
+             lcdd.add(subPos);
+             lcdd.add(subRot);
+             PhysVol subBasePV = new PhysVol(volumeSub, volume, subPos, subRot);
+             if(_debug) {
+                 System.out.println("Created physical vomume " + subBasePV.getName());
+             }
+            
+             lcdd.add(volumeSub);
+             volumeSub.setVisAttributes(lcdd.getVisAttributes("HybridVis"));
+
+             lcdd.add(volume);
+            
+            
+            
+            
+            }
+            
+
+        private void makeExample6(LCDD lcdd, SensitiveDetector sens) throws JDOMException {
+        
+        
+        if(_debug) {
+            System.out.println("--- makeExample6 ----");
+            
+        }
+        
+        String volName = "example6";
+        Box box = new Box(volName + "Box", HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width, HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length , HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/4.0);
+        lcdd.add(box);
+        Volume volume = new Volume(volName + "_volume", box, lcdd.getMaterial("Vacuum"));
+        
+        double [] rotations = {-0.5*Math.PI,0,0};
+        
+        
+        if(_debug) {
+    
+            
+            System.out.println("manual set lcdd angles: (" + rotations[0] + "," + rotations[1] + "," + rotations[2] + ")");
+
+        }
+        
+         
+        
+        //apply to unit vector
+        
+         Position pos = new Position(volName + "_position",HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width*1.5*-2,0,0);
+         Rotation rot = new Rotation(volName + "_rotation",rotations[0],rotations[1],rotations[2]);
+         lcdd.add(pos);
+         lcdd.add(rot);
+        
+        
+         PhysVol basePV = new PhysVol(volume, lcdd.pickMotherVolume(this), pos, rot);
+         if(_debug) {
+             System.out.println("Created physical vomume " + basePV.getName());
+         }
+        
+         
+         
+         
+         volName = volName + "_sub";
+         Box boxSub = new Box(volName + "Box", HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width, HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/4.0 , HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/8.0);
+         lcdd.add(boxSub);
+         Volume volumeSub = new Volume(volName + "_volume", boxSub, lcdd.getMaterial("Vacuum"));
+         Position subPos = new Position(volName + "_position",0,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/4.0*2-HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/8.0,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/16.0);
+         Rotation subRot = new Rotation(volName + "_rotation",0,0,0);
+         lcdd.add(subPos);
+         lcdd.add(subRot);
+         PhysVol subBasePV = new PhysVol(volumeSub, volume, subPos, subRot);
+         if(_debug) {
+             System.out.println("Created physical vomume " + subBasePV.getName());
+         }
+        
+         lcdd.add(volumeSub);
+         volumeSub.setVisAttributes(lcdd.getVisAttributes("SensorVis"));
+
+         lcdd.add(volume);
+        
+        
+        
+        
+        }
+        
+        
+        
+        private void makeExample66(LCDD lcdd, SensitiveDetector sens) throws JDOMException {
+            
+            
+            if(_debug) {
+                System.out.println("--- makeExample66 ----");
+                
+            }
+            
+            String volName = "example66";
+            Box box = new Box(volName + "Box", HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width, HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length , HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/4.0);
+            lcdd.add(box);
+            Volume volume = new Volume(volName + "_volume", box, lcdd.getMaterial("Vacuum"));
+        
+             
+
+            Hep3Vector u = new BasicHep3Vector(1,0,0);
+            Hep3Vector v = new BasicHep3Vector(0,1,0);
+            Hep3Vector w = new BasicHep3Vector(0,0,1);
+        
+            org.apache.commons.math3.geometry.euclidean.threed.Vector3D u_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(u.v());
+            org.apache.commons.math3.geometry.euclidean.threed.Vector3D v_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(v.v());
+            org.apache.commons.math3.geometry.euclidean.threed.Vector3D w_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(w.v());
+            
+            
+            
+            //set up a rotation about the X axis
+            org.apache.commons.math3.geometry.euclidean.threed.Rotation r1 = new org.apache.commons.math3.geometry.euclidean.threed.Rotation(u_3D, -0.5*Math.PI);
+             
+            // find y' and z'
+            org.apache.commons.math3.geometry.euclidean.threed.Vector3D u_3D_p = r1.applyTo(u_3D);
+            org.apache.commons.math3.geometry.euclidean.threed.Vector3D v_3D_p = r1.applyTo(v_3D);
+            org.apache.commons.math3.geometry.euclidean.threed.Vector3D w_3D_p = r1.applyTo(w_3D);
+            
+            
+            double [] rotations = r1.getAngles(org.apache.commons.math3.geometry.euclidean.threed.RotationOrder.XYZ);
+            
+            
+            if(_debug) {
+                System.out.println("u_3D:       " + u_3D.toString());
+                System.out.println("v_3D:       " + v_3D.toString());
+                System.out.println("w_3D:       " + w_3D.toString());
+                r1.toString();
+                System.out.println("u_3D_p: " + u_3D_p.toString());
+                System.out.println("v_3D_p: " + v_3D_p.toString());
+                System.out.println("w_3D_p: " + w_3D_p.toString());
+                
+                System.out.println("gives euler_angles: (" + rotations[0] + "," + rotations[1] + "," + rotations[2] + ")");
+
+            }
+            
+             
+            
+            //apply to unit vector
+            
+             Position pos = new Position(volName + "_position",HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width*1.5*-4,0,0);
+             Rotation rot = new Rotation(volName + "_rotation",rotations[0],rotations[1],rotations[2]);
+             lcdd.add(pos);
+             lcdd.add(rot);
+            
+            
+             PhysVol basePV = new PhysVol(volume, lcdd.pickMotherVolume(this), pos, rot);
+             if(_debug) {
+                 System.out.println("Created physical vomume " + basePV.getName());
+             }
+            
+             
+             
+             
+             volName = volName + "_sub";
+             Box boxSub = new Box(volName + "Box", HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width, HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/4.0 , HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/8.0);
+             lcdd.add(boxSub);
+             Volume volumeSub = new Volume(volName + "_volume", boxSub, lcdd.getMaterial("Vacuum"));
+             Position subPos = new Position(volName + "_position",0,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/4.0*2-HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/8.0,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/16.0);
+             Rotation subRot = new Rotation(volName + "_rotation",0,0,0);
+             lcdd.add(subPos);
+             lcdd.add(subRot);
+             PhysVol subBasePV = new PhysVol(volumeSub, volume, subPos, subRot);
+             if(_debug) {
+                 System.out.println("Created physical vomume " + subBasePV.getName());
+             }
+            
+             lcdd.add(volumeSub);
+             volumeSub.setVisAttributes(lcdd.getVisAttributes("SensorVis"));
+
+             lcdd.add(volume);
+            
+            
+            
+            
+            }
+        
+        
+        
+        
+        
+
+        private void makeExample7(LCDD lcdd, SensitiveDetector sens) throws JDOMException {
+        
+        
+        if(_debug) {
+            System.out.println("--- makeExample7 ----");
+            
+        }
+        
+        String volName = "example7";
+        Box box = new Box(volName + "Box", HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width, HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length , HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/4.0);
+        lcdd.add(box);
+        Volume volume = new Volume(volName + "_volume", box, lcdd.getMaterial("Vacuum"));
+        
+        double [] rotations = {-0.5*Math.PI,0,-0.25*Math.PI};
+        
+        
+        if(_debug) {
+    
+            
+            System.out.println("manual set lcdd angles: (" + rotations[0] + "," + rotations[1] + "," + rotations[2] + ")");
+
+        }
+        
+         
+        
+        //apply to unit vector
+        
+         Position pos = new Position(volName + "_position",HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width*1.5*-2,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length*-1,0);
+         Rotation rot = new Rotation(volName + "_rotation",rotations[0],rotations[1],rotations[2]);
+         lcdd.add(pos);
+         lcdd.add(rot);
+        
+        
+         PhysVol basePV = new PhysVol(volume, lcdd.pickMotherVolume(this), pos, rot);
+         if(_debug) {
+             System.out.println("Created physical vomume " + basePV.getName());
+         }
+        
+         
+         
+         
+         volName = volName + "_sub";
+         Box boxSub = new Box(volName + "Box", HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width, HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/4.0 , HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/8.0);
+         lcdd.add(boxSub);
+         Volume volumeSub = new Volume(volName + "_volume", boxSub, lcdd.getMaterial("Vacuum"));
+         Position subPos = new Position(volName + "_position",0,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/4.0*2-HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/8.0,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/16.0);
+         Rotation subRot = new Rotation(volName + "_rotation",0,0,0);
+         lcdd.add(subPos);
+         lcdd.add(subRot);
+         PhysVol subBasePV = new PhysVol(volumeSub, volume, subPos, subRot);
+         if(_debug) {
+             System.out.println("Created physical vomume " + subBasePV.getName());
+         }
+        
+         lcdd.add(volumeSub);
+         volumeSub.setVisAttributes(lcdd.getVisAttributes("SensorVis"));
+
+         lcdd.add(volume);
+        
+        
+        
+        
+        }
+        
+        
+        
+    private void makeExample77(LCDD lcdd, SensitiveDetector sens) throws JDOMException {
+            
+            
+            if(_debug) {
+                System.out.println("--- makeExample77 ----");
+                
+            }
+            
+            String volName = "example77";
+            Box box = new Box(volName + "Box", HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width, HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length , HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/4.0);
+            lcdd.add(box);
+            Volume volume = new Volume(volName + "_volume", box, lcdd.getMaterial("Vacuum"));
+        
+             
+
+            Hep3Vector u = new BasicHep3Vector(1,0,0);
+            Hep3Vector v = new BasicHep3Vector(0,1,0);
+            Hep3Vector w = new BasicHep3Vector(0,0,1);
+        
+            org.apache.commons.math3.geometry.euclidean.threed.Vector3D u_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(u.v());
+            org.apache.commons.math3.geometry.euclidean.threed.Vector3D v_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(v.v());
+            org.apache.commons.math3.geometry.euclidean.threed.Vector3D w_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(w.v());
+            
+            
+            
+            //set up a rotation about the X axis
+            org.apache.commons.math3.geometry.euclidean.threed.Rotation r1 = new org.apache.commons.math3.geometry.euclidean.threed.Rotation(u_3D, -0.5*Math.PI);
+             
+            // find y' and z'
+            org.apache.commons.math3.geometry.euclidean.threed.Vector3D u_3D_p = r1.applyTo(u_3D);
+            org.apache.commons.math3.geometry.euclidean.threed.Vector3D v_3D_p = r1.applyTo(v_3D);
+            org.apache.commons.math3.geometry.euclidean.threed.Vector3D w_3D_p = r1.applyTo(w_3D);
+            
+            
+          //set up a rotation about the Z xis
+           org.apache.commons.math3.geometry.euclidean.threed.Rotation r3 = new org.apache.commons.math3.geometry.euclidean.threed.Rotation(w_3D_p, -0.25*Math.PI);
+           
+           org.apache.commons.math3.geometry.euclidean.threed.Rotation r13 = r3.applyTo(r1);
+           
+           // find y'' and z''
+           org.apache.commons.math3.geometry.euclidean.threed.Vector3D u_3D_pp = r13.applyTo(u_3D);
+           org.apache.commons.math3.geometry.euclidean.threed.Vector3D v_3D_pp = r13.applyTo(v_3D);
+           org.apache.commons.math3.geometry.euclidean.threed.Vector3D w_3D_pp = r13.applyTo(w_3D);
+            
+           // find y'' and z'' (cross-check)
+           org.apache.commons.math3.geometry.euclidean.threed.Vector3D u_3D_pp_2 = r3.applyTo(u_3D_p);
+           org.apache.commons.math3.geometry.euclidean.threed.Vector3D v_3D_pp_2 = r3.applyTo(v_3D_p);
+           org.apache.commons.math3.geometry.euclidean.threed.Vector3D w_3D_pp_2 = r3.applyTo(w_3D_p);
+            
+            
+            double [] rotations = r13.getAngles(org.apache.commons.math3.geometry.euclidean.threed.RotationOrder.XYZ);
+            
+            
+            if(_debug) {
+                System.out.println("u_3D:       " + u_3D.toString());
+                System.out.println("v_3D:       " + v_3D.toString());
+                System.out.println("w_3D:       " + w_3D.toString());
+                r1.toString();
+                System.out.println("u_3D_p: " + u_3D_p.toString());
+                System.out.println("v_3D_p: " + v_3D_p.toString());
+                System.out.println("w_3D_p: " + w_3D_p.toString());
+                r13.toString();
+                System.out.println("u_3D_pp: " + u_3D_pp.toString());
+                System.out.println("v_3D_pp: " + v_3D_pp.toString());
+                System.out.println("w_3D_pp: " + w_3D_pp.toString());
+                
+                System.out.println("gives euler_angles: (" + rotations[0] + "," + rotations[1] + "," + rotations[2] + ")");
+                
+                System.out.println("u_3D_pp_2: " + u_3D_pp_2.toString());
+                System.out.println("v_3D_pp_2: " + v_3D_pp_2.toString());
+                System.out.println("w_3D_pp_2: " + w_3D_pp_2.toString());
+            }
+            
+             
+            
+            //apply to unit vector
+            
+             Position pos = new Position(volName + "_position",HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width*1.5*-4,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length*-1,0);
+             Rotation rot = new Rotation(volName + "_rotation",rotations[0],rotations[1],rotations[2]);
+             lcdd.add(pos);
+             lcdd.add(rot);
+            
+            
+             PhysVol basePV = new PhysVol(volume, lcdd.pickMotherVolume(this), pos, rot);
+             if(_debug) {
+                 System.out.println("Created physical vomume " + basePV.getName());
+             }
+            
+             
+             
+             
+             volName = volName + "_sub";
+             Box boxSub = new Box(volName + "Box", HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width, HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/4.0 , HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/8.0);
+             lcdd.add(boxSub);
+             Volume volumeSub = new Volume(volName + "_volume", boxSub, lcdd.getMaterial("Vacuum"));
+             Position subPos = new Position(volName + "_position",0,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/4.0*2-HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/8.0,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/16.0);
+             Rotation subRot = new Rotation(volName + "_rotation",0,0,0);
+             lcdd.add(subPos);
+             lcdd.add(subRot);
+             PhysVol subBasePV = new PhysVol(volumeSub, volume, subPos, subRot);
+             if(_debug) {
+                 System.out.println("Created physical vomume " + subBasePV.getName());
+             }
+            
+             lcdd.add(volumeSub);
+             volumeSub.setVisAttributes(lcdd.getVisAttributes("SensorVis"));
+
+             lcdd.add(volume);
+            
+            
+            
+            
+            }
+        
+        
+        
+
+    private void makeExample8(LCDD lcdd, SensitiveDetector sens) throws JDOMException {
     
     
     if(_debug) {
-
-		
-		System.out.println("euler angles " + euler_angles.toString());
-
+        System.out.println("--- makeExample8 ----");
+        
     }
     
- 	 
-	
-	//apply to unit vector
-	
+    String volName = "example8";
+    Box box = new Box(volName + "Box", HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width, HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length , HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/4.0);
+    lcdd.add(box);
+    Volume volume = new Volume(volName + "_volume", box, lcdd.getMaterial("Vacuum"));
+    
+    
+    Hep3Vector u = new BasicHep3Vector(1,0,0);
+    Hep3Vector v = new BasicHep3Vector(0,1,0);
+    Hep3Vector w = new BasicHep3Vector(0,0,1);
+
+    org.apache.commons.math3.geometry.euclidean.threed.Vector3D u_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(u.v());
+    org.apache.commons.math3.geometry.euclidean.threed.Vector3D v_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(v.v());
+    org.apache.commons.math3.geometry.euclidean.threed.Vector3D w_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(w.v());
+    
+    Hep3Vector u_L1 = new BasicHep3Vector(1/Math.sqrt(2),0,1/Math.sqrt(2));
+    Hep3Vector v_L1 = new BasicHep3Vector(-1/Math.sqrt(2),0,1/Math.sqrt(2));
+    Hep3Vector w_L1 = new BasicHep3Vector(0,-1,0);
+    
+    Hep3Vector euler_angles = TransformationUtils.getCardanAngles(u_L1, v_L1, u, v);
+    
+    
+    
+    
+    if(_debug) {
+
+        
+        System.out.println("euler angles " + euler_angles.toString());
+
+    }
+    
+     
+    
+    //apply to unit vector
+    
      Position pos = new Position(volName + "_position",HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width*1.5*-1,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length*-3,0);
      Rotation rot = new Rotation(volName + "_rotation",euler_angles.x(),euler_angles.y(),euler_angles.z());
      lcdd.add(pos);
      lcdd.add(rot);
-	
-	
+    
+    
      PhysVol basePV = new PhysVol(volume, lcdd.pickMotherVolume(this), pos, rot);
      if(_debug) {
-    	 System.out.println("Created physical vomume " + basePV.getName());
+         System.out.println("Created physical vomume " + basePV.getName());
      }
-	
+    
      
      
      
@@ -1244,197 +1243,197 @@
      lcdd.add(subRot);
      PhysVol subBasePV = new PhysVol(volumeSub, volume, subPos, subRot);
      if(_debug) {
-    	 System.out.println("Created physical vomume " + subBasePV.getName());
+         System.out.println("Created physical vomume " + subBasePV.getName());
      }
-	
+    
      lcdd.add(volumeSub);
      volumeSub.setVisAttributes(lcdd.getVisAttributes("SensorVis"));
 
      lcdd.add(volume);
-	
-	
-	
-	
-	}
-	
-		
-		
-	private void makeExample9(LCDD lcdd, SensitiveDetector sens) throws JDOMException {
-		
-		
-		if(_debug) {
-			System.out.println("--- makeExample9 ----");
-			
-		}
-		
-		String volName = "example9";
-		Box box = new Box(volName + "Box", HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width, HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length , HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/4.0);
-		lcdd.add(box);
-		Volume volume = new Volume(volName + "_volume", box, lcdd.getMaterial("Vacuum"));
-	    
-		
-		Hep3Vector u = new BasicHep3Vector(1,0,0);
-		Hep3Vector v = new BasicHep3Vector(0,1,0);
-		Hep3Vector w = new BasicHep3Vector(0,0,1);
-
-		org.apache.commons.math3.geometry.euclidean.threed.Vector3D u_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(u.v());
-		org.apache.commons.math3.geometry.euclidean.threed.Vector3D v_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(v.v());
-		org.apache.commons.math3.geometry.euclidean.threed.Vector3D w_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(w.v());
-		
-		Hep3Vector u_L1 = new BasicHep3Vector(1,0,0);
-		Hep3Vector v_L1 = new BasicHep3Vector(0,0,1);
-		Hep3Vector w_L1 = new BasicHep3Vector(0,-1,0);
-		
-		Hep3Vector euler_angles = TransformationUtils.getCardanAngles(u_L1, v_L1, u, v);
-		
-		
-	    
-	    
-	    if(_debug) {
-
-			
-			System.out.println("euler angles " + euler_angles.toString());
-
-	    }
-	    
-	 	 
-		
-		//apply to unit vector
-		
-	     Position pos = new Position(volName + "_position",HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width*1.5*-1,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length*-2,0);
-	     Rotation rot = new Rotation(volName + "_rotation",euler_angles.x(),euler_angles.y(),euler_angles.z());
-	     lcdd.add(pos);
-	     lcdd.add(rot);
-		
-		
-	     PhysVol basePV = new PhysVol(volume, lcdd.pickMotherVolume(this), pos, rot);
-	     if(_debug) {
-	    	 System.out.println("Created physical vomume " + basePV.getName());
-	     }
-		
-	     
-	     
-	     
-	     volName = volName + "_sub";
-	     Box boxSub = new Box(volName + "Box", HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width, HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/4.0 , HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/8.0);
-	     lcdd.add(boxSub);
-	     Volume volumeSub = new Volume(volName + "_volume", boxSub, lcdd.getMaterial("Vacuum"));
-	     Position subPos = new Position(volName + "_position",0,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/4.0*2-HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/8.0,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/16.0);
-	     Rotation subRot = new Rotation(volName + "_rotation",0,0,0);
-	     lcdd.add(subPos);
-	     lcdd.add(subRot);
-	     PhysVol subBasePV = new PhysVol(volumeSub, volume, subPos, subRot);
-	     if(_debug) {
-	    	 System.out.println("Created physical vomume " + subBasePV.getName());
-	     }
-		
-	     lcdd.add(volumeSub);
-	     volumeSub.setVisAttributes(lcdd.getVisAttributes("SensorVis"));
-
-	     lcdd.add(volume);
-		
-		
-		
-		
-		}
-		
-			
-	
-	
-	
-	private void makeExample10(LCDD lcdd, SensitiveDetector sens) throws JDOMException {
-		
-		
-		if(_debug) {
-			System.out.println("--- makeExample10 ----");
-			
-		}
-		
-		String volName = "example10";
-		Box box = new Box(volName + "Box", HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width, HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length , HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/4.0);
-		lcdd.add(box);
-		Volume volume = new Volume(volName + "_volume", box, lcdd.getMaterial("Vacuum"));
-	    
-		
-		Hep3Vector u = new BasicHep3Vector(1,0,0);
-		Hep3Vector v = new BasicHep3Vector(0,1,0);
-		Hep3Vector w = new BasicHep3Vector(0,0,1);
-
-		org.apache.commons.math3.geometry.euclidean.threed.Vector3D u_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(u.v());
-		org.apache.commons.math3.geometry.euclidean.threed.Vector3D v_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(v.v());
-		org.apache.commons.math3.geometry.euclidean.threed.Vector3D w_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(w.v());
-		
-		Hep3Vector u_L1 = new BasicHep3Vector(1/Math.sqrt(2),1/Math.sqrt(2),0);
-		Hep3Vector v_L1 = new BasicHep3Vector(0,0,1);
-		Hep3Vector w_L1 = new BasicHep3Vector(1/Math.sqrt(2),-1/Math.sqrt(2),0);
-		
-		Hep3Vector euler_angles = TransformationUtils.getCardanAngles(u_L1, v_L1, u, v);
-		
-		
-	    
-	    
-	    if(_debug) {
-
-			
-			System.out.println("euler angles " + euler_angles.toString());
-
-	    }
-	    
-	 	 
-		
-		//apply to unit vector
-		
-	     Position pos = new Position(volName + "_position",HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width*1.5*-2,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length*-2,0);
-	     Rotation rot = new Rotation(volName + "_rotation",euler_angles.x(),euler_angles.y(),euler_angles.z());
-	     lcdd.add(pos);
-	     lcdd.add(rot);
-		
-		
-	     PhysVol basePV = new PhysVol(volume, lcdd.pickMotherVolume(this), pos, rot);
-	     if(_debug) {
-	    	 System.out.println("Created physical vomume " + basePV.getName());
-	     }
-		
-	     
-	     
-	     
-	     volName = volName + "_sub";
-	     Box boxSub = new Box(volName + "Box", HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width, HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/4.0 , HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/8.0);
-	     lcdd.add(boxSub);
-	     Volume volumeSub = new Volume(volName + "_volume", boxSub, lcdd.getMaterial("Vacuum"));
-	     Position subPos = new Position(volName + "_position",0,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/4.0*2-HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/8.0,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/16.0);
-	     Rotation subRot = new Rotation(volName + "_rotation",0,0,0);
-	     lcdd.add(subPos);
-	     lcdd.add(subRot);
-	     PhysVol subBasePV = new PhysVol(volumeSub, volume, subPos, subRot);
-	     if(_debug) {
-	    	 System.out.println("Created physical vomume " + subBasePV.getName());
-	     }
-		
-	     lcdd.add(volumeSub);
-	     volumeSub.setVisAttributes(lcdd.getVisAttributes("SensorVis"));
-
-	     lcdd.add(volume);
-		
-		
-		
-		
-		}
+    
+    
+    
+    
+    }
+    
+        
+        
+    private void makeExample9(LCDD lcdd, SensitiveDetector sens) throws JDOMException {
+        
+        
+        if(_debug) {
+            System.out.println("--- makeExample9 ----");
+            
+        }
+        
+        String volName = "example9";
+        Box box = new Box(volName + "Box", HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width, HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length , HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/4.0);
+        lcdd.add(box);
+        Volume volume = new Volume(volName + "_volume", box, lcdd.getMaterial("Vacuum"));
+        
+        
+        Hep3Vector u = new BasicHep3Vector(1,0,0);
+        Hep3Vector v = new BasicHep3Vector(0,1,0);
+        Hep3Vector w = new BasicHep3Vector(0,0,1);
+
+        org.apache.commons.math3.geometry.euclidean.threed.Vector3D u_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(u.v());
+        org.apache.commons.math3.geometry.euclidean.threed.Vector3D v_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(v.v());
+        org.apache.commons.math3.geometry.euclidean.threed.Vector3D w_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(w.v());
+        
+        Hep3Vector u_L1 = new BasicHep3Vector(1,0,0);
+        Hep3Vector v_L1 = new BasicHep3Vector(0,0,1);
+        Hep3Vector w_L1 = new BasicHep3Vector(0,-1,0);
+        
+        Hep3Vector euler_angles = TransformationUtils.getCardanAngles(u_L1, v_L1, u, v);
+        
+        
+        
+        
+        if(_debug) {
+
+            
+            System.out.println("euler angles " + euler_angles.toString());
+
+        }
+        
+         
+        
+        //apply to unit vector
+        
+         Position pos = new Position(volName + "_position",HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width*1.5*-1,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length*-2,0);
+         Rotation rot = new Rotation(volName + "_rotation",euler_angles.x(),euler_angles.y(),euler_angles.z());
+         lcdd.add(pos);
+         lcdd.add(rot);
+        
+        
+         PhysVol basePV = new PhysVol(volume, lcdd.pickMotherVolume(this), pos, rot);
+         if(_debug) {
+             System.out.println("Created physical vomume " + basePV.getName());
+         }
+        
+         
+         
+         
+         volName = volName + "_sub";
+         Box boxSub = new Box(volName + "Box", HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width, HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/4.0 , HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/8.0);
+         lcdd.add(boxSub);
+         Volume volumeSub = new Volume(volName + "_volume", boxSub, lcdd.getMaterial("Vacuum"));
+         Position subPos = new Position(volName + "_position",0,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/4.0*2-HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/8.0,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/16.0);
+         Rotation subRot = new Rotation(volName + "_rotation",0,0,0);
+         lcdd.add(subPos);
+         lcdd.add(subRot);
+         PhysVol subBasePV = new PhysVol(volumeSub, volume, subPos, subRot);
+         if(_debug) {
+             System.out.println("Created physical vomume " + subBasePV.getName());
+         }
+        
+         lcdd.add(volumeSub);
+         volumeSub.setVisAttributes(lcdd.getVisAttributes("SensorVis"));
+
+         lcdd.add(volume);
+        
+        
+        
+        
+        }
+        
+            
+    
+    
+    
+    private void makeExample10(LCDD lcdd, SensitiveDetector sens) throws JDOMException {
+        
+        
+        if(_debug) {
+            System.out.println("--- makeExample10 ----");
+            
+        }
+        
+        String volName = "example10";
+        Box box = new Box(volName + "Box", HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width, HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length , HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/4.0);
+        lcdd.add(box);
+        Volume volume = new Volume(volName + "_volume", box, lcdd.getMaterial("Vacuum"));
+        
+        
+        Hep3Vector u = new BasicHep3Vector(1,0,0);
+        Hep3Vector v = new BasicHep3Vector(0,1,0);
+        Hep3Vector w = new BasicHep3Vector(0,0,1);
+
+        org.apache.commons.math3.geometry.euclidean.threed.Vector3D u_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(u.v());
+        org.apache.commons.math3.geometry.euclidean.threed.Vector3D v_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(v.v());
+        org.apache.commons.math3.geometry.euclidean.threed.Vector3D w_3D = new org.apache.commons.math3.geometry.euclidean.threed.Vector3D(w.v());
+        
+        Hep3Vector u_L1 = new BasicHep3Vector(1/Math.sqrt(2),1/Math.sqrt(2),0);
+        Hep3Vector v_L1 = new BasicHep3Vector(0,0,1);
+        Hep3Vector w_L1 = new BasicHep3Vector(1/Math.sqrt(2),-1/Math.sqrt(2),0);
+        
+        Hep3Vector euler_angles = TransformationUtils.getCardanAngles(u_L1, v_L1, u, v);
+        
+        
+        
+        
+        if(_debug) {
+
+            
+            System.out.println("euler angles " + euler_angles.toString());
+
+        }
+        
+         
+        
+        //apply to unit vector
+        
+         Position pos = new Position(volName + "_position",HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width*1.5*-2,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length*-2,0);
+         Rotation rot = new Rotation(volName + "_rotation",euler_angles.x(),euler_angles.y(),euler_angles.z());
+         lcdd.add(pos);
+         lcdd.add(rot);
+        
+        
+         PhysVol basePV = new PhysVol(volume, lcdd.pickMotherVolume(this), pos, rot);
+         if(_debug) {
+             System.out.println("Created physical vomume " + basePV.getName());
+         }
+        
+         
+         
+         
+         volName = volName + "_sub";
+         Box boxSub = new Box(volName + "Box", HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_width, HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/4.0 , HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/8.0);
+         lcdd.add(boxSub);
+         Volume volumeSub = new Volume(volName + "_volume", boxSub, lcdd.getMaterial("Vacuum"));
+         Position subPos = new Position(volName + "_position",0,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/4.0*2-HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_length/8.0,HPSTestRunTracker2014GeometryDefinition.TrackerEnvelope.base_height/16.0);
+         Rotation subRot = new Rotation(volName + "_rotation",0,0,0);
+         lcdd.add(subPos);
+         lcdd.add(subRot);
+         PhysVol subBasePV = new PhysVol(volumeSub, volume, subPos, subRot);
+         if(_debug) {
+             System.out.println("Created physical vomume " + subBasePV.getName());
+         }
+        
+         lcdd.add(volumeSub);
+         volumeSub.setVisAttributes(lcdd.getVisAttributes("SensorVis"));
+
+         lcdd.add(volume);
+        
+        
+        
+        
+        }
 
    
-			
-	
-	
-			
-	
-
-	
-	
-
-	
-	
-	
-	
+            
+    
+    
+            
+    
+
+    
+    
+
+    
+    
+    
+    
 
 }
 

Modified: java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/lcdd/HPSTracker.java
 =============================================================================
--- java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/lcdd/HPSTracker.java	(original)
+++ java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/lcdd/HPSTracker.java	Wed Apr 27 11:11:32 2016
@@ -69,7 +69,7 @@
         // layer
         for (Iterator i = node.getChildren("layer").iterator(); i.hasNext();)
         {
-        	// Modules are numbered from 0 starting in each layer.
+            // Modules are numbered from 0 starting in each layer.
             int moduleNumber = 0;
 
             Element layerElement = (Element) i.next();

Modified: java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/lcdd/HPSTracker2.java
 =============================================================================
--- java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/lcdd/HPSTracker2.java	(original)
+++ java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/lcdd/HPSTracker2.java	Wed Apr 27 11:11:32 2016
@@ -53,79 +53,79 @@
     }
 
     // Place modules within the tracking volume.
-	private void createModulePlacements(LCDD lcdd, int sysId, String subdetName) throws DataConversionException {
-		//Volume trackingVolume = lcdd.getTrackingVolume();
-		Volume momVolume = lcdd.pickMotherVolume(this);
-		// Loop over layers.
+    private void createModulePlacements(LCDD lcdd, int sysId, String subdetName) throws DataConversionException {
+        //Volume trackingVolume = lcdd.getTrackingVolume();
+        Volume momVolume = lcdd.pickMotherVolume(this);
+        // Loop over layers.
         for (Iterator i = node.getChildren("layer").iterator(); i.hasNext();) {        
-        	Element layerElement = (Element)i.next();
-        	int layerNumber = layerElement.getAttribute("id").getIntValue();
-        	// Loop over modules within layer.
-        	for (Iterator j = layerElement.getChildren("module_placement").iterator(); j.hasNext();) {
-        	    
-        		Element modulePlacementElement = (Element)j.next();
-        		String moduleName = modulePlacementElement.getAttributeValue("name");
-        		int moduleNumber = modulePlacementElement.getAttribute("id").getIntValue();
-        		
-        		// Get the position and rotation parameters.  All must be explicitly specified.
-        		double x, y, z;
-        		double rx, ry, rz;
-        		x = modulePlacementElement.getAttribute("x").getDoubleValue();
-        		y = modulePlacementElement.getAttribute("y").getDoubleValue();
-        		z = modulePlacementElement.getAttribute("z").getDoubleValue();
-        		rx = modulePlacementElement.getAttribute("rx").getDoubleValue();
-        		ry = modulePlacementElement.getAttribute("ry").getDoubleValue();
-        		rz = modulePlacementElement.getAttribute("rz").getDoubleValue();
-        		
-        		// Place the module with position and rotation from above.
-        		String modulePlacementName = subdetName + "_" + moduleName + "_layer" + layerNumber + "_module" + moduleNumber;
-        		Position p = new Position(modulePlacementName + "_position", x, y, z);
-        		Rotation r = new Rotation(modulePlacementName + "_rotation", rx, ry, rz);
-        		lcdd.add(p);
-        		lcdd.add(r);        		        		
-        		//PhysVol modulePhysVol = new PhysVol(modules.get(moduleName), trackingVolume, p, r);
-        		PhysVol modulePhysVol = new PhysVol(modules.get(moduleName), momVolume, p, r);
-        		
-        		// Add identifier values to the placement volume.
-        		modulePhysVol.addPhysVolID("system", sysId);
-        		modulePhysVol.addPhysVolID("barrel", 0);
-        		modulePhysVol.addPhysVolID("layer", layerNumber);
-        		modulePhysVol.addPhysVolID("module", moduleNumber);        		
-        	}
-        }
-	}
+            Element layerElement = (Element)i.next();
+            int layerNumber = layerElement.getAttribute("id").getIntValue();
+            // Loop over modules within layer.
+            for (Iterator j = layerElement.getChildren("module_placement").iterator(); j.hasNext();) {
+                
+                Element modulePlacementElement = (Element)j.next();
+                String moduleName = modulePlacementElement.getAttributeValue("name");
+                int moduleNumber = modulePlacementElement.getAttribute("id").getIntValue();
+                
+                // Get the position and rotation parameters.  All must be explicitly specified.
+                double x, y, z;
+                double rx, ry, rz;
+                x = modulePlacementElement.getAttribute("x").getDoubleValue();
+                y = modulePlacementElement.getAttribute("y").getDoubleValue();
+                z = modulePlacementElement.getAttribute("z").getDoubleValue();
+                rx = modulePlacementElement.getAttribute("rx").getDoubleValue();
+                ry = modulePlacementElement.getAttribute("ry").getDoubleValue();
+                rz = modulePlacementElement.getAttribute("rz").getDoubleValue();
+                
+                // Place the module with position and rotation from above.
+                String modulePlacementName = subdetName + "_" + moduleName + "_layer" + layerNumber + "_module" + moduleNumber;
+                Position p = new Position(modulePlacementName + "_position", x, y, z);
+                Rotation r = new Rotation(modulePlacementName + "_rotation", rx, ry, rz);
+                lcdd.add(p);
+                lcdd.add(r);                                
+                //PhysVol modulePhysVol = new PhysVol(modules.get(moduleName), trackingVolume, p, r);
+                PhysVol modulePhysVol = new PhysVol(modules.get(moduleName), momVolume, p, r);
+                
+                // Add identifier values to the placement volume.
+                modulePhysVol.addPhysVolID("system", sysId);
+                modulePhysVol.addPhysVolID("barrel", 0);
+                modulePhysVol.addPhysVolID("layer", layerNumber);
+                modulePhysVol.addPhysVolID("module", moduleNumber);             
+            }
+        }
+    }
 
     // Create the module logical volumes.
-	private void createModules(LCDD lcdd, SensitiveDetector sd) {
+    private void createModules(LCDD lcdd, SensitiveDetector sd) {
         for (Iterator i = node.getChildren("module").iterator(); i.hasNext();) {
             Element module = (Element) i.next();
             String moduleName = module.getAttributeValue("name");
             moduleParameters.put(moduleName, new ModuleParameters(module));
             modules.put(moduleName, makeModule(moduleParameters.get(moduleName), sd, lcdd));
         }
-	}
-
-	private Volume makeModule(ModuleParameters params, SensitiveDetector sd, LCDD lcdd) {
-		double thickness = params.getThickness();
-		double x, y;
-		// x = params.getDimension(0);
-		// y = params.getDimension(1);
-		y = params.getDimension(0); // Y is in X plane in world coordinates.
-		x = params.getDimension(1); // X is in Y plane in world coordinates.
-		// System.out.println("making module with x = " + x + " and y = " + y);
-		Box box = new Box(params.getName() + "Box", x, y, thickness);
-		lcdd.add(box);
-
-		Volume moduleVolume = new Volume(params.getName() + "Volume", box, vacuum);
-		makeModuleComponents(moduleVolume, params, sd, lcdd);
-		lcdd.add(moduleVolume);
-
-		if (params.getVis() != null) {
-			moduleVolume.setVisAttributes(lcdd.getVisAttributes(params.getVis()));
-		}
-
-		return moduleVolume;
-	}
+    }
+
+    private Volume makeModule(ModuleParameters params, SensitiveDetector sd, LCDD lcdd) {
+        double thickness = params.getThickness();
+        double x, y;
+        // x = params.getDimension(0);
+        // y = params.getDimension(1);
+        y = params.getDimension(0); // Y is in X plane in world coordinates.
+        x = params.getDimension(1); // X is in Y plane in world coordinates.
+        // System.out.println("making module with x = " + x + " and y = " + y);
+        Box box = new Box(params.getName() + "Box", x, y, thickness);
+        lcdd.add(box);
+
+        Volume moduleVolume = new Volume(params.getName() + "Volume", box, vacuum);
+        makeModuleComponents(moduleVolume, params, sd, lcdd);
+        lcdd.add(moduleVolume);
+
+        if (params.getVis() != null) {
+            moduleVolume.setVisAttributes(lcdd.getVisAttributes(params.getVis()));
+        }
+
+        return moduleVolume;
+    }
 
     private void makeModuleComponents(Volume moduleVolume, ModuleParameters moduleParameters, SensitiveDetector sd, LCDD lcdd) {
         Box envelope = (Box) lcdd.getSolid(moduleVolume.getSolidRef());

Modified: java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/lcdd/HPSTracker2014.java
 =============================================================================
--- java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/lcdd/HPSTracker2014.java	(original)
+++ java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/lcdd/HPSTracker2014.java	Wed Apr 27 11:11:32 2016
@@ -61,7 +61,7 @@
                 return moduleNumber;
     }
 
-    	
+        
 
 }
 

Modified: java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/subdetector/HPSEcal.java
 =============================================================================
--- java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/subdetector/HPSEcal.java	(original)
+++ java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/subdetector/HPSEcal.java	Wed Apr 27 11:11:32 2016
@@ -15,39 +15,33 @@
 /**
  * Reconstruction version of HPS ECal with crystal array.
  * 
- * @author Jeremy McCormick <[log in to unmask]>
- * @author Timothy Nelson <[log in to unmask]>
- * @version $Id: HPSEcal.java,v 1.6 2011/07/28 20:20:18 jeremy Exp $
+ * @author Jeremy McCormick, SLAC
+ * @author Timothy Nelson, SLAC
  */
-public class HPSEcal extends AbstractSubdetector
-{
+public class HPSEcal extends AbstractSubdetector {
+
     private int nx;
     private int ny;
     private double beamgap;
     private double dface;
     private boolean oddX;
 
-    public static class NeighborMap extends HashMap<Long,Set<Long>>
-    {
+    public static class NeighborMap extends HashMap<Long, Set<Long>> {
+
         IIdentifierHelper helper;
-        public NeighborMap(IIdentifierHelper helper)
-        {
+
+        public NeighborMap(IIdentifierHelper helper) {
             this.helper = helper;
         }
-        
-        public String toString()
-        {
+
+        public String toString() {
             System.out.println("NeighborMap has " + this.size() + " entries.");
             StringBuffer buff = new StringBuffer();
-            for (long id : this.keySet())
-            {
-                buff.append(helper.unpack(new Identifier(id)))
-                    .append("\n");
-                Set<Long> nei = this.get(id); 
-                for (long nid : nei)
-                {
-                    buff.append("  " + helper.unpack(new Identifier(nid)))
-                        .append("\n");
+            for (long id : this.keySet()) {
+                buff.append(helper.unpack(new Identifier(id))).append("\n");
+                Set<Long> nei = this.get(id);
+                for (long nid : nei) {
+                    buff.append("  " + helper.unpack(new Identifier(nid))).append("\n");
                 }
             }
             return buff.toString();
@@ -56,308 +50,270 @@
 
     private NeighborMap neighborMap = null;
 
-    HPSEcal(Element node) throws JDOMException
-    {
+    HPSEcal(Element node) throws JDOMException {
         super(node);
-        
+
         Element layout = node.getChild("layout");
-        
+
         nx = layout.getAttribute("nx").getIntValue();
         ny = layout.getAttribute("ny").getIntValue();
         beamgap = layout.getAttribute("beamgap").getDoubleValue();
         dface = layout.getAttribute("dface").getDoubleValue();
-        
-        if (nx % 2 != 0)
+
+        if (nx % 2 != 0) {
             oddX = true;
-     }
-    
-    public double distanceToFace()
-    {
+        }
+    }
+
+    public double distanceToFace() {
         return dface;
     }
-    
-    public double beamGap()
-    {
+
+    public double beamGap() {
         return beamgap;
     }
-    
+
     /**
      * The number of crystals in X in one section.
-     * @return
+     * 
+     * @return the number of crystals in X in one section
      */
-    public double nx()
-    {
+    public double nx() {
         return nx;
     }
-    
+
     /**
      * The number of crystals in y in one section.
-     * @return
+     * 
+     * @return the number of crystals in Y in one section
      */
-    public double ny()
-    {
+    public double ny() {
         return ny;
-    }   
-    
+    }
+
     // Class for storing neighbor incides in XY and side.
-    static class XYSide implements Comparator<XYSide>
-    {
+    static class XYSide implements Comparator<XYSide> {
+
         int x;
         int y;
         int side;
-        
-        public XYSide(int x, int y, int side)
-        {
+
+        public XYSide(int x, int y, int side) {
             this.x = x;
             this.y = y;
             this.side = side;
         }
-        
-        public int x()
-        {
+
+        public int x() {
             return x;
         }
-        
-        public int y()
-        {
+
+        public int y() {
             return y;
         }
-        
-        public int side()
-        {
+
+        public int side() {
             return side;
         }
-        
-        public boolean equals(Object o)
-        {
-            XYSide xy = (XYSide)o;
-            return xy.x() == x && xy.y() == y && xy.side() == side; 
-        }
-
-        public int compare(XYSide o1, XYSide o2)
-        {
-            if (o1.equals(o2))
-            {
+
+        public boolean equals(Object o) {
+            XYSide xy = (XYSide) o;
+            return xy.x() == x && xy.y() == y && xy.side() == side;
+        }
+
+        public int compare(XYSide o1, XYSide o2) {
+            if (o1.equals(o2)) {
                 return 0;
-            }
-            else
-            {
+            } else {
                 return -1;
             }
         }
     }
-    
+
     /**
-     * Get the neighbors for a given cell ID.  Each crystal not on an edge 
-     * has 8 neighbors.  Edge crystals have fewer.
+     * Get the neighbors for a given cell ID. Each crystal not on an edge has 8 neighbors. Edge crystals have fewer.
+     * 
      * @param id The cell ID.
      * @return A <code>Set</code> containing the cell's neighbors.
      */
-    Set<Long> getNeighbors(Long id)
-    {        
+    Set<Long> getNeighbors(Long id) {
         // Get the IDDecoder.
-        IDDecoder dec = getIDDecoder();        
-        
+        IDDecoder dec = getIDDecoder();
+
         // Set the ID.
         dec.setID(id);
-        
+
         // Get ID field values.
         int x = dec.getValue("ix");
         int y = dec.getValue("iy");
         int side = dec.getValue("side");
-       
+
         // Get field indices.
         int ix = dec.getFieldIndex("ix");
         int iy = dec.getFieldIndex("iy");
         int iside = dec.getFieldIndex("side");
-        
+
         // Get X, Y, & side neighbor data for this crystal.
         Set<XYSide> neighbors = getNeighbors(x, y, side);
 
         // Get buffer with values from current ID.
         int[] buffer = new int[dec.getFieldCount()];
-        dec.getValues(buffer);       
-        
+        dec.getValues(buffer);
+
         // Create an encoder to make neighbor IDs.
         IDEncoder enc = new IDEncoder(dec.getIDDescription());
-     
+
         // Set to hold neighbor IDs.
         Set<Long> ids = new HashSet<Long>();
-        
+
         // Loop over neighbor objects to make IDs.
-        for (XYSide xyside : neighbors)
-        {
+        for (XYSide xyside : neighbors) {
             buffer[ix] = xyside.x;
             buffer[iy] = xyside.y;
             buffer[iside] = xyside.side;
             long nId = enc.setValues(buffer);
             ids.add(nId);
         }
-        
+
         return ids;
     }
-    
-    Set<XYSide> getNeighbors(int ix, int iy, int side)
-    {
+
+    Set<XYSide> getNeighbors(int ix, int iy, int side) {
         Set<Integer> xneighbors = getXNeighbors(ix);
         Set<Integer> yneighbors = getYNeighbors(iy);
-        
+
         Set<XYSide> neighbors = new HashSet<XYSide>();
-        
-        for (Integer jx : xneighbors)
-        {
-            for (Integer jy : yneighbors)
-            {                
+
+        for (Integer jx : xneighbors) {
+            for (Integer jy : yneighbors) {
                 // Filter out self.
-                if (jx == ix && jy == iy)
-                {
+                if (jx == ix && jy == iy) {
                     continue;
                 }
-                
-                neighbors.add(new XYSide(jx,jy,side));
+
+                neighbors.add(new XYSide(jx, jy, side));
             }
         }
-        
+
         return neighbors;
     }
-    
-    Set<Integer> getXNeighbors(int ix)
-    {
+
+    Set<Integer> getXNeighbors(int ix) {
         Set<Integer> neighbors = new HashSet<Integer>();
-        
+
         // Add self.
         neighbors.add(ix);
-        
+
         // Left neighbor.
-        if (isValidX(ix - 1))
-        {
+        if (isValidX(ix - 1)) {
             neighbors.add(ix - 1);
-        }
-        else if (isValidX(ix - 2))
-        {
+        } else if (isValidX(ix - 2)) {
             neighbors.add(ix - 2);
         }
-        
+
         // Right neighbor.
-        if (isValidX(ix + 1))
-        {
+        if (isValidX(ix + 1)) {
             neighbors.add(ix + 1);
-        }
-        else if (isValidX(ix + 2))
-        {
+        } else if (isValidX(ix + 2)) {
             neighbors.add(ix + 2);
-        }                
-        
+        }
+
         return neighbors;
     }
-    
-    Set<Integer> getYNeighbors(int iy)
-    {
+
+    Set<Integer> getYNeighbors(int iy) {
         Set<Integer> neighbors = new HashSet<Integer>();
-        
+
         // Add self.
         neighbors.add(iy);
-        
+
         // Lower neighbor.
-        if (isValidY(iy - 1))
-        {
+        if (isValidY(iy - 1)) {
             neighbors.add(iy - 1);
         }
         // Upper neighbor.
-        if (isValidY(iy + 1))
-        {
+        if (isValidY(iy + 1)) {
             neighbors.add(iy + 1);
         }
-        
+
         return neighbors;
     }
-    
-    boolean isValidY(int iy)
-    {
+
+    boolean isValidY(int iy) {
         // Zero is not valid because ID scheme goes from 1.
         return iy > 0 && iy <= ny;
     }
-    
-    boolean isValidX(int ix)
-    {
+
+    boolean isValidX(int ix) {
         // Even case.
-        if (!oddX)
-        {
-            return ix >= -nx/2 && ix <= nx/2 && ix != 0;
+        if (!oddX) {
+            return ix >= -nx / 2 && ix <= nx / 2 && ix != 0;
         }
         // Odd case.
-        else
-        {
-            return ix >= (-nx-1)/2 && ix <= (nx+1)/2;
-        }
-    }
-        
+        else {
+            return ix >= (-nx - 1) / 2 && ix <= (nx + 1) / 2;
+        }
+    }
+
     /**
      * Create a map of crystal IDs to the <code>Set</code> of neighbor crystal IDs.
+     * 
      * @return A map of neighbors for each crystal ID.
      */
-    public NeighborMap getNeighborMap()
-    {
-        if (neighborMap != null)
-        {
+    public NeighborMap getNeighborMap() {
+        if (neighborMap != null) {
             return neighborMap;
         }
-       
-        // Setup the private instance of the map. 
+
+        // Setup the private instance of the map.
         neighborMap = new NeighborMap(this.getDetectorElement().getIdentifierHelper());
-        
+
         IDDecoder dec = getIDDecoder();
         IDEncoder enc = new IDEncoder(dec.getIDDescription());
-        
+
         int nfields = dec.getFieldCount();
         int[] vals = new int[nfields];
 
         vals[dec.getFieldIndex("system")] = getSystemID();
-        
+
         int idxx = dec.getFieldIndex("ix");
         int idxy = dec.getFieldIndex("iy");
-        
-        int hnx = nx;        
-        
-        // Calculate number of X for loop.  (from LCDD conv)
-        if (oddX)
-        {
+
+        int hnx = nx;
+
+        // Calculate number of X for loop. (from LCDD conv)
+        if (oddX) {
             hnx -= 1;
             hnx /= 2;
-        }
-        else
-        {
+        } else {
             hnx /= 2;
         }
-                
-        for (int side=-1; side <=1; side++)
-        {            
-            if (side == 0) continue;            
+
+        for (int side = -1; side <= 1; side++) {
+            if (side == 0)
+                continue;
             vals[dec.getFieldIndex("side")] = side;
             // Loop over y.
-            for (int iy=1; iy<=ny; iy++)
-            {       
+            for (int iy = 1; iy <= ny; iy++) {
                 // Loop over x.
-                for (int ix=0; ix<=hnx; ix++)
-                {                                                                                       
+                for (int ix = 0; ix <= hnx; ix++) {
                     // Loop for positive and negative x.
-                    for (int j=-1; j<=1; j++)
-                    {
+                    for (int j = -1; j <= 1; j++) {
                         if (j == 0)
                             continue;
-                                                
-                        vals[idxx] = ix*j;
+
+                        vals[idxx] = ix * j;
                         vals[idxy] = iy;
-                                                        
+
                         Long id = enc.setValues(vals);
                         Set<Long> neighbors = getNeighbors(id);
-                                        
+
                         neighborMap.put(id, neighbors);
                     }
                 }
             }
         }
-        
+
         return neighborMap;
-    }    
+    }
 }

Modified: java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/subdetector/HPSEcal3.java
 =============================================================================
--- java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/subdetector/HPSEcal3.java	(original)
+++ java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/subdetector/HPSEcal3.java	Wed Apr 27 11:11:32 2016
@@ -150,7 +150,7 @@
     /**
      * The number of crystals in X in one section.
      * 
-     * @return
+     * @return the number of crystals in X in one section
      */
     public double nx() {
         return nx;
@@ -159,7 +159,7 @@
     /**
      * The number of crystals in y in one section.
      * 
-     * @return
+     * @return the number of crystals in Y in one section
      */
     public double ny() {
         return ny;

Modified: java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/subdetector/HPSTestRunTracker2014.java
 =============================================================================
--- java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/subdetector/HPSTestRunTracker2014.java	(original)
+++ java/branches/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/subdetector/HPSTestRunTracker2014.java	Wed Apr 27 11:11:32 2016
@@ -9,21 +9,21 @@
 
 public class HPSTestRunTracker2014 extends AbstractTracker {
 
-	public HPSTestRunTracker2014(Element node) throws JDOMException 
-	{
-		super(node);
-	}
+    public HPSTestRunTracker2014(Element node) throws JDOMException 
+    {
+        super(node);
+    }
 
-	public void appendHepRep(HepRepFactory factory, HepRep heprep) 
-	{
+    public void appendHepRep(HepRepFactory factory, HepRep heprep) 
+    {
         DetectorElementToHepRepConverter.convert(getDetectorElement(), factory, heprep, -1, false, getVisAttributes().getColor());
-	}
-	
-	public boolean isEndcap() {
-		return false;
-	}
-	
-	public boolean isBarrel() {
-		return true;
-	}
+    }
+    
+    public boolean isEndcap() {
+        return false;
+    }
+    
+    public boolean isBarrel() {
+        return true;
+    }
 }

Modified: java/branches/HPSJAVA-409/detector-model/src/test/java/org/hps/detector/svt/SvtDetectorSetupTest.java
 =============================================================================
--- java/branches/HPSJAVA-409/detector-model/src/test/java/org/hps/detector/svt/SvtDetectorSetupTest.java	(original)
+++ java/branches/HPSJAVA-409/detector-model/src/test/java/org/hps/detector/svt/SvtDetectorSetupTest.java	Wed Apr 27 11:11:32 2016
@@ -63,7 +63,8 @@
 
         final DatabaseConditionsManager conditionsManager = DatabaseConditionsManager.getInstance();
         conditionsManager.addConditionsListener(new SvtDetectorSetup());
-        conditionsManager.setDetector("HPS-Proposal2014-v7-2pt2", 0);
+        //conditionsManager.setDetector("HPS-Proposal2014-v7-2pt2", 0);
+        conditionsManager.setDetector("HPS-EngRun2015-Nominal-v3", 5772);
 
         // Get the detector.
         final Detector detector = conditionsManager.getCachedConditions(Detector.class, "compact.xml").getCachedData();

Modified: java/branches/HPSJAVA-409/detector-model/src/test/java/org/lcsim/detector/converter/compact/HPSTracker2ConverterTest.java
 =============================================================================
--- java/branches/HPSJAVA-409/detector-model/src/test/java/org/lcsim/detector/converter/compact/HPSTracker2ConverterTest.java	(original)
+++ java/branches/HPSJAVA-409/detector-model/src/test/java/org/lcsim/detector/converter/compact/HPSTracker2ConverterTest.java	Wed Apr 27 11:11:32 2016
@@ -36,8 +36,8 @@
     private static final int TOTAL_NUMBER_OF_STEREO_LAYERS = 10; 
     private static final String SUBDETECTOR_NAME = "Tracker";
     
-	public static final int NUMBER_OF_READOUT_STRIPS = 639;
-	public static final int NUMBER_OF_SENSE_STRIPS = 1277;
+    public static final int NUMBER_OF_READOUT_STRIPS = 639;
+    public static final int NUMBER_OF_SENSE_STRIPS = 1277;
     
     //-----------------//
     //-----------------//
@@ -74,12 +74,12 @@
         for(HpsSiSensor sensor : sensors) {
             assertTrue("[ " + this.getClass().getSimpleName() + " ]: Sensor is of wrong type: " + sensor.getClass().getSimpleName(),
                         sensor instanceof HpsSiSensor);
-			assertTrue("[ " + this.getClass().getSimpleName() + " ]: Wrong number of readout electrodes found.",
-					sensor.getReadoutElectrodes(ChargeCarrier.HOLE).getNCells() == NUMBER_OF_READOUT_STRIPS);
-			
-			assertTrue("[ " + this.getClass().getSimpleName() + " ]: Wrong number of sense electrodes found.",
-					sensor.getSenseElectrodes(ChargeCarrier.HOLE).getNCells() == NUMBER_OF_SENSE_STRIPS);
-			LOGGER.info(sensor.toString());
+            assertTrue("[ " + this.getClass().getSimpleName() + " ]: Wrong number of readout electrodes found.",
+                    sensor.getReadoutElectrodes(ChargeCarrier.HOLE).getNCells() == NUMBER_OF_READOUT_STRIPS);
+            
+            assertTrue("[ " + this.getClass().getSimpleName() + " ]: Wrong number of sense electrodes found.",
+                    sensor.getSenseElectrodes(ChargeCarrier.HOLE).getNCells() == NUMBER_OF_SENSE_STRIPS);
+            LOGGER.info(sensor.toString());
         }
         LOGGER.info("Sensors were all initialized correctly.");
         

Modified: java/branches/HPSJAVA-409/detector-model/src/test/java/org/lcsim/geometry/compact/converter/lcdd/HPSTestRunTracker2014LCDDTest.java
 =============================================================================
--- java/branches/HPSJAVA-409/detector-model/src/test/java/org/lcsim/geometry/compact/converter/lcdd/HPSTestRunTracker2014LCDDTest.java	(original)
+++ java/branches/HPSJAVA-409/detector-model/src/test/java/org/lcsim/geometry/compact/converter/lcdd/HPSTestRunTracker2014LCDDTest.java	Wed Apr 27 11:11:32 2016
@@ -18,7 +18,7 @@
 {    
    public HPSTestRunTracker2014LCDDTest(String name)
    {
-   	super(name);
+    super(name);
    }
    
    public static TestSuite suite()

Modified: java/branches/HPSJAVA-409/detector-model/src/test/java/org/lcsim/geometry/compact/converter/lcdd/HPSTracker2014LCDDTest.java
 =============================================================================
--- java/branches/HPSJAVA-409/detector-model/src/test/java/org/lcsim/geometry/compact/converter/lcdd/HPSTracker2014LCDDTest.java	(original)
+++ java/branches/HPSJAVA-409/detector-model/src/test/java/org/lcsim/geometry/compact/converter/lcdd/HPSTracker2014LCDDTest.java	Wed Apr 27 11:11:32 2016
@@ -18,7 +18,7 @@
 {    
    public HPSTracker2014LCDDTest(String name)
    {
-   	super(name);
+    super(name);
    }
    
    public static TestSuite suite()

Modified: java/branches/HPSJAVA-409/detector-model/src/test/java/org/lcsim/geometry/compact/converter/lcdd/HPSTracker2014v1LCDDTest.java
 =============================================================================
--- java/branches/HPSJAVA-409/detector-model/src/test/java/org/lcsim/geometry/compact/converter/lcdd/HPSTracker2014v1LCDDTest.java	(original)
+++ java/branches/HPSJAVA-409/detector-model/src/test/java/org/lcsim/geometry/compact/converter/lcdd/HPSTracker2014v1LCDDTest.java	Wed Apr 27 11:11:32 2016
@@ -18,7 +18,7 @@
 {    
    public HPSTracker2014v1LCDDTest(String name)
    {
-   	super(name);
+    super(name);
    }
    
    public static TestSuite suite()

Modified: java/branches/HPSJAVA-409/detector-model/src/test/java/org/lcsim/geometry/compact/converter/lcdd/HPSTracker2014v1SurveyLCDDTest.java
 =============================================================================
--- java/branches/HPSJAVA-409/detector-model/src/test/java/org/lcsim/geometry/compact/converter/lcdd/HPSTracker2014v1SurveyLCDDTest.java	(original)
+++ java/branches/HPSJAVA-409/detector-model/src/test/java/org/lcsim/geometry/compact/converter/lcdd/HPSTracker2014v1SurveyLCDDTest.java	Wed Apr 27 11:11:32 2016
@@ -18,7 +18,7 @@
 {    
    public HPSTracker2014v1SurveyLCDDTest(String name)
    {
-   	super(name);
+    super(name);
    }
    
    public static TestSuite suite()

Modified: java/branches/HPSJAVA-409/detector-model/src/test/java/org/lcsim/geometry/subdetector/HPSTestRunTracker2014Test.java
 =============================================================================
--- java/branches/HPSJAVA-409/detector-model/src/test/java/org/lcsim/geometry/subdetector/HPSTestRunTracker2014Test.java	(original)
+++ java/branches/HPSJAVA-409/detector-model/src/test/java/org/lcsim/geometry/subdetector/HPSTestRunTracker2014Test.java	Wed Apr 27 11:11:32 2016
@@ -19,36 +19,36 @@
  */
 public class HPSTestRunTracker2014Test extends TestCase {
 
-	
-	Detector det;
-	public HPSTestRunTracker2014Test(String name) {
-		super(name);
-	}
-	
-	protected void setUp() throws Exception {
-		GeometryReader geometryReader = new GeometryReader();
-		geometryReader.setBuildDetailed(true);
-		String pathToCompactFile = "/org/lcsim/geometry/subdetector/HPSTestRunTracker2014.xml";
+    
+    Detector det;
+    public HPSTestRunTracker2014Test(String name) {
+        super(name);
+    }
+    
+    protected void setUp() throws Exception {
+        GeometryReader geometryReader = new GeometryReader();
+        geometryReader.setBuildDetailed(true);
+        String pathToCompactFile = "/org/lcsim/geometry/subdetector/HPSTestRunTracker2014.xml";
 
-		InputStream in = HPSTestRunTracker2014Test.class.getResourceAsStream(pathToCompactFile);
-		det = geometryReader.read(in);
-		
-		System.out.printf("%s: detector name converted: %s\n",this.getClass().getSimpleName(), det.getName());
-		
-		
-	}
-	
-	public void test() {
-		
-		
-//	    IDetectorElementStore store =  DetectorElementStore.getInstance();
-//	    System.out.printf("%s: Printing %d DE:\n",this.getClass().getSimpleName(), store.size());
-//	    System.out.printf("%s: %50s %40s %50s %50s\n",this.getClass().getSimpleName(), "name", "pos", "path","mother");
-//	    for(IDetectorElement e : store) {
-//	        System.out.printf("%s: %50s %40s %50s %50s \n",this.getClass().getSimpleName(), e.getName(),e.hasGeometryInfo()?e.getGeometry().getPosition().toString():" - ",e.hasGeometryInfo()?((PhysicalVolumePath)e.getGeometry().getPath()).toString():" - ",e.getParent()==null?" - ":e.getParent().getName());
-//	    }
-		
-		IDetectorElementStore store =  DetectorElementStore.getInstance();
+        InputStream in = HPSTestRunTracker2014Test.class.getResourceAsStream(pathToCompactFile);
+        det = geometryReader.read(in);
+        
+        System.out.printf("%s: detector name converted: %s\n",this.getClass().getSimpleName(), det.getName());
+        
+        
+    }
+    
+    public void test() {
+        
+        
+//      IDetectorElementStore store =  DetectorElementStore.getInstance();
+//      System.out.printf("%s: Printing %d DE:\n",this.getClass().getSimpleName(), store.size());
+//      System.out.printf("%s: %50s %40s %50s %50s\n",this.getClass().getSimpleName(), "name", "pos", "path","mother");
+//      for(IDetectorElement e : store) {
+//          System.out.printf("%s: %50s %40s %50s %50s \n",this.getClass().getSimpleName(), e.getName(),e.hasGeometryInfo()?e.getGeometry().getPosition().toString():" - ",e.hasGeometryInfo()?((PhysicalVolumePath)e.getGeometry().getPath()).toString():" - ",e.getParent()==null?" - ":e.getParent().getName());
+//      }
+        
+        IDetectorElementStore store =  DetectorElementStore.getInstance();
         System.out.printf("%s: Printing %d DE:\n",this.getClass().getSimpleName(), store.size());
         System.out.printf("%s: %50s %40s %50s %50s %s\n",this.getClass().getSimpleName(), "name", "pos", "path","mother", "expId");
         for(IDetectorElement e : store) {
@@ -58,8 +58,8 @@
                 expId = e.getExpandedIdentifier();
             System.out.printf("%s: %50s %40s %50s %50s %s\n",this.getClass().getSimpleName(), e.getName(),e.hasGeometryInfo()?e.getGeometry().getPosition().toString():" - ",e.hasGeometryInfo()?((PhysicalVolumePath)e.getGeometry().getPath()).toString():" - ",e.getParent()==null?" - ":e.getParent().getName(),expId==null?" no expId ":expId.toString());
         }
-		
-	}
+        
+    }
    
 
 }

Modified: java/branches/HPSJAVA-409/detector-model/src/test/resources/org/lcsim/geometry/subdetector/HPSTest.xml
 =============================================================================
--- java/branches/HPSJAVA-409/detector-model/src/test/resources/org/lcsim/geometry/subdetector/HPSTest.xml	(original)
+++ java/branches/HPSJAVA-409/detector-model/src/test/resources/org/lcsim/geometry/subdetector/HPSTest.xml	Wed Apr 27 11:11:32 2016
@@ -50,7 +50,7 @@
 <!--
         <constant name="tracking_region_radius" value="200.0*cm"/>
         <constant name="tracking_region_min" value="5.0*cm"/>
-        <constant name="tracking_region_zmax" value="100.0*cm"/>	
+        <constant name="tracking_region_zmax" value="100.0*cm"/>    
 
         <constant name="xCent1" value="10*cm" />
         <constant name="xCent2" value="20*cm" />

Modified: java/branches/HPSJAVA-409/detector-model/src/test/resources/org/lcsim/geometry/subdetector/HPSTestRunTracker2014.xml
 =============================================================================
--- java/branches/HPSJAVA-409/detector-model/src/test/resources/org/lcsim/geometry/subdetector/HPSTestRunTracker2014.xml	(original)
+++ java/branches/HPSJAVA-409/detector-model/src/test/resources/org/lcsim/geometry/subdetector/HPSTestRunTracker2014.xml	Wed Apr 27 11:11:32 2016
@@ -7,9 +7,9 @@
   </info>
   
   <define>
-	<!-- units -->
-	<constant name="mm" value="0.1*cm"/>
-	<constant name="inch" value="25.4*mm"/>
+    <!-- units -->
+    <constant name="mm" value="0.1*cm"/>
+    <constant name="inch" value="25.4*mm"/>
 
     <!-- world -->
     <constant name="world_side" value="500.0*cm" />
@@ -17,8 +17,8 @@
     <constant name="world_y" value="world_side" />
     <constant name="world_z" value="world_side" />
   
- 	 <!-- tracking region -->
- 	<constant name="tracking_region_radius" value="200.0*cm"/>
+     <!-- tracking region -->
+    <constant name="tracking_region_radius" value="200.0*cm"/>
     <constant name="tracking_region_min" value="5.0*cm"/>
     <constant name="tracking_region_zmax" value="131.8*cm"/>
  
@@ -34,7 +34,7 @@
   </materials>
   
   <display>
-	
+    
     <vis name="SensorVis" alpha="1.0" r="1.0" g="0.0" b="0.0" drawingStyle="wireframe" lineStyle="unbroken" showDaughters="true" visible="true"/>
     <vis name="ActiveSensorVis" alpha="1.0" r="1.0" g="0.0" b="0.0" drawingStyle="solid" lineStyle="unbroken" showDaughters="true" visible="true"/>
     <vis name="CarbonFiberVis" alpha="1.0" r="0.88" g="0.88" b="0.88" drawingStyle="solid" lineStyle="unbroken" showDaughters="true" visible="true"/>
@@ -48,7 +48,7 @@
     <vis name="BasePlateVis" alpha="1.0" r="0.35" g="0.35" b="0.35" drawingStyle="solid" lineStyle="dashed" showDaughters="true" visible="true"/>
     <vis name="LayerVis" alpha="0.0" r="0.0" g="0.0" b="1.0" drawingStyle="wireframe" showDaughters="true" visible="false"/>
     <vis name="ComponentVis" alpha="0.0" r="0.0" g="0.2" b="0.4" drawingStyle="solid" showDaughters="false" visible="false"/>
-	<vis name="BeamPlaneVis" alpha="1.0" r="1.0" g="1.0" b="1.0" drawingStyle="solid" lineStyle="unbroken" showDaughters="false" visible="true"/>
+    <vis name="BeamPlaneVis" alpha="1.0" r="1.0" g="1.0" b="1.0" drawingStyle="solid" lineStyle="unbroken" showDaughters="false" visible="true"/>
     
   </display>
   

Modified: java/branches/HPSJAVA-409/detector-model/target/antrun/build-main.xml
 =============================================================================
--- java/branches/HPSJAVA-409/detector-model/target/antrun/build-main.xml	(original)
+++ java/branches/HPSJAVA-409/detector-model/target/antrun/build-main.xml	Wed Apr 27 11:11:32 2016
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" ?>
 <project name="maven-antrun-" default="main"  >
 <target name="main">
-  <mkdir dir="/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/target/test-output"/>
+  <mkdir dir="/media/work/svn/hps-java/HPSJAVA-409/detector-model/target/test-output"/>
 </target>
 </project>

Modified: java/branches/HPSJAVA-409/detector-model/target/hps-detector-model-3.4.2-SNAPSHOT-bin.jar
 =============================================================================
Binary files - no diff available.

Modified: java/branches/HPSJAVA-409/detector-model/target/hps-detector-model-3.4.2-SNAPSHOT.jar
 =============================================================================
Binary files - no diff available.

Modified: java/branches/HPSJAVA-409/detector-model/target/maven-archiver/pom.properties
 =============================================================================
--- java/branches/HPSJAVA-409/detector-model/target/maven-archiver/pom.properties	(original)
+++ java/branches/HPSJAVA-409/detector-model/target/maven-archiver/pom.properties	Wed Apr 27 11:11:32 2016
@@ -1,5 +1,5 @@
 #Generated by Maven
-#Fri Dec 04 17:58:10 CET 2015
+#Fri Apr 08 16:49:44 PDT 2016
 version=3.4.2-SNAPSHOT
 groupId=org.hps
 artifactId=hps-detector-model

Modified: java/branches/HPSJAVA-409/detector-model/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
 =============================================================================
--- java/branches/HPSJAVA-409/detector-model/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst	(original)
+++ java/branches/HPSJAVA-409/detector-model/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst	Wed Apr 27 11:11:32 2016
@@ -1 +1,188 @@
+org/lcsim/geometry/compact/converter/HPSTracker2014GeometryDefinition$UChannelL13Top.class
+org/lcsim/geometry/compact/converter/HPSTracker2014LCDDBuilder.class
+org/lcsim/geometry/compact/converter/HPSTracker2014GeometryDefinition$ModuleL46Top.class
+org/lcsim/geometry/compact/converter/HPSTracker2014GeometryDefinition$UChannelPlate.class
+org/lcsim/geometry/compact/converter/HPSTracker2014GeometryDefinition$HalfModuleStereo.class
+org/lcsim/geometry/compact/converter/HPSTestRunTracker2014JavaBuilder.class
+org/lcsim/geometry/compact/converter/HPSTracker2014GeometryDefinition$UChannelL46TopSurveyBalls.class
+org/lcsim/detector/converter/compact/HPSTracker2014ConverterBase.class
+org/lcsim/detector/converter/compact/HPSTracker2Converter$ModuleParameters.class
+org/lcsim/geometry/compact/converter/lcdd/HPSEcal3$CrystalRange.class
+org/lcsim/geometry/compact/converter/HPSTracker2014GeometryDefinition$UChannelL46BottomPlate.class
+org/lcsim/geometry/compact/converter/SurveyVolumeImpl.class
+org/lcsim/detector/converter/compact/HPSTrackerConverter.class
+org/lcsim/detector/converter/compact/HPSTrackerConverter$ModuleParameters.class
+org/lcsim/geometry/compact/converter/HPSTestRunTracker2014GeometryDefinition$Hybrid.class
+org/hps/detector/ecal/EcalCrystalChannelMap.class
+org/hps/detector/svt/SvtDetectorSetup.class
+org/lcsim/geometry/subdetector/HPSTracker2014.class
+org/lcsim/geometry/compact/converter/HPSTracker2014GeometryDefinition$ModuleL5Bot.class
+org/lcsim/geometry/compact/converter/HPSTracker2014GeometryDefinition$UChannelL13BottomPlate.class
+org/lcsim/detector/converter/compact/subdetector/SvtStereoLayer.class
+org/lcsim/geometry/compact/converter/AlignmentCorrection.class
+org/lcsim/geometry/subdetector/HPSEcal3$NeighborMap.class
+org/lcsim/geometry/compact/converter/lcdd/HPSTracker2014Base.class
+org/lcsim/geometry/compact/converter/MilleParameter.class
+org/lcsim/geometry/compact/converter/LCDDSurveyVolume.class
+org/hps/detector/ecal/HPSEcalDetectorElement$NeighborDirection.class
+org/lcsim/detector/converter/compact/HPSMuonCalorimeterConverter.class
+org/lcsim/geometry/compact/converter/HPSTestRunTracker2014GeometryDefinition$TestRunColdBlockL45.class
+org/lcsim/geometry/compact/converter/HPSTestRunTracker2014GeometryDefinition$SupportTop.class
+org/lcsim/geometry/compact/converter/HPSTestRunTracker2014GeometryDefinition$HalfModuleComponent.class
+org/lcsim/geometry/compact/converter/HPSTracker2014GeometryDefinition$LongHalfModuleBundle.class
+org/lcsim/geometry/compact/converter/HPSTracker2014GeometryDefinition$ModuleL4Bot.class
+org/hps/detector/ecal/geo2015/crystal/Geant4Position.class
+org/lcsim/geometry/compact/converter/HPSTracker2014GeometryDefinition$LongAxialSlotHalfModule.class
+org/lcsim/geometry/subdetector/HPSTestRunTracker2014.class
+org/lcsim/geometry/compact/converter/HPSTestRunTracker2014GeometryDefinition$TestRunHalfModuleStereo.class
+org/lcsim/geometry/compact/converter/HPSTestRunTracker2014GeometryDefinition$TestRunModule.class
+org/lcsim/geometry/compact/converter/HPSTracker2014GeometryDefinition$ModuleL13.class
+org/lcsim/geometry/compact/converter/ReadSurveyOutput.class
+org/lcsim/geometry/compact/converter/HPSTestRunTracker2014GeometryDefinition$SupportPlateBottom.class
+org/lcsim/geometry/compact/converter/lcdd/HPSEcal4.class
+org/lcsim/geometry/compact/converter/HPSTestRunTracker2014GeometryDefinition$Sensor.class
+org/lcsim/geometry/subdetector/HPSEcal4.class
+org/lcsim/geometry/compact/converter/lcdd/HPSEcal.class
+org/hps/detector/ecal/CrystalRange.class
+org/lcsim/geometry/compact/converter/HPSTracker2014GeometryDefinition$LongAxialHoleHalfModule.class
+org/lcsim/detector/tracker/silicon/HpsTestRunSiSensor.class
+org/lcsim/geometry/compact/converter/HPSTracker2014GeometryDefinition$ModuleL6Top.class
+org/lcsim/geometry/subdetector/HPSEcal$XYSide.class
+org/lcsim/geometry/subdetector/HPSEcal$NeighborMap.class
+org/lcsim/geometry/compact/converter/HPSTestRunTracker2014LCDDBuilder.class
+org/lcsim/geometry/compact/converter/HPSTestRunTracker2014GeometryDefinition.class
+org/hps/detector/ecal/geo2015/geoutils/CenterMass.class
+org/lcsim/geometry/compact/converter/lcdd/HPSEcal3.class
+org/lcsim/geometry/compact/converter/HPSTrackerLCDDBuilder.class
+org/lcsim/geometry/compact/converter/HPSTracker2014GeometryDefinition$SupportRingL13KinMount.class
+org/lcsim/geometry/compact/converter/HPSTracker2014GeometryDefinition$UChannelL46.class
+org/lcsim/geometry/compact/converter/HPSTestRunTracker2014GeometryDefinition$SupportPlateTop.class
+org/lcsim/geometry/compact/converter/HPSTestRunTracker2014GeometryDefinition$HalfModuleLamination.class
+org/lcsim/geometry/compact/converter/SvtAlignmentConstantsReader.class
+org/lcsim/geometry/compact/converter/HPSTestRunTracker2014GeometryDefinition$TestRunColdBlockL13.class
+org/lcsim/geometry/compact/converter/SurveyVolume.class
+org/lcsim/geometry/compact/converter/HPSTracker2014JavaBuilder.class
+org/lcsim/geometry/compact/converter/HPSTracker2014GeometryDefinition$ModuleL3Top.class
+org/lcsim/geometry/compact/converter/HPSTestRunTracker2014GeometryDefinition$SupportBottom.class
+org/lcsim/geometry/compact/converter/lcdd/HPSTracker2$ModuleComponentParameters.class
+org/lcsim/geometry/compact/converter/HPSTestRunTracker2014GeometryDefinition$TestRunModuleL13.class
+org/lcsim/detector/converter/compact/subdetector/HpsTracker2.class
+org/lcsim/geometry/compact/converter/HPSTracker2014GeometryDefinition$ModuleL13Top.class
+org/lcsim/geometry/compact/converter/CompactSurveyVolume.class
+org/lcsim/geometry/compact/converter/SurveyVolumeVisualization.class
+org/lcsim/geometry/subdetector/HPSEcal3$XY.class
+org/lcsim/geometry/compact/converter/lcdd/HPSEcal2.class
+org/lcsim/geometry/compact/converter/HPSTracker2014GeometryDefinition$LongStereoHalfModule.class
+org/hps/detector/ecal/geo2015/ecal/EcalSurveyData.class
+org/lcsim/geometry/subdetector/HPSTracker.class
+org/lcsim/geometry/compact/converter/HPSTracker2014GeometryDefinition$UChannelL13BottomSurveyBalls.class
+org/lcsim/geometry/compact/converter/HPSTrackerGeometryDefinition.class
+org/lcsim/geometry/compact/converter/HPSTracker2014v1LCDDBuilder.class
+org/hps/detector/ecal/HPSEcalAPI.class
+org/lcsim/geometry/compact/converter/HPSTracker2014GeometryDefinition$UChannelL13Plate.class
+org/lcsim/geometry/compact/converter/JavaGhostSurveyVolume.class
+org/lcsim/geometry/compact/converter/HPSTrackerGeometryDefinition$TestRunModuleBundle.class
+org/lcsim/geometry/compact/converter/SurveyResult.class
+org/hps/detector/ecal/geo2015/ecal/EcalNominal.class
+org/lcsim/geometry/compact/converter/HPSTracker2014GeometryDefinition$LongAxialSlotHalfModuleBase.class
+org/lcsim/geometry/compact/converter/SurveyCoordinateSystem.class
+org/lcsim/geometry/compact/converter/HPSTracker2014GeometryDefinition$ModuleL1Bot.class
+org/hps/detector/ecal/geo2015/base/StatFunUtils.class
+org/hps/detector/ecal/geo2015/ecal/ECalRotationCalculator.class
+org/hps/detector/ecal/geo2015/ecal/Transformations.class
+org/lcsim/geometry/compact/converter/HPSTestRunTracker2014GeometryDefinition$TrackerEnvelope.class
+org/lcsim/geometry/compact/converter/HPSTracker2014GeometryDefinition$LongStereoHoleHalfModule.class
+org/lcsim/geometry/subdetector/HPSEcal3$CrystalRange.class
+org/lcsim/geometry/subdetector/HPSTracker2014v1.class
+org/lcsim/geometry/compact/converter/HPSTracker2014GeometryDefinition$PSVacuumChamber.class
+org/lcsim/detector/tracker/silicon/HpsSiSensor.class
+org/lcsim/detector/converter/compact/HPSTestRunTracker2014Converter.class
+org/lcsim/geometry/compact/converter/lcdd/HPSMuonCalorimeter2.class
+org/lcsim/geometry/compact/converter/HPSTracker2014GeometryDefinition$ModuleL6Bot.class
+org/lcsim/geometry/compact/converter/LCDDGhostSurveyVolume.class
+org/lcsim/geometry/compact/converter/lcdd/HPSTracker$ModuleComponentParameters.class
+org/lcsim/geometry/compact/converter/HPSTracker2014GeometryDefinition$UChannelL13TopSurveyBalls.class
+org/lcsim/geometry/compact/converter/HPSTestRunTracker2014GeometryDefinition$TestRunHalfModuleBundle.class
+org/hps/detector/ecal/geo2015/crystal/CrystalTaitBryanAngleCalculator.class
+org/lcsim/geometry/compact/converter/lcdd/HPSTracker.class
+org/lcsim/geometry/compact/converter/HPSTracker2014GeometryDefinition$UChannelL13TopPlate.class
+org/lcsim/geometry/compact/converter/lcdd/HPSMuonCalorimeter.class
+org/lcsim/geometry/compact/converter/HPSTracker2014GeometryDefinition$UChannelL13.class
+org/lcsim/geometry/compact/converter/HPSTracker2014GeometryDefinition$UChannelL46Bottom.class
+org/lcsim/detector/converter/compact/HPSTracker2014Converter.class
+org/hps/detector/ecal/EcalCrystal.class
+org/lcsim/geometry/subdetector/HPSTracker2.class
+org/lcsim/geometry/compact/converter/MilleParameter$Type.class
+org/lcsim/geometry/compact/converter/HPSTestRunTracker2014GeometryDefinition$TestRunHalfModuleAxial.class
+org/lcsim/geometry/compact/converter/HPSTestRunTracker2014GeometryDefinition$SupportPlate.class
 org/hps/detector/ecal/HPSEcalDetectorElement$1.class
+org/lcsim/geometry/compact/converter/IHPSTrackerLCDDBuilder.class
+org/lcsim/detector/converter/compact/HPSEcal2Converter.class
+org/lcsim/geometry/compact/converter/HPSTracker2014GeometryDefinition$UChannelL13Bottom.class
+org/lcsim/geometry/compact/converter/HPSTracker2014GeometryDefinition$ModuleL2Top.class
+org/lcsim/geometry/compact/converter/HPSTracker2014GeometryDefinition$SvtBoxBasePlate.class
+org/lcsim/geometry/compact/converter/HPSTrackerGeometryDefinition$TrackingVolume.class
+org/lcsim/geometry/compact/converter/HPSTestRunTracker2014GeometryDefinition$TestRunColdBlock.class
+org/lcsim/geometry/compact/converter/JavaSurveyVolume.class
+org/lcsim/geometry/compact/converter/HPSTrackerBuilder$BaseModuleBundle.class
+org/lcsim/geometry/compact/converter/HPSTracker2014GeometryDefinition$ModuleL13Bot.class
+org/lcsim/geometry/compact/converter/HPSTracker2014GeometryDefinition$ModuleL46.class
+org/lcsim/geometry/compact/converter/HPSTracker2014GeometryDefinition$SupportRingL13TopKinMount.class
+org/lcsim/geometry/compact/converter/HPSTracker2014GeometryDefinition$ModuleL3Bot.class
+org/lcsim/geometry/compact/converter/HPSTracker2014GeometryDefinition.class
+org/lcsim/detector/converter/compact/HPSTrackerConverter$ModuleComponentParameters.class
+org/lcsim/geometry/compact/converter/lcdd/HPSTracker2014.class
+org/hps/detector/ecal/geo2015/geoutils/Plane.class
+org/lcsim/geometry/compact/converter/HPSTracker2014GeometryDefinition$ModuleL5Top.class
+org/lcsim/geometry/compact/converter/HPSTracker2014GeometryDefinition$LongStereoSlotHalfModuleBase.class
+org/lcsim/geometry/compact/converter/HPSTestRunTracker2014GeometryDefinition$BasePlate.class
+org/lcsim/geometry/compact/converter/HPSTrackerBuilder$HalfModuleBundle.class
+org/lcsim/geometry/compact/converter/HPSTestRunTracker2014GeometryDefinition$ActiveSensor.class
+org/lcsim/geometry/compact/converter/HPSTracker2014GeometryDefinition$UChannelL46BottomSurveyBalls.class
+org/lcsim/geometry/compact/converter/HPSTracker2014v1GeometryDefinition$LongStereoSlotHalfModule.class
+org/lcsim/geometry/compact/converter/HPSTrackerJavaBuilder.class
+org/lcsim/geometry/subdetector/HPSEcal3.class
+org/lcsim/geometry/compact/converter/lcdd/HPSTestRunTracker2014.class
+org/hps/detector/ecal/geo2015/base/DataLoader.class
+org/lcsim/geometry/compact/converter/HPSTracker2014GeometryDefinition$LongHalfModule.class
+org/lcsim/detector/converter/compact/HPSEcalConverter.class
+org/lcsim/geometry/compact/converter/HPSTracker2014GeometryDefinition$SupportRingL13BottomKinMount.class
+org/lcsim/geometry/compact/converter/HPSTestRunTracker2014GeometryDefinition$BaseModule.class
+org/lcsim/geometry/compact/converter/lcdd/HPSTracker2.class
+org/lcsim/geometry/subdetector/HPSEcal.class
+org/lcsim/geometry/compact/converter/HPSTracker2014GeometryDefinition$HalfModuleAxial.class
+org/lcsim/geometry/compact/converter/HPSTracker2014GeometryDefinition$LongModuleBundle.class
+org/lcsim/geometry/compact/converter/HPSTracker2014GeometryDefinition$UChannelL46Plate.class
+org/lcsim/detector/converter/compact/HPSTracker2014v1Converter.class
+org/lcsim/geometry/compact/converter/HPSTracker2014GeometryDefinition$UChannelL46TopPlate.class
+org/lcsim/geometry/compact/converter/HPSTracker2014GeometryDefinition$ModuleL2Bot.class
+org/lcsim/geometry/compact/converter/HPSTestRunTracker2014GeometryDefinition$TestRunModuleL45.class
+org/lcsim/geometry/compact/converter/HPSTracker2014GeometryDefinition$SvtBox.class
+org/lcsim/geometry/compact/converter/HPSTestRunTracker2014GeometryDefinition$CSupport.class
+org/hps/detector/ecal/HPSEcalDetectorElement.class
+org/lcsim/geometry/compact/converter/HPSTracker2014GeometryDefinition$UChannelL46Top.class
+org/lcsim/detector/converter/compact/HPSEcal4Converter.class
+org/lcsim/geometry/compact/converter/HPSTracker2014v1GeometryDefinition$LongAxialSlotHalfModule.class
+org/lcsim/geometry/compact/converter/HPSTracker2014GeometryDefinition$HalfLongModuleLamination.class
+org/lcsim/geometry/compact/converter/lcdd/HPSTracker2$ModuleParameters.class
+org/lcsim/geometry/compact/converter/HPSTracker2014GeometryDefinition$SupportRing.class
+org/lcsim/geometry/compact/converter/HPSTestRunTracker2014GeometryDefinition$TestRunHalfModule.class
+org/hps/detector/ecal/geo2015/geoutils/Vector.class
+org/hps/detector/ecal/geo2015/geoutils/Line.class
+org/hps/detector/ecal/geo2015/crystal/Crystal.class
+org/lcsim/geometry/compact/converter/HPSTracker2014GeometryDefinition$ModuleL46Bot.class
+org/lcsim/detector/converter/compact/HPSTracker2Converter.class
+org/lcsim/geometry/compact/converter/HPSTracker2014v1GeometryDefinition.class
+org/lcsim/geometry/compact/converter/HPSTracker2014GeometryDefinition$LongStereoSlotHalfModule.class
+org/lcsim/detector/converter/compact/HPSEcal3Converter.class
+org/lcsim/geometry/compact/converter/HPSTrackerBuilder.class
+org/lcsim/geometry/compact/converter/HPSTestRunTracker2014GeometryDefinition$CarbonFiber.class
+org/lcsim/geometry/compact/converter/IHPSTrackerJavaBuilder.class
+org/lcsim/geometry/compact/converter/HPSTracker2014GeometryDefinition$ModuleL4Top.class
+org/lcsim/geometry/compact/converter/HPSTracker2014v1JavaBuilder.class
+org/lcsim/geometry/compact/converter/lcdd/HPSTracker$ModuleParameters.class
+org/lcsim/geometry/subdetector/HPSEcal2.class
+org/lcsim/detector/converter/compact/HPSTracker2Converter$ModuleComponentParameters.class
+org/lcsim/geometry/compact/converter/HPSTracker2014GeometryDefinition$ModuleL1Top.class
+org/lcsim/geometry/compact/converter/lcdd/HPSTracker2014v1.class
+org/lcsim/geometry/subdetector/HPSMuonCalorimeter.class

Modified: java/branches/HPSJAVA-409/detector-model/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
 =============================================================================
--- java/branches/HPSJAVA-409/detector-model/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst	(original)
+++ java/branches/HPSJAVA-409/detector-model/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst	Wed Apr 27 11:11:32 2016
@@ -1,92 +1,92 @@
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/hps/detector/ecal/geo2015/ecal/EcalNominal.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/lcsim/detector/converter/compact/package-info.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/lcsim/detector/converter/compact/HPSTracker2014ConverterBase.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTestRunTracker2014GeometryDefinition.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/hps/detector/ecal/geo2015/geoutils/Plane.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/subdetector/package-info.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/subdetector/HPSTracker2014.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/hps/detector/svt/SvtDetectorSetup.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTestRunTracker2014LCDDBuilder.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/lcdd/HPSTracker2014v1.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/LCDDSurveyVolume.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/IHPSTrackerLCDDBuilder.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/CompactSurveyVolume.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTestRunTracker2014JavaBuilder.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/hps/detector/ecal/geo2015/crystal/Crystal.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/lcdd/HPSEcal3.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/lcsim/detector/converter/compact/HPSTracker2Converter.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/SvtAlignmentConstantsReader.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/lcsim/detector/converter/compact/subdetector/SvtStereoLayer.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTracker2014GeometryDefinition.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTrackerLCDDBuilder.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/lcdd/HPSTestRunTracker2014.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/lcdd/HPSTracker2014Base.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/hps/detector/ecal/geo2015/crystal/Geant4Position.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/SurveyCoordinateSystem.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTracker2014v1GeometryDefinition.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/subdetector/HPSTracker2.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/MilleParameter.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/hps/detector/ecal/HPSEcalDetectorElement.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/lcsim/detector/converter/compact/HPSTrackerConverter.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/subdetector/HPSEcal2.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/hps/detector/ecal/geo2015/crystal/CrystalEulerAngleCalculator.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/package-info.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/lcsim/detector/converter/compact/HPSEcalConverter.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/subdetector/HPSMuonCalorimeter.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/lcdd/HPSMuonCalorimeter2.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/hps/detector/ecal/geo2015/base/FunCheatJava.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/subdetector/HPSEcal.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/hps/detector/ecal/EcalCrystal.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/hps/detector/ecal/geo2015/ecal/Transformations.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/lcsim/detector/converter/compact/HPSEcal3Converter.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/hps/detector/ecal/geo2015/base/DataLoader.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/hps/detector/ecal/geo2015/geoutils/CenterMass.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/lcdd/HPSTracker.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/lcdd/HPSEcal4.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/hps/detector/ecal/geo2015/geoutils/Line.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/lcdd/HPSMuonCalorimeter.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/lcdd/package-info.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/lcsim/detector/converter/compact/HPSEcal4Converter.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/hps/detector/ecal/CrystalRange.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/lcsim/detector/converter/compact/subdetector/HpsTracker2.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/hps/detector/ecal/geo2015/crystal/package-info.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTrackerGeometryDefinition.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/AlignmentCorrection.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/lcsim/detector/tracker/silicon/HpsTestRunSiSensor.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/hps/detector/ecal/EcalCrystalChannelMap.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/hps/detector/ecal/geo2015/base/package-info.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/subdetector/HPSEcal4.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/lcsim/detector/converter/compact/HPSTracker2014v1Converter.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/hps/detector/ecal/geo2015/ecal/package-info.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/lcsim/detector/converter/compact/HPSTracker2014Converter.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/LCDDGhostSurveyVolume.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/subdetector/HPSTestRunTracker2014.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTracker2014v1LCDDBuilder.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/hps/detector/ecal/geo2015/ecal/EcalSurveyData.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTrackerJavaBuilder.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTracker2014JavaBuilder.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/hps/detector/ecal/geo2015/ecal/ECalRotationCalculator.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/lcsim/detector/converter/compact/HPSMuonCalorimeterConverter.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/lcsim/detector/converter/compact/HPSEcal2Converter.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/lcdd/HPSEcal.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTrackerBuilder.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/SurveyVolume.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTracker2014LCDDBuilder.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTracker2014v1JavaBuilder.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/lcsim/detector/tracker/silicon/HpsSiSensor.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/JavaGhostSurveyVolume.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/IHPSTrackerJavaBuilder.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/ReadSurveyOutput.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/subdetector/HPSTracker.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/SurveyResult.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/hps/detector/ecal/geo2015/geoutils/Vector.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/SurveyVolumeVisualization.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/hps/detector/ecal/HPSEcalAPI.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/subdetector/HPSEcal3.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/lcdd/HPSTracker2.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/lcsim/detector/converter/compact/HPSTestRunTracker2014Converter.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/lcdd/HPSEcal2.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/lcdd/HPSTracker2014.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/SurveyVolumeImpl.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/subdetector/HPSTracker2014v1.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/JavaSurveyVolume.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTrackerJavaBuilder.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/lcsim/detector/tracker/silicon/HpsTestRunSiSensor.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/subdetector/HPSEcal4.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTestRunTracker2014GeometryDefinition.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/lcsim/detector/converter/compact/HPSTracker2014Converter.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/lcsim/detector/converter/compact/HPSTracker2014v1Converter.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/lcsim/detector/converter/compact/HPSEcalConverter.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/lcsim/detector/converter/compact/HPSEcal3Converter.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/lcdd/HPSEcal2.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/hps/detector/ecal/EcalCrystal.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/subdetector/HPSTestRunTracker2014.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/lcsim/detector/converter/compact/HPSEcal2Converter.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/lcsim/detector/tracker/silicon/HpsSiSensor.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/lcdd/HPSEcal3.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/lcsim/detector/converter/compact/HPSTestRunTracker2014Converter.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTestRunTracker2014LCDDBuilder.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/lcdd/HPSEcal4.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/hps/detector/ecal/geo2015/ecal/package-info.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/lcsim/detector/converter/compact/HPSTracker2Converter.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTracker2014v1JavaBuilder.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTrackerGeometryDefinition.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/package-info.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/SurveyVolume.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/subdetector/HPSEcal2.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/hps/detector/ecal/geo2015/crystal/Geant4Position.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTracker2014v1GeometryDefinition.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/lcsim/detector/converter/compact/subdetector/HpsTracker2.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTracker2014JavaBuilder.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/SurveyCoordinateSystem.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTracker2014LCDDBuilder.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/ReadSurveyOutput.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/lcdd/HPSTracker2.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTestRunTracker2014JavaBuilder.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/lcdd/package-info.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/hps/detector/ecal/geo2015/base/DataLoader.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/lcdd/HPSTracker2014v1.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTracker2014v1LCDDBuilder.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/JavaGhostSurveyVolume.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/hps/detector/ecal/geo2015/ecal/Transformations.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/hps/detector/ecal/geo2015/geoutils/CenterMass.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/lcsim/detector/converter/compact/HPSTracker2014ConverterBase.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/subdetector/package-info.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/lcsim/detector/converter/compact/HPSEcal4Converter.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/subdetector/HPSTracker2014.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/subdetector/HPSMuonCalorimeter.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/lcdd/HPSEcal.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/hps/detector/ecal/geo2015/crystal/Crystal.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/hps/detector/ecal/HPSEcalDetectorElement.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/SvtAlignmentConstantsReader.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTrackerBuilder.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/subdetector/HPSTracker2.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/lcdd/HPSMuonCalorimeter.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/hps/detector/ecal/geo2015/crystal/CrystalTaitBryanAngleCalculator.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/hps/detector/ecal/EcalCrystalChannelMap.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/IHPSTrackerJavaBuilder.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/subdetector/HPSTracker2014v1.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/lcdd/HPSTracker.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/hps/detector/ecal/CrystalRange.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/hps/detector/ecal/geo2015/geoutils/Line.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/lcsim/detector/converter/compact/package-info.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/hps/detector/ecal/geo2015/geoutils/Vector.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/lcsim/detector/converter/compact/HPSMuonCalorimeterConverter.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTrackerLCDDBuilder.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/hps/detector/ecal/geo2015/base/StatFunUtils.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/MilleParameter.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/hps/detector/ecal/geo2015/crystal/package-info.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/SurveyResult.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/lcdd/HPSMuonCalorimeter2.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/hps/detector/ecal/geo2015/ecal/EcalNominal.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/AlignmentCorrection.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/lcsim/detector/converter/compact/subdetector/SvtStereoLayer.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/LCDDGhostSurveyVolume.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/hps/detector/ecal/HPSEcalAPI.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/lcsim/detector/converter/compact/HPSTrackerConverter.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/HPSTracker2014GeometryDefinition.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/hps/detector/ecal/geo2015/geoutils/Plane.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/hps/detector/ecal/geo2015/ecal/EcalSurveyData.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/CompactSurveyVolume.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/SurveyVolumeImpl.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/hps/detector/svt/SvtDetectorSetup.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/subdetector/HPSEcal.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/hps/detector/ecal/geo2015/ecal/ECalRotationCalculator.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/JavaSurveyVolume.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/lcdd/HPSTracker2014Base.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/subdetector/HPSEcal3.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/hps/detector/ecal/geo2015/base/package-info.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/subdetector/HPSTracker.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/lcdd/HPSTracker2014.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/lcdd/HPSTestRunTracker2014.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/SurveyVolumeVisualization.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/IHPSTrackerLCDDBuilder.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/main/java/org/lcsim/geometry/compact/converter/LCDDSurveyVolume.java

Modified: java/branches/HPSJAVA-409/detector-model/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst
 =============================================================================
--- java/branches/HPSJAVA-409/detector-model/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst	(original)
+++ java/branches/HPSJAVA-409/detector-model/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst	Wed Apr 27 11:11:32 2016
@@ -1 +1,16 @@
+org/hps/detector/svt/SvtDetectorSetupTest.class
 org/lcsim/detector/converter/compact/HPSEcal4ConverterTest.class
+org/lcsim/detector/converter/compact/HPSMuonCalorimeterTest.class
+org/lcsim/detector/converter/compact/HPSTracker2ConverterTest.class
+org/lcsim/geometry/compact/converter/lcdd/HPSTracker2014LCDDTest.class
+org/lcsim/geometry/subdetector/HPSTestRunTracker2014Test.class
+org/hps/detector/svt/TestRunSvtDetectorSetupTest.class
+org/hps/detector/svt/SvtDaqMappingTest.class
+org/lcsim/geometry/compact/converter/lcdd/HPSTracker2014v1SurveyLCDDTest.class
+org/lcsim/geometry/compact/converter/lcdd/HPSTracker2014v1LCDDTest.class
+org/lcsim/geometry/subdetector/HPSTracker2014Test.class
+org/lcsim/detector/converter/compact/HpsTestRunSiSensorConverterTest.class
+org/lcsim/geometry/compact/converter/lcdd/HPSTestRunTracker2014LCDDTest.class
+org/hps/detector/ecal/HPSEcalAPITest.class
+org/hps/detector/SvtAlignmentTest.class
+org/lcsim/geometry/compact/converter/lcdd/HPSEcal4LCDDTest.class

Modified: java/branches/HPSJAVA-409/detector-model/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst
 =============================================================================
--- java/branches/HPSJAVA-409/detector-model/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst	(original)
+++ java/branches/HPSJAVA-409/detector-model/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst	Wed Apr 27 11:11:32 2016
@@ -1,16 +1,16 @@
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/test/java/org/lcsim/geometry/compact/converter/lcdd/HPSTestRunTracker2014LCDDTest.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/test/java/org/hps/detector/ecal/HPSEcalAPITest.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/test/java/org/hps/detector/svt/SvtDetectorSetupTest.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/test/java/org/hps/detector/SvtAlignmentTest.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/test/java/org/lcsim/detector/converter/compact/HPSEcal4ConverterTest.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/test/java/org/lcsim/geometry/subdetector/HPSTestRunTracker2014Test.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/test/java/org/hps/detector/svt/SvtDaqMappingTest.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/test/java/org/lcsim/geometry/compact/converter/lcdd/HPSTracker2014v1LCDDTest.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/test/java/org/lcsim/geometry/compact/converter/lcdd/HPSEcal4LCDDTest.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/test/java/org/lcsim/detector/converter/compact/HpsTestRunSiSensorConverterTest.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/test/java/org/hps/detector/svt/TestRunSvtDetectorSetupTest.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/test/java/org/lcsim/geometry/compact/converter/lcdd/HPSTracker2014v1SurveyLCDDTest.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/test/java/org/lcsim/geometry/subdetector/HPSTracker2014Test.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/test/java/org/lcsim/geometry/compact/converter/lcdd/HPSTracker2014LCDDTest.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/test/java/org/lcsim/detector/converter/compact/HPSMuonCalorimeterTest.java
-/projet/nucleon2/annie/HPS/withHPS_Java/SENA/hps_trunk_dev/HPSJAVA-409/detector-model/src/test/java/org/lcsim/detector/converter/compact/HPSTracker2ConverterTest.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/test/java/org/lcsim/geometry/compact/converter/lcdd/HPSTracker2014v1LCDDTest.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/test/java/org/hps/detector/SvtAlignmentTest.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/test/java/org/hps/detector/svt/SvtDaqMappingTest.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/test/java/org/lcsim/detector/converter/compact/HpsTestRunSiSensorConverterTest.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/test/java/org/lcsim/geometry/compact/converter/lcdd/HPSTracker2014v1SurveyLCDDTest.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/test/java/org/lcsim/geometry/compact/converter/lcdd/HPSTracker2014LCDDTest.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/test/java/org/lcsim/detector/converter/compact/HPSEcal4ConverterTest.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/test/java/org/hps/detector/svt/SvtDetectorSetupTest.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/test/java/org/hps/detector/svt/TestRunSvtDetectorSetupTest.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/test/java/org/lcsim/geometry/compact/converter/lcdd/HPSTestRunTracker2014LCDDTest.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/test/java/org/lcsim/geometry/compact/converter/lcdd/HPSEcal4LCDDTest.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/test/java/org/lcsim/geometry/subdetector/HPSTestRunTracker2014Test.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/test/java/org/lcsim/geometry/subdetector/HPSTracker2014Test.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/test/java/org/hps/detector/ecal/HPSEcalAPITest.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/test/java/org/lcsim/detector/converter/compact/HPSMuonCalorimeterTest.java
+/media/work/svn/hps-java/HPSJAVA-409/detector-model/src/test/java/org/lcsim/detector/converter/compact/HPSTracker2ConverterTest.java

Modified: java/branches/HPSJAVA-409/distribution/pom.xml
 =============================================================================
--- java/branches/HPSJAVA-409/distribution/pom.xml	(original)
+++ java/branches/HPSJAVA-409/distribution/pom.xml	Wed Apr 27 11:11:32 2016
@@ -13,7 +13,7 @@
         <groupId>org.hps</groupId>
         <artifactId>hps-parent</artifactId>
         <relativePath>../parent/pom.xml</relativePath>
-        <version>3.4.2-SNAPSHOT</version>
+        <version>3.9-SNAPSHOT</version>
     </parent>    
     <scm>
         <url>http://java.freehep.org/svn/repos/hps/list/java/trunk/distribution/</url>
@@ -80,7 +80,7 @@
                         <binFileExtensions>
                                 <unix>.sh</unix>
                             </binFileExtensions>
-                            <extraJvmArguments>-Djava.util.logging.config.class=org.hps.logging.config.DefaultLoggingConfig</extraJvmArguments>
+                            <extraJvmArguments>-Xmx2g -Djava.util.logging.config.class=org.hps.logging.config.DefaultLoggingConfig</extraJvmArguments>
                             <programs>
                                 <program>
                                     <mainClass>org.hps.evio.EvioToLcio</mainClass>
@@ -88,35 +88,31 @@
                                 </program>
                                 <program>
                                     <mainClass>org.hps.job.JobManager</mainClass>
-                                    <id>job</id>
+                                    <id>job-manager</id>
                                 </program>
                                 <program>
                                     <mainClass>org.hps.conditions.cli.CommandLineTool</mainClass>
-                                    <id>conddb</id>
-                                </program>
-                                <program>
-                                    <mainClass>org.hps.crawler.DatacatCrawler</mainClass>
-                                    <id>crawler</id>
+                                    <id>conditions-cli</id>
                                 </program>
                                 <program>
                                     <mainClass>org.hps.run.database.RunDatabaseCommandLine</mainClass>
-                                    <id>rundb</id>
+                                    <id>run-database-cli</id>
                                 </program>
                                 <program>
                                     <mainClass>org.hps.monitoring.application.Main</mainClass>
-                                    <id>monapp</id>
+                                    <id>monitoring-app</id>
                                 </program>
                                 <program>
                                     <mainClass>org.lcsim.geometry.compact.converter.Main</mainClass>
-                                    <id>detcnv</id>
+                                    <id>detector-converter</id>
                                 </program>
                                 <program>
                                     <mainClass>org.hps.record.evio.EvioFileProducer</mainClass>
-                                    <id>evio_file_producer</id>
+                                    <id>evio-file-producer</id>
                                 </program>
                                 <program>
                                     <mainClass>org.jlab.coda.et.apps.StartEt</mainClass>
-                                    <id>et_server</id>
+                                    <id>et-server</id>
                                     <commandLineArguments>
                                         <commandLineArgument>-f</commandLineArgument>
                                         <commandLineArgument>ETBuffer</commandLineArgument>
@@ -124,6 +120,18 @@
                                         <commandLineArgument>20000</commandLineArgument>
                                         <commandLineArgument>-v</commandLineArgument>
                                     </commandLineArguments>
+                                </program>
+                                <program>
+                                    <mainClass>org.hps.crawler.MetadataWriter</mainClass>
+                                    <id>dc-create-metadata</id>
+                                </program>
+                                <program>
+                                    <mainClass>org.hps.crawler.DatacatAddFile</mainClass>
+                                    <id>dc-add-file</id>
+                                </program>
+                                <program>
+                                    <mainClass>org.hps.crawler.DatacatCrawler</mainClass>
+                                    <id>dc-crawler</id>
                                 </program>
                             </programs>
                         </configuration>

Modified: java/branches/HPSJAVA-409/distribution/src/main/java/org/hps/HPSJavaProperties.java
 =============================================================================
--- java/branches/HPSJAVA-409/distribution/src/main/java/org/hps/HPSJavaProperties.java	(original)
+++ java/branches/HPSJAVA-409/distribution/src/main/java/org/hps/HPSJavaProperties.java	Wed Apr 27 11:11:32 2016
@@ -82,6 +82,11 @@
         return this.properties.getProperty("timestamp");
     }
 
+    /**
+     * Convert this object to a string.
+     *
+     * @return this object converted to a string
+     */
     @Override
     public String toString() {
         final StringBuffer sb = new StringBuffer();

Modified: java/branches/HPSJAVA-409/ecal-event-display/pom.xml
 =============================================================================
--- java/branches/HPSJAVA-409/ecal-event-display/pom.xml	(original)
+++ java/branches/HPSJAVA-409/ecal-event-display/pom.xml	Wed Apr 27 11:11:32 2016
@@ -7,7 +7,7 @@
         <groupId>org.hps</groupId>
         <artifactId>hps-parent</artifactId>
         <relativePath>../parent/pom.xml</relativePath>
-        <version>3.4.2-SNAPSHOT</version>
+        <version>3.9-SNAPSHOT</version>
     </parent>
     <scm>
         <url>http://java.freehep.org/svn/repos/hps/list/java/trunk/ecal-event-display/</url>

Modified: java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/event/Association.java
 =============================================================================
--- java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/event/Association.java	(original)
+++ java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/event/Association.java	Wed Apr 27 11:11:32 2016
@@ -10,52 +10,52 @@
  * @author Kyle McCarty
  */
 public final class Association {
-	private final Point parent;
-	private final Point child;
-	private final Color highlight;
-	
-	/**
-	 * <b>Association</b><br/><br/>
-	 * <code>public <b>Association</b>(Point parentCrystal, Point childCrystal, Color highlightColor)</code><br/><br/>
-	 * Creates an association between a child crystal and a parent
-	 * crystal.
-	 * @param parentCrystal - The crystal with which the child crystal
-	 * is connected.
-	 * @param childCrystal - The connected crystal.
-	 * @param highlightColor - The color in which the child crystal
-	 * should be highlighted.
-	 */
-	public Association(Point parentCrystal, Point childCrystal, Color highlightColor) {
-		parent = parentCrystal;
-		child = childCrystal;
-		highlight = highlightColor;
-	}
-	
-	/**
-	 * <b>getChildCrystal</b><br/><br/>
-	 * <code>public Point <b>getChildCrystal</b>()</code><br/><br/>
-	 * Indicates the indices for the child crystal.
-	 * @return Returns the child crystal's indices in a <code>Point
-	 * </code> object.
-	 */
-	public Point getChildCrystal() { return child; }
-	
-	/**
-	 * <b>getHighlight</b><br/><br/>
-	 * <code>public Color <b>getHighlight</b>()</code><br/><br/>
-	 * Gets the color with which the child crystal should be highlighted
-	 * whenever the parent crystal is selected.
-	 * @return Returns the highlight color as a <code>Color</code> object.
-	 */
-	public Color getHighlight() { return highlight; }
-	
-	/**
-	 * <b>getParentCrystal</b><br/><br/>
-	 * <code>public Point <b>getParentCrystal</b>()</code><br/><br/>
-	 * Indicates the indices for the parent crystal with which the
-	 * child crystal is connected.
-	 * @return Returns the parent crystal's indices in a <code>Point
-	 * </code> object.
-	 */
-	public Point getParentCrystal() { return parent; }
+    private final Point parent;
+    private final Point child;
+    private final Color highlight;
+    
+    /**
+     * <b>Association</b><br/><br/>
+     * <code>public <b>Association</b>(Point parentCrystal, Point childCrystal, Color highlightColor)</code><br/><br/>
+     * Creates an association between a child crystal and a parent
+     * crystal.
+     * @param parentCrystal - The crystal with which the child crystal
+     * is connected.
+     * @param childCrystal - The connected crystal.
+     * @param highlightColor - The color in which the child crystal
+     * should be highlighted.
+     */
+    public Association(Point parentCrystal, Point childCrystal, Color highlightColor) {
+        parent = parentCrystal;
+        child = childCrystal;
+        highlight = highlightColor;
+    }
+    
+    /**
+     * <b>getChildCrystal</b><br/><br/>
+     * <code>public Point <b>getChildCrystal</b>()</code><br/><br/>
+     * Indicates the indices for the child crystal.
+     * @return Returns the child crystal's indices in a <code>Point
+     * </code> object.
+     */
+    public Point getChildCrystal() { return child; }
+    
+    /**
+     * <b>getHighlight</b><br/><br/>
+     * <code>public Color <b>getHighlight</b>()</code><br/><br/>
+     * Gets the color with which the child crystal should be highlighted
+     * whenever the parent crystal is selected.
+     * @return Returns the highlight color as a <code>Color</code> object.
+     */
+    public Color getHighlight() { return highlight; }
+    
+    /**
+     * <b>getParentCrystal</b><br/><br/>
+     * <code>public Point <b>getParentCrystal</b>()</code><br/><br/>
+     * Indicates the indices for the parent crystal with which the
+     * child crystal is connected.
+     * @return Returns the parent crystal's indices in a <code>Point
+     * </code> object.
+     */
+    public Point getParentCrystal() { return parent; }
 }

Modified: java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/event/Cluster.java
 =============================================================================
--- java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/event/Cluster.java	(original)
+++ java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/event/Cluster.java	Wed Apr 27 11:11:32 2016
@@ -11,161 +11,161 @@
  * @author Kyle McCarty
  */
 public final class Cluster {
-	private final Point center;
-	private final double energy;
-	private final double time;
-	private ArrayList<Point> hitList = new ArrayList<Point>();
-	private ArrayList<Point> shareList = new ArrayList<Point>();
-	
-	/**
-	 * Creates a new cluster. All clusters are required to have a
-	 * cluster center.
-	 * @param ix - The cluster center's x-index.
-	 * @param iy - The cluster center's y-index.
-	 */
-	public Cluster(int ix, int iy) { this(new Point(ix, iy), Double.NaN, Double.NaN); }
-	
-	/**
-	 * Creates a new cluster. All clusters are required to have a seed
-	 * hit.
-	 * @param clusterCenter - The <code>Point</code> object indicating in
-	 * which crystal the seed hit occurred.
-	 */
-	public Cluster(Point clusterCenter) { this(clusterCenter, Double.NaN, Double.NaN); }
-	
-	/**
-	 * Creates a new cluster. All clusters are required to have a
-	 * cluster center.
-	 * @param ix - The cluster center's x-index.
-	 * @param iy - The cluster center's y-index.
-	 * @param energy - The cluster's energy.
-	 */
-	public Cluster(int ix, int iy, double energy) { this(new Point(ix, iy), energy, Double.NaN); }
-	
-	/**
-	 * Creates a new cluster. All clusters are required to have a
-	 * cluster center.
-	 * @param ix - The cluster center's x-index.
-	 * @param iy - The cluster center's y-index.
-	 * @param energy - The cluster's energy.
-	 * @param time - The cluster's time-stamp.
-	 */
-	public Cluster(int ix, int iy, double energy, double time) { this(new Point(ix, iy), energy, time); }
-	
-	/**
-	 * Creates a new cluster. All clusters are required to have a seed
-	 * hit.
-	 * @param clusterCenter - The <code>Point</code> object indicating in
-	 * which crystal the seed hit occurred.
-	 * @param energy - The cluster's energy.
-	 */
-	public Cluster(Point clusterCenter, double energy) {
-		this(clusterCenter, energy, Double.NaN);
-	}
-	
-	/**
-	 * Creates a new cluster. All clusters are required to have a seed
-	 * hit.
-	 * @param clusterCenter - The <code>Point</code> object indicating in
-	 * which crystal the seed hit occurred.
-	 * @param energy - The cluster's energy.
-	 * @param time - The cluster's time-stamp.
-	 */
-	public Cluster(Point clusterCenter, double energy, double time) {
-		center = clusterCenter;
-		this.energy = energy;
-		this.time = time;
-	}
-	
-	/**
-	 * Adds an <code>Point</code> to the list of this cluster's
-	 * component hits.
-	 * @param ix - The component hit's x-coordinate.
-	 * @param iy - The component hit's y-coordinate.
-	 */
-	public void addComponentHit(int ix, int iy) { hitList.add(new Point(ix, iy)); }
-	
-	/**
-	 * Adds an <code>Point</code> to the list of this cluster's
-	 * component hits.
-	 * @param eHit - The <code>Point</code> object indicating in which
-	 * crystal the hit occurred.
-	 */
-	public void addComponentHit(Point eHit) { hitList.add(eHit); }
-	
-	/**
-	 * Adds an <code>Point</code> to the list of this cluster's shared
-	 * hits.
-	 * @param ix - The shared hit's x-coordinate.
-	 * @param iy - The shared hit's y-coordinate.
-	 */
-	public void addSharedHit(int ix, int iy) { shareList.add(new Point(ix, iy)); }
-	
-	/**
-	 * Adds an <code>Point</code> to the list of this cluster's shared
-	 * hits.
-	 * @param eHit - The <code>Point</code> object indicating in which
-	 * crystal the hit occurred.
-	 */
-	public void addSharedHit(Point eHit) { shareList.add(eHit); }
-	
-	/**
-	 * Gets the hit representing the cluster center.
-	 * @return Returns the cluster center hit as an <code>Point</code>.
-	 */
-	public Point getClusterCenter() { return center; }
-	
-	/**
-	 * Gets the cluster's energy, if it was defined when the cluster
-	 * was constructed.
-	 * @return Returns the energy of the cluster if it was defined,
-	 * and <code>NaN</code> otherwise.
-	 */
-	public double getClusterEnergy() { return energy; }
-	
-	/**
-	 * Gets the time stamp for the cluster in nanoseconds.
-	 * @return Returns the cluster's time stamp.
-	 */
-	public double getClusterTime() { return time; }
-	
-	/**
-	 * Indicates how many component hits compose this cluster. Note
-	 * that this does not include the seed hit or shared hits.
-	 * @return Returns the number of component hits in the cluster
-	 * as an <code>int</code>.
-	 */
-	public int getComponentHitCount() { return hitList.size(); }
-	
-	/**
-	 * Gets the list of hits that make up the cluster, exempting the
-	 * seed hit and shared hits.
-	 * @return Returns the cluster hits as a <code>List</code> object
-	 * composed of <code>Point</code> objects.
-	 */
-	public List<Point> getComponentHits() { return hitList; }
-	
-	/**
-	 * Indicates how many total hits compose this cluster. This includes
-	 * component hits, shared hits, and the seed hit.
-	 * @return Returns the number of component hits in the cluster
-	 * as an <code>int</code>.
-	 */
-	public int getHitCount() { return hitList.size() + shareList.size() + 1; }
-	
-	/**
-	 * Indicates how many shared hits compose this cluster. Note that
-	 * this does not include the seed hit or component hits.
-	 * @return Returns the number of shared hits in the cluster as an
-	 * <code>int</code>.
-	 */
-	public int getSharedHitCount() { return shareList.size(); }
-	
-	/**
-	 * Gets the list of hits that make up the cluster, exempting the
-	 * seed hit and component hits.
-	 * @return Returns the shared hits as a <code>List</code> object
-	 * composed of <code>Point</code> objects.
-	 */
-	public List<Point> getSharedHits() { return shareList; }
+    private final Point center;
+    private final double energy;
+    private final double time;
+    private ArrayList<Point> hitList = new ArrayList<Point>();
+    private ArrayList<Point> shareList = new ArrayList<Point>();
+    
+    /**
+     * Creates a new cluster. All clusters are required to have a
+     * cluster center.
+     * @param ix - The cluster center's x-index.
+     * @param iy - The cluster center's y-index.
+     */
+    public Cluster(int ix, int iy) { this(new Point(ix, iy), Double.NaN, Double.NaN); }
+    
+    /**
+     * Creates a new cluster. All clusters are required to have a seed
+     * hit.
+     * @param clusterCenter - The <code>Point</code> object indicating in
+     * which crystal the seed hit occurred.
+     */
+    public Cluster(Point clusterCenter) { this(clusterCenter, Double.NaN, Double.NaN); }
+    
+    /**
+     * Creates a new cluster. All clusters are required to have a
+     * cluster center.
+     * @param ix - The cluster center's x-index.
+     * @param iy - The cluster center's y-index.
+     * @param energy - The cluster's energy.
+     */
+    public Cluster(int ix, int iy, double energy) { this(new Point(ix, iy), energy, Double.NaN); }
+    
+    /**
+     * Creates a new cluster. All clusters are required to have a
+     * cluster center.
+     * @param ix - The cluster center's x-index.
+     * @param iy - The cluster center's y-index.
+     * @param energy - The cluster's energy.
+     * @param time - The cluster's time-stamp.
+     */
+    public Cluster(int ix, int iy, double energy, double time) { this(new Point(ix, iy), energy, time); }
+    
+    /**
+     * Creates a new cluster. All clusters are required to have a seed
+     * hit.
+     * @param clusterCenter - The <code>Point</code> object indicating in
+     * which crystal the seed hit occurred.
+     * @param energy - The cluster's energy.
+     */
+    public Cluster(Point clusterCenter, double energy) {
+        this(clusterCenter, energy, Double.NaN);
+    }
+    
+    /**
+     * Creates a new cluster. All clusters are required to have a seed
+     * hit.
+     * @param clusterCenter - The <code>Point</code> object indicating in
+     * which crystal the seed hit occurred.
+     * @param energy - The cluster's energy.
+     * @param time - The cluster's time-stamp.
+     */
+    public Cluster(Point clusterCenter, double energy, double time) {
+        center = clusterCenter;
+        this.energy = energy;
+        this.time = time;
+    }
+    
+    /**
+     * Adds an <code>Point</code> to the list of this cluster's
+     * component hits.
+     * @param ix - The component hit's x-coordinate.
+     * @param iy - The component hit's y-coordinate.
+     */
+    public void addComponentHit(int ix, int iy) { hitList.add(new Point(ix, iy)); }
+    
+    /**
+     * Adds an <code>Point</code> to the list of this cluster's
+     * component hits.
+     * @param eHit - The <code>Point</code> object indicating in which
+     * crystal the hit occurred.
+     */
+    public void addComponentHit(Point eHit) { hitList.add(eHit); }
+    
+    /**
+     * Adds an <code>Point</code> to the list of this cluster's shared
+     * hits.
+     * @param ix - The shared hit's x-coordinate.
+     * @param iy - The shared hit's y-coordinate.
+     */
+    public void addSharedHit(int ix, int iy) { shareList.add(new Point(ix, iy)); }
+    
+    /**
+     * Adds an <code>Point</code> to the list of this cluster's shared
+     * hits.
+     * @param eHit - The <code>Point</code> object indicating in which
+     * crystal the hit occurred.
+     */
+    public void addSharedHit(Point eHit) { shareList.add(eHit); }
+    
+    /**
+     * Gets the hit representing the cluster center.
+     * @return Returns the cluster center hit as an <code>Point</code>.
+     */
+    public Point getClusterCenter() { return center; }
+    
+    /**
+     * Gets the cluster's energy, if it was defined when the cluster
+     * was constructed.
+     * @return Returns the energy of the cluster if it was defined,
+     * and <code>NaN</code> otherwise.
+     */
+    public double getClusterEnergy() { return energy; }
+    
+    /**
+     * Gets the time stamp for the cluster in nanoseconds.
+     * @return Returns the cluster's time stamp.
+     */
+    public double getClusterTime() { return time; }
+    
+    /**
+     * Indicates how many component hits compose this cluster. Note
+     * that this does not include the seed hit or shared hits.
+     * @return Returns the number of component hits in the cluster
+     * as an <code>int</code>.
+     */
+    public int getComponentHitCount() { return hitList.size(); }
+    
+    /**
+     * Gets the list of hits that make up the cluster, exempting the
+     * seed hit and shared hits.
+     * @return Returns the cluster hits as a <code>List</code> object
+     * composed of <code>Point</code> objects.
+     */
+    public List<Point> getComponentHits() { return hitList; }
+    
+    /**
+     * Indicates how many total hits compose this cluster. This includes
+     * component hits, shared hits, and the seed hit.
+     * @return Returns the number of component hits in the cluster
+     * as an <code>int</code>.
+     */
+    public int getHitCount() { return hitList.size() + shareList.size() + 1; }
+    
+    /**
+     * Indicates how many shared hits compose this cluster. Note that
+     * this does not include the seed hit or component hits.
+     * @return Returns the number of shared hits in the cluster as an
+     * <code>int</code>.
+     */
+    public int getSharedHitCount() { return shareList.size(); }
+    
+    /**
+     * Gets the list of hits that make up the cluster, exempting the
+     * seed hit and component hits.
+     * @return Returns the shared hits as a <code>List</code> object
+     * composed of <code>Point</code> objects.
+     */
+    public List<Point> getSharedHits() { return shareList; }
 }

Modified: java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/event/EcalHit.java
 =============================================================================
--- java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/event/EcalHit.java	(original)
+++ java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/event/EcalHit.java	Wed Apr 27 11:11:32 2016
@@ -23,7 +23,7 @@
      * @param energy - The raw energy of the hit.
      **/
     public EcalHit(int ix, int iy, double energy) {
-    	this(new Point(ix, iy), energy);
+        this(new Point(ix, iy), energy);
     }
     
     /**
@@ -32,7 +32,7 @@
      * @param energy - The raw energy of the hit.
      **/
     public EcalHit(Point ixy, double energy) {
-    	loc = ixy;
+        loc = ixy;
         this.energy = energy;
     }
     
@@ -44,7 +44,7 @@
      * @param time - The time-stamp for the hit.
      **/
     public EcalHit(int ix, int iy, double energy, double time) {
-    	this(new Point(ix, iy), energy, time);
+        this(new Point(ix, iy), energy, time);
     }
     
     /**
@@ -54,7 +54,7 @@
      * @param time - The time-stamp for the hit.
      **/
     public EcalHit(Point ixy, double energy, double time) {
-    	loc = ixy;
+        loc = ixy;
         this.energy = energy;
         this.time = time;
     }

Modified: java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/event/Event.java
 =============================================================================
--- java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/event/Event.java	(original)
+++ java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/event/Event.java	Wed Apr 27 11:11:32 2016
@@ -10,119 +10,119 @@
  * @author Kyle McCarty
  */
 public final class Event {
-	private List<EcalHit> hitList;
-	private List<Point> clusterList;
-	private List<Association> connectList;
-	
-	/**
-	 * <b>Event</b><br/><br/>
-	 * <code>public <b>Event</b>()</code><br/><br/>
-	 * Creates a new <code>Event</code>.
-	 */
-	public Event() { this(10, 10, 10); }
-	
-	/**
-	 * <b>Event</b><br/><br/>
-	 * <code>public <b>Event</b>(int hits, int clusters)</code><br/><br/>
-	 * Creates a new <code>Event</code> and reserves spaces for the
-	 * given number of hits and cluster centers.
-	 * @param hits - The number of hits for which to reserve space.
-	 * @param clusters - The number of cluster centers for which to
-	 * reserve space.
-	 */
-	public Event(int hits, int clusters) { this(hits, clusters, 10); }
-	
-	/**
-	 * <b>Event</b><br/><br/>
-	 * <code>public <b>Event</b>(int hits, int clusters, int associations)</code><br/><br/>
-	 * Creates a new <code>Event</code> and reserves spaces for the
-	 * given number of hits, cluster centers, and crystal associations.
-	 * @param hits - The number of hits for which to reserve space.
-	 * @param clusters - The number of cluster centers for which to
-	 * reserve space.
-	 * @param associations - The number of crystal associations for
-	 * which to reserve space.
-	 */
-	public Event(int hits, int clusters, int associations) {
-		hitList = new ArrayList<EcalHit>(hits);
-		clusterList = new ArrayList<Point>(clusters);
-		connectList = new ArrayList<Association>(associations);
-	}
-	
-	/**
-	 * <b>Event</b><br/><br/>
-	 * <code>public <b>Event</b>(List<EcalHit> hits, List<Point> clusters, List<Association> associations)</code><br/><br/>
-	 * Creates a new <code>Event</code> and sets its contents to those
-	 * of the given lists. The crystal association list will be empty.
-	 * @param hits - The list of calorimeter hits.
-	 * @param clusters - The list of cluster centers.
-	 */
-	public Event(List<EcalHit> hits, List<Point> clusters) {
-		this(hits, clusters, new ArrayList<Association>());
-	}
-	
-	/**
-	 * <b>Event</b><br/><br/>
-	 * <code>public <b>Event</b>(List<EcalHit> hits, List<Point> clusters, List<Association> associations)</code><br/><br/>
-	 * Creates a new <code>Event</code> and sets its contents to those
-	 * of the given lists.
-	 * @param hits - The list of calorimeter hits.
-	 * @param clusters - The list of cluster centers.
-	 * @param associations - The list of crystal associations.
-	 */
-	public Event(List<EcalHit> hits, List<Point> clusters, List<Association> associations) {
-		hitList = hits;
-		clusterList = clusters;
-		connectList = associations;
-	}
-	
-	/**
-	 * <b>addAssociation</b><br/><br/>
-	 * <code>public void <b>addAssociation</b>(Association connectedCrystal)</code><br/><br/>
-	 * Adds a crystal association to the event.
-	 * @param connectedCrystal - The crystal association to add.
-	 */
-	public void addAssociation(Association connectedCrystal) {
-		connectList.add(connectedCrystal);
-	}
-	
-	/**
-	 * <b>addCluster</b><br/><br/>
-	 * <code>public void <b>addCluster</b>(Point cluster)</code><br/><br/>
-	 * Adds a cluster center to the event.
-	 * @param cluster - The cluster center to add.
-	 */
-	public void addCluster(Point cluster) { clusterList.add(cluster); }
-	
-	/**
-	 * <b>addHit</b><br/><br/>
-	 * <code>public void <b>addHit</b>(EcalHit hit)</code><br/><br/>
-	 * Adds a calorimeter hit to the event.
-	 * @param hit - The calorimeter hit to add.
-	 */
-	public void addHit(EcalHit hit) { hitList.add(hit); }
-	
-	/**
-	 * <b>getAssociations</b><br/><br/>
-	 * <code>public List<Association> <b>getAssociations</b>()</code><br/><br/>
-	 * Gets the list of associated crystals for this event.
-	 * @return Returns the associations in a <code>List</code>.
-	 */
-	public List<Association> getAssociations() { return connectList; }
-	
-	/**
-	 * <b>getClusterCenters</b><br/><br/>
-	 * <code>List<Cluster><b>getClusterCenters</b>()</code><br/><br/>
-	 * Gets the list of cluster centers for this event.
-	 * @return Returns the cluster centers in a <code>List</code>.
-	 */
-	public List<Point> getClusterCenters() { return clusterList; }
-	
-	/**
-	 * <b>getHits</b><br/><br/>
-	 * <code>public List<EcalHit> <b>getHits</b>()</code><br/><br/>
-	 * Gets the list of calorimeter hits for this event.
-	 * @return Returns the hits in a <code>List</code>.
-	 */
-	public List<EcalHit> getHits() { return hitList; }
+    private List<EcalHit> hitList;
+    private List<Point> clusterList;
+    private List<Association> connectList;
+    
+    /**
+     * <b>Event</b><br/><br/>
+     * <code>public <b>Event</b>()</code><br/><br/>
+     * Creates a new <code>Event</code>.
+     */
+    public Event() { this(10, 10, 10); }
+    
+    /**
+     * <b>Event</b><br/><br/>
+     * <code>public <b>Event</b>(int hits, int clusters)</code><br/><br/>
+     * Creates a new <code>Event</code> and reserves spaces for the
+     * given number of hits and cluster centers.
+     * @param hits - The number of hits for which to reserve space.
+     * @param clusters - The number of cluster centers for which to
+     * reserve space.
+     */
+    public Event(int hits, int clusters) { this(hits, clusters, 10); }
+    
+    /**
+     * <b>Event</b><br/><br/>
+     * <code>public <b>Event</b>(int hits, int clusters, int associations)</code><br/><br/>
+     * Creates a new <code>Event</code> and reserves spaces for the
+     * given number of hits, cluster centers, and crystal associations.
+     * @param hits - The number of hits for which to reserve space.
+     * @param clusters - The number of cluster centers for which to
+     * reserve space.
+     * @param associations - The number of crystal associations for
+     * which to reserve space.
+     */
+    public Event(int hits, int clusters, int associations) {
+        hitList = new ArrayList<EcalHit>(hits);
+        clusterList = new ArrayList<Point>(clusters);
+        connectList = new ArrayList<Association>(associations);
+    }
+    
+    /**
+     * <b>Event</b><br/><br/>
+     * <code>public <b>Event</b>(List<EcalHit> hits, List<Point> clusters, List<Association> associations)</code><br/><br/>
+     * Creates a new <code>Event</code> and sets its contents to those
+     * of the given lists. The crystal association list will be empty.
+     * @param hits - The list of calorimeter hits.
+     * @param clusters - The list of cluster centers.
+     */
+    public Event(List<EcalHit> hits, List<Point> clusters) {
+        this(hits, clusters, new ArrayList<Association>());
+    }
+    
+    /**
+     * <b>Event</b><br/><br/>
+     * <code>public <b>Event</b>(List<EcalHit> hits, List<Point> clusters, List<Association> associations)</code><br/><br/>
+     * Creates a new <code>Event</code> and sets its contents to those
+     * of the given lists.
+     * @param hits - The list of calorimeter hits.
+     * @param clusters - The list of cluster centers.
+     * @param associations - The list of crystal associations.
+     */
+    public Event(List<EcalHit> hits, List<Point> clusters, List<Association> associations) {
+        hitList = hits;
+        clusterList = clusters;
+        connectList = associations;
+    }
+    
+    /**
+     * <b>addAssociation</b><br/><br/>
+     * <code>public void <b>addAssociation</b>(Association connectedCrystal)</code><br/><br/>
+     * Adds a crystal association to the event.
+     * @param connectedCrystal - The crystal association to add.
+     */
+    public void addAssociation(Association connectedCrystal) {
+        connectList.add(connectedCrystal);
+    }
+    
+    /**
+     * <b>addCluster</b><br/><br/>
+     * <code>public void <b>addCluster</b>(Point cluster)</code><br/><br/>
+     * Adds a cluster center to the event.
+     * @param cluster - The cluster center to add.
+     */
+    public void addCluster(Point cluster) { clusterList.add(cluster); }
+    
+    /**
+     * <b>addHit</b><br/><br/>
+     * <code>public void <b>addHit</b>(EcalHit hit)</code><br/><br/>
+     * Adds a calorimeter hit to the event.
+     * @param hit - The calorimeter hit to add.
+     */
+    public void addHit(EcalHit hit) { hitList.add(hit); }
+    
+    /**
+     * <b>getAssociations</b><br/><br/>
+     * <code>public List<Association> <b>getAssociations</b>()</code><br/><br/>
+     * Gets the list of associated crystals for this event.
+     * @return Returns the associations in a <code>List</code>.
+     */
+    public List<Association> getAssociations() { return connectList; }
+    
+    /**
+     * <b>getClusterCenters</b><br/><br/>
+     * <code>List<Cluster><b>getClusterCenters</b>()</code><br/><br/>
+     * Gets the list of cluster centers for this event.
+     * @return Returns the cluster centers in a <code>List</code>.
+     */
+    public List<Point> getClusterCenters() { return clusterList; }
+    
+    /**
+     * <b>getHits</b><br/><br/>
+     * <code>public List<EcalHit> <b>getHits</b>()</code><br/><br/>
+     * Gets the list of calorimeter hits for this event.
+     * @return Returns the hits in a <code>List</code>.
+     */
+    public List<EcalHit> getHits() { return hitList; }
 }

Modified: java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/io/EventManager.java
 =============================================================================
--- java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/io/EventManager.java	(original)
+++ java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/io/EventManager.java	Wed Apr 27 11:11:32 2016
@@ -21,16 +21,16 @@
      * may be read.
      * @throws IOException Occurs if there is an error closing the file stream.
      **/
-	public void close() throws IOException;
-	
-	/**
-	 * <b>getEventNumber</b><br/><br/>
+    public void close() throws IOException;
+    
+    /**
+     * <b>getEventNumber</b><br/><br/>
      * <code>public int <b>getEventNumber</b>()</code><br/><br/>
      * Gets the ordinal number for the currently displayed event.
-	 * @return Returns the current event's ordinal number.
-	 */
-	public int getEventNumber();
-	
+     * @return Returns the current event's ordinal number.
+     */
+    public int getEventNumber();
+    
     /**
      * <b>getClusters</b><br/><br/>
      * <code>public ArrayList<Cluster> <b>getClusters</b>()</code><br/><br/>
@@ -38,17 +38,17 @@
      * @return Returns the current clusters as an <code>ArrayList
      * </code> object.
      **/
-	public List<Cluster> getClusters();
-	
-	/**
+    public List<Cluster> getClusters();
+    
+    /**
      * <b>getHits</b><br/><br/>
      * <code>public ArrayList<EcalHit> <b>getHits</b>()</code><br/><br/>
      * Allows access to the current event's list of hits.
      * @return Returns the current hits as an <code>ArrayList</code> object.
      **/
-	public List<EcalHit> getHits();
-	
-	/**
+    public List<EcalHit> getHits();
+    
+    /**
      * <b>nextEvent</b><br/><br/>
      * <code>public boolean <b>nextEvent</b>()</code><br/><br/>
      * Populates the event manager with hits and clusters from the next event.
@@ -56,8 +56,8 @@
      * </code> if it was not.
      * @throws IOException Occurs if there was a file read error.
      **/
-	public boolean nextEvent() throws IOException;
-	
+    public boolean nextEvent() throws IOException;
+    
     /**
      * <b>previousEvent</b><br/><br/>
      * <code>public boolean <b>previousEvent</b>()</code><br/><br/>
@@ -66,5 +66,5 @@
      * </code> if it was not.
      * @throws IOException Occurs if there was a file read error.
      **/
-	public boolean previousEvent() throws IOException;
+    public boolean previousEvent() throws IOException;
 }

Modified: java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/io/TextManager.java
 =============================================================================
--- java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/io/TextManager.java	(original)
+++ java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/io/TextManager.java	Wed Apr 27 11:11:32 2016
@@ -53,7 +53,7 @@
     
     /**
      * Initializes an event manager that will read from the indicated file.
-     * @param filename - The path to the file containing hit information.
+     * @param file - The path to the file containing hit information.
      */
     public TextManager(File file) throws IOException {
         reader = new AdvancedReader(file);

Modified: java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/lcsim/EventDisplayOutputDriver.java
 =============================================================================
--- java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/lcsim/EventDisplayOutputDriver.java	(original)
+++ java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/lcsim/EventDisplayOutputDriver.java	Wed Apr 27 11:11:32 2016
@@ -97,30 +97,30 @@
                 
                 // Only write clusters if the option is selected.
                 if(outputClusters) {
-	                // Process the clusters.
-	                for (org.lcsim.event.Cluster cluster : clusters) {
-	                    // Get the seed hit for the cluster.
-	                    CalorimeterHit seedHit = (CalorimeterHit)cluster.getCalorimeterHits().get(0);
-	                    int ix = seedHit.getIdentifierFieldValue("ix");
-	                    int iy = seedHit.getIdentifierFieldValue("iy");
-	                    double time = seedHit.getTime();
-	                    
-	                    // Get the cluster's total energy.
-	                    double energy = cluster.getEnergy();
-	                    
-	                    // Write the seed hit to start a cluster.
-	                    writer.append(String.format("Cluster\t%d\t%d\t%f\t%f%n", ix, iy, energy, time));
-	                    
-	                    // Write the component hits to the cluster.
-	                    for (CalorimeterHit hit : cluster.getCalorimeterHits()) {
-	                        // Get each component hit's x/y coordinates.
-	                        ix = hit.getIdentifierFieldValue("ix");
-	                        iy = hit.getIdentifierFieldValue("iy");
-	                        
-	                        // Write them as component hits.
-	                        writer.append(String.format("CompHit\t%d\t%d%n", ix, iy));
-	                    }
-	                }
+                    // Process the clusters.
+                    for (org.lcsim.event.Cluster cluster : clusters) {
+                        // Get the seed hit for the cluster.
+                        CalorimeterHit seedHit = (CalorimeterHit)cluster.getCalorimeterHits().get(0);
+                        int ix = seedHit.getIdentifierFieldValue("ix");
+                        int iy = seedHit.getIdentifierFieldValue("iy");
+                        double time = seedHit.getTime();
+                        
+                        // Get the cluster's total energy.
+                        double energy = cluster.getEnergy();
+                        
+                        // Write the seed hit to start a cluster.
+                        writer.append(String.format("Cluster\t%d\t%d\t%f\t%f%n", ix, iy, energy, time));
+                        
+                        // Write the component hits to the cluster.
+                        for (CalorimeterHit hit : cluster.getCalorimeterHits()) {
+                            // Get each component hit's x/y coordinates.
+                            ix = hit.getIdentifierFieldValue("ix");
+                            iy = hit.getIdentifierFieldValue("iy");
+                            
+                            // Write them as component hits.
+                            writer.append(String.format("CompHit\t%d\t%d%n", ix, iy));
+                        }
+                    }
                 }
                 
                 // Append the end of event indicator.
@@ -169,7 +169,7 @@
      * indicates that they will be output.
      */
     public void setIgnoreEmptyEvents(boolean ignoreEmptyEvents) {
-    	this.ignoreEmptyEvents = ignoreEmptyEvents;
+        this.ignoreEmptyEvents = ignoreEmptyEvents;
     }
     
     /**
@@ -179,7 +179,7 @@
      * indicates that they will be output.
      */
     public void setIgnoreNoClusterEvents(boolean ignoreNoClusterEvents) {
-    	this.ignoreNoClusterEvents = ignoreNoClusterEvents;
+        this.ignoreNoClusterEvents = ignoreNoClusterEvents;
     }
     
     /**
@@ -196,6 +196,6 @@
      * will be written and <code>false</code> that they will not.
      */
     public void setOutputClusters(boolean outputClusters) {
-    	this.outputClusters = outputClusters;
+        this.outputClusters = outputClusters;
     }
 }

Modified: java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/lcsim/LCIOBridgeDriver.java
 =============================================================================
--- java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/lcsim/LCIOBridgeDriver.java	(original)
+++ java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/lcsim/LCIOBridgeDriver.java	Wed Apr 27 11:11:32 2016
@@ -39,9 +39,9 @@
      * @param event - The LCIO event.
      */
     public void process(EventHeader event) {
-    	// If we are still updating the display, skip this event.
-    	if(updating) { return; }
-    	
+        // If we are still updating the display, skip this event.
+        if(updating) { return; }
+        
         // Make sure that this event has calorimeter hits.
         if (event.hasCollection(CalorimeterHit.class, ecalCollectionName)) {
             // Get the list of calorimeter hits from the event.
@@ -55,44 +55,44 @@
             
             // If this is the correct place to update, do so.
             if(eventsProcessed >= displayInterval) {
-            	// Lock the update method for the duration of the update.
-            	updating = true;
-            	
-            	// Clear the event display.
-            	eventDisplay.resetDisplay();
-            	
-            	// Add all of the hits.
-            	for(CalorimeterHit hit : hits) {
-            		// Get the hit's location and energy.
-            		int ix = hit.getIdentifierFieldValue("ix");
-            		int iy = hit.getIdentifierFieldValue("iy");
-            		double energy = hit.getRawEnergy();
-            		
-            		// Add the hit energy to the event display.
-            		eventDisplay.addHit(new EcalHit(ix, iy, energy));
-            	}
-            	
-            	// Add all the clusters.
-            	for(org.lcsim.event.Cluster cluster : clusters) {
-            		// Get the seed hit.
-            		CalorimeterHit seed = cluster.getCalorimeterHits().get(0);
-            		int ix = seed.getIdentifierFieldValue("ix");
-            		int iy = seed.getIdentifierFieldValue("iy");
-            		double energy = seed.getRawEnergy(); // FIXME: Should this be getCorrectedEnergy() instead? --JM
-            		
-            		// Add the cluster center to the event display.
-            		Cluster cc = new Cluster(ix, iy, energy);
-            		eventDisplay.addCluster(cc);
-            	}
-            	
-            	// Update the display.
-            	eventDisplay.updateDisplay();
-            	
-            	// Reset the number of events we've seen since the last update.
-            	eventsProcessed = 0;
-            	
-            	// Unlock the update method so that more events can be processed.
-            	updating = false;
+                // Lock the update method for the duration of the update.
+                updating = true;
+                
+                // Clear the event display.
+                eventDisplay.resetDisplay();
+                
+                // Add all of the hits.
+                for(CalorimeterHit hit : hits) {
+                    // Get the hit's location and energy.
+                    int ix = hit.getIdentifierFieldValue("ix");
+                    int iy = hit.getIdentifierFieldValue("iy");
+                    double energy = hit.getRawEnergy();
+                    
+                    // Add the hit energy to the event display.
+                    eventDisplay.addHit(new EcalHit(ix, iy, energy));
+                }
+                
+                // Add all the clusters.
+                for(org.lcsim.event.Cluster cluster : clusters) {
+                    // Get the seed hit.
+                    CalorimeterHit seed = cluster.getCalorimeterHits().get(0);
+                    int ix = seed.getIdentifierFieldValue("ix");
+                    int iy = seed.getIdentifierFieldValue("iy");
+                    double energy = seed.getRawEnergy(); // FIXME: Should this be getCorrectedEnergy() instead? --JM
+                    
+                    // Add the cluster center to the event display.
+                    Cluster cc = new Cluster(ix, iy, energy);
+                    eventDisplay.addCluster(cc);
+                }
+                
+                // Update the display.
+                eventDisplay.updateDisplay();
+                
+                // Reset the number of events we've seen since the last update.
+                eventsProcessed = 0;
+                
+                // Unlock the update method so that more events can be processed.
+                updating = false;
             }
         }
     }
@@ -119,14 +119,14 @@
      * a new event is displayed.
      */
     public void setDisplayInterval(String displayInterval) {
-    	// Convert the argument to an integer.
-    	int disp = Integer.parseInt(displayInterval);
-    	
-    	// If it is negative, make it zero.
-    	if(disp < 0) { disp = 0; }
-    	
-    	// Set the display interval.
-    	this.displayInterval = disp;
+        // Convert the argument to an integer.
+        int disp = Integer.parseInt(displayInterval);
+        
+        // If it is negative, make it zero.
+        if(disp < 0) { disp = 0; }
+        
+        // Set the display interval.
+        this.displayInterval = disp;
     }
     
     /**

Modified: java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/ui/ActiveViewer.java
 =============================================================================
--- java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/ui/ActiveViewer.java	(original)
+++ java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/ui/ActiveViewer.java	Wed Apr 27 11:11:32 2016
@@ -34,8 +34,6 @@
      * events from the indicated data source with additional status
      * fields defined by the <code>fieldNames</code> argument.
      * @param em - The data source event manager.
-     * @param fieldNames - An array of additional status fields
-     * that should be displayed.
      */
     public ActiveViewer(EventManager em) {
         // Pass any additional field values to the super class.

Modified: java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/ui/CalorimeterPanel.java
 =============================================================================
--- java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/ui/CalorimeterPanel.java	(original)
+++ java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/ui/CalorimeterPanel.java	Wed Apr 27 11:11:32 2016
@@ -503,8 +503,8 @@
     /**
      * Determines if the crystal at the given coordinates is a active
      * or not.
-     * @param xCoor - The x-index of the crystal.
-     * @param yCoor - The y-index of the crystal.
+     * @param ix - The x-index of the crystal.
+     * @param iy - The y-index of the crystal.
      * @return Returns <code>true</code> if the crystal is active
      * and <code>false</code> if it is not.
      * @throws IndexOutOfBoundsException Occurs when either of the given
@@ -740,28 +740,28 @@
     
     /**
      * Sets whether to mirror the x-axis on the calorimeter display.
-     * @param state - <code>true</code> indicates that the axis should
+     * @param mirrorX - <code>true</code> indicates that the axis should
      * be mirrored and <code>false</code> that it should not.
      */
     public void setMirrorX(boolean mirrorX) {
-            // Process the change.
-            setMirror(mirrorX, mirrorY);
-            
-            // Throw an event.
-            throwSettingsEvent(SettingsEvent.PROPERTY_X_ORIENTATION);
+        // Process the change.
+        setMirror(mirrorX, mirrorY);
+        
+        // Throw an event.
+        throwSettingsEvent(SettingsEvent.PROPERTY_X_ORIENTATION);
     }
     
     /**
      * Sets whether to mirror the y-axis on the calorimeter display.
-     * @param state - <code>true</code> indicates that the axis should
+     * @param mirrorY - <code>true</code> indicates that the axis should
      * be mirrored and <code>false</code> that it should not.
      */
     public void setMirrorY(boolean mirrorY) {
-            // Process the change.
-            setMirror(mirrorX, mirrorY);
-            
-            // Throw an event.
-            throwSettingsEvent(SettingsEvent.PROPERTY_Y_ORIENTATION);
+        // Process the change.
+        setMirror(mirrorX, mirrorY);
+            
+        // Throw an event.
+        throwSettingsEvent(SettingsEvent.PROPERTY_Y_ORIENTATION);
     }
     
     /**

Modified: java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/ui/DataFileViewer.java
 =============================================================================
--- java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/ui/DataFileViewer.java	(original)
+++ java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/ui/DataFileViewer.java	Wed Apr 27 11:11:32 2016
@@ -97,9 +97,9 @@
         filterPanel.addActionListener(new ActionListener() {
             @Override
             public void actionPerformed(ActionEvent e) {
-            	// Suppress panel redrawing until the highlights are set.
-            	ecalPanel.setSuppressRedraw(true);
-            	
+                // Suppress panel redrawing until the highlights are set.
+                ecalPanel.setSuppressRedraw(true);
+                
                 // Clear the panel highlighting.
                 ecalPanel.clearHighlight();
                 

Modified: java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/ui/FileViewer.java
 =============================================================================
--- java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/ui/FileViewer.java	(original)
+++ java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/ui/FileViewer.java	Wed Apr 27 11:11:32 2016
@@ -178,9 +178,9 @@
             // be displayed.
             Double hitTime = crystalTimeMap.get(crystal);
             if(hitTime != null) {
-            	setStatusField(fieldNames[HIT_TIME], Double.toString(hitTime));
+                setStatusField(fieldNames[HIT_TIME], Double.toString(hitTime));
             } else {
-            	setStatusField(fieldNames[HIT_TIME], ResizableFieldPanel.NULL_VALUE);
+                setStatusField(fieldNames[HIT_TIME], ResizableFieldPanel.NULL_VALUE);
             }
         }
         // Otherwise, clear the field values.
@@ -257,7 +257,7 @@
         // Load hit time map.
         crystalTimeMap.clear();
         for(EcalHit hit : em.getHits()) {
-        	crystalTimeMap.put(new Point(toPanelX(hit.getX()), toPanelY(hit.getY())), hit.getTime());
+            crystalTimeMap.put(new Point(toPanelX(hit.getX()), toPanelY(hit.getY())), hit.getTime());
         }
         
         // Display it.

Modified: java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/ui/PDataEventViewer.java
 =============================================================================
--- java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/ui/PDataEventViewer.java	(original)
+++ java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/ui/PDataEventViewer.java	Wed Apr 27 11:11:32 2016
@@ -57,7 +57,6 @@
      * Initializes a new <code>DataFileViewer</code> that reads from
      * the given event manager for event data and the given hardware
      * data file for crystal hardware data readout.
-     * @param dataSource - The manager for event data.
      * @param crystalDataFilePath - The data file for crystal hardware
      * information.
      * @throws IOException Occurs if there is an error reading from
@@ -98,9 +97,9 @@
         filterPanel.addActionListener(new ActionListener() {
             @Override
             public void actionPerformed(ActionEvent e) {
-            	// Suppress panel redrawing until the highlights are set.
-            	ecalPanel.setSuppressRedraw(true);
-            	
+                // Suppress panel redrawing until the highlights are set.
+                ecalPanel.setSuppressRedraw(true);
+                
                 // Clear the panel highlighting.
                 ecalPanel.clearHighlight();
                 

Modified: java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/ui/PassiveViewer.java
 =============================================================================
--- java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/ui/PassiveViewer.java	(original)
+++ java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/ui/PassiveViewer.java	Wed Apr 27 11:11:32 2016
@@ -16,7 +16,7 @@
     
     /**
      * Adds a new hit to the display.
-     * @param hit - The hit to be added.
+     * @param lcioHit - The hit to be added.
      */
     public abstract void addHit(CalorimeterHit lcioHit);
     

Modified: java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/ui/Viewer.java
 =============================================================================
--- java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/ui/Viewer.java	(original)
+++ java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/ui/Viewer.java	Wed Apr 27 11:11:32 2016
@@ -122,8 +122,6 @@
     
     /**
      * Initializes the viewer window and calorimeter panel.
-     * @param statusFields - Additional fields to display in the status
-     * panel. This can not be <code>null</code>.
      * @throws NullPointerException Occurs if any of the additional field
      * arguments are <code>null</code>.
      **/
@@ -638,7 +636,7 @@
         
         JFileChooser chooser = new JFileChooser();
         if(chooser.showSaveDialog(this) == JFileChooser.CANCEL_OPTION) {
-        	return;
+            return;
         }
         
         // Parse the file name and make sure that it ends in .PNG.
@@ -646,9 +644,9 @@
         int index = filepath.lastIndexOf('.');
         if(index == -1) { filepath = filepath + ".png"; }
         else {
-        	if(filepath.substring(index + 1).compareTo("png") != 0) {
-        		filepath = filepath.substring(0, index) + ".png";
-        	}
+            if(filepath.substring(index + 1).compareTo("png") != 0) {
+                filepath = filepath.substring(0, index) + ".png";
+            }
         }
         
         // Get the lowest available file name.

Modified: java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/util/BooleanMap.java
 =============================================================================
--- java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/util/BooleanMap.java	(original)
+++ java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/util/BooleanMap.java	Wed Apr 27 11:11:32 2016
@@ -10,208 +10,208 @@
  * @author Kyle McCarty
  */
 public final class BooleanMap implements ColorMap<Double> {
-	// The color to display for values which pass the boolean check.
-	private Color activeColor = new Color(255, 50, 50);
-	// The color to display for values that fail the boolean check.
-	private Color inactiveColor = Color.WHITE;
-	// The critical value against which the boolean check is performed.
-	private double value = 0.0;
-	// The type of this boolean scale.
-	private final BooleanType boolType;
-	
-	/**
-	 * <b>BooleanMap</b><br/><br/>
-	 * <code>public <b>BooleanMap</b>(BooleanType type, double comparisonValue)</code><br/><br/>
-	 * Defines a <code>ColorScale</code> which maps values to colors
-	 * based on a boolean comparison.
-	 * @param type - The type of boolean comparison to perform.
-	 * @param comparisonValue - The value against which the comparison
-	 * should be made.
-	 */
-	public BooleanMap(BooleanType type, double comparisonValue) {
-		// Make sure the comparison type is not null.
-		if(type == null) { throw new IllegalArgumentException("Boolean comparison type can not be null."); }
-		
-		// Define the critical value and the boolean type.
-		value = comparisonValue;
-		boolType = type;
-	}
-	
-	/**
-	 * <b>BooleanMap</b><br/><br/>
-	 * <code>public <b>BooleanMap</b>(BooleanType type, double comparisonValue,
-	 * 			Color activeColor)</code><br/><br/>
-	 * Defines a <code>ColorScale</code> which maps values to colors
-	 * based on a boolean comparison.
-	 * @param type - The type of boolean comparison to perform.
-	 * @param comparisonValue - The value against which the comparison
-	 * should be made.
-	 * @param activeColor - The color in which values that pass the
-	 * comparison should be displayed.
-	 */
-	public BooleanMap(BooleanType type, double comparisonValue, Color activeColor) {
-		// Set the critical value and the boolean type.
-		this(type, comparisonValue);
-		
-		// Set the active color.
-		this.activeColor = activeColor;
-	}
-	
-	/**
-	 * <b>BooleanMap</b><br/><br/>
-	 * <code>public <b>BooleanMap</b>(BooleanType type, double comparisonValue,
-	 * 			Color activeColor, Color inactiveColor)</code><br/><br/>
-	 * Defines a <code>ColorScale</code> which maps values to colors
-	 * based on a boolean comparison.
-	 * @param type - The type of boolean comparison to perform.
-	 * @param comparisonValue - The value against which the comparison
-	 * should be made.
-	 * @param activeColor - The color in which values that pass the
-	 * comparison should be displayed.
-	 * @param inactiveColor - The color in which values that fail the
-	 * comparison should be displayed.
-	 */
-	public BooleanMap(BooleanType type, double comparisonValue, Color activeColor, Color inactiveColor) {
-		// Set the critical value and the boolean type.
-		this(type, comparisonValue);
-		
-		// Set the active and inactive colors.
-		this.activeColor = activeColor;
-		this.inactiveColor = inactiveColor;
-	}
-	
-	public Color getColor(Double value) {
-		// If the argument is null, treat it is zero.
-		if(value == null) { value = 0.0; }
-		
-		// If it passes the boolean comparison, return the active color.
-		if(passes(value)) { return activeColor; }
-		
-		// Otherwise, return the inactive color.
-		else { return inactiveColor; }
-	}
-	
-	/**
-	 * <b>getActiveColor</b><br/><br/>
-	 * <code>public Color <b>getActiveColor</b>()</code><br/><br/>
-	 * Gets the color used by the scale for values which pass the
-	 * boolean comparison.
-	 * @return Returns the color as a <code>Color</code> object.
-	 */
-	public Color getActiveColor() { return activeColor; }
-	
-	/**
-	 * <b>getBooleanType</b><br/><br/>
-	 * <code>public BooleanType <b>getBooleanType</b>()</code><br/><br/>
-	 * Indicates what type of boolean comparison is performed by this
-	 * scale.
-	 * @return Returns the type of comparison as a <code>BooleanType
-	 * </code> enumerable.
-	 */
-	public BooleanType getBooleanType() { return boolType; }
-	
-	/**
-	 * <b>getComparisonValue</b><br/><br/>
-	 * <code>public double <b>getComparisonValue</b>()</code><br/><br/>
-	 * Gets the value against which the boolean comparisons are
-	 * performed.
-	 * @return Returns the value which is compared against.
-	 */
-	public double getComparisonValue() { return value; }
-	
-	/**
-	 * <b>getInactiveColor</b><br/><br/>
-	 * <code>public Color <b>getInactiveColor</b>()</code><br/><br/>
-	 * Gets the color used by the scale for values which fail the
-	 * boolean comparison.
-	 * @return Returns the color as a <code>Color</code> object.
-	 */
-	public Color getInactiveColor() { return inactiveColor; }
-	
-	/**
-	 * <b>setComparisonValue</b><br/><br/>
-	 * <code>public void <b>setComparisonValue</b>(double value)</code><br/><br/>
-	 * Sets the value against which the boolean comparison is performed.
-	 * @param value - The value to compare against.
-	 */
-	public void setComparisonValue(double value) { this.value = value; }
-	
-	/**
-	 * <b>passes</b><br/><br/>
-	 * <code>private boolean <b>passes</b>(double d)</code><br/><br/>
-	 * Determines whether a given external value passes the boolean
-	 * check or not.
-	 * @param d - The external value to compare.
-	 * @return Returns <code>true</code> if the value passes the boolean
-	 * check and <code>false</code> if it does not.
-	 */
-	private boolean passes(double d) {
-		// Perform the appropriate comparison. Note that the default
-		// case is included to satisfy the compiler -- it should not
-		// ever actually be used.
-		switch(boolType) {
-			case EQUAL_TO:
-				return d == value;
-			case NOT_EQUAL_TO:
-				return d != value;
-			case GREATER_THAN:
-				return d > value;
-			case LESS_THAN:
-				return d < value;
-			case GREATER_THAN_OR_EQUAL_TO:
-				return d >= value;
-			case LESS_THAN_OR_EQUAL_TO:
-				return d<= value;
-			default:
-				return false;
-		}
-	}
-	
-	/**
-	 * Enumerable <code>BooleanType</code> defines the type of boolean
-	 * comparison that is to be performed by the scale.
-	 */
-	public enum BooleanType {
-		/**
-		 * <b>EQUAL_TO</b><br/><br/>
-		 * Performs the boolean check:<br/><br/>
-		 * <code>[External Value] == [Comparison Value]</code>
-		 */
-		EQUAL_TO,
-		
-		/**
-		 * <b>NOT_EQUAL_TO</b><br/><br/>
-		 * Performs the boolean check:<br/><br/>
-		 * <code>[External Value] != [Comparison Value]</code>
-		 */
-		NOT_EQUAL_TO,
-		
-		/**
-		 * <b>GREATER_THAN</b><br/><br/>
-		 * Performs the boolean check:<br/><br/>
-		 * <code>[External Value] > [Comparison Value]</code>
-		 */
-		GREATER_THAN,
-		
-		/**
-		 * <b>LESS_THAN</b><br/><br/>
-		 * Performs the boolean check:<br/><br/>
-		 * <code>[External Value] < [Comparison Value]</code>
-		 */
-		LESS_THAN,
-		
-		/**
-		 * <b>GREATER_THAN_OR_EQUAL_TO</b><br/><br/>
-		 * Performs the boolean check:<br/><br/>
-		 * <code>[External Value] >= [Comparison Value]</code>
-		 */
-		GREATER_THAN_OR_EQUAL_TO,
-		
-		/**
-		 * <b>LESS_THAN_OR_EQUAL_TO</b><br/><br/>
-		 * Performs the boolean check:<br/><br/>
-		 * <code>[External Value] <= [Comparison Value]</code>
-		 */
-		LESS_THAN_OR_EQUAL_TO
-	};
+    // The color to display for values which pass the boolean check.
+    private Color activeColor = new Color(255, 50, 50);
+    // The color to display for values that fail the boolean check.
+    private Color inactiveColor = Color.WHITE;
+    // The critical value against which the boolean check is performed.
+    private double value = 0.0;
+    // The type of this boolean scale.
+    private final BooleanType boolType;
+    
+    /**
+     * <b>BooleanMap</b><br/><br/>
+     * <code>public <b>BooleanMap</b>(BooleanType type, double comparisonValue)</code><br/><br/>
+     * Defines a <code>ColorScale</code> which maps values to colors
+     * based on a boolean comparison.
+     * @param type - The type of boolean comparison to perform.
+     * @param comparisonValue - The value against which the comparison
+     * should be made.
+     */
+    public BooleanMap(BooleanType type, double comparisonValue) {
+        // Make sure the comparison type is not null.
+        if(type == null) { throw new IllegalArgumentException("Boolean comparison type can not be null."); }
+        
+        // Define the critical value and the boolean type.
+        value = comparisonValue;
+        boolType = type;
+    }
+    
+    /**
+     * <b>BooleanMap</b><br/><br/>
+     * <code>public <b>BooleanMap</b>(BooleanType type, double comparisonValue,
+     *          Color activeColor)</code><br/><br/>
+     * Defines a <code>ColorScale</code> which maps values to colors
+     * based on a boolean comparison.
+     * @param type - The type of boolean comparison to perform.
+     * @param comparisonValue - The value against which the comparison
+     * should be made.
+     * @param activeColor - The color in which values that pass the
+     * comparison should be displayed.
+     */
+    public BooleanMap(BooleanType type, double comparisonValue, Color activeColor) {
+        // Set the critical value and the boolean type.
+        this(type, comparisonValue);
+        
+        // Set the active color.
+        this.activeColor = activeColor;
+    }
+    
+    /**
+     * <b>BooleanMap</b><br/><br/>
+     * <code>public <b>BooleanMap</b>(BooleanType type, double comparisonValue,
+     *          Color activeColor, Color inactiveColor)</code><br/><br/>
+     * Defines a <code>ColorScale</code> which maps values to colors
+     * based on a boolean comparison.
+     * @param type - The type of boolean comparison to perform.
+     * @param comparisonValue - The value against which the comparison
+     * should be made.
+     * @param activeColor - The color in which values that pass the
+     * comparison should be displayed.
+     * @param inactiveColor - The color in which values that fail the
+     * comparison should be displayed.
+     */
+    public BooleanMap(BooleanType type, double comparisonValue, Color activeColor, Color inactiveColor) {
+        // Set the critical value and the boolean type.
+        this(type, comparisonValue);
+        
+        // Set the active and inactive colors.
+        this.activeColor = activeColor;
+        this.inactiveColor = inactiveColor;
+    }
+    
+    public Color getColor(Double value) {
+        // If the argument is null, treat it is zero.
+        if(value == null) { value = 0.0; }
+        
+        // If it passes the boolean comparison, return the active color.
+        if(passes(value)) { return activeColor; }
+        
+        // Otherwise, return the inactive color.
+        else { return inactiveColor; }
+    }
+    
+    /**
+     * <b>getActiveColor</b><br/><br/>
+     * <code>public Color <b>getActiveColor</b>()</code><br/><br/>
+     * Gets the color used by the scale for values which pass the
+     * boolean comparison.
+     * @return Returns the color as a <code>Color</code> object.
+     */
+    public Color getActiveColor() { return activeColor; }
+    
+    /**
+     * <b>getBooleanType</b><br/><br/>
+     * <code>public BooleanType <b>getBooleanType</b>()</code><br/><br/>
+     * Indicates what type of boolean comparison is performed by this
+     * scale.
+     * @return Returns the type of comparison as a <code>BooleanType
+     * </code> enumerable.
+     */
+    public BooleanType getBooleanType() { return boolType; }
+    
+    /**
+     * <b>getComparisonValue</b><br/><br/>
+     * <code>public double <b>getComparisonValue</b>()</code><br/><br/>
+     * Gets the value against which the boolean comparisons are
+     * performed.
+     * @return Returns the value which is compared against.
+     */
+    public double getComparisonValue() { return value; }
+    
+    /**
+     * <b>getInactiveColor</b><br/><br/>
+     * <code>public Color <b>getInactiveColor</b>()</code><br/><br/>
+     * Gets the color used by the scale for values which fail the
+     * boolean comparison.
+     * @return Returns the color as a <code>Color</code> object.
+     */
+    public Color getInactiveColor() { return inactiveColor; }
+    
+    /**
+     * <b>setComparisonValue</b><br/><br/>
+     * <code>public void <b>setComparisonValue</b>(double value)</code><br/><br/>
+     * Sets the value against which the boolean comparison is performed.
+     * @param value - The value to compare against.
+     */
+    public void setComparisonValue(double value) { this.value = value; }
+    
+    /**
+     * <b>passes</b><br/><br/>
+     * <code>private boolean <b>passes</b>(double d)</code><br/><br/>
+     * Determines whether a given external value passes the boolean
+     * check or not.
+     * @param d - The external value to compare.
+     * @return Returns <code>true</code> if the value passes the boolean
+     * check and <code>false</code> if it does not.
+     */
+    private boolean passes(double d) {
+        // Perform the appropriate comparison. Note that the default
+        // case is included to satisfy the compiler -- it should not
+        // ever actually be used.
+        switch(boolType) {
+            case EQUAL_TO:
+                return d == value;
+            case NOT_EQUAL_TO:
+                return d != value;
+            case GREATER_THAN:
+                return d > value;
+            case LESS_THAN:
+                return d < value;
+            case GREATER_THAN_OR_EQUAL_TO:
+                return d >= value;
+            case LESS_THAN_OR_EQUAL_TO:
+                return d<= value;
+            default:
+                return false;
+        }
+    }
+    
+    /**
+     * Enumerable <code>BooleanType</code> defines the type of boolean
+     * comparison that is to be performed by the scale.
+     */
+    public enum BooleanType {
+        /**
+         * <b>EQUAL_TO</b><br/><br/>
+         * Performs the boolean check:<br/><br/>
+         * <code>[External Value] == [Comparison Value]</code>
+         */
+        EQUAL_TO,
+        
+        /**
+         * <b>NOT_EQUAL_TO</b><br/><br/>
+         * Performs the boolean check:<br/><br/>
+         * <code>[External Value] != [Comparison Value]</code>
+         */
+        NOT_EQUAL_TO,
+        
+        /**
+         * <b>GREATER_THAN</b><br/><br/>
+         * Performs the boolean check:<br/><br/>
+         * <code>[External Value] > [Comparison Value]</code>
+         */
+        GREATER_THAN,
+        
+        /**
+         * <b>LESS_THAN</b><br/><br/>
+         * Performs the boolean check:<br/><br/>
+         * <code>[External Value] < [Comparison Value]</code>
+         */
+        LESS_THAN,
+        
+        /**
+         * <b>GREATER_THAN_OR_EQUAL_TO</b><br/><br/>
+         * Performs the boolean check:<br/><br/>
+         * <code>[External Value] >= [Comparison Value]</code>
+         */
+        GREATER_THAN_OR_EQUAL_TO,
+        
+        /**
+         * <b>LESS_THAN_OR_EQUAL_TO</b><br/><br/>
+         * Performs the boolean check:<br/><br/>
+         * <code>[External Value] <= [Comparison Value]</code>
+         */
+        LESS_THAN_OR_EQUAL_TO
+    };
 }

Modified: java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/util/ColorScale.java
 =============================================================================
--- java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/util/ColorScale.java	(original)
+++ java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/util/ColorScale.java	Wed Apr 27 11:11:32 2016
@@ -47,8 +47,8 @@
      * value, if scaling is logarithmic.
      */
     public double getScaledMaximum() {
-    	if(linear) { return max; }
-    	else { return lMax; }
+        if(linear) { return max; }
+        else { return lMax; }
     }
     
     /**
@@ -61,8 +61,8 @@
      * value, if scaling is logarithmic.
      */
     public double getScaledMinimum() {
-    	if(linear) { return min; }
-    	else { return lMin; }
+        if(linear) { return min; }
+        else { return lMin; }
     }
     
     /**

Modified: java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/util/CrystalEvent.java
 =============================================================================
--- java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/util/CrystalEvent.java	(original)
+++ java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/util/CrystalEvent.java	Wed Apr 27 11:11:32 2016
@@ -14,41 +14,41 @@
  * @author Kyle McCarty
  */
 public class CrystalEvent extends AWTEvent {
-	private static final long serialVersionUID = 77198267255387212L;
-	// Stores the location of the triggering crystal.
-	private final Point crystal;
-	// The AWTEvent id for this event.
-	private static final int AWT_ID = AWTEvent.RESERVED_ID_MAX + 10;
-	
-	/**
-	 * <b>CrystalEvent</b><br/><br/>
-	 * <code>public <b>CrystalEvent</b>(Viewer parent, Point triggerCrystal)</code><br/><br/>
-	 * Creates a crystal event for the indicated crystal and triggering
-	 * component.
-	 * @param source - The triggering component.
-	 * @param triggerCrystal - The crystal associated with the event.
-	 * @throws IllegalArgumentException Occurs if the associated crystal
-	 * is <code>null</code>.
-	 */
-	public CrystalEvent(Viewer source, Point triggerCrystal) throws IllegalArgumentException {
-		// Run the superclass constructor.
-		super(source, AWT_ID);
-		
-		// Make sure that the trigger crystal is not null.
-		if(triggerCrystal == null) {
-			throw new IllegalArgumentException("Crystal events can not occur with respect to non-exstant crystals.");
-		}
-		
-		// Define the event parameters.
-		crystal = triggerCrystal;
-	}
-	
-	/**
-	 * <b>getCrystalID</b><br/><br/>
-	 * <code>public Point <b>getCrystalID</b>()</code><br/><br/>
-	 * Indicates the panel indices at which the crystal is located.
-	 * @return Returns the crystal's panel indices as a <code>Point
-	 * </code> object.
-	 */
-	public Point getCrystalID() { return crystal; }
+    private static final long serialVersionUID = 77198267255387212L;
+    // Stores the location of the triggering crystal.
+    private final Point crystal;
+    // The AWTEvent id for this event.
+    private static final int AWT_ID = AWTEvent.RESERVED_ID_MAX + 10;
+    
+    /**
+     * <b>CrystalEvent</b><br/><br/>
+     * <code>public <b>CrystalEvent</b>(Viewer parent, Point triggerCrystal)</code><br/><br/>
+     * Creates a crystal event for the indicated crystal and triggering
+     * component.
+     * @param source - The triggering component.
+     * @param triggerCrystal - The crystal associated with the event.
+     * @throws IllegalArgumentException Occurs if the associated crystal
+     * is <code>null</code>.
+     */
+    public CrystalEvent(Viewer source, Point triggerCrystal) throws IllegalArgumentException {
+        // Run the superclass constructor.
+        super(source, AWT_ID);
+        
+        // Make sure that the trigger crystal is not null.
+        if(triggerCrystal == null) {
+            throw new IllegalArgumentException("Crystal events can not occur with respect to non-exstant crystals.");
+        }
+        
+        // Define the event parameters.
+        crystal = triggerCrystal;
+    }
+    
+    /**
+     * <b>getCrystalID</b><br/><br/>
+     * <code>public Point <b>getCrystalID</b>()</code><br/><br/>
+     * Indicates the panel indices at which the crystal is located.
+     * @return Returns the crystal's panel indices as a <code>Point
+     * </code> object.
+     */
+    public Point getCrystalID() { return crystal; }
 }

Modified: java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/util/CrystalListener.java
 =============================================================================
--- java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/util/CrystalListener.java	(original)
+++ java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/util/CrystalListener.java	Wed Apr 27 11:11:32 2016
@@ -11,27 +11,27 @@
  * @author Kyle McCarty
  */
 public interface CrystalListener extends EventListener {
-	/**
-	 * <b>crystalActivated</b><br/><br/>
-	 * <code>public void <b>crystalActivated</b>(CrystalEvent e)</code><br/><br/>
-	 * Invoked when a crystal becomes highlighted.
-	 * @param e - An object describing the event.
-	 */
-	public void crystalActivated(CrystalEvent e);
-	
-	/**
-	 * <b>crystalDeactivated</b><br/><br/>
-	 * <code>public void <b>crystalDeactivated</b>(CrystalEvent e)</code><br/><br/>
-	 * Invoked when a crystal ceases to be highlighted.
-	 * @param e - An object describing the event.
-	 */
-	public void crystalDeactivated(CrystalEvent e);
-	
-	/**
-	 * <b>crystalClicked</b><br/><br/>
-	 * <code>public void <b>crystalClicked</b>(CrystalEvent e)</code><br/><br/>
-	 * Invoked when a crystal is clicked
-	 * @param e - An object describing the event.
-	 */
-	public void crystalClicked(CrystalEvent e);
+    /**
+     * <b>crystalActivated</b><br/><br/>
+     * <code>public void <b>crystalActivated</b>(CrystalEvent e)</code><br/><br/>
+     * Invoked when a crystal becomes highlighted.
+     * @param e - An object describing the event.
+     */
+    public void crystalActivated(CrystalEvent e);
+    
+    /**
+     * <b>crystalDeactivated</b><br/><br/>
+     * <code>public void <b>crystalDeactivated</b>(CrystalEvent e)</code><br/><br/>
+     * Invoked when a crystal ceases to be highlighted.
+     * @param e - An object describing the event.
+     */
+    public void crystalDeactivated(CrystalEvent e);
+    
+    /**
+     * <b>crystalClicked</b><br/><br/>
+     * <code>public void <b>crystalClicked</b>(CrystalEvent e)</code><br/><br/>
+     * Invoked when a crystal is clicked
+     * @param e - An object describing the event.
+     */
+    public void crystalClicked(CrystalEvent e);
 }

Modified: java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/util/DatabaseCheck.java
 =============================================================================
--- java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/util/DatabaseCheck.java	(original)
+++ java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/util/DatabaseCheck.java	Wed Apr 27 11:11:32 2016
@@ -17,122 +17,122 @@
 import org.lcsim.conditions.ConditionsManager.ConditionsNotFoundException;
 
 public class DatabaseCheck {
-	private static final Set<Integer> idFailSet = new HashSet<Integer>();
-	private static final Set<Point> pointFailSet = new HashSet<Point>();
-	
-	public static void main(String[] args) throws ConditionsNotFoundException, IOException {
-		// Check that an appropriate file has been given.
-		String filepath = null;
-		if(args.length == 1) {
-			filepath = args[0];
-		}
-		
-		// If no file path was defined, throw an error.
-		if(filepath == null) {
-			throw new FileNotFoundException("No CSV mapping file defined.");
-		}
-		
-		// Initialize the local database.
-		EcalWiringManager manager = new EcalWiringManager(filepath);
-		
-		// Initialize the database.
-		int runNumber = 2000;
-		String detectorName = "HPS-Proposal2014-v7-2pt2";
-		DatabaseConditionsManager conditionsManager = DatabaseConditionsManager.getInstance();
-		conditionsManager.setDetector(detectorName, runNumber);
-		
-		// Get ECAL conditions.
-		EcalConditions ecalConditions = DatabaseConditionsManager.getInstance().getEcalConditions(); 
-		
-		// Get the list of EcalChannel objects.
-		EcalChannelCollection channels = ecalConditions.getChannelCollection();
-		EcalLedCollection leds = conditionsManager.getCachedConditions(EcalLedCollection.class, "ecal_leds").getCachedData();
-		
-		// Map the LED objects to their channels.
-		Map<Integer, EcalLed> ledMap = new HashMap<Integer, EcalLed>();
+    private static final Set<Integer> idFailSet = new HashSet<Integer>();
+    private static final Set<Point> pointFailSet = new HashSet<Point>();
+    
+    public static void main(String[] args) throws ConditionsNotFoundException, IOException {
+        // Check that an appropriate file has been given.
+        String filepath = null;
+        if(args.length == 1) {
+            filepath = args[0];
+        }
+        
+        // If no file path was defined, throw an error.
+        if(filepath == null) {
+            throw new FileNotFoundException("No CSV mapping file defined.");
+        }
+        
+        // Initialize the local database.
+        EcalWiringManager manager = new EcalWiringManager(filepath);
+        
+        // Initialize the database.
+        int runNumber = 2000;
+        String detectorName = "HPS-Proposal2014-v7-2pt2";
+        DatabaseConditionsManager conditionsManager = DatabaseConditionsManager.getInstance();
+        conditionsManager.setDetector(detectorName, runNumber);
+        
+        // Get ECAL conditions.
+        EcalConditions ecalConditions = DatabaseConditionsManager.getInstance().getEcalConditions(); 
+        
+        // Get the list of EcalChannel objects.
+        EcalChannelCollection channels = ecalConditions.getChannelCollection();
+        EcalLedCollection leds = conditionsManager.getCachedConditions(EcalLedCollection.class, "ecal_leds").getCachedData();
+        
+        // Map the LED objects to their channels.
+        Map<Integer, EcalLed> ledMap = new HashMap<Integer, EcalLed>();
         for (EcalLed led : leds) {
-        	ledMap.put(led.getEcalChannelId(), led);
+            ledMap.put(led.getEcalChannelId(), led);
         }
-		
-		// Perform the comparison test.
-		for(EcalChannel channel : channels) {
-			// Get the crystal point information.
-			Point crystal = new Point(channel.getX(), channel.getY());
-			
-			// Get the data from manager.
-			CrystalDataSet data = manager.getCrystalData(crystal);
-			
-			// Get the appropriate LED collection.
-			EcalLed led = ledMap.get(channel.getChannelId());
-			
-			// Perform the comparison.
-			System.out.printf("Checking Mappings for Crystal (%3d, %3d):%n", crystal.x, crystal.y);
-			System.out.printf("\tChannel ID      :: %d%n", channel.getChannelId());
-			
-			System.out.printf("\tChannel     [ %3d ] vs [ %3d ] ... ", channel.getChannel(), data.getFADCChannel());
-			if(channel.getChannel() == data.getFADCChannel()) {
-				System.out.printf("[ Success ]%n");
-			} else {
-				System.out.printf("[ Failure ]%n");
-				idFailSet.add(channel.getChannelId());
-				pointFailSet.add(crystal);
-			}
-			
-			int crate = data.getMotherboard().isTop() ? 1 : 2;
-			System.out.printf("\tCrate       [ %3d ] vs [ %3d ] ... ", channel.getCrate(), crate);
-			if(channel.getCrate() == crate) {
-				System.out.printf("[ Success ]%n");
-			} else {
-				System.out.printf("[ Failure ]%n");
-				idFailSet.add(channel.getChannelId());
-				pointFailSet.add(crystal);
-			}
-			
-			System.out.printf("\tSlot        [ %3d ] vs [ %3d ] ... ", channel.getSlot(), data.getFADCSlot());
-			if(channel.getSlot() == data.getFADCSlot()) {
-				System.out.printf("[ Success ]%n");
-			} else {
-				System.out.printf("[ Failure ]%n");
-				idFailSet.add(channel.getChannelId());
-				pointFailSet.add(crystal);
-			}
-			
-			System.out.printf("\tLED Channel [ %3d ] vs [ %3d ] ... ", led.getLedNumber(), data.getLEDChannel());
-			if(led.getLedNumber() == data.getLEDChannel()) {
-				System.out.printf("[ Success ]%n");
-			} else {
-				System.out.printf("[ Failure ]%n");
-				idFailSet.add(channel.getChannelId());
-				pointFailSet.add(crystal);
-			}
-			
-			System.out.printf("\tLED Crate   [ %3d ] vs [ %3d ] ... ", led.getCrateNumber(), crate);
-			if(led.getCrateNumber() == crate) {
-				System.out.printf("[ Success ]%n");
-			} else {
-				System.out.printf("[ Failure ]%n");
-				idFailSet.add(channel.getChannelId());
-				pointFailSet.add(crystal);
-			}
-			
-			System.out.println();
-			System.out.println();
-		}
-		
-		// Print out the failing crystals.
-		System.out.println("Crystals that Failed:");
-		for(Point fail : pointFailSet) {
-			System.out.printf("\tCrystal (%3d, %3d)%n", fail.x, fail.y);
-		}
-		if(pointFailSet.isEmpty()) {
-			System.out.println("\tNone!");
-		}
-		
-		// Indicate the database connection settings.
-		System.out.println("\n");
-		System.out.printf("Detector           :: %s%n", detectorName);
-		System.out.printf("Run Number         :: %d%n", runNumber);
-		System.out.printf("Channel Collection :: %d%n", channels.getCollectionId());
-		System.out.printf("LED Collection     :: %d%n", leds.getCollectionId());
-	}
+        
+        // Perform the comparison test.
+        for(EcalChannel channel : channels) {
+            // Get the crystal point information.
+            Point crystal = new Point(channel.getX(), channel.getY());
+            
+            // Get the data from manager.
+            CrystalDataSet data = manager.getCrystalData(crystal);
+            
+            // Get the appropriate LED collection.
+            EcalLed led = ledMap.get(channel.getChannelId());
+            
+            // Perform the comparison.
+            System.out.printf("Checking Mappings for Crystal (%3d, %3d):%n", crystal.x, crystal.y);
+            System.out.printf("\tChannel ID      :: %d%n", channel.getChannelId());
+            
+            System.out.printf("\tChannel     [ %3d ] vs [ %3d ] ... ", channel.getChannel(), data.getFADCChannel());
+            if(channel.getChannel() == data.getFADCChannel()) {
+                System.out.printf("[ Success ]%n");
+            } else {
+                System.out.printf("[ Failure ]%n");
+                idFailSet.add(channel.getChannelId());
+                pointFailSet.add(crystal);
+            }
+            
+            int crate = data.getMotherboard().isTop() ? 1 : 2;
+            System.out.printf("\tCrate       [ %3d ] vs [ %3d ] ... ", channel.getCrate(), crate);
+            if(channel.getCrate() == crate) {
+                System.out.printf("[ Success ]%n");
+            } else {
+                System.out.printf("[ Failure ]%n");
+                idFailSet.add(channel.getChannelId());
+                pointFailSet.add(crystal);
+            }
+            
+            System.out.printf("\tSlot        [ %3d ] vs [ %3d ] ... ", channel.getSlot(), data.getFADCSlot());
+            if(channel.getSlot() == data.getFADCSlot()) {
+                System.out.printf("[ Success ]%n");
+            } else {
+                System.out.printf("[ Failure ]%n");
+                idFailSet.add(channel.getChannelId());
+                pointFailSet.add(crystal);
+            }
+            
+            System.out.printf("\tLED Channel [ %3d ] vs [ %3d ] ... ", led.getLedNumber(), data.getLEDChannel());
+            if(led.getLedNumber() == data.getLEDChannel()) {
+                System.out.printf("[ Success ]%n");
+            } else {
+                System.out.printf("[ Failure ]%n");
+                idFailSet.add(channel.getChannelId());
+                pointFailSet.add(crystal);
+            }
+            
+            System.out.printf("\tLED Crate   [ %3d ] vs [ %3d ] ... ", led.getCrateNumber(), crate);
+            if(led.getCrateNumber() == crate) {
+                System.out.printf("[ Success ]%n");
+            } else {
+                System.out.printf("[ Failure ]%n");
+                idFailSet.add(channel.getChannelId());
+                pointFailSet.add(crystal);
+            }
+            
+            System.out.println();
+            System.out.println();
+        }
+        
+        // Print out the failing crystals.
+        System.out.println("Crystals that Failed:");
+        for(Point fail : pointFailSet) {
+            System.out.printf("\tCrystal (%3d, %3d)%n", fail.x, fail.y);
+        }
+        if(pointFailSet.isEmpty()) {
+            System.out.println("\tNone!");
+        }
+        
+        // Indicate the database connection settings.
+        System.out.println("\n");
+        System.out.printf("Detector           :: %s%n", detectorName);
+        System.out.printf("Run Number         :: %d%n", runNumber);
+        System.out.printf("Channel Collection :: %d%n", channels.getCollectionId());
+        System.out.printf("LED Collection     :: %d%n", leds.getCollectionId());
+    }
 }

Modified: java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/util/GradientScale.java
 =============================================================================
--- java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/util/GradientScale.java	(original)
+++ java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/util/GradientScale.java	Wed Apr 27 11:11:32 2016
@@ -21,9 +21,9 @@
     private int[] drgb = { 255, 255, 255 };
     
     public Color getColor(Double value) {
-    	// If the argument is null, treat it as zero.
-    	if(value == null) { value = 0.0; }
-    	
+        // If the argument is null, treat it as zero.
+        if(value == null) { value = 0.0; }
+        
         // If the value is less than the minimum, return the cold color.
         if (value < min) { return coldColor; }
         

Modified: java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/util/MultiGradientScale.java
 =============================================================================
--- java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/util/MultiGradientScale.java	(original)
+++ java/branches/HPSJAVA-409/ecal-event-display/src/main/java/org/hps/monitoring/ecal/eventdisplay/util/MultiGradientScale.java	Wed Apr 27 11:11:32 2016
@@ -29,9 +29,9 @@
     }
     
     public Color getColor(Double value) {
-    	// If the value is null, treat it as zero.
-    	if(value == null) { value = 0.0; }
-    	
+        // If the value is null, treat it as zero.
+        if(value == null) { value = 0.0; }
+        
         // Get the number of colors and scales.
         int colors = colorList.size();
         int scales = scaleList.size();
@@ -48,7 +48,7 @@
         else { sValue = Math.log10(scale * value); }
         
         if(value < 1 && (Double.isNaN(sValue) || Double.isInfinite(sValue))) {
-        	return scaleList.get(0).getColor(0.0);
+            return scaleList.get(0).getColor(0.0);
         }
         
         // Otherwise, determine which scale should get the value.

Modified: java/branches/HPSJAVA-409/ecal-readout-sim/pom.xml
 =============================================================================
--- java/branches/HPSJAVA-409/ecal-readout-sim/pom.xml	(original)
+++ java/branches/HPSJAVA-409/ecal-readout-sim/pom.xml	Wed Apr 27 11:11:32 2016
@@ -8,7 +8,7 @@
         <groupId>org.hps</groupId>
         <artifactId>hps-parent</artifactId>
         <relativePath>../parent/pom.xml</relativePath>
-        <version>3.4.2-SNAPSHOT</version>
+        <version>3.9-SNAPSHOT</version>
     </parent>
     <scm>
         <url>http://java.freehep.org/svn/repos/hps/list/java/trunk/ecal-readout-sim/</url>

Modified: java/branches/HPSJAVA-409/ecal-readout-sim/src/main/java/org/hps/readout/ecal/ClockSingleton.java
 =============================================================================
--- java/branches/HPSJAVA-409/ecal-readout-sim/src/main/java/org/hps/readout/ecal/ClockSingleton.java	(original)
+++ java/branches/HPSJAVA-409/ecal-readout-sim/src/main/java/org/hps/readout/ecal/ClockSingleton.java	Wed Apr 27 11:11:32 2016
@@ -13,35 +13,35 @@
  */
 public class ClockSingleton {
 
-	public static final ClockSingleton _instance = new ClockSingleton();
-	private int clock;
-	//time between events (bunch spacing)
-	private double dt = 2.0;
+    public static final ClockSingleton _instance = new ClockSingleton();
+    private int clock;
+    //time between events (bunch spacing)
+    private double dt = 2.0;
 
-	private ClockSingleton() {
-	}
+    private ClockSingleton() {
+    }
 
-	public static void init() {
-		_instance.clock = 0;
-	}
+    public static void init() {
+        _instance.clock = 0;
+    }
 
-	public static int getClock() {
-		return _instance.clock;
-	}
+    public static int getClock() {
+        return _instance.clock;
+    }
 
-	public static double getTime() {
-		return _instance.dt * _instance.clock;
-	}
+    public static double getTime() {
+        return _instance.dt * _instance.clock;
+    }
 
-	public static double getDt() {
-		return _instance.dt;
-	}
+    public static double getDt() {
+        return _instance.dt;
+    }
 
-	public static void setDt(double dt) {
-		_instance.dt = dt;
-	}
+    public static void setDt(double dt) {
+        _instance.dt = dt;
+    }
 
-	public static void step() {
-		_instance.clock++;
-	}
+    public static void step() {
+        _instance.clock++;
+    }
 }

Modified: java/branches/HPSJAVA-409/ecal-readout-sim/src/main/java/org/hps/readout/ecal/FADCEcalReadoutDriver.java
 =============================================================================
--- java/branches/HPSJAVA-409/ecal-readout-sim/src/main/java/org/hps/readout/ecal/FADCEcalReadoutDriver.java	(original)
+++ java/branches/HPSJAVA-409/ecal-readout-sim/src/main/java/org/hps/readout/ecal/FADCEcalReadoutDriver.java	Wed Apr 27 11:11:32 2016
@@ -310,7 +310,7 @@
     /**
      * Return the map of preamp signal buffers. For debug only.
      *
-     * @return
+     * @return the map of preamp signal buffers
      */
     public Map<Long, RingBuffer> getSignalMap() {
         return analogPipelines;
@@ -319,7 +319,7 @@
     /**
      * Return the map of FADC pipelines. For debug only.
      *
-     * @return
+     * @return the map of FADC pipelines
      */
     public Map<Long, FADCPipeline> getPipelineMap() {
         return digitalPipelines;
@@ -383,7 +383,7 @@
                     }
                 } else {
                     if (pedestalSubtractedValue < triggerThreshold || triggerPathHitTimes.get(cellID) + delay0 == readoutCounter) {
-//					System.out.printf("sum = %f\n",sum);
+//                  System.out.printf("sum = %f\n",sum);
                         triggerPathDelayQueue.add(new BaseRawCalorimeterHit(cellID,
                                 (int) Math.round((sum + pedestalSubtractedValue) / scaleFactor),
                                 64 * triggerPathHitTimes.get(cellID)));
@@ -460,15 +460,15 @@
         short[] adcValues = new short[readoutWindow];
         for (int i = 0; i < readoutWindow; i++) {
             adcValues[i] = (short) pipeline.getValue(readoutLatency - i - 1);
-//			if (adcValues[i] != 0) {
-//				System.out.println("getWindow: " + adcValues[i] + " at i = " + i);
-//			}
+//          if (adcValues[i] != 0) {
+//              System.out.println("getWindow: " + adcValues[i] + " at i = " + i);
+//          }
         }
         return adcValues;
     }
 
     protected List<RawTrackerHit> readWindow() {
-//		System.out.println("Reading FADC data");
+//      System.out.println("Reading FADC data");
         List<RawTrackerHit> hits = new ArrayList<RawTrackerHit>();
         for (Long cellID : digitalPipelines.keySet()) {
             short[] adcValues = getWindow(cellID);
@@ -488,7 +488,7 @@
     }
 
     protected List<RawTrackerHit> readPulses() {
-//		System.out.println("Reading FADC data");
+//      System.out.println("Reading FADC data");
         List<RawTrackerHit> hits = new ArrayList<RawTrackerHit>();
         for (Long cellID : digitalPipelines.keySet()) {
             short[] window = getWindow(cellID);
@@ -522,7 +522,7 @@
     }
 
     protected List<RawCalorimeterHit> readIntegrals() {
-//		System.out.println("Reading FADC data");
+//      System.out.println("Reading FADC data");
         List<RawCalorimeterHit> hits = new ArrayList<RawCalorimeterHit>();
         for (Long cellID : digitalPipelines.keySet()) {
             short[] window = getWindow(cellID);

Modified: java/branches/HPSJAVA-409/ecal-readout-sim/src/main/java/org/hps/readout/ecal/FADCPrimaryTriggerDriver.java
 =============================================================================
--- java/branches/HPSJAVA-409/ecal-readout-sim/src/main/java/org/hps/readout/ecal/FADCPrimaryTriggerDriver.java	(original)
+++ java/branches/HPSJAVA-409/ecal-readout-sim/src/main/java/org/hps/readout/ecal/FADCPrimaryTriggerDriver.java	Wed Apr 27 11:11:32 2016
@@ -34,7 +34,7 @@
     private int pairCoincidence = 2;                              // Maximum allowed time difference between clusters. (4 ns clock-cycles)
     private int backgroundLevel = -1;                             // Automatically sets the cuts to achieve a predetermined background rate.
     private TriggerModule triggerModule = new TriggerModule(1.0, 0.050,
-    		6.600, 0.010, 6.600, 0.000, 13.200, 6.600, 0.0, 360, 0.0055);
+            6.600, 0.010, 6.600, 0.000, 13.200, 6.600, 0.0, 360, 0.0055);
     
     // ==================================================================
     // ==== Driver Internal Variables ===================================
@@ -77,55 +77,55 @@
      */
     @Override
     public void startOfData() {
-    	// Define plot type names.
-    	String[] plotType = new String[PLOT_COUNT];
-    	plotType[NO_CUTS] = "";
-    	plotType[ALL_CUTS] = " (Passed All Cuts)";
-    	plotType[OVER_1HIT] = " (More than 1 Hit)";
-    	plotType[OVER_2HIT] = " (More than 2 Hits)";
-    	plotType[SINGLES_CUTS] = " (Passed Single Cuts)";
-    	
-    	// Define plot type directories.
-    	String[] plotDir = new String[PLOT_COUNT];
-    	plotDir[NO_CUTS] = "NoCuts/";
-    	plotDir[ALL_CUTS] = "PassedAll/";
-    	plotDir[OVER_1HIT] = "2PlusHits/";
-    	plotDir[OVER_2HIT] = "3PlusHits/";
-    	plotDir[SINGLES_CUTS] = "PassedSingles/";
-    	
-    	// Instantiate the singles plot arrays.
-    	clusterSeedEnergy = new IHistogram1D[PLOT_COUNT];
-    	clusterHitCount = new IHistogram1D[PLOT_COUNT];
-    	clusterTotalEnergy = new IHistogram1D[PLOT_COUNT];
-    	clusterDistribution = new IHistogram2D[PLOT_COUNT];
-    	
-    	// Instantiate the pair plot arrays. Note that the pair cuts
-    	// only ever see clusters that pass the singles cuts, so the
-    	// "passed singles cuts" plots are meaningless. Thusly, the
-    	// pair plots have one fewer plot than the singles.
-    	pairEnergySum = new IHistogram1D[PLOT_COUNT - 1];
-    	pairEnergyDifference = new IHistogram1D[PLOT_COUNT - 1];
-    	pairCoplanarity = new IHistogram1D[PLOT_COUNT - 1];
-    	pairEnergySlope = new IHistogram1D[PLOT_COUNT - 1];
-    	pairEnergySum2DDistribution = new IHistogram2D[PLOT_COUNT - 1];
-    	
-    	// Instantiate the plots.
-    	for(int i = 0; i < PLOT_COUNT; i++) {
-    		System.out.println(plotDir[i] + "Cluster Seed Energy" + plotType[i]);
-    		clusterSeedEnergy[i] = aida.histogram1D(plotDir[i] + "Cluster Seed Energy" + plotType[i], 176, 0.0, 2.2);
-    		clusterHitCount[i] = aida.histogram1D(plotDir[i] + "Cluster Hit Count" + plotType[i], 9, 0.5, 9.5);
-    		clusterTotalEnergy[i] = aida.histogram1D(plotDir[i] + "Cluster Total Energy" + plotType[i], 176, 0.0, 2.2);
-    		clusterDistribution[i] = aida.histogram2D(plotDir[i] + "Cluster Seed" + plotType[i], 46, -23, 23, 11, -5.5, 5.5);
-    		
-    		if(i != PLOT_COUNT - 1) {
-    			pairEnergySum[i] = aida.histogram1D(plotDir[i] + "Pair Energy Sum" + plotType[i], 176, 0.0, 4.4);
-    			pairEnergyDifference[i] = aida.histogram1D(plotDir[i] + "Pair Energy Difference" + plotType[i], 176, 0.0, 2.2);
-    			pairCoplanarity[i] = aida.histogram1D(plotDir[i] + "Pair Coplanarity" + plotType[i], 180, 0.0, 180.0);
-    			pairEnergySlope[i] = aida.histogram1D(plotDir[i] + "Pair Energy Slope" + plotType[i], 200, 0.0, 4.0);
-    			pairEnergySum2DDistribution[i] = aida.histogram2D(plotDir[i] + "Pair Energy Sum 2D" + plotType[i], 176, 0.0, 4.4, 176, 0.0, 4.4);
-    		}
-    	}
-    	
+        // Define plot type names.
+        String[] plotType = new String[PLOT_COUNT];
+        plotType[NO_CUTS] = "";
+        plotType[ALL_CUTS] = " (Passed All Cuts)";
+        plotType[OVER_1HIT] = " (More than 1 Hit)";
+        plotType[OVER_2HIT] = " (More than 2 Hits)";
+        plotType[SINGLES_CUTS] = " (Passed Single Cuts)";
+        
+        // Define plot type directories.
+        String[] plotDir = new String[PLOT_COUNT];
+        plotDir[NO_CUTS] = "NoCuts/";
+        plotDir[ALL_CUTS] = "PassedAll/";
+        plotDir[OVER_1HIT] = "2PlusHits/";
+        plotDir[OVER_2HIT] = "3PlusHits/";
+        plotDir[SINGLES_CUTS] = "PassedSingles/";
+        
+        // Instantiate the singles plot arrays.
+        clusterSeedEnergy = new IHistogram1D[PLOT_COUNT];
+        clusterHitCount = new IHistogram1D[PLOT_COUNT];
+        clusterTotalEnergy = new IHistogram1D[PLOT_COUNT];
+        clusterDistribution = new IHistogram2D[PLOT_COUNT];
+        
+        // Instantiate the pair plot arrays. Note that the pair cuts
+        // only ever see clusters that pass the singles cuts, so the
+        // "passed singles cuts" plots are meaningless. Thusly, the
+        // pair plots have one fewer plot than the singles.
+        pairEnergySum = new IHistogram1D[PLOT_COUNT - 1];
+        pairEnergyDifference = new IHistogram1D[PLOT_COUNT - 1];
+        pairCoplanarity = new IHistogram1D[PLOT_COUNT - 1];
+        pairEnergySlope = new IHistogram1D[PLOT_COUNT - 1];
+        pairEnergySum2DDistribution = new IHistogram2D[PLOT_COUNT - 1];
+        
+        // Instantiate the plots.
+        for(int i = 0; i < PLOT_COUNT; i++) {
+            System.out.println(plotDir[i] + "Cluster Seed Energy" + plotType[i]);
+            clusterSeedEnergy[i] = aida.histogram1D(plotDir[i] + "Cluster Seed Energy" + plotType[i], 176, 0.0, 2.2);
+            clusterHitCount[i] = aida.histogram1D(plotDir[i] + "Cluster Hit Count" + plotType[i], 9, 0.5, 9.5);
+            clusterTotalEnergy[i] = aida.histogram1D(plotDir[i] + "Cluster Total Energy" + plotType[i], 176, 0.0, 2.2);
+            clusterDistribution[i] = aida.histogram2D(plotDir[i] + "Cluster Seed" + plotType[i], 46, -23, 23, 11, -5.5, 5.5);
+            
+            if(i != PLOT_COUNT - 1) {
+                pairEnergySum[i] = aida.histogram1D(plotDir[i] + "Pair Energy Sum" + plotType[i], 176, 0.0, 4.4);
+                pairEnergyDifference[i] = aida.histogram1D(plotDir[i] + "Pair Energy Difference" + plotType[i], 176, 0.0, 2.2);
+                pairCoplanarity[i] = aida.histogram1D(plotDir[i] + "Pair Coplanarity" + plotType[i], 180, 0.0, 180.0);
+                pairEnergySlope[i] = aida.histogram1D(plotDir[i] + "Pair Energy Slope" + plotType[i], 200, 0.0, 4.0);
+                pairEnergySum2DDistribution[i] = aida.histogram2D(plotDir[i] + "Pair Energy Sum 2D" + plotType[i], 176, 0.0, 4.4, 176, 0.0, 4.4);
+            }
+        }
+        
         // Make sure that a valid cluster collection name has been
         // defined. If it has not, throw an exception.
         if (clusterCollectionName == null) {
@@ -239,15 +239,15 @@
                 
                 // Fill the hit count plots for N > 1.
                 if(hitCount > 1) {
-                	// Populate the plots.
+                    // Populate the plots.
                     clusterSeedEnergy[OVER_1HIT].fill(seedEnergy);
                     clusterTotalEnergy[OVER_1HIT].fill(clusterEnergy);
                     clusterHitCount[OVER_1HIT].fill(hitCount);
                     clusterDistribution[OVER_1HIT].fill(ix, iy);
-                	
+                    
                     // Fill the hit count plots for N > 2.
                     if(hitCount > 2) {
-                    	// Populate the plots.
+                        // Populate the plots.
                         clusterSeedEnergy[OVER_2HIT].fill(seedEnergy);
                         clusterTotalEnergy[OVER_2HIT].fill(clusterEnergy);
                         clusterHitCount[OVER_2HIT].fill(hitCount);
@@ -260,14 +260,14 @@
                 // VERBOSE :: Print the seed energy comparison check.
                 if(verbose) {
                     System.out.printf("\tSeed Energy Cut    :: %.3f < %.3f < %.3f --> %b%n",
-                    		triggerModule.getCutValue(TriggerModule.CLUSTER_SEED_ENERGY_LOW), seedEnergy,
-                    		triggerModule.getCutValue(TriggerModule.CLUSTER_SEED_ENERGY_HIGH),
-                    		triggerModule.clusterSeedEnergyCut(cluster));
+                            triggerModule.getCutValue(TriggerModule.CLUSTER_SEED_ENERGY_LOW), seedEnergy,
+                            triggerModule.getCutValue(TriggerModule.CLUSTER_SEED_ENERGY_HIGH),
+                            triggerModule.clusterSeedEnergyCut(cluster));
                 }
                 
                 // If the cluster fails the cut, skip to the next cluster.
                 if(!triggerModule.clusterSeedEnergyCut(cluster)) {
-                	continue clusterLoop;
+                    continue clusterLoop;
                 }
                 
                 // Otherwise, note that it passed the cut.
@@ -278,13 +278,13 @@
                 // VERBOSE :: Print the hit count comparison check.
                 if(verbose) {
                     System.out.printf("\tHit Count Cut      :: %d >= %.0f --> %b%n",
-                    		hitCount, triggerModule.getCutValue(TriggerModule.CLUSTER_HIT_COUNT_LOW),
-                    		triggerModule.clusterHitCountCut(cluster));
+                            hitCount, triggerModule.getCutValue(TriggerModule.CLUSTER_HIT_COUNT_LOW),
+                            triggerModule.clusterHitCountCut(cluster));
                 }
                 
                 // If the cluster fails the cut, skip to the next cluster.
                 if(!triggerModule.clusterHitCountCut(cluster)) {
-                	continue clusterLoop;
+                    continue clusterLoop;
                 }
                 
                 // Otherwise, note that it passed the cut.
@@ -295,14 +295,14 @@
                 // VERBOSE :: Print the cluster energy comparison check.
                 if(verbose) {
                     System.out.printf("\tCluster Energy Cut :: %.3f < %.3f < %.3f --> %b%n",
-                    		triggerModule.getCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_LOW), clusterEnergy,
-                    		triggerModule.getCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_HIGH),
-                    		triggerModule.clusterTotalEnergyCut(cluster));
+                            triggerModule.getCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_LOW), clusterEnergy,
+                            triggerModule.getCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_HIGH),
+                            triggerModule.clusterTotalEnergyCut(cluster));
                 }
                 
                 // If the cluster fails the cut, skip to the next cluster.
                 if(!triggerModule.clusterTotalEnergyCut(cluster)) {
-                	continue clusterLoop;
+                    continue clusterLoop;
                 }
                 
                 // Otherwise, note that it passed the cut.
@@ -368,7 +368,7 @@
      * Sets the maximum deviation from coplanarity that a cluster pair
      * may possess and still pass the coplanarity pair cut. Value uses
      * units of degrees.
-     * @param maxCoplanarityAngle - The parameter value.
+     * @param coplanarityHigh - The parameter value.
      */
     public void setCoplanarityHigh(double coplanarityHigh) {
         triggerModule.setCutValue(TriggerModule.PAIR_COPLANARITY_HIGH, coplanarityHigh);
@@ -407,7 +407,7 @@
      * Sets the lowest allowed energy a cluster pair may have and
      * still pass the cluster pair energy sum cluster cut. Value uses
      * units of GeV.
-     * @param energySumHigh - The parameter value.
+     * @param energySumLow - The parameter value.
      */
     public void setEnergySumLow(double energySumLow) {
         triggerModule.setCutValue(TriggerModule.PAIR_ENERGY_SUM_LOW, energySumLow * EcalUtils.GeV);
@@ -544,63 +544,63 @@
         
         // Some cut values are almost always the same thing. Set those
         // here and only overwrite if necessary.
-    	triggerModule.setCutValue(TriggerModule.CLUSTER_SEED_ENERGY_LOW,     0.125);
-    	triggerModule.setCutValue(TriggerModule.CLUSTER_SEED_ENERGY_HIGH,    1.300);
-    	triggerModule.setCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_LOW,    0.200);
-    	triggerModule.setCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_HIGH,   1.700);
-    	triggerModule.setCutValue(TriggerModule.PAIR_ENERGY_SUM_LOW,         0.500);
-    	triggerModule.setCutValue(TriggerModule.PAIR_ENERGY_SUM_HIGH,        2.000);
-    	triggerModule.setCutValue(TriggerModule.PAIR_ENERGY_DIFFERENCE_HIGH, 1.200);
-    	triggerModule.setCutValue(TriggerModule.PAIR_COPLANARITY_HIGH,       30);
-    	triggerModule.setCutValue(TriggerModule.CLUSTER_HIT_COUNT_LOW,       2);
+        triggerModule.setCutValue(TriggerModule.CLUSTER_SEED_ENERGY_LOW,     0.125);
+        triggerModule.setCutValue(TriggerModule.CLUSTER_SEED_ENERGY_HIGH,    1.300);
+        triggerModule.setCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_LOW,    0.200);
+        triggerModule.setCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_HIGH,   1.700);
+        triggerModule.setCutValue(TriggerModule.PAIR_ENERGY_SUM_LOW,         0.500);
+        triggerModule.setCutValue(TriggerModule.PAIR_ENERGY_SUM_HIGH,        2.000);
+        triggerModule.setCutValue(TriggerModule.PAIR_ENERGY_DIFFERENCE_HIGH, 1.200);
+        triggerModule.setCutValue(TriggerModule.PAIR_COPLANARITY_HIGH,       30);
+        triggerModule.setCutValue(TriggerModule.CLUSTER_HIT_COUNT_LOW,       2);
         
         // Set the variable values.
         if(backgroundLevel == 1) {
-        	triggerModule.setCutValue(TriggerModule.PAIR_ENERGY_SUM_LOW,         1.000);
-        	triggerModule.setCutValue(TriggerModule.PAIR_ENERGY_SLOPE_LOW,       1.2);
-        	triggerModule.setCutValue(TriggerModule.PAIR_COPLANARITY_HIGH,       20);
+            triggerModule.setCutValue(TriggerModule.PAIR_ENERGY_SUM_LOW,         1.000);
+            triggerModule.setCutValue(TriggerModule.PAIR_ENERGY_SLOPE_LOW,       1.2);
+            triggerModule.setCutValue(TriggerModule.PAIR_COPLANARITY_HIGH,       20);
         } else if(backgroundLevel == 2) {
-        	triggerModule.setCutValue(TriggerModule.PAIR_ENERGY_SLOPE_LOW,       1.0);
-        	triggerModule.setCutValue(TriggerModule.PAIR_COPLANARITY_HIGH,       20);
+            triggerModule.setCutValue(TriggerModule.PAIR_ENERGY_SLOPE_LOW,       1.0);
+            triggerModule.setCutValue(TriggerModule.PAIR_COPLANARITY_HIGH,       20);
         } else if(backgroundLevel == 3) {
-        	triggerModule.setCutValue(TriggerModule.PAIR_ENERGY_SLOPE_LOW,       1.0);
+            triggerModule.setCutValue(TriggerModule.PAIR_ENERGY_SLOPE_LOW,       1.0);
         } else if(backgroundLevel == 4) {
-        	triggerModule.setCutValue(TriggerModule.PAIR_ENERGY_SLOPE_LOW,       0.8);
+            triggerModule.setCutValue(TriggerModule.PAIR_ENERGY_SLOPE_LOW,       0.8);
         } else if(backgroundLevel == 5) {
-        	triggerModule.setCutValue(TriggerModule.PAIR_ENERGY_SLOPE_LOW,       0.8);
+            triggerModule.setCutValue(TriggerModule.PAIR_ENERGY_SLOPE_LOW,       0.8);
         } else if(backgroundLevel == 6) {
-        	triggerModule.setCutValue(TriggerModule.PAIR_ENERGY_SLOPE_LOW,       0.6);
+            triggerModule.setCutValue(TriggerModule.PAIR_ENERGY_SLOPE_LOW,       0.6);
         } else if(backgroundLevel == 7) {
-        	triggerModule.setCutValue(TriggerModule.PAIR_ENERGY_SLOPE_LOW,       0.6);
+            triggerModule.setCutValue(TriggerModule.PAIR_ENERGY_SLOPE_LOW,       0.6);
         } else if(backgroundLevel == 8) {
-        	triggerModule.setCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_HIGH,   1.500);
-        	triggerModule.setCutValue(TriggerModule.PAIR_ENERGY_SLOPE_LOW,       0.4);
+            triggerModule.setCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_HIGH,   1.500);
+            triggerModule.setCutValue(TriggerModule.PAIR_ENERGY_SLOPE_LOW,       0.4);
         } else if(backgroundLevel == 9) {
-        	triggerModule.setCutValue(TriggerModule.PAIR_ENERGY_SLOPE_LOW,       0.4);
+            triggerModule.setCutValue(TriggerModule.PAIR_ENERGY_SLOPE_LOW,       0.4);
         } else if(backgroundLevel == 10) {
-        	triggerModule.setCutValue(TriggerModule.PAIR_ENERGY_SLOPE_LOW,       0.4);
+            triggerModule.setCutValue(TriggerModule.PAIR_ENERGY_SLOPE_LOW,       0.4);
         } else if(backgroundLevel == 0) {
-        	triggerModule.setCutValue(TriggerModule.CLUSTER_SEED_ENERGY_LOW,     0.100);
-        	triggerModule.setCutValue(TriggerModule.CLUSTER_SEED_ENERGY_HIGH,    6.600);
-        	triggerModule.setCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_LOW,    0.100);
-        	triggerModule.setCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_HIGH,   1.500);
-        	triggerModule.setCutValue(TriggerModule.PAIR_ENERGY_SUM_LOW,         0.000);
-        	triggerModule.setCutValue(TriggerModule.PAIR_ENERGY_SUM_HIGH,        1.900);
-        	triggerModule.setCutValue(TriggerModule.PAIR_ENERGY_DIFFERENCE_HIGH, 2.200);
-        	triggerModule.setCutValue(TriggerModule.PAIR_ENERGY_SLOPE_LOW,       1.1);
-        	triggerModule.setCutValue(TriggerModule.PAIR_COPLANARITY_HIGH,       35);
-        	triggerModule.setCutValue(TriggerModule.CLUSTER_HIT_COUNT_LOW,       1);
+            triggerModule.setCutValue(TriggerModule.CLUSTER_SEED_ENERGY_LOW,     0.100);
+            triggerModule.setCutValue(TriggerModule.CLUSTER_SEED_ENERGY_HIGH,    6.600);
+            triggerModule.setCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_LOW,    0.100);
+            triggerModule.setCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_HIGH,   1.500);
+            triggerModule.setCutValue(TriggerModule.PAIR_ENERGY_SUM_LOW,         0.000);
+            triggerModule.setCutValue(TriggerModule.PAIR_ENERGY_SUM_HIGH,        1.900);
+            triggerModule.setCutValue(TriggerModule.PAIR_ENERGY_DIFFERENCE_HIGH, 2.200);
+            triggerModule.setCutValue(TriggerModule.PAIR_ENERGY_SLOPE_LOW,       1.1);
+            triggerModule.setCutValue(TriggerModule.PAIR_COPLANARITY_HIGH,       35);
+            triggerModule.setCutValue(TriggerModule.CLUSTER_HIT_COUNT_LOW,       1);
         } else if(backgroundLevel == -1) {
-        	triggerModule.setCutValue(TriggerModule.CLUSTER_SEED_ENERGY_LOW,     0.050);
-        	triggerModule.setCutValue(TriggerModule.CLUSTER_SEED_ENERGY_HIGH,    6.600);
-        	triggerModule.setCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_LOW,    0.010);
-        	triggerModule.setCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_HIGH,   6.600);
-        	triggerModule.setCutValue(TriggerModule.PAIR_ENERGY_SUM_LOW,         0.000);
-        	triggerModule.setCutValue(TriggerModule.PAIR_ENERGY_SUM_HIGH,        13.200);
-        	triggerModule.setCutValue(TriggerModule.PAIR_ENERGY_DIFFERENCE_HIGH, 6.600);
-        	triggerModule.setCutValue(TriggerModule.PAIR_ENERGY_SLOPE_LOW,       0.0);
-        	triggerModule.setCutValue(TriggerModule.PAIR_COPLANARITY_HIGH,       360);
-        	triggerModule.setCutValue(TriggerModule.CLUSTER_HIT_COUNT_LOW,       1);
+            triggerModule.setCutValue(TriggerModule.CLUSTER_SEED_ENERGY_LOW,     0.050);
+            triggerModule.setCutValue(TriggerModule.CLUSTER_SEED_ENERGY_HIGH,    6.600);
+            triggerModule.setCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_LOW,    0.010);
+            triggerModule.setCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_HIGH,   6.600);
+            triggerModule.setCutValue(TriggerModule.PAIR_ENERGY_SUM_LOW,         0.000);
+            triggerModule.setCutValue(TriggerModule.PAIR_ENERGY_SUM_HIGH,        13.200);
+            triggerModule.setCutValue(TriggerModule.PAIR_ENERGY_DIFFERENCE_HIGH, 6.600);
+            triggerModule.setCutValue(TriggerModule.PAIR_ENERGY_SLOPE_LOW,       0.0);
+            triggerModule.setCutValue(TriggerModule.PAIR_COPLANARITY_HIGH,       360);
+            triggerModule.setCutValue(TriggerModule.CLUSTER_HIT_COUNT_LOW,       1);
         }
     }
     
@@ -636,16 +636,16 @@
             
             // Fill the hit count plots for N > 1.
             if(clusterPair[0].getCalorimeterHits().size() > 1 && clusterPair[1].getCalorimeterHits().size() > 1) {
-            	// Populate the plots.
+                // Populate the plots.
                 pairEnergySum[OVER_1HIT].fill(energySum);
                 pairEnergyDifference[OVER_1HIT].fill(energyDifference);
                 pairEnergySlope[OVER_1HIT].fill(energySlope);
                 pairCoplanarity[OVER_1HIT].fill(coplanarity);
                 pairEnergySum2DDistribution[OVER_1HIT].fill(clusterPair[0].getEnergy(), clusterPair[1].getEnergy());
-            	
+                
                 // Fill the hit count plots for N > 2.
                 if(clusterPair[0].getCalorimeterHits().size() > 2 && clusterPair[1].getCalorimeterHits().size() > 2) {
-                	// Populate the plots.
+                    // Populate the plots.
                     pairEnergySum[OVER_2HIT].fill(energySum);
                     pairEnergyDifference[OVER_2HIT].fill(energyDifference);
                     pairEnergySlope[OVER_2HIT].fill(energySlope);
@@ -658,7 +658,7 @@
             // =============================================================
             // If the cluster fails the cut, skip to the next pair.
             if(!triggerModule.pairEnergySumCut(clusterPair)) {
-            	continue pairLoop;
+                continue pairLoop;
             }
             
             // Otherwise, note that it passed the cut.
@@ -668,7 +668,7 @@
             // =============================================================
             // If the cluster fails the cut, skip to the next pair.
             if(!triggerModule.pairEnergyDifferenceCut(clusterPair)) {
-            	continue pairLoop;
+                continue pairLoop;
             }
             
             // Otherwise, note that it passed the cut.
@@ -678,7 +678,7 @@
             // =============================================================
             // If the cluster fails the cut, skip to the next pair.
             if(!triggerModule.pairEnergySlopeCut(clusterPair)) {
-            	continue pairLoop;
+                continue pairLoop;
             }
             
             // Otherwise, note that it passed the cut.
@@ -688,7 +688,7 @@
             // =============================================================
             // If the cluster fails the cut, skip to the next pair.
             if(!triggerModule.pairCoplanarityCut(clusterPair)) {
-            	continue pairLoop;
+                continue pairLoop;
             }
             
             // Otherwise, note that it passed the cut.
@@ -774,6 +774,6 @@
      * @param cuts - The cut string.
      */
     public void setCuts(String cuts) {
-    	triggerModule.setCutValues(false, cuts);
+        triggerModule.setCutValues(false, cuts);
     }
 }

Modified: java/branches/HPSJAVA-409/ecal-readout-sim/src/main/java/org/hps/readout/ecal/FADCTriggerDriver.java
 =============================================================================
--- java/branches/HPSJAVA-409/ecal-readout-sim/src/main/java/org/hps/readout/ecal/FADCTriggerDriver.java	(original)
+++ java/branches/HPSJAVA-409/ecal-readout-sim/src/main/java/org/hps/readout/ecal/FADCTriggerDriver.java	Wed Apr 27 11:11:32 2016
@@ -532,7 +532,6 @@
     /**
      * Get a list of all unique cluster pairs in the event
      *
-     * @param ecalClusters : List of ECal clusters
      * @return list of cluster pairs
      */
     protected List<Cluster[]> getClusterPairsTopBot() {
@@ -584,7 +583,7 @@
      * Checks if the ECal clusters making up a cluster pair both have at least
      * the minimum number of hits.
      *
-     * @param clusterPair: pair of clusters
+     * @param clusterPair the pair of clusters
      * @return true if pair passes cut, false if fail
      */
     protected boolean clusterHitCount(Cluster[] clusterPair) {

Modified: java/branches/HPSJAVA-409/ecal-readout-sim/src/main/java/org/hps/readout/ecal/FADCTriggerVariableDriver.java
 =============================================================================
--- java/branches/HPSJAVA-409/ecal-readout-sim/src/main/java/org/hps/readout/ecal/FADCTriggerVariableDriver.java	(original)
+++ java/branches/HPSJAVA-409/ecal-readout-sim/src/main/java/org/hps/readout/ecal/FADCTriggerVariableDriver.java	Wed Apr 27 11:11:32 2016
@@ -63,14 +63,14 @@
 
             //System.out.printf("%d ecal clusters in event\n", clusters.size());
             //System.out.printf("%s: %d clusters\n",this.getClass().getSimpleName(),clusters.size());
-        	//for(Cluster cl : clusters) {
-        	//	System.out.printf("%s: cl E %f x %f y %f \n",this.getClass().getSimpleName(),cl.getEnergy(),cl.getPosition()[0],cl.getPosition()[1]);
-        	//}
-        	List<Cluster> unique_clusters = this.getUniqueClusters(clusters);
-        	//System.out.printf("%s: %d unique clusters\n",this.getClass().getSimpleName(),unique_clusters.size());
-        	//for(Cluster cl : unique_clusters) {
-        	//	System.out.printf("%s: cl E %f x %f y %f \n",this.getClass().getSimpleName(),cl.getEnergy(),cl.getPosition()[0],cl.getPosition()[1]);
-        	//}
+            //for(Cluster cl : clusters) {
+            //  System.out.printf("%s: cl E %f x %f y %f \n",this.getClass().getSimpleName(),cl.getEnergy(),cl.getPosition()[0],cl.getPosition()[1]);
+            //}
+            List<Cluster> unique_clusters = this.getUniqueClusters(clusters);
+            //System.out.printf("%s: %d unique clusters\n",this.getClass().getSimpleName(),unique_clusters.size());
+            //for(Cluster cl : unique_clusters) {
+            //  System.out.printf("%s: cl E %f x %f y %f \n",this.getClass().getSimpleName(),cl.getEnergy(),cl.getPosition()[0],cl.getPosition()[1]);
+            //}
 
             updateClusterQueues(unique_clusters);
             List<Cluster[]> clusterPairs = getClusterPairsTopBot();
@@ -122,47 +122,47 @@
     
     
     private List<Cluster> getUniqueClusters(List<Cluster> clusters) {
-    	List<Cluster> unique = new ArrayList<Cluster>();
-    	for(Cluster loop_cl : clusters) {
-			ClusterCmp loop_clCmp = new ClusterCmp(loop_cl);
-    		boolean found = false;
-			for(Cluster cl : unique) {
-    			if( loop_clCmp.compareTo(cl) == 0 ) {
-    				found = true;
-    			}
-    		}
-			if( !found ) {
-				unique.add(loop_cl);
-			}
-    	}
-    	return unique;
+        List<Cluster> unique = new ArrayList<Cluster>();
+        for(Cluster loop_cl : clusters) {
+            ClusterCmp loop_clCmp = new ClusterCmp(loop_cl);
+            boolean found = false;
+            for(Cluster cl : unique) {
+                if( loop_clCmp.compareTo(cl) == 0 ) {
+                    found = true;
+                }
+            }
+            if( !found ) {
+                unique.add(loop_cl);
+            }
+        }
+        return unique;
     }
 
 
     private static class ClusterCmp implements Comparable<Cluster> {
-    	private Cluster _cluster;
-		public ClusterCmp(Cluster cl) {
-			set_cluster(cl);
-		}
-		@Override
-		public int compareTo(Cluster cl) {
-				if(cl.getEnergy()==get_cluster().getEnergy() && cl.getPosition()[0]==get_cluster().getPosition()[0] && cl.getPosition()[1]==get_cluster().getPosition()[1] ) {
-					return 0;
-				} else {
-					if( cl.getEnergy() > get_cluster().getEnergy()) {
-						return 1;
-					} else {
-						return -1;
-					}
-				}
-		}
-		public Cluster get_cluster() {
-			return _cluster;
-		}
-		public void set_cluster(Cluster _cluster) {
-			this._cluster = _cluster;
-		}
-    	
+        private Cluster _cluster;
+        public ClusterCmp(Cluster cl) {
+            set_cluster(cl);
+        }
+        @Override
+        public int compareTo(Cluster cl) {
+                if(cl.getEnergy()==get_cluster().getEnergy() && cl.getPosition()[0]==get_cluster().getPosition()[0] && cl.getPosition()[1]==get_cluster().getPosition()[1] ) {
+                    return 0;
+                } else {
+                    if( cl.getEnergy() > get_cluster().getEnergy()) {
+                        return 1;
+                    } else {
+                        return -1;
+                    }
+                }
+        }
+        public Cluster get_cluster() {
+            return _cluster;
+        }
+        public void set_cluster(Cluster _cluster) {
+            this._cluster = _cluster;
+        }
+        
     }
     
 }

Modified: java/branches/HPSJAVA-409/ecal-readout-sim/src/main/java/org/hps/readout/ecal/MollerTriggerDriver.java
 =============================================================================
--- java/branches/HPSJAVA-409/ecal-readout-sim/src/main/java/org/hps/readout/ecal/MollerTriggerDriver.java	(original)
+++ java/branches/HPSJAVA-409/ecal-readout-sim/src/main/java/org/hps/readout/ecal/MollerTriggerDriver.java	Wed Apr 27 11:11:32 2016
@@ -56,8 +56,8 @@
     
     @Override
     public void process(EventHeader event) {
-    	// Run the superclass process event.
-    	super.process(event);
+        // Run the superclass process event.
+        super.process(event);
     }
     
     @Override
@@ -87,29 +87,29 @@
         aMomentumAngle = aida.histogram2D("Trigger Plots :: Particle Momentum Distribution (t = 0, Passed All Cuts)", 500, -0.01, 0.06, 500, -0.04, 0.04);
         
         // Add the allowed seed crystal positions to the seed set.
-		if(useVersionOne) {
-	        // Add the allowed seed crystal positions to the seed set.
-	        // y = +/- 1, x = -11 -> -15
-	        for(int ix = -15; ix <= -11; ix++) {
-	            allowedSeedSet.add(new Point(ix, 1));
-	            allowedSeedSet.add(new Point(ix, -1));
-	        } // y = +/- 2, x = -9 -> -15
-	        for(int ix = -15; ix <= -9; ix++) {
-	            allowedSeedSet.add(new Point(ix, 2));
-	            allowedSeedSet.add(new Point(ix, -2));
-	        }
-		}
-		else {
-	        // y = +/- 1, x = -11 -> -13
-	        for(int ix = -13; ix <= -11; ix++) {
-	            allowedSeedSet.add(new Point(ix, 1));
-	            allowedSeedSet.add(new Point(ix, -1));
-	        } // y = +/- 2, x = -10 -> -14
-	        for(int ix = -14; ix <= -10; ix++) {
-	            allowedSeedSet.add(new Point(ix, 2));
-	            allowedSeedSet.add(new Point(ix, -2));
-	        }
-		}
+        if(useVersionOne) {
+            // Add the allowed seed crystal positions to the seed set.
+            // y = +/- 1, x = -11 -> -15
+            for(int ix = -15; ix <= -11; ix++) {
+                allowedSeedSet.add(new Point(ix, 1));
+                allowedSeedSet.add(new Point(ix, -1));
+            } // y = +/- 2, x = -9 -> -15
+            for(int ix = -15; ix <= -9; ix++) {
+                allowedSeedSet.add(new Point(ix, 2));
+                allowedSeedSet.add(new Point(ix, -2));
+            }
+        }
+        else {
+            // y = +/- 1, x = -11 -> -13
+            for(int ix = -13; ix <= -11; ix++) {
+                allowedSeedSet.add(new Point(ix, 1));
+                allowedSeedSet.add(new Point(ix, -1));
+            } // y = +/- 2, x = -10 -> -14
+            for(int ix = -14; ix <= -10; ix++) {
+                allowedSeedSet.add(new Point(ix, 2));
+                allowedSeedSet.add(new Point(ix, -2));
+            }
+        }
     }
     
     @Override
@@ -201,31 +201,31 @@
             // Require that the cluster pass each of the cuts in
             // order to qualify for a trigger.
             if(totalEnergyCut && seedEnergyCut && hitCountCut && positionCut) {
-            	// Increment the number of events that have passed
-            	// the cuts.
-            	passedEvents++;
-            	
-            	// If the number of passed events exceeds the prescaling
-            	// threshold, throw a trigger.
-            	if(passedEvents >= prescale) {
-            		// Reset the number of passed events.
-            		passedEvents = 0;
-            		
-	                // Add the clusters to the cut histograms.
-	                aClusterHitCount.fill(cluster.getCalorimeterHits().size());
-	                aClusterTotalEnergy.fill(cluster.getEnergy());
-	                aClusterSeedEnergy.fill(cluster.getCalorimeterHits().get(0).getCorrectedEnergy());
-	                aClusterDistribution.fill(ix > 0 ? ix - 1 : ix, iy, 1);
-	                
-	                // Increment the trigger count.
-	                triggers++;
-	                
-	                // VERBOSE :: Indicate that a trigger occurred.
-	                if(verbose) { System.out.printf("\tTriggered!%n%n"); }
-	                
-	                // Return a trigger.
-	                return true;
-            	}
+                // Increment the number of events that have passed
+                // the cuts.
+                passedEvents++;
+                
+                // If the number of passed events exceeds the prescaling
+                // threshold, throw a trigger.
+                if(passedEvents >= prescale) {
+                    // Reset the number of passed events.
+                    passedEvents = 0;
+                    
+                    // Add the clusters to the cut histograms.
+                    aClusterHitCount.fill(cluster.getCalorimeterHits().size());
+                    aClusterTotalEnergy.fill(cluster.getEnergy());
+                    aClusterSeedEnergy.fill(cluster.getCalorimeterHits().get(0).getCorrectedEnergy());
+                    aClusterDistribution.fill(ix > 0 ? ix - 1 : ix, iy, 1);
+                    
+                    // Increment the trigger count.
+                    triggers++;
+                    
+                    // VERBOSE :: Indicate that a trigger occurred.
+                    if(verbose) { System.out.printf("\tTriggered!%n%n"); }
+                    
+                    // Return a trigger.
+                    return true;
+                }
             }
         }
         
@@ -371,7 +371,7 @@
      * will be thrown.
      */
     public void setPrescale(int prescale) {
-    	this.prescale = prescale;
+        this.prescale = prescale;
     }
     
     /**
@@ -383,7 +383,7 @@
     public void setVerbose(boolean verbose) {
         this.verbose = verbose;
     }
-	
+    
     /**
      * Toggles whether the more inclusive acceptance region version 1
      * is used, or the slightly smaller and more exclusive acceptance
@@ -392,9 +392,9 @@
      * 1 of the acceptance region should be used and <code>false</code>
      * that version 2 should be used.
      */
-	public void setUseVersionOne(boolean useVersionOne) {
-		this.useVersionOne = useVersionOne;
-	}
+    public void setUseVersionOne(boolean useVersionOne) {
+        this.useVersionOne = useVersionOne;
+    }
     
     // ==================================================================
     // ==== AIDA Plots ==================================================

Modified: java/branches/HPSJAVA-409/ecal-readout-sim/src/main/java/org/hps/readout/ecal/OccupancyAnalysisDriver.java
 =============================================================================
--- java/branches/HPSJAVA-409/ecal-readout-sim/src/main/java/org/hps/readout/ecal/OccupancyAnalysisDriver.java	(original)
+++ java/branches/HPSJAVA-409/ecal-readout-sim/src/main/java/org/hps/readout/ecal/OccupancyAnalysisDriver.java	Wed Apr 27 11:11:32 2016
@@ -12,19 +12,19 @@
 import org.lcsim.util.aida.AIDA;
 
 public class OccupancyAnalysisDriver extends Driver {
-	// Internal variables.
-	private double scalingFactor = 0.05;
-	private double seedThreshold = 0.050;
-	private double beamRatio = 1.92 / 2.2;
-	private double clusterThreshold = 0.200;
+    // Internal variables.
+    private double scalingFactor = 0.05;
+    private double seedThreshold = 0.050;
+    private double beamRatio = 1.92 / 2.2;
+    private double clusterThreshold = 0.200;
     private AIDA aida = AIDA.defaultInstance();
-	private boolean ignoreBeamGapRows = false;
-	
+    private boolean ignoreBeamGapRows = false;
+    
     // LCIO Collection Names
     private String clusterCollectionName = "EcalClusters";
     private String hitCollectionName = "EcalCorrectedHits";
     
-	// Trigger plots.
+    // Trigger plots.
     IHistogram2D occupancyDistribution;
     IHistogram2D[] clusterDistribution = new IHistogram2D[2];
     IHistogram1D[] clusterHitDistribution = new IHistogram1D[2];
@@ -32,129 +32,129 @@
     IHistogram1D[] clusterEnergyDistribution = new IHistogram1D[2];
     
     public void setIgnoreBeamGapRows(boolean ignoreBeamGapRows) {
-    	this.ignoreBeamGapRows = ignoreBeamGapRows;
+        this.ignoreBeamGapRows = ignoreBeamGapRows;
     }
     
     public void setBeamRatio(double beamRatio) {
-    	this.beamRatio = beamRatio;
+        this.beamRatio = beamRatio;
     }
     
     public void setScalingFactor(double scalingFactor) {
-    	this.scalingFactor = scalingFactor;
+        this.scalingFactor = scalingFactor;
     }
     
     public void setSeedThreshold(double seedThreshold) {
-    	this.seedThreshold = seedThreshold;
+        this.seedThreshold = seedThreshold;
     }
     
     public void setClusterThreshold(double clusterThreshold) {
-    	this.clusterThreshold = clusterThreshold;
+        this.clusterThreshold = clusterThreshold;
     }
     
     public void setClusterCollectionName(String clusterCollectionName) {
-    	this.clusterCollectionName = clusterCollectionName;
+        this.clusterCollectionName = clusterCollectionName;
     }
     
     public void setHitCollectionName(String hitCollectionName) {
-    	this.hitCollectionName = hitCollectionName;
+        this.hitCollectionName = hitCollectionName;
     }
     
     @Override
     public void process(EventHeader event) {
-    	// If clusters are present, process them.
-    	if(event.hasCollection(Cluster.class, clusterCollectionName)) {
-    		// Get the list of clusters.
-    		List<Cluster> clusterList = event.get(Cluster.class, clusterCollectionName);
-    		
-    		// Use the clusters to populate the cluster plots.
-    		for(Cluster cluster : clusterList) {
-    			// Get the ix and iy values for the cluster.
-    			int ix = cluster.getCalorimeterHits().get(0).getIdentifierFieldValue("ix");
-    			int iy = cluster.getCalorimeterHits().get(0).getIdentifierFieldValue("iy");
-    			
-    			// If we want to ignore the beam gap rows, make sure
-    			// that iy exceeds two.
-    			if(!ignoreBeamGapRows || (Math.abs(iy) > 2)) {
-	        		// If the cluster passes the seed threshold, place it in
-	        		// the level 1 plots.
-	    			if(cluster.getCalorimeterHits().get(0).getCorrectedEnergy() >= seedThreshold) {
-	    				clusterDistribution[0].fill(ix, iy, scalingFactor);
-	    				clusterHitDistribution[0].fill(cluster.getCalorimeterHits().size(), scalingFactor);
-	    				clusterEnergyDistribution[0].fill(cluster.getEnergy() * beamRatio, scalingFactor);
-	    			}
-	    			
-	    			// If the cluster energy passes the cluster threshold,
-	    			// populate the level 2 plots.
-	    			if(cluster.getEnergy() >= clusterThreshold) {
-	    				clusterDistribution[1].fill(ix, iy, scalingFactor);
-	    				clusterHitDistribution[1].fill(cluster.getCalorimeterHits().size(), scalingFactor);
-	    				clusterEnergyDistribution[1].fill(cluster.getEnergy() * beamRatio, scalingFactor);
-	    			}
-    			}
-    		}
-    	}
-    	
-    	// If the event has hits, process them.
-    	if(event.hasCollection(CalorimeterHit.class, hitCollectionName)) {
-    		// Get the list of hits.
-    		List<CalorimeterHit> hitList = event.get(CalorimeterHit.class, hitCollectionName);
-    		
-    		// Track the energy in the top and bottom of the calorimeter.
-    		double[] energy = { 0.0, 0.0 };
-    		
-    		// Iterate over the hits.
-    		for(CalorimeterHit hit : hitList) {
-    			// Get the ix and iy values.
-    			int ix = hit.getIdentifierFieldValue("ix");
-    			int iy = hit.getIdentifierFieldValue("iy");
-    			
-    			// If we want to ignore beam gap rows, ensure that iy
-    			// is greater than 2.
-    			if(!ignoreBeamGapRows || Math.abs(iy) > 2) {
-	    			// Add the energy to the appropriate energy tracking
-	    			// variable for the calorimeter halves.
-	    			if(iy > 0) { energy[0] += hit.getCorrectedEnergy() * beamRatio; }
-	    			else { energy[1] += hit.getCorrectedEnergy() * beamRatio; }
-	    			
-	    			// Populate the occupancy distribution.
-	    			occupancyDistribution.fill(ix, iy, scalingFactor);
-    			}
-    		}
-			
-			// Populate the total calorimeter energy plot.
-			totalEnergyDistribution[0].fill(energy[0], scalingFactor);
-			totalEnergyDistribution[1].fill(energy[1], scalingFactor);
-    	}
+        // If clusters are present, process them.
+        if(event.hasCollection(Cluster.class, clusterCollectionName)) {
+            // Get the list of clusters.
+            List<Cluster> clusterList = event.get(Cluster.class, clusterCollectionName);
+            
+            // Use the clusters to populate the cluster plots.
+            for(Cluster cluster : clusterList) {
+                // Get the ix and iy values for the cluster.
+                int ix = cluster.getCalorimeterHits().get(0).getIdentifierFieldValue("ix");
+                int iy = cluster.getCalorimeterHits().get(0).getIdentifierFieldValue("iy");
+                
+                // If we want to ignore the beam gap rows, make sure
+                // that iy exceeds two.
+                if(!ignoreBeamGapRows || (Math.abs(iy) > 2)) {
+                    // If the cluster passes the seed threshold, place it in
+                    // the level 1 plots.
+                    if(cluster.getCalorimeterHits().get(0).getCorrectedEnergy() >= seedThreshold) {
+                        clusterDistribution[0].fill(ix, iy, scalingFactor);
+                        clusterHitDistribution[0].fill(cluster.getCalorimeterHits().size(), scalingFactor);
+                        clusterEnergyDistribution[0].fill(cluster.getEnergy() * beamRatio, scalingFactor);
+                    }
+                    
+                    // If the cluster energy passes the cluster threshold,
+                    // populate the level 2 plots.
+                    if(cluster.getEnergy() >= clusterThreshold) {
+                        clusterDistribution[1].fill(ix, iy, scalingFactor);
+                        clusterHitDistribution[1].fill(cluster.getCalorimeterHits().size(), scalingFactor);
+                        clusterEnergyDistribution[1].fill(cluster.getEnergy() * beamRatio, scalingFactor);
+                    }
+                }
+            }
+        }
+        
+        // If the event has hits, process them.
+        if(event.hasCollection(CalorimeterHit.class, hitCollectionName)) {
+            // Get the list of hits.
+            List<CalorimeterHit> hitList = event.get(CalorimeterHit.class, hitCollectionName);
+            
+            // Track the energy in the top and bottom of the calorimeter.
+            double[] energy = { 0.0, 0.0 };
+            
+            // Iterate over the hits.
+            for(CalorimeterHit hit : hitList) {
+                // Get the ix and iy values.
+                int ix = hit.getIdentifierFieldValue("ix");
+                int iy = hit.getIdentifierFieldValue("iy");
+                
+                // If we want to ignore beam gap rows, ensure that iy
+                // is greater than 2.
+                if(!ignoreBeamGapRows || Math.abs(iy) > 2) {
+                    // Add the energy to the appropriate energy tracking
+                    // variable for the calorimeter halves.
+                    if(iy > 0) { energy[0] += hit.getCorrectedEnergy() * beamRatio; }
+                    else { energy[1] += hit.getCorrectedEnergy() * beamRatio; }
+                    
+                    // Populate the occupancy distribution.
+                    occupancyDistribution.fill(ix, iy, scalingFactor);
+                }
+            }
+            
+            // Populate the total calorimeter energy plot.
+            totalEnergyDistribution[0].fill(energy[0], scalingFactor);
+            totalEnergyDistribution[1].fill(energy[1], scalingFactor);
+        }
     }
     
     @Override
     public void startOfData() {
-    	// Define the cluster distribution plots.
-    	String[] clusterDistName = { String.format("Comp Plots :: Cluster Seed Distribution [Seed Threshold %.3f GeV]", seedThreshold),
-    			String.format("Comp Plots :: Cluster Seed Distribution [Cluster Threshold %.3f GeV]", clusterThreshold) };
+        // Define the cluster distribution plots.
+        String[] clusterDistName = { String.format("Comp Plots :: Cluster Seed Distribution [Seed Threshold %.3f GeV]", seedThreshold),
+                String.format("Comp Plots :: Cluster Seed Distribution [Cluster Threshold %.3f GeV]", clusterThreshold) };
         clusterDistribution[0] = aida.histogram2D(clusterDistName[0], 46, -23, 23, 11, -5.5, 5.5);
         clusterDistribution[1] = aida.histogram2D(clusterDistName[1], 46, -23, 23, 11, -5.5, 5.5);
         
-    	// Define the occupancy distribution plots.
-    	String occupancyDistName = String.format("Comp Plots :: Crystal Occupancy");
-    	occupancyDistribution = aida.histogram2D(occupancyDistName, 46, -23, 23, 11, -5.5, 5.5);
-    	
+        // Define the occupancy distribution plots.
+        String occupancyDistName = String.format("Comp Plots :: Crystal Occupancy");
+        occupancyDistribution = aida.histogram2D(occupancyDistName, 46, -23, 23, 11, -5.5, 5.5);
+        
         // Define the cluster hit count distribution.
-    	String[] clusterHitDistName = { String.format("Comp Plots :: Cluster Hit Count Distribution [Seed Threshold %.3f GeV]", seedThreshold),
-    			String.format("Comp Plots :: Cluster Hit Count Distribution [Cluster Threshold %.3f GeV]", clusterThreshold) };
-    	clusterHitDistribution[0] = aida.histogram1D(clusterHitDistName[0], 9, 1, 10);
-    	clusterHitDistribution[1] = aida.histogram1D(clusterHitDistName[1], 9, 1, 10);
-    	
+        String[] clusterHitDistName = { String.format("Comp Plots :: Cluster Hit Count Distribution [Seed Threshold %.3f GeV]", seedThreshold),
+                String.format("Comp Plots :: Cluster Hit Count Distribution [Cluster Threshold %.3f GeV]", clusterThreshold) };
+        clusterHitDistribution[0] = aida.histogram1D(clusterHitDistName[0], 9, 1, 10);
+        clusterHitDistribution[1] = aida.histogram1D(clusterHitDistName[1], 9, 1, 10);
+        
         // Define the cluster total energy distribution.
-    	String[] clusterEnergyDistName = { String.format("Comp Plots :: Cluster Total Energy Distribution [Seed Threshold %.3f GeV]", seedThreshold),
-    			String.format("Comp Plots :: Cluster Total Energy Distribution [Cluster Threshold %.3f GeV]", clusterThreshold) };
-    	clusterEnergyDistribution[0] = aida.histogram1D(clusterEnergyDistName[0], 176, 0.0, 2.2);
-    	clusterEnergyDistribution[1] = aida.histogram1D(clusterEnergyDistName[1], 176, 0.0, 2.2);
-    	
+        String[] clusterEnergyDistName = { String.format("Comp Plots :: Cluster Total Energy Distribution [Seed Threshold %.3f GeV]", seedThreshold),
+                String.format("Comp Plots :: Cluster Total Energy Distribution [Cluster Threshold %.3f GeV]", clusterThreshold) };
+        clusterEnergyDistribution[0] = aida.histogram1D(clusterEnergyDistName[0], 176, 0.0, 2.2);
+        clusterEnergyDistribution[1] = aida.histogram1D(clusterEnergyDistName[1], 176, 0.0, 2.2);
+        
         // Define the calorimeter total energy distribution.
-    	String[] totalEnergyDistName = { String.format("Comp Plots :: Calorimeter Event Energy Distribution [Top]"),
-    			String.format("Comp Plots :: Calorimeter Event Energy Distribution [Bottom]") };
-    	totalEnergyDistribution[0] = aida.histogram1D(totalEnergyDistName[0], 500, 0.0, 10.0);
-    	totalEnergyDistribution[1] = aida.histogram1D(totalEnergyDistName[1], 500, 0.0, 10.0);
+        String[] totalEnergyDistName = { String.format("Comp Plots :: Calorimeter Event Energy Distribution [Top]"),
+                String.format("Comp Plots :: Calorimeter Event Energy Distribution [Bottom]") };
+        totalEnergyDistribution[0] = aida.histogram1D(totalEnergyDistName[0], 500, 0.0, 10.0);
+        totalEnergyDistribution[1] = aida.histogram1D(totalEnergyDistName[1], 500, 0.0, 10.0);
     }
 }

Modified: java/branches/HPSJAVA-409/ecal-readout-sim/src/main/java/org/hps/readout/ecal/ReadoutTrigger.java
 =============================================================================
--- java/branches/HPSJAVA-409/ecal-readout-sim/src/main/java/org/hps/readout/ecal/ReadoutTrigger.java	(original)
+++ java/branches/HPSJAVA-409/ecal-readout-sim/src/main/java/org/hps/readout/ecal/ReadoutTrigger.java	Wed Apr 27 11:11:32 2016
@@ -22,16 +22,16 @@
  * @author Kyle McCarty <[log in to unmask]>
  */
 public class ReadoutTrigger extends Driver {
-	// Define settable parameters.
-	private double energySlopeParamF = 0.0055;
-	private String clusterCollectionName = "EcalClusters";
-	
-	// Define internal variables.
-	private TriggerModule trigger = new TriggerModule();
-	
-	// Define output plots.
-	private static final int NO_CUTS  = 0;
-	private static final int ALL_CUTS = 1;
+    // Define settable parameters.
+    private double energySlopeParamF = 0.0055;
+    private String clusterCollectionName = "EcalClusters";
+    
+    // Define internal variables.
+    private TriggerModule trigger = new TriggerModule();
+    
+    // Define output plots.
+    private static final int NO_CUTS  = 0;
+    private static final int ALL_CUTS = 1;
     private AIDA aida = AIDA.defaultInstance();
     private IHistogram1D[] clusterSeedEnergy;
     private IHistogram1D[] clusterHitCount;
@@ -46,267 +46,267 @@
     private IHistogram2D[] clusterDistribution;
     private IHistogram2D[] pairEnergySum2D;
     private IHistogram2D[] pairEnergySlope2D;
-	
+    
     /**
      * Instantiates cluster plots.
      */
     @Override
     public void startOfData() {
-    	// Define plot type names.
-    	String[] plotType = new String[2];
-    	plotType[NO_CUTS] = "";
-    	plotType[ALL_CUTS] = " (Passed All Cuts)";
-    	
-    	// Define plot type directories.
-    	String[] plotDir = new String[2];
-    	plotDir[NO_CUTS] = "NoCuts/";
-    	plotDir[ALL_CUTS] = "PassedAll/";
-    	
-    	// Instantiate the plots.
-    	for(int i = 0; i < 2; i++) {
-    		System.out.println(plotDir[i] + "Cluster Seed Energy" + plotType[i]);
-    		clusterSeedEnergy[i] = aida.histogram1D(plotDir[i] + "Cluster Seed Energy" + plotType[i], 88, 0.0, 1.1);
-    		clusterSeedEnergy[i].annotation().addItem("xAxisLabel", "Seed Energy (GeV)");
-    		clusterSeedEnergy[i].annotation().addItem("yAxisLabel", "Count");
-    		
-    		clusterHitCount[i] = aida.histogram1D(plotDir[i] + "Cluster Hit Count" + plotType[i], 9, 0.5, 9.5);
-    		clusterHitCount[i].annotation().addItem("xAxisLabel", "Hit Count");
-    		clusterHitCount[i].annotation().addItem("yAxisLabel", "Count");
-    		
-    		clusterTotalEnergy[i] = aida.histogram1D(plotDir[i] + "Cluster Total Energy" + plotType[i], 88, 0.0, 1.1);
-    		clusterTotalEnergy[i].annotation().addItem("xAxisLabel", "Cluster Energy (GeV)");
-    		clusterTotalEnergy[i].annotation().addItem("yAxisLabel", "Count");
-    		
-    		clusterTime[i] = aida.histogram1D(plotDir[i] + "Cluster Time" + plotType[i], 100, 0.0, 400);
-    		clusterTime[i].annotation().addItem("xAxisLabel", "Cluster Time (ns)");
-    		clusterTime[i].annotation().addItem("yAxisLabel", "Count");
-		
-			pairEnergySum[i] = aida.histogram1D(plotDir[i] + "Pair Energy Sum" + plotType[i], 88, 0.0, 2.2);
-			pairEnergySum[i].annotation().addItem("xAxisLabel", "Energy Sum (GeV)");
-			pairEnergySum[i].annotation().addItem("yAxisLabel", "Count");
-    		
-			pairEnergyDifference[i] = aida.histogram1D(plotDir[i] + "Pair Energy Difference" + plotType[i], 88, 0.0, 1.1);
-			pairEnergyDifference[i].annotation().addItem("xAxisLabel", "Energy Difference (GeV)");
-			pairEnergyDifference[i].annotation().addItem("yAxisLabel", "Count");
-    		
-			pairCoplanarity[i] = aida.histogram1D(plotDir[i] + "Pair Coplanarity" + plotType[i], 180, 0.0, 180.0);
-			pairCoplanarity[i].annotation().addItem("xAxisLabel", "Coplanarity Angle (Degrees)");
-			pairCoplanarity[i].annotation().addItem("yAxisLabel", "Count");
-    		
-			pairEnergySlope[i] = aida.histogram1D(plotDir[i] + "Pair Energy Slope" + plotType[i], 200, 0.0, 4.0);
-			pairEnergySlope[i].annotation().addItem("xAxisLabel", "Energy Slope (GeV)");
-			pairEnergySlope[i].annotation().addItem("yAxisLabel", "Count");
-    		
-			pairTime[i] = aida.histogram1D(plotDir[i] + "Pair Time" + plotType[i], 100, 0.0, 400);
-			pairTime[i].annotation().addItem("xAxisLabel", "Cluster Time (ns)");
-			pairTime[i].annotation().addItem("yAxisLabel", "Count");
-    		
-			pairCoincidence[i] = aida.histogram1D(plotDir[i] + "Pair Coincidence" + plotType[i], 8, 0.0, 32);
-			pairCoincidence[i].annotation().addItem("xAxisLabel", "Coincidence Time (ns)");
-			pairCoincidence[i].annotation().addItem("yAxisLabel", "Count");
-    		
-    		clusterDistribution[i] = aida.histogram2D(plotDir[i] + "Cluster Seed Distribution" + plotType[i], 46, -23, 23, 11, -5.5, 5.5);
-    		clusterDistribution[i].annotation().addItem("xAxisLabel", "x-Index");
-    		clusterDistribution[i].annotation().addItem("yAxisLabel", "y-Index");
-    		
-    		pairEnergySum2D[i] = aida.histogram2D(plotDir[i] + "Pair Energy Sum 2D" + plotType[i], 88, 0.0, 2.2, 88, 0.0, 2.2);
-    		pairEnergySum2D[i].annotation().addItem("xAxisLabel", "E1");
-    		pairEnergySum2D[i].annotation().addItem("yAxisLabel", "E2");
-    		
-    		pairEnergySlope2D[i] = aida.histogram2D(plotDir[i] + "Pair Energy Slope 2D" + plotType[i], 88, 0.0, 1.1, 200, 0.0, 400);
-    		pairEnergySlope2D[i].annotation().addItem("xAxisLabel", "E1");
-    		pairEnergySlope2D[i].annotation().addItem("yAxisLabel", "E2");
-    	}
+        // Define plot type names.
+        String[] plotType = new String[2];
+        plotType[NO_CUTS] = "";
+        plotType[ALL_CUTS] = " (Passed All Cuts)";
+        
+        // Define plot type directories.
+        String[] plotDir = new String[2];
+        plotDir[NO_CUTS] = "NoCuts/";
+        plotDir[ALL_CUTS] = "PassedAll/";
+        
+        // Instantiate the plots.
+        for(int i = 0; i < 2; i++) {
+            System.out.println(plotDir[i] + "Cluster Seed Energy" + plotType[i]);
+            clusterSeedEnergy[i] = aida.histogram1D(plotDir[i] + "Cluster Seed Energy" + plotType[i], 88, 0.0, 1.1);
+            clusterSeedEnergy[i].annotation().addItem("xAxisLabel", "Seed Energy (GeV)");
+            clusterSeedEnergy[i].annotation().addItem("yAxisLabel", "Count");
+            
+            clusterHitCount[i] = aida.histogram1D(plotDir[i] + "Cluster Hit Count" + plotType[i], 9, 0.5, 9.5);
+            clusterHitCount[i].annotation().addItem("xAxisLabel", "Hit Count");
+            clusterHitCount[i].annotation().addItem("yAxisLabel", "Count");
+            
+            clusterTotalEnergy[i] = aida.histogram1D(plotDir[i] + "Cluster Total Energy" + plotType[i], 88, 0.0, 1.1);
+            clusterTotalEnergy[i].annotation().addItem("xAxisLabel", "Cluster Energy (GeV)");
+            clusterTotalEnergy[i].annotation().addItem("yAxisLabel", "Count");
+            
+            clusterTime[i] = aida.histogram1D(plotDir[i] + "Cluster Time" + plotType[i], 100, 0.0, 400);
+            clusterTime[i].annotation().addItem("xAxisLabel", "Cluster Time (ns)");
+            clusterTime[i].annotation().addItem("yAxisLabel", "Count");
+        
+            pairEnergySum[i] = aida.histogram1D(plotDir[i] + "Pair Energy Sum" + plotType[i], 88, 0.0, 2.2);
+            pairEnergySum[i].annotation().addItem("xAxisLabel", "Energy Sum (GeV)");
+            pairEnergySum[i].annotation().addItem("yAxisLabel", "Count");
+            
+            pairEnergyDifference[i] = aida.histogram1D(plotDir[i] + "Pair Energy Difference" + plotType[i], 88, 0.0, 1.1);
+            pairEnergyDifference[i].annotation().addItem("xAxisLabel", "Energy Difference (GeV)");
+            pairEnergyDifference[i].annotation().addItem("yAxisLabel", "Count");
+            
+            pairCoplanarity[i] = aida.histogram1D(plotDir[i] + "Pair Coplanarity" + plotType[i], 180, 0.0, 180.0);
+            pairCoplanarity[i].annotation().addItem("xAxisLabel", "Coplanarity Angle (Degrees)");
+            pairCoplanarity[i].annotation().addItem("yAxisLabel", "Count");
+            
+            pairEnergySlope[i] = aida.histogram1D(plotDir[i] + "Pair Energy Slope" + plotType[i], 200, 0.0, 4.0);
+            pairEnergySlope[i].annotation().addItem("xAxisLabel", "Energy Slope (GeV)");
+            pairEnergySlope[i].annotation().addItem("yAxisLabel", "Count");
+            
+            pairTime[i] = aida.histogram1D(plotDir[i] + "Pair Time" + plotType[i], 100, 0.0, 400);
+            pairTime[i].annotation().addItem("xAxisLabel", "Cluster Time (ns)");
+            pairTime[i].annotation().addItem("yAxisLabel", "Count");
+            
+            pairCoincidence[i] = aida.histogram1D(plotDir[i] + "Pair Coincidence" + plotType[i], 8, 0.0, 32);
+            pairCoincidence[i].annotation().addItem("xAxisLabel", "Coincidence Time (ns)");
+            pairCoincidence[i].annotation().addItem("yAxisLabel", "Count");
+            
+            clusterDistribution[i] = aida.histogram2D(plotDir[i] + "Cluster Seed Distribution" + plotType[i], 46, -23, 23, 11, -5.5, 5.5);
+            clusterDistribution[i].annotation().addItem("xAxisLabel", "x-Index");
+            clusterDistribution[i].annotation().addItem("yAxisLabel", "y-Index");
+            
+            pairEnergySum2D[i] = aida.histogram2D(plotDir[i] + "Pair Energy Sum 2D" + plotType[i], 88, 0.0, 2.2, 88, 0.0, 2.2);
+            pairEnergySum2D[i].annotation().addItem("xAxisLabel", "E1");
+            pairEnergySum2D[i].annotation().addItem("yAxisLabel", "E2");
+            
+            pairEnergySlope2D[i] = aida.histogram2D(plotDir[i] + "Pair Energy Slope 2D" + plotType[i], 88, 0.0, 1.1, 200, 0.0, 400);
+            pairEnergySlope2D[i].annotation().addItem("xAxisLabel", "E1");
+            pairEnergySlope2D[i].annotation().addItem("yAxisLabel", "E2");
+        }
     }
     
     /**
      * Produces both uncut and cut distributions from clusters.
      */
-	@Override
-	public void process(EventHeader event) {
-		// Check for a collection of clusters.
-		if(event.hasCollection(Cluster.class, clusterCollectionName)) {
-			// Get the list of clusters.
-			List<Cluster> clusters = event.get(Cluster.class, clusterCollectionName);
-			
-			// Track which clusters have already been plotted.
-			Set<Cluster> plottedClustersUncut = new HashSet<Cluster>(clusters.size());
-			Set<Cluster> plottedClustersCut = new HashSet<Cluster>(clusters.size());
-			
-			// Populate a list of cluster pairs.
-			List<Cluster[]> pairs = getClusterPairs(clusters);
-			
-			// Process all cluster pairs.
-			pairLoop:
-			for(Cluster[] pair : pairs) {
-				// Get the x and y indices for each cluster in the pair.
-				int[] ix = { pair[0].getCalorimeterHits().get(0).getIdentifierFieldValue("ix"),
-						pair[1].getCalorimeterHits().get(0).getIdentifierFieldValue("ix") };
-				int[] iy = { pair[0].getCalorimeterHits().get(0).getIdentifierFieldValue("iy"),
-						pair[1].getCalorimeterHits().get(0).getIdentifierFieldValue("iy") };
-				
-				// Iterate over the clusters in the pair and plot the
-				// cluster singles distributions.
-				for(int clusterIndex = 0; clusterIndex < 2; clusterIndex++) {
-					// Only plot cluster singles distributions for
-					// clusters if they have not already been plotted.
-					// Note that this is needed because the same cluster
-					// can appear across multiple pairs.
-					if(!plottedClustersUncut.contains(pair[clusterIndex])) {
-						clusterSeedEnergy[NO_CUTS].fill(TriggerModule.getValueClusterSeedEnergy(pair[clusterIndex]));
-						clusterTotalEnergy[NO_CUTS].fill(TriggerModule.getValueClusterTotalEnergy(pair[clusterIndex]));
-						clusterHitCount[NO_CUTS].fill(TriggerModule.getValueClusterHitCount(pair[clusterIndex]));
-						clusterDistribution[NO_CUTS].fill(ix[clusterIndex], iy[clusterIndex]);
-						clusterTime[NO_CUTS].fill(pair[clusterIndex].getCalorimeterHits().get(0).getTime());
-						plottedClustersUncut.add(pair[clusterIndex]);
-					}
-				}
-				
-				// Plot the cluster pair distributions.
-				pairEnergySum[NO_CUTS].fill(TriggerModule.getValueEnergySum(pair));
-				pairEnergyDifference[NO_CUTS].fill(TriggerModule.getValueEnergyDifference(pair));
-				pairEnergySlope[NO_CUTS].fill(TriggerModule.getValueEnergySlope(pair, energySlopeParamF));
-				pairCoplanarity[NO_CUTS].fill(TriggerModule.getValueCoplanarity(pair));
-				pairTime[NO_CUTS].fill(pair[1].getCalorimeterHits().get(0).getTime());
-				pairCoincidence[NO_CUTS].fill(TriggerModule.getValueTimeCoincidence(pair));
-				pairEnergySum2D[NO_CUTS].fill(pair[0].getEnergy(), pair[1].getEnergy());
-				if(pair[0].getEnergy() < pair[1].getEnergy()) {
-					pairEnergySlope2D[NO_CUTS].fill(pair[0].getEnergy(), TriggerModule.getClusterDistance(pair[0]));
-				} else {
-					pairEnergySlope2D[NO_CUTS].fill(pair[1].getEnergy(), TriggerModule.getClusterDistance(pair[1]));
-				}
-				
-				// Perform the cluster singles cuts.
-				if(!(trigger.clusterHitCountCut(pair[0]) && trigger.clusterHitCountCut(pair[1]))) {
-					continue pairLoop;
-				} if(!(trigger.clusterTotalEnergyCut(pair[0]) && trigger.clusterTotalEnergyCut(pair[1]))) {
-					continue pairLoop;
-				} if(!(trigger.clusterSeedEnergyCut(pair[0]) && trigger.clusterSeedEnergyCut(pair[1]))) {
-					continue pairLoop;
-				}
-				
-				// Perform the cluster pair cuts.
-				if(!trigger.pairCoplanarityCut(pair)) {
-					continue pairLoop;
-				} if(!trigger.pairEnergyDifferenceCut(pair)) {
-					continue pairLoop;
-				} if(!trigger.pairEnergySlopeCut(pair)) {
-					continue pairLoop;
-				} if(!trigger.pairEnergySumCut(pair)) {
-					continue pairLoop;
-				}
-				
-				// Iterate over the clusters in the pair and plot the
-				// cluster singles distributions.
-				for(int clusterIndex = 0; clusterIndex < 2; clusterIndex++) {
-					// Only plot cluster singles distributions for
-					// clusters if they have not already been plotted.
-					// Note that this is needed because the same cluster
-					// can appear across multiple pairs.
-					if(!plottedClustersCut.contains(pair[clusterIndex])) {
-						clusterSeedEnergy[ALL_CUTS].fill(TriggerModule.getValueClusterSeedEnergy(pair[clusterIndex]));
-						clusterTotalEnergy[ALL_CUTS].fill(TriggerModule.getValueClusterTotalEnergy(pair[clusterIndex]));
-						clusterHitCount[ALL_CUTS].fill(TriggerModule.getValueClusterHitCount(pair[clusterIndex]));
-						clusterDistribution[ALL_CUTS].fill(ix[clusterIndex], iy[clusterIndex]);
-						clusterTime[ALL_CUTS].fill(pair[clusterIndex].getCalorimeterHits().get(0).getTime());
-						plottedClustersCut.add(pair[clusterIndex]);
-					}
-				}
-				
-				// Plot the cluster pair distributions.
-				pairEnergySum[ALL_CUTS].fill(TriggerModule.getValueEnergySum(pair));
-				pairEnergyDifference[ALL_CUTS].fill(TriggerModule.getValueEnergyDifference(pair));
-				pairEnergySlope[ALL_CUTS].fill(TriggerModule.getValueEnergySlope(pair, energySlopeParamF));
-				pairCoplanarity[ALL_CUTS].fill(TriggerModule.getValueCoplanarity(pair));
-				pairTime[ALL_CUTS].fill(pair[1].getCalorimeterHits().get(0).getTime());
-				pairCoincidence[ALL_CUTS].fill(TriggerModule.getValueTimeCoincidence(pair));
-				pairEnergySum2D[ALL_CUTS].fill(pair[0].getEnergy(), pair[1].getEnergy());
-				if(pair[0].getEnergy() < pair[1].getEnergy()) {
-					pairEnergySlope2D[ALL_CUTS].fill(pair[0].getEnergy(), TriggerModule.getClusterDistance(pair[0]));
-				} else {
-					pairEnergySlope2D[ALL_CUTS].fill(pair[1].getEnergy(), TriggerModule.getClusterDistance(pair[1]));
-				}
-				
-			}
-		}
-	}
-	
-	public void setClusterCollectionName(String clusterCollectionName) {
-		this.clusterCollectionName = clusterCollectionName;
-	}
-	
-	public void setEnergySlopeParamF(double energySlopeParamF) {
-		this.energySlopeParamF = energySlopeParamF;
-		trigger.setCutValue(TriggerModule.PAIR_ENERGY_SLOPE_F, energySlopeParamF);
-	}
-	
-	public void setSeedEnergyLow(double value) {
-		trigger.setCutValue(TriggerModule.CLUSTER_SEED_ENERGY_LOW, value);
-	}
-	
-	public void setClusterEnergyLow(double value) {
-		trigger.setCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_LOW, value);
-	}
-	
-	public void setClusterEnergyHigh(double value) {
-		trigger.setCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_HIGH, value);
-	}
-	
-	public void setHitCountLow(double value) {
-		trigger.setCutValue(TriggerModule.CLUSTER_HIT_COUNT_LOW, value);
-	}
-	
-	public void setEnergySumLow(double value) {
-		trigger.setCutValue(TriggerModule.PAIR_ENERGY_SUM_LOW, value);
-	}
-	
-	public void setEnergySumHigh(double value) {
-		trigger.setCutValue(TriggerModule.PAIR_ENERGY_SUM_HIGH, value);
-	}
-	
-	public void setEnergyDifferenceHigh(double value) {
-		trigger.setCutValue(TriggerModule.PAIR_ENERGY_DIFFERENCE_HIGH, value);
-	}
-	
-	public void setEnergySlopeLow(double value) {
-		trigger.setCutValue(TriggerModule.PAIR_ENERGY_SLOPE_LOW, value);
-	}
-	
-	public void setCoplanarityHigh(double value) {
-		trigger.setCutValue(TriggerModule.PAIR_COPLANARITY_HIGH, value);
-	}
-	
-	public void setTimeCoincidence(double value) {
-		trigger.setCutValue(TriggerModule.PAIR_TIME_COINCIDENCE, value);
-	}
-	
-	/**
-	 * Creates all top/bottom pairs from the event data.
-	 * @param clusters - A list of clusters from which to form pairs.
-	 * @return Returns a <code>List</code> collection that contains
-	 * <code>Cluster</code> arrays of size two.
-	 */
-	private List<Cluster[]> getClusterPairs(List<Cluster> clusters) {
-		// Separate the clusters into top nad bottom clusters.
-		List<Cluster> topList = new ArrayList<Cluster>();
-		List<Cluster> botList = new ArrayList<Cluster>();
-		for(Cluster cluster : clusters) {
-			if(cluster.getCalorimeterHits().get(0).getIdentifierFieldValue("iy") > 0) {
-				topList.add(cluster);
-			} else {
-				botList.add(cluster);
-			}
-		}
-		
-		// Create all possible top/bottom cluster pairs.
-		List<Cluster[]> pairList = new ArrayList<Cluster[]>();
-		for(Cluster topCluster : topList) {
-			for(Cluster botCluster : botList) {
-				pairList.add(new Cluster[] { topCluster, botCluster });
-			}
-		}
-		
-		// Return the pairs.
-		return pairList;
-	}
+    @Override
+    public void process(EventHeader event) {
+        // Check for a collection of clusters.
+        if(event.hasCollection(Cluster.class, clusterCollectionName)) {
+            // Get the list of clusters.
+            List<Cluster> clusters = event.get(Cluster.class, clusterCollectionName);
+            
+            // Track which clusters have already been plotted.
+            Set<Cluster> plottedClustersUncut = new HashSet<Cluster>(clusters.size());
+            Set<Cluster> plottedClustersCut = new HashSet<Cluster>(clusters.size());
+            
+            // Populate a list of cluster pairs.
+            List<Cluster[]> pairs = getClusterPairs(clusters);
+            
+            // Process all cluster pairs.
+            pairLoop:
+            for(Cluster[] pair : pairs) {
+                // Get the x and y indices for each cluster in the pair.
+                int[] ix = { pair[0].getCalorimeterHits().get(0).getIdentifierFieldValue("ix"),
+                        pair[1].getCalorimeterHits().get(0).getIdentifierFieldValue("ix") };
+                int[] iy = { pair[0].getCalorimeterHits().get(0).getIdentifierFieldValue("iy"),
+                        pair[1].getCalorimeterHits().get(0).getIdentifierFieldValue("iy") };
+                
+                // Iterate over the clusters in the pair and plot the
+                // cluster singles distributions.
+                for(int clusterIndex = 0; clusterIndex < 2; clusterIndex++) {
+                    // Only plot cluster singles distributions for
+                    // clusters if they have not already been plotted.
+                    // Note that this is needed because the same cluster
+                    // can appear across multiple pairs.
+                    if(!plottedClustersUncut.contains(pair[clusterIndex])) {
+                        clusterSeedEnergy[NO_CUTS].fill(TriggerModule.getValueClusterSeedEnergy(pair[clusterIndex]));
+                        clusterTotalEnergy[NO_CUTS].fill(TriggerModule.getValueClusterTotalEnergy(pair[clusterIndex]));
+                        clusterHitCount[NO_CUTS].fill(TriggerModule.getValueClusterHitCount(pair[clusterIndex]));
+                        clusterDistribution[NO_CUTS].fill(ix[clusterIndex], iy[clusterIndex]);
+                        clusterTime[NO_CUTS].fill(pair[clusterIndex].getCalorimeterHits().get(0).getTime());
+                        plottedClustersUncut.add(pair[clusterIndex]);
+                    }
+                }
+                
+                // Plot the cluster pair distributions.
+                pairEnergySum[NO_CUTS].fill(TriggerModule.getValueEnergySum(pair));
+                pairEnergyDifference[NO_CUTS].fill(TriggerModule.getValueEnergyDifference(pair));
+                pairEnergySlope[NO_CUTS].fill(TriggerModule.getValueEnergySlope(pair, energySlopeParamF));
+                pairCoplanarity[NO_CUTS].fill(TriggerModule.getValueCoplanarity(pair));
+                pairTime[NO_CUTS].fill(pair[1].getCalorimeterHits().get(0).getTime());
+                pairCoincidence[NO_CUTS].fill(TriggerModule.getValueTimeCoincidence(pair));
+                pairEnergySum2D[NO_CUTS].fill(pair[0].getEnergy(), pair[1].getEnergy());
+                if(pair[0].getEnergy() < pair[1].getEnergy()) {
+                    pairEnergySlope2D[NO_CUTS].fill(pair[0].getEnergy(), TriggerModule.getClusterDistance(pair[0]));
+                } else {
+                    pairEnergySlope2D[NO_CUTS].fill(pair[1].getEnergy(), TriggerModule.getClusterDistance(pair[1]));
+                }
+                
+                // Perform the cluster singles cuts.
+                if(!(trigger.clusterHitCountCut(pair[0]) && trigger.clusterHitCountCut(pair[1]))) {
+                    continue pairLoop;
+                } if(!(trigger.clusterTotalEnergyCut(pair[0]) && trigger.clusterTotalEnergyCut(pair[1]))) {
+                    continue pairLoop;
+                } if(!(trigger.clusterSeedEnergyCut(pair[0]) && trigger.clusterSeedEnergyCut(pair[1]))) {
+                    continue pairLoop;
+                }
+                
+                // Perform the cluster pair cuts.
+                if(!trigger.pairCoplanarityCut(pair)) {
+                    continue pairLoop;
+                } if(!trigger.pairEnergyDifferenceCut(pair)) {
+                    continue pairLoop;
+                } if(!trigger.pairEnergySlopeCut(pair)) {
+                    continue pairLoop;
+                } if(!trigger.pairEnergySumCut(pair)) {
+                    continue pairLoop;
+                }
+                
+                // Iterate over the clusters in the pair and plot the
+                // cluster singles distributions.
+                for(int clusterIndex = 0; clusterIndex < 2; clusterIndex++) {
+                    // Only plot cluster singles distributions for
+                    // clusters if they have not already been plotted.
+                    // Note that this is needed because the same cluster
+                    // can appear across multiple pairs.
+                    if(!plottedClustersCut.contains(pair[clusterIndex])) {
+                        clusterSeedEnergy[ALL_CUTS].fill(TriggerModule.getValueClusterSeedEnergy(pair[clusterIndex]));
+                        clusterTotalEnergy[ALL_CUTS].fill(TriggerModule.getValueClusterTotalEnergy(pair[clusterIndex]));
+                        clusterHitCount[ALL_CUTS].fill(TriggerModule.getValueClusterHitCount(pair[clusterIndex]));
+                        clusterDistribution[ALL_CUTS].fill(ix[clusterIndex], iy[clusterIndex]);
+                        clusterTime[ALL_CUTS].fill(pair[clusterIndex].getCalorimeterHits().get(0).getTime());
+                        plottedClustersCut.add(pair[clusterIndex]);
+                    }
+                }
+                
+                // Plot the cluster pair distributions.
+                pairEnergySum[ALL_CUTS].fill(TriggerModule.getValueEnergySum(pair));
+                pairEnergyDifference[ALL_CUTS].fill(TriggerModule.getValueEnergyDifference(pair));
+                pairEnergySlope[ALL_CUTS].fill(TriggerModule.getValueEnergySlope(pair, energySlopeParamF));
+                pairCoplanarity[ALL_CUTS].fill(TriggerModule.getValueCoplanarity(pair));
+                pairTime[ALL_CUTS].fill(pair[1].getCalorimeterHits().get(0).getTime());
+                pairCoincidence[ALL_CUTS].fill(TriggerModule.getValueTimeCoincidence(pair));
+                pairEnergySum2D[ALL_CUTS].fill(pair[0].getEnergy(), pair[1].getEnergy());
+                if(pair[0].getEnergy() < pair[1].getEnergy()) {
+                    pairEnergySlope2D[ALL_CUTS].fill(pair[0].getEnergy(), TriggerModule.getClusterDistance(pair[0]));
+                } else {
+                    pairEnergySlope2D[ALL_CUTS].fill(pair[1].getEnergy(), TriggerModule.getClusterDistance(pair[1]));
+                }
+                
+            }
+        }
+    }
+    
+    public void setClusterCollectionName(String clusterCollectionName) {
+        this.clusterCollectionName = clusterCollectionName;
+    }
+    
+    public void setEnergySlopeParamF(double energySlopeParamF) {
+        this.energySlopeParamF = energySlopeParamF;
+        trigger.setCutValue(TriggerModule.PAIR_ENERGY_SLOPE_F, energySlopeParamF);
+    }
+    
+    public void setSeedEnergyLow(double value) {
+        trigger.setCutValue(TriggerModule.CLUSTER_SEED_ENERGY_LOW, value);
+    }
+    
+    public void setClusterEnergyLow(double value) {
+        trigger.setCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_LOW, value);
+    }
+    
+    public void setClusterEnergyHigh(double value) {
+        trigger.setCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_HIGH, value);
+    }
+    
+    public void setHitCountLow(double value) {
+        trigger.setCutValue(TriggerModule.CLUSTER_HIT_COUNT_LOW, value);
+    }
+    
+    public void setEnergySumLow(double value) {
+        trigger.setCutValue(TriggerModule.PAIR_ENERGY_SUM_LOW, value);
+    }
+    
+    public void setEnergySumHigh(double value) {
+        trigger.setCutValue(TriggerModule.PAIR_ENERGY_SUM_HIGH, value);
+    }
+    
+    public void setEnergyDifferenceHigh(double value) {
+        trigger.setCutValue(TriggerModule.PAIR_ENERGY_DIFFERENCE_HIGH, value);
+    }
+    
+    public void setEnergySlopeLow(double value) {
+        trigger.setCutValue(TriggerModule.PAIR_ENERGY_SLOPE_LOW, value);
+    }
+    
+    public void setCoplanarityHigh(double value) {
+        trigger.setCutValue(TriggerModule.PAIR_COPLANARITY_HIGH, value);
+    }
+    
+    public void setTimeCoincidence(double value) {
+        trigger.setCutValue(TriggerModule.PAIR_TIME_COINCIDENCE, value);
+    }
+    
+    /**
+     * Creates all top/bottom pairs from the event data.
+     * @param clusters - A list of clusters from which to form pairs.
+     * @return Returns a <code>List</code> collection that contains
+     * <code>Cluster</code> arrays of size two.
+     */
+    private List<Cluster[]> getClusterPairs(List<Cluster> clusters) {
+        // Separate the clusters into top nad bottom clusters.
+        List<Cluster> topList = new ArrayList<Cluster>();
+        List<Cluster> botList = new ArrayList<Cluster>();
+        for(Cluster cluster : clusters) {
+            if(cluster.getCalorimeterHits().get(0).getIdentifierFieldValue("iy") > 0) {
+                topList.add(cluster);
+            } else {
+                botList.add(cluster);
+            }
+        }
+        
+        // Create all possible top/bottom cluster pairs.
+        List<Cluster[]> pairList = new ArrayList<Cluster[]>();
+        for(Cluster topCluster : topList) {
+            for(Cluster botCluster : botList) {
+                pairList.add(new Cluster[] { topCluster, botCluster });
+            }
+        }
+        
+        // Return the pairs.
+        return pairList;
+    }
 }

Modified: java/branches/HPSJAVA-409/ecal-readout-sim/src/main/java/org/hps/readout/ecal/RingBuffer.java
 =============================================================================
--- java/branches/HPSJAVA-409/ecal-readout-sim/src/main/java/org/hps/readout/ecal/RingBuffer.java	(original)
+++ java/branches/HPSJAVA-409/ecal-readout-sim/src/main/java/org/hps/readout/ecal/RingBuffer.java	Wed Apr 27 11:11:32 2016
@@ -8,46 +8,46 @@
  */
 public class RingBuffer {
 
-	protected double[] array;
-	protected int ptr;
+    protected double[] array;
+    protected int ptr;
 
-	public RingBuffer(int size) {
-		array = new double[size]; //initialized to 0
-		ptr = 0;
-	}
+    public RingBuffer(int size) {
+        array = new double[size]; //initialized to 0
+        ptr = 0;
+    }
 
-	/**
-	 * 
-	 * @return value stored at current cell
-	 */
-	public double currentValue() {
-		return array[ptr];
-	}
+    /**
+     * 
+     * @return value stored at current cell
+     */
+    public double currentValue() {
+        return array[ptr];
+    }
 
-	//return content of specified cell (pos=0 for current cell)
-	public double getValue(int pos) {
-		return array[((ptr + pos) % array.length + array.length) % array.length];
-	}
+    //return content of specified cell (pos=0 for current cell)
+    public double getValue(int pos) {
+        return array[((ptr + pos) % array.length + array.length) % array.length];
+    }
 
-	/**
-	 * Clear value at current cell and step to the next one
-	 */
-	public void step() {
-		array[ptr] = 0;
-		ptr++;
-		if (ptr == array.length) {
-			ptr = 0;
-		}
-	}
+    /**
+     * Clear value at current cell and step to the next one
+     */
+    public void step() {
+        array[ptr] = 0;
+        ptr++;
+        if (ptr == array.length) {
+            ptr = 0;
+        }
+    }
 
-	/**
-	 * Add given value to specified cell
-	 * @param pos Target position relative to current cell (pos=0 for current cell)
-	 * @param val 
-	 */
-	public void addToCell(int pos, double val) {
-		array[(ptr + pos) % array.length] += val;
-	}
+    /**
+     * Add given value to specified cell
+     * @param pos Target position relative to current cell (pos=0 for current cell)
+     * @param val 
+     */
+    public void addToCell(int pos, double val) {
+        array[(ptr + pos) % array.length] += val;
+    }
 
     public int getLength() {
         return array.length;

Modified: java/branches/HPSJAVA-409/ecal-readout-sim/src/main/java/org/hps/readout/ecal/TimeEvolutionEcalReadoutDriver.java
 =============================================================================
--- java/branches/HPSJAVA-409/ecal-readout-sim/src/main/java/org/hps/readout/ecal/TimeEvolutionEcalReadoutDriver.java	(original)
+++ java/branches/HPSJAVA-409/ecal-readout-sim/src/main/java/org/hps/readout/ecal/TimeEvolutionEcalReadoutDriver.java	Wed Apr 27 11:11:32 2016
@@ -23,7 +23,7 @@
     double t0 = 18.0;
     
     public TimeEvolutionEcalReadoutDriver() {
-		hitClass = CalorimeterHit.class;
+        hitClass = CalorimeterHit.class;
     }
 
     public void setT0(double t0) {
@@ -39,8 +39,8 @@
     protected void readHits(List<CalorimeterHit> hits) {
         for (Long cellID : eDepMap.keySet()) {
             RingBuffer eDepBuffer = eDepMap.get(cellID);
-            if (eDepBuffer.currentValue() > threshold) {            	            	            	
-            	hits.add(CalorimeterHitUtilities.create(eDepBuffer.currentValue(), readoutTime(), cellID, hitType));
+            if (eDepBuffer.currentValue() > threshold) {                                                
+                hits.add(CalorimeterHitUtilities.create(eDepBuffer.currentValue(), readoutTime(), cellID, hitType));
             }
             eDepBuffer.step();
         }

Modified: java/branches/HPSJAVA-409/ecal-recon/pom.xml
 =============================================================================
--- java/branches/HPSJAVA-409/ecal-recon/pom.xml	(original)
+++ java/branches/HPSJAVA-409/ecal-recon/pom.xml	Wed Apr 27 11:11:32 2016
@@ -8,7 +8,7 @@
         <groupId>org.hps</groupId>
         <artifactId>hps-parent</artifactId>
         <relativePath>../parent/pom.xml</relativePath>
-        <version>3.4.2-SNAPSHOT</version>
+        <version>3.9-SNAPSHOT</version>
     </parent>
     <scm>
         <url>http://java.freehep.org/svn/repos/hps/list/java/trunk/ecal-recon/</url>

Modified: java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/EcalCalibrationsDriver.java
 =============================================================================
--- java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/EcalCalibrationsDriver.java	(original)
+++ java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/EcalCalibrationsDriver.java	Wed Apr 27 11:11:32 2016
@@ -35,7 +35,7 @@
 import org.lcsim.util.aida.AIDA;
 
 /**
- * This Driver will generate a {@link org.hps.conditions.EcalCalibration} collection
+ * This Driver will generate a {@link org.hps.conditions.ecal.EcalCalibration} collection
  * from the ADC value distributions of raw ECAL data.  It may optionally insert this
  * information into the conditions database using the file's run number.
  * 
@@ -46,20 +46,20 @@
  */
 public class EcalCalibrationsDriver extends Driver {
     
-    EcalConditions ecalConditions = null;
-    DatabaseConditionsManager conditionsManager = null;
-    AIDA aida = AIDA.defaultInstance();
-    IFunctionFactory functionFactory = aida.analysisFactory().createFunctionFactory(null);
-    IFitFactory fitFactory = aida.analysisFactory().createFitFactory();
-    boolean loadCalibrations = false;
-    boolean performFit = true;
-    Integer runStart = null;
-    Integer runEnd = null;
-    File outputFile = null;
-    Set<Integer> runs = new HashSet<Integer>();
-    static DecimalFormat decimalFormat = new DecimalFormat("#.####");
-    String inputHitsCollectionName = "EcalReadoutHits";
-    static String ECAL_CALIBRATIONS = "ecal_calibrations";
+    private EcalConditions ecalConditions = null;
+    private DatabaseConditionsManager conditionsManager = null;
+    private AIDA aida = AIDA.defaultInstance();
+    private IFunctionFactory functionFactory = aida.analysisFactory().createFunctionFactory(null);
+    private IFitFactory fitFactory = aida.analysisFactory().createFitFactory();
+    private boolean loadCalibrations = false;
+    private boolean performFit = true;
+    private Integer runStart = null;
+    private Integer runEnd = null;
+    private File outputFile = null;
+    private Set<Integer> runs = new HashSet<Integer>();
+    private static DecimalFormat DECIMAL_FORMAT = new DecimalFormat("#.####");
+    private String inputHitsCollectionName = "EcalReadoutHits";
+    private static String ECAL_CALIBRATIONS = "ecal_calibrations";
     
     /**
      * Set the RawTrackerHit collection of hits to be used for the calibration.
@@ -91,7 +91,7 @@
     /**
      * Set the end run number for the conditions record.  
      * It must be >= the runEnd.
-     * @param runStart The run start number.
+     * @param runEnd The run end number.
      */
     public void setRunEnd(int runEnd) {
         if (runEnd < 0) {
@@ -216,15 +216,15 @@
             }
             
             // Truncate to 4 decimal places.
-            mean = Double.valueOf(decimalFormat.format(mean));
-            sigma = Double.valueOf(decimalFormat.format(sigma));
+            mean = Double.valueOf(DECIMAL_FORMAT.format(mean));
+            sigma = Double.valueOf(DECIMAL_FORMAT.format(sigma));
             
             // Create a new calibration object and add it to the collection, using mean for pedestal
             // and sigma for noise.
             try {
-            	calibrations.add(new EcalCalibration(channelId, mean, sigma));
+                calibrations.add(new EcalCalibration(channelId, mean, sigma));
             } catch (ConditionsObjectException e) {
-            	throw new RuntimeException("Error adding new calibration object.", e);
+                throw new RuntimeException("Error adding new calibration object.", e);
             }
         } 
         

Modified: java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/EcalConverterDriver.java
 =============================================================================
--- java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/EcalConverterDriver.java	(original)
+++ java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/EcalConverterDriver.java	Wed Apr 27 11:11:32 2016
@@ -6,7 +6,6 @@
 import org.lcsim.event.CalorimeterHit;
 import org.lcsim.event.EventHeader;
 import org.lcsim.event.RawCalorimeterHit;
-import org.lcsim.event.base.BaseCalorimeterHit;
 import org.lcsim.geometry.Detector;
 import org.lcsim.lcio.LCIOConstants;
 import org.lcsim.util.Driver;
@@ -17,8 +16,8 @@
  * @version $Id: EcalConverterDriver.java,v 1.1 2013/02/25 22:39:24 meeg Exp $
  */
 public class EcalConverterDriver extends Driver {
-	
-	Detector detector = null;
+    
+    Detector detector = null;
 
     String rawCollectionName;
     String ecalReadoutName = "EcalHits";
@@ -59,7 +58,7 @@
     
     @Override
     public void detectorChanged(Detector detector) {
-    	this.detector = detector;
+        this.detector = detector;
     }
 
     @Override
@@ -87,8 +86,8 @@
     }
 
     private CalorimeterHit HitDtoA(RawCalorimeterHit hit) {
-    	double energy = DtoA(hit.getAmplitude(), hit.getCellID());
-    	return CalorimeterHitUtilities.create(energy, period * hit.getTimeStamp() + dt, hit.getCellID());
+        double energy = DtoA(hit.getAmplitude(), hit.getCellID());
+        return CalorimeterHitUtilities.create(energy, period * hit.getTimeStamp() + dt, hit.getCellID());
     }
 
 //    private RawCalorimeterHit HitAtoD(CalorimeterHit hit) {

Modified: java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/EcalEdepToTriggerConverterDriver.java
 =============================================================================
--- java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/EcalEdepToTriggerConverterDriver.java	(original)
+++ java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/EcalEdepToTriggerConverterDriver.java	Wed Apr 27 11:11:32 2016
@@ -29,11 +29,11 @@
  * @author Holly Szumila <[log in to unmask]>
  */
 public class EcalEdepToTriggerConverterDriver extends Driver {
-	
+    
     private EcalConditions ecalConditions = null;
     
     private static final boolean isBadChannelLoaded = true;
-	
+    
     private final String ecalReadoutName = "EcalHits";
     private String inputCollection = "EcalHits";
     private String readoutCollection = "EcalCalHits";
@@ -94,7 +94,7 @@
 
     @Override
     public void detectorChanged(Detector detector) {
-    	
+        
         // ECAL combined conditions object.
         ecalConditions = DatabaseConditionsManager.getInstance().getEcalConditions();
                 
@@ -104,7 +104,7 @@
     public boolean isBadCrystal(CalorimeterHit hit) {
         // Get the channel data.
         EcalChannelConstants channelData = findChannel(hit.getCellID());
-    	
+        
         return isBadChannelLoaded ? channelData.isBadChannel() : false;
     }
 
@@ -165,8 +165,8 @@
 //        System.out.format("trigger: %f %f\n", amplitude, triggerIntegral);
 
         int truncatedIntegral = (int) Math.floor(triggerIntegral / truncateScale);
-        if (truncatedIntegral > 0) {        	
-        	return CalorimeterHitUtilities.create(truncatedIntegral, hit.getTime(), hit.getCellID());
+        if (truncatedIntegral > 0) {            
+            return CalorimeterHitUtilities.create(truncatedIntegral, hit.getTime(), hit.getCellID());
         }
         return null;
     }

Modified: java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/EcalOnlineRawConverter.java
 =============================================================================
--- java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/EcalOnlineRawConverter.java	(original)
+++ java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/EcalOnlineRawConverter.java	Wed Apr 27 11:11:32 2016
@@ -27,28 +27,28 @@
     private int nPeak = 3;
     
     public EcalOnlineRawConverter() {
-    	// Track changes in the DAQ configuration.
-    	ConfigurationManager.addActionListener(new ActionListener() {
-			@Override
-			public void actionPerformed(ActionEvent e) {
-				// Get the FADC configuration.
-				config = ConfigurationManager.getInstance().getFADCConfig();
-				// Get the number of peaks.
-				if(config.getMode() == 1) nPeak = Integer.MAX_VALUE;
-				else                      nPeak = config.getMaxPulses();
-				// Print the FADC configuration.
-				System.out.println();
-				System.out.println();
-				System.out.printf("NSA            :: %d ns%n", config.getNSA());
-				System.out.printf("NSB            :: %d ns%n", config.getNSB());
-				System.out.printf("Window Samples :: %d clock-cycles%n", config.getWindowWidth());
-				System.out.printf("Max Peaks      :: %d peaks%n", nPeak);
-				System.out.println("======================================================================");
-				System.out.println("=== FADC Pulse-Processing Settings ===================================");
-				System.out.println("======================================================================");
-				config.printConfig();
-			}
-    	});
+        // Track changes in the DAQ configuration.
+        ConfigurationManager.addActionListener(new ActionListener() {
+            @Override
+            public void actionPerformed(ActionEvent e) {
+                // Get the FADC configuration.
+                config = ConfigurationManager.getInstance().getFADCConfig();
+                // Get the number of peaks.
+                if(config.getMode() == 1) nPeak = Integer.MAX_VALUE;
+                else                      nPeak = config.getMaxPulses();
+                // Print the FADC configuration.
+                System.out.println();
+                System.out.println();
+                System.out.printf("NSA            :: %d ns%n", config.getNSA());
+                System.out.printf("NSB            :: %d ns%n", config.getNSB());
+                System.out.printf("Window Samples :: %d clock-cycles%n", config.getWindowWidth());
+                System.out.printf("Max Peaks      :: %d peaks%n", nPeak);
+                System.out.println("======================================================================");
+                System.out.println("=== FADC Pulse-Processing Settings ===================================");
+                System.out.println("======================================================================");
+                config.printConfig(System.out);
+            }
+        });
     }
 
     /**
@@ -137,10 +137,10 @@
                 // search for next threshold crossing begins at end of this pulse:
                 if (ConfigurationManager.getInstance().getFADCConfig().getMode() == 1) {
                     // special case, emulating SSP:
-                	ii += 8;
+                    ii += 8;
                 } else {
                     // "normal" case, emulating FADC250:
-                	ii += config.getNSA()/nsPerSample - 1;
+                    ii += config.getNSA()/nsPerSample - 1;
                 }
 
                 // firmware limit on # of peaks:

Modified: java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/EcalOnlineRawConverterDriver.java
 =============================================================================
--- java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/EcalOnlineRawConverterDriver.java	(original)
+++ java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/EcalOnlineRawConverterDriver.java	Wed Apr 27 11:11:32 2016
@@ -85,12 +85,12 @@
 
     @Override
     public void process(EventHeader event) {
-    	// Do not process the event if the DAQ configuration should be
-    	// used for value, but is not initialized.
-    	if(!ConfigurationManager.isInitialized()) {
-    		return;
-    	}
-    	
+        // Do not process the event if the DAQ configuration should be
+        // used for value, but is not initialized.
+        if(!ConfigurationManager.isInitialized()) {
+            return;
+        }
+        
         double timeOffset = 0.0;
         int flags = 0;
         flags += 1 << LCIOConstants.RCHBIT_TIME; //store hit time
@@ -102,12 +102,12 @@
          * This is for FADC Mode-1 data:    
          */
         if (event.hasCollection(RawTrackerHit.class, rawCollectionName)) {
-        	List<RawTrackerHit> hits = event.get(RawTrackerHit.class, rawCollectionName);
+            List<RawTrackerHit> hits = event.get(RawTrackerHit.class, rawCollectionName);
 
-        	for (RawTrackerHit hit : hits) {
-        		newHits.addAll(converter.HitDtoA(event,hit));
-        	}
-        	event.put(ecalCollectionName, newHits, CalorimeterHit.class, flags, ecalReadoutName);
+            for (RawTrackerHit hit : hits) {
+                newHits.addAll(converter.HitDtoA(event,hit));
+            }
+            event.put(ecalCollectionName, newHits, CalorimeterHit.class, flags, ecalReadoutName);
         }
 
         /*
@@ -115,26 +115,26 @@
          */
         if (event.hasCollection(RawCalorimeterHit.class, rawCollectionName)) { 
 
-        	/*
-        	 * This is for FADC Mode-7 data:
-        	 */
-        	if (event.hasCollection(LCRelation.class, extraDataRelationsName)) { // extra information available from mode 7 readout
-        		List<LCRelation> extraDataRelations = event.get(LCRelation.class, extraDataRelationsName);
-        		for (LCRelation rel : extraDataRelations) {
-        			RawCalorimeterHit hit = (RawCalorimeterHit) rel.getFrom();
-        			GenericObject extraData = (GenericObject) rel.getTo();
-        			newHits.add(converter.HitDtoA(event,hit, extraData, timeOffset));
-        		}
-        	} else {
-        		/*
-        		 * This is for FADC Mode-3 data:
-        		 */
-        		List<RawCalorimeterHit> hits = event.get(RawCalorimeterHit.class, rawCollectionName);
-        		for (RawCalorimeterHit hit : hits) {
-        			newHits.add(converter.HitDtoA(event, hit, timeOffset));
-        		}
-        	}
-        	event.put(ecalCollectionName, newHits, CalorimeterHit.class, flags, ecalReadoutName);
+            /*
+             * This is for FADC Mode-7 data:
+             */
+            if (event.hasCollection(LCRelation.class, extraDataRelationsName)) { // extra information available from mode 7 readout
+                List<LCRelation> extraDataRelations = event.get(LCRelation.class, extraDataRelationsName);
+                for (LCRelation rel : extraDataRelations) {
+                    RawCalorimeterHit hit = (RawCalorimeterHit) rel.getFrom();
+                    GenericObject extraData = (GenericObject) rel.getTo();
+                    newHits.add(converter.HitDtoA(event,hit, extraData, timeOffset));
+                }
+            } else {
+                /*
+                 * This is for FADC Mode-3 data:
+                 */
+                List<RawCalorimeterHit> hits = event.get(RawCalorimeterHit.class, rawCollectionName);
+                for (RawCalorimeterHit hit : hits) {
+                    newHits.add(converter.HitDtoA(event, hit, timeOffset));
+                }
+            }
+            event.put(ecalCollectionName, newHits, CalorimeterHit.class, flags, ecalReadoutName);
         }
     }
 

Modified: java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/EcalPedestalCalculator.java
 =============================================================================
--- java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/EcalPedestalCalculator.java	(original)
+++ java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/EcalPedestalCalculator.java	Wed Apr 27 11:11:32 2016
@@ -114,11 +114,11 @@
             }
         }
         if (uploadToDB) {
-        	try {
-        		uploadToDB();
-        	} catch (DatabaseObjectException | ConditionsObjectException | SQLException e) {
-        		throw new RuntimeException("Error uploading to database.", e);
-        	}
+            try {
+                uploadToDB();
+            } catch (DatabaseObjectException | ConditionsObjectException | SQLException e) {
+                throw new RuntimeException("Error uploading to database.", e);
+            }
         } else {
             System.out.println("!!!!!!!!!!!!!!!!!!!!!!! Not Writing Database !!!!!!!!!!!!!!!!!!!!!!!!!!");
         }

Modified: java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/EcalRawConverter.java
 =============================================================================
--- java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/EcalRawConverter.java	(original)
+++ java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/EcalRawConverter.java	Wed Apr 27 11:11:32 2016
@@ -41,9 +41,9 @@
  */
 public class EcalRawConverter {
 
-	/**
-	 * If true, time walk correction is performed. 
-	 */
+    /**
+     * If true, time walk correction is performed. 
+     */
     private boolean useTimeWalkCorrection = true;
     
     /**
@@ -149,42 +149,42 @@
      * for trigger emulation.
      */
     public EcalRawConverter() {
-    	// Track changes in the DAQ configuration.
-    	ConfigurationManager.addActionListener(new ActionListener() {
-			@Override
-			public void actionPerformed(ActionEvent e) {
-				// If the DAQ configuration should be used, load the
-				// relevant settings into the driver.
-				if(useDAQConfig) {
-					// Get the FADC configuration.
-					config = ConfigurationManager.getInstance().getFADCConfig();
-					
-					// Load the settings.
-					NSB = config.getNSB();
-					NSA = config.getNSA();
-					windowSamples = config.getWindowWidth() / 4;
-					
-					// Get the number of peaks.
-					if(config.getMode() == 1) {
-						nPeak = Integer.MAX_VALUE;
-					} else {
-						nPeak = config.getMaxPulses();
-					}
-					
-					// Print the FADC configuration.
-					System.out.println();
-					System.out.println();
-					System.out.printf("NSA            :: %d ns%n", NSA);
-					System.out.printf("NSB            :: %d ns%n", NSB);
-					System.out.printf("Window Samples :: %d clock-cycles%n", windowSamples);
-					System.out.printf("Max Peaks      :: %d peaks%n", nPeak);
-					System.out.println("======================================================================");
-					System.out.println("=== FADC Pulse-Processing Settings ===================================");
-					System.out.println("======================================================================");
-					config.printConfig();
-				}
-			}
-    	});
+        // Track changes in the DAQ configuration.
+        ConfigurationManager.addActionListener(new ActionListener() {
+            @Override
+            public void actionPerformed(ActionEvent e) {
+                // If the DAQ configuration should be used, load the
+                // relevant settings into the driver.
+                if(useDAQConfig) {
+                    // Get the FADC configuration.
+                    config = ConfigurationManager.getInstance().getFADCConfig();
+                    
+                    // Load the settings.
+                    NSB = config.getNSB();
+                    NSA = config.getNSA();
+                    windowSamples = config.getWindowWidth() / 4;
+                    
+                    // Get the number of peaks.
+                    if(config.getMode() == 1) {
+                        nPeak = Integer.MAX_VALUE;
+                    } else {
+                        nPeak = config.getMaxPulses();
+                    }
+                    
+                    // Print the FADC configuration.
+                    System.out.println();
+                    System.out.println();
+                    System.out.printf("NSA            :: %d ns%n", NSA);
+                    System.out.printf("NSB            :: %d ns%n", NSB);
+                    System.out.printf("Window Samples :: %d clock-cycles%n", windowSamples);
+                    System.out.printf("Max Peaks      :: %d peaks%n", nPeak);
+                    System.out.println("======================================================================");
+                    System.out.println("=== FADC Pulse-Processing Settings ===================================");
+                    System.out.println("======================================================================");
+                    config.printConfig(System.out);
+                }
+            }
+        });
     }
     
  
@@ -313,7 +313,7 @@
      * for trigger emulation.
      */
     public void setUseDAQConfig(boolean state) {
-    	useDAQConfig = state;
+        useDAQConfig = state;
     }
     
 
@@ -325,10 +325,10 @@
         EcalChannelConstants channelData = findChannel(hit.getCellID());
         double pedestal;
         if(useDAQConfig) {
-    		//EcalChannel channel = ecalConditions.getChannelCollection().findGeometric(hit.getCellID());
-    		pedestal = config.getPedestal(hit.getCellID());
+            //EcalChannel channel = ecalConditions.getChannelCollection().findGeometric(hit.getCellID());
+            pedestal = config.getPedestal(hit.getCellID());
         } else {
-        	pedestal = channelData.getCalibration().getPedestal();
+            pedestal = channelData.getCalibration().getPedestal();
         }
         
         int sum = 0;
@@ -356,10 +356,10 @@
      * Choose whether to use static pedestal from database or running pedestal from mode-7.
      */
     public double getSingleSamplePedestal(EventHeader event,long cellID) {
-    	if(useDAQConfig) {
-    		//EcalChannel channel = ecalConditions.getChannelCollection().findGeometric(cellID);
-    		return config.getPedestal(cellID);
-    	}
+        if(useDAQConfig) {
+            //EcalChannel channel = ecalConditions.getChannelCollection().findGeometric(cellID);
+            return config.getPedestal(cellID);
+        }
         if (useRunningPedestal && event!=null) {
             if (event.hasItem("EcalRunningPedestals")) {
                 Map<EcalChannel, Double> runningPedMap = (Map<EcalChannel, Double>) event.get("EcalRunningPedestals");
@@ -536,12 +536,12 @@
         // threshold is pedestal plus threshold configuration parameter:
         final int absoluteThreshold;
         if(useDAQConfig) {
-        	//EcalChannel channel = ecalConditions.getChannelCollection().findGeometric(hit.getCellID());
-        	//int leadingEdgeThreshold = ConfigurationManager.getInstance().getFADCConfig().getThreshold(channel.getChannelId());
-        	int leadingEdgeThreshold = config.getThreshold(cellID);
-        	absoluteThreshold = (int) (getSingleSamplePedestal(event, cellID) + leadingEdgeThreshold);
+            //EcalChannel channel = ecalConditions.getChannelCollection().findGeometric(hit.getCellID());
+            //int leadingEdgeThreshold = ConfigurationManager.getInstance().getFADCConfig().getThreshold(channel.getChannelId());
+            int leadingEdgeThreshold = config.getThreshold(cellID);
+            absoluteThreshold = (int) (getSingleSamplePedestal(event, cellID) + leadingEdgeThreshold);
         } else {
-        	absoluteThreshold = (int) (getSingleSamplePedestal(event, cellID) + leadingEdgeThreshold);
+            absoluteThreshold = (int) (getSingleSamplePedestal(event, cellID) + leadingEdgeThreshold);
         }
         
         ArrayList <Integer> thresholdCrossings = new ArrayList<Integer>();
@@ -562,10 +562,10 @@
                 // search for next threshold crossing begins at end of this pulse:
                 if(useDAQConfig && ConfigurationManager.getInstance().getFADCConfig().getMode() == 1) {
                     // special case, emulating SSP:
-                	ii += 8;
+                    ii += 8;
                 } else {
                     // "normal" case, emulating FADC250:
-                	ii += NSA/nsPerSample - 1;
+                    ii += NSA/nsPerSample - 1;
                 }
 
                 // firmware limit on # of peaks:
@@ -674,8 +674,8 @@
         EcalChannelConstants channelData = findChannel(cellID);
         
         if(useDAQConfig) {
-        	//float gain = ConfigurationManager.getInstance().getFADCConfig().getGain(ecalConditions.getChannelCollection().findGeometric(cellID));
-        	return config.getGain(cellID) * adcSum * EcalUtils.MeV;
+            //float gain = ConfigurationManager.getInstance().getFADCConfig().getGain(ecalConditions.getChannelCollection().findGeometric(cellID));
+            return config.getGain(cellID) * adcSum * EcalUtils.MeV;
         }  else if(use2014Gain) {
             if (constantGain) {
                 return adcSum * EcalUtils.gainFactor * EcalUtils.ecalReadoutPeriod;

Modified: java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/EcalRawConverterDriver.java
 =============================================================================
--- java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/EcalRawConverterDriver.java	(original)
+++ java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/EcalRawConverterDriver.java	Wed Apr 27 11:11:32 2016
@@ -18,14 +18,18 @@
 import org.lcsim.util.Driver;
 
 /**
- * This class is used to convert between collections of {@link org.lcsim.event.RawCalorimeterHit}
- * and {@link org.lcsim.event.RawTrackerHit}, objects with ADC/sample information, and
- * collections of {@link org.lcsim.event.CalorimeterHit}, objects with energy/time information.
- * 
- * org.hps.recon.ecal.EcalRawConverter is called to do most of the lower level work.
- *
- *
-*/
+ * This <code>Driver</code> converts raw ECal data collections to {@link org.lcsim.event.CalorimeterHit} collections 
+ * with energy and time information.  The {@link EcalRawConverter} does most of the low-level work.
+ * <p>
+ * The following input collections are used:
+ * <ul>
+ * <li>EcalReadoutHits<li>
+ * <li>EcalReadoutExtraDataRelations</li>
+ * <li>EcalRunningPedestals</li>
+ * </ul>
+ * <p>
+ * The results are by default written to the <b>EcalCalHits</b> output collection.
+ */
 public class EcalRawConverterDriver extends Driver {
 
     // To import database conditions
@@ -376,8 +380,8 @@
      * conditions database.
      */
     public void setUseDAQConfig(boolean state) {
-    	useDAQConfig = state;
-    	converter.setUseDAQConfig(state);
+        useDAQConfig = state;
+        converter.setUseDAQConfig(state);
     }
 
     @Override
@@ -400,18 +404,17 @@
 
     /**
      * @return false if the channel is a good one, true if it is a bad one
-     * @param CalorimeterHit
+     * @param hit the <code>CalorimeterHit</code> pointing to the channel
      */
     public boolean isBadCrystal(CalorimeterHit hit) {
         // Get the channel data.
         EcalChannelConstants channelData = findChannel(hit.getCellID());
-
         return channelData.isBadChannel();
     }
 
     /**
      * @return false if the ADC is a good one, true if it is a bad one
-     * @param CalorimeterHit
+     * @param hit the <code>CalorimeterHit</code> pointing to the FADC
      */
     public boolean isBadFADC(CalorimeterHit hit) {
         return (getCrate(hit.getCellID()) == 1 && getSlot(hit.getCellID()) == 3);
@@ -433,12 +436,12 @@
 
     @Override
     public void process(EventHeader event) {
-    	// Do not process the event if the DAQ configuration should be
-    	// used for value, but is not initialized.
-    	if(useDAQConfig && !ConfigurationManager.isInitialized()) {
-    		return;
-    	}
-    	
+        // Do not process the event if the DAQ configuration should be
+        // used for value, but is not initialized.
+        if(useDAQConfig && !ConfigurationManager.isInitialized()) {
+            return;
+        }
+        
         final int SYSTEM_TRIGGER = 0;
 //        final int SYSTEM_TRACKER = 1;
         final int SYSTEM_ECAL = 2;

Modified: java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/EcalRunningPedestalDriver.java
 =============================================================================
--- java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/EcalRunningPedestalDriver.java	(original)
+++ java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/EcalRunningPedestalDriver.java	Wed Apr 27 11:11:32 2016
@@ -18,18 +18,21 @@
 import org.lcsim.util.Driver;
 
 /**
- * Calculate a running pedestal average for every channel from Mode7 FADCs. Uses
- * pedestals from the database if not available from the data.
- * 
- * May 2015:  Updated to also work on Mode1 data.
- * 
- * TODO: Use Logger.
+ * This <code>Driver</code> takes Mode-1 or Mode-7 ECal data and computes a running pedestal 
+ * average for every channel.  Pedestals from the database will be used if this is not available.
+ * <p>
+ * The following input collections are used:
+ * <ul>
+ * <li>EcalReadoutHits</li>
+ * <li>EcalReadoutExtraDataRelations</li>
+ * </ul>
+ * <p>
+ * Results are by default written to the <b>EcalRunningPedestals</b> output collection.
  * 
  * TODO: Timestamps from EVIO for some runs appear to not be monotonically increasing.
  *       This interferes with minLookbackTime, so it defaults to disabled and its setter
- *       is left private for now.
+ *       is left private for now. (Should be a JIRA item??? --JM)
  * 
- * @version $Id: ECalRunningPedestalDriver.java,v 1.0 2015/02/10 00:00:00
  * @author <[log in to unmask]>
  */
 public class EcalRunningPedestalDriver extends Driver {

Modified: java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/EcalTimeWalk.java
 =============================================================================
--- java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/EcalTimeWalk.java	(original)
+++ java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/EcalTimeWalk.java	Wed Apr 27 11:11:32 2016
@@ -39,11 +39,11 @@
      * Time walk parameters for pulse fitting
      */
     private static final double[] par = {
-    	0.9509,
-    	-33.21,
-    	0.2614,
-    	-0.9128,
-    	0.6251
+        0.9509,
+        -33.21,
+        0.2614,
+        -0.9128,
+        0.6251
    };
     
     /**
@@ -53,9 +53,9 @@
      * @return corrected time (ns)
      */
     public static final double correctTimeWalkPulseFitting(double time, double energy) {
-    	final double polyA = par[0] + par[1]*energy;
-    	final double polyB = par[2] + par[3] * energy + par[4] * Math.pow(energy, 2);
-    	return time - (Math.exp(polyA) + polyB);
+        final double polyA = par[0] + par[1]*energy;
+        final double polyB = par[2] + par[3] * energy + par[4] * Math.pow(energy, 2);
+        return time - (Math.exp(polyA) + polyB);
     }
     
     

Modified: java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/FADCGenericHit.java
 =============================================================================
--- java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/FADCGenericHit.java	(original)
+++ java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/FADCGenericHit.java	Wed Apr 27 11:11:32 2016
@@ -24,6 +24,14 @@
         this.slot = slot;
         this.channel = channel;
         this.data = data;
+    }
+    
+    public FADCGenericHit(GenericObject object) {
+        this.readoutMode = getReadoutMode(object);
+        this.crate = getCrate(object);
+        this.slot = getSlot(object);
+        this.channel = getChannel(object);
+        this.data = getData(object);
     }
 
     @Override
@@ -114,5 +122,5 @@
             data[i] = object.getIntVal(i+4);
         }
         return data;
-    }
+    }    
 }

Modified: java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/IterateGainFactorDriver.java
 =============================================================================
--- java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/IterateGainFactorDriver.java	(original)
+++ java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/IterateGainFactorDriver.java	Wed Apr 27 11:11:32 2016
@@ -26,15 +26,15 @@
  */
 
 public class IterateGainFactorDriver extends Driver {
-	
-	private EcalConditions ecalConditions  = null;
-		
-	/**
+    
+    private EcalConditions ecalConditions  = null;
+        
+    /**
      * Set the input collection name (source).
      *
      * @param inputCollectionName the input collection name
      */
-	private String inputCollectionName = "EcalCalHits";
+    private String inputCollectionName = "EcalCalHits";
     public void setInputCollectionName(final String inputCollectionName) {
         this.inputCollectionName = inputCollectionName;
     }
@@ -116,14 +116,14 @@
      * @return the output hit collection with gain corrected energies
      */
     public List<CalorimeterHit> iterateHits(final List<CalorimeterHit> hits) {
-    	ArrayList<CalorimeterHit> newHits = new ArrayList<CalorimeterHit>();
+        ArrayList<CalorimeterHit> newHits = new ArrayList<CalorimeterHit>();
         for (final CalorimeterHit hit : hits) {
-        	double time = hit.getTime();        	
-        	long cellID = hit.getCellID();
-        	double energy = hit.getCorrectedEnergy()*gainFileGains.get(findChannelId(cellID));
-        	CalorimeterHit newHit = CalorimeterHitUtilities.create(energy, time, cellID);
-        	newHits.add(newHit);	
-        	
+            double time = hit.getTime();            
+            long cellID = hit.getCellID();
+            double energy = hit.getCorrectedEnergy()*gainFileGains.get(findChannelId(cellID));
+            CalorimeterHit newHit = CalorimeterHitUtilities.create(energy, time, cellID);
+            newHits.add(newHit);    
+            
         }
         return newHits;
     }
@@ -134,26 +134,26 @@
      */
     @Override
     public void process(final EventHeader event) {
-    	readGainFile();
-    	
-    	        // Check if output collection already exists in event which is an error.
+        readGainFile();
+        
+                // Check if output collection already exists in event which is an error.
         if (event.hasItem(outputCollectionName)) {
             throw new RuntimeException("collection " + outputCollectionName + " already exists in event");
         }
 
         // Get the input collection.
         if (event.hasCollection(CalorimeterHit.class,inputCollectionName)){
-        	final List<CalorimeterHit> inputHitCollection = event.get(CalorimeterHit.class, inputCollectionName);
+            final List<CalorimeterHit> inputHitCollection = event.get(CalorimeterHit.class, inputCollectionName);
 
-        	// Iterate the gain correction coefficient on each hit.
-        	final List<CalorimeterHit> outputHitCollection = this.iterateHits(inputHitCollection);
-        	
+            // Iterate the gain correction coefficient on each hit.
+            final List<CalorimeterHit> outputHitCollection = this.iterateHits(inputHitCollection);
+            
             int flags = 0;
             flags += 1 << LCIOConstants.RCHBIT_TIME; //store hit time
             flags += 1 << LCIOConstants.RCHBIT_LONG; //store hit position; this flag has no effect for RawCalorimeterHits
-        	
-        	// Put the collection into the event.
-        	event.put(outputCollectionName, outputHitCollection, CalorimeterHit.class, flags, ecalReadoutName);
+            
+            // Put the collection into the event.
+            event.put(outputCollectionName, outputHitCollection, CalorimeterHit.class, flags, ecalReadoutName);
         }
     }
    

Modified: java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/AbstractClusterer.java
 =============================================================================
--- java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/AbstractClusterer.java	(original)
+++ java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/AbstractClusterer.java	Wed Apr 27 11:11:32 2016
@@ -16,7 +16,7 @@
 /**
  * This is an abstract class that {@link Clusterer} classes should implement
  * to perform a clustering algorithm on a <code>CalorimeterHit</code> collection.
- * The sub-class should implement {@link #createClusters(List)} which is 
+ * The sub-class should implement {@link #createClusters(EventHeader, List)} which is 
  * the method that should perform the clustering algorithm.
  * 
  * @see Clusterer
@@ -69,8 +69,8 @@
     
     /**
      * This is the primary method for sub-classes to implement their clustering algorithm.
-     * @param hits
-     * @return
+     * @param hits the list of hits
+     * @return the list of created clusters
      */
     public abstract List<Cluster> createClusters(EventHeader event, List<CalorimeterHit> hits);
     

Modified: java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/ClusterDriver.java
 =============================================================================
--- java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/ClusterDriver.java	(original)
+++ java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/ClusterDriver.java	Wed Apr 27 11:11:32 2016
@@ -73,7 +73,7 @@
     
     /**
      * Set the name of the input CalorimeterHit collection to use for clustering.
-     * @param inputHitcollectionName The name of the input hit collection.
+     * @param inputHitCollectionName The name of the input hit collection.
      */
     public void setInputHitCollectionName(String inputHitCollectionName) {
         this.inputHitCollectionName = inputHitCollectionName;
@@ -128,7 +128,7 @@
      * This will use a factory method which first tries to use some hard-coded names from 
      * the cluster package.  As a last resort, it will interpret the name as a canonical 
      * class name and try to instantiate it using the Class API.
-     * @param The name or canonical class name of the Clusterer.
+     * @param name The name or canonical class name of the Clusterer.
      */
     public void setClustererName(String name) {
         clusterer = ClustererFactory.create(name);

Modified: java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/ClusterEnergyCorrection.java
 =============================================================================
--- java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/ClusterEnergyCorrection.java	(original)
+++ java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/ClusterEnergyCorrection.java	Wed Apr 27 11:11:32 2016
@@ -1,89 +1,208 @@
 package org.hps.recon.ecal.cluster;
 
+import hep.physics.vec.Hep3Vector;
+
+import org.hps.detector.ecal.EcalCrystal;
+import org.hps.detector.ecal.HPSEcalDetectorElement;
+import org.jdom.DataConversionException;
+// import org.hps.recon.tracking.TrackUtils;
 import org.lcsim.event.Cluster;
 import org.lcsim.event.base.BaseCluster;
+import org.lcsim.geometry.subdetector.HPSEcal3;
 
 /**
- * This is the cluster energy correction requiring the particle id 
- * uncorrected cluster energy. This is not accurate for edge crystals
- * and should be used after cluster-track matching and after position
- * corrections.
+ * This is the cluster energy correction requiring the particle id uncorrected
+ * cluster energy. This is now updated to include edge corrections and sampling
+ * fractions derived from data.
  * 
  * @author Holly Vance <[log in to unmask]>
  * @author Jeremy McCormick <[log in to unmask]>
  */
 public final class ClusterEnergyCorrection {
+
+    // Variables for electron energy corrections.
+    static final double par0_em = -0.017;
+    static final double par1_em[] = { 35, -0.06738, -0.0005613, 16.42, 0.3431,
+            -2.021, 74.85, -0.3626 };
+    static final double par2_em[] = { 35, 0.933, 0.003234, 18.06, 0.24, 8.586,
+            75.08, -0.39 };
+
+    // Variables for positron energy corrections.
+    static final double par0_ep = -0.0131;
+    static final double par1_ep[] = { 35, -0.076, -0.0008183, 17.88, 0.2886,
+            -1.192, 73.12, -0.3747 };
+    static final double par2_ep[] = { 35, 0.94, 0.003713, 18.19, 0.24, 8.342,
+            72.44, -0.39 };
+
+    // Variables for photon energy corrections.
+    static final double par0_p = -0.0113;
+    static final double par1_p[] = { 35, -0.0585, -0.0008572, 16.76, 0.2784,
+            -0.07232, 72.88, -0.1685 };
+    static final double par2_p[] = { 35, 0.9307, 0.004, 18.05, 0.23, 3.027,
+            74.93, -0.34 };
+
+    /**
+     * Calculate the corrected energy for the cluster.
+     * 
+     * @param cluster
+     *            The input cluster.
+     * @return The corrected energy.
+     */
+    public static double calculateCorrectedEnergy(HPSEcal3 ecal, Cluster cluster) {
+        double rawE = cluster.getEnergy();
+        return computeCorrectedEnergy(ecal, cluster.getParticleId(), rawE,
+                cluster.getPosition()[0], cluster.getPosition()[1]);
+    }
+
+    /**
+     * Calculate the corrected energy for the cluster using track position at
+     * ecal.
+     * 
+     * @param cluster
+     *            The input cluster.
+     * @return The corrected energy.
+     */
+    public static double calculateCorrectedEnergy(HPSEcal3 ecal,
+            Cluster cluster, double ypos) {
+        double rawE = cluster.getEnergy();
+        return computeCorrectedEnergy(ecal, cluster.getParticleId(), rawE,
+                cluster.getPosition()[0], ypos);
+    }
+
+    /**
+     * Calculate the corrected energy and set on the cluster.
+     * 
+     * @param cluster
+     *            The input cluster.
+     */
+    public static void setCorrectedEnergy(HPSEcal3 ecal, BaseCluster cluster) {
+        double correctedEnergy = calculateCorrectedEnergy(ecal, cluster);
+        cluster.setEnergy(correctedEnergy);
+    }
+
+    /**
+     * Calculate the corrected energy and set on the cluster.
+     * 
+     * @param cluster
+     *            The input cluster.
+     */
+
+    public static void setCorrectedEnergy(HPSEcal3 ecal, BaseCluster cluster,
+            double ypos) {
+        double correctedEnergy = calculateCorrectedEnergy(ecal, cluster, ypos);
+        cluster.setEnergy(correctedEnergy);
+    }
+
+    /**
+     * Calculates energy correction based on cluster raw energy and particle
+     * type as per <a href=
+     * "https://misportal.jlab.org/mis/physics/hps_notes/index.cfm?note_year=2014"
+     * >HPS Note 2014-001</a>
+     * 
+     * @param pdg
+     *            Particle id as per PDG
+     * @param rawEnergy
+     *            Raw Energy of the cluster (sum of hits with shared hit
+     *            distribution)
+     * @return Corrected Energy
+     */
+
+    private static double computeCorrectedEnergy(HPSEcal3 ecal, int pdg,
+            double rawEnergy, double xpos, double ypos) {
+        // distance to beam gap edge
+        double r;
+        // Get these values from the Ecal geometry:
+        HPSEcalDetectorElement detElement = (HPSEcalDetectorElement) ecal
+                .getDetectorElement();
+        // double BEAMGAPTOP =
+        // 22.3;//ecal.getNode().getChild("layout").getAttribute("beamgapTop").getDoubleValue();//mm
+        double BEAMGAPTOP = 20.0;
+        try {
+            BEAMGAPTOP = ecal.getNode().getChild("layout")
+                    .getAttribute("beamgapTop").getDoubleValue();
+        } catch (DataConversionException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }// mm
+        double BEAMGAPBOT = -20.0;
+        try {
+            BEAMGAPBOT = -ecal.getNode().getChild("layout")
+                    .getAttribute("beamgapBottom").getDoubleValue();
+        } catch (DataConversionException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }// mm
+        double BEAMGAPTOPC = BEAMGAPTOP + 13.0;// mm
+        double BEAMGAPBOTC = BEAMGAPBOT - 13.0;// mm
+        // x-coordinates of crystals on either side of row 1 cut out
+        EcalCrystal crystalM = detElement.getCrystal(-11, 1);
+        Hep3Vector posM = crystalM.getPositionFront();
+        EcalCrystal crystalP = detElement.getCrystal(-1, 1);
+        Hep3Vector posP = crystalP.getPositionFront();
+
+        if ((xpos < posM.x()) || (xpos > posP.x())) {
+            if (ypos > 0) {
+                r = Math.abs(ypos - BEAMGAPTOP);
+            } else {
+                r = Math.abs(ypos - BEAMGAPBOT);
+            }
+        }
+        // crystals above row 1 cut out
+        else {
+            if (ypos > 0) {
+                if (ypos > (par1_em[0] + BEAMGAPTOP)) {
+                    r = Math.abs(ypos - BEAMGAPTOP);
+                } else {
+                    r = Math.abs(ypos - BEAMGAPTOPC);
+                }
+            } else {
+                if (ypos > (-par1_em[0] + BEAMGAPBOT)) {
+                    r = Math.abs(ypos - BEAMGAPBOTC);
+                } else {
+                    r = Math.abs(ypos - BEAMGAPBOT);
+                }
+            }
+        }
         
-    // Variables for electron energy corrections.
-    //Updated with recent monte carlo --7AUG15 HS. 
-    //Old values from 2014-2015 commented out to right.
-    static final double ELECTRON_ENERGY_A = 0.01004;//-0.0027;
-    static final double ELECTRON_ENERGY_B = -0.122;//-0.06;
-    static final double ELECTRON_ENERGY_C = 0.9646;//0.95;
-    
-    // Variables for positron energy corrections.
-    static final double POSITRON_ENERGY_A = 0.00711;//-0.0096;
-    static final double POSITRON_ENERGY_B = -0.1154;//-0.042;
-    static final double POSITRON_ENERGY_C = 0.9614;//0.94;
-    
-    // Variables for photon energy corrections.
-    static final double PHOTON_ENERGY_A = 0.007595;//0.0015;
-    static final double PHOTON_ENERGY_B = -0.09766;//-0.047;
-    static final double PHOTON_ENERGY_C = 0.9512;//0.94;
-          
-    /**
-     * Calculate the corrected energy for the cluster.
-     * @param cluster The input cluster.
-     * @return The corrected energy.
-     */
-    public static double calculateCorrectedEnergy(Cluster cluster) {
-        double rawE = cluster.getEnergy();
-        return computeCorrectedEnergy(cluster.getParticleId(), rawE);
-    }
-    
-    /**
-     * Calculate the corrected energy and set on the cluster.
-     * @param cluster The input cluster.
-     */
-    public static void setCorrectedEnergy(BaseCluster cluster) {
-        double correctedEnergy = calculateCorrectedEnergy(cluster);
-        cluster.setEnergy(correctedEnergy);
-    }
-                            
-    /**
-     * Calculates energy correction based on cluster raw energy and particle type as per 
-     * <a href="https://misportal.jlab.org/mis/physics/hps_notes/index.cfm?note_year=2014">HPS Note 2014-001</a>
-     * @param pdg Particle id as per PDG
-     * @param rawEnergy Raw Energy of the cluster (sum of hits with shared hit distribution)
-     * @return Corrected Energy
-     */    
-    private static double computeCorrectedEnergy(int pdg, double rawEnergy) {
-        switch(pdg) {
-            case 11: 
-                // electron             
-                return computeCorrectedEnergy(rawEnergy, ELECTRON_ENERGY_A, ELECTRON_ENERGY_B, ELECTRON_ENERGY_C);
-            case -11: 
-                // positron
-                return computeCorrectedEnergy(rawEnergy, POSITRON_ENERGY_A, POSITRON_ENERGY_B, POSITRON_ENERGY_C);
-            case 22: 
-                // photon
-                return computeCorrectedEnergy(rawEnergy, PHOTON_ENERGY_A, PHOTON_ENERGY_B, PHOTON_ENERGY_C);
-            default: 
-                // unknown 
-                return rawEnergy;
+        //Eliminates corrections at outermost edges to negative cluster energies
+        //66 for positrons, 69 is safe for electrons and photons
+        if (r > 66) {r = 66;}
+                
+        switch (pdg) {
+        case 11:
+            // electron
+            return computeCorrectedEnergy(r, rawEnergy, par0_em, par1_em,
+                    par2_em);
+        case -11:
+            // positron
+            return computeCorrectedEnergy(r, rawEnergy, par0_ep, par1_ep,
+                    par2_ep);
+        case 22:
+            // photon
+            return computeCorrectedEnergy(r, rawEnergy, par0_p, par1_p, par2_p);
+        default:
+            // unknown
+            return rawEnergy;
         }
     }
-    
-    /**
-     * Calculates the energy correction to a cluster given the variables from the fit as per
-     * <a href="https://misportal.jlab.org/mis/physics/hps_notes/index.cfm?note_year=2014">HPS Note 2014-001</a>
-     * Note that this is correct as there is a typo in the formula print in the note. 
-     * @param rawEnergy Raw energy of the cluster
+
+    /**
+     * Calculates the energy correction to a cluster given the variables from
+     * the fit as per <a href=
+     * "https://misportal.jlab.org/mis/physics/hps_notes/index.cfm?note_year=2014"
+     * >HPS Note 2014-001</a> Note that this is correct as there is a typo in
+     * the formula print in the note.
+     * 
+     * @param rawEnergy
+     *            Raw energy of the cluster
      * @param A,B,C from fitting in note
      * @return Corrected Energy
-     */   
-    private static double computeCorrectedEnergy(double rawEnergy, double varA, double varB, double varC){
-        double corrEnergy = rawEnergy / (varA / rawEnergy + varB / (Math.sqrt(rawEnergy)) + varC);
+     */
+    private static double computeCorrectedEnergy(double y, double rawEnergy,
+            double varA, double varB[], double varC[]) {
+        int ii = y < varB[0] ? 2 : 5;
+        double corrEnergy = rawEnergy/ (varA / rawEnergy+ (varB[1] - varB[ii]* Math.exp(-(y - varB[ii + 1]) * varB[ii + 2]))/ (Math.sqrt(rawEnergy)) + 
+                (varC[1] - varC[ii]* Math.exp(-(y - varC[ii + 1]) * varC[ii + 2])));
         return corrEnergy;
-    }                   
+    }
 }

Modified: java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/ClusterPositionCorrection.java
 =============================================================================
--- java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/ClusterPositionCorrection.java	(original)
+++ java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/ClusterPositionCorrection.java	Wed Apr 27 11:11:32 2016
@@ -12,30 +12,29 @@
  * @author Jeremy McCormick <[log in to unmask]>
  */
 public final class ClusterPositionCorrection {
-           
+    //Parameterizations tested in MC using v3-fieldmap
+    //Nov 2015
+      
     // Variables for electron position corrections.
-    static final double ELECTRON_POS_A1 = -0.0005813;//0.0066;
-    static final double ELECTRON_POS_A2 = 0.005738;//-0.03;
-    static final double ELECTRON_POS_A3 = -0.0309;
-    static final double ELECTRON_POS_B1 = 0.02963;//0.028;
-    static final double ELECTRON_POS_B2 = -4.289;//-0.451;
-    static final double ELECTRON_POS_B3 = 4.596;//0.465;
+    static final double ELECTRON_POS_A1 = 0.004483;
+    static final double ELECTRON_POS_A2 = -0.02884;
+    static final double ELECTRON_POS_B1 = 0.6197;
+    static final double ELECTRON_POS_B2 = -2.279;
+    static final double ELECTRON_POS_B3 = 3.66;
     
     // Variables for positron position corrections.
-    static final double POSITRON_POS_A1 = -0.0006243;//0.0072;
-    static final double POSITRON_POS_A2 = 0.006799;//-0.031;
-    static final double POSITRON_POS_A3 = -0.03141;
-    static final double POSITRON_POS_B1 = 0.0869;//0.007;
-    static final double POSITRON_POS_B2 = 2.965;//0.342;
-    static final double POSITRON_POS_B3 = 1.653;//0.108;
+    static final double POSITRON_POS_A1 = 0.006887;
+    static final double POSITRON_POS_A2 = -0.03207;
+    static final double POSITRON_POS_B1 = -0.8048;
+    static final double POSITRON_POS_B2 = 0.9366;
+    static final double POSITRON_POS_B3 = 2.628;
     
     // Variables for photon position corrections.
-    static final double PHOTON_POS_A1 = -0.0006329;//0.005;
-    static final double PHOTON_POS_A2 = 0.00595;//-0.032;
-    static final double PHOTON_POS_A3 = -0.03563;
-    static final double PHOTON_POS_B1 = 0.06444;//0.011;
-    static final double PHOTON_POS_B2 = -0.5836;//-0.037;
-    static final double PHOTON_POS_B3 = 3.508;//0.294;
+    static final double PHOTON_POS_A1 = 0.005385;
+    static final double PHOTON_POS_A2 = -0.03562;
+    static final double PHOTON_POS_B1 = -0.1948;
+    static final double PHOTON_POS_B2 = -0.7991;
+    static final double PHOTON_POS_B3 = 3.797;
     
   
     public static double[] calculateCorrectedPosition(Cluster cluster) {
@@ -59,20 +58,20 @@
      * @param pdg Particle id as per PDG
      * @param xCl Calculated x centroid position of the cluster, uncorrected, at face
      * @param rawEnergy Raw energy of the cluster (sum of hits with shared hit distribution)
-     * @return Corrected x position
+     * @return the corrected x position
      */
     private static double computeCorrectedPosition(int pdg, double xPos, double rawEnergy) {
         //double xCl = xPos / 10.0;//convert to cm
         double xCorr;
         switch(pdg) {
             case 11: //Particle is electron        
-                xCorr = positionCorrection(xPos, rawEnergy, ELECTRON_POS_A1, ELECTRON_POS_A2, ELECTRON_POS_A3, ELECTRON_POS_B1, ELECTRON_POS_B2, ELECTRON_POS_B3);
+                xCorr = positionCorrection(xPos, rawEnergy, ELECTRON_POS_A1, ELECTRON_POS_A2, ELECTRON_POS_B1, ELECTRON_POS_B2, ELECTRON_POS_B3);
                 return xCorr;
             case -11:// Particle is positron       
-                xCorr = positionCorrection(xPos, rawEnergy, POSITRON_POS_A1, POSITRON_POS_A2, POSITRON_POS_A3, POSITRON_POS_B1, POSITRON_POS_B2, POSITRON_POS_B3);
+                xCorr = positionCorrection(xPos, rawEnergy, POSITRON_POS_A1, POSITRON_POS_A2, POSITRON_POS_B1, POSITRON_POS_B2, POSITRON_POS_B3);
                 return xCorr;
             case 22: // Particle is photon      
-                xCorr = positionCorrection(xPos, rawEnergy, PHOTON_POS_A1, PHOTON_POS_A2, PHOTON_POS_A3, PHOTON_POS_B1, PHOTON_POS_B2, PHOTON_POS_B3);
+                xCorr = positionCorrection(xPos, rawEnergy, PHOTON_POS_A1, PHOTON_POS_A2, PHOTON_POS_B1, PHOTON_POS_B2, PHOTON_POS_B3);
                 return xCorr;
             default: //Unknown 
                 xCorr = xPos;
@@ -92,10 +91,10 @@
     * @param varB1
     * @param varB2
     * @param varB3
-    * @return
+    * @return the cluster position correction
     */    
-    private static double positionCorrection(double xCl, double rawEnergy, double varA1, double varA2, double varA3, double varB1, double varB2, double varB3) {
+    private static double positionCorrection(double xCl, double rawEnergy, double varA1, double varA2, double varB1, double varB2, double varB3) {
         //return ((xCl - (varB1 * rawEnergy + varB2 / Math.sqrt(rawEnergy) + varB3))/(varA1 / Math.sqrt(rawEnergy) + varA2 + 1));
-    	return ((xCl - (varB1 * rawEnergy + varB2 / Math.sqrt(rawEnergy) + varB3))/(varA1 * rawEnergy + varA2 / Math.sqrt(rawEnergy) + varA3 + 1));
+        return ((xCl - (varB1 * rawEnergy + varB2 / Math.sqrt(rawEnergy) + varB3))/(varA1 / Math.sqrt(rawEnergy) + varA2 + 1));
     }
-}
+}

Modified: java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/ClusterUtilities.java
 =============================================================================
--- java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/ClusterUtilities.java	(original)
+++ java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/ClusterUtilities.java	Wed Apr 27 11:11:32 2016
@@ -199,7 +199,7 @@
     
     /**
      * Find the unique set of MCParticles that are referenced by the hits of the Cluster.
-     * @param clusters The input Cluster.
+     * @param cluster The input Cluster.
      * @return The set of unique MCParticles.
      */
     public static Set<MCParticle> findMCParticles(Cluster cluster) {  
@@ -334,7 +334,7 @@
      * Apply HPS-specific energy and position corrections to a list of clusters in place.
      * @param clusters The list of clusters.
      */
-    public static void applyCorrections(List<Cluster> clusters) {
+    public static void applyCorrections(HPSEcal3 ecal, List<Cluster> clusters) {
                 
         // Loop over the clusters.
         for (Cluster cluster : clusters) {
@@ -347,16 +347,16 @@
                 ClusterPositionCorrection.setCorrectedPosition(baseCluster);
             
                 // Apply PID based energy correction.
-                ClusterEnergyCorrection.setCorrectedEnergy(baseCluster);
-            }
-        }
-    }
-    
-    /**
-     * Apply HPS-specific energy and position corrections to a cluster.
-     * @param cluster The input cluster.
-     */
-    public static void applyCorrections(Cluster cluster) {
+                ClusterEnergyCorrection.setCorrectedEnergy(ecal, baseCluster);
+            }
+        }
+    }
+      
+    /**
+     * Apply HPS-specific energy and position corrections to a cluster without track information.
+     * @param cluster The input cluster.
+     */
+    public static void applyCorrections(HPSEcal3 ecal, Cluster cluster) {
                             
         if (cluster instanceof BaseCluster) {
             
@@ -366,7 +366,25 @@
             ClusterPositionCorrection.setCorrectedPosition(baseCluster);
             
             // Apply PID based energy correction.
-            ClusterEnergyCorrection.setCorrectedEnergy(baseCluster);
+            ClusterEnergyCorrection.setCorrectedEnergy(ecal, baseCluster);
+        }        
+    }   
+    
+    /**
+     * Apply HPS-specific energy and position corrections to a cluster with track information.
+     * @param cluster The input cluster.
+     */
+    public static void applyCorrections(HPSEcal3 ecal, Cluster cluster, double ypos) {
+        
+        if (cluster instanceof BaseCluster) {
+            
+            BaseCluster baseCluster = (BaseCluster)cluster;            
+                        
+            // Apply PID based position correction, which should happen before final energy correction.
+            ClusterPositionCorrection.setCorrectedPosition(baseCluster);
+            
+            // Apply PID based energy correction.
+            ClusterEnergyCorrection.setCorrectedEnergy(ecal, baseCluster, ypos);
         }        
     }    
         
@@ -410,7 +428,7 @@
     
     /**
      * Get the set of hits from a list of clusters.
-     * @param The input cluster list.
+     * @param clusters The input cluster list.
      * @return The list of hits from all the clusters.
      */
     public static Set<CalorimeterHit> getHits(List<Cluster> clusters) {

Modified: java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/ClustererFactory.java
 =============================================================================
--- java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/ClustererFactory.java	(original)
+++ java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/ClustererFactory.java	Wed Apr 27 11:11:32 2016
@@ -38,7 +38,7 @@
      * @param name The name of the clustering algorithm.
      * @param cuts The set of cuts (can be null).
      * @return The clustering algorithm.
-     * @throw IllegalArgumentException if there is no Clusterer found with name.
+     * @throws IllegalArgumentException if there is no Clusterer found with name.
      */
     public static Clusterer create(String name, double[] cuts) {
         Clusterer clusterer;

Modified: java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/CopyClusterCollectionDriver.java
 =============================================================================
--- java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/CopyClusterCollectionDriver.java	(original)
+++ java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/CopyClusterCollectionDriver.java	Wed Apr 27 11:11:32 2016
@@ -111,8 +111,8 @@
 
     /**
      * Set to <code>true</code> to store hits in the output clusters.
-     *
-     * @return <code>true</code> to store hits in the output clusters
+     * 
+     * @param storeHits <code>true</code> to store hits; <code>false</code> to not store hits
      */
     public void setStoreHits(final boolean storeHits) {
         this.storeHits = storeHits;

Modified: java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/GTPClusterDriver.java
 =============================================================================
--- java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/GTPClusterDriver.java	(original)
+++ java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/GTPClusterDriver.java	Wed Apr 27 11:11:32 2016
@@ -22,8 +22,8 @@
  * @see GTPClusterer
  */
 public class GTPClusterDriver extends ClusterDriver {
-	/** An instance of the clustering algorithm object for producing
-	 * cluster objects. */
+    /** An instance of the clustering algorithm object for producing
+     * cluster objects. */
     private final GTPClusterer gtp;
     
     /**
@@ -112,11 +112,11 @@
      */
     @Override
     public void setWriteClusterCollection(boolean state) {
-    	// Set the flag as appropriate with the superclass.
-    	super.setWriteClusterCollection(state);
-    	
-    	// Also tell the clusterer whether it should persist its hit
-    	// collection or not.
-    	gtp.setWriteHitCollection(state);
+        // Set the flag as appropriate with the superclass.
+        super.setWriteClusterCollection(state);
+        
+        // Also tell the clusterer whether it should persist its hit
+        // collection or not.
+        gtp.setWriteHitCollection(state);
     }
 }

Modified: java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/GTPClusterer.java
 =============================================================================
--- java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/GTPClusterer.java	(original)
+++ java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/GTPClusterer.java	Wed Apr 27 11:11:32 2016
@@ -124,7 +124,7 @@
      * forms a collection of <code>Cluster</code> objects according to
      * the GTP clustering algorithm.
      * @param event - The object containing event data.
-     * @param hitList - A list of <code>CalorimeterHit</code> objects
+     * @param hits - A list of <code>CalorimeterHit</code> objects
      * from which clusters should be formed.
      */
     public List<Cluster> createClusters(EventHeader event, List<CalorimeterHit> hits) {
@@ -146,24 +146,24 @@
         // stored in LCIO format properly, it needs to separately store
         // its clusters' hits in a collection.
         if(writeHitCollection) {
-        	// Create a set to store the hits so that each one may be
-        	// stored only once.
-	        Set<CalorimeterHit> hitSet = new HashSet<CalorimeterHit>();
-	        
-	        // Loop over all clusters and add their hits to the set.
-	        for(Cluster cluster : clusterList) {
-	        	for(CalorimeterHit hit : cluster.getCalorimeterHits()) {
-	        		hitSet.add(hit);
-	        	}
-	        }
-	        
-	        // Convert the set into a List object so that it can be stored
-	        // in LCIO.
-	        List<CalorimeterHit> clusterHits = new ArrayList<CalorimeterHit>(hitSet.size());
-	        clusterHits.addAll(hitSet);
-	        
-	        // Place the list of hits into the event stream.
-	        event.put("GTPHits", hits, CalorimeterHit.class, 0);
+            // Create a set to store the hits so that each one may be
+            // stored only once.
+            Set<CalorimeterHit> hitSet = new HashSet<CalorimeterHit>();
+            
+            // Loop over all clusters and add their hits to the set.
+            for(Cluster cluster : clusterList) {
+                for(CalorimeterHit hit : cluster.getCalorimeterHits()) {
+                    hitSet.add(hit);
+                }
+            }
+            
+            // Convert the set into a List object so that it can be stored
+            // in LCIO.
+            List<CalorimeterHit> clusterHits = new ArrayList<CalorimeterHit>(hitSet.size());
+            clusterHits.addAll(hitSet);
+            
+            // Place the list of hits into the event stream.
+            event.put("GTPHits", hits, CalorimeterHit.class, 0);
         }
         
         // Return the clusters.
@@ -260,7 +260,7 @@
      * should not.
      */
     void setVerbose(boolean verbose) {
-    	this.verbose = verbose;
+        this.verbose = verbose;
     }
     
     /**
@@ -271,7 +271,7 @@
      * persisted and <code>false</code> that they will not.
      */
     void setWriteHitCollection(boolean state) {
-    	writeHitCollection = state;
+        writeHitCollection = state;
     }
     
 /**
@@ -291,7 +291,7 @@
     
     // VERBOSE :: Print the cluster window.
     if(verbose) {
-    	// Print the event header.
+        // Print the event header.
         System.out.printf("%n%nEvent:%n");
         
         // Calculate some constants.
@@ -304,9 +304,9 @@
             CalorimeterHit hit = null;
             
             for(Entry<Long, CalorimeterHit> entry : bufferMap.entrySet()) {
-            	hit = entry.getValue();
-            	System.out.printf("\t(%3d, %3d) --> %.4f (%.4f)%n", hit.getIdentifierFieldValue("ix"),
-            			hit.getIdentifierFieldValue("iy"), hit.getCorrectedEnergy(), hit.getRawEnergy());
+                hit = entry.getValue();
+                System.out.printf("\t(%3d, %3d) --> %.4f (%.4f)%n", hit.getIdentifierFieldValue("ix"),
+                        hit.getIdentifierFieldValue("iy"), hit.getCorrectedEnergy(), hit.getRawEnergy());
             }
             
             bufferNum++;
@@ -327,8 +327,8 @@
         // VERBOSE :: Print the current cluster.
         if(verbose) {
             System.out.printf("Cluster Check:%n");
-        	System.out.printf("\t(%3d, %3d) --> %.4f%n", currentHit.getIdentifierFieldValue("ix"),
-        			currentHit.getIdentifierFieldValue("iy"), currentHit.getCorrectedEnergy());
+            System.out.printf("\t(%3d, %3d) --> %.4f%n", currentHit.getIdentifierFieldValue("ix"),
+                    currentHit.getIdentifierFieldValue("iy"), currentHit.getCorrectedEnergy());
         }
         
         // Store the energy of the current hit.
@@ -337,11 +337,11 @@
         // If the hit energy is lower than the minimum threshold,
         // then we immediately reject this hit as a possible cluster.
         if (currentEnergy < seedEnergyThreshold) {
-        	// VERBOSE :: Note the reason the potential seed was
-        	//            rejected.
-        	if(verbose) { System.out.printf("\tREJECT :: Does not exceed seed threshold %.4f.%n", seedEnergyThreshold); }
-        	
-        	// Skip to the next potential seed.
+            // VERBOSE :: Note the reason the potential seed was
+            //            rejected.
+            if(verbose) { System.out.printf("\tREJECT :: Does not exceed seed threshold %.4f.%n", seedEnergyThreshold); }
+            
+            // Skip to the next potential seed.
             continue seedLoop;
         }
         
@@ -368,16 +368,16 @@
                 // is larger than then original hit. If it is, we may
                 // stop the comparison because this is not a cluster.
                 if (bufferHitEnergy > currentEnergy) {
-                	// VERBOSE :: Output the reason the potential
-                	//            seed was rejected along with the
-                	//            hit that caused it.
-                	if(verbose) {
-                    	System.out.printf("\tREJECT :: Buffer hit surpasses hit energy.");
-                    	System.out.printf("\tBUFFER HIT :: (%3d, %3d) --> %.4f%n", bufferHit.getIdentifierFieldValue("ix"),
-                    			bufferHit.getIdentifierFieldValue("iy"), bufferHit.getCorrectedEnergy(), bufferHit.getRawEnergy());
-                	}
-                	
-                	// Skip to the next potential seed.
+                    // VERBOSE :: Output the reason the potential
+                    //            seed was rejected along with the
+                    //            hit that caused it.
+                    if(verbose) {
+                        System.out.printf("\tREJECT :: Buffer hit surpasses hit energy.");
+                        System.out.printf("\tBUFFER HIT :: (%3d, %3d) --> %.4f%n", bufferHit.getIdentifierFieldValue("ix"),
+                                bufferHit.getIdentifierFieldValue("iy"), bufferHit.getCorrectedEnergy(), bufferHit.getRawEnergy());
+                    }
+                    
+                    // Skip to the next potential seed.
                     continue seedLoop;
                 }
                 
@@ -403,16 +403,16 @@
                     // If it is, we may stop the comparison because this
                     // is not a cluster.
                     if (neighborHitEnergy > currentEnergy) {
-                    	// VERBOSE :: Output the reason the potential
-                    	//            seed was rejected along with the
-                    	//            hit that caused it.
-                    	if(verbose) {
-                        	System.out.printf("\tREJECT :: Buffer hit surpasses hit energy.%n");
-                        	System.out.printf("\tBUFFER HIT :: (%3d, %3d) --> %.4f%n", neighborHit.getIdentifierFieldValue("ix"),
-                        			neighborHit.getIdentifierFieldValue("iy"), neighborHit.getCorrectedEnergy(), neighborHit.getRawEnergy());
-                    	}
-                    	
-                    	// Skip to the next potential seed.
+                        // VERBOSE :: Output the reason the potential
+                        //            seed was rejected along with the
+                        //            hit that caused it.
+                        if(verbose) {
+                            System.out.printf("\tREJECT :: Buffer hit surpasses hit energy.%n");
+                            System.out.printf("\tBUFFER HIT :: (%3d, %3d) --> %.4f%n", neighborHit.getIdentifierFieldValue("ix"),
+                                    neighborHit.getIdentifierFieldValue("iy"), neighborHit.getCorrectedEnergy(), neighborHit.getRawEnergy());
+                        }
+                        
+                        // Skip to the next potential seed.
                         continue seedLoop;
                     }
                     
@@ -436,10 +436,10 @@
         if(verbose) {
             System.out.printf("Cluster added.%n");
             System.out.printf("\t(%3d, %3d) --> %.4f GeV --> %d hits%n", cluster.getCalorimeterHits().get(0).getIdentifierFieldValue("ix"),
-            		cluster.getCalorimeterHits().get(0).getIdentifierFieldValue("iy"), cluster.getEnergy(), cluster.getCalorimeterHits().size());
+                    cluster.getCalorimeterHits().get(0).getIdentifierFieldValue("iy"), cluster.getEnergy(), cluster.getCalorimeterHits().size());
             for(CalorimeterHit hit : cluster.getCalorimeterHits()) {
-            	System.out.printf("\t\tCLUSTER HIT :: (%3d, %3d) --> %.4f%n", hit.getIdentifierFieldValue("ix"),
-            			hit.getIdentifierFieldValue("iy"), hit.getCorrectedEnergy(), hit.getRawEnergy());
+                System.out.printf("\t\tCLUSTER HIT :: (%3d, %3d) --> %.4f%n", hit.getIdentifierFieldValue("ix"),
+                        hit.getIdentifierFieldValue("iy"), hit.getCorrectedEnergy(), hit.getRawEnergy());
             }
         }
     }

Modified: java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/GTPOnlineClusterDriver.java
 =============================================================================
--- java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/GTPOnlineClusterDriver.java	(original)
+++ java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/GTPOnlineClusterDriver.java	Wed Apr 27 11:11:32 2016
@@ -39,8 +39,8 @@
  * @see org.hps.record.daqconfig.DAQConfigDriver
  */
 public class GTPOnlineClusterDriver extends ClusterDriver {
-	/** An instance of the clustering algorithm object for producing
-	 * cluster objects. */
+    /** An instance of the clustering algorithm object for producing
+     * cluster objects. */
     private final GTPOnlineClusterer gtp;
     /** Indicates whether the <code>ConfigurationManager</code> object
      * should be used for clustering settings or not. */
@@ -53,29 +53,29 @@
      * @see GTPOnlineClusterer
      */
     public GTPOnlineClusterDriver() {
-    	// Instantiate the clusterer.
+        // Instantiate the clusterer.
         clusterer = ClustererFactory.create("GTPOnlineClusterer");
         gtp = (GTPOnlineClusterer) clusterer;
         
         // Track the DAQ configuration status.
         ConfigurationManager.addActionListener(new ActionListener() {
-			@Override
-			public void actionPerformed(ActionEvent e) {
-				// If DAQ configuration settings should be used, then
-				// update the clusterer.
-				if(useDAQConfig) {
-					// Get the GTP settings.
-					GTPConfig config = ConfigurationManager.getInstance().getGTPConfig();
-					
-					// Send the DAQ configuration settings to the clusterer.
-					gtp.setSeedLowThreshold(config.getSeedEnergyCutConfig().getLowerBound());
-					gtp.setWindowAfter(config.getTimeWindowAfter());
-					gtp.setWindowBefore(config.getTimeWindowBefore());
-					
-					// Print the updated settings.
-					logSettings();
-				}
-			}
+            @Override
+            public void actionPerformed(ActionEvent e) {
+                // If DAQ configuration settings should be used, then
+                // update the clusterer.
+                if(useDAQConfig) {
+                    // Get the GTP settings.
+                    GTPConfig config = ConfigurationManager.getInstance().getGTPConfig();
+                    
+                    // Send the DAQ configuration settings to the clusterer.
+                    gtp.setSeedLowThreshold(config.getSeedEnergyCutConfig().getLowerBound());
+                    gtp.setWindowAfter(config.getTimeWindowAfter());
+                    gtp.setWindowBefore(config.getTimeWindowBefore());
+                    
+                    // Print the updated settings.
+                    logSettings();
+                }
+            }
         });
     }
     
@@ -90,11 +90,11 @@
      */
     @Override
     public void process(EventHeader event) {
-    	// Only process an event if either the DAQ configuration is not
-    	// in use or if it has been initialized.
-    	if((useDAQConfig && ConfigurationManager.isInitialized()) || !useDAQConfig) {
-    		super.process(event);
-    	}
+        // Only process an event if either the DAQ configuration is not
+        // in use or if it has been initialized.
+        if((useDAQConfig && ConfigurationManager.isInitialized()) || !useDAQConfig) {
+            super.process(event);
+        }
     }
     
     /**
@@ -103,8 +103,8 @@
      */
     @Override
     public void startOfData() {
-    	// VERBOSE :: Output the driver settings.
-    	if(gtp.isVerbose()) { logSettings(); }
+        // VERBOSE :: Output the driver settings.
+        if(gtp.isVerbose()) { logSettings(); }
     }
     
     /**
@@ -168,23 +168,23 @@
      * @see org.hps.record.daqconfig.DAQConfigDriver
      */
     public void setUseDAQConfig(boolean state) {
-    	useDAQConfig = state;
+        useDAQConfig = state;
     }
     
     /**
      * Outputs the current GTP settings to the terminal.
      */
     private void logSettings() {
-		// Print the cluster driver header.
-		System.out.println();
-		System.out.println();
-		System.out.println("======================================================================");
-		System.out.println("=== GTP Readout Clusterer Settings ===================================");
-		System.out.println("======================================================================");
-		
-		// Output the driver settings.
-		System.out.printf("Seed Energy Threshold :: %.3f GeV%n", gtp.getSeedLowThreshold());
-		System.out.printf("Time Window (Before)  :: %.0f ns%n", gtp.getWindowBefore());
-		System.out.printf("Time Window (After)   :: %.0f ns%n", gtp.getWindowAfter());
+        // Print the cluster driver header.
+        System.out.println();
+        System.out.println();
+        System.out.println("======================================================================");
+        System.out.println("=== GTP Readout Clusterer Settings ===================================");
+        System.out.println("======================================================================");
+        
+        // Output the driver settings.
+        System.out.printf("Seed Energy Threshold :: %.3f GeV%n", gtp.getSeedLowThreshold());
+        System.out.printf("Time Window (Before)  :: %.0f ns%n", gtp.getWindowBefore());
+        System.out.printf("Time Window (After)   :: %.0f ns%n", gtp.getWindowAfter());
     }
 }

Modified: java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/GTPOnlineClusterer.java
 =============================================================================
--- java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/GTPOnlineClusterer.java	(original)
+++ java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/GTPOnlineClusterer.java	Wed Apr 27 11:11:32 2016
@@ -69,10 +69,10 @@
  * @see GTPClusterer
  */
 public class GTPOnlineClusterer extends AbstractClusterer {
-	/**
-	 * The length of the temporal window for inclusing clusters that
-	 * occur before the seed hit.
-	 */
+    /**
+     * The length of the temporal window for inclusing clusters that
+     * occur before the seed hit.
+     */
     private double timeBefore = 4;
     
     /**
@@ -102,7 +102,7 @@
     
     // Diagnostic plots.
     private AIDA aida = AIDA.defaultInstance();
-    private IHistogram1D hitEnergy = aida.histogram1D("GTP(O) Cluster Plot/Hit Energy Distribution", 256, -1.0, 2.2);
+    private IHistogram1D hitEnergy = aida.histogram1D("GTP(O) Cluster Plots/Hit Energy Distribution", 256, -1.0, 2.2);
     private IHistogram1D clusterSeedEnergy = aida.histogram1D("GTP(O) Cluster Plots/Cluster Seed Energy Distribution", 176, 0.0, 2.2);
     private IHistogram1D clusterHitCount = aida.histogram1D("GTP(O) Cluster Plots/Cluster Hit Count Distribution", 9, 1, 10);
     private IHistogram1D clusterTotalEnergy = aida.histogram1D("GTP(O) Cluster Plots/Cluster Total Energy Distribution", 176, 0.0, 2.2);
@@ -128,29 +128,29 @@
      */
     @Override
     public List<Cluster> createClusters(EventHeader event, List<CalorimeterHit> hitList) {
-    	// VERBOSE :: Print the driver header.
-    	if(verbose) {
-    		System.out.println();
-    		System.out.println();
-    		System.out.println("======================================================================");
-    		System.out.println("=== GTP Readout Clusterer ============================================");
-    		System.out.println("======================================================================");
-    		
-    		// Sort the hits by x-index and then by y-index.
-        	Collections.sort(hitList, new Comparator<CalorimeterHit>() {
-				@Override
-				public int compare(CalorimeterHit firstHit, CalorimeterHit secondHit) {
-					int[] ix = { firstHit.getIdentifierFieldValue("ix"), secondHit.getIdentifierFieldValue("ix") };
-					if(ix[0] != ix[1]) { return Integer.compare(ix[0], ix[1]); }
-					else {
-						int iy[] = { firstHit.getIdentifierFieldValue("iy"), secondHit.getIdentifierFieldValue("iy") };
-						return Integer.compare(iy[0], iy[1]);
-					}
-				}
-        	});
-        	
-        	// Print the hit collection.
-        	System.out.println("Event Hit Collection:");
+        // VERBOSE :: Print the driver header.
+        if(verbose) {
+            System.out.println();
+            System.out.println();
+            System.out.println("======================================================================");
+            System.out.println("=== GTP Readout Clusterer ============================================");
+            System.out.println("======================================================================");
+            
+            // Sort the hits by x-index and then by y-index.
+            Collections.sort(hitList, new Comparator<CalorimeterHit>() {
+                @Override
+                public int compare(CalorimeterHit firstHit, CalorimeterHit secondHit) {
+                    int[] ix = { firstHit.getIdentifierFieldValue("ix"), secondHit.getIdentifierFieldValue("ix") };
+                    if(ix[0] != ix[1]) { return Integer.compare(ix[0], ix[1]); }
+                    else {
+                        int iy[] = { firstHit.getIdentifierFieldValue("iy"), secondHit.getIdentifierFieldValue("iy") };
+                        return Integer.compare(iy[0], iy[1]);
+                    }
+                }
+            });
+            
+            // Print the hit collection.
+            System.out.println("Event Hit Collection:");
             for(CalorimeterHit hit : hitList) {
                 int ix = hit.getIdentifierFieldValue("ix");
                 int iy = hit.getIdentifierFieldValue("iy");
@@ -161,7 +161,7 @@
             }
             System.out.println();
         }
-    	
+        
         // Track the valid clusters.
         List<Cluster> clusterList = new ArrayList<Cluster>();
         
@@ -183,10 +183,10 @@
         // Iterate over each hit and see if it qualifies as a seed hit.
         seedLoop:
             for(CalorimeterHit seed : hitList) {
-            	// Put the hit energy into the hit energy distribution.
-            	hitEnergy.fill(seed.getCorrectedEnergy());
-            	hitDistribution.fill(seed.getIdentifierFieldValue("ix"), seed.getIdentifierFieldValue("iy"));
-            	
+                // Put the hit energy into the hit energy distribution.
+                hitEnergy.fill(seed.getCorrectedEnergy());
+                hitDistribution.fill(seed.getIdentifierFieldValue("ix"), seed.getIdentifierFieldValue("iy"));
+                
                 // Check whether the potential seed passes the seed
                 // energy cut.
                 if(seed.getCorrectedEnergy() < seedThreshold) {
@@ -204,16 +204,16 @@
                 // energies.
                 hitLoop:
                 for(CalorimeterHit hit : hitList) {
-                	// Negative energy hits are never valid. Skip them.
-                	if(hit.getCorrectedEnergy() < 0) {
-                		continue hitLoop;
-                	}
-                	
-                	// Do not compare the potential seed hit to itself.
-                	if(hit == seed) {
-                		continue hitLoop;
-                	}
-                	
+                    // Negative energy hits are never valid. Skip them.
+                    if(hit.getCorrectedEnergy() < 0) {
+                        continue hitLoop;
+                    }
+                    
+                    // Do not compare the potential seed hit to itself.
+                    if(hit == seed) {
+                        continue hitLoop;
+                    }
+                    
                     // Check if the hit is within the spatiotemporal
                     // clustering window.
                     if(withinTimeVerificationWindow(seed, hit) && withinSpatialWindow(seed, hit)) {
@@ -246,25 +246,25 @@
                 clusterTotalEnergy.fill(protoCluster.getEnergy());
                 clusterHitCount.fill(protoCluster.getCalorimeterHits().size());
                 clusterDistribution.fill(protoCluster.getCalorimeterHits().get(0).getIdentifierFieldValue("ix"),
-                		protoCluster.getCalorimeterHits().get(0).getIdentifierFieldValue("iy"));
+                        protoCluster.getCalorimeterHits().get(0).getIdentifierFieldValue("iy"));
                 
                 // Determine how much energy in the cluster is negative
                 // and how is positive.
                 double nenergy = 0.0;
                 double penergy = 0.0;
                 for(CalorimeterHit hit : protoCluster.getCalorimeterHits()) {
-                	if(hit.getCorrectedEnergy() > 0) { penergy += hit.getCorrectedEnergy(); }
-                	else { nenergy += hit.getCorrectedEnergy(); }
+                    if(hit.getCorrectedEnergy() > 0) { penergy += hit.getCorrectedEnergy(); }
+                    else { nenergy += hit.getCorrectedEnergy(); }
                 }
                 energyDistribution.fill(Math.abs(nenergy) / (penergy + Math.abs(nenergy)));
             }
         
         // VERBOSE :: Print out all the clusters in the event.
         if(verbose) {
-        	// Print the clusters.
-        	System.out.println("Event Cluster Collection:");
+            // Print the clusters.
+            System.out.println("Event Cluster Collection:");
             for(Cluster cluster : clusterList) {
-            	// Output basic cluster positional and energy data.
+                // Output basic cluster positional and energy data.
                 CalorimeterHit seedHit = cluster.getCalorimeterHits().get(0);
                 int ix = seedHit.getIdentifierFieldValue("ix");
                 int iy = seedHit.getIdentifierFieldValue("iy");
@@ -281,7 +281,7 @@
                     System.out.printf("\t\tCompHit --> %.3f GeV at (%3d, %3d) and at t = %.2f%n", henergy, hix, hiy, htime);
                 }
             }
-        	System.out.println();
+            System.out.println();
         }
         
         // VERBOSE :: Print a new line.
@@ -366,11 +366,11 @@
      * the seed hit in clock cycles.
      */
     void setWindowBefore(int cyclesBefore) {
-    	// The cluster window can not be negative.
-    	if(cyclesBefore < 0) { cyclesBefore = 0; }
-    	
-    	// Convert the window to nanoseconds and set the two time
-    	// windows appropriately.
+        // The cluster window can not be negative.
+        if(cyclesBefore < 0) { cyclesBefore = 0; }
+        
+        // Convert the window to nanoseconds and set the two time
+        // windows appropriately.
         timeBefore = cyclesBefore * 4;
         timeWindow = Math.max(timeBefore, timeAfter);
     }
@@ -384,11 +384,11 @@
      * the seed hit in clock cycles.
      */
     void setWindowAfter(int cyclesAfter) {
-    	// The cluster window can not be negative.
-    	if(cyclesAfter < 0) { cyclesAfter = 0; }
-    	
-    	// Convert the window to nanoseconds and set the two time
-    	// windows appropriately.
+        // The cluster window can not be negative.
+        if(cyclesAfter < 0) { cyclesAfter = 0; }
+        
+        // Convert the window to nanoseconds and set the two time
+        // windows appropriately.
         timeAfter = cyclesAfter * 4;
         timeWindow = Math.max(timeBefore, timeAfter);
     }
@@ -494,9 +494,9 @@
             // considered to be adjacent to ix = -1 rather than the
             // expected ix = 0. (ix = 0 does not exist.)
             else {
-            	// ix = -1 is adjacent to ix = 1 and vice versa.
+                // ix = -1 is adjacent to ix = 1 and vice versa.
                 if((six == -1 && hix == 1) || (six == 1 && hix == -1)) {
-                	return true;
+                    return true;
                 }
                 
                 // Any other combination that reaches this point is not
@@ -561,4 +561,4 @@
         // treated as within time.
         else { return false; }
     }
-}
+}

Modified: java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/ReconClusterer.java
 =============================================================================
--- java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/ReconClusterer.java	(original)
+++ java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/ReconClusterer.java	Wed Apr 27 11:11:32 2016
@@ -289,7 +289,7 @@
                 // If the neighboring crystal exists and is not already
                 // in a cluster, add it to the list of neighboring hits.
                 if (secondaryNeighborHit != null && !hitToSeed.containsKey(secondaryNeighborHit)
-                		&& hitList.contains(secondaryNeighborHit)) {
+                        && hitList.contains(secondaryNeighborHit)) {
                     secondaryNeighborHits.add(secondaryNeighborHit);
                 }
             }
@@ -325,7 +325,7 @@
                 // If it exists, add it to the neighboring hit list.
 
                 if (clusteredNeighborHit != null && hitToSeed.get(clusteredNeighborHit) != null
-                		&& hitList.contains(clusteredNeighborHit)) {
+                        && hitList.contains(clusteredNeighborHit)) {
                     clusteredNeighborHits.add(clusteredNeighborHit);
                 }
             }
@@ -383,32 +383,32 @@
             
             // Consider time cut-is this hit in same time window as seed?
             if (useTimeCut){
-            	if(Math.abs(ihit.getTime() - iseed.getTime()) < timeWindow)
-            	{	
-            		icluster.addHit(ihit);
-            	}
+                if(Math.abs(ihit.getTime() - iseed.getTime()) < timeWindow)
+                {   
+                    icluster.addHit(ihit);
+                }
             } // end of using time cut
             else {icluster.addHit(ihit);}           
         }
 
         // Add common hits
         for (Map.Entry<CalorimeterHit, List<CalorimeterHit>> commHit : commonHits.entrySet()) {
-        	// Check that the common hit is in both time windows to their clusters
-        	CalorimeterHit seedA = commHit.getValue().get(0);
+            // Check that the common hit is in both time windows to their clusters
+            CalorimeterHit seedA = commHit.getValue().get(0);
             CalorimeterHit seedB = commHit.getValue().get(1);
-        	
+            
             boolean inTimeWithA = false;
             boolean inTimeWithB = false;
-        	// In time window with seedA?
+            // In time window with seedA?
             if (Math.abs(commHit.getKey().getTime() - seedA.getTime()) < timeWindow){
-            	inTimeWithA = true;
+                inTimeWithA = true;
             }
             
             // In time window with seedB?
             if (Math.abs(commHit.getKey().getTime() - seedB.getTime()) < timeWindow){
-            	inTimeWithB = true;
-            }
-                    	
+                inTimeWithB = true;
+            }
+                        
             double eclusterA = seedToCluster.get(seedA).getEnergy();
             double eclusterB = seedToCluster.get(seedB).getEnergy();
             double fractionA = eclusterA / (eclusterA + eclusterB);
@@ -420,25 +420,25 @@
             BaseCluster clusterB = seedToCluster.get(seedB);
 
             if (useTimeCut){
-            	// Do this if the hit is in both cluster's windows
-            	if (inTimeWithA && inTimeWithB){
-            		clusterA.addHit(commHit.getKey(), hitcontributionA);
-            		clusterB.addHit(commHit.getKey(), hitcontributionB);
-            	}
+                // Do this if the hit is in both cluster's windows
+                if (inTimeWithA && inTimeWithB){
+                    clusterA.addHit(commHit.getKey(), hitcontributionA);
+                    clusterB.addHit(commHit.getKey(), hitcontributionB);
+                }
             
-            	//If the hit is only in 1 cluster's window, add the full contribution
-            	else if(inTimeWithA ^ inTimeWithB){
-            		if(inTimeWithA){
-            			clusterA.addHit(commHit.getKey());
-            		}
-            		else{
-            			clusterB.addHit(commHit.getKey());
-            		}
-            	}
+                //If the hit is only in 1 cluster's window, add the full contribution
+                else if(inTimeWithA ^ inTimeWithB){
+                    if(inTimeWithA){
+                        clusterA.addHit(commHit.getKey());
+                    }
+                    else{
+                        clusterB.addHit(commHit.getKey());
+                    }
+                }
             } // end of using time cut
             else{
-            	clusterA.addHit(commHit.getKey(), hitcontributionA);
-        		clusterB.addHit(commHit.getKey(), hitcontributionB);           	
+                clusterA.addHit(commHit.getKey(), hitcontributionA);
+                clusterB.addHit(commHit.getKey(), hitcontributionB);            
             }
             
         }

Modified: java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/SimpleCosmicClusterer.java
 =============================================================================
--- java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/SimpleCosmicClusterer.java	(original)
+++ java/branches/HPSJAVA-409/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/SimpleCosmicClusterer.java	Wed Apr 27 11:11:32 2016
@@ -125,9 +125,8 @@
     }    
 
     /**
-     * This method takes a list of potential cluster hits and applies selection cuts,
-     * returning a new list that has the hit lists which did not pass the cuts removed.
-     * @param clusteredHitLists The input hit lists. 
+     * Apply selection cuts to cluster list and return filtered list.
+     * @param clusterList The input hit lists. 
      * @return The hit lists that passed the cuts.
      */
     protected List<Cluster> applyCuts(List<Cluster> clusterList) {

Modified: java/branches/HPSJAVA-409/evio/pom.xml
 =============================================================================
--- java/branches/HPSJAVA-409/evio/pom.xml	(original)
+++ java/branches/HPSJAVA-409/evio/pom.xml	Wed Apr 27 11:11:32 2016
@@ -8,7 +8,7 @@
         <groupId>org.hps</groupId>
         <artifactId>hps-parent</artifactId>
         <relativePath>../parent/pom.xml</relativePath>
-        <version>3.4.2-SNAPSHOT</version>
+        <version>3.9-SNAPSHOT</version>
     </parent>
     <scm>
         <url>http://java.freehep.org/svn/repos/hps/list/java/trunk/evio/</url>

Modified: java/branches/HPSJAVA-409/evio/src/main/java/org/hps/evio/AbstractSvtEvioReader.java
 =============================================================================
--- java/branches/HPSJAVA-409/evio/src/main/java/org/hps/evio/AbstractSvtEvioReader.java	(original)
+++ java/branches/HPSJAVA-409/evio/src/main/java/org/hps/evio/AbstractSvtEvioReader.java	Wed Apr 27 11:11:32 2016
@@ -12,12 +12,7 @@
 import org.hps.record.svt.SvtEvioExceptions.SvtEvioReaderException;
 import org.hps.util.Pair;
 import org.jlab.coda.jevio.BaseStructure;
-import org.jlab.coda.jevio.DataType;
 import org.jlab.coda.jevio.EvioEvent;
-import org.jlab.coda.jevio.IEvioFilter;
-import org.jlab.coda.jevio.IEvioStructure;
-import org.jlab.coda.jevio.StructureFinder;
-import org.jlab.coda.jevio.StructureType;
 import org.lcsim.detector.tracker.silicon.HpsSiSensor;
 import org.lcsim.event.EventHeader;
 import org.lcsim.event.RawTrackerHit;
@@ -31,7 +26,6 @@
  * 
  * @author Omar Moreno <[log in to unmask]>
  * @author Per Hansson Adrian <[log in to unmask]>
- * @date November 20, 2014
  *
  */
 public abstract class AbstractSvtEvioReader extends EvioReader {
@@ -39,7 +33,7 @@
     public static final String SVT_HEADER_COLLECTION_NAME = "SvtHeaders";
     
     // Initialize the logger
-    public static Logger LOGGER = Logger.getLogger(AbstractSvtEvioReader.class.getPackage().getName());
+    public static final Logger LOGGER = Logger.getLogger(AbstractSvtEvioReader.class.getPackage().getName());
     
     // A Map from DAQ pair (FPGA/Hybrid or FEB ID/FEB Hybrid ID) to the
     // corresponding sensor
@@ -47,16 +41,11 @@
                   HpsSiSensor /* Sensor */> daqPairToSensor 
                       = new HashMap<Pair<Integer, Integer>, HpsSiSensor>();
     
-    // A collection of banks that should be processed after all hits have been made
-    protected List<BaseStructure> eventBanks = new ArrayList<BaseStructure>();
-
     // Flag indicating whether the DAQ map has been setup
     protected boolean isDaqMapSetup = false;
 
     // Collections and names
     private static final String SVT_HIT_COLLECTION_NAME = "SVTRawTrackerHits";
-    List<RawTrackerHit> rawHits = new ArrayList<RawTrackerHit>();
-    List<SvtHeaderDataInfo> headers = new ArrayList<SvtHeaderDataInfo>();
 
     // Constants
     private static final String SUBDETECTOR_NAME = "Tracker";
@@ -76,6 +65,19 @@
      */
     abstract protected int getMaxRocBankTag(); 
     
+    /**
+     *  Get the minimum SVT ROC bank tag in the event.
+     *
+     *  @return Minimum SVT ROC bank tag
+     */
+    abstract protected int getMinDataBankTag(); 
+    
+    /**
+     *  Get the maximum SVT ROC bank tag in the event.
+     *
+     *  @return Maximum SVT ROC bank tag
+     */
+    abstract protected int getMaxDataBankTag(); 
 
     /**
      *  Get the SVT ROC bank number of the bank encapsulating the SVT samples.
@@ -116,14 +118,6 @@
      */
     abstract protected HpsSiSensor getSensor(int[] data);
 
-    /**
-     *  Check whether a data bank is valid i.e. contains SVT samples only.
-     * 
-     *  @param dataBank - An EVIO bank containing integer data
-     *  @return true if the bank is valid, false otherwise
-     */
-    abstract protected boolean isValidDataBank(BaseStructure dataBank);
-    
     /**
      * Check whether the samples are valid
      * 
@@ -154,125 +148,88 @@
      *  @return true if the raw hits were created successfully, false otherwise 
      * @throws SvtEvioReaderException 
      */
+    @Override
     public boolean makeHits(EvioEvent event, EventHeader lcsimEvent) throws SvtEvioReaderException {
 
         LOGGER.finest("Physics Event: " + event.toString());
         
-        // Retrieve the ROC banks encapsulated by the physics bank.  The ROC
+        // Retrieve the data banks encapsulated by the physics bank.  The ROC
         // bank range is set in the subclass.
-        List<BaseStructure> rocBanks = new ArrayList<BaseStructure>();
-        for (int rocBankTag = this.getMinRocBankTag(); 
-                rocBankTag <= this.getMaxRocBankTag(); rocBankTag++) { 
-            
-            LOGGER.finest("Retrieving ROC bank: " + rocBankTag);
-            List<BaseStructure> matchingRocBanks = this.getMatchingBanks(event, rocBankTag);
-            if (matchingRocBanks == null) { 
-                LOGGER.finest("ROC bank " + rocBankTag + " was not found!");
-                continue;
-            }
-            rocBanks.addAll(matchingRocBanks);
-        }
-        LOGGER.finest("Total ROC banks found: " + rocBanks.size());
-        
-        // Return false if ROC banks weren't found
-        if (rocBanks.isEmpty()) return false;  
+        List<BaseStructure> dataBanks = SvtEvioUtils.getDataBanks(event, this.getMinRocBankTag(), this.getMaxRocBankTag(), this.getMinDataBankTag(), this.getMaxDataBankTag());
+        
+        // Return false if data banks weren't found
+        if (dataBanks.isEmpty()) return false;  
     
         // Setup the DAQ map if it's not setup
         if (!this.isDaqMapSetup)
             this.setupDaqMap(lcsimEvent.getDetector().getSubdetector(
                     SUBDETECTOR_NAME));
 
-        // Clear the list of raw tracker hits
-        rawHits.clear();
-        
-        // Clear the list of headers
-        headers.clear();
-
-        // Loop over the SVT ROC banks and process all samples
-        for (BaseStructure rocBank : rocBanks) { 
-            
-            LOGGER.finest("ROC bank: " + rocBank.toString());
-            
-            LOGGER.finest("Processing ROC bank " + rocBank.getHeader().getTag());
-            
-            // If the ROC bank doesn't contain any data, raise an exception
-            if (rocBank.getChildCount() == 0) { 
-                throw new SvtEvioReaderException("[ " + this.getClass().getSimpleName() 
-                                + " ]: SVT bank doesn't contain any data banks.");
+        List<RawTrackerHit> rawHits = new ArrayList<RawTrackerHit>();
+        List<SvtHeaderDataInfo> headers = new ArrayList<SvtHeaderDataInfo>();
+
+        LOGGER.finest("Total data banks found: " + dataBanks.size());
+
+            // Loop over all of the data banks contained by the ROC banks and 
+        // processed them
+        for (BaseStructure dataBank : dataBanks) {
+
+            LOGGER.finest("Processing data bank: " + dataBank.toString());
+
+            // Get the int data encapsulated by the data bank
+            int[] data = dataBank.getIntData();
+            LOGGER.finest("Total number of integers contained by the data bank: " + data.length);
+
+            // Check that a complete set of samples exist
+            int sampleCount = data.length - this.getDataHeaderLength()
+                    - this.getDataTailLength();
+            LOGGER.finest("Total number of  samples: " + sampleCount);
+            if (sampleCount % 4 != 0) {
+                throw new SvtEvioReaderException("[ "
+                        + this.getClass().getSimpleName()
+                        + " ]: Size of samples array is not divisible by 4");
             }
-            
-            // Get the data banks containing the SVT samples.  
-            List<BaseStructure> dataBanks = rocBank.getChildren(); 
-            LOGGER.finest("Total data banks found: " + dataBanks.size());
-            
-            // Loop over all of the data banks contained by the ROC banks and 
-            // processed them
-            for (BaseStructure dataBank : dataBanks) { 
-        
-                LOGGER.finest("Processing data bank: " + dataBank.toString());
-                
-                // Check that the bank is valid
-                if (!this.isValidDataBank(dataBank)) continue;
-                
-                // Get the int data encapsulated by the data bank
-                int[] data = dataBank.getIntData();
-                LOGGER.finest("Total number of integers contained by the data bank: " + data.length);
-        
-                // Check that a complete set of samples exist
-                int sampleCount = data.length - this.getDataHeaderLength()
-                        - this.getDataTailLength();
-                LOGGER.finest("Total number of  samples: " + sampleCount);
-                if (sampleCount % 4 != 0) {
-                    throw new SvtEvioReaderException("[ "
-                            + this.getClass().getSimpleName()
-                            + " ]: Size of samples array is not divisible by 4");
-                }
-                
-                // extract header and tail information
-                SvtHeaderDataInfo headerData = this.extractSvtHeader(dataBank.getHeader().getNumber(), data);
-                
-                // Check that the multisample count is consistent
-                this.checkSvtSampleCount(sampleCount, headerData);
-                
-                // Add header to list
-                headers.add(headerData);
-                
-                
-                // Store the multisample headers
-                // Note that the length is not known but can't be longer than the multisample count
-                // in other words the data can be only header multisamples for example.
-                int multisampleHeaderData[] = new int[sampleCount];
-                int multisampleHeaderIndex = 0;
-
-                LOGGER.finest("sampleCount " + sampleCount);
-                
-                // Loop through all of the samples and make hits
-                for (int samplesN = 0; samplesN < sampleCount; samplesN += 4) {
-                    
-                    int[] samples = new int[4];
-                    System.arraycopy(data, this.getDataHeaderLength() + samplesN, samples, 0, samples.length);
-                    
-                    LOGGER.finest("samplesN " + samplesN + " multisampleHeaderCount " + multisampleHeaderIndex);
-                    if(SvtEvioUtils.isMultisampleHeader(samples))
-                        LOGGER.finest("this is a header multisample for apv " + SvtEvioUtils.getApvFromMultiSample(samples) + " ch " + SvtEvioUtils.getChannelNumber(samples));
-                    else 
-                        LOGGER.finest("this is a data multisample for apv " + SvtEvioUtils.getApvFromMultiSample(samples) + " ch " + SvtEvioUtils.getChannelNumber(samples));
-                    
-                    
+
+            // extract header and tail information
+            SvtHeaderDataInfo headerData = this.extractSvtHeader(dataBank.getHeader().getNumber(), data);
+
+            // Check that the multisample count is consistent
+            this.checkSvtSampleCount(sampleCount, headerData);
+
+            // Add header to list
+            headers.add(headerData);
+
+            // Store the multisample headers
+            // Note that the length is not known but can't be longer than the multisample count
+            // in other words the data can be only header multisamples for example.
+            int multisampleHeaderData[] = new int[sampleCount];
+            int multisampleHeaderIndex = 0;
+
+            LOGGER.finest("sampleCount " + sampleCount);
+
+            List<int[]> multisampleList = SvtEvioUtils.getMultisamples(data, sampleCount, this.getDataHeaderLength());
+            // Loop through all of the samples and make hits
+            for (int[] samples:multisampleList) {
+                if (SvtEvioUtils.isMultisampleHeader(samples)) {
+                    LOGGER.finest("this is a header multisample for apv " + SvtEvioUtils.getApvFromMultiSample(samples) + " ch " + SvtEvioUtils.getChannelNumber(samples));
                     // Extract data words from multisample header and update index
                     multisampleHeaderIndex += this.extractMultisampleHeaderData(samples, multisampleHeaderIndex, multisampleHeaderData);
-                    
-                    // If a set of samples is associated with an APV header or tail, skip it
-                    if (!this.isValidSampleSet(samples)) continue;
-                    rawHits.add(this.makeHit(samples));
+                } else {
+                    LOGGER.finest("this is a data multisample for apv " + SvtEvioUtils.getApvFromMultiSample(samples) + " ch " + SvtEvioUtils.getChannelNumber(samples));
                 }
-                
-                LOGGER.finest("got " +  multisampleHeaderIndex + " multisampleHeaderIndex for " + sampleCount + " sampleCount");
-                
-                // add multisample header tails to header data object
-                this.setMultiSampleHeaders(headerData, multisampleHeaderIndex, multisampleHeaderData);
-
+
+                // If a set of samples is associated with an APV header or tail, skip it
+                if (!this.isValidSampleSet(samples)) {
+                    continue;
+                }
+                rawHits.add(this.makeHit(samples));
             }
+
+            LOGGER.finest("got " + multisampleHeaderIndex + " multisampleHeaderIndex for " + sampleCount + " sampleCount");
+
+            // add multisample header tails to header data object
+            this.setMultiSampleHeaders(headerData, multisampleHeaderIndex, multisampleHeaderData);
+
         }
         
         LOGGER.finest("Total number of RawTrackerHits created: " + rawHits.size());
@@ -282,13 +239,9 @@
         // Add the collection of raw hits to the LCSim event
         lcsimEvent.put(SVT_HIT_COLLECTION_NAME, rawHits, RawTrackerHit.class, flag, READOUT_NAME);
 
-        
         // Process SVT headers
         this.processSvtHeaders(headers, lcsimEvent);
         
-       
-        
-
         return true;
     }
 
@@ -322,7 +275,7 @@
      * @param samples
      * @param index
      * @param multisampleHeaderData
-     * @return
+     * @return the length of the extracted samples or 0 if not a multisample header
      */
     protected int extractMultisampleHeaderData(int[] samples, int index, int[] multisampleHeaderData) {
         LOGGER.finest("extractMultisampleHeaderData: index " + index);
@@ -344,7 +297,7 @@
      */
     protected void checkSvtSampleCount(int sampleCount, SvtHeaderDataInfo headerData) throws SvtEvioHeaderException {
         if( sampleCount != SvtEvioUtils.getSvtTailMultisampleCount(headerData.getTail())*4)
-            throw new SvtEvioHeaderException("multisample count is not consistent with bank size.");
+            throw new SvtEvioHeaderException("ROC " + headerData.getNum() + " multisample count " + sampleCount + " is not consistent with bank size " + SvtEvioUtils.getSvtTailMultisampleCount(headerData.getTail()));
     }
     
     /**
@@ -394,26 +347,4 @@
         // Create and return a RawTrackerHit
         return new BaseRawTrackerHit(hitTime, cellID, SvtEvioUtils.getSamples(data), null, sensor);
     }
-    
-    /**
-     *  Retrieve all the banks in an event that match the given tag in their
-     *  header and are not data banks. 
-     *
-     *  @param structure : The event/bank being queried
-     *  @param tag : The tag to match
-     *  @return A collection of all bank structures that pass the filter 
-     *          provided by the event
-     */
-    protected List<BaseStructure> getMatchingBanks(BaseStructure structure, final int tag) { 
-        IEvioFilter filter = new IEvioFilter() { 
-            public boolean accept(StructureType type, IEvioStructure struc) { 
-                return (type == StructureType.BANK) 
-                        && (tag == struc.getHeader().getTag())
-                        && (struc.getHeader().getDataType() == DataType.ALSOBANK);
-            }
-        };
-        return StructureFinder.getMatchingStructures(structure, filter);
-    }
-
-   
 }

Modified: java/branches/HPSJAVA-409/evio/src/main/java/org/hps/evio/AugmentedSvtEvioReader.java
 =============================================================================
--- java/branches/HPSJAVA-409/evio/src/main/java/org/hps/evio/AugmentedSvtEvioReader.java	(original)
+++ java/branches/HPSJAVA-409/evio/src/main/java/org/hps/evio/AugmentedSvtEvioReader.java	Wed Apr 27 11:11:32 2016
@@ -32,7 +32,10 @@
     
     @Override
     protected void processSvtHeaders(List<SvtHeaderDataInfo> headers, EventHeader lcsimEvent) throws SvtEvioHeaderException {
-    
+
+
+        LOGGER.finest("Process " + headers.size() + " SVT headers for run " + lcsimEvent.getRunNumber() + " and event " + lcsimEvent.getEventNumber());
+        
         // Check that the SVT header data is valid
         // Catch the exceptions locally, add stuff to the event, then throw it again
         // and handle it outside
@@ -43,6 +46,8 @@
 
         if( !exceptions.isEmpty() ) {
 
+            LOGGER.finest("Found " + exceptions.size() + " " + SvtEvioHeaderException.class.getSimpleName() + " exceptions");
+            
             // print some debug info 
             
             List<String> exceptionNames = SvtEventHeaderChecker.getSvtEvioHeaderExceptionNames(exceptions);
@@ -68,8 +73,14 @@
                 throw new SvtEvioHeaderException(exceptions.get(0));
             
         } else { 
+            
+            LOGGER.finest("No " + SvtEvioHeaderException.class.getSimpleName() + " exceptions found for this event");
+            
             // add skimming flag - the header is OK since I would never get here otherwise
             SvtEventFlagger.voidAddHeaderCheckResultToMetaData(true, lcsimEvent);
+            
+            
+            
         }
 
         // Add SVT header data to the event

Modified: java/branches/HPSJAVA-409/evio/src/main/java/org/hps/evio/BasicEvioFileReader.java
 =============================================================================
--- java/branches/HPSJAVA-409/evio/src/main/java/org/hps/evio/BasicEvioFileReader.java	(original)
+++ java/branches/HPSJAVA-409/evio/src/main/java/org/hps/evio/BasicEvioFileReader.java	Wed Apr 27 11:11:32 2016
@@ -8,7 +8,7 @@
 import org.apache.commons.cli.Option;
 import org.apache.commons.cli.Options;
 import org.apache.commons.cli.ParseException;
-import org.apache.commons.cli.DefaultParser;
+import org.apache.commons.cli.PosixParser;
 import org.hps.record.evio.EvioEventUtilities;
 import org.hps.record.triggerbank.AbstractIntData.IntBankDefinition;
 import org.hps.record.triggerbank.HeadBankData;
@@ -33,7 +33,7 @@
         if (args.length == 0) {
             printUsage(options);
         }
-        final CommandLineParser parser = new DefaultParser();
+        final CommandLineParser parser = new PosixParser();
         CommandLine cl = null;
         try {
             cl = parser.parse(options, args);

Modified: java/branches/HPSJAVA-409/evio/src/main/java/org/hps/evio/DummyEventBuilder.java
 =============================================================================
--- java/branches/HPSJAVA-409/evio/src/main/java/org/hps/evio/DummyEventBuilder.java	(original)
+++ java/branches/HPSJAVA-409/evio/src/main/java/org/hps/evio/DummyEventBuilder.java	Wed Apr 27 11:11:32 2016
@@ -41,7 +41,7 @@
     public void readEvioEvent(EvioEvent evioEvent) {
     }
 
-	@Override
-	public void conditionsChanged(ConditionsEvent conditionsEvent) {
-	}	
+    @Override
+    public void conditionsChanged(ConditionsEvent conditionsEvent) {
+    }   
 }

Modified: java/branches/HPSJAVA-409/evio/src/main/java/org/hps/evio/EcalHitWriter.java
 =============================================================================
--- java/branches/HPSJAVA-409/evio/src/main/java/org/hps/evio/EcalHitWriter.java	(original)
+++ java/branches/HPSJAVA-409/evio/src/main/java/org/hps/evio/EcalHitWriter.java	Wed Apr 27 11:11:32 2016
@@ -212,10 +212,10 @@
         Map<Integer, List<Long>> slotMap = new HashMap<Integer, List<Long>>();
         for (Long id : hitMap.keySet()) {
             dec.setID(id);
-//			System.out.println(dec.getIDDescription());
-//			System.out.printf("ix = %d, iy = %d\n", dec.getValue("ix"), dec.getValue("iy"));
+//          System.out.println(dec.getIDDescription());
+//          System.out.printf("ix = %d, iy = %d\n", dec.getValue("ix"), dec.getValue("iy"));
 //            Long daqID = EcalConditions.physicalToDaqID(id);
-//			System.out.printf("physicalID %d, daqID %d\n", id, daqID);
+//          System.out.printf("physicalID %d, daqID %d\n", id, daqID);
             int slot = getSlot(id);
             if (slotMap.get(slot) == null) {
                 slotMap.put(slot, new ArrayList<Long>());
@@ -231,7 +231,7 @@
         for (int slot : slotMap.keySet()) {
             data.addUchar((byte) slot); // slot #
             data.addUint(0); // trigger #
-            data.addUlong(0); // timestamp    		
+            data.addUlong(0); // timestamp          
             List<Long> hitIDs = slotMap.get(slot);
             int nhits = hitIDs.size();
             data.addN(nhits); // number of channels
@@ -285,10 +285,10 @@
         Map<Integer, List<Long>> slotMap = new HashMap<Integer, List<Long>>();
         for (Long id : hitMap.keySet()) {
             dec.setID(id);
-//			System.out.println(dec.getIDDescription());
-//			System.out.printf("ix = %d, iy = %d\n", dec.getValue("ix"), dec.getValue("iy"));
+//          System.out.println(dec.getIDDescription());
+//          System.out.printf("ix = %d, iy = %d\n", dec.getValue("ix"), dec.getValue("iy"));
 //            Long daqID = EcalConditions.physicalToDaqID(id);
-//			System.out.printf("physicalID %d, daqID %d\n", id, daqID);
+//          System.out.printf("physicalID %d, daqID %d\n", id, daqID);
             int slot = getSlot(id);
             if (slotMap.get(slot) == null) {
                 slotMap.put(slot, new ArrayList<Long>());
@@ -304,7 +304,7 @@
         for (int slot : slotMap.keySet()) {
             data.addUchar((byte) slot); // slot #
             data.addUint(0); // trigger #
-            data.addUlong(0); // timestamp    		
+            data.addUlong(0); // timestamp          
             List<Long> hitIDs = slotMap.get(slot);
             int nhits = hitIDs.size();
             data.addN(nhits); // number of channels
@@ -358,10 +358,10 @@
         Map<Integer, List<Long>> slotMap = new HashMap<Integer, List<Long>>();
         for (Long id : hitMap.keySet()) {
             dec.setID(id);
-//			System.out.println(dec.getIDDescription());
-//			System.out.printf("ix = %d, iy = %d\n", dec.getValue("ix"), dec.getValue("iy"));
+//          System.out.println(dec.getIDDescription());
+//          System.out.printf("ix = %d, iy = %d\n", dec.getValue("ix"), dec.getValue("iy"));
 //            Long daqID = EcalConditions.physicalToDaqID(id);
-//			System.out.printf("physicalID %d, daqID %d\n", id, daqID);
+//          System.out.printf("physicalID %d, daqID %d\n", id, daqID);
             int slot = getSlot(id);
             if (slotMap.get(slot) == null) {
                 slotMap.put(slot, new ArrayList<Long>());
@@ -380,7 +380,7 @@
 //            EvioBank slotBank = new EvioBank(EventConstants.ECAL_WINDOW_BANK_TAG, DataType.COMPOSITE, slot);
             data.addUchar((byte) slot); // slot #
             data.addUint(0); // trigger #
-            data.addUlong(0); // timestamp    		
+            data.addUlong(0); // timestamp          
             List<Long> hitIDs = slotMap.get(slot);
             int nhits = hitIDs.size();
             data.addN(nhits); // number of channels

Modified: java/branches/HPSJAVA-409/evio/src/main/java/org/hps/evio/EvioReader.java
 =============================================================================
--- java/branches/HPSJAVA-409/evio/src/main/java/org/hps/evio/EvioReader.java	(original)
+++ java/branches/HPSJAVA-409/evio/src/main/java/org/hps/evio/EvioReader.java	Wed Apr 27 11:11:32 2016
@@ -5,45 +5,45 @@
 import org.lcsim.event.EventHeader;
 
 /**
- *	Abstract class containing shared methods used by EVIO readers.
+ *  Abstract class containing shared methods used by EVIO readers.
  *
- *	@author Sho Uemura <[log in to unmask]>
+ *  @author Sho Uemura <[log in to unmask]>
  */
 public abstract class EvioReader {
 
-	// Debug flag
-	protected boolean debug = false;
-	
-	// Name of the hit collection that will be created
-	protected String hitCollectionName = null;
+    // Debug flag
+    protected boolean debug = false;
+    
+    // Name of the hit collection that will be created
+    protected String hitCollectionName = null;
 
-	/**
-	 *	Make a LCIO hit collection (e.g. {@link RawTrackerHit}, 
-	 * 	{@link CalorimeterHit} from raw EVIO data.
-	 * 
-	 * 	@param event : The EVIO event to read the raw data from
-	 * 	@param lcsimEvent : The LCSim event to write the collections to
-	 * 	@return True if the appropriate EVIO bank is found, false otherwise	
-	 * @throws Exception 
-	 * 
-	 */
-	abstract boolean makeHits(EvioEvent event, EventHeader lcsimEvent) throws Exception;
+    /**
+     *  Make a LCIO hit collection (e.g. {@link org.lcsim.event.RawTrackerHit}, 
+     *  {@link org.lcsim.event.CalorimeterHit} from raw EVIO data.
+     * 
+     *  @param event : The EVIO event to read the raw data from
+     *  @param lcsimEvent : The LCSim event to write the collections to
+     *  @return True if the appropriate EVIO bank is found, false otherwise 
+     * @throws Exception 
+     * 
+     */
+    abstract boolean makeHits(EvioEvent event, EventHeader lcsimEvent) throws Exception;
 
-	/**
-	 *	Set the hit collection name.
-	 * 
-	 * 	@param hitCollectionName : Name of the hit collection
-	 */
-	public void setHitCollectionName(String hitCollectionName) {
-		this.hitCollectionName = hitCollectionName;
-	}
+    /**
+     *  Set the hit collection name.
+     * 
+     *  @param hitCollectionName : Name of the hit collection
+     */
+    public void setHitCollectionName(String hitCollectionName) {
+        this.hitCollectionName = hitCollectionName;
+    }
 
-	/**
-	 *	Enable/disable debug output.
-	 * 
-	 * 	@param debug : Set to true to enable, false to disable.
-	 */
-	public void setDebug(boolean debug) {
-		this.debug = debug;
-	}
+    /**
+     *  Enable/disable debug output.
+     * 
+     *  @param debug : Set to true to enable, false to disable.
+     */
+    public void setDebug(boolean debug) {
+        this.debug = debug;
+    }
 }

Modified: java/branches/HPSJAVA-409/evio/src/main/java/org/hps/evio/EvioToLcio.java
 =============================================================================
--- java/branches/HPSJAVA-409/evio/src/main/java/org/hps/evio/EvioToLcio.java	(original)
+++ java/branches/HPSJAVA-409/evio/src/main/java/org/hps/evio/EvioToLcio.java	Wed Apr 27 11:11:32 2016
@@ -71,7 +71,7 @@
  * @author Jeremy McCormick <[log in to unmask]>
  * @author Sho Uemura <[log in to unmask]>
  */
-public class EvioToLcio {
+public final class EvioToLcio {
 
     /**
      * The default steering resource, which basically does nothing except print event numbers.
@@ -113,6 +113,7 @@
      */
     private static Options OPTIONS = new Options();
     static {
+        OPTIONS.addOption(new Option("h", false, "print help and exit"));
         OPTIONS.addOption(new Option("d", true, "detector name (required)"));
         OPTIONS.getOption("d").setRequired(true);
         OPTIONS.addOption(new Option("f", true, "text file containing a list of EVIO files"));
@@ -251,10 +252,11 @@
     }
 
     public void parse(String[] args) {
-        // Parse the command line options.
+        
         if (args.length == 0) {
             this.printUsage();
         }
+        
         final CommandLineParser parser = new PosixParser();
         CommandLine cl = null;
         try {
@@ -262,8 +264,13 @@
         } catch (final ParseException e) {
             throw new RuntimeException("Problem parsing command line options.", e);
         }
+        
+        if (cl.hasOption("h")) {
+            this.printUsage();
+        }
 
         // Set the log level.
+        // TODO: Remove this argument; use java logging prop instead.
         if (cl.hasOption("L")) {
             final Level level = Level.parse(cl.getOptionValue("L").toUpperCase());
 
@@ -366,6 +373,10 @@
 
         // Process the LCSim job variable definitions, if any.
         jobManager = new JobManager();
+        
+        // Initialize run manager and add as listener on conditions system.
+        RunManager runManager = RunManager.getRunManager();
+        DatabaseConditionsManager.getInstance().addConditionsListener(runManager);
         
         // Enable dry run because events will be processed individually.
         jobManager.setDryRun(true);
@@ -452,8 +463,6 @@
      * This method will execute the EVIO to LCIO conversion and optionally process the events with LCSim Drivers from a
      * steering file. Then the resultant LCIO events will be written to disk if this option is enabled in the command
      * line arguments.
-     *
-     * @param args The command line arguments.
      */
     public void run() {
 

Modified: java/branches/HPSJAVA-409/evio/src/main/java/org/hps/evio/LCSimEngRunEventBuilder.java
 =============================================================================
--- java/branches/HPSJAVA-409/evio/src/main/java/org/hps/evio/LCSimEngRunEventBuilder.java	(original)
+++ java/branches/HPSJAVA-409/evio/src/main/java/org/hps/evio/LCSimEngRunEventBuilder.java	Wed Apr 27 11:11:32 2016
@@ -67,6 +67,11 @@
      * Modulus of TI timestamp offset (units of nanoseconds).
      */
     private final long timestampCycle = 24 * 6 * 35;
+    
+    /**
+     * The current TI time offset in nanoseconds from the run manager.
+     */
+    private Long currentTiTimeOffset = null;
 
     /**
      * Class constructor.
@@ -83,31 +88,59 @@
         intBanks.add(new IntBankDefinition(TIData.class, new int[]{sspCrateBankTag, 0xe10a}));
         intBanks.add(new IntBankDefinition(HeadBankData.class, new int[]{sspCrateBankTag, 0xe10f}));
         intBanks.add(new IntBankDefinition(TDCData.class, new int[]{0x3a, 0xe107}));
-        // ecalReader = new ECalEvioReader(0x25, 0x27);
         triggerConfigReader = new TriggerConfigEvioReader();
         svtEventFlagger = new SvtEventFlagger();
     }
 
     @Override
     public void conditionsChanged(final ConditionsEvent conditionsEvent) {
+        
         super.conditionsChanged(conditionsEvent);
         svtEventFlagger.initialize();
-    }
-
-    /**
-     * Get the time from the TI data.
+        
+        // Set TI time offset from run database.
+        setTiTimeOffsetForRun(conditionsEvent.getConditionsManager().getRun());
+    }
+    
+    /**
+     * Get TI time offset from the run database, if available.
+     * @param run the run number
+     */
+    private void setTiTimeOffsetForRun(int run) {
+        currentTiTimeOffset = null;
+        RunManager runManager = RunManager.getRunManager();
+        if (runManager.getRun() != null) {
+            if (runManager.runExists()) {
+                currentTiTimeOffset = runManager.getRunSummary().getTiTimeOffset();
+                LOGGER.info("TI time offset set to " + currentTiTimeOffset + " for run "
+                        + run + " from database");
+            } else {
+                LOGGER.warning("Run " + run 
+                        + " does not exist in the run database.");
+            }
+        } else {
+            LOGGER.info("Run manager is not initialized; TI time offset not available.");
+        }
+        /* Make sure connection is closed immediately. --JM */
+        try {
+            LOGGER.info("Closing run manager db connection ...");
+            RunManager.getRunManager().closeConnection();
+            LOGGER.info("Run manager db connection was closed.");
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * Get the time from the TI data with time offset applied from run database.
      *
      * @param triggerList the TI data list
      */
     @Override
     protected long getTime(final List<AbstractIntData> triggerList) {
         long tiTimeOffset = 0;
-        try {
-            if (RunManager.getRunManager().runExists() && RunManager.getRunManager().getTriggerConfig().getTiTimeOffset() != null) {
-                tiTimeOffset = (RunManager.getRunManager().getTriggerConfig().getTiTimeOffset() / timestampCycle) * timestampCycle;
-            }
-        } catch (IllegalStateException e) {
-            // May happen if RunManager is not initialized; just ignore.
+        if (currentTiTimeOffset != null) {
+            tiTimeOffset = (currentTiTimeOffset / timestampCycle) * timestampCycle;
         }
         for (final AbstractIntData data : triggerList) {
             if (data instanceof TIData) {
@@ -137,7 +170,11 @@
         LOGGER.finest("created new LCSim event " + lcsimEvent.getEventNumber());
 
         // Put DAQ Configuration info into lcsimEvent.
-        triggerConfigReader.getDAQConfig(evioEvent, lcsimEvent);
+        try {
+            triggerConfigReader.getDAQConfig(evioEvent, lcsimEvent);
+        } catch (final Exception e) {
+            LOGGER.log(Level.SEVERE,"DAQ CONFIG BROKEN.",e);
+        }
 
         // Make RawCalorimeterHit collection, combining top and bottom section
         // of ECal into one list.

Modified: java/branches/HPSJAVA-409/evio/src/main/java/org/hps/evio/RfFitFunction.java
 =============================================================================
--- java/branches/HPSJAVA-409/evio/src/main/java/org/hps/evio/RfFitFunction.java	(original)
+++ java/branches/HPSJAVA-409/evio/src/main/java/org/hps/evio/RfFitFunction.java	Wed Apr 27 11:11:32 2016
@@ -7,29 +7,29 @@
  * Straight line fit
  */
 public class RfFitFunction extends AbstractIFunction {
-	protected double intercept=0;
-	protected double slope=0;
-	public RfFitFunction() {
-		this("");
-	}
-	public RfFitFunction(String title) {
-		super();
-		this.variableNames=new String[]{"time"};
-		this.parameterNames=new String[]{"intercept","slope"};
+    protected double intercept=0;
+    protected double slope=0;
+    public RfFitFunction() {
+        this("");
+    }
+    public RfFitFunction(String title) {
+        super();
+        this.variableNames=new String[]{"time"};
+        this.parameterNames=new String[]{"intercept","slope"};
 
-		init(title);
-	}
-	public double value(double [] v) {
-		return  intercept + (v[0])*slope;
-	}
-	public void setParameters(double[] pars) throws IllegalArgumentException {
-		super.setParameters(pars);
-		intercept=pars[0];
-		slope=pars[1];
-	}
-	public void setParameter(String key,double value) throws IllegalArgumentException{
-		super.setParameter(key,value);
-		if      (key.equals("intercept")) intercept=value;
-		else if (key.equals("slope"))    slope=value;
-	}
+        init(title);
+    }
+    public double value(double [] v) {
+        return  intercept + (v[0])*slope;
+    }
+    public void setParameters(double[] pars) throws IllegalArgumentException {
+        super.setParameters(pars);
+        intercept=pars[0];
+        slope=pars[1];
+    }
+    public void setParameter(String key,double value) throws IllegalArgumentException{
+        super.setParameter(key,value);
+        if      (key.equals("intercept")) intercept=value;
+        else if (key.equals("slope"))    slope=value;
+    }
 }

Modified: java/branches/HPSJAVA-409/evio/src/main/java/org/hps/evio/RfFitterDriver.java
 =============================================================================
--- java/branches/HPSJAVA-409/evio/src/main/java/org/hps/evio/RfFitterDriver.java	(original)
+++ java/branches/HPSJAVA-409/evio/src/main/java/org/hps/evio/RfFitterDriver.java	Wed Apr 27 11:11:32 2016
@@ -1,9 +1,4 @@
 package org.hps.evio;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.logging.Level;
-import java.util.logging.Logger;
 
 import hep.aida.IAnalysisFactory;
 import hep.aida.IDataPointSet;
@@ -11,7 +6,9 @@
 import hep.aida.IFitResult;
 import hep.aida.IFitter;
 import hep.aida.IFunction;
-import hep.aida.IFunctionFactory;
+
+import java.util.ArrayList;
+import java.util.List;
 
 import org.hps.recon.ecal.FADCGenericHit;
 import org.lcsim.event.EventHeader;
@@ -19,146 +16,156 @@
 import org.lcsim.util.Driver;
 import org.lcsim.util.aida.AIDA;
 
-/*
+/**
  * Extract RF time from waveform and put into lcsim event.
  */
 public class RfFitterDriver extends Driver {
 
-	static final double NOISE=2.0; // units = FADC
-	static final int CRATE=46;
-	static final int SLOT=13;
-	static final int CHANNELS[]={0,1};
-	static final double NSPERSAMPLE=4;
-		
+    private static final double NOISE = 2.0; // units = FADC
+    private static final int CRATE = 46;
+    private static final int SLOT = 13;
+    private static final int CHANNELS[] = {0, 1};
+    private static final double NSPERSAMPLE = 4;
 
-	// boilerplate:
-    AIDA aida = AIDA.defaultInstance();
-    IAnalysisFactory analysisFactory = aida.analysisFactory();
-    IFunctionFactory functionFactory = analysisFactory.createFunctionFactory(null);
-    IFitFactory fitFactory = analysisFactory.createFitFactory();
-    IFitter fitter=fitFactory.createFitter();
-    IDataPointSet fitData=aida.analysisFactory().createDataPointSetFactory(null).create("RF ADC DataPointSet", 2);
-    
+    // boilerplate:
+    private AIDA aida = AIDA.defaultInstance();
+    private IAnalysisFactory analysisFactory = aida.analysisFactory();
+    //private IFunctionFactory functionFactory = analysisFactory.createFunctionFactory(null);
+    private IFitFactory fitFactory = analysisFactory.createFitFactory();
+    private IFitter fitter = fitFactory.createFitter();
+    private IDataPointSet fitData = aida.analysisFactory().createDataPointSetFactory(null).create("RF ADC DataPointSet", 2);
+
     // the function used to fit the RF pulse:
-    IFunction fitFunction=new RfFitFunction();
+    private IFunction fitFunction = new RfFitFunction();
 
-    /*
-     * Check the event for an RF pulse, and, if found, fit it to get
-     * RF time and then dump it in the lcsim event.
+    /**
+     * Check the event for an RF pulse, and, if found, fit it to get RF time.
      */
-	public void process(EventHeader event) {
-		if (!event.hasCollection(GenericObject.class,"FADCGenericHits")) return;
-		
-		boolean foundRf=false;
-    	double times[]={-9999,-9999};
-    	
-    	for (GenericObject gob : event.get(GenericObject.class,"FADCGenericHits")) {
-			FADCGenericHit hit=(FADCGenericHit)gob;
-    		
-			// ignore hits not from proper RF signals based on crate/slot/channel:
-			if (hit.getCrate()!=CRATE || hit.getSlot()!=SLOT) continue;
-    		for (int ii=0; ii<CHANNELS.length; ii++) {
-				if (hit.getChannel()==CHANNELS[ii]) {
-					
-					// we found a RF readout, fit it:
-					foundRf=true;
-					times[ii] = fitPulse(hit);
-									  				    
-					break;
-				}
-			}
-		}
-		
-    	// if we found an RF readout, dump the fit result in the event:  
-    	if (foundRf) {
-    		List <RfHit> rfHits=new ArrayList<RfHit>();
-    		rfHits.add(new RfHit(times));
-	    	event.put("RFHits", rfHits, RfHit.class, 1);
-		}
-	}
+    public void process(EventHeader event) {
 
-	/*
-	 * Perform the fit to the RF pulse:
-	 */
-	public double fitPulse(FADCGenericHit hit) {
-		fitData.clear();
-		final int adcSamples[]=hit.getData();
-		//stores the number of peaks
-		int iz=0;
-		int peakBin[]={-999,-999};
-		final int threshold = 300;	
-		double fitThresh[]={-999,-999};
-		double pedVal[]={-999,-999};
-		
-		// Look for bins containing the peaks (2-3 peaks)
-		for (int ii=4; ii<adcSamples.length; ii++) {
-			// After 2 peaks, stop looking for more
-			if (iz==2){break;}
-			if ((adcSamples[ii+1]>0) && (adcSamples[ii-1]>0) && (adcSamples[ii]>threshold) && ii>8){
-				if ((adcSamples[ii]>adcSamples[ii+1]) && (adcSamples[ii]>=adcSamples[ii-1]) ){
-					
-					peakBin[iz]=ii;
-					iz++;
-				}
-			}
-		}
-		
-		
-		int jj=0;
-		// Choose peak closest to center of window (second peak, ik=1)
-		final int ik=1;
-		pedVal[ik] = (adcSamples[peakBin[ik]-6]+adcSamples[peakBin[ik]-7]+adcSamples[peakBin[ik]-8]+adcSamples[peakBin[ik]-9])/4.0;
-		fitThresh[ik]= (adcSamples[peakBin[ik]]+pedVal[ik])/3.0;
-	
-		// Initial values: we find/fit 3 points:
-		double itime[] = {-999,-999,-999};
-		double ifadc[] = {-999,-999,-999};
-		
-		// Find the points of the peak bin to peak bin-5 
-		for (int ll=0; ll<5; ll++){	
-			if ((adcSamples[peakBin[ik]-5+ll]) > fitThresh[ik]){
-				// One point is below fit threshold and two points are above	
-				if(jj==0 && (adcSamples[peakBin[ik]-6+ll] > pedVal[ik])){
-					final int zz=fitData.size();	
-					fitData.addPoint();
-					itime[zz] = peakBin[ik]-6+ll;
-					ifadc[zz] = adcSamples[peakBin[ik]-6+ll];
-					fitData.point(zz).coordinate(0).setValue(peakBin[ik]-6+ll);
-					fitData.point(zz).coordinate(1).setValue(adcSamples[peakBin[ik]-6+ll]);
-					fitData.point(zz).coordinate(1).setErrorMinus(NOISE);
-					fitData.point(zz).coordinate(1).setErrorPlus(NOISE);		
-					jj++;	
-				}
-				final int zz=fitData.size();	
-				fitData.addPoint();
-				itime[zz] = peakBin[ik]-5+ll;
-				ifadc[zz] = adcSamples[peakBin[ik]-5+ll];
-				fitData.point(zz).coordinate(0).setValue(peakBin[ik]-5+ll);
-				fitData.point(zz).coordinate(1).setValue(adcSamples[peakBin[ik]-5+ll]);
-				fitData.point(zz).coordinate(1).setErrorMinus(NOISE);
-				fitData.point(zz).coordinate(1).setErrorPlus(NOISE);
-					
-				jj++;
-				if (jj==3) {break;}					
-			}
-		}
-		
-		double islope = ((double)(ifadc[2]-ifadc[0]))/(itime[2]-itime[0]);
-		double icept = ifadc[1] - islope*itime[1];
-		// Initialize fit parameters:
-		fitFunction.setParameter("intercept",icept);
-		fitFunction.setParameter("slope",islope);
+        List<RfHit> rfHits = new ArrayList<RfHit>();
 
-		// this used to be turned on somewhere else on every event, dunno if it still is:
-		//Logger.getLogger("org.freehep.math.minuit").setLevel(Level.OFF);
-	
-		IFitResult fitResults = fitter.fit(fitData,fitFunction);
-		
-		// Read the time value at this location on the fit:
-		double halfVal = (adcSamples[peakBin[1]]+pedVal[1])/2.0;	
-	
-		return NSPERSAMPLE*(halfVal-fitResults.fittedParameter("intercept"))/fitResults.fittedParameter("slope");
-			
-	}
-		
+        boolean foundRf = false;
+        double times[] = {-9999, -9999};
+
+        if (event.hasCollection(GenericObject.class, "FADCGenericHits")) {
+
+            for (GenericObject gob : event.get(GenericObject.class, "FADCGenericHits")) {
+
+                FADCGenericHit hit = null;
+
+                /* Added conversion from GenericObject in case loading back from an LCIO file. --JM */
+                if (gob instanceof FADCGenericHit) {
+                    hit = (FADCGenericHit) gob;
+                } else {
+                    hit = new FADCGenericHit(gob);
+                }
+
+                // ignore hits not from proper RF signals based on crate/slot/channel:
+                if (hit.getCrate() != CRATE || hit.getSlot() != SLOT)
+                    continue;
+
+                for (int ii = 0; ii < CHANNELS.length; ii++) {
+                    if (hit.getChannel() == CHANNELS[ii]) {
+
+                        // we found a RF readout, fit it:
+                        foundRf = true;
+                        times[ii] = fitPulse(hit);
+
+                        break;
+                    }
+                }
+            }
+        }
+        if (foundRf) {
+            rfHits.add(new RfHit(times));
+        }
+        event.put("RFHits", rfHits, RfHit.class, 1);
+    }
+
+    /**
+     * Perform the fit to the RF pulse:
+     */
+    private double fitPulse(FADCGenericHit hit) {
+        fitData.clear();
+        final int adcSamples[] = hit.getData();
+        // stores the number of peaks
+        int iz = 0;
+        int peakBin[] = {-999, -999};
+        final int threshold = 300;
+        double fitThresh[] = {-999, -999};
+        double pedVal[] = {-999, -999};
+
+        // Look for bins containing the peaks (2-3 peaks)
+        for (int ii = 4; ii < adcSamples.length; ii++) {
+            // After 2 peaks, stop looking for more
+            if (iz == 2) {
+                break;
+            }
+            if ((adcSamples[ii + 1] > 0) && (adcSamples[ii - 1] > 0) && (adcSamples[ii] > threshold) && ii > 8) {
+                if ((adcSamples[ii] > adcSamples[ii + 1]) && (adcSamples[ii] >= adcSamples[ii - 1])) {
+
+                    peakBin[iz] = ii;
+                    iz++;
+                }
+            }
+        }
+
+        int jj = 0;
+        // Choose peak closest to center of window (second peak, ik=1)
+        final int ik = 1;
+        pedVal[ik] = (adcSamples[peakBin[ik] - 6] + adcSamples[peakBin[ik] - 7] + adcSamples[peakBin[ik] - 8] + adcSamples[peakBin[ik] - 9]) / 4.0;
+        fitThresh[ik] = (adcSamples[peakBin[ik]] + pedVal[ik]) / 3.0;
+
+        // Initial values: we find/fit 3 points:
+        double itime[] = {-999, -999, -999};
+        double ifadc[] = {-999, -999, -999};
+
+        // Find the points of the peak bin to peak bin-5
+        for (int ll = 0; ll < 5; ll++) {
+            if ((adcSamples[peakBin[ik] - 5 + ll]) > fitThresh[ik]) {
+                // One point is below fit threshold and two points are above
+                if (jj == 0 && (adcSamples[peakBin[ik] - 6 + ll] > pedVal[ik])) {
+                    final int zz = fitData.size();
+                    fitData.addPoint();
+                    itime[zz] = peakBin[ik] - 6 + ll;
+                    ifadc[zz] = adcSamples[peakBin[ik] - 6 + ll];
+                    fitData.point(zz).coordinate(0).setValue(peakBin[ik] - 6 + ll);
+                    fitData.point(zz).coordinate(1).setValue(adcSamples[peakBin[ik] - 6 + ll]);
+                    fitData.point(zz).coordinate(1).setErrorMinus(NOISE);
+                    fitData.point(zz).coordinate(1).setErrorPlus(NOISE);
+                    jj++;
+                }
+                final int zz = fitData.size();
+                fitData.addPoint();
+                itime[zz] = peakBin[ik] - 5 + ll;
+                ifadc[zz] = adcSamples[peakBin[ik] - 5 + ll];
+                fitData.point(zz).coordinate(0).setValue(peakBin[ik] - 5 + ll);
+                fitData.point(zz).coordinate(1).setValue(adcSamples[peakBin[ik] - 5 + ll]);
+                fitData.point(zz).coordinate(1).setErrorMinus(NOISE);
+                fitData.point(zz).coordinate(1).setErrorPlus(NOISE);
+
+                jj++;
+                if (jj == 3) {
+                    break;
+                }
+            }
+        }
+
+        double islope = ((double) (ifadc[2] - ifadc[0])) / (itime[2] - itime[0]);
+        double icept = ifadc[1] - islope * itime[1];
+        // Initialize fit parameters:
+        fitFunction.setParameter("intercept", icept);
+        fitFunction.setParameter("slope", islope);
+
+        // this used to be turned on somewhere else on every event, dunno if it still is:
+        // Logger.getLogger("org.freehep.math.minuit").setLevel(Level.OFF);
+
+        IFitResult fitResults = fitter.fit(fitData, fitFunction);
+
+        // Read the time value at this location on the fit:
+        double halfVal = (adcSamples[peakBin[1]] + pedVal[1]) / 2.0;
+
+        return NSPERSAMPLE * (halfVal - fitResults.fittedParameter("intercept")) / fitResults.fittedParameter("slope");
+    }
 }

Modified: java/branches/HPSJAVA-409/evio/src/main/java/org/hps/evio/RfHit.java
 =============================================================================
--- java/branches/HPSJAVA-409/evio/src/main/java/org/hps/evio/RfHit.java	(original)
+++ java/branches/HPSJAVA-409/evio/src/main/java/org/hps/evio/RfHit.java	Wed Apr 27 11:11:32 2016
@@ -6,13 +6,13 @@
  * class to store RF times after extracting from waveform.
  */
 public class RfHit implements GenericObject {
-	private double[] times;
-	public RfHit(double[] times) { this.times=times; }
-	public int getNInt()    { return 0; }
-	public int getNFloat()  { return 0; }
-	public int getNDouble() { return times.length; }
-	public double getDoubleVal(int ii) { return times[ii]; }
-	public float  getFloatVal (int ii) { return 0; }
-	public int    getIntVal   (int ii) { return 0; }
-	public boolean isFixedSize() { return false; }
+    private double[] times;
+    public RfHit(double[] times) { this.times=times; }
+    public int getNInt()    { return 0; }
+    public int getNFloat()  { return 0; }
+    public int getNDouble() { return times.length; }
+    public double getDoubleVal(int ii) { return times[ii]; }
+    public float  getFloatVal (int ii) { return 0; }
+    public int    getIntVal   (int ii) { return 0; }
+    public boolean isFixedSize() { return false; }
 }

Modified: java/branches/HPSJAVA-409/evio/src/main/java/org/hps/evio/SvtEvioReader.java
 =============================================================================
--- java/branches/HPSJAVA-409/evio/src/main/java/org/hps/evio/SvtEvioReader.java	(original)
+++ java/branches/HPSJAVA-409/evio/src/main/java/org/hps/evio/SvtEvioReader.java	Wed Apr 27 11:11:32 2016
@@ -7,7 +7,6 @@
 import org.hps.record.svt.SvtEvioExceptions.SvtEvioHeaderException;
 import org.hps.record.svt.SvtEvioExceptions.SvtEvioReaderException;
 import org.hps.util.Pair;
-import org.jlab.coda.jevio.BaseStructure;
 import org.jlab.coda.jevio.EvioEvent;
 import org.lcsim.detector.tracker.silicon.HpsSiSensor;
 import org.lcsim.event.EventHeader;
@@ -18,8 +17,6 @@
  *  SVT EVIO reader used to convert SVT bank integer data to LCIO objects.
  * 
  *  @author Omar Moreno <[log in to unmask]>
- *  @data February 03, 2015
- *
  */
 public class SvtEvioReader extends AbstractSvtEvioReader {
 
@@ -30,6 +27,7 @@
     private static final int DATA_TAIL_LENGTH = 1; 
     public static final int MIN_ROC_BANK_TAG = 51;
     public static final int MAX_ROC_BANK_TAG = 66;
+    public static final int DATA_BANK_TAG = 3;
     private static final int ROC_BANK_NUMBER = 0; 
     
     /**
@@ -52,6 +50,16 @@
         return MAX_ROC_BANK_TAG; 
     }
     
+    @Override
+    protected int getMinDataBankTag() {
+        return DATA_BANK_TAG;
+    }
+
+    @Override
+    protected int getMaxDataBankTag() {
+        return DATA_BANK_TAG;
+    }
+
     /**
      *  Get the SVT ROC bank number of the bank encapsulating the SVT samples.
      * 
@@ -127,36 +135,13 @@
     }
     
     /**
-     *  Check whether a data bank is valid i.e. contains SVT samples only.  For
-     *  the engineering run, a valid data bank has a tag of 3.
-     * 
-     *  @param dataBank - An EVIO bank containing integer data
-     *  @return true if the bank is valid, false otherwise
-     * 
-     */
-    @Override
-    protected boolean isValidDataBank(BaseStructure dataBank) { 
-        
-        // The SVT configuration is stored in a bank with tag equal to 57614.
-        // All other event banks are invalid
-        if (dataBank.getHeader().getTag() == 57614) { 
-            
-            // Store the event bank for processing later.
-            eventBanks.add(dataBank);
-            
-            return false;
-        } else if (dataBank.getHeader().getTag() != 3) return false; 
-        
-        return true; 
-    }
-    
-    /**
      * Check whether the samples are valid. Specifically, check if the samples
      * are APV header or tails.
      * 
      * @param data : sample block of data
      * @return true if the samples are valid, false otherwise
      */
+    @Override
     protected boolean isValidSampleSet(int[] data) {
         return !(SvtEvioUtils.isMultisampleHeader(data) || SvtEvioUtils.isMultisampleTail(data));        
     }
@@ -191,9 +176,6 @@
            }
         }*/
         
-        // Clear out the event banks after they have been processed
-        eventBanks.clear();
-        
         return success;
     }
     

Modified: java/branches/HPSJAVA-409/evio/src/main/java/org/hps/evio/TestRunReconToEvio.java
 =============================================================================
--- java/branches/HPSJAVA-409/evio/src/main/java/org/hps/evio/TestRunReconToEvio.java	(original)
+++ java/branches/HPSJAVA-409/evio/src/main/java/org/hps/evio/TestRunReconToEvio.java	Wed Apr 27 11:11:32 2016
@@ -21,96 +21,96 @@
  */
 public class TestRunReconToEvio extends Driver {
 
-	EventWriter writer;
-	String rawCalorimeterHitCollectionName = "EcalDigitizedHits";
-	String evioOutputFile = "TestRunData.evio";
-	EventBuilder builder = null;
-	private int eventsWritten = 0;
-	EcalHitWriter ecalWriter = null;
-	SVTHitWriter svtWriter = null;
-	
-	Detector detector = null;
+    EventWriter writer;
+    String rawCalorimeterHitCollectionName = "EcalDigitizedHits";
+    String evioOutputFile = "TestRunData.evio";
+    EventBuilder builder = null;
+    private int eventsWritten = 0;
+    EcalHitWriter ecalWriter = null;
+    SVTHitWriter svtWriter = null;
+    
+    Detector detector = null;
 
-	public TestRunReconToEvio() {
-	}
-	
+    public TestRunReconToEvio() {
+    }
+    
     @Override
-    public void detectorChanged(Detector detector) {    	
-    	// set the detector
+    public void detectorChanged(Detector detector) {        
+        // set the detector
         this.detector = detector;
     }
 
-	public void setEvioOutputFile(String evioOutputFile) {
-		this.evioOutputFile = evioOutputFile;
-	}
+    public void setEvioOutputFile(String evioOutputFile) {
+        this.evioOutputFile = evioOutputFile;
+    }
 
-	public void setRawCalorimeterHitCollectionName(String rawCalorimeterHitCollectionName) {
-		this.rawCalorimeterHitCollectionName = rawCalorimeterHitCollectionName;
-		if (ecalWriter != null) {
-			ecalWriter.setHitCollectionName(rawCalorimeterHitCollectionName);
-		}
-	}
+    public void setRawCalorimeterHitCollectionName(String rawCalorimeterHitCollectionName) {
+        this.rawCalorimeterHitCollectionName = rawCalorimeterHitCollectionName;
+        if (ecalWriter != null) {
+            ecalWriter.setHitCollectionName(rawCalorimeterHitCollectionName);
+        }
+    }
 
-	protected void startOfData() {
-		try {
-			writer = new EventWriter(evioOutputFile);
-		} catch (EvioException e) {
-			throw new RuntimeException(e);
-		}
+    protected void startOfData() {
+        try {
+            writer = new EventWriter(evioOutputFile);
+        } catch (EvioException e) {
+            throw new RuntimeException(e);
+        }
 
-		ecalWriter = new EcalHitWriter();
-		ecalWriter.setDetector(detector);
-		ecalWriter.setHitCollectionName(rawCalorimeterHitCollectionName);
+        ecalWriter = new EcalHitWriter();
+        ecalWriter.setDetector(detector);
+        ecalWriter.setHitCollectionName(rawCalorimeterHitCollectionName);
 
-		svtWriter = new SVTHitWriter();
-	}
+        svtWriter = new SVTHitWriter();
+    }
 
-	protected void endOfData() {
-		System.out.println(this.getClass().getSimpleName() + " - wrote " + eventsWritten + " EVIO events in job.");
-		writer.close();		
-	}
+    protected void endOfData() {
+        System.out.println(this.getClass().getSimpleName() + " - wrote " + eventsWritten + " EVIO events in job.");
+        writer.close();     
+    }
 
-	protected void process(EventHeader event) {
+    protected void process(EventHeader event) {
 
-		if (!svtWriter.hasData(event)) {
-			return;
-		}
+        if (!svtWriter.hasData(event)) {
+            return;
+        }
 
-		// Make a new EVIO event.
-		builder = new EventBuilder(0, DataType.BANK, event.getEventNumber());
+        // Make a new EVIO event.
+        builder = new EventBuilder(0, DataType.BANK, event.getEventNumber());
 
-		// Write SVTData.
-		svtWriter.writeData(event, builder);
+        // Write SVTData.
+        svtWriter.writeData(event, builder);
 
-		// Write RawCalorimeterHit collection.
-		ecalWriter.writeData(event, builder);
-//		writeRawCalorimeterHits(event);
+        // Write RawCalorimeterHit collection.
+        ecalWriter.writeData(event, builder);
+//      writeRawCalorimeterHits(event);
 
-		// Write this EVIO event.
-		writeEvioEvent();
-	}
+        // Write this EVIO event.
+        writeEvioEvent();
+    }
 
-	private void writeEvioEvent() {
-		EvioBank eventIDBank = new EvioBank(EvioEventConstants.EVENTID_BANK_TAG, DataType.UINT32, 0);
-		int[] eventID = new int[3];
-		eventID[0] = eventsWritten;
-		eventID[1] = 0; //trigger type
-		eventID[2] = 0; //status
+    private void writeEvioEvent() {
+        EvioBank eventIDBank = new EvioBank(EvioEventConstants.EVENTID_BANK_TAG, DataType.UINT32, 0);
+        int[] eventID = new int[3];
+        eventID[0] = eventsWritten;
+        eventID[1] = 0; //trigger type
+        eventID[2] = 0; //status
 
-		try {
-			eventIDBank.appendIntData(eventID);
-			builder.addChild(builder.getEvent(), eventIDBank);
-		} catch (EvioException e) {
-			throw new RuntimeException(e);
-		}
-		builder.setAllHeaderLengths();
-		try {
-			writer.writeEvent(builder.getEvent());
-			++eventsWritten;
-		} catch (EvioException e) {
-			throw new RuntimeException(e);
-		} catch (IOException e) {
-			throw new RuntimeException(e);
-		}
-	}
+        try {
+            eventIDBank.appendIntData(eventID);
+            builder.addChild(builder.getEvent(), eventIDBank);
+        } catch (EvioException e) {
+            throw new RuntimeException(e);
+        }
+        builder.setAllHeaderLengths();
+        try {
+            writer.writeEvent(builder.getEvent());
+            ++eventsWritten;
+        } catch (EvioException e) {
+            throw new RuntimeException(e);
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
 }

Modified: java/branches/HPSJAVA-409/evio/src/main/java/org/hps/evio/TestRunSvtEvioReader.java
 =============================================================================
--- java/branches/HPSJAVA-409/evio/src/main/java/org/hps/evio/TestRunSvtEvioReader.java	(original)
+++ java/branches/HPSJAVA-409/evio/src/main/java/org/hps/evio/TestRunSvtEvioReader.java	Wed Apr 27 11:11:32 2016
@@ -6,7 +6,6 @@
 import org.hps.record.svt.SvtEvioUtils;
 import org.hps.record.svt.SvtHeaderDataInfo;
 import org.hps.util.Pair;
-import org.jlab.coda.jevio.BaseStructure;
 import org.lcsim.detector.tracker.silicon.HpsSiSensor;
 import org.lcsim.detector.tracker.silicon.HpsTestRunSiSensor;
 import org.lcsim.event.EventHeader;
@@ -18,8 +17,6 @@
  *  objects.
  * 
  *  @author Omar Moreno <[log in to unmask]>
- *  @date November 20, 2014
- *
  */
 public class TestRunSvtEvioReader extends AbstractSvtEvioReader {
 
@@ -30,6 +27,7 @@
     private static final int DATA_HEADER_LENGTH = 7;
     private static final int DATA_TAIL_LENGTH = 1; 
     private static final int MAX_FPGA_ID = 6;
+    public static final int MIN_DATA_BANK_TAG = 0;
     private static final int ROC_BANK_TAG = 3;
     private static final int ROC_BANK_NUMBER = -1; 
     
@@ -56,6 +54,16 @@
     @Override 
     protected int getMaxRocBankTag() { 
         return ROC_BANK_TAG; 
+    }
+    
+    @Override
+    protected int getMinDataBankTag() {
+        return MIN_DATA_BANK_TAG;
+    }
+
+    @Override
+    protected int getMaxDataBankTag() {
+        return MAX_FPGA_ID;
     }
     
     /**
@@ -131,26 +139,12 @@
     }
 
     /**
-     *  Check whether a data bank is valid i.e. contains SVT samples only.  For
-     *  the test run, a valid data bank has a tag in the range 0-6.
-     * 
-     *  @param dataBank - An EVIO bank containing integer data
-     *  @return true if the bank is valid, false otherwise
-     * 
-     */
-    @Override
-    protected boolean isValidDataBank(BaseStructure dataBank) { 
-        if (dataBank.getHeader().getTag() < 0 
-                || dataBank.getHeader().getTag() >= MAX_FPGA_ID) return false; 
-        return true; 
-    }
-    
-    /**
      * Check whether the samples are valid.
      * 
      * @param data : sample block of data
      * @return true if the samples are valid, false otherwise
      */
+    @Override
     protected boolean isValidSampleSet(int[] data) { 
         return true;        
     }

Modified: java/branches/HPSJAVA-409/evio/src/test/java/org/hps/evio/LCSimEngRunEventBuilderTest.java
 =============================================================================
--- java/branches/HPSJAVA-409/evio/src/test/java/org/hps/evio/LCSimEngRunEventBuilderTest.java	(original)
+++ java/branches/HPSJAVA-409/evio/src/test/java/org/hps/evio/LCSimEngRunEventBuilderTest.java	Wed Apr 27 11:11:32 2016
@@ -24,60 +24,60 @@
  */
 public class LCSimEngRunEventBuilderTest extends TestCase {
 
-	public void testLCSimEngRunEventBuilder() throws Exception {
-	    
-		// Setup database conditions.
-		DatabaseConditionsManager conditionsManager = DatabaseConditionsManager.getInstance();
-		conditionsManager.setXmlConfig("/org/hps/conditions/config/conditions_dev.xml");
-		conditionsManager.setDetector("HPS-Proposal2014-v8-6pt6", 2000);
+    public void testLCSimEngRunEventBuilder() throws Exception {
+        
+        // Setup database conditions.
+        DatabaseConditionsManager conditionsManager = DatabaseConditionsManager.getInstance();
+        conditionsManager.setXmlConfig("/org/hps/conditions/config/conditions_dev.xml");
+        conditionsManager.setDetector("HPS-Proposal2014-v8-6pt6", 2000);
 
-		// Configure LCIO writer.
-		new TestOutputFile(getClass().getSimpleName()).mkdirs();
-		File lcioFile = new TestOutputFile(getClass().getSimpleName() + File.separator + getClass().getSimpleName() + "_output.slcio");
-		LCIOWriter writer;
-		try {
-			writer = new LCIOWriter(lcioFile);
-		} catch (IOException e) {
-			throw new RuntimeException(e);
-		}
+        // Configure LCIO writer.
+        new TestOutputFile(getClass().getSimpleName()).mkdirs();
+        File lcioFile = new TestOutputFile(getClass().getSimpleName() + File.separator + getClass().getSimpleName() + "_output.slcio");
+        LCIOWriter writer;
+        try {
+            writer = new LCIOWriter(lcioFile);
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
 
-		// Create event builder.
-		LCSimEventBuilder builder = new LCSimEngRunEventBuilder();
-		conditionsManager.addConditionsListener(builder);
-		//builder.setDetectorName("HPS-Proposal2014-v8-6pt6");
-		conditionsManager.setDetector("HPS-Proposal2014-v8-6pt6", 2744);
+        // Create event builder.
+        LCSimEventBuilder builder = new LCSimEngRunEventBuilder();
+        conditionsManager.addConditionsListener(builder);
+        //builder.setDetectorName("HPS-Proposal2014-v8-6pt6");
+        conditionsManager.setDetector("HPS-Proposal2014-v8-6pt6", 2744);
 
-		// Get remote test file.
-		FileCache cache = new FileCache();
-		File evioFile = cache.getCachedFile(new URL("http://www.lcsim.org/test/hps-java/LCSimEngRunEventBuilderTest/hps_002744.evio.0"));
+        // Get remote test file.
+        FileCache cache = new FileCache();
+        File evioFile = cache.getCachedFile(new URL("http://www.lcsim.org/test/hps-java/LCSimEngRunEventBuilderTest/hps_002744.evio.0"));
 
-		// Open the EVIO reader.
-		System.out.println("Opening file " + evioFile);
-		EvioReader reader = null;
-		try {
-			reader = new EvioReader(evioFile);
-		} catch (Exception e) {
-			throw new RuntimeException(e);
-		}
+        // Open the EVIO reader.
+        System.out.println("Opening file " + evioFile);
+        EvioReader reader = null;
+        try {
+            reader = new EvioReader(evioFile);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
 
-		// Run the event builder on the EVIO.
-		EvioEvent evioEvent = null;
-		while ((evioEvent = reader.nextEvent()) != null) {
-			reader.parseEvent(evioEvent);
-			builder.readEvioEvent(evioEvent);
-			if (EvioEventUtilities.isPhysicsEvent(evioEvent)) {
-				try {
-					EventHeader lcsimEvent = builder.makeLCSimEvent(evioEvent);
-					System.out.println("created LCSim event #" + lcsimEvent.getEventNumber());
-					writer.write(lcsimEvent);
-				} catch (Exception e) {
-					e.printStackTrace();
-				}
-			}
-		}
+        // Run the event builder on the EVIO.
+        EvioEvent evioEvent = null;
+        while ((evioEvent = reader.nextEvent()) != null) {
+            reader.parseEvent(evioEvent);
+            builder.readEvioEvent(evioEvent);
+            if (EvioEventUtilities.isPhysicsEvent(evioEvent)) {
+                try {
+                    EventHeader lcsimEvent = builder.makeLCSimEvent(evioEvent);
+                    System.out.println("created LCSim event #" + lcsimEvent.getEventNumber());
+                    writer.write(lcsimEvent);
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            }
+        }
 
-		// Close the LCIO writer.
-		writer.flush();
-		writer.close();
-	}
+        // Close the LCIO writer.
+        writer.flush();
+        writer.close();
+    }
 }

Modified: java/branches/HPSJAVA-409/evio/src/test/java/org/hps/evio/LCSimTestRunEventBuilderTest.java
 =============================================================================
--- java/branches/HPSJAVA-409/evio/src/test/java/org/hps/evio/LCSimTestRunEventBuilderTest.java	(original)
+++ java/branches/HPSJAVA-409/evio/src/test/java/org/hps/evio/LCSimTestRunEventBuilderTest.java	Wed Apr 27 11:11:32 2016
@@ -15,60 +15,60 @@
 import org.hps.record.evio.EvioEventUtilities;
 
 /**
- * 	Integration test to check the conversion of test run EVIO to LCIO 
+ *  Integration test to check the conversion of test run EVIO to LCIO 
  * 
- * 	@author Omar Moreno <[log in to unmask]>
- *	@date November 20, 2014
+ *  @author Omar Moreno <[log in to unmask]>
+ *  @date November 20, 2014
  */
 public class LCSimTestRunEventBuilderTest extends TestCase {
 
-	//-----------------//
-	//--- Constants ---//
-	//-----------------//
-	private static final String DB_CONFIGURATION
-		= "/org/hps/conditions/config/conditions_database_testrun_2012.xml";
-	
-	public void testLCSimTestRunEventBuilder() throws Exception { 
-	
-		// Configure the conditions system to retrieve test run conditions fo run 1351.
-		DatabaseConditionsManager conditionsManager = DatabaseConditionsManager.getInstance();
-		conditionsManager.setXmlConfig(DB_CONFIGURATION);
-		
-		// Create the test run event builder
-		LCSimTestRunEventBuilder builder = new LCSimTestRunEventBuilder();
-		conditionsManager.addConditionsListener(builder);
+    //-----------------//
+    //--- Constants ---//
+    //-----------------//
+    private static final String DB_CONFIGURATION
+        = "/org/hps/conditions/config/conditions_database_testrun_2012.xml";
+    
+    public void testLCSimTestRunEventBuilder() throws Exception { 
+    
+        // Configure the conditions system to retrieve test run conditions fo run 1351.
+        DatabaseConditionsManager conditionsManager = DatabaseConditionsManager.getInstance();
+        conditionsManager.setXmlConfig(DB_CONFIGURATION);
+        
+        // Create the test run event builder
+        LCSimTestRunEventBuilder builder = new LCSimTestRunEventBuilder();
+        conditionsManager.addConditionsListener(builder);
 
-		conditionsManager.setDetector("HPS-TestRun-v5", 1351);
+        conditionsManager.setDetector("HPS-TestRun-v5", 1351);
 
-		// Retrieve the remote test file.  The file currently being contains a
-		// subset of events from run 1351
-		FileCache cache = new FileCache();
-		File evioFile = cache.getCachedFile(new URL("http://www.lcsim.org/test/hps-java/hps1351_test.evio"));
-	
-		// Instantiate the EVIO reader and open the test file.  If the file
-		// can't be found, throw a runtime exception
-		EvioReader reader = null;
-		try {
-			reader = new EvioReader(evioFile);
-		} catch (Exception e) {
-			throw new RuntimeException(
-					"[ " + this.getClass().getSimpleName() + " ]: EVIO file couldn't be opened.");
-		}
-		
-		// Loop through all EVIO events in the file and process them using the
-		// event builder.  If the event is a physics event, process the event
-		// using the subdetector readers.
-		EvioEvent evioEvent = null;
-		while ((evioEvent = reader.nextEvent()) != null) {
-			reader.parseEvent(evioEvent);
-			builder.readEvioEvent(evioEvent);
-			if (EvioEventUtilities.isPhysicsEvent(evioEvent)) {
-				EventHeader lcsimEvent = builder.makeLCSimEvent(evioEvent);
-				System.out.println("[ " + this.getClass().getSimpleName() + " ]: Created event number " + lcsimEvent.getEventNumber());
-			}
-		}
-		
-		// Close the EVIO reader
-		reader.close();
-	}
+        // Retrieve the remote test file.  The file currently being contains a
+        // subset of events from run 1351
+        FileCache cache = new FileCache();
+        File evioFile = cache.getCachedFile(new URL("http://www.lcsim.org/test/hps-java/hps1351_test.evio"));
+    
+        // Instantiate the EVIO reader and open the test file.  If the file
+        // can't be found, throw a runtime exception
+        EvioReader reader = null;
+        try {
+            reader = new EvioReader(evioFile);
+        } catch (Exception e) {
+            throw new RuntimeException(
+                    "[ " + this.getClass().getSimpleName() + " ]: EVIO file couldn't be opened.");
+        }
+        
+        // Loop through all EVIO events in the file and process them using the
+        // event builder.  If the event is a physics event, process the event
+        // using the subdetector readers.
+        EvioEvent evioEvent = null;
+        while ((evioEvent = reader.nextEvent()) != null) {
+            reader.parseEvent(evioEvent);
+            builder.readEvioEvent(evioEvent);
+            if (EvioEventUtilities.isPhysicsEvent(evioEvent)) {
+                EventHeader lcsimEvent = builder.makeLCSimEvent(evioEvent);
+                System.out.println("[ " + this.getClass().getSimpleName() + " ]: Created event number " + lcsimEvent.getEventNumber());
+            }
+        }
+        
+        // Close the EVIO reader
+        reader.close();
+    }
 }

Modified: java/branches/HPSJAVA-409/evio/src/test/java/org/hps/evio/SvtEvioReaderTest.java
 =============================================================================
--- java/branches/HPSJAVA-409/evio/src/test/java/org/hps/evio/SvtEvioReaderTest.java	(original)
+++ java/branches/HPSJAVA-409/evio/src/test/java/org/hps/evio/SvtEvioReaderTest.java	Wed Apr 27 11:11:32 2016
@@ -25,47 +25,47 @@
     // Initialize the logger
     protected static Logger LOGGER = Logger.getLogger(SvtEvioReaderTest.class.getPackage().getName());
     
-	public void testSvtEvioReaderTest() throws Exception { 
+    public void testSvtEvioReaderTest() throws Exception { 
 
-		// Get the EVIO file that will be used to test the reader
-		FileCache fileCache = new FileCache(); 
-		File evioFile = fileCache.getCachedFile(
-				new URL("http://www.lcsim.org/test/hps-java/svt_evio_reader_test.evio")); 
+        // Get the EVIO file that will be used to test the reader
+        FileCache fileCache = new FileCache(); 
+        File evioFile = fileCache.getCachedFile(
+                new URL("http://www.lcsim.org/test/hps-java/svt_evio_reader_test.evio")); 
 
-		LOGGER.info("Opening file " + evioFile); 
+        LOGGER.info("Opening file " + evioFile); 
 
-		// Instantiate the EVIO reader and open the file
-		EvioReader evioReader = new EvioReader(evioFile); 
-	
-		// Instantiate the SVT EVIO reader
-		SvtEvioReader svtReader = new SvtEvioReader(); 
+        // Instantiate the EVIO reader and open the file
+        EvioReader evioReader = new EvioReader(evioFile); 
+    
+        // Instantiate the SVT EVIO reader
+        SvtEvioReader svtReader = new SvtEvioReader(); 
 
-		// Setup the database conditions 
-		DatabaseConditionsManager conditionsManager = DatabaseConditionsManager.getInstance();
-		conditionsManager.setDetector("HPS-Proposal2014-v9-2pt2", 2000); 
+        // Setup the database conditions 
+        DatabaseConditionsManager conditionsManager = DatabaseConditionsManager.getInstance();
+        conditionsManager.setDetector("HPS-Proposal2014-v9-2pt2", 2000); 
 
-		// Instantiate the event builder
-		LCSimEventBuilder eventBuilder = new LCSimEngRunEventBuilder(); 
+        // Instantiate the event builder
+        LCSimEventBuilder eventBuilder = new LCSimEngRunEventBuilder(); 
 
-		// Check that the file contains the expected number of events
-		int eventCount = evioReader.getEventCount(); 
-		LOGGER.info("File " + evioFile + " contains " + eventCount + " events."); 
+        // Check that the file contains the expected number of events
+        int eventCount = evioReader.getEventCount(); 
+        LOGGER.info("File " + evioFile + " contains " + eventCount + " events."); 
 
 
-		// Loop through the EVIO events and process them.
-		EvioEvent evioEvent = null; 
-		while ((evioEvent = evioReader.nextEvent()) != null) { 
-			evioReader.parseEvent(evioEvent); 	
+        // Loop through the EVIO events and process them.
+        EvioEvent evioEvent = null; 
+        while ((evioEvent = evioReader.nextEvent()) != null) { 
+            evioReader.parseEvent(evioEvent);   
 
-			// Only process physics events
-			if (!EvioEventUtilities.isPhysicsEvent(evioEvent)) continue;
-			LOGGER.info("Found physics event."); 	
-	
-			EventHeader lcsimEvent = eventBuilder.makeLCSimEvent(evioEvent); 
-			LOGGER.info("Created LCSim event # " + lcsimEvent.getEventNumber()); 	
+            // Only process physics events
+            if (!EvioEventUtilities.isPhysicsEvent(evioEvent)) continue;
+            LOGGER.info("Found physics event.");    
+    
+            EventHeader lcsimEvent = eventBuilder.makeLCSimEvent(evioEvent); 
+            LOGGER.info("Created LCSim event # " + lcsimEvent.getEventNumber());    
 
-			// Process the event using the SVT evio reader
-			svtReader.processEvent(evioEvent, lcsimEvent);  
-		}
-	}
+            // Process the event using the SVT evio reader
+            svtReader.processEvent(evioEvent, lcsimEvent);  
+        }
+    }
 }

Modified: java/branches/HPSJAVA-409/integration-tests/pom.xml
 =============================================================================
--- java/branches/HPSJAVA-409/integration-tests/pom.xml	(original)
+++ java/branches/HPSJAVA-409/integration-tests/pom.xml	Wed Apr 27 11:11:32 2016
@@ -23,7 +23,7 @@
         <dependency>
             <groupId>org.hps</groupId>
             <artifactId>hps-test-data</artifactId>
-            <version>1.0.0-SNAPSHOT</version>
+            <version>1.0-SNAPSHOT</version>
             <scope>test</scope>
             <classifier>archive</classifier>
             <type>jar</type>
@@ -31,7 +31,7 @@
         <dependency>
             <groupId>org.hps</groupId>
             <artifactId>hps-test-data</artifactId>
-            <version>1.0.0-SNAPSHOT</version>
+            <version>1.0-SNAPSHOT</version>
             <scope>test</scope>
             <type>jar</type>
         </dependency>
@@ -51,7 +51,8 @@
                 <version>2.19</version>
                 <configuration>
                     <argLine>-server -Xmx2g -XX:MaxPermSize=512m -Djava.util.logging.config.class=org.hps.logging.config.TestLoggingConfig</argLine>
-                    <forkMode>always</forkMode>
+                    <forkCount>1</forkCount>
+                    <reuseForks>false</reuseForks>
                     <includes>
                         <include>org/hps/test/it/*Test.java</include>
                     </includes>
@@ -86,28 +87,5 @@
                 </plugins>
             </build>
         </profile> 
-        <!-- This profile activates automatically when not running tests on a SLAC Unix system with NFS access. -->
-        <profile>
-            <id>no-slac-nfs</id>
-            <activation>
-                <activeByDefault>false</activeByDefault>
-                <file>
-                    <missing>/nfs/slac/g/hps/</missing>
-                </file>
-            </activation>
-            <build>
-                <plugins>
-                    <plugin>
-                        <groupId>org.apache.maven.plugins</groupId>
-                        <artifactId>maven-surefire-plugin</artifactId>
-                        <configuration>
-                            <excludes>                           
-                                <exclude>org/hps/test/it/EvioToLcioTest.java</exclude> 
-                            </excludes>
-                        </configuration>
-                    </plugin>
-                </plugins>
-            </build>        
-        </profile>  
     </profiles>    
 </project>

Modified: java/branches/HPSJAVA-409/integration-tests/src/test/java/org/hps/test/it/DataQualityMonitorTest.java
 =============================================================================
--- java/branches/HPSJAVA-409/integration-tests/src/test/java/org/hps/test/it/DataQualityMonitorTest.java	(original)
+++ java/branches/HPSJAVA-409/integration-tests/src/test/java/org/hps/test/it/DataQualityMonitorTest.java	Wed Apr 27 11:11:32 2016
@@ -17,16 +17,14 @@
 
     private static final String CLASS_NAME = DataQualityMonitorTest.class.getSimpleName();
     private static final File OUTPUT_DIR = new File("./target/test-output/" + CLASS_NAME);
-    private static final File OUTPUT_FILE = new File(OUTPUT_DIR.getAbsolutePath() + File.separator + CLASS_NAME);
-    private static final File AIDA_FILE = new File(OUTPUT_FILE.getAbsolutePath() + ".aida");
+    private static final File OUTPUT_FILE = new File(OUTPUT_DIR.getAbsolutePath() + File.separator + CLASS_NAME + ".aida");
     private static final String STEERING_RESOURCE = "/org/hps/steering/test/DataQualityTest.lcsim";
 
     public void setUp() {
         
-        System.out.println("Setting up DQM Test");
         // Delete files if they already exist.     
-        if (AIDA_FILE.exists())
-            AIDA_FILE.delete();
+        if (OUTPUT_FILE.exists())
+            OUTPUT_FILE.delete();
 
         // Create output dir.
         OUTPUT_DIR.mkdirs();
@@ -36,11 +34,12 @@
 
     public void testQualityMonitor() {
         File dataFile = new TestDataUtility().getTestData("DataQualityMonitorTest.slcio");
-        System.out.println("running data quality job with steering resource " + STEERING_RESOURCE);
+        System.out.println("running data quality job with steering resource " + STEERING_RESOURCE + " ...");
         JobManager jobManager = new JobManager();
         jobManager.addVariableDefinition("outputFile", OUTPUT_FILE.getPath());
         jobManager.addInputFile(dataFile);
         jobManager.setup(STEERING_RESOURCE);
         jobManager.run();
+        System.out.println("Done!");
     }
 }

Modified: java/branches/HPSJAVA-409/integration-tests/src/test/java/org/hps/test/it/EvioToLcioTest.java
 =============================================================================
--- java/branches/HPSJAVA-409/integration-tests/src/test/java/org/hps/test/it/EvioToLcioTest.java	(original)
+++ java/branches/HPSJAVA-409/integration-tests/src/test/java/org/hps/test/it/EvioToLcioTest.java	Wed Apr 27 11:11:32 2016
@@ -1,5 +1,6 @@
 package org.hps.test.it;
 
+import java.io.File;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.logging.Level;
@@ -7,8 +8,8 @@
 
 import junit.framework.TestCase;
 
+import org.hps.data.test.TestDataUtility;
 import org.hps.evio.EvioToLcio;
-import org.hps.record.epics.EpicsData;
 import org.hps.record.scalers.ScalerData;
 import org.hps.test.util.TestOutputFile;
 import org.lcsim.event.EventHeader;
@@ -20,16 +21,6 @@
 /**
  * Basic test of converting EVIO to LCIO using the {@link org.hps.evio.EvioToLcio} command line utility on Engineering
  * Run 2015 data.
- * <p>
- * This test checks the LCIO output for the:</br>
- * <ul>
- * <li>correct number of EPICS data collections</li>
- * <li>correct number of scaler data collections</li>
- * <li>all expected event collections</li>
- * <li>scaler parameters in event header</li>
- * </ul>
- * <p>
- * The test input is the first file of run 5772 in which scaler data appears around every 100k events.
  *
  * @author Jeremy McCormick, SLAC
  */
@@ -45,12 +36,7 @@
          * Map to keep track of number of events with empty collections.
          */
         Map<String, Integer> emptyCollections = new HashMap<String, Integer>();
-
-        /**
-         * Number of EPICS data collections found.
-         */
-        int epicsDataCount = 0;
-
+       
         /**
          * Number of events processed.
          */
@@ -60,6 +46,12 @@
          * Number of scaler data collections found.
          */
         int scalerDataCount = 0;
+        
+        CheckDriver() {
+            for (String collectionName : COLLECTION_NAMES) {
+                emptyCollections.put(collectionName, new Integer(0));
+            }
+        }
 
         /**
          * Check a collection by making sure it is present in the event and incrementing a counter if it is empty.
@@ -72,13 +64,9 @@
             if (!event.hasCollection(type, name)) {
                 throw new RuntimeException("Missing " + name + " collection.");
             }
+            Integer nEmpty = emptyCollections.get(name);
             if (event.get(type, name).isEmpty()) {
-                Integer nEmpty = emptyCollections.get(name);
-                if (nEmpty == null) {
-                    nEmpty = 0;
-                }
                 ++nEmpty;
-                // System.out.println(name + " is empty in event " + event.getEventNumber());
                 emptyCollections.put(name, nEmpty);
             }
         }
@@ -88,17 +76,7 @@
                 this.checkCollection(event, COLLECTION_TYPES[i], COLLECTION_NAMES[i]);
             }
         }
-
-        private void checkEpicsData(final EventHeader event) {
-            final EpicsData epicsData = EpicsData.read(event);
-            if (epicsData != null) {
-                if (epicsData.getEpicsHeader() == null) {
-                    throw new RuntimeException("The EpicsData header is null.");
-                }
-                ++epicsDataCount;
-            }
-        }
-
+ 
         private void checkScalarData(final EventHeader event) {
             final ScalerData scalerData = ScalerData.read(event);
             if (scalerData != null) {
@@ -113,10 +91,7 @@
          */
         @Override
         public void process(final EventHeader event) {
-
-            // Find and check EPICS data.
-            this.checkEpicsData(event);
-
+          
             // Find scaler data.
             this.checkScalarData(event);
 
@@ -128,41 +103,34 @@
     }
 
     /**
-     * The number of empty collections that are allowed.
-     */
-    private static int[] ALLOWED_EMPTY = new int[] {45, 0, 0, 0};
-
-    /**
      * Names of collections to check.
      */
-    private static String[] COLLECTION_NAMES = new String[] {"EcalReadoutHits", "FADCGenericHits", "SVTRawTrackerHits",
-            "TriggerBank"};
+    private static String[] COLLECTION_NAMES = new String[] {
+        "EcalReadoutHits", 
+        "FADCGenericHits", 
+        "SVTRawTrackerHits",
+        "TriggerBank"
+    };
 
     /**
      * Classes of collections.
      */
-    private static Class<?>[] COLLECTION_TYPES = new Class<?>[] {RawTrackerHit.class, GenericObject.class,
-            RawTrackerHit.class, GenericObject.class};
-
-    /**
-     * The number of EPICS collections that should be found.
-     */
-    private static int EPICS_DATA_COUNT = 7;
-
-    /**
-     * The default input file (large file at SLAC so the pom.xml file excludes this test on non-SLAC hosts).
-     */
-    private static final String INPUT_FILE = "/nfs/slac/g/hps3/data/engrun2015/evio/hps_005772.evio.0";
+    private static Class<?>[] COLLECTION_TYPES = new Class<?>[] {
+        RawTrackerHit.class, 
+        GenericObject.class,
+        RawTrackerHit.class, 
+        GenericObject.class
+    };
 
     /**
      * The number of events that should be processed.
      */
-    private static int PROCESSED_COUNT = 251823;
+    private static int PROCESSED_COUNT = 1000;
 
     /**
      * The number of scaler data collections that should be found.
      */
-    private static int SCALER_DATA_COUNT = 3;
+    private static int SCALER_DATA_COUNT = 1;
    
     /**
      * Run the test.
@@ -171,13 +139,15 @@
      */
     public void testEvioToLcio() throws Exception {
 
+        final File inputFile = new TestDataUtility().getTestData("run5772_integrationTest.evio");
+        
         // LCIO output file.
         final TestOutputFile outputFile = new TestOutputFile(EvioToLcioTest.class, "hps_005772.slcio");
 
         // Run the command line utility.
         final String[] args = new String[] {"-l", outputFile.getPath(), "-d", "HPS-EngRun2015-Nominal-v1", "-r", "-x", 
-                "/org/hps/steering/EventMarker.lcsim", INPUT_FILE};
-        System.out.println("Running EvioToLcio on " + INPUT_FILE);
+                "/org/hps/steering/EventMarker.lcsim", inputFile.getAbsolutePath()};
+        System.out.println("Running EvioToLcio on " + inputFile.getPath());
         Logger.getLogger("org.hps.evio").setLevel(Level.WARNING);
         System.out.println("org.hps.evio logging level is " + Logger.getLogger("org.hps.evio").getLevel());
         EvioToLcio cnv = new EvioToLcio();
@@ -188,9 +158,6 @@
         System.out.println("Done running EvioToLcio!");
         System.out.println("conversion to LCIO took " + elapsed + " ms");
         
-        // Check that the conversion did not take too long.
-        //assertTrue("Conversion from EVIO to LCIO took too long.", elapsed < 2000000);
-
         // Read in the LCIO file and run the CheckDriver on it.
         System.out.println("Checking LCIO output ...");
         final LCSimLoop loop = new LCSimLoop();
@@ -209,22 +176,15 @@
         System.out.println("CheckDriver processed " + checkDriver.processedCount + " events.");
         assertEquals("Wrong number of events processed by the check Driver.", PROCESSED_COUNT, checkDriver.processedCount);
 
-        // Check that the correct number of EPICS data collections were written out.
-        System.out.println("Found " + checkDriver.epicsDataCount + " events with EPICS data.");
-        assertTrue("EPICS data count is wrong.", checkDriver.epicsDataCount == EPICS_DATA_COUNT);
-
         // Check that the correct number of scaler data collections were written out.
         System.out.println("Found " + checkDriver.scalerDataCount + " events with scaler data.");
         assertTrue("Scaler data count is wrong.", checkDriver.scalerDataCount == SCALER_DATA_COUNT);
-
-        // Check that there were not too many empty collections.  
+        
+        // Check that there were no empty output collections.
         for (int i = 0; i < COLLECTION_NAMES.length; i++) {
             final String collection = COLLECTION_NAMES[i];
             final Integer nEmpty = checkDriver.emptyCollections.get(collection);
-            if (nEmpty != null) {
-                System.out.println(collection + " had " + nEmpty + " empty collections.");
-                assertTrue(collection + " had too many empty collections.", nEmpty <= ALLOWED_EMPTY[i]);
-            }
+            assertTrue("Collection " + collection + " was empty.", nEmpty == 0);
         }
     }
 }

Modified: java/branches/HPSJAVA-409/integration-tests/src/test/java/org/hps/test/it/ReconSteeringTest.java
 =============================================================================
--- java/branches/HPSJAVA-409/integration-tests/src/test/java/org/hps/test/it/ReconSteeringTest.java	(original)
+++ java/branches/HPSJAVA-409/integration-tests/src/test/java/org/hps/test/it/ReconSteeringTest.java	Wed Apr 27 11:11:32 2016
@@ -1,100 +1,42 @@
 package org.hps.test.it;
 
 import java.io.File;
-import java.io.IOException;
-import java.net.URL;
 
 import junit.framework.TestCase;
 
 import org.hps.data.test.TestDataUtility;
 import org.hps.job.JobManager;
-import org.lcsim.util.cache.FileCache;
 import org.lcsim.util.test.TestUtil.TestOutputFile;
 
 /**
- * Test that production MC recon steering files are not broken by running an LCSim job on them
- * using an LCIO file.
+ * Run a test job on Eng Run 2015 data.
  * 
  * @author Jeremy McCormick, SLAC
  */
 public class ReconSteeringTest extends TestCase {
     
-    /**
-     * List of steering files to run.
-     */
-    final static String[] STEERING_FILES = {
-        "EngineeringRun2014EcalRecon_Pass1.lcsim",
-        "EngineeringRun2014EcalRecon.lcsim",
-        "EngineeringRun2015EcalRecon.lcsim",
-        "EngineeringRun2015FullRecon.lcsim",
-        "EngineeringRun2015FullRecon_Pass2.lcsim",
-        "EngineeringRun2015HitRecon.lcsim",
-        "HPSTrackingDefaultsRecon.lcsim"
-    };
-            
-    /**
-     * Test recon steering files.
-     * @throws Exception if any error occurs running the recon job
-     */
-    public void testSteeringFiles() {
+    final static String STEERING_RESOURCE = "/org/hps/steering/recon/EngineeringRun2015FullRecon.lcsim";
+              
+    public void testReconSteering() throws Exception {
         
-        File inputFile = new TestDataUtility().getTestData("tritrigv1-egsv3-triv2-g4v1_s2d6_HPS-EngRun2015-Nominal-v3_3.4.0_pairs1_1.slcio");
-        
-        for (String steeringFile : STEERING_FILES) {
-            
-            // Run the reconstruction steering file.
-            File outputFile = null;
-            try {
-                outputFile = new TestOutputFile(new File(steeringFile).getName().replace(".lcsim", ""));
-                runSteering("/org/hps/steering/recon/" + steeringFile, inputFile, outputFile);
-            } catch (Throwable e) {
-                System.err.println("Job with steering " + steeringFile + " failed!");
-                throw new RuntimeException("Recon job failed.", e);
-            }
-            
-            Runtime runtime = Runtime.getRuntime();
-            
-            int mb = 1024 * 1024;
-            
-            System.out.println("total memory: " + runtime.totalMemory() / mb);
-            System.out.println("free memory: " + runtime.freeMemory() / mb);
-            System.out.println("max memory: " + runtime.maxMemory() / mb);
-            System.out.println("used memory: " + (runtime.totalMemory() - runtime.freeMemory()) / mb);
-            
-            System.gc();
-            
-            // Create DQM output for QA.
-            try {
-                runDQM(outputFile);
-            } catch (Throwable e) {
-                throw new RuntimeException("The DQM job failed.", e);
-            }
-        }
-    }
-       
-    private void runSteering(String steeringFile, File inputFile, File outputFile) {
-        System.out.println("Testing steering file " + steeringFile + " ...");
+        File inputFile = new TestDataUtility().getTestData("run_5772_data_only.slcio");
+                           
+        File outputFile = null;
+        outputFile = new TestOutputFile(new File(STEERING_RESOURCE).getName().replace(".lcsim", ""));
+        System.out.println("Testing steering " + STEERING_RESOURCE + " ...");
         JobManager job = new JobManager();
         job.addVariableDefinition("outputFile", outputFile.getPath());
-        job.addVariableDefinition("detector", "HPS-EngRun2015-Nominal-v3");
-        job.addVariableDefinition("run", "5772");
-        job.addVariableDefinition("isMC", "true");
         job.addInputFile(inputFile);
-        job.setup(steeringFile);
+        job.setup(STEERING_RESOURCE);
+        job.setNumberOfEvents(1000);
         job.run();
-        System.out.println("Job with steering " + steeringFile + " successfully processed " + job.getLCSimLoop().getTotalCountableConsumed() + " events.");
-    }
-    
-    private void runDQM(File outputFile) {
-        System.out.println("Running DQM on " + outputFile.getPath() + " ...");
-        JobManager job = new JobManager();
-        File inputFile = new File(outputFile.getPath() + ".slcio");
-        job.addInputFile(inputFile);
-        job.addVariableDefinition("outputFile", outputFile.getPath().replace(".slcio", ""));
-        job.setup("/org/hps/steering/production/DataQualityRecon.lcsim");
-        job.run();
-        System.out.println("DQM processed " + job.getLCSimLoop().getTotalCountableConsumed() + " events from " + outputFile + ".");
+        System.out.println("Done processing " + job.getLCSimLoop().getTotalCountableConsumed() + " events.");
+                            
+        Runtime runtime = Runtime.getRuntime();
+        int mb = 1024 * 1024; 
+        System.out.printf("total memory: %d mb\n", runtime.totalMemory() / mb); 
+        System.out.printf("free memory: %d mb\n", runtime.freeMemory() / mb);
+        System.out.printf("max memory: %d mb\n", runtime.maxMemory() / mb);
+        System.out.printf("used memory: %d mb\n", (runtime.totalMemory() - runtime.freeMemory()) / mb);
     }
 }
-
-

Modified: java/branches/HPSJAVA-409/integration-tests/src/test/java/org/hps/test/it/SimpleSvtReadoutTest.java
 =============================================================================
--- java/branches/HPSJAVA-409/integration-tests/src/test/java/org/hps/test/it/SimpleSvtReadoutTest.java	(original)
+++ java/branches/HPSJAVA-409/integration-tests/src/test/java/org/hps/test/it/SimpleSvtReadoutTest.java	Wed Apr 27 11:11:32 2016
@@ -26,14 +26,14 @@
     // Collection Names
     static final String rawTrackerHitCollectionName = "SVTRawTrackerHits";
     
-	public void testSimpleSvtReadout() throws Exception { 
-				
-		File inputFile = new TestDataUtility().getTestData("ReadoutToLcioTest.slcio");
-			        
+    public void testSimpleSvtReadout() throws Exception { 
+                
+        File inputFile = new TestDataUtility().getTestData("ReadoutToLcioTest.slcio");
+                    
         outputDir.mkdirs();
         if(!outputDir.exists()){ 
-        	this.printDebug("Failed to create directory " + outputDir.getPath());
-        	throw new RuntimeException("Failed to create output directory.");
+            this.printDebug("Failed to create directory " + outputDir.getPath());
+            throw new RuntimeException("Failed to create output directory.");
         }
         
         FinalCheckDriver checker = new FinalCheckDriver();
@@ -54,25 +54,25 @@
         this.printDebug("");
         this.printDebug("===============================");
         
-	}
-	
-	class FinalCheckDriver extends Driver { 
-	
-		private int totalRawTrackerHits = 0; 
-		
-		public void process(EventHeader event){
-			if(!event.hasCollection(RawTrackerHit.class, rawTrackerHitCollectionName)) return;
-			List<RawTrackerHit> rawHits = event.get(RawTrackerHit.class, rawTrackerHitCollectionName);
-		
-			totalRawTrackerHits += rawHits.size();
-		}
-		
-		public int getTotalNumberOfRawTrackerHits(){
-			return totalRawTrackerHits;
-		}
-	}
-	
-	private void printDebug(String message){
-		System.out.println("[ SimpleSvtReadoutTest ]: " + message);
-	}
+    }
+    
+    class FinalCheckDriver extends Driver { 
+    
+        private int totalRawTrackerHits = 0; 
+        
+        public void process(EventHeader event){
+            if(!event.hasCollection(RawTrackerHit.class, rawTrackerHitCollectionName)) return;
+            List<RawTrackerHit> rawHits = event.get(RawTrackerHit.class, rawTrackerHitCollectionName);
+        
+            totalRawTrackerHits += rawHits.size();
+        }
+        
+        public int getTotalNumberOfRawTrackerHits(){
+            return totalRawTrackerHits;
+        }
+    }
+    
+    private void printDebug(String message){
+        System.out.println("[ SimpleSvtReadoutTest ]: " + message);
+    }
 }

Modified: java/branches/HPSJAVA-409/integration-tests/src/test/resources/org/hps/ecalreadoutsim/EcalReadoutSimTest.lcsim
 =============================================================================
--- java/branches/HPSJAVA-409/integration-tests/src/test/resources/org/hps/ecalreadoutsim/EcalReadoutSimTest.lcsim	(original)
+++ java/branches/HPSJAVA-409/integration-tests/src/test/resources/org/hps/ecalreadoutsim/EcalReadoutSimTest.lcsim	Wed Apr 27 11:11:32 2016
@@ -32,7 +32,7 @@
         <driver name="TestRunReconToLcio" type="org.hps.evio.TestRunTriggeredReconToLcio">
             <outputFile>${outputFile}.slcio</outputFile>
         </driver>
-			
+            
         <driver name="EcalReadout" type="org.hps.readout.ecal.FADCEcalReadoutDriver">
             <coincidenceWindow>1</coincidenceWindow>
             <ecalName>Ecal</ecalName>
@@ -50,7 +50,7 @@
             <applyBadCrystalMap>false</applyBadCrystalMap>
             <use2014Gain>true</use2014Gain>
 <!--            <debug>true</debug>-->
-        </driver>	
+        </driver>   
 
         <driver name="EcalClusterer" type="org.hps.recon.ecal.GTPEcalClusterer">
             <ecalName>Ecal</ecalName>
@@ -63,7 +63,7 @@
             <deadTime>10</deadTime>
             <pairCoincidence>2</pairCoincidence>
             <outputFileName>${outputFile}.triggers</outputFileName>
-        </driver>	
+        </driver>   
         <driver name="SimpleSVTReadout" type="org.hps.readout.svt.SimpleSvtReadout">
             <addNoise>false</addNoise>
         </driver>
@@ -74,4 +74,4 @@
         </driver> 
     </drivers>
 </lcsim>
-	
+    

Modified: java/branches/HPSJAVA-409/integration-tests/src/test/resources/org/hps/steering/test/DataQualityTest.lcsim
 =============================================================================
--- java/branches/HPSJAVA-409/integration-tests/src/test/resources/org/hps/steering/test/DataQualityTest.lcsim	(original)
+++ java/branches/HPSJAVA-409/integration-tests/src/test/resources/org/hps/steering/test/DataQualityTest.lcsim	Wed Apr 27 11:11:32 2016
@@ -18,13 +18,12 @@
         <driver name="CleanupDriver"/>
     </execute>    
     <drivers>    
-        <!--    <driver name="DQMDatabaseDriver" type="org.hps.analysis.dataquality.DQMDatabaseDriver"/> -->
         <driver name="EventMarkerDriver" type="org.lcsim.job.EventMarkerDriver">
-            <eventInterval>1</eventInterval>
+            <eventInterval>100</eventInterval>
         </driver>        
         <driver name="RawTrackerHitSensorSetup" type="org.lcsim.recon.tracking.digitization.sisim.config.RawTrackerHitSensorSetup"/>
         <driver name="AidaSaveDriver" type="org.lcsim.job.AidaSaveDriver">
-            <outputFileName>${outputFile}.root</outputFileName>
+            <outputFileName>${outputFile}</outputFileName>
         </driver>
         <driver name="SVTMonitoring" type="org.hps.analysis.dataquality.SvtMonitoring">
             <overwriteDB>false</overwriteDB>
@@ -48,6 +47,5 @@
             <overwriteDB>false</overwriteDB>
         </driver>
         <driver name="CleanupDriver" type="org.lcsim.recon.tracking.digitization.sisim.config.ReadoutCleanupDriver"/>
-
     </drivers>
 </lcsim>

Modified: java/branches/HPSJAVA-409/integration-tests/src/test/resources/org/hps/steering/test/Dummy.lcsim
 =============================================================================
--- java/branches/HPSJAVA-409/integration-tests/src/test/resources/org/hps/steering/test/Dummy.lcsim	(original)
+++ java/branches/HPSJAVA-409/integration-tests/src/test/resources/org/hps/steering/test/Dummy.lcsim	Wed Apr 27 11:11:32 2016
@@ -10,4 +10,4 @@
         <driver name="DummyDriver" type="org.hps.test.util.DummyDriver"/>
     </drivers>
 </lcsim>
-	
+    

Modified: java/branches/HPSJAVA-409/integration-tests/src/test/resources/org/hps/steering/test/EcalReadoutSimTest.lcsim
 =============================================================================
--- java/branches/HPSJAVA-409/integration-tests/src/test/resources/org/hps/steering/test/EcalReadoutSimTest.lcsim	(original)
+++ java/branches/HPSJAVA-409/integration-tests/src/test/resources/org/hps/steering/test/EcalReadoutSimTest.lcsim	Wed Apr 27 11:11:32 2016
@@ -28,7 +28,7 @@
         <driver name="TestRunReconToLcio" type="org.hps.evio.TestRunTriggeredReconToLcio">
             <outputFile>${outputFile}.slcio</outputFile>
         </driver>
-			
+            
         <driver name="EcalReadout" type="org.hps.readout.ecal.FADCEcalReadoutDriver">
             <coincidenceWindow>1</coincidenceWindow>
             <ecalName>Ecal</ecalName>
@@ -46,7 +46,7 @@
             <applyBadCrystalMap>false</applyBadCrystalMap>
             <use2014Gain>true</use2014Gain>
 <!--            <debug>true</debug>-->
-        </driver>	
+        </driver>   
 
         <driver name="EcalClusterer" type="org.hps.recon.ecal.GTPEcalClusterer">
             <ecalName>Ecal</ecalName>
@@ -59,7 +59,7 @@
             <deadTime>10</deadTime>
             <pairCoincidence>2</pairCoincidence>
             <outputFileName>${outputFile}.triggers</outputFileName>
-        </driver>	
+        </driver>   
         <driver name="SimpleSVTReadout" type="org.hps.readout.svt.SimpleSvtReadout">
             <addNoise>false</addNoise>
         </driver>
@@ -70,4 +70,4 @@
         </driver> 
     </drivers>
 </lcsim>
-	
+    

Modified: java/branches/HPSJAVA-409/job/pom.xml
 =============================================================================
--- java/branches/HPSJAVA-409/job/pom.xml	(original)
+++ java/branches/HPSJAVA-409/job/pom.xml	Wed Apr 27 11:11:32 2016
@@ -7,7 +7,7 @@
         <groupId>org.hps</groupId>
         <artifactId>hps-parent</artifactId>
         <relativePath>../parent/pom.xml</relativePath>
-        <version>3.4.2-SNAPSHOT</version>
+        <version>3.9-SNAPSHOT</version>
     </parent>
     <scm>
         <url>http://java.freehep.org/svn/repos/hps/list/java/trunk/job/</url>
@@ -19,5 +19,9 @@
             <groupId>org.hps</groupId>
             <artifactId>hps-detector-model</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.hps</groupId>
+            <artifactId>hps-run-database</artifactId>
+        </dependency>        
     </dependencies>
 </project>

Modified: java/branches/HPSJAVA-409/job/src/main/java/org/hps/job/JobManager.java
 =============================================================================
--- java/branches/HPSJAVA-409/job/src/main/java/org/hps/job/JobManager.java	(original)
+++ java/branches/HPSJAVA-409/job/src/main/java/org/hps/job/JobManager.java	Wed Apr 27 11:11:32 2016
@@ -1,20 +1,25 @@
 package org.hps.job;
 
-import java.io.InputStream;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.lcsim.util.Driver;
 
 import org.hps.conditions.ConditionsDriver;
-import org.hps.conditions.database.DatabaseConditionsManager;
-import org.hps.detector.svt.SvtDetectorSetup;
+
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Options;
 import org.lcsim.job.JobControlManager;
-import org.lcsim.util.Driver;
 
 /**
- * Extension of standard LCSim job manager which does some HPS-specific management of the conditions system.
+ * Extension of standard LCSim job manager.
+ * <p>
+ * Provides setup of database conditions system and adds option to provide conditions system tags.
  *
  * @author Jeremy McCormick, SLAC
  */
-public class JobManager extends JobControlManager {
-
+public final class JobManager extends JobControlManager {
+    
     /**
      * Run the job manager from the command line.
      *
@@ -31,58 +36,58 @@
      * Class constructor.
      */
     public JobManager() {
+        conditionsSetup = new DatabaseConditionsManagerSetup();
+    }
+    
+    /**
+     * Get the conditions setup.
+     * @return the conditions setup
+     */
+    public DatabaseConditionsManagerSetup getDatabaseConditionsManagerSetup() {
+        return (DatabaseConditionsManagerSetup) this.conditionsSetup;
+    }
+    
+    /**
+     * Override creation of command line options.
+     * @return the overridden command line options
+     */
+    @Override
+    protected Options createCommandLineOptions() {
+        Options options = super.createCommandLineOptions();
+        options.addOption("t", "tag", true, "conditions system tag (can be used multiple times)");
+        return options;
+    }
+    
+    /**
+     * Override command line parsing.
+     * @return the overridden, parsed command line
+     */
+    @Override
+    public CommandLine parse(final String args[]) {
+        CommandLine commandLine = super.parse(args);
+        if (commandLine.hasOption("t")) {
+            Set<String> tags = new HashSet<String>();
+            for (String tag : commandLine.getOptionValues("t")) {
+                tags.add(tag);
+            }
+            getDatabaseConditionsManagerSetup().setTags(tags);
+        }
+        return commandLine;
     }
 
     /**
-     * Override setup so the conditions system can be reset.
-     * 
-     * @param is the input stream containing config information
-     */
-    public void setup(InputStream is) {
-        
-        // Add class that will setup SVT detector with conditions data (this is awkward but has to be done someplace).
-        DatabaseConditionsManager.getInstance().addConditionsListener(new SvtDetectorSetup());
-        
-        super.setup(is);
-                
-        // Setup the conditions system if there is a ConditionsDriver present.
-        this.setupConditionsDriver();
-    }
-    
-    /**
-     * Override the parent classes method that runs the job in order to perform conditions system initialization.
-     *
-     * @return <code>true</code> if job was successful
-     */
-    @Override
-    public final boolean run() {
-        
-        // Run the job.
-        final boolean result = super.run();
-
-        // Close the conditions database connection if it is open.
-        DatabaseConditionsManager.getInstance().closeConnection();
-
-        return result;
-    }
-
-    /**
-     * This method will find the {@link org.hps.conditions.ConditionsDriver} in the list of Drivers registered with the
-     * manager and then execute its initialization method, which may override the default behavior of the conditions
-     * system.
-     */
-    private void setupConditionsDriver() {
-        ConditionsDriver conditionsDriver = null;
-        for (final Driver driver : this.getDriverAdapter().getDriver().drivers()) {
+     * Initialize <code>ConditionsDriver</code> if necessary.
+     **/
+    protected void setupDrivers() {
+        super.setupDrivers();
+        for (Driver driver : this.getDriverExecList()) {
             if (driver instanceof ConditionsDriver) {
-                conditionsDriver = (ConditionsDriver) driver;
+                ConditionsDriver conditions = (ConditionsDriver) driver;
+                getConditionsSetup().setRun(conditions.getRunNumber());
+                getConditionsSetup().setDetectorName(conditions.getDetectorName());
                 break;
             }
         }
-        if (conditionsDriver != null) {
-            LOGGER.config("initializing conditions Driver");            
-            conditionsDriver.initialize();
-            LOGGER.warning("Conditions driver will be removed soon!");
-        }
     }
+
 }

Modified: java/branches/HPSJAVA-409/logging/pom.xml
 =============================================================================
--- java/branches/HPSJAVA-409/logging/pom.xml	(original)
+++ java/branches/HPSJAVA-409/logging/pom.xml	Wed Apr 27 11:11:32 2016
@@ -7,7 +7,7 @@
         <groupId>org.hps</groupId>
         <artifactId>hps-parent</artifactId>
         <relativePath>../parent/pom.xml</relativePath>
-        <version>3.4.2-SNAPSHOT</version>
+        <version>3.9-SNAPSHOT</version>
     </parent>
     <scm>
         <url>http://java.freehep.org/svn/repos/hps/list/java/trunk/logging/</url>

Modified: java/branches/HPSJAVA-409/logging/src/main/resources/org/hps/logging/config/logging.properties
 =============================================================================
--- java/branches/HPSJAVA-409/logging/src/main/resources/org/hps/logging/config/logging.properties	(original)
+++ java/branches/HPSJAVA-409/logging/src/main/resources/org/hps/logging/config/logging.properties	Wed Apr 27 11:11:32 2016
@@ -16,6 +16,9 @@
 # configure the console handler
 java.util.logging.ConsoleHandler.level = ALL
 java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
+
+# turn minuit logging off
+org.freehep.math.minuit = OFF
 
 # lcsim job
 org.lcsim.job.level = CONFIG
@@ -49,7 +52,6 @@
 # ecal-recon
 org.hps.recon.ecal.level = CONFIG
 org.hps.recon.ecal.cluster.level = WARNING
-org.hps.recon.ecal.cluster.ClusterDriver.level = WARNING
 
 # recon
 org.hps.recon.filtering.level = WARNING
@@ -75,7 +77,7 @@
 # detector-model
 org.lcsim.detector.converter.compact.level = INFO
 org.lcsim.geometry.compact.converter.level = INFO
-org.hps.detector.svt.level = ALL
+org.hps.detector.svt.level = INFO
 
 # test data
 org.hps.data.test = INFO

Modified: java/branches/HPSJAVA-409/logging/src/main/resources/org/hps/logging/config/test_logging.properties
 =============================================================================
--- java/branches/HPSJAVA-409/logging/src/main/resources/org/hps/logging/config/test_logging.properties	(original)
+++ java/branches/HPSJAVA-409/logging/src/main/resources/org/hps/logging/config/test_logging.properties	Wed Apr 27 11:11:32 2016
@@ -16,15 +16,18 @@
 # configure the console handler
 java.util.logging.ConsoleHandler.level = ALL
 java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
-f
+
+# turn minuit off
+org.freehep.math.minuit = OFF
+
 # lcsim job
-org.lcsim.job.level = WARNING
+org.lcsim.job.level = CONFIG
 org.lcsim.job.EventMarkerDriver.level = OFF
 org.lcsim.job.EventPrintLoopAdapter = ALL
 
 # conditions
 org.hps.conditions.api.level = WARNING
-org.hps.conditions.database.level = CONFIG
+org.hps.conditions.database.level = WARNING
 org.hps.conditions.cli.level = WARNING
 org.hps.conditions.ecal.level = WARNING
 org.hps.conditions.svt.level = WARNING
@@ -44,12 +47,11 @@
 org.hps.crawler.level = WARNING
 
 # datacat
-org.hps.datacat.client.level = ALL
+org.hps.datacat.client.level = OFF
 
 # ecal-recon
 org.hps.recon.ecal.level = WARNING
 org.hps.recon.ecal.cluster.level = WARNING
-org.hps.recon.ecal.cluster.ClusterDriver.level = WARNING
 
 # recon
 org.hps.recon.filtering.level = WARNING
@@ -79,3 +81,6 @@
 
 # test data
 org.hps.data.test = INFO
+
+# HPS job manager
+org.hps.job.JobManager = WARNING

Modified: java/branches/HPSJAVA-409/monitoring-app/pom.xml
 =============================================================================
--- java/branches/HPSJAVA-409/monitoring-app/pom.xml	(original)
+++ java/branches/HPSJAVA-409/monitoring-app/pom.xml	Wed Apr 27 11:11:32 2016
@@ -7,7 +7,7 @@
         <groupId>org.hps</groupId>
         <artifactId>hps-parent</artifactId>
         <relativePath>../parent/pom.xml</relativePath>
-        <version>3.4.2-SNAPSHOT</version>
+        <version>3.9-SNAPSHOT</version>
     </parent>
     <scm>
         <url>http://java.freehep.org/svn/repos/hps/list/java/trunk/monitoring-app/</url>

Modified: java/branches/HPSJAVA-409/monitoring-app/src/main/java/org/hps/monitoring/application/EventProcessing.java
 =============================================================================
--- java/branches/HPSJAVA-409/monitoring-app/src/main/java/org/hps/monitoring/application/EventProcessing.java	(original)
+++ java/branches/HPSJAVA-409/monitoring-app/src/main/java/org/hps/monitoring/application/EventProcessing.java	Wed Apr 27 11:11:32 2016
@@ -6,11 +6,14 @@
 import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 import java.util.logging.Logger;
 
 import org.freehep.record.loop.RecordLoop.Command;
 import org.hps.conditions.database.DatabaseConditionsManager;
+import org.hps.job.DatabaseConditionsManagerSetup;
 import org.hps.job.JobManager;
 import org.hps.monitoring.application.model.ConfigurationModel;
 import org.hps.monitoring.application.model.ConnectionStatus;
@@ -34,7 +37,6 @@
 import org.jlab.coda.et.exception.EtClosedException;
 import org.jlab.coda.et.exception.EtException;
 import org.lcsim.conditions.ConditionsListener;
-import org.lcsim.conditions.ConditionsReader;
 import org.lcsim.util.Driver;
 
 /**
@@ -194,11 +196,6 @@
     private SessionState sessionState;
    
     /**
-     * The current conditions manager.
-     */ 
-    private DatabaseConditionsManager conditionsManager;
-
-    /**
      * Class constructor, which will initialize with reference to the current monitoring application and lists of extra
      * processors to add to the loop, as well as supplemental conditions listeners that activate when the conditions
      * change.
@@ -306,7 +303,7 @@
      *
      * @param configurationModel the current global {@link org.hps.monitoring.application.ConfigurationModel} object
      */
-    private void createEventBuilder(final ConfigurationModel configurationModel) {
+    private LCSimEventBuilder createEventBuilder(final ConfigurationModel configurationModel) {
 
         // Get the class for the event builder.
         final String eventBuilderClassName = configurationModel.getEventBuilderClassName();
@@ -318,9 +315,8 @@
         } catch (final Exception e) {
             throw new RuntimeException("Failed to create LCSimEventBuilder.", e);
         }
-
-        // Add the builder as a listener so it is notified when conditions change.
-        this.conditionsManager.addConditionsListener(this.sessionState.eventBuilder);
+        
+        return this.sessionState.eventBuilder; 
     }
 
     /**
@@ -464,35 +460,70 @@
             steering = configurationModel.getSteeringFile();
         } else {
             steering = configurationModel.getSteeringResource();
-        }
-
-        this.logger.config("set steering " + steering + " with type "
+            if (!steering.startsWith("/")) {
+                steering = "/" + steering;
+            }
+        }
+
+        this.logger.config("set steering " + steering + " with type " 
                 + (steeringType == SteeringType.RESOURCE ? "RESOURCE" : "FILE"));
 
         try {
             // Create the job manager. A new conditions manager is instantiated from this call but not configured.
             this.sessionState.jobManager = new JobManager();
-
-            // Set ref to current conditions manager.
-            this.conditionsManager = DatabaseConditionsManager.getInstance();
             
-            // Add conditions listeners after new database conditions manager is initialized from the job manager.
+            // Setup class for conditions system.
+            DatabaseConditionsManagerSetup conditions = new DatabaseConditionsManagerSetup();
+            
+            // Disable run manager.
+            conditions.setEnableRunManager(false);
+            
+            // Setup the event builder to translate from EVIO to LCIO.
+            LCSimEventBuilder eventBuilder = this.createEventBuilder(configurationModel);            
+            conditions.addConditionsListener(eventBuilder);
+                        
+            // Add extra conditions listeners.
             for (final ConditionsListener conditionsListener : this.sessionState.conditionsListeners) {
-                this.logger.config("adding conditions listener " + conditionsListener.getClass().getName());
-                this.conditionsManager.addConditionsListener(conditionsListener);
-            }
-
+                this.logger.config("Adding conditions listener " + conditionsListener.getClass().getName());
+                conditions.addConditionsListener(conditionsListener);
+            }
+
+            // Add detector alias.
             if (configurationModel.hasValidProperty(ConfigurationModel.DETECTOR_ALIAS_PROPERTY)) {
-                // Set a detector alias.
-                ConditionsReader.addAlias(configurationModel.getDetectorName(),
+                conditions.addAlias(configurationModel.getDetectorName(),
                         "file://" + configurationModel.getDetectorAlias());
-                this.logger.config("using detector alias " + configurationModel.getDetectorAlias());
-            }
-
-            // Setup the event builder to translate from EVIO to LCIO.
-            // This must happen before Driver setup so the builder's listeners are activated first!
-            this.createEventBuilder(configurationModel);
-
+                this.logger.config("Added detector alias " + configurationModel.getDetectorAlias() 
+                        + " for " + configurationModel.getDetectorName());
+            }
+
+            // Add conditions tag.
+            if (configurationModel.hasValidProperty(ConfigurationModel.CONDITIONS_TAG_PROPERTY)
+                    && !configurationModel.getConditionsTag().equals("")) {
+                Set<String> tags = new HashSet<String>();
+                tags.add(configurationModel.getConditionsTag());
+                this.logger.config("Added conditions tag " + configurationModel.getConditionsTag());
+                conditions.setTags(tags);
+            }
+            
+            // Set user specified job number.
+            if (configurationModel.hasValidProperty(ConfigurationModel.USER_RUN_NUMBER_PROPERTY)) {
+                final int userRun = configurationModel.getUserRunNumber();
+                this.logger.config("User run number set to " + userRun);
+                conditions.setRun(userRun);
+            }
+            
+            // Set detector name.
+            conditions.setDetectorName(configurationModel.getDetectorName());
+            
+            // Freeze the conditions system to ignore run numbers from event data.
+            if (configurationModel.hasPropertyKey(ConfigurationModel.FREEZE_CONDITIONS_PROPERTY)) {
+                this.logger.config("user configured to freeze conditions system");
+                conditions.setFreeze(configurationModel.getFreezeConditions());
+            }
+                        
+            // Register the configured conditions settings with the job manager.
+            this.sessionState.jobManager.setConditionsSetup(conditions);
+                        
             // Configure the job manager for the XML steering.
             this.sessionState.jobManager.setDryRun(true);
             if (steeringType == SteeringType.RESOURCE) {
@@ -500,32 +531,10 @@
             } else if (steeringType.equals(SteeringType.FILE)) {
                 this.setupSteeringFile(steering);
             }
-
-            // Set conditions tag if applicable.
-            if (configurationModel.hasValidProperty(ConfigurationModel.CONDITIONS_TAG_PROPERTY)
-                    && !configurationModel.getConditionsTag().equals("")) {
-                this.logger.config("conditions tag is set to " + configurationModel.getConditionsTag());
-            } else {
-                this.logger.config("conditions NOT using a tag");
-            }
-
-            // Is there a user specified run number from the JobPanel?
-            if (configurationModel.hasValidProperty(ConfigurationModel.USER_RUN_NUMBER_PROPERTY)) {
-                final int userRunNumber = configurationModel.getUserRunNumber();
-                final String detectorName = configurationModel.getDetectorName();
-                this.logger.config("setting user run number " + userRunNumber + " with detector " + detectorName);
-                conditionsManager.setDetector(detectorName, userRunNumber);
-                if (configurationModel.hasPropertyKey(ConfigurationModel.FREEZE_CONDITIONS_PROPERTY)) {
-                    // Freeze the conditions system to ignore run numbers from the events.
-                    this.logger.config("user configured to freeze conditions system");
-                    this.conditionsManager.freeze();
-                } else {
-                    // Allow run numbers to be picked up from the events.
-                    this.logger.config("user run number provided but conditions system is NOT frozen");
-                    this.conditionsManager.unfreeze();
-                }
-            }
-
+            
+            // Post-init conditions system which may freeze if run and name were provided.
+            this.sessionState.jobManager.getConditionsSetup().postInitialize();
+            
             this.logger.info("lcsim setup was successful");
 
         } catch (final Throwable t) {
@@ -592,15 +601,19 @@
             this.logger.config("added extra Driver " + driver.getName());
         }
 
-        // Enable conditions system activation from EVIO event data in case the PRESTART is missed.
-        loopConfig.add(new EvioDetectorConditionsProcessor(configurationModel.getDetectorName()));
-        this.logger.config("added EvioDetectorConditionsProcessor to job with detector "
-                + configurationModel.getDetectorName());
+        // Enable conditions activation from EVIO; not needed if conditions are frozen for the job.
+        if (!DatabaseConditionsManager.getInstance().isFrozen()) {
+            loopConfig.add(new EvioDetectorConditionsProcessor(configurationModel.getDetectorName()));
+            this.logger.config("added EvioDetectorConditionsProcessor to job with detector "
+                    + configurationModel.getDetectorName());
+        } else {
+            this.logger.config("Conditions activation from EVIO is disabled.");
+        }
 
         // Create the CompositeLoop with the configuration.
         this.sessionState.loop = new CompositeLoop(loopConfig);
 
-        this.logger.config("record loop is setup");
+        this.logger.config("Record loop is setup.");
     }
 
     /**

Modified: java/branches/HPSJAVA-409/monitoring-app/src/main/java/org/hps/monitoring/application/Main.java
 =============================================================================
--- java/branches/HPSJAVA-409/monitoring-app/src/main/java/org/hps/monitoring/application/Main.java	(original)
+++ java/branches/HPSJAVA-409/monitoring-app/src/main/java/org/hps/monitoring/application/Main.java	Wed Apr 27 11:11:32 2016
@@ -8,7 +8,7 @@
 import org.apache.commons.cli.Option;
 import org.apache.commons.cli.Options;
 import org.apache.commons.cli.ParseException;
-import org.apache.commons.cli.DefaultParser;
+import org.apache.commons.cli.PosixParser;
 import org.hps.monitoring.application.model.Configuration;
 
 /**
@@ -29,7 +29,7 @@
         final Options options = new Options();
         options.addOption(new Option("h", false, "Print help."));
         options.addOption(new Option("c", true, "Load a properties file with configuration parameters."));
-        final CommandLineParser parser = new DefaultParser();
+        final CommandLineParser parser = new PosixParser();
 
         // Parse command line arguments.
         final CommandLine cl;

Modified: java/branches/HPSJAVA-409/monitoring-app/src/main/java/org/hps/monitoring/application/MonitoringApplication.java
 =============================================================================
--- java/branches/HPSJAVA-409/monitoring-app/src/main/java/org/hps/monitoring/application/MonitoringApplication.java	(original)
+++ java/branches/HPSJAVA-409/monitoring-app/src/main/java/org/hps/monitoring/application/MonitoringApplication.java	Wed Apr 27 11:11:32 2016
@@ -78,7 +78,6 @@
          */
         @Override
         public void close() throws SecurityException {
-            // Does nothing.
         }
 
         /**
@@ -86,7 +85,6 @@
          */
         @Override
         public void flush() {
-            // Does nothing.
         }
 
         /**
@@ -121,8 +119,6 @@
         @Override
         public void publish(final LogRecord record) {
             super.publish(record);
-
-            // FIXME: Is this efficient? Should this always happen here?
             flush();
         }
 
@@ -295,18 +291,18 @@
             loadConfiguration(new Configuration(DEFAULT_CONFIGURATION), false);
 
             if (userConfiguration != null) {
-                // Load user configuration.
+                // Load user configuration to supplement default settings.
                 loadConfiguration(userConfiguration, true);
             }
 
-            // Enable the GUI now that initialization is complete.
+            // Enable the GUI after initialization.
             this.frame.setEnabled(true);
 
-            LOGGER.info("application initialized successfully");
+            LOGGER.info("Monitoring app initialized successfully.");
 
         } catch (final Exception e) {
-            // Don't use the ErrorHandler here because we don't know that it initialized successfully.
-            System.err.println("MonitoringApplication failed to initialize without errors!");
+            // Initialization failed so print info and die.
+            System.err.println("ERROR: MonitoringApplication failed to initialize!");
             DialogUtil.showErrorDialog(null, "Error Starting Monitoring Application",
                     "Monitoring application failed to initialize.");
             e.printStackTrace();
@@ -321,9 +317,6 @@
      */
     @Override
     public void actionPerformed(final ActionEvent e) {
-
-        // logger.finest("actionPerformed - " + e.getActionCommand());
-
         final String command = e.getActionCommand();
         if (Commands.CONNECT.equals(command)) {
             startSession();
@@ -374,7 +367,7 @@
     }
 
     /**
-     * Redirect <code>System.out</code> and <code>System.err</code> to a file chosen by a file chooser.
+     * Redirect <code>System.out</code> and <code>System.err</code> to a chosen file.
      */
     private void chooseLogFile() {
         final JFileChooser fc = new JFileChooser();
@@ -420,7 +413,7 @@
     }
 
     /**
-     * Exit from the application from exit menu item or hitting close window button.
+     * Exit from the application.
      */
     private void exit() {
         if (this.connectionModel.isConnected()) {
@@ -954,7 +947,6 @@
 
             // Add listener to push conditions changes to conditions panel.
             final List<ConditionsListener> conditionsListeners = new ArrayList<ConditionsListener>();
-            conditionsListeners.add(this.frame.getConditionsPanel().new ConditionsPanelListener());
 
             // Instantiate the event processing wrapper.
             this.processing = new EventProcessing(this, processors, drivers, conditionsListeners);
@@ -973,7 +965,7 @@
             // Start the event processing thread.
             this.processing.start();
 
-            LOGGER.info("new session successfully initialized");
+            LOGGER.info("Event processing session started.");
 
         } catch (final Exception e) {
 
@@ -989,7 +981,7 @@
                             "There was an error while starting the session." + '\n' + "See the log for details.",
                             "Session Error");
 
-            LOGGER.severe("failed to start new session");
+            LOGGER.severe("Failed to start event processing.");
         }
     }
 

Modified: java/branches/HPSJAVA-409/monitoring-app/src/main/java/org/hps/monitoring/application/MonitoringApplicationFrame.java
 =============================================================================
--- java/branches/HPSJAVA-409/monitoring-app/src/main/java/org/hps/monitoring/application/MonitoringApplicationFrame.java	(original)
+++ java/branches/HPSJAVA-409/monitoring-app/src/main/java/org/hps/monitoring/application/MonitoringApplicationFrame.java	Wed Apr 27 11:11:32 2016
@@ -37,7 +37,7 @@
     /**
      * The conditions panel.
      */
-    private final ConditionsPanel conditionsPanel;
+    //private final ConditionsPanel conditionsPanel;
 
     /**
      * The dashboard panel.
@@ -150,8 +150,8 @@
         tableTabbedPane.addTab("Trigger Diagnostics", this.triggerPanel);
 
         // Add the conditions panel.
-        this.conditionsPanel = new ConditionsPanel();
-        tableTabbedPane.addTab("Detector Conditions", this.conditionsPanel);
+        //this.conditionsPanel = new ConditionsPanel();
+        //tableTabbedPane.addTab("Detector Conditions", this.conditionsPanel);
 
         // Vertical split pane in left panel.
         this.leftSplitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, this.dashboardPanel, tableTabbedPane);
@@ -209,9 +209,9 @@
      *
      * @return the conditions panel
      */
-    ConditionsPanel getConditionsPanel() {
-        return this.conditionsPanel;
-    }
+    //ConditionsPanel getConditionsPanel() {
+    //    return this.conditionsPanel;
+    //}
 
     /**
      * Get the panel for the dashboard.

Modified: java/branches/HPSJAVA-409/monitoring-app/src/main/java/org/hps/monitoring/application/SystemStatusPanel.java
 =============================================================================
--- java/branches/HPSJAVA-409/monitoring-app/src/main/java/org/hps/monitoring/application/SystemStatusPanel.java	(original)
+++ java/branches/HPSJAVA-409/monitoring-app/src/main/java/org/hps/monitoring/application/SystemStatusPanel.java	Wed Apr 27 11:11:32 2016
@@ -1,6 +1,3 @@
-/**
- *
- */
 package org.hps.monitoring.application;
 
 import java.awt.BorderLayout;
@@ -81,7 +78,7 @@
         
         this.statuses.clear();
     }
-
+    
     private class SystemStatusBeeper extends TimerTask {
 
         @Override
@@ -93,7 +90,7 @@
                 }
             }
             if (isAlarming) {
-                System.out.println("beep\007");
+                Toolkit.getDefaultToolkit().beep();
             }
         }
     }

Modified: java/branches/HPSJAVA-409/monitoring-app/src/main/java/org/hps/monitoring/application/util/TableExporter.java
 =============================================================================
--- java/branches/HPSJAVA-409/monitoring-app/src/main/java/org/hps/monitoring/application/util/TableExporter.java	(original)
+++ java/branches/HPSJAVA-409/monitoring-app/src/main/java/org/hps/monitoring/application/util/TableExporter.java	Wed Apr 27 11:11:32 2016
@@ -33,7 +33,7 @@
 
         // Column headers.
         for (int columnIndex = 0; columnIndex < columnCount; columnIndex++) {
-            buffer.append("\"" + model.getColumnName(columnIndex) + "\"" + fieldDelimiter);
+            buffer.append("\"" + model.getColumnName(columnIndex) + "\"" + fieldDelimiter + ",");
         }
         buffer.setLength(buffer.length() - 1);
         buffer.append('\n');
@@ -47,6 +47,7 @@
                 } else {
                     buffer.append("\"" + value + "\"" + fieldDelimiter);
                 }
+                buffer.append(",");
             }
             buffer.setLength(buffer.length() - 1);
             buffer.append('\n');

Modified: java/branches/HPSJAVA-409/monitoring-drivers/pom.xml
 =============================================================================
--- java/branches/HPSJAVA-409/monitoring-drivers/pom.xml	(original)
+++ java/branches/HPSJAVA-409/monitoring-drivers/pom.xml	Wed Apr 27 11:11:32 2016
@@ -7,7 +7,7 @@
         <groupId>org.hps</groupId>
         <artifactId>hps-parent</artifactId>
         <relativePath>../parent/pom.xml</relativePath>
-        <version>3.4.2-SNAPSHOT</version>
+        <version>3.9-SNAPSHOT</version>
     </parent>
     <scm>
         <url>http://java.freehep.org/svn/repos/hps/list/java/trunk/monitoring-drivers/</url>

Modified: java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/scalers/DeadtimePlots.java
 =============================================================================
--- java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/scalers/DeadtimePlots.java	(original)
+++ java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/scalers/DeadtimePlots.java	Wed Apr 27 11:11:32 2016
@@ -9,9 +9,7 @@
 import org.hps.record.scalers.ScalerUtilities;
 import org.hps.record.scalers.ScalerUtilities.LiveTimeIndex;
 import org.jfree.chart.JFreeChart;
-import org.jfree.chart.axis.Axis;
 import org.jfree.chart.axis.DateAxis;
-import org.jfree.chart.axis.ValueAxis;
 import org.jfree.data.time.Second;
 import org.jfree.data.time.TimeSeriesCollection;
 import org.lcsim.event.EventHeader;

Modified: java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/svt/PedestalPlots.java
 =============================================================================
--- java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/svt/PedestalPlots.java	(original)
+++ java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/svt/PedestalPlots.java	Wed Apr 27 11:11:32 2016
@@ -23,6 +23,7 @@
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
+import org.hps.recon.tracking.SvtPlotUtils;
 //===> import org.hps.conditions.deprecated.HPSSVTCalibrationConstants;
 //===> import org.hps.conditions.deprecated.SvtUtils;
 import org.lcsim.detector.tracker.silicon.HpsSiSensor;

Modified: java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/svt/SVTCellIDPrintDriver.java
 =============================================================================
--- java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/svt/SVTCellIDPrintDriver.java	(original)
+++ java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/svt/SVTCellIDPrintDriver.java	Wed Apr 27 11:11:32 2016
@@ -17,52 +17,52 @@
  */
 public class SVTCellIDPrintDriver extends Driver {
 
-	String rawTrackerHitCollectionName = "SVTData";
-	String outputFileName;
-	PrintWriter outputStream = null;
+    String rawTrackerHitCollectionName = "SVTData";
+    String outputFileName;
+    PrintWriter outputStream = null;
 
-	public SVTCellIDPrintDriver() {
-	}
+    public SVTCellIDPrintDriver() {
+    }
 
-	public void setRawTrackerHitCollectionName(String rawTrackerHitCollectionName) {
-		this.rawTrackerHitCollectionName = rawTrackerHitCollectionName;
-	}
+    public void setRawTrackerHitCollectionName(String rawTrackerHitCollectionName) {
+        this.rawTrackerHitCollectionName = rawTrackerHitCollectionName;
+    }
 
-	public void setOutputFileName(String outputFileName) {
-		this.outputFileName = outputFileName;
-	}
+    public void setOutputFileName(String outputFileName) {
+        this.outputFileName = outputFileName;
+    }
 
-	public void startOfData() {
-		if (rawTrackerHitCollectionName == null) {
-			throw new RuntimeException("The parameter ecalCollectionName was not set!");
-		}
+    public void startOfData() {
+        if (rawTrackerHitCollectionName == null) {
+            throw new RuntimeException("The parameter ecalCollectionName was not set!");
+        }
 
-		if (outputFileName != null) {
-			try {
-				outputStream = new PrintWriter(outputFileName);
-			} catch (IOException ex) {
-				throw new RuntimeException("Invalid outputFilePath!");
-			}
-		} else {
-			outputStream = new PrintWriter(System.out, true);
-		}
-	}
+        if (outputFileName != null) {
+            try {
+                outputStream = new PrintWriter(outputFileName);
+            } catch (IOException ex) {
+                throw new RuntimeException("Invalid outputFilePath!");
+            }
+        } else {
+            outputStream = new PrintWriter(System.out, true);
+        }
+    }
 
-	public void process(EventHeader event) {
-		// Get the list of ECal hits.
-		if (event.hasCollection(SVTData.class, rawTrackerHitCollectionName)) {
-			List<SVTData> hits = event.get(SVTData.class, rawTrackerHitCollectionName);
-			//outputStream.println("Reading RawCalorimeterHit from event " + event.getEventNumber());
-			for (SVTData hit : hits) {
-				outputStream.printf("FPGA=%d\thybrid=%d\tchannel=%d\n", hit.getFPGAAddress(), hit.getHybridNumber(), hit.getChannelNumber());
-			}
-		}
-		if (event.hasCollection(RawTrackerHit.class, rawTrackerHitCollectionName)) {
-			List<RawTrackerHit> hits = event.get(RawTrackerHit.class, rawTrackerHitCollectionName);
-			//outputStream.println("Reading RawCalorimeterHit from event " + event.getEventNumber());
-			for (RawTrackerHit hit : hits) {
-				outputStream.printf("name=%s\tside=%d\tstrip=%d\n", hit.getDetectorElement().getName(), hit.getIdentifierFieldValue("side"), hit.getIdentifierFieldValue("strip"));
-			}
-		}
-	}
+    public void process(EventHeader event) {
+        // Get the list of ECal hits.
+        if (event.hasCollection(SVTData.class, rawTrackerHitCollectionName)) {
+            List<SVTData> hits = event.get(SVTData.class, rawTrackerHitCollectionName);
+            //outputStream.println("Reading RawCalorimeterHit from event " + event.getEventNumber());
+            for (SVTData hit : hits) {
+                outputStream.printf("FPGA=%d\thybrid=%d\tchannel=%d\n", hit.getFPGAAddress(), hit.getHybridNumber(), hit.getChannelNumber());
+            }
+        }
+        if (event.hasCollection(RawTrackerHit.class, rawTrackerHitCollectionName)) {
+            List<RawTrackerHit> hits = event.get(RawTrackerHit.class, rawTrackerHitCollectionName);
+            //outputStream.println("Reading RawCalorimeterHit from event " + event.getEventNumber());
+            for (RawTrackerHit hit : hits) {
+                outputStream.printf("name=%s\tside=%d\tstrip=%d\n", hit.getDetectorElement().getName(), hit.getIdentifierFieldValue("side"), hit.getIdentifierFieldValue("strip"));
+            }
+        }
+    }
 }

Modified: java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/svt/SVTHitRecoCorrelations.java
 =============================================================================
--- java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/svt/SVTHitRecoCorrelations.java	(original)
+++ java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/svt/SVTHitRecoCorrelations.java	Wed Apr 27 11:11:32 2016
@@ -32,7 +32,7 @@
  */
 public class SVTHitRecoCorrelations extends Driver {
 
-	//private List<AIDAFrame> plotterFrame = new ArrayList<AIDAFrame>();
+    //private List<AIDAFrame> plotterFrame = new ArrayList<AIDAFrame>();
     private List<IPlotter> plotters = new ArrayList<IPlotter>();
     private AIDA aida = AIDA.defaultInstance();                  
     private String rawTrackerHitCollectionName = "SVTRawTrackerHits";
@@ -225,7 +225,7 @@
         */
         
         //for(int i=0;i<2;++i) {
-       	//plotterFrame.get(i).pack();
+        //plotterFrame.get(i).pack();
         //    plotterFrame.get(i).setVisible(true);
         //}
     }

Modified: java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/svt/SVTHitReconstructionPlots.java
 =============================================================================
--- java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/svt/SVTHitReconstructionPlots.java	(original)
+++ java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/svt/SVTHitReconstructionPlots.java	Wed Apr 27 11:11:32 2016
@@ -1,13 +1,9 @@
 package org.hps.monitoring.drivers.svt;
 
-import org.hps.monitoring.drivers.trackrecon.TrackingReconPlots;
 import hep.aida.IAnalysisFactory;
-import hep.aida.IHistogram1D;
-import hep.aida.IHistogram2D;
 import hep.aida.IPlotter;
 import hep.aida.IPlotterStyle;
 import hep.aida.IProfile1D;
-import hep.aida.ref.plotter.PlotterRegion;
 
 import java.io.IOException;
 import java.util.HashMap;
@@ -16,14 +12,14 @@
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
-
+import org.hps.monitoring.drivers.trackrecon.TrackingReconPlots;
 //===> import org.hps.conditions.deprecated.SvtUtils;
 import org.hps.recon.tracking.FittedRawTrackerHit;
 import org.lcsim.detector.identifier.IIdentifier;
 import org.lcsim.detector.identifier.IIdentifierHelper;
 import org.lcsim.detector.tracker.silicon.DopedSilicon;
+import org.lcsim.detector.tracker.silicon.HpsSiSensor;
 import org.lcsim.detector.tracker.silicon.SiSensor;
-import org.lcsim.detector.tracker.silicon.HpsSiSensor;
 import org.lcsim.detector.tracker.silicon.SiTrackerIdentifierHelper;
 import org.lcsim.event.EventHeader;
 import org.lcsim.event.RawTrackerHit;
@@ -38,7 +34,7 @@
  */
 public class SVTHitReconstructionPlots extends Driver {
 
-	//private AIDAFrame plotterFrame;
+    //private AIDAFrame plotterFrame;
     private AIDA aida = AIDA.defaultInstance();
     private String fittedTrackerHitCollectionName = "SVTFittedRawTrackerHits";
     private String trackerHitCollectionName = "StripClusterer_SiTrackerHitStrip1D";
@@ -138,18 +134,18 @@
        
        // TODO: Check if this block of code is equivalent to the block commented out below
        for(SiSensor sensor : sensors){
-    	   
-                int region = computePlotterRegion(sensor);
-                if(region >= plotter1.numberOfRegions()) {
-                    throw new RuntimeException("not enough regions! (" + region + "/"+ plotter1.numberOfRegions()+ ")");
-                }
-                plotter1.region(region).plot(aida.histogram1D(sensor.getName() + "_raw_hits", 10, -0.5, 9.5));
-                plotter3.region(region).plot(aida.histogram1D(sensor.getName() + "_reco_hits", 10, -0.5, 9.5));
-                plotter2.region(region).plot(aida.histogram1D(sensor.getName() + "_cluster_hits", 10, -0.5, 9.5));
-                plotter4.region(region).plot(aida.histogram1D(sensor.getName() + "_cluster_size", 9, 0.5, 9.5));
-                plotter5.region(region).plot(aida.histogram1D(sensor.getName() + "_cluster_amp", 50, 0, 4000.0));
-                ((PlotterRegion) plotter5.region(region)).getPlot().getXAxis().setLabel("Cluster amplitude [ADC counts]");
-                plotter6.region(region).plot(aida.histogram2D(sensor.getName() + "_cluster_vs_strip", 128, 0, 640, 100, -50, 50));
+            int region = computePlotterRegion(sensor);
+            if (region >= plotter1.numberOfRegions()) {
+                throw new RuntimeException("not enough regions! (" + region + "/" + plotter1.numberOfRegions() + ")");
+            }
+            plotter1.region(region).plot(aida.histogram1D(sensor.getName() + "_raw_hits", 10, -0.5, 9.5));
+            plotter3.region(region).plot(aida.histogram1D(sensor.getName() + "_reco_hits", 10, -0.5, 9.5));
+            plotter2.region(region).plot(aida.histogram1D(sensor.getName() + "_cluster_hits", 10, -0.5, 9.5));
+            plotter4.region(region).plot(aida.histogram1D(sensor.getName() + "_cluster_size", 9, 0.5, 9.5));
+            plotter5.region(region).plot(aida.histogram1D(sensor.getName() + "_cluster_amp", 50, 0, 4000.0));
+            plotter5.style().xAxisStyle().setLabel("Cluster amplitude [ADC counts]");
+            plotter6.region(region).plot(
+                    aida.histogram2D(sensor.getName() + "_cluster_vs_strip", 128, 0, 640, 100, -50, 50));
        }
         
         /* ===> 

Modified: java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/svt/SampleZeroHVBiasChecker.java
 =============================================================================
--- java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/svt/SampleZeroHVBiasChecker.java	(original)
+++ java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/svt/SampleZeroHVBiasChecker.java	Wed Apr 27 11:11:32 2016
@@ -28,6 +28,7 @@
 import org.hps.conditions.svt.SvtBiasMyaDataReader;
 import org.hps.conditions.svt.SvtBiasMyaDataReader.SvtBiasMyaRange;
 import org.hps.conditions.svt.SvtBiasMyaDataReader.SvtBiasRunRange;
+import org.hps.recon.tracking.SvtPlotUtils;
 import org.hps.record.epics.EpicsData;
 import org.hps.record.triggerbank.AbstractIntData;
 import org.hps.record.triggerbank.HeadBankData;

Modified: java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/svt/SensorOccupancyPlotsDriver.java
 =============================================================================
--- java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/svt/SensorOccupancyPlotsDriver.java	(original)
+++ java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/svt/SensorOccupancyPlotsDriver.java	Wed Apr 27 11:11:32 2016
@@ -1,9 +1,4 @@
 package org.hps.monitoring.drivers.svt;
-
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
 
 import hep.aida.IAnalysisFactory;
 import hep.aida.IHistogram1D;
@@ -13,22 +8,27 @@
 import hep.aida.IPlotterRegion;
 import hep.aida.IPlotterStyle;
 import hep.aida.ITree;
-import hep.aida.ref.plotter.Plotter;
-import hep.aida.ref.plotter.PlotterRegion;
+import hep.aida.jfree.plotter.Plotter;
+import hep.aida.jfree.plotter.PlotterRegion;
 import hep.aida.ref.rootwriter.RootFileStore;
 import hep.physics.vec.Hep3Vector;
 
-import java.util.HashSet;
-import java.util.Set;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 
 import org.hps.monitoring.subsys.StatusCode;
 import org.hps.monitoring.subsys.Subsystem;
 import org.hps.monitoring.subsys.SystemStatus;
 import org.hps.monitoring.subsys.SystemStatusImpl;
+import org.hps.recon.tracking.SvtPlotUtils;
+import org.hps.record.triggerbank.AbstractIntData;
+import org.hps.record.triggerbank.TIData;
+import org.lcsim.detector.ITransform3D;
+import org.lcsim.detector.tracker.silicon.ChargeCarrier;
 import org.lcsim.detector.tracker.silicon.HpsSiSensor;
-import org.lcsim.detector.tracker.silicon.ChargeCarrier;
 import org.lcsim.detector.tracker.silicon.SiStrips;
-import org.lcsim.detector.ITransform3D;
 import org.lcsim.event.EventHeader;
 import org.lcsim.event.GenericObject;
 import org.lcsim.event.RawTrackerHit;
@@ -36,8 +36,6 @@
 import org.lcsim.recon.tracking.digitization.sisim.SiTrackerHitStrip1D;
 import org.lcsim.recon.tracking.digitization.sisim.TrackerHitType;
 import org.lcsim.util.Driver;
-import org.hps.record.triggerbank.AbstractIntData;
-import org.hps.record.triggerbank.TIData;
 import org.lcsim.util.aida.AIDA;
 
 /**
@@ -51,7 +49,6 @@
     //static {
     //    hep.aida.jfree.AnalysisFactory.register();
     //}
-
     // Plotting
     private static ITree tree = null;
     private IAnalysisFactory analysisFactory = AIDA.defaultInstance().analysisFactory();
@@ -75,8 +72,6 @@
     private String triggerBankCollectionName = "TriggerBank";
     private String stripClusterCollectionName = "StripClusterer_SiTrackerHitStrip1D";
 
-    String rootFile = null;
-
     private int maxSamplePosition = -1;
     private int timeWindowWeight = 1;
     private int eventCount = 0;
@@ -108,7 +103,9 @@
     private boolean enableClusterTimeCuts = true;
     private double clusterTimeCutMax = 4.0;
     private double clusterTimeCutMin = -4.0;
-    
+
+    private boolean saveRootFile = true;
+
     public SensorOccupancyPlotsDriver() {
         maxSampleStatus = new SystemStatusImpl(Subsystem.SVT, "Checks that SVT is timed in (max sample plot)", true);
         maxSampleStatus.setStatus(StatusCode.UNKNOWN, "Status is unknown.");
@@ -194,6 +191,10 @@
 
     public void setMaxPeakOccupancy(double maxPeakOccupancy) {
         this.maxPeakOccupancy = maxPeakOccupancy;
+    }
+
+    public void setSaveRootFile(boolean saveRootFile) {
+        this.saveRootFile = saveRootFile;
     }
 
     /**
@@ -404,12 +405,12 @@
                 plotters.get("Occupancy vs Position").region(SvtPlotUtils.computePlotterRegion(sensor))
                         .plot(positionPlots.get(sensor.getName()), this.createOccupancyPlotStyle("Distance from Beam [mm]", sensor, false));
                 plotters.get("Cluster occupancy vs Position").region(SvtPlotUtils.computePlotterRegion(sensor))
-                .plot(clusterPositionPlots.get(sensor.getName()), this.createOccupancyPlotStyle("Distance from Beam [mm]", sensor, false));
+                        .plot(clusterPositionPlots.get(sensor.getName()), this.createOccupancyPlotStyle("Distance from Beam [mm]", sensor, false));
             }
             occupancyMap.put(sensor.getName(), new int[640]);
 
             if (enableMaxSamplePlots) {
-                maxSamplePositionPlots.put(sensor.getName(), histogramFactory.createHistogram1D(sensor.getName() + " - Max Sample Number", 6, 0, 6));
+                maxSamplePositionPlots.put(sensor.getName(), histogramFactory.createHistogram1D(sensor.getName() + " - Max Sample Number", 6, -0.5, 5.5));
                 plotters.get("Max Sample Number").region(SvtPlotUtils.computePlotterRegion(sensor))
                         .plot(maxSamplePositionPlots.get(sensor.getName()),
                                 this.createOccupancyPlotStyle("Max Sample Number", sensor, false));
@@ -418,12 +419,11 @@
 
         for (IPlotter plotter : plotters.values()) {
             for (int regionN = 0; regionN < plotter.numberOfRegions(); regionN++) {
-                //Plotter l;
-                //PlotterRegion region = ((PlotterRegion) ((Plotter) plotter).region(regionN));
-                //if (region..getPlottedObjects().isEmpty()) {
-                //    continue;
-                //}
-                //region.getPanel().addMouseListener(new PopupPlotterListener(region));
+                PlotterRegion region = ((PlotterRegion) ((Plotter) plotter).region(regionN));
+                if (region.getPlottedObjects().isEmpty()) {
+                    continue;
+                }
+                region.getPanel().addMouseListener(new PopupPlotterListener(region));
             }
             plotter.show();
         }
@@ -520,22 +520,22 @@
                 maxSamplePositionPlots.get(((HpsSiSensor) rawHit.getDetectorElement()).getName()).fill(maxSamplePositionFound);
             }
         }
-        
+
         // Fill the strip cluster counts if available
-        if(event.hasCollection(SiTrackerHitStrip1D.class, stripClusterCollectionName)) {
+        if (event.hasCollection(SiTrackerHitStrip1D.class, stripClusterCollectionName)) {
             List<SiTrackerHitStrip1D> stripHits1D = event.get(SiTrackerHitStrip1D.class, stripClusterCollectionName);
-            for(SiTrackerHitStrip1D h : stripHits1D) {
+            for (SiTrackerHitStrip1D h : stripHits1D) {
                 SiTrackerHitStrip1D global = h.getTransformedHit(TrackerHitType.CoordinateSystem.GLOBAL);
                 Hep3Vector pos_global = global.getPositionAsVector();
-                if(enableClusterTimeCuts) {
-                    if( h.getTime() < clusterTimeCutMax && h.getTime() > clusterTimeCutMin) 
+                if (enableClusterTimeCuts) {
+                    if (h.getTime() < clusterTimeCutMax && h.getTime() > clusterTimeCutMin) {
                         clusterPositionPlotCounts.get(((HpsSiSensor) h.getRawHits().get(0).getDetectorElement()).getName()).fill(pos_global.y());
-                } else
+                    }
+                } else {
                     clusterPositionPlotCounts.get(((HpsSiSensor) h.getRawHits().get(0).getDetectorElement()).getName()).fill(pos_global.y());
-            }
-        }
-        
-        
+                }
+            }
+        }
 
         if (enableMaxSamplePlots && eventCount > maxSampleMonitorStart && eventCount % maxSampleMonitorPeriod == 0) {
             checkMaxSample();
@@ -563,17 +563,17 @@
                         positionPlots.get(sensor.getName()).fill(stripPosition, stripOccupancy);
                     }
                 }
-                if(enablePositionPlots) {
+                if (enablePositionPlots) {
                     clusterPositionPlots.get(sensor.getName()).reset();
                     IHistogram1D h = clusterPositionPlotCounts.get(sensor.getName());
-                    for(int bin=0; bin<h.axis().bins(); ++bin) {
+                    for (int bin = 0; bin < h.axis().bins(); ++bin) {
                         int y = h.binEntries(bin);
                         double stripClusterOccupancy = (double) y / (double) eventCount;
                         double x = h.axis().binCenter(bin);
-                        clusterPositionPlots.get(sensor.getName()).fill(x,stripClusterOccupancy);
+                        clusterPositionPlots.get(sensor.getName()).fill(x, stripClusterOccupancy);
                     }
                 }
-                
+
             }
         }
 
@@ -704,14 +704,16 @@
     @Override
     public void endOfData() {
 
-        rootFile = "run" + runNumber + "_occupancy.root";
-        RootFileStore store = new RootFileStore(rootFile);
-        try {
-            store.open();
-            store.add(tree);
-            store.close();
-        } catch (IOException e) {
-            e.printStackTrace();
+        if (saveRootFile) {
+            String rootFile = "run" + runNumber + "_occupancy.root";
+            RootFileStore store = new RootFileStore(rootFile);
+            try {
+                store.open();
+                store.add(tree);
+                store.close();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
         }
 
         System.out.println("%===============================================================================%");

Modified: java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/svt/SvtClusterPlots.java
 =============================================================================
--- java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/svt/SvtClusterPlots.java	(original)
+++ java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/svt/SvtClusterPlots.java	Wed Apr 27 11:11:32 2016
@@ -1,9 +1,4 @@
 package org.hps.monitoring.drivers.svt;
-
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.List;
 
 import hep.aida.IAnalysisFactory;
 import hep.aida.IHistogram1D;
@@ -16,18 +11,20 @@
 import hep.aida.jfree.plotter.Plotter;
 import hep.aida.jfree.plotter.PlotterRegion;
 import hep.aida.ref.rootwriter.RootFileStore;
-import java.util.HashSet;
-import java.util.Set;
-
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.hps.recon.tracking.SvtPlotUtils;
+import org.lcsim.detector.tracker.silicon.DopedSilicon;
 import org.lcsim.detector.tracker.silicon.HpsSiSensor;
 import org.lcsim.event.EventHeader;
 import org.lcsim.event.RawTrackerHit;
 import org.lcsim.geometry.Detector;
 import org.lcsim.recon.tracking.digitization.sisim.SiTrackerHitStrip1D;
 import org.lcsim.util.Driver;
-
-import org.hps.recon.tracking.FittedRawTrackerHit;
-import org.lcsim.detector.tracker.silicon.DopedSilicon;
 import org.lcsim.util.aida.AIDA;
 
 /**
@@ -55,11 +52,15 @@
     private static Map<String, IHistogram1D> singleHitClusterChargePlots = new HashMap<String, IHistogram1D>();
     private static Map<String, IHistogram1D> clusterTimePlots = new HashMap<String, IHistogram1D>();
     private static Map<String, IHistogram2D> hitTimeTrigTimePlots = new HashMap<String, IHistogram2D>();
-    private static IHistogram1D[] hitTimeTrigTimePlots1D = new IHistogram1D[6];
+    private static IHistogram1D[][] hitTimeTrigTimePlots1D = new IHistogram1D[6][2];
+    private static IHistogram2D[][] hitTimeTrigTimePlots2D = new IHistogram2D[6][2];
+
+    private static final int TOP = 0;
+    private static final int BOTTOM = 1;
 
     private List<HpsSiSensor> sensors;
-    private Map<RawTrackerHit, FittedRawTrackerHit> fittedRawTrackerHitMap
-            = new HashMap<RawTrackerHit, FittedRawTrackerHit>();
+//    private Map<RawTrackerHit, FittedRawTrackerHit> fittedRawTrackerHitMap
+//            = new HashMap<RawTrackerHit, FittedRawTrackerHit>();
 
     // Detector name
     private static final String SUBDETECTOR_NAME = "Tracker";
@@ -70,10 +71,16 @@
 
     private int runNumber = -1;
 
+    private boolean saveRootFile = true;
+
     private boolean dropSmallHitEvents = true;
 
     public void setDropSmallHitEvents(boolean dropSmallHitEvents) {
         this.dropSmallHitEvents = dropSmallHitEvents;
+    }
+
+    public void setSaveRootFile(boolean saveRootFile) {
+        this.saveRootFile = saveRootFile;
     }
 
     private int computePlotterRegion(HpsSiSensor sensor) {
@@ -84,20 +91,17 @@
             } else {
                 return 6 * (sensor.getLayerNumber() - 1) + 1;
             }
-        } else {
-
-            if (sensor.isTopLayer()) {
-                if (sensor.getSide() == HpsSiSensor.POSITRON_SIDE) {
-                    return 6 * (sensor.getLayerNumber() - 7) + 2;
-                } else {
-                    return 6 * (sensor.getLayerNumber() - 7) + 3;
-                }
-            } else if (sensor.isBottomLayer()) {
-                if (sensor.getSide() == HpsSiSensor.POSITRON_SIDE) {
-                    return 6 * (sensor.getLayerNumber() - 7) + 4;
-                } else {
-                    return 6 * (sensor.getLayerNumber() - 7) + 5;
-                }
+        } else if (sensor.isTopLayer()) {
+            if (sensor.getSide() == HpsSiSensor.POSITRON_SIDE) {
+                return 6 * (sensor.getLayerNumber() - 7) + 2;
+            } else {
+                return 6 * (sensor.getLayerNumber() - 7) + 3;
+            }
+        } else if (sensor.isBottomLayer()) {
+            if (sensor.getSide() == HpsSiSensor.POSITRON_SIDE) {
+                return 6 * (sensor.getLayerNumber() - 7) + 4;
+            } else {
+                return 6 * (sensor.getLayerNumber() - 7) + 5;
             }
         }
         return -1;
@@ -158,8 +162,7 @@
     private void resetPlots() {
 
         // Clear the fitted raw hit map of old values
-        fittedRawTrackerHitMap.clear();
-
+//        fittedRawTrackerHitMap.clear();
         // Since all plots are mapped to the name of a sensor, loop 
         // through the sensors, get the corresponding plots and clear them.
         for (HpsSiSensor sensor : sensors) {
@@ -171,34 +174,40 @@
         for (IHistogram2D histogram : hitTimeTrigTimePlots.values()) {
             histogram.reset();
         }
-    }
-
-    /**
-     * Method that creates a map between a fitted raw hit and it's corresponding
-     * raw fit
-     *
-     * @param fittedHits : List of fitted hits to map
-     */
-    private void mapFittedRawHits(List<FittedRawTrackerHit> fittedHits) {
-
-        // Clear the fitted raw hit map of old values
-        fittedRawTrackerHitMap.clear();
-
-        // Loop through all fitted hits and map them to their corresponding raw hits
-        for (FittedRawTrackerHit fittedHit : fittedHits) {
-            fittedRawTrackerHitMap.put(fittedHit.getRawTrackerHit(), fittedHit);
-        }
-    }
-
-    /**
-     *
-     * @param rawHit
-     * @return
-     */
-    private FittedRawTrackerHit getFittedHit(RawTrackerHit rawHit) {
-        return fittedRawTrackerHitMap.get(rawHit);
-    }
-
+
+        for (int i = 0; i < 6; i++) {
+            for (int j = 0; j < 2; j++) {
+                hitTimeTrigTimePlots1D[i][j].reset();
+                hitTimeTrigTimePlots2D[i][j].reset();
+            }
+        }
+    }
+
+//    /**
+//     * Method that creates a map between a fitted raw hit and it's corresponding
+//     * raw fit
+//     *
+//     * @param fittedHits : List of fitted hits to map
+//     */
+//    private void mapFittedRawHits(List<FittedRawTrackerHit> fittedHits) {
+//
+//        // Clear the fitted raw hit map of old values
+//        fittedRawTrackerHitMap.clear();
+//
+//        // Loop through all fitted hits and map them to their corresponding raw hits
+//        for (FittedRawTrackerHit fittedHit : fittedHits) {
+//            fittedRawTrackerHitMap.put(fittedHit.getRawTrackerHit(), fittedHit);
+//        }
+//    }
+//
+//    /**
+//     *
+//     * @param rawHit
+//     * @return
+//     */
+//    private FittedRawTrackerHit getFittedHit(RawTrackerHit rawHit) {
+//        return fittedRawTrackerHitMap.get(rawHit);
+//    }
     protected void detectorChanged(Detector detector) {
 
         // Get the HpsSiSensor objects from the geometry
@@ -236,7 +245,7 @@
                     .plot(singleHitClusterChargePlots.get(sensor.getName()), this.createStyle(null, "Cluster Amplitude [ADC Counts]", ""));
 
             clusterTimePlots.put(sensor.getName(),
-                    histogramFactory.createHistogram1D(sensor.getName() + " - Cluster Time", 100, -50, 50));
+                    histogramFactory.createHistogram1D(sensor.getName() + " - Cluster Time", 100, -75, 50));
             plotters.get("Cluster Time").region(this.computePlotterRegion(sensor))
                     .plot(clusterTimePlots.get(sensor.getName()), this.createStyle(null, "Cluster Time [ns]", ""));
         }
@@ -245,18 +254,25 @@
         plotters.get("SVT-trigger timing top-bottom").createRegions(1, 2);
 
         hitTimeTrigTimePlots.put("Top",
-                histogramFactory.createHistogram2D("Top Cluster Time vs. Trigger Phase", 100, -50, 50, 6, 0, 24));
+                histogramFactory.createHistogram2D("Top Cluster Time vs. Trigger Phase", 100, -75, 50, 6, 0, 24));
         plotters.get("SVT-trigger timing top-bottom").region(0).plot(hitTimeTrigTimePlots.get("Top"), this.createStyle(null, "Cluster Time [ns]", "Trigger Phase[ns]"));
         hitTimeTrigTimePlots.put("Bottom",
-                histogramFactory.createHistogram2D("Bottom Cluster Time vs. Trigger Phase", 100, -50, 50, 6, 0, 24));
+                histogramFactory.createHistogram2D("Bottom Cluster Time vs. Trigger Phase", 100, -75, 50, 6, 0, 24));
         plotters.get("SVT-trigger timing top-bottom").region(1).plot(hitTimeTrigTimePlots.get("Bottom"), this.createStyle(null, "Cluster Time [ns]", "Trigger Phase[ns]"));
 
         plotters.put("SVT-trigger timing by phase", plotterFactory.create("SVT-trigger timing by phase"));
-        plotters.get("SVT-trigger timing by phase").createRegions(1, 6);
+        plotters.get("SVT-trigger timing by phase").createRegions(2, 6);
+
+        plotters.put("SVT-trigger timing and amplitude by phase", plotterFactory.create("SVT-trigger timing and amplitude by phase"));
+        plotters.get("SVT-trigger timing and amplitude by phase").createRegions(2, 6);
 
         for (int i = 0; i < 6; i++) {
-            hitTimeTrigTimePlots1D[i] = histogramFactory.createHistogram1D("Cluster Time for Phase " + i, 100, -50, 50);
-            plotters.get("SVT-trigger timing by phase").region(i).plot(hitTimeTrigTimePlots1D[i], this.createStyle(null, "Cluster Time [ns]", ""));
+            for (int j = 0; j < 2; j++) {
+                hitTimeTrigTimePlots1D[i][j] = histogramFactory.createHistogram1D(String.format("Cluster Time for Phase %d, %s", i, j == TOP ? "Top" : "Bottom"), 100, -75, 50);
+                plotters.get("SVT-trigger timing by phase").region(i + 6 * j).plot(hitTimeTrigTimePlots1D[i][j], this.createStyle(null, "Cluster Time [ns]", ""));
+                hitTimeTrigTimePlots2D[i][j] = histogramFactory.createHistogram2D(String.format("Cluster Amplitude vs. Time for Phase %d, %s", i, j == TOP ? "Top" : "Bottom"), 100, -75, 50, 100, 0, 5000.0);
+                plotters.get("SVT-trigger timing and amplitude by phase").region(i + 6 * j).plot(hitTimeTrigTimePlots2D[i][j], this.createStyle(null, "Cluster Time [ns]", "Cluster Amplitude [ADC Counts]"));
+            }
         }
 
         for (IPlotter plotter : plotters.values()) {
@@ -277,17 +293,15 @@
             runNumber = event.getRunNumber();
         }
 
-        // If the event doesn't contain fitted raw hits, skip it
-        if (!event.hasCollection(FittedRawTrackerHit.class, fittedHitsCollectionName)) {
-            return;
-        }
-
-        // Get the list of fitted hits from the event
-        List<FittedRawTrackerHit> fittedHits = event.get(FittedRawTrackerHit.class, fittedHitsCollectionName);
-
-        // Map the fitted hits to their corresponding raw hits
-        this.mapFittedRawHits(fittedHits);
-
+//        // If the event doesn't contain fitted raw hits, skip it
+//        if (!event.hasCollection(FittedRawTrackerHit.class, fittedHitsCollectionName)) {
+//            return;
+//        }
+//         Get the list of fitted hits from the event
+//        List<FittedRawTrackerHit> fittedHits = event.get(FittedRawTrackerHit.class, fittedHitsCollectionName);
+//
+//        // Map the fitted hits to their corresponding raw hits
+//        this.mapFittedRawHits(fittedHits);
         // If the event doesn't contain any clusters, skip it
         if (!event.hasCollection(SiTrackerHitStrip1D.class, clusterCollectionName)) {
             return;
@@ -318,26 +332,29 @@
             }
 
             clusterTimePlots.get(sensor.getName()).fill(cluster.getTime());
-            hitTimeTrigTimePlots1D[(int) ((event.getTimeStamp() / 4) % 6)].fill(cluster.getTime());
             if (sensor.isTopLayer()) {
+                hitTimeTrigTimePlots1D[(int) ((event.getTimeStamp() / 4) % 6)][TOP].fill(cluster.getTime());
+                hitTimeTrigTimePlots2D[(int) ((event.getTimeStamp() / 4) % 6)][TOP].fill(cluster.getTime(), cluster.getdEdx() / DopedSilicon.ENERGY_EHPAIR);
                 hitTimeTrigTimePlots.get("Top").fill(cluster.getTime(), event.getTimeStamp() % 24);
             } else {
+                hitTimeTrigTimePlots1D[(int) ((event.getTimeStamp() / 4) % 6)][BOTTOM].fill(cluster.getTime());
+                hitTimeTrigTimePlots2D[(int) ((event.getTimeStamp() / 4) % 6)][BOTTOM].fill(cluster.getTime(), cluster.getdEdx() / DopedSilicon.ENERGY_EHPAIR);
                 hitTimeTrigTimePlots.get("Bottom").fill(cluster.getTime(), event.getTimeStamp() % 24);
             }
         }
     }
 
     public void endOfData() {
-
-        String rootFile = "run" + runNumber + "_cluster_analysis.root";
-        RootFileStore store = new RootFileStore(rootFile);
-        try {
-            store.open();
-            store.add(tree);
-            store.close();
-        } catch (IOException e) {
-            e.printStackTrace();
-        }
-    }
-
+        if (saveRootFile) {
+            String rootFile = "run" + runNumber + "_cluster_analysis.root";
+            RootFileStore store = new RootFileStore(rootFile);
+            try {
+                store.open();
+                store.add(tree);
+                store.close();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+    }
 }

Modified: java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/svt/SvtHitPlots.java
 =============================================================================
--- java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/svt/SvtHitPlots.java	(original)
+++ java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/svt/SvtHitPlots.java	Wed Apr 27 11:11:32 2016
@@ -2,6 +2,7 @@
 
 import hep.aida.IAnalysisFactory;
 import hep.aida.IHistogram1D;
+import hep.aida.IHistogram2D;
 import hep.aida.IHistogramFactory;
 import hep.aida.IPlotter;
 import hep.aida.IPlotterFactory;
@@ -9,18 +10,19 @@
 import hep.aida.ITree;
 import hep.aida.jfree.plotter.Plotter;
 import hep.aida.jfree.plotter.PlotterRegion;
-
+import hep.aida.ref.rootwriter.RootFileStore;
+
+import java.io.IOException;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
-
+
+import org.hps.recon.tracking.SvtPlotUtils;
 import org.lcsim.detector.tracker.silicon.HpsSiSensor;
-import org.lcsim.util.Driver;
-import org.lcsim.geometry.Detector;
 import org.lcsim.event.EventHeader;
 import org.lcsim.event.RawTrackerHit;
+import org.lcsim.geometry.Detector;
+import org.lcsim.util.Driver;
 import org.lcsim.util.aida.AIDA;
 
 /**
@@ -28,6 +30,8 @@
  * event.
  *
  * @author Omar Moreno <[log in to unmask]>
+ * @author Per Hansson Adrian <[log in to unmask]>
+ *
  */
 public class SvtHitPlots extends Driver {
 
@@ -38,23 +42,25 @@
 
     // Plotting
     private static ITree tree = null;
-    private IAnalysisFactory analysisFactory = AIDA.defaultInstance().analysisFactory();
-    private IPlotterFactory plotterFactory = analysisFactory.createPlotterFactory("SVT Hits");
+    private final IAnalysisFactory analysisFactory = AIDA.defaultInstance().analysisFactory();
+    private final IPlotterFactory plotterFactory = analysisFactory.createPlotterFactory("SVT Hits");
     private IHistogramFactory histogramFactory = null;
     protected Map<String, IPlotter> plotters = new HashMap<String, IPlotter>();
 
     // Histogram Maps
-    private static Map<String, IHistogram1D> hitsPerSensorPlots = new HashMap<String, IHistogram1D>();
-    private static Map<String, int[]> hitsPerSensor = new HashMap<String, int[]>();
-    private static Map<String, IHistogram1D> layersHitPlots = new HashMap<String, IHistogram1D>();
-    private static Map<String, IHistogram1D> hitCountPlots = new HashMap<String, IHistogram1D>();
-    private static Map<String, IHistogram1D> firstSamplePlots = new HashMap<String, IHistogram1D>();
+    private static final Map<String, IHistogram1D> hitsPerSensorPlots = new HashMap<String, IHistogram1D>();
+    private static final Map<String, int[]> hitsPerSensor = new HashMap<String, int[]>();
+    private static final Map<String, IHistogram1D> layersHitPlots = new HashMap<String, IHistogram1D>();
+    private static final Map<String, IHistogram1D> hitCountPlots = new HashMap<String, IHistogram1D>();
+    private static final Map<String, IHistogram1D> firstSamplePlots = new HashMap<String, IHistogram1D>();
+//    private static Map<String, IHistogram1D> firstSamplePlotsNoise = new HashMap<String, IHistogram1D>();
+    private static final Map<String, IHistogram2D> firstSamplePlotsNoisePerChannel = new HashMap<String, IHistogram2D>();
 
     private List<HpsSiSensor> sensors;
 
     private static final String SUBDETECTOR_NAME = "Tracker";
-    private String rawTrackerHitCollectionName = "SVTRawTrackerHits";
-    
+    private final String rawTrackerHitCollectionName = "SVTRawTrackerHits";
+
     // Counters
     double eventCount = 0;
     double totalHitCount = 0;
@@ -62,36 +68,23 @@
     double totalBotHitCount = 0;
 
     private boolean dropSmallHitEvents = true;
+    private static final boolean debug = false;
+    private boolean doPerChannelSamplePlots = false;
+    private int maxSampleCutForNoise = -1;
+    private boolean saveRootFile = false;
+    private String outputRootFilename = "";
+    private boolean showPlots = true;
 
     public void setDropSmallHitEvents(boolean dropSmallHitEvents) {
         this.dropSmallHitEvents = dropSmallHitEvents;
     }
 
-    private int computePlotterRegion(HpsSiSensor sensor) {
-
-        if (sensor.getLayerNumber() < 7) {
-            if (sensor.isTopLayer()) {
-                return 6 * (sensor.getLayerNumber() - 1);
-            } else {
-                return 6 * (sensor.getLayerNumber() - 1) + 1;
-            }
-        } else {
-
-            if (sensor.isTopLayer()) {
-                if (sensor.getSide() == HpsSiSensor.POSITRON_SIDE) {
-                    return 6 * (sensor.getLayerNumber() - 7) + 2;
-                } else {
-                    return 6 * (sensor.getLayerNumber() - 7) + 3;
-                }
-            } else if (sensor.isBottomLayer()) {
-                if (sensor.getSide() == HpsSiSensor.POSITRON_SIDE) {
-                    return 6 * (sensor.getLayerNumber() - 7) + 4;
-                } else {
-                    return 6 * (sensor.getLayerNumber() - 7) + 5;
-                }
-            }
-        }
-        return -1;
+    public void setDoPerChannelsSampleplots(boolean val) {
+        doPerChannelSamplePlots = val;
+    }
+
+    public void setSaveRootFile(boolean save) {
+        saveRootFile = save;
     }
 
     /**
@@ -137,6 +130,10 @@
         for (HpsSiSensor sensor : sensors) {
             hitsPerSensorPlots.get(sensor.getName()).reset();
             firstSamplePlots.get(sensor.getName()).reset();
+//            firstSamplePlotsNoise.get(sensor.getName()).reset();
+            if (doPerChannelSamplePlots) {
+                firstSamplePlotsNoisePerChannel.get(sensor.getName()).reset();
+            }
         }
 
         for (IHistogram1D histogram : layersHitPlots.values()) {
@@ -149,12 +146,13 @@
 
     }
 
+    @Override
     protected void detectorChanged(Detector detector) {
 
         // Get the HpsSiSensor objects from the geometry
         sensors = detector.getSubdetector(SUBDETECTOR_NAME).getDetectorElement().findDescendants(HpsSiSensor.class);
 
-        if (sensors.size() == 0) {
+        if (sensors.isEmpty()) {
             throw new RuntimeException("No sensors were found in this detector.");
         }
 
@@ -192,43 +190,74 @@
         plotters.get("Raw hit counts/Event").createRegions(2, 2);
 
         hitCountPlots.put("Raw hit counts/Event",
-                histogramFactory.createHistogram1D("Raw hit counts", 100, 0, 100));
+                histogramFactory.createHistogram1D("Raw hit counts", 100, 0, 500));
         plotters.get("Raw hit counts/Event").region(0).plot(hitCountPlots.get("Raw hit counts/Event"), SvtPlotUtils.createStyle(plotterFactory, "Number of Raw Hits", ""));
         hitCountPlots.put("SVT top raw hit counts/Event",
-                histogramFactory.createHistogram1D("SVT top raw hit counts", 100, 0, 100));
+                histogramFactory.createHistogram1D("SVT top raw hit counts", 100, 0, 300));
         plotters.get("Raw hit counts/Event").region(2).plot(hitCountPlots.get("SVT top raw hit counts/Event"), SvtPlotUtils.createStyle(plotterFactory, "Number of Raw Hits in Top Volume", ""));
         hitCountPlots.put("SVT bottom raw hit counts/Event",
-                histogramFactory.createHistogram1D("SVT bottom raw hit counts", 100, 0, 100));
+                histogramFactory.createHistogram1D("SVT bottom raw hit counts", 100, 0, 300));
         plotters.get("Raw hit counts/Event").region(3).plot(hitCountPlots.get("SVT bottom raw hit counts/Event"), SvtPlotUtils.createStyle(plotterFactory, "Number of Raw Bits in the Bottom Volume", ""));
 
         plotters.put("First sample distributions (pedestal shifts)", plotterFactory.create("First sample distributions (pedestal shifts)"));
         plotters.get("First sample distributions (pedestal shifts)").createRegions(6, 6);
+
+//        plotters.put("First sample distributions (pedestal shifts, MAX_SAMPLE>=4)", plotterFactory.create("First sample distributions (pedestal shifts, MAX_SAMPLE>=4)"));
+//        plotters.get("First sample distributions (pedestal shifts, MAX_SAMPLE>=4)").createRegions(6, 6);
+        if (doPerChannelSamplePlots) {
+            plotters.put("First sample channel distributions (pedestal shifts)", plotterFactory.create("First sample channel distributions (pedestal shifts)"));
+            plotters.get("First sample channel distributions (pedestal shifts)").createRegions(6, 6);
+        }
+
         for (HpsSiSensor sensor : sensors) {
             firstSamplePlots.put(sensor.getName(),
                     histogramFactory.createHistogram1D(sensor.getName() + " - first sample", 100, -500.0, 2000.0));
-            plotters.get("First sample distributions (pedestal shifts)").region(this.computePlotterRegion(sensor))
+            plotters.get("First sample distributions (pedestal shifts)").region(SvtPlotUtils.computePlotterRegion(sensor))
                     .plot(firstSamplePlots.get(sensor.getName()), this.createStyle(sensor, "First sample - pedestal [ADC counts]", ""));
+//            firstSamplePlotsNoise.put(sensor.getName(),
+//                    histogramFactory.createHistogram1D(sensor.getName() + " - first sample (MAX_SAMPLE>=4)", 100, -500.0, 2000.0));
+//            plotters.get("First sample distributions (pedestal shifts, MAX_SAMPLE>=4)").region(SvtPlotUtils.computePlotterRegion(sensor))
+//                    .plot(firstSamplePlotsNoise.get(sensor.getName()), this.createStyle(sensor, "First sample - pedestal (MAX_SAMPLE>=4) [ADC counts]", ""));
+
+            if (doPerChannelSamplePlots) {
+                firstSamplePlotsNoisePerChannel.put(sensor.getName(),
+                        histogramFactory.createHistogram2D(sensor.getName() + " channels - first sample", 640, -0.5, 639.5, 20, -500.0, 500.0));
+                plotters.get("First sample channel distributions (pedestal shifts)").region(SvtPlotUtils.computePlotterRegion(sensor))
+                        .plot(firstSamplePlotsNoisePerChannel.get(sensor.getName()), this.createStyle(sensor, "First sample channels - pedestal [ADC counts]", ""));
+            }
+
         }
 
         for (IPlotter plotter : plotters.values()) {
             for (int regionN = 0; regionN < plotter.numberOfRegions(); regionN++) {
                 PlotterRegion region = ((PlotterRegion) ((Plotter) plotter).region(regionN));
-                if (region.getPlottedObjects().size() == 0) {
+                if (region.getPlottedObjects().isEmpty()) {
                     continue;
                 }
                 region.getPanel().addMouseListener(new PopupPlotterListener(region));
             }
-            plotter.show();
-        }
-    }
-
+            if (showPlots) {
+                plotter.show();
+            }
+        }
+    }
+
+    @Override
     public void process(EventHeader event) {
 
         if (!event.hasCollection(RawTrackerHit.class, rawTrackerHitCollectionName)) {
             return;
         }
 
+        if (debug && ((int) eventCount % 100 == 0)) {
+            System.out.println(this.getClass().getSimpleName() + ": processed " + String.valueOf(eventCount) + " events");
+        }
+
         eventCount++;
+
+        if (outputRootFilename.isEmpty()) {
+            outputRootFilename = "run" + String.valueOf(event.getRunNumber());
+        }
 
         // Get RawTrackerHit collection from event.
         List<RawTrackerHit> rawHits = event.get(RawTrackerHit.class, rawTrackerHitCollectionName);
@@ -240,8 +269,31 @@
         this.clearHitMaps();
         for (RawTrackerHit rawHit : rawHits) {
             HpsSiSensor sensor = (HpsSiSensor) rawHit.getDetectorElement();
+            int channel = rawHit.getIdentifierFieldValue("strip");
+            double pedestal = sensor.getPedestal(channel, 0);
+            // Find the sample with maximum ADC count
+            int maxSample = 0;
+            double maxSampleValue = 0;
+            for (int s = 0; s < 6; ++s) {
+                if (((double) rawHit.getADCValues()[s] - pedestal) > maxSampleValue) {
+                    maxSample = s;
+                    maxSampleValue = ((double) rawHit.getADCValues()[s]) - pedestal;
+                }
+            }
+
             hitsPerSensor.get(sensor.getName())[0]++;
-            firstSamplePlots.get(sensor.getName()).fill(rawHit.getADCValues()[0] - sensor.getPedestal(rawHit.getIdentifierFieldValue("strip"), 0));
+            firstSamplePlots.get(sensor.getName()).fill(rawHit.getADCValues()[0] - pedestal);
+//            if (maxSampleCutForNoise >= 0 && maxSample >= maxSampleCutForNoise) {
+//                firstSamplePlotsNoise.get(sensor.getName()).fill(rawHit.getADCValues()[0] - pedestal);
+            if (doPerChannelSamplePlots) {
+                firstSamplePlotsNoisePerChannel.get(sensor.getName()).fill(channel, rawHit.getADCValues()[0] - pedestal);
+            }
+//            } else {
+//                firstSamplePlotsNoise.get(sensor.getName()).fill(rawHit.getADCValues()[0] - pedestal);
+//                if (doPerChannelSamplePlots) {
+//                    firstSamplePlotsNoisePerChannel.get(sensor.getName()).fill(channel, rawHit.getADCValues()[0] - pedestal);
+//                }
+//            }
         }
 
         int[] topLayersHit = new int[12];
@@ -300,6 +352,23 @@
         System.out.println("% Total Top SVT Hits/Event: " + totalTopHitCount / eventCount);
         System.out.println("% Total Bottom SVT Hits/Event: " + totalBotHitCount / eventCount);
         System.out.println("\n%================================================%");
+
+        if (saveRootFile) {
+            String rootFileName = outputRootFilename.isEmpty() ? "svthitplots.root" : outputRootFilename + "_svthitplots.root";
+            RootFileStore rootFileStore = new RootFileStore(rootFileName);
+            try {
+                rootFileStore.open();
+                rootFileStore.add(tree);
+                rootFileStore.close();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+
+    }
+
+    public void setShowPlots(boolean showPlots) {
+        this.showPlots = showPlots;
     }
 
 }

Modified: java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/svt/SvtTimingInPlots.java
 =============================================================================
--- java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/svt/SvtTimingInPlots.java	(original)
+++ java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/svt/SvtTimingInPlots.java	Wed Apr 27 11:11:32 2016
@@ -1,35 +1,31 @@
 package org.hps.monitoring.drivers.svt;
 
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map; 
-
 import hep.aida.IAnalysisFactory;
-import hep.aida.IHistogramFactory;
 import hep.aida.IHistogram1D;
 import hep.aida.IHistogram2D;
+import hep.aida.IHistogramFactory;
 import hep.aida.IPlotter;
 import hep.aida.IPlotterFactory;
 import hep.aida.IPlotterStyle;
 import hep.aida.ITree;
 import hep.aida.ref.rootwriter.RootFileStore;
 
-import org.lcsim.util.Driver; 
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.hps.recon.tracking.FittedRawTrackerHit;
+import org.hps.recon.tracking.ShapeFitParameters;
+import org.hps.record.triggerbank.SSPCluster;
+import org.hps.record.triggerbank.SSPData;
 import org.lcsim.detector.tracker.silicon.HpsSiSensor;
 import org.lcsim.detector.tracker.silicon.SiSensor;
 import org.lcsim.event.EventHeader;
-import org.lcsim.event.GenericObject;
 import org.lcsim.event.LCRelation;
 import org.lcsim.event.RawTrackerHit;
 import org.lcsim.geometry.Detector;
-import org.hps.recon.tracking.FittedRawTrackerHit;
-import org.hps.recon.tracking.ShapeFitParameters;
-import org.hps.record.triggerbank.AbstractIntData;
-import org.hps.record.triggerbank.SSPCluster;
-import org.hps.record.triggerbank.SSPData;
-import org.hps.record.triggerbank.SSPSinglesTrigger;
-import org.hps.record.triggerbank.TIData;
+import org.lcsim.util.Driver;
 
 /**
  *  Monitoring driver that will be used when 'timing in' the SVT.
@@ -244,51 +240,51 @@
         isEcalTopCluster = false;
         List<SSPCluster> clusters = null;
         SSPData sspData = null;
-		/*if(event.hasCollection(GenericObject.class, triggerBankCollectionName)) {
-		
-		    // Get the list of trigger banks from the event
-			List<GenericObject> triggerBanks = event.get(GenericObject.class, triggerBankCollectionName);
-
-			System.out.println("Total trigger banks: " + triggerBanks.size());
-			
-			// Loop through the collection of banks and get the SSP and TI banks.
-			for (GenericObject triggerBank : triggerBanks) { 
-			    
-			    // If the bank contains TI data, process it
-			    if (AbstractIntData.getTag(triggerBank) == TIData.BANK_TAG) { 
-			        
-			        TIData tiData = new TIData(triggerBank);
-			      
-			        // Check if the trigger is singles
-			        if (tiData.isSingle0Trigger() || tiData.isSingle1Trigger()) { 
-			            isSingleClusterTrigger = true;
-			        } 
-			        
-			    } else if (AbstractIntData.getTag(triggerBank) == SSPData.BANK_TAG) { 
-			       
-			        sspData = new SSPData(triggerBank);
-			        
-			        clusters = sspData.getClusters();
-			        
-			        for (SSPCluster cluster : clusters) { 
-			            if (cluster.getYIndex() > 0) { 
-			                isEcalTopCluster = true;
-			            }
-			        }
-			    }
-			}
-
-			if (isSingleClusterTrigger) {
-			    System.out.println("Total number of singles triggers: " + sspData.getSinglesTriggers().size());
-			    for (SSPSinglesTrigger trigger : sspData.getSinglesTriggers()) { 
-			        System.out.println("Trigger: " + trigger.toString());
-			    }
-			    System.out.println("Total number of SSP clusters: " + clusters.size());
-			    for (SSPCluster cluster : clusters) { 
-			        System.out.println("X: " + cluster.getXIndex() + " Y: " + cluster.getYIndex() + " time: " + cluster.getTime());
-			    }
-			}
-		}*/	
+        /*if(event.hasCollection(GenericObject.class, triggerBankCollectionName)) {
+        
+            // Get the list of trigger banks from the event
+            List<GenericObject> triggerBanks = event.get(GenericObject.class, triggerBankCollectionName);
+
+            System.out.println("Total trigger banks: " + triggerBanks.size());
+            
+            // Loop through the collection of banks and get the SSP and TI banks.
+            for (GenericObject triggerBank : triggerBanks) { 
+                
+                // If the bank contains TI data, process it
+                if (AbstractIntData.getTag(triggerBank) == TIData.BANK_TAG) { 
+                    
+                    TIData tiData = new TIData(triggerBank);
+                  
+                    // Check if the trigger is singles
+                    if (tiData.isSingle0Trigger() || tiData.isSingle1Trigger()) { 
+                        isSingleClusterTrigger = true;
+                    } 
+                    
+                } else if (AbstractIntData.getTag(triggerBank) == SSPData.BANK_TAG) { 
+                   
+                    sspData = new SSPData(triggerBank);
+                    
+                    clusters = sspData.getClusters();
+                    
+                    for (SSPCluster cluster : clusters) { 
+                        if (cluster.getYIndex() > 0) { 
+                            isEcalTopCluster = true;
+                        }
+                    }
+                }
+            }
+
+            if (isSingleClusterTrigger) {
+                System.out.println("Total number of singles triggers: " + sspData.getSinglesTriggers().size());
+                for (SSPSinglesTrigger trigger : sspData.getSinglesTriggers()) { 
+                    System.out.println("Trigger: " + trigger.toString());
+                }
+                System.out.println("Total number of SSP clusters: " + clusters.size());
+                for (SSPCluster cluster : clusters) { 
+                    System.out.println("X: " + cluster.getXIndex() + " Y: " + cluster.getYIndex() + " time: " + cluster.getTime());
+                }
+            }
+        }*/ 
         
         // Obtain all relations between an SVT raw hit and its corresponding
         // fit parameters.  The fit parameters are obtained from the fit to

Modified: java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/trackrecon/PlotAndFitUtilities.java
 =============================================================================
--- java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/trackrecon/PlotAndFitUtilities.java	(original)
+++ java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/trackrecon/PlotAndFitUtilities.java	Wed Apr 27 11:11:32 2016
@@ -50,7 +50,7 @@
     static void plot(IPlotter plotter, IBaseHistogram histogram, IPlotterStyle style, int region) {
         if (style == null)
             style = getPlotterStyle(histogram);
-        System.out.println("Putting plot in region " + region);
+        //System.out.println("Putting plot in region " + region);
         plotter.region(region).plot(histogram, style);
 
     }

Modified: java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/trackrecon/SVTOpeningAlignment.java
 =============================================================================
--- java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/trackrecon/SVTOpeningAlignment.java	(original)
+++ java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/trackrecon/SVTOpeningAlignment.java	Wed Apr 27 11:11:32 2016
@@ -1,8 +1,8 @@
 package org.hps.monitoring.drivers.trackrecon;
 
+import static org.hps.monitoring.drivers.trackrecon.PlotAndFitUtilities.fitAndPutParameters;
 import hep.aida.IAnalysisFactory;
 import hep.aida.IFitFactory;
-import hep.aida.IFitResult;
 import hep.aida.IFitter;
 import hep.aida.IFunction;
 import hep.aida.IFunctionFactory;
@@ -10,12 +10,13 @@
 import hep.aida.IPlotter;
 import hep.aida.IPlotterFactory;
 import hep.aida.IPlotterStyle;
+
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.logging.Level;
 import java.util.logging.Logger;
-import static org.hps.monitoring.drivers.trackrecon.PlotAndFitUtilities.fitAndPutParameters;
+
 import org.lcsim.event.EventHeader;
 import org.lcsim.event.Track;
 import org.lcsim.event.TrackState;
@@ -24,7 +25,6 @@
 import org.lcsim.geometry.Detector;
 import org.lcsim.util.Driver;
 import org.lcsim.util.aida.AIDA;
-import static org.hps.monitoring.drivers.trackrecon.PlotAndFitUtilities.performGaussianFit;
 
 /**
  *

Modified: java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/trackrecon/TrackResiduals.java
 =============================================================================
--- java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/trackrecon/TrackResiduals.java	(original)
+++ java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/trackrecon/TrackResiduals.java	Wed Apr 27 11:11:32 2016
@@ -1,20 +1,20 @@
 package org.hps.monitoring.drivers.trackrecon;
 
+import static org.hps.monitoring.drivers.trackrecon.PlotAndFitUtilities.fitAndPutParameters;
+import static org.hps.monitoring.drivers.trackrecon.PlotAndFitUtilities.plot;
 import hep.aida.IAnalysisFactory;
 import hep.aida.IFitFactory;
-import hep.aida.IFitResult;
-import hep.aida.IFitter;
 import hep.aida.IFunction;
 import hep.aida.IFunctionFactory;
 import hep.aida.IHistogram1D;
 import hep.aida.IPlotter;
 import hep.aida.IPlotterFactory;
+
 import java.io.IOException;
 import java.util.List;
 import java.util.logging.Level;
 import java.util.logging.Logger;
-import static org.hps.monitoring.drivers.trackrecon.PlotAndFitUtilities.fitAndPutParameters;
-import static org.hps.monitoring.drivers.trackrecon.PlotAndFitUtilities.plot;
+
 import org.lcsim.event.EventHeader;
 import org.lcsim.event.GenericObject;
 import org.lcsim.geometry.Detector;

Modified: java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/trackrecon/TrackTimePlots.java
 =============================================================================
--- java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/trackrecon/TrackTimePlots.java	(original)
+++ java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/trackrecon/TrackTimePlots.java	Wed Apr 27 11:11:32 2016
@@ -7,17 +7,14 @@
 import hep.aida.IPlotterStyle;
 import hep.aida.ref.plotter.style.registry.IStyleStore;
 import hep.aida.ref.plotter.style.registry.StyleRegistry;
-
 import java.util.List;
 
 import static org.hps.monitoring.drivers.trackrecon.PlotAndFitUtilities.plot;
 
-import org.hps.record.triggerbank.AbstractIntData;
-import org.hps.record.triggerbank.TestRunTriggerData;
 import org.lcsim.detector.tracker.silicon.DopedSilicon;
 import org.lcsim.detector.tracker.silicon.HpsSiSensor;
 import org.lcsim.event.EventHeader;
-import org.lcsim.event.GenericObject;
+import org.lcsim.event.RawTrackerHit;
 import org.lcsim.event.Track;
 import org.lcsim.event.TrackerHit;
 import org.lcsim.fit.helicaltrack.HelicalTrackCross;
@@ -116,7 +113,7 @@
 
         for (int i = 0; i < nlayers; i++) {
             int region = computePlotterRegion(i);
-            trackHit2D[i] = aida.histogram2D("Layer " + i + " trackHit vs dt", 75, -50, 100.0, 50, -20, 20.0);
+            trackHit2D[i] = aida.histogram2D("Layer " + i + " trigger phase vs dt", 80, -20, 20.0, 6, 0, 24.0);
             plot(plotter5, trackHit2D[i], style2d, region);
             trackHitDtChan[i] = aida.histogram2D("Layer " + i + " dt vs position", 200, -20, 20, 50, -20, 20.0);
             plot(plotter6, trackHitDtChan[i], style2d, region);
@@ -124,23 +121,23 @@
         plotter.show();
         plotter3.show();
         plotter4.show();
-//         plotter5.show();"Track Time vs. dt"
-//        plotter6.show(); "Track dt vs. Channel"
+        plotter5.show();//"Track Time vs. dt"
+        plotter6.show();// "Track dt vs. Channel"
 
         for (int module = 0; module < 2; module++) {
-            trackT0[module] = aida.histogram1D((module == 0 ? "Top" : "Bottom") + " Track Time", 75, -50, 100.0);
+            trackT0[module] = aida.histogram1D((module == 0 ? "Top" : "Bottom") + " Track Time", 80, -20, 20.0);
             plot(plotter2, trackT0[module], null, module);
-            trackTrigTime[module] = aida.histogram2D((module == 0 ? "Top" : "Bottom") + " Track Time vs. Trig Time", 75, -50, 100.0, 6, -2, 22);
+            trackTrigTime[module] = aida.histogram2D((module == 0 ? "Top" : "Bottom") + " Track Time vs. Trig Time", 80, -20, 20.0, 6, 0, 24);
             plot(plotter2, trackTrigTime[module], style2d, module + 2);
 
             trackTimeRange[module] = aida.histogram1D((module == 0 ? "Top" : "Bottom") + " Track Hit Time Range", 75, 0, 30.0);
             plot(plotter7, trackTimeRange[module], null, module);
-            trackTimeMinMax[module] = aida.histogram2D((module == 0 ? "Top" : "Bottom") + " First and Last Track Hit Times", 75, -50, 100.0, 75, -50, 100.0);
+            trackTimeMinMax[module] = aida.histogram2D((module == 0 ? "Top" : "Bottom") + " First and Last Track Hit Times", 80, -20, 20.0, 80, -20, 20.0);
             plot(plotter7, trackTimeMinMax[module], style2d, module + 2);
         }
 
         plotter2.show();
-//        plotter7.show(); //"Track Hit Time Range"
+        plotter7.show(); //"Track Hit Time Range"
     }
 
     public void setHitCollection(String hitCollection) {
@@ -166,7 +163,7 @@
 
         List<Track> tracks = event.get(Track.class, trackCollectionName);
         for (Track track : tracks) {
-            int trackModule = -1;
+            int trackModule;
             if (track.getTrackerHits().get(0).getPosition()[2] > 0) {
                 trackModule = 0;
             } else {
@@ -179,7 +176,8 @@
             for (TrackerHit hitCross : track.getTrackerHits()) {
                 for (HelicalTrackStrip hit : ((HelicalTrackCross) hitCross).getStrips()) {
                     int layer = hit.layer();
-                    trackHitT0[trackModule][layer - 1].fill(hit.dEdx() / DopedSilicon.ENERGY_EHPAIR);
+                    int module = ((RawTrackerHit) hit.rawhits().get(0)).getIdentifierFieldValue("module");
+                    trackHitT0[module][layer - 1].fill(hit.dEdx() / DopedSilicon.ENERGY_EHPAIR);
                     trackTime += hit.time();
                     hitCount++;
                     if (hit.time() > maxTime) {
@@ -202,8 +200,9 @@
             for (TrackerHit hitCross : track.getTrackerHits()) {
                 for (HelicalTrackStrip hit : ((HelicalTrackCross) hitCross).getStrips()) {
                     int layer = hit.layer();
-                    trackHitDt[trackModule][layer - 1].fill(hit.time() - trackTime);
-                    trackHit2D[layer - 1].fill(trackTime, hit.time() - trackTime);
+                    int module = ((RawTrackerHit) hit.rawhits().get(0)).getIdentifierFieldValue("module");
+                    trackHitDt[module][layer - 1].fill(hit.time() - trackTime);
+                    trackHit2D[layer - 1].fill(hit.time() - trackTime, event.getTimeStamp() % 24);
                     trackHitDtChan[layer - 1].fill(hit.umeas(), hit.time() - trackTime);
                 }
             }

Modified: java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/trackrecon/TrackingReconPlots.java
 =============================================================================
--- java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/trackrecon/TrackingReconPlots.java	(original)
+++ java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/trackrecon/TrackingReconPlots.java	Wed Apr 27 11:11:32 2016
@@ -12,14 +12,17 @@
 import java.util.List;
 import java.util.logging.Level;
 import java.util.logging.Logger;
+
 import static org.hps.monitoring.drivers.trackrecon.PlotAndFitUtilities.plot;
-import org.hps.recon.tracking.HPSTrack;
+
+import org.hps.recon.tracking.HpsHelicalTrackFit;
+import org.hps.recon.tracking.TrackUtils;
 import org.lcsim.event.Cluster;
-
 import org.lcsim.event.EventHeader;
 import org.lcsim.event.LCIOParameters.ParameterName;
 import org.lcsim.event.RawTrackerHit;
 import org.lcsim.event.Track;
+import org.lcsim.event.TrackState;
 import org.lcsim.event.TrackerHit;
 import org.lcsim.fit.helicaltrack.HelicalTrackFit;
 import org.lcsim.geometry.Detector;
@@ -267,10 +270,12 @@
             SeedTrack stEle = (SeedTrack) trk;
             SeedCandidate seedEle = stEle.getSeedCandidate();
             HelicalTrackFit ht = seedEle.getHelix();
-            HPSTrack hpstrk = new HPSTrack(ht);
+            HpsHelicalTrackFit hpstrk = new HpsHelicalTrackFit(ht);
             double svt_l12 = 900.00;//mm ~approximately...this doesn't matter much
             double ecal_face = 1393.00;//mm ~approximately ... this matters!  Should use typical shower depth...or, once have cluster match, use that value of Z
-            Hep3Vector posAtEcal = hpstrk.getPositionAtZMap(svt_l12, ecal_face, 5.0, event.getDetector().getFieldMap())[0];
+            TrackState stateAtEcal = TrackUtils.getTrackStateAtECal(trk);
+            Hep3Vector posAtEcal = new BasicHep3Vector(stateAtEcal.getReferencePoint());
+            //Hep3Vector posAtEcal = hpstrk.getPositionAtZMap(svt_l12, ecal_face, 5.0, event.getDetector().getFieldMap())[0];
             List<Cluster> clusters = event.get(Cluster.class, ecalCollectionName);
             if (clusters != null) {
                 if (debug)
@@ -282,10 +287,11 @@
                     Hep3Vector clusterPos = new BasicHep3Vector(clust.getPosition());
                     double zCluster = clusterPos.z();
                     //improve the extrapolation...use the reconstructed cluster z-position
-                    posAtEcal = hpstrk.getPositionAtZMap(svt_l12, zCluster, 5.0, event.getDetector().getFieldMap())[0];
+//                    stateAtEcal = TrackUtils.extrapolateTrackUsingFieldMap(trk, svt_l12, zCluster, 5.0, event.getDetector().getFieldMap());
+//                    posAtEcal = new BasicHep3Vector(stateAtEcal.getReferencePoint());
                     double eOverP = clust.getEnergy() / pmag;
-                    double dx = posAtEcal.x() - clusterPos.x();
-                    double dy = posAtEcal.y() - clusterPos.y();
+                    double dx = posAtEcal.y() - clusterPos.x();
+                    double dy = posAtEcal.z() - clusterPos.y();
                     heOverP.fill(eOverP);
                     hdelXECal.fill(dx);
                     hdelYECal.fill(dy);

Modified: java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/trackrecon/V0ReconPlots.java
 =============================================================================
--- java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/trackrecon/V0ReconPlots.java	(original)
+++ java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/trackrecon/V0ReconPlots.java	Wed Apr 27 11:11:32 2016
@@ -1,5 +1,6 @@
 package org.hps.monitoring.drivers.trackrecon;
 
+import static org.hps.monitoring.drivers.trackrecon.PlotAndFitUtilities.plot;
 import hep.aida.IAnalysisFactory;
 import hep.aida.IFitFactory;
 import hep.aida.IFunctionFactory;
@@ -7,12 +8,12 @@
 import hep.aida.IHistogram2D;
 import hep.aida.IPlotter;
 import hep.aida.IPlotterFactory;
-import hep.aida.IPlotterStyle;
+
 import java.io.IOException;
 import java.util.List;
 import java.util.logging.Level;
 import java.util.logging.Logger;
-import static org.hps.monitoring.drivers.trackrecon.PlotAndFitUtilities.plot;
+
 import org.lcsim.event.EventHeader;
 import org.lcsim.event.ReconstructedParticle;
 import org.lcsim.event.Track;
@@ -58,7 +59,7 @@
 
     @Override
     protected void detectorChanged(Detector detector) {
-        System.out.println("V0Monitoring::detectorChanged  Setting up the plotter");
+        //System.out.println("V0Monitoring::detectorChanged  Setting up the plotter");
 
         IAnalysisFactory fac = aida.analysisFactory();
         IPlotterFactory pfac = fac.createPlotterFactory("V0 Recon");

Modified: java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/BasicMonitoringPlotsDriver.java
 =============================================================================
--- java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/BasicMonitoringPlotsDriver.java	(original)
+++ java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/BasicMonitoringPlotsDriver.java	Wed Apr 27 11:11:32 2016
@@ -18,83 +18,83 @@
  * @author Jeremy McCormick <[log in to unmask]>
  */
 public class BasicMonitoringPlotsDriver extends Driver {
-	
-	private String calHitsCollectionName = "EcalCalHits"; 
-	private String rawHitsCollectionName = "EcalReadoutHits";
-	private String clustersCollectionName = "EcalClusters";
-	
-	private IHistogram1D calHitEnergyH1D;
-	private IHistogram1D clusterEnergyH1D;
-	private IHistogram1D rawHitAmplitudeH1D;
-	private IHistogram2D calHitEnergyMapH2D;
-	
-	public BasicMonitoringPlotsDriver() {		
-	}
-	
-	public void startOfData() {		
-		
-		IAnalysisFactory.create().createHistogramFactory(null);
-		IPlotterFactory plotFactory = IAnalysisFactory.create().createPlotterFactory("ECAL Monitoring");
-		IHistogramFactory histogramFactory = IAnalysisFactory.create().createHistogramFactory(null);
-		
-		calHitEnergyH1D = histogramFactory.createHistogram1D(calHitsCollectionName + ": Energy", calHitsCollectionName + ": Energy", 200, 0.0, 2.0);
-		calHitEnergyH1D.annotation().addItem("xAxisLabel", "GeV");
-		calHitEnergyH1D.annotation().addItem("yAxisLabel", "Count");
-		IPlotter plotter = plotFactory.create("CalorimeterHits");
-		plotter.createRegion();
-		plotter.style().gridStyle().setVisible(false);
-		plotter.style().dataStyle().errorBarStyle().setVisible(false);
-		plotter.region(0).plot(calHitEnergyH1D);
-		plotter.show();
-		
-		rawHitAmplitudeH1D = histogramFactory.createHistogram1D(rawHitsCollectionName + ": Amplitude", rawHitsCollectionName + ": Amplitude", 150, 0.0, 15000.0);
-		rawHitAmplitudeH1D.annotation().addItem("xAxisLabel", "ADC Value");
-		rawHitAmplitudeH1D.annotation().addItem("yAxisLabel", "Count");
-		plotter = plotFactory.create("RawCalorimeterHits");
-		plotter.createRegion();
-		plotter.style().gridStyle().setVisible(false);
-		plotter.style().dataStyle().errorBarStyle().setVisible(false);
-		plotter.region(0).plot(rawHitAmplitudeH1D);
-		plotter.show();
-		
-		clusterEnergyH1D = histogramFactory.createHistogram1D(clustersCollectionName + ": Energy", clustersCollectionName + ": Energy", 100, 0.0, 3.0);
-		clusterEnergyH1D.annotation().addItem("xAxisLabel", "GeV");
-		clusterEnergyH1D.annotation().addItem("yAxisLabel", "Count");
-		plotter = plotFactory.create("Clusters");
-		plotter.createRegion();
-		plotter.style().gridStyle().setVisible(false);
-		plotter.style().dataStyle().errorBarStyle().setVisible(false);
-		plotter.region(0).plot(clusterEnergyH1D);
-		plotter.show();
-		
-		calHitEnergyMapH2D = histogramFactory.createHistogram2D(calHitsCollectionName + ": Energy Map", calHitsCollectionName + ": Energy Map", 47, -23.5, 23.5, 11, -5.5, 5.5);
-		plotter = plotFactory.create("CalorimeterHit Energy Map");
-		plotter.createRegion();
-		plotter.style().setParameter("hist2DStyle", "colorMap");
-		plotter.style().gridStyle().setVisible(false);
-		plotter.region(0).plot(calHitEnergyMapH2D);
-		plotter.show();
-	}
-	
-	public void process(EventHeader event) {
-		
+    
+    private String calHitsCollectionName = "EcalCalHits"; 
+    private String rawHitsCollectionName = "EcalReadoutHits";
+    private String clustersCollectionName = "EcalClusters";
+    
+    private IHistogram1D calHitEnergyH1D;
+    private IHistogram1D clusterEnergyH1D;
+    private IHistogram1D rawHitAmplitudeH1D;
+    private IHistogram2D calHitEnergyMapH2D;
+    
+    public BasicMonitoringPlotsDriver() {       
+    }
+    
+    public void startOfData() {     
+        
+        IAnalysisFactory.create().createHistogramFactory(null);
+        IPlotterFactory plotFactory = IAnalysisFactory.create().createPlotterFactory("ECAL Monitoring");
+        IHistogramFactory histogramFactory = IAnalysisFactory.create().createHistogramFactory(null);
+        
+        calHitEnergyH1D = histogramFactory.createHistogram1D(calHitsCollectionName + ": Energy", calHitsCollectionName + ": Energy", 200, 0.0, 2.0);
+        calHitEnergyH1D.annotation().addItem("xAxisLabel", "GeV");
+        calHitEnergyH1D.annotation().addItem("yAxisLabel", "Count");
+        IPlotter plotter = plotFactory.create("CalorimeterHits");
+        plotter.createRegion();
+        plotter.style().gridStyle().setVisible(false);
+        plotter.style().dataStyle().errorBarStyle().setVisible(false);
+        plotter.region(0).plot(calHitEnergyH1D);
+        plotter.show();
+        
+        rawHitAmplitudeH1D = histogramFactory.createHistogram1D(rawHitsCollectionName + ": Amplitude", rawHitsCollectionName + ": Amplitude", 150, 0.0, 15000.0);
+        rawHitAmplitudeH1D.annotation().addItem("xAxisLabel", "ADC Value");
+        rawHitAmplitudeH1D.annotation().addItem("yAxisLabel", "Count");
+        plotter = plotFactory.create("RawCalorimeterHits");
+        plotter.createRegion();
+        plotter.style().gridStyle().setVisible(false);
+        plotter.style().dataStyle().errorBarStyle().setVisible(false);
+        plotter.region(0).plot(rawHitAmplitudeH1D);
+        plotter.show();
+        
+        clusterEnergyH1D = histogramFactory.createHistogram1D(clustersCollectionName + ": Energy", clustersCollectionName + ": Energy", 100, 0.0, 3.0);
+        clusterEnergyH1D.annotation().addItem("xAxisLabel", "GeV");
+        clusterEnergyH1D.annotation().addItem("yAxisLabel", "Count");
+        plotter = plotFactory.create("Clusters");
+        plotter.createRegion();
+        plotter.style().gridStyle().setVisible(false);
+        plotter.style().dataStyle().errorBarStyle().setVisible(false);
+        plotter.region(0).plot(clusterEnergyH1D);
+        plotter.show();
+        
+        calHitEnergyMapH2D = histogramFactory.createHistogram2D(calHitsCollectionName + ": Energy Map", calHitsCollectionName + ": Energy Map", 47, -23.5, 23.5, 11, -5.5, 5.5);
+        plotter = plotFactory.create("CalorimeterHit Energy Map");
+        plotter.createRegion();
+        plotter.style().setParameter("hist2DStyle", "colorMap");
+        plotter.style().gridStyle().setVisible(false);
+        plotter.region(0).plot(calHitEnergyMapH2D);
+        plotter.show();
+    }
+    
+    public void process(EventHeader event) {
+        
         if (event.hasCollection(CalorimeterHit.class, calHitsCollectionName)) {
             for (CalorimeterHit hit : event.get(CalorimeterHit.class, calHitsCollectionName)) {
                 calHitEnergyH1D.fill(hit.getCorrectedEnergy());
                 calHitEnergyMapH2D.fill(hit.getIdentifierFieldValue("ix"), hit.getIdentifierFieldValue("iy"), hit.getCorrectedEnergy());
             }
         }
-		
+        
         if (event.hasCollection(Cluster.class, clustersCollectionName)) {
             for (Cluster cluster : event.get(Cluster.class, clustersCollectionName)) {
                 clusterEnergyH1D.fill(cluster.getEnergy());
             }
         }
-		
-		if (event.hasCollection(RawCalorimeterHit.class, rawHitsCollectionName)) {
-			for (RawCalorimeterHit hit : event.get(RawCalorimeterHit.class, rawHitsCollectionName)) {
-				rawHitAmplitudeH1D.fill(hit.getAmplitude());
-			}
-		}
-	}
+        
+        if (event.hasCollection(RawCalorimeterHit.class, rawHitsCollectionName)) {
+            for (RawCalorimeterHit hit : event.get(RawCalorimeterHit.class, rawHitsCollectionName)) {
+                rawHitAmplitudeH1D.fill(hit.getAmplitude());
+            }
+        }
+    }
 }

Modified: java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/EcalClusterPlots.java
 =============================================================================
--- java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/EcalClusterPlots.java	(original)
+++ java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/EcalClusterPlots.java	Wed Apr 27 11:11:32 2016
@@ -49,15 +49,15 @@
  * @author Kyle McCarty <[log in to unmask]>
  */
 public class EcalClusterPlots extends Driver {
-	// Internal variables.
+    // Internal variables.
     private boolean hide = false;
     private boolean logScale = false;
-	private AIDA aida = AIDA.defaultInstance();
+    private AIDA aida = AIDA.defaultInstance();
     private double maxE = 5000 * EcalUtils.MeV;
-	private IPlotter[] plotter = new IPlotter[4];
-	private String clusterCollectionName = "EcalClusters";
-	
-	// Monitoring plot variables.
+    private IPlotter[] plotter = new IPlotter[4];
+    private String clusterCollectionName = "EcalClusters";
+    
+    // Monitoring plot variables.
     private IHistogram1D clusterCountPlot;
     private IHistogram1D clusterSizePlot;
     private IHistogram1D clusterEnergyPlot;
@@ -79,7 +79,7 @@
     private static final int TAB_CLUSTER_TIME = 2;
     private static final int TAB_CLUSTER_PAIR = 3;
     private static final String[] TAB_NAMES = { "Cluster Count Plots", "Cluster Energy Plots",
-    	"Cluster Time Plots", "Cluster Pair Plots" };
+        "Cluster Time Plots", "Cluster Pair Plots" };
     
     /**
      * Resets all of the plots for the new detector.
@@ -110,10 +110,10 @@
         
         // Apply formatting that is constant across all tabs.
         for(int tabIndex = 0; tabIndex < plotter.length; tabIndex++) {
-        	plotter[tabIndex] = plotterFactory.create(TAB_NAMES[tabIndex]);
-        	plotter[tabIndex].setTitle(TAB_NAMES[tabIndex]);
-        	plotter[tabIndex].style().dataStyle().errorBarStyle().setVisible(false);
-        	plotter[tabIndex].style().dataStyle().fillStyle().setParameter("showZeroHeightBins", Boolean.FALSE.toString());
+            plotter[tabIndex] = plotterFactory.create(TAB_NAMES[tabIndex]);
+            plotter[tabIndex].setTitle(TAB_NAMES[tabIndex]);
+            plotter[tabIndex].style().dataStyle().errorBarStyle().setVisible(false);
+            plotter[tabIndex].style().dataStyle().fillStyle().setParameter("showZeroHeightBins", Boolean.FALSE.toString());
             if(logScale) { plotter[tabIndex].style().yAxisStyle().setParameter("scale", "log"); }
         }
         
@@ -145,9 +145,9 @@
         
         // If they should not be hidden, display the tabs.
         if(!hide) {
-        	for(IPlotter tab : plotter) {
-        		tab.show();
-        	}
+            for(IPlotter tab : plotter) {
+                tab.show();
+            }
         }
     }
     
@@ -157,121 +157,121 @@
      */
     @Override
     public void process(EventHeader event) {
-    	// Check whether the event has clusters or not.
-    	if(event.hasCollection(Cluster.class, clusterCollectionName)) {
-    		// Get the list of clusters.
-    		List<Cluster> clusterList = event.get(Cluster.class, clusterCollectionName);
-    		
-    		// Create lists to store the clusters from the top of the
-    		// calorimeter and the bottom.
-    		List<Cluster> topList = new ArrayList<Cluster>();
-    		List<Cluster> bottomList = new ArrayList<Cluster>();
-    		
-    		// Track the highest energy cluster in the event.
-    		double maxEnergy = 0.0;
-    		
-    		// Process each of the clusters.
-    		for(Cluster cluster : clusterList) {
-    			// If this cluster has a higher energy then was seen
-    			// previously, it is now the highest energy cluster.
-				if (cluster.getEnergy() > maxEnergy) {
-					maxEnergy = cluster.getEnergy();
-				}
-				
-				
-				// Get the list of calorimeter hits and its size.
-				List<CalorimeterHit> hitList = cluster.getCalorimeterHits();
-				int hitCount = hitList.size();
-				
-				// Track cluster statistics.
-				double xEnergyWeight = 0.0;
-				double yEnergyWeight = 0.0;
-				double[] hitTimes = new double[hitCount];
-				double totalHitEnergy = 0.0;
-				
-				// Iterate over the hits and extract statistics from them.
-				for(int hitIndex = 0; hitIndex < hitCount; hitIndex++) {
-					hitTimes[hitIndex] = hitList.get(hitIndex).getTime();
-					totalHitEnergy += hitList.get(hitIndex).getRawEnergy();
-					xEnergyWeight += (hitList.get(hitIndex).getRawEnergy() * hitList.get(hitIndex).getIdentifierFieldValue("ix"));
-					yEnergyWeight += (hitList.get(hitIndex).getRawEnergy() * hitList.get(hitIndex).getIdentifierFieldValue("iy"));
-				}
-				
-				// If the cluster energy exceeds zero, plot the cluster
-				// statistics.
-				if(cluster.getEnergy() > 0) {
-					clusterSizePlot.fill(hitCount);
-					clusterTimes.fill(StatUtils.mean(hitTimes, 0, hitCount));
-					clusterTimeSigma.fill(Math.sqrt(StatUtils.variance(hitTimes, 0, hitCount)));
-					edgePlot.fill(xEnergyWeight / totalHitEnergy, yEnergyWeight / totalHitEnergy);
-				}
-				
-				// Fill the single cluster plots.
-				clusterEnergyPlot.fill(cluster.getEnergy());
-				
-    			// Cluster pairs are formed from all top/bottom cluster
-    			// combinations. To create these pairs, separate the
-    			// clusters into two lists based on their y-indices.
-    			if(cluster.getCalorimeterHits().get(0).getIdentifierFieldValue("ix") > 0) {
-    				topList.add(cluster);
-    			} else {
-    				bottomList.add(cluster);
-    			}
-    		}
-    		
-    		// Populate the event plots.
-    		clusterCountPlot.fill(clusterList.size());
-    		if(maxEnergy > 0) { clusterMaxEnergyPlot.fill(maxEnergy); }
-    		
-    		// Create a list to store cluster pairs.
-    		List<Cluster[]> pairList = new ArrayList<Cluster[]>(topList.size() * bottomList.size());
-    		
-    		// Form pairs from all possible combinations of clusters
-    		// from the top and bottom lists.
-    		for(Cluster topCluster : topList) {
-    			for(Cluster bottomCluster : bottomList) {
-    				// Make a cluster pair array.
-    				Cluster[] pair = new Cluster[2];
-    				
-    				// The lower energy cluster goes in the second slot.
-    				if(topCluster.getEnergy() > bottomCluster.getEnergy()) {
-    					pair[0] = topCluster;
-    					pair[1] = bottomCluster;
-    				} else {
-    					pair[0] = bottomCluster;
-    					pair[1] = topCluster;
-    				}
-    				
-    				// Add the pair to the pair list.
-    				pairList.add(pair);
-    			}
-    		}
-    		
-    		// Iterate over each pair and calculate the pair cut values.
-    		for(Cluster[] pair : pairList) {
-    			// Get the energy slope value.
-    			double energySumValue = TriggerModule.getValueEnergySum(pair);
-    			double energyDifferenceValue = TriggerModule.getValueEnergyDifference(pair);
-    			double energySlopeValue = TriggerModule.getValueEnergySlope(pair, 0.005500);
-    			double coplanarityValue = TriggerModule.getValueCoplanarity(pair);
-    			double xMean = ((pair[0].getEnergy() * pair[0].getPosition()[0]) +
-    					(pair[1].getEnergy() * pair[1].getPosition()[0])) / energySumValue;
-    			double yMean = ((pair[0].getEnergy() * pair[0].getPosition()[1]) +
-    					(pair[1].getEnergy() * pair[1].getPosition()[1])) / energySumValue;
-    			
-    			// Populate the cluster pair plots.
-    			pairEnergySum.fill(energySumValue, 1);;
-    			pairEnergyDifference.fill(energyDifferenceValue, 1);
-    			pairEnergySlope.fill(energySlopeValue, 1);
-    			pairCoplanarity.fill(coplanarityValue, 1);
-    			pairEnergyPositionMeanX.fill(xMean);
-    			pairEnergyPositionMeanY.fill(yMean);
-    		}
-    	}
-    	
-    	// If the event does not contain clusters, update the "Event
-    	// Clusters" plot accordingly.
-    	else { clusterCountPlot.fill(0); }
+        // Check whether the event has clusters or not.
+        if(event.hasCollection(Cluster.class, clusterCollectionName)) {
+            // Get the list of clusters.
+            List<Cluster> clusterList = event.get(Cluster.class, clusterCollectionName);
+            
+            // Create lists to store the clusters from the top of the
+            // calorimeter and the bottom.
+            List<Cluster> topList = new ArrayList<Cluster>();
+            List<Cluster> bottomList = new ArrayList<Cluster>();
+            
+            // Track the highest energy cluster in the event.
+            double maxEnergy = 0.0;
+            
+            // Process each of the clusters.
+            for(Cluster cluster : clusterList) {
+                // If this cluster has a higher energy then was seen
+                // previously, it is now the highest energy cluster.
+                if (cluster.getEnergy() > maxEnergy) {
+                    maxEnergy = cluster.getEnergy();
+                }
+                
+                
+                // Get the list of calorimeter hits and its size.
+                List<CalorimeterHit> hitList = cluster.getCalorimeterHits();
+                int hitCount = hitList.size();
+                
+                // Track cluster statistics.
+                double xEnergyWeight = 0.0;
+                double yEnergyWeight = 0.0;
+                double[] hitTimes = new double[hitCount];
+                double totalHitEnergy = 0.0;
+                
+                // Iterate over the hits and extract statistics from them.
+                for(int hitIndex = 0; hitIndex < hitCount; hitIndex++) {
+                    hitTimes[hitIndex] = hitList.get(hitIndex).getTime();
+                    totalHitEnergy += hitList.get(hitIndex).getRawEnergy();
+                    xEnergyWeight += (hitList.get(hitIndex).getRawEnergy() * hitList.get(hitIndex).getIdentifierFieldValue("ix"));
+                    yEnergyWeight += (hitList.get(hitIndex).getRawEnergy() * hitList.get(hitIndex).getIdentifierFieldValue("iy"));
+                }
+                
+                // If the cluster energy exceeds zero, plot the cluster
+                // statistics.
+                if(cluster.getEnergy() > 0) {
+                    clusterSizePlot.fill(hitCount);
+                    clusterTimes.fill(StatUtils.mean(hitTimes, 0, hitCount));
+                    clusterTimeSigma.fill(Math.sqrt(StatUtils.variance(hitTimes, 0, hitCount)));
+                    edgePlot.fill(xEnergyWeight / totalHitEnergy, yEnergyWeight / totalHitEnergy);
+                }
+                
+                // Fill the single cluster plots.
+                clusterEnergyPlot.fill(cluster.getEnergy());
+                
+                // Cluster pairs are formed from all top/bottom cluster
+                // combinations. To create these pairs, separate the
+                // clusters into two lists based on their y-indices.
+                if(cluster.getCalorimeterHits().get(0).getIdentifierFieldValue("ix") > 0) {
+                    topList.add(cluster);
+                } else {
+                    bottomList.add(cluster);
+                }
+            }
+            
+            // Populate the event plots.
+            clusterCountPlot.fill(clusterList.size());
+            if(maxEnergy > 0) { clusterMaxEnergyPlot.fill(maxEnergy); }
+            
+            // Create a list to store cluster pairs.
+            List<Cluster[]> pairList = new ArrayList<Cluster[]>(topList.size() * bottomList.size());
+            
+            // Form pairs from all possible combinations of clusters
+            // from the top and bottom lists.
+            for(Cluster topCluster : topList) {
+                for(Cluster bottomCluster : bottomList) {
+                    // Make a cluster pair array.
+                    Cluster[] pair = new Cluster[2];
+                    
+                    // The lower energy cluster goes in the second slot.
+                    if(topCluster.getEnergy() > bottomCluster.getEnergy()) {
+                        pair[0] = topCluster;
+                        pair[1] = bottomCluster;
+                    } else {
+                        pair[0] = bottomCluster;
+                        pair[1] = topCluster;
+                    }
+                    
+                    // Add the pair to the pair list.
+                    pairList.add(pair);
+                }
+            }
+            
+            // Iterate over each pair and calculate the pair cut values.
+            for(Cluster[] pair : pairList) {
+                // Get the energy slope value.
+                double energySumValue = TriggerModule.getValueEnergySum(pair);
+                double energyDifferenceValue = TriggerModule.getValueEnergyDifference(pair);
+                double energySlopeValue = TriggerModule.getValueEnergySlope(pair, 0.005500);
+                double coplanarityValue = TriggerModule.getValueCoplanarity(pair);
+                double xMean = ((pair[0].getEnergy() * pair[0].getPosition()[0]) +
+                        (pair[1].getEnergy() * pair[1].getPosition()[0])) / energySumValue;
+                double yMean = ((pair[0].getEnergy() * pair[0].getPosition()[1]) +
+                        (pair[1].getEnergy() * pair[1].getPosition()[1])) / energySumValue;
+                
+                // Populate the cluster pair plots.
+                pairEnergySum.fill(energySumValue, 1);;
+                pairEnergyDifference.fill(energyDifferenceValue, 1);
+                pairEnergySlope.fill(energySlopeValue, 1);
+                pairCoplanarity.fill(coplanarityValue, 1);
+                pairEnergyPositionMeanX.fill(xMean);
+                pairEnergyPositionMeanY.fill(yMean);
+            }
+        }
+        
+        // If the event does not contain clusters, update the "Event
+        // Clusters" plot accordingly.
+        else { clusterCountPlot.fill(0); }
     }
     
     /**

Modified: java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/EcalDaqPlots.java
 =============================================================================
--- java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/EcalDaqPlots.java	(original)
+++ java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/EcalDaqPlots.java	Wed Apr 27 11:11:32 2016
@@ -11,23 +11,19 @@
 
 import org.hps.conditions.database.DatabaseConditionsManager;
 import org.hps.conditions.ecal.EcalChannel;
-import org.hps.conditions.ecal.EcalConditions;
-import org.hps.detector.ecal.EcalCrystal;
 import org.lcsim.event.CalorimeterHit;
 import org.lcsim.event.EventHeader;
 import org.lcsim.geometry.Detector;
-import org.lcsim.geometry.compact.Subdetector;
 import org.lcsim.util.Driver;
 import org.lcsim.util.aida.AIDA;
 
-/*Conditions system imports*/
-
 /**
- * The driver <code>EcalDaqPlots</code> implements the histogram shown to the user in the fourth tab of the Monitoring Application, when using the Ecal monitoring lcsim file. It contains only a
- * sub-tab, showing the number of hits recorded by the different FADC channels. It is a very preliminary driver to monitor the DAQ status. These plots are updated continuosly.
+ * The driver <code>EcalDaqPlots</code> implements the histogram shown to the user in the fourth tab of the 
+ * Monitoring Application, when using the Ecal monitoring lcsim file. It contains only a sub-tab, showing
+ * the number of hits recorded by the different FADC channels. It is a very preliminary driver to monitor
+ * the DAQ status. These plots are updated continuously.
+ * 
  * @author Andrea Celentano
- * @TODO: integrate with the new conditions system.
- * 
  */
 public class EcalDaqPlots extends Driver {
 

Modified: java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/EcalEventDisplay.java
 =============================================================================
--- java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/EcalEventDisplay.java	(original)
+++ java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/EcalEventDisplay.java	Wed Apr 27 11:11:32 2016
@@ -13,7 +13,6 @@
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
-import java.lang.IllegalArgumentException;
 
 import javax.swing.SwingUtilities;
 

Modified: java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/EcalEventDisplayWithRawWaveform.java
 =============================================================================
--- java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/EcalEventDisplayWithRawWaveform.java	(original)
+++ java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/EcalEventDisplayWithRawWaveform.java	Wed Apr 27 11:11:32 2016
@@ -13,14 +13,12 @@
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
-import java.lang.IllegalArgumentException;
 
 import org.hps.monitoring.ecal.eventdisplay.ui.PDataEventViewer;
 import org.hps.monitoring.ecal.eventdisplay.ui.PEventViewer;
 import org.hps.monitoring.ecal.eventdisplay.ui.Viewer;
 import org.hps.monitoring.ecal.eventdisplay.util.CrystalEvent;
 import org.hps.monitoring.ecal.eventdisplay.util.CrystalListener;
-import org.hps.monitoring.ecal.plots.EcalMonitoringUtilities;
 import org.hps.recon.ecal.EcalUtils;
 import org.lcsim.event.CalorimeterHit;
 import org.lcsim.event.RawTrackerHit;
@@ -54,7 +52,7 @@
     // Plotter objects and variables.
     private IPlotter plotter;
     private IPlotterFactory plotterFactory;
-    private AIDA aida = AIDA.defaultInstance();	
+    private AIDA aida = AIDA.defaultInstance(); 
 
     // LCIO Collection names.
     private String inputCollection = "EcalCalHits";
@@ -69,16 +67,16 @@
     private ArrayList<IHistogram2D> channelTimeVsEnergyPlot;
 
     // Internal variables.
-    private PEventViewer viewer;								 // Single event display.
-    private int pedSamples = 10;								 // 
-    private IPlotterStyle pstyle;								 // The plotter style for all plots.
-    private long lastEventTime = 0;								 // Tracks the time at which the last event occurred.
-    private int eventRefreshRate = 1;							 // The number of seconds before an update occurs.
-    private boolean resetOnUpdate = true;						 // Clears the event display on each update.
-    private double minEch = 10 * EcalUtils.MeV;					 // The energy scale minimum.
-    private double maxEch = 3500 * EcalUtils.MeV;				 // The energy scale maximum.
-    private int[] windowRaw = new int[NUM_CHANNELS];			 // The number of samples in a waveform for each channel.
-    private boolean[] isFirstRaw = new boolean[NUM_CHANNELS];	 // Whether a waveform plot was initiated for each channel.
+    private PEventViewer viewer;                                 // Single event display.
+    private int pedSamples = 10;                                 // 
+    private IPlotterStyle pstyle;                                // The plotter style for all plots.
+    private long lastEventTime = 0;                              // Tracks the time at which the last event occurred.
+    private int eventRefreshRate = 1;                            // The number of seconds before an update occurs.
+    private boolean resetOnUpdate = true;                        // Clears the event display on each update.
+    private double minEch = 10 * EcalUtils.MeV;                  // The energy scale minimum.
+    private double maxEch = 3500 * EcalUtils.MeV;                // The energy scale maximum.
+    private int[] windowRaw = new int[NUM_CHANNELS];             // The number of samples in a waveform for each channel.
+    private boolean[] isFirstRaw = new boolean[NUM_CHANNELS];    // Whether a waveform plot was initiated for each channel.
 
     // Plot style and title variables.
     private static final String NO_TITLE = "";

Modified: java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/EcalHitPlots.java
 =============================================================================
--- java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/EcalHitPlots.java	(original)
+++ java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/EcalHitPlots.java	Wed Apr 27 11:11:32 2016
@@ -190,17 +190,17 @@
                 GenericObject triggerData = triggerList.get(0);
                
                 if (triggerData instanceof SSPData){
-                	// TODO: TOP, BOTTOM, OR, and AND triggers are test
-                	// run specific parameters and are not supported
-                	// by SSPData.
-                	orTrigTime  = 0; //((SSPData)triggerData).getOrTrig();
-                	topTrigTime = 0; //((SSPData)triggerData).getTopTrig();
-                	botTrigTime = 0; //((SSPData)triggerData).getBotTrig(); 
-
-                	
-                	orTrigTimePlot.fill(orTrigTime);
+                    // TODO: TOP, BOTTOM, OR, and AND triggers are test
+                    // run specific parameters and are not supported
+                    // by SSPData.
+                    orTrigTime  = 0; //((SSPData)triggerData).getOrTrig();
+                    topTrigTime = 0; //((SSPData)triggerData).getTopTrig();
+                    botTrigTime = 0; //((SSPData)triggerData).getBotTrig(); 
+
+                    
+                    orTrigTimePlot.fill(orTrigTime);
                     topTrigTimePlot.fill(topTrigTime);
-                	botTrigTimePlot.fill(botTrigTime);
+                    botTrigTimePlot.fill(botTrigTime);
 
                 }       
                 

Modified: java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/EcalLedSequenceMonitor.java
 =============================================================================
--- java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/EcalLedSequenceMonitor.java	(original)
+++ java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/EcalLedSequenceMonitor.java	Wed Apr 27 11:11:32 2016
@@ -1,4 +1,5 @@
 package org.hps.monitoring.ecal.plots;
+
 
 import hep.aida.IEvaluator;
 import hep.aida.IFitResult;
@@ -21,7 +22,6 @@
 import java.io.PrintWriter;
 import java.sql.SQLException;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -53,6 +53,8 @@
 import org.lcsim.util.Driver;
 import org.lcsim.util.aida.AIDA;
 
+
+
 /* This is the driver used to determine the response of each calorimeter channel after a LED run
  * @author Andrea Celentano  <[log in to unmask]>
  */
@@ -64,16 +66,16 @@
     private static final int runNumberMax = 9999;
     private static final int nDrivers = 8;
     private static final int nSteps = 100; //should be 56 but here is to avoid seg fault
-    
-   
+
+
 
     String inputCollectionRaw = "EcalReadoutHits";
-    String inputCollection = "EcalCalHits";	
+    String inputCollection = "EcalCalHits";
     AIDA aida;
 
     DatabaseConditionsManager conditionsManager;
 
-    private EcalChannelCollection ChannelCollection;	
+    private EcalChannelCollection ChannelCollection;    
     private EcalLedCollection LedCollection;
     private EcalConditions ecalConditions;
 
@@ -88,7 +90,7 @@
     String outFileName;
 
 
-    private int runNumber = 0;	
+    private int runNumber = 0;    
     private int eventN    = 0;
     private int id,row,column,chid,ledId,driverId;
     private  int[][] expectedSequence = new int[][]{ /*A.C. it is a terrible thing to have this hard-coded here!*/
@@ -98,9 +100,9 @@
             {112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,-1}, //missing 135 is ok
             {168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223},
             //second 4 are the flasher2 sequence, BOTTOM controller 
-            {2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,-1,-1},	
+            {2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,-1,-1},    
             {56,57,58,59,60,61,62,63,64,65,66,67,68,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,-1}, //missing 69 is OK
-            {112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167},	
+            {112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167},    
             {168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223},
     };
     private int[][] actualSequence=new int[nDrivers][nSteps];
@@ -126,7 +128,8 @@
 
     private IFunction  fFunction,fFunction1;
     private IProfile1D   cProfile;
-    private IHistogram2D			hMeanCharge2D;
+    private IHistogram2D            hMeanCharge2D;
+    private IHistogram2D            hMeanCharge2DReferenceRatio;
     private ArrayList<IHistogram1D> hCharge;
     private ArrayList<IHistogram2D> hChargeVsEvn;
     private IPlotterFactory factory;
@@ -149,6 +152,11 @@
     private double fEvnMaxDraw=80000.;
     private double fChargeMinDraw=0.;
     private double fChargeMaxDraw=100.;
+
+    /*The reference run numbers*/
+    private int fRedReferenceID;
+    private int fBlueReferenceID;
+
 
     /*Components for user interaction*/
     private JDialog dialog;
@@ -161,6 +169,14 @@
     private LedColor m_ret=LedColor.UNKNOWN; //use UNKNONW as CANCEL button
     static Object modalMonitor = new Object();
 
+    public void setRedReferenceID(int redReference){
+        this.fRedReferenceID=redReference;
+    }
+
+    public void setBlueReferenceID(int blueReference){
+        this.fBlueReferenceID=blueReference;
+    }
+
     public void setUseRawEnergy(boolean useRawEnergy) {
         this.useRawEnergy=useRawEnergy;
     }
@@ -218,29 +234,29 @@
         conditionsManager = DatabaseConditionsManager.getInstance();
 
         LedTopMap = new HashMap< Integer , Integer >(); //key: ecal channel ID. Value:  led id
-        LedBotMap = new HashMap< Integer , Integer >();	
+        LedBotMap = new HashMap< Integer , Integer >();    
 
         LedTopMapInverted = new HashMap< Integer , Integer >(); //key: led id. Value: ecal channel id
         LedBotMapInverted = new HashMap< Integer , Integer >(); 
 
 
-        ChannelCollection = conditionsManager.getCachedConditions(EcalChannelCollection.class, "ecal_channels").getCachedData();	
+        ChannelCollection = conditionsManager.getCachedConditions(EcalChannelCollection.class, "ecal_channels").getCachedData();    
         LedCollection = conditionsManager.getCachedConditions(EcalLedCollection.class, "ecal_leds").getCachedData();
-        ecalConditions = conditionsManager.getEcalConditions();		
+        ecalConditions = conditionsManager.getEcalConditions();        
 
         for (EcalChannel channel : ChannelCollection){
             chid = channel.getChannelId();
-            for (EcalLed Led : LedCollection) {    	
-                if (Led.getEcalChannelId()==chid){
-                    if (channel.getY()>0){
-                        LedTopMap.put( chid , Led.getLedNumber() );
-                        LedTopMapInverted.put(  Led.getLedNumber(), chid  );
-                    }
-                    else if (channel.getY()<0){
-                        LedBotMap.put( chid , Led.getLedNumber() );
-                        LedBotMapInverted.put( Led.getLedNumber(), chid );                    
-                    }
-                }
+            for (EcalLed Led : LedCollection) {        
+    if (Led.getEcalChannelId()==chid){
+        if (channel.getY()>0){
+            LedTopMap.put( chid , Led.getLedNumber() );
+            LedTopMapInverted.put(  Led.getLedNumber(), chid  );
+        }
+        else if (channel.getY()<0){
+            LedBotMap.put( chid , Led.getLedNumber() );
+            LedBotMapInverted.put( Led.getLedNumber(), chid );        
+        }
+    }
             }
         }
 
@@ -250,14 +266,16 @@
         aida = AIDA.defaultInstance();
         aida.tree().cd("/");
         hMeanCharge2D = aida.histogram2D("Average LED response", 47, -23.5, 23.5, 11, -5.5, 5.5);
-
+        hMeanCharge2DReferenceRatio = aida.histogram2D("Ratio this run VS reference run", 47, -23.5, 23.5, 11, -5.5, 5.5);
+        
         factory= aida.analysisFactory().createPlotterFactory("Ecal Led Sequence");
         pPlotter= factory.create("Drivers");
         pPlotter.createRegions(4,2);
         if (isMonitoringApp){
             pPlotter2=factory.create("Sequence Map");
-            pPlotter2.createRegions(1,1);
+            pPlotter2.createRegions(1,2);
             pPlotter2.region(0).plot(hMeanCharge2D);
+            pPlotter2.region(1).plot(hMeanCharge2DReferenceRatio);
         }   
         iTuple = new ArrayList<ITuple>(NUM_CHANNELS);   
         hCharge = new ArrayList<IHistogram1D>(NUM_CHANNELS);
@@ -269,7 +287,7 @@
 
         for (int ii=0;ii<NUM_CHANNELS;ii++){
             int row = EcalMonitoringUtilities.getRowFromHistoID(ii);
-            int column = EcalMonitoringUtilities.getColumnFromHistoID(ii);	    
+            int column = EcalMonitoringUtilities.getColumnFromHistoID(ii);        
             iTuple.add(aida.analysisFactory().createTupleFactory(aida.tree()).create("nTuple"+ii,"nTuple"+ii,"int fEvn=0 , double fCharge=0.,double fTime=0.",""));
         }
 
@@ -281,7 +299,7 @@
         pPlotter.show();
         if (isMonitoringApp) pPlotter2.show();
 
-    }		
+    }        
 
     @Override
     public void process(EventHeader event) {
@@ -292,81 +310,83 @@
             List<CalorimeterHit> hits = event.get(CalorimeterHit.class, inputCollection);
             for (CalorimeterHit hit : hits) {
 
-                column = hit.getIdentifierFieldValue("ix");
-                row = hit.getIdentifierFieldValue("iy");
-                id = EcalMonitoringUtilities.getHistoIDFromRowColumn(row, column);
-                cellID=hit.getCellID();        
-                chid = ChannelCollection.findGeometric(cellID).getChannelId();
-
-                energy = hit.getCorrectedEnergy();
-                
-                if (useRawEnergy){
-                    fillEnergy = getRawADCSum(energy,cellID);
-                }
-                else {
-                    fillEnergy = energy;
-                }
-                fillTime = hit.getTime();
-
-
-                //find the LED
-                if (row>0){
-                    ledId=LedTopMap.get(chid);
-                }
-                else if (row<0){
-                    ledId=LedBotMap.get(chid);
-                }
-                driverId=getDriver(ledId);
-                if (row<0) driverId+=4;
-
-
-
-                /*Skip the events under thr*/
-                if (energy<energyCut) continue;
-                
-                /*First, check if this led is the one in the NEXT step. Therefore, increment by 1 the step*/
-                if (iStep[driverId]==0){
+    column = hit.getIdentifierFieldValue("ix");
+    row = hit.getIdentifierFieldValue("iy");
+    id = EcalMonitoringUtilities.getHistoIDFromRowColumn(row, column);
+    cellID=hit.getCellID();        
+    chid = ChannelCollection.findGeometric(cellID).getChannelId();
+
+    energy = hit.getCorrectedEnergy();
+
+    if (useRawEnergy){
+        fillEnergy = getRawADCSum(energy,cellID);
+    }
+    else {
+        fillEnergy = energy;
+    }
+    fillTime = hit.getTime();
+
+
+    //find the LED
+    if (row>0){
+        ledId=LedTopMap.get(chid);
+    }
+    else if (row<0){
+        ledId=LedBotMap.get(chid);
+    }
+    driverId=getDriver(ledId);
+    if (row<0) driverId+=4;
+
+
+
+    /*Skip the events under thr*/
+    if (energy<energyCut) continue;
+
+    /*First, check if this led is the one in the NEXT step. Therefore, increment by 1 the step*/
+    /*
+     * if (iStep[driverId]==0){
+
                     actualSequence[driverId][iStep[driverId]]=ledId;
-                    iStep[driverId]=1;                  
+                    iStep[driverId]=1;      
                 }
                 else if ((iStep[driverId]==1)&&(ledId!=actualSequence[driverId][0])){              
-                    System.out.println("LedAnalysis:: increment step ("+iStep[driverId]+") for driver "+driverId+" . Led ID: "+ledId+" Column: "+column+" Row: "+row);                 
+                    System.out.println("LedAnalysis:: increment step ("+iStep[driverId]+") for driver "+driverId+" . Led ID: "+ledId+" Column: "+column+" Row: "+row);     
                     if (iStep[driverId]>0) drawProfiles(actualSequence[driverId][iStep[driverId]-1],driverId); 
                     actualSequence[driverId][iStep[driverId]]=ledId;
                     iStep[driverId]++;
                 }
                 else if ((iStep[driverId]>1)&&(ledId!=actualSequence[driverId][iStep[driverId]-1])&&(ledId!=actualSequence[driverId][iStep[driverId]-2])){
-                    System.out.println("LedAnalysis:: increment step ("+iStep[driverId]+") for driver "+driverId+" . Led ID: "+ledId+" Column: "+column+" Row: "+row);                 
+                    System.out.println("LedAnalysis:: increment step ("+iStep[driverId]+") for driver "+driverId+" . Led ID: "+ledId+" Column: "+column+" Row: "+row);     
                     if (iStep[driverId]>0) drawProfiles(actualSequence[driverId][iStep[driverId]-1],driverId); 
                     actualSequence[driverId][iStep[driverId]]=ledId;
                     iStep[driverId]++;
                 }
 
 
-
-
-
-
-                if (iStep[driverId]==-1) continue; /*Not yet data*/
-
-                /*Put this code here, since we want to always fill the ntuple*/
-                iTuple.get(id).fill(0,nEvents[id]);
-                iTuple.get(id).fill(1,fillEnergy);
-                iTuple.get(id).fill(2,fillTime);
-                iTuple.get(id).addRow();
-                nEvents[id]++;
-
-
-
-                /*Add a debug print */
-                if (eventN % 10000==0){
-                    System.out.println("Debug. Event "+eventN+" LED ID: "+ledId+" DRIVER ID: "+driverId+" ECAL ID: "+id+" ROW: "+row+" COLUMN: "+column+ "HISTO ID: "+id);
-                }
+                //    if (iStep[driverId]==-1) continue; 
+
+     */
+
+    if (iStep[driverId]==-1) continue; /*Not yet data*/
+
+    /*Put this code here, since we want to always fill the ntuple*/
+    iTuple.get(id).fill(0,nEvents[id]);
+    iTuple.get(id).fill(1,fillEnergy);
+    iTuple.get(id).fill(2,fillTime);
+    iTuple.get(id).addRow();
+    nEvents[id]++;
+
+
+
+    /*Add a debug print */
+    if (eventN % 10000==0){
+        System.out.println("Debug. Event "+eventN+" LED ID: "+ledId+" DRIVER ID: "+driverId+" ECAL ID: "+id+" ROW: "+row+" COLUMN: "+column+ "HISTO ID: "+id);
+    }
             }
             if (eventN % 10000==0){
-                System.out.println("\n");
-            }
-        }		
+    System.out.println("\n");
+            }
+        }        
     }
 
     /*
@@ -392,7 +412,7 @@
 
         double e,eMin,eMax;
         double t;
-        int n,nBins,nFits,nSkip;
+        int n,nBins,nSkip;
 
         int row, column;
 
@@ -400,7 +420,7 @@
         IFunctionFactory fFactory=aida.analysisFactory().createFunctionFactory(aida.tree());
 
         IFitResult fResult;
-        IFitter	   fFitter;
+        IFitter       fFitter;
 
         for (int id = 0; id < 11 * 47; id++) {
 
@@ -409,7 +429,7 @@
             row = EcalMonitoringUtilities.getRowFromHistoID(id);
             column = EcalMonitoringUtilities.getColumnFromHistoID(id);
             System.out.println("");
-            System.out.println("Doing channel: X= "+column+" Y= "+row);
+            System.out.println("Doing channel: X= "+column+" Y= "+row+ "id= "+id);
             System.out.println("Number of entries in analysis ntuple: "+iTuple.get(id).rows());
             System.out.println("Number of recognized events: "+nEvents[id]);
             /*Create the profile. Create it for all the channels, to keep sync.*/
@@ -419,9 +439,9 @@
             /*Clear previous*/
 
             if (id>0){
-                aida.tree().rm("strip");
-                aida.tree().rm("fun0");
-                aida.tree().rm("fun1");
+    aida.tree().rm("strip");
+    aida.tree().rm("fun0");
+    aida.tree().rm("fun1");
             }
             /*Create the profile.*/
             cProfile=aida.profile1D("strip",nBins,-0.5,nEvents[id]*(1-skipInitial)+0.5);
@@ -431,98 +451,79 @@
             fFunction1=fFactory.createFunctionByName("fun1","G");
 
             if (EcalMonitoringUtilities.isInHole(row,column)==true){
-                System.out.println("Channel X= "+column+" Y= "+row+" is in hole. Skip");
-                hCharge.add(aida.histogram1D("charge_"+id,200,0.,1.)); //create here the histogram to keep sync
-                System.out.println("In hole, skip");
-                continue;
+    System.out.println("Channel X= "+column+" Y= "+row+" is in hole. Skip");
+    hCharge.add(aida.histogram1D("charge_"+id,200,0.,1.)); //create here the histogram to keep sync
+    System.out.println("In hole, skip");
+    continue;
             }
             else if (nEvents[id]<nEventsMin) {
-                hCharge.add(aida.histogram1D("charge_"+id,200,0.,1.)); //create here the histogram to keep sync
-                System.err.println("LedAnalysis:: the channel X= "+column+" Y= "+row+" has not enough events "+nEvents[id]+" "+nEventsMin);
-
-                continue;
-            }			  
+    hCharge.add(aida.histogram1D("charge_"+id,200,0.,1.)); //create here the histogram to keep sync
+    System.err.println("LedAnalysis:: the channel X= "+column+" Y= "+row+" has not enough events "+nEvents[id]+" "+nEventsMin);
+
+    continue;
+            }              
 
             //Fill the profile*/
             nSkip=(int)(nEvents[id]*skipInitial);
             if (nSkip>iTuple.get(id).rows()){
-                System.out.println("Can't skip initial events?");
-                nSkip=0;
+    System.out.println("Can't skip initial events?");
+    nSkip=0;
             }
             iTuple.get(id).start();
             iTuple.get(id).skip(nSkip); //This is the work-around for those channels with charge starting from 0 and rapidly growing//
             n=0;
             iTuple.get(id).next(); 
             while ( iTuple.get(id).next() ){
-                e=iTuple.get(id).getDouble(1);
-                if (e<eMin) eMin=e;           			  
-                if (e>eMax) eMax=e;
-                cProfile.fill(1.*n,e);
-                n++;
-            }			
+    e=iTuple.get(id).getDouble(1);
+    if (e<eMin) eMin=e;                         
+    if (e>eMax) eMax=e;
+    cProfile.fill(1.*n,e);
+    n++;
+            }            
             fFitter=aida.analysisFactory().createFitFactory().createFitter("chi2","","v");
 
             if (doFullAnalysis){ 
-                //Init function parameters
-                double[] initialPars={eMax-eMin,nEvents[id]/10.,eMin};
-                if (initialPars[0]<0) initialPars[0]=0;
-                fFunction.setParameters(initialPars);
-
-                //Do the fit      
-                System.out.println("LedAnalysis:: do profile fit "+id+" "+fFitter.engineName()+" "+fFitter.fitMethodName());
-                System.out.println("LedAnalysis:: initial parameters "+initialPars[0]+" "+initialPars[1]+" "+initialPars[2]);
-                fResult=fFitter.fit(cProfile,fFunction);
-                fPars     = fResult.fittedParameters();
-                fParErrs  = fResult.errors();
-                fParNames = fResult.fittedParameterNames();			
-                System.out.println("LedAnalysis:: Status= "+fResult.fitStatus()+" "+fResult.isValid()+" Chi2 = "+fResult.quality()+" NDF: "+fResult.ndf());
-                for(int i=0; i< fResult.fittedFunction().numberOfParameters(); i++ ){
-                    System.out.println(fParNames[i]+" : "+fPars[i]+" +- "+fParErrs[i]);
-                }  
-                fFunction.setParameters(fPars);
-
-
-                //Do again the fit: it is a terrible work-around
-                nFits=0;
-                if (Double.isNaN(fParErrs[1])){
-                    fPars=fPrevPars;
-                }
-                while (Double.isNaN(fParErrs[1])){
-                    System.out.println("LedAnalysis:: redo fit");
-                    fFunction.setParameters(fPars);
-                    fResult=fFitter.fit(cProfile,fFunction);
-                    fPars     = fResult.fittedParameters();
-                    fParErrs  = fResult.errors();
-                    System.out.println("LedAnalysis:: Status= "+fResult.fitStatus()+" "+fResult.isValid()+" Chi2 = "+fResult.quality()+" NDF: "+fResult.ndf());
-                    for(int i=0; i< fResult.fittedFunction().numberOfParameters(); i++ ){
-                        System.out.println(fParNames[i]+" : "+fPars[i]+" +- "+fParErrs[i]);
-                    }  
-                    fFunction.setParameters(fPars);
-                    nFits++;
-                    if (nFits>=10){
-                        System.out.println("LedAnalysis:: Error, too many fits without convergence");
-                        break;
-                    }
-                }
-                fPrevPars=Arrays.copyOf(fPars,fPars.length);
-                System.out.println("LedAnalysis:: fit "+id+" done");  
-
-                //Now we have the tau parameter. Take ONLY the events that are with N>5*tau/
-                //As a cross-check, also verify that tau > Nevents/10, otherwise skip the first Nevents/2
-                //and emit warning
-                nSkip=(int)( fPars[1]*5);
-                if (nSkip < (nEvents[id]*skipMin)){
-                    System.out.println("LedAnalysis:: Skip number too low: "+nSkip+" Increment it to "+nEvents[id]/2);
-                    nSkip=(int)(nEvents[id]*skipMin);
-                }
-                if (nSkip > nEvents[id]){
-                    System.out.println("LedAnalysis:: Skip number too high, reduce it");
-                    nSkip=(int)(nEvents[id]*skipMin);
-                }
-
+    //Init function parameters
+    double[] initialPars={eMax-eMin,nEvents[id]/10.,eMin};
+    if (initialPars[0]<0) initialPars[0]=0;
+    fFunction.setParameters(initialPars);
+
+    //Do the fit      
+    System.out.println("LedAnalysis:: do profile fit "+id+" "+fFitter.engineName()+" "+fFitter.fitMethodName());
+    System.out.println("LedAnalysis:: initial parameters "+initialPars[0]+" "+initialPars[1]+" "+initialPars[2]);
+    fResult=fFitter.fit(cProfile,fFunction);
+    fPars     = fResult.fittedParameters();
+    fParErrs  = fResult.errors();
+    fParNames = fResult.fittedParameterNames();            
+    System.out.println("LedAnalysis:: Status= "+fResult.fitStatus()+" "+fResult.isValid()+" Chi2 = "+fResult.quality()+" NDF: "+fResult.ndf());
+    for(int i=0; i< fResult.fittedFunction().numberOfParameters(); i++ ){
+        System.out.println(fParNames[i]+" : "+fPars[i]+" +- "+fParErrs[i]);
+    }  
+    fFunction.setParameters(fPars);
+
+
+    //if fit failed, revert to simpler case
+    if ((fResult.isValid()==false)||Double.isNaN(fParErrs[0])||Double.isNaN(fParErrs[1])||Double.isNaN(fParErrs[2])){
+        System.out.println("LedAnalysis:: fit failed. Reverting to simpler case");
+        nSkip=(int)(nEvents[id]*(skipMin+skipInitial));
+    }
+    else{   
+        //Now we have the tau parameter. Take ONLY the events that are with N>5*tau/
+        //As a cross-check, also verify that tau > Nevents/10, otherwise skip the first Nevents/2
+        //and emit warning
+        nSkip=(int)( fPars[1]*5);
+        if (nSkip < (nEvents[id]*skipMin)){
+            System.out.println("LedAnalysis:: Skip number too low: "+nSkip+" Increment it to "+nEvents[id]/2);
+            nSkip=(int)(nEvents[id]*(skipMin+skipInitial));
+        }
+        if (nSkip > nEvents[id]){
+            System.out.println("LedAnalysis:: Skip number too high, reduce it");
+            nSkip=(int)(nEvents[id]*(skipMin+skipInitial));
+        }
+    }
             }
             else{
-                nSkip=(int)(nEvents[id]*(skipMin+skipInitial));
+    nSkip=(int)(nEvents[id]*(skipMin+skipInitial));
             }
 
             System.out.println("LedAnalysis:: gaus fit :: Going to skip "+nSkip+" out of "+nEvents[id]);
@@ -534,11 +535,11 @@
             iTuple.get(id).skip(nSkip); 
             n=0;
             while (iTuple.get(id).next()){
-                e=iTuple.get(id).getDouble(1);
-                t=iTuple.get(id).getDouble(2);
-                hCharge.get(id).fill(e);
-                n++;
-            }			
+    e=iTuple.get(id).getDouble(1);
+    t=iTuple.get(id).getDouble(2);
+    hCharge.get(id).fill(e);
+    n++;
+            }            
 
             /*Finally do the fit with the gaussian*/
             double[] initialPars1={hCharge.get(id).maxBinHeight(),hCharge.get(id).mean(),hCharge.get(id).rms()};
@@ -550,10 +551,10 @@
             fResult=fFitter.fit(hCharge.get(id),fFunction1);
             fPars     = fResult.fittedParameters();
             fParErrs  = fResult.errors();
-            fParNames = fResult.fittedParameterNames();			
+            fParNames = fResult.fittedParameterNames();            
             System.out.println("Status= "+fResult.fitStatus()+" "+fResult.isValid()+" Chi2 = "+fResult.quality()+" NDF: "+fResult.ndf());
             for(int i=0; i< fResult.fittedFunction().numberOfParameters(); i++ ){
-                System.out.println(fParNames[i]+" : "+fPars[i]+" +- "+fParErrs[i]);
+    System.out.println(fParNames[i]+" : "+fPars[i]+" +- "+fParErrs[i]);
             }  
             fFunction1.setParameters(fPars);
             mMean[id]=fPars[1];
@@ -572,6 +573,15 @@
             style.dataStyle().fillStyle().setParameter("showZeroHeightBins", Boolean.FALSE.toString()); 
             pPlotter2.region(0).plot(hMeanCharge2D);
             pPlotter2.region(0).refresh();
+            
+            
+            style = pPlotter2.region(1).style();
+            style.setParameter("hist2DStyle", "colorMap");
+            style.dataStyle().fillStyle().setParameter("colorMapScheme", "rainbow");
+            style.dataStyle().fillStyle().setParameter("showZeroHeightBins", Boolean.FALSE.toString()); 
+            pPlotter2.region(1).plot(hMeanCharge2DReferenceRatio);
+            pPlotter2.region(1).refresh();
+            
         }
         else{
             IPlotterStyle pstyle =  aida.analysisFactory().createPlotterFactory().createPlotterStyle();
@@ -581,58 +591,72 @@
             pstyle.dataStyle().fillStyle().setParameter("showZeroHeightBins", Boolean.FALSE.toString());
             pstyle.setParameter("hist2DStyle", "colorMap");
             if (pPlotter2!=null){
-                pPlotter2.createRegion().plot(hMeanCharge2D,pstyle);
-                pPlotter2.show();
+    pPlotter2.createRegion().plot(hMeanCharge2D,pstyle);
+    pPlotter2.show();
             }
         }
 
         if (isMonitoringApp){
             askUploadToDBDialog();
             synchronized (modalMonitor) {
-                try{
-                    modalMonitor.wait(60000); //wait 1 minute for user interaction.
-                }
-                catch(InterruptedException excp){
-                    System.out.println("Got exception: "+excp);
-                }
+    try{
+        modalMonitor.wait(60000); //wait 1 minute for user interaction.
+    }
+    catch(InterruptedException excp){
+        System.out.println("Got exception: "+excp);
+    }
             }
             if ((m_ret!=LedColor.UNKNOWN)){
-                if (m_ret==LedColor.BLUE)    System.out.println("OK, upload to DB BLUE");
-                else System.out.println("OK, upload to DB RED");
-                try {
-                    uploadToDB(m_ret);
-                } catch (SQLException | DatabaseObjectException | ConditionsObjectException error) {
-                    throw new RuntimeException("Error uploading to the database ", error);
-                }
-
-                System.out.println("Save an Elog too");
-                uploadToElog();
+    if (m_ret==LedColor.BLUE)    System.out.println("OK, upload to DB BLUE");
+    else System.out.println("OK, upload to DB RED");
+    try {
+        uploadToDB(m_ret);
+    } catch (SQLException | DatabaseObjectException | ConditionsObjectException error) {
+        throw new RuntimeException("Error uploading to the database ", error);
+    }
+
+    System.out.println("Get reference data, produce reference ratio map");
+    compareWithReference(m_ret);
+
+    style = pPlotter2.region(1).style();
+    style.setParameter("hist2DStyle", "colorMap");
+    style.dataStyle().fillStyle().setParameter("colorMapScheme", "rainbow");
+    style.dataStyle().fillStyle().setParameter("showZeroHeightBins", Boolean.FALSE.toString()); 
+    pPlotter2.region(1).plot(hMeanCharge2DReferenceRatio);
+    pPlotter2.region(1).refresh();
+    
+    System.out.println("Save an Elog too");
+    uploadToElog();
             }
             else{
-                System.out.println("Cancel pressed. Nothing to do");
-            }
-        }
+    System.out.println("Cancel pressed. Nothing to do");
+            }
+        }
+
+       
 
         /*Write a file with the LED values*/
         try {
             if (useRawEnergy){
-                outFileName=runNumber+".raw.txt";
+    outFileName=runNumber+".raw.txt";
             }
             else{
-                outFileName=runNumber+".energy.txt";
+    outFileName=runNumber+".energy.txt";
             }
             PrintWriter writer = new PrintWriter(outFileName, "UTF-8");
 
-
-            for (int id = 0; id < 11 * 47; id++) {
-
-                row = EcalMonitoringUtilities.getRowFromHistoID(id);
-                column = EcalMonitoringUtilities.getColumnFromHistoID(id);
-                if (EcalMonitoringUtilities.isInHole(row, column)) continue;
-                if ((row == 0) || (column == 0)) continue;
-
-                writer.print(column+" "+row+" "+" "+ mMean[id]+" "+mRMS[id]+"\r\n");
-
+            for (int cid = 1; cid <= 442; cid++) {/*This is a loop over the channel ID, as in the conditions system*/
+    EcalChannel cc = findChannel(cid);
+    column = cc.getX(); //This is the column
+    row = cc.getY(); //This is the row
+    id=EcalMonitoringUtilities.getHistoIDFromRowColumn(row,column);
+    row = EcalMonitoringUtilities.getRowFromHistoID(id);
+    column = EcalMonitoringUtilities.getColumnFromHistoID(id);
+    if (EcalMonitoringUtilities.isInHole(row, column)) continue;
+    if ((row == 0) || (column == 0)) continue;
+
+    writer.print(cid+" "+column+" "+row+" "+" "+ mMean[id]+" "+mRMS[id]+"\r\n");
+    
             }
             writer.close();
 
@@ -648,30 +672,31 @@
             System.out.println(ioe.getMessage());
 
         }
-
-
+        
+        
+        
+        
         System.out.println("EcalLedSequenceMonitor endOfData clear histograms"); 
-        for(int ii = 0; ii < NUM_CHANNELS; ii++) {   	
+        for(int ii = 0; ii < NUM_CHANNELS; ii++) {       
             row=EcalMonitoringUtilities.getRowFromHistoID(ii);
-            column = EcalMonitoringUtilities.getColumnFromHistoID(ii);      	  
-            hName="charge_"+ii;	 
+            column = EcalMonitoringUtilities.getColumnFromHistoID(ii);            
+            hName="charge_"+ii;     
             try{
-                aida.tree().rm(hName);
+    aida.tree().rm(hName);
             }
             catch(IllegalArgumentException ee){
-                System.out.println("Got exception "+ee);
+    System.out.println("Got exception "+ee);
             }
 
             if (!saveTuple||(isMonitoringApp)){
-                hName="nTuple"+ii;
-                try{
-                    aida.tree().rm(hName);
-                }
-                catch(IllegalArgumentException ee){
-                    System.out.println("Got exception "+ee);
-                }
-            }
-
+    hName="nTuple"+ii;
+    try{
+        aida.tree().rm(hName);
+    }
+    catch(IllegalArgumentException ee){
+        System.out.println("Got exception "+ee);
+    }
+            }
         }
         System.out.println("EcalLedSequenceMonitor endOfData clear histograms done");   
         System.out.println("endOfData end");
@@ -682,10 +707,10 @@
     /**
      * This function returns the driver number (from 0 to 3) given the LED id.
      * @param led
-     * @return
+     * @return the driver number from the LED id
      */
     public int getDriver(int led){
-        int ret=-1;	
+        int ret=-1;    
         if ((led>=2)&&(led<56)) ret=0;
         else if ((led>=56)&&(led<112)) ret=1;
         else if ((led>=112)&&(led<168)) ret=2;
@@ -698,7 +723,7 @@
      * If the gain changes (because we do a re-calibration), I do not want to include this in the LED analysis
      * @param energy
      * @param cellID
-     * @return
+     * @return the pedestal-subtracted raw energy
      */
     public double getRawADCSum(double energy,long cellID){
         EcalChannelConstants channelData = ecalConditions.getChannelConstants(ecalConditions.getChannelCollection().findGeometric(cellID));
@@ -713,8 +738,8 @@
         int x,y,id;
         double mean,rms;
         System.out.println(String.format("Uploading new led data to the database, runMin=%d, runMax=%d, tag=%s ....",
-                runNumber,runNumberMax,dbTag));
-        
+    runNumber,runNumberMax,dbTag));
+
         conditionsManager = DatabaseConditionsManager.getInstance();
         EcalLedCalibrationCollection led_calibrations =  new EcalLedCalibrationCollection();
         led_calibrations.setConnection(conditionsManager.getConnection());
@@ -743,8 +768,8 @@
         System.err.println("CollectionID:  "+collectionId);
         led_calibrations.insert();
         ConditionsRecord conditionsRecord = new ConditionsRecord(
-                led_calibrations.getCollectionId(), runNumber, runNumberMax, dbTableName, dbTableName, 
-                "Generated by LedAnalysis from Run #"+runNumber, dbTag);
+    led_calibrations.getCollectionId(), runNumber, runNumberMax, dbTableName, dbTableName, 
+    "Generated by LedAnalysis from Run #"+runNumber, dbTag);
         conditionsRecord.setConnection(conditionsManager.getConnection());
         tableMetaData = conditionsManager.findTableMetaData("conditions");
         conditionsRecord.setTableMetaData(tableMetaData);
@@ -789,6 +814,79 @@
         }
     }
 
+    private void compareWithReference(LedColor color){
+        int ID=0;
+        int x,y,chid;
+        double mean,rms,fillData=1;
+        if (color==LedColor.UNKNOWN){
+            System.out.println("LedMonitoringSequence::compare with reference, doing nothing");
+            return;
+        }
+        else if (color==LedColor.RED) ID=fRedReferenceID;
+        else if (color==LedColor.BLUE) ID=fBlueReferenceID;
+
+        conditionsManager = DatabaseConditionsManager.getInstance();
+
+
+        EcalLedCalibrationCollection referenceDataCollection =  new EcalLedCalibrationCollection();
+        referenceDataCollection.setConnection(conditionsManager.getConnection());
+
+        TableMetaData tableMetaData = conditionsManager.findTableMetaData(dbTableName);
+        referenceDataCollection.setTableMetaData(tableMetaData);
+        System.out.println("Try to get reference data from DB. Collection ID is "+ID);
+        try {
+            referenceDataCollection.select(ID);
+        } catch (SQLException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        } catch (DatabaseObjectException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+      
+        /*Now data from the reference should be there*/
+        for (EcalLedCalibration referenceData : referenceDataCollection){
+
+            chid=referenceData.getFieldValue("ecal_channel_id");
+            mean=referenceData.getFieldValue("led_response");
+            rms=referenceData.getFieldValue("rms");
+
+            EcalChannel cc = findChannel(chid);
+            column = cc.getX(); //This is the column
+            row = cc.getY(); //This is the row
+            chid=EcalMonitoringUtilities.getHistoIDFromRowColumn(row,column);
+            row = EcalMonitoringUtilities.getRowFromHistoID(id);
+            column = EcalMonitoringUtilities.getColumnFromHistoID(id);
+            
+
+            if (mean!=0) fillData=mMean[id]/mean;
+            else fillData=1;
+            System.out.println("row= "+row+" column= "+column+" data= "+mMean[id]+" ref= "+mean+" ratio= "+fillData);
+            hMeanCharge2DReferenceRatio.fill(column,row,fillData);
+         
+          
+
+        }
+
+
+        
+        style = pPlotter2.region(0).style();
+        style.setParameter("hist2DStyle", "colorMap");
+        style.dataStyle().fillStyle().setParameter("colorMapScheme", "rainbow");
+        style.dataStyle().fillStyle().setParameter("showZeroHeightBins", Boolean.FALSE.toString()); 
+        pPlotter2.region(0).plot(hMeanCharge2D);
+        pPlotter2.region(0).refresh();
+        
+        
+        style = pPlotter2.region(1).style();
+        style.setParameter("hist2DStyle", "colorMap");
+        style.dataStyle().fillStyle().setParameter("colorMapScheme", "rainbow");
+        style.dataStyle().fillStyle().setParameter("showZeroHeightBins", Boolean.FALSE.toString()); 
+        pPlotter2.region(1).plot(hMeanCharge2DReferenceRatio);
+        pPlotter2.region(1).refresh();
+        
+
+    }
 
     private void drawProfiles(int ledID,int driverID){
 
@@ -836,9 +934,9 @@
         okButtonBlue = new JButton("Yes, blue");
         cancelButton = new JButton("Cancel");
         labelString = "<html> Update conditions to DB <br> for run: <br> "+runNumber+" - "+runNumberMax+" <br> ???? <br> "
-                + "Use the monitoring app to look at the map<br>"
-                + "(Tab LED sequence)<br>"
-                +"Reply in 60 seconds<br>"+"</html>";   
+    + "Use the monitoring app to look at the map<br>"
+    + "(Tab LED sequence)<br>"
+    +"Reply in 60 seconds<br>"+"</html>";   
         label = new JLabel( labelString);
 
         frame  = new JFrame("Upload to DB?");
@@ -859,49 +957,49 @@
         panel.add(cancelButton);
         panel.add(okButtonBlue);
         panel.add(okButtonRed);
-     
+
 
         frame.setVisible(true);
         okButtonBlue.addActionListener(new ActionListener(){
             public void actionPerformed(ActionEvent event)
             {
-                m_ret=LedColor.BLUE;
-                frame.dispose();    
-                synchronized(modalMonitor)
-                {
-                    System.out.println("Blue pressed");
-                    modalMonitor.notify();
-                }
-            }
-        }
-                );
+    m_ret=LedColor.BLUE;
+    frame.dispose();    
+    synchronized(modalMonitor)
+    {
+        System.out.println("Blue pressed");
+        modalMonitor.notify();
+    }
+            }
+        }
+    );
         okButtonRed.addActionListener(new ActionListener(){
             public void actionPerformed(ActionEvent event)
             {
-                m_ret=LedColor.RED;
-                frame.dispose();    
-                synchronized(modalMonitor)
-                {
-                    System.out.println("Red pressed");
-                    modalMonitor.notify();
-                }
-            }
-        }
-                );
+    m_ret=LedColor.RED;
+    frame.dispose();    
+    synchronized(modalMonitor)
+    {
+        System.out.println("Red pressed");
+        modalMonitor.notify();
+    }
+            }
+        }
+    );
 
         cancelButton.addActionListener(new ActionListener(){
             public void actionPerformed(ActionEvent event)
             {
-                m_ret=LedColor.UNKNOWN;
-                frame.dispose();   
-                synchronized(modalMonitor)
-                {
-                    System.out.println("Cancel pressed");
-                    modalMonitor.notify();
-                }
-            }
-        }
-                );
+    m_ret=LedColor.UNKNOWN;
+    frame.dispose();   
+    synchronized(modalMonitor)
+    {
+        System.out.println("Cancel pressed");
+        modalMonitor.notify();
+    }
+            }
+        }
+    );
 
         System.out.println("askUploadDB done");
     }

Modified: java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/EcalMonitoringPlots.java
 =============================================================================
--- java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/EcalMonitoringPlots.java	(original)
+++ java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/EcalMonitoringPlots.java	Wed Apr 27 11:11:32 2016
@@ -59,7 +59,7 @@
 
     /**
      * Set the refresh rate for histograms in this driver
-     * @param eventRefreshRate: the refresh rate, defined as number of events to accumulate before
+     * @param eventRefreshRate the refresh rate, defined as number of events to accumulate before
      *        refreshing the plot
      */
     public void setEventRefreshRate(int eventRefreshRate) {

Modified: java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/EcalPedestalViewer.java
 =============================================================================
--- java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/EcalPedestalViewer.java	(original)
+++ java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/EcalPedestalViewer.java	Wed Apr 27 11:11:32 2016
@@ -33,80 +33,80 @@
     // this has to match the one in EcalPedstalCalculator:
     private String histoNameFormat = "Ecal/Pedestals/Mode7/ped%03d";
     
-	private AIDA aida = AIDA.defaultInstance();	
-	private IPlotter plotter;
-	private IPlotterFactory plotterFactory;
-	private IPlotterStyle pstyle;
-	private PEventViewer viewer;
+    private AIDA aida = AIDA.defaultInstance(); 
+    private IPlotter plotter;
+    private IPlotterFactory plotterFactory;
+    private IPlotterStyle pstyle;
+    private PEventViewer viewer;
 
-	static final String[] colors={"red","black","blue","green","yellow","pink","cyan","magenta","brown"};
-	static final int nRows=3;
-	static final int nColumns=3;
-	private int theRegion=0;
-	
-	@Override
-	public void detectorChanged(Detector detector) {
-		plotterFactory = aida.analysisFactory().createPlotterFactory("ECal Peds");
-		plotter = plotterFactory.create("ECal Peds");
-		plotter.createRegions(nColumns,nRows);
-		// Plot dummmy histos, else null plotter regions later:
-		for (int ii=0; ii<nColumns*nRows; ii++) {
-  	    	plotter.region(ii).plot(aida.histogram1D("ASDF"+ii,100,11e9,11e11));
-		}
-		plotter.show();
-		
-		pstyle=plotterFactory.createPlotterStyle();
-		pstyle.xAxisStyle().labelStyle().setBold(true);
-		pstyle.yAxisStyle().labelStyle().setBold(true);
-		pstyle.xAxisStyle().tickLabelStyle().setBold(true);
-		pstyle.yAxisStyle().tickLabelStyle().setBold(true);
-		pstyle.xAxisStyle().lineStyle().setColor("black");
-		pstyle.yAxisStyle().lineStyle().setColor("black");
-		pstyle.xAxisStyle().lineStyle().setThickness(2);
-		pstyle.yAxisStyle().lineStyle().setThickness(2);
-		pstyle.dataStyle().errorBarStyle().setThickness(0);
-		pstyle.legendBoxStyle().setVisible(false);
-	}
-	
-	@Override
-	public void startOfData() {
-		File config = new File("ecal-mapping-config.csv");
-		if(config.exists() && config.canRead()) {
-			try { viewer = new PDataEventViewer(config.getAbsolutePath()); }
-			catch (IOException e) { viewer = new PEventViewer(); }
-		} else { viewer = new PEventViewer(); }
-		viewer.addCrystalListener(this);
-		viewer.setVisible(true);
-	}
-	
-	@Override
-	public void actionPerformed(ActionEvent ae) { }
-	
-	@Override
-	public void crystalActivated(CrystalEvent e) { }
-	
-	@Override
-	public void crystalDeactivated(CrystalEvent e) { }
+    static final String[] colors={"red","black","blue","green","yellow","pink","cyan","magenta","brown"};
+    static final int nRows=3;
+    static final int nColumns=3;
+    private int theRegion=0;
+    
+    @Override
+    public void detectorChanged(Detector detector) {
+        plotterFactory = aida.analysisFactory().createPlotterFactory("ECal Peds");
+        plotter = plotterFactory.create("ECal Peds");
+        plotter.createRegions(nColumns,nRows);
+        // Plot dummmy histos, else null plotter regions later:
+        for (int ii=0; ii<nColumns*nRows; ii++) {
+            plotter.region(ii).plot(aida.histogram1D("ASDF"+ii,100,11e9,11e11));
+        }
+        plotter.show();
+        
+        pstyle=plotterFactory.createPlotterStyle();
+        pstyle.xAxisStyle().labelStyle().setBold(true);
+        pstyle.yAxisStyle().labelStyle().setBold(true);
+        pstyle.xAxisStyle().tickLabelStyle().setBold(true);
+        pstyle.yAxisStyle().tickLabelStyle().setBold(true);
+        pstyle.xAxisStyle().lineStyle().setColor("black");
+        pstyle.yAxisStyle().lineStyle().setColor("black");
+        pstyle.xAxisStyle().lineStyle().setThickness(2);
+        pstyle.yAxisStyle().lineStyle().setThickness(2);
+        pstyle.dataStyle().errorBarStyle().setThickness(0);
+        pstyle.legendBoxStyle().setVisible(false);
+    }
+    
+    @Override
+    public void startOfData() {
+        File config = new File("ecal-mapping-config.csv");
+        if(config.exists() && config.canRead()) {
+            try { viewer = new PDataEventViewer(config.getAbsolutePath()); }
+            catch (IOException e) { viewer = new PEventViewer(); }
+        } else { viewer = new PEventViewer(); }
+        viewer.addCrystalListener(this);
+        viewer.setVisible(true);
+    }
+    
+    @Override
+    public void actionPerformed(ActionEvent ae) { }
+    
+    @Override
+    public void crystalActivated(CrystalEvent e) { }
+    
+    @Override
+    public void crystalDeactivated(CrystalEvent e) { }
 
-	@Override
-	public void crystalClicked(CrystalEvent e) {
-		aida.tree().cd("/");
-		Point ecalPoint = Viewer.toEcalPoint(e.getCrystalID());
-		if (ecalPoint.x == 0 || ecalPoint.y == 0) return;
-		if (EcalMonitoringUtilities.isInHole(ecalPoint.y,ecalPoint.x)) return;
-		final int cid=EcalMonitoringUtilities.getChannelIdFromRowColumn(ecalPoint.y,ecalPoint.x);
-	    IHistogram1D hist=aida.histogram1D(String.format(histoNameFormat,cid));
-	    if (hist==null) {
-	        System.err.println("Running the Driver?");
-	    } else {
-     	    hist.setTitle(String.format("(%d,%d)",ecalPoint.x,ecalPoint.y));
+    @Override
+    public void crystalClicked(CrystalEvent e) {
+        aida.tree().cd("/");
+        Point ecalPoint = Viewer.toEcalPoint(e.getCrystalID());
+        if (ecalPoint.x == 0 || ecalPoint.y == 0) return;
+        if (EcalMonitoringUtilities.isInHole(ecalPoint.y,ecalPoint.x)) return;
+        final int cid=EcalMonitoringUtilities.getChannelIdFromRowColumn(ecalPoint.y,ecalPoint.x);
+        IHistogram1D hist=aida.histogram1D(String.format(histoNameFormat,cid));
+        if (hist==null) {
+            System.err.println("Running the Driver?");
+        } else {
+            hist.setTitle(String.format("(%d,%d)",ecalPoint.x,ecalPoint.y));
             pstyle.dataStyle().lineStyle().setParameter("color", colors[theRegion%colors.length]);
-	        plotter.region(theRegion).clear();
-	        plotter.region(theRegion).plot(hist,pstyle);
-	        plotter.region(theRegion).refresh();
-	        theRegion=(theRegion+1)%(nColumns*nRows);
-	    }
-	}
-	
-	
+            plotter.region(theRegion).clear();
+            plotter.region(theRegion).plot(hist,pstyle);
+            plotter.region(theRegion).refresh();
+            theRegion=(theRegion+1)%(nColumns*nRows);
+        }
+    }
+    
+    
 }

Modified: java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/EcalWindowPlotsXY.java
 =============================================================================
--- java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/EcalWindowPlotsXY.java	(original)
+++ java/branches/HPSJAVA-409/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/EcalWindowPlotsXY.java	Wed Apr 27 11:11:32 2016
@@ -93,7 +93,7 @@
     }
 
     private void setupPlots() {
-    	System.out.println("ECAL WINDOW PLOTS START");
+        System.out.println("ECAL WINDOW PLOTS START");
         //if (plotterFrame != null) {
         //    plotterFrame.dispose();
         //}
@@ -108,8 +108,8 @@
         IPlotterStyle pstyle = plotter.style();
         pstyle.dataStyle().errorBarStyle().setVisible(false);
         plotter.createRegions(1,1);     
-    	windowPlot1 = aida.histogram1D(detector.getDetectorName() + " : " + inputCollection + " : dummy", 1, -0.5, 1 - 0.5);
-    	plotter.region(0).plot(windowPlot1);
+        windowPlot1 = aida.histogram1D(detector.getDetectorName() + " : " + inputCollection + " : dummy", 1, -0.5, 1 - 0.5);
+        plotter.region(0).plot(windowPlot1);
         plotter.show();
     }
 
@@ -126,15 +126,15 @@
                 dec.setID(hit.getCellID());
                 int x = dec.getValue("ix");
                 int y = dec.getValue("iy");
-//				System.out.println("got hit: x= " + x + ", y= " + y);
+//              System.out.println("got hit: x= " + x + ", y= " + y);
                 if (isFirst) {
-                	System.out.println("FIRST!!!");
+                    System.out.println("FIRST!!!");
                     isFirst=false;
-                	window=hit.getADCValues().length;
-                	windowPlot = aida.histogram1D(detector.getDetectorName() + " : " + inputCollection + " : Window Mode Data", window, -0.5, window - 0.5);
-                	plotter.region(0).clear();
-                	plotter.region(0).plot(windowPlot);
-                	plotter.region(0).refresh();
+                    window=hit.getADCValues().length;
+                    windowPlot = aida.histogram1D(detector.getDetectorName() + " : " + inputCollection + " : Window Mode Data", window, -0.5, window - 0.5);
+                    plotter.region(0).clear();
+                    plotter.region(0).plot(windowPlot);
+                    plotter.region(0).refresh();
                 
                 }
                 if (testX && x != plotX) {

Modified: java/branches/HPSJAVA-409/monitoring-util/pom.xml
 =============================================================================
--- java/branches/HPSJAVA-409/monitoring-util/pom.xml	(original)
+++ java/branches/HPSJAVA-409/monitoring-util/pom.xml	Wed Apr 27 11:11:32 2016
@@ -7,7 +7,7 @@
         <groupId>org.hps</groupId>
         <artifactId>hps-parent</artifactId>
         <relativePath>../parent/pom.xml</relativePath>
-        <version>3.4.2-SNAPSHOT</version>
+        <version>3.9-SNAPSHOT</version>
     </parent>
     <scm>
         <url>http://java.freehep.org/svn/repos/hps/list/java/trunk/monitoring-util/</url>

Modified: java/branches/HPSJAVA-409/monitoring-util/src/main/java/org/hps/monitoring/plotting/ExportPdf.java
 =============================================================================
--- java/branches/HPSJAVA-409/monitoring-util/src/main/java/org/hps/monitoring/plotting/ExportPdf.java	(original)
+++ java/branches/HPSJAVA-409/monitoring-util/src/main/java/org/hps/monitoring/plotting/ExportPdf.java	Wed Apr 27 11:11:32 2016
@@ -8,6 +8,9 @@
 import java.awt.image.BufferedImage;
 import java.io.FileOutputStream;
 import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
 import java.util.List;
 import java.util.logging.Logger;
 
@@ -42,12 +45,10 @@
     /**
      * Save a set of tabs containing plots to a file.
      *
-     * @param plotTabs the top level tab component (plots are actually in a set
-     * of tabs without these tabs)
+     * @param plotters the list of plotters to save (from plots in the regions)
      * @param fileName the file name
      * @param runData the list of run data to save on the cover page
-     * @throws IOException if there is a problem with the IO (e.g. writing to
-     * PDF file)
+     * @throws IOException if there is a problem with the IO (e.g. writing to PDF file)
      */
     public static void write(List<IPlotter> plotters, String fileName, List<String> runData)
             throws IOException {
@@ -70,9 +71,23 @@
         } catch (DocumentException e) {
             throw new IOException(e);
         }
+        
+        // Sort plotters so output appears the same every time.
+        ArrayList<IPlotter> sortedPlotters = new ArrayList<IPlotter>(plotters);
+        Collections.sort(sortedPlotters, new Comparator<IPlotter>() {
+           public int compare(IPlotter object1, IPlotter object2) {
+               if (object1.title() == null) {
+                   return -1;
+               }
+               if (object2.title() == null) {
+                   return 1;
+               }
+               return object1.title().compareTo(object2.title());
+           }
+        });
 
         // Write the graphics from each plotter on a new page.
-        for (IPlotter plotter : plotters) {
+        for (IPlotter plotter : sortedPlotters) {
             plotter.refresh();
             document.newPage();
             writePage(document, writer, plotter);

Modified: java/branches/HPSJAVA-409/monitoring-util/src/main/java/org/hps/monitoring/subsys/et/package-info.java
 =============================================================================
--- java/branches/HPSJAVA-409/monitoring-util/src/main/java/org/hps/monitoring/subsys/et/package-info.java	(original)
+++ java/branches/HPSJAVA-409/monitoring-util/src/main/java/org/hps/monitoring/subsys/et/package-info.java	Wed Apr 27 11:11:32 2016
@@ -1,7 +1,5 @@
 /**
  * ET subsystem monitoring
- * <p>
- * {@link EtSystemMonitor} implements basic status checks of the ET system.
  * 
  * @author Jeremy McCormick, SLAC
  */

Modified: java/branches/HPSJAVA-409/monitoring-util/src/main/java/org/hps/monitoring/trigger/AbstractTablePanel.java
 =============================================================================
--- java/branches/HPSJAVA-409/monitoring-util/src/main/java/org/hps/monitoring/trigger/AbstractTablePanel.java	(original)
+++ java/branches/HPSJAVA-409/monitoring-util/src/main/java/org/hps/monitoring/trigger/AbstractTablePanel.java	Wed Apr 27 11:11:32 2016
@@ -26,224 +26,224 @@
  * @see DiagnosticUpdatable
  */
 public abstract class AbstractTablePanel extends JPanel implements DiagnosticUpdatable {
-	// Static variables.
-	private static final long serialVersionUID = 0L;
-	public static final int ORIENTATION_HORIZONTAL = 0;
-	public static final int ORIENTATION_VERTICAL   = 1;
-	
-	// Components.
-	private JLabel localHeader;
-	private JLabel globalHeader;
-	protected final JTable localTable;
-	protected final JTable globalTable;
-	
-	// Component parameters.
-	private boolean horizontal = true;
-	private Dimension userPrefSize = null;
-	private Dimension defaultPrefSize = new Dimension(0, 0);
-	
-	/**
-	 * Instantiates an <code>AbstractTablePanel</code>.
-	 * @param args Arguments to be used when generating the panel tables.
-	 */
-	public AbstractTablePanel(Object... args) {
-		// Initialize the tables.
-		JTable[] tables = initializeTables(args);
-		localTable = tables[0];
-		globalTable = tables[1];
-		add(globalTable);
-		add(localTable);
-		
-		// Set the panels to their null starting values.
-		updatePanel(null, null);
-		
-		// Define the panel layout.
-		setLayout(null);
-		
-		// Create header labels for the tables.
-		localHeader = new JLabel("Instantaneous Statistics");
-		localHeader.setHorizontalAlignment(JLabel.CENTER);
-		add(localHeader);
-		
-		globalHeader = new JLabel("Run Statistics");
-		globalHeader.setHorizontalAlignment(JLabel.CENTER);
-		add(globalHeader);
-		
-		// Track when the component changes size and reposition the
-		// components accordingly.
-		addComponentListener(new ComponentAdapter() {
-			@Override
-			public void componentResized(ComponentEvent e) { positionComponents(); }
-		});
-		
-		// Define the component preferred size.
-		defaultPrefSize.width = localTable.getPreferredSize().width +
-				ComponentUtils.hinternal + globalTable.getPreferredSize().width;
-		defaultPrefSize.height = localTable.getPreferredSize().height +
-				ComponentUtils.vinternal + globalTable.getPreferredSize().height;
-	}
-	
-	@Override
-	public Dimension getPreferredSize() {
-		// If there is a user-specified preferred size, return that.
-		if(userPrefSize == null) { return defaultPrefSize; }
-		
-		// Otherwise, return the default calculated preferred size.
-		else { return userPrefSize; }
-	}
-	
-	@Override
-	public void setBackground(Color bg) {
-		// Set the base component background.
-		super.setBackground(bg);
-		
-		// If the components have been initialized, pass the background
-		// color change to them as appropriate. Note that the tables
-		// will always retain the same background color.
-		if(localTable != null) {
-			// Set the header backgrounds.
-			localHeader.setBackground(bg);
-			globalHeader.setBackground(bg);
-		}
-	}
-	
-	@Override
-	public void setFont(Font font) {
-		// Set the base component font.
-		super.setFont(font);
-		
-		// If the components have been initialized, pass the font change
-		// to them as appropriate.
-		if(localTable != null) {
-			// Set the table fonts.
-			localTable.setFont(font);
-			globalTable.setFont(font);
-			
-			// Set the header fonts.
-			Font headerFont = font.deriveFont(Font.BOLD, (float) Math.ceil(font.getSize2D() * 1.3));
-			localHeader.setFont(headerFont);
-			globalHeader.setFont(headerFont);
-		}
-	}
-	
-	@Override
-	public void setForeground(Color fg) {
-		// Set the base component foreground.
-		super.setForeground(fg);
-		
-		// If the components have been initialized, pass the foreground
-		// color change to them as appropriate. Note that the tables
-		// will always retain the same foreground color.
-		if(localTable != null) {
-			// Set the header foregrounds.
-			localHeader.setForeground(fg);
-			globalHeader.setForeground(fg);
-		}
-	}
-	
-	/**
-	 * Sets the orientation of components on the panel.
-	 * @param orientation - The orientation identifier. Identifiers can
-	 * be obtained as static variables from the within the root object
-	 * <code>AbstractTable</code>.
-	 */
-	public void setOrientation(int orientation) {
-		if(orientation == ORIENTATION_HORIZONTAL) {
-			if(!horizontal) {
-				horizontal = true;
-				positionComponents();
-			}
-		} else if(orientation == ORIENTATION_VERTICAL) {
-			if(horizontal) {
-				horizontal = false;
-				positionComponents();
-			}
-		} else {
-			throw new IllegalArgumentException("Invalid orienation identifier.");
-		}
-	}
-	
-	@Override
-	public void setPreferredSize(Dimension preferredSize) {
-		userPrefSize = preferredSize;
-	}
-	
-	/**
-	 * Generates the two tables that are used by the component. This
-	 * must return an array of size two.
-	 * @param args - Any arguments that should be passed to the method
-	 * for generating tables.
-	 * @return Returns an array of size two, where the first index must
-	 * contain the local table and the second index the global table.
-	 */
-	protected abstract JTable[] initializeTables(Object... args);
-	
-	/**
-	 * Repositions the components to the correct places on the parent
-	 * <code>JPanel</code>. This should be run whenever the panel
-	 * changes size.
-	 */
-	private void positionComponents() {
-		// Do not update if the components have not been initialized.
-		if(localHeader == null) { return; }
-		
-		// If the components should be position horizontally...
-		if(horizontal) {
-			// The local components get the left half of the panel and the
-			// global components the right. Find half of the panel width,
-			// accounting for the internal spacing. This is an internal
-			// component, so it does not employ additional spacing between
-			// itself and the parent component's edges.
-			int compWidth = (getWidth() - 10) / 2;
-			
-			// If there is any width remaining, it goes to the spacing.
-			int horizontal = ComponentUtils.hinternal + (getWidth() - 10) % 2;
-			
-			// Place the header labels. These are given their preferred
-			// height. Note that this means a very small panel may cut off
-			// some of the components. First, get the preferred height of
-			// the label with the larger preferred height. These should be
-			// the same thing, but just in case...
-			int labelHeight = localHeader.getPreferredSize().height;
-			if(labelHeight < globalHeader.getPreferredSize().height) {
-				labelHeight = globalHeader.getPreferredSize().height;
-			}
-			
-			// Set the label sizes and positions.
-			localHeader.setBounds(0, 0, compWidth, labelHeight);
-			globalHeader.setLocation(ComponentUtils.getNextX(localHeader, horizontal), 0);
-			globalHeader.setSize(compWidth, labelHeight);
-			
-			// The tables go under their respective labels and should fill
-			// the remainder of the label height.
-			int tableY = ComponentUtils.getNextY(localHeader, ComponentUtils.vinternal);
-			localTable.setBounds(0, tableY, compWidth, localTable.getPreferredSize().height);
-			globalTable.setBounds(globalHeader.getX(), tableY, compWidth, globalTable.getPreferredSize().height);
-		}
-		
-		// Otherwise, position them vertically.
-		else {
-			// Place the header labels. These are given their preferred
-			// height. Note that this means a very small panel may cut off
-			// some of the components. First, get the preferred height of
-			// the label with the larger preferred height. These should be
-			// the same thing, but just in case...
-			int labelHeight = localHeader.getPreferredSize().height;
-			if(labelHeight < globalHeader.getPreferredSize().height) {
-				labelHeight = globalHeader.getPreferredSize().height;
-			}
-			
-			// The local components go first, taking up the entire upper
-			// width of the panel.
-			localHeader.setBounds(0, 0, getWidth(), labelHeight);
-			localTable.setBounds(0, ComponentUtils.getNextY(localHeader, ComponentUtils.vinternal),
-					getWidth(), localTable.getPreferredSize().height);
-			
-			// The global components go immediately below.
-			globalHeader.setBounds(0, ComponentUtils.getNextY(localTable, ComponentUtils.vinternal),
-					getWidth(), labelHeight);
-			globalTable.setBounds(0, ComponentUtils.getNextY(globalHeader, ComponentUtils.vinternal),
-					getWidth(), globalTable.getPreferredSize().height);
-		}
-	}
+    // Static variables.
+    private static final long serialVersionUID = 0L;
+    public static final int ORIENTATION_HORIZONTAL = 0;
+    public static final int ORIENTATION_VERTICAL   = 1;
+    
+    // Components.
+    private JLabel localHeader;
+    private JLabel globalHeader;
+    protected final JTable localTable;
+    protected final JTable globalTable;
+    
+    // Component parameters.
+    private boolean horizontal = true;
+    private Dimension userPrefSize = null;
+    private Dimension defaultPrefSize = new Dimension(0, 0);
+    
+    /**
+     * Instantiates an <code>AbstractTablePanel</code>.
+     * @param args Arguments to be used when generating the panel tables.
+     */
+    public AbstractTablePanel(Object... args) {
+        // Initialize the tables.
+        JTable[] tables = initializeTables(args);
+        localTable = tables[0];
+        globalTable = tables[1];
+        add(globalTable);
+        add(localTable);
+        
+        // Set the panels to their null starting values.
+        updatePanel(null, null);
+        
+        // Define the panel layout.
+        setLayout(null);
+        
+        // Create header labels for the tables.
+        localHeader = new JLabel("Instantaneous Statistics");
+        localHeader.setHorizontalAlignment(JLabel.CENTER);
+        add(localHeader);
+        
+        globalHeader = new JLabel("Run Statistics");
+        globalHeader.setHorizontalAlignment(JLabel.CENTER);
+        add(globalHeader);
+        
+        // Track when the component changes size and reposition the
+        // components accordingly.
+        addComponentListener(new ComponentAdapter() {
+            @Override
+            public void componentResized(ComponentEvent e) { positionComponents(); }
+        });
+        
+        // Define the component preferred size.
+        defaultPrefSize.width = localTable.getPreferredSize().width +
+                ComponentUtils.hinternal + globalTable.getPreferredSize().width;
+        defaultPrefSize.height = localTable.getPreferredSize().height +
+                ComponentUtils.vinternal + globalTable.getPreferredSize().height;
+    }
+    
+    @Override
+    public Dimension getPreferredSize() {
+        // If there is a user-specified preferred size, return that.
+        if(userPrefSize == null) { return defaultPrefSize; }
+        
+        // Otherwise, return the default calculated preferred size.
+        else { return userPrefSize; }
+    }
+    
+    @Override
+    public void setBackground(Color bg) {
+        // Set the base component background.
+        super.setBackground(bg);
+        
+        // If the components have been initialized, pass the background
+        // color change to them as appropriate. Note that the tables
+        // will always retain the same background color.
+        if(localTable != null) {
+            // Set the header backgrounds.
+            localHeader.setBackground(bg);
+            globalHeader.setBackground(bg);
+        }
+    }
+    
+    @Override
+    public void setFont(Font font) {
+        // Set the base component font.
+        super.setFont(font);
+        
+        // If the components have been initialized, pass the font change
+        // to them as appropriate.
+        if(localTable != null) {
+            // Set the table fonts.
+            localTable.setFont(font);
+            globalTable.setFont(font);
+            
+            // Set the header fonts.
+            Font headerFont = font.deriveFont(Font.BOLD, (float) Math.ceil(font.getSize2D() * 1.3));
+            localHeader.setFont(headerFont);
+            globalHeader.setFont(headerFont);
+        }
+    }
+    
+    @Override
+    public void setForeground(Color fg) {
+        // Set the base component foreground.
+        super.setForeground(fg);
+        
+        // If the components have been initialized, pass the foreground
+        // color change to them as appropriate. Note that the tables
+        // will always retain the same foreground color.
+        if(localTable != null) {
+            // Set the header foregrounds.
+            localHeader.setForeground(fg);
+            globalHeader.setForeground(fg);
+        }
+    }
+    
+    /**
+     * Sets the orientation of components on the panel.
+     * @param orientation - The orientation identifier. Identifiers can
+     * be obtained as static variables from the within the root object
+     * <code>AbstractTable</code>.
+     */
+    public void setOrientation(int orientation) {
+        if(orientation == ORIENTATION_HORIZONTAL) {
+            if(!horizontal) {
+                horizontal = true;
+                positionComponents();
+            }
+        } else if(orientation == ORIENTATION_VERTICAL) {
+            if(horizontal) {
+                horizontal = false;
+                positionComponents();
+            }
+        } else {
+            throw new IllegalArgumentException("Invalid orienation identifier.");
+        }
+    }
+    
+    @Override
+    public void setPreferredSize(Dimension preferredSize) {
+        userPrefSize = preferredSize;
+    }
+    
+    /**
+     * Generates the two tables that are used by the component. This
+     * must return an array of size two.
+     * @param args - Any arguments that should be passed to the method
+     * for generating tables.
+     * @return Returns an array of size two, where the first index must
+     * contain the local table and the second index the global table.
+     */
+    protected abstract JTable[] initializeTables(Object... args);
+    
+    /**
+     * Repositions the components to the correct places on the parent
+     * <code>JPanel</code>. This should be run whenever the panel
+     * changes size.
+     */
+    private void positionComponents() {
+        // Do not update if the components have not been initialized.
+        if(localHeader == null) { return; }
+        
+        // If the components should be position horizontally...
+        if(horizontal) {
+            // The local components get the left half of the panel and the
+            // global components the right. Find half of the panel width,
+            // accounting for the internal spacing. This is an internal
+            // component, so it does not employ additional spacing between
+            // itself and the parent component's edges.
+            int compWidth = (getWidth() - 10) / 2;
+            
+            // If there is any width remaining, it goes to the spacing.
+            int horizontal = ComponentUtils.hinternal + (getWidth() - 10) % 2;
+            
+            // Place the header labels. These are given their preferred
+            // height. Note that this means a very small panel may cut off
+            // some of the components. First, get the preferred height of
+            // the label with the larger preferred height. These should be
+            // the same thing, but just in case...
+            int labelHeight = localHeader.getPreferredSize().height;
+            if(labelHeight < globalHeader.getPreferredSize().height) {
+                labelHeight = globalHeader.getPreferredSize().height;
+            }
+            
+            // Set the label sizes and positions.
+            localHeader.setBounds(0, 0, compWidth, labelHeight);
+            globalHeader.setLocation(ComponentUtils.getNextX(localHeader, horizontal), 0);
+            globalHeader.setSize(compWidth, labelHeight);
+            
+            // The tables go under their respective labels and should fill
+            // the remainder of the label height.
+            int tableY = ComponentUtils.getNextY(localHeader, ComponentUtils.vinternal);
+            localTable.setBounds(0, tableY, compWidth, localTable.getPreferredSize().height);
+            globalTable.setBounds(globalHeader.getX(), tableY, compWidth, globalTable.getPreferredSize().height);
+        }
+        
+        // Otherwise, position them vertically.
+        else {
+            // Place the header labels. These are given their preferred
+            // height. Note that this means a very small panel may cut off
+            // some of the components. First, get the preferred height of
+            // the label with the larger preferred height. These should be
+            // the same thing, but just in case...
+            int labelHeight = localHeader.getPreferredSize().height;
+            if(labelHeight < globalHeader.getPreferredSize().height) {
+                labelHeight = globalHeader.getPreferredSize().height;
+            }
+            
+            // The local components go first, taking up the entire upper
+            // width of the panel.
+            localHeader.setBounds(0, 0, getWidth(), labelHeight);
+            localTable.setBounds(0, ComponentUtils.getNextY(localHeader, ComponentUtils.vinternal),
+                    getWidth(), localTable.getPreferredSize().height);
+            
+            // The global components go immediately below.
+            globalHeader.setBounds(0, ComponentUtils.getNextY(localTable, ComponentUtils.vinternal),
+                    getWidth(), labelHeight);
+            globalTable.setBounds(0, ComponentUtils.getNextY(globalHeader, ComponentUtils.vinternal),
+                    getWidth(), globalTable.getPreferredSize().height);
+        }
+    }
 }

Modified: java/branches/HPSJAVA-409/monitoring-util/src/main/java/org/hps/monitoring/trigger/AbstractTriggerTablePanel.java
 =============================================================================
--- java/branches/HPSJAVA-409/monitoring-util/src/main/java/org/hps/monitoring/trigger/AbstractTriggerTablePanel.java	(original)
+++ java/branches/HPSJAVA-409/monitoring-util/src/main/java/org/hps/monitoring/trigger/AbstractTriggerTablePanel.java	Wed Apr 27 11:11:32 2016
@@ -14,189 +14,189 @@
  * @author Kyle McCarty <[log in to unmask]>
  */
 public abstract class AbstractTriggerTablePanel extends AbstractTwoColumnTablePanel {
-	// Static variables.
-	private static final long serialVersionUID = 0L;
-	
-	// Internal variables.
-	private final int numCuts;
-	private final boolean singles;
-	
-	// Store reference index variables for local and run values.
-	private static final int GLOBAL = 0;
-	private static final int LOCAL  = 1;
-	
-	// Reference variables to the default table rows.
-	protected static final int ROW_RECON_COUNT        = 0;
-	protected static final int ROW_SSP_SIM_COUNT      = 1;
-	protected static final int ROW_SSP_BANK_COUNT     = 2;
-	protected static final int ROW_SSP_EFFICIENCY     = 3;
-	protected static final int ROW_TRIGGER_EFFICIENCY = 4;
-	protected static final int ROW_EMPTY_SPACE        = 5;
-	protected static final int ROW_CUT_FAILS_TITLE    = 6;
-	protected static final int ROW_FIRST_TRIGGER_CUT  = 7;
-	
-	/**
-	 * Instantiates an <code>AbstractTriggerTablePanel</code> with the
-	 * indicated cut names.
-	 * @param cutNames
-	 */
-	public AbstractTriggerTablePanel(String[] cutNames, boolean isSingles) {
-		// Instantiate the superclass.
-		super(makeTitle(cutNames));
-		
-		// Store the number of cuts.
-		numCuts = cutNames.length;
-		updatePanel(null, null);
-		
-		// Store whether this is a singles or pair trigger panel.
-		singles = isSingles;
-	}
-	
-	@Override
-	public void updatePanel(DiagnosticSnapshot runSnapshot, DiagnosticSnapshot localSnapshot) {
-		// If the snapshot is null, all values should be "N/A."
-		if(runSnapshot == null || localSnapshot == null) {
-			// Output cluster count data.
-			String scalerNullValue = "---";
-			setLocalRowValue(ROW_RECON_COUNT,     scalerNullValue);
-			setLocalRowValue(ROW_SSP_SIM_COUNT,   scalerNullValue);
-			setLocalRowValue(ROW_SSP_BANK_COUNT,  scalerNullValue);
-			setGlobalRowValue(ROW_RECON_COUNT,    scalerNullValue);
-			setGlobalRowValue(ROW_SSP_SIM_COUNT,  scalerNullValue);
-			setGlobalRowValue(ROW_SSP_BANK_COUNT, scalerNullValue);
-			
-			// Output the tracked statistical data.
-			String percentNullValue = "--- / --- (---%)";
-			setLocalRowValue(ROW_SSP_EFFICIENCY,      percentNullValue);
-			setLocalRowValue(ROW_TRIGGER_EFFICIENCY,  percentNullValue);
-			setGlobalRowValue(ROW_SSP_EFFICIENCY,     percentNullValue);
-			setGlobalRowValue(ROW_TRIGGER_EFFICIENCY, percentNullValue);
-			
-			int ROW_SECOND_TRIGGER_CUT = ROW_FIRST_TRIGGER_CUT + numCuts + 2;
-			for(int cutRow = 0; cutRow < numCuts; cutRow++) {
-				setLocalRowValue(cutRow + ROW_FIRST_TRIGGER_CUT,   percentNullValue);
-				setLocalRowValue(cutRow + ROW_SECOND_TRIGGER_CUT,  percentNullValue);
-				setGlobalRowValue(cutRow + ROW_FIRST_TRIGGER_CUT,  percentNullValue);
-				setGlobalRowValue(cutRow + ROW_SECOND_TRIGGER_CUT, percentNullValue);
-			}
-		} else {
-			// Get the local and run trigger statistics from the snapshot.
-			DiagnosticSnapshot[] stat = new DiagnosticSnapshot[2];
-			stat[GLOBAL] = runSnapshot;
-			stat[LOCAL] = localSnapshot;
-			
-			// Get the appropriate trigger statistical modules.
-			TriggerStatModule[][] triggerStats = new TriggerStatModule[2][2];
-			if(singles) {
-				triggerStats[LOCAL][0] = stat[LOCAL].getSingles0Stats();
-				triggerStats[LOCAL][1] = stat[LOCAL].getSingles1Stats();
-				triggerStats[GLOBAL][0] = stat[GLOBAL].getSingles0Stats();
-				triggerStats[GLOBAL][1] = stat[GLOBAL].getSingles1Stats();
-			} else {
-				triggerStats[LOCAL][0] = stat[LOCAL].getPair0Stats();
-				triggerStats[LOCAL][1] = stat[LOCAL].getPair1Stats();
-				triggerStats[GLOBAL][0] = stat[GLOBAL].getPair0Stats();
-				triggerStats[GLOBAL][1] = stat[GLOBAL].getPair1Stats();
-			}
-			
-			// Get the total number of triggers of each type.
-			int[] sspSimTriggers = new int[2];
-			int[] sspBankTriggers = new int[2];
-			int[] reconSimTriggers = new int[2];
-			int[] sspMatchedTriggers = new int[2];
-			int[] reconMatchedTriggers = new int[2];
-			
-			for(int i = 0; i < 2; i++) {
-				sspSimTriggers[i] = triggerStats[i][0].getSSPSimulatedTriggers() + triggerStats[i][1].getSSPSimulatedTriggers();
-				sspBankTriggers[i] = triggerStats[i][0].getReportedTriggers() + triggerStats[i][1].getReportedTriggers();
-				reconSimTriggers[i] = triggerStats[i][0].getReconSimulatedTriggers() + triggerStats[i][1].getReconSimulatedTriggers();
-				sspMatchedTriggers[i] = triggerStats[i][0].getMatchedSSPSimulatedTriggers() + triggerStats[i][1].getMatchedSSPSimulatedTriggers();
-				reconMatchedTriggers[i] = triggerStats[i][0].getMatchedReconSimulatedTriggers() + triggerStats[i][1].getMatchedReconSimulatedTriggers();
-			}
-			
-			// Determine the most spaces needed to display the values.
-			// Get the largest number of digits in any of the values.
-			int mostDigits = ComponentUtils.max(reconSimTriggers[LOCAL], sspBankTriggers[LOCAL],
-					sspSimTriggers[LOCAL], reconSimTriggers[GLOBAL], sspBankTriggers[GLOBAL],
-					sspSimTriggers[GLOBAL]);
-			int spaces = ComponentUtils.getDigits(mostDigits);
-			
-			// Update the single-value counters.
-			String countFormat = "%" + spaces + "d";
-			setLocalRowValue(ROW_RECON_COUNT,     String.format(countFormat, reconSimTriggers[LOCAL]));
-			setLocalRowValue(ROW_SSP_SIM_COUNT,   String.format(countFormat, sspSimTriggers[LOCAL]));
-			setLocalRowValue(ROW_SSP_BANK_COUNT,  String.format(countFormat, sspBankTriggers[LOCAL]));
-			setGlobalRowValue(ROW_RECON_COUNT,    String.format(countFormat, reconSimTriggers[GLOBAL]));
-			setGlobalRowValue(ROW_SSP_SIM_COUNT,  String.format(countFormat, sspSimTriggers[GLOBAL]));
-			setGlobalRowValue(ROW_SSP_BANK_COUNT, String.format(countFormat, sspBankTriggers[GLOBAL]));
-			
-			// Update the percentage counters.
-			String percentFormat = "%" + spaces + "d / %" + spaces + "d (%7.3f)";
-			
-			setLocalRowValue(ROW_SSP_EFFICIENCY, String.format(percentFormat, sspMatchedTriggers[LOCAL],
-					sspSimTriggers[LOCAL], (100.0 * sspMatchedTriggers[LOCAL] / sspSimTriggers[LOCAL])));
-			setLocalRowValue(ROW_TRIGGER_EFFICIENCY, String.format(percentFormat, reconMatchedTriggers[LOCAL],
-					reconSimTriggers[LOCAL], (100.0 * reconMatchedTriggers[LOCAL] / reconSimTriggers[LOCAL])));
-			setGlobalRowValue(ROW_SSP_EFFICIENCY, String.format(percentFormat, sspMatchedTriggers[GLOBAL],
-					sspSimTriggers[GLOBAL], (100.0 * sspMatchedTriggers[GLOBAL] / sspSimTriggers[GLOBAL])));
-			setGlobalRowValue(ROW_TRIGGER_EFFICIENCY, String.format(percentFormat, reconMatchedTriggers[GLOBAL],
-					reconSimTriggers[GLOBAL], (100.0 * reconMatchedTriggers[GLOBAL] / reconSimTriggers[GLOBAL])));
-			
-			int ROW_SECOND_TRIGGER_CUT = ROW_FIRST_TRIGGER_CUT + numCuts + 2;
-			for(int cutRow = 0; cutRow < numCuts; cutRow++) {
-				setLocalRowValue(cutRow + ROW_FIRST_TRIGGER_CUT, String.format(percentFormat,
-						triggerStats[LOCAL][0].getSSPCutFailures(cutRow), triggerStats[LOCAL][0].getSSPSimulatedTriggers(),
-						(100.0 * triggerStats[LOCAL][0].getSSPCutFailures(cutRow) / triggerStats[LOCAL][0].getSSPSimulatedTriggers())));
-				setLocalRowValue(cutRow + ROW_SECOND_TRIGGER_CUT, String.format(percentFormat,
-						triggerStats[LOCAL][1].getSSPCutFailures(cutRow), triggerStats[LOCAL][1].getSSPSimulatedTriggers(),
-						(100.0 * triggerStats[LOCAL][1].getSSPCutFailures(cutRow) / triggerStats[LOCAL][1].getSSPSimulatedTriggers())));
-				setGlobalRowValue(cutRow + ROW_FIRST_TRIGGER_CUT, String.format(percentFormat,
-						triggerStats[GLOBAL][0].getSSPCutFailures(cutRow), triggerStats[GLOBAL][0].getSSPSimulatedTriggers(),
-						(100.0 * triggerStats[GLOBAL][0].getSSPCutFailures(cutRow) / triggerStats[GLOBAL][0].getSSPSimulatedTriggers())));
-				setGlobalRowValue(cutRow + ROW_SECOND_TRIGGER_CUT, String.format(percentFormat,
-						triggerStats[GLOBAL][1].getSSPCutFailures(cutRow), triggerStats[GLOBAL][1].getSSPSimulatedTriggers(),
-						(100.0 * triggerStats[GLOBAL][1].getSSPCutFailures(cutRow) / triggerStats[GLOBAL][1].getSSPSimulatedTriggers())));
-			}
-		}
-	}
-	
-	/**
-	 * Creates the table appropriate table rows from the argument cut
-	 * names.
-	 * @param cutNames - An array containing the names of the cuts to
-	 * display.
-	 * @return Returns an array with the default table rows merged in
-	 * with the provided cut names.
-	 */
-	private static final String[] makeTitle(String[] cutNames) {
-		// Make a new array to hold all the text.
-		String[] mergedArray = new String[cutNames.length + cutNames.length + 9];
-		
-		// Define the default trigger headers.
-		mergedArray[0] = "Recon Triggers:";
-		mergedArray[1] = "SSP Sim Triggers:";
-		mergedArray[2] = "SSP Bank Triggers:";
-		mergedArray[3] = "SSP Efficiency:";
-		mergedArray[4] = "Trigger Efficiency:";
-		mergedArray[5] = "";
-		mergedArray[6] = "First Trigger Cut Failures";
-		
-		// Insert the cut names for the first trigger.
-		for(int cutIndex = 0; cutIndex < cutNames.length; cutIndex++) {
-			mergedArray[7 + cutIndex] = cutNames[cutIndex];
-		}
-		
-		// Insert the header for the second trigger cut names.
-		int startIndex = 7 + cutNames.length;
-		mergedArray[startIndex]     = "";
-		mergedArray[startIndex + 1] = "Second Trigger Cut Failures";
-		
-		// Insert the next set of cut names.
-		for(int cutIndex = 0; cutIndex < cutNames.length; cutIndex++) {
-			mergedArray[startIndex + 2 + cutIndex] = cutNames[cutIndex];
-		}
-		
-		// Return the resultant array.
-		return mergedArray;
-	}
+    // Static variables.
+    private static final long serialVersionUID = 0L;
+    
+    // Internal variables.
+    private final int numCuts;
+    private final boolean singles;
+    
+    // Store reference index variables for local and run values.
+    private static final int GLOBAL = 0;
+    private static final int LOCAL  = 1;
+    
+    // Reference variables to the default table rows.
+    protected static final int ROW_RECON_COUNT        = 0;
+    protected static final int ROW_SSP_SIM_COUNT      = 1;
+    protected static final int ROW_SSP_BANK_COUNT     = 2;
+    protected static final int ROW_SSP_EFFICIENCY     = 3;
+    protected static final int ROW_TRIGGER_EFFICIENCY = 4;
+    protected static final int ROW_EMPTY_SPACE        = 5;
+    protected static final int ROW_CUT_FAILS_TITLE    = 6;
+    protected static final int ROW_FIRST_TRIGGER_CUT  = 7;
+    
+    /**
+     * Instantiates an <code>AbstractTriggerTablePanel</code> with the
+     * indicated cut names.
+     * @param cutNames
+     */
+    public AbstractTriggerTablePanel(String[] cutNames, boolean isSingles) {
+        // Instantiate the superclass.
+        super(makeTitle(cutNames));
+        
+        // Store the number of cuts.
+        numCuts = cutNames.length;
+        updatePanel(null, null);
+        
+        // Store whether this is a singles or pair trigger panel.
+        singles = isSingles;
+    }
+    
+    @Override
+    public void updatePanel(DiagnosticSnapshot runSnapshot, DiagnosticSnapshot localSnapshot) {
+        // If the snapshot is null, all values should be "N/A."
+        if(runSnapshot == null || localSnapshot == null) {
+            // Output cluster count data.
+            String scalerNullValue = "---";
+            setLocalRowValue(ROW_RECON_COUNT,     scalerNullValue);
+            setLocalRowValue(ROW_SSP_SIM_COUNT,   scalerNullValue);
+            setLocalRowValue(ROW_SSP_BANK_COUNT,  scalerNullValue);
+            setGlobalRowValue(ROW_RECON_COUNT,    scalerNullValue);
+            setGlobalRowValue(ROW_SSP_SIM_COUNT,  scalerNullValue);
+            setGlobalRowValue(ROW_SSP_BANK_COUNT, scalerNullValue);
+            
+            // Output the tracked statistical data.
+            String percentNullValue = "--- / --- (---%)";
+            setLocalRowValue(ROW_SSP_EFFICIENCY,      percentNullValue);
+            setLocalRowValue(ROW_TRIGGER_EFFICIENCY,  percentNullValue);
+            setGlobalRowValue(ROW_SSP_EFFICIENCY,     percentNullValue);
+            setGlobalRowValue(ROW_TRIGGER_EFFICIENCY, percentNullValue);
+            
+            int ROW_SECOND_TRIGGER_CUT = ROW_FIRST_TRIGGER_CUT + numCuts + 2;
+            for(int cutRow = 0; cutRow < numCuts; cutRow++) {
+                setLocalRowValue(cutRow + ROW_FIRST_TRIGGER_CUT,   percentNullValue);
+                setLocalRowValue(cutRow + ROW_SECOND_TRIGGER_CUT,  percentNullValue);
+                setGlobalRowValue(cutRow + ROW_FIRST_TRIGGER_CUT,  percentNullValue);
+                setGlobalRowValue(cutRow + ROW_SECOND_TRIGGER_CUT, percentNullValue);
+            }
+        } else {
+            // Get the local and run trigger statistics from the snapshot.
+            DiagnosticSnapshot[] stat = new DiagnosticSnapshot[2];
+            stat[GLOBAL] = runSnapshot;
+            stat[LOCAL] = localSnapshot;
+            
+            // Get the appropriate trigger statistical modules.
+            TriggerStatModule[][] triggerStats = new TriggerStatModule[2][2];
+            if(singles) {
+                triggerStats[LOCAL][0] = stat[LOCAL].getSingles0Stats();
+                triggerStats[LOCAL][1] = stat[LOCAL].getSingles1Stats();
+                triggerStats[GLOBAL][0] = stat[GLOBAL].getSingles0Stats();
+                triggerStats[GLOBAL][1] = stat[GLOBAL].getSingles1Stats();
+            } else {
+                triggerStats[LOCAL][0] = stat[LOCAL].getPair0Stats();
+                triggerStats[LOCAL][1] = stat[LOCAL].getPair1Stats();
+                triggerStats[GLOBAL][0] = stat[GLOBAL].getPair0Stats();
+                triggerStats[GLOBAL][1] = stat[GLOBAL].getPair1Stats();
+            }
+            
+            // Get the total number of triggers of each type.
+            int[] sspSimTriggers = new int[2];
+            int[] sspBankTriggers = new int[2];
+            int[] reconSimTriggers = new int[2];
+            int[] sspMatchedTriggers = new int[2];
+            int[] reconMatchedTriggers = new int[2];
+            
+            for(int i = 0; i < 2; i++) {
+                sspSimTriggers[i] = triggerStats[i][0].getSSPSimulatedTriggers() + triggerStats[i][1].getSSPSimulatedTriggers();
+                sspBankTriggers[i] = triggerStats[i][0].getReportedTriggers() + triggerStats[i][1].getReportedTriggers();
+                reconSimTriggers[i] = triggerStats[i][0].getReconSimulatedTriggers() + triggerStats[i][1].getReconSimulatedTriggers();
+                sspMatchedTriggers[i] = triggerStats[i][0].getMatchedSSPSimulatedTriggers() + triggerStats[i][1].getMatchedSSPSimulatedTriggers();
+                reconMatchedTriggers[i] = triggerStats[i][0].getMatchedReconSimulatedTriggers() + triggerStats[i][1].getMatchedReconSimulatedTriggers();
+            }
+            
+            // Determine the most spaces needed to display the values.
+            // Get the largest number of digits in any of the values.
+            int mostDigits = ComponentUtils.max(reconSimTriggers[LOCAL], sspBankTriggers[LOCAL],
+                    sspSimTriggers[LOCAL], reconSimTriggers[GLOBAL], sspBankTriggers[GLOBAL],
+                    sspSimTriggers[GLOBAL]);
+            int spaces = ComponentUtils.getDigits(mostDigits);
+            
+            // Update the single-value counters.
+            String countFormat = "%" + spaces + "d";
+            setLocalRowValue(ROW_RECON_COUNT,     String.format(countFormat, reconSimTriggers[LOCAL]));
+            setLocalRowValue(ROW_SSP_SIM_COUNT,   String.format(countFormat, sspSimTriggers[LOCAL]));
+            setLocalRowValue(ROW_SSP_BANK_COUNT,  String.format(countFormat, sspBankTriggers[LOCAL]));
+            setGlobalRowValue(ROW_RECON_COUNT,    String.format(countFormat, reconSimTriggers[GLOBAL]));
+            setGlobalRowValue(ROW_SSP_SIM_COUNT,  String.format(countFormat, sspSimTriggers[GLOBAL]));
+            setGlobalRowValue(ROW_SSP_BANK_COUNT, String.format(countFormat, sspBankTriggers[GLOBAL]));
+            
+            // Update the percentage counters.
+            String percentFormat = "%" + spaces + "d / %" + spaces + "d (%7.3f)";
+            
+            setLocalRowValue(ROW_SSP_EFFICIENCY, String.format(percentFormat, sspMatchedTriggers[LOCAL],
+                    sspSimTriggers[LOCAL], (100.0 * sspMatchedTriggers[LOCAL] / sspSimTriggers[LOCAL])));
+            setLocalRowValue(ROW_TRIGGER_EFFICIENCY, String.format(percentFormat, reconMatchedTriggers[LOCAL],
+                    reconSimTriggers[LOCAL], (100.0 * reconMatchedTriggers[LOCAL] / reconSimTriggers[LOCAL])));
+            setGlobalRowValue(ROW_SSP_EFFICIENCY, String.format(percentFormat, sspMatchedTriggers[GLOBAL],
+                    sspSimTriggers[GLOBAL], (100.0 * sspMatchedTriggers[GLOBAL] / sspSimTriggers[GLOBAL])));
+            setGlobalRowValue(ROW_TRIGGER_EFFICIENCY, String.format(percentFormat, reconMatchedTriggers[GLOBAL],
+                    reconSimTriggers[GLOBAL], (100.0 * reconMatchedTriggers[GLOBAL] / reconSimTriggers[GLOBAL])));
+            
+            int ROW_SECOND_TRIGGER_CUT = ROW_FIRST_TRIGGER_CUT + numCuts + 2;
+            for(int cutRow = 0; cutRow < numCuts; cutRow++) {
+                setLocalRowValue(cutRow + ROW_FIRST_TRIGGER_CUT, String.format(percentFormat,
+                        triggerStats[LOCAL][0].getSSPCutFailures(cutRow), triggerStats[LOCAL][0].getSSPSimulatedTriggers(),
+                        (100.0 * triggerStats[LOCAL][0].getSSPCutFailures(cutRow) / triggerStats[LOCAL][0].getSSPSimulatedTriggers())));
+                setLocalRowValue(cutRow + ROW_SECOND_TRIGGER_CUT, String.format(percentFormat,
+                        triggerStats[LOCAL][1].getSSPCutFailures(cutRow), triggerStats[LOCAL][1].getSSPSimulatedTriggers(),
+                        (100.0 * triggerStats[LOCAL][1].getSSPCutFailures(cutRow) / triggerStats[LOCAL][1].getSSPSimulatedTriggers())));
+                setGlobalRowValue(cutRow + ROW_FIRST_TRIGGER_CUT, String.format(percentFormat,
+                        triggerStats[GLOBAL][0].getSSPCutFailures(cutRow), triggerStats[GLOBAL][0].getSSPSimulatedTriggers(),
+                        (100.0 * triggerStats[GLOBAL][0].getSSPCutFailures(cutRow) / triggerStats[GLOBAL][0].getSSPSimulatedTriggers())));
+                setGlobalRowValue(cutRow + ROW_SECOND_TRIGGER_CUT, String.format(percentFormat,
+                        triggerStats[GLOBAL][1].getSSPCutFailures(cutRow), triggerStats[GLOBAL][1].getSSPSimulatedTriggers(),
+                        (100.0 * triggerStats[GLOBAL][1].getSSPCutFailures(cutRow) / triggerStats[GLOBAL][1].getSSPSimulatedTriggers())));
+            }
+        }
+    }
+    
+    /**
+     * Creates the table appropriate table rows from the argument cut
+     * names.
+     * @param cutNames - An array containing the names of the cuts to
+     * display.
+     * @return Returns an array with the default table rows merged in
+     * with the provided cut names.
+     */
+    private static final String[] makeTitle(String[] cutNames) {
+        // Make a new array to hold all the text.
+        String[] mergedArray = new String[cutNames.length + cutNames.length + 9];
+        
+        // Define the default trigger headers.
+        mergedArray[0] = "Recon Triggers:";
+        mergedArray[1] = "SSP Sim Triggers:";
+        mergedArray[2] = "SSP Bank Triggers:";
+        mergedArray[3] = "SSP Efficiency:";
+        mergedArray[4] = "Trigger Efficiency:";
+        mergedArray[5] = "";
+        mergedArray[6] = "First Trigger Cut Failures";
+        
+        // Insert the cut names for the first trigger.
+        for(int cutIndex = 0; cutIndex < cutNames.length; cutIndex++) {
+            mergedArray[7 + cutIndex] = cutNames[cutIndex];
+        }
+        
+        // Insert the header for the second trigger cut names.
+        int startIndex = 7 + cutNames.length;
+        mergedArray[startIndex]     = "";
+        mergedArray[startIndex + 1] = "Second Trigger Cut Failures";
+        
+        // Insert the next set of cut names.
+        for(int cutIndex = 0; cutIndex < cutNames.length; cutIndex++) {
+            mergedArray[startIndex + 2 + cutIndex] = cutNames[cutIndex];
+        }
+        
+        // Return the resultant array.
+        return mergedArray;
+    }
 }

Modified: java/branches/HPSJAVA-409/monitoring-util/src/main/java/org/hps/monitoring/trigger/AbstractTwoColumnTablePanel.java
 =============================================================================
--- java/branches/HPSJAVA-409/monitoring-util/src/main/java/org/hps/monitoring/trigger/AbstractTwoColumnTablePanel.java	(original)
+++ java/branches/HPSJAVA-409/monitoring-util/src/main/java/org/hps/monitoring/trigger/AbstractTwoColumnTablePanel.java	Wed Apr 27 11:11:32 2016
@@ -16,94 +16,94 @@
  * @see AbstractTablePanel
  */
 public abstract class AbstractTwoColumnTablePanel extends AbstractTablePanel {
-	// Static variables.
-	private static final long serialVersionUID = 0L;
-	
-	// Table models.
-	private TableTextModel localModel;
-	private TableTextModel globalModel;
-	
-	// Table model mappings.
-	private static final int COL_TITLE = 0;
-	private static final int COL_VALUE = 1;
-	
-	/**
-	 * Instantiates an <code>AbstractTwoColumnTablePanel</code> object
-	 * with the indicated row names.
-	 * @param rowNames - The names of the rows.
-	 */
-	public AbstractTwoColumnTablePanel(String[] rowNames) {
-		super((Object[]) rowNames);
-	}
-	
-	@Override
-	protected JTable[] initializeTables(Object... args) {
-		// The arguments should be a string array.
-		if(!(args instanceof String[])) {
-			throw new IllegalArgumentException("Row names must be strings!");
-		}
-		String[] rowNames = (String[]) args;
-		
-		// Initialize the table models. They should have two columns
-		// (one for values and one for headers) and a number of rows
-		// equal to the number of row names.
-		localModel = new TableTextModel(rowNames.length, 2);
-		globalModel = new TableTextModel(rowNames.length, 2);
-		
-		// Initialize the titles.
-		for(int i = 0; i < rowNames.length; i++) {
-			localModel.setValueAt(rowNames[i], i, COL_TITLE);
-			globalModel.setValueAt(rowNames[i], i, COL_TITLE);
-		}
-		updatePanel(null, null);
-		
-		// Make a cell renderer.
-		DefaultTableCellRenderer centerRenderer = new DefaultTableCellRenderer();
-		centerRenderer.setHorizontalAlignment(JLabel.CENTER);
-		
-		// Create JTable objects to display the data.
-		JTable localTable = new JTable(localModel);
-		localTable.setRowSelectionAllowed(false);
-		localTable.setColumnSelectionAllowed(false);
-		localTable.setCellSelectionEnabled(false);
-		localTable.setShowVerticalLines(false);
-		localTable.getColumnModel().getColumn(0).setMinWidth(200);
-		localTable.getColumnModel().getColumn(0).setMaxWidth(200);
-		localTable.getColumnModel().getColumn(1).setCellRenderer(centerRenderer);
-		localTable.setFont(new Font("monospaced", localTable.getFont().getStyle(), localTable.getFont().getSize()));
-		
-		JTable globalTable = new JTable(globalModel);
-		globalTable.setRowSelectionAllowed(false);
-		globalTable.setColumnSelectionAllowed(false);
-		globalTable.setCellSelectionEnabled(false);
-		globalTable.setShowVerticalLines(false);
-		globalTable.getColumnModel().getColumn(0).setMinWidth(200);
-		globalTable.getColumnModel().getColumn(0).setMaxWidth(200);
-		globalTable.getColumnModel().getColumn(1).setCellRenderer(centerRenderer);
-		globalTable.setFont(new Font("monospaced", globalTable.getFont().getStyle(), globalTable.getFont().getSize()));
-		
-		// Return the two tables.
-		return new JTable[] { localTable, globalTable };
-	}
-	
-	/**
-	 * Sets the value of the indicated row for the global statistical
-	 * table.
-	 * @param rowIndex - The row.
-	 * @param value - The new value.
-	 */
-	protected void setGlobalRowValue(int rowIndex, String value) {
-		globalModel.setValueAt(value, rowIndex, COL_VALUE);
-	}
-	
-	/**
-	 * Sets the value of the indicated row for the local statistical
-	 * table.
-	 * @param rowIndex - The row.
-	 * @param value - The new value.
-	 */
-	protected void setLocalRowValue(int rowIndex, String value) {
-		localModel.setValueAt(value, rowIndex, COL_VALUE);
-	}
+    // Static variables.
+    private static final long serialVersionUID = 0L;
+    
+    // Table models.
+    private TableTextModel localModel;
+    private TableTextModel globalModel;
+    
+    // Table model mappings.
+    private static final int COL_TITLE = 0;
+    private static final int COL_VALUE = 1;
+    
+    /**
+     * Instantiates an <code>AbstractTwoColumnTablePanel</code> object
+     * with the indicated row names.
+     * @param rowNames - The names of the rows.
+     */
+    public AbstractTwoColumnTablePanel(String[] rowNames) {
+        super((Object[]) rowNames);
+    }
+    
+    @Override
+    protected JTable[] initializeTables(Object... args) {
+        // The arguments should be a string array.
+        if(!(args instanceof String[])) {
+            throw new IllegalArgumentException("Row names must be strings!");
+        }
+        String[] rowNames = (String[]) args;
+        
+        // Initialize the table models. They should have two columns
+        // (one for values and one for headers) and a number of rows
+        // equal to the number of row names.
+        localModel = new TableTextModel(rowNames.length, 2);
+        globalModel = new TableTextModel(rowNames.length, 2);
+        
+        // Initialize the titles.
+        for(int i = 0; i < rowNames.length; i++) {
+            localModel.setValueAt(rowNames[i], i, COL_TITLE);
+            globalModel.setValueAt(rowNames[i], i, COL_TITLE);
+        }
+        updatePanel(null, null);
+        
+        // Make a cell renderer.
+        DefaultTableCellRenderer centerRenderer = new DefaultTableCellRenderer();
+        centerRenderer.setHorizontalAlignment(JLabel.CENTER);
+        
+        // Create JTable objects to display the data.
+        JTable localTable = new JTable(localModel);
+        localTable.setRowSelectionAllowed(false);
+        localTable.setColumnSelectionAllowed(false);
+        localTable.setCellSelectionEnabled(false);
+        localTable.setShowVerticalLines(false);
+        localTable.getColumnModel().getColumn(0).setMinWidth(200);
+        localTable.getColumnModel().getColumn(0).setMaxWidth(200);
+        localTable.getColumnModel().getColumn(1).setCellRenderer(centerRenderer);
+        localTable.setFont(new Font("monospaced", localTable.getFont().getStyle(), localTable.getFont().getSize()));
+        
+        JTable globalTable = new JTable(globalModel);
+        globalTable.setRowSelectionAllowed(false);
+        globalTable.setColumnSelectionAllowed(false);
+        globalTable.setCellSelectionEnabled(false);
+        globalTable.setShowVerticalLines(false);
+        globalTable.getColumnModel().getColumn(0).setMinWidth(200);
+        globalTable.getColumnModel().getColumn(0).setMaxWidth(200);
+        globalTable.getColumnModel().getColumn(1).setCellRenderer(centerRenderer);
+        globalTable.setFont(new Font("monospaced", globalTable.getFont().getStyle(), globalTable.getFont().getSize()));
+        
+        // Return the two tables.
+        return new JTable[] { localTable, globalTable };
+    }
+    
+    /**
+     * Sets the value of the indicated row for the global statistical
+     * table.
+     * @param rowIndex - The row.
+     * @param value - The new value.
+     */
+    protected void setGlobalRowValue(int rowIndex, String value) {
+        globalModel.setValueAt(value, rowIndex, COL_VALUE);
+    }
+    
+    /**
+     * Sets the value of the indicated row for the local statistical
+     * table.
+     * @param rowIndex - The row.
+     * @param value - The new value.
+     */
+    protected void setLocalRowValue(int rowIndex, String value) {
+        localModel.setValueAt(value, rowIndex, COL_VALUE);
+    }
 
 }

Modified: java/branches/HPSJAVA-409/monitoring-util/src/main/java/org/hps/monitoring/trigger/ClusterTablePanel.java
 =============================================================================
--- java/branches/HPSJAVA-409/monitoring-util/src/main/java/org/hps/monitoring/trigger/ClusterTablePanel.java	(original)
+++ java/branches/HPSJAVA-409/monitoring-util/src/main/java/org/hps/monitoring/trigger/ClusterTablePanel.java	Wed Apr 27 11:11:32 2016
@@ -14,99 +14,99 @@
  * @see AbstractTablePanel
  */
 public class ClusterTablePanel extends AbstractTwoColumnTablePanel {
-	// Static variables.
-	private static final long serialVersionUID = 0L;
-	private static final String[] TABLE_TITLES = { "Recon Clusters", "SSP Clusters", "Matched Clusters",
-			"Failed (Position)", "Failed (Energy)", "Failed (Hit Count)" };
-	
-	// Table model mappings.
-	private static final int ROW_RECON_COUNT      = 0;
-	private static final int ROW_SSP_COUNT        = 1;
-	private static final int ROW_MATCHED          = 2;
-	private static final int ROW_FAILED_POSITION  = 3;
-	private static final int ROW_FAILED_ENERGY    = 4;
-	private static final int ROW_FAILED_HIT_COUNT = 5;
-	
-	/**
-	 * Instantiate a new <code>ClusterTablePanel</code>.
-	 */
-	public ClusterTablePanel() { super(TABLE_TITLES); }
-	
-	@Override
-	public void updatePanel(DiagnosticSnapshot runSnapshot, DiagnosticSnapshot localSnapshot) {
-		// If the snapshot is null, all values should be "N/A."
-		if(localSnapshot == null || runSnapshot == null) {
-			// Output cluster count data.
-			String scalerNullValue = "---";
-			setLocalRowValue(ROW_RECON_COUNT,  scalerNullValue);
-			setLocalRowValue(ROW_SSP_COUNT,    scalerNullValue);
-			setGlobalRowValue(ROW_RECON_COUNT, scalerNullValue);
-			setGlobalRowValue(ROW_SSP_COUNT,   scalerNullValue);
-			
-			// Output the tracked statistical data.
-			String percentNullValue = "--- / --- (---%)";
-			setLocalRowValue(ROW_MATCHED,           percentNullValue);
-			setLocalRowValue(ROW_FAILED_POSITION,   percentNullValue);
-			setLocalRowValue(ROW_FAILED_ENERGY,     percentNullValue);
-			setLocalRowValue(ROW_FAILED_HIT_COUNT,  percentNullValue);
-			setGlobalRowValue(ROW_MATCHED,          percentNullValue);
-			setGlobalRowValue(ROW_FAILED_POSITION,  percentNullValue);
-			setGlobalRowValue(ROW_FAILED_ENERGY,    percentNullValue);
-			setGlobalRowValue(ROW_FAILED_HIT_COUNT, percentNullValue);
-		}
-		
-		// Otherwise, populate the table with the diagnostic data.
-		else {
-			// Get the cluster statistical banks.
-			ClusterStatModule lstat = localSnapshot.getClusterStats();
-			ClusterStatModule rstat = runSnapshot.getClusterStats();
-			
-			// Get the largest number of digits in any of the values.
-			int mostDigits = ComponentUtils.max(lstat.getReconClusterCount(), lstat.getSSPClusterCount(), lstat.getMatches(),
-					lstat.getPositionFailures(), lstat.getEnergyFailures(), lstat.getHitCountFailures(),
-					rstat.getReconClusterCount(), rstat.getSSPClusterCount(), rstat.getMatches(),
-					rstat.getPositionFailures(), rstat.getEnergyFailures(), rstat.getHitCountFailures());
-			int spaces = ComponentUtils.getDigits(mostDigits);
-			
-			// Put the number of reconstructed and SSP clusters into
-			// the tables.
-			int[] clusterValue = {
-					lstat.getReconClusterCount(),
-					lstat.getSSPClusterCount(),
-					rstat.getReconClusterCount(),
-					rstat.getSSPClusterCount()
-			};
-			String countFormat = "%" + spaces + "d";
-			setLocalRowValue(ROW_RECON_COUNT,  String.format(countFormat, clusterValue[0]));
-			setLocalRowValue(ROW_SSP_COUNT,    String.format(countFormat, clusterValue[1]));
-			setGlobalRowValue(ROW_RECON_COUNT, String.format(countFormat, clusterValue[2]));
-			setGlobalRowValue(ROW_SSP_COUNT,   String.format(countFormat, clusterValue[3]));
-			
-			// Output the tracked statistical data.
-			int total;
-			String percentFormat = "%" + spaces + "d / %" + spaces + "d (%7.3f)";
-			int[] statValue = {
-					lstat.getMatches(),
-					lstat.getPositionFailures(),
-					lstat.getEnergyFailures(),
-					lstat.getHitCountFailures(),
-					rstat.getMatches(),
-					rstat.getPositionFailures(),
-					rstat.getEnergyFailures(),
-					rstat.getHitCountFailures()
-			};
-			
-			total = lstat.getReconClusterCount();
-			setLocalRowValue(ROW_MATCHED,          String.format(percentFormat, statValue[0], total, 100.0 * statValue[0] / total));
-			setLocalRowValue(ROW_FAILED_POSITION,  String.format(percentFormat, statValue[1], total, 100.0 * statValue[1] / total));
-			setLocalRowValue(ROW_FAILED_ENERGY,    String.format(percentFormat, statValue[2], total, 100.0 * statValue[2] / total));
-			setLocalRowValue(ROW_FAILED_HIT_COUNT, String.format(percentFormat, statValue[3], total, 100.0 * statValue[3] / total));
-			
-			total = rstat.getReconClusterCount();
-			setGlobalRowValue(ROW_MATCHED,          String.format(percentFormat, statValue[4], total, 100.0 * statValue[4] / total));
-			setGlobalRowValue(ROW_FAILED_POSITION,  String.format(percentFormat, statValue[5], total, 100.0 * statValue[5] / total));
-			setGlobalRowValue(ROW_FAILED_ENERGY,    String.format(percentFormat, statValue[6], total, 100.0 * statValue[6] / total));
-			setGlobalRowValue(ROW_FAILED_HIT_COUNT, String.format(percentFormat, statValue[7], total, 100.0 * statValue[7] / total));
-		}
-	}
+    // Static variables.
+    private static final long serialVersionUID = 0L;
+    private static final String[] TABLE_TITLES = { "Recon Clusters", "SSP Clusters", "Matched Clusters",
+            "Failed (Position)", "Failed (Energy)", "Failed (Hit Count)" };
+    
+    // Table model mappings.
+    private static final int ROW_RECON_COUNT      = 0;
+    private static final int ROW_SSP_COUNT        = 1;
+    private static final int ROW_MATCHED          = 2;
+    private static final int ROW_FAILED_POSITION  = 3;
+    private static final int ROW_FAILED_ENERGY    = 4;
+    private static final int ROW_FAILED_HIT_COUNT = 5;
+    
+    /**
+     * Instantiate a new <code>ClusterTablePanel</code>.
+     */
+    public ClusterTablePanel() { super(TABLE_TITLES); }
+    
+    @Override
+    public void updatePanel(DiagnosticSnapshot runSnapshot, DiagnosticSnapshot localSnapshot) {
+        // If the snapshot is null, all values should be "N/A."
+        if(localSnapshot == null || runSnapshot == null) {
+            // Output cluster count data.
+            String scalerNullValue = "---";
+            setLocalRowValue(ROW_RECON_COUNT,  scalerNullValue);
+            setLocalRowValue(ROW_SSP_COUNT,    scalerNullValue);
+            setGlobalRowValue(ROW_RECON_COUNT, scalerNullValue);
+            setGlobalRowValue(ROW_SSP_COUNT,   scalerNullValue);
+            
+            // Output the tracked statistical data.
+            String percentNullValue = "--- / --- (---%)";
+            setLocalRowValue(ROW_MATCHED,           percentNullValue);
+            setLocalRowValue(ROW_FAILED_POSITION,   percentNullValue);
+            setLocalRowValue(ROW_FAILED_ENERGY,     percentNullValue);
+            setLocalRowValue(ROW_FAILED_HIT_COUNT,  percentNullValue);
+            setGlobalRowValue(ROW_MATCHED,          percentNullValue);
+            setGlobalRowValue(ROW_FAILED_POSITION,  percentNullValue);
+            setGlobalRowValue(ROW_FAILED_ENERGY,    percentNullValue);
+            setGlobalRowValue(ROW_FAILED_HIT_COUNT, percentNullValue);
+        }
+        
+        // Otherwise, populate the table with the diagnostic data.
+        else {
+            // Get the cluster statistical banks.
+            ClusterStatModule lstat = localSnapshot.getClusterStats();
+            ClusterStatModule rstat = runSnapshot.getClusterStats();
+            
+            // Get the largest number of digits in any of the values.
+            int mostDigits = ComponentUtils.max(lstat.getReconClusterCount(), lstat.getSSPClusterCount(), lstat.getMatches(),
+                    lstat.getPositionFailures(), lstat.getEnergyFailures(), lstat.getHitCountFailures(),
+                    rstat.getReconClusterCount(), rstat.getSSPClusterCount(), rstat.getMatches(),
+                    rstat.getPositionFailures(), rstat.getEnergyFailures(), rstat.getHitCountFailures());
+            int spaces = ComponentUtils.getDigits(mostDigits);
+            
+            // Put the number of reconstructed and SSP clusters into
+            // the tables.
+            int[] clusterValue = {
+                    lstat.getReconClusterCount(),
+                    lstat.getSSPClusterCount(),
+                    rstat.getReconClusterCount(),
+                    rstat.getSSPClusterCount()
+            };
+            String countFormat = "%" + spaces + "d";
+            setLocalRowValue(ROW_RECON_COUNT,  String.format(countFormat, clusterValue[0]));
+            setLocalRowValue(ROW_SSP_COUNT,    String.format(countFormat, clusterValue[1]));
+            setGlobalRowValue(ROW_RECON_COUNT, String.format(countFormat, clusterValue[2]));
+            setGlobalRowValue(ROW_SSP_COUNT,   String.format(countFormat, clusterValue[3]));
+            
+            // Output the tracked statistical data.
+            int total;
+            String percentFormat = "%" + spaces + "d / %" + spaces + "d (%7.3f)";
+            int[] statValue = {
+                    lstat.getMatches(),
+                    lstat.getPositionFailures(),
+                    lstat.getEnergyFailures(),
+                    lstat.getHitCountFailures(),
+                    rstat.getMatches(),
+                    rstat.getPositionFailures(),
+                    rstat.getEnergyFailures(),
+                    rstat.getHitCountFailures()
+            };
+            
+            total = lstat.getReconClusterCount();
+            setLocalRowValue(ROW_MATCHED,          String.format(percentFormat, statValue[0], total, 100.0 * statValue[0] / total));
+            setLocalRowValue(ROW_FAILED_POSITION,  String.format(percentFormat, statValue[1], total, 100.0 * statValue[1] / total));
+            setLocalRowValue(ROW_FAILED_ENERGY,    String.format(percentFormat, statValue[2], total, 100.0 * statValue[2] / total));
+            setLocalRowValue(ROW_FAILED_HIT_COUNT, String.format(percentFormat, statValue[3], total, 100.0 * statValue[3] / total));
+            
+            total = rstat.getReconClusterCount();
+            setGlobalRowValue(ROW_MATCHED,          String.format(percentFormat, statValue[4], total, 100.0 * statValue[4] / total));
+            setGlobalRowValue(ROW_FAILED_POSITION,  String.format(percentFormat, statValue[5], total, 100.0 * statValue[5] / total));
+            setGlobalRowValue(ROW_FAILED_ENERGY,    String.format(percentFormat, statValue[6], total, 100.0 * statValue[6] / total));
+            setGlobalRowValue(ROW_FAILED_HIT_COUNT, String.format(percentFormat, statValue[7], total, 100.0 * statValue[7] / total));
+        }
+    }
 }

Modified: java/branches/HPSJAVA-409/monitoring-util/src/main/java/org/hps/monitoring/trigger/ComponentUtils.java
 =============================================================================
--- java/branches/HPSJAVA-409/monitoring-util/src/main/java/org/hps/monitoring/trigger/ComponentUtils.java	(original)
+++ java/branches/HPSJAVA-409/monitoring-util/src/main/java/org/hps/monitoring/trigger/ComponentUtils.java	Wed Apr 27 11:11:32 2016
@@ -11,116 +11,116 @@
  * @author Kyle McCarty <[log in to unmask]>
  */
 public class ComponentUtils {
-	/** The default spacing used between a horizontal edge of one
-	 * component and the horizontal edge of another. */
-	static final int hinternal = 10;
-	/** The default spacing used between a vertical edge of one
-	 * component and the vertical edge of another. */
-	static final int vinternal = 10;
-	/** The default spacing used between a horizontal edge of one
-	 * component and the edge of its parent component. */
-	static final int hexternal = 0;
-	/** The default spacing used between a vertical edge of one
-	 * component and the edge of its parent component. */
-	static final int vexternal = 0;
-	
-	/**
-	 * Gets a <code>String</code> composed of a number of instances of
-	 * character <code>c</code> equal to <code>number</code>.
-	 * @param c - The character to repeat.
-	 * @param number - The number of repetitions.
-	 * @return Returns the repeated character as a <code>String</code>.
-	 */
-	public static final String getChars(char c, int number) {
-		// Create a buffer to store the characters in.
-		StringBuffer s = new StringBuffer();
-		
-		// Add the indicated number of instances.
-		for(int i = 0; i < number; i++) {
-			s.append(c);
-		}
-		
-		// Return the string.
-		return s.toString();
-	}
-	
-	/**
-	 * Gets the number of digits in the base-10 String representation
-	 * of an integer primitive. Negative signs are not included in the
-	 * digit count.
-	 * @param value - The value of which to obtain the length.
-	 * @return Returns the number of digits in the String representation
-	 * of the argument value.
-	 */
-	public static final int getDigits(int value) {
-		return TriggerDiagnosticUtil.getDigits(value);
-	}
-	
-	/**
-	 * Gets the maximum value from a list of values.
-	 * @param values - The values to compare.
-	 * @return Returns the largest of the argument values.
-	 * @throws IllegalArgumentException Occurs if no values are given.
-	 */
-	public static final int max(int... values) throws IllegalArgumentException {
-		// Throw an error if no arguments are provided.
-		if(values == null || values.length == 0) {
-			throw new IllegalArgumentException("Can not determine maximum value from a list of 0 values.");
-		}
-		
-		// If there is only one value, return it.
-		if(values.length == 1) { return values[0]; }
-		
-		// Otherwise, get the largest value.
-		int largest = Integer.MIN_VALUE;
-		for(int value : values) {
-			if(value > largest) { largest = value; }
-		}
-		
-		// Return the result.
-		return largest;
-	}
-	
-	/**
-	 * Gets the x-coordinate immediately to the right of the given
-	 * component.
-	 * @param c - The component of which to find the edge.
-	 * @return Returns the x-coordinate as an <code>int</code> value.
-	 */
-	static final int getNextX(Component c) {
-		return getNextX(c, 0);
-	}
-	
-	/**
-	 * Gets the x-coordinate a given distance to the right edge of the
-	 * argument component.
-	 * @param c - The component of which to find the edge.
-	 * @param spacing - The additional spacing past the edge of the
-	 * component to add.
-	 * @return Returns the x-coordinate as an <code>int</code> value.
-	 */
-	static final int getNextX(Component c, int spacing) {
-		return c.getX() + c.getWidth() + spacing;
-	}
-	
-	/**
-	 * Gets the y-coordinate immediately below the given component.
-	 * @param c - The component of which to find the edge.
-	 * @return Returns the y-coordinate as an <code>int</code> value.
-	 */
-	static final int getNextY(Component c) {
-		return getNextY(c, 0);
-	}
-	
-	/**
-	 * Gets the y-coordinate a given distance below the bottom edge
-	 * of the argument component.
-	 * @param c - The component of which to find the edge.
-	 * @param spacing - The additional spacing past the edge of the
-	 * component to add.
-	 * @return Returns the y-coordinate as an <code>int</code> value.
-	 */
-	static final int getNextY(Component c, int spacing) {
-		return c.getY() + c.getHeight() + spacing;
-	}
+    /** The default spacing used between a horizontal edge of one
+     * component and the horizontal edge of another. */
+    static final int hinternal = 10;
+    /** The default spacing used between a vertical edge of one
+     * component and the vertical edge of another. */
+    static final int vinternal = 10;
+    /** The default spacing used between a horizontal edge of one
+     * component and the edge of its parent component. */
+    static final int hexternal = 0;
+    /** The default spacing used between a vertical edge of one
+     * component and the edge of its parent component. */
+    static final int vexternal = 0;
+    
+    /**
+     * Gets a <code>String</code> composed of a number of instances of
+     * character <code>c</code> equal to <code>number</code>.
+     * @param c - The character to repeat.
+     * @param number - The number of repetitions.
+     * @return Returns the repeated character as a <code>String</code>.
+     */
+    public static final String getChars(char c, int number) {
+        // Create a buffer to store the characters in.
+        StringBuffer s = new StringBuffer();
+        
+        // Add the indicated number of instances.
+        for(int i = 0; i < number; i++) {
+            s.append(c);
+        }
+        
+        // Return the string.
+        return s.toString();
+    }
+    
+    /**
+     * Gets the number of digits in the base-10 String representation
+     * of an integer primitive. Negative signs are not included in the
+     * digit count.
+     * @param value - The value of which to obtain the length.
+     * @return Returns the number of digits in the String representation
+     * of the argument value.
+     */
+    public static final int getDigits(int value) {
+        return TriggerDiagnosticUtil.getDigits(value);
+    }
+    
+    /**
+     * Gets the maximum value from a list of values.
+     * @param values - The values to compare.
+     * @return Returns the largest of the argument values.
+     * @throws IllegalArgumentException Occurs if no values are given.
+     */
+    public static final int max(int... values) throws IllegalArgumentException {
+        // Throw an error if no arguments are provided.
+        if(values == null || values.length == 0) {
+            throw new IllegalArgumentException("Can not determine maximum value from a list of 0 values.");
+        }
+        
+        // If there is only one value, return it.
+        if(values.length == 1) { return values[0]; }
+        
+        // Otherwise, get the largest value.
+        int largest = Integer.MIN_VALUE;
+        for(int value : values) {
+            if(value > largest) { largest = value; }
+        }
+        
+        // Return the result.
+        return largest;
+    }
+    
+    /**
+     * Gets the x-coordinate immediately to the right of the given
+     * component.
+     * @param c - The component of which to find the edge.
+     * @return Returns the x-coordinate as an <code>int</code> value.
+     */
+    static final int getNextX(Component c) {
+        return getNextX(c, 0);
+    }
+    
+    /**
+     * Gets the x-coordinate a given distance to the right edge of the
+     * argument component.
+     * @param c - The component of which to find the edge.
+     * @param spacing - The additional spacing past the edge of the
+     * component to add.
+     * @return Returns the x-coordinate as an <code>int</code> value.
+     */
+    static final int getNextX(Component c, int spacing) {
+        return c.getX() + c.getWidth() + spacing;
+    }
+    
+    /**
+     * Gets the y-coordinate immediately below the given component.
+     * @param c - The component of which to find the edge.
+     * @return Returns the y-coordinate as an <code>int</code> value.
+     */
+    static final int getNextY(Component c) {
+        return getNextY(c, 0);
+    }
+    
+    /**
+     * Gets the y-coordinate a given distance below the bottom edge
+     * of the argument component.
+     * @param c - The component of which to find the edge.
+     * @param spacing - The additional spacing past the edge of the
+     * component to add.
+     * @return Returns the y-coordinate as an <code>int</code> value.
+     */
+    static final int getNextY(Component c, int spacing) {
+        return c.getY() + c.getHeight() + spacing;
+    }
 }

Modified: java/branches/HPSJAVA-409/monitoring-util/src/main/java/org/hps/monitoring/trigger/DiagnosticUpdatable.java
 =============================================================================
--- java/branches/HPSJAVA-409/monitoring-util/src/main/java/org/hps/monitoring/trigger/DiagnosticUpdatable.java	(original)
+++ java/branches/HPSJAVA-409/monitoring-util/src/main/java/org/hps/monitoring/trigger/DiagnosticUpdatable.java	Wed Apr 27 11:11:32 2016
@@ -9,14 +9,15 @@
  * alter their displayed or constituent values.
  * 
  * @author Kyle McCarty <[log in to unmask]>
- * @see DiagSnapshot
+ * @see org.hps.analysis.trigger.data.DiagnosticSnapshot
  */
 public interface DiagnosticUpdatable {
-	/**
-	 * Updates the object with information from the trigger diagnostic
-	 * snapshot in the argument.
-	 * @param snapshot - The snapshot containing information with which
-	 * to update the object.
-	 */
-	public void updatePanel(DiagnosticSnapshot runSnapshot, DiagnosticSnapshot localSnapshot);
+    /**
+     * Updates the object with information from the trigger diagnostic
+     * snapshot in the argument.
+     * @param runSnapshot the accumulated snapshot
+     * @param localSnapshot The snapshot containing information with which
+     * to update the object. 
+     */
+    public void updatePanel(DiagnosticSnapshot runSnapshot, DiagnosticSnapshot localSnapshot);
 }

Modified: java/branches/HPSJAVA-409/monitoring-util/src/main/java/org/hps/monitoring/trigger/EfficiencyTablePanel.java
 =============================================================================
--- java/branches/HPSJAVA-409/monitoring-util/src/main/java/org/hps/monitoring/trigger/EfficiencyTablePanel.java	(original)
+++ java/branches/HPSJAVA-409/monitoring-util/src/main/java/org/hps/monitoring/trigger/EfficiencyTablePanel.java	Wed Apr 27 11:11:32 2016
@@ -11,200 +11,200 @@
 import org.hps.analysis.trigger.util.ComponentUtils;
 
 public class EfficiencyTablePanel extends AbstractTablePanel implements DiagnosticUpdatable {
-	// Static variables.
-	private static final long serialVersionUID = 0L;
-	
-	// Table models.
-	private TableTextModel localModel;
-	private TableTextModel globalModel;
-	
-	// Column/row reference variables.
-	private static final int ROWS = 7;
-	private static final int COLUMNS = 6;
-	/* private static final int COL_HEADER    = 0;
-	private static final int COL_SINGLES_0 = 1;
-	private static final int COL_SINGLES_1 = 2;
-	private static final int COL_PAIR_0    = 3;
-	private static final int COL_PAIR_1    = 4; */
-	private static final int COL_COUNT     = 5;
-	/* private static final int ROW_HEADER    = 0;
-	private static final int ROW_PULSER    = 1;
-	private static final int ROW_COSMIC    = 2;
-	private static final int ROW_SINGLES_0 = 3;
-	private static final int ROW_SINGLES_1 = 4;
-	private static final int ROW_PAIR_0    = 5;
-	private static final int ROW_PAIR_1    = 6; */
-	
-	// Global/local reference variables.
-	private static final int GLOBAL = 0;
-	private static final int LOCAL  = 1;
-	
-	// Trigger type reference variables.
-	private static final int TYPE_SINGLES_0 = TriggerStatModule.SINGLES_0;
-	private static final int TYPE_SINGLES_1 = TriggerStatModule.SINGLES_1;
-	private static final int TYPE_PAIR_0    = TriggerStatModule.PAIR_0;
-	private static final int TYPE_PAIR_1    = TriggerStatModule.PAIR_1;
-	
-	// Column/row header names.
-	private static final String[] COL_NAMES = {
-		"", "Singles 0", "Singles 1", "Pair 0", "Pair 1", "Count"
-	};
-	private static final String[] ROW_NAMES = {
-		"", "Singles 0", "Singles 1", "Pair 0", "Pair 1", "Pulser", "Cosmic"
-		//"", "Random", "Cosmic", "Singles 0", "Singles 1", "Pair 0", "Pair 1"
-	};
-	
-	/**
-	 * Instantiates a new <code>EfficiencyTablePanel</code>.
-	 */
-	public EfficiencyTablePanel() {
-		// Instantiate the superclass.
-		super();
-		
-		// Set the orientation to vertical.
-		setOrientation(ORIENTATION_VERTICAL);
-	}
-	
-	@Override
-	public void updatePanel(DiagnosticSnapshot runSnapshot, DiagnosticSnapshot localSnapshot) {
-		// If there is no snapshot, the tables should all display an
-		// empty value.
-		if(runSnapshot == null || localSnapshot == null) {
-			for(int row = 1; row < ROWS; row++) {
-				for(int col = 1; col < COLUMNS; col++) {
-					localModel.setValueAt("---", row, col);
-					globalModel.setValueAt("---", row, col);
-				}
-			}
-		}
-		
-		// Otherwise, update the table cells from the snapshot data.
-		else {
-			// Get the efficiency modules.
-			DiagnosticSnapshot[] stat = new DiagnosticSnapshot[2];
-			stat[GLOBAL] = runSnapshot;
-			stat[LOCAL] = localSnapshot;
-			
-			// Get the trigger count for each trigger type for both the
-			// local and global snapshots.
-			int[][][] matched = new int[2][4][6];
-			int[][][] triggers = new int[2][4][6];
-			for(int i = 0; i < 2; i++) {
-				for(int triggerType = 0; triggerType < 6; triggerType++) {
-					// Get the total triggers seen for each type.
-					triggers[i][TYPE_SINGLES_0][triggerType] = stat[i].getSingles0Stats().getSSPSimulatedTriggers(triggerType);
-					triggers[i][TYPE_SINGLES_1][triggerType] = stat[i].getSingles1Stats().getSSPSimulatedTriggers(triggerType);
-					triggers[i][TYPE_PAIR_0][triggerType] = stat[i].getPair0Stats().getSSPSimulatedTriggers(triggerType);
-					triggers[i][TYPE_PAIR_1][triggerType] = stat[i].getPair1Stats().getSSPSimulatedTriggers(triggerType);
-					
-					// Get the total triggers matched for each type.
-					matched[i][TYPE_SINGLES_0][triggerType] = stat[i].getSingles0Stats().getMatchedSSPSimulatedTriggers(triggerType);
-					matched[i][TYPE_SINGLES_1][triggerType] = stat[i].getSingles1Stats().getMatchedSSPSimulatedTriggers(triggerType);
-					matched[i][TYPE_PAIR_0][triggerType] = stat[i].getPair0Stats().getMatchedSSPSimulatedTriggers(triggerType);
-					matched[i][TYPE_PAIR_1][triggerType] = stat[i].getPair1Stats().getMatchedSSPSimulatedTriggers(triggerType);
-				}
-			}
-			
-			// Determine the spacing needed to display the largest numerical
-			// cell value.
-			int numWidth = -1;
-			for(int tiTriggerType = 0; tiTriggerType < 6; tiTriggerType++) {
-				for(int seenTriggerType = 0; seenTriggerType < 4; seenTriggerType++) {
-					int rSize = ComponentUtils.getDigits(triggers[GLOBAL][seenTriggerType][tiTriggerType]);
-					int lSize = ComponentUtils.getDigits(triggers[LOCAL][seenTriggerType][tiTriggerType]);
-					numWidth = ComponentUtils.max(numWidth, rSize, lSize);
-				}
-			}
-			
-			// Generate the format string for the cells.
-			String format = "%" + numWidth + "d / %" + numWidth + "d";
-			
-			// Update the table.
-			for(int tiTriggerType = 0; tiTriggerType < 6; tiTriggerType++) {
-				// Fill the row/column combinations that hold trigger
-				// statistical information.
-				for(int seenTriggerType = 0; seenTriggerType < 4; seenTriggerType++) {
-					// Fill the local table cell.
-					String localText = String.format(format, matched[LOCAL][seenTriggerType][tiTriggerType],
-							triggers[LOCAL][seenTriggerType][tiTriggerType]);
-					if(triggers[LOCAL][seenTriggerType][tiTriggerType] == 0) {
-						localText = localText + " (  N/A  %)";
-					} else {
-						localText = String.format("%s (%7.3f%%)", localText,
-								(100.0 * matched[LOCAL][seenTriggerType][tiTriggerType] / triggers[LOCAL][seenTriggerType][tiTriggerType]));
-					}
-					localModel.setValueAt(localText, tiTriggerType + 1, seenTriggerType + 1);
-					
-					// Fill the global table cell.
-					String globalText = String.format(format, matched[GLOBAL][seenTriggerType][tiTriggerType],
-							triggers[GLOBAL][seenTriggerType][tiTriggerType]);
-					if(triggers[GLOBAL][seenTriggerType][tiTriggerType] == 0) {
-						globalText = globalText + " (  N/A  %)";
-					} else {
-						globalText = String.format("%s (%7.3f%%)", globalText,
-								(100.0 * matched[GLOBAL][seenTriggerType][tiTriggerType] / triggers[GLOBAL][seenTriggerType][tiTriggerType]));
-					}
-					globalModel.setValueAt(globalText, tiTriggerType + 1, seenTriggerType + 1);
-				}
-				
-				// Populate the count column.
-				localModel.setValueAt("" + stat[LOCAL].getTITriggers(tiTriggerType, true), tiTriggerType + 1, COL_COUNT);
-				globalModel.setValueAt("" + stat[GLOBAL].getTITriggers(tiTriggerType, true), tiTriggerType + 1, COL_COUNT);
-			}
-		}
-	}
-	
-	@Override
-	protected JTable[] initializeTables(Object... args) {
-		// Initialize the table models. There should be one row and
-		// one column for each type of trigger plus an additional one
-		// of each for headers.
-		localModel = new TableTextModel(ROWS, COLUMNS);
-		globalModel = new TableTextModel(ROWS, COLUMNS);
-		
-		// Set the column headers.
-		for(int col = 0; col < COLUMNS; col++) {
-			localModel.setValueAt(COL_NAMES[col], 0, col);
-			globalModel.setValueAt(COL_NAMES[col], 0, col);
-		}
-		
-		// Set the row headers.
-		for(int row = 0; row < ROWS; row++) {
-			localModel.setValueAt(ROW_NAMES[row], row, 0);
-			globalModel.setValueAt(ROW_NAMES[row], row, 0);
-		}
-		
-		// Make a cell renderer.
-		DefaultTableCellRenderer centerRenderer = new DefaultTableCellRenderer();
-		centerRenderer.setHorizontalAlignment(JLabel.CENTER);
-		
-		// Create JTable objects to display the data.
-		JTable localTable = new JTable(localModel);
-		localTable.setRowSelectionAllowed(false);
-		localTable.setColumnSelectionAllowed(false);
-		localTable.setCellSelectionEnabled(false);
-		localTable.setShowVerticalLines(false);
-		localTable.getColumnModel().getColumn(0).setMaxWidth(150);
-		localTable.getColumnModel().getColumn(COL_COUNT).setMaxWidth(150);
-		for(int col = 1; col < COLUMNS; col++) {
-			localTable.getColumnModel().getColumn(col).setCellRenderer(centerRenderer);
-		}
-		localTable.setFont(new Font("monospaced", localTable.getFont().getStyle(), localTable.getFont().getSize()));
-		
-		JTable globalTable = new JTable(globalModel);
-		globalTable.setRowSelectionAllowed(false);
-		globalTable.setColumnSelectionAllowed(false);
-		globalTable.setCellSelectionEnabled(false);
-		globalTable.setShowVerticalLines(false);
-		globalTable.getColumnModel().getColumn(0).setMaxWidth(150);
-		globalTable.getColumnModel().getColumn(COL_COUNT).setMaxWidth(150);
-		for(int col = 1; col < COLUMNS; col++) {
-			globalTable.getColumnModel().getColumn(col).setCellRenderer(centerRenderer);
-		}
-		globalTable.setFont(new Font("monospaced", globalTable.getFont().getStyle(), globalTable.getFont().getSize()));
-		
-		// Return the tables.
-		return new JTable[] { localTable, globalTable };
-	}
-	
+    // Static variables.
+    private static final long serialVersionUID = 0L;
+    
+    // Table models.
+    private TableTextModel localModel;
+    private TableTextModel globalModel;
+    
+    // Column/row reference variables.
+    private static final int ROWS = 7;
+    private static final int COLUMNS = 6;
+    /* private static final int COL_HEADER    = 0;
+    private static final int COL_SINGLES_0 = 1;
+    private static final int COL_SINGLES_1 = 2;
+    private static final int COL_PAIR_0    = 3;
+    private static final int COL_PAIR_1    = 4; */
+    private static final int COL_COUNT     = 5;
+    /* private static final int ROW_HEADER    = 0;
+    private static final int ROW_PULSER    = 1;
+    private static final int ROW_COSMIC    = 2;
+    private static final int ROW_SINGLES_0 = 3;
+    private static final int ROW_SINGLES_1 = 4;
+    private static final int ROW_PAIR_0    = 5;
+    private static final int ROW_PAIR_1    = 6; */
+    
+    // Global/local reference variables.
+    private static final int GLOBAL = 0;
+    private static final int LOCAL  = 1;
+    
+    // Trigger type reference variables.
+    private static final int TYPE_SINGLES_0 = TriggerStatModule.SINGLES_0;
+    private static final int TYPE_SINGLES_1 = TriggerStatModule.SINGLES_1;
+    private static final int TYPE_PAIR_0    = TriggerStatModule.PAIR_0;
+    private static final int TYPE_PAIR_1    = TriggerStatModule.PAIR_1;
+    
+    // Column/row header names.
+    private static final String[] COL_NAMES = {
+        "", "Singles 0", "Singles 1", "Pair 0", "Pair 1", "Count"
+    };
+    private static final String[] ROW_NAMES = {
+        "", "Singles 0", "Singles 1", "Pair 0", "Pair 1", "Pulser", "Cosmic"
+        //"", "Random", "Cosmic", "Singles 0", "Singles 1", "Pair 0", "Pair 1"
+    };
+    
+    /**
+     * Instantiates a new <code>EfficiencyTablePanel</code>.
+     */
+    public EfficiencyTablePanel() {
+        // Instantiate the superclass.
+        super();
+        
+        // Set the orientation to vertical.
+        setOrientation(ORIENTATION_VERTICAL);
+    }
+    
+    @Override
+    public void updatePanel(DiagnosticSnapshot runSnapshot, DiagnosticSnapshot localSnapshot) {
+        // If there is no snapshot, the tables should all display an
+        // empty value.
+        if(runSnapshot == null || localSnapshot == null) {
+            for(int row = 1; row < ROWS; row++) {
+                for(int col = 1; col < COLUMNS; col++) {
+                    localModel.setValueAt("---", row, col);
+                    globalModel.setValueAt("---", row, col);
+                }
+            }
+        }
+        
+        // Otherwise, update the table cells from the snapshot data.
+        else {
+            // Get the efficiency modules.
+            DiagnosticSnapshot[] stat = new DiagnosticSnapshot[2];
+            stat[GLOBAL] = runSnapshot;
+            stat[LOCAL] = localSnapshot;
+            
+            // Get the trigger count for each trigger type for both the
+            // local and global snapshots.
+            int[][][] matched = new int[2][4][6];
+            int[][][] triggers = new int[2][4][6];
+            for(int i = 0; i < 2; i++) {
+                for(int triggerType = 0; triggerType < 6; triggerType++) {
+                    // Get the total triggers seen for each type.
+                    triggers[i][TYPE_SINGLES_0][triggerType] = stat[i].getSingles0Stats().getSSPSimulatedTriggers(triggerType);
+                    triggers[i][TYPE_SINGLES_1][triggerType] = stat[i].getSingles1Stats().getSSPSimulatedTriggers(triggerType);
+                    triggers[i][TYPE_PAIR_0][triggerType] = stat[i].getPair0Stats().getSSPSimulatedTriggers(triggerType);
+                    triggers[i][TYPE_PAIR_1][triggerType] = stat[i].getPair1Stats().getSSPSimulatedTriggers(triggerType);
+                    
+                    // Get the total triggers matched for each type.
+                    matched[i][TYPE_SINGLES_0][triggerType] = stat[i].getSingles0Stats().getMatchedSSPSimulatedTriggers(triggerType);
+                    matched[i][TYPE_SINGLES_1][triggerType] = stat[i].getSingles1Stats().getMatchedSSPSimulatedTriggers(triggerType);
+                    matched[i][TYPE_PAIR_0][triggerType] = stat[i].getPair0Stats().getMatchedSSPSimulatedTriggers(triggerType);
+                    matched[i][TYPE_PAIR_1][triggerType] = stat[i].getPair1Stats().getMatchedSSPSimulatedTriggers(triggerType);
+                }
+            }
+            
+            // Determine the spacing needed to display the largest numerical
+            // cell value.
+            int numWidth = -1;
+            for(int tiTriggerType = 0; tiTriggerType < 6; tiTriggerType++) {
+                for(int seenTriggerType = 0; seenTriggerType < 4; seenTriggerType++) {
+                    int rSize = ComponentUtils.getDigits(triggers[GLOBAL][seenTriggerType][tiTriggerType]);
+                    int lSize = ComponentUtils.getDigits(triggers[LOCAL][seenTriggerType][tiTriggerType]);
+                    numWidth = ComponentUtils.max(numWidth, rSize, lSize);
+                }
+            }
+            
+            // Generate the format string for the cells.
+            String format = "%" + numWidth + "d / %" + numWidth + "d";
+            
+            // Update the table.
+            for(int tiTriggerType = 0; tiTriggerType < 6; tiTriggerType++) {
+                // Fill the row/column combinations that hold trigger
+                // statistical information.
+                for(int seenTriggerType = 0; seenTriggerType < 4; seenTriggerType++) {
+                    // Fill the local table cell.
+                    String localText = String.format(format, matched[LOCAL][seenTriggerType][tiTriggerType],
+                            triggers[LOCAL][seenTriggerType][tiTriggerType]);
+                    if(triggers[LOCAL][seenTriggerType][tiTriggerType] == 0) {
+                        localText = localText + " (  N/A  %)";
+                    } else {
+                        localText = String.format("%s (%7.3f%%)", localText,
+                                (100.0 * matched[LOCAL][seenTriggerType][tiTriggerType] / triggers[LOCAL][seenTriggerType][tiTriggerType]));
+                    }
+                    localModel.setValueAt(localText, tiTriggerType + 1, seenTriggerType + 1);
+                    
+                    // Fill the global table cell.
+                    String globalText = String.format(format, matched[GLOBAL][seenTriggerType][tiTriggerType],
+                            triggers[GLOBAL][seenTriggerType][tiTriggerType]);
+                    if(triggers[GLOBAL][seenTriggerType][tiTriggerType] == 0) {
+                        globalText = globalText + " (  N/A  %)";
+                    } else {
+                        globalText = String.format("%s (%7.3f%%)", globalText,
+                                (100.0 * matched[GLOBAL][seenTriggerType][tiTriggerType] / triggers[GLOBAL][seenTriggerType][tiTriggerType]));
+                    }
+                    globalModel.setValueAt(globalText, tiTriggerType + 1, seenTriggerType + 1);
+                }
+                
+                // Populate the count column.
+                localModel.setValueAt("" + stat[LOCAL].getTITriggers(tiTriggerType, true), tiTriggerType + 1, COL_COUNT);
+                globalModel.setValueAt("" + stat[GLOBAL].getTITriggers(tiTriggerType, true), tiTriggerType + 1, COL_COUNT);
+            }
+        }
+    }
+    
+    @Override
+    protected JTable[] initializeTables(Object... args) {
+        // Initialize the table models. There should be one row and
+        // one column for each type of trigger plus an additional one
+        // of each for headers.
+        localModel = new TableTextModel(ROWS, COLUMNS);
+        globalModel = new TableTextModel(ROWS, COLUMNS);
+        
+        // Set the column headers.
+        for(int col = 0; col < COLUMNS; col++) {
+            localModel.setValueAt(COL_NAMES[col], 0, col);
+            globalModel.setValueAt(COL_NAMES[col], 0, col);
+        }
+        
+        // Set the row headers.
+        for(int row = 0; row < ROWS; row++) {
+            localModel.setValueAt(ROW_NAMES[row], row, 0);
+            globalModel.setValueAt(ROW_NAMES[row], row, 0);
+        }
+        
+        // Make a cell renderer.
+        DefaultTableCellRenderer centerRenderer = new DefaultTableCellRenderer();
+        centerRenderer.setHorizontalAlignment(JLabel.CENTER);
+        
+        // Create JTable objects to display the data.
+        JTable localTable = new JTable(localModel);
+        localTable.setRowSelectionAllowed(false);
+        localTable.setColumnSelectionAllowed(false);
+        localTable.setCellSelectionEnabled(false);
+        localTable.setShowVerticalLines(false);
+        localTable.getColumnModel().getColumn(0).setMaxWidth(150);
+        localTable.getColumnModel().getColumn(COL_COUNT).setMaxWidth(150);
+        for(int col = 1; col < COLUMNS; col++) {
+            localTable.getColumnModel().getColumn(col).setCellRenderer(centerRenderer);
+        }
+        localTable.setFont(new Font("monospaced", localTable.getFont().getStyle(), localTable.getFont().getSize()));
+        
+        JTable globalTable = new JTable(globalModel);
+        globalTable.setRowSelectionAllowed(false);
+        globalTable.setColumnSelectionAllowed(false);
+        globalTable.setCellSelectionEnabled(false);
+        globalTable.setShowVerticalLines(false);
+        globalTable.getColumnModel().getColumn(0).setMaxWidth(150);
+        globalTable.getColumnModel().getColumn(COL_COUNT).setMaxWidth(150);
+        for(int col = 1; col < COLUMNS; col++) {
+            globalTable.getColumnModel().getColumn(col).setCellRenderer(centerRenderer);
+        }
+        globalTable.setFont(new Font("monospaced", globalTable.getFont().getStyle(), globalTable.getFont().getSize()));
+        
+        // Return the tables.
+        return new JTable[] { localTable, globalTable };
+    }
+    
 }

Modified: java/branches/HPSJAVA-409/monitoring-util/src/main/java/org/hps/monitoring/trigger/PairTablePanel.java
 =============================================================================
--- java/branches/HPSJAVA-409/monitoring-util/src/main/java/org/hps/monitoring/trigger/PairTablePanel.java	(original)
+++ java/branches/HPSJAVA-409/monitoring-util/src/main/java/org/hps/monitoring/trigger/PairTablePanel.java	Wed Apr 27 11:11:32 2016
@@ -7,14 +7,14 @@
  * @author Kyle McCarty
  */
 public class PairTablePanel extends AbstractTriggerTablePanel {
-	// Static variables.
-	private static final long serialVersionUID = 0L;
-	private static final String[] CUT_NAMES = { "    Energy Sum:",
-		"    Energy Difference:", "    Energy Slope:", "    Coplanarity:" };
-	
-	/**
-	 * Instantiates a <code>PairTablePanel</code>.
-	 */
-	public PairTablePanel() { super(CUT_NAMES, false); }
-	
+    // Static variables.
+    private static final long serialVersionUID = 0L;
+    private static final String[] CUT_NAMES = { "    Energy Sum:",
+        "    Energy Difference:", "    Energy Slope:", "    Coplanarity:" };
+    
+    /**
+     * Instantiates a <code>PairTablePanel</code>.
+     */
+    public PairTablePanel() { super(CUT_NAMES, false); }
+    
 }

Modified: java/branches/HPSJAVA-409/monitoring-util/src/main/java/org/hps/monitoring/trigger/ShifterTrigPanel.java
 =============================================================================
--- java/branches/HPSJAVA-409/monitoring-util/src/main/java/org/hps/monitoring/trigger/ShifterTrigPanel.java	(original)
+++ java/branches/HPSJAVA-409/monitoring-util/src/main/java/org/hps/monitoring/trigger/ShifterTrigPanel.java	Wed Apr 27 11:11:32 2016
@@ -12,291 +12,291 @@
 import org.hps.analysis.trigger.util.ComponentUtils;
 
 public class ShifterTrigPanel extends JPanel {
-	private static final Color BG_WARNING = new Color(255, 235, 20);
-	private static final Color BG_CRITICAL = new Color(230, 0, 0);
-	private static final Color FONT_WARNING = new Color(255, 157, 0);
-	private static final Color FONT_CRITICAL = new Color(117, 0, 0);
-	private static final long serialVersionUID = 1L;
-	
-	private JLabel panelTitle;
-	private JLabel[] fieldTitle;
-	private JLabel[] fieldValue;
-	
-	/**
-	 * Instantiates a new <code>ShifterTrigPanel</code> with the
-	 * indicated name.
-	 */
-	public ShifterTrigPanel(String name) {
-		// Instantiate a layout for the fields.
-		SpringLayout layout = new SpringLayout();
-		setLayout(layout);
-		
-		// Instantiate the header title.
-		panelTitle = new JLabel(name);
-		panelTitle.setVerticalAlignment(JLabel.CENTER);
-		panelTitle.setHorizontalAlignment(JLabel.CENTER);
-		add(panelTitle);
-		
-		// Instantiate the field title labels.
-		String[] titleName = { "Cluster Efficiency", "Singles 0 Logic Efficiency",
-				"Singles 0 Trigger Efficiency", "Singles 1 Logic Efficiency",
-				"Singles 1 Trigger Efficiency", "Pair 0 Logic Efficiency",
-				"Pair 0 Trigger Efficiency", "Pair 1 Logic Efficiency", "Pair 1 Trigger Efficiency" };
-		fieldTitle = new JLabel[titleName.length];
-		for(int index = 0; index < titleName.length; index++) {
-			fieldTitle[index] = new JLabel(titleName[index]);
-			fieldTitle[index].setVerticalAlignment(JLabel.CENTER);
-			fieldTitle[index].setHorizontalAlignment(JLabel.RIGHT);
-			fieldTitle[index].setOpaque(true);
-			add(fieldTitle[index]);
-		}
-		
-		// Instantiate the field value labels.
-		fieldValue = new JLabel[titleName.length];
-		for(int index = 0; index < titleName.length; index++) {
-			fieldValue[index] = new JLabel("");
-			fieldValue[index].setVerticalAlignment(JLabel.CENTER);
-			fieldValue[index].setHorizontalAlignment(JLabel.LEFT);
-			fieldValue[index].setOpaque(true);
-			add(fieldValue[index]);
-		}
-		
-		// Get the longest title.
-		int maxWidth = -1;
-		int maxIndex = -1;
-		for(int index = 0; index < titleName.length; index++) {
-			int width = fieldTitle[index].getFontMetrics(fieldTitle[index].getFont()).stringWidth(titleName[index]);
-			if(width > maxWidth) {
-				maxWidth = width;
-				maxIndex = index;
-			}
-		}
-		
-		// Define border edge and spacing variables.
-		String EAST = SpringLayout.EAST;
-		String WEST = SpringLayout.WEST;
-		String NORTH = SpringLayout.NORTH;
-		String SOUTH = SpringLayout.SOUTH;
-		int hinternal =  5;
-		int vinternal = 10;
-		int hexternal =  5;
-		int vexternal =  5;
-		
-		// Position the panel header.
-		layout.putConstraint(EAST,  panelTitle, hexternal, EAST,  this);
-		layout.putConstraint(WEST,  panelTitle, hexternal, WEST,  this);
-		layout.putConstraint(NORTH, panelTitle, vexternal, NORTH, this);
-		
-		// Position the field entries.
-		Component lastComp = panelTitle;
-		for(int index = 0; index < titleName.length; index++) {
-			// For all field titles except the largest, lock the right
-			// edge of the title to match the position of the largest
-			// title's right edge. The largest title is allowed to size
-			// itself to its preferred width.
-			if(index == maxIndex) {
-				layout.putConstraint(NORTH, fieldTitle[index], vinternal, SOUTH, lastComp);
-				layout.putConstraint(WEST,  fieldTitle[index], hexternal, WEST,  this);
-			} else {
-				layout.putConstraint(NORTH, fieldTitle[index], vinternal, SOUTH, lastComp);
-				layout.putConstraint(WEST,  fieldTitle[index], hexternal, WEST,  this);
-				layout.putConstraint(EAST,  fieldTitle[index],         0, EAST,  fieldTitle[maxIndex]);
-			}
-			
-			// Position the field value label to the right of the field
-			// title label. It should use up the remainder of the width
-			// allowed by the component.
-			layout.putConstraint(WEST,  fieldValue[index], hinternal, EAST,  fieldTitle[index]);
-			layout.putConstraint(EAST,  fieldValue[index], hexternal, EAST,  this);
-			layout.putConstraint(NORTH, fieldValue[index], vinternal, SOUTH, lastComp);
-			
-			// Update the "last component" to the current field title
-			// label.
-			lastComp = fieldTitle[index];
-		}
-		
-		// Update the fonts.
-		setFont(getFont());
-	}
-	
-	@Override
-	public void setBackground(Color bg) {
-		// Set the superclass background.
-		super.setBackground(bg);
-		
-		// Set the component backgrounds.
-		if(panelTitle != null) {
-			panelTitle.setBackground(bg);
-			for(int index = 0; index < fieldTitle.length; index++) {
-				fieldTitle[index].setBackground(bg);
-				
-				// If the field value label has a special alert color,
-				// then do not overwrite it.
-				if(!fieldValue[index].getBackground().equals(BG_WARNING)
-						&& !fieldValue[index].getBackground().equals(BG_CRITICAL)) {
-					fieldValue[index].setBackground(bg);
-				}
-			}
-		}
-	}
-	
-	@Override
-	public void setFont(Font font) {
-		// Set the superclass font.
-		super.setFont(font);
-		
-		// Set the component fonts.
-		if(panelTitle != null) {
-			panelTitle.setFont(font.deriveFont(Font.BOLD, (float) (font.getSize2D() * 1.5)));
-			for(int index = 0; index < fieldTitle.length; index++) {
-				fieldTitle[index].setFont(font.deriveFont(Font.BOLD));
-				fieldValue[index].setFont(font);
-			}
-		}
-	}
-	
-	@Override
-	public void setForeground(Color fg) {
-		// Set the superclass foreground.
-		super.setForeground(fg);
-		
-		// Set the component backgrounds.
-		if(panelTitle != null) {
-			panelTitle.setForeground(fg);
-			for(int index = 0; index < fieldTitle.length; index++) {
-				fieldTitle[index].setForeground(fg);
-				
-				// If the field value label has a special alert color,
-				// then do not overwrite it.
-				if(!fieldValue[index].getForeground().equals(FONT_WARNING)
-						&& !fieldValue[index].getForeground().equals(FONT_CRITICAL)) {
-					fieldValue[index].setBackground(fg);
-				}
-			}
-		}
-	}
-	
-	/**
-	 * Updates the panel statistical display with data from the
-	 * argument snapshot.
-	 * @param stat - The snapshot from which to derive statistical
-	 *               data.
-	 */
-	public void updatePanel(DiagnosticSnapshot stat) {
-		// If the snapshot is null, insert "null" values in the
-		// field panels,
-		if(stat == null) {
-			// Populate the fields with a "null" entry.
-			for(int index = 0; index < fieldValue.length; index++) {
-				fieldValue[index].setText("--- / --- (  N/A  %)");
-			}
-			
-			// No data exists, so no further processing is needed.
-			return;
-		}
-		
-		// Define index constants.
-		int RECON = 0;
-		int SSP = 1;
-		int TRIGGER_0 = 0;
-		int TRIGGER_1 = 1;
-		
-		// Get the tracked values from the snapshot.
-		int seenClusters = stat.getClusterStats().getReconClusterCount();
-		int[][] seenSinglesTriggers = {
-			{ stat.getSingles0Stats().getReconSimulatedTriggers(), stat.getSingles1Stats().getReconSimulatedTriggers() },
-			{ stat.getSingles0Stats().getSSPSimulatedTriggers(), stat.getSingles1Stats().getSSPSimulatedTriggers() }
-		};
-		int[][] seenPairTriggers = {
+    private static final Color BG_WARNING = new Color(255, 235, 20);
+    private static final Color BG_CRITICAL = new Color(230, 0, 0);
+    private static final Color FONT_WARNING = new Color(255, 157, 0);
+    private static final Color FONT_CRITICAL = new Color(117, 0, 0);
+    private static final long serialVersionUID = 1L;
+    
+    private JLabel panelTitle;
+    private JLabel[] fieldTitle;
+    private JLabel[] fieldValue;
+    
+    /**
+     * Instantiates a new <code>ShifterTrigPanel</code> with the
+     * indicated name.
+     */
+    public ShifterTrigPanel(String name) {
+        // Instantiate a layout for the fields.
+        SpringLayout layout = new SpringLayout();
+        setLayout(layout);
+        
+        // Instantiate the header title.
+        panelTitle = new JLabel(name);
+        panelTitle.setVerticalAlignment(JLabel.CENTER);
+        panelTitle.setHorizontalAlignment(JLabel.CENTER);
+        add(panelTitle);
+        
+        // Instantiate the field title labels.
+        String[] titleName = { "Cluster Efficiency", "Singles 0 Logic Efficiency",
+                "Singles 0 Trigger Efficiency", "Singles 1 Logic Efficiency",
+                "Singles 1 Trigger Efficiency", "Pair 0 Logic Efficiency",
+                "Pair 0 Trigger Efficiency", "Pair 1 Logic Efficiency", "Pair 1 Trigger Efficiency" };
+        fieldTitle = new JLabel[titleName.length];
+        for(int index = 0; index < titleName.length; index++) {
+            fieldTitle[index] = new JLabel(titleName[index]);
+            fieldTitle[index].setVerticalAlignment(JLabel.CENTER);
+            fieldTitle[index].setHorizontalAlignment(JLabel.RIGHT);
+            fieldTitle[index].setOpaque(true);
+            add(fieldTitle[index]);
+        }
+        
+        // Instantiate the field value labels.
+        fieldValue = new JLabel[titleName.length];
+        for(int index = 0; index < titleName.length; index++) {
+            fieldValue[index] = new JLabel("");
+            fieldValue[index].setVerticalAlignment(JLabel.CENTER);
+            fieldValue[index].setHorizontalAlignment(JLabel.LEFT);
+            fieldValue[index].setOpaque(true);
+            add(fieldValue[index]);
+        }
+        
+        // Get the longest title.
+        int maxWidth = -1;
+        int maxIndex = -1;
+        for(int index = 0; index < titleName.length; index++) {
+            int width = fieldTitle[index].getFontMetrics(fieldTitle[index].getFont()).stringWidth(titleName[index]);
+            if(width > maxWidth) {
+                maxWidth = width;
+                maxIndex = index;
+            }
+        }
+        
+        // Define border edge and spacing variables.
+        String EAST = SpringLayout.EAST;
+        String WEST = SpringLayout.WEST;
+        String NORTH = SpringLayout.NORTH;
+        String SOUTH = SpringLayout.SOUTH;
+        int hinternal =  5;
+        int vinternal = 10;
+        int hexternal =  5;
+        int vexternal =  5;
+        
+        // Position the panel header.
+        layout.putConstraint(EAST,  panelTitle, hexternal, EAST,  this);
+        layout.putConstraint(WEST,  panelTitle, hexternal, WEST,  this);
+        layout.putConstraint(NORTH, panelTitle, vexternal, NORTH, this);
+        
+        // Position the field entries.
+        Component lastComp = panelTitle;
+        for(int index = 0; index < titleName.length; index++) {
+            // For all field titles except the largest, lock the right
+            // edge of the title to match the position of the largest
+            // title's right edge. The largest title is allowed to size
+            // itself to its preferred width.
+            if(index == maxIndex) {
+                layout.putConstraint(NORTH, fieldTitle[index], vinternal, SOUTH, lastComp);
+                layout.putConstraint(WEST,  fieldTitle[index], hexternal, WEST,  this);
+            } else {
+                layout.putConstraint(NORTH, fieldTitle[index], vinternal, SOUTH, lastComp);
+                layout.putConstraint(WEST,  fieldTitle[index], hexternal, WEST,  this);
+                layout.putConstraint(EAST,  fieldTitle[index],         0, EAST,  fieldTitle[maxIndex]);
+            }
+            
+            // Position the field value label to the right of the field
+            // title label. It should use up the remainder of the width
+            // allowed by the component.
+            layout.putConstraint(WEST,  fieldValue[index], hinternal, EAST,  fieldTitle[index]);
+            layout.putConstraint(EAST,  fieldValue[index], hexternal, EAST,  this);
+            layout.putConstraint(NORTH, fieldValue[index], vinternal, SOUTH, lastComp);
+            
+            // Update the "last component" to the current field title
+            // label.
+            lastComp = fieldTitle[index];
+        }
+        
+        // Update the fonts.
+        setFont(getFont());
+    }
+    
+    @Override
+    public void setBackground(Color bg) {
+        // Set the superclass background.
+        super.setBackground(bg);
+        
+        // Set the component backgrounds.
+        if(panelTitle != null) {
+            panelTitle.setBackground(bg);
+            for(int index = 0; index < fieldTitle.length; index++) {
+                fieldTitle[index].setBackground(bg);
+                
+                // If the field value label has a special alert color,
+                // then do not overwrite it.
+                if(!fieldValue[index].getBackground().equals(BG_WARNING)
+                        && !fieldValue[index].getBackground().equals(BG_CRITICAL)) {
+                    fieldValue[index].setBackground(bg);
+                }
+            }
+        }
+    }
+    
+    @Override
+    public void setFont(Font font) {
+        // Set the superclass font.
+        super.setFont(font);
+        
+        // Set the component fonts.
+        if(panelTitle != null) {
+            panelTitle.setFont(font.deriveFont(Font.BOLD, (float) (font.getSize2D() * 1.5)));
+            for(int index = 0; index < fieldTitle.length; index++) {
+                fieldTitle[index].setFont(font.deriveFont(Font.BOLD));
+                fieldValue[index].setFont(font);
+            }
+        }
+    }
+    
+    @Override
+    public void setForeground(Color fg) {
+        // Set the superclass foreground.
+        super.setForeground(fg);
+        
+        // Set the component backgrounds.
+        if(panelTitle != null) {
+            panelTitle.setForeground(fg);
+            for(int index = 0; index < fieldTitle.length; index++) {
+                fieldTitle[index].setForeground(fg);
+                
+                // If the field value label has a special alert color,
+                // then do not overwrite it.
+                if(!fieldValue[index].getForeground().equals(FONT_WARNING)
+                        && !fieldValue[index].getForeground().equals(FONT_CRITICAL)) {
+                    fieldValue[index].setBackground(fg);
+                }
+            }
+        }
+    }
+    
+    /**
+     * Updates the panel statistical display with data from the
+     * argument snapshot.
+     * @param stat - The snapshot from which to derive statistical
+     *               data.
+     */
+    public void updatePanel(DiagnosticSnapshot stat) {
+        // If the snapshot is null, insert "null" values in the
+        // field panels,
+        if(stat == null) {
+            // Populate the fields with a "null" entry.
+            for(int index = 0; index < fieldValue.length; index++) {
+                fieldValue[index].setText("--- / --- (  N/A  %)");
+            }
+            
+            // No data exists, so no further processing is needed.
+            return;
+        }
+        
+        // Define index constants.
+        int RECON = 0;
+        int SSP = 1;
+        int TRIGGER_0 = 0;
+        int TRIGGER_1 = 1;
+        
+        // Get the tracked values from the snapshot.
+        int seenClusters = stat.getClusterStats().getReconClusterCount();
+        int[][] seenSinglesTriggers = {
+            { stat.getSingles0Stats().getReconSimulatedTriggers(), stat.getSingles1Stats().getReconSimulatedTriggers() },
+            { stat.getSingles0Stats().getSSPSimulatedTriggers(), stat.getSingles1Stats().getSSPSimulatedTriggers() }
+        };
+        int[][] seenPairTriggers = {
                         { stat.getPair0Stats().getReconSimulatedTriggers(), stat.getPair1Stats().getReconSimulatedTriggers() },
                         { stat.getPair0Stats().getSSPSimulatedTriggers(), stat.getPair1Stats().getSSPSimulatedTriggers() }
-		};
-		int matchedClusters = stat.getClusterStats().getMatches();
-		int[][] matchedSinglesTriggers = {
+        };
+        int matchedClusters = stat.getClusterStats().getMatches();
+        int[][] matchedSinglesTriggers = {
                         { stat.getSingles0Stats().getMatchedReconSimulatedTriggers(), stat.getSingles1Stats().getMatchedReconSimulatedTriggers() },
                         { stat.getSingles0Stats().getMatchedSSPSimulatedTriggers(), stat.getSingles1Stats().getMatchedSSPSimulatedTriggers() }
-		};
-		int[][] matchedPairTriggers = {
+        };
+        int[][] matchedPairTriggers = {
                         { stat.getPair0Stats().getMatchedReconSimulatedTriggers(), stat.getPair1Stats().getMatchedReconSimulatedTriggers() },
                         { stat.getPair0Stats().getMatchedSSPSimulatedTriggers(), stat.getPair1Stats().getMatchedSSPSimulatedTriggers() }
-		};
-		
-		// Get the largest digit of the tracked values. This should
-		// always be one of the "seen" values.
-		int mostDigits = ComponentUtils.max(seenClusters, seenSinglesTriggers[0][0], seenSinglesTriggers[0][1],
-				seenSinglesTriggers[1][0], seenSinglesTriggers[1][1], seenPairTriggers[0][0], seenPairTriggers[0][1],
-				seenPairTriggers[1][0], seenPairTriggers[1][1]);
-		int spaces = ComponentUtils.getDigits(mostDigits);
-		
-		// Populate the cluster field panel.
-		processEfficiency(seenClusters, matchedClusters, 0, spaces, 0.98, 0.94);
-		
-		// Populate the singles trigger field panels.
-		processEfficiency(seenSinglesTriggers[RECON][TRIGGER_0], matchedSinglesTriggers[RECON][TRIGGER_0], 1, spaces, 0.99, 0.95);
+        };
+        
+        // Get the largest digit of the tracked values. This should
+        // always be one of the "seen" values.
+        int mostDigits = ComponentUtils.max(seenClusters, seenSinglesTriggers[0][0], seenSinglesTriggers[0][1],
+                seenSinglesTriggers[1][0], seenSinglesTriggers[1][1], seenPairTriggers[0][0], seenPairTriggers[0][1],
+                seenPairTriggers[1][0], seenPairTriggers[1][1]);
+        int spaces = ComponentUtils.getDigits(mostDigits);
+        
+        // Populate the cluster field panel.
+        processEfficiency(seenClusters, matchedClusters, 0, spaces, 0.98, 0.94);
+        
+        // Populate the singles trigger field panels.
+        processEfficiency(seenSinglesTriggers[RECON][TRIGGER_0], matchedSinglesTriggers[RECON][TRIGGER_0], 1, spaces, 0.99, 0.95);
                 processEfficiency(seenSinglesTriggers[SSP][TRIGGER_0],   matchedSinglesTriggers[SSP][TRIGGER_0],   2, spaces, 0.99, 0.95);
                 processEfficiency(seenSinglesTriggers[RECON][TRIGGER_1], matchedSinglesTriggers[RECON][TRIGGER_1], 3, spaces, 0.99, 0.95);
                 processEfficiency(seenSinglesTriggers[SSP][TRIGGER_1],   matchedSinglesTriggers[SSP][TRIGGER_1],   4, spaces, 0.99, 0.95);
-		
-		// Populate the pair trigger field panels.
-		processEfficiency(seenPairTriggers[RECON][TRIGGER_0], matchedPairTriggers[RECON][TRIGGER_0], 5, spaces, 0.99, 0.95);
+        
+        // Populate the pair trigger field panels.
+        processEfficiency(seenPairTriggers[RECON][TRIGGER_0], matchedPairTriggers[RECON][TRIGGER_0], 5, spaces, 0.99, 0.95);
                 processEfficiency(seenPairTriggers[SSP][TRIGGER_0],   matchedPairTriggers[SSP][TRIGGER_0],   6, spaces, 0.99, 0.95);
                 processEfficiency(seenPairTriggers[RECON][TRIGGER_1], matchedPairTriggers[RECON][TRIGGER_1], 7, spaces, 0.99, 0.95);
                 processEfficiency(seenPairTriggers[SSP][TRIGGER_1],   matchedPairTriggers[SSP][TRIGGER_1],   8, spaces, 0.99, 0.95);
-	}
-	
-	/**
-	 * Updates the indicated field value using the indicated number
-	 * seen and matched elements. Automatically handles the special
-	 * case of zero seen elements and also updates the colors of the
-	 * field labels to the appropriate color based on the efficiency
-	 * and the thresholds for warnings.
-	 * @param seen - The number of elements seen.
-	 * @param matched - The number of elements matched.
-	 * @param fieldIndex - The index for the field that should display
-	 *                     the statistical data.
-	 * @param spaces - The number of spaces to giveto each displayed
-	 *                 value.
-	 * @param threshWarning - The threshold at which the "warning
-	 *                        color should be used.
-	 * @param threshCritical - The threshold at which the "critical"
-	 *                         color should be used.
-	 */
-	private void processEfficiency(int seen, int matched, int fieldIndex, int spaces, double threshWarning, double threshCritical) {
-		// Calculate the efficiency.
-		double efficiency = 100.0 * matched / seen;
-		
-		// Create the format string.
-		String format = "%" + spaces + "d / %";
-		
-		// If the number of values seen is zero, there is no
-		// percentage that can be calculated.
-		if(seen == 0) {
-			fieldValue[fieldIndex].setText(String.format(format + " (  N/A  %%)", seen, matched));
-		}
-		
-		// Otherwise, include the percentage.
-		else {
-			fieldValue[fieldIndex].setText(String.format(format + " (7.3f%%)", seen, matched, efficiency));
-		}
-		
-		// If the efficiency is below the critical threshold,
-		// change the field background to the critical color.
-		if(efficiency < threshCritical) {
-			fieldValue[fieldIndex].setBackground(BG_CRITICAL);
-			fieldValue[fieldIndex].setForeground(FONT_CRITICAL);
-		}
-		
-		// Otherwise, if the efficiency is below the warning
-		// level, set the field background to the warning color.
-		else if(efficiency < threshWarning) {
-			fieldValue[fieldIndex].setBackground(BG_WARNING);
-			fieldValue[fieldIndex].setForeground(FONT_WARNING);
-		}
-		
-		// Otherwise, use the default component background.
-		else {
-			fieldValue[fieldIndex].setBackground(getBackground());
-			fieldValue[fieldIndex].setForeground(getForeground());
-		}
-	}
+    }
+    
+    /**
+     * Updates the indicated field value using the indicated number
+     * seen and matched elements. Automatically handles the special
+     * case of zero seen elements and also updates the colors of the
+     * field labels to the appropriate color based on the efficiency
+     * and the thresholds for warnings.
+     * @param seen - The number of elements seen.
+     * @param matched - The number of elements matched.
+     * @param fieldIndex - The index for the field that should display
+     *                     the statistical data.
+     * @param spaces - The number of spaces to giveto each displayed
+     *                 value.
+     * @param threshWarning - The threshold at which the "warning
+     *                        color should be used.
+     * @param threshCritical - The threshold at which the "critical"
+     *                         color should be used.
+     */
+    private void processEfficiency(int seen, int matched, int fieldIndex, int spaces, double threshWarning, double threshCritical) {
+        // Calculate the efficiency.
+        double efficiency = 100.0 * matched / seen;
+        
+        // Create the format string.
+        String format = "%" + spaces + "d / %";
+        
+        // If the number of values seen is zero, there is no
+        // percentage that can be calculated.
+        if(seen == 0) {
+            fieldValue[fieldIndex].setText(String.format(format + " (  N/A  %%)", seen, matched));
+        }
+        
+        // Otherwise, include the percentage.
+        else {
+            fieldValue[fieldIndex].setText(String.format(format + " (7.3f%%)", seen, matched, efficiency));
+        }
+        
+        // If the efficiency is below the critical threshold,
+        // change the field background to the critical color.
+        if(efficiency < threshCritical) {
+            fieldValue[fieldIndex].setBackground(BG_CRITICAL);
+            fieldValue[fieldIndex].setForeground(FONT_CRITICAL);
+        }
+        
+        // Otherwise, if the efficiency is below the warning
+        // level, set the field background to the warning color.
+        else if(efficiency < threshWarning) {
+            fieldValue[fieldIndex].setBackground(BG_WARNING);
+            fieldValue[fieldIndex].setForeground(FONT_WARNING);
+        }
+        
+        // Otherwise, use the default component background.
+        else {
+            fieldValue[fieldIndex].setBackground(getBackground());
+            fieldValue[fieldIndex].setForeground(getForeground());
+        }
+    }
 }

Modified: java/branches/HPSJAVA-409/monitoring-util/src/main/java/org/hps/monitoring/trigger/ShifterTrigWindow.java
 =============================================================================
--- java/branches/HPSJAVA-409/monitoring-util/src/main/java/org/hps/monitoring/trigger/ShifterTrigWindow.java	(original)
+++ java/branches/HPSJAVA-409/monitoring-util/src/main/java/org/hps/monitoring/trigger/ShifterTrigWindow.java	Wed Apr 27 11:11:32 2016
@@ -12,25 +12,25 @@
  * to either yellow or red if the efficiencies drop too low.
  */
 public class ShifterTrigWindow extends JPanel implements DiagnosticUpdatable {
-	private static final long serialVersionUID = 1L;
-	private ShifterTrigPanel localPanel = new ShifterTrigPanel("Instantaneous");
-	private ShifterTrigPanel globalPanel = new ShifterTrigPanel("Run-Integrated");
-	
-	/**
-	 * Instantiates a new panel for displaying basic information
-	 * pertaining to trigger diagnostics.
-	 */
-	public ShifterTrigWindow() {
-		setLayout(new GridLayout(1, 2));
-		add(localPanel);
-		add(globalPanel);
-		updatePanel(null, null);
-	}
-	
-	@Override
-	public void updatePanel(DiagnosticSnapshot runSnapshot, DiagnosticSnapshot localSnapshot) {
-		// Update each panel with the appropriate snapshot.
-		localPanel.updatePanel(localSnapshot);
-		globalPanel.updatePanel(runSnapshot);
-	}
+    private static final long serialVersionUID = 1L;
+    private ShifterTrigPanel localPanel = new ShifterTrigPanel("Instantaneous");
+    private ShifterTrigPanel globalPanel = new ShifterTrigPanel("Run-Integrated");
+    
+    /**
+     * Instantiates a new panel for displaying basic information
+     * pertaining to trigger diagnostics.
+     */
+    public ShifterTrigWindow() {
+        setLayout(new GridLayout(1, 2));
+        add(localPanel);
+        add(globalPanel);
+        updatePanel(null, null);
+    }
+    
+    @Override
+    public void updatePanel(DiagnosticSnapshot runSnapshot, DiagnosticSnapshot localSnapshot) {
+        // Update each panel with the appropriate snapshot.
+        localPanel.updatePanel(localSnapshot);
+        globalPanel.updatePanel(runSnapshot);
+    }
 }

Modified: java/branches/HPSJAVA-409/monitoring-util/src/main/java/org/hps/monitoring/trigger/SinglesTablePanel.java
 =============================================================================
--- java/branches/HPSJAVA-409/monitoring-util/src/main/java/org/hps/monitoring/trigger/SinglesTablePanel.java	(original)
+++ java/branches/HPSJAVA-409/monitoring-util/src/main/java/org/hps/monitoring/trigger/SinglesTablePanel.java	Wed Apr 27 11:11:32 2016
@@ -7,14 +7,14 @@
  * @author Kyle McCarty
  */
 public class SinglesTablePanel extends AbstractTriggerTablePanel {
-	// Static variables.
-	private static final long serialVersionUID = 0L;
-	private static final String[] CUT_NAMES = { "    Cluster Energy (Low):",
-		"    Cluster Energy (High):", "    Hit Count:"  };
-	
-	/**
-	 * Instantiates a <code>SinglesTablePanel</code>.
-	 */
-	public SinglesTablePanel() { super(CUT_NAMES, true); }
-	
+    // Static variables.
+    private static final long serialVersionUID = 0L;
+    private static final String[] CUT_NAMES = { "    Cluster Energy (Low):",
+        "    Cluster Energy (High):", "    Hit Count:"  };
+    
+    /**
+     * Instantiates a <code>SinglesTablePanel</code>.
+     */
+    public SinglesTablePanel() { super(CUT_NAMES, true); }
+    
 }

Modified: java/branches/HPSJAVA-409/monitoring-util/src/main/java/org/hps/monitoring/trigger/TableTextModel.java
 =============================================================================
--- java/branches/HPSJAVA-409/monitoring-util/src/main/java/org/hps/monitoring/trigger/TableTextModel.java	(original)
+++ java/branches/HPSJAVA-409/monitoring-util/src/main/java/org/hps/monitoring/trigger/TableTextModel.java	Wed Apr 27 11:11:32 2016
@@ -11,96 +11,96 @@
  * @author Kyle McCarty <[log in to unmask]>
  */
 public class TableTextModel extends AbstractTableModel {
-	// Serial UID.
-	private static final long serialVersionUID = 0L;
-	
-	// Stored values.
-	private final int rows, columns;
-	private final String[][] values;
-	
-	/**
-	 * Instantiates a new <code>TableTextModel</code> with the indicated
-	 * number of rows and columns.
-	 * @param rows - The number of rows.
-	 * @param columns - The number of columns.
-	 */
-	public TableTextModel(int rows, int columns) {
-		// Make sure that the arguments for rows and columns are valid.
-		if(rows < 1) {
-			throw new IllegalArgumentException("TableTextModel must have at least one row.");
-		} else 	if(columns < 1) {
-			throw new IllegalArgumentException("TableTextModel must have at least one column.");
-		}
-		
-		// Define the number of rows and columns.
-		this.rows = rows;
-		this.columns = columns;
-		
-		// Instantiate the data storage array.
-		values = new String[rows][columns];
-	}
-	
-	@Override
-	public int getRowCount() { return rows; }
-	
-	@Override
-	public int getColumnCount() { return columns; }
-	
-	@Override
-	public Object getValueAt(int rowIndex, int columnIndex) {
-		// Ensure that the value is within the allowed range.
-		validateIndex(rowIndex, columnIndex);
-		
-		// Return the value.
-		return values[rowIndex][columnIndex];
-	}
-	
-	@Override
-	public void setValueAt(Object value, int rowIndex, int columnIndex) {
-		// If the object is a string, pass it to the preferred handler.
-		// This can also be performed if the value is null.
-		if(value == null || value instanceof String) {
-			setValueAt((String) value, rowIndex, columnIndex);
-		}
-		
-		// Otherwise, cast the object to a string and use that instead.
-		else { setValueAt(value.toString(), rowIndex, columnIndex); }
-	}
-	
-	/**
-	 * Sets the text for the indicated column and row of the table.
-	 * @param value - The new text.
-	 * @param rowIndex - The row.
-	 * @param columnIndex - The column.
-	 * @throws IndexOutOfBoundsException Occurs if the row and column
-	 * are not a valid member of table model.
-	 */
-	public void setValueAt(String value, int rowIndex, int columnIndex) throws IndexOutOfBoundsException {
-		// Ensure that the value is within the allowed range.
-		validateIndex(rowIndex, columnIndex);
-		
-		// Set the value.
-		values[rowIndex][columnIndex] = value;
-		
-		// Update the table.
-		this.fireTableCellUpdated(rowIndex, columnIndex);
-	}
-	
-	/**
-	 * Checks to make sure that a given row/column pointer refers to
-	 * an extant position in the data array. In the event that the row
-	 * and column values are not valid, an <code>IndexOutOfBounds</code>
-	 * exception is thrown.
-	 * @param rowIndex - The row index.
-	 * @param columnIndex - The column index.
-	 * @throws IndexOutOfBoundsException Occurs if the row and column
-	 * are not a valid member of the data array.
-	 */
-	private void validateIndex(int rowIndex, int columnIndex) throws IndexOutOfBoundsException {
-		if(rowIndex < 0 || rowIndex >= getRowCount()) {
-			throw new IndexOutOfBoundsException(String.format("Row index %d is out of bounds.", rowIndex));
-		} else if(columnIndex < 0 || columnIndex >= getColumnCount()) {
-			throw new IndexOutOfBoundsException(String.format("Column index %d is out of bounds.", columnIndex));
-		}
-	}
+    // Serial UID.
+    private static final long serialVersionUID = 0L;
+    
+    // Stored values.
+    private final int rows, columns;
+    private final String[][] values;
+    
+    /**
+     * Instantiates a new <code>TableTextModel</code> with the indicated
+     * number of rows and columns.
+     * @param rows - The number of rows.
+     * @param columns - The number of columns.
+     */
+    public TableTextModel(int rows, int columns) {
+        // Make sure that the arguments for rows and columns are valid.
+        if(rows < 1) {
+            throw new IllegalArgumentException("TableTextModel must have at least one row.");
+        } else  if(columns < 1) {
+            throw new IllegalArgumentException("TableTextModel must have at least one column.");
+        }
+        
+        // Define the number of rows and columns.
+        this.rows = rows;
+        this.columns = columns;
+        
+        // Instantiate the data storage array.
+        values = new String[rows][columns];
+    }
+    
+    @Override
+    public int getRowCount() { return rows; }
+    
+    @Override
+    public int getColumnCount() { return columns; }
+    
+    @Override
+    public Object getValueAt(int rowIndex, int columnIndex) {
+        // Ensure that the value is within the allowed range.
+        validateIndex(rowIndex, columnIndex);
+        
+        // Return the value.
+        return values[rowIndex][columnIndex];
+    }
+    
+    @Override
+    public void setValueAt(Object value, int rowIndex, int columnIndex) {
+        // If the object is a string, pass it to the preferred handler.
+        // This can also be performed if the value is null.
+        if(value == null || value instanceof String) {
+            setValueAt((String) value, rowIndex, columnIndex);
+        }
+        
+        // Otherwise, cast the object to a string and use that instead.
+        else { setValueAt(value.toString(), rowIndex, columnIndex); }
+    }
+    
+    /**
+     * Sets the text for the indicated column and row of the table.
+     * @param value - The new text.
+     * @param rowIndex - The row.
+     * @param columnIndex - The column.
+     * @throws IndexOutOfBoundsException Occurs if the row and column
+     * are not a valid member of table model.
+     */
+    public void setValueAt(String value, int rowIndex, int columnIndex) throws IndexOutOfBoundsException {
+        // Ensure that the value is within the allowed range.
+        validateIndex(rowIndex, columnIndex);
+        
+        // Set the value.
+        values[rowIndex][columnIndex] = value;
+        
+        // Update the table.
+        this.fireTableCellUpdated(rowIndex, columnIndex);
+    }
+    
+    /**
+     * Checks to make sure that a given row/column pointer refers to
+     * an extant position in the data array. In the event that the row
+     * and column values are not valid, an <code>IndexOutOfBounds</code>
+     * exception is thrown.
+     * @param rowIndex - The row index.
+     * @param columnIndex - The column index.
+     * @throws IndexOutOfBoundsException Occurs if the row and column
+     * are not a valid member of the data array.
+     */
+    private void validateIndex(int rowIndex, int columnIndex) throws IndexOutOfBoundsException {
+        if(rowIndex < 0 || rowIndex >= getRowCount()) {
+            throw new IndexOutOfBoundsException(String.format("Row index %d is out of bounds.", rowIndex));
+        } else if(columnIndex < 0 || columnIndex >= getColumnCount()) {
+            throw new IndexOutOfBoundsException(String.format("Column index %d is out of bounds.", columnIndex));
+        }
+    }
 }

Modified: java/branches/HPSJAVA-409/monitoring-util/src/main/java/org/hps/monitoring/trigger/TriggerDiagnosticGUIDriver.java
 =============================================================================
--- java/branches/HPSJAVA-409/monitoring-util/src/main/java/org/hps/monitoring/trigger/TriggerDiagnosticGUIDriver.java	(original)
+++ java/branches/HPSJAVA-409/monitoring-util/src/main/java/org/hps/monitoring/trigger/TriggerDiagnosticGUIDriver.java	Wed Apr 27 11:11:32 2016
@@ -9,45 +9,45 @@
 import org.lcsim.util.Driver;
 
 public class TriggerDiagnosticGUIDriver extends Driver {
-	private JFrame window = new JFrame();
-	private ClusterTablePanel clusterTable = new ClusterTablePanel();
-	private SinglesTablePanel singlesTable = new SinglesTablePanel();
-	private PairTablePanel pairTable = new PairTablePanel();
-	private EfficiencyTablePanel efficiencyTable = new EfficiencyTablePanel();
-	private String diagnosticCollectionName = "DiagnosticSnapshot";
-	
-	@Override
-	public void startOfData() {
-		window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
-		window.setSize(500, 400);
-		//window.add(clusterTable);
-		//window.add(singlesTable);
-		//window.add(pairTable);
-		window.add(efficiencyTable);
-		window.setVisible(true);
-	}
-	
-	@Override
-	public void process(EventHeader event) {
-		// Updates are only performed if a diagnostic snapshot object
-		// exists. Otherwise, do nothing.
-		if(event.hasCollection(DiagnosticSnapshot.class, diagnosticCollectionName)) {
-			// Get the snapshot collection.
-			List<DiagnosticSnapshot> snapshotList = event.get(DiagnosticSnapshot.class, diagnosticCollectionName);
-			
-			// Get the snapshot. There will only ever be one.
-			DiagnosticSnapshot runSnapshot = snapshotList.get(1);
-			DiagnosticSnapshot localSnapshot = snapshotList.get(0);
-			
-			// Feed it to the table.
-			clusterTable.updatePanel(runSnapshot, localSnapshot);
-			singlesTable.updatePanel(runSnapshot, localSnapshot);
-			pairTable.updatePanel(runSnapshot, localSnapshot);
-			efficiencyTable.updatePanel(runSnapshot, localSnapshot);
-		}
-	}
-	
-	public void setDiagnosticCollectionName(String name) {
-		diagnosticCollectionName = name;
-	}
+    private JFrame window = new JFrame();
+    private ClusterTablePanel clusterTable = new ClusterTablePanel();
+    private SinglesTablePanel singlesTable = new SinglesTablePanel();
+    private PairTablePanel pairTable = new PairTablePanel();
+    private EfficiencyTablePanel efficiencyTable = new EfficiencyTablePanel();
+    private String diagnosticCollectionName = "DiagnosticSnapshot";
+    
+    @Override
+    public void startOfData() {
+        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+        window.setSize(500, 400);
+        //window.add(clusterTable);
+        //window.add(singlesTable);
+        //window.add(pairTable);
+        window.add(efficiencyTable);
+        window.setVisible(true);
+    }
+    
+    @Override
+    public void process(EventHeader event) {
+        // Updates are only performed if a diagnostic snapshot object
+        // exists. Otherwise, do nothing.
+        if(event.hasCollection(DiagnosticSnapshot.class, diagnosticCollectionName)) {
+            // Get the snapshot collection.
+            List<DiagnosticSnapshot> snapshotList = event.get(DiagnosticSnapshot.class, diagnosticCollectionName);
+            
+            // Get the snapshot. There will only ever be one.
+            DiagnosticSnapshot runSnapshot = snapshotList.get(1);
+            DiagnosticSnapshot localSnapshot = snapshotList.get(0);
+            
+            // Feed it to the table.
+            clusterTable.updatePanel(runSnapshot, localSnapshot);
+            singlesTable.updatePanel(runSnapshot, localSnapshot);
+            pairTable.updatePanel(runSnapshot, localSnapshot);
+            efficiencyTable.updatePanel(runSnapshot, localSnapshot);
+        }
+    }
+    
+    public void setDiagnosticCollectionName(String name) {
+        diagnosticCollectionName = name;
+    }
 }

Modified: java/branches/HPSJAVA-409/parent/pom.xml
 =============================================================================
--- java/branches/HPSJAVA-409/parent/pom.xml	(original)
+++ java/branches/HPSJAVA-409/parent/pom.xml	Wed Apr 27 11:11:32 2016
@@ -6,13 +6,14 @@
     <groupId>org.hps</groupId>
     <artifactId>hps-parent</artifactId>
     <packaging>pom</packaging>
-    <version>3.4.2-SNAPSHOT</version>
+    <version>3.9-SNAPSHOT</version>
     <name>parent</name>
     <description>HPS Java parent POM</description>
     <properties>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
         <org.lcsim.cacheDir>${user.home}</org.lcsim.cacheDir>
-        <lcsimVersion>3.1.6-SNAPSHOT</lcsimVersion>
+        <lcsimVersion>3.6</lcsimVersion>
         <skipSite>false</skipSite>
         <skipPlugin>false</skipPlugin>
     </properties>
@@ -35,17 +36,22 @@
         </repository>
         <repository>
             <id>freehep-repo-public</id>
-            <name>FreeHEP Maven Public</name>
+            <name>FreeHEP</name>
             <url>http://srs.slac.stanford.edu/nexus/content/groups/freehep-maven2-public/</url>
         </repository>
         <repository>
+            <id>srs-repo-public</id>
+            <name>SRS</name>
+            <url>http://srs.slac.stanford.edu/nexus/content/groups/srs-maven2-public/</url>
+        </repository>
+        <repository>
             <id>lcsim-repo-public</id>
-            <name>LCSIM Public Maven Repository</name>
+            <name>LCSim</name>
             <url>http://srs.slac.stanford.edu/nexus/content/groups/lcsim-maven2-public/</url>
         </repository>
         <repository>
             <id>jlab-coda-repo-public</id>
-            <name>JLAB CODA Maven Repository</name>
+            <name>CODA</name>
             <url>https://coda.jlab.org/maven/</url>
         </repository>
     </repositories>
@@ -59,14 +65,14 @@
     <distributionManagement>
         <repository>
             <id>lcsim-repo-releases</id>
-            <name>LCSIM Releases maven repository</name>
-            <!--<url>http://srs.slac.stanford.edu/nexus/content/repositories/lcsim-maven2-releases/</url>-->
+            <name>LCSim Releases</name>
+            <!--<url>http://srs.slac.stanford.edu/nexus/content/repositories/lcsim-maven2-releases/</url> -->
             <url>http://scalnx-v01.slac.stanford.edu:8180/nexus/content/repositories/lcsim-maven2-releases/</url>
         </repository>
         <snapshotRepository>
             <id>lcsim-repo-snapshots</id>
-            <name>LCSIM Snapshots maven repository</name>
-            <!--<url>http://srs.slac.stanford.edu/nexus/content/repositories/lcsim-maven2-snapshot/</url>-->
+            <name>LCSim Snapshots</name>
+            <!--<url>http://srs.slac.stanford.edu/nexus/content/repositories/lcsim-maven2-snapshot/</url> -->
             <url>http://scalnx-v01.slac.stanford.edu:8180/nexus/content/repositories/lcsim-maven2-snapshot/</url>
         </snapshotRepository>
         <site>
@@ -137,117 +143,112 @@
             <dependency>
                 <groupId>org.hps</groupId>
                 <artifactId>hps-util</artifactId>
-                <version>${project.version}</version>
+                <version>3.9-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.hps</groupId>
                 <artifactId>hps-detector-data</artifactId>
-                <version>${project.version}</version>
+                <version>3.9-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.hps</groupId>
                 <artifactId>hps-detector-model</artifactId>
-                <version>${project.version}</version>
+                <version>3.9-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.hps</groupId>
                 <artifactId>hps-conditions</artifactId>
-                <version>${project.version}</version>
+                <version>3.9-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.hps</groupId>
                 <artifactId>hps-ecal-recon</artifactId>
-                <version>${project.version}</version>
+                <version>3.9-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.hps</groupId>
                 <artifactId>hps-ecal-readout-sim</artifactId>
-                <version>${project.version}</version>
+                <version>3.9-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.hps</groupId>
                 <artifactId>hps-tracking</artifactId>
-                <version>${project.version}</version>
+                <version>3.9-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.hps</groupId>
                 <artifactId>hps-evio</artifactId>
-                <version>${project.version}</version>
+                <version>3.9-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.hps</groupId>
                 <artifactId>hps-recon</artifactId>
-                <version>${project.version}</version>
+                <version>3.9-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.hps</groupId>
                 <artifactId>hps-analysis</artifactId>
-                <version>${project.version}</version>
+                <version>3.9-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.hps</groupId>
                 <artifactId>hps-monitoring-drivers</artifactId>
-                <version>${project.version}</version>
+                <version>3.9-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.hps</groupId>
                 <artifactId>hps-monitoring-app</artifactId>
-                <version>${project.version}</version>
+                <version>3.9-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.hps</groupId>
                 <artifactId>hps-users</artifactId>
-                <version>${project.version}</version>
+                <version>3.9-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.hps</groupId>
                 <artifactId>hps-steering-files</artifactId>
-                <version>${project.version}</version>
+                <version>3.9-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.hps</groupId>
                 <artifactId>hps-distribution</artifactId>
-                <version>${project.version}</version>
+                <version>3.9-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.hps</groupId>
                 <artifactId>hps-ecal-event-display</artifactId>
-                <version>${project.version}</version>
+                <version>3.9-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.hps</groupId>
                 <artifactId>hps-record-util</artifactId>
-                <version>${project.version}</version>
+                <version>3.9-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.hps</groupId>
                 <artifactId>hps-monitoring-util</artifactId>
-                <version>${project.version}</version>
+                <version>3.9-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.hps</groupId>
                 <artifactId>hps-run-database</artifactId>
-                <version>${project.version}</version>
+                <version>3.9-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.hps</groupId>
                 <artifactId>hps-crawler</artifactId>
-                <version>${project.version}</version>
-            </dependency>
-            <dependency>
-                <groupId>org.hps</groupId>
-                <artifactId>hps-datacat-client</artifactId>
-                <version>${project.version}</version>
+                <version>3.9-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.hps</groupId>
                 <artifactId>hps-job</artifactId>
-                <version>${project.version}</version>
+                <version>3.9-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.hps</groupId>
                 <artifactId>hps-logging</artifactId>
-                <version>${project.version}</version>
+                <version>3.9-SNAPSHOT</version>
             </dependency>
             <!-- Next are external dependencies used in multiple modules. -->
             <dependency>
@@ -278,7 +279,7 @@
             <dependency>
                 <groupId>jfreechart-aida-experimental</groupId>
                 <artifactId>jfreechart-aida-experimental</artifactId>
-                <version>1.8-SNAPSHOT</version>
+                <version>1.8</version>
                 <exclusions>
                     <exclusion>
                         <groupId>jdom</groupId>
@@ -289,6 +290,11 @@
                         <artifactId>commons-math</artifactId>
                     </exclusion>
                 </exclusions>
+            </dependency>
+            <dependency>
+                <groupId>srs</groupId>
+                <artifactId>org-srs-datacat-client</artifactId>
+                <version>0.5-TEST3</version>
             </dependency>
         </dependencies>
     </dependencyManagement>
@@ -336,10 +342,8 @@
                 <artifactId>maven-surefire-report-plugin</artifactId>
                 <version>2.17</version>
             </plugin>
-            <plugin>
-                <groupId>org.kuali.maven.plugins</groupId>
-                <artifactId>graph-maven-plugin</artifactId>
-            </plugin>
+            <!-- <plugin> <groupId>org.kuali.maven.plugins</groupId> <artifactId>graph-maven-plugin</artifactId> 
+                </plugin> -->
         </plugins>
     </reporting>
     <build>
@@ -372,7 +376,8 @@
                     <artifactId>maven-antrun-plugin</artifactId>
                     <version>1.7</version>
                 </plugin>
-                <!-- This fixes the lifecycle not covered by plugin execution error in Eclipse. -->
+                <!-- This fixes the lifecycle not covered by plugin execution 
+                    error in Eclipse. -->
                 <plugin>
                     <groupId>org.eclipse.m2e</groupId>
                     <artifactId>lifecycle-mapping</artifactId>
@@ -399,11 +404,8 @@
                         </lifecycleMappingMetadata>
                     </configuration>
                 </plugin>
-                <plugin>
-                    <groupId>org.kuali.maven.plugins</groupId>
-                    <artifactId>graph-maven-plugin</artifactId>
-                    <version>1.2.3</version>
-                </plugin>
+                <!-- <plugin> <groupId>org.kuali.maven.plugins</groupId> 
+                    <artifactId>graph-maven-plugin</artifactId> <version>1.2.3</version> </plugin> -->
             </plugins>
         </pluginManagement>
         <plugins>
@@ -423,10 +425,7 @@
                     <target>1.7</target>
                     <showWarnings>true</showWarnings>
                     <showDeprecation>true</showDeprecation>
-                    <!--                    
-                    <staleMillis>1</staleMillis>
-                    <useIncrementalCompilation>false</useIncrementalCompilation>
-                    -->
+                    <!-- <staleMillis>1</staleMillis> <useIncrementalCompilation>false</useIncrementalCompilation> -->
                 </configuration>
             </plugin>
             <plugin>
@@ -436,7 +435,7 @@
                 <configuration>
                     <argLine>-Xmx1024m</argLine>
                     <forkMode>pertest</forkMode>
-                    <systemPropertyVariables>                    
+                    <systemPropertyVariables>
                         <org.lcsim.cacheDir>${org.lcsim.cacheDir}</org.lcsim.cacheDir>
                         <java.util.logging.config.class>org.hps.logging.config.TestLoggingConfig</java.util.logging.config.class>
                     </systemPropertyVariables>
@@ -476,7 +475,44 @@
             <plugin>
                 <artifactId>maven-resources-plugin</artifactId>
                 <version>2.7</version>
-            </plugin>            
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-checkstyle-plugin</artifactId>
+                <version>2.17</version>
+                <configuration>
+                    <excludes>org/hps/users/**/*</excludes>
+                    <logViolationsToConsole>true</logViolationsToConsole>
+                    <consoleOutput>true</consoleOutput>
+                    <includeResources>true</includeResources>
+                    <includeTestResources>true</includeTestResources>
+                    <checkstyleRules>
+                        <module name="Checker">
+                            <module name="FileTabCharacter">
+                                <property name="fileExtensions" value="java,xml,lcsim,prop,properties" />
+                            </module>
+                            <module name="TreeWalker">
+                                <module name="UnusedImports">
+                                    <property name="processJavadoc" value="false" />
+                                </module>
+                                <module name="RedundantImport" />
+                                <!--                                
+                                <module name="EmptyBlock" />
+                                <module name="EmptyStatement" />
+                                -->
+                            </module>
+                        </module>
+                    </checkstyleRules>
+                </configuration>
+                <executions>
+                    <execution>
+                        <phase>compile</phase>
+                        <goals>
+                            <goal>check</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
         </plugins>
     </build>
     <developers>
@@ -490,9 +526,6 @@
                 <role>release manager</role>
             </roles>
             <timezone>-8</timezone>
-            <properties>
-                <aim>jeremyslac</aim>
-            </properties>
         </developer>
         <developer>
             <name>Norman Graf</name>
@@ -503,9 +536,6 @@
                 <role>developer</role>
             </roles>
             <timezone>-8</timezone>
-            <properties>
-                <aim>ngraf137</aim>
-            </properties>
         </developer>
         <developer>
             <name>Maurik Holtrop</name>
@@ -556,7 +586,7 @@
             </roles>
             <timezone>-8</timezone>
         </developer>
-	<developer>
+        <developer>
             <name>Holly Szumila-Vance</name>
             <email>[log in to unmask]</email>
             <organization>Old Dominion University</organization>

Modified: java/branches/HPSJAVA-409/plugin/pom.xml
 =============================================================================
--- java/branches/HPSJAVA-409/plugin/pom.xml	(original)
+++ java/branches/HPSJAVA-409/plugin/pom.xml	Wed Apr 27 11:11:32 2016
@@ -7,7 +7,7 @@
         <groupId>org.hps</groupId>
         <artifactId>hps-parent</artifactId>
         <relativePath>../parent/pom.xml</relativePath>
-        <version>3.4.2-SNAPSHOT</version>
+        <version>3.9-SNAPSHOT</version>
     </parent>
     <scm>
         <url>http://java.freehep.org/svn/repos/hps/list/java/trunk/plugin/</url>

Modified: java/branches/HPSJAVA-409/pom.xml
 =============================================================================
--- java/branches/HPSJAVA-409/pom.xml	(original)
+++ java/branches/HPSJAVA-409/pom.xml	Wed Apr 27 11:11:32 2016
@@ -1,5 +1,4 @@
-<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">
+<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-modules</artifactId>
     <packaging>pom</packaging>
@@ -10,7 +9,7 @@
         <groupId>org.hps</groupId>
         <artifactId>hps-parent</artifactId>
         <relativePath>parent/pom.xml</relativePath>
-        <version>3.4.2-SNAPSHOT</version>
+        <version>3.9-SNAPSHOT</version>
     </parent>
     <scm>
         <url>svn://svn.freehep.org/hps/java/trunk/</url>
@@ -108,7 +107,6 @@
         <module>analysis</module>
         <module>conditions</module>
         <module>crawler</module>
-        <module>datacat-client</module>
         <module>detector-data</module>
         <module>detector-model</module>
         <module>distribution</module>

Modified: java/branches/HPSJAVA-409/recon/pom.xml
 =============================================================================
--- java/branches/HPSJAVA-409/recon/pom.xml	(original)
+++ java/branches/HPSJAVA-409/recon/pom.xml	Wed Apr 27 11:11:32 2016
@@ -8,7 +8,7 @@
         <groupId>org.hps</groupId>
         <artifactId>hps-parent</artifactId>
         <relativePath>../parent/pom.xml</relativePath>
-        <version>3.4.2-SNAPSHOT</version>
+        <version>3.9-SNAPSHOT</version>
     </parent>
     <scm>
         <url>http://java.freehep.org/svn/repos/hps/list/java/trunk/recon/</url>

Modified: java/branches/HPSJAVA-409/recon/src/main/java/org/hps/recon/filtering/EcalGainCalibFilter.java
 =============================================================================
--- java/branches/HPSJAVA-409/recon/src/main/java/org/hps/recon/filtering/EcalGainCalibFilter.java	(original)
+++ java/branches/HPSJAVA-409/recon/src/main/java/org/hps/recon/filtering/EcalGainCalibFilter.java	Wed Apr 27 11:11:32 2016
@@ -7,11 +7,11 @@
 
 public class EcalGainCalibFilter extends EventReconFilter {
 
-	private double feeCut = 0.6;
-	private double molCut = 0.6;
-	private double tMin = 16.0;
-	private double tMax = 80.0;
-	private double dtMax = 12.0;
+    private double feeCut = 0.6;
+    private double molCut = 0.6;
+    private double tMin = 16.0;
+    private double tMax = 80.0;
+    private double dtMax = 12.0;
     private String clusterCollectionName = "EcalClusters";
 
     public void setFeeCut(double feeCut) { this.feeCut = feeCut; }
@@ -27,32 +27,32 @@
     @Override
     public void process(EventHeader event) 
     {
-    	incrementEventProcessed();
+        incrementEventProcessed();
         if (!event.hasCollection(Cluster.class, clusterCollectionName)) skipEvent();
         List<Cluster> cc = event.get(Cluster.class, clusterCollectionName);
         if (cc.size() < 1) skipEvent();
         boolean keepEvent = false;
         for (Cluster c1 : cc) 
         {
-        	final double t1 = ClusterUtilities.getSeedHitTime(c1);
-        	if (t1<tMin || t1>tMax) continue;
-        	if (c1.getEnergy() > feeCut)
-        	{
-        		keepEvent = true;
-        		break;
-        	}
-        	for (Cluster c2 : cc)
-        	{
-        		final double t2 = ClusterUtilities.getSeedHitTime(c2);
-        		if (c1 == c2) continue;
-        		if (t2<tMin || t2>tMax) continue;
-        		if (Math.abs(t1-t2) > dtMax) continue;
-        		if (c1.getEnergy() + c2.getEnergy() > molCut)
-        		{
-        			keepEvent = true;
-        			break;
-        		}
-        	}
+            final double t1 = ClusterUtilities.getSeedHitTime(c1);
+            if (t1<tMin || t1>tMax) continue;
+            if (c1.getEnergy() > feeCut)
+            {
+                keepEvent = true;
+                break;
+            }
+            for (Cluster c2 : cc)
+            {
+                final double t2 = ClusterUtilities.getSeedHitTime(c2);
+                if (c1 == c2) continue;
+                if (t2<tMin || t2>tMax) continue;
+                if (Math.abs(t1-t2) > dtMax) continue;
+                if (c1.getEnergy() + c2.getEnergy() > molCut)
+                {
+                    keepEvent = true;
+                    break;
+                }
+            }
         }
         if (!keepEvent) skipEvent();
         incrementEventPassed();

Modified: java/branches/HPSJAVA-409/recon/src/main/java/org/hps/recon/filtering/EcalPairsFilter.java
 =============================================================================
--- java/branches/HPSJAVA-409/recon/src/main/java/org/hps/recon/filtering/EcalPairsFilter.java	(original)
+++ java/branches/HPSJAVA-409/recon/src/main/java/org/hps/recon/filtering/EcalPairsFilter.java	Wed Apr 27 11:11:32 2016
@@ -18,6 +18,7 @@
 
     private String clusterCollectionName = "EcalClusters";
     private double maxDt = 2.5;
+    private boolean strictPairs = false;
 
     public void setClusterCollectionName(String clusterCollectionName) {
         this.clusterCollectionName = clusterCollectionName;
@@ -27,12 +28,19 @@
         this.maxDt = maxDt;
     }
 
+    public void setStrictPairs(boolean strictPairs) {
+        this.strictPairs = strictPairs;
+    }
+
     @Override
     public void process(EventHeader event) {
         incrementEventProcessed();
         if (event.hasCollection(Cluster.class, clusterCollectionName)) {
             List<Cluster> clusters = event.get(Cluster.class, clusterCollectionName);
             if (clusters.size() < 2) {
+                skipEvent();
+            }
+            if (strictPairs && clusters.size() > 2) {
                 skipEvent();
             }
             List<Double> clusterTimes = new ArrayList<Double>();
@@ -52,7 +60,7 @@
                 skipEvent();
             }
         } else {
-                skipEvent();
+            skipEvent();
         }
         incrementEventPassed();
     }

Modified: java/branches/HPSJAVA-409/recon/src/main/java/org/hps/recon/filtering/FEEFilterDriver.java
 =============================================================================
--- java/branches/HPSJAVA-409/recon/src/main/java/org/hps/recon/filtering/FEEFilterDriver.java	(original)
+++ java/branches/HPSJAVA-409/recon/src/main/java/org/hps/recon/filtering/FEEFilterDriver.java	Wed Apr 27 11:11:32 2016
@@ -1,16 +1,38 @@
 package org.hps.recon.filtering;
 
+import org.lcsim.event.Cluster;
+import org.hps.recon.ecal.cluster.ClusterUtilities;
+import org.hps.record.epics.EpicsData;
 import org.hps.record.triggerbank.AbstractIntData;
 import org.hps.record.triggerbank.TIData;
+import org.lcsim.event.EventHeader;
 import org.lcsim.event.GenericObject;
-
-import org.lcsim.event.Cluster;
-import org.lcsim.event.EventHeader;
 import org.lcsim.util.Driver;
-import org.hps.recon.ecal.cluster.ClusterUtilities;
-import org.hps.record.epics.EpicsData;
 public class FEEFilterDriver extends Driver
 {
+    //Set min seed energy value, default to 2015 run
+    private double seedCut = 0.4;
+    
+    //set min cluster energy value, default to 2015 run
+    private double clusterCut = 0.6;
+    
+    /**
+     * Set the cut value for seed energy in GeV
+     * @param seedCut
+     */
+    public void setSeedCut(double seedCut) {
+        this.seedCut = seedCut;
+    }
+    
+    /**
+     * Set the cut value for cluster energy in GeV
+     * @param clusterCut
+     */
+    public void setClusterCut(double clusterCut) {
+        this.clusterCut = clusterCut;
+    }
+    
+    
   public void process(EventHeader event) {
 
     // don't drop any events with EPICS data:
@@ -44,9 +66,10 @@
       //    ClusterUtilities.findSeedHit(cc).getRawEnergy() < 0.4)
       //  cc.Delete();
 
-      // keep events with a cluster over 600 MeV with seed over 400 MeV:
-      if (cc.getEnergy() > 0.6 && 
-          ClusterUtilities.findSeedHit(cc).getCorrectedEnergy() > 0.4)
+      // keep events with a cluster over 600 MeV with seed over 400 MeV (for 2015 running).
+        // keep events with cluster over 1.2 GeV and seed over 650 MeV for 2016 running.
+      if (cc.getEnergy() > clusterCut && 
+          ClusterUtilities.findSeedHit(cc).getCorrectedEnergy() > seedCut )
         return;
     }
 

Modified: java/branches/HPSJAVA-409/recon/src/main/java/org/hps/recon/filtering/MinimumHitsFilter.java
 =============================================================================
--- java/branches/HPSJAVA-409/recon/src/main/java/org/hps/recon/filtering/MinimumHitsFilter.java	(original)
+++ java/branches/HPSJAVA-409/recon/src/main/java/org/hps/recon/filtering/MinimumHitsFilter.java	Wed Apr 27 11:11:32 2016
@@ -61,7 +61,7 @@
 
 
     private boolean isHitOnTop(RawTrackerHit hit){
-    	HpsSiSensor sensor=(HpsSiSensor) hit.getDetectorElement();
+        HpsSiSensor sensor=(HpsSiSensor) hit.getDetectorElement();
         IIdentifier id=hit.getIdentifier();
         SiTrackerIdentifierHelper _sid_helper=(SiTrackerIdentifierHelper) sensor.getIdentifierHelper();
 

Modified: java/branches/HPSJAVA-409/recon/src/main/java/org/hps/recon/filtering/PulserScalerAndEpicsFilter.java
 =============================================================================
--- java/branches/HPSJAVA-409/recon/src/main/java/org/hps/recon/filtering/PulserScalerAndEpicsFilter.java	(original)
+++ java/branches/HPSJAVA-409/recon/src/main/java/org/hps/recon/filtering/PulserScalerAndEpicsFilter.java	Wed Apr 27 11:11:32 2016
@@ -7,101 +7,97 @@
 import java.io.File;
 import java.io.IOException;
 
-import org.lcsim.event.Cluster;
+import org.hps.conditions.ConditionsDriver;
+import org.hps.record.epics.EpicsData;
+import org.hps.record.triggerbank.AbstractIntData;
+import org.hps.record.triggerbank.TIData;
 import org.lcsim.event.EventHeader;
 import org.lcsim.event.GenericObject;
 import org.lcsim.lcio.LCIOReader;
 import org.lcsim.lcio.LCIOWriter;
 import org.lcsim.util.Driver;
-import org.hps.conditions.ConditionsDriver;
-import org.hps.recon.ecal.cluster.ClusterUtilities;
 //import org.hps.recon.ecal.triggerbank.AbstractIntData;
 //import org.hps.recon.ecal.triggerbank.TIData;
 
-import org.hps.record.triggerbank.AbstractIntData;
-import org.hps.record.triggerbank.TIData;
-import org.hps.record.epics.EpicsData;
-import org.hps.record.scalers.ScalerData;
-
 public class PulserScalerAndEpicsFilter extends Driver{
 
-	public void process(EventHeader event) {
+    public void process(EventHeader event) {
 
-		// only keep pulser triggers:
-		if (!event.hasCollection(GenericObject.class,"TriggerBank"))
-			throw new Driver.NextEventException();
-		boolean isPulser=false;
-		for (GenericObject gob : event.get(GenericObject.class,"TriggerBank"))
-		{
-			if (!(AbstractIntData.getTag(gob) == TIData.BANK_TAG)) continue;
-			TIData tid = new TIData(gob);
-			if (tid.isPulserTrigger())
-			{
-				isPulser=true;
-				break;
-			}
-		}
+        // only keep pulser triggers:
+        if (!event.hasCollection(GenericObject.class,"TriggerBank"))
+            throw new Driver.NextEventException();
+        boolean isPulser=false;
+        for (GenericObject gob : event.get(GenericObject.class,"TriggerBank"))
+        {
+            if (!(AbstractIntData.getTag(gob) == TIData.BANK_TAG)) continue;
+            TIData tid = new TIData(gob);
+            if (tid.isPulserTrigger())
+            {
+                isPulser=true;
+                break;
+            }
+        }
 
-		// don't drop any events with EPICS data or scalers data
-		// (could also do this via event tag=31)
-		final EpicsData edata = EpicsData.read(event);
-		if (edata != null) return;
-		
-		if( event.hasCollection(GenericObject.class, "ScalerData"))
-			return;
+        // don't drop any events with EPICS data or scalers data
+        // (could also do this via event tag=31)
+        final EpicsData edata = EpicsData.read(event);
+        if (edata != null) return;
+        
+        if( event.hasCollection(GenericObject.class, "ScalerData"))
+            return;
 
-		if (!isPulser) throw new Driver.NextEventException();
+        if (!isPulser) throw new Driver.NextEventException();
 
 
-	}
-	/**
-	 * standalone way to run this:
-	 * 
-	 * @param arg [0] inputFile [1] outputFile [2] run number [3] detectorName (optional, default = "HPS-EngRun2015-Nominal-v1") 
-	 * @throws IOException
-	 */
-	public static void main(String arg[]) throws IOException{
-		ConditionsDriver hack = new ConditionsDriver();
-		
-		String detectorName = "HPS-EngRun2015-Nominal-v1";
-		if(arg.length >3)
-		hack.setDetectorName(arg[3]);
-		hack.setFreeze(true);
-		hack.setRunNumber(Integer.parseInt(arg[2]));
-		hack.initialize();
-		PulserScalerAndEpicsFilter pf = new PulserScalerAndEpicsFilter();
-		LCIOWriter writer = new LCIOWriter(arg[1]);
-		File file = new File(arg[0]);
-		LCIOReader reader = new LCIOReader(file);
-		System.out.println(file.getPath());
-		int nEventsKept = 0;
-		int nEvents = 0;
-		try{
-			while(true){
-				try{
-					
-					EventHeader eh = reader.read();
-					if(eh.getEventNumber() %1000 == 0){
-						//Driver.this.
-						System.out.println("PulserFitter:");
-						System.out.println("    " + nEventsKept + " events kept");
-						System.out.println("    " + nEvents + "events read");
-					}
-					nEvents ++;
-					pf.process(eh); //might throw NextEventException
-					
-					nEventsKept++;
-					writer.write(eh);
-				}catch(Driver.NextEventException e){
+    }
+    /**
+     * standalone way to run this:
+     * 
+     * @param arg [0] inputFile [1] outputFile [2] run number [3] detectorName (optional, default = "HPS-EngRun2015-Nominal-v1") 
+     * @throws IOException
+     */
+    public static void main(String arg[]) throws IOException{
+        ConditionsDriver hack = new ConditionsDriver();
+        
+        String detectorName = "HPS-EngRun2015-Nominal-v1";
+        if(arg.length >3)
+        hack.setDetectorName(arg[3]);
+        hack.setFreeze(true);
+        hack.setRunNumber(Integer.parseInt(arg[2]));
+        hack.initialize();
+        PulserScalerAndEpicsFilter pf = new PulserScalerAndEpicsFilter();
+        LCIOWriter writer = new LCIOWriter(arg[1]);
+        File file = new File(arg[0]);
+        LCIOReader reader = new LCIOReader(file);
+        System.out.println(file.getPath());
+        int nEventsKept = 0;
+        int nEvents = 0;
+        try{
+            while(true){
+                try{
+                    
+                    EventHeader eh = reader.read();
+                    if(eh.getEventNumber() %1000 == 0){
+                        //Driver.this.
+                        System.out.println("PulserFitter:");
+                        System.out.println("    " + nEventsKept + " events kept");
+                        System.out.println("    " + nEvents + "events read");
+                    }
+                    nEvents ++;
+                    pf.process(eh); //might throw NextEventException
+                    
+                    nEventsKept++;
+                    writer.write(eh);
+                }catch(Driver.NextEventException e){
 
-				}
-			}
-		}catch(IOException e){
-			e.printStackTrace();
-			reader.close();
-		}
+                }
+            }
+        }catch(IOException e){
+            e.printStackTrace();
+            reader.close();
+        }
 
 
-		writer.close();
-	}
+        writer.close();
+    }
 }

Modified: java/branches/HPSJAVA-409/recon/src/main/java/org/hps/recon/filtering/V0CandidateFilter.java
 =============================================================================
--- java/branches/HPSJAVA-409/recon/src/main/java/org/hps/recon/filtering/V0CandidateFilter.java	(original)
+++ java/branches/HPSJAVA-409/recon/src/main/java/org/hps/recon/filtering/V0CandidateFilter.java	Wed Apr 27 11:11:32 2016
@@ -4,15 +4,22 @@
 import java.util.List;
 import org.hps.recon.ecal.cluster.ClusterUtilities;
 import org.hps.recon.particle.ReconParticleDriver;
+import org.hps.recon.tracking.TrackData;
+import org.hps.recon.tracking.TrackType;
 import org.hps.record.epics.EpicsData;
+import org.hps.record.scalers.ScalerData;
 import org.lcsim.event.EventHeader;
 import org.lcsim.event.ReconstructedParticle;
 
 /**
  * Class to strip off trident candidates. Currently defined as: e+ e- events
- * with tracks. If the tight constraint is enabled, tracks must be matched to
- * clusters and the Ecal cluster times must be within _timingCut [2.5ns] of each
- * other.
+ * with tracks; track and vertex chi2 must be better than values defined by
+ * cuts, and track times must be within trackDtCut of each other. If the tight
+ * constraint is enabled, tracks must be matched to clusters, the Ecal cluster
+ * times must be within _timingCut [2.5ns] of each other, and there must be
+ * exactly one V0 passing all cuts.
+ *
+ * Only GBL vertices are considered.
  *
  * @author Norman A Graf
  *
@@ -20,8 +27,13 @@
  */
 public class V0CandidateFilter extends EventReconFilter {
 
-    private String _V0CandidateCollectionName = "TargetConstrainedV0Candidates";
+    private String _V0CandidateCollectionName = "UnconstrainedV0Candidates";
     private double _clusterTimingCut = 2.5;
+    private double v0Chi2Cut = 10.0;
+    private double trackChi2Cut = 20.0;
+    private double trackDtCut = 5.0;
+    private double trackPMax = 0.9;
+    private double v0PMax = 1.4;
 
     private boolean _tight = false;
     private boolean _keepEpicsDataEvents = false;
@@ -30,9 +42,15 @@
     protected void process(EventHeader event) {
         incrementEventProcessed();
         if (_keepEpicsDataEvents) {
-            // don't drop any events with EPICS data:
-            final EpicsData data = EpicsData.read(event);
-            if (data != null) {
+            // don't drop any events with EPICS or scaler data:
+            final EpicsData epicsData = EpicsData.read(event);
+            if (epicsData != null) {
+                incrementEventPassed();
+                return;
+            }
+
+            final ScalerData scalerData = ScalerData.read(event);
+            if (scalerData != null) {
                 incrementEventPassed();
                 return;
             }
@@ -41,45 +59,96 @@
             skipEvent();
         }
         List<ReconstructedParticle> V0Candidates = event.get(ReconstructedParticle.class, _V0CandidateCollectionName);
-        if (V0Candidates.isEmpty()) {
-            skipEvent();
-        }
+        int nV0 = 0; //number of good V0
+        for (ReconstructedParticle v0 : V0Candidates) {
+            ReconstructedParticle electron = v0.getParticles().get(ReconParticleDriver.ELECTRON);
+            ReconstructedParticle positron = v0.getParticles().get(ReconParticleDriver.POSITRON);
 
-        // tight requires ONLY ONE real vertex fit 
-        if (_tight) {
-            if (V0Candidates.size() != 2) {
-                skipEvent();
+            if (!TrackType.isGBL(v0.getType())) { //we only care about GBL vertices
+                continue;
             }
-            for (ReconstructedParticle rp : V0Candidates) {
-
-                ReconstructedParticle electron;
-                ReconstructedParticle positron;
-
-                List<ReconstructedParticle> fsParticles = rp.getParticles();
-                if (fsParticles.size() != 2) {
-                    skipEvent();
+            if (v0.getStartVertex().getChi2() > v0Chi2Cut) {
+                continue;
+            }
+            if (electron.getTracks().get(0).getChi2() > trackChi2Cut || positron.getTracks().get(0).getChi2() > trackChi2Cut) {
+                continue;
+            }
+            if (electron.getMomentum().magnitude() > trackPMax || positron.getMomentum().magnitude() > trackPMax) {
+                continue;
+            }
+            if (v0.getMomentum().magnitude() > v0PMax) {
+                continue;
+            }
+            double eleTime = TrackData.getTrackTime(TrackData.getTrackData(event, electron.getTracks().get(0)));
+            double posTime = TrackData.getTrackTime(TrackData.getTrackData(event, positron.getTracks().get(0)));
+            if (Math.abs(eleTime - posTime) > trackDtCut) {
+                continue;
+            }
+            if (_tight) { // tight requires cluster matches and cluster time cut
+                if (electron.getClusters().isEmpty() || positron.getClusters().isEmpty()) {
+                    continue;
                 }
-                // require both electrons to be associated with an ECal cluster
-                electron = fsParticles.get(ReconParticleDriver.ELECTRON);
-                if (electron.getClusters().isEmpty()) {
-                    skipEvent();
-                }
-                positron = fsParticles.get(ReconParticleDriver.POSITRON);
-                if (positron.getClusters().isEmpty()) {
-                    skipEvent();
-                }
-
                 // calorimeter cluster timing cut
                 // first CalorimeterHit in the list is the seed crystal
                 double t1 = ClusterUtilities.getSeedHitTime(electron.getClusters().get(0));
                 double t2 = ClusterUtilities.getSeedHitTime(positron.getClusters().get(0));
 
                 if (abs(t1 - t2) > _clusterTimingCut) {
-                    skipEvent();
+                    continue;
                 }
             }
+            nV0++;
+        }
+        if (nV0 == 0) {
+            skipEvent();
+        }
+        // tight requires ONLY ONE candidate vertex
+        if (_tight && nV0 != 1) {
+            skipEvent();
         }
         incrementEventPassed();
+    }
+
+    /**
+     * Maximum vertex chi2 for a V0 to be counted.
+     *
+     * @param v0Chi2Cut default of 10.0.
+     */
+    public void setV0Chi2Cut(double v0Chi2Cut) {
+        this.v0Chi2Cut = v0Chi2Cut;
+    }
+
+    /**
+     * Maximum track chi2 for a V0 to be counted. A V0 is rejected if either of
+     * the final state tracks has a chi2 exceeding the cut.
+     *
+     * @param trackChi2Cut default of 20.0.
+     */
+    public void setTrackChi2Cut(double trackChi2Cut) {
+        this.trackChi2Cut = trackChi2Cut;
+    }
+
+    /**
+     * Maximum track time different for a V0 to be counted.
+     *
+     * @param trackDtCut units of ns, default of 5.0
+     */
+    public void setTrackDtCut(double trackDtCut) {
+        this.trackDtCut = trackDtCut;
+    }
+
+    /**
+     * Maximum track momentum for a V0 to be counted. A V0 is rejected if either
+     * of the final state tracks has momentum exceeding this cut.
+     *
+     * @param trackPMax units of GeV, default of 0.9
+     */
+    public void setTrackPMax(double trackPMax) {
+        this.trackPMax = trackPMax;
+    }
+
+    public void setV0PMax(double v0PMax) {
+        this.v0PMax = v0PMax;
     }
 
     /**

Modified: java/branches/HPSJAVA-409/recon/src/main/java/org/hps/recon/particle/HpsReconParticleDriver.java
 =============================================================================
--- java/branches/HPSJAVA-409/recon/src/main/java/org/hps/recon/particle/HpsReconParticleDriver.java	(original)
+++ java/branches/HPSJAVA-409/recon/src/main/java/org/hps/recon/particle/HpsReconParticleDriver.java	Wed Apr 27 11:11:32 2016
@@ -242,6 +242,7 @@
         BilliorVertexer vtxFitter = new BilliorVertexer(bField);
         // TODO: The beam size should come from the conditions database.
         vtxFitter.setBeamSize(beamSize);
+        vtxFitter.setDebug(debug);
 
         // Perform the vertexing based on the specified constraint.
         switch (constraint) {
@@ -319,7 +320,7 @@
 
             // Generate a candidate vertex and particle.
             BilliorVertex vtxFit = fitVertex(constraint, firstElectronBTrack, secondElectronBTrack);
-            ReconstructedParticle candidate = this.makeReconstructedParticle(topElectron, botElectron, vtxFit);
+            ReconstructedParticle candidate = makeReconstructedParticle(topElectron, botElectron, vtxFit);
 
             // Add the candidate vertex and particle to the
             // appropriate LCIO collection.
@@ -354,7 +355,7 @@
      * @return Returns a reconstructed particle with properties generated from
      * the child particles and vertex given as an argument.
      */
-    private ReconstructedParticle makeReconstructedParticle(ReconstructedParticle electron, ReconstructedParticle positron, BilliorVertex vtxFit) {
+    public static ReconstructedParticle makeReconstructedParticle(ReconstructedParticle electron, ReconstructedParticle positron, BilliorVertex vtxFit) {
 
         // Create a new reconstructed particle to represent the V0
         // candidate and populate it with the electron and positron.
@@ -396,9 +397,8 @@
         ((BaseReconstructedParticle) candidate).setCharge(particleCharge);
 
         // VERBOSE :: Output the fitted momentum data.
-        printDebug("Fitted momentum in tracking frame: " + fittedMomentum.toString());
-        printDebug("Fitted momentum in detector frame: " + fittedMomentum.toString());
-
+//        printDebug("Fitted momentum in tracking frame: " + fittedMomentum.toString());
+//        printDebug("Fitted momentum in detector frame: " + fittedMomentum.toString());
         // Add the ReconstructedParticle to the vertex.
         vtxFit.setAssociatedParticle(candidate);
 

Modified: java/branches/HPSJAVA-409/recon/src/main/java/org/hps/recon/particle/ReconParticleDriver.java
 =============================================================================
--- java/branches/HPSJAVA-409/recon/src/main/java/org/hps/recon/particle/ReconParticleDriver.java	(original)
+++ java/branches/HPSJAVA-409/recon/src/main/java/org/hps/recon/particle/ReconParticleDriver.java	Wed Apr 27 11:11:32 2016
@@ -7,12 +7,14 @@
 import hep.physics.vec.VecOp;
 
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 
 import org.hps.recon.ecal.cluster.ClusterUtilities;
 import org.hps.recon.tracking.CoordinateTransformations;
+import org.hps.recon.tracking.TrackUtils;
 import org.hps.recon.utils.TrackClusterMatcher;
 import org.lcsim.event.Cluster;
 import org.lcsim.event.EventHeader;
@@ -22,7 +24,9 @@
 import org.lcsim.event.base.BaseCluster;
 import org.lcsim.event.base.BaseReconstructedParticle;
 import org.lcsim.geometry.Detector;
+import org.lcsim.geometry.subdetector.HPSEcal3;
 import org.lcsim.util.Driver;
+
 
 /**
  * Driver framework for generating reconstructed particles and matching clusters
@@ -44,6 +48,11 @@
     public static final int POSITRON = 1;
     public static final int MOLLER_TOP = 0;
     public static final int MOLLER_BOT = 1;
+    
+    // normalized cluster-track distance required for qualifying as a match:
+    private double MAXNSIGMAPOSITIONMATCH=30.0;
+
+    HPSEcal3 ecal;
 
     /**
      * Sets the name of the LCIO collection for beam spot constrained V0
@@ -173,6 +182,17 @@
         this.trackCollectionNames = trackCollectionNames;
     }
 
+    /**
+     * Set the requirement on cluster-track position matching in terms of N-sigma.
+     * 
+     * @param nsigma
+     */
+    public void setNSigmaPositionMatch(double nsigma) {
+        MAXNSIGMAPOSITIONMATCH=nsigma;
+    }
+    
+        
+    
     /**
      * Updates the magnetic field parameters to match the appropriate values for
      * the current detector settings.
@@ -188,6 +208,7 @@
             flipSign = -1;
         }
 
+        ecal = (HPSEcal3) detector.getSubdetector("Ecal");
         matcher.setBFieldMap(detector.getFieldMap());
 
     }
@@ -209,7 +230,7 @@
      * clusters. Clusters will be matched with tracks when this is possible.
      *
      * @param clusters - The list of event clusters.
-     * @param tracks - The list of event tracks.
+     * @param trackCollections - The list of event tracks.
      * @return Returns a <code>List</code> collection containing all of the
      * <code>ReconstructedParticle</code> objects generated from the argument
      * data.
@@ -222,15 +243,19 @@
         // Create a list of unmatched clusters. A cluster should be
         // removed from the list if a matching track is found.
         Set<Cluster> unmatchedClusters = new HashSet<Cluster>(clusters);
-
+        
+        // Create a mapping of matched clusters to corresponding tracks.
+        HashMap<Cluster, Track> clusterToTrack = new HashMap<Cluster,Track>();
+        
         // Loop through all of the track collections and try to match every
         // track to a cluster.  Allow a cluster to be matched to multiple 
         // tracks and use a probability (to be coded later) to determine what 
         // the best match is.
         // TODO: At some point, pull this out to it's own method
         for (List<Track> tracks : trackCollections) {
+       
             for (Track track : tracks) {
-
+                
                 // Create a reconstructed particle to represent the track.
                 ReconstructedParticle particle = new BaseReconstructedParticle();
 
@@ -244,6 +269,9 @@
 
                 // Derive the charge of the particle from the track.
                 ((BaseReconstructedParticle) particle).setCharge(track.getCharge() * flipSign);
+
+                // initialize PID quality to a junk value:
+                ((BaseReconstructedParticle)particle).setGoodnessOfPid(9999);
 
                 // Extrapolate the particle ID from the track. Positively
                 // charged particles are assumed to be positrons and those
@@ -254,33 +282,48 @@
                     ((BaseReconstructedParticle) particle).setParticleIdUsed(new SimpleParticleID(11, 0, 0, 0));
                 }
 
+                // normalized distance of the closest match:
+                double smallestNSigma=Double.MAX_VALUE;
+               
+                // try to find a matching cluster:
                 Cluster matchedCluster = null;
-
-                // Track the best matching cluster for the track.
-                // TODO: This should find the best match not just the first match.
-                clusterLoop:
                 for (Cluster cluster : clusters) {
-                    // Check if the cluster and track are a valid match.
-                    if (matcher.isMatch(cluster, track)) {
-
-                        // Store the matched cluster.
-                        matchedCluster = cluster;
-
-                        // Since a match has been found, the loop can be
-                        // terminated.
-                        break clusterLoop;
+
+                    // normalized distance between this cluster and track:
+                    final double thisNSigma=matcher.getNSigmaPosition(cluster, particle);
+
+                    // ignore if matching quality doesn't make the cut:
+                    if (thisNSigma > MAXNSIGMAPOSITIONMATCH) continue;
+
+                    // ignore if we already found a cluster that's a better match:
+                    if (thisNSigma > smallestNSigma) continue;
+
+                    // we found a new best cluster candidate for this track:
+                    smallestNSigma = thisNSigma;
+                    matchedCluster = cluster;
+
+                    // prefer using GBL tracks to correct (later) the clusters, for some consistency:
+                    if (track.getType() >= 32 || !clusterToTrack.containsKey(matchedCluster)) {
+                          clusterToTrack.put(matchedCluster,track);
                     }
                 }
 
                 // If a cluster was found that matches the track...
                 if (matchedCluster != null) {
+
+                    // add cluster to the particle:
                     particle.addCluster(matchedCluster);
 
-                    int pid = particle.getParticleIDUsed().getPDG();
+                    // use pid quality to store track-cluster matching quality:
+                    ((BaseReconstructedParticle)particle).setGoodnessOfPid(smallestNSigma);
+                    
+                    // propogate pid to the cluster:
+                    final int pid = particle.getParticleIDUsed().getPDG();
                     if (Math.abs(pid) == 11) {
                         ((BaseCluster) matchedCluster).setParticleId(pid);
                     }
 
+                    // unmatched clusters will (later) be used to create photon particles:
                     unmatchedClusters.remove(matchedCluster);
                 }
 
@@ -290,35 +333,40 @@
         }
 
         // Iterate over the remaining unmatched clusters.
-        if (!unmatchedClusters.isEmpty()) {
-            for (Cluster unmatchedCluster : unmatchedClusters) {
-
-                // Create a reconstructed particle to represent the unmatched cluster.
-                ReconstructedParticle particle = new BaseReconstructedParticle();
-
-                // The particle is assumed to be a photon, since it did not leave a track.
-                ((BaseReconstructedParticle) particle).setParticleIdUsed(new SimpleParticleID(22, 0, 0, 0));
-
-                int pid = particle.getParticleIDUsed().getPDG();
-                if (Math.abs(pid) != 11) {
-                    ((BaseCluster) unmatchedCluster).setParticleId(pid);
-                }
-
-                // Add the cluster to the particle.
-                particle.addCluster(unmatchedCluster);
-
-                // Set the reconstructed particle properties based on the cluster properties.
-                ((BaseReconstructedParticle) particle).setCharge(0);
-
-                // Add the particle to the reconstructed particle list.
-                particles.add(particle);
-            }
-        }
-
-        // Apply the corrections to the Ecal clusters
+        for (Cluster unmatchedCluster : unmatchedClusters) {
+
+            // Create a reconstructed particle to represent the unmatched cluster.
+            ReconstructedParticle particle = new BaseReconstructedParticle();
+
+            // The particle is assumed to be a photon, since it did not leave a track.
+            ((BaseReconstructedParticle) particle).setParticleIdUsed(new SimpleParticleID(22, 0, 0, 0));
+
+            int pid = particle.getParticleIDUsed().getPDG();
+            if (Math.abs(pid) != 11) {
+                ((BaseCluster) unmatchedCluster).setParticleId(pid);
+            }
+
+            // Add the cluster to the particle.
+            particle.addCluster(unmatchedCluster);
+
+            // Set the reconstructed particle properties based on the cluster properties.
+            ((BaseReconstructedParticle) particle).setCharge(0);
+
+            // Add the particle to the reconstructed particle list.
+            particles.add(particle);
+        }
+
+        // Apply the corrections to the Ecal clusters using track information, if available
         for (Cluster cluster : clusters) {
             if (cluster.getParticleId() != 0) {
-                ClusterUtilities.applyCorrections(cluster);
+                if (clusterToTrack.containsKey(cluster)){
+                    Track matchedT = clusterToTrack.get(cluster);
+                    double ypos = TrackUtils.getTrackStateAtECal(matchedT).getReferencePoint()[2];
+                    ClusterUtilities.applyCorrections(ecal, cluster, ypos);
+                }
+                else {
+                    ClusterUtilities.applyCorrections(ecal, cluster);               
+                }
             }
         }
 
@@ -525,7 +573,7 @@
     /**
      * Indicates whether debug text should be output or not.
      */
-    private boolean debug = false;
+    protected boolean debug = false;
 
     /**
      * The simple name of the class used for debug print statements.
@@ -622,7 +670,7 @@
     // Beam size variables.
     // The beamsize array is in the tracking frame
     /* TODO  mg-May 14, 2014:  the the beam size from the conditions db...also beam position!  */
-    protected double[] beamSize = {0.001, 0.2, 0.02};
+    protected double[] beamSize = {0.001, 0.130, 0.050}; //rough estimate from harp scans during engineering run production running
     protected double bField;
 
     //  flipSign is a kludge...

Modified: java/branches/HPSJAVA-409/recon/src/main/java/org/hps/recon/particle/SimpleParticleID.java
 =============================================================================
--- java/branches/HPSJAVA-409/recon/src/main/java/org/hps/recon/particle/SimpleParticleID.java	(original)
+++ java/branches/HPSJAVA-409/recon/src/main/java/org/hps/recon/particle/SimpleParticleID.java	Wed Apr 27 11:11:32 2016
@@ -9,67 +9,67 @@
  *
  */
 public class SimpleParticleID implements ParticleID {
-	
-	int algorithmType = 0; 
-	int pdgID = UnknownPDG;
-	int type = 0; 
-	
-	double likelihood = 0.; 
-	// TODO: Need to define what other parameters are needed.
-	double[] parameters = new double[1]; 
+    
+    int algorithmType = 0; 
+    int pdgID = UnknownPDG;
+    int type = 0; 
+    
+    double likelihood = 0.; 
+    // TODO: Need to define what other parameters are needed.
+    double[] parameters = new double[1]; 
 
-	public SimpleParticleID(){}
-	
-	public SimpleParticleID(int pdgID, int algorithmType, int type, double likelihood){
-		this.pdgID = pdgID; 
-		this.algorithmType = algorithmType; 
-		this.type = type; 
-		this.likelihood = likelihood; 
-	}
-	
-	@Override
-	public int getAlgorithmType() {
-		return algorithmType;
-	}
+    public SimpleParticleID(){}
+    
+    public SimpleParticleID(int pdgID, int algorithmType, int type, double likelihood){
+        this.pdgID = pdgID; 
+        this.algorithmType = algorithmType; 
+        this.type = type; 
+        this.likelihood = likelihood; 
+    }
+    
+    @Override
+    public int getAlgorithmType() {
+        return algorithmType;
+    }
 
-	@Override
-	public double getLikelihood() {
-		return likelihood;
-	}
+    @Override
+    public double getLikelihood() {
+        return likelihood;
+    }
 
-	@Override
-	public int getPDG() {
-		return pdgID;
-	}
+    @Override
+    public int getPDG() {
+        return pdgID;
+    }
 
-	@Override
-	public double[] getParameters() {
-		return parameters;
-	}
+    @Override
+    public double[] getParameters() {
+        return parameters;
+    }
 
-	@Override
-	public int getType() {
-		return type;
-	}
-	
-	public void setAlgorithmType(int algorithmType){
-		this.algorithmType = algorithmType;
-	}
-	
-	public void setLikelihood(int likelihood){
-		this.likelihood = likelihood; 
-	}
-	
-	public void setPDG(int pdgID){
-		this.pdgID = pdgID; 
-	}
-	
-	public void setType(int type){
-		this.type = type; 
-	}
-	
-	public void setParameters(double[] parameters){
-		this.parameters = parameters;
-	}
+    @Override
+    public int getType() {
+        return type;
+    }
+    
+    public void setAlgorithmType(int algorithmType){
+        this.algorithmType = algorithmType;
+    }
+    
+    public void setLikelihood(int likelihood){
+        this.likelihood = likelihood; 
+    }
+    
+    public void setPDG(int pdgID){
+        this.pdgID = pdgID; 
+    }
+    
+    public void setType(int type){
+        this.type = type; 
+    }
+    
+    public void setParameters(double[] parameters){
+        this.parameters = parameters;
+    }
 
 }

Modified: java/branches/HPSJAVA-409/recon/src/main/java/org/hps/recon/utils/TrackClusterMatcher.java
 =============================================================================
--- java/branches/HPSJAVA-409/recon/src/main/java/org/hps/recon/utils/TrackClusterMatcher.java	(original)
+++ java/branches/HPSJAVA-409/recon/src/main/java/org/hps/recon/utils/TrackClusterMatcher.java	Wed Apr 27 11:11:32 2016
@@ -1,8 +1,4 @@
 package org.hps.recon.utils;
-
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
 
 import hep.aida.IAnalysisFactory;
 import hep.aida.IHistogram1D;
@@ -13,12 +9,17 @@
 import hep.physics.vec.BasicHep3Vector;
 import hep.physics.vec.Hep3Vector;
 
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.hps.recon.tracking.CoordinateTransformations;
+import org.hps.recon.tracking.TrackUtils;
 import org.lcsim.event.Cluster;
+import org.lcsim.event.ReconstructedParticle;
 import org.lcsim.event.Track;
 import org.lcsim.event.TrackState;
 import org.lcsim.geometry.FieldMap;
-import org.hps.recon.tracking.CoordinateTransformations;
-import org.hps.recon.tracking.TrackUtils;
 
 /**
  * Utility used to determine if a track and cluster are matched.
@@ -65,6 +66,53 @@
     private double bottomClusterTrackMatchDeltaYHigh = 24; // mm 
 
     /**
+     * Rafo's parameterization of cluster-seed x/y position residuals as function of energy.
+     * 
+     * Derived using GBL/seed tracks, non-analytic extrapolation, uncorrected cluster positions,
+     * and EngRun2015-Nominal-v4-4-fieldmap detector.
+     * 
+     *  f = p0+e*(p1+e*(p2+e*(p3+e*(p4+e*p5))))
+     */
+    private static final double dxMeanTopPosiGBL[] = { 6.67414,-9.57296, 5.70647, 27.4523,-28.1103,-9.11424 };
+    private static final double dxSigmTopPosiGBL[] = { 52.6437,-478.805, 1896.73,-3761.48, 3676.77,-1408.31 };
+    private static final double dxMeanBotPosiGBL[] = { 4.13802, 15.8887,-74.2844,-9.78944, 308.541,-287.668 };
+    private static final double dxSigmBotPosiGBL[] = { 37.6513,-294.851, 1002.15,-1639.08, 1228.02,-308.754 };
+    
+    private static final double dxMeanTopElecGBL[] = {-1.6473,  5.58701, 25.3977,-17.1523,-121.025, 145.969 };
+    private static final double dxSigmTopElecGBL[] = { 48.7018,-423.599, 1592.66,-2959.99, 2668.97,-919.876 };
+    private static final double dxMeanBotElecGBL[] = {-6.63558, 83.7763,-460.451, 1275.63,-1702.83, 873.913 };
+    private static final double dxSigmBotElecGBL[] = { 47.0029,-411.784, 1586.52,-3083.37, 2985.58,-1145.53 };
+    
+    private static final double dyMeanTopPosiGBL[] = { 0.31245, 5.57585,-6.50267,-8.21688, 39.8607,-43.9661 };
+    private static final double dySigmTopPosiGBL[] = { 33.0213,-275.174, 1168.77,-2642.34, 3045.52,-1406.21 };
+    private static final double dyMeanBotPosiGBL[] = {-7.032,   74.9738,-383.972, 977.849,-1250.28, 637.75  };
+    private static final double dySigmBotPosiGBL[] = { 19.019, -83.9253, 133.813, 119.883,-546.951, 405.207 };
+    
+    private static final double dyMeanTopElecGBL[] = { 2.48498,-20.4101, 62.9689, 25.6386,-259.957, 207.145 };
+    private static final double dySigmTopElecGBL[] = { 8.65583, 120.676,-1166.43, 3811.72,-5383.19, 2787.42 };
+    private static final double dyMeanBotElecGBL[] = {-10.5228, 112.329,-489.761, 953.037,-829.96,  260.772 };
+    private static final double dySigmBotElecGBL[] = { 23.4856,-108.19,  158.7,   189.261,-682.034, 459.15  };
+
+    private static final double dxMeanTopPosiSeed[] ={ 11.6245,-28.5061, 13.0332, 59.9465,-21.1014,-63.6126 };
+    private static final double dxSigmTopPosiSeed[] ={ 61.5911,-540.596, 2077.22,-3973.22, 3704.45,-1332.07 };
+    private static final double dxMeanBotPosiSeed[] ={ 4.53394, 11.3773,-63.7127,-2.81629, 273.868,-264.709 };
+    private static final double dxSigmBotPosiSeed[] ={ 48.3163,-409.249, 1590.36,-3212.85, 3326.04,-1402.3  };
+    
+    private static final double dxMeanTopElecSeed[] ={ 2.14163,-20.8713, 76.3054,  34.894,-340.272,  295.24 };
+    private static final double dxSigmTopElecSeed[] ={ 48.585, -385.166, 1320.26,-2157.45, 1581.06,-366.012 };
+    private static final double dxMeanBotElecSeed[] ={-3.44302, 12.4687, 4.09878,-30.0057,-13.3151, 40.2707 };
+    private static final double dxSigmBotElecSeed[] ={ 48.4089,-385.494, 1341.37,-2271.52, 1814.02,-526.555 };
+
+    private static final double dyMeanTopPosiSeed[] ={-0.527741,10.4944, -18.242,-12.9155, 81.0116,-73.9773 };
+    private static final double dySigmTopPosiSeed[] ={ 37.3097, -357.55, 1607.03,-3709.55, 4282.36,-1957.91 };
+    private static final double dyMeanBotPosiSeed[] ={ 0.74392,-55.2003,  405.04,-1250.64, 1731.47,-887.262 };
+    private static final double dySigmBotPosiSeed[] ={ 25.5776,-199.731,  754.59,-1408.72, 1240.36,-400.912 };
+
+    private static final double dyMeanTopElecSeed[] ={ 2.85429,-24.0858, 69.0145, 34.1213,-297.752, 239.939 };
+    private static final double dySigmTopElecSeed[] ={ 19.9111,-53.2699,-261.915,  1593.2,-2774.01, 1605.54 };
+    private static final double dyMeanBotElecSeed[] ={-9.22963, 98.1346, -427.91, 840.225,-751.188, 250.792 };
+    private static final double dySigmBotElecSeed[] ={ 21.7909,-85.4757,-56.9423, 977.522,-1902.05, 1137.92 };
+    /**
      * Z position to start extrapolation from
      */
     double extStartPos = 700; // mm
@@ -172,6 +220,122 @@
         this.topClusterTrackMatchDeltaYLow = yLow;
         this.topClusterTrackMatchDeltaYHigh = yHigh;
     }
+
+    /**
+     * Get distance between track and cluster.
+     * 
+     * @param cluster
+     * @param track
+     * @return distance between cluster and track
+     */
+    public double getDistance(Cluster cluster,Track track) {
+        
+        // Get the cluster position
+        Hep3Vector cPos = new BasicHep3Vector(cluster.getPosition());
+        
+        // Extrapolate the track to the Ecal cluster position
+        Hep3Vector tPos = null;
+        if (this.useAnalyticExtrapolator) {
+            tPos = TrackUtils.extrapolateTrack(track, cPos.z());
+        } else {
+            TrackState trackStateAtEcal = TrackUtils.getTrackStateAtECal(track);
+            tPos = new BasicHep3Vector(trackStateAtEcal.getReferencePoint());
+            tPos = CoordinateTransformations.transformVectorToDetector(tPos);
+        }
+       
+        return Math.sqrt(Math.pow(cPos.x()-tPos.x(),2)+Math.pow(cPos.y()-tPos.y(),2));
+    }
+    
+    /**
+     * Calculate #sigma between cluster-track x/y position at calorimeter.
+     *
+     * Based on Rafo's parameterizations.  Requires non-analytic extrapolation
+     * and uncorrected cluster positions.
+     * 
+     * @param cluster = position-uncorrected cluster
+     * @param particle recon particle with tracks
+     *
+     * @return #sigma between cluster and track positions
+     */
+    public double getNSigmaPosition(Cluster cluster, ReconstructedParticle particle) {
+
+        if (particle.getTracks().size()<1) return Double.MAX_VALUE;
+          Track track=particle.getTracks().get(0);
+        
+        if (this.useAnalyticExtrapolator)
+            throw new RuntimeException("This is to be used with non-analytic extrapolator only.");
+
+        // Get the cluster position:
+        Hep3Vector cPos = new BasicHep3Vector(cluster.getPosition());
+
+        // whether track is in top half of detector:
+        final boolean isTopTrack = track.getTrackStates().get(0).getTanLambda() > 0;
+
+        // ignore if track and cluster in different halves:
+        if (isTopTrack != cPos.y()>0) return Double.MAX_VALUE;
+
+        // Get the extrapolated track position at the calorimeter:
+        TrackState trackStateAtEcal = TrackUtils.getTrackStateAtECal(track);
+        Hep3Vector tPos = new BasicHep3Vector(trackStateAtEcal.getReferencePoint());
+        tPos = CoordinateTransformations.transformVectorToDetector(tPos);
+
+        // whether it's a GBL track:
+        final boolean isGBL = track.getType() >= 32;
+       
+        // choose which parameterization of mean and sigma to use:
+        double dxMean[],dyMean[],dxSigm[],dySigm[];
+        if (particle.getCharge()>0) {
+            if (isTopTrack) {
+                dxMean = isGBL ? dxMeanTopPosiGBL : dxMeanTopPosiSeed;
+                dxSigm = isGBL ? dxSigmTopPosiGBL : dxSigmTopPosiSeed;
+                dyMean = isGBL ? dyMeanTopPosiGBL : dyMeanTopPosiSeed;
+                dySigm = isGBL ? dySigmTopPosiGBL : dySigmTopPosiSeed;
+            }
+            else {
+                dxMean = isGBL ? dxMeanBotPosiGBL : dxMeanBotPosiSeed;
+                dxSigm = isGBL ? dxSigmBotPosiGBL : dxSigmBotPosiSeed;
+                dyMean = isGBL ? dyMeanBotPosiGBL : dyMeanBotPosiSeed;
+                dySigm = isGBL ? dySigmBotPosiGBL : dySigmBotPosiSeed;
+            }
+        }
+        else if (particle.getCharge()<0) {
+            if (isTopTrack) {
+                dxMean = isGBL ? dxMeanTopElecGBL : dxMeanTopElecSeed;
+                dxSigm = isGBL ? dxSigmTopElecGBL : dxSigmTopElecSeed;
+                dyMean = isGBL ? dyMeanTopElecGBL : dyMeanTopElecSeed;
+                dySigm = isGBL ? dySigmTopElecGBL : dySigmTopElecSeed;
+            }
+            else {
+                dxMean = isGBL ? dxMeanBotElecGBL : dxMeanBotElecSeed;
+                dxSigm = isGBL ? dxSigmBotElecGBL : dxSigmBotElecSeed;
+                dyMean = isGBL ? dyMeanBotElecGBL : dyMeanBotElecSeed;
+                dySigm = isGBL ? dySigmBotElecGBL : dySigmBotElecSeed;
+            }
+        }
+        else return Double.MAX_VALUE;
+
+        // get particle energy:
+        Hep3Vector p3 = new BasicHep3Vector(track.getTrackStates().get(0).getMomentum());
+        p3 = CoordinateTransformations.transformVectorToDetector(p3);
+        double ee = p3.magnitude();
+        
+        // Rafo's parameterization isn't measured above 650 MeV/c but expected to be constant:
+        if (ee > 0.65) ee=0.65;
+
+        // calculate measured mean and sigma of deltaX and deltaY for this energy:
+        double aDxMean=0,aDxSigm=0,aDyMean=0,aDySigm=0;
+        for (int ii=dxMean.length-1; ii>=0; ii--) aDxMean = dxMean[ii] + ee*aDxMean;
+        for (int ii=dxSigm.length-1; ii>=0; ii--) aDxSigm = dxSigm[ii] + ee*aDxSigm;
+        for (int ii=dyMean.length-1; ii>=0; ii--) aDyMean = dyMean[ii] + ee*aDyMean;
+        for (int ii=dySigm.length-1; ii>=0; ii--) aDySigm = dySigm[ii] + ee*aDySigm;
+
+        // calculate nSigma between track and cluster:
+        final double nSigmaX = (cPos.x() - tPos.x() - aDxMean) / aDxSigm;
+        final double nSigmaY = (cPos.y() - tPos.y() - aDyMean) / aDySigm;
+        return Math.sqrt(nSigmaX*nSigmaX + nSigmaY*nSigmaY);
+        //return Math.sqrt( 1 / ( 1/nSigmaX/nSigmaX + 1/nSigmaY/nSigmaY ) );
+    }
+
 
     /**
      * Determine if a track is matched to a cluster. Currently, this is
@@ -363,4 +527,16 @@
             e.printStackTrace();
         }
     }
+
+    /**
+     * Class to store track-cluster matching qualities.
+     */
+    public class TrackClusterMatch {
+        private double nSigmaPositionMatch=Double.MAX_VALUE;
+        public TrackClusterMatch(ReconstructedParticle pp, Cluster cc) {
+            nSigmaPositionMatch = getNSigmaPosition(cc,pp);
+        }
+        public double getNSigmaPositionMatch() { return nSigmaPositionMatch; }
+    }
+    
 }

Modified: java/branches/HPSJAVA-409/recon/src/main/java/org/hps/recon/vertexing/BaseSimpleVertexer.java
 =============================================================================
--- java/branches/HPSJAVA-409/recon/src/main/java/org/hps/recon/vertexing/BaseSimpleVertexer.java	(original)
+++ java/branches/HPSJAVA-409/recon/src/main/java/org/hps/recon/vertexing/BaseSimpleVertexer.java	Wed Apr 27 11:11:32 2016
@@ -12,25 +12,25 @@
 public abstract class BaseSimpleVertexer implements SimpleVertexer {
 
 
-	protected boolean _debug = false;
-	protected Vertex _fitted_vertex = null;
+    protected boolean _debug = false;
+    protected Vertex _fitted_vertex = null;
 
-	public BaseSimpleVertexer() {
-	}
+    public BaseSimpleVertexer() {
+    }
 
-	@Override
-	public abstract void fitVertex();
+    @Override
+    public abstract void fitVertex();
 
-	@Override
-	public Vertex getFittedVertex() {
-		return _fitted_vertex;
-	}
-	
-	public void clear() {
-		_fitted_vertex = null;
-	}
-	
-	public abstract boolean isValid();
-	
+    @Override
+    public Vertex getFittedVertex() {
+        return _fitted_vertex;
+    }
+    
+    public void clear() {
+        _fitted_vertex = null;
+    }
+    
+    public abstract boolean isValid();
+    
 
 }

Modified: java/branches/HPSJAVA-409/recon/src/main/java/org/hps/recon/vertexing/BilliorVertex.java
 =============================================================================
--- java/branches/HPSJAVA-409/recon/src/main/java/org/hps/recon/vertexing/BilliorVertex.java	(original)
+++ java/branches/HPSJAVA-409/recon/src/main/java/org/hps/recon/vertexing/BilliorVertex.java	Wed Apr 27 11:11:32 2016
@@ -14,8 +14,8 @@
 
 /**
  * 
- *	@author Mathew Thomas Graham <[log in to unmask]>
- *	@version $Id:$
+ *  @author Mathew Thomas Graham <[log in to unmask]>
+ *  @version $Id:$
  *
  */
 public class BilliorVertex implements Vertex {
@@ -74,12 +74,12 @@
      * @param particle : The ReconstructedParticle Associated with this Vertex
      */
     public void setAssociatedParticle(ReconstructedParticle particle){
-    	this._particle = particle;
+        this._particle = particle;
     }
 
     @Override
     public boolean isPrimary() {
-    	return _isPrimary; 
+        return _isPrimary; 
     }
 
     @Override
@@ -94,7 +94,7 @@
 
     @Override
     public double getProbability() {
-    	return _probability;
+        return _probability;
     }
 
     @Override
@@ -108,7 +108,7 @@
     }
 
     // TODO: These should be pulled out and accessed by their own 
-    //		 getter methods.  
+    //       getter methods.  
     @Override
     public Map<String, Double> getParameters() {
         Map<String, Double> pars = new HashMap<String, Double>();
@@ -128,6 +128,6 @@
 
     @Override
     public ReconstructedParticle getAssociatedParticle() {
-    	return _particle; 
+        return _particle; 
     }
 }

Modified: java/branches/HPSJAVA-409/recon/src/main/java/org/hps/recon/vertexing/BilliorVertexer.java
 =============================================================================
--- java/branches/HPSJAVA-409/recon/src/main/java/org/hps/recon/vertexing/BilliorVertexer.java	(original)
+++ java/branches/HPSJAVA-409/recon/src/main/java/org/hps/recon/vertexing/BilliorVertexer.java	Wed Apr 27 11:11:32 2016
@@ -16,394 +16,97 @@
 
 /**
  * @version $Id: BilliorVertexer.java,v 1.3 2013/03/13 19:24:20 mgraham Exp $
- * @version Vertex tracks using least-squares method laid out by billior etal used in the HPS Java package.
+ * @version Vertex tracks using least-squares method laid out by billior etal
+ * used in the HPS Java package.
  */
 public class BilliorVertexer {
     // the value of the magnetic field in the vicinity of the vertex
     // default is a constant field along the z axis
 
     private boolean _debug = false;
-    private double _bField;
-    private boolean _beamspotConstraint = true;
-    private boolean _targetConstraint = false;
-    private double[] _beamSize = {0.001, 0.01, 0.01}; //10um in y and z
+    private final double _bField;
+    private boolean _beamspotConstraint;
+    private boolean _targetConstraint;
+    private String _constraintType;
+    private final double[] _beamSize = {0.001, 0.01, 0.01}; //10um in y and z
+    private final double[] _beamPosition = {0.0, 0.0, 0.0}; //origin
     private int _ntracks;
-    private List<Matrix> paramList = new ArrayList<Matrix>();
-    private List<Matrix> WList = new ArrayList<Matrix>();
-    private List<Matrix> DList = new ArrayList<Matrix>();
-    private List<Matrix> EList = new ArrayList<Matrix>();
-    private Matrix A;
-    private Matrix T;
-    private List<Matrix> BList = new ArrayList<Matrix>();
-    private List<Matrix> CinvList = new ArrayList<Matrix>();
-    private List<Matrix> CList = new ArrayList<Matrix>();
-    private List<Matrix> UList = new ArrayList<Matrix>();
-    private List<Matrix> dqList = new ArrayList<Matrix>();
-    private double[] _v0 = {0.0, 0.0, 0.0};
+    private double[] _v0 = {0.0, 0.0, 0.0}; //initial guess for unconstrained vertex fit
 //    private double[] _vertexPosition = {0., 0.0, 0.0};
-    private Matrix _vertexPosition = new BasicMatrix(3, 1);
-    private Matrix _covVtx = new BasicMatrix(3, 3);
-    private List<Matrix> _pFit = new ArrayList<Matrix>();
+    private Matrix _vertexPosition;
+    private Matrix _covVtx;
+    private List<Matrix> _pFit;
 
     ;//theta,phi_v,rho
-    private List<Matrix> covVtxMomList = new ArrayList<Matrix>();
-    private Matrix[][] covMomList = new Matrix[2][2];//max 2 tracks...just make this bigger for more
+    private List<Matrix> covVtxMomList;
+    private Matrix[][] covMomList;//max 2 tracks...just make this bigger for more
     private Matrix _constrainedFit;
     private Matrix _constrainedCov;
     private double _chiSq;
-     private String _constraintType="Unspecified";
-    // constructor
-    public BilliorVertexer() {
-    }
 
     public BilliorVertexer(double bField) {
         _bField = bField;
-        _constraintType="Unconstrained";
-        _beamspotConstraint =false;
+        _constraintType = "Unconstrained";
+        _beamspotConstraint = false;
         _targetConstraint = false;
     }
-    
-    public BilliorVertexer(double bField,boolean bsConst, boolean constToBS) {
+
+    public BilliorVertexer(double bField, boolean bsConst, boolean constToBS) {
         _bField = bField;
-        _beamspotConstraint =bsConst;
+        _beamspotConstraint = bsConst;
         _targetConstraint = constToBS;
-        if(_beamspotConstraint&&_targetConstraint)
+        if (_beamspotConstraint && _targetConstraint) {
             System.out.println("BilliorVertexer::Warning!!!  Setting both _beamspotConstraint and _targetConstraint to true!");
-        if(_beamspotConstraint)
-            _constraintType="BeamspotConstrained";
-        if(_targetConstraint)
-            _constraintType="TargetConstrained";
+        }
+        if (_beamspotConstraint) {
+            _constraintType = "BeamspotConstrained";
+        }
+        if (_targetConstraint) {
+            _constraintType = "TargetConstrained";
+        }
+    }
+
+    public void setDebug(boolean debug) {
+        _debug = debug;
     }
 
     public BilliorVertex fitVertex(List<BilliorTrack> tracks) {
         _ntracks = tracks.size();
         follow1985Paper(tracks);
-        if (_beamspotConstraint)
-            addV0fromBSConstraint();
-        else if (_targetConstraint)
-            constrainV0toBS();
-        Map<Integer,Hep3Vector> pFitMap=new HashMap<Integer,Hep3Vector>();
-        for(int i=0;i<tracks.size();i++){
-            Hep3Vector pFit=new BasicHep3Vector(this.getFittedMomentum(i));
-            pFitMap.put(i, pFit);            
-        }
-        Hep3Vector vert=new BasicHep3Vector(_vertexPosition.e(0, 0),_vertexPosition.e(1, 0),_vertexPosition.e(2, 0));
-        Hep3Vector vertDet=CoordinateTransformations.transformVectorToDetector(vert);
-        SymmetricMatrix covVtxDet=CoordinateTransformations.transformCovarianceToDetector(new SymmetricMatrix( _covVtx));
-        return new BilliorVertex(vertDet,covVtxDet,_chiSq,getInvMass(),pFitMap,_constraintType);
-    }
-
-    public BilliorVertex fitFastVertex(List<BilliorTrack> tracks) {
-        _ntracks = tracks.size();
-        fastVertex(tracks);
-     Hep3Vector vert=new BasicHep3Vector(_vertexPosition.e(0, 0),_vertexPosition.e(1, 0),_vertexPosition.e(2, 0));
-     return new BilliorVertex((Hep3Vector)_vertexPosition,_covVtx,_chiSq,getInvMass());
-    }
-
-    private void calculateCovariance() {
-        for (int i = 0; i < _ntracks; i++) {
-            BasicMatrix b = (BasicMatrix) BList.get(i);
-            BasicMatrix cinv = (BasicMatrix) CinvList.get(i);
-            BasicMatrix bt = (BasicMatrix) MatrixOp.transposed(b);
-            covVtxMomList.add((MatrixOp.mult(-1, MatrixOp.mult(_covVtx, MatrixOp.mult(b, cinv)))));
-            for (int j = 0; j < _ntracks; j++) {
-                BasicMatrix bj = (BasicMatrix) BList.get(j);
-                BasicMatrix cjinv = (BasicMatrix) CinvList.get(j);
-                BasicMatrix tmp = (BasicMatrix) MatrixOp.mult(cinv, MatrixOp.mult(bt, MatrixOp.mult(_covVtx, MatrixOp.mult(bj, cjinv))));
-                if (i == j)
-                    tmp = (BasicMatrix) MatrixOp.add(tmp, cinv);
-                covMomList[i][j] = tmp;
-            }
-        }
-    }
-
-    private void calculateMomenta() {
-
-        for (int i = 0; i < _ntracks; i++) {
-            BasicMatrix params = (BasicMatrix) paramList.get(i);
-            BasicMatrix b = (BasicMatrix) BList.get(i);
-            BasicMatrix cinv = (BasicMatrix) CinvList.get(i);
-            BasicMatrix u = (BasicMatrix) UList.get(i);
-            //not sure following line is correct...mg 10/21/10
-            BasicMatrix CinvU = (BasicMatrix) MatrixOp.mult(cinv, u);
-            BasicMatrix CinvBTdV = (BasicMatrix) MatrixOp.mult(-1, MatrixOp.mult(cinv, MatrixOp.mult(MatrixOp.transposed(b), _vertexPosition)));
-//            if(_debug)System.out.println(" B = "+b.toString());
-//            if(_debug)System.out.println(" cinv = "+cinv.toString());
-//            if(_debug)System.out.println(" u = "+u.toString());
-//            if(_debug)System.out.println(" CinvU = "+CinvU.toString());
-//            if(_debug)System.out.println(" CinvBTdV = "+CinvBTdV.toString());
-            BasicMatrix tmpP = (BasicMatrix) MatrixOp.add(CinvBTdV, CinvU);
-            tmpP.setElement(0, 0, tmpP.e(0, 0) + params.e(2, 0));
-            tmpP.setElement(1, 0, tmpP.e(1, 0) + params.e(3, 0));
-            tmpP.setElement(2, 0, tmpP.e(2, 0) + params.e(4, 0));
-            _pFit.add(tmpP);
-//            if(_debug)System.out.println("Track "+i+" orig parameters  = "+params);
-//            if(_debug)System.out.println("Track "+i+" deltaP  = "+MatrixOp.add(CinvBTdV, CinvU));
-//            if(_debug)System.out.println("Track " + i + " _pFit  = " + tmpP);
-        }
-    }
-
-    private void calculateVertexPosition() {
-        BasicMatrix tmpcov = new BasicMatrix(3, 3);
-        BasicMatrix tmp = new BasicMatrix(3, 1);
-        for (int i = 0; i < _ntracks; i++) {
-            BasicMatrix b = (BasicMatrix) BList.get(i);
-            BasicMatrix cinv = (BasicMatrix) CinvList.get(i);
-            BasicMatrix u = (BasicMatrix) UList.get(i);
-//            if(_debug)System.out.println("Cinv matrix " + cinv.toString());
-//            if(_debug)System.out.println("B matrix " + b.toString());
-//            if(_debug)System.out.println("U matrix " + u.toString());
-            BasicMatrix bt = (BasicMatrix) MatrixOp.transposed(b);
-            //           if(_debug)System.out.println("Adding this to tmpcov : " + MatrixOp.mult(-1, MatrixOp.mult(b, MatrixOp.mult(cinv, bt))));
-            if (i == 0) {
-                tmpcov = (BasicMatrix) MatrixOp.mult(-1, MatrixOp.mult(b, MatrixOp.mult(cinv, bt)));
-                tmp = (BasicMatrix) MatrixOp.mult(-1, MatrixOp.mult(b, MatrixOp.mult(cinv, u)));
-            } else {
-                tmpcov = (BasicMatrix) MatrixOp.add(tmpcov, MatrixOp.mult(-1, MatrixOp.mult(b, MatrixOp.mult(cinv, bt))));
-                tmp = (BasicMatrix) MatrixOp.add(tmp, MatrixOp.mult(-1, MatrixOp.mult(b, MatrixOp.mult(cinv, u))));
-            }
-//            if(_debug)System.out.println("tmpCov matrix " + tmpcov.toString());
-//            if(_debug)System.out.println("tmp matrix " + tmp.toString());
-        }
-//
-//        if(_debug)System.out.println("A matrix " + A.toString());
-//        if(_debug)System.out.println("tmpCov matrix " + tmpcov.toString());
-//        if(_debug)System.out.println("sum of A and tmpCov = " + MatrixOp.add(A, tmpcov).toString());
-        _covVtx = MatrixOp.inverse(MatrixOp.add(A, tmpcov));
-//        if(_debug)System.out.println("_covVtx matrix " + _covVtx.toString());
-//        if(_debug)System.out.println("T matrix " + T.toString());
-        _vertexPosition = (BasicMatrix) MatrixOp.mult(_covVtx, MatrixOp.add(T, tmp));
-
-    }
-
-    private void makeOtherMatrices() {
-        BasicMatrix tmpA = new BasicMatrix(3, 3);
-        BasicMatrix tmpT = new BasicMatrix(3, 1);
-
-        for (int i = 0; i < _ntracks; i++) {
-            BasicMatrix tmpD = (BasicMatrix) DList.get(i);
-            BasicMatrix tmpE = (BasicMatrix) EList.get(i);
-            BasicMatrix dq = (BasicMatrix) dqList.get(i);
-            BasicMatrix tmpW = (BasicMatrix) WList.get(i);
-
-            if (i == 0) {
-                tmpA = (BasicMatrix) MatrixOp.mult(MatrixOp.transposed(tmpD), MatrixOp.mult(tmpW, tmpD));
-                tmpT = (BasicMatrix) MatrixOp.mult(MatrixOp.transposed(tmpD), MatrixOp.mult(tmpW, dq));
-            } else {
-                tmpT = (BasicMatrix) MatrixOp.add(tmpT, MatrixOp.mult(MatrixOp.transposed(tmpD), MatrixOp.mult(tmpW, dq)));
-                tmpA = (BasicMatrix) MatrixOp.add(tmpA, MatrixOp.mult(MatrixOp.transposed(tmpD), MatrixOp.mult(tmpW, tmpD)));
-            }
-            BList.add(MatrixOp.mult(MatrixOp.transposed(tmpD), MatrixOp.mult(tmpW, tmpE)));
-            BasicMatrix tmpC = (BasicMatrix) MatrixOp.mult(MatrixOp.transposed(tmpE), MatrixOp.mult(tmpW, tmpE));
-            CList.add(tmpC);
-            CinvList.add(MatrixOp.inverse(tmpC));
-            UList.add(MatrixOp.mult(MatrixOp.transposed(tmpE), MatrixOp.mult(tmpW, dq)));
-
-        }
-        A = tmpA;
-        T = tmpT;
-    }
-
-    private void calculateChisq() {
-        _chiSq = 0;
-        for (int i = 0; i < _ntracks; i++) {
-            BasicMatrix params = (BasicMatrix) paramList.get(i);
-            BasicMatrix d = (BasicMatrix) DList.get(i);
-            BasicMatrix e = (BasicMatrix) EList.get(i);
-            BasicMatrix w = (BasicMatrix) WList.get(i);
-            BasicMatrix pi = (BasicMatrix) _pFit.get(i);
-            BasicMatrix Vtilde = (BasicMatrix) MatrixOp.mult(d, _vertexPosition);
-            BasicMatrix Trtilde = (BasicMatrix) MatrixOp.mult(e, pi);
-            BasicMatrix ptilde = (BasicMatrix) MatrixOp.add(Vtilde, Trtilde);
-            //          if(_debug)System.out.println("Vtilde = "+Vtilde);
-            //          if(_debug)System.out.println("Trtilde = "+Trtilde);
-            BasicMatrix resid = (BasicMatrix) MatrixOp.add(params, MatrixOp.mult(-1, ptilde));
-            BasicMatrix residT = (BasicMatrix) MatrixOp.transposed(resid);
-//            if(_debug)System.out.println("ptilde = "+ptilde);
-//              if(_debug)System.out.println("params = "+params);
-//            if(_debug)System.out.println("resid = "+resid);
-//            if(_debug)System.out.println("Covariance = "+MatrixOp.inverse(w));
-//             if(_debug)System.out.println("Weight = "+w);
-            _chiSq = _chiSq + (MatrixOp.mult(residT, MatrixOp.mult(w, resid))).e(0, 0);
-//            if(_debug)System.out.println("_chiSq = "+_chiSq);
-        }
-    }
-
-    private void fastVertex(List<BilliorTrack> tracks) {
-        boolean firstTrack = true;
-        BasicMatrix sumwi = new BasicMatrix(3, 3);
-        BasicMatrix sumwiXi = new BasicMatrix(3, 1);
-        BasicMatrix dX = new BasicMatrix(3, 1);
-
-        for (BilliorTrack bt : tracks) {
-            double[] par = bt.parameters();
-//            if(_debug)System.out.println("Track parameters = (" + par[0] + ", " + par[1] + ", " + par[2] + ", " + par[3] + ", " + par[4] + ")");
-            double cotth = 1. / tan(par[2]);
-            double phiv = par[3];
-            double cosf = cos(phiv);
-            double sinf = sin(phiv);
-
-            double xi = par[0] * sin(par[3]);
-            double yi = -par[0] * cos(par[3]);
-            double zi = par[1];
-
-            dX.setElement(0, 0, xi);
-            dX.setElement(1, 0, yi);
-            dX.setElement(2, 0, zi);
-
-            BasicMatrix tmpD = new BasicMatrix(2, 3);
-            tmpD.setElement(0, 0, sinf);
-            tmpD.setElement(0, 1, -cosf);
-            tmpD.setElement(1, 0, -cotth * cosf);
-            tmpD.setElement(1, 1, -cotth * sinf);
-            tmpD.setElement(1, 2, 1);
-            BasicMatrix trkCov = new BasicMatrix(2, 2);
-            trkCov.setElement(0, 0, bt.covariance().e(0, 0));
-            trkCov.setElement(0, 1, bt.covariance().e(0, 1));
-            trkCov.setElement(1, 0, bt.covariance().e(1, 0));
-            trkCov.setElement(1, 1, bt.covariance().e(1, 1));
-            BasicMatrix tmpW = (BasicMatrix) MatrixOp.inverse(trkCov);
-            BasicMatrix wi = (BasicMatrix) MatrixOp.mult(MatrixOp.transposed(tmpD), MatrixOp.mult(tmpW, tmpD));
-            if (firstTrack) {
-                sumwi = wi;
-                sumwiXi = (BasicMatrix) MatrixOp.mult(wi, dX);
-            } else {
-                sumwi = (BasicMatrix) MatrixOp.add(sumwi, wi);
-                sumwiXi = (BasicMatrix) MatrixOp.add(sumwiXi, MatrixOp.mult(wi, dX));
-            }
-            firstTrack = false;
-        }
-        _covVtx = MatrixOp.inverse(sumwi);
-        if (_debug)
-            System.out.println("fastVertex::_covVtx matrix " + _covVtx.toString());
-        _vertexPosition = (BasicMatrix) MatrixOp.mult(_covVtx, sumwiXi);
-        _chiSq = 0;
-        //get the chisq
-        for (BilliorTrack bt : tracks) {
-            double[] par = bt.parameters();
-//            if(_debug)System.out.println("Track parameters = (" + par[0] + ", " + par[1] + ", " + par[2] + ", " + par[3] + ", " + par[4] + ")");
-            double cotth = 1. / tan(par[2]);
-            double phiv = par[3];
-            double cosf = cos(phiv);
-            double sinf = sin(phiv);
-
-            double xi = par[0] * sin(par[3]);
-            double yi = -par[0] * cos(par[3]);
-            double zi = par[1];
-            //this is xi - fitted vertex now
-            dX.setElement(0, 0, xi - _vertexPosition.e(0, 0));
-            dX.setElement(1, 0, yi - _vertexPosition.e(1, 0));
-            dX.setElement(2, 0, zi - _vertexPosition.e(2, 0));
-
-            BasicMatrix tmpD = new BasicMatrix(2, 3);
-            tmpD.setElement(0, 0, sinf);
-            tmpD.setElement(0, 1, -cosf);
-            tmpD.setElement(1, 0, -cotth * cosf);
-            tmpD.setElement(1, 1, -cotth * sinf);
-            tmpD.setElement(1, 2, 1);
-            BasicMatrix trkCov = new BasicMatrix(2, 2);
-            trkCov.setElement(0, 0, bt.covariance().e(0, 0));
-            trkCov.setElement(0, 1, bt.covariance().e(0, 1));
-            trkCov.setElement(1, 0, bt.covariance().e(1, 0));
-            trkCov.setElement(1, 1, bt.covariance().e(1, 1));
-            BasicMatrix tmpW = (BasicMatrix) MatrixOp.inverse(trkCov);
-            BasicMatrix wi = (BasicMatrix) MatrixOp.mult(MatrixOp.transposed(tmpD), MatrixOp.mult(tmpW, tmpD));
-            _chiSq += MatrixOp.mult(MatrixOp.transposed(dX), MatrixOp.mult(wi, dX)).e(0, 0);
-        }
-    }
-
-    private void makeDerivativeMatrices(List<BilliorTrack> tracks) {
-
-        //DList.clear();
-        //EList.clear();
-        //paramList.clear();
-        //dqList.clear();
-        //WList.clear();
-        BasicMatrix dq = new BasicMatrix(5, 1);
-        BasicMatrix tmpW = new BasicMatrix(5, 5);
-        for (BilliorTrack bt : tracks) {
-            double[] par = bt.parameters();
-            BasicMatrix tmpPar = new BasicMatrix(5, 1);
-            tmpPar.setElement(0, 0, par[0]);
-            tmpPar.setElement(1, 0, par[1]);
-            tmpPar.setElement(2, 0, par[2]);
-            tmpPar.setElement(3, 0, par[3]);
-            tmpPar.setElement(4, 0, par[4]);
-            paramList.add(tmpPar);
-            double cotth = 1. / tan(par[2]);
-            double uu = _v0[0] * cos(par[3]) + _v0[1] * sin(par[3]);//Q
-            double vv = _v0[1] * cos(par[3]) - _v0[0] * sin(par[3]);//R
-            double eps = -vv - .5 * uu * uu * par[4];
-            double zp = _v0[2] - uu * (1 - vv * par[4]) * cotth;
-            // * phi at vertex with these parameters
-            double phiv = par[3] + uu * par[4];
-            double cosf = cos(phiv);
-            double sinf = sin(phiv);
-
-            BasicMatrix tmpD = new BasicMatrix(5, 3);
-            tmpD.setElement(0, 0, sinf);
-            tmpD.setElement(0, 1, -cosf);
-            tmpD.setElement(1, 0, -cotth * cosf);
-            tmpD.setElement(1, 1, -cotth * sinf);
-            tmpD.setElement(1, 2, 1);
-            tmpD.setElement(3, 0, -par[4] * cosf);
-            tmpD.setElement(3, 1, -par[4] * sinf);
-
-            BasicMatrix tmpE = new BasicMatrix(5, 3);
-            tmpE.setElement(0, 1, uu);
-            tmpE.setElement(0, 2, -uu * uu / 2);
-            tmpE.setElement(1, 0, uu * (1 + cotth * cotth));
-            tmpE.setElement(1, 1, -vv * cotth);
-            tmpE.setElement(1, 2, uu * vv * cotth);
-            tmpE.setElement(3, 1, 1);
-            tmpE.setElement(3, 2, -uu);
-            tmpE.setElement(2, 0, 1);  //partial(theta)/dtheta
-            tmpE.setElement(4, 2, 1); //partial (rho)/drho
-            DList.add(tmpD);
-            EList.add(tmpE);
-
-            double deps = par[0] - eps;
-            double dzp = par[1] - zp;
-            double dphi = par[3] - phiv;
-
-            dq.setElement(0, 0, deps);
-            dq.setElement(1, 0, dzp);
-            dq.setElement(3, 0, dphi);
-            dqList.add(dq);
-            tmpW = (BasicMatrix) MatrixOp.inverse(bt.covariance());
-            WList.add(tmpW);
-
-            if (_debug)
-                System.out.println("makeDerivativeMatrices::Params = \n" + tmpPar);
-            if (_debug)
-                System.out.println("D = \n" + tmpD);
-            if (_debug)
-                System.out.println("E = \n" + tmpE);
-            if (_debug)
-                System.out.println("dq = \n" + dq);
-            if (_debug)
-                System.out.println("W = \n" + tmpW);
-        }
-
-    }
-
-    /*  Add the constraint that V0 points back to beamspot
+        if (_beamspotConstraint) {
+            applyBSconstraint(true);
+        } else if (_targetConstraint) {
+            applyBSconstraint(false);
+        }
+        Map<Integer, Hep3Vector> pFitMap = new HashMap<Integer, Hep3Vector>();
+        for (int i = 0; i < tracks.size(); i++) {
+            Hep3Vector pFit = new BasicHep3Vector(this.getFittedMomentum(i));
+            pFitMap.put(i, pFit);
+        }
+        Hep3Vector vert = new BasicHep3Vector(_vertexPosition.e(0, 0), _vertexPosition.e(1, 0), _vertexPosition.e(2, 0));
+        Hep3Vector vertDet = CoordinateTransformations.transformVectorToDetector(vert);
+        SymmetricMatrix covVtxDet = CoordinateTransformations.transformCovarianceToDetector(new SymmetricMatrix(_covVtx));
+        return new BilliorVertex(vertDet, covVtxDet, _chiSq, getInvMass(), pFitMap, _constraintType);
+    }
+
+    /*  Add the constraint that V0 is at/points back to beamspot
      *  this method is based on progressive least squares fit
      *  using the unconstrained fit result as the (k-1) fit
      *
      *  all notation is taken from:
      * W. Hulsbergen, NIM 552 (2005) 566-575
      */
-    private void addV0fromBSConstraint() {
-        BasicMatrix Hk = new BasicMatrix(3 * (_ntracks + 1), 3);
+    private void applyBSconstraint(boolean pointback) {
+        String methodName = pointback ? "constrainV0toBS" : "constrainV0toTarget";
         BasicMatrix Ckm1 = new BasicMatrix(3 * (_ntracks + 1), 3 * (_ntracks + 1));
         BasicMatrix Xkm1 = new BasicMatrix(3 * (_ntracks + 1), 1);
         MatrixOp.setSubMatrix(Ckm1, _covVtx, 0, 0);
         MatrixOp.setSubMatrix(Xkm1, _vertexPosition, 0, 0);
         int n = 1;
         for (Matrix covVtxMom : covVtxMomList) {
-            if (_debug)
-                System.out.println("addV0fromBSConstraint::Track " + n + "  covVtxMom : " + covVtxMom.toString());
+            if (_debug) {
+                System.out.println(methodName + "::Track " + n + "  covVtxMom : " + covVtxMom.toString());
+            }
             MatrixOp.setSubMatrix(Ckm1, covVtxMom, 0, 3 * n);
             MatrixOp.setSubMatrix(Ckm1, MatrixOp.transposed(covVtxMom), 3 * n, 0);
             n++;
@@ -411,10 +114,12 @@
         for (int i = 0; i < _ntracks; i++) {
             BasicMatrix pi = (BasicMatrix) _pFit.get(i);
             MatrixOp.setSubMatrix(Xkm1, pi, 3 * (i + 1), 0);
-            if (_debug)
-                System.out.println("addV0fromBSConstraint::Track " + i + "  p : " + pi.toString());
-            for (int j = 0; j < _ntracks; j++)
+            if (_debug) {
+                System.out.println(methodName + "::Track " + i + "  p : " + pi.toString());
+            }
+            for (int j = 0; j < _ntracks; j++) {
                 MatrixOp.setSubMatrix(Ckm1, covMomList[i][j], 3 * (i + 1), 3 * (j + 1));
+            }
         }
 
         //  now calculate the derivative matrix for the beam constraint.
@@ -443,17 +148,96 @@
             pztot += pz;
         }
         //calculate the position of the A' at X=0
-        BasicMatrix rk = new BasicMatrix(3, 1);
-        if (_debug)
-            System.out.println("addV0fromBSConstraint::Vx = " + Vx + "; Vy = " + Vy + "; Vz = " + Vz + "; pxtot = " + pxtot + "; pytot = " + pytot + "; pztot = " + pztot);
-        rk.setElement(0, 0, 0);
-        rk.setElement(1, 0, 0 - (Vy - pytot / pxtot * Vx));
-        rk.setElement(2, 0, 0 - (Vz - pztot / pxtot * Vx));
-
+        BasicMatrix rk = makeRk(Vx, Vy, Vz, pxtot, pytot, pztot, pointback);
+        if (_debug) {
+            System.out.println(methodName + "::rk = " + rk);
+        }
+
+        BasicMatrix Hk = makeHk(Vx, pxtot, pytot, pztot, pointback);
+        if (_debug) {
+            System.out.println(methodName + "::Hk = " + Hk);
+        }
+
+        // the beam covariance
+        BasicMatrix Vk = new BasicMatrix(3, 3);
+        Vk.setElement(0, 0, _beamSize[0] * _beamSize[0]);
+        Vk.setElement(1, 1, _beamSize[1] * _beamSize[1]);
+        Vk.setElement(2, 2, _beamSize[2] * _beamSize[2]);
+
+        //now do the matrix operations to get the constrained parameters
+        BasicMatrix Hkt = (BasicMatrix) MatrixOp.transposed(Hk);
+        if (_debug) {
+            System.out.println(methodName + "::Ckm1Hk = " + MatrixOp.mult(Ckm1, Hk));
+        }
+
+        BasicMatrix Rk = (BasicMatrix) MatrixOp.mult(Hkt, MatrixOp.mult(Ckm1, Hk));
+        if (_debug) {
+            System.out.println("Pre Vk:  Rk = " + Rk.toString());
+        }
+        Rk = (BasicMatrix) MatrixOp.add(Rk, Vk);
+        if (_debug) {
+            System.out.println("Post Vk:  Rk = " + Rk.toString());
+        }
+        BasicMatrix Rkinv = (BasicMatrix) MatrixOp.inverse(Rk);
+        BasicMatrix Kk = (BasicMatrix) MatrixOp.mult(Ckm1, MatrixOp.mult(Hk, Rkinv));
+
+//        if(_debug)System.out.println("Ckm1 = " + Ckm1.toString());
+//        if(_debug)System.out.println("Hk = " + Hk.toString());
+//        if(_debug)System.out.println("Rk = " + Rk.toString());
+//        if(_debug)System.out.println("Vk = " + Vk.toString());
+//        if(_debug)System.out.println("rk = " + rk.toString());
+//        if(_debug)System.out.println("Kk = " + Kk.toString());
+        _constrainedFit = MatrixOp.mult(Kk, rk);
+        _constrainedFit = MatrixOp.add(_constrainedFit, Xkm1);//Xk
+
+        //ok, get the new covariance
+        BasicMatrix RkKkt = (BasicMatrix) MatrixOp.mult(Rk, MatrixOp.transposed(Kk));
+        BasicMatrix HkCkm1 = (BasicMatrix) MatrixOp.mult(Hkt, Ckm1);
+        RkKkt = (BasicMatrix) MatrixOp.mult(1, RkKkt);
+        HkCkm1 = (BasicMatrix) MatrixOp.mult(-2, HkCkm1);
+        BasicMatrix sumMatrix = (BasicMatrix) MatrixOp.mult(Kk, MatrixOp.add(HkCkm1, RkKkt));
+        _constrainedCov = (BasicMatrix) MatrixOp.add(Ckm1, sumMatrix);
+
+        //update the regular parameter names to the constrained result
+//        if(_debug)System.out.println("Without Constraint : " + _vertexPosition.toString());
+//        if(_debug)System.out.println("Without Constraint:  x= "+_vertexPosition.e(0,0));
+        //        if(_debug)System.out.println(_constrainedFit.toString());
+//         if(_debug)System.out.println("Without Constraint : " + _covVtx.toString());
+        _vertexPosition = (BasicMatrix) MatrixOp.getSubMatrix(_constrainedFit, 0, 0, 3, 1);
+        _covVtx = (BasicMatrix) MatrixOp.getSubMatrix(_constrainedCov, 0, 0, 3, 3);
+//        if(_debug)System.out.println("With Constraint : " + _vertexPosition.toString());
+//        if(_debug)System.out.println("With Constraint : " + _covVtx.toString());
+
+        if (_debug) {
+            System.out.println("Constrained vertex: " + _vertexPosition);
+        }
+
+        for (int i = 0; i < _ntracks; i++) {
+            BasicMatrix ptmp = (BasicMatrix) MatrixOp.getSubMatrix(_constrainedFit, 3 * (i + 1), 0, 3, 1);
+            _pFit.set(i, ptmp);
+        }
+
+//        if(_debug)System.out.println("Unconstrained chi^2 = "+_chiSq);
+        //ok...add to the chi^2
+        if (_debug) {
+            System.out.println("Chisq contribution: " + MatrixOp.mult(MatrixOp.transposed(rk), MatrixOp.mult(Rkinv, rk)));
+        }
+        _chiSq += MatrixOp.mult(MatrixOp.transposed(rk), MatrixOp.mult(Rkinv, rk)).e(0, 0);
+//        if(_debug)System.out.println("Constrained chi^2 = "+_chiSq);
+    }
+
+    private BasicMatrix makeHk(double Vx, double pxtot, double pytot, double pztot, boolean bscon) {
+        BasicMatrix Hk = new BasicMatrix(3 * (_ntracks + 1), 3);
 //  ok, can set the derivitives wrt to V
-        Hk.setElement(0, 0, 0);
-        Hk.setElement(0, 1, pytot / pxtot);
-        Hk.setElement(0, 2, pztot / pxtot);
+        if (bscon) {
+            Hk.setElement(0, 0, 0);
+            Hk.setElement(0, 1, pytot / pxtot);
+            Hk.setElement(0, 2, pztot / pxtot);
+        } else {
+            Hk.setElement(0, 0, 1);
+            Hk.setElement(0, 1, 0);
+            Hk.setElement(0, 2, 0);
+        }
         Hk.setElement(1, 0, 0);
         Hk.setElement(1, 1, 1);
         Hk.setElement(1, 2, 0);
@@ -467,243 +251,67 @@
             double phiv = pi.e(1, 0);
             double rho = pi.e(2, 0);
             double Pt = Math.abs((1. / rho) * _bField * Constants.fieldConversion);
-            double px = Pt * Math.cos(phiv);
-            double py = Pt * Math.sin(phiv);
-            double pz = Pt * 1 / Math.tan(theta);
+//            double px = Pt * Math.cos(phiv);
+//            double py = Pt * Math.sin(phiv);
+//            double pz = Pt * 1 / Math.tan(theta);
             //derivities wrt theta
             Hk.setElement(3 * (i + 1), 0, 0);
             Hk.setElement(3 * (i + 1), 1, 0);
-            Hk.setElement(3 * (i + 1), 2, -Pt / Math.pow(sin(theta), 2) * Vx);
+            if (bscon) {
+                Hk.setElement(3 * (i + 1), 2,
+                        -Pt / Math.pow(sin(theta), 2) * (Vx - _beamPosition[0]));
+            } else {
+                Hk.setElement(3 * (i + 1), 2, 0);
+            }
             //derivities wrt phi
             Hk.setElement(3 * (i + 1) + 1, 0, 0);
-            Hk.setElement(3 * (i + 1) + 1, 1,
-                    (Pt * Pt * cos(phiv) * sin(phiv) / (pxtot * pxtot)) * Vx);
-            Hk.setElement(3 * (i + 1) + 1, 2, (Pt * sin(phiv) / (pxtot * pxtot)) * Vx * pztot);
+            if (bscon) {
+                Hk.setElement(3 * (i + 1) + 1, 1,
+                        (Pt * Pt * cos(phiv) * sin(phiv) / (pxtot * pxtot)) * (Vx - _beamPosition[0]));
+                Hk.setElement(3 * (i + 1) + 1, 2,
+                        (Pt * sin(phiv) / (pxtot * pxtot)) * (Vx - _beamPosition[0]) * pztot);
+            } else {
+                Hk.setElement(3 * (i + 1) + 1, 1, 0);
+                Hk.setElement(3 * (i + 1) + 1, 2, 0);
+            }
             //derivities wrt rho
             Hk.setElement(3 * (i + 1) + 2, 0, 0);
 //            Hk.setElement(3 * (i + 1) + 2, 1,
 //                    (pytot / pxtot - 1) * (Pt / rho) * (1 / pxtot) * Vx);
 //            Hk.setElement(3 * (i + 1) + 2, 2,
 //                    (pztot / pxtot - 1) * (Pt / rho) * (1 / pxtot) * Vx);
-            Hk.setElement(3 * (i + 1) + 2, 1,
-                    (cos(phiv) * pytot / pxtot - sin(phiv)) * (Pt / rho) * (1 / pxtot) * Vx);
-            Hk.setElement(3 * (i + 1) + 2, 2,
-                    (cos(phiv) * pztot / pxtot - sin(phiv)) * (Pt / rho) * (1 / pxtot) * Vx);
+            if (bscon) {
+                Hk.setElement(3 * (i + 1) + 2, 1,
+                        (cos(phiv) * pytot / pxtot - sin(phiv)) * (Pt / rho) * (1 / pxtot) * (Vx - _beamPosition[0]));
+                Hk.setElement(3 * (i + 1) + 2, 2,
+                        (cos(phiv) * pztot / pxtot - sin(phiv)) * (Pt / rho) * (1 / pxtot) * (Vx - _beamPosition[0]));
+            } else {
+                Hk.setElement(3 * (i + 1) + 2, 1, 0);
+                Hk.setElement(3 * (i + 1) + 2, 2, 0);
+            }
             //                   if(_debug)System.out.println("pxtot = "+pxtot+"; rho = "+rho+"; Pt = "+Pt);
             //                   if(_debug)System.out.println("cos(phiv)*pytot / pxtot - sin(phiv) = "+(cos(phiv)*pytot / pxtot - sin(phiv)));
             //                   if(_debug)System.out.println("Pt/(rho*pxtot) = "+(Pt / rho) * (1 / pxtot));
         }
-        // the beam covariance
-        BasicMatrix Vk = new BasicMatrix(3, 3);
-        Vk.setElement(0, 0, _beamSize[0] * _beamSize[0]);
-        Vk.setElement(1, 1, _beamSize[1] * _beamSize[1]);
-        Vk.setElement(2, 2, _beamSize[2] * _beamSize[2]);
-
-        //now do the matrix operations to get the constrained parameters
-        BasicMatrix Hkt = (BasicMatrix) MatrixOp.transposed(Hk);
-        if (_debug)
-            System.out.println("addV0fromBSConstraint::Ckm1Hk = " + MatrixOp.mult(Ckm1, Hk));
-
-        BasicMatrix Rk = (BasicMatrix) MatrixOp.mult(Hkt, MatrixOp.mult(Ckm1, Hk));
-        if (_debug)
-            System.out.println("Pre Vk:  Rk = " + Rk.toString());
-        Rk = (BasicMatrix) MatrixOp.add(Rk, Vk);
-        if (_debug)
-            System.out.println("Post Vk:  Rk = " + Rk.toString());
-        BasicMatrix Rkinv = (BasicMatrix) MatrixOp.inverse(Rk);
-        BasicMatrix Kk = (BasicMatrix) MatrixOp.mult(Ckm1, MatrixOp.mult(Hk, Rkinv));
-
-//        if(_debug)System.out.println("Ckm1 = " + Ckm1.toString());
-//        if(_debug)System.out.println("Hk = " + Hk.toString());
-//        if(_debug)System.out.println("Rk = " + Rk.toString());
-//        if(_debug)System.out.println("Vk = " + Vk.toString());
-//        if(_debug)System.out.println("rk = " + rk.toString());
-//        if(_debug)System.out.println("Kk = " + Kk.toString());
-        _constrainedFit = MatrixOp.mult(Kk, rk);
-        _constrainedFit = MatrixOp.add(_constrainedFit, Xkm1);//Xk
-
-        //ok, get the new covariance
-        BasicMatrix RkKkt = (BasicMatrix) MatrixOp.mult(Rk, MatrixOp.transposed(Kk));
-        BasicMatrix HkCkm1 = (BasicMatrix) MatrixOp.mult(Hkt, Ckm1);
-        RkKkt = (BasicMatrix) MatrixOp.mult(1, RkKkt);
-        HkCkm1 = (BasicMatrix) MatrixOp.mult(-2, HkCkm1);
-        BasicMatrix sumMatrix = (BasicMatrix) MatrixOp.mult(Kk, MatrixOp.add(HkCkm1, RkKkt));
-        _constrainedCov = (BasicMatrix) MatrixOp.add(Ckm1, sumMatrix);
-
-        //update the regular parameter names to the constrained result
-//        if(_debug)System.out.println("Without Constraint : " + _vertexPosition.toString());
-//        if(_debug)System.out.println("Without Constraint:  x= "+_vertexPosition.e(0,0));
-        //        if(_debug)System.out.println(_constrainedFit.toString());
-//         if(_debug)System.out.println("Without Constraint : " + _covVtx.toString());
-        _vertexPosition = (BasicMatrix) MatrixOp.getSubMatrix(_constrainedFit, 0, 0, 3, 1);
-        _covVtx = (BasicMatrix) MatrixOp.getSubMatrix(_constrainedCov, 0, 0, 3, 3);
-//        if(_debug)System.out.println("With Constraint : " + _vertexPosition.toString());
-//        if(_debug)System.out.println("With Constraint : " + _covVtx.toString());
-
-        for (int i = 0; i < _ntracks; i++) {
-            BasicMatrix ptmp = (BasicMatrix) MatrixOp.getSubMatrix(_constrainedFit, 3 * (i + 1), 0, 3, 1);
-            _pFit.set(i, ptmp);
-        }
-
-//        if(_debug)System.out.println("Unconstrained chi^2 = "+_chiSq);
-        //ok...add to the chi^2
-        if (_debug)
-            System.out.println(MatrixOp.mult(MatrixOp.transposed(rk), MatrixOp.mult(Rkinv, rk)));
-        _chiSq += MatrixOp.mult(MatrixOp.transposed(rk), MatrixOp.mult(Rkinv, rk)).e(0, 0);
-//        if(_debug)System.out.println("Constrained chi^2 = "+_chiSq);
-    }
-
-    private void constrainV0toBS() {
-        BasicMatrix Hk = new BasicMatrix(3 * (_ntracks + 1), 3);
-        BasicMatrix Ckm1 = new BasicMatrix(3 * (_ntracks + 1), 3 * (_ntracks + 1));
-        BasicMatrix Xkm1 = new BasicMatrix(3 * (_ntracks + 1), 1);
-        MatrixOp.setSubMatrix(Ckm1, _covVtx, 0, 0);
-        MatrixOp.setSubMatrix(Xkm1, _vertexPosition, 0, 0);
-
-        int n = 1;
-        for (Matrix covVtxMom : covVtxMomList) {
-            if (_debug)
-                System.out.println("constrainV0toBS::Track " + n + "  covVtxMom : " + covVtxMom.toString());
-            MatrixOp.setSubMatrix(Ckm1, covVtxMom, 0, 3 * n);
-            MatrixOp.setSubMatrix(Ckm1, MatrixOp.transposed(covVtxMom), 3 * n, 0);
-            n++;
-        }
-        for (int i = 0; i < _ntracks; i++) {
-            BasicMatrix pi = (BasicMatrix) _pFit.get(i);
-            MatrixOp.setSubMatrix(Xkm1, pi, 3 * (i + 1), 0);
-            //           if(_debug)System.out.println("Track "+i+"  p : " + pi.toString());
-            for (int j = 0; j < _ntracks; j++)
-                MatrixOp.setSubMatrix(Ckm1, covMomList[i][j], 3 * (i + 1), 3 * (j + 1));
-        }
-        //  now calculate the derivative matrix for the beam constraint.
-        //  the beamspot is assumed to be at bvec=(0,0,0)
-        //  the V0 production position is Vbvec=(0,0,0)
-        //  where ptot=sum_i (pi)
-        //  need derivites wrt to the vertex position and momentum (theta,phi_v,rho)
-        double Vx = _vertexPosition.e(0, 0);
-        double Vy = _vertexPosition.e(1, 0);
-        double Vz = _vertexPosition.e(2, 0);
-        //first, get the sum of momenta...
-        double pxtot = 0;
-        double pytot = 0;
-        double pztot = 0;
-        for (int i = 0; i < _ntracks; i++) {
-            BasicMatrix pi = (BasicMatrix) _pFit.get(i);
-            double theta = pi.e(0, 0);
-            double phiv = pi.e(1, 0);
-            double rho = pi.e(2, 0);
-            double Pt = Math.abs((1. / rho) * _bField * Constants.fieldConversion);
-            double px = Pt * Math.cos(phiv);
-            double py = Pt * Math.sin(phiv);
-            double pz = Pt * 1 / Math.tan(theta);
-            pxtot += px;
-            pytot += py;
-            pztot += pz;
-        }
+        return Hk;
+    }
+
+    private BasicMatrix makeRk(double Vx, double Vy, double Vz, double pxtot, double pytot, double pztot, boolean bscon) {
         //calculate the position of the A' at X=0
         BasicMatrix rk = new BasicMatrix(3, 1);
-        //       if(_debug)System.out.println("Vx = " + Vx + "; Vy = " + Vy + "; Vz = " + Vz + "; pxtot = " + pxtot + "; pytot = " + pytot + "; pztot = " + pztot);
-        rk.setElement(0, 0, -Vx);
-        rk.setElement(1, 0, -Vy);
-        rk.setElement(2, 0, -Vz);
-
-//  ok, can set the derivitives wrt to V
-        Hk.setElement(0, 0, 1);
-        Hk.setElement(0, 1, 0);
-        Hk.setElement(0, 2, 0);
-        Hk.setElement(1, 0, 0);
-        Hk.setElement(1, 1, 1);
-        Hk.setElement(1, 2, 0);
-        Hk.setElement(2, 0, 0);
-        Hk.setElement(2, 1, 0);
-        Hk.setElement(2, 2, 1);
-//ok, loop over tracks again to set the derivitives wrt track momenta (theta,phi,rho)
-        for (int i = 0; i < _ntracks; i++) {
-            BasicMatrix pi = (BasicMatrix) _pFit.get(i);
-            double theta = pi.e(0, 0);
-            double phiv = pi.e(1, 0);
-            double rho = pi.e(2, 0);
-            double Pt = Math.abs((1. / rho) * _bField * Constants.fieldConversion);
-            double px = Pt * Math.cos(phiv);
-            double py = Pt * Math.sin(phiv);
-            double pz = Pt * 1 / Math.tan(theta);
-            //derivities wrt theta
-            Hk.setElement(3 * (i + 1), 0, 0);
-            Hk.setElement(3 * (i + 1), 1, 0);
-            Hk.setElement(3 * (i + 1), 2, 0);
-            //derivities wrt phi
-            Hk.setElement(3 * (i + 1) + 1, 0, 0);
-            Hk.setElement(3 * (i + 1) + 1, 1,
-                    0);
-            Hk.setElement(3 * (i + 1) + 1, 2, 0);
-            //derivities wrt rho
-            Hk.setElement(3 * (i + 1) + 2, 0, 0);
-//            Hk.setElement(3 * (i + 1) + 2, 1,
-//                    (pytot / pxtot - 1) * (Pt / rho) * (1 / pxtot) * Vx);
-//            Hk.setElement(3 * (i + 1) + 2, 2,
-//                    (pztot / pxtot - 1) * (Pt / rho) * (1 / pxtot) * Vx);
-            Hk.setElement(3 * (i + 1) + 2, 1,
-                    0);
-            Hk.setElement(3 * (i + 1) + 2, 2,
-                    0);
-            //                   if(_debug)System.out.println("pxtot = "+pxtot+"; rho = "+rho+"; Pt = "+Pt);
-            //                   if(_debug)System.out.println("cos(phiv)*pytot / pxtot - sin(phiv) = "+(cos(phiv)*pytot / pxtot - sin(phiv)));
-            //                   if(_debug)System.out.println("Pt/(rho*pxtot) = "+(Pt / rho) * (1 / pxtot));
-        }
-        // the beam covariance
-        BasicMatrix Vk = new BasicMatrix(3, 3);
-        Vk.setElement(0, 0, _beamSize[0] * _beamSize[0]);
-        Vk.setElement(1, 1, _beamSize[1] * _beamSize[1]);
-        Vk.setElement(2, 2, _beamSize[2] * _beamSize[2]);
-
-        //now do the matrix operations to get the constrained parameters
-        BasicMatrix Hkt = (BasicMatrix) MatrixOp.transposed(Hk);
-//         if(_debug)System.out.println("Ckm1Hk = " + MatrixOp.mult(Ckm1, Hk));
-
-        BasicMatrix Rk = (BasicMatrix) MatrixOp.mult(Hkt, MatrixOp.mult(Ckm1, Hk));
-//        if(_debug)System.out.println("Pre Vk:  Rk = " + Rk.toString());
-        Rk = (BasicMatrix) MatrixOp.add(Rk, Vk);
-        BasicMatrix Rkinv = (BasicMatrix) MatrixOp.inverse(Rk);
-        BasicMatrix Kk = (BasicMatrix) MatrixOp.mult(Ckm1, MatrixOp.mult(Hk, Rkinv));
-
-//        if(_debug)System.out.println("Ckm1 = " + Ckm1.toString());
-//        if(_debug)System.out.println("Hk = " + Hk.toString());
-//        if(_debug)System.out.println("Rk = " + Rk.toString());
-//        if(_debug)System.out.println("Vk = " + Vk.toString());
-//        if(_debug)System.out.println("rk = " + rk.toString());
-//        if(_debug)System.out.println("Kk = " + Kk.toString());
-        _constrainedFit = MatrixOp.mult(Kk, rk);
-        _constrainedFit = MatrixOp.add(_constrainedFit, Xkm1);//Xk
-
-        //ok, get the new covariance
-        BasicMatrix RkKkt = (BasicMatrix) MatrixOp.mult(Rk, MatrixOp.transposed(Kk));
-        BasicMatrix HkCkm1 = (BasicMatrix) MatrixOp.mult(Hkt, Ckm1);
-        RkKkt = (BasicMatrix) MatrixOp.mult(1, RkKkt);
-        HkCkm1 = (BasicMatrix) MatrixOp.mult(-2, HkCkm1);
-        BasicMatrix sumMatrix = (BasicMatrix) MatrixOp.mult(Kk, MatrixOp.add(HkCkm1, RkKkt));
-        _constrainedCov = (BasicMatrix) MatrixOp.add(Ckm1, sumMatrix);
-
-        //update the regular parameter names to the constrained result
-//        if(_debug)System.out.println("Without Constraint : " + _vertexPosition.toString());
-//        if(_debug)System.out.println("Without Constraint:  x= "+_vertexPosition.e(0,0));
-        //        if(_debug)System.out.println(_constrainedFit.toString());
-//         if(_debug)System.out.println("Without Constraint : " + _covVtx.toString());
-        _vertexPosition = (BasicMatrix) MatrixOp.getSubMatrix(_constrainedFit, 0, 0, 3, 1);
-        _covVtx = (BasicMatrix) MatrixOp.getSubMatrix(_constrainedCov, 0, 0, 3, 3);
-//        if(_debug)System.out.println("With Constraint : " + _vertexPosition.toString());
-//        if(_debug)System.out.println("With Constraint : " + _covVtx.toString());
-
-        for (int i = 0; i < _ntracks; i++) {
-            BasicMatrix ptmp = (BasicMatrix) MatrixOp.getSubMatrix(_constrainedFit, 3 * (i + 1), 0, 3, 1);
-            _pFit.set(i, ptmp);
-        }
-
-//        if(_debug)System.out.println("Unconstrained chi^2 = "+_chiSq);
-        //ok...add to the chi^2
-        if (_debug)
-            System.out.println(MatrixOp.mult(MatrixOp.transposed(rk), MatrixOp.mult(Rkinv, rk)));
-        _chiSq += MatrixOp.mult(MatrixOp.transposed(rk), MatrixOp.mult(Rkinv, rk)).e(0, 0);
-//        if(_debug)System.out.println("Constrained chi^2 = "+_chiSq);
+        if (_debug) {
+            System.out.println("makeRk::Vx = " + Vx + "; Vy = " + Vy + "; Vz = " + Vz + "; pxtot = " + pxtot + "; pytot = " + pytot + "; pztot = " + pztot);
+        }
+        if (bscon) {
+            rk.setElement(0, 0, 0);
+            rk.setElement(1, 0, _beamPosition[1] - (Vy - pytot / pxtot * (Vx - _beamPosition[0])));
+            rk.setElement(2, 0, _beamPosition[2] - (Vz - pztot / pxtot * (Vx - _beamPosition[0])));
+        } else {
+            rk.setElement(0, 0, _beamPosition[0] - Vx);
+            rk.setElement(1, 0, _beamPosition[1] - Vy);
+            rk.setElement(2, 0, _beamPosition[2] - Vz);
+        }
+        return rk;
     }
 
     public void setV0(double[] v0) {
@@ -716,15 +324,23 @@
         _beamSize[2] = bs[2];
     }
 
+    public void setBeamPosition(double[] bp) {
+        _beamPosition[0] = bp[0];
+        _beamPosition[1] = bp[1];
+        _beamPosition[2] = bp[2];
+    }
+
     public void doBeamSpotConstraint(boolean bsconst) {
         _beamspotConstraint = bsconst;
-         _constraintType="BeamspotConstrained";
-        
+        _targetConstraint = false;
+        _constraintType = "BeamspotConstrained";
+
     }
 
     public void doTargetConstraint(boolean bsconst) {
+        _beamspotConstraint = false;
         _targetConstraint = bsconst;
-         _constraintType="TargetConstrained";
+        _constraintType = "TargetConstrained";
     }
 
     public double getChiSq() {
@@ -742,12 +358,12 @@
         mom[0] = Pt * Math.cos(phiv);
         mom[1] = Pt * Math.sin(phiv);
         mom[2] = Pt * 1 / Math.tan(theta);
-        if (_debug){
-            System.out.println("getFittedMomentum::  "+mom[0] + "; " + mom[1] + "; " + mom[2]);
-
-            System.out.println("pT= "+Pt+"; phi = "+phiv+"; B = "+ _bField);
-        }
-      return mom;
+        if (_debug) {
+            System.out.println("getFittedMomentum::  " + mom[0] + "; " + mom[1] + "; " + mom[2]);
+
+            System.out.println("pT= " + Pt + "; phi = " + phiv + "; B = " + _bField);
+        }
+        return mom;
     }
 
     private double getInvMass() {
@@ -772,15 +388,17 @@
         double psum = Math.sqrt(pxsum * pxsum + pysum * pysum + pzsum * pzsum);
         double evtmass = esum * esum - psum * psum;
 
-        if (evtmass > 0)
+        if (evtmass > 0) {
             return Math.sqrt(evtmass);
-        else
+        } else {
             return -99;
-    }
-
+        }
+    }
+
+    @Override
     public String toString() {
-        StringBuffer sb = new StringBuffer("Vertex at : \nx= " + _vertexPosition.e(0, 0) + " +/- " + Math.sqrt(_covVtx.e(0, 0)) + "\ny= " + _vertexPosition.e(1, 0) + " +/- " + Math.sqrt(_covVtx.e(1, 1)) + "\nz= " + _vertexPosition.e(2, 0) + " +/- " + Math.sqrt(_covVtx.e(2, 2)));
-        return sb.toString();
+        String sb = "Vertex at : \nx= " + _vertexPosition.e(0, 0) + " +/- " + Math.sqrt(_covVtx.e(0, 0)) + "\ny= " + _vertexPosition.e(1, 0) + " +/- " + Math.sqrt(_covVtx.e(1, 1)) + "\nz= " + _vertexPosition.e(2, 0) + " +/- " + Math.sqrt(_covVtx.e(2, 2));
+        return sb;
     }
 
     private void follow1985Paper(List<BilliorTrack> tracks) {
@@ -789,8 +407,8 @@
         v0.setElement(0, 0, _v0[0]);
         v0.setElement(1, 0, _v0[1]);
         v0.setElement(2, 0, _v0[2]);
-        List<Matrix> params = new ArrayList<Matrix>();
-        List<Matrix> q0s = new ArrayList<Matrix>();
+//        List<Matrix> params = new ArrayList<Matrix>();
+//        List<Matrix> q0s = new ArrayList<Matrix>();
         List<Matrix> Gs = new ArrayList<Matrix>();
         List<Matrix> Ds = new ArrayList<Matrix>();
         List<Matrix> Es = new ArrayList<Matrix>();
@@ -809,13 +427,11 @@
             tmpPar.setElement(2, 0, par[2]);
             tmpPar.setElement(3, 0, par[3]);
             tmpPar.setElement(4, 0, par[4]);
-            params.add(tmpPar);
+//            params.add(tmpPar);
             double theta = par[2];
-            double phiv = par[3];
+//            double phiv = par[3];
             double rho = par[4];
-            double Pt = Math.abs((1. / rho) * _bField * Constants.fieldConversion);
-
-
+//            double Pt = Math.abs((1. / rho) * _bField * Constants.fieldConversion);
 
             double cotth = 1. / tan(par[2]);
             double uu = v0.e(0, 0) * cos(par[3]) + v0.e(1, 0) * sin(par[3]);//Q
@@ -833,15 +449,15 @@
 
             BasicMatrix q0 = new BasicMatrix(3, 1);
             /*   this looks just wrong...
-            q0.setElement(0, 0, Pt * Math.cos(phiv));
-            q0.setElement(1, 0, Pt * Math.sin(phiv));
-            q0.setElement(2, 0, Pt * 1 / Math.tan(theta));
-            q0s.add(q0);
+             q0.setElement(0, 0, Pt * Math.cos(phiv));
+             q0.setElement(1, 0, Pt * Math.sin(phiv));
+             q0.setElement(2, 0, Pt * 1 / Math.tan(theta));
+             q0s.add(q0);
              */
             q0.setElement(0, 0, theta);
             q0.setElement(1, 0, phiVert);
             q0.setElement(2, 0, rho);
-            q0s.add(q0);
+//            q0s.add(q0);
 
             double cosf = cos(phiVert);
             double sinf = sin(phiVert);
@@ -875,10 +491,11 @@
             BasicMatrix tmpG = (BasicMatrix) MatrixOp.inverse(bt.covariance());
             Gs.add(tmpG);
 
-            if (firstTrack)
+            if (firstTrack) {
                 D0 = (BasicMatrix) MatrixOp.mult(MatrixOp.transposed(tmpA), MatrixOp.mult(tmpG, tmpA));
-            else
+            } else {
                 D0 = (BasicMatrix) MatrixOp.add(D0, MatrixOp.mult(MatrixOp.transposed(tmpA), MatrixOp.mult(tmpG, tmpA)));
+            }
 
             BasicMatrix tmpDi = (BasicMatrix) MatrixOp.mult(MatrixOp.transposed(tmpA), MatrixOp.mult(tmpG, tmpB));
             BasicMatrix tmpEi = (BasicMatrix) MatrixOp.mult(MatrixOp.transposed(tmpB), MatrixOp.mult(tmpG, tmpB));
@@ -904,19 +521,21 @@
             BasicMatrix beIbTg = (BasicMatrix) MatrixOp.mult(b, MatrixOp.mult(MatrixOp.inverse(e), MatrixOp.mult(MatrixOp.transposed(b), g)));
             BasicMatrix MinusaTgbeIbTg = (BasicMatrix) MatrixOp.mult(-1, MatrixOp.mult(aTg, beIbTg));
 
-            if (firstTrack)
+            if (firstTrack) {
                 bigsum = (BasicMatrix) MatrixOp.mult(MatrixOp.add(aTg, MinusaTgbeIbTg), p);
-            else
+            } else {
                 bigsum = (BasicMatrix) MatrixOp.add(bigsum, MatrixOp.mult(MatrixOp.add(aTg, MinusaTgbeIbTg), p));
+            }
         }
         BasicMatrix covVtx = (BasicMatrix) MatrixOp.inverse(tmpCovVtx);
         BasicMatrix xtilde = (BasicMatrix) MatrixOp.mult(covVtx, bigsum);
-        if (_debug)
+        if (_debug) {
             System.out.println("follow1985Paper::Vertex at : \nx= " + xtilde.e(0, 0) + " +/- " + Math.sqrt(covVtx.e(0, 0)) + "\ny= " + xtilde.e(1, 0) + " +/- " + Math.sqrt(covVtx.e(1, 1)) + "\nz= " + xtilde.e(2, 0) + " +/- " + Math.sqrt(covVtx.e(2, 2)));
+        }
 
         //ok, now the momentum
-        List<Matrix> qtildes = new ArrayList<Matrix>();
-        List<Matrix> ptildes = new ArrayList<Matrix>();
+//        List<Matrix> qtildes = new ArrayList<Matrix>();
+//        List<Matrix> ptildes = new ArrayList<Matrix>();
         List<Matrix> C0j = new ArrayList<Matrix>();
         List<Matrix> pfit = new ArrayList<Matrix>();
         Matrix[][] Cij = new Matrix[2][2];//max 2 tracks...just make this bigger for more
@@ -934,32 +553,38 @@
             BasicMatrix second = (BasicMatrix) MatrixOp.mult(MatrixOp.inverse(e), MatrixOp.mult(MatrixOp.transposed(b), g));
             second = (BasicMatrix) MatrixOp.mult(second, p);
             BasicMatrix qtilde = (BasicMatrix) MatrixOp.add(first, second);
-            qtildes.add(qtilde);
+//            qtildes.add(qtilde);
             BasicMatrix ptilde = (BasicMatrix) MatrixOp.add(MatrixOp.mult(a, xtilde), MatrixOp.mult(b, qtilde));
-            ptildes.add(ptilde);
+//            ptildes.add(ptilde);
             chisq += MatrixOp.mult(MatrixOp.transposed(MatrixOp.add(p, MatrixOp.mult(-1, ptilde))), MatrixOp.mult(g, MatrixOp.add(p, MatrixOp.mult(-1, ptilde)))).e(0, 0);
-            if (_debug)
+            if (_debug) {
                 System.out.println("\n\nfollow1985Paper::Track #" + j);
-            if (_debug)
+            }
+            if (_debug) {
                 System.out.println("eps(meas)    = " + p.e(0, 0) + "        eps(fit)   =" + ptilde.e(0, 0));
-            if (_debug)
+            }
+            if (_debug) {
                 System.out.println("zp(meas)     = " + p.e(1, 0) + "        zp(fit)    =" + ptilde.e(1, 0));
-            if (_debug)
+            }
+            if (_debug) {
                 System.out.println("theta(meas)  = " + p.e(2, 0) + "        theta(fit) =" + ptilde.e(2, 0));
-            if (_debug)
+            }
+            if (_debug) {
                 System.out.println("phi(meas)    = " + p.e(3, 0) + "        phi(fit)   =" + ptilde.e(3, 0));
-            if (_debug)
+            }
+            if (_debug) {
                 System.out.println("rho(meas)    = " + p.e(4, 0) + "        rho(fit)   =" + ptilde.e(4, 0));
+            }
 
             BasicMatrix tmpC0j = (BasicMatrix) MatrixOp.mult(-1, MatrixOp.mult(covVtx, MatrixOp.mult(d, MatrixOp.inverse(e))));
             C0j.add(tmpC0j);
             for (int i = 0; i < _ntracks; i++) {
-                BasicMatrix ai = (BasicMatrix) As.get(i);
-                BasicMatrix bi = (BasicMatrix) Bs.get(i);
-                BasicMatrix di = (BasicMatrix) Ds.get(i);
-                BasicMatrix ei = (BasicMatrix) Es.get(i);
-                BasicMatrix gi = (BasicMatrix) Gs.get(i);
-                BasicMatrix pi = (BasicMatrix) pis.get(i);
+//                BasicMatrix ai = (BasicMatrix) As.get(i);
+//                BasicMatrix bi = (BasicMatrix) Bs.get(i);
+//                BasicMatrix di = (BasicMatrix) Ds.get(i);
+//                BasicMatrix ei = (BasicMatrix) Es.get(i);
+//                BasicMatrix gi = (BasicMatrix) Gs.get(i);
+//                BasicMatrix pi = (BasicMatrix) pis.get(i);
                 BasicMatrix tmpCij = (BasicMatrix) MatrixOp.mult(-1, MatrixOp.mult(MatrixOp.inverse(e), MatrixOp.mult(MatrixOp.transposed(d), tmpC0j)));
                 Cij[i][j] = tmpCij;
             }
@@ -970,8 +595,9 @@
             pfit.add(tmppfit);
         }
 
-        if (_debug)
+        if (_debug) {
             System.out.println("follow1985Paper::chi^2 = " + chisq);
+        }
 
         _chiSq = chisq;
         _covVtx = covVtx;

Modified: java/branches/HPSJAVA-409/recon/src/main/java/org/hps/recon/vertexing/TwoLineVertexer.java
 =============================================================================
--- java/branches/HPSJAVA-409/recon/src/main/java/org/hps/recon/vertexing/TwoLineVertexer.java	(original)
+++ java/branches/HPSJAVA-409/recon/src/main/java/org/hps/recon/vertexing/TwoLineVertexer.java	Wed Apr 27 11:11:32 2016
@@ -20,21 +20,21 @@
  */
 public class TwoLineVertexer extends BaseSimpleVertexer {
     protected Hep3Vector A1,A2,B1,B2;
-	
-	public TwoLineVertexer() {
-		
-	}
-	
+    
+    public TwoLineVertexer() {
+        
+    }
+    
     public void setLines(Hep3Vector PA1, Hep3Vector PA2, Hep3Vector PB1, Hep3Vector PB2) {
-    	this.A1 = PA1;
-    	this.A2 = PA2;
-    	this.B1 = PB1;
-    	this.B2 = PB2;
+        this.A1 = PA1;
+        this.A2 = PA2;
+        this.B1 = PB1;
+        this.B2 = PB2;
     }
   
     public void clear() {
-    	super.clear();
-    	setLines(null,null,null,null);
+        super.clear();
+        setLines(null,null,null,null);
     }
     
     public boolean isValid() {
@@ -44,11 +44,11 @@
     
     @Override
     public void fitVertex() {
-    	assert isValid();
-    	Hep3Vector vtxPosition = getPOCALineToLine();
-		if (vtxPosition!=null) {
-			_fitted_vertex = new BaseVertex(true, "Two Line Vertexer", 0, 0, new SymmetricMatrix(0), vtxPosition, null); 
-    	}
+        assert isValid();
+        Hep3Vector vtxPosition = getPOCALineToLine();
+        if (vtxPosition!=null) {
+            _fitted_vertex = new BaseVertex(true, "Two Line Vertexer", 0, 0, new SymmetricMatrix(0), vtxPosition, null); 
+        }
     }
     
     /**
@@ -94,57 +94,57 @@
      */
     private Hep3Vector getPOCALineToLine() {
 
-		if(_debug) System.out.printf("%s: A1=%s A2=%s B1=%s B2=%s\n", this.getClass().getSimpleName(), A1.toString(), A2.toString(), B1.toString(), B2.toString());
+        if(_debug) System.out.printf("%s: A1=%s A2=%s B1=%s B2=%s\n", this.getClass().getSimpleName(), A1.toString(), A2.toString(), B1.toString(), B2.toString());
 
-    	double ya[][] = {VecOp.mult(-1,VecOp.sub(B1, A1)).v()};
-    	BasicMatrix y = (BasicMatrix)MatrixOp.transposed(new BasicMatrix(ya));
-    	Hep3Vector dB = VecOp.sub(B2, B1);
-    	Hep3Vector dA = VecOp.sub(A2, A1);
-    	BasicMatrix X = new BasicMatrix(3,2);
-    	for(int col=0;col<2;++col) {
-    		if(col==0) {
-    			X.setElement(0, col, dB.x());
-    			X.setElement(1, col, dB.y());
-    			X.setElement(2, col, dB.z());
-    		} else {
-    			X.setElement(0, col, -1*dA.x());
-    			X.setElement(1, col, -1*dA.y());
-    			X.setElement(2, col, -1*dA.z());
-    		}
-    	}
+        double ya[][] = {VecOp.mult(-1,VecOp.sub(B1, A1)).v()};
+        BasicMatrix y = (BasicMatrix)MatrixOp.transposed(new BasicMatrix(ya));
+        Hep3Vector dB = VecOp.sub(B2, B1);
+        Hep3Vector dA = VecOp.sub(A2, A1);
+        BasicMatrix X = new BasicMatrix(3,2);
+        for(int col=0;col<2;++col) {
+            if(col==0) {
+                X.setElement(0, col, dB.x());
+                X.setElement(1, col, dB.y());
+                X.setElement(2, col, dB.z());
+            } else {
+                X.setElement(0, col, -1*dA.x());
+                X.setElement(1, col, -1*dA.y());
+                X.setElement(2, col, -1*dA.z());
+            }
+        }
 
-    	BasicMatrix X_T = (BasicMatrix)MatrixOp.transposed(X);
-    	BasicMatrix XX_T = (BasicMatrix)MatrixOp.mult(X_T, X);
-		BasicMatrix IXX_T = null;
-		try {
-			IXX_T = (BasicMatrix)MatrixOp.inverse(XX_T);
-		} 
-		catch(MatrixOp.IndeterminateMatrixException e) {
-			System.out.printf("%s: caught indeterminate exception %s\n",this.getClass().getSimpleName(),e.getMessage());
-			return null;
-		}
-    	BasicMatrix X_Ty = (BasicMatrix)MatrixOp.mult(X_T,y);
-    	BasicMatrix b = (BasicMatrix)MatrixOp.mult(IXX_T, X_Ty);
-    	double t = b.e(0, 0);
-    	double s = b.e(1, 0);
-    	Hep3Vector Bpca = VecOp.add(B1, VecOp.mult(t, dB));
-    	Hep3Vector Apca = VecOp.add(A1, VecOp.mult(s, dA));
+        BasicMatrix X_T = (BasicMatrix)MatrixOp.transposed(X);
+        BasicMatrix XX_T = (BasicMatrix)MatrixOp.mult(X_T, X);
+        BasicMatrix IXX_T = null;
+        try {
+            IXX_T = (BasicMatrix)MatrixOp.inverse(XX_T);
+        } 
+        catch(MatrixOp.IndeterminateMatrixException e) {
+            System.out.printf("%s: caught indeterminate exception %s\n",this.getClass().getSimpleName(),e.getMessage());
+            return null;
+        }
+        BasicMatrix X_Ty = (BasicMatrix)MatrixOp.mult(X_T,y);
+        BasicMatrix b = (BasicMatrix)MatrixOp.mult(IXX_T, X_Ty);
+        double t = b.e(0, 0);
+        double s = b.e(1, 0);
+        Hep3Vector Bpca = VecOp.add(B1, VecOp.mult(t, dB));
+        Hep3Vector Apca = VecOp.add(A1, VecOp.mult(s, dA));
         Hep3Vector vertex = VecOp.add(Apca, VecOp.mult(0.5, VecOp.sub(Bpca, Apca)));
-    	if(_debug) {
-    		System.out.printf("y:\n%s\n",y.toString());
-    		System.out.printf("X:\n%s\n",X.toString());
-    		System.out.printf("b:\n%s\n",b.toString());
-        	Hep3Vector ymin = VecOp.add(VecOp.mult(t, dB) , VecOp.mult(s, dA) );
-        	Hep3Vector yminprime = VecOp.add(VecOp.sub(B1, A1), ymin);
-        	System.out.printf("ymin:\n%s\n",ymin.toString());
-        	System.out.printf("yminprime:\n%s\n",yminprime.toString());
-        	System.out.printf("Apca:\n%s\n",Apca.toString());
-        	System.out.printf("Bpca:\n%s\n",Bpca.toString());
-        	System.out.printf("vertex:\n%s\n",vertex.toString());
-    	}
-    	return vertex;
-    	
-    	
+        if(_debug) {
+            System.out.printf("y:\n%s\n",y.toString());
+            System.out.printf("X:\n%s\n",X.toString());
+            System.out.printf("b:\n%s\n",b.toString());
+            Hep3Vector ymin = VecOp.add(VecOp.mult(t, dB) , VecOp.mult(s, dA) );
+            Hep3Vector yminprime = VecOp.add(VecOp.sub(B1, A1), ymin);
+            System.out.printf("ymin:\n%s\n",ymin.toString());
+            System.out.printf("yminprime:\n%s\n",yminprime.toString());
+            System.out.printf("Apca:\n%s\n",Apca.toString());
+            System.out.printf("Bpca:\n%s\n",Bpca.toString());
+            System.out.printf("vertex:\n%s\n",vertex.toString());
+        }
+        return vertex;
+        
+        
     }
 
     

Modified: java/branches/HPSJAVA-409/recon/src/main/java/org/hps/recon/vertexing/TwoParticleVertexer.java
 =============================================================================
--- java/branches/HPSJAVA-409/recon/src/main/java/org/hps/recon/vertexing/TwoParticleVertexer.java	(original)
+++ java/branches/HPSJAVA-409/recon/src/main/java/org/hps/recon/vertexing/TwoParticleVertexer.java	Wed Apr 27 11:11:32 2016
@@ -18,7 +18,7 @@
  */
 public class TwoParticleVertexer extends TwoLineVertexer {
     
-	public TwoParticleVertexer() {
+    public TwoParticleVertexer() {
     }
     public void setParticle(MCParticle track1,MCParticle track2) {
         
@@ -34,8 +34,8 @@
         Hep3Vector PB2 = this.propAlongLine(PB1, p2, dz);
         
         if(_debug) {
-        	System.out.printf("A1 %s p1 %s B1 %s p2 %s\n", PA1.toString(), p1.toString(), PB1.toString(), p2.toString());
-        	System.out.printf("A2 %s B2 %s\n", PA2.toString(), PB2.toString());
+            System.out.printf("A1 %s p1 %s B1 %s p2 %s\n", PA1.toString(), p1.toString(), PB1.toString(), p2.toString());
+            System.out.printf("A2 %s B2 %s\n", PA2.toString(), PB2.toString());
         }
         
         //set the member variables

Modified: java/branches/HPSJAVA-409/recon/src/main/java/org/hps/recon/vertexing/TwoTrackFringeVertexer.java
 =============================================================================
--- java/branches/HPSJAVA-409/recon/src/main/java/org/hps/recon/vertexing/TwoTrackFringeVertexer.java	(original)
+++ java/branches/HPSJAVA-409/recon/src/main/java/org/hps/recon/vertexing/TwoTrackFringeVertexer.java	Wed Apr 27 11:11:32 2016
@@ -4,14 +4,14 @@
 import hep.physics.vec.Hep3Vector;
 
 import org.hps.recon.tracking.BeamlineConstants;
-import org.hps.recon.tracking.HPSTrack;
+import org.hps.recon.tracking.HpsHelicalTrackFit;
 import org.hps.recon.tracking.HelixConverter;
-import org.hps.recon.tracking.StraightLineTrack;
+import org.hps.recon.tracking.TrackUtils;
 import org.lcsim.event.Track;
 import org.lcsim.fit.helicaltrack.HelicalTrackFit;
 import org.lcsim.fit.helicaltrack.HelixUtils;
+import org.lcsim.geometry.FieldMap;
 import org.lcsim.recon.tracking.seedtracker.SeedTrack;
-import org.lcsim.util.swim.Helix;
 
 /**
  * 
@@ -20,38 +20,42 @@
  * @author phansson
  *
  */
+
 public class TwoTrackFringeVertexer extends TwoTrackVertexer {
     protected HelixConverter converter = new HelixConverter(0.);
     
-    public void setTracks(Track track1, Track track2) {
-    	SeedTrack s1 = (SeedTrack) track1;
+    public void setTracks(Track track1, Track track2, FieldMap fieldMap) {
+        SeedTrack s1 = (SeedTrack) track1;
         HelicalTrackFit htf1 = s1.getSeedCandidate().getHelix();
-        HPSTrack hpstrk1 = new HPSTrack(htf1);
+        HpsHelicalTrackFit hpstrk1 = new HpsHelicalTrackFit(htf1);
         SeedTrack s2 = (SeedTrack) track2;
         HelicalTrackFit htf2 = s2.getSeedCandidate().getHelix();
-        HPSTrack hpstrk2 = new HPSTrack(htf2);
+        HpsHelicalTrackFit hpstrk2 = new HpsHelicalTrackFit(htf2);
         boolean debug = false;
+
+        Hep3Vector posAtConv1 = new BasicHep3Vector( TrackUtils.extrapolateTrackUsingFieldMap(track1, 100.0, BeamlineConstants.HARP_POSITION_TESTRUN, 5.0, fieldMap).getReferencePoint());
+        Hep3Vector posAtConv2 = new BasicHep3Vector( TrackUtils.extrapolateTrackUsingFieldMap(track2, 100.0, BeamlineConstants.HARP_POSITION_TESTRUN, 5.0, fieldMap).getReferencePoint());
+
+        //FIXME the straight line objects are not working
         
-        Hep3Vector posAtConv1 = hpstrk1.getPositionAtZMap(100.0, BeamlineConstants.HARP_POSITION_TESTRUN, 5.0)[0];
-        Hep3Vector posAtConv2 = hpstrk2.getPositionAtZMap(100.0, BeamlineConstants.HARP_POSITION_TESTRUN, 5.0)[0];
+        //StraightLineTrack slt1_conv = converter.Convert((Helix)hpstrk1.getTrajectory());
+        //StraightLineTrack slt2_conv = converter.Convert((Helix)hpstrk2.getTrajectory());
+        
+        //A1 = new BasicHep3Vector(slt1_conv.x0(),slt1_conv.y0(),slt1_conv.z0());
+        //B1 = new BasicHep3Vector(slt2_conv.x0(),slt2_conv.y0(),slt2_conv.z0());
 
-        StraightLineTrack slt1_conv = converter.Convert((Helix)hpstrk1.getTrajectory());
-        StraightLineTrack slt2_conv = converter.Convert((Helix)hpstrk2.getTrajectory());
+        //double YZAtConv1[] = slt1_conv.getYZAtX(BeamlineConstants.HARP_POSITION_TESTRUN);
+        //double YZAtConv2[] = slt2_conv.getYZAtX(BeamlineConstants.HARP_POSITION_TESTRUN);
         
-        A1 = new BasicHep3Vector(slt1_conv.x0(),slt1_conv.y0(),slt1_conv.z0());
-        B1 = new BasicHep3Vector(slt2_conv.x0(),slt2_conv.y0(),slt2_conv.z0());
-
-        double YZAtConv1[] = slt1_conv.getYZAtX(BeamlineConstants.HARP_POSITION_TESTRUN);
-        double YZAtConv2[] = slt2_conv.getYZAtX(BeamlineConstants.HARP_POSITION_TESTRUN);
+        //A2 = new BasicHep3Vector(BeamlineConstants.HARP_POSITION_TESTRUN,YZAtConv1[0],YZAtConv1[1]);
+        //B2 = new BasicHep3Vector(BeamlineConstants.HARP_POSITION_TESTRUN,YZAtConv2[0],YZAtConv2[1]);
         
-        A2 = new BasicHep3Vector(BeamlineConstants.HARP_POSITION_TESTRUN,YZAtConv1[0],YZAtConv1[1]);
-        B2 = new BasicHep3Vector(BeamlineConstants.HARP_POSITION_TESTRUN,YZAtConv2[0],YZAtConv2[1]);
         
         if(debug) {
             System.out.printf("%s: original track1 direction at x=0 %s  \n",this.getClass().getSimpleName(),HelixUtils.Direction(hpstrk1,0.).toString());
             System.out.printf("%s: original track2 direction at x=0 %s  \n",this.getClass().getSimpleName(),HelixUtils.Direction(hpstrk2,0.).toString());
-            System.out.printf("%s: track1 direction at conv %s  \n",this.getClass().getSimpleName(),hpstrk1.getTrajectory().getUnitTangentAtLength(0.).toString());
-            System.out.printf("%s: track2 direction at conv %s  \n",this.getClass().getSimpleName(),hpstrk2.getTrajectory().getUnitTangentAtLength(0.).toString());
+            //System.out.printf("%s: track1 direction at conv %s  \n",this.getClass().getSimpleName(),hpstrk1.getTrajectory().getUnitTangentAtLength(0.).toString());
+            //System.out.printf("%s: track2 direction at conv %s  \n",this.getClass().getSimpleName(),hpstrk2.getTrajectory().getUnitTangentAtLength(0.).toString());
            
             
             System.out.printf("%s: pos at converter track1 %s  \n",this.getClass().getSimpleName(),posAtConv1.toString());
@@ -67,5 +71,5 @@
     }
     
     
-	
+    
 }

Modified: java/branches/HPSJAVA-409/recon/src/test/java/org/hps/recon/particle/HpsReconParticleDriverTest.java
 =============================================================================
--- java/branches/HPSJAVA-409/recon/src/test/java/org/hps/recon/particle/HpsReconParticleDriverTest.java	(original)
+++ java/branches/HPSJAVA-409/recon/src/test/java/org/hps/recon/particle/HpsReconParticleDriverTest.java	Wed Apr 27 11:11:32 2016
@@ -26,165 +26,165 @@
  */
 public class HpsReconParticleDriverTest extends TestCase { 
 
-	private static final double B_FIELD = 0.5; // Tesla
-  	double[] trackParameters = new double[5];
- 	List<Track> tracks = new ArrayList<Track>(); 
-	List<Cluster> clusters = new ArrayList<Cluster>();
-	List<ReconstructedParticle> particleTracks; 
-	HpsReconParticleDriver particleDriver = null; 
-	
-   	public void setUp() throws Exception {
-   		
-   		System.out.println("\n#=== Creating Ideal Tracks ===#\n");
+    private static final double B_FIELD = 0.5; // Tesla
+    double[] trackParameters = new double[5];
+    List<Track> tracks = new ArrayList<Track>(); 
+    List<Cluster> clusters = new ArrayList<Cluster>();
+    List<ReconstructedParticle> particleTracks; 
+    HpsReconParticleDriver particleDriver = null; 
+    
+    public void setUp() throws Exception {
+        
+        System.out.println("\n#=== Creating Ideal Tracks ===#\n");
    
-   		// Create a pair of ideal e+e- tracks in opposite detector volumes.
-   		// The e+ track is created on the bottom half of the detector while
-   		// the e- track is created on the top half.
-   		Track electronTrack = new BaseTrack(); 
-   		trackParameters[BaseTrack.D0] = 0.41051;
-   		trackParameters[BaseTrack.OMEGA] = -2.2584e-4; 
-   		trackParameters[BaseTrack.PHI] = 6.2626; 
-   		trackParameters[BaseTrack.TANLAMBDA] = 0.046548; 
-   		trackParameters[BaseTrack.Z0] = .23732; 
-   		((BaseTrack) electronTrack).setTrackParameters(trackParameters, B_FIELD);
-   		
-   		System.out.println("\n[ Track ] Electron:  \n" + electronTrack.toString());
-   		
-   		Track positronTrack = new BaseTrack();
-   		trackParameters[BaseTrack.D0] = 0.19691;
-   		trackParameters[BaseTrack.OMEGA] = 1.005e-4; 
-   		trackParameters[BaseTrack.PHI] = 6.2447; 
-   		trackParameters[BaseTrack.TANLAMBDA] = -0.024134; 
-   		trackParameters[BaseTrack.Z0] = -0.040231; 
-   		((BaseTrack) positronTrack).setTrackParameters(trackParameters, B_FIELD);
+        // Create a pair of ideal e+e- tracks in opposite detector volumes.
+        // The e+ track is created on the bottom half of the detector while
+        // the e- track is created on the top half.
+        Track electronTrack = new BaseTrack(); 
+        trackParameters[BaseTrack.D0] = 0.41051;
+        trackParameters[BaseTrack.OMEGA] = -2.2584e-4; 
+        trackParameters[BaseTrack.PHI] = 6.2626; 
+        trackParameters[BaseTrack.TANLAMBDA] = 0.046548; 
+        trackParameters[BaseTrack.Z0] = .23732; 
+        ((BaseTrack) electronTrack).setTrackParameters(trackParameters, B_FIELD);
+        
+        System.out.println("\n[ Track ] Electron:  \n" + electronTrack.toString());
+        
+        Track positronTrack = new BaseTrack();
+        trackParameters[BaseTrack.D0] = 0.19691;
+        trackParameters[BaseTrack.OMEGA] = 1.005e-4; 
+        trackParameters[BaseTrack.PHI] = 6.2447; 
+        trackParameters[BaseTrack.TANLAMBDA] = -0.024134; 
+        trackParameters[BaseTrack.Z0] = -0.040231; 
+        ((BaseTrack) positronTrack).setTrackParameters(trackParameters, B_FIELD);
 
-   		System.out.println("\n[ Track ] Positron: \n" + positronTrack.toString());
+        System.out.println("\n[ Track ] Positron: \n" + positronTrack.toString());
 
-   		// Add the tracks to the list of tracks that will be used for test
-   		// purposes.
-   		tracks.add(electronTrack);
-   		tracks.add(positronTrack);
-   		
-   		System.out.println("\n#=== Creating Ideal Ecal Clusters ===#\n");
-   		
-   		// Create a pair of ideal clusters to match the e+e- pairs created
-   		// above.  Since the properties of a cluster cannot be modified 
-   		// directly via setter methods, first create a CalorimeterHit and
-   		// then use that to create a cluster.
-   		//Hep3Vector topHitPosition = new BasicHep3Vector(190.27, 69.729, 1422.8);
-   		//BaseCalorimeterHit topHit 
-   		//	= new BaseCalorimeterHit(.4600, .4600, 0, 0, 0, topHitPosition, 0);
-   		
-   		//System.out.println("\n[ Calorimeter Hit ] Top: \n" + topHit.toString());
-   		
-   		Cluster topCluster = new BaseCluster();
-   		//((BaseCluster) topCluster).addHit(topHit);
-   		
-   		
-   		System.out.print("\n[ Cluster ] Top: " + topCluster.toString());
-   		System.out.println(" and position= ["  + topCluster.getPosition()[0] + ", " 
-   											   + topCluster.getPosition()[1] + ", " 
-   											   + topCluster.getPosition()[2] + " ]");
-   		
-   		//Hep3Vector bottomHitPosition = new BasicHep3Vector(-148.46, -39.27, 1430.5);
-   		//BaseCalorimeterHit bottomHit 
-   		//	= new BaseCalorimeterHit(1.1420, 1.1420, 0, 0, 0, bottomHitPosition, 0);
+        // Add the tracks to the list of tracks that will be used for test
+        // purposes.
+        tracks.add(electronTrack);
+        tracks.add(positronTrack);
+        
+        System.out.println("\n#=== Creating Ideal Ecal Clusters ===#\n");
+        
+        // Create a pair of ideal clusters to match the e+e- pairs created
+        // above.  Since the properties of a cluster cannot be modified 
+        // directly via setter methods, first create a CalorimeterHit and
+        // then use that to create a cluster.
+        //Hep3Vector topHitPosition = new BasicHep3Vector(190.27, 69.729, 1422.8);
+        //BaseCalorimeterHit topHit 
+        //  = new BaseCalorimeterHit(.4600, .4600, 0, 0, 0, topHitPosition, 0);
+        
+        //System.out.println("\n[ Calorimeter Hit ] Top: \n" + topHit.toString());
+        
+        Cluster topCluster = new BaseCluster();
+        //((BaseCluster) topCluster).addHit(topHit);
+        
+        
+        System.out.print("\n[ Cluster ] Top: " + topCluster.toString());
+        System.out.println(" and position= ["  + topCluster.getPosition()[0] + ", " 
+                                               + topCluster.getPosition()[1] + ", " 
+                                               + topCluster.getPosition()[2] + " ]");
+        
+        //Hep3Vector bottomHitPosition = new BasicHep3Vector(-148.46, -39.27, 1430.5);
+        //BaseCalorimeterHit bottomHit 
+        //  = new BaseCalorimeterHit(1.1420, 1.1420, 0, 0, 0, bottomHitPosition, 0);
 
-   		//System.out.println("\n[ Calorimeter Hit ] Bottom:\n " + bottomHit.toString());
-   		
-   		Cluster bottomCluster = new BaseCluster();
-   		//((BaseCluster) bottomCluster).addHit(bottomHit);
-   		
-   		System.out.print("\n[ Cluster ] bottom: " + bottomCluster.toString());
-   		System.out.println(" and position= [ " + topCluster.getPosition()[0] + ", " 
-   											   + topCluster.getPosition()[1] + ", " 
-   											   + topCluster.getPosition()[2] + " ]");
+        //System.out.println("\n[ Calorimeter Hit ] Bottom:\n " + bottomHit.toString());
+        
+        Cluster bottomCluster = new BaseCluster();
+        //((BaseCluster) bottomCluster).addHit(bottomHit);
+        
+        System.out.print("\n[ Cluster ] bottom: " + bottomCluster.toString());
+        System.out.println(" and position= [ " + topCluster.getPosition()[0] + ", " 
+                                               + topCluster.getPosition()[1] + ", " 
+                                               + topCluster.getPosition()[2] + " ]");
 
-   		// Add the clusters to the list of clusters that will be used for test
-   		// purposes.
-   		clusters.add(topCluster);
-   		clusters.add(bottomCluster);
-   		
-   		particleDriver = new HpsReconParticleDriver();
-   		particleDriver.setDebug(true);
-   	}
-   	
-   	public void testMakeReconstructedParticles(){
-   		
-   		System.out.println("\n#=== Running makeReconstructedParticles Test ===#");
-    	
-    	
-    	// Create two ReconstructedParticles with tracks only
-    	List<Cluster> emptyClusters = new ArrayList<Cluster>(); 
-    	List<List<Track>> trackCollections = new ArrayList<List<Track>>(0);
-    	trackCollections.add(tracks);
-    	particleTracks = particleDriver.makeReconstructedParticles(emptyClusters, trackCollections);
+        // Add the clusters to the list of clusters that will be used for test
+        // purposes.
+        clusters.add(topCluster);
+        clusters.add(bottomCluster);
+        
+        particleDriver = new HpsReconParticleDriver();
+        particleDriver.setDebug(true);
+    }
     
-    	//
-    	// The list contains two Tracks which should result in two 
-    	// ReconstructedParticles.
-    	//
-    	assertTrue("More particles than expected were created.", particleTracks.size() == 2);
-    	System.out.println("\nThe number of ReconstructedParticles created: " + particleTracks.size());
+    public void testMakeReconstructedParticles(){
+        
+        System.out.println("\n#=== Running makeReconstructedParticles Test ===#");
+        
+        
+        // Create two ReconstructedParticles with tracks only
+        List<Cluster> emptyClusters = new ArrayList<Cluster>(); 
+        List<List<Track>> trackCollections = new ArrayList<List<Track>>(0);
+        trackCollections.add(tracks);
+        particleTracks = particleDriver.makeReconstructedParticles(emptyClusters, trackCollections);
     
-    	for(int particleN = 0; particleN < particleTracks.size(); particleN++){
-    	
-    		//
-    		//	Check if the RecontructedParticle track is the same as the track 
-    		//	that created it
-    		// 
-    		assertTrue("The particle track does not match the track that created it",
-    					particleTracks.get(particleN).getTracks().get(0).equals(tracks.get(particleN)));
-    	
-    	
-    		//
-    		// Check that the charge of the ReconstructedParticles was set properly
-    		//
-    		assertTrue("The charge of the ReconstructedParticle is equal to zero.", 
-    					Math.abs(particleTracks.get(particleN).getCharge()) != 0);
-    		System.out.println("The charge of ReconstructedParticle number " + particleN + ": " + particleTracks.get(particleN).getCharge());
-    	
-    	
-    		//
-    		// Check that the particle ID was set correctly
-    		//
-    		assertTrue("The particle ID of the ReconstructedParticle is equal to zero.", 
-    				   particleTracks.get(particleN).getParticleIDUsed().getPDG() != 0);
-    		System.out.println("The particle ID of ReconstructedParticle number " + particleN + ": " + particleTracks.get(particleN).getParticleIDUsed().getPDG());
-    	}
-    	
-    	//
-    	// Check that the momentum of the ReconstructedParticles was set properly 
-    	// and rotated to the detector frame.
-    	//
-    	Hep3Vector electronMomentum = new BasicHep3Vector(tracks.get(0).getTrackStates().get(0).getMomentum());
-    	electronMomentum = CoordinateTransformations.transformVectorToDetector(electronMomentum);
-    	assertTrue("The momentum of the track and ReconstructedParticle don't match! Top track p = " 
-    				+ electronMomentum.toString() + " Recon particle p = " + particleTracks.get(0).getMomentum().toString(),
-    				particleTracks.get(0).getMomentum().equals(electronMomentum));
-    	
-    	System.out.println("The momentum of the first ReconstructedParticle: " + particleTracks.get(0).getMomentum().toString());
-    	
-    	Hep3Vector positronMomentum = new BasicHep3Vector(tracks.get(1).getTrackStates().get(0).getMomentum());
-    	positronMomentum = CoordinateTransformations.transformVectorToDetector(positronMomentum);
-    	assertTrue("The momentum of track and ReconstructedParticle don't march! Bottom track p = "
-    			    + positronMomentum.toString() + " Recon particle p = " + particleTracks.get(1).getMomentum().toString(),
-    			    particleTracks.get(1).getMomentum().equals(positronMomentum));
-    	
-    	System.out.println("The momentum of the second ReconstructedParticle: " + particleTracks.get(1).getMomentum().toString());
-    	
-   	}
-   	
-   	public void testVertexParticles(){
-   	
-    	// Create two ReconstructedParticles with tracks only
-    	//List<Cluster> emptyClusters = new ArrayList<Cluster>(); 
-    	//particleTracks = particleDriver.makeReconstructedParticles(emptyClusters, tracks);
+        //
+        // The list contains two Tracks which should result in two 
+        // ReconstructedParticles.
+        //
+        assertTrue("More particles than expected were created.", particleTracks.size() == 2);
+        System.out.println("\nThe number of ReconstructedParticles created: " + particleTracks.size());
+    
+        for(int particleN = 0; particleN < particleTracks.size(); particleN++){
+        
+            //
+            //  Check if the RecontructedParticle track is the same as the track 
+            //  that created it
+            // 
+            assertTrue("The particle track does not match the track that created it",
+                        particleTracks.get(particleN).getTracks().get(0).equals(tracks.get(particleN)));
+        
+        
+            //
+            // Check that the charge of the ReconstructedParticles was set properly
+            //
+            assertTrue("The charge of the ReconstructedParticle is equal to zero.", 
+                        Math.abs(particleTracks.get(particleN).getCharge()) != 0);
+            System.out.println("The charge of ReconstructedParticle number " + particleN + ": " + particleTracks.get(particleN).getCharge());
+        
+        
+            //
+            // Check that the particle ID was set correctly
+            //
+            assertTrue("The particle ID of the ReconstructedParticle is equal to zero.", 
+                       particleTracks.get(particleN).getParticleIDUsed().getPDG() != 0);
+            System.out.println("The particle ID of ReconstructedParticle number " + particleN + ": " + particleTracks.get(particleN).getParticleIDUsed().getPDG());
+        }
+        
+        //
+        // Check that the momentum of the ReconstructedParticles was set properly 
+        // and rotated to the detector frame.
+        //
+        Hep3Vector electronMomentum = new BasicHep3Vector(tracks.get(0).getTrackStates().get(0).getMomentum());
+        electronMomentum = CoordinateTransformations.transformVectorToDetector(electronMomentum);
+        assertTrue("The momentum of the track and ReconstructedParticle don't match! Top track p = " 
+                    + electronMomentum.toString() + " Recon particle p = " + particleTracks.get(0).getMomentum().toString(),
+                    particleTracks.get(0).getMomentum().equals(electronMomentum));
+        
+        System.out.println("The momentum of the first ReconstructedParticle: " + particleTracks.get(0).getMomentum().toString());
+        
+        Hep3Vector positronMomentum = new BasicHep3Vector(tracks.get(1).getTrackStates().get(0).getMomentum());
+        positronMomentum = CoordinateTransformations.transformVectorToDetector(positronMomentum);
+        assertTrue("The momentum of track and ReconstructedParticle don't march! Bottom track p = "
+                    + positronMomentum.toString() + " Recon particle p = " + particleTracks.get(1).getMomentum().toString(),
+                    particleTracks.get(1).getMomentum().equals(positronMomentum));
+        
+        System.out.println("The momentum of the second ReconstructedParticle: " + particleTracks.get(1).getMomentum().toString());
+        
+    }
+    
+    public void testVertexParticles(){
+    
+        // Create two ReconstructedParticles with tracks only
+        //List<Cluster> emptyClusters = new ArrayList<Cluster>(); 
+        //particleTracks = particleDriver.makeReconstructedParticles(emptyClusters, tracks);
 
-    	//List<ReconstructedParticle> electrons = particleTracks.subList(0, 1);
-   		//List<ReconstructedParticle> positrons = particleTracks.subList(1, 2);
-   	
-   		//particleDriver.vertexParticles(electrons, positrons);
-   		
-   	}
+        //List<ReconstructedParticle> electrons = particleTracks.subList(0, 1);
+        //List<ReconstructedParticle> positrons = particleTracks.subList(1, 2);
+    
+        //particleDriver.vertexParticles(electrons, positrons);
+        
+    }
 }

Modified: java/branches/HPSJAVA-409/record-util/pom.xml
 =============================================================================
--- java/branches/HPSJAVA-409/record-util/pom.xml	(original)
+++ java/branches/HPSJAVA-409/record-util/pom.xml	Wed Apr 27 11:11:32 2016
@@ -7,7 +7,7 @@
         <groupId>org.hps</groupId>
         <artifactId>hps-parent</artifactId>
         <relativePath>../parent/pom.xml</relativePath>
-        <version>3.4.2-SNAPSHOT</version>
+        <version>3.9-SNAPSHOT</version>
     </parent>
     <scm>
         <url>http://java.freehep.org/svn/repos/hps/list/java/trunk/record-util/</url>

Modified: java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/AbstractRecordProcessor.java
 =============================================================================
--- java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/AbstractRecordProcessor.java	(original)
+++ java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/AbstractRecordProcessor.java	Wed Apr 27 11:11:32 2016
@@ -10,6 +10,8 @@
  */
 public abstract class AbstractRecordProcessor<RecordType> implements RecordProcessor<RecordType> {
 
+    private boolean active = true;
+    
     /**
      * End of job action.
      */
@@ -59,4 +61,12 @@
     @Override
     public void suspend() {
     }
+    
+    protected void setActive(boolean active) {
+        this.active = active;
+    }
+    
+    public boolean isActive() {
+        return this.active;
+    }
 }

Modified: java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/AbstractRecordQueue.java
 =============================================================================
--- java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/AbstractRecordQueue.java	(original)
+++ java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/AbstractRecordQueue.java	Wed Apr 27 11:11:32 2016
@@ -45,7 +45,8 @@
     /**
      * Class constructor with the timeout in seconds.
      *
-     * @param timeoutSeconds the timeout in seconds
+     * @param timeOutMillis the timeout in seconds
+     * @param maxSize the maximum size of the queue
      */
     public AbstractRecordQueue(final long timeOutMillis, final int maxSize) {
         this.timeOutMillis = timeOutMillis;
@@ -55,7 +56,7 @@
     /**
      * Add a record to the queue if there is space.
      *
-     * @param event the LCIO event to add
+     * @param record the LCIO event to add
      */
     // FIXME: Should drain queue if over capacity.
     public void addRecord(final RecordType record) {
@@ -102,7 +103,7 @@
      * @throws NoSuchRecordException if there are no records available from the queue
      */
     @Override
-    public void next() throws IOException, NoSuchRecordException {
+    public synchronized void next() throws IOException, NoSuchRecordException {
         try {
             if (this.timeOutMillis > 0L) {
                 // Poll the queue for the next record until timeout is exceeded.

Modified: java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/RecordProcessor.java
 =============================================================================
--- java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/RecordProcessor.java	(original)
+++ java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/RecordProcessor.java	Wed Apr 27 11:11:32 2016
@@ -45,4 +45,11 @@
      * Suspend processing action.
      */
     void suspend();
+    
+    /**
+     * Return <code>true</code> if processor is active.
+     * 
+     * @return <code>true</code> if processor is active
+     */
+    boolean isActive();
 }

Modified: java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/composite/RecordProcessorAdapter.java
 =============================================================================
--- java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/composite/RecordProcessorAdapter.java	(original)
+++ java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/composite/RecordProcessorAdapter.java	Wed Apr 27 11:11:32 2016
@@ -44,7 +44,7 @@
     /**
      * Activate the <code>endJob</code> methods of the registered processors.
      *
-     * @param the <code>LoopEvent</code> which activated <code>finish</code>
+     * @param loopEvent the <code>LoopEvent</code> which activated <code>finish</code>
      */
     @Override
     public void finish(final LoopEvent loopEvent) {
@@ -80,7 +80,7 @@
     /**
      * Activate the <code>startJob</code> methods of the registered processors.
      *
-     * @param the <code>LoopEvent</code> which activated the start
+     * @param loopEvent the <code>LoopEvent</code> which activated the start
      */
     @Override
     public void start(final LoopEvent loopEvent) {
@@ -103,7 +103,7 @@
     /**
      * Activate the <code>suspend</code> methods of the registered processors.
      *
-     * @param the <code>LoopEvent</code> which activated <code>suspend</code>.
+     * @param loopEvent the <code>LoopEvent</code> which activated <code>suspend</code>.
      */
     @Override
     public void suspend(final LoopEvent loopEvent) {

Modified: java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/daqconfig/DAQConfig.java
 =============================================================================
--- java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/daqconfig/DAQConfig.java	(original)
+++ java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/daqconfig/DAQConfig.java	Wed Apr 27 11:11:32 2016
@@ -1,4 +1,8 @@
 package org.hps.record.daqconfig;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+
 
 /**
  * Class <code>DAQConfig</code> holds all of the supported parameters
@@ -47,13 +51,23 @@
     }
 
     @Override
-    public void printConfig() {
+    public void printConfig(PrintStream ps) {
         // Print the system-specific objects.
-        fadcConfig.printConfig();
-        System.out.println();
-        gtpConfig.printConfig();
-        System.out.println();
-        sspConfig.printConfig();
+        fadcConfig.printConfig(ps);
+        ps.println();
+        gtpConfig.printConfig(ps);
+        ps.println();
+        sspConfig.printConfig(ps);
     }
-    
-}
+
+    public String toString() {
+        ByteArrayOutputStream os = new ByteArrayOutputStream();
+        PrintStream ps = new PrintStream(os);
+        printConfig(ps);
+        try {
+            return os.toString("UTF8");
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+}

Modified: java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/daqconfig/DAQConfigDriver.java
 =============================================================================
--- java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/daqconfig/DAQConfigDriver.java	(original)
+++ java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/daqconfig/DAQConfigDriver.java	Wed Apr 27 11:11:32 2016
@@ -39,57 +39,57 @@
  * @see ConfigurationManager
  */
 public class DAQConfigDriver extends Driver {
-	private int runNumber = -1;
-	private String filepath = null;
-	private boolean firstEvent = true;
-	private boolean readDataFiles = false;
-	private File[] dataFiles = new File[3];
-	private int[] crateNumber = { 46, 37, 39 };
-	
-	/**
-	 * Verifies the parameter <code>filepath</code> for the data file
-	 * repository and checks that appropriate data files exist for the
-	 * requested run number if the driver is set to read from data files.
-	 * Otherwise, this does nothing.
-	 */
-	@Override
-	public void startOfData() {
-		// Check whether to use stored data files or the EvIO data stream
-		// as the source of the DAQ settings. Nothing needs to be done
-		// in the latter case.
-		if(readDataFiles) {
-			// The user must define a data file prefix and repository
-			// location for this option to be used.
-			if(filepath == null) {
-				throw new NullPointerException("DAQ settings repository filepath must be defined.");
-			} if(runNumber == -1) {
-				throw new NullPointerException("Run number must be defined.");
-			}
-			
-			// Verify that the repository actually exist.
-			File repository = new File(filepath);
-			if(!repository.exists() || !repository.isDirectory()) {
-				throw new IllegalArgumentException("Repository location \"" + filepath + "\" must be an existing directory.");
-			}
-			
-			// Define the data file objects.
-			for(int i = 0; i < dataFiles.length; i++) {
-				try {
-					dataFiles[i] = new File(repository.getCanonicalPath() + "/" + runNumber + "_" + crateNumber[i] + ".txt");
-				} catch(IOException e) {
-					throw new RuntimeException("Error resolving absolute repository filepath.");
-				}
-			}
-			
-			// Verify that the data files actually exist.
-			for(File dataFile : dataFiles) {
-				if(!dataFile.exists() || !dataFile.canRead()) {
-					throw new IllegalArgumentException("Data file \"" + dataFile.getName() + "\" does not exist or can not be read.");
-				}
-			}
-		}
-	}
-	
+    private int runNumber = -1;
+    private String filepath = null;
+    private boolean firstEvent = true;
+    private boolean readDataFiles = false;
+    private File[] dataFiles = new File[3];
+    private int[] crateNumber = { 46, 37, 39 };
+    
+    /**
+     * Verifies the parameter <code>filepath</code> for the data file
+     * repository and checks that appropriate data files exist for the
+     * requested run number if the driver is set to read from data files.
+     * Otherwise, this does nothing.
+     */
+    @Override
+    public void startOfData() {
+        // Check whether to use stored data files or the EvIO data stream
+        // as the source of the DAQ settings. Nothing needs to be done
+        // in the latter case.
+        if(readDataFiles) {
+            // The user must define a data file prefix and repository
+            // location for this option to be used.
+            if(filepath == null) {
+                throw new NullPointerException("DAQ settings repository filepath must be defined.");
+            } if(runNumber == -1) {
+                throw new NullPointerException("Run number must be defined.");
+            }
+            
+            // Verify that the repository actually exist.
+            File repository = new File(filepath);
+            if(!repository.exists() || !repository.isDirectory()) {
+                throw new IllegalArgumentException("Repository location \"" + filepath + "\" must be an existing directory.");
+            }
+            
+            // Define the data file objects.
+            for(int i = 0; i < dataFiles.length; i++) {
+                try {
+                    dataFiles[i] = new File(repository.getCanonicalPath() + "/" + runNumber + "_" + crateNumber[i] + ".txt");
+                } catch(IOException e) {
+                    throw new RuntimeException("Error resolving absolute repository filepath.");
+                }
+            }
+            
+            // Verify that the data files actually exist.
+            for(File dataFile : dataFiles) {
+                if(!dataFile.exists() || !dataFile.canRead()) {
+                    throw new IllegalArgumentException("Data file \"" + dataFile.getName() + "\" does not exist or can not be read.");
+                }
+            }
+        }
+    }
+    
     /**
      * Checks an event for the DAQ configuration banks and passes them
      * to the <code>ConfigurationManager</code> if the driver is set to
@@ -99,28 +99,28 @@
      */
     @Override
     public void process(EventHeader event) {
-    	// If this is the first event and data files are to be read,
-    	// import the data files and generate the DAQ information.
-    	if(firstEvent && readDataFiles) {
-    		// Get the data files in the form of a data array.
-    		String[][] data;
-    		try { data = getDataFileArrays(dataFiles); }
-    		catch(IOException e) {
-				throw new RuntimeException("An error occurred when processing the data files.");
-			}
-    		
-    		// Instantiate an EvIO DAQ parser and feed it the data.
-    		EvioDAQParser daqConfig = new EvioDAQParser();
-    		for(int i = 0; i < dataFiles.length; i++) {
-        		daqConfig.parse(crateNumber[i], runNumber, data[i]);
-    		}
-    		
-    		// Update the configuration manager.
-    		ConfigurationManager.updateConfiguration(daqConfig);
-    	}
-    	
+        // If this is the first event and data files are to be read,
+        // import the data files and generate the DAQ information.
+        if(firstEvent && readDataFiles) {
+            // Get the data files in the form of a data array.
+            String[][] data;
+            try { data = getDataFileArrays(dataFiles); }
+            catch(IOException e) {
+                throw new RuntimeException("An error occurred when processing the data files.");
+            }
+            
+            // Instantiate an EvIO DAQ parser and feed it the data.
+            EvioDAQParser daqConfig = new EvioDAQParser();
+            for(int i = 0; i < dataFiles.length; i++) {
+                daqConfig.parse(crateNumber[i], runNumber, data[i]);
+            }
+            
+            // Update the configuration manager.
+            ConfigurationManager.updateConfiguration(daqConfig);
+        }
+        
         // Check if a trigger configuration bank exists.
-    	if(!readDataFiles && event.hasCollection(EvioDAQParser.class, "TriggerConfig")) {
+        if(!readDataFiles && event.hasCollection(EvioDAQParser.class, "TriggerConfig")) {
             // Get the trigger configuration bank. There should only be
             // one in the list.
             List<EvioDAQParser> configList = event.get(EvioDAQParser.class, "TriggerConfig");
@@ -134,7 +134,7 @@
         // Note that it is no longer the first event.
         firstEvent = false;
     }
-	
+    
     /**
      * Converts DAQ configuration data files into an array of strings
      * where each array entry represents a line in the configuration
@@ -152,44 +152,44 @@
      * or reading the objects in the objects referred to by the files
      * pointed to in the <code>dataFiles</code> array.
      */
-	private static final String[][] getDataFileArrays(File[] dataFiles) throws IOException {
-		// Create file readers to process the data files.
-		FileReader[] fr = new FileReader[dataFiles.length];
-		BufferedReader[] reader = new BufferedReader[dataFiles.length];
-		for(int i = 0; i < dataFiles.length; i++) {
-			fr[i] = new FileReader(dataFiles[i]);
-			reader[i] = new BufferedReader(fr[i]);
-		}
-		
-		// Generate String arrays where each entry in the array is
-		// a line from the data file.
-		String[][] data = new String[dataFiles.length][0];
-		for(int i = 0; i < dataFiles.length; i++) {
-			// Create a list to hold the raw strings.
-			List<String> rawData = new ArrayList<String>();
-			
-			// Add each line from the current data file to the list
-			// as a single entry.
-			String curLine = null;
-			while((curLine = reader[i].readLine()) != null) {
-				rawData.add(curLine);
-			}
-			
-			// Convert the list into a String array.
-			data[i] = rawData.toArray(new String[rawData.size()]);
-		}
-		
-		// Return the data array.
-		return data;
-	}
-    
-	/**
-	 * Sets the run number of the DAQ configuration being processed.
-	 * This is only used when reading from data files.
-	 * @param run - The run number of the data files to be used.
-	 */
+    private static final String[][] getDataFileArrays(File[] dataFiles) throws IOException {
+        // Create file readers to process the data files.
+        FileReader[] fr = new FileReader[dataFiles.length];
+        BufferedReader[] reader = new BufferedReader[dataFiles.length];
+        for(int i = 0; i < dataFiles.length; i++) {
+            fr[i] = new FileReader(dataFiles[i]);
+            reader[i] = new BufferedReader(fr[i]);
+        }
+        
+        // Generate String arrays where each entry in the array is
+        // a line from the data file.
+        String[][] data = new String[dataFiles.length][0];
+        for(int i = 0; i < dataFiles.length; i++) {
+            // Create a list to hold the raw strings.
+            List<String> rawData = new ArrayList<String>();
+            
+            // Add each line from the current data file to the list
+            // as a single entry.
+            String curLine = null;
+            while((curLine = reader[i].readLine()) != null) {
+                rawData.add(curLine);
+            }
+            
+            // Convert the list into a String array.
+            data[i] = rawData.toArray(new String[rawData.size()]);
+        }
+        
+        // Return the data array.
+        return data;
+    }
+    
+    /**
+     * Sets the run number of the DAQ configuration being processed.
+     * This is only used when reading from data files.
+     * @param run - The run number of the data files to be used.
+     */
     public void setRunNumber(int run) {
-    	runNumber = run;
+        runNumber = run;
     }
     
     /**
@@ -198,7 +198,7 @@
      * @param filepath - The file path of the data file repository.
      */
     public void setDataFileRepository(String filepath) {
-    	this.filepath = filepath;
+        this.filepath = filepath;
     }
     
     /**
@@ -211,6 +211,6 @@
      * should be read from the EvIO stream.
      */
     public void setReadDataFiles(boolean state) {
-    	readDataFiles = state;
+        readDataFiles = state;
     }
 }

Modified: java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/daqconfig/EvioDAQParser.java
 =============================================================================
--- java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/daqconfig/EvioDAQParser.java	(original)
+++ java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/daqconfig/EvioDAQParser.java	Wed Apr 27 11:11:32 2016
@@ -42,7 +42,7 @@
      * 
      * TODO: Restructure, clean up...
      */
-	/** The EvIO bank identification tag for DAQ configuration banks. */
+    /** The EvIO bank identification tag for DAQ configuration banks. */
     public static final int BANK_TAG = 0xE10E;
     
     // Stores the hardware codes for each trigger type.
@@ -204,7 +204,7 @@
      * Instantiates the <code>EvioDAQParser</code>.
      */
     public EvioDAQParser() {
-    	// Create a map to map crystals to their database channel object.
+        // Create a map to map crystals to their database channel object.
         ecalConditions = DatabaseConditionsManager.getInstance().getEcalConditions();
         for (int ii = 0; ii < 442; ii++) {
             channels.add(findChannel(ii + 1));
@@ -220,9 +220,9 @@
      * parameters.
      */
     public void parse(int crate, int runNumber, String[] configurationTables) {
-    	// Track the number of banks that have been parsed. If the
-    	// parameter values have not been populated after a certain
-    	// number of banks, there is missing information.
+        // Track the number of banks that have been parsed. If the
+        // parameter values have not been populated after a certain
+        // number of banks, there is missing information.
         nBanks++;
         
         // Create a map that maps an identifier for each configuration
@@ -256,10 +256,10 @@
      * contain the DAQ configuration parameters.
      */
     private void loadConfigMap(int crate, String[] configTables) {
-    	// Iterate over each configuration table.
+        // Iterate over each configuration table.
         for(String configTable : configTables) {
-        	// Split each table into rows and iterate over the rows.
-        	rowLoop:
+            // Split each table into rows and iterate over the rows.
+            rowLoop:
             for(String line : configTable.trim().split("\n")) {
                 // Split the first column from the row.
                 String[] cols = line.trim().split(" +", 2);
@@ -290,8 +290,8 @@
                 // This entry indicates which triggers are enabled and
                 // needs to be parsed differently than normal.
                 else if(key.startsWith("SSP_HPS_SET_IO_SRC")) {
-                	// The first "parameter value" is a hardware code
-                	// that identifies the trigger. Obtain it.
+                    // The first "parameter value" is a hardware code
+                    // that identifies the trigger. Obtain it.
                     int trig = Integer.valueOf(vals.get(1));
                     
                     // There are two trigger of each type, singles and
@@ -313,8 +313,8 @@
                 // This indicates a regular parameter that does not
                 // require any special parsing.
                 if(vals.size() > 1 && key.startsWith("SSP")) {
-                	// List the parameter by "[ROW NAME]_[KEY]" and
-                	// remove the key so that only the values remain.
+                    // List the parameter by "[ROW NAME]_[KEY]" and
+                    // remove the key so that only the values remain.
                     key += "_" + vals.remove(0);
                 }
                 
@@ -330,7 +330,7 @@
      * format of <code>[PARAMETER KEY] --> { [PARAMETER VALUES] }</code>.
      */
     public void parseConfigMap() {
-    	// Parse simple FADC data.
+        // Parse simple FADC data.
         fadcNSA    = Integer.valueOf(getConfigParameter("FADC250_NSA",      0));
         fadcNSB    = Integer.valueOf(getConfigParameter("FADC250_NSB",      0));
         fadcNPEAK  = Integer.valueOf(getConfigParameter("FADC250_NPEAK",    0));
@@ -345,12 +345,12 @@
         
         // Parse trigger data.
         for(int ii = 0; ii < 2; ii++) {
-        	// Check singles trigger cuts enabled status.
+            // Check singles trigger cuts enabled status.
             singlesNhitsEn[ii]         = getBoolConfigSSP(ii,  "SINGLES_NMIN",          1);
             singlesEnergyMinEn[ii]     = getBoolConfigSSP(ii,  "SINGLES_EMIN",          1);
             singlesEnergyMaxEn[ii]     = getBoolConfigSSP(ii,  "SINGLES_EMAX",          1);
             
-        	// Check pair trigger cuts enabled status.
+            // Check pair trigger cuts enabled status.
             pairsEnergySumMaxMinEn[ii] = getBoolConfigSSP(ii,  "PAIRS_SUMMAX_MIN",      2);
             pairsEnergyDiffEn[ii]      = getBoolConfigSSP(ii,  "PAIRS_DIFFMAX",         1);
             pairsCoplanarityEn[ii]     = getBoolConfigSSP(ii,  "PAIRS_COPLANARITY",     1);
@@ -383,7 +383,7 @@
      * used to determine if the run is a "bugged" run.
      */
     private void fixConfigMap2014Run(int runNumber) {
-    	// If this is a good run, noting should be done. Return.
+        // If this is a good run, noting should be done. Return.
         if(runNumber > 3470 || runNumber < 3100) { return; }
         
         // Populate missing GTP entries.
@@ -412,10 +412,10 @@
      * the FADC channel with which they are associated.
      */
     private void parseFADC(int crate, String key, List<String> vals) {
-    	// The FADC slot is not stored on the same line as the other
-    	// data and must be parsed and retained, as it is necessary
-    	// for handling the subsequent lines. If this line is the
-    	// FADC slot, store it.
+        // The FADC slot is not stored on the same line as the other
+        // data and must be parsed and retained, as it is necessary
+        // for handling the subsequent lines. If this line is the
+        // FADC slot, store it.
         if(key.equals("FADC250_SLOT")) {
             thisFadcSlot = Integer.valueOf(vals.get(0));
         }
@@ -449,8 +449,8 @@
      * to FADC channels 0 - 15.
      */
     private void setChannelParsFloat(int crate, int slot, Map<EcalChannel, Float> map, List<String> vals) {
-    	// Iterate over each channel and map the database channel object
-    	// to the corresponding list value.
+        // Iterate over each channel and map the database channel object
+        // to the corresponding list value.
         for(int ii = 0; ii < 16; ii++) {
             map.put(findChannel(crate, slot, ii), Float.valueOf(vals.get(ii)));
         }
@@ -468,8 +468,8 @@
      * objects representing the channel values.
      */
     private void setChannelParsInt(int crate, int slot, Map<EcalChannel, Integer> map, List<String> vals) {
-    	// Iterate over each channel and map the database channel object
-    	// to the corresponding list value.
+        // Iterate over each channel and map the database channel object
+        // to the corresponding list value.
         for(int ii = 0; ii < 16; ii++) {
             map.put(findChannel(crate, slot, ii), Integer.valueOf(vals.get(ii)));
         }
@@ -619,9 +619,9 @@
      * can not be found, an error message is passed to the logger.
      */
     public String getConfigParameter(String key, int ival) {
-    	// Check the parameter map for the requested parameter key.
+        // Check the parameter map for the requested parameter key.
         if(configMap.containsKey(key)) {
-        	// Get the list of values associated with this parameter key.
+            // Get the list of values associated with this parameter key.
             List<String> vals = configMap.get(key);
             
             // Check that the list of values contains a parameter for
@@ -639,7 +639,7 @@
         // If the key is not present...
         else {
             // If more than 2 banks have been read, the absence of a
-        	// key represents an error. Log that this has occurred.
+            // key represents an error. Log that this has occurred.
             if(nBanks > 2) {
                 Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, "ConfigMap MISSING KEY:   " + key);
             }
@@ -659,13 +659,13 @@
      * if it exists, and <code>null</code> if it does not.
      */
     public EcalChannel findChannel(int crate, int fadcSlot, int fadcChan) {
-    	// Search through the database channels for a channel that
-    	// matches the the argument parameters.
+        // Search through the database channels for a channel that
+        // matches the the argument parameters.
         for (EcalChannel cc : channels) {
-        	// A channel matches the argument if the slot and channel
-        	// values are the same. Crate number must also match, but
-        	// note that EcalChannel follows a different convention
-        	// with respect to crate numbering.
+            // A channel matches the argument if the slot and channel
+            // values are the same. Crate number must also match, but
+            // note that EcalChannel follows a different convention
+            // with respect to crate numbering.
             if( ((cc.getCrate() - 1) * 2 == crate - 37) && (cc.getSlot() == fadcSlot) && (cc.getChannel() == fadcChan) ) {
                 return cc;
             }

Modified: java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/daqconfig/FADCConfig.java
 =============================================================================
--- java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/daqconfig/FADCConfig.java	(original)
+++ java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/daqconfig/FADCConfig.java	Wed Apr 27 11:11:32 2016
@@ -1,6 +1,7 @@
 package org.hps.record.daqconfig;
 
 import java.awt.Point;
+import java.io.PrintStream;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -129,13 +130,13 @@
      * per ADC.
      */
     public float getGain(Point ixy) {
-    	// Get the channel index.
-    	Integer index = indexChannelMap.get(ixy);
-    	
-    	// If the channel index was defined, return the pedestal.
+        // Get the channel index.
+        Integer index = indexChannelMap.get(ixy);
+        
+        // If the channel index was defined, return the pedestal.
         if(index != null) { return getGain(index); }
         else {
-        	throw new IllegalArgumentException(String.format("Crystal (%3d, %3d) does not exist.", ixy.x, ixy.y));
+            throw new IllegalArgumentException(String.format("Crystal (%3d, %3d) does not exist.", ixy.x, ixy.y));
         }
     }
     
@@ -225,13 +226,13 @@
      * of ADC.
      */
     public float getPedestal(Point ixy) {
-    	// Get the channel index.
-    	Integer index = indexChannelMap.get(ixy);
-    	
-    	// If the channel index was defined, return the pedestal.
+        // Get the channel index.
+        Integer index = indexChannelMap.get(ixy);
+        
+        // If the channel index was defined, return the pedestal.
         if(index != null) { return getPedestal(index); }
         else {
-        	throw new IllegalArgumentException(String.format("Crystal (%3d, %3d) does not exist.", ixy.x, ixy.y));
+            throw new IllegalArgumentException(String.format("Crystal (%3d, %3d) does not exist.", ixy.x, ixy.y));
         }
     }
     
@@ -305,39 +306,39 @@
     }
     
     @Override
-    public void printConfig() {
-    	// Print the basic configuration information.
-        System.out.println("FADC Configuration:");
-        System.out.printf("\tMode          :: %d%n", mode);
-        System.out.printf("\tNSA           :: %d%n", nsa);
-        System.out.printf("\tNSB           :: %d%n", nsb);
-        System.out.printf("\tWindow Width  :: %d%n", windowWidth);
-        System.out.printf("\tWindow Offset :: %d%n", offset);
-        System.out.printf("\tMax Peaks     :: %d%n", maxPulses);
+    public void printConfig(PrintStream ps) {
+        // Print the basic configuration information.
+        ps.println("FADC Configuration:");
+        ps.printf("\tMode          :: %d%n", mode);
+        ps.printf("\tNSA           :: %d%n", nsa);
+        ps.printf("\tNSB           :: %d%n", nsb);
+        ps.printf("\tWindow Width  :: %d%n", windowWidth);
+        ps.printf("\tWindow Offset :: %d%n", offset);
+        ps.printf("\tMax Peaks     :: %d%n", maxPulses);
         
         // Output the pedestal/gain write-out header.
-        System.out.println("\tix\tiy\tPedestal (ADC)\tGain (MeV/ADC)\tThreshold (ADC)");
+        ps.println("\tix\tiy\tPedestal (ADC)\tGain (MeV/ADC)\tThreshold (ADC)");
         
         // Iterate over each crystal y-index.
         yLoop:
         for(int iy = -5; iy <= 5; iy++) {
-        	// iy = 0 does not exists; skip it!
-        	if(iy == 0) { continue yLoop; }
-        	
-        	// Iterate over each crystal x-index.
-        	xLoop:
-        	for(int ix = -23; ix <= 23; ix++) {
-        		// ix = 0 and the beam hole do not exist; skip these!
-        		if(ix == 0) { continue xLoop; }
-        		if((ix >= -10 && ix <= -2) && (iy == -1 || iy == 1)) {
-        			continue xLoop;
-        		}
-        		
-        		// Output the crystal indices, pedestal, and gain.
-        		int channelID = indexChannelMap.get(new Point(ix, iy));
-        		System.out.printf("\t%3d\t%3d\t%8.3f\t%8.3f\t%4d%n", ix, iy,
-        				getPedestal(channelID), getGain(channelID), getThreshold(channelID));
-        	}
+            // iy = 0 does not exists; skip it!
+            if(iy == 0) { continue yLoop; }
+            
+            // Iterate over each crystal x-index.
+            xLoop:
+            for(int ix = -23; ix <= 23; ix++) {
+                // ix = 0 and the beam hole do not exist; skip these!
+                if(ix == 0) { continue xLoop; }
+                if((ix >= -10 && ix <= -2) && (iy == -1 || iy == 1)) {
+                    continue xLoop;
+                }
+                
+                // Output the crystal indices, pedestal, and gain.
+                int channelID = indexChannelMap.get(new Point(ix, iy));
+                ps.printf("\t%3d\t%3d\t%8.3f\t%8.3f\t%4d%n", ix, iy,
+                        getPedestal(channelID), getGain(channelID), getThreshold(channelID));
+            }
         }
     }
     

Modified: java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/daqconfig/GTPConfig.java
 =============================================================================
--- java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/daqconfig/GTPConfig.java	(original)
+++ java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/daqconfig/GTPConfig.java	Wed Apr 27 11:11:32 2016
@@ -1,4 +1,6 @@
 package org.hps.record.daqconfig;
+
+import java.io.PrintStream;
 
 /**
  * Class <code>GTPConfig</code> stores GTP configuration settings
@@ -57,14 +59,14 @@
     }
     
     @Override
-    public void printConfig() {
+    public void printConfig(PrintStream ps) {
         // Print the configuration header.
-        System.out.println("GTP Configuration:");
+        ps.println("GTP Configuration:");
         
         // Print the GTP settings.
-        System.out.printf("\tTime Window Before :: %d clock-cycles%n", windowBefore);
-        System.out.printf("\tTime Window After  :: %d clock-cycles%n", windowAfter);
-        System.out.printf("\tSeed Energy Min    :: %5.3f GeV%n",       seedCut.getLowerBound());
+        ps.printf("\tTime Window Before :: %d clock-cycles%n", windowBefore);
+        ps.printf("\tTime Window After  :: %d clock-cycles%n", windowAfter);
+        ps.printf("\tSeed Energy Min    :: %5.3f GeV%n",       seedCut.getLowerBound());
     }
 
 }

Modified: java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/daqconfig/IDAQConfig.java
 =============================================================================
--- java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/daqconfig/IDAQConfig.java	(original)
+++ java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/daqconfig/IDAQConfig.java	Wed Apr 27 11:11:32 2016
@@ -1,4 +1,6 @@
 package org.hps.record.daqconfig;
+
+import java.io.PrintStream;
 
 
 /**
@@ -20,5 +22,5 @@
      * Prints a textual representation of the configuration bank to the
      * terminal.
      */
-    public abstract void printConfig();
+    public abstract void printConfig(PrintStream ps);
 }

Modified: java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/daqconfig/SSPConfig.java
 =============================================================================
--- java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/daqconfig/SSPConfig.java	(original)
+++ java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/daqconfig/SSPConfig.java	Wed Apr 27 11:11:32 2016
@@ -1,4 +1,6 @@
 package org.hps.record.daqconfig;
+
+import java.io.PrintStream;
 
 
 /**
@@ -98,64 +100,64 @@
     }
     
     @Override
-    public void printConfig() {
+    public void printConfig(PrintStream ps) {
         // Print the configuration header.
-        System.out.println("SSP Configuration:");
+        ps.println("SSP Configuration:");
         
         // Print the singles triggers.
         for(int triggerNum = 0; triggerNum < 2; triggerNum++) {
-            System.out.printf("\tSingles Trigger %d%n", (triggerNum + 1));
-            System.out.println("\t\tCluster Energy Lower Bound Cut");
-            System.out.printf("\t\t\tEnabled :: %b%n", singlesTrigger[triggerNum].getEnergyMinCutConfig().isEnabled());
-            System.out.printf("\t\t\tValue   :: %5.3f GeV%n", singlesTrigger[triggerNum].getEnergyMinCutConfig().getLowerBound());
+            ps.printf("\tSingles Trigger %d%n", (triggerNum + 1));
+            ps.println("\t\tCluster Energy Lower Bound Cut");
+            ps.printf("\t\t\tEnabled :: %b%n", singlesTrigger[triggerNum].getEnergyMinCutConfig().isEnabled());
+            ps.printf("\t\t\tValue   :: %5.3f GeV%n", singlesTrigger[triggerNum].getEnergyMinCutConfig().getLowerBound());
             
-            System.out.println("\t\tCluster Energy Upper Bound Cut");
-            System.out.printf("\t\t\tEnabled :: %b%n", singlesTrigger[triggerNum].getEnergyMaxCutConfig().isEnabled());
-            System.out.printf("\t\t\tValue   :: %5.3f GeV%n", singlesTrigger[triggerNum].getEnergyMaxCutConfig().getUpperBound());
+            ps.println("\t\tCluster Energy Upper Bound Cut");
+            ps.printf("\t\t\tEnabled :: %b%n", singlesTrigger[triggerNum].getEnergyMaxCutConfig().isEnabled());
+            ps.printf("\t\t\tValue   :: %5.3f GeV%n", singlesTrigger[triggerNum].getEnergyMaxCutConfig().getUpperBound());
             
-            System.out.println("\t\tCluster Hit Count Cut");
-            System.out.printf("\t\t\tEnabled :: %b%n", singlesTrigger[triggerNum].getHitCountCutConfig().isEnabled());
-            System.out.printf("\t\t\tValue   :: %1.0f hits%n", singlesTrigger[triggerNum].getHitCountCutConfig().getLowerBound());
-            System.out.println();
+            ps.println("\t\tCluster Hit Count Cut");
+            ps.printf("\t\t\tEnabled :: %b%n", singlesTrigger[triggerNum].getHitCountCutConfig().isEnabled());
+            ps.printf("\t\t\tValue   :: %1.0f hits%n", singlesTrigger[triggerNum].getHitCountCutConfig().getLowerBound());
+            ps.println();
         }
         
         // Print the pair triggers.
         for(int triggerNum = 0; triggerNum < 2; triggerNum++) {
-            System.out.printf("\tPair Trigger %d%n", (triggerNum + 1));
-            System.out.println("\t\tCluster Energy Lower Bound Cut");
-            System.out.printf("\t\t\tEnabled :: %b%n", pairTrigger[triggerNum].getEnergyMinCutConfig().isEnabled());
-            System.out.printf("\t\t\tValue   :: %5.3f GeV%n", pairTrigger[triggerNum].getEnergyMinCutConfig().getLowerBound());
+            ps.printf("\tPair Trigger %d%n", (triggerNum + 1));
+            ps.println("\t\tCluster Energy Lower Bound Cut");
+            ps.printf("\t\t\tEnabled :: %b%n", pairTrigger[triggerNum].getEnergyMinCutConfig().isEnabled());
+            ps.printf("\t\t\tValue   :: %5.3f GeV%n", pairTrigger[triggerNum].getEnergyMinCutConfig().getLowerBound());
             
-            System.out.println("\t\tCluster Energy Upper Bound Cut");
-            System.out.printf("\t\t\tEnabled :: %b%n", pairTrigger[triggerNum].getEnergyMaxCutConfig().isEnabled());
-            System.out.printf("\t\t\tValue   :: %5.3f GeV%n", pairTrigger[triggerNum].getEnergyMaxCutConfig().getUpperBound());
+            ps.println("\t\tCluster Energy Upper Bound Cut");
+            ps.printf("\t\t\tEnabled :: %b%n", pairTrigger[triggerNum].getEnergyMaxCutConfig().isEnabled());
+            ps.printf("\t\t\tValue   :: %5.3f GeV%n", pairTrigger[triggerNum].getEnergyMaxCutConfig().getUpperBound());
             
-            System.out.println("\t\tCluster Hit Count Cut");
-            System.out.printf("\t\t\tEnabled :: %b%n", pairTrigger[triggerNum].getHitCountCutConfig().isEnabled());
-            System.out.printf("\t\t\tValue   :: %1.0f hits%n", pairTrigger[triggerNum].getHitCountCutConfig().getLowerBound());
+            ps.println("\t\tCluster Hit Count Cut");
+            ps.printf("\t\t\tEnabled :: %b%n", pairTrigger[triggerNum].getHitCountCutConfig().isEnabled());
+            ps.printf("\t\t\tValue   :: %1.0f hits%n", pairTrigger[triggerNum].getHitCountCutConfig().getLowerBound());
             
-            System.out.println("\t\tPair Energy Sum Cut");
-            System.out.printf("\t\t\tEnabled :: %b%n", pairTrigger[triggerNum].getEnergySumCutConfig().isEnabled());
-            System.out.printf("\t\t\tMin     :: %5.3f GeV%n", pairTrigger[triggerNum].getEnergySumCutConfig().getLowerBound());
-            System.out.printf("\t\t\tMax     :: %5.3f GeV%n", pairTrigger[triggerNum].getEnergySumCutConfig().getUpperBound());
+            ps.println("\t\tPair Energy Sum Cut");
+            ps.printf("\t\t\tEnabled :: %b%n", pairTrigger[triggerNum].getEnergySumCutConfig().isEnabled());
+            ps.printf("\t\t\tMin     :: %5.3f GeV%n", pairTrigger[triggerNum].getEnergySumCutConfig().getLowerBound());
+            ps.printf("\t\t\tMax     :: %5.3f GeV%n", pairTrigger[triggerNum].getEnergySumCutConfig().getUpperBound());
             
-            System.out.println("\t\tPair Energy Difference Cut");
-            System.out.printf("\t\t\tEnabled :: %b%n", pairTrigger[triggerNum].getEnergyDifferenceCutConfig().isEnabled());
-            System.out.printf("\t\t\tValue   :: %5.3f GeV%n", pairTrigger[triggerNum].getEnergyDifferenceCutConfig().getUpperBound());
+            ps.println("\t\tPair Energy Difference Cut");
+            ps.printf("\t\t\tEnabled :: %b%n", pairTrigger[triggerNum].getEnergyDifferenceCutConfig().isEnabled());
+            ps.printf("\t\t\tValue   :: %5.3f GeV%n", pairTrigger[triggerNum].getEnergyDifferenceCutConfig().getUpperBound());
             
-            System.out.println("\t\tPair Energy Slope Cut");
-            System.out.printf("\t\t\tEnabled :: %b%n", pairTrigger[triggerNum].getEnergySlopeCutConfig().isEnabled());
-            System.out.printf("\t\t\tValue   :: %5.3f GeV%n", pairTrigger[triggerNum].getEnergySlopeCutConfig().getLowerBound());
-            System.out.printf("\t\t\tParam F :: %6.4f GeV/mm%n", pairTrigger[triggerNum].getEnergySlopeCutConfig().getParameterF());
+            ps.println("\t\tPair Energy Slope Cut");
+            ps.printf("\t\t\tEnabled :: %b%n", pairTrigger[triggerNum].getEnergySlopeCutConfig().isEnabled());
+            ps.printf("\t\t\tValue   :: %5.3f GeV%n", pairTrigger[triggerNum].getEnergySlopeCutConfig().getLowerBound());
+            ps.printf("\t\t\tParam F :: %6.4f GeV/mm%n", pairTrigger[triggerNum].getEnergySlopeCutConfig().getParameterF());
             
-            System.out.println("\t\tPair Coplanarity Cut");
-            System.out.printf("\t\t\tEnabled :: %b%n", pairTrigger[triggerNum].getCoplanarityCutConfig().isEnabled());
-            System.out.printf("\t\t\tValue   :: %3.0f degrees%n", pairTrigger[triggerNum].getCoplanarityCutConfig().getUpperBound());
+            ps.println("\t\tPair Coplanarity Cut");
+            ps.printf("\t\t\tEnabled :: %b%n", pairTrigger[triggerNum].getCoplanarityCutConfig().isEnabled());
+            ps.printf("\t\t\tValue   :: %3.0f degrees%n", pairTrigger[triggerNum].getCoplanarityCutConfig().getUpperBound());
             
-            System.out.println("\t\tPair Time Coincidence Cut");
-            System.out.printf("\t\t\tEnabled :: %b%n", pairTrigger[triggerNum].getTimeDifferenceCutConfig().isEnabled());
-            System.out.printf("\t\t\tValue   :: %1.0f clock-cycles%n", pairTrigger[triggerNum].getTimeDifferenceCutConfig().getUpperBound());
-            System.out.println();
+            ps.println("\t\tPair Time Coincidence Cut");
+            ps.printf("\t\t\tEnabled :: %b%n", pairTrigger[triggerNum].getTimeDifferenceCutConfig().isEnabled());
+            ps.printf("\t\t\tValue   :: %1.0f clock-cycles%n", pairTrigger[triggerNum].getTimeDifferenceCutConfig().getUpperBound());
+            ps.println();
         }
     }
 }

Modified: java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/epics/EpicsData.java
 =============================================================================
--- java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/epics/EpicsData.java	(original)
+++ java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/epics/EpicsData.java	Wed Apr 27 11:11:32 2016
@@ -276,12 +276,13 @@
      * @param evioEvent the EVIO event
      * @return the EPICS data or <code>null</code> if it is not present in the event
      */
+    // FIXME: Not currently used.
     public static EpicsData getEpicsData(EvioEvent evioEvent) {
         
         EpicsData epicsData = null;
         
         // Is this an EPICS event?
-        if (EventTagConstant.EPICS.equals(evioEvent)) {
+        if (EventTagConstant.EPICS.matches(evioEvent)) {
 
             // Find the bank with the EPICS data string.
             final BaseStructure epicsBank = EvioBankTag.EPICS_STRING.findBank(evioEvent);

Modified: java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/epics/EpicsEvioProcessor.java
 =============================================================================
--- java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/epics/EpicsEvioProcessor.java	(original)
+++ java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/epics/EpicsEvioProcessor.java	Wed Apr 27 11:11:32 2016
@@ -45,7 +45,7 @@
     public void process(final EvioEvent evioEvent) {
 
         // Is this an EPICS event?
-        if (EventTagConstant.EPICS.equals(evioEvent)) {
+        if (EventTagConstant.EPICS.matches(evioEvent)) {
 
             LOGGER.fine("processing EPICS event " + evioEvent.getEventNumber());
 

Modified: java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/epics/EpicsRunProcessor.java
 =============================================================================
--- java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/epics/EpicsRunProcessor.java	(original)
+++ java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/epics/EpicsRunProcessor.java	Wed Apr 27 11:11:32 2016
@@ -39,7 +39,7 @@
     private final EpicsEvioProcessor processor = new EpicsEvioProcessor();
 
     /**
-     * Create an EPICs log.
+     * Create a processor that will make a list of EPICS data.
      */
     public EpicsRunProcessor() {
     }
@@ -66,9 +66,9 @@
 
         // Add EPICS data to the collection.
         if (this.currentEpicsData != null) {
-            LOGGER.info("adding EPICS data for run " + this.currentEpicsData.getEpicsHeader().getRun() + " and timestamp " 
-                    + this.currentEpicsData.getEpicsHeader().getTimestamp() + " with seq " 
-                    + this.currentEpicsData.getEpicsHeader().getSequence());
+            LOGGER.fine("Adding EPICS data with run " + this.currentEpicsData.getEpicsHeader().getRun() + "; timestamp " 
+                    + this.currentEpicsData.getEpicsHeader().getTimestamp() + "; seq "
+                    + this.currentEpicsData.getEpicsHeader().getSequence() + ".");
             this.epicsDataSet.add(this.currentEpicsData);
         }
     }

Modified: java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/evio/EventTagConstant.java
 =============================================================================
--- java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/evio/EventTagConstant.java	(original)
+++ java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/evio/EventTagConstant.java	Wed Apr 27 11:11:32 2016
@@ -63,7 +63,7 @@
         return tag == this.tag;
     }
     
-    public boolean equals(final EvioEvent evioEvent) {
+    public boolean matches(final EvioEvent evioEvent) {
         return evioEvent.getHeader().getTag() == this.tag;
     }
     

Modified: java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/evio/EvioBankTag.java
 =============================================================================
--- java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/evio/EvioBankTag.java	(original)
+++ java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/evio/EvioBankTag.java	Wed Apr 27 11:11:32 2016
@@ -25,8 +25,10 @@
     /** Scaler data bank. */
     SCALERS(57621),
     /** Trigger configuration bank. */
-    TRIGGER_CONFIG(0xE10E);
-
+    TRIGGER_CONFIG(0xE10E),
+    /** TI trigger bank. */
+    TI_TRIGGER(0xe10a);
+    
     /**
      * The bank's tag value.
      */
@@ -46,7 +48,7 @@
      *
      * @param startBank the starting bank
      * @return the first bank matching the tag or <code>null<code> if not found
-     */
+     */    
     public BaseStructure findBank(final BaseStructure startBank) {
         BaseStructure foundBank = null;
         if (this.equals(startBank)) {
@@ -60,8 +62,8 @@
             }
         }
         return foundBank;
-    }
-
+    }    
+    
     /**
      * Get the bank tag value.
      *

Modified: java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/evio/EvioDetectorConditionsProcessor.java
 =============================================================================
--- java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/evio/EvioDetectorConditionsProcessor.java	(original)
+++ java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/evio/EvioDetectorConditionsProcessor.java	Wed Apr 27 11:11:32 2016
@@ -39,21 +39,28 @@
      */
     @Override
     public void process(final EvioEvent evioEvent) throws Exception {
+        
         // Get the head head bank from event.
         final BaseStructure headBank = EvioEventUtilities.getHeadBank(evioEvent);
 
-        // Is the head bank present?
-        if (headBank != null) {
+        // Initialize from head bank.
+        if (headBank != null) {            
+            initializeConditions(headBank.getIntData()[1]);
+        }
+        
+        // Initialize from PRESTART.
+        if (EventTagConstant.PRESTART.matches(evioEvent)) {
+            int runNumber = EvioEventUtilities.getControlEventData(evioEvent)[1];
+            initializeConditions(runNumber);
+        }
+    }
 
-            // Get the run number from the head bank.
-            final int runNumber = headBank.getIntData()[1];
-
-            // Initialize the conditions system from the detector name and run number.
-            try {
-                ConditionsManager.defaultInstance().setDetector(this.detectorName, runNumber);
-            } catch (final ConditionsNotFoundException e) {
-                throw new RuntimeException("Error setting up conditions from EVIO head bank.", e);
-            }
+    private void initializeConditions(final int runNumber) {
+        // Initialize the conditions system from the detector name and run number.
+        try {
+            ConditionsManager.defaultInstance().setDetector(this.detectorName, runNumber);
+        } catch (final ConditionsNotFoundException e) {
+            throw new RuntimeException("Error setting up conditions from EVIO head bank.", e);
         }
     }
 
@@ -65,6 +72,7 @@
      * @param evioEvent the <code>EvioEvent</code> to process
      */
     @Override
+    // FIXME: not activated by EvioLoop
     public void startRun(final EvioEvent evioEvent) {
         // System.out.println("EvioDetectorConditionsProcessor.startRun");
         if (EvioEventUtilities.isPreStartEvent(evioEvent)) {

Modified: java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/evio/EvioEventSkimmer.java
 =============================================================================
--- java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/evio/EvioEventSkimmer.java	(original)
+++ java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/evio/EvioEventSkimmer.java	Wed Apr 27 11:11:32 2016
@@ -14,7 +14,7 @@
 import org.apache.commons.cli.CommandLine;
 import org.apache.commons.cli.Options;
 import org.apache.commons.cli.ParseException;
-import org.apache.commons.cli.DefaultParser;
+import org.apache.commons.cli.PosixParser;
 import org.jlab.coda.jevio.EventWriter;
 import org.jlab.coda.jevio.EvioEvent;
 import org.jlab.coda.jevio.EvioReader;
@@ -51,7 +51,7 @@
      */
     public static void main(String[] args) {
 
-        DefaultParser parser = new DefaultParser();
+        PosixParser parser = new PosixParser();
 
         CommandLine commandLine = null;
         try {

Modified: java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/evio/EvioEventUtilities.java
 =============================================================================
--- java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/evio/EvioEventUtilities.java	(original)
+++ java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/evio/EvioEventUtilities.java	Wed Apr 27 11:11:32 2016
@@ -13,9 +13,6 @@
 
 import org.hps.conditions.database.DatabaseConditionsManager;
 import org.hps.record.daqconfig.EvioDAQParser;
-import org.hps.record.epics.EpicsData;
-import org.hps.record.epics.EpicsHeader;
-import org.hps.record.scalers.ScalerData;
 import org.jlab.coda.jevio.BaseStructure;
 import org.jlab.coda.jevio.EvioEvent;
 import org.lcsim.conditions.ConditionsManager.ConditionsNotFoundException;
@@ -113,23 +110,18 @@
     /**
      * Get the run number from an EVIO event.
      *
-     * @return the run number
-     * @throws IllegalArgumentException if event does not have a head bank
-     */
-    public static int getRunNumber(final EvioEvent event) {
+     * @return the run number or <code>null</code> if not present in event
+     */
+    public static Integer getRunNumber(final EvioEvent event) {
         if (isControlEvent(event)) {
             return getControlEventData(event)[1];
         } else if (isPhysicsEvent(event)) {
             final BaseStructure headBank = EvioEventUtilities.getHeadBank(event);
             if (headBank != null) {
                 return headBank.getIntData()[1];
-            } else {
-                throw new IllegalArgumentException("Head bank is missing from physics event.");
-            }
-        } else {
-            // Not sure if this would ever happen.
-            throw new IllegalArgumentException("Wrong event type: " + event.getHeader().getTag());
-        }
+            } 
+        } 
+        return null;
     }
 
     /**

Modified: java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/evio/EvioFileProducer.java
 =============================================================================
--- java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/evio/EvioFileProducer.java	(original)
+++ java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/evio/EvioFileProducer.java	Wed Apr 27 11:11:32 2016
@@ -16,7 +16,7 @@
 import org.apache.commons.cli.CommandLine;
 import org.apache.commons.cli.HelpFormatter;
 import org.apache.commons.cli.Options;
-import org.apache.commons.cli.DefaultParser;
+import org.apache.commons.cli.PosixParser;
 import org.jlab.coda.et.EtAttachment;
 import org.jlab.coda.et.EtConstants;
 import org.jlab.coda.et.EtEvent;
@@ -195,7 +195,7 @@
     public void run(final String[] args) {
 
         // Command line parser.
-        final DefaultParser parser = new DefaultParser();
+        final PosixParser parser = new PosixParser();
 
         try {
 

Modified: java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/evio/EvioFileSource.java
 =============================================================================
--- java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/evio/EvioFileSource.java	(original)
+++ java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/evio/EvioFileSource.java	Wed Apr 27 11:11:32 2016
@@ -4,6 +4,8 @@
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
 
 import org.freehep.record.source.NoSuchRecordException;
 import org.hps.record.AbstractRecordQueue;
@@ -12,15 +14,15 @@
 import org.jlab.coda.jevio.EvioReader;
 
 /**
- * A basic implementation of an <tt>AbstractRecordSource</tt> for supplying <tt>EvioEvent</tt> objects to a loop from a
- * list of EVIO files.
- * <p>
- * Unlike the LCIO record source, it has no rewind or indexing capabilities.
+ * A basic implementation of an <code>AbstractRecordSource</code> for supplying <code>EvioEvent</code> objects to a 
+ * loop from a list of EVIO files.
  *
  * @author Jeremy McCormick, SLAC
  */
 public final class EvioFileSource extends AbstractRecordQueue<EvioEvent> {
 
+    private static final Logger LOGGER = Logger.getLogger(EvioFileSource.class.getPackage().getName());
+    
     /**
      * The current event.
      */
@@ -40,7 +42,12 @@
      * The reader to use for reading and parsing the EVIO data.
      */
     private EvioReader reader;
-
+    
+    /**
+     * Whether to continue on parse errors or not.
+     */
+    private boolean continueOnErrors = false;
+   
     /**
      * Constructor taking a single EVIO file.
      *
@@ -60,7 +67,15 @@
         this.files.addAll(files);
         this.openReader();
     }
-
+    
+    /**
+     * Set whether to continue on errors or not.
+     * @param continueOnErrors <code>true</code> to continue on errors
+     */
+    public void setContinueOnErrors(boolean continueOnErrors) {
+        this.continueOnErrors = continueOnErrors;
+    }
+    
     /**
      * Close the current reader.
      */
@@ -135,20 +150,26 @@
         for (;;) {
             try {
                 this.currentEvent = this.reader.parseNextEvent();
-            } catch (final EvioException e) {
-                throw new IOException(e);
+                if (this.reader.getNumEventsRemaining() == 0 && this.currentEvent == null) {
+                    this.closeReader();
+                    this.fileIndex++;
+                    if (!this.endOfFiles()) {
+                        this.openReader();
+                    } else {
+                        throw new NoSuchRecordException("End of data.");
+                    }
+                } else {
+                    LOGGER.finest("Read EVIO event " + this.currentEvent.getEventNumber() + " okay.");
+                    break;
+                }                   
+            } catch (EvioException | NegativeArraySizeException e) { 
+                LOGGER.log(Level.SEVERE, "Error parsing next EVIO event.", e);
+                if (!continueOnErrors) {
+                    throw new IOException("Fatal error parsing next EVIO event.", e);
+                }
+            } catch (Exception e) {
+                throw new IOException("Error parsing EVIO event.", e);
             }
-            if (this.currentEvent == null) {
-                this.closeReader();
-                this.fileIndex++;
-                if (!this.endOfFiles()) {
-                    this.openReader();
-                    continue;
-                } else {
-                    throw new NoSuchRecordException();
-                }
-            }
-            return;
         }
     }
 
@@ -159,10 +180,9 @@
      */
     private void openReader() {
         try {
-            System.out.println("Opening reader for file " + this.files.get(this.fileIndex) + " ...");
-            // FIXME: this should use the reader directly and cached paths should be managed externally
+            // FIXME: This should use the reader directly and MSS paths should be transformed externally.
+            LOGGER.info("opening EVIO file " + this.files.get(this.fileIndex).getPath() + " ...");
             this.reader = EvioFileUtilities.open(this.files.get(this.fileIndex), true);
-            System.out.println("Done opening file.");
         } catch (EvioException | IOException e) {
             throw new RuntimeException(e);
         }

Modified: java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/evio/EvioFileUtilities.java
 =============================================================================
--- java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/evio/EvioFileUtilities.java	(original)
+++ java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/evio/EvioFileUtilities.java	Wed Apr 27 11:11:32 2016
@@ -25,24 +25,7 @@
      * Milliseconds constant for conversion to/from second.
      */
     private static final long MILLISECONDS = 1000L;
-
-    /**
-     * Get a cached file path, assuming that the input file path is on the JLAB MSS e.g. it starts with "/mss".
-     *
-     * @param file the MSS file path
-     * @return the cached file path (prepends "/cache" to the path)
-     * @throws IllegalArgumentException if the file is not on the MSS (e.g. path does not start with "/mss")
-     */
-    public static File getCachedFile(final File file) {
-        if (!isMssFile(file)) {
-            throw new IllegalArgumentException("File " + file.getPath() + " is not on the JLab MSS.");
-        }
-        if (isCachedFile(file)) {
-            throw new IllegalArgumentException("File " + file.getPath() + " is already on the cache disk.");
-        }
-        return new File("/cache" + file.getPath());
-    }
-
+   
     /**
      * Get the run number from the file name.
      *
@@ -70,26 +53,6 @@
     }
 
     /**
-     * Return <code>true</code> if this is a file on the cache disk e.g. the path starts with "/cache".
-     *
-     * @param file the file
-     * @return <code>true</code> if the file is a cached file
-     */
-    public static boolean isCachedFile(final File file) {
-        return file.getPath().startsWith("/cache");
-    }
-
-    /**
-     * Return <code>true</code> if this file is on the JLAB MSS e.g. the path starts with "/mss".
-     *
-     * @param file the file
-     * @return <code>true</code> if the file is on the MSS
-     */
-    public static boolean isMssFile(final File file) {
-        return file.getPath().startsWith("/mss");
-    }
-
-    /**
      * Open an EVIO file using an <code>EvioReader</code> in memory mapping mode.
      *
      * @param file the EVIO file
@@ -98,7 +61,7 @@
      * @throws EvioException if there is an error reading the EVIO data
      */
     public static EvioReader open(final File file) throws IOException, EvioException {
-        return open(file, false);
+        return open(file, true);
     }
 
     /**
@@ -111,14 +74,11 @@
      * @throws EvioException if there is an error reading the EVIO data
      */
     public static EvioReader open(final File file, final boolean sequential) throws IOException, EvioException {
-        File openFile = file;
-        if (isMssFile(file)) {
-            openFile = getCachedFile(file);
-        }
+        LOGGER.info("opening " + file.getPath() + " in " + (sequential ? "sequential" : "mmap" + " mode"));
         final long start = System.currentTimeMillis();
-        final EvioReader reader = new EvioReader(openFile, false, sequential);
+        final EvioReader reader = new EvioReader(file, false, sequential);
         final long end = System.currentTimeMillis() - start;
-        LOGGER.info("opened " + openFile.getPath() + " in " + (double) end / (double) MILLISECONDS + " seconds in "
+        LOGGER.info("opened " + file.getPath() + " in " + (double) end / (double) MILLISECONDS + " seconds in "
                 + (sequential ? "sequential" : "mmap" + " mode"));
         return reader;
     }

Modified: java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/evio/EvioLoop.java
 =============================================================================
--- java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/evio/EvioLoop.java	(original)
+++ java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/evio/EvioLoop.java	Wed Apr 27 11:11:32 2016
@@ -1,52 +1,24 @@
 package org.hps.record.evio;
 
-import org.freehep.record.loop.DefaultRecordLoop;
+import org.hps.record.AbstractRecordLoop;
+import org.jlab.coda.jevio.EvioEvent;
 
 /**
  * Implementation of a Freehep <code>RecordLoop</code> for EVIO data.
  *
  * @author Jeremy McCormick, SLAC
  */
-public class EvioLoop extends DefaultRecordLoop {
-
-    /**
-     * The record adapter.
-     */
-    private final EvioLoopAdapter adapter = new EvioLoopAdapter();
+public class EvioLoop extends AbstractRecordLoop<EvioEvent> {
 
     /**
      * Create a new record loop.
      */
     public EvioLoop() {
+        this.adapter = new EvioLoopAdapter();
         this.addLoopListener(adapter);
         this.addRecordListener(adapter);
     }
-
-    /**
-     * Add an EVIO event processor to the adapter which will be activated for every EVIO event that is processed.
-     *
-     * @param evioEventProcessor the EVIO processor to add
-     */
-    public void addEvioEventProcessor(final EvioEventProcessor evioEventProcessor) {
-        adapter.addEvioEventProcessor(evioEventProcessor);
-    }
-
-    /**
-     * Loop over events from the source.
-     *
-     * @param number the number of events to process or -1L for all events from the source
-     * @return the number of records that were processed
-     */
-    public long loop(final long number) {
-        if (number < 0L) {
-            this.execute(Command.GO, true);
-        } else {
-            this.execute(Command.GO_N, number, true);
-            this.execute(Command.STOP);
-        }
-        return this.getSupplied();
-    }
-
+  
     /**
      * Set the EVIO data source.
      *

Modified: java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/evio/EvioLoopAdapter.java
 =============================================================================
--- java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/evio/EvioLoopAdapter.java	(original)
+++ java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/evio/EvioLoopAdapter.java	Wed Apr 27 11:11:32 2016
@@ -1,14 +1,6 @@
 package org.hps.record.evio;
 
-import java.util.ArrayList;
-import java.util.List;
-import java.util.logging.Logger;
-
-import org.freehep.record.loop.AbstractLoopListener;
-import org.freehep.record.loop.LoopEvent;
-import org.freehep.record.loop.LoopListener;
-import org.freehep.record.loop.RecordEvent;
-import org.freehep.record.loop.RecordListener;
+import org.hps.record.AbstractLoopAdapter;
 import org.jlab.coda.jevio.EvioEvent;
 
 /**
@@ -16,79 +8,5 @@
  *
  * @author Jeremy McCormick, SLAC
  */
-public final class EvioLoopAdapter extends AbstractLoopListener implements RecordListener, LoopListener {
-
-    /**
-     * Initialize the logger.
-     */
-    private static final Logger LOGGER = Logger.getLogger(EvioLoopAdapter.class.getPackage().getName());
-
-    /**
-     * List of event processors to activate.
-     */
-    private final List<EvioEventProcessor> processors = new ArrayList<EvioEventProcessor>();
-
-    /**
-     * Create a new loop adapter.
-     */
-    EvioLoopAdapter() {
-    }
-
-    /**
-     * Add an EVIO processor to the adapter.
-     *
-     * @param processor the EVIO processor to add to the adapter
-     */
-    void addEvioEventProcessor(final EvioEventProcessor processor) {
-        LOGGER.info("adding " + processor.getClass().getName() + " to EVIO processors");
-        this.processors.add(processor);
-    }
-
-    /**
-     * Implementation of the finish hook which activates the {@link EvioEventProcessor#endJob()} method of all
-     * registered processors.
-     */
-    @Override
-    protected void finish(final LoopEvent event) {
-        LOGGER.info("finish");
-        for (final EvioEventProcessor processor : processors) {
-            processor.endJob();
-        }
-    }
-
-    /**
-     * Primary event processing method that activates the {@link EvioEventProcessor#process(EvioEvent)} method of all
-     * registered processors.
-     *
-     * @param recordEvent the record event to process which should have an EVIO event
-     * @throws IllegalArgumentException if the record is the wrong type
-     */
-    @Override
-    public void recordSupplied(final RecordEvent recordEvent) {
-        final Object record = recordEvent.getRecord();
-        if (record instanceof EvioEvent) {
-            final EvioEvent evioEvent = EvioEvent.class.cast(record);
-            for (final EvioEventProcessor processor : processors) {
-                try {
-                    processor.process(evioEvent);
-                } catch (final Exception e) {
-                    throw new RuntimeException(e);
-                }
-            }
-        } else {
-            throw new IllegalArgumentException("The supplied record has the wrong type: " + record.getClass());
-        }
-    }
-
-    /**
-     * Implementation of the start hook which activates the {@link EvioEventProcessor#startJob()} method of all
-     * registered processors.
-     */
-    @Override
-    protected void start(final LoopEvent event) {
-        LOGGER.info("start");
-        for (final EvioEventProcessor processor : processors) {
-            processor.startJob();
-        }
-    }
+public final class EvioLoopAdapter extends AbstractLoopAdapter<EvioEvent> {
 }

Modified: java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/scalers/ScalerUtilities.java
 =============================================================================
--- java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/scalers/ScalerUtilities.java	(original)
+++ java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/scalers/ScalerUtilities.java	Wed Apr 27 11:11:32 2016
@@ -74,7 +74,6 @@
         // [67]/[68] = CLOCK
         final double clock = (double) clockGated / (double) clockUngated;
 
-        // Compute the live times.
         final double[] liveTimes = new double[3];
         liveTimes[LiveTimeIndex.FCUP_TDC.ordinal()] = fcupTdc;
         liveTimes[LiveTimeIndex.FCUP_TRG.ordinal()] = fcupTrg;

Modified: java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/svt/SvtEvioUtils.java
 =============================================================================
--- java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/svt/SvtEvioUtils.java	(original)
+++ java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/svt/SvtEvioUtils.java	Wed Apr 27 11:11:32 2016
@@ -1,11 +1,16 @@
 package org.hps.record.svt;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.jlab.coda.jevio.BaseStructure;
+import org.jlab.coda.jevio.DataType;
+import org.jlab.coda.jevio.StructureType;
 
 
 /**
  *  A set of static utility methods used to decode SVT data.
  * 
  *  @author Omar Moreno <[log in to unmask]>
- *  @date November 20, 2014
  */
 public class SvtEvioUtils {
 
@@ -19,9 +24,7 @@
     private static final int APV_HEADER_BUFFER_ADDRESS_MASK  = 0xFF; //[8:1]
     private static final int APV_HEADER_DATA_FRAME_COUNT_MASK = 0xF; //[12:9]
     private static final int APV_HEADER_DATA_APV_NR_MASK = 0x3; //[15:13]
-    
-
-   
+      
     // TODO: Move these to constants class
     public static final int APV25_PER_HYBRID = 5;
     public static final int CHANNELS_PER_APV25 = 128;
@@ -90,13 +93,12 @@
      *  Extract and return the front end board (FEB) ID associated with the
      *  multisample tail
      *  
-     *  @param data : a multisample header
+     *  @param multisampleTail : a multisample header
      *  @return A FEB ID in the range 0-10
      */
     public static int getFebIDFromMultisampleTail(int multisampleTail) { 
         return (multisampleTail >>> 8) & FEB_MASK; 
     }
-
     
     /**
      *  Extract and return the front end board (FEB) hybrid ID associated with 
@@ -113,7 +115,7 @@
      *  Extract and return the front end board (FEB) hybrid ID associated with 
      *  the multisample tail 
      *
-     *  @param multisample : a  multisample tail
+     *  @param multisampleTail : a  multisample tail
      *  @return A FEB hybrid ID in the range 0-3
      */
     public static int getFebHybridIDFromMultisampleTail(int multisampleTail) { 
@@ -258,7 +260,7 @@
     /**
      *  Extract the error bit from the multisample header.
      *
-     *  @param data : multisample of data
+     *  @param multisampleHeader : multisample of data
      *  @return value of the error bit.  This is non-zero if there is an error.
      */
     public static int getErrorBitFromMultisampleHeader(int multisampleHeader) { 
@@ -441,6 +443,56 @@
         return samples;
     }
 
+    /**
+     *  Retrieve all the banks in an event that match the given tag in their
+     *  header and are not data banks. 
+     *
+     *  @param evioEvent : The event/bank being queried
+     *  @param tag : The tag to match
+     *  @return A collection of all bank structures that pass the filter 
+     *          provided by the event
+     */
+    public static List<BaseStructure> getROCBanks(BaseStructure evioEvent, int minROCTag, int maxROCTag) {
+        List<BaseStructure> matchingBanks = new ArrayList<BaseStructure>();
+        if (evioEvent.getChildCount() > 0) {
+            for (BaseStructure childBank : evioEvent.getChildrenList()) {
+                if (childBank.getStructureType() == StructureType.BANK
+                        && childBank.getHeader().getDataType() == DataType.ALSOBANK
+                        && childBank.getHeader().getTag() >= minROCTag
+                        && childBank.getHeader().getTag() <= maxROCTag) {
+                    matchingBanks.add(childBank);
+                }
+            }
+        }
+        return matchingBanks;
+    }
+
+    public static List<BaseStructure> getDataBanks(BaseStructure evioEvent, int minROCTag, int maxROCTag, int minDataTag, int maxDataTag) {
+        List<BaseStructure> rocBanks = getROCBanks(evioEvent, minROCTag, maxROCTag);
+        List<BaseStructure> matchingBanks = new ArrayList<BaseStructure>();
+        for (BaseStructure rocBank : rocBanks) {
+            if (rocBank.getChildCount() > 0) {
+                for (BaseStructure childBank : rocBank.getChildrenList()) {
+                    if (childBank.getHeader().getTag() >= minDataTag
+                            && childBank.getHeader().getTag() <= maxDataTag) {
+                        matchingBanks.add(childBank);
+                    }
+                }
+            }
+        }
+        return matchingBanks;
+    }
+    
+    public static List<int[]> getMultisamples(int[] data, int sampleCount, int headerLength) {
+        List<int[]> sampleList = new ArrayList<int[]>();
+        // Loop through all of the samples and make hits
+        for (int samplesN = 0; samplesN < sampleCount; samplesN += 4) {
+            int[] samples = new int[4];
+            System.arraycopy(data, headerLength + samplesN, samples, 0, samples.length);
+            sampleList.add(samples);
+        }
+        return sampleList;
+    }
 
     /**
      *  Private constructor to prevent the class from being instantiated.

Modified: java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/triggerbank/AbstractIntData.java
 =============================================================================
--- java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/triggerbank/AbstractIntData.java	(original)
+++ java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/triggerbank/AbstractIntData.java	Wed Apr 27 11:11:32 2016
@@ -74,7 +74,6 @@
      * Return the int bank of an AbstractIntData read from LCIO.
      *
      * @param object
-     * @return
      */
     public static int[] getBank(GenericObject object) {
         int N = object.getNInt() - 1;

Modified: java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/triggerbank/SSPData.java
 =============================================================================
--- java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/triggerbank/SSPData.java	(original)
+++ java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/triggerbank/SSPData.java	Wed Apr 27 11:11:32 2016
@@ -175,7 +175,7 @@
      * of <code>SSPCosmicTrigger</code> objects.
      */
     public List<SSPCosmicTrigger> getCosmicTriggers() {
-    	return cosmicList;
+        return cosmicList;
     }
     
     /**
@@ -184,7 +184,7 @@
      * of <code>SSPPairTrigger</code> objects.
      */
     public List<SSPPairTrigger> getPairTriggers() {
-    	return pairList;
+        return pairList;
     }
     
     /**
@@ -193,7 +193,7 @@
      * of <code>SSPSinglesTrigger</code> objects.
      */
     public List<SSPSinglesTrigger> getSinglesTriggers() {
-    	return singlesList;
+        return singlesList;
     }
     
     /**

Modified: java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/triggerbank/SSPNumberedTrigger.java
 =============================================================================
--- java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/triggerbank/SSPNumberedTrigger.java	(original)
+++ java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/triggerbank/SSPNumberedTrigger.java	Wed Apr 27 11:11:32 2016
@@ -10,16 +10,41 @@
  * @see SSPTrigger
  */
 public abstract class SSPNumberedTrigger extends SSPTrigger {
-	/**
-	 * Instantiates the <code>SSPNumberedTrigger</code>.
+    /**
+     * Instantiates the <code>SSPNumberedTrigger</code>.
      * @param type - The type of trigger.
      * @param time - The time at which the trigger occurred in ns.
      * @param data - The trigger bit data.
-	 */
-	public SSPNumberedTrigger(int type, int time, int data) {
-		super(type, time, data);
-	}
-	
+     */
+    public SSPNumberedTrigger(int type, int time, int data) {
+        super(type, time, data);
+    }
+    
+    /**
+     * Gets the number of the trigger which generated this object.
+     * @return Returns either <code>0</code> or </code>1</code>.
+     */
+    public abstract int getTriggerNumber();
+    
+    /**
+     * Indicates whether the trigger was reported by the trigger number
+     * 0 trigger.
+     * @return <code>true</code> if the trigger was reported by the
+     * trigger number 0 trigger and <code>false</code> if by either
+     * the trigger number 1 or an unknown trigger.
+     */
+    public abstract boolean isTrigger0();
+    
+    /**
+     * Indicates whether the trigger was reported by the trigger number
+     * 1 trigger.
+     * @return <code>true</code> if the trigger was reported by the
+     * trigger number 1 trigger and <code>false</code> if by either
+     * the trigger number 0 or an unknown trigger.
+     */
+    public abstract boolean isTrigger1();
+    
+    
     /**
      * Indicates whether the trigger was reported by the first of the
      * singles triggers.
@@ -27,6 +52,7 @@
      * first trigger and <code>false</code> if it was reported by the
      * second trigger.
      */
+    @Deprecated
     public abstract boolean isFirstTrigger();
     
     /**
@@ -36,5 +62,6 @@
      * second trigger and <code>false</code> if it was reported by
      * the first trigger.
      */
+    @Deprecated
     public abstract boolean isSecondTrigger();
-}
+}

Modified: java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/triggerbank/SSPPairTrigger.java
 =============================================================================
--- java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/triggerbank/SSPPairTrigger.java	(original)
+++ java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/triggerbank/SSPPairTrigger.java	Wed Apr 27 11:11:32 2016
@@ -20,13 +20,30 @@
     }
     
     @Override
+    public int getTriggerNumber() {
+        if(isFirstTrigger()) { return 0; }
+        else if(isSecondTrigger()) { return 1; }
+        else { return -1; }
+    }
+    
+    @Override
+    public boolean isTrigger0() {
+        return (type == SSPData.TRIG_TYPE_PAIR0);
+    }
+    
+    @Override
+    public boolean isTrigger1() {
+        return (type == SSPData.TRIG_TYPE_PAIR1);
+    }
+    
+    @Override
     public boolean isFirstTrigger() {
-    	return (type == SSPData.TRIG_TYPE_PAIR0);
+        return isTrigger0();
     }
     
     @Override
     public boolean isSecondTrigger() {
-    	return (type == SSPData.TRIG_TYPE_PAIR1);
+        return isTrigger1();
     }
     
     /**
@@ -71,9 +88,9 @@
     
     @Override
     public String toString() {
-		return String.format("Trigger %d :: %3d ns :: ESum: %d, EDiff: %d, ESlope: %d, Coplanarity: %d",
-				isFirstTrigger() ? 1 : 2, getTime(), passCutEnergySum() ? 1 : 0,
-				passCutEnergyDifference() ? 1 : 0, passCutEnergySlope() ? 1 : 0,
-				passCutCoplanarity() ? 1 : 0);
+        return String.format("Trigger %d :: %3d ns :: ESum: %d, EDiff: %d, ESlope: %d, Coplanarity: %d",
+                isFirstTrigger() ? 1 : 2, getTime(), passCutEnergySum() ? 1 : 0,
+                passCutEnergyDifference() ? 1 : 0, passCutEnergySlope() ? 1 : 0,
+                passCutCoplanarity() ? 1 : 0);
     }
 }

Modified: java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/triggerbank/SSPSinglesTrigger.java
 =============================================================================
--- java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/triggerbank/SSPSinglesTrigger.java	(original)
+++ java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/triggerbank/SSPSinglesTrigger.java	Wed Apr 27 11:11:32 2016
@@ -26,13 +26,30 @@
     }
     
     @Override
+    public int getTriggerNumber() {
+        if(isFirstTrigger()) { return 0; }
+        else if(isSecondTrigger()) { return 1; }
+        else { return -1; }
+    }
+    
+    @Override
+    public boolean isTrigger0() {
+        return (type == SSPData.TRIG_TYPE_SINGLES0_BOT) || (type == SSPData.TRIG_TYPE_SINGLES0_TOP);
+    }
+    
+    @Override
+    public boolean isTrigger1() {
+        return (type == SSPData.TRIG_TYPE_SINGLES1_BOT) || (type == SSPData.TRIG_TYPE_SINGLES1_TOP);
+    }
+    
+    @Override
     public boolean isFirstTrigger() {
-    	return (type == SSPData.TRIG_TYPE_SINGLES0_BOT) || (type == SSPData.TRIG_TYPE_SINGLES0_TOP);
+        return isTrigger0();
     }
     
     @Override
     public boolean isSecondTrigger() {
-    	return (type == SSPData.TRIG_TYPE_SINGLES1_BOT) || (type == SSPData.TRIG_TYPE_SINGLES1_TOP);
+        return isTrigger1();
     }
     
     /**
@@ -67,8 +84,8 @@
     
     @Override
     public String toString() {
-		return String.format("Trigger %d :: %3d ns :: EClusterLow: %d; EClusterHigh %d; HitCount: %d",
-				isFirstTrigger() ? 1 : 2, getTime(), passCutEnergyMin() ? 1 : 0,
-				passCutEnergyMax() ? 1 : 0, passCutHitCount() ? 1 : 0);
+        return String.format("Trigger %d :: %3d ns :: EClusterLow: %d; EClusterHigh %d; HitCount: %d",
+                isFirstTrigger() ? 1 : 2, getTime(), passCutEnergyMin() ? 1 : 0,
+                passCutEnergyMax() ? 1 : 0, passCutHitCount() ? 1 : 0);
     }
 }

Modified: java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/triggerbank/TIData.java
 =============================================================================
--- java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/triggerbank/TIData.java	(original)
+++ java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/triggerbank/TIData.java	Wed Apr 27 11:11:32 2016
@@ -5,18 +5,25 @@
 /**
  * Class <code>TIData</code> is an implementation of abstract class
  * <code>AbstractIntData</code> that represents a TI trigger bit bank.
- * It contains both a time window length and a set of flags that track
- * whether a trigger of a given type was registered with the event to
- * which this bank is attached.
  *
  * @author Nathan Baltzell <[log in to unmask]>
  */
 public class TIData extends AbstractIntData {
-	/** The EvIO bank header tag for TI data banks. */
+
+    /**
+     * The EvIO bank header tag for TI data banks.
+     */
     public static final int BANK_TAG = 0xe10a; // EvioEventConstants.TI_TRIGGER_BANK_TAG;
-    /** The expected number of entries in the data bank. */
-    public static final int BANK_SIZE = 4;
-    
+    /**
+     * The expected number of entries in the data bank for the 2015 data.
+     */
+    private static final int BANK_SIZE_2015 = 4;
+    /**
+     * The expected number of entries in the data bank for the 2016 data (after
+     * unprescaled trigger bits were added).
+     */
+    private static final int BANK_SIZE_2016 = 5;
+
     // Store the parsed data bank parameters.
     private long time = 0;
     private boolean singles0 = false;
@@ -25,36 +32,59 @@
     private boolean pairs1 = false;
     private boolean calib = false;
     private boolean pulser = false;
-    
-    /**
-     * Creates a <code>TIData</code> bank from a raw EvIO data bank.
-     * It is expected that the EvIO reader will verify that the bank
-     * tag is of the appropriate type.
+    private boolean hasUnprescaledTriggerBits = false;
+    private boolean singles0Unprescaled = false;
+    private boolean singles1Unprescaled = false;
+    private boolean pairs0Unprescaled = false;
+    private boolean pairs1Unprescaled = false;
+    private boolean calibUnprescaled = false;
+    private boolean pulserUnprescaled = false;
+
+    /**
+     * Creates a <code>TIData</code> bank from a raw EvIO data bank. It is
+     * expected that the EvIO reader will verify that the bank tag is of the
+     * appropriate type.
+     *
      * @param bank - The EvIO data bank.
      */
     public TIData(int[] bank) {
         super(bank);
         decodeData();
     }
-    
+
     /**
      * Creates a <code>TIData</code> object from an existing LCIO
      * <code>GenericObject</code>.
+     *
      * @param tiData - The source data bank object.
      */
     public TIData(GenericObject tiData) {
         super(tiData, BANK_TAG);
         decodeData();
     }
-    
+
     @Override
     protected final void decodeData() {
-    	// Check that the data bank is the expected size. If not, throw
-    	// and exception.
-        if(this.bank.length != BANK_SIZE) {
-            throw new RuntimeException("Invalid Data Length:  " + bank.length);
-        }
-        
+        // Check that the data bank is the expected size. If not, throw
+        // and exception.
+        switch (this.bank.length) {
+            case BANK_SIZE_2015:
+//                System.out.println("2015-style TI bank");
+                break;
+            case BANK_SIZE_2016:
+//                System.out.format("2016-style TI bank, first word %x, last word %x\n", bank[0], bank[4]);
+                hasUnprescaledTriggerBits = true;
+                singles0Unprescaled = ((bank[0]) & 1) == 1;
+                singles1Unprescaled = ((bank[0] >> 1) & 1) == 1;
+                pairs0Unprescaled = ((bank[0] >> 2) & 1) == 1;
+                pairs1Unprescaled = ((bank[0] >> 3) & 1) == 1;
+                calibUnprescaled = ((bank[0] >> 4) & 1) == 1;
+                pulserUnprescaled = ((bank[0] >> 5) & 1) == 1;
+                break;
+            default:
+                throw new RuntimeException("Invalid Data Length:  " + bank.length);
+        }
+
         // Check each trigger bit to see if it is active. A value of 
         // 1 indicates a trigger of that type occurred, and 0 that it
         // did not.
@@ -64,83 +94,175 @@
         pairs1 = ((bank[0] >> 27) & 1) == 1;
         calib = ((bank[0] >> 28) & 1) == 1;
         pulser = ((bank[0] >> 29) & 1) == 1;
-        
-        // Get the unprocessed start and end times for the bank.
-        long w1 = bank[2] & 0xffffffffL;
-        long w2 = bank[3] & 0xffffffffL;
-        
-        // Process the times into units of clock-cycles.
+
+        // interpret time:
+        final long w1 = bank[2] & 0xffffffffL;
+        final long w2 = bank[3] & 0xffffffffL;
         final long timelo = w1;
         final long timehi = (w2 & 0xffff) << 32;
-        
-        // Store the time difference in nanoseconds.
         time = 4 * (timelo + timehi);
     }
-    
+
     @Override
     public int getTag() {
         return BANK_TAG;
     }
-    
-    /**
-     * Gets the time window for the bank.
-     * @return Returns the time window length in nanoseconds.
-     */
+
     public long getTime() {
         return time;
     }
-    
+
     /**
      * Indicates whether a singles 0 trigger was registered.
+     *
      * @return Returns <code>true</code> if the trigger occurred, and
      * <code>false</code> otherwise.
      */
     public boolean isSingle0Trigger() {
         return singles0;
     }
-    
+
     /**
      * Indicates whether a singles 1 trigger was registered.
+     *
      * @return Returns <code>true</code> if the trigger occurred, and
      * <code>false</code> otherwise.
      */
     public boolean isSingle1Trigger() {
         return singles1;
     }
-    
+
     /**
      * Indicates whether a pair 0 trigger was registered.
+     *
      * @return Returns <code>true</code> if the trigger occurred, and
      * <code>false</code> otherwise.
      */
     public boolean isPair0Trigger() {
         return pairs0;
     }
-    
+
     /**
      * Indicates whether a pair 1 trigger was registered.
+     *
      * @return Returns <code>true</code> if the trigger occurred, and
      * <code>false</code> otherwise.
      */
     public boolean isPair1Trigger() {
         return pairs1;
     }
-    
+
     /**
      * Indicates whether a cosmic trigger was registered.
+     *
      * @return Returns <code>true</code> if the trigger occurred, and
      * <code>false</code> otherwise.
      */
     public boolean isCalibTrigger() {
         return calib;
     }
-    
+
     /**
      * Indicates whether a random/pulser trigger was registered.
+     *
      * @return Returns <code>true</code> if the trigger occurred, and
      * <code>false</code> otherwise.
      */
     public boolean isPulserTrigger() {
         return pulser;
     }
-}
+
+    /**
+     * Indicates whether this TI data has unprescaled trigger bits.
+     *
+     * @return Returns <code>true</code> if the TI data has a fifth int
+     * containing unprescaled trigger bits, and <code>false</code> otherwise.
+     */
+    public boolean hasUnprescaledTriggerBits() {
+        return hasUnprescaledTriggerBits;
+    }
+
+    /**
+     * Indicates whether a singles 0 (unprescaled) trigger was registered.
+     *
+     * @return Returns <code>true</code> if the trigger occurred, and
+     * <code>false</code> otherwise. Throws a RuntimeException if this data does
+     * not have unprescaled trigger bits.
+     */
+    public boolean isSingle0UnprescaledTrigger() {
+        if (!hasUnprescaledTriggerBits) {
+            throw new RuntimeException("This TI data does not have unprescaled trigger bits.");
+        }
+        return singles0Unprescaled;
+    }
+
+    /**
+     * Indicates whether a singles 1 (unprescaled) trigger was registered.
+     *
+     * @return Returns <code>true</code> if the trigger occurred, and
+     * <code>false</code> otherwise. Throws a RuntimeException if this data does
+     * not have unprescaled trigger bits.
+     */
+    public boolean isSingle1UnprescaledTrigger() {
+        if (!hasUnprescaledTriggerBits) {
+            throw new RuntimeException("This TI data does not have unprescaled trigger bits.");
+        }
+        return singles1Unprescaled;
+    }
+
+    /**
+     * Indicates whether a pairs 0 (unprescaled) trigger was registered.
+     *
+     * @return Returns <code>true</code> if the trigger occurred, and
+     * <code>false</code> otherwise. Throws a RuntimeException if this data does
+     * not have unprescaled trigger bits.
+     */
+    public boolean isPair0UnprescaledTrigger() {
+        if (!hasUnprescaledTriggerBits) {
+            throw new RuntimeException("This TI data does not have unprescaled trigger bits.");
+        }
+        return pairs0Unprescaled;
+    }
+
+    /**
+     * Indicates whether a pairs 1 (unprescaled) trigger was registered.
+     *
+     * @return Returns <code>true</code> if the trigger occurred, and
+     * <code>false</code> otherwise. Throws a RuntimeException if this data does
+     * not have unprescaled trigger bits.
+     */
+    public boolean isPair1UnprescaledTrigger() {
+        if (!hasUnprescaledTriggerBits) {
+            throw new RuntimeException("This TI data does not have unprescaled trigger bits.");
+        }
+        return pairs1Unprescaled;
+    }
+
+    /**
+     * Indicates whether a cosmic (unprescaled) trigger was registered.
+     *
+     * @return Returns <code>true</code> if the trigger occurred, and
+     * <code>false</code> otherwise. Throws a RuntimeException if this data does
+     * not have unprescaled trigger bits.
+     */
+    public boolean isCalibUnprescaledTrigger() {
+        if (!hasUnprescaledTriggerBits) {
+            throw new RuntimeException("This TI data does not have unprescaled trigger bits.");
+        }
+        return calibUnprescaled;
+    }
+
+    /**
+     * Indicates whether a random/pulser (unprescaled) trigger was registered.
+     *
+     * @return Returns <code>true</code> if the trigger occurred, and
+     * <code>false</code> otherwise. Throws a RuntimeException if this data does
+     * not have unprescaled trigger bits.
+     */
+    public boolean isPulserUnprescaledTrigger() {
+        if (!hasUnprescaledTriggerBits) {
+            throw new RuntimeException("This TI data does not have unprescaled trigger bits.");
+        }
+        return pulserUnprescaled;
+    }
+}

Modified: java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/triggerbank/TiTimeOffsetEvioProcessor.java
 =============================================================================
--- java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/triggerbank/TiTimeOffsetEvioProcessor.java	(original)
+++ java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/triggerbank/TiTimeOffsetEvioProcessor.java	Wed Apr 27 11:11:32 2016
@@ -55,13 +55,30 @@
             }
         }
     }
+    
+    public long getMinOffset() {
+        return this.minOffset;
+    }
+    
+    public long getMaxOffset() {
+        return this.maxOffset;
+    }
+    
+    public int getNumOutliers() {
+        return this.nOutliers;
+    }
+    
+    public long getTiTimeOffset() {
+        final long offsetRange = maxOffset - minOffset;
+        if (offsetRange > minRange && nOutliers < maxOutliers) {
+            return minOffset;
+        } else {
+            return 0L;
+        }
+    }
 
     public void updateTriggerConfig(final TriggerConfig triggerConfig) {
-        final long offsetRange = maxOffset - minOffset;
-        if (offsetRange > minRange && nOutliers < maxOutliers) {
-            triggerConfig.put(TriggerConfigVariable.TI_TIME_OFFSET, minOffset);
-        } else {
-            triggerConfig.put(TriggerConfigVariable.TI_TIME_OFFSET, 0L);
-        }
+        long tiTimeOffset = getTiTimeOffset();
+        triggerConfig.put(TriggerConfigVariable.TI_TIME_OFFSET, tiTimeOffset);
     }
 }

Modified: java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/triggerbank/TriggerModule.java
 =============================================================================
--- java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/triggerbank/TriggerModule.java	(original)
+++ java/branches/HPSJAVA-409/record-util/src/main/java/org/hps/record/triggerbank/TriggerModule.java	Wed Apr 27 11:11:32 2016
@@ -44,8 +44,8 @@
  * @see SSPCluster
  */
 public final class TriggerModule {
-	/** The calorimeter mid-plane, defined by the photon beam position
-	* (30.52 mrad) at the calorimeter face (z = 1393 mm). */
+    /** The calorimeter mid-plane, defined by the photon beam position
+    * (30.52 mrad) at the calorimeter face (z = 1393 mm). */
     private static final double ORIGIN_X = 1393.0 * Math.tan(0.03052);
     
     /** The value of the parameter "F" in the energy slope equation
@@ -104,23 +104,23 @@
      * above zero) will be accepted.
      */
     public TriggerModule() {
-    	// Set the cluster singles cuts to accept all values by default.
-    	cuts.put(CLUSTER_HIT_COUNT_LOW, 0.0);
-    	cuts.put(CLUSTER_SEED_ENERGY_LOW, 0.0);
-    	cuts.put(CLUSTER_SEED_ENERGY_HIGH, Double.MAX_VALUE);
-    	cuts.put(CLUSTER_TOTAL_ENERGY_LOW, 0.0);
-    	cuts.put(CLUSTER_TOTAL_ENERGY_HIGH, Double.MAX_VALUE);
-    	
-    	// Set the cluster pair cuts to accept all values by default.
-    	cuts.put(PAIR_COPLANARITY_HIGH, 180.0);
-    	cuts.put(PAIR_ENERGY_DIFFERENCE_HIGH, Double.MAX_VALUE);
-    	cuts.put(PAIR_ENERGY_SLOPE_LOW, 0.0);
-    	cuts.put(PAIR_ENERGY_SUM_LOW, 0.0);
-    	cuts.put(PAIR_ENERGY_SUM_HIGH, Double.MAX_VALUE);
-    	cuts.put(PAIR_TIME_COINCIDENCE, Double.MAX_VALUE);
-    	
-    	// Set the default value of the energy slope parameter F.
-    	cuts.put(PAIR_ENERGY_SLOPE_F, 0.0055);
+        // Set the cluster singles cuts to accept all values by default.
+        cuts.put(CLUSTER_HIT_COUNT_LOW, 0.0);
+        cuts.put(CLUSTER_SEED_ENERGY_LOW, 0.0);
+        cuts.put(CLUSTER_SEED_ENERGY_HIGH, Double.MAX_VALUE);
+        cuts.put(CLUSTER_TOTAL_ENERGY_LOW, 0.0);
+        cuts.put(CLUSTER_TOTAL_ENERGY_HIGH, Double.MAX_VALUE);
+        
+        // Set the cluster pair cuts to accept all values by default.
+        cuts.put(PAIR_COPLANARITY_HIGH, 180.0);
+        cuts.put(PAIR_ENERGY_DIFFERENCE_HIGH, Double.MAX_VALUE);
+        cuts.put(PAIR_ENERGY_SLOPE_LOW, 0.0);
+        cuts.put(PAIR_ENERGY_SUM_LOW, 0.0);
+        cuts.put(PAIR_ENERGY_SUM_HIGH, Double.MAX_VALUE);
+        cuts.put(PAIR_TIME_COINCIDENCE, Double.MAX_VALUE);
+        
+        // Set the default value of the energy slope parameter F.
+        cuts.put(PAIR_ENERGY_SLOPE_F, 0.0055);
     }
     
     /**
@@ -142,25 +142,25 @@
      * </ul>
      */
     public TriggerModule(double... cutValues) {
-    	// Set the cuts to the default values.
-    	this();
-    	
-    	// Define the cuts in the order that they correspond to the
-    	// value arguments.
-    	String[] cutID = { CLUSTER_HIT_COUNT_LOW, CLUSTER_SEED_ENERGY_LOW, CLUSTER_SEED_ENERGY_HIGH,
-    			CLUSTER_TOTAL_ENERGY_LOW, CLUSTER_TOTAL_ENERGY_HIGH, PAIR_ENERGY_SUM_LOW, PAIR_ENERGY_SUM_HIGH,
-    			PAIR_ENERGY_DIFFERENCE_HIGH, PAIR_ENERGY_SLOPE_LOW, PAIR_COPLANARITY_HIGH, PAIR_ENERGY_SLOPE_F };
-    	
-    	// Iterate over the value arguments and assign them to the
-    	// appropriate cut.
-    	for(int i = 0; i < cutValues.length; i++) {
-    		// If more values were given then cuts exist, break from
-    		// the loop.
-    		if(i == 11) { break; }
-    		
-    		// Set the current cut to its corresponding value.
-    		cuts.put(cutID[i], cutValues[i]);
-    	}
+        // Set the cuts to the default values.
+        this();
+        
+        // Define the cuts in the order that they correspond to the
+        // value arguments.
+        String[] cutID = { CLUSTER_HIT_COUNT_LOW, CLUSTER_SEED_ENERGY_LOW, CLUSTER_SEED_ENERGY_HIGH,
+                CLUSTER_TOTAL_ENERGY_LOW, CLUSTER_TOTAL_ENERGY_HIGH, PAIR_ENERGY_SUM_LOW, PAIR_ENERGY_SUM_HIGH,
+                PAIR_ENERGY_DIFFERENCE_HIGH, PAIR_ENERGY_SLOPE_LOW, PAIR_COPLANARITY_HIGH, PAIR_ENERGY_SLOPE_F };
+        
+        // Iterate over the value arguments and assign them to the
+        // appropriate cut.
+        for(int i = 0; i < cutValues.length; i++) {
+            // If more values were given then cuts exist, break from
+            // the loop.
+            if(i == 11) { break; }
+            
+            // Set the current cut to its corresponding value.
+            cuts.put(cutID[i], cutValues[i]);
+        }
     }
     
     /**
@@ -172,14 +172,14 @@
      * specified in the argument is not valid.
      */
     public double getCutValue(String cut) throws IllegalArgumentException {
-    	// Try to get the indicated cut.
-    	Double value = cuts.get(cut);
-    	
-    	// If the cut is valid, return it.
-    	if(value != null) { return value.doubleValue(); }
-    	
-    	// Otherwise, produce an exception.
-    	else { throw new IllegalArgumentException(String.format("Cut \"%s\" does not exist.", cut)); }
+        // Try to get the indicated cut.
+        Double value = cuts.get(cut);
+        
+        // If the cut is valid, return it.
+        if(value != null) { return value.doubleValue(); }
+        
+        // Otherwise, produce an exception.
+        else { throw new IllegalArgumentException(String.format("Cut \"%s\" does not exist.", cut)); }
     }
     
     /**
@@ -190,22 +190,22 @@
      * @param config - The DAQ configuration settings.
      */
     public void loadDAQConfiguration(SinglesTriggerConfig config) {
-    	// Set the trigger values.
-    	setCutValue(CLUSTER_TOTAL_ENERGY_LOW,  config.getEnergyMinCutConfig().getLowerBound());
-    	setCutValue(CLUSTER_TOTAL_ENERGY_HIGH, config.getEnergyMaxCutConfig().getUpperBound());
-    	setCutValue(CLUSTER_HIT_COUNT_LOW,     config.getHitCountCutConfig().getLowerBound());
-    	
-    	// The remaining triggers should be set to their default values.
-    	// These settings effectively accept all possible clusters.
-    	cuts.put(PAIR_COPLANARITY_HIGH, 180.0);
-    	cuts.put(PAIR_ENERGY_DIFFERENCE_HIGH, Double.MAX_VALUE);
-    	cuts.put(PAIR_ENERGY_SLOPE_LOW, 0.0);
-    	cuts.put(PAIR_ENERGY_SUM_LOW, 0.0);
-    	cuts.put(PAIR_ENERGY_SUM_HIGH, Double.MAX_VALUE);
-    	cuts.put(PAIR_TIME_COINCIDENCE, Double.MAX_VALUE);
-    	
-    	// Set the default value of the energy slope parameter F.
-    	cuts.put(PAIR_ENERGY_SLOPE_F, 0.0055);
+        // Set the trigger values.
+        setCutValue(CLUSTER_TOTAL_ENERGY_LOW,  config.getEnergyMinCutConfig().getLowerBound());
+        setCutValue(CLUSTER_TOTAL_ENERGY_HIGH, config.getEnergyMaxCutConfig().getUpperBound());
+        setCutValue(CLUSTER_HIT_COUNT_LOW,     config.getHitCountCutConfig().getLowerBound());
+        
+        // The remaining triggers should be set to their default values.
+        // These settings effectively accept all possible clusters.
+        cuts.put(PAIR_COPLANARITY_HIGH, 180.0);
+        cuts.put(PAIR_ENERGY_DIFFERENCE_HIGH, Double.MAX_VALUE);
+        cuts.put(PAIR_ENERGY_SLOPE_LOW, 0.0);
+        cuts.put(PAIR_ENERGY_SUM_LOW, 0.0);
+        cuts.put(PAIR_ENERGY_SUM_HIGH, Double.MAX_VALUE);
+        cuts.put(PAIR_TIME_COINCIDENCE, Double.MAX_VALUE);
+        
+        // Set the default value of the energy slope parameter F.
+        cuts.put(PAIR_ENERGY_SLOPE_F, 0.0055);
     }
     
     /**
@@ -215,22 +215,22 @@
      * @param config - The DAQ configuration settings.
      */
     public void loadDAQConfiguration(PairTriggerConfig config) {
-    	// Set the trigger values.
-    	setCutValue(CLUSTER_TOTAL_ENERGY_LOW,  config.getEnergyMinCutConfig().getLowerBound());
-    	setCutValue(CLUSTER_TOTAL_ENERGY_HIGH, config.getEnergyMaxCutConfig().getUpperBound());
-    	setCutValue(CLUSTER_HIT_COUNT_LOW,     config.getHitCountCutConfig().getLowerBound());
-    	
-    	// The remaining triggers should be set to their default values.
-    	// These settings effectively accept all possible clusters.
-    	cuts.put(PAIR_COPLANARITY_HIGH, config.getCoplanarityCutConfig().getUpperBound());
-    	cuts.put(PAIR_ENERGY_DIFFERENCE_HIGH, config.getEnergyDifferenceCutConfig().getUpperBound());
-    	cuts.put(PAIR_ENERGY_SLOPE_LOW, config.getEnergySlopeCutConfig().getLowerBound());
-    	cuts.put(PAIR_ENERGY_SUM_LOW, config.getEnergySumCutConfig().getLowerBound());
-    	cuts.put(PAIR_ENERGY_SUM_HIGH, config.getEnergySumCutConfig().getUpperBound());
-    	cuts.put(PAIR_TIME_COINCIDENCE, config.getTimeDifferenceCutConfig().getUpperBound() * 4.0);
-    	
-    	// Set the default value of the energy slope parameter F.
-    	cuts.put(PAIR_ENERGY_SLOPE_F, config.getEnergySlopeCutConfig().getParameterF());
+        // Set the trigger values.
+        setCutValue(CLUSTER_TOTAL_ENERGY_LOW,  config.getEnergyMinCutConfig().getLowerBound());
+        setCutValue(CLUSTER_TOTAL_ENERGY_HIGH, config.getEnergyMaxCutConfig().getUpperBound());
+        setCutValue(CLUSTER_HIT_COUNT_LOW,     config.getHitCountCutConfig().getLowerBound());
+        
+        // The remaining triggers should be set to their default values.
+        // These settings effectively accept all possible clusters.
+        cuts.put(PAIR_COPLANARITY_HIGH, config.getCoplanarityCutConfig().getUpperBound());
+        cuts.put(PAIR_ENERGY_DIFFERENCE_HIGH, config.getEnergyDifferenceCutConfig().getUpperBound());
+        cuts.put(PAIR_ENERGY_SLOPE_LOW, config.getEnergySlopeCutConfig().getLowerBound());
+        cuts.put(PAIR_ENERGY_SUM_LOW, config.getEnergySumCutConfig().getLowerBound());
+        cuts.put(PAIR_ENERGY_SUM_HIGH, config.getEnergySumCutConfig().getUpperBound());
+        cuts.put(PAIR_TIME_COINCIDENCE, config.getTimeDifferenceCutConfig().getUpperBound() * 4.0);
+        
+        // Set the default value of the energy slope parameter F.
+        cuts.put(PAIR_ENERGY_SLOPE_F, config.getEnergySlopeCutConfig().getParameterF());
     }
     
     /**
@@ -244,76 +244,76 @@
      * identifier is not valid.
      */
     public void setCutValue(String cut, double value) throws IllegalArgumentException {
-    	// Make sure that the cut exists. If it does, change it to the
-    	// new cut value.
-    	if(cuts.containsKey(cut)) {
-    		cuts.put(cut, value);
-    	}
-    	
-    	// Otherwise, throw an exception.
-    	else { throw new IllegalArgumentException(String.format("Cut \"%s\" does not exist.", cut)); }
-    }
-    
-	/**
-	 * Sets the cluster singles cuts to the values parsed from an
-	 * argument string.
-	 * @param isSingles - Indicates whether the parser should expect
-	 * 10 cut values (for pairs) or 3 (for singles).
-	 * @param cutValues - A string representing the cuts values. This
-	 * must be formatted in the style of "Emin Emax Nmin ...".
-	 */
+        // Make sure that the cut exists. If it does, change it to the
+        // new cut value.
+        if(cuts.containsKey(cut)) {
+            cuts.put(cut, value);
+        }
+        
+        // Otherwise, throw an exception.
+        else { throw new IllegalArgumentException(String.format("Cut \"%s\" does not exist.", cut)); }
+    }
+    
+    /**
+     * Sets the cluster singles cuts to the values parsed from an
+     * argument string.
+     * @param isSingles - Indicates whether the parser should expect
+     * 10 cut values (for pairs) or 3 (for singles).
+     * @param cutValues - A string representing the cuts values. This
+     * must be formatted in the style of "Emin Emax Nmin ...".
+     */
     // TODO: Specify in JavaDoc what the order of these arguments is.
-	public void setCutValues(boolean isSingles, String cutValues) {
-		// Make sure that the string is not null.
-		if(cutValues == null) {
-			throw new NullPointerException(String.format("Cut arguments for trigger are null!"));
-		}
-		
-		// Tokenize the argument string.
-		StringTokenizer tokens = new StringTokenizer(cutValues);
-		
-		// Store the cut values. Entry format is:
-		// clusterEnergyMin clusterEnergyMax hitCountMin
-		// clusterEnergyMin clusterEnergyMax hitCountMin pairSumMin pairSumMax pairDiffMax pairSlopeMin pairSlopeF pairCoplanarityMax pairTimeCoincidence
-		double cuts[];
-		if(isSingles) { cuts = new double[] { 0.0, 8.191, 0 }; }
-		else { cuts = new double[] { 0.0, 8.191, 0, 0, 8.191, 8.191, 0, 0.0055, 180, Double.MAX_VALUE }; }
-		String[] cutNames = { "clusterEnergyMin", "clusterEnergyMax", "hitCountMin",
-				"pairSumMin", "pairSumMax", "pairDiffMax", "pairSlopeMin", "pairSlopeF",
-				"pairCoplanarityMax", "pairTimeCoincidence" };
-		
-		// Iterate over the number of cuts and extract that many values
-		// from the cut value string.
-		for(int cutNum = 0; cutNum < cuts.length; cutNum++) {
-			// If there are no more tokens left, the argument string
-			// is missing some values. Throw an exception!
-			if(tokens.hasMoreTokens()) {
-				// Get the next token from the string.
-				String arg = tokens.nextToken();
-				
-				// Try to parse the token as a double. All cut values
-				// should be rendered as doubles (or integers, which
-				// can be parsed as doubles). If it is not, the string
-				// is improperly formatted.
-				try { cuts[cutNum] = Double.parseDouble(arg); }
-				catch(NumberFormatException e) {
-					throw new NumberFormatException(String.format("Argument for \"%s\" improperly formatted: %s", cutNames[cutNum], arg));
-				}
-			}
-		}
-		
-		// Store the cuts in the trigger.
-		setCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_LOW,    cuts[0]);
-		setCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_HIGH,   cuts[1]);
-		setCutValue(TriggerModule.CLUSTER_HIT_COUNT_LOW,       cuts[2]);
-		setCutValue(TriggerModule.PAIR_ENERGY_SUM_LOW,         cuts[3]);
-		setCutValue(TriggerModule.PAIR_ENERGY_SUM_HIGH,        cuts[4]);
-		setCutValue(TriggerModule.PAIR_ENERGY_DIFFERENCE_HIGH, cuts[5]);
-		setCutValue(TriggerModule.PAIR_ENERGY_SLOPE_LOW,       cuts[6]);
-		setCutValue(TriggerModule.PAIR_ENERGY_SLOPE_F,         cuts[7]);
-		setCutValue(TriggerModule.PAIR_COPLANARITY_HIGH,       cuts[8]);
-		setCutValue(TriggerModule.PAIR_TIME_COINCIDENCE,       cuts[9]);
-	}
+    public void setCutValues(boolean isSingles, String cutValues) {
+        // Make sure that the string is not null.
+        if(cutValues == null) {
+            throw new NullPointerException(String.format("Cut arguments for trigger are null!"));
+        }
+        
+        // Tokenize the argument string.
+        StringTokenizer tokens = new StringTokenizer(cutValues);
+        
+        // Store the cut values. Entry format is:
+        // clusterEnergyMin clusterEnergyMax hitCountMin
+        // clusterEnergyMin clusterEnergyMax hitCountMin pairSumMin pairSumMax pairDiffMax pairSlopeMin pairSlopeF pairCoplanarityMax pairTimeCoincidence
+        double cuts[];
+        if(isSingles) { cuts = new double[] { 0.0, 8.191, 0 }; }
+        else { cuts = new double[] { 0.0, 8.191, 0, 0, 8.191, 8.191, 0, 0.0055, 180, Double.MAX_VALUE }; }
+        String[] cutNames = { "clusterEnergyMin", "clusterEnergyMax", "hitCountMin",
+                "pairSumMin", "pairSumMax", "pairDiffMax", "pairSlopeMin", "pairSlopeF",
+                "pairCoplanarityMax", "pairTimeCoincidence" };
+        
+        // Iterate over the number of cuts and extract that many values
+        // from the cut value string.
+        for(int cutNum = 0; cutNum < cuts.length; cutNum++) {
+            // If there are no more tokens left, the argument string
+            // is missing some values. Throw an exception!
+            if(tokens.hasMoreTokens()) {
+                // Get the next token from the string.
+                String arg = tokens.nextToken();
+                
+                // Try to parse the token as a double. All cut values
+                // should be rendered as doubles (or integers, which
+                // can be parsed as doubles). If it is not, the string
+                // is improperly formatted.
+                try { cuts[cutNum] = Double.parseDouble(arg); }
+                catch(NumberFormatException e) {
+                    throw new NumberFormatException(String.format("Argument for \"%s\" improperly formatted: %s", cutNames[cutNum], arg));
+                }
+            }
+        }
+        
+        // Store the cuts in the trigger.
+        setCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_LOW,    cuts[0]);
+        setCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_HIGH,   cuts[1]);
+        setCutValue(TriggerModule.CLUSTER_HIT_COUNT_LOW,       cuts[2]);
+        setCutValue(TriggerModule.PAIR_ENERGY_SUM_LOW,         cuts[3]);
+        setCutValue(TriggerModule.PAIR_ENERGY_SUM_HIGH,        cuts[4]);
+        setCutValue(TriggerModule.PAIR_ENERGY_DIFFERENCE_HIGH, cuts[5]);
+        setCutValue(TriggerModule.PAIR_ENERGY_SLOPE_LOW,       cuts[6]);
+        setCutValue(TriggerModule.PAIR_ENERGY_SLOPE_F,         cuts[7]);
+        setCutValue(TriggerModule.PAIR_COPLANARITY_HIGH,       cuts[8]);
+        setCutValue(TriggerModule.PAIR_TIME_COINCIDENCE,       cuts[9]);
+    }
     
     /**
      * Checks whether a cluster passes the cluster hit count cut. This
@@ -346,7 +346,7 @@
      * and <code>false</code> if the cluster does not.
      */
     public boolean clusterSeedEnergyCut(Cluster cluster) {
-    	return clusterSeedEnergyCut(getValueClusterSeedEnergy(cluster));
+        return clusterSeedEnergyCut(getValueClusterSeedEnergy(cluster));
     }
     
     /**
@@ -357,7 +357,7 @@
      * and <code>false</code> if the cluster does not.
      */
     public boolean clusterSeedEnergyCutHigh(Cluster cluster) {
-    	return clusterSeedEnergyCutHigh(getValueClusterSeedEnergy(cluster));
+        return clusterSeedEnergyCutHigh(getValueClusterSeedEnergy(cluster));
     }
     
     /**
@@ -368,7 +368,7 @@
      * and <code>false</code> if the cluster does not.
      */
     public boolean clusterSeedEnergyCutLow(Cluster cluster) {
-    	return clusterSeedEnergyCutLow(getValueClusterSeedEnergy(cluster));
+        return clusterSeedEnergyCutLow(getValueClusterSeedEnergy(cluster));
     }
     
     /**
@@ -380,7 +380,7 @@
      * and <code>false</code> if the cluster does not.
      */
     public boolean clusterTotalEnergyCut(Cluster cluster) {
-    	return clusterTotalEnergyCut(getValueClusterTotalEnergy(cluster));
+        return clusterTotalEnergyCut(getValueClusterTotalEnergy(cluster));
     }
     
     /**
@@ -392,7 +392,7 @@
      * and <code>false</code> if the cluster does not.
      */
     public boolean clusterTotalEnergyCutHigh(Cluster cluster) {
-    	return clusterTotalEnergyCutHigh(getValueClusterTotalEnergy(cluster));
+        return clusterTotalEnergyCutHigh(getValueClusterTotalEnergy(cluster));
     }
     
     /**
@@ -404,7 +404,7 @@
      * and <code>false</code> if the cluster does not.
      */
     public boolean clusterTotalEnergyCutLow(Cluster cluster) {
-    	return clusterTotalEnergyCutLow(getValueClusterTotalEnergy(cluster));
+        return clusterTotalEnergyCutLow(getValueClusterTotalEnergy(cluster));
     }
     
     /**
@@ -416,7 +416,7 @@
      * and <code>false</code> if the cluster does not.
      */
     public boolean clusterTotalEnergyCut(SSPCluster cluster) {
-    	return clusterTotalEnergyCut(getValueClusterTotalEnergy(cluster));
+        return clusterTotalEnergyCut(getValueClusterTotalEnergy(cluster));
     }
     
     /**
@@ -428,7 +428,7 @@
      * and <code>false</code> if the cluster does not.
      */
     public boolean clusterTotalEnergyCutHigh(SSPCluster cluster) {
-    	return clusterTotalEnergyCutHigh(getValueClusterTotalEnergy(cluster));
+        return clusterTotalEnergyCutHigh(getValueClusterTotalEnergy(cluster));
     }
     
     /**
@@ -440,7 +440,39 @@
      * and <code>false</code> if the cluster does not.
      */
     public boolean clusterTotalEnergyCutLow(SSPCluster cluster) {
-    	return clusterTotalEnergyCutLow(getValueClusterTotalEnergy(cluster));
+        return clusterTotalEnergyCutLow(getValueClusterTotalEnergy(cluster));
+    }
+    
+    /**
+     * Gets the angle between the cluster and the centerpoint of the
+     * calorimeter.
+     * @param cluster - The cluster for which to calculate the angle.
+     * @return Returns the cluster angle as an <code>int</code> in units
+     * of degrees.
+     */
+    public static int getClusterAngle(Cluster cluster) {
+        // Get the cluster position.
+        double x = getClusterX(cluster);
+        double y = getClusterY(cluster);
+        
+        // Return the cluster angle.
+        return getClusterAngle(x, y);
+    }
+    
+    /**
+     * Gets the angle between the cluster and the centerpoint of the
+     * calorimeter.
+     * @param cluster - The cluster for which to calculate the angle.
+     * @return Returns the cluster angle as an <code>int</code> in units
+     * of degrees.
+     */
+    public static int getClusterAngle(SSPCluster cluster) {
+        // Get the cluster position.
+        double x = getClusterX(cluster);
+        double y = getClusterY(cluster);
+        
+        // Return the cluster angle.
+        return getClusterAngle(x, y);
     }
     
     /**
@@ -449,14 +481,28 @@
      * be calculated.
      * @return Returns displacement of the cluster.
      */
-    // TODO: What defines cluster distance?
     public static double getClusterDistance(Cluster cluster) {
-    	// Get the variables from the cluster.
-    	double x = getClusterX(cluster);
-    	double y = getClusterY(cluster);
-    	
-    	// Perform the calculation.
-    	return getClusterDistance(x, y);
+        // Get the variables from the cluster.
+        double x = getClusterX(cluster);
+        double y = getClusterY(cluster);
+        
+        // Perform the calculation.
+        return getClusterDistance(x, y);
+    }
+    
+    /**
+     * Calculates the distance between the origin and a cluster.
+     * @param cluster - The cluster pair from which the value should
+     * be calculated.
+     * @return Returns displacement of the cluster.
+     */
+    public static double getClusterDistance(SSPCluster cluster) {
+        // Get the variables from the cluster.
+        double x = getClusterX(cluster);
+        double y = getClusterY(cluster);
+        
+        // Perform the calculation.
+        return getClusterDistance(x, y);
     }
     
     /**
@@ -466,7 +512,7 @@
      * @return Returns the size as an <code>int</code>.
      */
     public static final double getClusterHitCount(Cluster cluster) {
-    	return cluster.getCalorimeterHits().size();
+        return cluster.getCalorimeterHits().size();
     }
     
     /**
@@ -476,7 +522,7 @@
      * @return Returns the size as an <code>int</code>.
      */
     public static final double getClusterHitCount(SSPCluster cluster) {
-    	return cluster.getHitCount();
+        return cluster.getHitCount();
     }
     
     /**
@@ -486,11 +532,11 @@
      * object.
      */
     public static final CalorimeterHit getClusterSeedHit(Cluster cluster) {
-    	if(getClusterHitCount(cluster) > 0) {
-    		return cluster.getCalorimeterHits().get(0);
-    	} else {
-    		throw new NullPointerException("Cluster does not define hits!");
-    	}
+        if(getClusterHitCount(cluster) > 0) {
+            return cluster.getCalorimeterHits().get(0);
+        } else {
+            throw new NullPointerException("Cluster does not define hits!");
+        }
     }
     
     /**
@@ -500,7 +546,7 @@
      * @return Returns the time as a <code>double</code>.
      */
     public static final double getClusterTime(Cluster cluster) {
-    	return getClusterSeedHit(cluster).getTime();
+        return getClusterSeedHit(cluster).getTime();
     }
     
     /**
@@ -510,7 +556,7 @@
      * @return Returns the time as a <code>double</code>.
      */
     public static final double getClusterTime(SSPCluster cluster) {
-    	return cluster.getTime();
+        return cluster.getTime();
     }
     
     /**
@@ -520,7 +566,7 @@
      * @return Returns the cluster x-position.
      */
     public static double getClusterX(Cluster cluster) {
-    	return getCrystalPosition(getClusterXIndex(cluster), getClusterYIndex(cluster))[0];
+        return getCrystalPosition(getClusterXIndex(cluster), getClusterYIndex(cluster))[0];
     }
     
     /**
@@ -530,7 +576,7 @@
      * @return Returns the cluster x-position.
      */
     public static double getClusterX(SSPCluster cluster) {
-    	return getCrystalPosition(cluster.getXIndex(), cluster.getYIndex())[0];
+        return getCrystalPosition(cluster.getXIndex(), cluster.getYIndex())[0];
     }
     
     /**
@@ -539,7 +585,7 @@
      * @return Returns the index as an <code>int</code>.
      */
     public static final int getClusterXIndex(Cluster cluster) {
-    	return getClusterSeedHit(cluster).getIdentifierFieldValue("ix");
+        return getClusterSeedHit(cluster).getIdentifierFieldValue("ix");
     }
     
     /**
@@ -548,7 +594,7 @@
      * @return Returns the index as an <code>int</code>.
      */
     public static final int getClusterXIndex(SSPCluster cluster) {
-    	return cluster.getXIndex();
+        return cluster.getXIndex();
     }
     
     /**
@@ -558,7 +604,7 @@
      * @return Returns the cluster y-position.
      */
     public static double getClusterY(Cluster cluster) {
-    	return getCrystalPosition(getClusterXIndex(cluster), getClusterYIndex(cluster))[1];
+        return getCrystalPosition(getClusterXIndex(cluster), getClusterYIndex(cluster))[1];
     }
     
     /**
@@ -568,7 +614,7 @@
      * @return Returns the cluster y-position.
      */
     public static double getClusterY(SSPCluster cluster) {
-    	return getCrystalPosition(cluster.getXIndex(), cluster.getYIndex())[1];
+        return getCrystalPosition(cluster.getXIndex(), cluster.getYIndex())[1];
     }
     
     /**
@@ -577,7 +623,7 @@
      * @return Returns the index as an <code>int</code>.
      */
     public static final int getClusterYIndex(Cluster cluster) {
-    	return getClusterSeedHit(cluster).getIdentifierFieldValue("iy");
+        return getClusterSeedHit(cluster).getIdentifierFieldValue("iy");
     }
     
     /**
@@ -586,7 +632,7 @@
      * @return Returns the index as an <code>int</code>.
      */
     public static final int getClusterYIndex(SSPCluster cluster) {
-    	return cluster.getYIndex();
+        return cluster.getYIndex();
     }
     
     /**
@@ -596,7 +642,7 @@
      * @return Returns the cluster z-position.
      */
     public static double getClusterZ(Cluster cluster) {
-    	return getCrystalPosition(getClusterXIndex(cluster), getClusterYIndex(cluster))[2];
+        return getCrystalPosition(getClusterXIndex(cluster), getClusterYIndex(cluster))[2];
     }
     
     /**
@@ -606,7 +652,7 @@
      * @return Returns the cluster z-position.
      */
     public static double getClusterZ(SSPCluster cluster) {
-    	return getCrystalPosition(cluster.getXIndex(), cluster.getYIndex())[2];
+        return getCrystalPosition(cluster.getXIndex(), cluster.getYIndex())[2];
     }
     
     /**
@@ -618,48 +664,48 @@
      * first entry in the array is always the top cluster, with the
      * bottom cluster in the next position.
      */
-	public static <E> List<E[]> getTopBottomPairs(List<E> clusters, Class<E> clusterType) throws IllegalArgumentException {
-		// Ensure that only valid cluster types are processed.
-		if(!clusterType.equals(Cluster.class) && !clusterType.equals(SSPCluster.class)) {
-			throw new IllegalArgumentException("Class \"" + clusterType.getSimpleName() + "\" is not a supported cluster type.");
-		}
-		
-    	// Create a list to store top clusters, bottom clusters, and
-    	// cluster pairs.
-    	List<E> topClusters = new ArrayList<E>();
-    	List<E> botClusters = new ArrayList<E>();
-    	List<E[]> pairClusters = new ArrayList<E[]>();
-    	
-    	// Separate the cluster list into top/bottom clusters.
-    	for(E cluster : clusters) {
-    		// Process LCIO clusters...
-    		if(clusterType.equals(Cluster.class)) {
-				if(getClusterYIndex((Cluster) cluster) > 0) {
-					topClusters.add(cluster);
-				} else { botClusters.add(cluster); }
-    		}
-    		
-    		// Process SSP clusters...
-    		else if(clusterType.equals(SSPCluster.class)) {
-				if(getClusterYIndex((SSPCluster) cluster) > 0) {
-					topClusters.add(cluster);
-				} else { botClusters.add(cluster); }
-    		}
-    	}
-    	
-    	// Form all top/bottom cluster pairs.
-    	for(E topCluster : topClusters) {
-    		for(E botCluster : botClusters) {
-    			@SuppressWarnings("unchecked")
-				E[] pair = (E[]) Array.newInstance(clusterType, 2);
-    			pair[0] = topCluster;
-    			pair[1] = botCluster;
-    			pairClusters.add(pair);
-    		}
-    	}
-    	
-    	// Return the cluster pairs.
-    	return pairClusters;
+    public static <E> List<E[]> getTopBottomPairs(List<E> clusters, Class<E> clusterType) throws IllegalArgumentException {
+        // Ensure that only valid cluster types are processed.
+        if(!clusterType.equals(Cluster.class) && !clusterType.equals(SSPCluster.class)) {
+            throw new IllegalArgumentException("Class \"" + clusterType.getSimpleName() + "\" is not a supported cluster type.");
+        }
+        
+        // Create a list to store top clusters, bottom clusters, and
+        // cluster pairs.
+        List<E> topClusters = new ArrayList<E>();
+        List<E> botClusters = new ArrayList<E>();
+        List<E[]> pairClusters = new ArrayList<E[]>();
+        
+        // Separate the cluster list into top/bottom clusters.
+        for(E cluster : clusters) {
+            // Process LCIO clusters...
+            if(clusterType.equals(Cluster.class)) {
+                if(getClusterYIndex((Cluster) cluster) > 0) {
+                    topClusters.add(cluster);
+                } else { botClusters.add(cluster); }
+            }
+            
+            // Process SSP clusters...
+            else if(clusterType.equals(SSPCluster.class)) {
+                if(getClusterYIndex((SSPCluster) cluster) > 0) {
+                    topClusters.add(cluster);
+                } else { botClusters.add(cluster); }
+            }
+        }
+        
+        // Form all top/bottom cluster pairs.
+        for(E topCluster : topClusters) {
+            for(E botCluster : botClusters) {
+                @SuppressWarnings("unchecked")
+                E[] pair = (E[]) Array.newInstance(clusterType, 2);
+                pair[0] = topCluster;
+                pair[1] = botCluster;
+                pairClusters.add(pair);
+            }
+        }
+        
+        // Return the cluster pairs.
+        return pairClusters;
     }
     
     /**
@@ -671,29 +717,29 @@
      * first entry in the array is always the top cluster, with the
      * bottom cluster in the next position.
      */
-	public static List<Cluster[]> getTopBottomPairs(Cluster... clusters) {
-    	// Create a list to store top clusters, bottom clusters, and
-    	// cluster pairs.
-    	List<Cluster> topClusters = new ArrayList<Cluster>();
-    	List<Cluster> botClusters = new ArrayList<Cluster>();
-    	List<Cluster[]> pairClusters = new ArrayList<Cluster[]>();
-    	
-    	// Separate the cluster list into top/bottom clusters.
-    	for(Cluster cluster : clusters) {
-			if(getClusterYIndex(cluster) > 0) {
-				topClusters.add(cluster);
-			} else { botClusters.add(cluster); }
-    	}
-    	
-    	// Form all top/bottom cluster pairs.
-    	for(Cluster topCluster : topClusters) {
-    		for(Cluster botCluster : botClusters) {
-    			pairClusters.add(new Cluster[] { topCluster, botCluster });
-    		}
-    	}
-    	
-    	// Return the cluster pairs.
-    	return pairClusters;
+    public static List<Cluster[]> getTopBottomPairs(Cluster... clusters) {
+        // Create a list to store top clusters, bottom clusters, and
+        // cluster pairs.
+        List<Cluster> topClusters = new ArrayList<Cluster>();
+        List<Cluster> botClusters = new ArrayList<Cluster>();
+        List<Cluster[]> pairClusters = new ArrayList<Cluster[]>();
+        
+        // Separate the cluster list into top/bottom clusters.
+        for(Cluster cluster : clusters) {
+            if(getClusterYIndex(cluster) > 0) {
+                topClusters.add(cluster);
+            } else { botClusters.add(cluster); }
+        }
+        
+        // Form all top/bottom cluster pairs.
+        for(Cluster topCluster : topClusters) {
+            for(Cluster botCluster : botClusters) {
+                pairClusters.add(new Cluster[] { topCluster, botCluster });
+            }
+        }
+        
+        // Return the cluster pairs.
+        return pairClusters;
     }
     
     /**
@@ -705,29 +751,29 @@
      * The first entry in the array is always the top cluster, with
      * the bottom cluster in the next position.
      */
-	public static List<SSPCluster[]> getTopBottomPairs(SSPCluster... clusters) {
-    	// Create a list to store top clusters, bottom clusters, and
-    	// cluster pairs.
-    	List<SSPCluster> topClusters = new ArrayList<SSPCluster>();
-    	List<SSPCluster> botClusters = new ArrayList<SSPCluster>();
-    	List<SSPCluster[]> pairClusters = new ArrayList<SSPCluster[]>();
-    	
-    	// Separate the cluster list into top/bottom clusters.
-    	for(SSPCluster cluster : clusters) {
-			if(getClusterYIndex(cluster) > 0) {
-				topClusters.add(cluster);
-			} else { botClusters.add(cluster); }
-    	}
-    	
-    	// Form all top/bottom cluster pairs.
-    	for(SSPCluster topCluster : topClusters) {
-    		for(SSPCluster botCluster : botClusters) {
-    			pairClusters.add(new SSPCluster[] { topCluster, botCluster });
-    		}
-    	}
-    	
-    	// Return the cluster pairs.
-    	return pairClusters;
+    public static List<SSPCluster[]> getTopBottomPairs(SSPCluster... clusters) {
+        // Create a list to store top clusters, bottom clusters, and
+        // cluster pairs.
+        List<SSPCluster> topClusters = new ArrayList<SSPCluster>();
+        List<SSPCluster> botClusters = new ArrayList<SSPCluster>();
+        List<SSPCluster[]> pairClusters = new ArrayList<SSPCluster[]>();
+        
+        // Separate the cluster list into top/bottom clusters.
+        for(SSPCluster cluster : clusters) {
+            if(getClusterYIndex(cluster) > 0) {
+                topClusters.add(cluster);
+            } else { botClusters.add(cluster); }
+        }
+        
+        // Form all top/bottom cluster pairs.
+        for(SSPCluster topCluster : topClusters) {
+            for(SSPCluster botCluster : botClusters) {
+                pairClusters.add(new SSPCluster[] { topCluster, botCluster });
+            }
+        }
+        
+        // Return the cluster pairs.
+        return pairClusters;
     }
     
     /**
@@ -791,12 +837,12 @@
      * @return Returns the cut value.
      */
     public static double getValueCoplanarity(Cluster[] clusterPair) {
-    	// Get the variables used by the calculation.
-    	double x[] = { getClusterX(clusterPair[0]), getClusterX(clusterPair[1]) };
-    	double y[] = { getClusterY(clusterPair[0]), getClusterY(clusterPair[1]) };
-    	
-    	// Return the calculated value.
-    	return getValueCoplanarity(x, y);
+        // Get the variables used by the calculation.
+        double x[] = { getClusterX(clusterPair[0]), getClusterX(clusterPair[1]) };
+        double y[] = { getClusterY(clusterPair[0]), getClusterY(clusterPair[1]) };
+        
+        // Return the calculated value.
+        return getValueCoplanarity(x, y);
     }
     
     /**
@@ -807,12 +853,12 @@
      * @return Returns the cut value.
      */
     public static double getValueCoplanarity(SSPCluster[] clusterPair) {
-    	// Get the variables used by the calculation.
-    	double x[] = { getClusterX(clusterPair[0]), getClusterX(clusterPair[1]) };
-    	double y[] = { getClusterY(clusterPair[0]), getClusterY(clusterPair[1]) };
-    	
-    	// Return the calculated value.
-    	return getValueCoplanarity(x, y);
+        // Get the variables used by the calculation.
+        double x[] = { getClusterX(clusterPair[0]), getClusterX(clusterPair[1]) };
+        double y[] = { getClusterY(clusterPair[0]), getClusterY(clusterPair[1]) };
+        
+        // Return the calculated value.
+        return getValueCoplanarity(x, y);
     }
     
     /**
@@ -824,14 +870,14 @@
      */
     @Deprecated
     public static double getValueCoplanarityLegacy(Cluster[] clusterPair) {
-    	// Get the variables used by the calculation.
-    	double x[] = { getClusterSeedHit(clusterPair[0]).getIdentifierFieldValue("ix"),
-    			getClusterSeedHit(clusterPair[1]).getIdentifierFieldValue("ix") };
-    	double y[] = { getClusterSeedHit(clusterPair[0]).getIdentifierFieldValue("iy"),
-    			getClusterSeedHit(clusterPair[1]).getIdentifierFieldValue("iy") };
-    	
-    	// Return the calculated value.
-    	return getValueCoplanarityLegacy(x, y);
+        // Get the variables used by the calculation.
+        double x[] = { getClusterSeedHit(clusterPair[0]).getIdentifierFieldValue("ix"),
+                getClusterSeedHit(clusterPair[1]).getIdentifierFieldValue("ix") };
+        double y[] = { getClusterSeedHit(clusterPair[0]).getIdentifierFieldValue("iy"),
+                getClusterSeedHit(clusterPair[1]).getIdentifierFieldValue("iy") };
+        
+        // Return the calculated value.
+        return getValueCoplanarityLegacy(x, y);
     }
     
     /**
@@ -841,10 +887,10 @@
      * @return Returns the difference between the cluster energies.
      */
     public static double getValueEnergyDifference(Cluster[] clusterPair) {
-    	// Get the variables used by the calculation.
-    	double[] energy = { clusterPair[0].getEnergy(), clusterPair[1].getEnergy() };
-    	
-    	// Perform the calculation.
+        // Get the variables used by the calculation.
+        double[] energy = { clusterPair[0].getEnergy(), clusterPair[1].getEnergy() };
+        
+        // Perform the calculation.
         return getValueEnergyDifference(energy);
     }
     
@@ -855,10 +901,10 @@
      * @return Returns the difference between the cluster energies.
      */
     public static double getValueEnergyDifference(SSPCluster[] clusterPair) {
-    	// Get the variables used by the calculation.
-    	double[] energy = { clusterPair[0].getEnergy(), clusterPair[1].getEnergy() };
-    	
-    	// Perform the calculation.
+        // Get the variables used by the calculation.
+        double[] energy = { clusterPair[0].getEnergy(), clusterPair[1].getEnergy() };
+        
+        // Perform the calculation.
         return getValueEnergyDifference(energy);
     }
     
@@ -871,13 +917,13 @@
      * @return Returns the energy slope value.
      */
     public static double getValueEnergySlope(Cluster[] clusterPair, double energySlopeParamF) {
-    	// Get the variables used by the calculation.
-    	double[] energy = { clusterPair[0].getEnergy(), clusterPair[1].getEnergy() };
-    	double x[] = { getClusterX(clusterPair[0]), getClusterX(clusterPair[1]) };
-    	double y[] = { getClusterY(clusterPair[0]), getClusterY(clusterPair[1]) };
-    	
-    	// Perform the calculation.
-    	return getValueEnergySlope(energy, x, y, energySlopeParamF);
+        // Get the variables used by the calculation.
+        double[] energy = { clusterPair[0].getEnergy(), clusterPair[1].getEnergy() };
+        double x[] = { getClusterX(clusterPair[0]), getClusterX(clusterPair[1]) };
+        double y[] = { getClusterY(clusterPair[0]), getClusterY(clusterPair[1]) };
+        
+        // Perform the calculation.
+        return getValueEnergySlope(energy, x, y, energySlopeParamF);
     }
     
     /**
@@ -889,13 +935,13 @@
      * @return Returns the energy slope value.
      */
     public static double getValueEnergySlope(SSPCluster[] clusterPair, double energySlopeParamF) {
-    	// Get the variables used by the calculation.
-    	double[] energy = { clusterPair[0].getEnergy(), clusterPair[1].getEnergy() };
-    	double x[] = { getClusterX(clusterPair[0]), getClusterX(clusterPair[1]) };
-    	double y[] = { getClusterY(clusterPair[0]), getClusterY(clusterPair[1]) };
-    	
-    	// Perform the calculation.
-    	return getValueEnergySlope(energy, x, y, energySlopeParamF);
+        // Get the variables used by the calculation.
+        double[] energy = { clusterPair[0].getEnergy(), clusterPair[1].getEnergy() };
+        double x[] = { getClusterX(clusterPair[0]), getClusterX(clusterPair[1]) };
+        double y[] = { getClusterY(clusterPair[0]), getClusterY(clusterPair[1]) };
+        
+        // Perform the calculation.
+        return getValueEnergySlope(energy, x, y, energySlopeParamF);
     }
     
     /**
@@ -910,15 +956,15 @@
      */
     @Deprecated
     public static double getValueEnergySlopeLegacy(Cluster[] clusterPair, double energySlopeParamF) {
-    	// Get the variables used by the calculation.
-    	double[] energy = { clusterPair[0].getEnergy(), clusterPair[1].getEnergy() };
-    	double x[] = { getClusterSeedHit(clusterPair[0]).getIdentifierFieldValue("ix"),
-    			getClusterSeedHit(clusterPair[1]).getIdentifierFieldValue("ix") };
-    	double y[] = { getClusterSeedHit(clusterPair[0]).getIdentifierFieldValue("iy"),
-    			getClusterSeedHit(clusterPair[1]).getIdentifierFieldValue("iy") };
-    	
-    	// Perform the calculation.
-    	return getValueEnergySlopeLegacy(energy, x, y, energySlopeParamF);
+        // Get the variables used by the calculation.
+        double[] energy = { clusterPair[0].getEnergy(), clusterPair[1].getEnergy() };
+        double x[] = { getClusterSeedHit(clusterPair[0]).getIdentifierFieldValue("ix"),
+                getClusterSeedHit(clusterPair[1]).getIdentifierFieldValue("ix") };
+        double y[] = { getClusterSeedHit(clusterPair[0]).getIdentifierFieldValue("iy"),
+                getClusterSeedHit(clusterPair[1]).getIdentifierFieldValue("iy") };
+        
+        // Perform the calculation.
+        return getValueEnergySlopeLegacy(energy, x, y, energySlopeParamF);
     }
     
     /**
@@ -928,11 +974,11 @@
      * @return Returns the sum of the cluster energies.
      */
     public static double getValueEnergySum(Cluster[] clusterPair) {
-    	// Get the variables used by the calculation.
-    	double[] energy = { clusterPair[0].getEnergy(), clusterPair[1].getEnergy() };
-    	
-    	// Perform the calculation.
-    	return getValueEnergySum(energy);
+        // Get the variables used by the calculation.
+        double[] energy = { clusterPair[0].getEnergy(), clusterPair[1].getEnergy() };
+        
+        // Perform the calculation.
+        return getValueEnergySum(energy);
     }
     
     /**
@@ -942,11 +988,11 @@
      * @return Returns the sum of the cluster energies.
      */
     public static double getValueEnergySum(SSPCluster[] clusterPair) {
-    	// Get the variables used by the calculation.
-    	double[] energy = { clusterPair[0].getEnergy(), clusterPair[1].getEnergy() };
-    	
-    	// Perform the calculation.
-    	return getValueEnergySum(energy);
+        // Get the variables used by the calculation.
+        double[] energy = { clusterPair[0].getEnergy(), clusterPair[1].getEnergy() };
+        
+        // Perform the calculation.
+        return getValueEnergySum(energy);
     }
     
     /**
@@ -956,12 +1002,12 @@
      * @return Returns the absolute difference in the cluster times..
      */
     public static double getValueTimeCoincidence(Cluster[] clusterPair) {
-    	// Get the variables used by the calculation.
-    	double[] time = { clusterPair[0].getCalorimeterHits().get(0).getTime(),
-    			clusterPair[1].getCalorimeterHits().get(0).getTime() };
-    	
-    	// Perform the calculation.
-    	return getValueTimeCoincidence(time);
+        // Get the variables used by the calculation.
+        double[] time = { clusterPair[0].getCalorimeterHits().get(0).getTime(),
+                clusterPair[1].getCalorimeterHits().get(0).getTime() };
+        
+        // Perform the calculation.
+        return getValueTimeCoincidence(time);
     }
     
     /**
@@ -971,34 +1017,34 @@
      * @return Returns the absolute difference in the cluster times..
      */
     public static double getValueTimeCoincidence(SSPCluster[] clusterPair) {
-    	// Get the variables used by the calculation.
-    	double[] time = { clusterPair[0].getTime(), clusterPair[1].getTime() };
-    	
-    	// Perform the calculation.
-    	return getValueTimeCoincidence(time);
-    }
-    
-    /**
-	 * Indicates whether the argument cluster is located in the fiducial
-	 * region or not.
-	 * @param cluster - The cluster to check.
-	 * @return Returns <code>true</code> if the cluster is located in
-	 * the fiducial region and <code>false</code> otherwise.
-	 */
-	public static final boolean inFiducialRegion(Cluster cluster) {
-		return inFiducialRegion(getClusterXIndex(cluster), getClusterYIndex(cluster));
-	}
-    
-    /**
-	 * Indicates whether the argument cluster is located in the fiducial
-	 * region or not.
-	 * @param cluster - The cluster to check.
-	 * @return Returns <code>true</code> if the cluster is located in
-	 * the fiducial region and <code>false</code> otherwise.
-	 */
-	public static final boolean inFiducialRegion(SSPCluster cluster) {
-		return inFiducialRegion(getClusterXIndex(cluster), getClusterYIndex(cluster));
-	}
+        // Get the variables used by the calculation.
+        double[] time = { clusterPair[0].getTime(), clusterPair[1].getTime() };
+        
+        // Perform the calculation.
+        return getValueTimeCoincidence(time);
+    }
+    
+    /**
+     * Indicates whether the argument cluster is located in the fiducial
+     * region or not.
+     * @param cluster - The cluster to check.
+     * @return Returns <code>true</code> if the cluster is located in
+     * the fiducial region and <code>false</code> otherwise.
+     */
+    public static final boolean inFiducialRegion(Cluster cluster) {
+        return inFiducialRegion(getClusterXIndex(cluster), getClusterYIndex(cluster));
+    }
+    
+    /**
+     * Indicates whether the argument cluster is located in the fiducial
+     * region or not.
+     * @param cluster - The cluster to check.
+     * @return Returns <code>true</code> if the cluster is located in
+     * the fiducial region and <code>false</code> otherwise.
+     */
+    public static final boolean inFiducialRegion(SSPCluster cluster) {
+        return inFiducialRegion(getClusterXIndex(cluster), getClusterYIndex(cluster));
+    }
     
     /**
      * Checks if a cluster pair is coplanar to the beam within a given
@@ -1080,7 +1126,7 @@
      * the cut and <code>false</code> if it does not.
      */
     public boolean pairEnergySumCut(Cluster[] clusterPair) {
-    	return pairEnergySumCut(getValueEnergySum(clusterPair));
+        return pairEnergySumCut(getValueEnergySum(clusterPair));
     }
     
     /**
@@ -1092,7 +1138,7 @@
      * the cut and <code>false</code> if it does not.
      */
     public boolean pairEnergySumCutHigh(Cluster[] clusterPair) {
-    	return pairEnergySumCutHigh(getValueEnergySum(clusterPair));
+        return pairEnergySumCutHigh(getValueEnergySum(clusterPair));
     }
     
     /**
@@ -1104,7 +1150,7 @@
      * the cut and <code>false</code> if it does not.
      */
     public boolean pairEnergySumCutLow(Cluster[] clusterPair) {
-    	return pairEnergySumCutLow(getValueEnergySum(clusterPair));
+        return pairEnergySumCutLow(getValueEnergySum(clusterPair));
     }
     
     /**
@@ -1117,7 +1163,7 @@
      * the cut and <code>false</code> if it does not.
      */
     public boolean pairEnergySumCut(SSPCluster[] clusterPair) {
-    	return pairEnergySumCut(getValueEnergySum(clusterPair));
+        return pairEnergySumCut(getValueEnergySum(clusterPair));
     }
     
     /**
@@ -1129,7 +1175,7 @@
      * the cut and <code>false</code> if it does not.
      */
     public boolean pairEnergySumCutHigh(SSPCluster[] clusterPair) {
-    	return pairEnergySumCutHigh(getValueEnergySum(clusterPair));
+        return pairEnergySumCutHigh(getValueEnergySum(clusterPair));
     }
     
     /**
@@ -1141,7 +1187,7 @@
      * the cut and <code>false</code> if it does not.
      */
     public boolean pairEnergySumCutLow(SSPCluster[] clusterPair) {
-    	return pairEnergySumCutLow(getValueEnergySum(clusterPair));
+        return pairEnergySumCutLow(getValueEnergySum(clusterPair));
     }
     
     /**
@@ -1153,7 +1199,7 @@
      * the cut and <code>false</code> if it does not.
      */
     public boolean pairTimeCoincidenceCut(Cluster[] clusterPair) {
-    	return pairTimeCoincidenceCut(getValueTimeCoincidence(clusterPair));
+        return pairTimeCoincidenceCut(getValueTimeCoincidence(clusterPair));
     }
     
     /**
@@ -1165,7 +1211,7 @@
      * the cut and <code>false</code> if it does not.
      */
     public boolean pairTimeCoincidenceCut(SSPCluster[] clusterPair) {
-    	return pairTimeCoincidenceCut(getValueTimeCoincidence(clusterPair));
+        return pairTimeCoincidenceCut(getValueTimeCoincidence(clusterPair));
     }
     
     /**
@@ -1243,6 +1289,18 @@
      */
     private boolean clusterTotalEnergyCutLow(double clusterEnergy) {
         return (clusterEnergy >= cuts.get(CLUSTER_TOTAL_ENERGY_LOW));
+    }
+    
+    /**
+     * Gets the angle between the cluster and the centerpoint of the
+     * calorimeter.
+     * @param x - The cluster seed x-position.
+     * @param y - The cluster seed y-position.
+     * @return Returns the cluster angle as an <code>int</code> in units
+     * of degrees.
+     */
+    private static int getClusterAngle(double x, double y) {
+        return (int) Math.round(Math.atan(x / y) * 180.0 / Math.PI);
     }
     
     /**
@@ -1266,22 +1324,22 @@
      * the x-index and either of the cases where <code>iy == 0</code>
      * or <code>|iy| > 5</code> for the y-index.
      */
-	private static double[] getCrystalPosition(int ix, int iy) throws IndexOutOfBoundsException {
-		// Make sure that the requested crystal is a valid crystal.
-		if(ix == 0 || ix < -23 || ix > 23) {
-			throw new IndexOutOfBoundsException(String.format("Value \"%d\" is invalid for field x-index.", ix));
-		} if(iy == 0 || iy < -5 || iy > 5) {
-			throw new IndexOutOfBoundsException(String.format("Value \"%d\" is invalid for field y-index.", iy));
-		}
-		
-		// Get the position map.
-		double posMap[];
-		if(ix < 1) { posMap = position[5 - iy][22 - ix]; }
-		else { posMap = position[5 - iy][23 - ix]; }
-		
-		// Return the corrected mapped position.
-		return new double[] { posMap[0], posMap[2], posMap[1] };
-	}
+    private static double[] getCrystalPosition(int ix, int iy) throws IndexOutOfBoundsException {
+        // Make sure that the requested crystal is a valid crystal.
+        if(ix == 0 || ix < -23 || ix > 23) {
+            throw new IndexOutOfBoundsException(String.format("Value \"%d\" is invalid for field x-index.", ix));
+        } if(iy == 0 || iy < -5 || iy > 5) {
+            throw new IndexOutOfBoundsException(String.format("Value \"%d\" is invalid for field y-index.", iy));
+        }
+        
+        // Get the position map.
+        double posMap[];
+        if(ix < 1) { posMap = position[5 - iy][22 - ix]; }
+        else { posMap = position[5 - iy][23 - ix]; }
+        
+        // Return the corrected mapped position.
+        return new double[] { posMap[0], posMap[2], posMap[1] };
+    }
     
     /**
      * Calculates the value used by the coplanarity cut.
@@ -1295,7 +1353,7 @@
         // Get the cluster angles.
         int[] clusterAngle = new int[2];
         for(int i = 0; i < 2; i++) {
-        	clusterAngle[i] = (int) Math.round(Math.atan(x[i] / y[i]) * 180.0 / Math.PI);
+            clusterAngle[i] = getClusterAngle(x[i], y[i]); //(int) Math.round(Math.atan(x[i] / y[i]) * 180.0 / Math.PI);
         }
         
         // Calculate the coplanarity cut value.
@@ -1343,9 +1401,9 @@
      * @return Returns the cut value.
      */
     private static double getValueEnergySlope(double energy[], double x[], double y[], double energySlopeParamF) {
-    	// Determine which cluster is the lower-energy cluster.
-    	int lei = energy[0] < energy[1] ? 0 : 1;
-    	
+        // Determine which cluster is the lower-energy cluster.
+        int lei = energy[0] < energy[1] ? 0 : 1;
+        
         // E + R*F
         // Get the low energy cluster energy.
         double slopeParamE = energy[lei];
@@ -1369,9 +1427,9 @@
      */
     @Deprecated
     private static double getValueEnergySlopeLegacy(double energy[], double x[], double y[], double energySlopeParamF) {
-    	// Determine which cluster is the lower-energy cluster.
-    	int lei = energy[0] < energy[1] ? 0 : 1;
-    	
+        // Determine which cluster is the lower-energy cluster.
+        int lei = energy[0] < energy[1] ? 0 : 1;
+        
         // E + R*F
         // Get the low energy cluster energy.
         double slopeParamE = energy[lei];
@@ -1401,52 +1459,52 @@
      * the two clusters.
      */
     private static double getValueTimeCoincidence(double[] time) {
-    	return Math.abs(time[0] - time[1]);
-    }
-    
-    /**
-	 * Indicates whether the argument cluster is located in the fiducial
-	 * region or not.
-	 * @param cluster - The cluster to check.
-	 * @return Returns <code>true</code> if the cluster is located in
-	 * the fiducial region and <code>false</code> otherwise.
-	 */
-	private static final boolean inFiducialRegion(int ix, int iy) {
-		// Get the x and y indices for the cluster.
-		int absx = Math.abs(ix);
-		int absy = Math.abs(iy);
-		
-		// Check if the cluster is on the top or the bottom of the
-		// calorimeter, as defined by |y| == 5. This is an edge cluster
-		// and is not in the fiducial region.
-		if(absy == 5) {
-			return false;
-		}
-		
-		// Check if the cluster is on the extreme left or right side
-		// of the calorimeter, as defined by |x| == 23. This is also
-		// and edge cluster is not in the fiducial region.
-		if(absx == 23) {
-			return false;
-		}
-		
-		// Check if the cluster is along the beam gap, as defined by
-		// |y| == 1. This is an internal edge cluster and is not in the
-		// fiducial region.
-		if(absy == 1) {
-			return false;
-		}
-		
-		// Lastly, check if the cluster falls along the beam hole, as
-		// defined by clusters with -11 <= x <= -1 and |y| == 2. This
-		// is not the fiducial region.
-		if(absy == 2 && ix <= -1 && ix >= -11) {
-			return false;
-		}
-		
-		// If all checks fail, the cluster is in the fiducial region.
-		return true;
-	}
+        return Math.abs(time[0] - time[1]);
+    }
+    
+    /**
+     * Indicates whether the argument cluster is located in the fiducial
+     * region or not.
+     * @param cluster - The cluster to check.
+     * @return Returns <code>true</code> if the cluster is located in
+     * the fiducial region and <code>false</code> otherwise.
+     */
+    private static final boolean inFiducialRegion(int ix, int iy) {
+        // Get the x and y indices for the cluster.
+        int absx = Math.abs(ix);
+        int absy = Math.abs(iy);
+        
+        // Check if the cluster is on the top or the bottom of the
+        // calorimeter, as defined by |y| == 5. This is an edge cluster
+        // and is not in the fiducial region.
+        if(absy == 5) {
+            return false;
+        }
+        
+        // Check if the cluster is on the extreme left or right side
+        // of the calorimeter, as defined by |x| == 23. This is also
+        // and edge cluster is not in the fiducial region.
+        if(absx == 23) {
+            return false;
+        }
+        
+        // Check if the cluster is along the beam gap, as defined by
+        // |y| == 1. This is an internal edge cluster and is not in the
+        // fiducial region.
+        if(absy == 1) {
+            return false;
+        }
+        
+        // Lastly, check if the cluster falls along the beam hole, as
+        // defined by clusters with -11 <= x <= -1 and |y| == 2. This
+        // is not the fiducial region.
+        if(absy == 2 && ix <= -1 && ix >= -11) {
+            return false;
+        }
+        
+        // If all checks fail, the cluster is in the fiducial region.
+        return true;
+    }
     
     /**
      * Checks if a coplanarity angle is within threshold.
@@ -1522,7 +1580,7 @@
      * the cut and <code>false</code> if it does not.
      */
     private boolean pairTimeCoincidenceCut(double timeDifference) {
-    	return (timeDifference <= cuts.get(PAIR_TIME_COINCIDENCE));
+        return (timeDifference <= cuts.get(PAIR_TIME_COINCIDENCE));
     }
     
     /**
@@ -1535,193 +1593,193 @@
      * Note that in this table, position[][] = { x, z, y } by in the
      * coordinate system employed by the rest of the class.
      */
-	private static final double[][][] position = {
-		{	{ -340.003,   97.065,   87.845 }, { -324.283,   97.450,   87.875 }, { -308.648,   97.810,   87.900 },
-			{ -293.093,   98.150,   87.920 }, { -277.618,   98.470,   87.940 }, { -262.213,   98.765,   87.965 },
-			{ -246.878,   99.040,   87.980 }, { -231.603,   99.290,   87.995 }, { -216.393,   99.520,   88.010 },
-			{ -201.228,   99.725,   88.030 }, { -186.118,   99.905,   88.040 }, { -171.058,  100.070,   88.050 },
-			{ -156.038,  100.205,   88.055 }, { -141.058,  100.325,   88.070 }, { -126.113,  100.415,   88.075 },
-			{ -111.198,  100.485,   88.075 }, {  -96.313,  100.530,   88.080 }, {  -81.453,  100.555,   88.085 },
-			{  -66.608,  100.560,   88.085 }, {  -51.788,  100.540,   88.080 }, {  -36.983,  100.490,   88.075 },
-			{  -22.183,  100.425,   88.075 }, {   -7.393,  100.335,   88.070 }, {    7.393,  100.335,   88.070 },
-			{   22.183,  100.425,   88.075 }, {   36.983,  100.490,   88.075 }, {   51.793,  100.540,   88.080 },
-			{   66.613,  100.560,   88.085 }, {   81.453,  100.555,   88.085 }, {   96.313,  100.530,   88.080 },
-			{  111.198,  100.485,   88.075 }, {  126.113,  100.415,   88.075 }, {  141.053,  100.325,   88.070 },
-			{  156.038,  100.205,   88.055 }, {  171.053,  100.070,   88.050 }, {  186.118,   99.905,   88.040 },
-			{  201.228,   99.725,   88.030 }, {  216.388,   99.520,   88.010 }, {  231.608,   99.290,   87.995 },
-			{  246.878,   99.040,   87.980 }, {  262.218,   98.765,   87.965 }, {  277.623,   98.470,   87.940 },
-			{  293.098,   98.150,   87.920 }, {  308.653,   97.810,   87.900 }, {  324.288,   97.450,   87.875 },
-			{  340.008,   97.065,   87.845 }
-		},
-		{	{ -340.003,   97.040,   72.715 }, { -324.283,   97.420,   72.735 }, { -308.648,   97.785,   72.750 },
-			{ -293.093,   98.125,   72.765 }, { -277.618,   98.450,   72.785 }, { -262.213,   98.745,   72.800 },
-			{ -246.878,   99.015,   72.815 }, { -231.603,   99.265,   72.825 }, { -216.388,   99.495,   72.840 },
-			{ -201.228,   99.700,   72.850 }, { -186.118,   99.885,   72.860 }, { -171.058,  100.045,   72.865 },
-			{ -156.033,  100.185,   72.875 }, { -141.053,  100.300,   72.880 }, { -126.108,  100.395,   72.880 },
-			{ -111.193,  100.460,   72.890 }, {  -96.308,  100.510,   72.890 }, {  -81.448,  100.535,   72.895 },
-			{  -66.608,  100.535,   72.890 }, {  -51.788,  100.510,   72.890 }, {  -36.978,  100.470,   72.890 },
-			{  -22.183,  100.405,   72.880 }, {   -7.388,  100.310,   72.880 }, {    7.393,  100.310,   72.880 },
-			{   22.188,  100.405,   72.885 }, {   36.983,  100.470,   72.890 }, {   51.793,  100.510,   72.890 },
-			{   66.613,  100.535,   72.890 }, {   81.453,  100.535,   72.895 }, {   96.313,  100.510,   72.890 },
-			{  111.198,  100.460,   72.890 }, {  126.113,  100.395,   72.880 }, {  141.063,  100.300,   72.880 },
-			{  156.043,  100.185,   72.875 }, {  171.063,  100.045,   72.865 }, {  186.123,   99.885,   72.860 },
-			{  201.233,   99.700,   72.850 }, {  216.393,   99.495,   72.840 }, {  231.608,   99.265,   72.825 },
-			{  246.883,   99.015,   72.815 }, {  262.218,   98.745,   72.800 }, {  277.623,   98.450,   72.785 },
-			{  293.098,   98.125,   72.765 }, {  308.653,   97.785,   72.750 }, {  324.288,   97.420,   72.735 },
-			{  340.008,   97.040,   72.715 }
-		},
-		{	{ -340.003,   96.990,   57.600 }, { -324.283,   97.375,   57.610 }, { -308.648,   97.740,   57.625 },
-			{ -293.093,   98.080,   57.630 }, { -277.618,   98.395,   57.645 }, { -262.213,   98.700,   57.655 },
-			{ -246.873,   98.970,   57.660 }, { -231.603,   99.220,   57.670 }, { -216.383,   99.450,   57.680 },
-			{ -201.228,   99.660,   57.685 }, { -186.113,   99.840,   57.695 }, { -171.053,  100.005,   57.695 },
-			{ -156.033,  100.140,   57.700 }, { -141.053,  100.255,   57.710 }, { -126.108,  100.345,   57.710 },
-			{ -111.193,  100.420,   57.710 }, {  -96.308,  100.465,   57.715 }, {  -81.448,  100.490,   57.715 },
-			{  -66.608,  100.490,   57.715 }, {  -51.788,  100.470,   57.710 }, {  -36.978,  100.425,   57.710 },
-			{  -22.178,  100.355,   57.710 }, {   -7.388,  100.265,   57.705 }, {    7.398,  100.265,   57.705 },
-			{   22.188,  100.355,   57.710 }, {   36.988,  100.425,   57.710 }, {   51.793,  100.470,   57.710 },
-			{   66.613,  100.490,   57.715 }, {   81.458,  100.490,   57.715 }, {   96.318,  100.465,   57.715 },
-			{  111.198,  100.420,   57.710 }, {  126.118,  100.345,   57.710 }, {  141.063,  100.255,   57.710 },
-			{  156.043,  100.140,   57.700 }, {  171.063,  100.005,   57.695 }, {  186.123,   99.840,   57.695 },
-			{  201.233,   99.660,   57.685 }, {  216.393,   99.450,   57.680 }, {  231.608,   99.220,   57.670 },
-			{  246.883,   98.970,   57.660 }, {  262.218,   98.700,   57.655 }, {  277.623,   98.395,   57.645 },
-			{  293.098,   98.080,   57.630 }, {  308.653,   97.740,   57.625 }, {  324.288,   97.375,   57.610 },
-			{  340.008,   96.990,   57.600 }
-		},
-		{	{ -340.003,   96.925,   42.490 }, { -324.283,   97.305,   42.495 }, { -308.648,   97.675,   42.505 },
-			{ -293.093,   98.010,   42.510 }, { -277.618,   98.330,   42.510 }, { -262.213,   98.625,   42.515 },
-			{ -246.873,   98.900,   42.525 }, { -231.603,   99.155,   42.530 }, { -216.383,   99.385,   42.535 },
-			{ -201.223,   99.590,   42.530 }, { -186.113,   99.775,   42.535 }, { -171.048,   99.930,   42.540 },
-			{ -156.033,  100.070,   42.545 }, { -141.048,  100.185,   42.545 }, { -126.108,  100.280,   42.550 },
-			{ -111.193,  100.350,   42.545 }, {  -96.308,  100.400,   42.545 }, {  -81.448,  100.420,   42.550 },
-			{  -66.608,  100.425,   42.550 }, {  -51.788,  100.405,   42.550 }, {  -36.978,  100.355,   42.545 },
-			{  -22.178,  100.290,   42.545 }, {   -7.388,  100.200,   42.545 }, {    7.398,  100.200,   42.545 },
-			{   22.188,  100.290,   42.545 }, {   36.988,  100.355,   42.545 }, {   51.793,  100.405,   42.550 },
-			{   66.613,  100.425,   42.550 }, {   81.458,  100.420,   42.550 }, {   96.318,  100.400,   42.545 },
-			{  111.198,  100.350,   42.545 }, {  126.118,  100.280,   42.550 }, {  141.063,  100.185,   42.545 },
-			{  156.043,  100.070,   42.545 }, {  171.063,   99.930,   42.540 }, {  186.123,   99.775,   42.535 },
-			{  201.233,   99.590,   42.530 }, {  216.393,   99.385,   42.535 }, {  231.608,   99.155,   42.530 },
-			{  246.883,   98.900,   42.525 }, {  262.218,   98.625,   42.515 }, {  277.628,   98.330,   42.510 },
-			{  293.098,   98.010,   42.510 }, {  308.653,   97.675,   42.505 }, {  324.288,   97.305,   42.495 },
-			{  340.008,   96.925,   42.490 }
-		},
-		{	{ -340.003,   96.830,   27.385 }, { -324.278,   97.215,   27.385 }, { -308.648,   97.575,   27.385 },
-			{ -293.093,   97.915,   27.385 }, { -277.613,   98.240,   27.385 }, { -262.213,   98.535,   27.385 },
-			{ -246.878,   98.810,   27.385 }, { -231.603,   99.060,   27.385 }, { -216.383,   99.290,   27.385 },
-			{ -201.223,   99.495,   27.385 }, { -186.113,   99.680,   27.385 }, { -171.048,   99.840,   27.385 },
-			{ -156.033,   99.980,   27.385 }, { -141.048,  100.095,   27.385 }, { -126.103,  100.185,   27.385 },
-			{ -111.193,  100.255,   27.385 }, {  -96.303,  100.305,   27.385 }, {  -81.448,  100.330,   27.385 },
-			{  -66.608,  100.330,   27.385 }, {  -51.783,  100.310,   27.385 }, {  -36.973,  100.265,   27.385 },
-			{  -22.178,  100.200,   27.385 }, {   -7.388,  100.105,   27.385 }, {    7.403,  100.105,   27.385 },
-			{    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 },
-			{    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 },
-			{    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 },
-			{  156.078,   99.980,   27.385 }, {  171.103,   99.840,   27.385 }, {  186.168,   99.680,   27.385 },
-			{  201.268,   99.495,   27.385 }, {  216.423,   99.290,   27.385 }, {  231.638,   99.060,   27.385 },
-			{  246.913,   98.810,   27.385 }, {  262.248,   98.535,   27.385 }, {  277.658,   98.240,   27.385 },
-			{  293.133,   97.920,   27.385 }, {  308.688,   97.575,   27.385 }, {  324.323,   97.215,   27.385 },
-			{  340.043,   96.830,   27.385 }
-		},
-		{	{    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 },
-			{    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 },
-			{    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 },
-			{    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 },
-			{    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 },
-			{    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 },
-			{    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 },
-			{    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 },
-			{    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 },
-			{    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 },
-			{    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 },
-			{    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 },
-			{    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 },
-			{    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 },
-			{    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 },
-			{    0.000,    0.000,    0.000 }
-		},
-		{	{ -339.998,   96.840,  -27.330 }, { -324.278,   97.225,  -27.340 }, { -308.643,   97.585,  -27.345 },
-			{ -293.093,   97.925,  -27.350 }, { -277.613,   98.245,  -27.360 }, { -262.213,   98.545,  -27.365 },
-			{ -246.868,   98.820,  -27.365 }, { -231.598,   99.070,  -27.370 }, { -216.383,   99.300,  -27.375 },
-			{ -201.223,   99.505,  -27.380 }, { -186.113,   99.690,  -27.385 }, { -171.048,   99.850,  -27.380 },
-			{ -156.028,   99.990,  -27.385 }, { -141.048,  100.100,  -27.390 }, { -126.103,  100.195,  -27.390 },
-			{ -111.193,  100.265,  -27.395 }, {  -96.303,  100.315,  -27.395 }, {  -81.443,  100.340,  -27.390 },
-			{  -66.603,  100.335,  -27.390 }, {  -51.783,  100.315,  -27.390 }, {  -36.973,  100.275,  -27.395 },
-			{  -22.173,  100.205,  -27.390 }, {   -7.383,  100.115,  -27.385 }, {    7.403,  100.115,  -27.385 },
-			{    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 },
-			{    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 },
-			{    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 },
-			{  156.088,   99.985,  -27.385 }, {  171.103,   99.845,  -27.380 }, {  186.168,   99.680,  -27.385 },
-			{  201.268,   99.495,  -27.380 }, {  216.428,   99.290,  -27.375 }, {  231.643,   99.060,  -27.370 },
-			{  246.913,   98.810,  -27.365 }, {  262.258,   98.535,  -27.365 }, {  277.658,   98.240,  -27.360 },
-			{  293.138,   97.925,  -27.350 }, {  308.688,   97.580,  -27.345 }, {  324.323,   97.215,  -27.340 },
-			{  340.043,   96.835,  -27.330 }
-		},
-		{	{ -339.998,   96.930,  -42.435 }, { -324.278,   97.315,  -42.445 }, { -308.648,   97.680,  -42.455 },
-			{ -293.093,   98.015,  -42.470 }, { -277.613,   98.340,  -42.480 }, { -262.208,   98.635,  -42.490 },
-			{ -246.873,   98.910,  -42.500 }, { -231.593,   99.160,  -42.510 }, { -216.383,   99.390,  -42.515 },
-			{ -201.223,   99.595,  -42.525 }, { -186.113,   99.780,  -42.525 }, { -171.048,   99.940,  -42.535 },
-			{ -156.028,  100.080,  -42.540 }, { -141.048,  100.195,  -42.540 }, { -126.103,  100.290,  -42.545 },
-			{ -111.193,  100.355,  -42.550 }, {  -96.303,  100.405,  -42.550 }, {  -81.443,  100.430,  -42.550 },
-			{  -66.608,  100.430,  -42.550 }, {  -51.783,  100.405,  -42.550 }, {  -36.973,  100.365,  -42.550 },
-			{  -22.178,  100.295,  -42.545 }, {   -7.388,  100.205,  -42.545 }, {    7.403,  100.205,  -42.545 },
-			{   22.193,  100.295,  -42.545 }, {   36.988,  100.365,  -42.550 }, {   51.798,  100.405,  -42.550 },
-			{   66.623,  100.430,  -42.550 }, {   81.458,  100.430,  -42.550 }, {   96.318,  100.405,  -42.550 },
-			{  111.208,  100.355,  -42.550 }, {  126.118,  100.290,  -42.545 }, {  141.063,  100.195,  -42.540 },
-			{  156.043,  100.080,  -42.540 }, {  171.063,   99.940,  -42.535 }, {  186.128,   99.780,  -42.525 },
-			{  201.238,   99.595,  -42.525 }, {  216.398,   99.390,  -42.515 }, {  231.613,   99.160,  -42.510 },
-			{  246.888,   98.910,  -42.500 }, {  262.223,   98.635,  -42.490 }, {  277.628,   98.340,  -42.480 },
-			{  293.108,   98.015,  -42.470 }, {  308.663,   97.680,  -42.455 }, {  324.293,   97.315,  -42.445 },
-			{  340.013,   96.930,  -42.435 }
-		},
-		{	{ -339.998,   97.000,  -57.540 }, { -324.278,   97.385,  -57.560 }, { -308.648,   97.745,  -57.575 },
-			{ -293.093,   98.090,  -57.595 }, { -277.613,   98.410,  -57.610 }, { -262.208,   98.705,  -57.625 },
-			{ -246.873,   98.975,  -57.640 }, { -231.593,   99.225,  -57.655 }, { -216.383,   99.455,  -57.665 },
-			{ -201.223,   99.665,  -57.675 }, { -186.113,   99.845,  -57.685 }, { -171.048,  100.010,  -57.690 },
-			{ -156.028,  100.145,  -57.700 }, { -141.048,  100.265,  -57.705 }, { -126.103,  100.355,  -57.710 },
-			{ -111.193,  100.425,  -57.710 }, {  -96.303,  100.475,  -57.720 }, {  -81.443,  100.495,  -57.715 },
-			{  -66.608,  100.500,  -57.720 }, {  -51.783,  100.480,  -57.715 }, {  -36.973,  100.430,  -57.710 },
-			{  -22.178,  100.365,  -57.710 }, {   -7.388,  100.275,  -57.705 }, {    7.403,  100.275,  -57.705 },
-			{   22.193,  100.365,  -57.710 }, {   36.988,  100.430,  -57.710 }, {   51.798,  100.480,  -57.715 },
-			{   66.623,  100.500,  -57.720 }, {   81.458,  100.495,  -57.715 }, {   96.318,  100.475,  -57.720 },
-			{  111.208,  100.425,  -57.710 }, {  126.118,  100.355,  -57.710 }, {  141.063,  100.265,  -57.705 },
-			{  156.043,  100.145,  -57.700 }, {  171.063,  100.010,  -57.690 }, {  186.128,   99.845,  -57.685 },
-			{  201.238,   99.665,  -57.675 }, {  216.398,   99.455,  -57.665 }, {  231.613,   99.225,  -57.655 },
-			{  246.888,   98.975,  -57.640 }, {  262.223,   98.705,  -57.625 }, {  277.628,   98.410,  -57.610 },
-			{  293.108,   98.090,  -57.595 }, {  308.663,   97.745,  -57.575 }, {  324.293,   97.385,  -57.560 },
-			{  340.013,   97.000,  -57.540 }
-		},
-		{	{ -339.998,   97.045,  -72.655 }, { -324.278,   97.435,  -72.680 }, { -308.648,   97.795,  -72.710 },
-			{ -293.093,   98.135,  -72.730 }, { -277.613,   98.455,  -72.750 }, { -262.208,   98.750,  -72.775 },
-			{ -246.873,   99.020,  -72.795 }, { -231.593,   99.280,  -72.810 }, { -216.383,   99.505,  -72.820 },
-			{ -201.223,   99.710,  -72.840 }, { -186.113,   99.895,  -72.850 }, { -171.048,  100.055,  -72.860 },
-			{ -156.028,  100.190,  -72.870 }, { -141.048,  100.305,  -72.880 }, { -126.103,  100.400,  -72.885 },
-			{ -111.193,  100.470,  -72.890 }, {  -96.303,  100.520,  -72.890 }, {  -81.443,  100.540,  -72.895 },
-			{  -66.608,  100.540,  -72.895 }, {  -51.783,  100.520,  -72.895 }, {  -36.973,  100.480,  -72.890 },
-			{  -22.178,  100.405,  -72.885 }, {   -7.388,  100.320,  -72.880 }, {    7.403,  100.320,  -72.880 },
-			{   22.193,  100.405,  -72.885 }, {   36.988,  100.480,  -72.890 }, {   51.798,  100.520,  -72.895 },
-			{   66.623,  100.540,  -72.895 }, {   81.458,  100.540,  -72.895 }, {   96.318,  100.520,  -72.890 },
-			{  111.208,  100.470,  -72.890 }, {  126.118,  100.400,  -72.885 }, {  141.063,  100.305,  -72.880 },
-			{  156.043,  100.190,  -72.870 }, {  171.063,  100.055,  -72.860 }, {  186.128,   99.895,  -72.850 },
-			{  201.238,   99.710,  -72.840 }, {  216.398,   99.505,  -72.820 }, {  231.613,   99.280,  -72.810 },
-			{  246.888,   99.020,  -72.795 }, {  262.223,   98.750,  -72.775 }, {  277.628,   98.455,  -72.750 },
-			{  293.108,   98.135,  -72.730 }, {  308.663,   97.795,  -72.710 }, {  324.293,   97.435,  -72.680 },
-			{  340.013,   97.045,  -72.655 }
-		},
-		{	{ -339.998,   97.070,  -87.790 }, { -324.278,   97.460,  -87.820 }, { -308.648,   97.820,  -87.850 },
-			{ -293.093,   98.160,  -87.885 }, { -277.613,   98.480,  -87.910 }, { -262.208,   98.775,  -87.935 },
-			{ -246.873,   99.050,  -87.960 }, { -231.593,   99.300,  -87.980 }, { -216.383,   99.530,  -88.000 },
-			{ -201.223,   99.735,  -88.015 }, { -186.113,   99.920,  -88.030 }, { -171.048,  100.080,  -88.045 },
-			{ -156.028,  100.215,  -88.055 }, { -141.048,  100.335,  -88.065 }, { -126.103,  100.420,  -88.070 },
-			{ -111.193,  100.490,  -88.075 }, {  -96.303,  100.540,  -88.085 }, {  -81.443,  100.565,  -88.085 },
-			{  -66.608,  100.560,  -88.085 }, {  -51.783,  100.540,  -88.085 }, {  -36.973,  100.500,  -88.080 },
-			{  -22.178,  100.430,  -88.075 }, {   -7.388,  100.340,  -88.065 }, {    7.403,  100.340,  -88.070 },
-			{   22.193,  100.430,  -88.075 }, {   36.988,  100.500,  -88.080 }, {   51.798,  100.540,  -88.085 },
-			{   66.623,  100.560,  -88.085 }, {   81.458,  100.565,  -88.085 }, {   96.318,  100.540,  -88.085 },
-			{  111.208,  100.490,  -88.075 }, {  126.118,  100.420,  -88.070 }, {  141.063,  100.335,  -88.065 },
-			{  156.043,  100.215,  -88.055 }, {  171.063,  100.080,  -88.045 }, {  186.128,   99.915,  -88.030 },
-			{  201.238,   99.735,  -88.015 }, {  216.398,   99.530,  -88.000 }, {  231.613,   99.300,  -87.980 },
-			{  246.888,   99.050,  -87.960 }, {  262.223,   98.775,  -87.935 }, {  277.628,   98.480,  -87.910 },
-			{  293.108,   98.160,  -87.885 }, {  308.663,   97.820,  -87.850 }, {  324.293,   97.460,  -87.820 },
-			{  340.013,   97.070,  -87.790 }
-		}
-	};
-}
+    private static final double[][][] position = {
+        {   { -340.003,   97.065,   87.845 }, { -324.283,   97.450,   87.875 }, { -308.648,   97.810,   87.900 },
+            { -293.093,   98.150,   87.920 }, { -277.618,   98.470,   87.940 }, { -262.213,   98.765,   87.965 },
+            { -246.878,   99.040,   87.980 }, { -231.603,   99.290,   87.995 }, { -216.393,   99.520,   88.010 },
+            { -201.228,   99.725,   88.030 }, { -186.118,   99.905,   88.040 }, { -171.058,  100.070,   88.050 },
+            { -156.038,  100.205,   88.055 }, { -141.058,  100.325,   88.070 }, { -126.113,  100.415,   88.075 },
+            { -111.198,  100.485,   88.075 }, {  -96.313,  100.530,   88.080 }, {  -81.453,  100.555,   88.085 },
+            {  -66.608,  100.560,   88.085 }, {  -51.788,  100.540,   88.080 }, {  -36.983,  100.490,   88.075 },
+            {  -22.183,  100.425,   88.075 }, {   -7.393,  100.335,   88.070 }, {    7.393,  100.335,   88.070 },
+            {   22.183,  100.425,   88.075 }, {   36.983,  100.490,   88.075 }, {   51.793,  100.540,   88.080 },
+            {   66.613,  100.560,   88.085 }, {   81.453,  100.555,   88.085 }, {   96.313,  100.530,   88.080 },
+            {  111.198,  100.485,   88.075 }, {  126.113,  100.415,   88.075 }, {  141.053,  100.325,   88.070 },
+            {  156.038,  100.205,   88.055 }, {  171.053,  100.070,   88.050 }, {  186.118,   99.905,   88.040 },
+            {  201.228,   99.725,   88.030 }, {  216.388,   99.520,   88.010 }, {  231.608,   99.290,   87.995 },
+            {  246.878,   99.040,   87.980 }, {  262.218,   98.765,   87.965 }, {  277.623,   98.470,   87.940 },
+            {  293.098,   98.150,   87.920 }, {  308.653,   97.810,   87.900 }, {  324.288,   97.450,   87.875 },
+            {  340.008,   97.065,   87.845 }
+        },
+        {   { -340.003,   97.040,   72.715 }, { -324.283,   97.420,   72.735 }, { -308.648,   97.785,   72.750 },
+            { -293.093,   98.125,   72.765 }, { -277.618,   98.450,   72.785 }, { -262.213,   98.745,   72.800 },
+            { -246.878,   99.015,   72.815 }, { -231.603,   99.265,   72.825 }, { -216.388,   99.495,   72.840 },
+            { -201.228,   99.700,   72.850 }, { -186.118,   99.885,   72.860 }, { -171.058,  100.045,   72.865 },
+            { -156.033,  100.185,   72.875 }, { -141.053,  100.300,   72.880 }, { -126.108,  100.395,   72.880 },
+            { -111.193,  100.460,   72.890 }, {  -96.308,  100.510,   72.890 }, {  -81.448,  100.535,   72.895 },
+            {  -66.608,  100.535,   72.890 }, {  -51.788,  100.510,   72.890 }, {  -36.978,  100.470,   72.890 },
+            {  -22.183,  100.405,   72.880 }, {   -7.388,  100.310,   72.880 }, {    7.393,  100.310,   72.880 },
+            {   22.188,  100.405,   72.885 }, {   36.983,  100.470,   72.890 }, {   51.793,  100.510,   72.890 },
+            {   66.613,  100.535,   72.890 }, {   81.453,  100.535,   72.895 }, {   96.313,  100.510,   72.890 },
+            {  111.198,  100.460,   72.890 }, {  126.113,  100.395,   72.880 }, {  141.063,  100.300,   72.880 },
+            {  156.043,  100.185,   72.875 }, {  171.063,  100.045,   72.865 }, {  186.123,   99.885,   72.860 },
+            {  201.233,   99.700,   72.850 }, {  216.393,   99.495,   72.840 }, {  231.608,   99.265,   72.825 },
+            {  246.883,   99.015,   72.815 }, {  262.218,   98.745,   72.800 }, {  277.623,   98.450,   72.785 },
+            {  293.098,   98.125,   72.765 }, {  308.653,   97.785,   72.750 }, {  324.288,   97.420,   72.735 },
+            {  340.008,   97.040,   72.715 }
+        },
+        {   { -340.003,   96.990,   57.600 }, { -324.283,   97.375,   57.610 }, { -308.648,   97.740,   57.625 },
+            { -293.093,   98.080,   57.630 }, { -277.618,   98.395,   57.645 }, { -262.213,   98.700,   57.655 },
+            { -246.873,   98.970,   57.660 }, { -231.603,   99.220,   57.670 }, { -216.383,   99.450,   57.680 },
+            { -201.228,   99.660,   57.685 }, { -186.113,   99.840,   57.695 }, { -171.053,  100.005,   57.695 },
+            { -156.033,  100.140,   57.700 }, { -141.053,  100.255,   57.710 }, { -126.108,  100.345,   57.710 },
+            { -111.193,  100.420,   57.710 }, {  -96.308,  100.465,   57.715 }, {  -81.448,  100.490,   57.715 },
+            {  -66.608,  100.490,   57.715 }, {  -51.788,  100.470,   57.710 }, {  -36.978,  100.425,   57.710 },
+            {  -22.178,  100.355,   57.710 }, {   -7.388,  100.265,   57.705 }, {    7.398,  100.265,   57.705 },
+            {   22.188,  100.355,   57.710 }, {   36.988,  100.425,   57.710 }, {   51.793,  100.470,   57.710 },
+            {   66.613,  100.490,   57.715 }, {   81.458,  100.490,   57.715 }, {   96.318,  100.465,   57.715 },
+            {  111.198,  100.420,   57.710 }, {  126.118,  100.345,   57.710 }, {  141.063,  100.255,   57.710 },
+            {  156.043,  100.140,   57.700 }, {  171.063,  100.005,   57.695 }, {  186.123,   99.840,   57.695 },
+            {  201.233,   99.660,   57.685 }, {  216.393,   99.450,   57.680 }, {  231.608,   99.220,   57.670 },
+            {  246.883,   98.970,   57.660 }, {  262.218,   98.700,   57.655 }, {  277.623,   98.395,   57.645 },
+            {  293.098,   98.080,   57.630 }, {  308.653,   97.740,   57.625 }, {  324.288,   97.375,   57.610 },
+            {  340.008,   96.990,   57.600 }
+        },
+        {   { -340.003,   96.925,   42.490 }, { -324.283,   97.305,   42.495 }, { -308.648,   97.675,   42.505 },
+            { -293.093,   98.010,   42.510 }, { -277.618,   98.330,   42.510 }, { -262.213,   98.625,   42.515 },
+            { -246.873,   98.900,   42.525 }, { -231.603,   99.155,   42.530 }, { -216.383,   99.385,   42.535 },
+            { -201.223,   99.590,   42.530 }, { -186.113,   99.775,   42.535 }, { -171.048,   99.930,   42.540 },
+            { -156.033,  100.070,   42.545 }, { -141.048,  100.185,   42.545 }, { -126.108,  100.280,   42.550 },
+            { -111.193,  100.350,   42.545 }, {  -96.308,  100.400,   42.545 }, {  -81.448,  100.420,   42.550 },
+            {  -66.608,  100.425,   42.550 }, {  -51.788,  100.405,   42.550 }, {  -36.978,  100.355,   42.545 },
+            {  -22.178,  100.290,   42.545 }, {   -7.388,  100.200,   42.545 }, {    7.398,  100.200,   42.545 },
+            {   22.188,  100.290,   42.545 }, {   36.988,  100.355,   42.545 }, {   51.793,  100.405,   42.550 },
+            {   66.613,  100.425,   42.550 }, {   81.458,  100.420,   42.550 }, {   96.318,  100.400,   42.545 },
+            {  111.198,  100.350,   42.545 }, {  126.118,  100.280,   42.550 }, {  141.063,  100.185,   42.545 },
+            {  156.043,  100.070,   42.545 }, {  171.063,   99.930,   42.540 }, {  186.123,   99.775,   42.535 },
+            {  201.233,   99.590,   42.530 }, {  216.393,   99.385,   42.535 }, {  231.608,   99.155,   42.530 },
+            {  246.883,   98.900,   42.525 }, {  262.218,   98.625,   42.515 }, {  277.628,   98.330,   42.510 },
+            {  293.098,   98.010,   42.510 }, {  308.653,   97.675,   42.505 }, {  324.288,   97.305,   42.495 },
+            {  340.008,   96.925,   42.490 }
+        },
+        {   { -340.003,   96.830,   27.385 }, { -324.278,   97.215,   27.385 }, { -308.648,   97.575,   27.385 },
+            { -293.093,   97.915,   27.385 }, { -277.613,   98.240,   27.385 }, { -262.213,   98.535,   27.385 },
+            { -246.878,   98.810,   27.385 }, { -231.603,   99.060,   27.385 }, { -216.383,   99.290,   27.385 },
+            { -201.223,   99.495,   27.385 }, { -186.113,   99.680,   27.385 }, { -171.048,   99.840,   27.385 },
+            { -156.033,   99.980,   27.385 }, { -141.048,  100.095,   27.385 }, { -126.103,  100.185,   27.385 },
+            { -111.193,  100.255,   27.385 }, {  -96.303,  100.305,   27.385 }, {  -81.448,  100.330,   27.385 },
+            {  -66.608,  100.330,   27.385 }, {  -51.783,  100.310,   27.385 }, {  -36.973,  100.265,   27.385 },
+            {  -22.178,  100.200,   27.385 }, {   -7.388,  100.105,   27.385 }, {    7.403,  100.105,   27.385 },
+            {    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 },
+            {    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 },
+            {    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 },
+            {  156.078,   99.980,   27.385 }, {  171.103,   99.840,   27.385 }, {  186.168,   99.680,   27.385 },
+            {  201.268,   99.495,   27.385 }, {  216.423,   99.290,   27.385 }, {  231.638,   99.060,   27.385 },
+            {  246.913,   98.810,   27.385 }, {  262.248,   98.535,   27.385 }, {  277.658,   98.240,   27.385 },
+            {  293.133,   97.920,   27.385 }, {  308.688,   97.575,   27.385 }, {  324.323,   97.215,   27.385 },
+            {  340.043,   96.830,   27.385 }
+        },
+        {   {    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 },
+            {    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 },
+            {    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 },
+            {    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 },
+            {    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 },
+            {    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 },
+            {    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 },
+            {    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 },
+            {    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 },
+            {    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 },
+            {    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 },
+            {    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 },
+            {    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 },
+            {    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 },
+            {    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 },
+            {    0.000,    0.000,    0.000 }
+        },
+        {   { -339.998,   96.840,  -27.330 }, { -324.278,   97.225,  -27.340 }, { -308.643,   97.585,  -27.345 },
+            { -293.093,   97.925,  -27.350 }, { -277.613,   98.245,  -27.360 }, { -262.213,   98.545,  -27.365 },
+            { -246.868,   98.820,  -27.365 }, { -231.598,   99.070,  -27.370 }, { -216.383,   99.300,  -27.375 },
+            { -201.223,   99.505,  -27.380 }, { -186.113,   99.690,  -27.385 }, { -171.048,   99.850,  -27.380 },
+            { -156.028,   99.990,  -27.385 }, { -141.048,  100.100,  -27.390 }, { -126.103,  100.195,  -27.390 },
+            { -111.193,  100.265,  -27.395 }, {  -96.303,  100.315,  -27.395 }, {  -81.443,  100.340,  -27.390 },
+            {  -66.603,  100.335,  -27.390 }, {  -51.783,  100.315,  -27.390 }, {  -36.973,  100.275,  -27.395 },
+            {  -22.173,  100.205,  -27.390 }, {   -7.383,  100.115,  -27.385 }, {    7.403,  100.115,  -27.385 },
+            {    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 },
+            {    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 },
+            {    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 }, {    0.000,    0.000,    0.000 },
+            {  156.088,   99.985,  -27.385 }, {  171.103,   99.845,  -27.380 }, {  186.168,   99.680,  -27.385 },
+            {  201.268,   99.495,  -27.380 }, {  216.428,   99.290,  -27.375 }, {  231.643,   99.060,  -27.370 },
+            {  246.913,   98.810,  -27.365 }, {  262.258,   98.535,  -27.365 }, {  277.658,   98.240,  -27.360 },
+            {  293.138,   97.925,  -27.350 }, {  308.688,   97.580,  -27.345 }, {  324.323,   97.215,  -27.340 },
+            {  340.043,   96.835,  -27.330 }
+        },
+        {   { -339.998,   96.930,  -42.435 }, { -324.278,   97.315,  -42.445 }, { -308.648,   97.680,  -42.455 },
+            { -293.093,   98.015,  -42.470 }, { -277.613,   98.340,  -42.480 }, { -262.208,   98.635,  -42.490 },
+            { -246.873,   98.910,  -42.500 }, { -231.593,   99.160,  -42.510 }, { -216.383,   99.390,  -42.515 },
+            { -201.223,   99.595,  -42.525 }, { -186.113,   99.780,  -42.525 }, { -171.048,   99.940,  -42.535 },
+            { -156.028,  100.080,  -42.540 }, { -141.048,  100.195,  -42.540 }, { -126.103,  100.290,  -42.545 },
+            { -111.193,  100.355,  -42.550 }, {  -96.303,  100.405,  -42.550 }, {  -81.443,  100.430,  -42.550 },
+            {  -66.608,  100.430,  -42.550 }, {  -51.783,  100.405,  -42.550 }, {  -36.973,  100.365,  -42.550 },
+            {  -22.178,  100.295,  -42.545 }, {   -7.388,  100.205,  -42.545 }, {    7.403,  100.205,  -42.545 },
+            {   22.193,  100.295,  -42.545 }, {   36.988,  100.365,  -42.550 }, {   51.798,  100.405,  -42.550 },
+            {   66.623,  100.430,  -42.550 }, {   81.458,  100.430,  -42.550 }, {   96.318,  100.405,  -42.550 },
+            {  111.208,  100.355,  -42.550 }, {  126.118,  100.290,  -42.545 }, {  141.063,  100.195,  -42.540 },
+            {  156.043,  100.080,  -42.540 }, {  171.063,   99.940,  -42.535 }, {  186.128,   99.780,  -42.525 },
+            {  201.238,   99.595,  -42.525 }, {  216.398,   99.390,  -42.515 }, {  231.613,   99.160,  -42.510 },
+            {  246.888,   98.910,  -42.500 }, {  262.223,   98.635,  -42.490 }, {  277.628,   98.340,  -42.480 },
+            {  293.108,   98.015,  -42.470 }, {  308.663,   97.680,  -42.455 }, {  324.293,   97.315,  -42.445 },
+            {  340.013,   96.930,  -42.435 }
+        },
+        {   { -339.998,   97.000,  -57.540 }, { -324.278,   97.385,  -57.560 }, { -308.648,   97.745,  -57.575 },
+            { -293.093,   98.090,  -57.595 }, { -277.613,   98.410,  -57.610 }, { -262.208,   98.705,  -57.625 },
+            { -246.873,   98.975,  -57.640 }, { -231.593,   99.225,  -57.655 }, { -216.383,   99.455,  -57.665 },
+            { -201.223,   99.665,  -57.675 }, { -186.113,   99.845,  -57.685 }, { -171.048,  100.010,  -57.690 },
+            { -156.028,  100.145,  -57.700 }, { -141.048,  100.265,  -57.705 }, { -126.103,  100.355,  -57.710 },
+            { -111.193,  100.425,  -57.710 }, {  -96.303,  100.475,  -57.720 }, {  -81.443,  100.495,  -57.715 },
+            {  -66.608,  100.500,  -57.720 }, {  -51.783,  100.480,  -57.715 }, {  -36.973,  100.430,  -57.710 },
+            {  -22.178,  100.365,  -57.710 }, {   -7.388,  100.275,  -57.705 }, {    7.403,  100.275,  -57.705 },
+            {   22.193,  100.365,  -57.710 }, {   36.988,  100.430,  -57.710 }, {   51.798,  100.480,  -57.715 },
+            {   66.623,  100.500,  -57.720 }, {   81.458,  100.495,  -57.715 }, {   96.318,  100.475,  -57.720 },
+            {  111.208,  100.425,  -57.710 }, {  126.118,  100.355,  -57.710 }, {  141.063,  100.265,  -57.705 },
+            {  156.043,  100.145,  -57.700 }, {  171.063,  100.010,  -57.690 }, {  186.128,   99.845,  -57.685 },
+            {  201.238,   99.665,  -57.675 }, {  216.398,   99.455,  -57.665 }, {  231.613,   99.225,  -57.655 },
+            {  246.888,   98.975,  -57.640 }, {  262.223,   98.705,  -57.625 }, {  277.628,   98.410,  -57.610 },
+            {  293.108,   98.090,  -57.595 }, {  308.663,   97.745,  -57.575 }, {  324.293,   97.385,  -57.560 },
+            {  340.013,   97.000,  -57.540 }
+        },
+        {   { -339.998,   97.045,  -72.655 }, { -324.278,   97.435,  -72.680 }, { -308.648,   97.795,  -72.710 },
+            { -293.093,   98.135,  -72.730 }, { -277.613,   98.455,  -72.750 }, { -262.208,   98.750,  -72.775 },
+            { -246.873,   99.020,  -72.795 }, { -231.593,   99.280,  -72.810 }, { -216.383,   99.505,  -72.820 },
+            { -201.223,   99.710,  -72.840 }, { -186.113,   99.895,  -72.850 }, { -171.048,  100.055,  -72.860 },
+            { -156.028,  100.190,  -72.870 }, { -141.048,  100.305,  -72.880 }, { -126.103,  100.400,  -72.885 },
+            { -111.193,  100.470,  -72.890 }, {  -96.303,  100.520,  -72.890 }, {  -81.443,  100.540,  -72.895 },
+            {  -66.608,  100.540,  -72.895 }, {  -51.783,  100.520,  -72.895 }, {  -36.973,  100.480,  -72.890 },
+            {  -22.178,  100.405,  -72.885 }, {   -7.388,  100.320,  -72.880 }, {    7.403,  100.320,  -72.880 },
+            {   22.193,  100.405,  -72.885 }, {   36.988,  100.480,  -72.890 }, {   51.798,  100.520,  -72.895 },
+            {   66.623,  100.540,  -72.895 }, {   81.458,  100.540,  -72.895 }, {   96.318,  100.520,  -72.890 },
+            {  111.208,  100.470,  -72.890 }, {  126.118,  100.400,  -72.885 }, {  141.063,  100.305,  -72.880 },
+            {  156.043,  100.190,  -72.870 }, {  171.063,  100.055,  -72.860 }, {  186.128,   99.895,  -72.850 },
+            {  201.238,   99.710,  -72.840 }, {  216.398,   99.505,  -72.820 }, {  231.613,   99.280,  -72.810 },
+            {  246.888,   99.020,  -72.795 }, {  262.223,   98.750,  -72.775 }, {  277.628,   98.455,  -72.750 },
+            {  293.108,   98.135,  -72.730 }, {  308.663,   97.795,  -72.710 }, {  324.293,   97.435,  -72.680 },
+            {  340.013,   97.045,  -72.655 }
+        },
+        {   { -339.998,   97.070,  -87.790 }, { -324.278,   97.460,  -87.820 }, { -308.648,   97.820,  -87.850 },
+            { -293.093,   98.160,  -87.885 }, { -277.613,   98.480,  -87.910 }, { -262.208,   98.775,  -87.935 },
+            { -246.873,   99.050,  -87.960 }, { -231.593,   99.300,  -87.980 }, { -216.383,   99.530,  -88.000 },
+            { -201.223,   99.735,  -88.015 }, { -186.113,   99.920,  -88.030 }, { -171.048,  100.080,  -88.045 },
+            { -156.028,  100.215,  -88.055 }, { -141.048,  100.335,  -88.065 }, { -126.103,  100.420,  -88.070 },
+            { -111.193,  100.490,  -88.075 }, {  -96.303,  100.540,  -88.085 }, {  -81.443,  100.565,  -88.085 },
+            {  -66.608,  100.560,  -88.085 }, {  -51.783,  100.540,  -88.085 }, {  -36.973,  100.500,  -88.080 },
+            {  -22.178,  100.430,  -88.075 }, {   -7.388,  100.340,  -88.065 }, {    7.403,  100.340,  -88.070 },
+            {   22.193,  100.430,  -88.075 }, {   36.988,  100.500,  -88.080 }, {   51.798,  100.540,  -88.085 },
+            {   66.623,  100.560,  -88.085 }, {   81.458,  100.565,  -88.085 }, {   96.318,  100.540,  -88.085 },
+            {  111.208,  100.490,  -88.075 }, {  126.118,  100.420,  -88.070 }, {  141.063,  100.335,  -88.065 },
+            {  156.043,  100.215,  -88.055 }, {  171.063,  100.080,  -88.045 }, {  186.128,   99.915,  -88.030 },
+            {  201.238,   99.735,  -88.015 }, {  216.398,   99.530,  -88.000 }, {  231.613,   99.300,  -87.980 },
+            {  246.888,   99.050,  -87.960 }, {  262.223,   98.775,  -87.935 }, {  277.628,   98.480,  -87.910 },
+            {  293.108,   98.160,  -87.885 }, {  308.663,   97.820,  -87.850 }, {  324.293,   97.460,  -87.820 },
+            {  340.013,   97.070,  -87.790 }
+        }
+    };
+}

Modified: java/branches/HPSJAVA-409/run-database/pom.xml
 =============================================================================
--- java/branches/HPSJAVA-409/run-database/pom.xml	(original)
+++ java/branches/HPSJAVA-409/run-database/pom.xml	Wed Apr 27 11:11:32 2016
@@ -7,7 +7,7 @@
         <groupId>org.hps</groupId>
         <artifactId>hps-parent</artifactId>
         <relativePath>../parent/pom.xml</relativePath>
-        <version>3.4.2-SNAPSHOT</version>
+        <version>3.9-SNAPSHOT</version>
     </parent>
     <scm>
         <url>http://java.freehep.org/svn/repos/hps/list/java/trunk/run-database/</url>
@@ -20,8 +20,21 @@
             <artifactId>hps-record-util</artifactId>
         </dependency>
         <dependency>
-            <groupId>org.hps</groupId>
-            <artifactId>hps-datacat-client</artifactId>
+            <groupId>srs</groupId>
+            <artifactId>org-srs-datacat-client</artifactId>
         </dependency>
     </dependencies>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <configuration>
+                    <excludes>
+                        <exclude>org/hps/run/database/RunBuilderTest.java</exclude>
+                    </excludes>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
 </project>

Modified: java/branches/HPSJAVA-409/run-database/src/main/java/org/hps/run/database/EpicsDataDao.java
 =============================================================================
--- java/branches/HPSJAVA-409/run-database/src/main/java/org/hps/run/database/EpicsDataDao.java	(original)
+++ java/branches/HPSJAVA-409/run-database/src/main/java/org/hps/run/database/EpicsDataDao.java	Wed Apr 27 11:11:32 2016
@@ -16,7 +16,7 @@
      *
      * @param run the run number
      */
-    public void deleteEpicsData(EpicsType epicsType, final int run);
+    public void deleteEpicsData(EpicsType epicsType, int run);
 
     /**
      * Get EPICS data by run.
@@ -34,5 +34,5 @@
      *
      * @param epicsDataList the list of EPICS data
      */
-    void insertEpicsData(List<EpicsData> epicsDataList);   
+    void insertEpicsData(List<EpicsData> epicsDataList, int run);
 }

Modified: java/branches/HPSJAVA-409/run-database/src/main/java/org/hps/run/database/EpicsDataDaoImpl.java
 =============================================================================
--- java/branches/HPSJAVA-409/run-database/src/main/java/org/hps/run/database/EpicsDataDaoImpl.java	(original)
+++ java/branches/HPSJAVA-409/run-database/src/main/java/org/hps/run/database/EpicsDataDaoImpl.java	Wed Apr 27 11:11:32 2016
@@ -74,6 +74,9 @@
 
     /**
      * Delete all EPICS data for a run from the database.
+     * <p>
+     * Only the <code>epics_header</code> records are deleted and the child records
+     * are deleted automatically via a <code>CASCADE</code>.
      *
      * @param run the run number
      */
@@ -97,12 +100,12 @@
                 deleteEpicsData.setInt(1, headerId);
                 int rowsAffected = deleteEpicsData.executeUpdate();
                 if (rowsAffected == 0) {
-                    throw new SQLException("Deletion of EPICS data failed; no rows affect.");
+                    throw new SQLException("Deletion of EPICS data failed; no rows affected.");
                 }
                 deleteHeader.setInt(1, headerId);
                 rowsAffected = deleteHeader.executeUpdate();
                 if (rowsAffected == 0) {
-                    throw new SQLException("Deletion of EPICS header failed; no rows affect.");
+                    throw new SQLException("Deletion of EPICS header failed; no rows affected.");
                 }
             }
 
@@ -137,7 +140,7 @@
      * Get EPICS data by run.
      *
      * @param run the run number
-     * @param epicsType the type of EPICS data (1s or 10s)
+     * @param epicsType the type of EPICS data (2s or 20s)
      * @return the EPICS data
      */
     @Override
@@ -149,7 +152,7 @@
             final List<EpicsVariable> variables = epicsVariableDao.getEpicsVariables(epicsType);
             selectEpicsData = connection.prepareStatement("SELECT * FROM " + epicsType.getTableName() 
                     + " LEFT JOIN epics_headers ON " + epicsType.getTableName() + ".epics_header_id = epics_headers.id"
-                    + " WHERE epics_headers.run = ?");
+                    + " WHERE epics_headers.run = ? ORDER BY epics_headers.sequence");
             selectEpicsData.setInt(1, run);
             ResultSet resultSet = selectEpicsData.executeQuery();
             while (resultSet.next()) {
@@ -189,12 +192,14 @@
     /**
      * Insert a list of EPICS data into the database.
      * <p>
-     * The run number comes from the header information.
+     * By default, the run number from the header will be used, but it will be overridden
+     * if it does not match the <code>run</code> argument.  (There are a few data files
+     * where the run in the EPICS header is occassionally wrong.)
      *
      * @param epicsDataList the list of EPICS data
      */
     @Override
-    public void insertEpicsData(final List<EpicsData> epicsDataList) {
+    public void insertEpicsData(final List<EpicsData> epicsDataList, int run) {
         if (epicsDataList.isEmpty()) {
             throw new IllegalArgumentException("The EPICS data list is empty.");
         }
@@ -208,9 +213,11 @@
                 if (epicsHeader == null) {
                     throw new IllegalArgumentException("The EPICS data is missing a header.");
                 }
-                insertHeaderStatement.setInt(1, epicsHeader.getRun());
+                insertHeaderStatement.setInt(1, run); /* Don't use run from bank as it is sometimes wrong! */
                 insertHeaderStatement.setInt(2, epicsHeader.getSequence());
                 insertHeaderStatement.setInt(3, epicsHeader.getTimestamp());
+                LOGGER.finer("creating EPICs record with run = " + run + " ; seq = " 
+                        + epicsHeader.getSequence() + "; ts = " + epicsHeader.getTimestamp());
                 final int rowsCreated = insertHeaderStatement.executeUpdate();
                 if (rowsCreated == 0) {
                     throw new SQLException("Creation of EPICS header record failed; no rows affected.");
@@ -238,11 +245,11 @@
                     insertStatement.setDouble(parameterIndex, value);
                     ++parameterIndex;
                 }
-                final int dataRowsCreated = insertStatement.executeUpdate();                
+                final int dataRowsCreated = insertStatement.executeUpdate();
                 if (dataRowsCreated == 0) {
                     throw new SQLException("Creation of EPICS data failed; no rows affected.");
                 }
-                LOGGER.info("inserted EPICS data with run " + epicsHeader.getRun() + ", seq " + epicsHeader.getSequence() + "timestamp " 
+                LOGGER.finer("inserted EPICS data with run = " + run + "; seq = " + epicsHeader.getSequence() + "; ts = " 
                         + epicsHeader.getTimestamp());
                 insertStatement.close();
             }

Modified: java/branches/HPSJAVA-409/run-database/src/main/java/org/hps/run/database/EpicsType.java
 =============================================================================
--- java/branches/HPSJAVA-409/run-database/src/main/java/org/hps/run/database/EpicsType.java	(original)
+++ java/branches/HPSJAVA-409/run-database/src/main/java/org/hps/run/database/EpicsType.java	Wed Apr 27 11:11:32 2016
@@ -3,34 +3,35 @@
 import org.hps.record.epics.EpicsData;
 
 /**
- * Enum for representing different types of EPICS data in the run database, of which there are currently two (1s and
- * 10s).
+ * Enum for representing different types of EPICS data in the run database, of which there are currently two (2s and
+ * 20s).
  *
  * @author Jeremy McCormick, SLAC
  */
+// FIXME: move to record-util
 public enum EpicsType {
 
     /**
-     * 10S EPICS data.
+     * 20S EPICS data.
      */
-    EPICS_10S(10),
+    EPICS_20S(20),
     /**
-     * 1S EPICS data.
+     * 2S EPICS data.
      */
-    EPICS_1S(1);
+    EPICS_2S(2);
 
     /**
      * Get the type from an int.
      *
      * @param type the type from an int
      * @return the type from an int
-     * @throws IllegalArgumentException if <code>type</code> is invalid (not 1 or 10)
+     * @throws IllegalArgumentException if <code>type</code> is invalid (not 2 or 20)
      */
     public static EpicsType fromInt(final int type) {
-        if (type == EPICS_1S.type) {
-            return EPICS_1S;
-        } else if (type == EPICS_10S.type) {
-            return EPICS_10S;
+        if (type == EPICS_2S.type) {
+            return EPICS_2S;
+        } else if (type == EPICS_20S.type) {
+            return EPICS_20S;
         } else {
             throw new IllegalArgumentException("The type code is invalid (must be 1 or 10): " + type);
         }
@@ -44,9 +45,9 @@
     public static EpicsType getEpicsType(final EpicsData epicsData) {
         // FIXME: The type argument should be set on creation which would make this key check unnecessary.
         if (epicsData.getKeys().contains("MBSY2C_energy")) {
-            return EpicsType.EPICS_1S;
+            return EpicsType.EPICS_2S;
         } else {
-            return EpicsType.EPICS_10S;
+            return EpicsType.EPICS_20S;
         }
     }
 

Modified: java/branches/HPSJAVA-409/run-database/src/main/java/org/hps/run/database/EpicsVariable.java
 =============================================================================
--- java/branches/HPSJAVA-409/run-database/src/main/java/org/hps/run/database/EpicsVariable.java	(original)
+++ java/branches/HPSJAVA-409/run-database/src/main/java/org/hps/run/database/EpicsVariable.java	Wed Apr 27 11:11:32 2016
@@ -2,7 +2,7 @@
 
 /**
  * Information about an EPICS variable including its name in the EPICS database, column name for the run database,
- * description of the variable, and type (either 1s or 10s).
+ * description of the variable, and type (either 2s or 20s).
  * <p>
  * This class is used to represent data from the <i>epics_variables</i> table in the run database.
  *
@@ -29,7 +29,7 @@
     private final String variableName;
 
     /**
-     * The type of the variable (1s or 10s).
+     * The type of the variable (2s or 20s).
      */
     private final EpicsType variableType;
 
@@ -53,9 +53,9 @@
      * Create an EPICs variable.
      *
      * @param variableName the name of the variable
-     * @param columnName the column name in the run db
+     * @param columnName the column name in the run database
      * @param description the variable's description
-     * @param variableType the type of the variable
+     * @param type the integer encoding of the type
      */
     public EpicsVariable(final String variableName, final String columnName, final String description, final int type) {
         this.variableName = variableName;

Modified: java/branches/HPSJAVA-409/run-database/src/main/java/org/hps/run/database/RunDatabaseCommandLine.java
 =============================================================================
--- java/branches/HPSJAVA-409/run-database/src/main/java/org/hps/run/database/RunDatabaseCommandLine.java	(original)
+++ java/branches/HPSJAVA-409/run-database/src/main/java/org/hps/run/database/RunDatabaseCommandLine.java	Wed Apr 27 11:11:32 2016
@@ -1,62 +1,24 @@
 package org.hps.run.database;
 
 import java.io.File;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.logging.Logger;
+import java.net.URISyntaxException;
 
 import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.PosixParser;
 import org.apache.commons.cli.HelpFormatter;
 import org.apache.commons.cli.Options;
 import org.apache.commons.cli.ParseException;
-import org.apache.commons.cli.DefaultParser;
 import org.hps.conditions.database.ConnectionParameters;
-import org.hps.datacat.client.DatacatClient;
-import org.hps.datacat.client.DatacatClientFactory;
-import org.hps.datacat.client.Dataset;
-import org.hps.datacat.client.DatasetMetadata;
-import org.hps.record.evio.EvioFileUtilities;
+import org.srs.datacat.client.Client;
+import org.srs.datacat.client.ClientBuilder;
 
 /**
- * Command line tool for updating the run database from EVIO files registered in the data catalog.
+ * Command line tool for inserting records into the run database.
  *
  * @author Jeremy McCormick, SLAC
  */
-public class RunDatabaseCommandLine {
-
-    /**
-     * Set of features supported by the tool.
-     */
-    static enum Feature {
-        /**
-         * Insert EPICS data.
-         */
-        EPICS,
-        /**
-         * Insert scaler data.
-         */
-        SCALERS,
-        /**
-         * Insert run summary.
-         */
-        SUMMARY,
-        /**
-         * Insert trigger config.
-         */
-        TRIGGER_CONFIG
-    }
-
-    /**
-     * Initialize the logger.
-     */
-    private static final Logger LOGGER = Logger.getLogger(RunDatabaseCommandLine.class.getPackage().getName());
-
+public final class RunDatabaseCommandLine {
+        
     /**
      * Command line options for the crawler.
      */
@@ -66,11 +28,18 @@
      * Statically define the command options.
      */
     static {
-        OPTIONS.addOption("f", "feature", true, "enable a feature");
-        OPTIONS.addOption("p", "connection-properties", true, "database connection properties file (required)");
         OPTIONS.addOption("h", "help", false, "print help and exit (overrides all other arguments)");
         OPTIONS.addOption("r", "run", true, "run to update");
-        OPTIONS.addOption("u", "update", false, "allow updating existing run in the database");
+        OPTIONS.addOption("p", "connection-properties", true, "database connection properties file (required)");       
+        OPTIONS.addOption("Y", "dry-run", false, "dry run which will not update the database");
+        OPTIONS.addOption("x", "replace", false, "allow deleting and replacing an existing run");
+        OPTIONS.addOption("s", "spreadsheet", true, "path to run database spreadsheet (CSV format)");
+        OPTIONS.addOption("d", "detector", true, "conditions system detector name");
+        OPTIONS.addOption("N", "no-evio-processing", false, "skip processing of all EVIO files");
+        OPTIONS.addOption("L", "load", false, "load back run information after inserting (for debugging)");
+        OPTIONS.addOption("u", "url", true, "data catalog URL");
+        OPTIONS.addOption("S", "site", true, "data catalog site (e.g. SLAC or JLAB)");
+        OPTIONS.addOption("f", "folder", true, "folder in datacat for dataset search");
     }
 
     /**
@@ -81,113 +50,76 @@
     public static void main(final String args[]) {
         new RunDatabaseCommandLine().parse(args).run();
     }
-
-    /**
-     * Allow updating of the database for existing runs.
-     */
-    private boolean allowUpdates = false;
-
-    /**
-     * The set of enabled features.
-     */
-    private final Set<Feature> features = new HashSet<Feature>();
-
-    /**
-     * The run manager for interacting with the run db.
-     */
-    private RunManager runManager;
-
-    /**
-     * Create a run processor from the current configuration.
-     *
-     * @return the run processor
-     */
-    private RunProcessor createEvioRunProcessor(final RunSummaryImpl runSummary, final List<File> files) {
-
-        final RunProcessor runProcessor = new RunProcessor(runSummary, files);
-
-        if (features.contains(Feature.EPICS)) {
-            runProcessor.addEpicsProcessor();
-        }
-        if (features.contains(Feature.SCALERS)) {
-            runProcessor.addScalerProcessor();
-        }
-        if (features.contains(Feature.TRIGGER_CONFIG)) {
-            runProcessor.addTriggerTimeProcessor();
-        }
-
-        return runProcessor;
-    }
-
-    /**
-     * Get the list of EVIO files for the run.
-     *
-     * @param run the run number
-     * @return the list of EVIO files from the run
-     */
-    private Map<File, Dataset> getEvioFiles(final int run) {
-        final DatacatClient datacatClient = new DatacatClientFactory().createClient();
-        final Set<String> metadata = new HashSet<String>();
-        final Map<File, Dataset> files = new HashMap<File, Dataset>();
-        metadata.add("runMin");
-        metadata.add("eventCount");
-        metadata.add("fileNumber");
-        metadata.add("endTimestamp");
-        metadata.add("startTimestamp");
-        metadata.add("hasEnd");
-        metadata.add("hasPrestart");
-        final List<Dataset> datasets = datacatClient.findDatasets("data/raw",
-                "fileFormat eq 'EVIO' AND dataType eq 'RAW' AND runMin eq " + run, metadata);
-        if (datasets.isEmpty()) {
-            throw new IllegalStateException("No EVIO datasets for run " + run + " were found in the data catalog.");
-        }
-        for (final Dataset dataset : datasets) {
-            files.put(new File(dataset.getLocations().get(0).getResource()), dataset);
-        }
-        return files;
-    }
-
-    /**
-     * Insert information for a run into the database.
-     *
-     * @param runManager the run manager for interacting with the run db
-     * @param runSummary the run summary with information about the run
-     */
-    private void insertRun(final RunManager runManager, final RunSummary runSummary) {
-
-        final RunDatabaseDaoFactory runFactory = new RunDatabaseDaoFactory(runManager.getConnection());
-
-        // Add the run summary record.
-        if (this.features.contains(Feature.SUMMARY)) {
-            LOGGER.info("inserting run summary");
-            runFactory.createRunSummaryDao().insertRunSummary(runSummary);
-        }
-
-        if (this.features.contains(Feature.EPICS)) {
-            LOGGER.info("inserting EPICS data");
-            runFactory.createEpicsDataDao().insertEpicsData(runSummary.getEpicsData());
-        }
-
-        if (this.features.contains(Feature.SCALERS)) {
-            LOGGER.info("inserting scaler data");
-            runFactory.createScalerDataDao().insertScalerData(runSummary.getScalerData(), runManager.getRun());
-        }
-
-        if (this.features.contains(Feature.TRIGGER_CONFIG)) {
-            LOGGER.info("inserting trigger config");
-            runFactory.createTriggerConfigDao().insertTriggerConfig(runSummary.getTriggerConfig(), runManager.getRun());
-        }
-    }
-
-    /**
-     * Parse command line options and return reference to <code>this</code>.
+    
+    /**
+     * Enable dry run which will not update the run database.
+     */
+    private boolean dryRun = false;
+    
+    /**
+     * Run number.
+     */
+    private int run;
+    
+    /**
+     * Path to spreadsheet CSV file.
+     */
+    private File spreadsheetFile = null;
+    
+    /**
+     * Name of detector for conditions system (default for Eng Run 2015 provided here).
+     */
+    private String detectorName = "HPS-EngRun2015-Nominal-v3";
+    
+    /**
+     * Allow replacement of existing records.
+     */
+    private boolean replace = false;
+    
+    /**
+     * Skip full EVIO file processing.
+     */
+    private boolean skipEvioProcessing = false;
+    
+    /**
+     * Load back run information after insert (for debugging).
+     */
+    private boolean reload = false;
+    
+    /**
+     * Database connection parameters.
+     */
+    private ConnectionParameters connectionParameters = null;
+    
+    /**
+     * Data catalog client interface.
+     */
+    private Client datacatClient = null;
+    
+    /**
+     * Data catalog site.
+     */
+    private String site = "JLAB";                             
+    
+    /**
+     * Data catalog URL.
+     */
+    private String url = "http://hpsweb.jlab.org/datacat/r";  
+    
+    /**
+     * Default folder for file search.
+     */
+    private String folder = "/HPS/data/raw";
+    
+    /**
+     * Parse command line options and return reference to <code>this</code> object.
      *
      * @param args the command line arguments
      * @return reference to this object
      */
-    RunDatabaseCommandLine parse(final String args[]) {
+    private RunDatabaseCommandLine parse(final String args[]) {
         try {
-            final CommandLine cl = new DefaultParser().parse(OPTIONS, args);
+            final CommandLine cl = new PosixParser().parse(OPTIONS, args);
 
             // Print help and exit.
             if (cl.hasOption("h") || args.length == 0) {
@@ -204,43 +136,74 @@
                     throw new IllegalArgumentException("Connection properties file " + dbPropFile.getPath()
                             + " does not exist.");
                 }
-                final ConnectionParameters connectionParameters = ConnectionParameters.fromProperties(dbPropFile);
-                LOGGER.config("using " + dbPropPath + " for db connection properties");
-
-                runManager = new RunManager(connectionParameters.createConnection());
-
+                connectionParameters = ConnectionParameters.fromProperties(dbPropFile);
             } else {
                 // Database connection properties file is required.
-                throw new RuntimeException("Connection properties are required.");
-            }
-
-            Integer run = null;
+                throw new RuntimeException("Connection properties are a required argument.");
+            }
+
+            // Run number.
             if (cl.hasOption("r")) {
                 run = Integer.parseInt(cl.getOptionValue("r"));
             } else {
                 throw new RuntimeException("The run number is required.");
             }
-            runManager.setRun(run);
-
+            
+            // Dry run.
+            if (cl.hasOption("Y")) {
+                this.dryRun = true;
+            }
+            
+            // Run spreadsheet.
+            if (cl.hasOption("s")) {
+                this.spreadsheetFile = new File(cl.getOptionValue("s"));
+                if (!this.spreadsheetFile.exists()) {
+                    throw new RuntimeException("The run spreadsheet " + this.spreadsheetFile.getPath() + " is inaccessible or does not exist.");
+                }
+            }
+            
+            // Detector name.
+            if (cl.hasOption("d")) {
+                this.detectorName = cl.getOptionValue("d");
+            }
+            
+            // Replace existing run.
+            if (cl.hasOption("x")) {
+                this.replace = true;
+            }
+            
+            // Skip full EVIO processing.
+            if (cl.hasOption("N")) {
+                this.skipEvioProcessing = true;
+            }
+            
+            // Load back run info at end of job.
+            if (cl.hasOption("L")) {
+                this.reload = true;
+            }
+            
+            // Data catalog URL.
+            if (cl.hasOption("u")) {
+                url = cl.getOptionValue("u");
+            }
+            
+            // Site in the data catalog.
+            if (cl.hasOption("S")) {
+                site = cl.getOptionValue("S");
+            }
+            
+            // Set folder for dataset search.
             if (cl.hasOption("f")) {
-                // Enable individual features.
-                for (final String arg : cl.getOptionValues("f")) {
-                    features.add(Feature.valueOf(arg));
-                }
-            } else {
-                // By default all features are enabled.
-                features.addAll(Arrays.asList(Feature.values()));
-            }
-            for (final Feature feature : features) {
-                LOGGER.config("feature " + feature.name() + " is enabled.");
-            }
-
-            // Allow updates to existing runs in the db.
-            if (cl.hasOption("u")) {
-                this.allowUpdates = true;
-                LOGGER.config("updating or replacing existing run data is enabled");
-            }
-
+                folder = cl.getOptionValue("f");
+            }
+            
+            // Initialize the data catalog client.
+            try {
+                datacatClient = new ClientBuilder().setUrl(url).build();
+            } catch (URISyntaxException e) {
+                throw new RuntimeException("Bad datacat URL.", e);
+            }
+            
         } catch (final ParseException e) {
             throw new RuntimeException(e);
         }
@@ -249,90 +212,21 @@
     }
 
     /**
-     * Run the job to update the information in the run database.
+     * Configure the builder from command line options and run the job to update the database.
      */
     private void run() {
-
-        LOGGER.info("starting");
-
-        final boolean runExists = runManager.runExists();
-
-        // Fail if run exists and updates are not allowed.
-        if (runExists && !allowUpdates) {
-            throw new IllegalStateException("The run " + runManager.getRun()
-                    + " already exists and updates are not allowed.");
-        }
-
-        // Get the run number configured from command line.
-        final int run = runManager.getRun();
-
-        // Get the list of EVIO files for the run using a data catalog query.
-        final Map<File, Dataset> fileDatasets = this.getEvioFiles(run);
-        final List<File> files = new ArrayList<File>(fileDatasets.keySet());
-        EvioFileUtilities.sortBySequence(files);
-
-        // Process the run's files to get information.
-        final RunSummaryImpl runSummary = new RunSummaryImpl(run);
-        final RunProcessor runProcessor = this.createEvioRunProcessor(runSummary, files);
-        try {
-            runProcessor.processRun();
-        } catch (final Exception e) {
-            throw new RuntimeException(e);
-        }
-
-        // Set number of files from datacat query.
-        runSummary.setTotalFiles(files.size());
-
-        // Set run start date.
-        this.setStartDate(fileDatasets, files, runSummary);
-
-        // Set run end date.
-        this.setEndDate(fileDatasets, files, runSummary);
-
-        // Delete existing run.
-        if (runExists) {
-            runManager.deleteRun();
-        }
-
-        // Insert run into database.
-        this.insertRun(runManager, runSummary);
-
-        // Close the database connection.
-        runManager.closeConnection();
-
-        LOGGER.info("done");
-    }
-
-    /**
-     * Set the run end date.
-     *
-     * @param fileDatasets the run's datasets
-     * @param files the run's EVIO files
-     * @param runSummary the run summary
-     */
-    private void setEndDate(final Map<File, Dataset> fileDatasets, final List<File> files,
-            final RunSummaryImpl runSummary) {
-        final Dataset lastDataset = fileDatasets.get(files.get(files.size() - 1));
-        final DatasetMetadata metadata = lastDataset.getMetadata();
-        // System.out.println("endTimestamp: " + metadata.getLong("endTimestamp"));
-        final Date endDate = new Date(metadata.getLong("endTimestamp"));
-        // System.out.println("endDate: " + startDate);
-        runSummary.setEndDate(endDate);
-        runSummary.setEndOkay(metadata.getLong("hasEnd") == 0 ? false : true);
-    }
-
-    /**
-     * Set the run start date.
-     *
-     * @param fileDatasets the run's datasets
-     * @param files the run's EVIO files
-     * @param runSummary the run summary
-     */
-    private void setStartDate(final Map<File, Dataset> fileDatasets, final List<File> files,
-            final RunSummaryImpl runSummary) {
-        final Dataset firstDataset = fileDatasets.get(files.get(0));
-        final DatasetMetadata metadata = firstDataset.getMetadata();
-        final Date startDate = new Date(metadata.getLong("startTimestamp"));
-        runSummary.setStartDate(startDate);
-    }
+        new RunDatabaseBuilder()
+            .createRunSummary(run)
+            .setFolder(folder)
+            .setDetectorName(detectorName)
+            .setConnectionParameters(connectionParameters)
+            .setDatacatClient(datacatClient)
+            .setSite(site)
+            .setDryRun(dryRun)
+            .setReplace(replace)
+            .skipEvioProcessing(skipEvioProcessing)
+            .setSpreadsheetFile(spreadsheetFile)
+            .setReload(reload)
+            .run();
+    }        
 }

Modified: java/branches/HPSJAVA-409/run-database/src/main/java/org/hps/run/database/RunManager.java
 =============================================================================
--- java/branches/HPSJAVA-409/run-database/src/main/java/org/hps/run/database/RunManager.java	(original)
+++ java/branches/HPSJAVA-409/run-database/src/main/java/org/hps/run/database/RunManager.java	Wed Apr 27 11:11:32 2016
@@ -6,37 +6,26 @@
 import java.util.logging.Logger;
 
 import org.hps.conditions.database.ConnectionParameters;
+import org.hps.record.daqconfig.DAQConfig;
 import org.hps.record.epics.EpicsData;
 import org.hps.record.scalers.ScalerData;
-import org.hps.record.triggerbank.TriggerConfig;
+import org.hps.record.svt.SvtConfigData;
+import org.hps.record.triggerbank.TriggerConfigData;
 import org.lcsim.conditions.ConditionsEvent;
 import org.lcsim.conditions.ConditionsListener;
 
 /**
- * Manages read-only access to the run database and creates a {@link RunSummary} for a specific run.
+ * Manages access to the run database.
  *
  * @author Jeremy McCormick, SLAC
  */
 public final class RunManager implements ConditionsListener {
 
     /**
-     * Simple class for caching data.
-     */
-    private class DataCache {
-
-        List<EpicsData> epicsData;
-        RunSummary fullRunSummary;
-        Boolean runExists;
-        RunSummary runSummary;
-        List<ScalerData> scalerData;
-        TriggerConfig triggerConfig;
-    }
-
-    /**
      * The default connection parameters for read-only access to the run database.
      */
     private static ConnectionParameters DEFAULT_CONNECTION_PARAMETERS = new ConnectionParameters("hpsuser",
-            "darkphoton", "hps_run_db", "hpsdb.jlab.org");
+            "darkphoton", "hps_run_db_v2", "hpsdb.jlab.org");
 
     /**
      * The singleton instance of the RunManager.
@@ -49,8 +38,7 @@
     private static final Logger LOGGER = Logger.getLogger(RunManager.class.getPackage().getName());
 
     /**
-     * Get the global instance of the {@link RunManager}.
-     *
+     * Get the global instance of the {@link RunManager}.     
      * @return the global instance of the {@link RunManager}
      */
     public static RunManager getRunManager() {
@@ -64,21 +52,11 @@
      * The active database connection.
      */
     private Connection connection;
-
-    /**
-     * The database connection parameters, initially set to the default parameters.
-     */
-    private final ConnectionParameters connectionParameters = DEFAULT_CONNECTION_PARAMETERS;
-
-    /**
-     * The data cache of run information.
-     */
-    private DataCache dataCache;
-
+   
     /**
      * Factory for creating database API objects.
      */
-    private final RunDatabaseDaoFactory factory;
+    private final DaoProvider factory;
 
     /**
      * The run number; the -1 value indicates that this has not been set externally yet.
@@ -86,34 +64,28 @@
     private Integer run = null;
 
     /**
+     * Class constructor.     
+     * @param connection the database connection
+     */
+    public RunManager(final Connection connection) {
+        try {
+            if (connection.isClosed()) {
+                throw new RuntimeException("The connection is already closed and cannot be used.");
+            }
+        } catch (SQLException e) {
+            throw new RuntimeException(e);
+        }
+        this.connection = connection;
+        factory = new DaoProvider(this.connection);
+    }
+    
+    /**
      * Class constructor using default connection parameters.
      */
     public RunManager() {
-        this.connection = DEFAULT_CONNECTION_PARAMETERS.createConnection();
-        this.openConnection();
-        factory = new RunDatabaseDaoFactory(this.connection);
-    }
-
-    /**
-     * Class constructor.
-     *
-     * @param connection the database connection
-     */
-    public RunManager(final Connection connection) {
-        this.connection = connection;
-        this.openConnection();
-        factory = new RunDatabaseDaoFactory(this.connection);
-    }
-
-    /**
-     * Check if the run number has been set.
-     */
-    private void checkRunNumber() {
-        if (this.run == null) {
-            throw new IllegalStateException("The run number was not set.");
-        }
-    }
-
+        this(DEFAULT_CONNECTION_PARAMETERS.createConnection());
+    }
+        
     /**
      * Close the database connection.
      */
@@ -129,7 +101,6 @@
 
     /**
      * Load new run information when conditions have changed.
-     *
      * @param conditionsEvent the event with new conditions information
      */
     @Override
@@ -138,21 +109,7 @@
     }
 
     /**
-     * Delete a run from the database.
-     *
-     * @param run the run number
-     */
-    public void deleteRun() {
-        // Create object for updating run info in the database.
-        final RunSummaryDao runSummaryDao = factory.createRunSummaryDao();
-
-        // Delete run from the database.
-        runSummaryDao.deleteFullRun(run);
-    }
-
-    /**
-     * Return the database connection.
-     *
+     * Return the database connection.     
      * @return the database connection
      */
     Connection getConnection() {
@@ -161,186 +118,159 @@
 
     /**
      * Get the EPICS data for the current run.
-     *
      * @param epicsType the type of EPICS data
      * @return the EPICS data for the current run
      */
     public List<EpicsData> getEpicsData(final EpicsType epicsType) {
-        this.checkRunNumber();
-        if (this.dataCache.epicsData == null) {
-            LOGGER.info("loading EPICS data for run " + this.run);
-            this.dataCache.epicsData = factory.createEpicsDataDao().getEpicsData(epicsType, this.run);
-        }
-        return this.dataCache.epicsData;
-    }
-
-    /**
-     * Get the EPICS variables.
-     *
+        return factory.getEpicsDataDao().getEpicsData(epicsType, this.run);
+    }
+
+    /**
+     * Get the list of EPICS variables definitions.     
      * @param epicsType the type of EPICS data
-     * @return the EPICS data for the current run
+     * @return the list of EPICS variable definitions
      */
     public List<EpicsVariable> getEpicsVariables(final EpicsType epicsType) {
-        return factory.createEpicsVariableDao().getEpicsVariables(epicsType);
-    }
-
-    /**
-     * Get the full run summary for the current run including scaler data, etc.
-     *
-     * @return the full run summary for the current run
-     */
-    public RunSummary getFullRunSummary() {
-        this.checkRunNumber();
-        if (this.dataCache.fullRunSummary == null) {
-            this.dataCache.fullRunSummary = factory.createRunSummaryDao().readFullRunSummary(this.run);
-        }
-        return this.dataCache.fullRunSummary;
-    }
-
-    /**
-     * Get the current run number.
-     *
-     * @return the run number
-     */
-    public int getRun() {
-        return run;
-    }
-
-    /**
-     * Get the complete list of run numbers from the database.
-     *
+        return factory.getEpicsVariableDao().getEpicsVariables(epicsType);
+    }
+
+    /**
+     * Get the full list of run numbers from the database.     
      * @return the complete list of run numbers
      */
     public List<Integer> getRuns() {
-        return new RunSummaryDaoImpl(this.connection).getRuns();
-    }
-
-    /**
-     * Get the full list of summaries for all runs in the database without complex data like EPICS records.
-     *
-     * @return the full list of run summaries
-     */
-    public List<RunSummary> getRunSummaries() {
-        return this.factory.createRunSummaryDao().getRunSummaries();
-    }
-
-    /**
-     * Get the run summary for the current run not including its sub-objects like scaler data.
-     *
+        return factory.getRunSummaryDao().getRuns();
+    }
+  
+    /**
+     * Get the run summary for the current run.     
      * @return the run summary for the current run
      */
     public RunSummary getRunSummary() {
-        this.checkRunNumber();
-        if (this.dataCache.runSummary == null) {
-            this.dataCache.runSummary = factory.createRunSummaryDao().getRunSummary(this.run);
-        }
-        return this.dataCache.runSummary;
-    }
-
-    /**
-     * Get the scaler data for the current run.
-     *
+        return factory.getRunSummaryDao().getRunSummary(this.run);
+    }
+
+    /**
+     * Get the scaler data for the current run.     
      * @return the scaler data for the current run
      */
     public List<ScalerData> getScalerData() {
-        this.checkRunNumber();
-        if (this.dataCache.scalerData == null) {
-            LOGGER.info("loading scaler data for run " + this.run);
-            this.dataCache.scalerData = factory.createScalerDataDao().getScalerData(run);
-        }
-        return this.dataCache.scalerData;
-    }
-
-    /**
-     * Get the trigger config for the current run.
-     *
-     * @return the trigger config for the current run
-     */
-    public TriggerConfig getTriggerConfig() {
-        this.checkRunNumber();
-        if (this.dataCache.triggerConfig == null) {
-            LOGGER.info("loading trigger config for run " + this.run);
-            this.dataCache.triggerConfig = factory.createTriggerConfigDao().getTriggerConfig(run);
-        }
-        return this.dataCache.triggerConfig;
-    }
-
-    /**
-     * Update the database with information found from crawling the files.
-     *
-     * @param runs the list of runs to update
-     * @throws SQLException if there is a database query error
-     */
-    public void insertRun(final RunSummary runSummary) throws SQLException {
-        LOGGER.info("updating run database for run " + runSummary.getRun());
-
-        // Create object for updating run info in the database.
-        final RunSummaryDao runSummaryDao = factory.createRunSummaryDao();
-
-        // Insert run summary into database.
-        runSummaryDao.insertFullRunSummary(runSummary);
-
-        LOGGER.info("done updating run database");
-    }
-
-    /**
-     * Open a new database connection from the connection parameters if the current one is closed or <code>null</code>.
-     * <p>
-     * This method does nothing if the connection is already open.
-     */
-    public void openConnection() {
-        try {
-            if (this.connection.isClosed()) {
-                LOGGER.info("creating new database connection");
-                this.connection = connectionParameters.createConnection();
-            } 
-        } catch (final SQLException e) {
-            throw new RuntimeException("Error opening database connection.", e);
-        }
-    }
+        return factory.getScalerDataDao().getScalerData(this.run);
+    }
+    
+    /**
+     * Get SVT configuration data.     
+     * @return the SVT configuration data
+     */
+    public List<SvtConfigData> getSvtConfigData() {
+        return factory.getSvtConfigDao().getSvtConfigs(this.run);
+    }
+    
+    /**
+     * Get the DAQ (trigger) configuration for the run.
+     * @return the DAQ configuration for the run
+     */
+    public DAQConfig getDAQConfig() {
+        TriggerConfigData config = factory.getTriggerConfigDao().getTriggerConfig(this.run);
+        return config.loadDAQConfig(this.run);
+    }   
 
     /**
      * Return <code>true</code> if the run exists in the database.
-     *
      * @return <code>true</code> if the run exists in the database
      */
-    public boolean runExists() {
-        this.checkRunNumber();
-        if (this.dataCache.runExists == null) {
-            this.dataCache.runExists = factory.createRunSummaryDao().runSummaryExists(this.run);
-        }
-        return this.dataCache.runExists;
-    }
-
-    /**
-     * Return <code>true</code> if the run exists in the database.
-     *
+    public boolean runExists() {      
+        return factory.getRunSummaryDao().runSummaryExists(this.run);
+    }
+
+    /**
+     * Set the run number and then load the applicable {@link RunSummary} from the database.
      * @param run the run number
-     * @return <code>true</code> if the run exists in the database
-     */
-    boolean runExists(final int run) {
-        if (this.dataCache.runExists == null) {
-            this.dataCache.runExists = factory.createRunSummaryDao().runSummaryExists(run);
-        }
-        return this.dataCache.runExists;
-    }
-
-    /**
-     * Set the run number and then load the applicable {@link RunSummary} from the database.
-     *
-     * @param run the run number
      */
     public void setRun(final int run) {
-
         if (this.run == null || run != this.run) {
-
-            LOGGER.info("setting new run " + run);
-
+            LOGGER.info("setting run " + run);
             // Set the run number.
             this.run = run;
-
-            // Reset the data cache.
-            this.dataCache = new DataCache();
-        }
-    }
+        }
+    }
+    
+    /**
+     * Get the currently active run number or <code>null</code>.
+     * @return the currently active run number of <code>null</code>
+     */
+    public Integer getRun() {
+        return this.run;
+    }
+    
+    /**
+     * Create or replace a run summary in the database.
+     * @param runSummary the run summary to update
+     * @param replaceExisting <code>true</code> to allow an existing run summary to be replaced
+     */
+    void updateRunSummary(RunSummary runSummary, boolean replaceExisting) {
+        final RunSummaryDao runSummaryDao = factory.getRunSummaryDao();
+        RunManager runManager = new RunManager();
+        runManager.setRun(runSummary.getRun());
+        if (runManager.runExists()) {
+            if (replaceExisting) {
+                runSummaryDao.updateRunSummary(runSummary);
+            } else {
+                throw new RuntimeException("Run already exists and replacement is not allowed.");
+            }
+        } else {
+            runSummaryDao.insertRunSummary(runSummary);
+        }                
+    }
+    
+    /**
+     * Create or replace the trigger config for the run.
+     * @param triggerConfig the trigger config
+     * @param replaceExisting <code>true</code> to allow an existing trigger to be replaced
+     */
+    void updateTriggerConfig(TriggerConfigData triggerConfig, boolean replaceExisting) {
+        final TriggerConfigDao configDao = factory.getTriggerConfigDao();
+        if (configDao.getTriggerConfig(run) != null) {
+            if (replaceExisting) {
+                configDao.deleteTriggerConfig(run);
+            } else {
+                throw new RuntimeException("Run already exists and replacement is not allowed.");
+            }
+        }
+        configDao.insertTriggerConfig(triggerConfig, run);
+    }
+    
+    /**
+     * Create or replace EPICS data for the run.
+     * @param epicsData the EPICS data
+     */
+    void updateEpicsData(List<EpicsData> epicsData) {
+        if (epicsData != null && !epicsData.isEmpty()) {
+            factory.getEpicsDataDao().insertEpicsData(epicsData, this.run);
+        }
+    }
+    
+    /**
+     * Create or replace scaler data for the run.
+     * @param scalerData the scaler data
+     */
+    void updateScalerData(List<ScalerData> scalerData) {
+        if (scalerData != null) {
+            factory.getScalerDataDao().insertScalerData(scalerData, this.run);
+        } 
+    }     
+    
+    /**
+     * Delete a run from the database.
+     * @param run the run number
+     */
+    void deleteRun() {        
+        factory.getEpicsDataDao().deleteEpicsData(EpicsType.EPICS_2S, run);
+        factory.getEpicsDataDao().deleteEpicsData(EpicsType.EPICS_20S, run);
+        factory.getScalerDataDao().deleteScalerData(run);
+        factory.getSvtConfigDao().deleteSvtConfigs(run);
+        factory.getTriggerConfigDao().deleteTriggerConfig(run);
+        factory.getRunSummaryDao().deleteRunSummary(run);
+    }
+    
 }

Modified: java/branches/HPSJAVA-409/run-database/src/main/java/org/hps/run/database/RunSummary.java
 =============================================================================
--- java/branches/HPSJAVA-409/run-database/src/main/java/org/hps/run/database/RunSummary.java	(original)
+++ java/branches/HPSJAVA-409/run-database/src/main/java/org/hps/run/database/RunSummary.java	Wed Apr 27 11:11:32 2016
@@ -1,137 +1,129 @@
 package org.hps.run.database;
 
-import java.io.File;
 import java.util.Date;
-import java.util.List;
-
-import org.hps.datacat.client.DatasetFileFormat;
-import org.hps.record.epics.EpicsData;
-import org.hps.record.scalers.ScalerData;
-import org.hps.record.triggerbank.TriggerConfig;
 
 /**
- * This is an API for accessing run summary information which is persisted as a row in the <i>runs</i> table of the run
- * database.
+ * This is an API for accessing run summary information which is persisted as a row in the <i>run_summaries</i> table.
  * <p>
- * This information includes:
- * <ul>
- * <li>run number</li>
- * <li>start date</li>
- * <li>end date</li>
- * <li>number of events</li>
- * <li>number of EVIO files</li>
- * <li>whether the END event was found indicating that the DAQ did not crash</li>
- * <li>whether the run is considered good (all <code>true</code> for now)</li>
- * </ul>
- * <p>
- * It also references several complex objects including lists of {@link org.hps.record.epics.EpicsData} and
- * {@link org.hps.record.scalers.ScalerData} for the run, as well as a list of EVIO files.
+ * All timestamp fields use the Unix convention (seconds since the epoch).
  *
+ * @author Jeremy McCormick, SLAC
  * @see RunSummaryImpl
  * @see RunSummaryDao
  * @see RunSummaryDaoImpl
  * @see RunManager
- * 
- * @author Jeremy McCormick, SLAC
  */
 public interface RunSummary {
-  
+
     /**
-     * Get the creation date of this run record.
+     * Get the creation date of this record.
      *
-     * @return the creation date of this run record
+     * @return the creation date of this record
      */
     Date getCreated();
 
     /**
-     * Get the end date.
-     *
-     * @return the end date
+     * Get the END event timestamp or the timestamp from the last head bank if END is not present.
+     * 
+     * @return the last event timestamp
      */
-    Date getEndDate();
+    Integer getEndTimestamp();
 
     /**
-     * Return <code>true</code> if END event was found in the data.
-     *
-     * @return <code>true</code> if END event was in the data
+     * Get the GO event timestamp.
+     * 
+     * @return the GO event timestamp
      */
-    boolean getEndOkay();
+    Integer getGoTimestamp();
 
     /**
-     * Get the EPICS data from the run.
-     *
-     * @return the EPICS data from the run
+     * Get the livetime computed from the clock scaler.
+     * 
+     * @return the livetime computed from the clock scaler
      */
-    List<EpicsData> getEpicsData();
+    Double getLivetimeClock();
 
     /**
-     * Get the event rate (effectively the trigger rate) which is the total events divided by the number of seconds in
-     * the run.
-     *
-     * @return the event rate
+     * Get the livetime computed from the FCUP_TDC scaler.
+     * 
+     * @return the livetime computed from the FCUP_TDC scaler
      */
-    double getEventRate();
+    Double getLivetimeFcupTdc();
+
+    /**
+     * Get the livetime computed from the FCUP_TRG scaler.
+     * 
+     * @return the livetime computed from the FCUP_TRG scaler
+     */
+    Double getLivetimeFcupTrg();
+
+    /**
+     * Get the notes for the run (from the run spreadsheet).
+     * 
+     * @return the notes for the run
+     */
+    String getNotes();
+
+    /**
+     * Get the PRESTART event timestamp.
+     * 
+     * @return the PRESTART event timestamp
+     */
+    Integer getPrestartTimestamp();
 
     /**
      * Get the run number.
      *
      * @return the run number
      */
-    int getRun();
+    Integer getRun();
+   
+    /**
+     * Get the target setting for the run (string from run spreadsheet).
+     * 
+     * @return the target setting for the run
+     */
+    String getTarget();
 
     /**
-     * Return <code>true</code> if the run was okay (no major errors or data corruption occurred).
-     *
-     * @return <code>true</code> if the run was okay
+     * Get the TI time offset in ns.
+     * 
+     * @return the TI time offset in ns
      */
-    boolean getRunOkay();
+    Long getTiTimeOffset();
 
     /**
-     * Get the scaler data of this run.
+     * Get the total number of events in the run.
      *
-     * @return the scaler data of this run
+     * @return the total number of events in the run
      */
-    List<ScalerData> getScalerData();
+    Long getTotalEvents();
 
     /**
-     * Get the trigger config int values.
+     * Get the total number of EVIO files in this run.
      *
-     * @return the trigger config int values
+     * @return the total number of files in this run
      */
-    TriggerConfig getTriggerConfig();
+    Integer getTotalFiles();
 
     /**
-     * Get the start date.
-     *
-     * @return the start date
+     * Get the trigger config name (from the run spreadsheet).
+     * 
+     * @return the trigger config name
      */
-    Date getStartDate();
+    String getTriggerConfigName();
 
     /**
-     * Get the total events in the run.
-     *
-     * @return the total events in the run
+     * Get the trigger rate in KHz.
+     * 
+     * @return the trigger rate in KHz
      */
-    int getTotalEvents();
+    Double getTriggerRate();
 
     /**
-     * Get the total number of EVIO files for this run.
+     * Get the date when this record was last updated.
      *
-     * @return the total number of files for this run
-     */
-    int getTotalFiles();
-
-    /**
-     * Get the number of seconds in the run which is the difference between the start and end times.
-     *
-     * @return the total seconds in the run
-     */
-    long getTotalSeconds();
-
-    /**
-     * Get the date when this run record was last updated.
-     *
-     * @return the date when this run record was last updated
+     * @return the date when this record was last updated
      */
     Date getUpdated();
 }

Modified: java/branches/HPSJAVA-409/run-database/src/main/java/org/hps/run/database/RunSummaryDao.java
 =============================================================================
--- java/branches/HPSJAVA-409/run-database/src/main/java/org/hps/run/database/RunSummaryDao.java	(original)
+++ java/branches/HPSJAVA-409/run-database/src/main/java/org/hps/run/database/RunSummaryDao.java	Wed Apr 27 11:11:32 2016
@@ -8,14 +8,7 @@
  * @author Jeremy McCormick, SLAC
  */
 interface RunSummaryDao {
-
-    /**
-     * Delete a run summary from the database including its referenced objects such as EPICS data.
-     *
-     * @param runSummary the run summary to delete
-     */
-    void deleteFullRun(int run);
-
+  
     /**
      * Delete a run summary by run number.
      *
@@ -24,26 +17,12 @@
     void deleteRunSummary(int run);
 
     /**
-     * Delete a run summary but not its objects.
-     *
-     * @param runSummary the run summary object
-     */
-    void deleteRunSummary(RunSummary runSummary);
-
-    /**
      * Get the list of run numbers.
      *
      * @return the list of run numbers
      */
     List<Integer> getRuns();
-
-    /**
-     * Get a list of run summaries without loading their objects such as EPICS data.
-     *
-     * @return the list of run summaries
-     */
-    List<RunSummary> getRunSummaries();
-
+  
     /**
      * Get a run summary by run number without loading object state.
      *
@@ -51,36 +30,13 @@
      * @return the run summary object
      */
     RunSummary getRunSummary(int run);
-
+  
     /**
-     * Insert a list of run summaries along with its referenced objects such as scaler and EPICS data.
-     *
-     * @param runSummaryList the list of run summaries
-     * @param deleteExisting <code>true</code> to allow deletion and replacement of existing run summaries
-     */
-    void insertFullRunSummaries(List<RunSummary> runSummaryList, boolean deleteExisting);
-
-    /**
-     * Insert a run summary including all its objects.
-     *
-     * @param runSummary the run summary object
-     */
-    void insertFullRunSummary(RunSummary runSummary);
-
-    /**
-     * Insert a run summary but not its objects.
+     * Insert a run summary.
      *
      * @param runSummary the run summary object
      */
     void insertRunSummary(RunSummary runSummary);
-
-    /**
-     * Read a run summary and its objects such as scaler data.
-     *
-     * @param run the run number
-     * @return the full run summary
-     */
-    RunSummary readFullRunSummary(int run);
 
     /**
      * Return <code>true</code> if a run summary exists in the database.
@@ -89,10 +45,10 @@
      * @return <code>true</code> if <code>run</code> exists in the database
      */
     boolean runSummaryExists(int run);
-
+    
     /**
-     * Update a run summary but not its objects.
-     *
+     * Update a run summary that already exists.
+     * 
      * @param runSummary the run summary to update
      */
     void updateRunSummary(RunSummary runSummary);

Modified: java/branches/HPSJAVA-409/run-database/src/main/java/org/hps/run/database/RunSummaryDaoImpl.java
 =============================================================================
--- java/branches/HPSJAVA-409/run-database/src/main/java/org/hps/run/database/RunSummaryDaoImpl.java	(original)
+++ java/branches/HPSJAVA-409/run-database/src/main/java/org/hps/run/database/RunSummaryDaoImpl.java	Wed Apr 27 11:11:32 2016
@@ -5,13 +5,8 @@
 import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.GregorianCalendar;
 import java.util.List;
-import java.util.TimeZone;
 import java.util.logging.Logger;
-
-import org.hps.record.epics.EpicsData;
 
 /**
  * Implementation of database operations for {@link RunSummary} objects in the run database.
@@ -21,37 +16,29 @@
 final class RunSummaryDaoImpl implements RunSummaryDao {
 
     /**
-     * SQL query strings.
-     */
-    private static final class RunSummaryQuery {
-
-        /**
-         * Delete by run number.
-         */
-        private static final String DELETE_RUN = "DELETE FROM runs WHERE run = ?";
-        /**
-         * Insert a record for a run.
-         */
-        private static final String INSERT = "INSERT INTO runs (run, start_date, end_date, nevents, nfiles, end_ok, created) VALUES(?, ?, ?, ?, ?, ?, NOW())";
-        /**
-         * Select all records.
-         */
-        private static final String SELECT_ALL = "SELECT * from runs";
-        /**
-         * Select record by run number.
-         */
-        private static final String SELECT_RUN = "SELECT run, start_date, end_date, nevents, nfiles, end_ok, run_ok, updated, created FROM runs WHERE run = ?";
-        /**
-         * Update information for a run.
-         */
-        private static final String UPDATE_RUN = "UPDATE runs SET start_date, end_date, nevents, nfiles, end_ok, run_ok WHERE run = ?";
-    }
-
-    /**
-     * Eastern time zone.
-     */
-    private static Calendar CALENDAR = new GregorianCalendar(TimeZone.getTimeZone("America/New_York"));
-
+     * Delete by run number.
+     */
+    private static final String DELETE = "DELETE FROM run_summaries WHERE run = ?";
+        
+    /**
+     * Insert a record for a run.
+     */
+    private static final String INSERT = "INSERT INTO run_summaries (run, nevents, nfiles, prestart_timestamp,"
+            + " go_timestamp, end_timestamp, trigger_rate, trigger_config_name, ti_time_offset," 
+            + " livetime_clock, livetime_fcup_tdc, livetime_fcup_trg, target, notes, created, updated)"
+            + " VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NOW(), NOW())";
+    
+    private static final String UPDATE = "UPDATE run_summaries SET nevents = ?, nfiles = ?, prestart_timestamp = ?,"
+            + " go_timestamp = ?, end_timestamp = ?, trigger_rate = ?, trigger_config_name = ?, ti_time_offset = ?," 
+            + " livetime_clock = ?, livetime_fcup_tdc = ?, livetime_fcup_trg = ?, target = ?, notes = ?, updated = NOW()"
+            + " WHERE run = ?";
+    
+                     
+    /**
+     * Select record by run number.
+     */
+    private static final String SELECT = "SELECT * FROM run_summaries WHERE run = ?";
+           
     /**
      * Initialize the logger.
      */
@@ -61,60 +48,17 @@
      * The database connection.
      */
     private final Connection connection;
-
-    /**
-     * The database API for EPICS data.
-     */
-    private EpicsDataDao epicsDataDao = null;
-
-    /**
-     * The database API for scaler data.
-     */
-    private ScalerDataDao scalerDataDao = null;
-
-    /**
-     * The database API for integer trigger config.
-     */
-    private TriggerConfigDao triggerConfigIntDao = null;
-
+  
     /**
      * Create a new DAO object for run summary information.
      *
      * @param connection the database connection
      */
     RunSummaryDaoImpl(final Connection connection) {
-        // Set the connection.
         if (connection == null) {
             throw new IllegalArgumentException("The connection is null.");
         }
         this.connection = connection;
-
-        // Setup DAO API objects for managing complex object state.
-        epicsDataDao = new EpicsDataDaoImpl(this.connection);
-        scalerDataDao = new ScalerDataDaoImpl(this.connection);
-        triggerConfigIntDao = new TriggerConfigDaoImpl(this.connection);
-    }
-
-    /**
-     * Delete a run from the database including its referenced objects such as EPICS data.
-     *
-     * @param runSummary the run summary to delete
-     */
-    @Override
-    public void deleteFullRun(int run) {
-
-        // Delete EPICS log.
-        this.epicsDataDao.deleteEpicsData(EpicsType.EPICS_1S, run);
-        this.epicsDataDao.deleteEpicsData(EpicsType.EPICS_10S, run);
-
-        // Delete scaler data.
-        this.scalerDataDao.deleteScalerData(run);
-
-        // Delete trigger config.
-        this.triggerConfigIntDao.deleteTriggerConfigInt(run);
-
-        // Finally delete the run summary information.
-        this.deleteRunSummary(run);
     }
 
     /**
@@ -126,7 +70,7 @@
     public void deleteRunSummary(final int run) {
         PreparedStatement preparedStatement = null;
         try {
-            preparedStatement = connection.prepareStatement(RunSummaryQuery.DELETE_RUN);
+            preparedStatement = connection.prepareStatement(DELETE);
             preparedStatement.setInt(1, run);
             preparedStatement.executeUpdate();
         } catch (final SQLException e) {
@@ -141,32 +85,7 @@
             }
         }
     }
-
-    /**
-     * Delete a run summary but not its objects.
-     *
-     * @param runSummary the run summary object
-     */
-    @Override
-    public void deleteRunSummary(final RunSummary runSummary) {
-        PreparedStatement preparedStatement = null;
-        try {
-            preparedStatement = connection.prepareStatement(RunSummaryQuery.DELETE_RUN);
-            preparedStatement.setInt(1, runSummary.getRun());
-            preparedStatement.executeUpdate();
-        } catch (final SQLException e) {
-            throw new RuntimeException(e);
-        } finally {
-            if (preparedStatement != null) {
-                try {
-                    preparedStatement.close();
-                } catch (final SQLException e) {
-                    e.printStackTrace();
-                }
-            }
-        }
-    }
-
+   
     /**
      * Get the list of run numbers.
      *
@@ -177,7 +96,7 @@
         final List<Integer> runs = new ArrayList<Integer>();
         PreparedStatement preparedStatement = null;
         try {
-            preparedStatement = this.connection.prepareStatement("SELECT distinct(run) FROM runs ORDER BY run");
+            preparedStatement = this.connection.prepareStatement("SELECT distinct(run) FROM run_summaries ORDER BY run");
             final ResultSet resultSet = preparedStatement.executeQuery();
             while (resultSet.next()) {
                 final Integer run = resultSet.getInt(1);
@@ -196,47 +115,9 @@
         }
         return runs;
     }
-
-    /**
-     * Get a list of run summaries without loading their objects such as EPICS data.
-     *
-     * @return the list of run summaries
-     */
-    @Override
-    public List<RunSummary> getRunSummaries() {
-        PreparedStatement statement = null;
-        final List<RunSummary> runSummaries = new ArrayList<RunSummary>();
-        try {
-            statement = this.connection.prepareStatement(RunSummaryQuery.SELECT_ALL);
-            final ResultSet resultSet = statement.executeQuery();
-            while (resultSet.next()) {
-                final RunSummaryImpl runSummary = new RunSummaryImpl(resultSet.getInt("run"));
-                runSummary.setStartDate(resultSet.getTimestamp("start_date"));
-                runSummary.setEndDate(resultSet.getTimestamp("end_date"));
-                runSummary.setTotalEvents(resultSet.getInt("nevents"));
-                runSummary.setTotalFiles(resultSet.getInt("nfiles"));
-                runSummary.setEndOkay(resultSet.getBoolean("end_ok"));
-                runSummary.setRunOkay(resultSet.getBoolean("run_ok"));
-                runSummary.setUpdated(resultSet.getTimestamp("updated"));
-                runSummary.setCreated(resultSet.getTimestamp("created"));
-                runSummaries.add(runSummary);
-            }
-        } catch (final SQLException e) {
-            throw new RuntimeException(e);
-        } finally {
-            if (statement != null) {
-                try {
-                    statement.close();
-                } catch (final SQLException e) {
-                    e.printStackTrace();
-                }
-            }
-        }
-        return runSummaries;
-    }
-
-    /**
-     * Get a run summary by run number without loading object state.
+   
+    /**
+     * Get a run summary.
      *
      * @param run the run number
      * @return the run summary object
@@ -246,22 +127,28 @@
         PreparedStatement statement = null;
         RunSummaryImpl runSummary = null;
         try {
-            statement = this.connection.prepareStatement(RunSummaryQuery.SELECT_RUN);
+            statement = this.connection.prepareStatement(SELECT);
             statement.setInt(1, run);
             final ResultSet resultSet = statement.executeQuery();
             if (!resultSet.next()) {
-                throw new IllegalArgumentException("No record exists for run " + run + " in database.");
-            }
-
+                throw new IllegalArgumentException("Run " + run + " does not exist in database.");
+            }
             runSummary = new RunSummaryImpl(run);
-            runSummary.setStartDate(resultSet.getTimestamp("start_date"));
-            runSummary.setEndDate(resultSet.getTimestamp("end_date"));
-            runSummary.setTotalEvents(resultSet.getInt("nevents"));
+            runSummary.setTotalEvents(resultSet.getLong("nevents"));
             runSummary.setTotalFiles(resultSet.getInt("nfiles"));
-            runSummary.setEndOkay(resultSet.getBoolean("end_ok"));
-            runSummary.setRunOkay(resultSet.getBoolean("run_ok"));
+            runSummary.setPrestartTimestamp(resultSet.getInt("prestart_timestamp"));
+            runSummary.setGoTimestamp(resultSet.getInt("go_timestamp"));
+            runSummary.setEndTimestamp(resultSet.getInt("end_timestamp"));
+            runSummary.setTriggerRate(resultSet.getDouble("trigger_rate"));
+            runSummary.setTriggerConfigName(resultSet.getString("trigger_config_name"));
+            runSummary.setTiTimeOffset(resultSet.getLong("ti_time_offset"));
+            runSummary.setLivetimeClock(resultSet.getDouble("livetime_clock"));
+            runSummary.setLivetimeFcupTdc(resultSet.getDouble("livetime_fcup_tdc"));
+            runSummary.setLivetimeFcupTrg(resultSet.getDouble("livetime_fcup_trg"));
+            runSummary.setTarget(resultSet.getString("target"));
+            runSummary.setNotes(resultSet.getString("notes"));
+            runSummary.setCreated(resultSet.getTimestamp("created"));
             runSummary.setUpdated(resultSet.getTimestamp("updated"));
-            runSummary.setCreated(resultSet.getTimestamp("created"));
         } catch (final SQLException e) {
             throw new RuntimeException(e);
         } finally {
@@ -275,129 +162,9 @@
         }
         return runSummary;
     }
-
-    /**
-     * Insert a list of run summaries along with their complex state such as referenced scaler and EPICS data.
-     *
-     * @param runSummaryList the list of run summaries
-     * @param deleteExisting <code>true</code> to allow deletion and replacement of existing run summaries
-     */
-    @Override
-    public void insertFullRunSummaries(final List<RunSummary> runSummaryList, final boolean deleteExisting) {
-
-        if (runSummaryList == null) {
-            throw new IllegalArgumentException("The run summary list is null.");
-        }
-        if (runSummaryList.isEmpty()) {
-            throw new IllegalArgumentException("The run summary list is empty.");
-        }
-
-        LOGGER.info("inserting " + runSummaryList.size() + " run summaries into database");
-
-        // Turn off auto commit.
-        try {
-            LOGGER.info("turning off auto commit");
-            this.connection.setAutoCommit(false);
-        } catch (final SQLException e) {
-            throw new RuntimeException(e);
-        }
-
-        // Loop over all runs found while crawling.
-        for (final RunSummary runSummary : runSummaryList) {
-
-            final int run = runSummary.getRun();
-
-            LOGGER.info("inserting run summary for run " + run + " into database");
-
-            // Does the run exist in the database already?
-            if (this.runSummaryExists(run)) {
-                // Is deleting existing rows allowed?
-                if (deleteExisting) {
-                    LOGGER.info("deleting existing run summary");
-                    // Delete the existing rows.
-                    this.deleteFullRun(runSummary.getRun());
-                } else {
-                    // Rows exist but updating is disallowed which is a fatal error.
-                    throw new IllegalStateException("Run " + runSummary.getRun()
-                            + " already exists and updates are disallowed.");
-                }
-            }
-
-            // Insert full run summary information including sub-objects.
-            LOGGER.info("inserting run summary");
-            this.insertFullRunSummary(runSummary);
-            LOGGER.info("run summary for " + run + " inserted successfully");
-
-            try {
-                // Commit the transaction for the run.
-                LOGGER.info("committing transaction");
-                this.connection.commit();
-            } catch (final SQLException e1) {
-                try {
-                    LOGGER.severe("rolling back transaction");
-                    // Rollback the transaction if there was an error.
-                    this.connection.rollback();
-                } catch (final SQLException e2) {
-                    throw new RuntimeException(e2);
-                }
-            }
-
-            LOGGER.info("done inserting run summary " + run);
-        }
-
-        try {
-            LOGGER.info("turning auto commit on");
-            // Turn auto commit back on.
-            this.connection.setAutoCommit(true);
-        } catch (final SQLException e) {
-            e.printStackTrace();
-        }
-
-        LOGGER.info("done inserting run summaries");
-    }
-
-    /**
-     * Insert a run summary including all its objects.
-     *
-     * @param runSummary the run summary object to insert
-     */
-    @Override
-    public void insertFullRunSummary(final RunSummary runSummary) {
-
-        if (runSummary == null) {
-            throw new IllegalArgumentException("The run summary is null.");
-        }
-        
-        // Insert basic run log info.
-        this.insertRunSummary(runSummary);
-
-        // Insert EPICS data.
-        if (runSummary.getEpicsData() != null && !runSummary.getEpicsData().isEmpty()) {
-            LOGGER.info("inserting " + runSummary.getEpicsData().size() + " EPICS records");
-            epicsDataDao.insertEpicsData(runSummary.getEpicsData());
-        } else {
-            LOGGER.warning("no EPICS data to insert");
-        }
-
-        // Insert scaler data.
-        if (runSummary.getScalerData() != null && !runSummary.getScalerData().isEmpty()) {
-            LOGGER.info("inserting " + runSummary.getScalerData().size() + " scaler data records");
-            scalerDataDao.insertScalerData(runSummary.getScalerData(), runSummary.getRun());
-        } else {
-            LOGGER.warning("no scaler data to insert");
-        }
-
-        // Insert trigger config.
-        if (runSummary.getTriggerConfig() != null && !runSummary.getTriggerConfig().isEmpty()) {
-            LOGGER.info("inserting " + runSummary.getTriggerConfig().size() + " trigger config variables");
-            triggerConfigIntDao.insertTriggerConfig(runSummary.getTriggerConfig(), runSummary.getRun());
-        } else {
-            LOGGER.warning("no trigger config to insert");
-        }
-    }
-
-    /**
-     * Insert a run summary but not its objects.
+      
+    /**
+     * Insert a run summary.
      *
      * @param runSummary the run summary object
      */
@@ -405,13 +172,23 @@
     public void insertRunSummary(final RunSummary runSummary) {
         PreparedStatement preparedStatement = null;
         try {
-            preparedStatement = connection.prepareStatement(RunSummaryQuery.INSERT);
+            preparedStatement = connection.prepareStatement(INSERT);                       
             preparedStatement.setInt(1, runSummary.getRun());
-            preparedStatement.setTimestamp(2, new java.sql.Timestamp(runSummary.getStartDate().getTime()), CALENDAR);
-            preparedStatement.setTimestamp(3, new java.sql.Timestamp(runSummary.getEndDate().getTime()), CALENDAR);
-            preparedStatement.setInt(4, runSummary.getTotalEvents());
-            preparedStatement.setInt(5, runSummary.getTotalFiles());
-            preparedStatement.setBoolean(6, runSummary.getEndOkay());
+            preparedStatement.setLong(2, runSummary.getTotalEvents());
+            preparedStatement.setInt(3, runSummary.getTotalFiles());
+            /* Use setObject on the rest as they may be null. */
+            preparedStatement.setObject(4, runSummary.getPrestartTimestamp());
+            preparedStatement.setObject(5, runSummary.getGoTimestamp());
+            preparedStatement.setObject(6, runSummary.getEndTimestamp());
+            preparedStatement.setObject(7, runSummary.getTriggerRate());
+            preparedStatement.setObject(8, runSummary.getTriggerConfigName());
+            preparedStatement.setObject(9, runSummary.getTiTimeOffset());
+            preparedStatement.setObject(10, runSummary.getLivetimeClock());
+            preparedStatement.setObject(11, runSummary.getLivetimeFcupTdc());
+            preparedStatement.setObject(12, runSummary.getLivetimeFcupTrg());
+            preparedStatement.setObject(13, runSummary.getTarget());
+            preparedStatement.setObject(14, runSummary.getNotes());
+            LOGGER.fine(preparedStatement.toString());
             preparedStatement.executeUpdate();
         } catch (final SQLException e) {
             throw new RuntimeException(e);
@@ -425,34 +202,42 @@
             }
         }
     }
-
-    /**
-     * Read a run summary and its objects such as scaler data.
-     *
-     * @param run the run number
-     * @return the full run summary
-     */
-    @Override
-    public RunSummary readFullRunSummary(final int run) {
-
-        // Read main run summary but not referenced objects.
-        final RunSummaryImpl runSummary = (RunSummaryImpl) this.getRunSummary(run);
-
-        // Read EPICS data and set on RunSummary.
-        final List<EpicsData> epicsDataList = new ArrayList<EpicsData>();
-        epicsDataList.addAll(epicsDataDao.getEpicsData(EpicsType.EPICS_1S, run));
-        epicsDataList.addAll(epicsDataDao.getEpicsData(EpicsType.EPICS_10S, run));
-        runSummary.setEpicsData(epicsDataList);
-
-        // Read scaler data and set on RunSummary.
-        runSummary.setScalerData(scalerDataDao.getScalerData(run));
-
-        // Read trigger config.
-        runSummary.setTriggerConfig(triggerConfigIntDao.getTriggerConfig(run));
-
-        return runSummary;
-    }
-
+    
+    @Override
+    public void updateRunSummary(RunSummary runSummary) {
+        PreparedStatement preparedStatement = null;
+        try {
+            preparedStatement = connection.prepareStatement(UPDATE);                                   
+            preparedStatement.setLong(1, runSummary.getTotalEvents());
+            preparedStatement.setInt(2, runSummary.getTotalFiles());
+            preparedStatement.setObject(3, runSummary.getPrestartTimestamp());
+            preparedStatement.setObject(4, runSummary.getGoTimestamp());
+            preparedStatement.setObject(5, runSummary.getEndTimestamp());
+            preparedStatement.setObject(6, runSummary.getTriggerRate());
+            preparedStatement.setObject(7, runSummary.getTriggerConfigName());
+            preparedStatement.setObject(8, runSummary.getTiTimeOffset());
+            preparedStatement.setObject(9, runSummary.getLivetimeClock());
+            preparedStatement.setObject(10, runSummary.getLivetimeFcupTdc());
+            preparedStatement.setObject(11, runSummary.getLivetimeFcupTrg());
+            preparedStatement.setObject(12, runSummary.getTarget());
+            preparedStatement.setObject(13, runSummary.getNotes());
+            preparedStatement.setInt(14, runSummary.getRun());
+            LOGGER.fine(preparedStatement.toString());
+            preparedStatement.executeUpdate();
+        } catch (final SQLException e) {
+            throw new RuntimeException(e);
+        } finally {
+            if (preparedStatement != null) {
+                try {
+                    preparedStatement.close();
+                } catch (final SQLException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
+    
+   
     /**
      * Return <code>true</code> if a run summary exists in the database for the run number.
      *
@@ -463,7 +248,7 @@
     public boolean runSummaryExists(final int run) {
         PreparedStatement preparedStatement = null;
         try {
-            preparedStatement = connection.prepareStatement("SELECT run FROM runs where run = ?");
+            preparedStatement = connection.prepareStatement("SELECT run FROM run_summaries where run = ?");
             preparedStatement.setInt(1, run);
             final ResultSet rs = preparedStatement.executeQuery();
             return rs.first();
@@ -479,35 +264,4 @@
             }
         }
     }
-
-    /**
-     * Update a run summary but not its complex state.
-     *
-     * @param runSummary the run summary to update
-     */
-    @Override
-    public void updateRunSummary(final RunSummary runSummary) {
-        PreparedStatement preparedStatement = null;
-        try {
-            preparedStatement = connection.prepareStatement(RunSummaryQuery.UPDATE_RUN);
-            preparedStatement.setTimestamp(1, new java.sql.Timestamp(runSummary.getStartDate().getTime()), CALENDAR);
-            preparedStatement.setTimestamp(2, new java.sql.Timestamp(runSummary.getEndDate().getTime()), CALENDAR);
-            preparedStatement.setInt(3, runSummary.getTotalEvents());
-            preparedStatement.setInt(4, runSummary.getTotalFiles());
-            preparedStatement.setBoolean(5, runSummary.getEndOkay());
-            preparedStatement.setBoolean(6, runSummary.getRunOkay());
-            preparedStatement.setInt(7, runSummary.getRun());
-            preparedStatement.executeUpdate();
-        } catch (final SQLException e) {
-            throw new RuntimeException(e);
-        } finally {
-            if (preparedStatement != null) {
-                try {
-                    preparedStatement.close();
-                } catch (final SQLException e) {
-                    e.printStackTrace();
-                }
-            }
-        }
-    }
 }

Modified: java/branches/HPSJAVA-409/run-database/src/main/java/org/hps/run/database/RunSummaryImpl.java
 =============================================================================
--- java/branches/HPSJAVA-409/run-database/src/main/java/org/hps/run/database/RunSummaryImpl.java	(original)
+++ java/branches/HPSJAVA-409/run-database/src/main/java/org/hps/run/database/RunSummaryImpl.java	Wed Apr 27 11:11:32 2016
@@ -1,40 +1,13 @@
 package org.hps.run.database;
 
-import java.io.File;
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
 import java.util.Date;
-import java.util.GregorianCalendar;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.TimeZone;
-
-import org.hps.datacat.client.DatasetFileFormat;
-import org.hps.record.epics.EpicsData;
-import org.hps.record.scalers.ScalerData;
-import org.hps.record.triggerbank.TriggerConfig;
 
 /**
  * Implementation of {@link RunSummary} for retrieving information from the run database.
  *
  * @author Jeremy McCormick, SLAC
  */
-public final class RunSummaryImpl implements RunSummary {
-
-    /**
-     * Default date display format.
-     */
-    private static final DateFormat DATE_DISPLAY = new SimpleDateFormat();
-
-    static {
-        /**
-         * Set default time zone for display to East Coast (JLAB) where data was
-         * taken.
-         */
-        DATE_DISPLAY.setCalendar(new GregorianCalendar(TimeZone.getTimeZone("America/New_York")));
-    }
+final class RunSummaryImpl implements RunSummary {
 
     /**
      * Date this record was created.
@@ -42,60 +15,80 @@
     private Date created;
 
     /**
-     * End date of run.
-     */
-    private Date endDate;
-
-    /**
-     * This is <code>true</code> if the END event is found in the data.
-     */
-    private boolean endOkay;
-
-    /**
-     * The EPICS data from the run.
-     */
-    private List<EpicsData> epicsDataList;
+     * Timestamp of END event.
+     */
+    private Integer endTimestamp;
+
+    /**
+     * Timestamp of GO event.
+     */
+    private Integer goTimestamp;
+
+    /**
+     * Clock livetime calculation.
+     */
+    private Double livetimeClock;
+
+    /**
+     * FCup TDC livetime calculation.
+     */
+    private Double livetimeTdc;
+
+    /**
+     * FCup TRG livetime calculation.
+     */
+    private Double livetimeTrg;
+
+    /**
+     * Notes about the run (from spreadsheet).
+     */
+    private String notes;
+
+    /**
+     * Timestamp of PRESTART event.
+     */
+    private Integer prestartTimestamp;
 
     /**
      * The run number.
      */
-    private final int run;
-
-    /**
-     * Flag to indicate run was okay.
-     */
-    private boolean runOkay = true;
-
-    /**
-     * The scaler data for the run.
-     */
-    private List<ScalerData> scalerDataList;
-
-    /**
-     * The trigger data for the run.
-     */
-    private TriggerConfig triggerConfig;
-
-    /**
-     * Start date of run.
-     */
-    private Date startDate;
+    private final Integer run;
+
+    /**
+     * Target setup (string from run spreadsheet).
+     */
+    private String target;
+
+    /**
+     * TI time offset in ns.
+     */
+    private Long tiTimeOffset;
 
     /**
      * The total events found in the run across all files.
      */
-    private int totalEvents = -1;
+    private Long totalEvents;
 
     /**
      * The total number of files in the run.
      */
-    private int totalFiles = 0;
+    private Integer totalFiles;
+   
+    /**
+     * Name of the trigger config file.
+     */
+    private String triggerConfigName;
+
+    /**
+     * Trigger rate in KHz.
+     */
+    private double triggerRate;
 
     /**
      * Date when the run record was last updated.
      */
     private Date updated;
-    
+
     /**
      * Create a run summary.
      *
@@ -105,209 +98,174 @@
         this.run = run;
     }
 
-    /**
-     * Get the creation date of this run record.
-     *
-     * @return the creation date of this run record
-     */
+    @Override
     public Date getCreated() {
         return this.created;
     }
 
-    /**
-     * Get the end date.
-     *
-     * @return the end date
-     */
-    public Date getEndDate() {
-        return endDate;
-    }
-
-    /**
-     * Return <code>true</code> if END event was found in the data.
-     *
-     * @return <code>true</code> if END event was in the data
-     */
-    public boolean getEndOkay() {
-        return this.endOkay;
-    }
-
-    /**
-     * Get the EPICS data from the run.
-     *
-     * @return the EPICS data from the run
-     */
-    public List<EpicsData> getEpicsData() {
-        return this.epicsDataList;
-    }
-
-    /**
-     * Get the event rate (effectively the trigger rate) which is the total
-     * events divided by the number of seconds in the run.
-     *
-     * @return the event rate
-     */
-    public double getEventRate() {
-        if (this.getTotalEvents() <= 0) {
-            throw new RuntimeException("Total events is zero or invalid.");
-        }
-        return (double) this.getTotalEvents() / (double) this.getTotalSeconds();
-    }
-
-    /**
-     * Get the run number.
-     *
-     * @return the run number
-     */
-    public int getRun() {
+    @Override
+    public Integer getEndTimestamp() {
+        return endTimestamp;
+    }
+
+    @Override
+    public Integer getGoTimestamp() {
+        return goTimestamp;
+    }
+
+    @Override
+    public Double getLivetimeClock() {
+        return this.livetimeClock;
+    }
+
+    @Override
+    public Double getLivetimeFcupTdc() {
+        return this.livetimeTdc;
+    }
+
+    @Override
+    public Double getLivetimeFcupTrg() {
+        return this.livetimeTrg;
+    }
+
+    @Override
+    public String getNotes() {
+        return this.notes;
+    }
+
+    @Override
+    public Integer getPrestartTimestamp() {
+        return prestartTimestamp;
+    }
+
+    @Override
+    public Integer getRun() {
         return this.run;
     }
 
-    /**
-     * Return <code>true</code> if the run was okay (no major errors or data
-     * corruption occurred).
-     *
-     * @return <code>true</code> if the run was okay
-     */
-    public boolean getRunOkay() {
-        return this.runOkay;
-    }
-
-    /**
-     * Get the scaler data of this run.
-     *
-     * @return the scaler data of this run
-     */
-    public List<ScalerData> getScalerData() {
-        return this.scalerDataList;
-    }
-
-    /**
-     * Get the trigger config of this run.
-     *
-     * @return the trigger config of this run
-     */
-    public TriggerConfig getTriggerConfig() {
-        return triggerConfig;
-    }
-
-    /**
-     * Get the start date.
-     *
-     * @return the start date
-     */
-    public Date getStartDate() {
-        return startDate;
-    }
-
-    /**
-     * Get the total events in the run.
-     *
-     * @return the total events in the run
-     */
-    public int getTotalEvents() {
+    @Override
+    public String getTarget() {
+        return this.target;
+    }
+
+    @Override
+    public Long getTiTimeOffset() {
+        return this.tiTimeOffset;
+    }
+
+    @Override
+    public Long getTotalEvents() {
         return this.totalEvents;
     }
 
-    /**
-     * Get the total number of files for this run.
-     *
-     * @return the total number of files for this run
-     */
-    public int getTotalFiles() {
+    @Override
+    public Integer getTotalFiles() {
         return this.totalFiles;
     }
-
-    /**
-     * Get the number of seconds in the run which is the difference between the
-     * start and end times.
-     *
-     * @return the total seconds in the run
-     */
-    public long getTotalSeconds() {
-        return (endDate.getTime() - startDate.getTime()) / 1000;
-    }
-
-    /**
-     * Get the date when this run record was last updated.
-     *
-     * @return the date when this run record was last updated
-     */
+   
+    @Override
+    public String getTriggerConfigName() {
+        return this.triggerConfigName;
+    }
+
+    @Override
+    public Double getTriggerRate() {
+        return this.triggerRate;
+    }
+
+    @Override
     public Date getUpdated() {
         return updated;
     }
-    
-    /**
-     * Set the creation date of the run record.
-     *
-     * @param created the creation date of the run record
-     */
-    void setCreated(final Date created) {
+
+    /**
+     * Set the creation date of the run summary.
+     * 
+     * @param created the creation date
+     */
+    void setCreated(Date created) {
         this.created = created;
     }
 
     /**
-     * Set the start date.
-     *
-     * @param startDate the start date
-     */
-    void setEndDate(final Date endDate) {
-        this.endDate = endDate;
-    }
-
-    /**
-     * Set if end is okay.
-     *
-     * @param endOkay <code>true</code> if end is okay
-     */
-    void setEndOkay(final boolean endOkay) {
-        this.endOkay = endOkay;
-    }
-   
-    /**
-     * Set the EPICS data for the run.
-     *
-     * @param epics the EPICS data for the run
-     */
-    void setEpicsData(final List<EpicsData> epicsDataList) {
-        this.epicsDataList = epicsDataList;
-    }
-    
-    /**
-     * Set whether the run was "okay" meaning the data is usable for physics
-     * analysis.
-     *
-     * @param runOkay <code>true</code> if the run is okay
-     */
-    void setRunOkay(final boolean runOkay) {
-        this.runOkay = runOkay;
-    }
-
-    /**
-     * Set the scaler data of the run.
-     *
-     * @param scalerData the scaler data
-     */
-    void setScalerData(final List<ScalerData> scalerDataList) {
-        this.scalerDataList = scalerDataList;
-    }
-
-    /**
-     * Set the trigger config of the run.
-     *
-     * @param triggerConfig the trigger config
-     */
-    void setTriggerConfig(final TriggerConfig triggerConfig) {
-        this.triggerConfig = triggerConfig;
-    }
-
-    /**
-     * Set the start date.
-     *
-     * @param startDate the start date
-     */
-    void setStartDate(final Date startDate) {
-        this.startDate = startDate;
+     * Set the end timestamp.
+     * 
+     * @param endTimestamp the end timestamp
+     */
+    void setEndTimestamp(Integer endTimestamp) {
+        this.endTimestamp = endTimestamp;
+    }
+
+    /**
+     * Set the GO timestamp.
+     * 
+     * @param goTimestamp the GO timestamp
+     */
+    void setGoTimestamp(Integer goTimestamp) {
+        this.goTimestamp = goTimestamp;
+    }
+
+    /**
+     * Set the clock livetime. 
+     * 
+     * @param livetimeClock the clock livetime
+     */
+    void setLivetimeClock(Double livetimeClock) {
+        this.livetimeClock = livetimeClock;
+    }
+
+    /**
+     * Set the FCUP TDC livetime.
+     * 
+     * @param livetimeTdc the FCUP TDC livetime
+     */
+    void setLivetimeFcupTdc(Double livetimeTdc) {
+        this.livetimeTdc = livetimeTdc;
+    }
+
+    /**
+     * Set the FCUP TRG livetime.
+     * 
+     * @param livetimeTrg the FCUP TRG livetime
+     */
+    void setLivetimeFcupTrg(Double livetimeTrg) {
+        this.livetimeTrg = livetimeTrg;
+    }
+
+    /**
+     * Set the notes.
+     * 
+     * @param notes the notes
+     */
+    void setNotes(String notes) {
+        this.notes = notes;
+    }
+
+    /**
+     * Set the PRESTART timestamp.
+     * 
+     * @param prestartTimestamp the PRESTART timestamp
+     */
+    void setPrestartTimestamp(Integer prestartTimestamp) {
+        this.prestartTimestamp = prestartTimestamp;
+    }
+
+    /**
+     * Set the target description.
+     * 
+     * @param target the target description
+     */
+    void setTarget(String target) {
+        this.target = target;
+    }
+
+    /**
+     * Set the TI time offset in ns.
+     * 
+     * @param tiTimeOffset the TIM time offset in ns
+     */
+    void setTiTimeOffset(Long tiTimeOffset) {
+        this.tiTimeOffset = tiTimeOffset;
     }
 
     /**
@@ -315,7 +273,7 @@
      *
      * @param totalEvents the total number of physics events in the run
      */
-    void setTotalEvents(final int totalEvents) {
+    void setTotalEvents(final Long totalEvents) {
         this.totalEvents = totalEvents;
     }
 
@@ -324,37 +282,59 @@
      *
      * @param totalFiles the total number of EVIO files in the run
      */
-    void setTotalFiles(final int totalFiles) {
+    void setTotalFiles(final Integer totalFiles) {
         this.totalFiles = totalFiles;
     }
 
     /**
-     * Set the date when this run record was last updated.
-     *
-     * @param updated the date when the run record was last updated
-     */
-    void setUpdated(final Date updated) {
+     * Set the trigger config file.
+     * 
+     * @param triggerConfigName the trigger config file
+     */
+    void setTriggerConfigName(String triggerConfigName) {
+        this.triggerConfigName = triggerConfigName;
+    }
+
+    /**
+     * Set the trigger rate in KHz.
+     * 
+     * @param triggerRate the trigger rate in KHz
+     */
+    void setTriggerRate(Double triggerRate) {
+        this.triggerRate = triggerRate;
+    }
+
+    /**
+     * Set the updated date of the summary.
+     * 
+     * @param updated the updated date
+     */
+    void setUpdated(Date updated) {
         this.updated = updated;
     }
-    
-    /**
-     * Convert this object to a string.
-     *
+
+    /**
+     * Convert the object to a string.
+     * 
      * @return this object converted to a string
      */
     @Override
     public String toString() {
         return "RunSummary { " 
                 + "run: " + this.getRun() 
-                + ", startDate: " + (this.getStartDate() != null ? DATE_DISPLAY.format(this.getStartDate()) : null)
-                + ", endDate: " + (this.getEndDate() != null ? DATE_DISPLAY.format(this.getEndDate()) : null) 
-                + ", totalEvents: " + this.getTotalEvents()
-                + ", totalFiles: " + this.getTotalFiles() 
-                + ", endOkay: " + this.getEndOkay() 
-                + ", runOkay: "
-                + this.getRunOkay() 
-                + ", updated: " + this.getUpdated() 
+                + ", events: " + this.getTotalEvents() 
+                + ", files: " + this.getTotalFiles() 
                 + ", created: " + this.getCreated() 
+                + ", updated: " + this.getUpdated()
+                + ", prestartTimestamp: " + this.getPrestartTimestamp()
+                + ", goTimestamp: " + this.getGoTimestamp()
+                + ", endTimestamp: " + this.getEndTimestamp()
+                + ", triggerConfigFile: " + this.getTriggerConfigName()
+                + ", triggerRate: " + this.getTriggerRate()
+                + ", livetimeClock: " + this.getLivetimeClock()
+                + ", livetimeTdc: " + this.getLivetimeFcupTdc()
+                + ", livetimeTrg: " + this.getLivetimeFcupTrg()
+                + ", tiTimeOffset: " + this.getTiTimeOffset() 
                 + " }";
     }
 }

Modified: java/branches/HPSJAVA-409/run-database/src/main/java/org/hps/run/database/ScalerDataDaoImpl.java
 =============================================================================
--- java/branches/HPSJAVA-409/run-database/src/main/java/org/hps/run/database/ScalerDataDaoImpl.java	(original)
+++ java/branches/HPSJAVA-409/run-database/src/main/java/org/hps/run/database/ScalerDataDaoImpl.java	Wed Apr 27 11:11:32 2016
@@ -18,15 +18,9 @@
 final class ScalerDataDaoImpl implements ScalerDataDao {
 
     /**
-     * SQL query strings.
+     * Insert a record.
      */
-    private static final class ScalerDataQuery {
-
-        /**
-         * Insert a record.
-         */
-        private static final String INSERT = createInsertSql();
-    }
+    private static final String INSERT = createInsertSql();    
 
     /**
      * Create insert SQL for scaler data.
@@ -102,7 +96,8 @@
         PreparedStatement selectScalers = null;
         final List<ScalerData> scalerDataList = new ArrayList<ScalerData>();
         try {
-            selectScalers = this.connection.prepareStatement("SELECT * FROM scalers WHERE run = ? ORDER BY event");
+            selectScalers = this.connection.prepareStatement("SELECT * FROM sc"
+                    + "alers WHERE run = ? ORDER BY event");
             selectScalers.setInt(1, run);
             final ResultSet resultSet = selectScalers.executeQuery();
             while (resultSet.next()) {
@@ -139,7 +134,7 @@
     public void insertScalerData(final List<ScalerData> scalerDataList, final int run) {
         PreparedStatement insertScalers = null;
         try {
-            insertScalers = this.connection.prepareStatement(ScalerDataQuery.INSERT);
+            insertScalers = this.connection.prepareStatement(INSERT);
             for (final ScalerData scalerData : scalerDataList) {
                 insertScalers.setInt(1, run);
                 insertScalers.setInt(2, scalerData.getEventId());

Modified: java/branches/HPSJAVA-409/run-database/src/main/java/org/hps/run/database/package-info.java
 =============================================================================
--- java/branches/HPSJAVA-409/run-database/src/main/java/org/hps/run/database/package-info.java	(original)
+++ java/branches/HPSJAVA-409/run-database/src/main/java/org/hps/run/database/package-info.java	Wed Apr 27 11:11:32 2016
@@ -1,4 +1,4 @@
 /**
- * API for accessing the HPS run database.
+ * API for accessing and updating the HPS run database.
  */
 package org.hps.run.database;

Modified: java/branches/HPSJAVA-409/steering-files/pom.xml
 =============================================================================
--- java/branches/HPSJAVA-409/steering-files/pom.xml	(original)
+++ java/branches/HPSJAVA-409/steering-files/pom.xml	Wed Apr 27 11:11:32 2016
@@ -8,7 +8,7 @@
         <groupId>org.hps</groupId>
         <artifactId>hps-parent</artifactId>
         <relativePath>../parent/pom.xml</relativePath>
-        <version>3.4.2-SNAPSHOT</version>
+        <version>3.9-SNAPSHOT</version>
     </parent>
     <scm>
         <url>http://java.freehep.org/svn/repos/hps/list/java/trunk/steering-files/</url>

Modified: java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/analysis/StarterAnalysis.lcsim
 =============================================================================
--- java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/analysis/StarterAnalysis.lcsim	(original)
+++ java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/analysis/StarterAnalysis.lcsim	Wed Apr 27 11:11:32 2016
@@ -20,4 +20,4 @@
         </driver>
     </drivers>
 </lcsim>
-	
+    

Modified: java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/monitoring/EcalLedSequenceMonitoringApp.lcsim
 =============================================================================
--- java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/monitoring/EcalLedSequenceMonitoringApp.lcsim	(original)
+++ java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/monitoring/EcalLedSequenceMonitoringApp.lcsim	Wed Apr 27 11:11:32 2016
@@ -1,9 +1,9 @@
 <lcsim xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" 
        xs:noNamespaceSchemaLocation="http://www.lcsim.org/schemas/lcsim/1.0/lcsim.xsd">         
     <execute>
-    	<driver name="EventMarkerDriver"/>
+        <driver name="EventMarkerDriver"/>
         <driver name="EcalRunningPedestal"/>
-  	    <driver name="EcalRawConverter" />    
+        <driver name="EcalRawConverter" />    
         <driver name="LedAnalysisDriver"/>
         <driver name="EcalEventDisplay" />         <!-- Ecal event display -->
         <driver name="AidaSaveDriver"/>
@@ -48,5 +48,5 @@
         <driver name="AidaSaveDriver" type="org.lcsim.job.AidaSaveDriver">
             <outputFileName>LedSequenceMonitorOut.aida</outputFileName>
         </driver>
-	</drivers>
+    </drivers>
 </lcsim>

Modified: java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/monitoring/EcalLedSequenceStandalone.lcsim
 =============================================================================
--- java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/monitoring/EcalLedSequenceStandalone.lcsim	(original)
+++ java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/monitoring/EcalLedSequenceStandalone.lcsim	Wed Apr 27 11:11:32 2016
@@ -5,8 +5,7 @@
 	        <driver name="EcalRunningPedestal"/>
 	  	    <driver name="EcalRawConverter" />    
 	        <driver name="LedAnalysisDriver"/>
-	   <!-- <driver name="EcalEventDisplay" />    -->     <!-- Ecal event display -->
-	        <driver name="AidaSaveDriver"/>
+	        <driver name="AidaSaveDriver"/>	     
 	    </execute>           
 	    <drivers>    
 	        <driver name="EventMarkerDriver" type="org.lcsim.job.EventMarkerDriver">
@@ -18,13 +17,14 @@
 	        </driver>
 	        <driver name="EcalRawConverter" type="org.hps.recon.ecal.EcalRawConverterDriver">
 	            <ecalCollectionName>EcalCalHits</ecalCollectionName>
-	            <use2014Gain>false</use2014Gain>
 	            <useTimestamps>false</useTimestamps>
 	            <useTruthTime>false</useTruthTime>
 	            <useRunningPedestal>true</useRunningPedestal>
 	            <useTimeWalkCorrection>true</useTimeWalkCorrection>
+	            <nsa>60</nsa>  <!-- these are critical since the defaults in software are 100 - 20, as in prod. runs -->
+       		    <nsb>16</nsb>
 	        </driver>       
-	       <driver name="EcalEventDisplay" type="org.hps.monitoring.ecal.plots.EcalEventDisplay">
+	  <!--     <driver name="EcalEventDisplay" type="org.hps.monitoring.ecal.plots.EcalEventDisplay">
 	            <inputCollection>EcalCalHits</inputCollection>
 	            <inputCollectionRaw>EcalReadoutHits</inputCollectionRaw>
 	            <inputClusterCollection>EcalClusters</inputClusterCollection>
@@ -33,19 +33,21 @@
 	            <minEch>0.005</minEch>
 	            <eventRefreshRate>2</eventRefreshRate>
 	        </driver>
+	        -->
 	        <driver name="LedAnalysisDriver" type="org.hps.monitoring.ecal.plots.EcalLedSequenceMonitor">
 	           <isMonitoringApp>false</isMonitoringApp>
 	           <doFullAnalysis>false</doFullAnalysis>
-	           <skipMin>0.25</skipMin>
+	           <skipMin>0.2</skipMin>
 	           <skipInitial>0.05</skipInitial>    
 	           <useRawEnergy>true</useRawEnergy>
-	           <energyCut>1</energyCut>
+	           <energyCut>2.0</energyCut>
 	           <nEventsMin>300</nEventsMin>
 	           <evnMinDraw>0.</evnMinDraw>
-	           <evnMaxDraw>20000.</evnMaxDraw>
+	           <evnMaxDraw>80000.</evnMaxDraw>
+	           <saveTuple>false</saveTuple>
 	        </driver>
 	        <driver name="AidaSaveDriver" type="org.lcsim.job.AidaSaveDriver">
-	            <outputFileName>${outputFile}</outputFileName>
-	        </driver>
+	            <outputFileName>${outputFile}.LedAnalysis.aida</outputFileName>
+	        </driver>        
 		</drivers>
 	</lcsim>

Modified: java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/monitoring/EcalMonitoringFinal.lcsim
 =============================================================================
--- java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/monitoring/EcalMonitoringFinal.lcsim	(original)
+++ java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/monitoring/EcalMonitoringFinal.lcsim	Wed Apr 27 11:11:32 2016
@@ -1,7 +1,7 @@
 <lcsim xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" xs:noNamespaceSchemaLocation="http://www.lcsim.org/schemas/lcsim/1.0/lcsim.xsd">
     <execute>
         <driver name="EcalRawConverter" />
-      	<driver name="EcalClusterer" />
+        <driver name="EcalClusterer" />
         <driver name="EcalMonitoringPlots" />      <!-- General plots -->
         <driver name="EcalHitPlots" />             <!-- Single hit distributions -->
         <driver name="EcalClusterPlots" />         <!-- Clusters distributions -->

Modified: java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/monitoring/EcalMonitoringOnly.lcsim
 =============================================================================
--- java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/monitoring/EcalMonitoringOnly.lcsim	(original)
+++ java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/monitoring/EcalMonitoringOnly.lcsim	Wed Apr 27 11:11:32 2016
@@ -1,7 +1,7 @@
 <lcsim xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" xs:noNamespaceSchemaLocation="http://www.lcsim.org/schemas/lcsim/1.0/lcsim.xsd">
     <execute>
         <driver name="EcalRawConverter" />
-      	<driver name="EcalClusterer" />
+        <driver name="EcalClusterer" />
         <driver name="EcalMonitoringPlots" />      <!-- General plots -->
         <driver name="EcalHitPlots" />             <!-- Single hit distributions -->
         <driver name="EcalClusterPlots" />         <!-- Clusters distributions -->

Modified: java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/monitoring/SvtOnlineMonitoring.lcsim
 =============================================================================
--- java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/monitoring/SvtOnlineMonitoring.lcsim	(original)
+++ java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/monitoring/SvtOnlineMonitoring.lcsim	Wed Apr 27 11:11:32 2016
@@ -10,22 +10,27 @@
         <driver name="PedestalPlots" />-->
         <driver name="SensorOccupancy" />
         <driver name="RawTrackerHitFitterDriver" />
+        <!--<driver name="SVTPulseFitPlots" />--> 
         <driver name="TrackerHitDriver" />
         <driver name="ClusterPlots" /> 
         <driver name="CleanupDriver" />
     </execute>
     <drivers>
         <driver name="SensorOccupancy" type="org.hps.monitoring.drivers.svt.SensorOccupancyPlotsDriver" >
-        	<eventRefreshRate>100</eventRefreshRate>
+            <eventRefreshRate>100</eventRefreshRate>
             <enablePositionPlots>false</enablePositionPlots>
             <enableMaxSamplePlots>true</enableMaxSamplePlots>
             <maxSamplePosition>3</maxSamplePosition>
             <timeWindowWeight>3</timeWindowWeight>
             <resetPeriod>50000</resetPeriod>
+            <saveRootFile>false</saveRootFile>
        </driver>
-        <driver name="SvtHitPlots" type="org.hps.monitoring.drivers.svt.SvtHitPlots" />
-        <driver name="SamplesPlots" type="org.hps.monitoring.drivers.svt.SamplesPlots" />
-        <driver name="PedestalPlots" type="org.hps.monitoring.drivers.svt.PedestalPlots" />
+        <driver name="SvtHitPlots" type="org.hps.monitoring.drivers.svt.SvtHitPlots">
+            <doPerChannelsSampleplots>true</doPerChannelsSampleplots>
+            <!--<saveRootFile>false</saveRootFile>-->
+        </driver>
+        <!--<driver name="SamplesPlots" type="org.hps.monitoring.drivers.svt.SamplesPlots" />-->
+        <!--<driver name="PedestalPlots" type="org.hps.monitoring.drivers.svt.PedestalPlots" />-->
         <driver name="RawTrackerHitFitterDriver" type="org.hps.recon.tracking.RawTrackerHitFitterDriver">
             <fitAlgorithm>Linear</fitAlgorithm>
             <useTimestamps>false</useTimestamps>
@@ -41,7 +46,10 @@
             <neighborDeltaT>8.0</neighborDeltaT>
             <debug>false</debug>
         </driver>
-        <driver name="ClusterPlots" type="org.hps.monitoring.drivers.svt.SvtClusterPlots" />
+        <!--<driver name="SVTPulseFitPlots" type="org.hps.monitoring.drivers.svt.SVTPulseFitPlots" />-->
+        <driver name="ClusterPlots" type="org.hps.monitoring.drivers.svt.SvtClusterPlots">
+            <saveRootFile>false</saveRootFile>
+        </driver>
         <driver name="CleanupDriver" type="org.lcsim.recon.tracking.digitization.sisim.config.ReadoutCleanupDriver" />
     </drivers>
 </lcsim>

Modified: java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/monitoring/TriggerDiagnosticsMonitoring.lcsim
 =============================================================================
--- java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/monitoring/TriggerDiagnosticsMonitoring.lcsim	(original)
+++ java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/monitoring/TriggerDiagnosticsMonitoring.lcsim	Wed Apr 27 11:11:32 2016
@@ -19,7 +19,7 @@
         <driver name="ConditionsDriver" type="org.hps.conditions.ConditionsDriver">
             <tag>pass0</tag>
         </driver>        
-        <driver name="DAQConfig" type="org.hps.recon.ecal.daqconfig.DAQConfigDriver"/>        
+        <driver name="DAQConfig" type="org.hps.record.daqconfig.DAQConfigDriver"/>
         <driver name="EcalRawConverter" type="org.hps.recon.ecal.EcalRawConverterDriver">
             <ecalCollectionName>EcalCalHits</ecalCollectionName>
             <use2014Gain>false</use2014Gain>

Modified: java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/production/V0CandidateFilter.lcsim
 =============================================================================
--- java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/production/V0CandidateFilter.lcsim	(original)
+++ java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/production/V0CandidateFilter.lcsim	Wed Apr 27 11:11:32 2016
@@ -22,12 +22,6 @@
         <!-- Driver to strip events -->
         <driver name="StripEvent"
                 type="org.hps.recon.filtering.V0CandidateFilter">
-              <!-- Name of the V0 Candidate Collection of ReconstructedParticles -->
-              <v0CandidateCollectionName>TargetConstrainedV0Candidates</v0CandidateCollectionName>
-              <!-- Maximum difference in the ECal cluster times [ns]-->
-              <clusterTimingCut>2.5</clusterTimingCut>
-              <!-- A tight selection requires one and only one real V0 vertex --> 
-              <tightConstraint>false</tightConstraint>
               <!-- Setting this true keeps ALL events containing EPICS data -->
               <keepEpicsDataEvents>true</keepEpicsDataEvents>
         </driver>

Modified: java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/readout/CommRun2014TightPairs.lcsim
 =============================================================================
--- java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/readout/CommRun2014TightPairs.lcsim	(original)
+++ java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/readout/CommRun2014TightPairs.lcsim	Wed Apr 27 11:11:32 2016
@@ -44,7 +44,7 @@
             <applyBadCrystalMap>false</applyBadCrystalMap>
             <use2014Gain>false</use2014Gain>      
             <debug>true</debug>
-        </driver>	
+        </driver>   
         <driver name="EcalClusterer" type="org.hps.recon.ecal.cluster.GTPClusterDriver">
             <inputHitCollectionName>EcalCorrectedHits</inputHitCollectionName>
             <clusterWindow>1</clusterWindow>
@@ -62,7 +62,7 @@
             <energySlopeParamF>0.005500</energySlopeParamF>
             <energySlopeLow>0.4</energySlopeLow>
             <outputFileName>${outputFile}.triggers</outputFileName>
-        </driver>	      
+        </driver>         
         <driver name="AidaSaveDriver"
                 type="org.lcsim.job.AidaSaveDriver">
             <outputFileName>${outputFile}_triggerPlots</outputFileName>
@@ -73,4 +73,4 @@
         </driver> 
     </drivers>
 </lcsim>
-	
+    

Modified: java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/readout/EngineeringRun2014PrescaledTriggers.lcsim
 =============================================================================
--- java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/readout/EngineeringRun2014PrescaledTriggers.lcsim	(original)
+++ java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/readout/EngineeringRun2014PrescaledTriggers.lcsim	Wed Apr 27 11:11:32 2016
@@ -54,7 +54,7 @@
             <nsa>100</nsa>
             <nsb>20</nsb>
             <use2014Gain>false</use2014Gain> 
-        </driver>	
+        </driver>   
         <driver name="EcalClustererGTP" type="org.hps.recon.ecal.cluster.GTPClusterDriver">
             <inputHitCollectionName>EcalCorrectedHits</inputHitCollectionName>
             <outputClusterCollectionName>EcalClusters</outputClusterCollectionName>            
@@ -82,7 +82,7 @@
             <outputFileName>${outputFile}.triggers.singles0</outputFileName>
             <lcioFile>${outputFile}.singles0.slcio</lcioFile>    
             <!--<verbose>true</verbose>-->
-        </driver>	      
+        </driver>         
         <driver name="SinglesTrigger1" type="org.hps.readout.ecal.SinglesTriggerDriver">
             <clusterCollectionName>EcalClusters</clusterCollectionName>
             <deadTime>32</deadTime>
@@ -94,7 +94,7 @@
             <outputFileName>${outputFile}.triggers.singles1</outputFileName>
             <lcioFile>${outputFile}.singles1.slcio</lcioFile>            
             <!--<verbose>true</verbose>-->
-        </driver>	      
+        </driver>         
         <driver name="PairTrigger0" type="org.hps.readout.ecal.FADCPrimaryTriggerDriver">
             <clusterCollectionName>EcalClusters</clusterCollectionName>
             <deadTime>32</deadTime>
@@ -113,7 +113,7 @@
             <outputFileName>${outputFile}.triggers.pairs0</outputFileName>
             <lcioFile>${outputFile}.pairs0.slcio</lcioFile>            
             <!--<verbose>true</verbose>-->
-        </driver>	      
+        </driver>         
         <driver name="PairTrigger1" type="org.hps.readout.ecal.FADCPrimaryTriggerDriver">
             <clusterCollectionName>EcalClusters</clusterCollectionName>
             <deadTime>32</deadTime>
@@ -132,7 +132,7 @@
             <outputFileName>${outputFile}.triggers.pairs1</outputFileName>
             <lcioFile>${outputFile}.pairs1.slcio</lcioFile>
             <!--<verbose>true</verbose>-->
-        </driver>	      
+        </driver>         
         <driver name="AidaSaveDriver"
                 type="org.lcsim.job.AidaSaveDriver">
             <outputFileName>${outputFile}_triggerPlots</outputFileName>
@@ -143,4 +143,4 @@
         </driver> 
     </drivers>
 </lcsim>
-	
+    

Modified: java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/readout/HPS2014ReadoutNoPileup.lcsim
 =============================================================================
--- java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/readout/HPS2014ReadoutNoPileup.lcsim	(original)
+++ java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/readout/HPS2014ReadoutNoPileup.lcsim	Wed Apr 27 11:11:32 2016
@@ -48,7 +48,7 @@
             <deadTime>0</deadTime>
             <pairCoincidence>0</pairCoincidence>
             <lcioFile>${outputFile}.slcio</lcioFile>
-        </driver>	
+        </driver>   
         <driver name="SimpleSVTReadout" type="org.hps.readout.svt.SimpleSvtReadout">
             <noPileup>true</noPileup>
         </driver>

Modified: java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/readout/HPS2014ReadoutToEvio.lcsim
 =============================================================================
--- java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/readout/HPS2014ReadoutToEvio.lcsim	(original)
+++ java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/readout/HPS2014ReadoutToEvio.lcsim	Wed Apr 27 11:11:32 2016
@@ -44,7 +44,7 @@
             <applyBadCrystalMap>false</applyBadCrystalMap>
             <use2014Gain>true</use2014Gain>
             <!--            <debug>true</debug>-->
-        </driver>	
+        </driver>   
         <driver name="EcalClusterer" type="org.hps.recon.ecal.cluster.GTPClusterDriver">
             <inputHitCollectionName>EcalCorrectedHits</inputHitCollectionName>
             <clusterWindow>1</clusterWindow>
@@ -54,7 +54,7 @@
             <deadTime>10</deadTime>
             <pairCoincidence>2</pairCoincidence>
             <outputFileName>${outputFile}.triggers</outputFileName>
-        </driver>	
+        </driver>   
         <driver name="SimpleSVTReadout" type="org.hps.readout.svt.SimpleSvtReadout" />
         <driver name="ClockDriver" type="org.hps.readout.ecal.ClockDriver"/>
         <driver name="CleanupDriver" type="org.lcsim.recon.tracking.digitization.sisim.config.ReadoutCleanupDriver">
@@ -62,4 +62,4 @@
         </driver> 
     </drivers>
 </lcsim>
-	
+    

Modified: java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/readout/HPS2014TruthReadoutToLcio.lcsim
 =============================================================================
--- java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/readout/HPS2014TruthReadoutToLcio.lcsim	(original)
+++ java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/readout/HPS2014TruthReadoutToLcio.lcsim	Wed Apr 27 11:11:32 2016
@@ -47,7 +47,7 @@
             <applyBadCrystalMap>false</applyBadCrystalMap>
             <use2014Gain>true</use2014Gain>
             <!--            <debug>true</debug>-->
-        </driver>	
+        </driver>   
         <driver name="EcalClusterer" type="org.hps.recon.ecal.cluster.GTPClusterDriver">
             <inputHitCollectionName>EcalCorrectedHits</inputHitCollectionName>
             <clusterWindow>1</clusterWindow>
@@ -57,7 +57,7 @@
             <deadTime>10</deadTime>
             <pairCoincidence>2</pairCoincidence>
             <outputFileName>${outputFile}.triggers</outputFileName>
-        </driver>	
+        </driver>   
         <driver name="SimpleSVTReadout" type="org.hps.readout.svt.SimpleSvtReadout">
         </driver>
         <driver name="AidaSaveDriver"
@@ -70,4 +70,4 @@
         </driver> 
     </drivers>
 </lcsim>
-	
+    

Modified: java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/readout/LcioToEvio.lcsim
 =============================================================================
--- java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/readout/LcioToEvio.lcsim	(original)
+++ java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/readout/LcioToEvio.lcsim	Wed Apr 27 11:11:32 2016
@@ -15,7 +15,7 @@
             <period>1</period>
             <deadTime>0</deadTime>
             <triggerDelay>0</triggerDelay>
-        </driver>	
+        </driver>   
         <driver name="TestRunReconToEvio" type="org.hps.evio.TestRunTriggeredReconToEvio">
             <evioOutputFile>${outputFile}.evio</evioOutputFile>
         </driver>
@@ -23,4 +23,4 @@
         </driver>
     </drivers>
 </lcsim>
-	
+    

Modified: java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/readout/TestRunNoPileup.lcsim
 =============================================================================
--- java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/readout/TestRunNoPileup.lcsim	(original)
+++ java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/readout/TestRunNoPileup.lcsim	Wed Apr 27 11:11:32 2016
@@ -39,7 +39,7 @@
             <clusterCollectionName>EcalTriggerClusters</clusterCollectionName>
             <deadTime>0</deadTime>
             <lcioFile>${outputFile}.slcio</lcioFile>
-        </driver>	
+        </driver>   
         <driver name="ClockDriver" type="org.hps.readout.ecal.ClockDriver"/>
         <driver name="CleanupDriver" type="org.lcsim.recon.tracking.digitization.sisim.config.ReadoutCleanupDriver"/>
     </drivers>

Modified: java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/readout/TestRunReadoutToEvio.lcsim
 =============================================================================
--- java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/readout/TestRunReadoutToEvio.lcsim	(original)
+++ java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/readout/TestRunReadoutToEvio.lcsim	Wed Apr 27 11:11:32 2016
@@ -20,7 +20,7 @@
         <driver name="EventMarkerDriver" type="org.lcsim.job.EventMarkerDriver">
             <eventInterval>1000</eventInterval>
         </driver> 
-        <driver name="BadChannelFilter" type="org.hps.recon.tracking.SVTBadChannelFilterDriver" /> 		
+        <driver name="BadChannelFilter" type="org.hps.recon.tracking.SVTBadChannelFilterDriver" />      
         <driver name="EcalReadout" type="org.hps.readout.ecal.FADCEcalReadoutDriver">
             <coincidenceWindow>8</coincidenceWindow>
             <ecalName>Ecal</ecalName>
@@ -39,7 +39,7 @@
             <rawCollectionName>EcalRawHits</rawCollectionName>
             <ecalCollectionName>EcalCorrectedHits</ecalCollectionName>
             <scale>1</scale>
-        </driver>	
+        </driver>   
         <driver name="EcalTriggerFilter" type="org.hps.recon.ecal.EcalTriggerFilterDriver">
             <inputCollection>EcalCorrectedHits</inputCollection>
             <outputCollection>EcalFilteredHits</outputCollection>
@@ -55,7 +55,7 @@
             <clusterCollectionName>EcalClusters</clusterCollectionName>
             <deadTime>10</deadTime>
             <outputFileName>${outputFile}.triggers</outputFileName>
-        </driver>	
+        </driver>   
         <driver name="SimpleSVTReadout" type="org.hps.readout.svt.SimpleSvtReadout" />
         <driver name="ClockDriver" type="org.hps.readout.ecal.ClockDriver"/>
         <driver name="TestRunReconToEvio" type="org.hps.evio.TestRunTriggeredReconToEvio">

Modified: java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/recon/EngineeringRun2014EcalReconMC.lcsim
 =============================================================================
--- java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/recon/EngineeringRun2014EcalReconMC.lcsim	(original)
+++ java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/recon/EngineeringRun2014EcalReconMC.lcsim	Wed Apr 27 11:11:32 2016
@@ -18,6 +18,7 @@
     <execute>
         <!--<driver name="EventMarkerDriver" />-->
         <driver name="EcalRunningPedestal"/>
+        <driver name="RfFitter"/>
         <driver name="EcalRawConverter" />
         <driver name="ReconClusterer" />
         <driver name="GTPOnlineClusterer" />
@@ -28,6 +29,8 @@
         <driver name="EventMarkerDriver" type="org.lcsim.job.EventMarkerDriver">
             <eventInterval>100</eventInterval>
         </driver>
+        <driver name="RfFitter" type="org.hps.evio.RfFitterDriver"/>       
+        
      <driver name="ConditionsDriver" type="org.hps.conditions.ConditionsDriver">
        <detectorName>HPS-ECalCommissioning-v3-fieldmap</detectorName>
        <runNumber>3422</runNumber>

Modified: java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/recon/EngineeringRun2015FullRecon.lcsim
 =============================================================================
--- java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/recon/EngineeringRun2015FullRecon.lcsim	(original)
+++ java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/recon/EngineeringRun2015FullRecon.lcsim	Wed Apr 27 11:11:32 2016
@@ -7,7 +7,9 @@
       @author <a href="mailto:[log in to unmask]">Omar Moreno</a>
     -->
     <execute>
-        
+        <!--RF driver-->
+        <driver name="RfFitter"/>
+ 
         <!-- Ecal reconstruction drivers -->        
         <driver name="EcalRunningPedestal"/>
         <driver name="EcalRawConverter" />
@@ -51,7 +53,6 @@
            ReconstructedParticle types are properly set.
         -->
         <driver name="MergeTrackCollections"/>
-        <driver name="GBLOutputDriver" />
         <driver name="GBLRefitterDriver" />
         <driver name="TrackDataDriver" />
         <driver name="ReconParticleDriver" />   
@@ -61,7 +62,9 @@
     <drivers>    
         <driver name="EventMarkerDriver" type="org.lcsim.job.EventMarkerDriver">
             <eventInterval>1000</eventInterval>
-        </driver>        
+        </driver> 
+        
+        <driver name="RfFitter" type="org.hps.evio.RfFitterDriver"/>       
 
         <!-- Ecal reconstruction drivers -->
         <driver name="EcalRunningPedestal" type="org.hps.recon.ecal.EcalRunningPedestalDriver">
@@ -134,8 +137,7 @@
             <ecalClusterCollectionName>EcalClustersCorr</ecalClusterCollectionName>        
             <trackCollectionNames>MatchedTracks GBLTracks</trackCollectionNames>
         </driver>  
-        <driver name="GBLOutputDriver" type="org.hps.recon.tracking.gbl.GBLOutputDriver"/>      
-        <driver name="GBLRefitterDriver" type="org.hps.recon.tracking.gbl.HpsGblRefitter"/>
+        <driver name="GBLRefitterDriver" type="org.hps.recon.tracking.gbl.GBLRefitterDriver"/>
         <driver name="LCIOWriter" type="org.lcsim.util.loop.LCIODriver">
             <outputFilePath>${outputFile}.slcio</outputFilePath>
         </driver>

Modified: java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/recon/EngineeringRun2015FullReconMC.lcsim
 =============================================================================
--- java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/recon/EngineeringRun2015FullReconMC.lcsim	(original)
+++ java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/recon/EngineeringRun2015FullReconMC.lcsim	Wed Apr 27 11:11:32 2016
@@ -11,6 +11,7 @@
     
         <driver name="ConditionsDriver"/>
         <driver name="EventMarkerDriver"/>
+        <driver name="RfFitter"/>
         <!-- Ecal reconstruction drivers -->        
         <driver name="EcalRawConverter" />
         <driver name="ReconClusterer" />
@@ -53,7 +54,6 @@
             ReconstructedParticle types are properly set.
          -->
         <driver name="MergeTrackCollections"/>
-        <driver name="GBLOutputDriver" />
         <driver name="GBLRefitterDriver" />
         <driver name="TrackDataDriver" />
         <driver name="ReconParticleDriver" />   
@@ -69,7 +69,9 @@
 
         <driver name="EventMarkerDriver" type="org.lcsim.job.EventMarkerDriver">
             <eventInterval>1000</eventInterval>
-        </driver>        
+        </driver>   
+        <driver name="RfFitter" type="org.hps.evio.RfFitterDriver"/>       
+             
         <driver name="RawTrackerHitSensorSetup" type="org.lcsim.recon.tracking.digitization.sisim.config.RawTrackerHitSensorSetup">
             <readoutCollections>SVTRawTrackerHits</readoutCollections>
         </driver>
@@ -119,8 +121,7 @@
             <rmsTimeCut>8.0</rmsTimeCut>
         </driver>       
         <driver name="MergeTrackCollections" type="org.hps.recon.tracking.MergeTrackCollections" />
-        <driver name="GBLOutputDriver" type="org.hps.recon.tracking.gbl.GBLOutputDriver"/>             
-        <driver name="GBLRefitterDriver" type="org.hps.recon.tracking.gbl.HpsGblRefitter"/>
+        <driver name="GBLRefitterDriver" type="org.hps.recon.tracking.gbl.GBLRefitterDriver"/>
         <driver name="EcalRawConverter" type="org.hps.recon.ecal.EcalRawConverterDriver">
             <ecalCollectionName>EcalCalHits</ecalCollectionName>
             <fixShapeParameter>true</fixShapeParameter>

Modified: java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/users/celentan/LedAnalysisFromEvio.lcsim
 =============================================================================
--- java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/users/celentan/LedAnalysisFromEvio.lcsim	(original)
+++ java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/users/celentan/LedAnalysisFromEvio.lcsim	Wed Apr 27 11:11:32 2016
@@ -1,9 +1,9 @@
 <lcsim xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" 
        xs:noNamespaceSchemaLocation="http://www.lcsim.org/schemas/lcsim/1.0/lcsim.xsd">         
     <execute>
-    	<driver name="EventMarkerDriver"/>
+        <driver name="EventMarkerDriver"/>
         <driver name="EcalRunningPedestal"/>
-  	    <driver name="EcalRawConverter" />    
+        <driver name="EcalRawConverter" />    
         <driver name="AidaSaveDriver"/>
     </execute>           
     <drivers>    
@@ -25,5 +25,5 @@
         <driver name="AidaSaveDriver" type="org.lcsim.job.AidaSaveDriver">
             <outputFileName>${outputFile}.aida</outputFileName>
         </driver>
-	</drivers>
+    </drivers>
 </lcsim>

Modified: java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/users/holly/ClusterRecon.lcsim
 =============================================================================
--- java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/users/holly/ClusterRecon.lcsim	(original)
+++ java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/users/holly/ClusterRecon.lcsim	Wed Apr 27 11:11:32 2016
@@ -5,7 +5,7 @@
   @author Holly Szumila <[log in to unmask]>
 -->
     <execute>
-    	<driver name="EventMarkerDriver"/>
+        <driver name="EventMarkerDriver"/>
         <driver name="EcalRunningPedestal"/>
         <driver name="EcalRawConverter" />
         <driver name="ReconClusterer" />
@@ -13,7 +13,7 @@
         <driver name="LCIOWriter"/>
     </execute>    
     <drivers>    
-   		<driver name="EventMarkerDriver" type="org.lcsim.job.EventMarkerDriver">
+        <driver name="EventMarkerDriver" type="org.lcsim.job.EventMarkerDriver">
             <eventInterval>1000</eventInterval>
         </driver> 
         <driver name="EcalRunningPedestal" type="org.hps.recon.ecal.EcalRunningPedestalDriver">

Modified: java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/users/holly/EcalSimReadout.lcsim
 =============================================================================
--- java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/users/holly/EcalSimReadout.lcsim	(original)
+++ java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/users/holly/EcalSimReadout.lcsim	Wed Apr 27 11:11:32 2016
@@ -21,11 +21,11 @@
             <eventInterval>1000</eventInterval>
         </driver>       
         <driver name="ConditionsDriver" type="org.hps.conditions.ConditionsDriver">
-     		<runNumber>0</runNumber>
-    		<freeze>true</freeze>
-    		<detectorName>HPS-ECalCommissioning-v3-fieldmap</detectorName>
-   		 </driver>
-<!--   		 <driver name="TestRunReconToLcio" type="org.hps.evio.TestRunTriggeredReconToLcio">
+            <runNumber>0</runNumber>
+            <freeze>true</freeze>
+            <detectorName>HPS-ECalCommissioning-v3-fieldmap</detectorName>
+         </driver>
+<!--         <driver name="TestRunReconToLcio" type="org.hps.evio.TestRunTriggeredReconToLcio">
             <outputFile>${outputFile}.slcio</outputFile>
             <rejectBackground>true</rejectBackground>
         </driver>-->
@@ -45,7 +45,7 @@
             <ecalCollectionName>EcalCorrectedHits</ecalCollectionName>
             <applyBadCrystalMap>false</applyBadCrystalMap>
             <use2014Gain>false</use2014Gain>      
-        </driver>	
+        </driver>   
         <driver name="ReconClusterer" type="org.hps.recon.ecal.cluster.ReconClusterDriver">
             <logLevel>WARNING</logLevel>
             <inputHitCollectionName>EcalCorrectedHits</inputHitCollectionName>
@@ -65,4 +65,4 @@
         </driver> 
     </drivers>
 </lcsim>
-	
+    

Modified: java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/users/holly/EngineeringRun2015EcalOnly.lcsim
 =============================================================================
Binary files - no diff available.

Modified: java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/users/holly/EngineeringRun2015_FEEIter_Filter.lcsim
 =============================================================================
Binary files - no diff available.

Modified: java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/users/holly/QuickEcalReadout.lcsim
 =============================================================================
--- java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/users/holly/QuickEcalReadout.lcsim	(original)
+++ java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/users/holly/QuickEcalReadout.lcsim	Wed Apr 27 11:11:32 2016
@@ -18,11 +18,11 @@
             <eventInterval>1000</eventInterval>
         </driver>       
         <driver name="ConditionsDriver" type="org.hps.conditions.ConditionsDriver">
-     		<runNumber>0</runNumber>
-    		<freeze>true</freeze>
-    		<detectorName>HPS-Proposal2014-v7-2pt2</detectorName>
-   		 </driver>
-   		 <driver name="TestRunReconToLcio" type="org.hps.evio.TestRunTriggeredReconToLcio">
+            <runNumber>0</runNumber>
+            <freeze>true</freeze>
+            <detectorName>HPS-Proposal2014-v7-2pt2</detectorName>
+         </driver>
+         <driver name="TestRunReconToLcio" type="org.hps.evio.TestRunTriggeredReconToLcio">
             <outputFile>${outputFile}.slcio</outputFile>
             <rejectBackground>true</rejectBackground>
         </driver>
@@ -44,4 +44,4 @@
         </driver> 
     </drivers>
 </lcsim>
-	
+    

Modified: java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/users/meeg/EcalScoring.lcsim
 =============================================================================
--- java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/users/meeg/EcalScoring.lcsim	(original)
+++ java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/users/meeg/EcalScoring.lcsim	Wed Apr 27 11:11:32 2016
@@ -25,4 +25,4 @@
 
     </drivers>
 </lcsim>
-	
+    

Modified: java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/users/meeg/HitTimes.lcsim
 =============================================================================
--- java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/users/meeg/HitTimes.lcsim	(original)
+++ java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/users/meeg/HitTimes.lcsim	Wed Apr 27 11:11:32 2016
@@ -1,14 +1,14 @@
 
 <lcsim xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" 
        xs:noNamespaceSchemaLocation="http://www.lcsim.org/schemas/lcsim/1.0/lcsim.xsd">
-	<execute>
-		<driver name="EventMarkerDriver"/>
-		<driver name="HitTimePrintDriver"/>
-	</execute>
-	<drivers>
-		<driver name="EventMarkerDriver" type="org.lcsim.job.EventMarkerDriver">
-			<eventInterval>1</eventInterval>
-		</driver>
-		<driver name="HitTimePrintDriver" type="org.hps.users.meeg.HitTimePrintDriver"/>
-	</drivers>
+    <execute>
+        <driver name="EventMarkerDriver"/>
+        <driver name="HitTimePrintDriver"/>
+    </execute>
+    <drivers>
+        <driver name="EventMarkerDriver" type="org.lcsim.job.EventMarkerDriver">
+            <eventInterval>1</eventInterval>
+        </driver>
+        <driver name="HitTimePrintDriver" type="org.hps.users.meeg.HitTimePrintDriver"/>
+    </drivers>
 </lcsim>

Modified: java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/users/meeg/PairsSkimmer.lcsim
 =============================================================================
--- java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/users/meeg/PairsSkimmer.lcsim	(original)
+++ java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/users/meeg/PairsSkimmer.lcsim	Wed Apr 27 11:11:32 2016
@@ -44,4 +44,4 @@
         </driver>
     </drivers>
 </lcsim>
-	
+    

Modified: java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/users/meeg/SmallHits.lcsim
 =============================================================================
--- java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/users/meeg/SmallHits.lcsim	(original)
+++ java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/users/meeg/SmallHits.lcsim	Wed Apr 27 11:11:32 2016
@@ -1,18 +1,18 @@
 
 <lcsim xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" 
        xs:noNamespaceSchemaLocation="http://www.lcsim.org/schemas/lcsim/1.0/lcsim.xsd">
-	<execute>
-		<driver name="EventMarkerDriver"/>
-		<driver name="SVTSmallHitsDriver"/>
+    <execute>
+        <driver name="EventMarkerDriver"/>
+        <driver name="SVTSmallHitsDriver"/>
         <driver name="AidaSaveDriver"/>
-	</execute>
-	<drivers>
-		<driver name="EventMarkerDriver" type="org.lcsim.job.EventMarkerDriver">
-			<eventInterval>1000</eventInterval>
-		</driver>
-		<driver name="SVTSmallHitsDriver" type="org.hps.users.meeg.SVTSmallHitsDriver"/>
+    </execute>
+    <drivers>
+        <driver name="EventMarkerDriver" type="org.lcsim.job.EventMarkerDriver">
+            <eventInterval>1000</eventInterval>
+        </driver>
+        <driver name="SVTSmallHitsDriver" type="org.hps.users.meeg.SVTSmallHitsDriver"/>
         <driver name="AidaSaveDriver" type="org.lcsim.job.AidaSaveDriver">
             <outputFileName>smallhits.root</outputFileName>
         </driver>
-	</drivers>
+    </drivers>
 </lcsim>

Modified: java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/users/meeg/ecal_fadc_bkgd.lcsim
 =============================================================================
--- java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/users/meeg/ecal_fadc_bkgd.lcsim	(original)
+++ java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/users/meeg/ecal_fadc_bkgd.lcsim	Wed Apr 27 11:11:32 2016
@@ -10,11 +10,11 @@
         <driver name="EcalConverter" />
         <driver name="EcalClusterer" />
         <driver name="EcalTrigger" />
-<!--		<driver name="EcalPlots"/>-->
+<!--        <driver name="EcalPlots"/>-->
         <driver name="EcalFADCPlots" />
         <driver name="EcalTriggerPlots" />
         <driver name="MCParticlePlots" />
-<!--		<driver name="Writer"/>-->
+<!--        <driver name="Writer"/>-->
         <driver name="AidaSaveDriver" />
         <driver name="ClockDriver" />
     </execute>

Modified: java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/users/meeg/raw_triggers.lcsim
 =============================================================================
--- java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/users/meeg/raw_triggers.lcsim	(original)
+++ java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/users/meeg/raw_triggers.lcsim	Wed Apr 27 11:11:32 2016
@@ -5,10 +5,10 @@
 -->
 <lcsim xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" xs:noNamespaceSchemaLocation="http://www.lcsim.org/schemas/lcsim/1.0/lcsim.xsd">
     <execute>
-<!--		<driver name="EventMarkerDriver"/>-->
+<!--        <driver name="EventMarkerDriver"/>-->
         <driver name="EcalClusterer" />
         <driver name="EcalTrigger" />
-<!--		<driver name="MCParticlePlots"/>-->
+<!--        <driver name="MCParticlePlots"/>-->
         <driver name="AidaSaveDriver" />
         <driver name="ClockDriver" />
     </execute>

Modified: java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/users/phansson/EngineeringRun2015FullRecon_Pass2_Gbl.lcsim
 =============================================================================
--- java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/users/phansson/EngineeringRun2015FullRecon_Pass2_Gbl.lcsim	(original)
+++ java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/users/phansson/EngineeringRun2015FullRecon_Pass2_Gbl.lcsim	Wed Apr 27 11:11:32 2016
@@ -56,7 +56,7 @@
         <driver name="GBLOutputDriver" />
         <driver name="GBLRefitterDriver" />
         <driver name="TrackDataDriver" />
-        <!--<driver name="GblResidualEcalDriver" />-->
+        <driver name="GblResidualEcalDriver" />
         <!--<driver name="TrackExtrapolationTestDriver"/>-->
         <driver name="ReconParticleDriver" />  
         <!--<driver name="TrackingReconstructionPlots" />-->
@@ -162,13 +162,13 @@
             <outputFileName>${outputFile}.root</outputFileName>
         </driver>  
         <driver name="AlignmentFilterDriver" type="org.hps.recon.filtering.SvtAlignmentFilter"/>     
-        <driver name="GblResidualEcalDriver" type="org.hps.users.phansson.ECalExtrapolationDriver"/>   
+        <driver name="GblResidualEcalDriver" type="org.hps.users.phansson.GblResidualDriver"/>   
         <driver name="TrackExtrapolationTestDriver" type="org.hps.users.phansson.TrackExtrapolationTestDriver"/>   
         <driver name="TrackingReconstructionPlots" type="org.hps.users.phansson.TrackingReconstructionPlots">
             <showPlots>False</showPlots>
         </driver>
         <driver name="TimerDriver1" type="org.hps.util.TimerDriver"/>
-        <driver name="GeomChecker" type="org.hps.users.phansson.TrackingGeometryChecker"/>
+        <driver name="GeomChecker" type="org.hps.users.phansson.tools.TrackingGeometryChecker"/>
 
     </drivers>
 </lcsim>

Modified: java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/users/phansson/TestRunOfflineRecon.lcsim
 =============================================================================
--- java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/users/phansson/TestRunOfflineRecon.lcsim	(original)
+++ java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/users/phansson/TestRunOfflineRecon.lcsim	Wed Apr 27 11:11:32 2016
@@ -39,7 +39,7 @@
         </driver>
         <driver name="TrackerReconDriver" type="org.hps.recon.tracking.TrackerReconDriver">
             <debug>false</debug>
-		    <!--<strategyResource>/org/hps/recon/tracking/strategies/HPS-Test-All.xml</strategyResource>-->
+            <!--<strategyResource>/org/hps/recon/tracking/strategies/HPS-Test-All.xml</strategyResource>-->
             <strategyResource>/org/hps/recon/tracking/strategies/HPS-TestRun-357.xml</strategyResource>
         </driver>
         <driver name="EcalRawConverter" type="org.hps.recon.ecal.EcalRawConverterDriver">

Modified: java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/users/rafo/TestSteering.lcsim
 =============================================================================
--- java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/users/rafo/TestSteering.lcsim	(original)
+++ java/branches/HPSJAVA-409/steering-files/src/main/resources/org/hps/steering/users/rafo/TestSteering.lcsim	Wed Apr 27 11:11:32 2016
@@ -17,4 +17,4 @@
         </driver> 
     </drivers>
 </lcsim>
-	
+    

Modified: java/branches/HPSJAVA-409/tracking/pom.xml
 =============================================================================
--- java/branches/HPSJAVA-409/tracking/pom.xml	(original)
+++ java/branches/HPSJAVA-409/tracking/pom.xml	Wed Apr 27 11:11:32 2016
@@ -8,7 +8,7 @@
         <groupId>org.hps</groupId>
         <artifactId>hps-parent</artifactId>
         <relativePath>../parent/pom.xml</relativePath>
-        <version>3.4.2-SNAPSHOT</version>
+        <version>3.9-SNAPSHOT</version>
     </parent>
     <scm>
         <url>http://java.freehep.org/svn/repos/hps/list/java/trunk/tracking/</url>

Modified: java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/readout/svt/FpgaData.java
 =============================================================================
--- java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/readout/svt/FpgaData.java	(original)
+++ java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/readout/svt/FpgaData.java	Wed Apr 27 11:11:32 2016
@@ -39,8 +39,9 @@
 
     /**
      * 
-     * @param temperature : array containing hybrid temperatures
-     * @param tail : word present at the end of a FPGA data set
+     * @param fpgaID FPGA ID
+     * @param data : array containing hybrid temperatures
+     * @param tail : word present at the end of a FPGA data set     
      */
     public FpgaData(int fpgaID, int[] data, int tail) {
         this.fpgaID = fpgaID;

Modified: java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/DumbShaperFit.java
 =============================================================================
--- java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/DumbShaperFit.java	(original)
+++ java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/DumbShaperFit.java	Wed Apr 27 11:11:32 2016
@@ -34,7 +34,7 @@
     }
     
     public Collection<ShapeFitParameters> fitShape(int channel, short[] samples, HpsSiSensor sensor){
-    	
+        
         ShapeFitParameters fitresults = new ShapeFitParameters();
         double[] pedSub = {-99.0, -99.0, -99.0, -99.0, -99.0, -99.0};
         double maxADC = -99999;

Modified: java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/HelicalTrackHitDriver.java
 =============================================================================
--- java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/HelicalTrackHitDriver.java	(original)
+++ java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/HelicalTrackHitDriver.java	Wed Apr 27 11:11:32 2016
@@ -41,15 +41,39 @@
 import org.lcsim.recon.tracking.digitization.sisim.TrackerHitType;
 
 /**
- * Driver used to create stereo hits from clusters.
- *
+ * This <code>Driver</code> creates 3D hits from SVT strip clusters of stereo pairs, which by default
+ * are read from the <b>StripClusterer_SiTrackerHitStrip1D</b> input collection.
+ * <p>
+ * The following collections will be added to the output event:
+ * <ul>
+ * <li>HelicalTrackHits</li>
+ * <li>RotatedHelicalTrackHits</li>
+ * <li>HelicalTrackHitRelations</li>
+ * <li>RotatedHelicalTrackHitRelations</li>
+ * <li>HelicalTrackMCRelations</li>
+ * <li>RotatedHelicalTrackMCRelations<li>
+ * </ul>
+ * <p>
+ * Class has the following default parameters values in the code (or from <code>EngineeringRun2015FullRecon.lcsim</code>):
+ * <ul>
+ * <li>{@link #setClusterTimeCut(double)} - 12.0 (ns)</li>
+ * <li>{@link #setMaxDt(double)} - 16.0 (ns)</li>
+ * <li>{@link #setClusterAmplitudeCut(double)} - 400.0</li>
+ * <li>{@link #setRejectGhostHits(boolean)} - <code>false</code></li>
+ * <li>{@link #setDebug(boolean)} - <code>false</code></li>
+ * <li>{@link #setEpsParallel(double)} - 0.013</li>
+ * <li>{@link #setEpsStereo(double)} - 0.01</li>
+ * <li>{@link #setSaveAxialHits(boolean)} - <code>false</code></li>
+ * <li>{@link #setStripHitsCollectionName(String)} - StripClusterer_SiTrackerHitStrip1D</li>
+ * <li>{@link #setHelicalTrackHitRelationsCollectionName(String)} - HelicalTrackHitRelations</li>
+ * <li>{@link #setHelicalTrackMCRelationsCollectionName(String)} -  HelicalTrackMCRelations</li>
+ * <li>{@link #setOutputHitCollectionName(String)} - HelicalTrackHits</li>
+ * </ul>
  *
  * @author Mathew Graham <[log in to unmask]>
  * @author Per Hansson <[log in to unmask]>
  * @author Omar Moreno <[log in to unmask]>
- *
  */
-// TODO: Add class documentation.
 // FIXME: The option to run using the Common geometry should be removed
 public class HelicalTrackHitDriver extends org.lcsim.fit.helicaltrack.HelicalTrackHitDriver {
 
@@ -64,8 +88,8 @@
     private final List<String> _colnames = new ArrayList<String>();
     private boolean _doTransformToTracking = true;
     private boolean _saveAxialHits = false;
-    private String _axialname = "AxialTrackHits";
-    private String _axialmcrelname = "AxialTrackHitsMCRelations";
+    private final String _axialname = "AxialTrackHits";
+    private final String _axialmcrelname = "AxialTrackHitsMCRelations";
     private boolean rejectGhostHits = false;
 
     public enum LayerGeometryType {
@@ -143,7 +167,7 @@
     public void setEpsStereo(double eps) {
         this._crosser.setEpsStereoAngle(eps);
     }
-    
+
     /**
      *
      * @param trans
@@ -199,8 +223,9 @@
         // Create an LCRelation from a HelicalTrackHit to an MC particle used to
         // create it
         List<LCRelation> mcrelations = new ArrayList<LCRelation>();
-        RelationalTable hittomc = new BaseRelationalTable(RelationalTable.Mode.ONE_TO_MANY, RelationalTable.Weighting.UNWEIGHTED);
+        RelationalTable hittomc = null;
         if (event.hasCollection(LCRelation.class, "SVTTrueHitRelations")) {
+            hittomc = new BaseRelationalTable(RelationalTable.Mode.ONE_TO_MANY, RelationalTable.Weighting.UNWEIGHTED);
             List<LCRelation> trueHitRelations = event.get(LCRelation.class, "SVTTrueHitRelations");
             for (LCRelation relation : trueHitRelations) {
                 if (relation != null && relation.getFrom() != null && relation.getTo() != null) {
@@ -241,9 +266,11 @@
 
                     // Create a HelicalTrackStrip for this hit
                     HelicalTrackStrip strip = makeDigiStrip(h);
-                    for (RawTrackerHit rth : h.getRawHits()) {
-                        for (Object simHit : hittomc.allFrom(rth)) {
-                            strip.addMCParticle(((SimTrackerHit) simHit).getMCParticle());
+                    if (hittomc != null) {
+                        for (RawTrackerHit rth : h.getRawHits()) {
+                            for (Object simHit : hittomc.allFrom(rth)) {
+                                strip.addMCParticle(((SimTrackerHit) simHit).getMCParticle());
+                            }
                         }
                     }
 
@@ -259,10 +286,12 @@
                         if (((HpsSiSensor) h.getSensor()).isAxial()) {
                             HelicalTrack2DHit haxial = makeDigiAxialHit(h);
                             axialhits.add(haxial);
-                            List<RawTrackerHit> rl = haxial.getRawHits();
-                            for (RawTrackerHit rth : rl) {
-                                for (Object simHit : hittomc.allFrom(rth)) {
-                                    haxial.addMCParticle(((SimTrackerHit) simHit).getMCParticle());
+                            if (hittomc != null) {
+                                List<RawTrackerHit> rl = haxial.getRawHits();
+                                for (RawTrackerHit rth : rl) {
+                                    for (Object simHit : hittomc.allFrom(rth)) {
+                                        haxial.addMCParticle(((SimTrackerHit) simHit).getMCParticle());
+                                    }
                                 }
                             }
                             axialmcrelations.add(new MyLCRelation(haxial, haxial.getMCParticles()));
@@ -427,7 +456,7 @@
                     Collection<TrackerHit> htsList = hittostrip.allFrom(cross);
                     for (TrackerHit strip : htsList) {
                         Set<HelicalTrackHit> sharedCrosses = hittostrip.allTo(strip);
-                        System.out.println(sharedCrosses.size());
+//                        System.out.println(sharedCrosses.size());
                         if (sharedCrosses.size() > 1) {
 //                    this.getLogger().warning(String.format("removing possible ghost hit"));
                             iter.remove();
@@ -456,14 +485,18 @@
         helhits.addAll(stereoCrosses);
         event.put(_outname, helhits, HelicalTrackHit.class, 0);
         event.put(_hitrelname, hitrelations, LCRelation.class, 0);
-        event.put(_mcrelname, mcrelations, LCRelation.class, 0);
+        if (hittomc != null) {
+            event.put(_mcrelname, mcrelations, LCRelation.class, 0);
+        }
         if (_saveAxialHits) {
             event.put(_axialname, axialhits, HelicalTrackHit.class, 0);
-            event.put(_axialmcrelname, axialmcrelations, LCRelation.class, 0);
-            System.out.println(this.getClass().getSimpleName() + " : number of " + _axialmcrelname + " found = " + axialmcrelations.size());
+            if (hittomc != null) {
+                event.put(_axialmcrelname, axialmcrelations, LCRelation.class, 0);
+                System.out.println(this.getClass().getSimpleName() + " : number of " + _axialmcrelname + " found = " + axialmcrelations.size());
+            }
         }
         if (_doTransformToTracking) {
-            addRotatedHitsToEvent(event, stereoCrosses);
+            addRotatedHitsToEvent(event, stereoCrosses, hittomc != null);
             if (_saveAxialHits) {
                 addRotated2DHitsToEvent(event, axialhits);
             }
@@ -595,7 +628,7 @@
         return strip;
     }
 
-    private void addRotatedHitsToEvent(EventHeader event, List<HelicalTrackCross> stereohits) {
+    private void addRotatedHitsToEvent(EventHeader event, List<HelicalTrackCross> stereohits, boolean isMC) {
 
         List<HelicalTrackHit> rotatedhits = new ArrayList<HelicalTrackHit>();
         List<LCRelation> hthrelations = new ArrayList<LCRelation>();
@@ -634,10 +667,10 @@
             strip1.add(rotatedstriphits.get(0));
             strip2.add(rotatedstriphits.get(1));
             List<HelicalTrackCross> newhits = _crosser.MakeHits(strip1, strip2);
-            if(newhits.size()!=1) {
+            if (newhits.size() != 1) {
                 throw new RuntimeException("no rotated cross was created!?");
             }
-            HelicalTrackCross newhit  = newhits.get(0);
+            HelicalTrackCross newhit = newhits.get(0);
             //HelicalTrackCross newhit = new HelicalTrackCross(rotatedstriphits.get(0), rotatedstriphits.get(1));
             for (MCParticle mcp : cross.getMCParticles()) {
                 newhit.addMCParticle(mcp);
@@ -651,7 +684,9 @@
 
         event.put("Rotated" + _outname, rotatedhits, HelicalTrackHit.class, 0);
         event.put("Rotated" + _hitrelname, hthrelations, LCRelation.class, 0);
-        event.put("Rotated" + _mcrelname, mcrelations, LCRelation.class, 0);
+        if (isMC) {
+            event.put("Rotated" + _mcrelname, mcrelations, LCRelation.class, 0);
+        }
     }
 
     /*

Modified: java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/HitTimeTrackCheck.java
 =============================================================================
--- java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/HitTimeTrackCheck.java	(original)
+++ java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/HitTimeTrackCheck.java	Wed Apr 27 11:11:32 2016
@@ -28,9 +28,15 @@
         this.rmsTimeCut = rmsTimeCut;
     }
 
+    public void setDebug(boolean debug) {
+        this.debug = debug;
+    }
+
     @Override
     public boolean checkSeed(SeedCandidate candidate) {
-//        System.out.format("seed with %d hits\n", candidate.getHits().size());
+        if (debug) {
+            System.out.format("%s: seed with %d hits\n", this.getClass().getSimpleName(), candidate.getHits().size());
+        }
         int nStrips = 0;
         double meanTime = 0;
         for (HelicalTrackHit hth : candidate.getHits()) {
@@ -50,15 +56,16 @@
         }
 //        if (nStrips<6) return true;
         seedsChecked++;
-//        rmsTime = Math.sqrt(rmsTime / nStrips);
-//        System.out.format("seed RMS %f on %d hits\n",rmsTime,nStrips);
+        if (debug) {
+            System.out.format("%s: seed RMS %f on %d hits\n", this.getClass().getSimpleName(), Math.sqrt(rmsTime / nStrips), nStrips);
+        }
         boolean passCheck = (rmsTime < minTrackHits * rmsTimeCut * rmsTimeCut);
 //        boolean passCheck = (rmsTime < minTrackHits * rmsTimeCut);
         if (passCheck) {
             seedsPassed++;
         }
         if (debug && seedsChecked % 10000 == 0) {
-            System.out.format("Checked %d seeds, %d passed (%d failed)\n", seedsChecked, seedsPassed, seedsChecked - seedsPassed);
+            System.out.format("%s: Checked %d seeds, %d passed (%d failed)\n", this.getClass().getSimpleName(), seedsChecked, seedsPassed, seedsChecked - seedsPassed);
         }
         return passCheck;
 
@@ -66,7 +73,9 @@
 
     @Override
     public boolean checkTrack(SeedTrack track) {
-//        System.out.format("track with %d hits\n", track.getTrackerHits().size());
+        if (debug) {
+            System.out.format("%s: track with %d hits\n", this.getClass().getSimpleName(), track.getTrackerHits().size());
+        }
         tracksChecked++;
         int nStrips = 0;
         double meanTime = 0;
@@ -87,13 +96,15 @@
         }
         rmsTime = Math.sqrt(rmsTime / nStrips);
 //        rmsTime = rmsTime / nStrips;
-//        System.out.format("track RMS %f on %d hits\n", rmsTime, nStrips);
+        if (debug) {
+            System.out.format("%s: track RMS %f on %d hits\n", this.getClass().getSimpleName(), rmsTime, nStrips);
+        }
         boolean passCheck = (rmsTime < rmsTimeCut);
         if (passCheck) {
             tracksPassed++;
         }
         if (debug && tracksChecked % 100 == 0) {
-            System.out.format("Checked %d tracks, %d passed (%d failed)\n", tracksChecked, tracksPassed, tracksChecked - tracksPassed);
+            System.out.format("%s: Checked %d tracks, %d passed (%d failed)\n", this.getClass().getSimpleName(), tracksChecked, tracksPassed, tracksChecked - tracksPassed);
         }
         return passCheck;
     }

Modified: java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/NearestNeighborRMSClusterer.java
 =============================================================================
--- java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/NearestNeighborRMSClusterer.java	(original)
+++ java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/NearestNeighborRMSClusterer.java	Wed Apr 27 11:11:32 2016
@@ -161,7 +161,7 @@
             double signal = base_hit.getAmp();
             double noiseRMS = 0; 
             for(int sampleN = 0; sampleN < HPSSVTConstants.TOTAL_NUMBER_OF_SAMPLES; sampleN++){
-            	noiseRMS += ((HpsSiSensor) rth.getDetectorElement()).getNoise(channel_number, sampleN);
+                noiseRMS += ((HpsSiSensor) rth.getDetectorElement()).getNoise(channel_number, sampleN);
             }
             noiseRMS = noiseRMS/HPSSVTConstants.TOTAL_NUMBER_OF_SAMPLES;
             
@@ -225,7 +225,7 @@
                 cluster_signal += hit.getAmp();
                 double strip_noise = 0; 
                 for(int sampleN = 0; sampleN < HPSSVTConstants.TOTAL_NUMBER_OF_SAMPLES; sampleN++){
-                	strip_noise += ((HpsSiSensor) hit.getRawTrackerHit().getDetectorElement()).getNoise(clustered_cell, sampleN);
+                    strip_noise += ((HpsSiSensor) hit.getRawTrackerHit().getDetectorElement()).getNoise(clustered_cell, sampleN);
                 }
                 strip_noise = strip_noise/HPSSVTConstants.TOTAL_NUMBER_OF_SAMPLES;
                 cluster_noise_squared += Math.pow(strip_noise, 2); 

Modified: java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/NoiselessReadoutChip.java
 =============================================================================
--- java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/NoiselessReadoutChip.java	(original)
+++ java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/NoiselessReadoutChip.java	Wed Apr 27 11:11:32 2016
@@ -164,8 +164,8 @@
 
         // Loop over the channels contained in the SiElectrodeDataCollection
         for (Integer channel : data.keySet()) {
-        	
-        	if(dropBadChannels && ((HpsSiSensor) electrodes.getDetectorElement()).isBadChannel(channel)){
+            
+            if(dropBadChannels && ((HpsSiSensor) electrodes.getDetectorElement()).isBadChannel(channel)){
             //===> if (dropBadChannels && HPSSVTCalibrationConstants.isBadChannel((SiSensor) electrodes.getDetectorElement(), channel)) {
                 // System.out.format("%d bad\n", channel);
                 continue;

Modified: java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/SVTBadChannelFilterDriver.java
 =============================================================================
--- java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/SVTBadChannelFilterDriver.java	(original)
+++ java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/SVTBadChannelFilterDriver.java	Wed Apr 27 11:11:32 2016
@@ -19,33 +19,33 @@
  */
 public class SVTBadChannelFilterDriver extends Driver {
 
-	// RawTrackerHit collection name 
+    // RawTrackerHit collection name 
     private String rawTrackerHitCollection = "SVTRawTrackerHits";
 
     @Override
     public void process(EventHeader event) {
-    	
+        
         if (event.hasCollection(RawTrackerHit.class, rawTrackerHitCollection)) {
             
-        	// Get the list of raw hits from the event
-        	List<RawTrackerHit> hits = event.get(RawTrackerHit.class, rawTrackerHitCollection);
-        	
+            // Get the list of raw hits from the event
+            List<RawTrackerHit> hits = event.get(RawTrackerHit.class, rawTrackerHitCollection);
+            
             // Get the hits meta data from the event
-        	LCMetaData meta = event.getMetaData(hits);
+            LCMetaData meta = event.getMetaData(hits);
             
-        	// Iterate over all raw hits in the event.  If the raw hit is 
-        	// identified to come from a noisy/bad channel, remove it from
-        	// the list of raw hits.
+            // Iterate over all raw hits in the event.  If the raw hit is 
+            // identified to come from a noisy/bad channel, remove it from
+            // the list of raw hits.
             Iterator<RawTrackerHit> hitsIterator = hits.iterator();
             while (hitsIterator.hasNext()) {
                 
-            	RawTrackerHit hit = hitsIterator.next();
+                RawTrackerHit hit = hitsIterator.next();
                 //hit.setMetaData(meta);
                 int strip = hit.getIdentifierFieldValue("strip");
                 HpsSiSensor sensor = (HpsSiSensor) hit.getDetectorElement();
 
                 if(sensor.isBadChannel(strip)){
-                	hitsIterator.remove();
+                    hitsIterator.remove();
                 }
 
                 if (!sensor.getReadout().getHits(RawTrackerHit.class).isEmpty()) {

Modified: java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/ShaperLinearFitAlgorithm.java
 =============================================================================
--- java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/ShaperLinearFitAlgorithm.java	(original)
+++ java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/ShaperLinearFitAlgorithm.java	Wed Apr 27 11:11:32 2016
@@ -34,6 +34,7 @@
     private final int nPulses;
     final double[] amplitudes;
     final double[] amplitudeErrors;
+    private double pedestal;
     //===> private ChannelConstants channelConstants;
     private HpsSiSensor sensor;
     private int channel;
@@ -44,6 +45,7 @@
     private int nUsedSamples;
     private int firstFittedPulse;
     private int nFittedPulses;
+    private boolean fitPedestal = false;
     private boolean debug = false;
     private static final Logger minuitLoggger = Logger.getLogger("org.freehep.math.minuit");
 
@@ -61,6 +63,18 @@
         } else {
             minuitLoggger.setLevel(Level.OFF);
         }
+    }
+
+    public void setFitPedestal(boolean fitPedestal) {
+        this.fitPedestal = fitPedestal;
+    }
+
+    public boolean fitsPedestal() {
+        return fitPedestal;
+    }
+
+    public double getPedestal() {
+        return pedestal;
     }
 
     @Override
@@ -120,7 +134,11 @@
             ShapeFitParameters fit = new ShapeFitParameters();
             fit.setAmp(amplitudes[i]);
             fit.setAmpErr(amplitudeErrors[i]);
-            fit.setChiProb(Gamma.regularizedGammaQ(samples.length - 2 * nPulses, chisq));
+            if (fitPedestal) {
+                fit.setChiProb(Gamma.regularizedGammaQ(samples.length - 2 * nPulses - 1, chisq));
+            } else {
+                fit.setChiProb(Gamma.regularizedGammaQ(samples.length - 2 * nPulses, chisq));
+            }
 
             fit.setT0(min.userState().value(i));
 
@@ -177,15 +195,22 @@
                 nUsedSamples = split;
                 //fit only the first pulse
                 nFittedPulses = 1;
-                FunctionMinimum frontFit = doRecursiveFit(fitData);
+                FunctionMinimum frontFit;
+                frontFit = doRecursiveFit(fitData);
                 if (debug) {
-                    System.out.format("front fit:\tt0=%f,\tA=%f,\tchisq=%f\n", frontFit.userState().value(0), amplitudes[firstFittedPulse], frontFit.fval());
-                }
-
+                    if (fitPedestal) {
+                        System.out.format("front fit:\tt0=%f,\tA=%f,\tchisq=%f,\tpedestal=%f\n", frontFit.userState().value(0), amplitudes[firstFittedPulse], frontFit.fval(), pedestal);
+                    } else {
+                        System.out.format("front fit:\tt0=%f,\tA=%f,\tchisq=%f\n", frontFit.userState().value(0), amplitudes[firstFittedPulse], frontFit.fval());
+                    }
+                }
                 //subtract first pulse from fit input
                 for (int i = 0; i < samples.length; i++) {
                     //===> fitData[i] -= amplitudes[firstFittedPulse] * getAmplitude(HPSSVTConstants.SAMPLING_INTERVAL * i - frontFit.userState().value(0), channelConstants);
                     fitData[i] -= amplitudes[firstFittedPulse] * shape.getAmplitudePeakNorm(HPSSVTConstants.SAMPLING_INTERVAL * i - frontFit.userState().value(0));
+                    if (fitPedestal) {
+                        fitData[i] -= pedestal;
+                    }
                 }
 
                 if (debug) {
@@ -201,7 +226,14 @@
                 //fit the rest of the pulses
                 firstFittedPulse++;
                 nFittedPulses = nPulses - firstFittedPulse;
-                FunctionMinimum backFit = doRecursiveFit(fitData);
+                FunctionMinimum backFit;
+                if (fitPedestal) {
+                    fitPedestal = false;
+                    backFit = doRecursiveFit(fitData);
+                    fitPedestal = true;
+                } else {
+                    backFit = doRecursiveFit(fitData);
+                }
 
                 if (debug) {
                     System.out.format("back fit:\tt0=%f,\tA=%f,\tchisq=%f\n", backFit.userState().value(0), amplitudes[firstFittedPulse], backFit.fval());
@@ -221,7 +253,11 @@
                 FunctionMinimum combinedFit = minuitFit(combinedGuess);
 
                 if (debug) {
-                    System.out.format("combined fit:\tt0=%f,\tA=%f,\tt0=%f,\tA=%f,\tchisq=%f\n", combinedFit.userState().value(0), amplitudes[firstFittedPulse], combinedFit.userState().value(1), amplitudes[firstFittedPulse + 1], combinedFit.fval());
+                    if (fitPedestal) {
+                        System.out.format("combined fit:\tt0=%f,\tA=%f,\tt0=%f,\tA=%f,\tchisq=%f,\tpedestal=%f\n", combinedFit.userState().value(0), amplitudes[firstFittedPulse], combinedFit.userState().value(1), amplitudes[firstFittedPulse + 1], combinedFit.fval(), pedestal);
+                    } else {
+                        System.out.format("combined fit:\tt0=%f,\tA=%f,\tt0=%f,\tA=%f,\tchisq=%f\n", combinedFit.userState().value(0), amplitudes[firstFittedPulse], combinedFit.userState().value(1), amplitudes[firstFittedPulse + 1], combinedFit.fval());
+                    }
                 }
 
                 double newchisq = evaluateMinimum(combinedFit);
@@ -234,8 +270,11 @@
 
 //            double newchisq = evaluateMinimum(bestFit);
             if (debug) {
-                System.out.println("new chisq:\t" + bestChisq);
-                System.out.format("best fit:\tt0=%f,\tA=%f,\tt0=%f,\tA=%f,\tchisq=%f\n", bestFit.userState().value(0), amplitudes[firstFittedPulse], bestFit.userState().value(1), amplitudes[firstFittedPulse + 1], bestFit.fval());
+                if (fitPedestal) {
+                    System.out.format("best fit:\tt0=%f,\tA=%f,\tt0=%f,\tA=%f,\tchisq=%f,\tpedestal=%f\n", bestFit.userState().value(0), amplitudes[firstFittedPulse], bestFit.userState().value(1), amplitudes[firstFittedPulse + 1], bestFit.fval(), pedestal);
+                } else {
+                    System.out.format("best fit:\tt0=%f,\tA=%f,\tt0=%f,\tA=%f,\tchisq=%f\n", bestFit.userState().value(0), amplitudes[firstFittedPulse], bestFit.userState().value(1), amplitudes[firstFittedPulse + 1], bestFit.fval());
+                }
             }
             return bestFit;
         }
@@ -322,7 +361,8 @@
         if (times.length != nFittedPulses) {
             throw new RuntimeException("wrong number of parameters in doLinFit");
         }
-        RealMatrix sc_mat = new Array2DRowRealMatrix(nFittedPulses, nUsedSamples);
+        int nAmplitudes = fitPedestal ? nFittedPulses + 1 : nFittedPulses;
+        RealMatrix sc_mat = new Array2DRowRealMatrix(nAmplitudes, nUsedSamples);
         RealVector y_vec = new ArrayRealVector(nUsedSamples);
         RealVector var_vec = new ArrayRealVector(nUsedSamples);
 
@@ -330,6 +370,9 @@
             for (int i = 0; i < nFittedPulses; i++) {
                 //===> sc_mat.setEntry(i, j, getAmplitude(HPSSVTConstants.SAMPLING_INTERVAL * (firstUsedSample + j) - times[i], channelConstants) / sigma[firstUsedSample + j]);
                 sc_mat.setEntry(i, j, shape.getAmplitudePeakNorm(HPSSVTConstants.SAMPLING_INTERVAL * (firstUsedSample + j) - times[i]) / sigma[firstUsedSample + j]);
+            }
+            if (fitPedestal) {
+                sc_mat.setEntry(nFittedPulses, j, 1.0 / sigma[firstUsedSample + j]);
             }
             y_vec.setEntry(j, y[firstUsedSample + j] / sigma[firstUsedSample + j]);
             var_vec.setEntry(j, sigma[firstUsedSample + j] * sigma[firstUsedSample + j]);
@@ -344,7 +387,7 @@
             a_solver = a_cholesky.getSolver();
             solved_amplitudes = a_solver.solve(a_vec);
             amplitude_err = a_solver.solve(sc_mat.operate(var_vec));
-            if (solved_amplitudes.getMinValue() < 0) {
+            if (solved_amplitudes.getSubVector(0, nFittedPulses).getMinValue() < 0) {
                 goodFit = false;
             }
         } catch (NonPositiveDefiniteMatrixException e) {
@@ -352,8 +395,8 @@
         }
 
         if (!goodFit) {
-            solved_amplitudes = new ArrayRealVector(nFittedPulses, 0.0);
-            amplitude_err = new ArrayRealVector(nFittedPulses, Double.POSITIVE_INFINITY);
+            solved_amplitudes = new ArrayRealVector(nAmplitudes, 0.0);
+            amplitude_err = new ArrayRealVector(nAmplitudes, Double.POSITIVE_INFINITY);
         }
 
         double chisq = y_vec.subtract(sc_mat.preMultiply(solved_amplitudes)).getNorm();
@@ -361,6 +404,9 @@
         for (int i = 0; i < nFittedPulses; i++) {
             amplitudes[firstFittedPulse + i] = solved_amplitudes.getEntry(i);
             amplitudeErrors[firstFittedPulse + i] = Math.sqrt(amplitude_err.getEntry(i));
+        }
+        if (fitPedestal) {
+            pedestal = solved_amplitudes.getEntry(nFittedPulses);
         }
         return chisq;
     }

Modified: java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/StrategyType.java
 =============================================================================
--- java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/StrategyType.java	(original)
+++ java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/StrategyType.java	Wed Apr 27 11:11:32 2016
@@ -4,7 +4,7 @@
 import java.util.Map;
 
 /**
- * Enum constants for different {@link Track}s based on what tracking
+ * Enum constants for different {@link org.lcsim.event.Track} objects based on what tracking
  * strategy was used.  The type is defined by comparing the tracking strategy
  * name to the name of all the enum constants.
  *  

Modified: java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/TrackData.java
 =============================================================================
--- java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/TrackData.java	(original)
+++ java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/TrackData.java	Wed Apr 27 11:11:32 2016
@@ -1,6 +1,13 @@
 package org.hps.recon.tracking;
 
+import java.util.List;
+import org.apache.commons.math3.util.Pair;
+import org.lcsim.event.EventHeader;
 import org.lcsim.event.GenericObject;
+import org.lcsim.event.LCRelation;
+import org.lcsim.event.RelationalTable;
+import org.lcsim.event.Track;
+import org.lcsim.event.base.BaseRelationalTable;
 
 /**
  * Generic object used to persist track data not available through a Track
@@ -155,4 +162,24 @@
     public boolean isFixedSize() {
         return true;
     }
+
+    private static Pair<EventHeader, RelationalTable> trackDataToTrackCache = null;
+
+    public static RelationalTable getTrackDataToTrackTable(EventHeader event) {
+        if (trackDataToTrackCache == null || trackDataToTrackCache.getFirst() != event) {
+            RelationalTable trackDataToTrack = new BaseRelationalTable(RelationalTable.Mode.MANY_TO_MANY, RelationalTable.Weighting.UNWEIGHTED);
+            List<LCRelation> hitrelations = event.get(LCRelation.class, TRACK_DATA_RELATION_COLLECTION);
+            for (LCRelation relation : hitrelations) {
+                if (relation != null && relation.getFrom() != null && relation.getTo() != null) {
+                    trackDataToTrack.add(relation.getFrom(), relation.getTo());
+                }
+            }
+            trackDataToTrackCache = new Pair<EventHeader, RelationalTable>(event, trackDataToTrack);
+        }
+        return trackDataToTrackCache.getSecond();
+    }
+
+    public static GenericObject getTrackData(EventHeader event, Track track) {
+        return (GenericObject) getTrackDataToTrackTable(event).from(track);
+    }
 }

Modified: java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/TrackDataDriver.java
 =============================================================================
--- java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/TrackDataDriver.java	(original)
+++ java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/TrackDataDriver.java	Wed Apr 27 11:11:32 2016
@@ -8,7 +8,6 @@
 
 import org.lcsim.detector.tracker.silicon.HpsSiSensor;
 import org.lcsim.event.EventHeader;
-import org.lcsim.event.GenericObject;
 import org.lcsim.event.LCRelation;
 import org.lcsim.event.RawTrackerHit;
 import org.lcsim.event.RelationalTable;
@@ -16,7 +15,6 @@
 import org.lcsim.event.TrackState;
 import org.lcsim.event.TrackerHit;
 import org.lcsim.event.base.BaseLCRelation;
-import org.lcsim.event.base.BaseRelationalTable;
 import org.lcsim.fit.helicaltrack.HelicalTrackCross;
 import org.lcsim.fit.helicaltrack.HelicalTrackHit;
 import org.lcsim.fit.helicaltrack.HelicalTrackStrip;
@@ -25,8 +23,8 @@
 import org.lcsim.util.Driver;
 
 /**
- * Driver used to persist additional {@link Track} information via a
- * {@link GenericObject}.
+ * Driver used to persist additional {@link org.lcsim.event.Track} information via a 
+ * {@link org.lcsim.event.GenericObject} collection.
  *
  * @author Omar Moreno, UCSC
  * @author Sho Uemura, SLAC
@@ -34,7 +32,7 @@
 public final class TrackDataDriver extends Driver {
 
     /** logger **/
-    private static Logger LOGGER  = Logger.getLogger(TrackDataDriver.class.getPackage().getName());
+    private static final Logger LOGGER  = Logger.getLogger(TrackDataDriver.class.getPackage().getName());
     
     
     /** The B field map */
@@ -107,6 +105,7 @@
      * 
      * @param detector LCSim {@link Detector} geometry 
      */     
+    @Override
     protected void detectorChanged(Detector detector) { 
        
         // Get the field map from the detector object
@@ -121,6 +120,7 @@
      * 
      * @param event : LCSim event
      */
+    @Override
     protected void process(EventHeader event) {
 
         // Check if the event contains a collection of the type Track. If it
@@ -135,15 +135,11 @@
 
         // Get the collection of LCRelations relating RotatedHelicalTrackHits to
         // HelicalTrackHits
-        List<LCRelation> rotatedHthToHthRelations = event.get(LCRelation.class, ROTATED_HTH_REL_COL_NAME);
-        BaseRelationalTable hthToRotatedHth = new BaseRelationalTable(RelationalTable.Mode.ONE_TO_ONE,
-                        RelationalTable.Weighting.UNWEIGHTED);
-        hthToRotatedHth.addRelations(rotatedHthToHthRelations);
 
         RelationalTable hitToStrips = TrackUtils.getHitToStripsTable(event);
         RelationalTable hitToRotated = TrackUtils.getHitToRotatedTable(event);
 
-        List<HelicalTrackHit> rotatedHths = event.get(HelicalTrackHit.class, ROTATED_HTH_COL_NAME);
+//        List<HelicalTrackHit> rotatedHths = event.get(HelicalTrackHit.class, ROTATED_HTH_COL_NAME);
 
         // Create a container that will be used to store all TrackData objects.
         List<TrackData> trackDataCollection = new ArrayList<TrackData>();
@@ -159,21 +155,21 @@
         // residuals
         List<LCRelation> trackToTrackResidualsRelations = new ArrayList<LCRelation>();
 
-        double xResidual = 0;
-        double yResidual = 0;
-
-        float totalT0 = 0;
-        float totalHits = 0;
-        float trackTime = 0;
+        double xResidual;
+        double yResidual;
+
+        float totalT0;
+        float totalHits;
+        float trackTime;
 
         int trackerVolume = -1;
 
-        boolean isFirstHit = true;
-
-        HpsSiSensor sensor = null;
-        Hep3Vector stereoHitPosition = null;
-        Hep3Vector trackPosition = null;
-        HelicalTrackHit helicalTrackHit = null;
+        boolean isFirstHit;
+
+        HpsSiSensor sensor;
+        Hep3Vector stereoHitPosition;
+        Hep3Vector trackPosition;
+        HelicalTrackHit helicalTrackHit;
 
         List<Double> t0Residuals = new ArrayList<Double>();
         List<Double> trackResidualsX = new ArrayList<Double>();
@@ -183,9 +179,7 @@
 
         // Loop over each of the track collections retrieved from the event
         for (List<Track> tracks : trackCollections) {
-            
-            
-
+                        
             // Loop over all the tracks in the event
             for (Track track : tracks) {
 
@@ -198,7 +192,10 @@
                 stereoLayers.clear();
                 isFirstHit = true;
 
-                //
+//                TrackState trackStateForResiduals = TrackUtils.getTrackStateAtLocation(track, TrackState.AtLastHit);
+//                if (trackStateForResiduals == null ) trackStateForResiduals= TrackUtils.getTrackStateAtLocation(track, TrackState.AtIP);
+                TrackState trackStateForResiduals = TrackUtils.getTrackStateAtLocation(track, TrackState.AtIP);
+                
                 // Change the position of a HelicalTrackHit to be the corrected
                 // one.
                 // FIXME: Now that multiple track collections are being used, 
@@ -216,7 +213,7 @@
                     // Extrapolate the track to the stereo hit position and
                     // calculate track residuals
                     stereoHitPosition = ((HelicalTrackHit) rotatedStereoHit).getCorrectedPosition();
-                    trackPosition = TrackUtils.extrapolateTrack(track, stereoHitPosition.x());
+                    trackPosition = TrackUtils.extrapolateTrack(trackStateForResiduals, stereoHitPosition.x());
                     xResidual = trackPosition.x() - stereoHitPosition.y();
                     yResidual = trackPosition.y() - stereoHitPosition.z();
                     trackResidualsX.add(xResidual);
@@ -230,7 +227,7 @@
                     
                     // Get the HelicalTrackHit corresponding to the 
                     // RotatedHelicalTrackHit associated with a track
-                    helicalTrackHit = (HelicalTrackHit) hthToRotatedHth.from(rotatedStereoHit);
+                    helicalTrackHit = (HelicalTrackHit) hitToRotated.from(rotatedStereoHit);
                     ((HelicalTrackHit) rotatedStereoHit).setPosition(stereoHitPosition.v());
                     stereoHitPosition = CoordinateTransformations.transformVectorToDetector(stereoHitPosition);
                     helicalTrackHit.setPosition(stereoHitPosition.v());
@@ -261,18 +258,7 @@
 
                 // Extrapolate the track to the face of the Ecal and get the TrackState
                 if( TrackType.isGBL(track.getType())) {
-                    TrackState stateLast = null;
-                    TrackState stateIP = null;
-                    for(int ist= 0; ist < track.getTrackStates().size(); ist++) {
-                        if( track.getTrackStates().get(ist).getLocation() == TrackState.AtLastHit ) 
-                            stateLast = track.getTrackStates().get(ist);
-                        if( track.getTrackStates().get(ist).getLocation() == TrackState.AtIP ) 
-                            stateIP = track.getTrackStates().get(ist);
-                    }
-                    if( stateLast == null)
-                        throw new RuntimeException("last hit track state for GBL track was not found");
-//                    TrackState stateEcal = TrackUtils.extrapolateTrackUsingFieldMap(stateLast, extStartPos, ecalPosition, stepSize, bFieldMap);
-//                    track.getTrackStates().add(stateEcal);
+                    TrackState stateIP = TrackUtils.getTrackStateAtLocation(track, TrackState.AtIP);
                     if( stateIP == null)
                         throw new RuntimeException("IP track state for GBL track was not found");
                     TrackState stateEcalIP = TrackUtils.extrapolateTrackUsingFieldMap(stateIP, extStartPos, ecalPosition, stepSize, bFieldMap);
@@ -317,7 +303,7 @@
         }
         
         // Add all collections to the event
-        event.put(TrackData.TRACK_DATA_COLLECTION, trackDataCollection, TrackTimeData.class, 0);
+        event.put(TrackData.TRACK_DATA_COLLECTION, trackDataCollection, TrackData.class, 0);
         event.put(TrackData.TRACK_DATA_RELATION_COLLECTION, trackDataRelations, LCRelation.class, 0);
         event.put(TRK_RESIDUALS_COL_NAME, trackResidualsCollection, TrackResidualsData.class, 0);
         event.put(TRK_RESIDUALS_REL_COL_NAME, trackToTrackResidualsRelations, LCRelation.class, 0);

Modified: java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/TrackQualityData.java
 =============================================================================
--- java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/TrackQualityData.java	(original)
+++ java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/TrackQualityData.java	Wed Apr 27 11:11:32 2016
@@ -17,10 +17,7 @@
     private final double[] doubles;
 
     /**
-     * Default Ctor
-     *
-     * @param trackerVolume : The SVT volume to which the track used to
-     * calculate the residuals corresponds to.
+     * Default Ctor    
      */
     public TrackQualityData() {
         doubles = new double[2];

Modified: java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/TrackResidualsData.java
 =============================================================================
--- java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/TrackResidualsData.java	(original)
+++ java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/TrackResidualsData.java	Wed Apr 27 11:11:32 2016
@@ -13,84 +13,84 @@
  */
 public class TrackResidualsData implements GenericObject {
 
-	List<Double> trackResidualsX = new ArrayList<Double>();
-	List<Float> trackResidualsY = new ArrayList<Float>();
-	List<Integer> layers = new ArrayList<Integer>();
-	
-	/**
-	 * Default Ctor
-	 * 
-	 * @param trackerVolume : The SVT volume to which the track used to calculate
-	 * 						  the residuals corresponds to.
-	 */
-	public TrackResidualsData(int trackerVolume, List<Integer> layers, List<Double> trackResidualsX, List<Float> trackResidualsY){
-		this.layers.addAll(layers);
-		this.layers.add(trackerVolume);
-		this.trackResidualsX.addAll(trackResidualsX);
-		this.trackResidualsY.addAll(trackResidualsY);
-	}
+    List<Double> trackResidualsX = new ArrayList<Double>();
+    List<Float> trackResidualsY = new ArrayList<Float>();
+    List<Integer> layers = new ArrayList<Integer>();
+    
+    /**
+     * Default Ctor
+     * 
+     * @param trackerVolume : The SVT volume to which the track used to calculate
+     *                        the residuals corresponds to.
+     */
+    public TrackResidualsData(int trackerVolume, List<Integer> layers, List<Double> trackResidualsX, List<Float> trackResidualsY){
+        this.layers.addAll(layers);
+        this.layers.add(trackerVolume);
+        this.trackResidualsX.addAll(trackResidualsX);
+        this.trackResidualsY.addAll(trackResidualsY);
+    }
 
-	/**
-	 * 
-	 * @return tracker volume : 0 if top 1 if bottom
-	 */
-	public int getTrackerVolume(){
-		return layers.get(layers.size() - 1);
-	}
-	
-	/**
-	 * 
-	 */
-	@Override
-	public double getDoubleVal(int index) {
-		return trackResidualsX.get(index);
-	}
+    /**
+     * 
+     * @return tracker volume : 0 if top 1 if bottom
+     */
+    public int getTrackerVolume(){
+        return layers.get(layers.size() - 1);
+    }
+    
+    /**
+     * 
+     */
+    @Override
+    public double getDoubleVal(int index) {
+        return trackResidualsX.get(index);
+    }
 
-	/**
-	 * 
-	 */
-	@Override
-	public float getFloatVal(int index) {
-		return trackResidualsY.get(index);
-	}
+    /**
+     * 
+     */
+    @Override
+    public float getFloatVal(int index) {
+        return trackResidualsY.get(index);
+    }
 
-	/**
-	 * 
-	 */
-	@Override
-	public int getIntVal(int index) {
-		return layers.get(index);
-	}
+    /**
+     * 
+     */
+    @Override
+    public int getIntVal(int index) {
+        return layers.get(index);
+    }
 
-	/**
-	 * 
-	 */
-	@Override
-	public int getNDouble() {
-		return trackResidualsX.size();
-	}
+    /**
+     * 
+     */
+    @Override
+    public int getNDouble() {
+        return trackResidualsX.size();
+    }
 
-	/**
-	 * 
-	 */
-	@Override
-	public int getNFloat() {
-		return trackResidualsY.size();
-	}
+    /**
+     * 
+     */
+    @Override
+    public int getNFloat() {
+        return trackResidualsY.size();
+    }
 
-	/**
-	 * 
-	 */
-	@Override
-	public int getNInt() {
-		return layers.size();
-	}
+    /**
+     * 
+     */
+    @Override
+    public int getNInt() {
+        return layers.size();
+    }
 
-	/**
-	 * 
-	 */
-	@Override
-	public boolean isFixedSize() {
-		return false;
-	}
+    /**
+     * 
+     */
+    @Override
+    public boolean isFixedSize() {
+        return false;
+    }
 }

Modified: java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/TrackTimeData.java
 =============================================================================
--- java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/TrackTimeData.java	(original)
+++ java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/TrackTimeData.java	Wed Apr 27 11:11:32 2016
@@ -12,124 +12,124 @@
  */
 public class TrackTimeData implements GenericObject {
 
-	List<Float> trackTimeData = new ArrayList<Float>(); 
-	List<Double> t0Residuals = new ArrayList<Double>(); 
-	List<Integer> layers = new ArrayList<Integer>(); 
-	
-	// Constants
-	private final static int SVT_VOLUME_INDEX = 0;
-	private final static int TRACK_TIME_INDEX = 1;
-	
-	/**
-	 * Default Ctor
-	 * 
-	 * @param trackTime : The mean t0 time of all hits of a track
-	 * @param trackerVolume : The SVT volume to which the track used to calculate
-	 * 						  the track time corresponds to.
-	 *
-	 */
-	public TrackTimeData(float trackerVolume, double trackTime, List<Integer> layers, List<Double> t0Residuals){
-		trackTimeData.add(trackerVolume);
-		trackTimeData.add((float) trackTime);
-		this.layers.addAll(layers);
-		this.t0Residuals.addAll(t0Residuals);
-	}
-	
-	/**
-	 *	 
-	 * 
-	 * @param layer : 
-	 * @param t0Residual : 
-	 * 
-	 */
-	private void addResidual(int layer, double t0Residual) {
-		layers.add(layer); 
-		t0Residuals.add(t0Residual);
-	}
+    List<Float> trackTimeData = new ArrayList<Float>(); 
+    List<Double> t0Residuals = new ArrayList<Double>(); 
+    List<Integer> layers = new ArrayList<Integer>(); 
+    
+    // Constants
+    private final static int SVT_VOLUME_INDEX = 0;
+    private final static int TRACK_TIME_INDEX = 1;
+    
+    /**
+     * Default Ctor
+     * 
+     * @param trackTime : The mean t0 time of all hits of a track
+     * @param trackerVolume : The SVT volume to which the track used to calculate
+     *                        the track time corresponds to.
+     *
+     */
+    public TrackTimeData(float trackerVolume, double trackTime, List<Integer> layers, List<Double> t0Residuals){
+        trackTimeData.add(trackerVolume);
+        trackTimeData.add((float) trackTime);
+        this.layers.addAll(layers);
+        this.t0Residuals.addAll(t0Residuals);
+    }
+    
+    /**
+     *   
+     * 
+     * @param layer : 
+     * @param t0Residual : 
+     * 
+     */
+    private void addResidual(int layer, double t0Residual) {
+        layers.add(layer); 
+        t0Residuals.add(t0Residual);
+    }
 
-	/**
-	 * 
-	 */
-	public double getTrackTime() { 
-	    return trackTimeData.get(TRACK_TIME_INDEX); 
-	}
-	
-	/**
-	 * 
-	 * 
-	 */
-	public double getT0Residual(int layer) { 
-	    return this.getDoubleVal(layer);
-	}
+    /**
+     * 
+     */
+    public double getTrackTime() { 
+        return trackTimeData.get(TRACK_TIME_INDEX); 
+    }
+    
+    /**
+     * 
+     * 
+     */
+    public double getT0Residual(int layer) { 
+        return this.getDoubleVal(layer);
+    }
 
-	/**
-	 * 
-	 */
-	public double getClusterTime(int layer) {
-	   return this.getTrackTime() - this.getT0Residual(layer); 
-	}
-	
-	/**
-	 * 
-	 * 
-	 */
-	public boolean isTopSvtVolume() { 
-	    return (trackTimeData.get(SVT_VOLUME_INDEX) == 0) ? true : false;
-	}
-	
-	/**
-	 * 
-	 */
-	@Override
-	public double getDoubleVal(int index) {
-		return t0Residuals.get(index);
-	}
+    /**
+     * 
+     */
+    public double getClusterTime(int layer) {
+       return this.getTrackTime() - this.getT0Residual(layer); 
+    }
+    
+    /**
+     * 
+     * 
+     */
+    public boolean isTopSvtVolume() { 
+        return (trackTimeData.get(SVT_VOLUME_INDEX) == 0) ? true : false;
+    }
+    
+    /**
+     * 
+     */
+    @Override
+    public double getDoubleVal(int index) {
+        return t0Residuals.get(index);
+    }
 
-	/**
-	 * 
-	 */
-	@Override
-	public float getFloatVal(int index) {
-		return trackTimeData.get(index);
-	}
+    /**
+     * 
+     */
+    @Override
+    public float getFloatVal(int index) {
+        return trackTimeData.get(index);
+    }
 
-	/**
-	 * 
-	 */
-	@Override
-	public int getIntVal(int index) {
-		return layers.get(index);
-	}
+    /**
+     * 
+     */
+    @Override
+    public int getIntVal(int index) {
+        return layers.get(index);
+    }
 
-	/**
-	 * 
-	 */
-	@Override
-	public int getNDouble() {
-		return t0Residuals.size();
-	}
+    /**
+     * 
+     */
+    @Override
+    public int getNDouble() {
+        return t0Residuals.size();
+    }
 
-	/**
-	 * 
-	 */
-	@Override
-	public int getNFloat() {
-		return trackTimeData.size();
-	}
+    /**
+     * 
+     */
+    @Override
+    public int getNFloat() {
+        return trackTimeData.size();
+    }
 
-	/**
-	 * 
-	 */
-	@Override
-	public int getNInt() {
-		return layers.size();
-	}
+    /**
+     * 
+     */
+    @Override
+    public int getNInt() {
+        return layers.size();
+    }
 
-	/**
-	 * 
-	 */
-	@Override
-	public boolean isFixedSize() {
-		return false;
-	}
+    /**
+     * 
+     */
+    @Override
+    public boolean isFixedSize() {
+        return false;
+    }
 }

Modified: java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/TrackUtils.java
 =============================================================================
--- java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/TrackUtils.java	(original)
+++ java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/TrackUtils.java	Wed Apr 27 11:11:32 2016
@@ -1,18 +1,26 @@
 package org.hps.recon.tracking;
 
+import hep.physics.matrix.SymmetricMatrix;
+import hep.physics.vec.BasicHep3Vector;
+import hep.physics.vec.Hep3Matrix;
+import hep.physics.vec.Hep3Vector;
+import hep.physics.vec.VecOp;
+
 import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
-import hep.physics.matrix.SymmetricMatrix;
-import hep.physics.vec.BasicHep3Vector;
-import hep.physics.vec.Hep3Matrix;
-import hep.physics.vec.Hep3Vector;
-import hep.physics.vec.SpacePoint;
-import hep.physics.vec.VecOp;
+import org.apache.commons.math3.util.Pair;
+import org.hps.recon.tracking.EventQuality.Quality;
+import org.hps.recon.tracking.gbl.HelicalTrackStripGbl;
+
+import static org.lcsim.constants.Constants.fieldConversion;
 
 import org.lcsim.detector.ITransform3D;
 import org.lcsim.detector.solids.Box;
@@ -48,10 +56,6 @@
 import org.lcsim.util.swim.Helix;
 import org.lcsim.util.swim.Line;
 import org.lcsim.util.swim.Trajectory;
-import org.hps.recon.tracking.EventQuality.Quality;
-import org.hps.recon.tracking.gbl.HelicalTrackStripGbl;
-
-import static org.lcsim.constants.Constants.fieldConversion;
 
 /**
  * Assorted helper functions for the track and helix objects in lcsim. Re-use as
@@ -60,7 +64,6 @@
  * @author Omar Moreno <[log in to unmask]>
  */
 // TODO: Switch to tracking/LCsim coordinates for the extrapolation output!
-// FIXME: This class should probably be broken up into several different sets of utilities by type. --JM
 public class TrackUtils {
 
     /**
@@ -75,7 +78,7 @@
      *
      * @param track
      * @param x
-     * @return
+     * @return the position along the x-axis
      */
     public static Hep3Vector extrapolateHelixToXPlane(Track track, double x) {
         return extrapolateHelixToXPlane(getHTF(track), x);
@@ -85,13 +88,74 @@
         return extrapolateHelixToXPlane(getHTF(track), x);
     }
     
+    /** 
+     * Change reference point of helix (following L3 Internal Note 1666.)
+     * @param newRefPoint - The new reference point in XY
+     */
+    public static double[] getParametersAtNewRefPoint(double[] newRefPoint, HpsHelicalTrackFit helicalTrackFit) {
+        return getParametersAtNewRefPoint(newRefPoint, helicalTrackFit.getRefPoint(),helicalTrackFit.parameters());
+    }
+    
+    /** 
+     * Change reference point of helix (following L3 Internal Note 1666.)
+     * @param newRefPoint - The new reference point in XY
+     */
+    public static double[] getParametersAtNewRefPoint(double[] newRefPoint, double[] __refPoint, 
+                                                 double[] parameters) {
+
+        double phi0 = parameters[HelicalTrackFit.phi0Index];
+        double curvature =parameters[HelicalTrackFit.curvatureIndex];
+        double dca = parameters[HelicalTrackFit.dcaIndex];
+        double slope = parameters[HelicalTrackFit.slopeIndex]; 
+        double z0 = parameters[HelicalTrackFit.z0Index];
+
+        //take care of phi0 range if needed (this matters for dphi below I think)
+        // L3 defines it in the range [-pi,pi]
+        if(phi0 > Math.PI) 
+            phi0 -= Math.PI*2;
+        
+        double dx = newRefPoint[0] - __refPoint[0];
+        double dy = newRefPoint[1] - __refPoint[1];
+        double sinphi = Math.sin(phi0);
+        double cosphi = Math.cos(phi0);
+        double R = 1.0/curvature;
+
+        // calculate new phi
+        double phinew = Math.atan2( sinphi - dx/(R-dca) , cosphi + dy/(R-dca)  );
+
+        // difference in phi
+        // watch out for ambiguity
+        double dphi = phinew - phi0;
+        if (Math.abs( dphi ) > Math.PI) 
+            throw new RuntimeException("dphi is large " +  dphi + " from phi0 " + phi0 
+                                        + " and phinew " + phinew + " take care of the ambiguity!!??");
+        
+        // calculate new dca
+        double dcanew = dca + dx*sinphi - dy*cosphi + (dx*cosphi + dy*sinphi)*Math.tan( dphi/2. );
+
+        // path length from old to new point
+        double s = -1.0*dphi/curvature;
+
+        // new z0
+        double z0new = z0 + s*slope;
+
+        // new array
+        double[] params = new double[5];
+        params[HelicalTrackFit.phi0Index] = phinew;
+        params[HelicalTrackFit.curvatureIndex] = curvature;
+        params[HelicalTrackFit.dcaIndex] = dcanew;
+        params[HelicalTrackFit.slopeIndex] = slope;
+        params[HelicalTrackFit.z0Index] = z0new;
+        return params;
+    }
+    
 
     /**
      * Extrapolate helix to a position along the x-axis. Re-use HelixUtils.
      *
-     * @param track
+     * @param htf
      * @param x
-     * @return
+     * @return the position along the x-axis
      */
     public static Hep3Vector extrapolateHelixToXPlane(HelicalTrackFit htf, double x) {
         double s = HelixUtils.PathToXPlane(htf, x, 0., 0).get(0);
@@ -282,7 +346,7 @@
      *
      * @param track - to be extrapolated
      * @param z
-     * @return
+     * @return extrapolated position
      */
     public static Hep3Vector extrapolateTrack(Track track, double z) {
         return extrapolateTrack(track.getTrackStates().get(0),z);
@@ -293,7 +357,7 @@
      *
      * @param track - to be extrapolated
      * @param z
-     * @return
+     * @return extrapolated position
      */
     public static Hep3Vector extrapolateTrack(TrackState track, double z) {
 
@@ -329,10 +393,8 @@
     /**
      * Extrapolate track to given position, using dipole position from geometry.
      *
-     * @param helix - to be extrapolated
-     * @param track - position along the x-axis of the helix in lcsim
-     * coordiantes
-     * @return
+     * @param track - position along the x-axis of the helix in lcsim coordinates
+     * @return extrapolated position
      */
     public static Hep3Vector extrapolateTrack(Track track, double z, Detector detector) {
 
@@ -375,7 +437,7 @@
      *
      * @param helix - to be extrapolated
      * @param z - position along the x-axis of the helix in lcsim coordiantes
-     * @return
+     * @return the extrapolated position
      */
     public static Hep3Vector extrapolateTrack(HelicalTrackFit helix, double z) {
         SeedTrack trk = new SeedTrack();
@@ -800,11 +862,11 @@
     
     
     /**
-     * Transform MCParticle into a Helix object. Note that it produces the helix
-     * parameters at nominal x=0 and assumes that there is no field at x<0
-     *
-     * @param mcp MC particle to be transformed
-     * @param org origin to be used for the track 
+     * Transform MCParticle into a {@link HelicalTrackFit} object. Note that it produces the {@link HelicalTrackFit}
+     * parameters at nominal reference point at origin and assumes that there is no field at x<0
+     *
+     * @param mcp - MC particle to be transformed
+     * @param origin  - origin to be used for the track 
      * @return {@link HelicalTrackFit} object based on the MC particle
      */
     public static HelicalTrackFit getHTF(MCParticle mcp, Hep3Vector origin, double Bz) {
@@ -870,27 +932,7 @@
         return htf;
     }
 
-    public static StraightLineTrack findSLTAtZ(Track trk1, double zVal, boolean useFringe) {
-        SeedTrack s1 = (SeedTrack) trk1;
-        HelicalTrackFit htf1 = s1.getSeedCandidate().getHelix();
-        HPSTrack hpstrk1 = new HPSTrack(htf1);
-        Hep3Vector pos1;
-        if (useFringe) {
-            // broken because you need ot provide the Field Map to get this...
-//            pos1 = hpstrk1.getPositionAtZMap(100.0, zVal, 5.0)[0];            
-        } else
-            pos1 = TrackUtils.extrapolateTrack(trk1, zVal);
-        // System.out.printf("%s: Position1 at edge of fringe %s\n",this.getClass().getSimpleName(),pos1.toString());
-        Helix traj = (Helix) hpstrk1.getTrajectory();
-        if (traj == null) {
-            SpacePoint r0 = new SpacePoint(HelixUtils.PointOnHelix(htf1, 0));
-            traj = new Helix(r0, htf1.R(), htf1.phi0(), Math.atan(htf1.slope()));
-        }
-        HelixConverter converter = new HelixConverter(0.);
-        StraightLineTrack slt1 = converter.Convert(traj);
-        // System.out.printf("%s: straight line track: x0=%f,y0=%f,z0=%f dz/dx=%f dydx=%f targetY=%f targetZ=%f \n",this.getClass().getSimpleName(),slt1.x0(),slt1.y0(),slt1.z0(),slt1.dzdx(),slt1.dydx(),slt1.TargetYZ()[0],slt1.TargetYZ()[1]);
-        return slt1;
-    }
+    
 
     public static MCParticle getMatchedTruthParticle(Track track) {
         boolean debug = false;
@@ -984,24 +1026,36 @@
         return new HelicalTrackHit(pos, hitcov, dedx, time, type, rhits, detname, layer, beflag);
     }
 
+    private static Pair<EventHeader, RelationalTable> hitToStripsCache = null;
+
     public static RelationalTable getHitToStripsTable(EventHeader event) {
-        RelationalTable hitToStrips = new BaseRelationalTable(RelationalTable.Mode.MANY_TO_MANY, RelationalTable.Weighting.UNWEIGHTED);
-        List<LCRelation> hitrelations = event.get(LCRelation.class, "HelicalTrackHitRelations");
-        for (LCRelation relation : hitrelations)
-            if (relation != null && relation.getFrom() != null && relation.getTo() != null)
-                hitToStrips.add(relation.getFrom(), relation.getTo());
-
-        return hitToStrips;
-    }
+        if (hitToStripsCache == null || hitToStripsCache.getFirst() != event) {
+            RelationalTable hitToStrips = new BaseRelationalTable(RelationalTable.Mode.MANY_TO_MANY, RelationalTable.Weighting.UNWEIGHTED);
+            List<LCRelation> hitrelations = event.get(LCRelation.class, "HelicalTrackHitRelations");
+            for (LCRelation relation : hitrelations) {
+                if (relation != null && relation.getFrom() != null && relation.getTo() != null) {
+                    hitToStrips.add(relation.getFrom(), relation.getTo());
+                }
+            }
+            hitToStripsCache = new Pair<EventHeader, RelationalTable>(event, hitToStrips);
+        }
+        return hitToStripsCache.getSecond();
+    }
+
+    private static Pair<EventHeader, RelationalTable> hitToRotatedCache = null;
 
     public static RelationalTable getHitToRotatedTable(EventHeader event) {
-
-        RelationalTable hitToRotated = new BaseRelationalTable(RelationalTable.Mode.ONE_TO_ONE, RelationalTable.Weighting.UNWEIGHTED);
-        List<LCRelation> rotaterelations = event.get(LCRelation.class, "RotatedHelicalTrackHitRelations");
-        for (LCRelation relation : rotaterelations)
-            if (relation != null && relation.getFrom() != null && relation.getTo() != null)
-                hitToRotated.add(relation.getFrom(), relation.getTo());
-        return hitToRotated;
+        if (hitToRotatedCache == null || hitToRotatedCache.getFirst() != event) {
+            RelationalTable hitToRotated = new BaseRelationalTable(RelationalTable.Mode.ONE_TO_ONE, RelationalTable.Weighting.UNWEIGHTED);
+            List<LCRelation> rotaterelations = event.get(LCRelation.class, "RotatedHelicalTrackHitRelations");
+            for (LCRelation relation : rotaterelations) {
+                if (relation != null && relation.getFrom() != null && relation.getTo() != null) {
+                    hitToRotated.add(relation.getFrom(), relation.getTo());
+                }
+            }
+            hitToRotatedCache = new Pair<EventHeader, RelationalTable>(event, hitToRotated);
+        }
+        return hitToRotatedCache.getSecond();
     }
 
     public static double getTrackTime(Track track, RelationalTable hitToStrips, RelationalTable hitToRotated) {
@@ -1019,6 +1073,20 @@
         for (TrackerHit hit : track.getTrackerHits())
             hits.addAll(hitToStrips.allFrom(hitToRotated.from(hit)));
         return hits;
+    }
+
+    public static List<TrackerHit> sortHits(Collection<TrackerHit> hits) {
+        List<TrackerHit> hitList = new ArrayList<TrackerHit>(hits);
+        Collections.sort(hitList, new LayerComparator());
+        return hitList;
+    }
+
+    private static class LayerComparator implements Comparator<TrackerHit> {
+
+        @Override
+        public int compare(TrackerHit o1, TrackerHit o2) {
+            return Integer.compare(TrackUtils.getLayer(o1), TrackUtils.getLayer(o2));
+        }
     }
 
     public static boolean hasSharedStrips(Track track1, Track track2, RelationalTable hitToStrips, RelationalTable hitToRotated) {
@@ -1091,7 +1159,7 @@
      * @param trk
      * @param hitToStrips
      * @param hitToRotated
-     * @return
+     * @return isolations for all 12 strip layers
      */
     public static Double[] getIsolations(Track trk, RelationalTable hitToStrips, RelationalTable hitToRotated) {
         Double[] isolations = new Double[12];
@@ -1263,7 +1331,7 @@
      * @param r0
      * @param q
      * @param B
-     * @return
+     * @return the created trajectory
      */
     public static Trajectory getTrajectory(Hep3Vector p0, org.lcsim.spacegeom.SpacePoint r0, double q, double B) {
         SpaceVector p = new CartesianVector(p0.v());
@@ -1279,15 +1347,25 @@
             return new Line(r0, phi, lambda);
     }
 
-    public static TrackState getTrackStateAtECal(Track trk) {
+    /**
+     * Port of Track.getTrackState(int location) from the C++ LCIO API.
+     * @param trk A track.
+     * @param location A TrackState location constant
+     * @return The first matching TrackState; null if none is found.
+     */
+    public static TrackState getTrackStateAtLocation(Track trk, int location) {
         for (TrackState state : trk.getTrackStates()) {
-            if (state.getLocation() == TrackState.AtCalorimeter) {
+            if (state.getLocation() == location) {
                 return state;
             }
         }
         return null;
     }
 
+    public static TrackState getTrackStateAtECal(Track trk) {
+        return getTrackStateAtLocation(trk, TrackState.AtCalorimeter);
+    }
+    
     public static Hep3Vector getBField(Detector detector) {
         return detector.getFieldMap().getField(new BasicHep3Vector(0., 0., 500.0));
     }

Modified: java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/TrackerReconDriver.java
 =============================================================================
--- java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/TrackerReconDriver.java	(original)
+++ java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/TrackerReconDriver.java	Wed Apr 27 11:11:32 2016
@@ -13,11 +13,9 @@
 import java.util.logging.Logger;
 
 import org.lcsim.event.EventHeader;
-import org.lcsim.event.LCRelation;
 import org.lcsim.event.RelationalTable;
 import org.lcsim.event.Track;
 import org.lcsim.event.TrackerHit;
-import org.lcsim.event.base.BaseRelationalTable;
 import org.lcsim.event.base.BaseTrack;
 import org.lcsim.fit.helicaltrack.HelicalTrackHit;
 import org.lcsim.geometry.Detector;
@@ -37,7 +35,7 @@
 public final class TrackerReconDriver extends Driver {
 
     private static final Logger LOGGER = Logger.getLogger(TrackerReconDriver.class.getPackage().getName());
-    
+
     // Debug flag.
     private boolean debug = false;
     // Tracks found across all events.
@@ -65,7 +63,7 @@
     private double rmsTimeCut = -1;
     private boolean rejectUncorrectedHits = true;
     private boolean rejectSharedHits = false;
-    
+
     public TrackerReconDriver() {
     }
 
@@ -145,10 +143,8 @@
 
         // Get B-field Y with no sign. Seed Tracker doesn't like signed B-field components.
         // FIXME Is this always right?
-//        this.bfield = Math.abs((detector.getFieldMap().getField(new BasicHep3Vector(0, 0, 0)).y()));
-        double zvalInTracker=500.0;//50cm...about the middle
-        Hep3Vector fieldInTracker=detector.getFieldMap().getField(new BasicHep3Vector(0, 0, zvalInTracker));
-        LOGGER.config("fieldInTracker at "+zvalInTracker+": Bx = "+fieldInTracker.x()+"; By = "+fieldInTracker.y()+"; Bz = "+fieldInTracker.z());      
+        Hep3Vector fieldInTracker = TrackUtils.getBField(detector);
+        LOGGER.config("fieldInTracker: Bx = " + fieldInTracker.x() + "; By = " + fieldInTracker.y() + "; Bz = " + fieldInTracker.z());
         this.bfield = Math.abs(fieldInTracker.y());
         LOGGER.config(String.format("%s: Set B-field to %.6f\n", this.getClass().getSimpleName(), this.bfield));
 
@@ -165,8 +161,9 @@
         //
         // 1) Driver to run Seed Tracker.
         //
-        if (!strategyResource.startsWith("/"))
+        if (!strategyResource.startsWith("/")) {
             strategyResource = "/org/hps/recon/tracking/strategies/" + strategyResource;
+        }
         List<SeedStrategy> sFinallist = StrategyXMLUtils.getStrategyListFromInputStream(this.getClass().getResourceAsStream(strategyResource));
         SeedTracker stFinal = new SeedTracker(sFinallist, this._useHPSMaterialManager, this.includeMS);
         stFinal.setApplySectorBinning(_applySectorBinning);
@@ -177,14 +174,18 @@
         stFinal.setInputCollectionName(stInputCollectionName);
         stFinal.setTrkCollectionName(trackCollectionName);
         stFinal.setBField(bfield);
-        if (debug)
+        if (debug) {
             stFinal.setDiagnostics(new SeedTrackerDiagnostics());
+        }
         // stFinal.setSectorParams(false); //this doesn't actually seem to do anything
         stFinal.setSectorParams(1, 10000);
         add(stFinal);
 
-        if (rmsTimeCut > 0)
-            stFinal.setTrackCheck(new HitTimeTrackCheck(rmsTimeCut));
+        if (rmsTimeCut > 0) {
+            HitTimeTrackCheck timeCheck = new HitTimeTrackCheck(rmsTimeCut);
+            timeCheck.setDebug(debug);
+            stFinal.setTrackCheck(timeCheck);
+        }
     }
 
     /**
@@ -198,10 +199,11 @@
 
         // Debug printouts.
         if (debug) {
-            if (event.hasCollection(HelicalTrackHit.class, stInputCollectionName))
+            if (event.hasCollection(HelicalTrackHit.class, stInputCollectionName)) {
                 System.out.println(this.getClass().getSimpleName() + ": The HelicalTrackHit collection " + stInputCollectionName + " has " + event.get(HelicalTrackHit.class, stInputCollectionName).size() + " hits.");
-            else
+            } else {
                 System.out.println(this.getClass().getSimpleName() + ": No HelicalTrackHit collection for this event");
+            }
             // Check for Tracks.
             List<Track> tracks = event.get(Track.class, trackCollectionName);
             System.out.println(this.getClass().getSimpleName() + ": The Track collection " + trackCollectionName + " has " + tracks.size() + " tracks.");
@@ -236,27 +238,13 @@
         }
 
         if (rejectSharedHits) {
-
-            RelationalTable hittostrip = new BaseRelationalTable(RelationalTable.Mode.MANY_TO_MANY, RelationalTable.Weighting.UNWEIGHTED);
-            List<LCRelation> hitrelations = event.get(LCRelation.class, "HelicalTrackHitRelations");
-            for (LCRelation relation : hitrelations) {
-                if (relation != null && relation.getFrom() != null && relation.getTo() != null) {
-                    hittostrip.add(relation.getFrom(), relation.getTo());
-                }
-            }
-
-            RelationalTable hittorotated = new BaseRelationalTable(RelationalTable.Mode.ONE_TO_ONE, RelationalTable.Weighting.UNWEIGHTED);
-            List<LCRelation> rotaterelations = event.get(LCRelation.class, "RotatedHelicalTrackHitRelations");
-            for (LCRelation relation : rotaterelations) {
-                if (relation != null && relation.getFrom() != null && relation.getTo() != null) {
-                    hittorotated.add(relation.getFrom(), relation.getTo());
-                }
-            }
+            RelationalTable hitToStrips = TrackUtils.getHitToStripsTable(event);
+            RelationalTable hitToRotated = TrackUtils.getHitToRotatedTable(event);
 
             Map<TrackerHit, List<Track>> stripsToTracks = new HashMap<TrackerHit, List<Track>>();
             for (Track track : tracks) {
                 for (TrackerHit hit : track.getTrackerHits()) {
-                    Collection<TrackerHit> htsList = hittostrip.allFrom(hittorotated.from(hit));
+                    Collection<TrackerHit> htsList = hitToStrips.allFrom(hitToRotated.from(hit));
                     for (TrackerHit strip : htsList) {
                         List<Track> sharedTracks = stripsToTracks.get(strip);
                         if (sharedTracks == null) {
@@ -272,7 +260,7 @@
             while (iter.hasNext()) {
                 Track track = iter.next();
                 for (TrackerHit hit : track.getTrackerHits()) {
-                    Collection<TrackerHit> htsList = hittostrip.allFrom(hittorotated.from(hit));
+                    Collection<TrackerHit> htsList = hitToStrips.allFrom(hitToRotated.from(hit));
                     for (TrackerHit strip : htsList) {
                         List<Track> sharedTracks = stripsToTracks.get(strip);
                         if (sharedTracks.size() > 1) {
@@ -304,15 +292,16 @@
      * @param tracks The list of <code>Track</code> objects.
      */
     private void setTrackType(List<Track> tracks) {
-        for (Track track : tracks)
+        for (Track track : tracks) {
             ((BaseTrack) track).setTrackType(BaseTrack.TrackType.Y_FIELD.ordinal());
+        }
     }
 
     @Override
     public void endOfData() {
         if (debug) {
             System.out.println("-------------------------------------------");
-            System.out.println(this.getName() + " found " + ntracks + " tracks in " + nevents + " events which is " + ((double) ntracks / (double) nevents) + " tracks per event.");
+            System.out.println(this.getName() + " with strategy " + strategyResource + " found " + ntracks + " tracks in " + nevents + " events which is " + ((double) ntracks / (double) nevents) + " tracks per event.");
         }
     }
 }

Modified: java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/WTrack.java
 =============================================================================
--- java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/WTrack.java	(original)
+++ java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/WTrack.java	Wed Apr 27 11:11:32 2016
@@ -12,9 +12,12 @@
 import org.lcsim.fit.helicaltrack.HelicalTrackFit;
 
 /**
- * Track parameterization representation.
- * 
- * @author phansson
+ * Track representation based on paper
+ * Paul Avery, CBX 98-39, June 9, 1998
+ *  
+ * Used primarily for the algorithm to intersect a helix with a generic plane in space.
+ *  
+ * @author phansson <[log in to unmask]>
  */
 public class WTrack {
 
@@ -25,7 +28,6 @@
     private boolean _debug = false;
     private final int max_iterations_intercept = 10;
     private final double epsilon_intercept = 1e-4;
-
       
     /**
      * Constructor. Assumes that b-field is in detector z direction. 
@@ -34,8 +36,8 @@
      * @param bfield value and sign of magnetic field
      */
     public WTrack(HelicalTrackFit track, double bfield) {
-    	_htf = track;
-    	//_bfield = flip ? -1.0 * bfield : bfield; // flip if needed
+        _htf = track;
+        //_bfield = flip ? -1.0 * bfield : bfield; // flip if needed
         _bfield = bfield; 
         _a = -1 * Constants.fieldConversion * _bfield * Math.signum(track.R());
         double p = track.p(Math.abs(_bfield));
@@ -185,7 +187,7 @@
      * Get point on helix at path length s in arbitrary oriented, constant magnetic field with unit vector h
      * @param s - path length
      * @param h - magnetic field unit vector
-     * @return
+     * @return get a 3D point along the helix
      */
     private Hep3Vector getPointOnHelix(double s, Hep3Vector h) {
         WTrack track = this;
@@ -224,8 +226,8 @@
     }
 
     /*
-    	Calculate the exact position of the new helix parameters at path length s in an arbitrarily oriented, 
-    	constant magnetic field point xp is the point h is a unit vector in the direction of the magnetic field.         
+        Calculate the exact position of the new helix parameters at path length s in an arbitrarily oriented, 
+        constant magnetic field point xp is the point h is a unit vector in the direction of the magnetic field.         
      * @param s - path length
      * @param h - magnetic field unit vector
      * @return track parameters
@@ -262,11 +264,9 @@
      * @param xp point on the plane
      * @param eta unit vector of the plane 
      * @param h unit vector of magnetic field
-     * @return
+     * @return the intersection point of the helix with the plane
      */
     public Hep3Vector getHelixAndPlaneIntercept(Hep3Vector xp, Hep3Vector eta, Hep3Vector h) {
-
-        
 
         int iteration = 1;
         double s_total = 0.;

Modified: java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/axial/HelicalTrack2DHit.java
 =============================================================================
--- java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/axial/HelicalTrack2DHit.java	(original)
+++ java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/axial/HelicalTrack2DHit.java	Wed Apr 27 11:11:32 2016
@@ -11,8 +11,8 @@
  * This class is explicitly for HPS where the length of the
  * sensors are (mostly) along the detector 
  * y-dimension ( == HelicalTrackFit x-dimension);
+ * Copied/Modified from org.lcsim.recon.tracking.helicaltrack.HelicalTrack2DHit.java
  * @author Matt Graham <[log in to unmask]>
- * Copied/Modified from org.lcsim.recon.tracking.helicaltrack.HelicalTrack2DHit.java
  */
 public class HelicalTrack2DHit  extends HelicalTrackHit {
     private double _axmin;//min value along the bend-direction..
@@ -27,8 +27,6 @@
      * @param dEdx deposited energy
      * @param time hit time
      * @param rawhits list of raw hits
-     * @param axmin minimum z for the strip
-     * @param axmax maximum z for the strip
      * @param detname detector name
      * @param layer layer number
      * @param beflag

Modified: java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/gbl/FittedGblTrajectory.java
 =============================================================================
--- java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/gbl/FittedGblTrajectory.java	(original)
+++ java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/gbl/FittedGblTrajectory.java	Wed Apr 27 11:11:32 2016
@@ -1,6 +1,20 @@
 package org.hps.recon.tracking.gbl;
 
+import hep.physics.matrix.SymmetricMatrix;
+import hep.physics.vec.Hep3Vector;
+
+import java.util.Map;
+import java.util.logging.Logger;
+
+import org.apache.commons.math3.util.Pair;
+import org.hps.recon.tracking.HpsHelicalTrackFit;
+import org.hps.recon.tracking.TrackUtils;
+import org.hps.recon.tracking.gbl.matrix.Matrix;
+import org.hps.recon.tracking.gbl.matrix.SymMatrix;
+import org.hps.recon.tracking.gbl.matrix.Vector;
 import org.lcsim.event.Track;
+import org.lcsim.fit.helicaltrack.HelicalTrackFit;
+import org.lcsim.fit.helicaltrack.HelixUtils;
 
 /**
  * A class that collects information about a fitted GBL trajectory. 
@@ -9,6 +23,9 @@
  * 
  */
 public class FittedGblTrajectory {
+    
+    public static Logger LOGGER = Logger.getLogger(FittedGblTrajectory.class.getName());
+
     public enum GBLPOINT {
         IP(0), LAST(1), VERTEX(2);
         private int numVal;
@@ -34,6 +51,7 @@
         }
         
     }
+    
     public static enum GBLPARIDX {
         QOVERP(0),YTPRIME(1),XTPRIME(2),XT(3),YT(4);
         private int _value;
@@ -44,18 +62,101 @@
             return _value;
         }
     };
+    
     private GblTrajectory _traj;
     private double _chi2;
     private double _lost;
     private int _ndf;
     private Track _seed = null;
-    private GBLTrackData _t = null;
+    private Map<Integer, Double> pathLengthMap = null;
+
+    /**
+     * Default constructor.
+     * 
+     * @param traj
+     * @param chi2
+     * @param ndf
+     * @param lost
+     */
     public FittedGblTrajectory(GblTrajectory traj, double chi2, int ndf, double lost) {
         _traj = traj;
         _chi2 = chi2;
         _ndf = ndf;
         _lost = lost;
     }
+    
+    /**
+     * Find the index (or label) of the GBL point on the trajectory from the {@link GBLPOINT}.
+     * @param point
+     * @return the index of the GBL point on the trajectory from the enum
+     */
+    public int getPointIndex(GBLPOINT point) {
+        int gblPointIndex;
+        if (point.compareTo(GBLPOINT.IP) == 0)
+            gblPointIndex = 1;
+        else if (point.compareTo(GBLPOINT.LAST) == 0)
+            gblPointIndex = _traj.getNumPoints();
+        else 
+            throw new RuntimeException("This GBL point " + point.toString() + "( " + point.name() + ") is not valid");
+        return gblPointIndex;
+    }
+    
+    
+    /**
+     * Find the corrections and covariance matrix for a particular {@link GBLPOINT}
+     * @param point
+     * @param locPar
+     * @param locCov
+     */
+    public void getResults(GBLPOINT point, Vector locPar, SymMatrix locCov) {
+        
+        // find the GBL point index
+        int gblPointIndex = getPointIndex(point);
+    
+        // get the results
+        getResults(gblPointIndex, locPar, locCov);
+
+    }
+    
+    
+    /**
+     * Find the corrections and covariance matrix for a particular point on the GBL trajectory
+     * @param iLabel
+     * @param locPar
+     * @param locCov
+     */
+    public void getResults(int iLabel, Vector locPar, SymMatrix locCov) {
+        
+        // Get the result from the trajectory
+        int ok = _traj.getResults(iLabel, locPar, locCov);
+        
+        // check that the fit was ok
+        if( ok != 0)
+            throw new RuntimeException("Trying to extract GBL corrections for fit that failed!?");
+    }
+    
+    
+    /**
+     * Find the path length to this point.
+     * @param point - {@link GBLPOINT} point
+     * @return path length
+     */
+    public double getPathLength(GBLPOINT point) {
+        int gblPointIndex = getPointIndex(point);
+        return getPathLength(gblPointIndex);
+    }
+    
+    /**
+     * Find the path length to this point.
+     * @param iLabel - GBL point index
+     * @return path length
+     */
+    public double getPathLength(int iLabel) {
+        if( !this.pathLengthMap.containsKey(iLabel) ) 
+            throw new RuntimeException("This iLabel " + iLabel + " doesn't exists in the path length map.");
+        return this.pathLengthMap.get(iLabel);
+    }
+    
     public void set_seed(Track seed) {
         _seed = seed;
     }
@@ -74,5 +175,149 @@
     public int get_ndf() {
         return _ndf;
     }
+
+    public void setPathLengthMap(Map<Integer, Double> pathLengthMap) {
+        this.pathLengthMap = pathLengthMap;
+    }
+    
+    public Map<Integer, Double> getPathLengthMap() {
+        if (this.pathLengthMap == null)
+            throw new RuntimeException("No path length map has been set on this trajectory!");
+        return this.pathLengthMap;
+    }
+
+    
+    
+    /**
+     * Get the corrected perigee parameters and covariance matrix for a point on the {@link GblTrajectory}.
+     * 
+     * FIXME the covariance matrix is not properly propagated along the trajectory right now!
+     * 
+     * @param htf - helix to be corrected
+     * @param point - {@link GBLPOINT} on the trajectory
+     * @param bfield - magnitude of B-field.
+     * @return the corrected perigee parameters and covariance matrix
+     */
+    public Pair<double[], SymmetricMatrix> getCorrectedPerigeeParameters(HelicalTrackFit htf, GBLPOINT point, double bfield) {
+        
+        // find the point on the trajectory from the GBLPOINT
+        int iLabel = getPointIndex(point);
+        
+        return getCorrectedPerigeeParameters(htf, iLabel, bfield);
+                
+    }
+
+    
+    /**
+     * Get the corrected perigee parameters and covariance matrix for a point on the {@link GblTrajectory}.
+     * 
+     * FIXME the covariance matrix is not properly propagated along the trajectory right now!
+     * 
+     * @param htf - helix to be corrected
+     * @param iLabel - label of the point on the {@link GblTrajectory}
+     * @param bfield - magnitude of B-field.
+     * @return the corrected perigee parameters
+     */
+    public Pair<double[], SymmetricMatrix> getCorrectedPerigeeParameters(HelicalTrackFit htf, int iLabel, double bfield) {
+
+        // Get corrections from GBL fit
+        Vector locPar = new Vector(5);
+        SymMatrix locCov = new SymMatrix(5);
+
+        // Extract the corrections to the track parameters and the covariance matrix from the GBL trajectory
+        getResults(iLabel, locPar, locCov); 
+
+        // Use the super class to keep track of reference point of the helix
+        HpsHelicalTrackFit helicalTrackFit = new HpsHelicalTrackFit(htf);
+        double[] refIP = helicalTrackFit.getRefPoint();
+
+        // Calculate new reference point for this point
+        // This is the intersection of the helix with the plane
+        // The trajectory has this information already in the form of a map between GBL point and path length
+        double pathLength = getPathLength(iLabel);
+        Hep3Vector refPointVec = HelixUtils.PointOnHelix(helicalTrackFit, pathLength);
+        double[] refPoint = new double[]{refPointVec.x(), refPointVec.y()};
+        
+        LOGGER.finest("pathLength " + pathLength + " -> refPointVec " + refPointVec.toString());
+        
+        // Propagate the helix to new reference point
+        double[] helixParametersAtPoint = TrackUtils.getParametersAtNewRefPoint(refPoint, helicalTrackFit);
+        
+        // Create a new helix with the new parameters and the new reference point
+        HpsHelicalTrackFit helicalTrackFitAtPoint = new HpsHelicalTrackFit(helixParametersAtPoint, helicalTrackFit.covariance(), 
+                                                        helicalTrackFit.chisq(), helicalTrackFit.ndf(), helicalTrackFit.PathMap(), 
+                                                        helicalTrackFit.ScatterMap(), refPoint);
+                
+        // find the corrected perigee track parameters at this point
+        double[] helixParametersAtPointCorrected = GblUtils.getCorrectedPerigeeParameters(locPar, helicalTrackFitAtPoint, bfield);
+        
+        // create a new helix
+        HpsHelicalTrackFit helicalTrackFitAtPointCorrected = new HpsHelicalTrackFit(helixParametersAtPointCorrected, helicalTrackFit.covariance(), 
+                helicalTrackFit.chisq(), helicalTrackFit.ndf(), helicalTrackFit.PathMap(), 
+                helicalTrackFit.ScatterMap(), refPoint);
+        
+        // change reference point back to the original one
+        double[] helixParametersAtIPCorrected = TrackUtils.getParametersAtNewRefPoint(refIP, helicalTrackFitAtPointCorrected);
+        
+        // create a new helix for the new parameters at the IP reference point
+        HpsHelicalTrackFit helicalTrackFitAtIPCorrected = new HpsHelicalTrackFit(helixParametersAtIPCorrected, helicalTrackFit.covariance(), 
+                helicalTrackFit.chisq(), helicalTrackFit.ndf(), helicalTrackFit.PathMap(), 
+                helicalTrackFit.ScatterMap(), refIP);
+        
+        
+        // Calculate the updated covariance
+        Matrix jacobian = GblUtils.getCLToPerigeeJacobian(helicalTrackFit, helicalTrackFitAtIPCorrected, bfield);
+        Matrix helixCovariance = jacobian.times(locCov.times(jacobian.transpose()));
+        SymmetricMatrix cov = new SymmetricMatrix(5);
+        for (int i = 0; i < 5; i++) {
+            for (int j = 0; j < 5; j++) {
+                if (i >= j) {
+                    cov.setElement(i, j, helixCovariance.get(i, j));
+                }
+            }
+        }
+        LOGGER.finest("corrected helix covariance:\n" + cov);
+        
+        double parameters_gbl[] = helicalTrackFitAtIPCorrected.parameters();
+        
+        return new Pair<double[], SymmetricMatrix>(parameters_gbl,cov);
+    }
+
+    
+    
+    /**
+     * Extract kinks across the trajectory.
+     * @return kinks in a {@link GBLKinkData} object.
+     */
+    public GBLKinkData getKinks() {
+        GblTrajectory traj = this._traj;
+        // get corrections from GBL fit
+        Vector locPar = new Vector(5);
+        SymMatrix locCov = new SymMatrix(5);
+        float[] lambdaKinks = new float[traj.getNumPoints() - 1];
+        double[] phiKinks = new double[traj.getNumPoints() - 1];
+
+        double oldPhi = 0, oldLambda = 0;
+        for (int i = 0; i < traj.getNumPoints(); i++) {
+            traj.getResults(i + 1, locPar, locCov); // vertex point
+            double newPhi = locPar.get(GBLPARIDX.XTPRIME.getValue());
+            double newLambda = locPar.get(GBLPARIDX.YTPRIME.getValue());
+            if (i > 0) {
+                lambdaKinks[i - 1] = (float) (newLambda - oldLambda);
+                phiKinks[i - 1] = newPhi - oldPhi;
+                //                System.out.println("phikink: " + (newPhi - oldPhi));
+            }
+            oldPhi = newPhi;
+            oldLambda = newLambda;
+        }
+
+        return new GBLKinkData(lambdaKinks, phiKinks);
+    }
+
+    
+    
+
+    
+
     
 }

Modified: java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/gbl/GBLEventData.java
 =============================================================================
--- java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/gbl/GBLEventData.java	(original)
+++ java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/gbl/GBLEventData.java	Wed Apr 27 11:11:32 2016
@@ -3,87 +3,87 @@
 import org.lcsim.event.GenericObject;
 
 public class GBLEventData implements GenericObject {
-	
-	/*
-	 * 
-	 * Interface enumerator to access the correct data
-	 * 
-	 */
-	private static class GBLINT {
-		public static final int RUNNR = 0;
-		public static final int BANK_INT_SIZE = 1;
-	}
-	private static class GBLDOUBLE {
-		public static final int BFIELD = 0;
-		public static final int BANK_DOUBLE_SIZE = 1;
-	}
-	// array holding the integer data
-	private int bank_int[] = new int[GBLINT.BANK_INT_SIZE];
-	private double bank_double[] = new double[GBLDOUBLE.BANK_DOUBLE_SIZE];
-	
+    
+    /*
+     * 
+     * Interface enumerator to access the correct data
+     * 
+     */
+    private static class GBLINT {
+        public static final int RUNNR = 0;
+        public static final int BANK_INT_SIZE = 1;
+    }
+    private static class GBLDOUBLE {
+        public static final int BFIELD = 0;
+        public static final int BANK_DOUBLE_SIZE = 1;
+    }
+    // array holding the integer data
+    private int bank_int[] = new int[GBLINT.BANK_INT_SIZE];
+    private double bank_double[] = new double[GBLDOUBLE.BANK_DOUBLE_SIZE];
+    
 
-	/**
-	 * Constructor with event number as parameter
-	 * @param eventNumber the event number
-	 * 
-	 */
-	public GBLEventData(int eventNumber,double Bz) {
-		setRunNr(eventNumber);
-		setBfield(Bz);
-	}
-	
-	public void setRunNr(int val) {
-		bank_int[GBLINT.RUNNR] = val;
-	}
-	
-	public int getRunNr() {
-		return this.getIntVal(GBLINT.RUNNR);
-	}
-	
-	public void setBfield(double val) {
-		bank_double[GBLDOUBLE.BFIELD] = val;
-	}
-	
-	public double getBfield() {
-		return this.getDoubleVal(GBLDOUBLE.BFIELD);
-	}
-	
-	
-	@Override
-	public int getNInt() {
-		return GBLINT.BANK_INT_SIZE;
-	}
+    /**
+     * Constructor with event number as parameter
+     * @param eventNumber the event number
+     * 
+     */
+    public GBLEventData(int eventNumber,double Bz) {
+        setRunNr(eventNumber);
+        setBfield(Bz);
+    }
+    
+    public void setRunNr(int val) {
+        bank_int[GBLINT.RUNNR] = val;
+    }
+    
+    public int getRunNr() {
+        return this.getIntVal(GBLINT.RUNNR);
+    }
+    
+    public void setBfield(double val) {
+        bank_double[GBLDOUBLE.BFIELD] = val;
+    }
+    
+    public double getBfield() {
+        return this.getDoubleVal(GBLDOUBLE.BFIELD);
+    }
+    
+    
+    @Override
+    public int getNInt() {
+        return GBLINT.BANK_INT_SIZE;
+    }
 
-	@Override
-	public int getNFloat() {
-		return 0;
-	}
+    @Override
+    public int getNFloat() {
+        return 0;
+    }
 
-	@Override
-	public int getNDouble() {
-		return GBLDOUBLE.BANK_DOUBLE_SIZE;
-	}
+    @Override
+    public int getNDouble() {
+        return GBLDOUBLE.BANK_DOUBLE_SIZE;
+    }
 
-	@Override
-	public int getIntVal(int index) {
-		return bank_int[index];
-	}
+    @Override
+    public int getIntVal(int index) {
+        return bank_int[index];
+    }
 
-	@Override
-	public float getFloatVal(int index) {
-		// TODO Auto-generated method stub
-		return 0;
-	}
+    @Override
+    public float getFloatVal(int index) {
+        // TODO Auto-generated method stub
+        return 0;
+    }
 
-	@Override
-	public double getDoubleVal(int index) {
-		return bank_double[index];
-	}
+    @Override
+    public double getDoubleVal(int index) {
+        return bank_double[index];
+    }
 
-	@Override
-	public boolean isFixedSize() {
-		// TODO Auto-generated method stub
-		return false;
-	}
+    @Override
+    public boolean isFixedSize() {
+        // TODO Auto-generated method stub
+        return false;
+    }
 
 }

Modified: java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/gbl/GBLFileIO.java
 =============================================================================
--- java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/gbl/GBLFileIO.java	(original)
+++ java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/gbl/GBLFileIO.java	Wed Apr 27 11:11:32 2016
@@ -11,8 +11,6 @@
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
-import org.hps.recon.tracking.gbl.GBLOutput.ClParams;
-import org.hps.recon.tracking.gbl.GBLOutput.PerigeeParams;
 import org.hps.svt.alignment.RunAlignment;
 import org.lcsim.fit.helicaltrack.HelicalTrackFit;
 
@@ -47,11 +45,11 @@
         }
     }
     private void openFile(String fileName) {
-    	if(fileName.equalsIgnoreCase("")) {
-    		System.out.printf("%s: no file name specified \n", this.getClass().getSimpleName());
-    		System.exit(1);
-    	}
-    	try {
+        if(fileName.equalsIgnoreCase("")) {
+            System.out.printf("%s: no file name specified \n", this.getClass().getSimpleName());
+            System.exit(1);
+        }
+        try {
             _fWriter = new FileWriter(fileName);
             _pWriter = new PrintWriter(_fWriter);
         } catch (IOException ex) {
@@ -67,34 +65,34 @@
         addLine(String.format("Track perPar (R phi0 slope d0 z0) %.12f %.12f %.12f %.12f %.12f",htf.R(),htf.phi0(),htf.slope(),htf.dca(),htf.z0()));
     }
     
-    String getPerTrackParamStr(PerigeeParams perPar) {
+    String getPerTrackParamStr(GblUtils.PerigeeParams perPar) {
         return String.format("Track perPar (R theta phi d0 z0) %.12f %.12f %.12f %.12f %.12f",1.0/perPar.getKappa(),perPar.getTheta(),perPar.getPhi(),perPar.getD0(),perPar.getZ0());
     }
     
-    void printPerTrackParam(PerigeeParams perPar) {
+    void printPerTrackParam(GblUtils.PerigeeParams perPar) {
         addLine(this.getPerTrackParamStr(perPar));
     }
 
-    String getPerTrackParamTruthStr(PerigeeParams perPar) {
+    String getPerTrackParamTruthStr(GblUtils.PerigeeParams perPar) {
         return String.format("Truth perPar (kappa theta phi d0 z0) %.12f %.12f %.12f %.12f %.12f",perPar.getKappa(),perPar.getTheta(),perPar.getPhi(),perPar.getD0(),perPar.getZ0());
     }
 
-    void printPerTrackParamTruth(PerigeeParams perPar) {
+    void printPerTrackParamTruth(GblUtils.PerigeeParams perPar) {
         addLine(this.getPerTrackParamTruthStr(perPar));
     }
 
-    String getClTrackParamTruthStr(ClParams perPar) {
+    String getClTrackParamTruthStr(GblUtils.ClParams perPar) {
         return String.format("Truth clPar (q/p lambda phi xT yT) %.12f %.12f %.12f %.12f %.12f",perPar.getQoverP(),perPar.getLambda(),perPar.getPhi(),perPar.getXt(),perPar.getYt());
     }
 
-    void printClTrackParamTruth(ClParams perPar) {
+    void printClTrackParamTruth(GblUtils.ClParams perPar) {
         addLine(this.getClTrackParamTruthStr(perPar));
     }
 
-    String getClTrackParamStr(ClParams perPar) {
+    String getClTrackParamStr(GblUtils.ClParams perPar) {
         return String.format("Track clPar (q/p lambda phi xT yT) %.12f %.12f %.12f %.12f %.12f",perPar.getQoverP(),perPar.getLambda(),perPar.getPhi(),perPar.getXt(),perPar.getYt());
     }
-    void printClTrackParam(ClParams perPar) {
+    void printClTrackParam(GblUtils.ClParams perPar) {
         addLine(String.format("%s",this.getClTrackParamStr(perPar)));
     }
 

Modified: java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/gbl/GBLKinkData.java
 =============================================================================
--- java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/gbl/GBLKinkData.java	(original)
+++ java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/gbl/GBLKinkData.java	Wed Apr 27 11:11:32 2016
@@ -1,6 +1,13 @@
 package org.hps.recon.tracking.gbl;
 
+import java.util.List;
+import org.apache.commons.math3.util.Pair;
+import org.lcsim.event.EventHeader;
 import org.lcsim.event.GenericObject;
+import org.lcsim.event.LCRelation;
+import org.lcsim.event.RelationalTable;
+import org.lcsim.event.Track;
+import org.lcsim.event.base.BaseRelationalTable;
 
 /**
  * Generic object used to persist GBL kink data.
@@ -94,4 +101,27 @@
     public boolean isFixedSize() {
         return true;
     }
+
+    private static Pair<EventHeader, RelationalTable> kinkDataToTrackCache = null;
+
+    public static RelationalTable getKinkDataToTrackTable(EventHeader event) {
+        if (kinkDataToTrackCache == null || kinkDataToTrackCache.getFirst() != event) {
+            RelationalTable kinkDataToTrack = new BaseRelationalTable(RelationalTable.Mode.MANY_TO_MANY, RelationalTable.Weighting.UNWEIGHTED);
+            if (event.hasCollection(LCRelation.class, DATA_RELATION_COLLECTION)) {
+                List<LCRelation> relations = event.get(LCRelation.class, DATA_RELATION_COLLECTION);
+                for (LCRelation relation : relations) {
+                    if (relation != null && relation.getFrom() != null && relation.getTo() != null) {
+                        kinkDataToTrack.add(relation.getFrom(), relation.getTo());
+                    }
+                }
+            }
+            kinkDataToTrackCache = new Pair<EventHeader, RelationalTable>(event, kinkDataToTrack);
+        }
+        return kinkDataToTrackCache.getSecond();
+    }
+
+    public static GenericObject getKinkData(EventHeader event, Track track) {
+        return (GenericObject) getKinkDataToTrackTable(event).from(track);
+    }
+
 }

Modified: java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/gbl/GBLOutput.java
 =============================================================================
--- java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/gbl/GBLOutput.java	(original)
+++ java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/gbl/GBLOutput.java	Wed Apr 27 11:11:32 2016
@@ -40,8 +40,6 @@
 import org.lcsim.geometry.subdetector.BarrelEndcapFlag;
 import org.lcsim.recon.tracking.digitization.sisim.SiTrackerHitStrip1D;
 import org.lcsim.recon.tracking.digitization.sisim.TrackerHitType;
-import org.lcsim.recon.tracking.seedtracker.SeedCandidate;
-import org.lcsim.recon.tracking.seedtracker.SeedTrack;
 
 /**
  * Calculate the input needed for Millepede minimization.
@@ -153,15 +151,13 @@
 
     void printGBL(Track trk, List<SiTrackerHitStrip1D> stripHits, GBLTrackData gtd, List<GBLStripClusterData> stripClusterDataList, List<MCParticle> mcParticles, List<SimTrackerHit> simTrackerHits, boolean isMC) {
 
-        SeedTrack st = (SeedTrack) trk;
-        SeedCandidate seed = st.getSeedCandidate();
-        HelicalTrackFit htf = seed.getHelix();
+        HelicalTrackFit htf = TrackUtils.getHTF(trk);
 
         // Find scatter points along the path
         ScatterPoints scatters = _scattering.FindHPSScatterPoints(htf);
 
         // Hits on track
-        List<HelicalTrackHit> hits = seed.getHits();
+        List<TrackerHit> hits = trk.getTrackerHits();
 
         // Find the truth particle of the track
         MCParticle mcp = null;
@@ -171,7 +167,7 @@
         if (isMC) {
             
             // find the truth particle for this track
-            mcp = getMatchedTruthParticle(trk);
+            mcp = TrackUtils.getMatchedTruthParticle(trk);
 
             // check if this is an A' event
             for(MCParticle part : mcParticles) {
@@ -224,8 +220,8 @@
         // Use the truth helix as the initial track for GBL?
         //htf = htfTruth;
         // Get perigee parameters to curvilinear frame
-        PerigeeParams perPar = new PerigeeParams(htf, bFieldVector.z());
-        PerigeeParams perParTruth = new PerigeeParams(htfTruth, bFieldVector.z());
+        GblUtils.PerigeeParams perPar = new GblUtils.PerigeeParams(htf, bFieldVector.z());
+        GblUtils.PerigeeParams perParTruth = new GblUtils.PerigeeParams(htfTruth, bFieldVector.z());
 
         //GBLDATA
         gtd.setPerigeeTrackParameters(perPar);
@@ -236,8 +232,8 @@
 
         // Get curvilinear parameters
         if (textFile != null) {
-            ClParams clPar = new ClParams(htf, bFieldVector.z());
-            ClParams clParTruth = new ClParams(htfTruth, bFieldVector.z());
+            GblUtils.ClParams clPar = new GblUtils.ClParams(htf, bFieldVector.z());
+            GblUtils.ClParams clParTruth = new GblUtils.ClParams(htfTruth, bFieldVector.z());
             textFile.printClTrackParam(clPar);
             textFile.printClTrackParamTruth(clParTruth);
 
@@ -248,7 +244,7 @@
         }
 
         // find the projection from the I,J,K to U,V,T curvilinear coordinates
-        Hep3Matrix perToClPrj = getPerToClPrj(htf);
+        Hep3Matrix perToClPrj = GblUtils.getPerToClPrj(htf);
 
         //GBLDATA
         for (int row = 0; row < perToClPrj.getNRows(); ++row) {
@@ -326,7 +322,7 @@
                      continue;
             } 
             else {
-                hit = hits.get(ihit);
+                hit = (HelicalTrackHit) hits.get(ihit);
                 htc = (HelicalTrackCross) hit;
                 strips = htc.getStrips();
                 correctedHitPosition = hit.getCorrectedPosition();
@@ -782,171 +778,10 @@
         }
     }
 
-    MCParticle getMatchedTruthParticle(Track track) {
-        boolean debug = false;
-
-        Map<MCParticle, Integer> particlesOnTrack = new HashMap<MCParticle, Integer>();
-
-        if (debug) {
-            System.out.printf("getmatched mc particle from %d tracker hits on the track \n", track.getTrackerHits().size());
-        }
-
-        for (TrackerHit hit : track.getTrackerHits()) {
-            List<MCParticle> mcps = ((HelicalTrackHit) hit).getMCParticles();
-            if (mcps == null) {
-                System.out.printf("%s: warning, this hit (layer %d pos=%s) has no mc particles.\n", this.getClass().getSimpleName(), ((HelicalTrackHit) hit).Layer(), ((HelicalTrackHit) hit).getCorrectedPosition().toString());
-            } else {
-                if (debug) {
-                    System.out.printf("%s: this hit (layer %d pos=%s) has %d mc particles.\n", this.getClass().getSimpleName(), ((HelicalTrackHit) hit).Layer(), ((HelicalTrackHit) hit).getCorrectedPosition().toString(), mcps.size());
-                }
-                for (MCParticle mcp : mcps) {
-                    if (!particlesOnTrack.containsKey(mcp)) {
-                        particlesOnTrack.put(mcp, 0);
-                    }
-                    int c = particlesOnTrack.get(mcp);
-                    particlesOnTrack.put(mcp, c + 1);
-                }
-            }
-        }
-        if (debug) {
-            System.out.printf("Track p=[ %f, %f, %f] \n", track.getTrackStates().get(0).getMomentum()[0], track.getTrackStates().get(0).getMomentum()[1], track.getTrackStates().get(0).getMomentum()[1]);
-            System.out.printf("FOund %d particles\n", particlesOnTrack.size());
-            for (Map.Entry<MCParticle, Integer> entry : particlesOnTrack.entrySet()) {
-                System.out.printf("%d hits assigned to %d p=%s \n", entry.getValue(), entry.getKey().getPDGID(), entry.getKey().getMomentum().toString());
-            }
-        }
-        Map.Entry<MCParticle, Integer> maxEntry = null;
-        for (Map.Entry<MCParticle, Integer> entry : particlesOnTrack.entrySet()) {
-            if (maxEntry == null || entry.getValue().compareTo(maxEntry.getValue()) > 0) {
-                maxEntry = entry; //if ( maxEntry != null ) {
-            }        //    if(entry.getValue().compareTo(maxEntry.getValue()) < 0) continue;
-        }        //}
-        //maxEntry = entry;
-        if (debug) {
-            if (maxEntry != null) {
-                System.out.printf("Matched particle with pdgId=%d and mom %s to track with charge %d and momentum [%f %f %f]\n",
-                        maxEntry.getKey().getPDGID(), maxEntry.getKey().getMomentum().toString(),
-                        track.getCharge(), track.getTrackStates().get(0).getMomentum()[0], track.getTrackStates().get(0).getMomentum()[1], track.getTrackStates().get(0).getMomentum()[2]);
-            } else {
-                System.out.printf("No truth particle found on this track\n");
-            }
-        }
-        return maxEntry == null ? null : maxEntry.getKey();
-    }
-
-//    private BasicMatrix getJacPerToCl(HelicalTrackFit htf) {
-//        System.out.printf("%s: getJacPerToCl\n", this.getClass().getSimpleName());
-//        //use propoerly normalized B-field
-//        Hep3Vector Bnorm = VecOp.mult(Constants.fieldConversion, _B);
-//        //init jacobian to zero
-//        BasicMatrix j = new BasicMatrix(5, 5);
-//        initZero(j);
-//        double lambda = Math.atan(htf.slope());
-//        double q = Math.signum(htf.R());
-//        double theta = Math.PI / 2.0 - lambda;
-//        Hep3Vector T = HelixUtils.Direction(htf, 0.);
-//        Hep3Vector p = VecOp.mult(htf.p(Math.abs(_B.z())), T);
-//        double pT = htf.pT(Math.abs(_B.z()));
-//        Hep3Vector H = VecOp.mult(1. / (Bnorm.magnitude()), Bnorm);
-//        Hep3Vector Z = new BasicHep3Vector(0, 0, 1);
-//        Hep3Vector J = VecOp.mult(1. / VecOp.cross(T, Z).magnitude(), VecOp.cross(T, Z));
-//        Hep3Vector U = VecOp.mult(-1, J);
-//        Hep3Vector V = VecOp.cross(T, U);
-//        double alpha = VecOp.cross(H, T).magnitude();
-//        Hep3Vector N = VecOp.mult(1. / alpha, VecOp.cross(H, T));
-//        Hep3Vector K = Z;
-//        double Q = -Bnorm.magnitude() * q / p.magnitude();
-//        double kappa = -1.0 * q * Bnorm.z() / pT;
-//
-//        if (this._debug != 0) {
-//            System.out.printf("%s: Bnorm=%s mag(Bnorm)=%f\n", this.getClass().getSimpleName(), Bnorm.toString(), Bnorm.magnitude());
-//            System.out.printf("%s: p=%s |p|=%f pT=%f\n", this.getClass().getSimpleName(), p.toString(), p.magnitude(), pT);
-//            System.out.printf("%s: q=%f\n", this.getClass().getSimpleName(), q);
-//            System.out.printf("%s: q/p=%f\n", this.getClass().getSimpleName(), q / p.magnitude());
-//            System.out.printf("%s: T=%s\n", this.getClass().getSimpleName(), T.toString());
-//            System.out.printf("%s: H=%s\n", this.getClass().getSimpleName(), H.toString());
-//            System.out.printf("%s: kappa=%f\n", this.getClass().getSimpleName(), kappa);
-//            System.out.printf("%s: alpha=%f Q=%f \n", this.getClass().getSimpleName(), alpha, Q);
-//            System.out.printf("%s: J=%s \n", this.getClass().getSimpleName(), J.toString());
-//            System.out.printf("%s: V=%s \n", this.getClass().getSimpleName(), V.toString());
-//            System.out.printf("%s: N=%s \n", this.getClass().getSimpleName(), N.toString());
-//            System.out.printf("%s: TdotJ=%f \n", this.getClass().getSimpleName(), VecOp.dot(T, J));
-//            System.out.printf("%s: VdotN=%f \n", this.getClass().getSimpleName(), VecOp.dot(V, N));
-//            System.out.printf("%s: TdotK=%f \n", this.getClass().getSimpleName(), VecOp.dot(T, K));
-//            System.out.printf("%s: UdotN=%f \n", this.getClass().getSimpleName(), VecOp.dot(U, N));
-//        }
-//
-//        j.setElement(0, 0, -1.0 * Math.sin(theta) / Bnorm.z());
-//
-//        j.setElement(0, 1, q / (p.magnitude() * Math.tan(theta)));
-//
-//        j.setElement(1, 1, -1);
-//
-//        j.setElement(1, 3, -alpha * Q * VecOp.dot(T, J) * VecOp.dot(V, N));
-//
-//        j.setElement(1, 4, -alpha * Q * VecOp.dot(T, K) * VecOp.dot(V, N));
-//
-//        j.setElement(2, 2, 1);
-//
-//        j.setElement(2, 3, -alpha * Q * VecOp.dot(T, J) * VecOp.dot(U, N) / Math.cos(lambda));
-//
-//        j.setElement(2, 4, -alpha * Q * VecOp.dot(T, K) * VecOp.dot(U, N) / Math.cos(lambda));
-//
-//        j.setElement(3, 3, -1);
-//
-//        j.setElement(4, 4, VecOp.dot(V, K));
-//
-//        if (_debug > 0) {
-//            System.out.printf("%s: lambda= J(1,1)=%f  * theta + J(1,3)=%f * eps + J(1,4)=%f * z0 \n",
-//                    this.getClass().getSimpleName(),
-//                    j.e(1, 1), j.e(1, 3), j.e(1, 4));
-//
-//        }
-//
-//        return j;
-//
-//    }
-    /**
-     * Transform MCParticle into a Helix object. Note that it produces the helix
-     * parameters at nominal x=0 and assumes that there is no field at x<0
-     *
-     * @param mcp MC particle to be transformed
-     * @return helix object based on the MC particle
-     */
-//    private HelicalTrackFit getHTF(MCParticle mcp) {
-//        Hep3Vector org = this._hpstrans.transformVectorToTracking(mcp.getOrigin());
-//        Hep3Vector p = this._hpstrans.transformVectorToTracking(mcp.getMomentum());
-//        // Move to x=0 if needed
-//        if(org.x() < 0.) { 
-//        	double dydx = p.y()/p.x();
-//        	double dzdx = p.z()/p.x();
-//        	double delta_x = -1. * org.x(); 
-//        	double y = delta_x * dydx;
-//        	double z = delta_x * dzdx;
-//        	double x = org.x() + delta_x;
-//        	if( Math.abs(x) > 1e-8) throw new RuntimeException("Error: origin is not zero!");
-//        	Hep3Vector old = org;
-//        	org = new BasicHep3Vector(x,y,z);
-//        	System.out.printf("org %s p %s -> org %s\n", old.toString(),p.toString(),org.toString());
-//        } else {
-//        	org = this._hpstrans.transformVectorToTracking(mcp.getOrigin());
-//        }
-//        
-//        
-//        
-//        HelixParamCalculator helixParamCalculator = new HelixParamCalculator(p, org, -1*((int)mcp.getCharge()), -1.0*this._B.z());
-//        double par[] = new double[5];
-//        par[HelicalTrackFit.dcaIndex] = helixParamCalculator.getDCA();
-//        par[HelicalTrackFit.slopeIndex] = helixParamCalculator.getSlopeSZPlane();
-//        par[HelicalTrackFit.phi0Index] = helixParamCalculator.getPhi0();
-//        par[HelicalTrackFit.curvatureIndex] = 1.0/helixParamCalculator.getRadius();
-//        par[HelicalTrackFit.z0Index] = helixParamCalculator.getZ0();
-//        SymmetricMatrix cov = new SymmetricMatrix(5);
-//        for(int i=0;i<cov.getNRows();++i) cov.setElement(i, i, 1.);
-//        HelicalTrackFit htf = new HelicalTrackFit(par, cov, new double[2], new int[2], null, null);
-//        return htf;
-//    }
-    private double truthTrackFitChi2(PerigeeParams perPar, PerigeeParams perParTruth, SymmetricMatrix covariance) {
+    
+    
+
+    private double truthTrackFitChi2(GblUtils.PerigeeParams perPar, GblUtils.PerigeeParams perParTruth, SymmetricMatrix covariance) {
         //re-shuffle the param vector to match the covariance order of parameters
         BasicMatrix p = new BasicMatrix(1, 5);
         p.setElement(0, 0, perPar.getD0());
@@ -1007,190 +842,6 @@
         return Math.sqrt(Math.pow(E1 + E2, 2) - VecOp.add(p1vec, p2vec).magnitudeSquared());
     }
 
-    private static BasicMatrix getPerParVector(double kappa, double theta, double phi, double d0, double z0) {
-        BasicMatrix perPar = new BasicMatrix(1, 5);
-        perPar.setElement(0, 0, kappa);
-        perPar.setElement(0, 1, theta);
-        perPar.setElement(0, 2, phi);
-        perPar.setElement(0, 3, d0);
-        perPar.setElement(0, 4, z0);
-        return perPar;
-    }
-
-    private static BasicMatrix getPerParVector(HelicalTrackFit htf, double B) {
-        if (htf != null) {
-            double kappa = -1.0 * Math.signum(B) / htf.R();
-            double theta = Math.PI / 2.0 - Math.atan(htf.slope());
-            return getPerParVector(kappa, theta, htf.phi0(), htf.dca(), htf.z0());
-        }
-        return new BasicMatrix(1, 5);
-    }
-
-    /**
-     * 
-     * Store perigee track parameters. 
-     * 
-     * @author Per Hansson Adrian <[log in to unmask]>
-     *
-     */
-    public static class PerigeeParams {
-
-        private final BasicMatrix _params;
-
-        public PerigeeParams(HelicalTrackFit htf, double B) {
-            _params = getPerParVector(htf, B);
-        }
-
-        public PerigeeParams(double kappa, double theta, double phi, double d0, double z0) {
-            this._params = getPerParVector(kappa, theta, phi, d0, z0);
-        }
-
-        public BasicMatrix getParams() {
-            return _params;
-        }
-
-        public double getKappa() {
-            return _params.e(0, 0);
-        }
-
-        public double getTheta() {
-            return _params.e(0, 1);
-        }
-
-        public double getPhi() {
-            return _params.e(0, 2);
-        }
-
-        public double getD0() {
-            return _params.e(0, 3);
-        }
-
-        public double getZ0() {
-            return _params.e(0, 4);
-        }
-    }
-
-    /**
-     * Computes the projection matrix from the perigee XY plane variables dca
-     * and z0 into the curvilinear xT,yT,zT frame (U,V,T)
-     *
-     * @param htf input helix to find the track direction
-     * @return 3x3 projection matrix
-     */
-    static Hep3Matrix getPerToClPrj(HelicalTrackFit htf) {
-        Hep3Vector Z = new BasicHep3Vector(0, 0, 1);
-        Hep3Vector T = HelixUtils.Direction(htf, 0.);
-        Hep3Vector J = VecOp.mult(1. / VecOp.cross(T, Z).magnitude(), VecOp.cross(T, Z));
-        Hep3Vector K = Z;
-        Hep3Vector U = VecOp.mult(-1, J);
-        Hep3Vector V = VecOp.cross(T, U);
-        Hep3Vector I = VecOp.cross(J, K);
-
-        BasicHep3Matrix trans = new BasicHep3Matrix();
-        trans.setElement(0, 0, VecOp.dot(I, U));
-        trans.setElement(0, 1, VecOp.dot(J, U));
-        trans.setElement(0, 2, VecOp.dot(K, U));
-        trans.setElement(1, 0, VecOp.dot(I, V));
-        trans.setElement(1, 1, VecOp.dot(J, V));
-        trans.setElement(1, 2, VecOp.dot(K, V));
-        trans.setElement(2, 0, VecOp.dot(I, T));
-        trans.setElement(2, 1, VecOp.dot(J, T));
-        trans.setElement(2, 2, VecOp.dot(K, T));
-        return trans;
-
-        /*
-         Hep3Vector B = new BasicHep3Vector(0, 0, 1); // TODO sign convention?
-         Hep3Vector H = VecOp.mult(1 / bfield, B);
-         Hep3Vector T = HelixUtils.Direction(helix, 0.);
-         Hep3Vector HcrossT = VecOp.cross(H, T);
-         double alpha = HcrossT.magnitude(); // this should be Bvec cross TrackDir/|B|
-         double Q = Math.abs(bfield) * q / p;
-         Hep3Vector Z = new BasicHep3Vector(0, 0, 1);
-         Hep3Vector J = VecOp.mult(1. / VecOp.cross(T, Z).magnitude(), VecOp.cross(T, Z));
-         Hep3Vector K = Z;
-         Hep3Vector U = VecOp.mult(-1, J);
-         Hep3Vector V = VecOp.cross(T, U);
-         Hep3Vector I = VecOp.cross(J, K);
-         Hep3Vector N = VecOp.mult(1 / alpha, VecOp.cross(H, T)); //-cross(T,H)/alpha = -cross(T,Z) = -J
-         double UdotI = VecOp.dot(U, I); // 0,0
-         double NdotV = VecOp.dot(N, V); // 1,1?
-         double NdotU = VecOp.dot(N, U); // 0,1?
-         double TdotI = VecOp.dot(T, I); // 2,0
-         double VdotI = VecOp.dot(V, I); // 1,0
-         double VdotK = VecOp.dot(V, K); // 1,2
-         */
-    }
-
-    
-    /**
-     * 
-     * Store curvilinear track parameters. 
-     * 
-     * @author Per Hansson Adrian <[log in to unmask]>
-     *
-     */
-    public static class ClParams {
-
-        private BasicMatrix _params = new BasicMatrix(1, 5);
-
-        public ClParams(HelicalTrackFit htf, double B) {
-
-            if (htf == null) {
-                return;
-            }
-
-            Hep3Matrix perToClPrj = getPerToClPrj(htf);
-
-            double d0 = -1 * htf.dca(); //sign convention for curvilinear frame
-            double z0 = htf.z0();
-            Hep3Vector vecPer = new BasicHep3Vector(0., d0, z0);
-            //System.out.printf("%s: vecPer=%s\n",this.getClass().getSimpleName(),vecPer.toString());
-
-            Hep3Vector vecCl = VecOp.mult(perToClPrj, vecPer);
-            //System.out.printf("%s: vecCl=%s\n",this.getClass().getSimpleName(),vecCl.toString());
-            double xT = vecCl.x();
-            double yT = vecCl.y();
-            //double zT = vecCl.z();
-
-            double lambda = Math.atan(htf.slope());
-            double q = Math.signum(htf.R());
-            double qOverP = q / htf.p(Math.abs(B));
-            double phi = htf.phi0();
-
-            _params.setElement(0, FittedGblTrajectory.GBLPARIDX.QOVERP.getValue(), qOverP);
-            _params.setElement(0, FittedGblTrajectory.GBLPARIDX.YTPRIME.getValue(), lambda);
-            _params.setElement(0, FittedGblTrajectory.GBLPARIDX.XTPRIME.getValue(), phi);
-            _params.setElement(0, FittedGblTrajectory.GBLPARIDX.XT.getValue(), xT);
-            _params.setElement(0, FittedGblTrajectory.GBLPARIDX.YT.getValue(), yT);
-        }
-
-        public BasicMatrix getParams() {
-            return _params;
-        }
-
-        double getQoverP() {
-            return _params.e(0, FittedGblTrajectory.GBLPARIDX.QOVERP.getValue());
-        }
-
-        double getLambda() {
-            return _params.e(0, FittedGblTrajectory.GBLPARIDX.YTPRIME.getValue());
-        }
-
-        double getPhi() {
-            return _params.e(0, FittedGblTrajectory.GBLPARIDX.XTPRIME.getValue());
-        }
-
-        double getXt() {
-            return _params.e(0, FittedGblTrajectory.GBLPARIDX.XT.getValue());
-        }
-
-        double getYt() {
-            return _params.e(0, FittedGblTrajectory.GBLPARIDX.YT.getValue());
-        }
-
-    }
-    
-    
     /**
      * 
      * {@link HelicalTrackStripGbl} that explicitly uses the given unit vectors when accessed. 

Modified: java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/gbl/GBLOutputDriver.java
 =============================================================================
--- java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/gbl/GBLOutputDriver.java	(original)
+++ java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/gbl/GBLOutputDriver.java	Wed Apr 27 11:11:32 2016
@@ -1,41 +1,30 @@
 package org.hps.recon.tracking.gbl;
 
-import hep.physics.vec.BasicHep3Vector;
 import hep.physics.vec.Hep3Vector;
 import java.io.IOException;
 import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
 import java.util.List;
-import java.util.Map;
-import java.util.Set;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 import org.hps.recon.tracking.EventQuality;
-import org.hps.recon.tracking.StrategyType;
-import org.hps.recon.tracking.TrackType;
 import org.hps.recon.tracking.TrackUtils;
 import org.lcsim.event.EventHeader;
 import org.lcsim.event.LCRelation;
 import org.lcsim.event.MCParticle;
-import org.lcsim.event.RelationalTable;
 import org.lcsim.event.SimTrackerHit;
 import org.lcsim.event.Track;
-import org.lcsim.event.TrackerHit;
 import org.lcsim.event.base.MyLCRelation;
 import org.lcsim.geometry.Detector;
-import org.lcsim.lcio.LCIOConstants;
 import org.lcsim.recon.tracking.digitization.sisim.SiTrackerHitStrip1D;
-import org.lcsim.recon.tracking.seedtracker.SeedTrack;
 import org.lcsim.util.Driver;
 import org.lcsim.util.aida.AIDA;
 
 /**
- * This driver class is used to 1) write lcio collection of GBL info objects OR
- * 2) write GBL info into a unstructures text-based output
+ * This driver class is used to 
+ * 1) write LCIO collection of GBL info objects, or, 
+ * 2) write GBL info into a structured text-based output
  *
- * It uses a helper class that does the actual work. We will port GBL to java
- * and that will replace this driver.
+ * It uses a helper class that does the actual work. 
  *
  * @author Per Hansson Adrian <[log in to unmask]>
  * @version $Id: GBLOutputDriver.java,v 1.9 2013/11/07 03:54:58 phansson Exp $
@@ -58,15 +47,12 @@
     private int totalTracksProcessed = 0;
     private int iTrack = 0;
     private int iEvent = 0;
-    private boolean addBeamspot=false;
+    private boolean addBeamspot = false;
     private double beamspotScatAngle = 0.000001;
     private double beamspotWidthZ = 0.05;
     private double beamspotWidthY = 0.15;
-    private double beamspotTiltZOverY = 15.0*180.0/Math.PI;
-    private double beamspotPosition[] = {0,0,0};
-
-    
-    
+    private double beamspotTiltZOverY = 15.0 * 180.0 / Math.PI;
+    private double beamspotPosition[] = {0, 0, 0};
 
     public GBLOutputDriver() {
     }
@@ -95,7 +81,7 @@
 
     @Override
     public void process(EventHeader event) {
-        List<Track> tracklist = null;
+        List<Track> tracklist;
         if (event.hasCollection(Track.class, trackCollectionName)) {
             tracklist = event.get(Track.class, trackCollectionName);
             if (_debug > 0) {
@@ -107,7 +93,7 @@
 
         List<SiTrackerHitStrip1D> stripHits = event.get(SiTrackerHitStrip1D.class, "StripClusterer_SiTrackerHitStrip1D");
         if (_debug > 0) {
-            System.out.printf("%s: Got %d SiTrackerHitStrip1D in this event\n",this.getClass().getSimpleName(), stripHits.size());
+            System.out.printf("%s: Got %d SiTrackerHitStrip1D in this event\n", this.getClass().getSimpleName(), stripHits.size());
         }
 
         List<MCParticle> mcParticles = new ArrayList<MCParticle>();
@@ -143,13 +129,11 @@
         // Loop over each of the track collections retrieved from the event
         for (Track trk : tracklist) {
             totalTracks++;
-            
-            if (_debug > 0) System.out.printf("%s: PX %f bottom %d\n", this.getClass().getSimpleName(), trk.getPX(), TrackUtils.isBottomTrack(trk, 4)?1:0) ;
-            
-            //if( trk.getPX() < 0.9) continue;
-            
-            //if( TrackUtils.isBottomTrack(trk, 4)) continue;
-            
+
+            if (_debug > 0) {
+                System.out.printf("%s: PX %f bottom %d\n", this.getClass().getSimpleName(), trk.getPX(), TrackUtils.isBottomTrack(trk, 4) ? 1 : 0);
+            }
+
             if (TrackUtils.isGoodTrack(trk, tracklist, EventQuality.Quality.NONE)) {
                 if (_debug > 0) {
                     System.out.printf("%s: Print GBL output for this track\n", this.getClass().getSimpleName());
@@ -228,8 +212,8 @@
         this.isMC = isMC;
     }
 
-    public void setAddBeamspot(boolean add){
-        this.addBeamspot=add;
+    public void setAddBeamspot(boolean add) {
+        this.addBeamspot = add;
     }
 
     public double getBeamspotScatAngle() {
@@ -271,5 +255,8 @@
     public void setBeamspotPosition(double beamspotPosition[]) {
         this.beamspotPosition = beamspotPosition;
     }
-    
+
+    public void setTrackCollectionName(String trackCollectionName) {
+        this.trackCollectionName = trackCollectionName;
+    }
 }

Modified: java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/gbl/GBLRefitterDriver.java
 =============================================================================
--- java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/gbl/GBLRefitterDriver.java	(original)
+++ java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/gbl/GBLRefitterDriver.java	Wed Apr 27 11:11:32 2016
@@ -11,9 +11,11 @@
 import org.hps.recon.tracking.MultipleScattering;
 import org.hps.recon.tracking.TrackUtils;
 import org.lcsim.event.EventHeader;
+import org.lcsim.event.LCRelation;
 import org.lcsim.event.RelationalTable;
 import org.lcsim.event.Track;
 import org.lcsim.event.TrackerHit;
+import org.lcsim.event.base.BaseLCRelation;
 import org.lcsim.geometry.Detector;
 import org.lcsim.lcio.LCIOConstants;
 import org.lcsim.util.Driver;
@@ -26,6 +28,7 @@
 
     private String inputCollectionName = "MatchedTracks";
     private String outputCollectionName = "GBLTracks";
+    private String trackRelationCollectionName = "MatchedToGBLTrackRelations";
 
     private double bfield;
     private final MultipleScattering _scattering = new MultipleScattering(new MaterialSupervisor());
@@ -66,12 +69,21 @@
         RelationalTable hitToRotated = TrackUtils.getHitToRotatedTable(event);
 
         List<Track> refittedTracks = new ArrayList<Track>();
+        List<LCRelation> trackRelations = new ArrayList<LCRelation>();
+
+        List<GBLKinkData> kinkDataCollection = new ArrayList<GBLKinkData>();
+        List<LCRelation> kinkDataRelations = new ArrayList<LCRelation>();
 
         Map<Track, Track> inputToRefitted = new HashMap<Track, Track>();
         for (Track track : tracks) {
-            Pair<Track, GBLKinkData> newTrack = MakeGblTracks.refitTrack(TrackUtils.getHTF(track), TrackUtils.getStripHits(track, hitToStrips, hitToRotated), track.getTrackerHits(), 5, _scattering, bfield);
+            Pair<Track, GBLKinkData> newTrack = MakeGblTracks.refitTrack(TrackUtils.getHTF(track), TrackUtils.getStripHits(track, hitToStrips, hitToRotated), track.getTrackerHits(), 5, track.getType(), _scattering, bfield);
+//            newTrack.getFirst().
             refittedTracks.add(newTrack.getFirst());
+            trackRelations.add(new BaseLCRelation(track, newTrack.getFirst()));
             inputToRefitted.put(track, newTrack.getFirst());
+
+            kinkDataCollection.add(newTrack.getSecond());
+            kinkDataRelations.add(new BaseLCRelation(newTrack.getSecond(), newTrack.getFirst()));
         }
 
         if (mergeTracks) {
@@ -106,7 +118,7 @@
                         }
                     }
 
-                    Pair<Track, GBLKinkData> mergedTrack = MakeGblTracks.refitTrack(TrackUtils.getHTF(track), TrackUtils.getStripHits(track, hitToStrips, hitToRotated), allHth, 5, _scattering, bfield);
+                    Pair<Track, GBLKinkData> mergedTrack = MakeGblTracks.refitTrack(TrackUtils.getHTF(track), TrackUtils.getStripHits(track, hitToStrips, hitToRotated), allHth, 5, track.getType(), _scattering, bfield);
                     mergedTracks.add(mergedTrack.getFirst());
 //                    System.out.format("%f %f %f\n", fit.get_chi2(), inputToRefitted.get(track).getChi2(), inputToRefitted.get(otherTrack).getChi2());
 //                mergedTrackToTrackList.put(mergedTrack, new ArrayList<Track>());
@@ -131,5 +143,8 @@
         // Put the tracks back into the event and exit
         int flag = 1 << LCIOConstants.TRBIT_HITS;
         event.put(outputCollectionName, refittedTracks, Track.class, flag);
+        event.put(trackRelationCollectionName, trackRelations, LCRelation.class, 0);
+        event.put(GBLKinkData.DATA_COLLECTION, kinkDataCollection, GBLKinkData.class, 0);
+        event.put(GBLKinkData.DATA_RELATION_COLLECTION, kinkDataRelations, LCRelation.class, 0);
     }
 }

Modified: java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/gbl/GBLStripClusterData.java
 =============================================================================
--- java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/gbl/GBLStripClusterData.java	(original)
+++ java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/gbl/GBLStripClusterData.java	Wed Apr 27 11:11:32 2016
@@ -13,55 +13,55 @@
  * @version $Id:
  */
 public class GBLStripClusterData implements GenericObject {
-	
-	/*
-	 * 
-	 * Interface enumerator to access the correct data
-	 * 
-	 */
-	public static class GBLINT {
-		public static final int ID = 0;
-		public static final int BANK_INT_SIZE = 1;
-	}
-	public static class GBLDOUBLE {
-		public static final int PATH3D = 0;
-		public static final int PATH = 1;
-		public static final int UX = 2;
-		public static final int UY = 3;
-		public static final int UZ = 4;
-		public static final int VX = 5;
-		public static final int VY = 6;
-		public static final int VZ = 7;
-		public static final int WX = 8;
-		public static final int WY = 9;
-		public static final int WZ = 10;	
-		public static final int TDIRX = 11;	
-		public static final int TDIRY = 12;	
-		public static final int TDIRZ = 13;	
-		public static final int TPHI = 14;	
-		public static final int UMEAS = 15;	
-		public static final int TPOSU = 16	;	
-		public static final int TPOSV = 17;	
-		public static final int TPOSW = 18;	
-		public static final int UMEASERR = 19;	
-		public static final int MSANGLE = 20;
-		public static final int TLAMBDA = 21;
-		
-		
-		public static final int BANK_DOUBLE_SIZE = 22;
-		
-	}
-	// array holding the integer data
-	private int bank_int[] = new int[GBLINT.BANK_INT_SIZE];
-	// array holding the double data
-	private double bank_double[] = new double[GBLDOUBLE.BANK_DOUBLE_SIZE];
-	
-	/**
-	 * Default constructor
-	 */
-	public GBLStripClusterData(int id) {
-		setId(id);
-	}
+    
+    /*
+     * 
+     * Interface enumerator to access the correct data
+     * 
+     */
+    public static class GBLINT {
+        public static final int ID = 0;
+        public static final int BANK_INT_SIZE = 1;
+    }
+    public static class GBLDOUBLE {
+        public static final int PATH3D = 0;
+        public static final int PATH = 1;
+        public static final int UX = 2;
+        public static final int UY = 3;
+        public static final int UZ = 4;
+        public static final int VX = 5;
+        public static final int VY = 6;
+        public static final int VZ = 7;
+        public static final int WX = 8;
+        public static final int WY = 9;
+        public static final int WZ = 10;    
+        public static final int TDIRX = 11; 
+        public static final int TDIRY = 12; 
+        public static final int TDIRZ = 13; 
+        public static final int TPHI = 14;  
+        public static final int UMEAS = 15; 
+        public static final int TPOSU = 16  ;   
+        public static final int TPOSV = 17; 
+        public static final int TPOSW = 18; 
+        public static final int UMEASERR = 19;  
+        public static final int MSANGLE = 20;
+        public static final int TLAMBDA = 21;
+        
+        
+        public static final int BANK_DOUBLE_SIZE = 22;
+        
+    }
+    // array holding the integer data
+    private int bank_int[] = new int[GBLINT.BANK_INT_SIZE];
+    // array holding the double data
+    private double bank_double[] = new double[GBLDOUBLE.BANK_DOUBLE_SIZE];
+    
+    /**
+     * Default constructor
+     */
+    public GBLStripClusterData(int id) {
+        setId(id);
+    }
         
         /*
         * Constructor from GenericObject
@@ -79,239 +79,239 @@
             }
             
         }
-	
-	/**
-	 * @param set track id to val
-	 */
-	public void setId(int val) {
-		bank_int[GBLINT.ID] = val;
-	}
-	
-	/**
-	 * @return track id for this object
-	 */
-	public int getId() {
-		return this.getIntVal(GBLINT.ID);
-	}
-	
-	/**
-	 * Set path length to this strip cluster
-	 * @param val
-	 */
-	public void setPath(double val) {
-		bank_double[GBLDOUBLE.PATH] = val;
-	}
-	
-	/**
-	 * Get path length to this strip cluster
-	 */
-	public double getPath() {
-		return getDoubleVal(GBLDOUBLE.PATH);
-	}
-
-	/**
-	 * Set path length to this strip cluster
-	 * @param val
-	 */
-	public void setPath3D(double val) {
-		bank_double[GBLDOUBLE.PATH3D] = val;
-	}
-	
-	/**
-	 * Get path length to this strip cluster
-	 */
-	public double getPath3D() {
-		return getDoubleVal(GBLDOUBLE.PATH3D);
-	}
-
-
-	/**
-	 *  Set and get u vector for this strip sensor
-	 */
-	public void setU(Hep3Vector u) {
-		bank_double[GBLDOUBLE.UX] = u.x();
-		bank_double[GBLDOUBLE.UY] = u.y();
-		bank_double[GBLDOUBLE.UZ] = u.z();		
-	}
-	public Hep3Vector getU() {
-		return new BasicHep3Vector(getUx(),getUy(),getUz());
-	}
-	public double getUx() {
-		return getDoubleVal(GBLDOUBLE.UX);
-	}
-	public double getUy() {
-		return getDoubleVal(GBLDOUBLE.UY);
-	}
-	public double getUz() {
-		return getDoubleVal(GBLDOUBLE.UZ);
-	}
-	
-	/**
-	 *  Set and get v vector for this strip sensor
-	 */
-
-	public void setV(Hep3Vector v) {
-		bank_double[GBLDOUBLE.VX] = v.x();
-		bank_double[GBLDOUBLE.VY] = v.y();
-		bank_double[GBLDOUBLE.VZ] = v.z();		
-	}
-	public Hep3Vector getV() {
-		return new BasicHep3Vector(getVx(),getVy(),getVz());
-	}
-	public double getVx() {
-		return getDoubleVal(GBLDOUBLE.VX);
-	}
-	public double getVy() {
-		return getDoubleVal(GBLDOUBLE.VY);
-	}
-	public double getVz() {
-		return getDoubleVal(GBLDOUBLE.VZ);
-	}
-
-	/**
-	 *  Set and get w vector for this strip sensor
-	 */
-
-	public void setW(Hep3Vector v) {
-		bank_double[GBLDOUBLE.WX] = v.x();
-		bank_double[GBLDOUBLE.WY] = v.y();
-		bank_double[GBLDOUBLE.WZ] = v.z();		
-	}
-	public Hep3Vector getW() {
-		return new BasicHep3Vector(getWx(),getWy(),getWz());
-	}
-	public double getWx() {
-		return getDoubleVal(GBLDOUBLE.WX);
-	}
-	public double getWy() {
-		return getDoubleVal(GBLDOUBLE.WY);
-	}
-	public double getWz() {
-		return getDoubleVal(GBLDOUBLE.WZ);
-	}
-
-	/**
-	 * Set track direction at this cluster
-	 * 
-	 * @param tDir
-	 */
-	public void setTrackDir(Hep3Vector v) {
-		bank_double[GBLDOUBLE.TDIRX] = v.x();
-		bank_double[GBLDOUBLE.TDIRY] = v.y();
-		bank_double[GBLDOUBLE.TDIRZ] = v.z();		
-	}
-	public Hep3Vector getTrackDirection() {
-		return new BasicHep3Vector(getTx(),getTy(),getTz());
-	}
-	public double getTx() {
-		return getDoubleVal(GBLDOUBLE.TDIRX);
-	}
-	public double getTy() {
-		return getDoubleVal(GBLDOUBLE.TDIRY);
-	}
-	public double getTz() {
-		return getDoubleVal(GBLDOUBLE.TDIRZ);
-	}
-
-	public void setTrackPhi(double phi) {
-		bank_double[GBLDOUBLE.TPHI] = phi;
-	}
-	
-	public double getTrackPhi() {
-		return getDoubleVal(GBLDOUBLE.TPHI);
-	}
-
-	public void setTrackLambda(double lambda) {
-		bank_double[GBLDOUBLE.TLAMBDA] = lambda;
-	}
-	
-	public double getTrackLambda() {
-		return getDoubleVal(GBLDOUBLE.TLAMBDA);
-	}
-
-	
-	public void setMeas(double umeas) {
-		bank_double[GBLDOUBLE.UMEAS] = umeas;
-	}
-	
-	public double getMeas() {
-		return getDoubleVal(GBLDOUBLE.UMEAS);
-	}
-	
-	public void setMeasErr(double x) {
-		bank_double[GBLDOUBLE.UMEASERR] = x;
-	}
-
-	public double getMeasErr() {
-		return getDoubleVal(GBLDOUBLE.UMEASERR);
-	}
-
-	
-	/**
-	 * Set track position in local frame
-	 * @param trkpos_meas
-	 */
-	public void setTrackPos(Hep3Vector trkpos_meas) {
-		bank_double[GBLDOUBLE.TPOSU] = trkpos_meas.x();
-		bank_double[GBLDOUBLE.TPOSV] = trkpos_meas.y();
-		bank_double[GBLDOUBLE.TPOSW] = trkpos_meas.z();
-	}
-
-	public Hep3Vector getTrackPos() {
-		return new BasicHep3Vector(getTrackPosU(),getTrackPosV(),getTrackPosW());
-	}
-	
-	public double getTrackPosU() {
-		return getDoubleVal(GBLDOUBLE.TPOSU);
-	}
-
-	public double getTrackPosV() {
-		return getDoubleVal(GBLDOUBLE.TPOSV);
-	}
-
-	public double getTrackPosW() {
-		return getDoubleVal(GBLDOUBLE.TPOSW);
-	}
-
-	public void setScatterAngle(double scatAngle) {
-		bank_double[GBLDOUBLE.MSANGLE] = scatAngle;
-	}
-	
-	public double getScatterAngle() {
-		return getDoubleVal(GBLDOUBLE.MSANGLE);
-	}
-	
-	/*
-	 * The functions below are all overide from 
-	 * @see org.lcsim.event.GenericObject#getNInt()
-	 */
-	
-	public int getNInt() {
-		return GBLINT.BANK_INT_SIZE;
-	}
-
-	public int getNFloat() {
-		return 0;
-	}
-
-	public int getNDouble() {
-		return GBLDOUBLE.BANK_DOUBLE_SIZE;
-	}
-
-	public int getIntVal(int index) {
-		return bank_int[index];
-	}
-
-	public float getFloatVal(int index) {
-		return 0;
-	}
-
-	public double getDoubleVal(int index) {
-		return bank_double[index];
-	}
-
-	public boolean isFixedSize() {
-		return false;
-	}
+    
+    /**
+     * @param val set track id to val
+     */
+    public void setId(int val) {
+        bank_int[GBLINT.ID] = val;
+    }
+    
+    /**
+     * @return track id for this object
+     */
+    public int getId() {
+        return this.getIntVal(GBLINT.ID);
+    }
+    
+    /**
+     * Set path length to this strip cluster
+     * @param val
+     */
+    public void setPath(double val) {
+        bank_double[GBLDOUBLE.PATH] = val;
+    }
+    
+    /**
+     * Get path length to this strip cluster
+     */
+    public double getPath() {
+        return getDoubleVal(GBLDOUBLE.PATH);
+    }
+
+    /**
+     * Set path length to this strip cluster
+     * @param val
+     */
+    public void setPath3D(double val) {
+        bank_double[GBLDOUBLE.PATH3D] = val;
+    }
+    
+    /**
+     * Get path length to this strip cluster
+     */
+    public double getPath3D() {
+        return getDoubleVal(GBLDOUBLE.PATH3D);
+    }
+
+
+    /**
+     *  Set and get u vector for this strip sensor
+     */
+    public void setU(Hep3Vector u) {
+        bank_double[GBLDOUBLE.UX] = u.x();
+        bank_double[GBLDOUBLE.UY] = u.y();
+        bank_double[GBLDOUBLE.UZ] = u.z();      
+    }
+    public Hep3Vector getU() {
+        return new BasicHep3Vector(getUx(),getUy(),getUz());
+    }
+    public double getUx() {
+        return getDoubleVal(GBLDOUBLE.UX);
+    }
+    public double getUy() {
+        return getDoubleVal(GBLDOUBLE.UY);
+    }
+    public double getUz() {
+        return getDoubleVal(GBLDOUBLE.UZ);
+    }
+    
+    /**
+     *  Set and get v vector for this strip sensor
+     */
+
+    public void setV(Hep3Vector v) {
+        bank_double[GBLDOUBLE.VX] = v.x();
+        bank_double[GBLDOUBLE.VY] = v.y();
+        bank_double[GBLDOUBLE.VZ] = v.z();      
+    }
+    public Hep3Vector getV() {
+        return new BasicHep3Vector(getVx(),getVy(),getVz());
+    }
+    public double getVx() {
+        return getDoubleVal(GBLDOUBLE.VX);
+    }
+    public double getVy() {
+        return getDoubleVal(GBLDOUBLE.VY);
+    }
+    public double getVz() {
+        return getDoubleVal(GBLDOUBLE.VZ);
+    }
+
+    /**
+     *  Set and get w vector for this strip sensor
+     */
+
+    public void setW(Hep3Vector v) {
+        bank_double[GBLDOUBLE.WX] = v.x();
+        bank_double[GBLDOUBLE.WY] = v.y();
+        bank_double[GBLDOUBLE.WZ] = v.z();      
+    }
+    public Hep3Vector getW() {
+        return new BasicHep3Vector(getWx(),getWy(),getWz());
+    }
+    public double getWx() {
+        return getDoubleVal(GBLDOUBLE.WX);
+    }
+    public double getWy() {
+        return getDoubleVal(GBLDOUBLE.WY);
+    }
+    public double getWz() {
+        return getDoubleVal(GBLDOUBLE.WZ);
+    }
+
+    /**
+     * Set track direction at this cluster
+     * 
+     * @param v the track direction
+     */
+    public void setTrackDir(Hep3Vector v) {
+        bank_double[GBLDOUBLE.TDIRX] = v.x();
+        bank_double[GBLDOUBLE.TDIRY] = v.y();
+        bank_double[GBLDOUBLE.TDIRZ] = v.z();       
+    }
+    public Hep3Vector getTrackDirection() {
+        return new BasicHep3Vector(getTx(),getTy(),getTz());
+    }
+    public double getTx() {
+        return getDoubleVal(GBLDOUBLE.TDIRX);
+    }
+    public double getTy() {
+        return getDoubleVal(GBLDOUBLE.TDIRY);
+    }
+    public double getTz() {
+        return getDoubleVal(GBLDOUBLE.TDIRZ);
+    }
+
+    public void setTrackPhi(double phi) {
+        bank_double[GBLDOUBLE.TPHI] = phi;
+    }
+    
+    public double getTrackPhi() {
+        return getDoubleVal(GBLDOUBLE.TPHI);
+    }
+
+    public void setTrackLambda(double lambda) {
+        bank_double[GBLDOUBLE.TLAMBDA] = lambda;
+    }
+    
+    public double getTrackLambda() {
+        return getDoubleVal(GBLDOUBLE.TLAMBDA);
+    }
+
+    
+    public void setMeas(double umeas) {
+        bank_double[GBLDOUBLE.UMEAS] = umeas;
+    }
+    
+    public double getMeas() {
+        return getDoubleVal(GBLDOUBLE.UMEAS);
+    }
+    
+    public void setMeasErr(double x) {
+        bank_double[GBLDOUBLE.UMEASERR] = x;
+    }
+
+    public double getMeasErr() {
+        return getDoubleVal(GBLDOUBLE.UMEASERR);
+    }
+
+    
+    /**
+     * Set track position in local frame
+     * @param trkpos_meas
+     */
+    public void setTrackPos(Hep3Vector trkpos_meas) {
+        bank_double[GBLDOUBLE.TPOSU] = trkpos_meas.x();
+        bank_double[GBLDOUBLE.TPOSV] = trkpos_meas.y();
+        bank_double[GBLDOUBLE.TPOSW] = trkpos_meas.z();
+    }
+
+    public Hep3Vector getTrackPos() {
+        return new BasicHep3Vector(getTrackPosU(),getTrackPosV(),getTrackPosW());
+    }
+    
+    public double getTrackPosU() {
+        return getDoubleVal(GBLDOUBLE.TPOSU);
+    }
+
+    public double getTrackPosV() {
+        return getDoubleVal(GBLDOUBLE.TPOSV);
+    }
+
+    public double getTrackPosW() {
+        return getDoubleVal(GBLDOUBLE.TPOSW);
+    }
+
+    public void setScatterAngle(double scatAngle) {
+        bank_double[GBLDOUBLE.MSANGLE] = scatAngle;
+    }
+    
+    public double getScatterAngle() {
+        return getDoubleVal(GBLDOUBLE.MSANGLE);
+    }
+    
+    /*
+     * The functions below are all overide from 
+     * @see org.lcsim.event.GenericObject#getNInt()
+     */
+    
+    public int getNInt() {
+        return GBLINT.BANK_INT_SIZE;
+    }
+
+    public int getNFloat() {
+        return 0;
+    }
+
+    public int getNDouble() {
+        return GBLDOUBLE.BANK_DOUBLE_SIZE;
+    }
+
+    public int getIntVal(int index) {
+        return bank_int[index];
+    }
+
+    public float getFloatVal(int index) {
+        return 0;
+    }
+
+    public double getDoubleVal(int index) {
+        return bank_double[index];
+    }
+
+    public boolean isFixedSize() {
+        return false;
+    }
 
 }

Modified: java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/gbl/GBLTrackData.java
 =============================================================================
--- java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/gbl/GBLTrackData.java	(original)
+++ java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/gbl/GBLTrackData.java	Wed Apr 27 11:11:32 2016
@@ -3,7 +3,6 @@
 import hep.physics.vec.BasicHep3Matrix;
 import hep.physics.vec.Hep3Matrix;
 
-import org.hps.recon.tracking.gbl.GBLOutput.PerigeeParams;
 import org.lcsim.event.GenericObject;
 
 /**
@@ -61,7 +60,7 @@
     }
 
     /**
-     * @param set track id to val
+     * @param val track ID value
      */
     public void setTrackId(int val) {
         bank_int[GBLINT.ID] = val;
@@ -77,7 +76,7 @@
     /**
      * @param perPar is the perigee parameters that is added to object
      */
-    public void setPerigeeTrackParameters(PerigeeParams perPar) {
+    public void setPerigeeTrackParameters(GblUtils.PerigeeParams perPar) {
         this.bank_double[GBLDOUBLE.PERKAPPA] = perPar.getKappa();
         this.bank_double[GBLDOUBLE.PERTHETA] = perPar.getTheta();
         this.bank_double[GBLDOUBLE.PERPHI] = perPar.getPhi();
@@ -85,8 +84,8 @@
         this.bank_double[GBLDOUBLE.PERZ0] = perPar.getZ0();
     }
 
-    public PerigeeParams getPerigeeTrackParameters() {
-        return new PerigeeParams(this.bank_double[GBLDOUBLE.PERKAPPA],
+    public GblUtils.PerigeeParams getPerigeeTrackParameters() {
+        return new GblUtils.PerigeeParams(this.bank_double[GBLDOUBLE.PERKAPPA],
                 this.bank_double[GBLDOUBLE.PERTHETA],
                 this.bank_double[GBLDOUBLE.PERPHI],
                 this.bank_double[GBLDOUBLE.PERD0],

Modified: java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/gbl/GblData.java
 =============================================================================
--- java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/gbl/GblData.java	(original)
+++ java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/gbl/GblData.java	Wed Apr 27 11:11:32 2016
@@ -69,8 +69,8 @@
             nExt = extDer.getColumnDimension();
         }
         int nParMax = 5 + nLocal + nExt;
-//	theParameters.reserve(nParMax); // have to be sorted
-//	theDerivatives.reserve(nParMax);
+//  theParameters.reserve(nParMax); // have to be sorted
+//  theDerivatives.reserve(nParMax);
 
         if (derLocal != null) {
             for (int i = 0; i < derLocal.getColumnDimension(); ++i) // local derivatives
@@ -123,8 +123,8 @@
             nExtDer = extDer.getColumnDimension();
         }
         int nParMax = 7 + nExtDer;
-//	theParameters.reserve(nParMax); // have to be sorted
-//	theDerivatives.reserve(nParMax);
+//  theParameters.reserve(nParMax); // have to be sorted
+//  theDerivatives.reserve(nParMax);
 
         if (extDer != null) {
             for (int i = 0; i < extDer.getColumnDimension(); ++i) // external derivatives
@@ -151,14 +151,14 @@
 // * \param [in] derivatives Derivatives (vector)
 // */
 //void addDerivatives(const std::vector<unsigned int> &index,
-//		const std::vector<double> &derivatives) {
-//	for (unsigned int i = 0; i < derivatives.size(); ++i) // any derivatives
-//			{
-//		if (derivatives[i]) {
-//			theParameters.push_back(index[i]);
-//			theDerivatives.push_back(derivatives[i]);
-//		}
-//	}
+//      const std::vector<double> &derivatives) {
+//  for (unsigned int i = 0; i < derivatives.size(); ++i) // any derivatives
+//          {
+//      if (derivatives[i]) {
+//          theParameters.push_back(index[i]);
+//          theDerivatives.push_back(derivatives[i]);
+//      }
+//  }
 //}
 /// Calculate prediction for data from fit (by GblTrajectory::fit).
     void setPrediction(VVector aVector)
@@ -176,27 +176,27 @@
 // */
 //double setDownWeighting(unsigned int aMethod) {
 //
-//	double aWeight = 1.;
-//	double scaledResidual = fabs(theValue - thePrediction) * sqrt(thePrecision);
-//	if (aMethod == 1) // Tukey
-//			{
-//		if (scaledResidual < 4.6851) {
-//			aWeight = (1.0 - 0.045558 * scaledResidual * scaledResidual);
-//			aWeight *= aWeight;
-//		} else {
-//			aWeight = 0.;
-//		}
-//	} else if (aMethod == 2) //Huber
-//			{
-//		if (scaledResidual >= 1.345) {
-//			aWeight = 1.345 / scaledResidual;
-//		}
-//	} else if (aMethod == 3) //Cauchy
-//			{
-//		aWeight = 1.0 / (1.0 + (scaledResidual * scaledResidual / 5.6877));
-//	}
-//	theDownWeight = aWeight;
-//	return aWeight;
+//  double aWeight = 1.;
+//  double scaledResidual = fabs(theValue - thePrediction) * sqrt(thePrecision);
+//  if (aMethod == 1) // Tukey
+//          {
+//      if (scaledResidual < 4.6851) {
+//          aWeight = (1.0 - 0.045558 * scaledResidual * scaledResidual);
+//          aWeight *= aWeight;
+//      } else {
+//          aWeight = 0.;
+//      }
+//  } else if (aMethod == 2) //Huber
+//          {
+//      if (scaledResidual >= 1.345) {
+//          aWeight = 1.345 / scaledResidual;
+//      }
+//  } else if (aMethod == 3) //Cauchy
+//          {
+//      aWeight = 1.0 / (1.0 + (scaledResidual * scaledResidual / 5.6877));
+//  }
+//  theDownWeight = aWeight;
+//  return aWeight;
 //}
 //
 /// Calculate Chi2 contribution.

Modified: java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/gbl/GblPoint.java
 =============================================================================
--- java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/gbl/GblPoint.java	(original)
+++ java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/gbl/GblPoint.java	Wed Apr 27 11:11:32 2016
@@ -486,7 +486,7 @@
     {
         int ifail = 0;
 // to optimize: need only two last rows of inverse
-//	prevJacobian = aJac.InverseFast(ifail);
+//  prevJacobian = aJac.InverseFast(ifail);
 //  block matrix algebra
         Matrix CA = aJac.sub(2, 3, 3, 0).times(aJac.sub(3, 0, 0).inverse()); // C*A^-1
         Matrix DCAB = aJac.sub(2, 3, 3).minus(CA.times(aJac.sub(3, 2, 0, 3))); // D - C*A^-1 *B
@@ -531,14 +531,14 @@
         }
 
         matW.placeAt(matWt.inverse(), 0, 0);
-//	if (!matW.InvertFast()) {
-//		std::cout << " getDerivatives failed to invert matrix: "
-//				<< matW << "\n";
-//		std::cout
-//				<< " Possible reason for singular matrix: multiple GblPoints at same arc-length"
-//				<< "\n";
-//		throw std::overflow_error("Singular matrix inversion exception");
-//	}
+//  if (!matW.InvertFast()) {
+//      std::cout << " getDerivatives failed to invert matrix: "
+//              << matW << "\n";
+//      std::cout
+//              << " Possible reason for singular matrix: multiple GblPoints at same arc-length"
+//              << "\n";
+//      throw std::overflow_error("Singular matrix inversion exception");
+//  }
         matWJ.placeAt(matW.times(matJ), 0, 0);
         vecWd.placeAt(matW.times(vecd), 0, 0);
 

Modified: java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/gbl/GblTrajectory.java
 =============================================================================
--- java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/gbl/GblTrajectory.java	(original)
+++ java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/gbl/GblTrajectory.java	Wed Apr 27 11:11:32 2016
@@ -214,7 +214,7 @@
     }
 
 /// Retrieve validity of trajectory
-    boolean isValid()
+    public boolean isValid()
     {
         return constructOK;
     }
@@ -268,7 +268,7 @@
             List<GblPoint> list = thePoints.get(iTraj);
             int size = list.size();
             // first point is offset
-            list.get(0).setOffset(numOffsets++);		// intermediate scatterers are offsets
+            list.get(0).setOffset(numOffsets++);        // intermediate scatterers are offsets
             for (int i = 1; i < size - 1; ++i) {
                 GblPoint p = list.get(i);
                 if (p.hasScatterer()) {
@@ -434,7 +434,7 @@
             aPoint.getDerivatives(0, prevW, prevWJ, prevWd); // W-, W- * J-, W- * d-
             aPoint.getDerivatives(1, nextW, nextWJ, nextWd); // W-, W- * J-, W- * d-
             Matrix sumWJ = prevWJ.plus(nextWJ);
-//?		matN = sumWJ.inverse(ierr); // N = (W- * J- + W+ * J+)^-1
+//?     matN = sumWJ.inverse(ierr); // N = (W- * J- + W+ * J+)^-1
             // derivatives for u_int
             Matrix prevNW = matN.times(prevW); // N * W-
             Matrix nextNW = matN.times(nextW); // N * W+
@@ -841,7 +841,7 @@
     /**
      * \param [in] level print level (0: minimum, >0: more)
      */
-    void printPoints(int level)
+    public void printPoints(int level)
     {
         System.out.println("GblPoints ");
 

Modified: java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/gbl/GblUtils.java
 =============================================================================
--- java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/gbl/GblUtils.java	(original)
+++ java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/gbl/GblUtils.java	Wed Apr 27 11:11:32 2016
@@ -1,29 +1,240 @@
 package org.hps.recon.tracking.gbl;
 
+import java.util.logging.Logger;
+
 import hep.physics.matrix.BasicMatrix;
+import hep.physics.vec.BasicHep3Matrix;
+import hep.physics.vec.BasicHep3Vector;
+import hep.physics.vec.Hep3Matrix;
+import hep.physics.vec.Hep3Vector;
+import hep.physics.vec.VecOp;
+
+import org.hps.recon.tracking.HpsHelicalTrackFit;
 import org.hps.recon.tracking.MaterialSupervisor;
 import org.hps.recon.tracking.MultipleScattering;
+import org.hps.recon.tracking.gbl.matrix.Matrix;
+import org.hps.recon.tracking.gbl.matrix.Vector;
+import org.lcsim.constants.Constants;
 import org.lcsim.detector.IDetectorElement;
 import org.lcsim.fit.helicaltrack.HelicalTrackFit;
 import org.lcsim.fit.helicaltrack.HelixUtils;
 import org.lcsim.recon.tracking.seedtracker.ScatterAngle;
 
 /**
- * A class providing various utilities related to GBL
+ * A class with only static utilities related to GBL
  *
  * @author Per Hansson Adrian <[log in to unmask]>
  *
  */
 public class GblUtils {
-
+    
+    public static Logger LOGGER = Logger.getLogger(GblUtils.class.getName());
+    
+    
+    
+
+    /**
+     * Private constructor to avoid instantiation.
+     */
     private GblUtils() {
     }
+
+    
+    /**
+     * 
+     * Store local curvilinear track parameters. 
+     * 
+     * @author Per Hansson Adrian <[log in to unmask]>
+     *
+     */
+    public static class ClParams {
+    
+        private BasicMatrix _params = new BasicMatrix(1, 5);
+    
+        public ClParams(HelicalTrackFit htf, double B) {
+    
+            if (htf == null) {
+                return;
+            }
+    
+            Hep3Matrix perToClPrj = getPerToClPrj(htf);
+    
+            double d0 = -1 * htf.dca(); //sign convention for curvilinear frame
+            double z0 = htf.z0();
+            Hep3Vector vecPer = new BasicHep3Vector(0., d0, z0);
+            //System.out.printf("%s: vecPer=%s\n",this.getClass().getSimpleName(),vecPer.toString());
+    
+            Hep3Vector vecCl = VecOp.mult(perToClPrj, vecPer);
+            //System.out.printf("%s: vecCl=%s\n",this.getClass().getSimpleName(),vecCl.toString());
+            double xT = vecCl.x();
+            double yT = vecCl.y();
+            //double zT = vecCl.z();
+    
+            double lambda = Math.atan(htf.slope());
+            double q = Math.signum(htf.R());
+            double qOverP = q / htf.p(Math.abs(B));
+            double phi = htf.phi0();
+    
+            _params.setElement(0, FittedGblTrajectory.GBLPARIDX.QOVERP.getValue(), qOverP);
+            _params.setElement(0, FittedGblTrajectory.GBLPARIDX.YTPRIME.getValue(), lambda);
+            _params.setElement(0, FittedGblTrajectory.GBLPARIDX.XTPRIME.getValue(), phi);
+            _params.setElement(0, FittedGblTrajectory.GBLPARIDX.XT.getValue(), xT);
+            _params.setElement(0, FittedGblTrajectory.GBLPARIDX.YT.getValue(), yT);
+        }
+    
+        public BasicMatrix getParams() {
+            return _params;
+        }
+    
+        double getQoverP() {
+            return _params.e(0, FittedGblTrajectory.GBLPARIDX.QOVERP.getValue());
+        }
+    
+        double getLambda() {
+            return _params.e(0, FittedGblTrajectory.GBLPARIDX.YTPRIME.getValue());
+        }
+    
+        double getPhi() {
+            return _params.e(0, FittedGblTrajectory.GBLPARIDX.XTPRIME.getValue());
+        }
+    
+        double getXt() {
+            return _params.e(0, FittedGblTrajectory.GBLPARIDX.XT.getValue());
+        }
+    
+        double getYt() {
+            return _params.e(0, FittedGblTrajectory.GBLPARIDX.YT.getValue());
+        }
+    
+    }
+
+
+
+
+
+    /**
+     * 
+     * Store perigee track parameters. 
+     * 
+     * @author Per Hansson Adrian <[log in to unmask]>
+     *
+     */
+    public static class PerigeeParams {
+    
+        private final BasicMatrix _params;
+    
+        public PerigeeParams(HelicalTrackFit htf, double B) {
+            _params = GblUtils.getPerParVector(htf, B);
+        }
+    
+        public PerigeeParams(double kappa, double theta, double phi, double d0, double z0) {
+            this._params = GblUtils.getPerParVector(kappa, theta, phi, d0, z0);
+        }
+    
+        public BasicMatrix getParams() {
+            return _params;
+        }
+    
+        public double getKappa() {
+            return _params.e(0, 0);
+        }
+    
+        public double getTheta() {
+            return _params.e(0, 1);
+        }
+    
+        public double getPhi() {
+            return _params.e(0, 2);
+        }
+    
+        public double getD0() {
+            return _params.e(0, 3);
+        }
+    
+        public double getZ0() {
+            return _params.e(0, 4);
+        }
+    }
+
+
+
+
+
+    
+    /**
+     * Get corrected perigee parameters. 
+     * @param locPar - GBL local curvilinear corrections
+     * @param helicalTrackFit - helix
+     * @param bfield - B-field strength
+     * @return corrected parameters
+     */
+    public static double[] getCorrectedPerigeeParameters(Vector locPar, HelicalTrackFit helicalTrackFit, double bfield) {
+        
+        
+        // Explicitly assign corrections to local variables
+        double qOverPCorr = locPar.get(FittedGblTrajectory.GBLPARIDX.QOVERP.getValue());
+        double xTPrimeCorr = locPar.get(FittedGblTrajectory.GBLPARIDX.XTPRIME.getValue());
+        double yTPrimeCorr = locPar.get(FittedGblTrajectory.GBLPARIDX.YTPRIME.getValue());
+        double xTCorr = locPar.get(FittedGblTrajectory.GBLPARIDX.XT.getValue());
+        double yTCorr = locPar.get(FittedGblTrajectory.GBLPARIDX.YT.getValue());
+
+        
+        // Get helix parameters
+        double qOverP = helicalTrackFit.curvature() / (Constants.fieldConversion * Math.abs(bfield) * Math.sqrt(1 + Math.pow(helicalTrackFit.slope(), 2)));
+        double d0 = -1.0 * helicalTrackFit.dca(); // correct for different sign convention of d0 in perigee frame
+        double z0 = helicalTrackFit.z0();
+        double phi0 = helicalTrackFit.phi0();
+        double lambda = Math.atan(helicalTrackFit.slope());
+        
+        // calculate new d0 and z0
+        Hep3Matrix perToClPrj = GblUtils.getPerToClPrj(helicalTrackFit);
+
+        Hep3Matrix clToPerPrj = VecOp.inverse(perToClPrj);
+        Hep3Vector corrPer = VecOp.mult(clToPerPrj, new BasicHep3Vector(xTCorr, yTCorr, 0.0));
+
+        //d0
+        double d0_corr = corrPer.y();
+        double dca_gbl = -1.0 * (d0 + d0_corr);
+
+        //z0
+        double z0_corr = corrPer.z();
+        double z0_gbl = z0 + z0_corr;
+
+        //calculate new slope
+        double lambda_gbl = lambda + yTPrimeCorr;
+        double slope_gbl = Math.tan(lambda_gbl);
+
+        // calculate new curvature
+        double qOverP_gbl = qOverP + qOverPCorr;
+        double C_gbl = Constants.fieldConversion * Math.abs(bfield) * qOverP_gbl / Math.cos(lambda_gbl);
+
+        //calculate new phi0
+        double phi0_gbl = phi0 + xTPrimeCorr - corrPer.x() * C_gbl;
+
+        LOGGER.info("qOverP=" + qOverP + " qOverPCorr=" + qOverPCorr + " qOverP_gbl=" + qOverP_gbl + " ==> pGbl=" + 1.0 / qOverP_gbl + " C_gbl=" + C_gbl);
+
+        LOGGER.info(String.format("corrected helix: d0=%f, z0=%f, omega=%f, tanlambda=%f, phi0=%f, p=%f", dca_gbl, z0_gbl, C_gbl, slope_gbl, phi0_gbl, Math.abs(1 / qOverP_gbl)));
+        
+        double parameters_gbl[] = new double[5];
+        parameters_gbl[HelicalTrackFit.dcaIndex] = dca_gbl;
+        parameters_gbl[HelicalTrackFit.phi0Index] = phi0_gbl;
+        parameters_gbl[HelicalTrackFit.curvatureIndex] = C_gbl;
+        parameters_gbl[HelicalTrackFit.z0Index] = z0_gbl;
+        parameters_gbl[HelicalTrackFit.slopeIndex] = slope_gbl;
+        
+        return parameters_gbl;
+        
+    }
+    
+    
+    
+    
 
     public static BasicMatrix gblSimpleJacobianLambdaPhi(double ds, double cosl, double bfac) {
         /*
          Simple jacobian: quadratic in arc length difference.
          using lambda phi as directions
-	    
+        
          @param ds: arc length difference
          @type ds: float
          @param cosl: cos(lambda)
@@ -105,4 +316,168 @@
             throw new UnsupportedOperationException("Should not happen. This problem is only solved with the MaterialSupervisor.");
         }
     }
+
+    /**
+     * Calculate the Jacobian from Curvilinear to Perigee frame. 
+     * @param helicalTrackFit - original helix
+     * @param helicalTrackFitAtIPCorrected - corrected helix at this point
+     * @param bfield - magnitude of B-field
+     * @return the Jacobian matrix from Curvilinear to Perigee frame
+     */
+    public static Matrix getCLToPerigeeJacobian(HelicalTrackFit helicalTrackFit, HpsHelicalTrackFit helicalTrackFitAtIPCorrected, double bfield) {
+        
+        /*
+         * This part is taken from:
+         // Strandlie, Wittek, NIMA 566, 2006
+         Matrix covariance_gbl = new Matrix(5, 5);
+         //helpers
+         double Bz = -Constants.fieldConversion * Math.abs(bfield); // TODO sign convention and should it be it scaled from Telsa?
+         double p = Math.abs(1 / qOverP_gbl);
+         double q = Math.signum(qOverP_gbl);
+         double tanLambda = Math.tan(lambda_gbl);
+         double cosLambda = Math.cos(lambda_gbl);
+         //        Hep3Vector B = new BasicHep3Vector(0, 0, Bz); // TODO sign convention?
+         Hep3Vector H = new BasicHep3Vector(0, 0, 1);
+         Hep3Vector T = HelixUtils.Direction(helix, 0.);
+         Hep3Vector HcrossT = VecOp.cross(H, T);
+         double alpha = HcrossT.magnitude(); // this should be Bvec cross TrackDir/|B|
+         double Q = Bz * q / p;
+         Hep3Vector Z = new BasicHep3Vector(0, 0, 1);
+         Hep3Vector J = VecOp.mult(1. / VecOp.cross(T, Z).magnitude(), VecOp.cross(T, Z));
+         Hep3Vector K = Z;
+         Hep3Vector U = VecOp.mult(-1, J);
+         Hep3Vector V = VecOp.cross(T, U);
+         Hep3Vector I = VecOp.cross(J, K);
+         Hep3Vector N = VecOp.mult(1 / alpha, VecOp.cross(H, T));
+         double UdotI = VecOp.dot(U, I);
+         double NdotV = VecOp.dot(N, V);
+         double NdotU = VecOp.dot(N, U);
+         double TdotI = VecOp.dot(T, I);
+         double VdotI = VecOp.dot(V, I);
+         double VdotK = VecOp.dot(V, K);
+         covariance_gbl.set(HelicalTrackFit.dcaIndex, FittedGblTrajectory.GBLPARIDX.XT.getValue(), VdotK / TdotI);
+         covariance_gbl.set(HelicalTrackFit.phi0Index, FittedGblTrajectory.GBLPARIDX.XTPRIME.getValue(), 1);
+         covariance_gbl.set(HelicalTrackFit.phi0Index, FittedGblTrajectory.GBLPARIDX.XT.getValue(), -alpha * Q * UdotI * NdotU / (cosLambda * TdotI));
+         covariance_gbl.set(HelicalTrackFit.phi0Index, FittedGblTrajectory.GBLPARIDX.YT.getValue(), -alpha * Q * VdotI * NdotU / (cosLambda * TdotI));
+         covariance_gbl.set(HelicalTrackFit.curvatureIndex, FittedGblTrajectory.GBLPARIDX.QOVERP.getValue(), -1 * Bz / cosLambda);
+         //        covariance_gbl.set(HelicalTrackFit.curvatureIndex, FittedGblTrajectory.GBLPARIDX.XTPRIME.getValue(), 0);
+         covariance_gbl.set(HelicalTrackFit.curvatureIndex, FittedGblTrajectory.GBLPARIDX.YTPRIME.getValue(), -1 * q * Bz * tanLambda / (p * cosLambda));
+         covariance_gbl.set(HelicalTrackFit.curvatureIndex, FittedGblTrajectory.GBLPARIDX.XT.getValue(), q * Bz * alpha * Q * tanLambda * UdotI * NdotV / (p * cosLambda * TdotI));
+         covariance_gbl.set(HelicalTrackFit.curvatureIndex, FittedGblTrajectory.GBLPARIDX.YT.getValue(), q * Bz * alpha * Q * tanLambda * VdotI * NdotV / (p * cosLambda * TdotI));
+         covariance_gbl.set(HelicalTrackFit.z0Index, FittedGblTrajectory.GBLPARIDX.YT.getValue(), -1 / TdotI);
+         covariance_gbl.set(HelicalTrackFit.slopeIndex, FittedGblTrajectory.GBLPARIDX.YTPRIME.getValue(), -1);
+         covariance_gbl.set(HelicalTrackFit.slopeIndex, FittedGblTrajectory.GBLPARIDX.XT.getValue(), alpha * Q * UdotI * NdotV / TdotI);
+         covariance_gbl.set(HelicalTrackFit.slopeIndex, FittedGblTrajectory.GBLPARIDX.YT.getValue(), alpha * Q * VdotI * NdotV / TdotI);
+
+         covariance_gbl.print(15, 13);
+         */
+        
+        // Sho's magic below
+        
+        // Use projection matrix
+        //TODO should this not be the corrected helix?
+        Hep3Matrix perToClPrj = getPerToClPrj(helicalTrackFit);
+        Hep3Matrix clToPerPrj = VecOp.inverse(perToClPrj);
+        double C_gbl = helicalTrackFitAtIPCorrected.curvature();
+        double lambda_gbl = Math.atan(helicalTrackFitAtIPCorrected.slope());
+        double qOverP_gbl = helicalTrackFitAtIPCorrected.curvature() / (Constants.fieldConversion * Math.abs(bfield) * Math.sqrt(1 + Math.pow(helicalTrackFitAtIPCorrected.slope(), 2)));
+        
+        Matrix jacobian = new Matrix(5, 5);
+        jacobian.set(HelicalTrackFit.dcaIndex, FittedGblTrajectory.GBLPARIDX.XT.getValue(), -clToPerPrj.e(1, 0));
+        jacobian.set(HelicalTrackFit.dcaIndex, FittedGblTrajectory.GBLPARIDX.YT.getValue(), -clToPerPrj.e(1, 1));
+        jacobian.set(HelicalTrackFit.phi0Index, FittedGblTrajectory.GBLPARIDX.XTPRIME.getValue(), 1.0);
+        jacobian.set(HelicalTrackFit.phi0Index, FittedGblTrajectory.GBLPARIDX.YT.getValue(), clToPerPrj.e(0, 1) * C_gbl);
+        jacobian.set(HelicalTrackFit.curvatureIndex, FittedGblTrajectory.GBLPARIDX.QOVERP.getValue(), Constants.fieldConversion * Math.abs(bfield) / Math.cos(lambda_gbl));
+        jacobian.set(HelicalTrackFit.curvatureIndex, FittedGblTrajectory.GBLPARIDX.YTPRIME.getValue(), Constants.fieldConversion * Math.abs(bfield) * qOverP_gbl * Math.tan(lambda_gbl) / Math.cos(lambda_gbl));
+        jacobian.set(HelicalTrackFit.z0Index, FittedGblTrajectory.GBLPARIDX.XT.getValue(), clToPerPrj.e(2, 0));
+        jacobian.set(HelicalTrackFit.z0Index, FittedGblTrajectory.GBLPARIDX.YT.getValue(), clToPerPrj.e(2, 1));
+        jacobian.set(HelicalTrackFit.slopeIndex, FittedGblTrajectory.GBLPARIDX.YTPRIME.getValue(), Math.pow(Math.cos(lambda_gbl), -2.0));
+        
+        return jacobian;
+    }
+
+
+
+
+
+    /**
+     * Computes the projection matrix from the perigee XY plane variables dca
+     * and z0 into the curvilinear xT,yT,zT frame (U,V,T) with reference point (0,0,0) 
+     * for the perigee frame.
+     *
+     * @param htf input helix to find the track direction
+     * @return 3x3 projection matrix
+     */
+    static Hep3Matrix getPerToClPrj(HelicalTrackFit htf) {
+        Hep3Vector Z = new BasicHep3Vector(0, 0, 1);
+        Hep3Vector T = HelixUtils.Direction(htf, 0.);
+        Hep3Vector J = VecOp.mult(1. / VecOp.cross(T, Z).magnitude(), VecOp.cross(T, Z));
+        Hep3Vector K = Z;
+        Hep3Vector U = VecOp.mult(-1, J);
+        Hep3Vector V = VecOp.cross(T, U);
+        Hep3Vector I = VecOp.cross(J, K);
+    
+        BasicHep3Matrix trans = new BasicHep3Matrix();
+        trans.setElement(0, 0, VecOp.dot(I, U));
+        trans.setElement(0, 1, VecOp.dot(J, U));
+        trans.setElement(0, 2, VecOp.dot(K, U));
+        trans.setElement(1, 0, VecOp.dot(I, V));
+        trans.setElement(1, 1, VecOp.dot(J, V));
+        trans.setElement(1, 2, VecOp.dot(K, V));
+        trans.setElement(2, 0, VecOp.dot(I, T));
+        trans.setElement(2, 1, VecOp.dot(J, T));
+        trans.setElement(2, 2, VecOp.dot(K, T));
+        return trans;
+    
+        /*
+         Hep3Vector B = new BasicHep3Vector(0, 0, 1); // TODO sign convention?
+         Hep3Vector H = VecOp.mult(1 / bfield, B);
+         Hep3Vector T = HelixUtils.Direction(helix, 0.);
+         Hep3Vector HcrossT = VecOp.cross(H, T);
+         double alpha = HcrossT.magnitude(); // this should be Bvec cross TrackDir/|B|
+         double Q = Math.abs(bfield) * q / p;
+         Hep3Vector Z = new BasicHep3Vector(0, 0, 1);
+         Hep3Vector J = VecOp.mult(1. / VecOp.cross(T, Z).magnitude(), VecOp.cross(T, Z));
+         Hep3Vector K = Z;
+         Hep3Vector U = VecOp.mult(-1, J);
+         Hep3Vector V = VecOp.cross(T, U);
+         Hep3Vector I = VecOp.cross(J, K);
+         Hep3Vector N = VecOp.mult(1 / alpha, VecOp.cross(H, T)); //-cross(T,H)/alpha = -cross(T,Z) = -J
+         double UdotI = VecOp.dot(U, I); // 0,0
+         double NdotV = VecOp.dot(N, V); // 1,1?
+         double NdotU = VecOp.dot(N, U); // 0,1?
+         double TdotI = VecOp.dot(T, I); // 2,0
+         double VdotI = VecOp.dot(V, I); // 1,0
+         double VdotK = VecOp.dot(V, K); // 1,2
+         */
+    }
+
+
+
+
+
+    private static BasicMatrix getPerParVector(double kappa, double theta, double phi, double d0, double z0) {
+        BasicMatrix perPar = new BasicMatrix(1, 5);
+        perPar.setElement(0, 0, kappa);
+        perPar.setElement(0, 1, theta);
+        perPar.setElement(0, 2, phi);
+        perPar.setElement(0, 3, d0);
+        perPar.setElement(0, 4, z0);
+        return perPar;
+    }
+
+
+
+
+
+    private static BasicMatrix getPerParVector(HelicalTrackFit htf, double B) {
+        if (htf != null) {
+            double kappa = -1.0 * Math.signum(B) / htf.R();
+            double theta = Math.PI / 2.0 - Math.atan(htf.slope());
+            return getPerParVector(kappa, theta, htf.phi0(), htf.dca(), htf.z0());
+        }
+        return new BasicMatrix(1, 5);
+    }
+
+
 }

Modified: java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/gbl/HelicalTrackStripGbl.java
 =============================================================================
--- java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/gbl/HelicalTrackStripGbl.java	(original)
+++ java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/gbl/HelicalTrackStripGbl.java	Wed Apr 27 11:11:32 2016
@@ -13,10 +13,8 @@
 import org.lcsim.fit.helicaltrack.HelicalTrackStrip;
 
 /**
- * Encapsulates the {@HelicalTrackStrip} to make sure that the local unit vectors are 
+ * Encapsulates the {@link org.lcsim.fit.helicaltrack.HelicalTrackStrip} to make sure that the local unit vectors are
  * coming from the underlying geometry.
- * 
- * I think the base calss should change but whatever.
  * 
  * @author Per Hansson Adrian <[log in to unmask]>
  *

Modified: java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/gbl/HpsGblRefitter.java
 =============================================================================
--- java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/gbl/HpsGblRefitter.java	(original)
+++ java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/gbl/HpsGblRefitter.java	Wed Apr 27 11:11:32 2016
@@ -14,10 +14,12 @@
 import java.util.logging.Formatter;
 import java.util.logging.Level;
 import java.util.logging.Logger;
+
 import org.apache.commons.math3.util.Pair;
-
 import org.hps.recon.tracking.TrackUtils;
+
 import static org.hps.recon.tracking.gbl.MakeGblTracks.makeCorrectedTrack;
+
 import org.hps.recon.tracking.gbl.matrix.Matrix;
 import org.hps.recon.tracking.gbl.matrix.SymMatrix;
 import org.hps.recon.tracking.gbl.matrix.Vector;
@@ -52,6 +54,8 @@
     private final String track2GblTrackRelationName = "TrackToGBLTrack";
     private final String gblTrack2StripRelationName = "GBLTrackToStripData";
     private final String outputTrackCollectionName = "GBLTracks";
+    private final String trackRelationCollectionName = "MatchedToGBLTrackRelations";
+
 
     private MilleBinary mille;
     private String milleBinaryFileName = MilleBinary.DEFAULT_OUTPUT_FILE_NAME;
@@ -184,6 +188,8 @@
         LOGGER.info(trackFits.size() + " fitted GBL tracks before adding to event");
 
         List<Track> newTracks = new ArrayList<Track>();
+        
+        List<LCRelation> trackRelations = new ArrayList<LCRelation>();
 
         List<GBLKinkData> kinkDataCollection = new ArrayList<GBLKinkData>();
 
@@ -201,6 +207,10 @@
 
             //  Add the track to the list of tracks
             newTracks.add(trk.getFirst());
+
+            // Create relation from seed to GBL track
+            trackRelations.add(new BaseLCRelation(fittedTraj.get_seed(), trk.getFirst()));
+            
             kinkDataCollection.add(trk.getSecond());
             kinkDataRelations.add(new BaseLCRelation(trk.getSecond(), trk.getFirst()));
         }
@@ -210,6 +220,7 @@
         // Put the tracks back into the event and exit
         int flag = 1 << LCIOConstants.TRBIT_HITS;
         event.put(outputTrackCollectionName, newTracks, Track.class, flag);
+        event.put(trackRelationCollectionName, trackRelations, LCRelation.class, 0);
         event.put(GBLKinkData.DATA_COLLECTION, kinkDataCollection, GBLKinkData.class, 0);
         event.put(GBLKinkData.DATA_RELATION_COLLECTION, kinkDataRelations, LCRelation.class, 0);
 
@@ -222,12 +233,15 @@
     public static FittedGblTrajectory fit(List<GBLStripClusterData> hits, double bfac, boolean debug) {
         // path length along trajectory
         double s = 0.;
+        int iLabel;
+
 
         // jacobian to transport errors between points along the path
         Matrix jacPointToPoint = new Matrix(5, 5);
         jacPointToPoint.UnitMatrix();
         // Vector of the strip clusters used for the GBL fit
         List<GblPoint> listOfPoints = new ArrayList<GblPoint>();
+        Map<Integer, Double> pathLengthMap = new HashMap<Integer, Double>();
 
         // Store the projection from local to measurement frame for each strip cluster
         Map< Integer, Matrix> proL2m_list = new HashMap<Integer, Matrix>();
@@ -236,6 +250,10 @@
         //start trajectory at refence point (s=0) - this point has no measurement
         GblPoint ref_point = new GblPoint(jacPointToPoint);
         listOfPoints.add(ref_point);
+        
+        // save path length to each point
+        iLabel = listOfPoints.size();
+        pathLengthMap.put(iLabel, s);
 
         // Loop over strips
         int n_strips = hits.size();
@@ -323,11 +341,11 @@
             // measurement/residual in the measurement system
             // only 1D measurement in u-direction, set strip measurement direction to zero
             Vector meas = new Vector(2);
-//		double uRes = strip->GetUmeas() - strip->GetTrackPos().x(); // how can this be correct?
+//      double uRes = strip->GetUmeas() - strip->GetTrackPos().x(); // how can this be correct?
             double uRes = strip.getMeas() - strip.getTrackPos().x();
             meas.set(0, uRes);
             meas.set(1, 0.);
-//		//meas[0][0] += deltaU[iLayer] # misalignment
+//      //meas[0][0] += deltaU[iLayer] # misalignment
             Vector measErr = new Vector(2);
             measErr.set(0, strip.getMeasErr());
             measErr.set(1, 0.);
@@ -405,7 +423,10 @@
 
             // Add this GBL point to list that will be used in fit
             listOfPoints.add(point);
-            int iLabel = listOfPoints.size();
+            iLabel = listOfPoints.size();
+
+            // save path length to each point
+            pathLengthMap.put(iLabel, s);
 
             // Update MS covariance matrix 
             msCov.set(1, 1, msCov.get(1, 1) + scatErr.get(0) * scatErr.get(0));
@@ -493,8 +514,10 @@
 
         LOGGER.fine("locPar " + aCorrection.toString());
 
-//
-        return new FittedGblTrajectory(traj, dVals[0], iVals[0], dVals[1]);
+        FittedGblTrajectory fittedTraj = new FittedGblTrajectory(traj, dVals[0], iVals[0], dVals[1]);
+        fittedTraj.setPathLengthMap(pathLengthMap);
+        
+        return fittedTraj;
     }
 
     @Override

Modified: java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/gbl/MakeGblTracks.java
 =============================================================================
--- java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/gbl/MakeGblTracks.java	(original)
+++ java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/gbl/MakeGblTracks.java	Wed Apr 27 11:11:32 2016
@@ -5,22 +5,18 @@
 import hep.physics.vec.Hep3Matrix;
 import hep.physics.vec.Hep3Vector;
 import hep.physics.vec.VecOp;
+
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
 import java.util.List;
 import java.util.logging.Level;
 import java.util.logging.Logger;
+
 import org.apache.commons.math3.util.Pair;
 import org.hps.recon.tracking.CoordinateTransformations;
 import org.hps.recon.tracking.MultipleScattering;
 import org.hps.recon.tracking.TrackType;
 import org.hps.recon.tracking.TrackUtils;
-import static org.hps.recon.tracking.gbl.GBLOutput.getPerToClPrj;
-import org.hps.recon.tracking.gbl.matrix.Matrix;
-import org.hps.recon.tracking.gbl.matrix.SymMatrix;
-import org.hps.recon.tracking.gbl.matrix.Vector;
 import org.lcsim.constants.Constants;
 import org.lcsim.detector.ITransform3D;
 import org.lcsim.detector.tracker.silicon.ChargeCarrier;
@@ -48,7 +44,11 @@
 public class MakeGblTracks {
 
     private final static Logger LOGGER = Logger.getLogger(MakeGblTracks.class.getPackage().getName());
-
+    static {
+        LOGGER.setLevel(Level.WARNING);
+    }
+    
+    
     private MakeGblTracks() {
     }
 
@@ -60,7 +60,16 @@
         }
     }
 
-    public static Pair<Track, GBLKinkData> makeCorrectedTrack(FittedGblTrajectory fittedTraj, HelicalTrackFit helix, List<TrackerHit> trackHits, int trackType, double bfield) {
+    /**
+     * Create a new {@link BaseTrack} from a {@link FittedGblTrajectory}. 
+     * @param fittedGblTrajectory
+     * @param helicalTrackFit
+     * @param hitsOnTrack
+     * @param trackType
+     * @param bfield
+     * @return the new {@link BaseTrack} and the kinks along the {@link GblTrajectory} as a {@link Pair}.
+     */
+    public static Pair<Track, GBLKinkData> makeCorrectedTrack(FittedGblTrajectory fittedGblTrajectory, HelicalTrackFit helicalTrackFit, List<TrackerHit> hitsOnTrack, int trackType, double bfield) {
         //  Initialize the reference point to the origin
         double[] ref = new double[]{0., 0., 0.};
 
@@ -68,220 +77,41 @@
         BaseTrack trk = new BaseTrack();
 
         //  Add the hits to the track
-        for (TrackerHit hit : trackHits) {
+        for (TrackerHit hit : hitsOnTrack) {
             trk.addHit(hit);
         }
 
-        // Set state at vertex
-        Pair<double[], SymmetricMatrix> correctedHelixParams = getGblCorrectedHelixParameters(helix, fittedTraj.get_traj(), bfield, FittedGblTrajectory.GBLPOINT.IP);
+        // Set base track parameters
+        Pair<double[], SymmetricMatrix> correctedHelixParams = fittedGblTrajectory.getCorrectedPerigeeParameters(helicalTrackFit, FittedGblTrajectory.GBLPOINT.IP, bfield);
         trk.setTrackParameters(correctedHelixParams.getFirst(), bfield);// hack to set the track charge
         trk.getTrackStates().clear();
 
-        TrackState stateVertex = new BaseTrackState(correctedHelixParams.getFirst(), ref, correctedHelixParams.getSecond().asPackedArray(true), TrackState.AtIP, bfield);
-        trk.getTrackStates().add(stateVertex);
-
-        // Set state at last point
-        Pair<double[], SymmetricMatrix> correctedHelixParamsLast = getGblCorrectedHelixParameters(helix, fittedTraj.get_traj(), bfield, FittedGblTrajectory.GBLPOINT.LAST);
+        // Set state at IP
+        TrackState stateIP = new BaseTrackState(correctedHelixParams.getFirst(), ref, correctedHelixParams.getSecond().asPackedArray(true), TrackState.AtIP, bfield);
+        trk.getTrackStates().add(stateIP);
+
+        // Set state at last point on trajectory
+        Pair<double[], SymmetricMatrix> correctedHelixParamsLast = fittedGblTrajectory.getCorrectedPerigeeParameters(helicalTrackFit, FittedGblTrajectory.GBLPOINT.LAST, bfield);
         TrackState stateLast = new BaseTrackState(correctedHelixParamsLast.getFirst(), ref, correctedHelixParamsLast.getSecond().asPackedArray(true), TrackState.AtLastHit, bfield);
         trk.getTrackStates().add(stateLast);
 
-        GBLKinkData kinkData = getKinks(fittedTraj.get_traj());
+        // Extract kinks from trajectory
+        GBLKinkData kinkData = fittedGblTrajectory.getKinks();
 
         // Set other info needed
-        trk.setChisq(fittedTraj.get_chi2());
-        trk.setNDF(fittedTraj.get_ndf());
+        trk.setChisq(fittedGblTrajectory.get_chi2());
+        trk.setNDF(fittedGblTrajectory.get_ndf());
         trk.setFitSuccess(true);
         trk.setRefPointIsDCA(true);
         trk.setTrackType(TrackType.setGBL(trackType, true));
 
         //  Add the track to the list of tracks
 //            tracks.add(trk);
-        LOGGER.info(String.format("helix chi2 %f ndf %d gbl chi2 %f ndf %d\n", helix.chisqtot(), helix.ndf()[0] + helix.ndf()[1], trk.getChi2(), trk.getNDF()));
-        if (LOGGER.getLevel().intValue() <= Level.INFO.intValue()) {
-            for (int i = 0; i < 5; ++i) {
-                LOGGER.info(String.format("param %d: %.10f -> %.10f    helix-gbl= %f", i, helix.parameters()[i], trk.getTrackParameter(i), helix.parameters()[i] - trk.getTrackParameter(i)));
-            }
-        }
+        LOGGER.fine(String.format("helix chi2 %f ndf %d gbl chi2 %f ndf %d\n", helicalTrackFit.chisqtot(), helicalTrackFit.ndf()[0] + helicalTrackFit.ndf()[1], trk.getChi2(), trk.getNDF()));
         return new Pair<Track, GBLKinkData>(trk, kinkData);
     }
 
-    /**
-     * Compute the updated helix parameters and covariance matrix at a given
-     * point along the trajectory.
-     *
-     * @param helix - original seed track
-     * @param traj - fitted GBL trajectory
-     * @param point - the point along the track where the result is computed.
-     * @return corrected parameters.
-     */
-    public static Pair<double[], SymmetricMatrix> getGblCorrectedHelixParameters(HelicalTrackFit helix, GblTrajectory traj, double bfield, FittedGblTrajectory.GBLPOINT point) {
-
-        // get seed helix parameters
-        double qOverP = helix.curvature() / (Constants.fieldConversion * Math.abs(bfield) * Math.sqrt(1 + Math.pow(helix.slope(), 2)));
-        double d0 = -1.0 * helix.dca(); // correct for different sign convention of d0 in perigee frame
-        double z0 = helix.z0();
-        double phi0 = helix.phi0();
-        double lambda = Math.atan(helix.slope());
-
-        LOGGER.info("GblPoint: " + point.toString() + "( " + point.name() + ")");
-        LOGGER.info(String.format("original helix: d0=%f, z0=%f, omega=%f, tanlambda=%f, phi0=%f, p=%f", helix.dca(), helix.z0(), helix.curvature(), helix.slope(), helix.phi0(), helix.p(Math.abs(bfield))));
-        LOGGER.info("original helix covariance:\n" + helix.covariance());
-
-        // get corrections from GBL fit
-        Vector locPar = new Vector(5);
-        SymMatrix locCov = new SymMatrix(5);
-        int pointIndex;
-        if (point.compareTo(FittedGblTrajectory.GBLPOINT.IP) == 0) {
-            pointIndex = 1;
-        } else if (point.compareTo(FittedGblTrajectory.GBLPOINT.LAST) == 0) {
-            pointIndex = traj.getNumPoints();
-        } else {
-            throw new RuntimeException("This GBLPOINT " + point.toString() + "( " + point.name() + ") is not valid");
-        }
-
-        traj.getResults(pointIndex, locPar, locCov); // vertex point
-//        locCov.print(10, 8);
-        double qOverPCorr = locPar.get(FittedGblTrajectory.GBLPARIDX.QOVERP.getValue());
-        double xTPrimeCorr = locPar.get(FittedGblTrajectory.GBLPARIDX.XTPRIME.getValue());
-        double yTPrimeCorr = locPar.get(FittedGblTrajectory.GBLPARIDX.YTPRIME.getValue());
-        double xTCorr = locPar.get(FittedGblTrajectory.GBLPARIDX.XT.getValue());
-        double yTCorr = locPar.get(FittedGblTrajectory.GBLPARIDX.YT.getValue());
-
-        LOGGER.info((helix.slope() > 0 ? "top: " : "bot ") + "qOverPCorr " + qOverPCorr + " xtPrimeCorr " + xTPrimeCorr + " yTPrimeCorr " + yTPrimeCorr + " xTCorr " + xTCorr + " yTCorr " + yTCorr);
-
-        // calculate new d0 and z0
-//        Hep3Matrix perToClPrj = traj.get_track_data().getPrjPerToCl();
-        Hep3Matrix perToClPrj = getPerToClPrj(helix);
-
-        Hep3Matrix clToPerPrj = VecOp.inverse(perToClPrj);
-        Hep3Vector corrPer = VecOp.mult(clToPerPrj, new BasicHep3Vector(xTCorr, yTCorr, 0.0));
-
-        //d0
-        double d0_corr = corrPer.y();
-        double dca_gbl = -1.0 * (d0 + d0_corr);
-
-        //z0
-        double z0_corr = corrPer.z();
-        double z0_gbl = z0 + z0_corr;
-
-        //calculate new slope
-        double lambda_gbl = lambda + yTPrimeCorr;
-        double slope_gbl = Math.tan(lambda_gbl);
-
-        // calculate new curvature
-        double qOverP_gbl = qOverP + qOverPCorr;
-//        double pt_gbl = (1.0 / qOverP_gbl) * Math.cos(lambda_gbl);
-//        double C_gbl = Constants.fieldConversion * Math.abs(bfield) / pt_gbl;
-        double C_gbl = Constants.fieldConversion * Math.abs(bfield) * qOverP_gbl / Math.cos(lambda_gbl);
-
-        //calculate new phi0
-        double phi0_gbl = phi0 + xTPrimeCorr - corrPer.x() * C_gbl;
-
-        LOGGER.info("qOverP=" + qOverP + " qOverPCorr=" + qOverPCorr + " qOverP_gbl=" + qOverP_gbl + " ==> pGbl=" + 1.0 / qOverP_gbl + " C_gbl=" + C_gbl);
-
-        LOGGER.info(String.format("corrected helix: d0=%f, z0=%f, omega=%f, tanlambda=%f, phi0=%f, p=%f", dca_gbl, z0_gbl, C_gbl, slope_gbl, phi0_gbl, Math.abs(1 / qOverP_gbl)));
-
-        /*
-         // Strandlie, Wittek, NIMA 566, 2006
-         Matrix covariance_gbl = new Matrix(5, 5);
-         //helpers
-         double Bz = -Constants.fieldConversion * Math.abs(bfield); // TODO sign convention and should it be it scaled from Telsa?
-         double p = Math.abs(1 / qOverP_gbl);
-         double q = Math.signum(qOverP_gbl);
-         double tanLambda = Math.tan(lambda_gbl);
-         double cosLambda = Math.cos(lambda_gbl);
-         //        Hep3Vector B = new BasicHep3Vector(0, 0, Bz); // TODO sign convention?
-         Hep3Vector H = new BasicHep3Vector(0, 0, 1);
-         Hep3Vector T = HelixUtils.Direction(helix, 0.);
-         Hep3Vector HcrossT = VecOp.cross(H, T);
-         double alpha = HcrossT.magnitude(); // this should be Bvec cross TrackDir/|B|
-         double Q = Bz * q / p;
-         Hep3Vector Z = new BasicHep3Vector(0, 0, 1);
-         Hep3Vector J = VecOp.mult(1. / VecOp.cross(T, Z).magnitude(), VecOp.cross(T, Z));
-         Hep3Vector K = Z;
-         Hep3Vector U = VecOp.mult(-1, J);
-         Hep3Vector V = VecOp.cross(T, U);
-         Hep3Vector I = VecOp.cross(J, K);
-         Hep3Vector N = VecOp.mult(1 / alpha, VecOp.cross(H, T));
-         double UdotI = VecOp.dot(U, I);
-         double NdotV = VecOp.dot(N, V);
-         double NdotU = VecOp.dot(N, U);
-         double TdotI = VecOp.dot(T, I);
-         double VdotI = VecOp.dot(V, I);
-         double VdotK = VecOp.dot(V, K);
-         covariance_gbl.set(HelicalTrackFit.dcaIndex, FittedGblTrajectory.GBLPARIDX.XT.getValue(), VdotK / TdotI);
-         covariance_gbl.set(HelicalTrackFit.phi0Index, FittedGblTrajectory.GBLPARIDX.XTPRIME.getValue(), 1);
-         covariance_gbl.set(HelicalTrackFit.phi0Index, FittedGblTrajectory.GBLPARIDX.XT.getValue(), -alpha * Q * UdotI * NdotU / (cosLambda * TdotI));
-         covariance_gbl.set(HelicalTrackFit.phi0Index, FittedGblTrajectory.GBLPARIDX.YT.getValue(), -alpha * Q * VdotI * NdotU / (cosLambda * TdotI));
-         covariance_gbl.set(HelicalTrackFit.curvatureIndex, FittedGblTrajectory.GBLPARIDX.QOVERP.getValue(), -1 * Bz / cosLambda);
-         //        covariance_gbl.set(HelicalTrackFit.curvatureIndex, FittedGblTrajectory.GBLPARIDX.XTPRIME.getValue(), 0);
-         covariance_gbl.set(HelicalTrackFit.curvatureIndex, FittedGblTrajectory.GBLPARIDX.YTPRIME.getValue(), -1 * q * Bz * tanLambda / (p * cosLambda));
-         covariance_gbl.set(HelicalTrackFit.curvatureIndex, FittedGblTrajectory.GBLPARIDX.XT.getValue(), q * Bz * alpha * Q * tanLambda * UdotI * NdotV / (p * cosLambda * TdotI));
-         covariance_gbl.set(HelicalTrackFit.curvatureIndex, FittedGblTrajectory.GBLPARIDX.YT.getValue(), q * Bz * alpha * Q * tanLambda * VdotI * NdotV / (p * cosLambda * TdotI));
-         covariance_gbl.set(HelicalTrackFit.z0Index, FittedGblTrajectory.GBLPARIDX.YT.getValue(), -1 / TdotI);
-         covariance_gbl.set(HelicalTrackFit.slopeIndex, FittedGblTrajectory.GBLPARIDX.YTPRIME.getValue(), -1);
-         covariance_gbl.set(HelicalTrackFit.slopeIndex, FittedGblTrajectory.GBLPARIDX.XT.getValue(), alpha * Q * UdotI * NdotV / TdotI);
-         covariance_gbl.set(HelicalTrackFit.slopeIndex, FittedGblTrajectory.GBLPARIDX.YT.getValue(), alpha * Q * VdotI * NdotV / TdotI);
-
-         covariance_gbl.print(15, 13);
-         */
-        // Sho's magic
-        Matrix jacobian = new Matrix(5, 5);
-        jacobian.set(HelicalTrackFit.dcaIndex, FittedGblTrajectory.GBLPARIDX.XT.getValue(), -clToPerPrj.e(1, 0));
-        jacobian.set(HelicalTrackFit.dcaIndex, FittedGblTrajectory.GBLPARIDX.YT.getValue(), -clToPerPrj.e(1, 1));
-        jacobian.set(HelicalTrackFit.phi0Index, FittedGblTrajectory.GBLPARIDX.XTPRIME.getValue(), 1.0);
-        jacobian.set(HelicalTrackFit.phi0Index, FittedGblTrajectory.GBLPARIDX.YT.getValue(), clToPerPrj.e(0, 1) * C_gbl);
-        jacobian.set(HelicalTrackFit.curvatureIndex, FittedGblTrajectory.GBLPARIDX.QOVERP.getValue(), Constants.fieldConversion * Math.abs(bfield) / Math.cos(lambda_gbl));
-        jacobian.set(HelicalTrackFit.curvatureIndex, FittedGblTrajectory.GBLPARIDX.YTPRIME.getValue(), Constants.fieldConversion * Math.abs(bfield) * qOverP_gbl * Math.tan(lambda_gbl) / Math.cos(lambda_gbl));
-        jacobian.set(HelicalTrackFit.z0Index, FittedGblTrajectory.GBLPARIDX.XT.getValue(), clToPerPrj.e(2, 0));
-        jacobian.set(HelicalTrackFit.z0Index, FittedGblTrajectory.GBLPARIDX.YT.getValue(), clToPerPrj.e(2, 1));
-        jacobian.set(HelicalTrackFit.slopeIndex, FittedGblTrajectory.GBLPARIDX.YTPRIME.getValue(), Math.pow(Math.cos(lambda_gbl), -2.0));
-
-//        jacobian.print(15, 13);
-        Matrix helixCovariance = jacobian.times(locCov.times(jacobian.transpose()));
-        SymmetricMatrix cov = new SymmetricMatrix(5);
-        for (int i = 0; i < 5; i++) {
-            for (int j = 0; j < 5; j++) {
-                if (i >= j) {
-                    cov.setElement(i, j, helixCovariance.get(i, j));
-                }
-            }
-        }
-        LOGGER.info("corrected helix covariance:\n" + cov);
-
-        double parameters_gbl[] = new double[5];
-        parameters_gbl[HelicalTrackFit.dcaIndex] = dca_gbl;
-        parameters_gbl[HelicalTrackFit.phi0Index] = phi0_gbl;
-        parameters_gbl[HelicalTrackFit.curvatureIndex] = C_gbl;
-        parameters_gbl[HelicalTrackFit.z0Index] = z0_gbl;
-        parameters_gbl[HelicalTrackFit.slopeIndex] = slope_gbl;
-
-        return new Pair<double[], SymmetricMatrix>(parameters_gbl, cov);
-    }
-
-    public static GBLKinkData getKinks(GblTrajectory traj) {
-
-        // get corrections from GBL fit
-        Vector locPar = new Vector(5);
-        SymMatrix locCov = new SymMatrix(5);
-        float[] lambdaKinks = new float[traj.getNumPoints() - 1];
-        double[] phiKinks = new double[traj.getNumPoints() - 1];
-
-        double oldPhi = 0, oldLambda = 0;
-        for (int i = 0; i < traj.getNumPoints(); i++) {
-            traj.getResults(i + 1, locPar, locCov); // vertex point
-            double newPhi = locPar.get(FittedGblTrajectory.GBLPARIDX.XTPRIME.getValue());
-            double newLambda = locPar.get(FittedGblTrajectory.GBLPARIDX.YTPRIME.getValue());
-            if (i > 0) {
-                lambdaKinks[i - 1] = (float) (newLambda - oldLambda);
-                phiKinks[i - 1] = newPhi - oldPhi;
-            }
-            oldPhi = newPhi;
-            oldLambda = newLambda;
-        }
-
-        return new GBLKinkData(lambdaKinks, phiKinks);
-    }
+    
 
     /**
      * Do a GBL fit to an arbitrary set of strip hits, with a starting value of
@@ -298,19 +128,28 @@
      * @param bfield B-field
      * @return The refitted track.
      */
-    public static Pair<Track, GBLKinkData> refitTrack(HelicalTrackFit helix, Collection<TrackerHit> stripHits, Collection<TrackerHit> hth, int nIterations, MultipleScattering scattering, double bfield) {
-        List<TrackerHit> allHthList = sortHits(hth);
-        List<TrackerHit> sortedStripHits = sortHits(stripHits);
-        FittedGblTrajectory fit = MakeGblTracks.doGBLFit(helix, sortedStripHits, scattering, bfield, 0);
+    public static Pair<Track, GBLKinkData> refitTrack(HelicalTrackFit helix, Collection<TrackerHit> stripHits, Collection<TrackerHit> hth, int nIterations, int trackType, MultipleScattering scattering, double bfield) {
+        List<TrackerHit> allHthList = TrackUtils.sortHits(hth);
+        List<TrackerHit> sortedStripHits = TrackUtils.sortHits(stripHits);
+        FittedGblTrajectory fit = doGBLFit(helix, sortedStripHits, scattering, bfield, 0);
         for (int i = 0; i < nIterations; i++) {
-            Pair<Track, GBLKinkData> newTrack = MakeGblTracks.makeCorrectedTrack(fit, helix, allHthList, 0, bfield);
+            Pair<Track, GBLKinkData> newTrack = makeCorrectedTrack(fit, helix, allHthList, trackType, bfield);
             helix = TrackUtils.getHTF(newTrack.getFirst());
-            fit = MakeGblTracks.doGBLFit(helix, sortedStripHits, scattering, bfield, 0);
-        }
-        Pair<Track, GBLKinkData> mergedTrack = MakeGblTracks.makeCorrectedTrack(fit, helix, allHthList, 0, bfield);
+            fit = doGBLFit(helix, sortedStripHits, scattering, bfield, 0);
+        }
+        Pair<Track, GBLKinkData> mergedTrack = makeCorrectedTrack(fit, helix, allHthList, trackType, bfield);
         return mergedTrack;
     }
 
+    /**
+     * Do a GBL fit to a list of {@link TrackerHit}. 
+     * @param htf - seed fit
+     * @param stripHits - list of {@link TrackerHit}.
+     * @param _scattering - estimation of the multiple scattering {@link MultipleScattering}.
+     * @param bfield - magnitude of B-field.
+     * @param debug - debug flag.
+     * @return the fitted GBL trajectory
+     */
     public static FittedGblTrajectory doGBLFit(HelicalTrackFit htf, List<TrackerHit> stripHits, MultipleScattering _scattering, double bfield, int debug) {
         List<GBLStripClusterData> stripData = makeStripData(htf, stripHits, _scattering, bfield, debug);
         double bfac = Constants.fieldConversion * bfield;
@@ -319,6 +158,15 @@
         return fit;
     }
 
+    /**
+     * Create a list of {@link GBLStripClusterData} objects that can be used as input to the GBL fitter.
+     * @param htf
+     * @param stripHits
+     * @param _scattering
+     * @param _B
+     * @param _debug
+     * @return the list of GBL strip cluster data
+     */
     public static List<GBLStripClusterData> makeStripData(HelicalTrackFit htf, List<TrackerHit> stripHits, MultipleScattering _scattering, double _B, int _debug) {
         List<GBLStripClusterData> stripClusterDataList = new ArrayList<GBLStripClusterData>();
 
@@ -480,18 +328,4 @@
 
         return strip;
     }
-
-    private static List<TrackerHit> sortHits(Collection<TrackerHit> hits) {
-        List<TrackerHit> hitList = new ArrayList<TrackerHit>(hits);
-        Collections.sort(hitList, new LayerComparator());
-        return hitList;
-    }
-
-    private static class LayerComparator implements Comparator<TrackerHit> {
-
-        @Override
-        public int compare(TrackerHit o1, TrackerHit o2) {
-            return Integer.compare(TrackUtils.getLayer(o1), TrackUtils.getLayer(o2));
-        }
-    }
 }

Modified: java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/gbl/TruthResiduals.java
 =============================================================================
--- java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/gbl/TruthResiduals.java	(original)
+++ java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/gbl/TruthResiduals.java	Wed Apr 27 11:11:32 2016
@@ -73,14 +73,14 @@
         Map<Integer, List<SimTrackerHit>> simHitsLayerMap = new HashMap<Integer, List<SimTrackerHit> >();
         Map<MCParticle, List<SimTrackerHit> > mcPartSimHitsMap = new HashMap<MCParticle, List<SimTrackerHit > >();
         for(SimTrackerHit sh : simTrackerHits) {
-        	 Hep3Vector shpos = CoordinateTransformations.transformVectorToTracking(sh.getPositionVec());
-        	if(Math.abs(shpos.x()) < 50.0) {
-        		 System.out.printf("%s: Weird hit at %s (%s) in layer %d for MC part %d org %s p %s\n",
+             Hep3Vector shpos = CoordinateTransformations.transformVectorToTracking(sh.getPositionVec());
+            if(Math.abs(shpos.x()) < 50.0) {
+                 System.out.printf("%s: Weird hit at %s (%s) in layer %d for MC part %d org %s p %s\n",
                          this.getClass().getSimpleName(),sh.getPositionVec().toString(),shpos.toString(),sh.getIdentifierFieldValue("layer"),
                          sh.getMCParticle().getPDGID(),sh.getMCParticle().getOrigin().toString(),sh.getMCParticle().getMomentum().toString());
-        		 System.exit(1);
-        	}
-        	
+                 System.exit(1);
+            }
+            
             int layer  = sh.getIdentifierFieldValue("layer");
             if(!simHitsLayerMap.containsKey(layer)) {
                 simHitsLayerMap.put(layer, new ArrayList<SimTrackerHit>());
@@ -96,28 +96,28 @@
 
         
         for(MCParticle mcp : mcPartSimHitsMap.keySet()) {
-        	this.h_mcp_org.fill(mcp.getOriginX(), mcp.getOriginY());
+            this.h_mcp_org.fill(mcp.getOriginX(), mcp.getOriginY());
         }
 
         // Find the particle responsible for the hit in each layer and compute the residual
         
         for(int layer=1;layer<13;++layer) {
-        	//System.out.printf("layer %d: \n",layer);
+            //System.out.printf("layer %d: \n",layer);
             
             List<SimTrackerHit> simHitsLayer = simHitsLayerMap.get(layer);
-        	
+            
             
             if(simHitsLayer != null ) {
-            	
-            	if(simHitsLayer.size()==2) continue;
-            	
+                
+                if(simHitsLayer.size()==2) continue;
+                
                 for(SimTrackerHit simHit : simHitsLayer) {
-                	
-                	 // Find the MC particle
+                    
+                     // Find the MC particle
                     MCParticle mcp = simHit.getMCParticle();
                     
                     if(mcp.getMomentum().magnitude()<0.5) continue;
-                	
+                    
                     // Position in tracking coord
                     Hep3Vector simHitPosTracking = CoordinateTransformations.transformVectorToTracking(simHit.getPositionVec());
                     
@@ -171,24 +171,24 @@
                     }
                     
                     if(layer == 1 && res.y() > 0.1 && this.firstWeirdTrack) {
-                    	double dx = 1.0;
-                    	double xpos = mcp.getOriginZ();
-                    	while(xpos< 100.) {
-                    		xpos += dx;
-                    		trkposExtraPolator = CoordinateTransformations.transformVectorToTracking(TrackUtils.extrapolateTrack(htfTruth,xpos));
-                    		double ypos = trkposExtraPolator.y();
-                    		trkpos_y_vs_x.fill(xpos,ypos);
-                    	}
-                    	
-                    	int idummy = 0;
-                    	while(idummy<2) {
-                    		trkpos_y_vs_x.fill(simHitPosTracking.x(),simHitPosTracking.y());
-                    		idummy++;
-                    		//System.out.printf("weird simhit res pos %s \n", simHitPosTracking.toString());
-                    	}
-                    	
-                    	this.firstWeirdTrack = false;
-                    	
+                        double dx = 1.0;
+                        double xpos = mcp.getOriginZ();
+                        while(xpos< 100.) {
+                            xpos += dx;
+                            trkposExtraPolator = CoordinateTransformations.transformVectorToTracking(TrackUtils.extrapolateTrack(htfTruth,xpos));
+                            double ypos = trkposExtraPolator.y();
+                            trkpos_y_vs_x.fill(xpos,ypos);
+                        }
+                        
+                        int idummy = 0;
+                        while(idummy<2) {
+                            trkpos_y_vs_x.fill(simHitPosTracking.x(),simHitPosTracking.y());
+                            idummy++;
+                            //System.out.printf("weird simhit res pos %s \n", simHitPosTracking.toString());
+                        }
+                        
+                        this.firstWeirdTrack = false;
+                        
                     }
                     
                 
@@ -200,12 +200,12 @@
 
   
     public IHistogram getResidual(int layer,String coord) {
-    	if( !this.res_truthsimhit.containsKey(layer) ) 
-    		throw new RuntimeException("Error the layer number is not valid");
-    	if( coord!="x" || coord!="y")
-    		throw new RuntimeException("Error the coord is not valid");
-    	IHistogram1D h = this.res_truthsimhit.get(layer).get(coord=="x"?0:1);
-    	return h;
+        if( !this.res_truthsimhit.containsKey(layer) ) 
+            throw new RuntimeException("Error the layer number is not valid");
+        if( coord!="x" || coord!="y")
+            throw new RuntimeException("Error the coord is not valid");
+        IHistogram1D h = this.res_truthsimhit.get(layer).get(coord=="x"?0:1);
+        return h;
     }
     
 

Modified: java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/gbl/matrix/Matrix.java
 =============================================================================
--- java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/gbl/matrix/Matrix.java	(original)
+++ java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/gbl/matrix/Matrix.java	Wed Apr 27 11:11:32 2016
@@ -1,8 +1,6 @@
 package org.hps.recon.tracking.gbl.matrix;
 
-import java.io.BufferedReader;
 import java.io.PrintWriter;
-import java.io.StreamTokenizer;
 import java.text.DecimalFormat;
 import java.text.DecimalFormatSymbols;
 import java.text.NumberFormat;

Modified: java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/gbl/matrix/Vector.java
 =============================================================================
--- java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/gbl/matrix/Vector.java	(original)
+++ java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/recon/tracking/gbl/matrix/Vector.java	Wed Apr 27 11:11:32 2016
@@ -1,6 +1,5 @@
 package org.hps.recon.tracking.gbl.matrix;
 
-import java.io.PrintWriter;
 
 /**
  * Specializes the Matrix class to a vector.

Modified: java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/svt/alignment/BuildCompact.java
 =============================================================================
--- java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/svt/alignment/BuildCompact.java	(original)
+++ java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/svt/alignment/BuildCompact.java	Wed Apr 27 11:11:32 2016
@@ -23,7 +23,7 @@
 import org.apache.commons.cli.Option;
 import org.apache.commons.cli.Options;
 import org.apache.commons.cli.ParseException;
-import org.apache.commons.cli.DefaultParser;
+import org.apache.commons.cli.PosixParser;
 
 import org.jdom.Document;
 import org.jdom.Element;
@@ -49,361 +49,360 @@
  * Class building a new compact.xml detector based on MillepedeII input
  * corrections.
  * 
- * @author 	Per Ola Hansson Adrian <[log in to unmask]>
- * @date 	January 15, 2014 
+ * @author  Per Ola Hansson Adrian <[log in to unmask]> 
  */
 public class BuildCompact {
 
-	private static int runNumber = -1; //1351;
-	private static String detectorName = ""; //"HPS-TestRun-v7";
-	private static ConditionsManager conditionsManager = null;
-	
-	private static Options createCmdLineOpts() {
-		Options options = new Options();
-		options.addOption(new Option("c",true,"The path to the compact xml file."));
-		options.addOption(new Option("o",true,"The name of the new compact xml file."));
-		options.addOption(new Option("d",true,"Detector name."));
-		options.addOption(new Option("r",true,"Run number."));
-		
-		return options;
-	}
-	
-	private static void printHelpAndExit(Options options) {
-		HelpFormatter help = new HelpFormatter();
-		help.printHelp(" ", options);
-		System.exit(1);
-	}
-	
-	//private static buildDetector()
-
-	
-	
-	
-	
-	
-	private static class MilleParameterSet {
-		private IDetectorElement _det = null;
-		 List<MilleParameter> params = new ArrayList<MilleParameter>();
-		public MilleParameterSet(IDetectorElement d) {
-			setDetector(d);
-		}
-		public void setDetector(IDetectorElement d) {
-			_det = d;
-		}
-		public IDetectorElement getDetector() {
-			return _det;
-		}
-		public void add(MilleParameter par) {
-			params.add(par);
-		}
-		public Hep3Vector getLocalTranslation() {
-			Map<String,Double> m = new HashMap<String,Double>();
-			for(MilleParameter p : params) {
-				if (p.getType() == 1) {
-					if (p.getDim() == 1) m.put("u", p.getValue());
-					else if(p.getDim() == 2) m.put("v", p.getValue());
-					else m.put("w", p.getValue());
-				}
-			}
-			if(m.size() != 3) {
-				System.out.println("bad trans!!");
-				System.exit(1);
-			}
-			return new BasicHep3Vector(m.get("u"),m.get("v"),m.get("w"));
-			 
-		}
-		public Hep3Vector getLocalRotation() {
-			Map<String,Double> m = new HashMap<String,Double>();
-			for(MilleParameter p : params) {
-				if (p.getType() == 2) {
-					if (p.getDim() == 1) m.put("alpha",p.getValue());
-					else if(p.getDim() == 2) m.put("beta", p.getValue());
-					else m.put("gamma", p.getValue());
-				}
-			}
-			if(m.size() != 3) {
-				System.out.println("bad rot!!");
-				System.exit(1);
-			}
-			return new BasicHep3Vector(m.get("alpha"),m.get("beta"),m.get("gamma"));
-		}
-		public Hep3Vector getGlobalTranslation() {
-			ITransform3D localToGlobal = getLocalToGlobal();
-			return localToGlobal.getRotation().rotated(getLocalTranslation());
-		}
-		public double getGlobalTranslation(int d) {
-			return getGlobalTranslation().v()[d-1];
-		}
-		public Hep3Vector getGlobalRotation() {
-			ITransform3D localToGlobal = getLocalToGlobal();
-			return localToGlobal.getRotation().rotated(getLocalRotation());
-		}
-		public double getGlobalRotation(int d) {
-			return getGlobalRotation().v()[d-1];
-		}
-		public ITransform3D getLocalToGlobal() {
-			ITransform3D localToGlobal = ( (SiSensor) _det).getReadoutElectrodes(ChargeCarrier.HOLE).getLocalToGlobal();
-			return localToGlobal;
-		}		
-		
-	}
-	
-	public static void main(String[] args) {
-
-		// Setup command line input
-		Options options = createCmdLineOpts();
-		if (args.length == 0) {
-			printHelpAndExit(options);
-		}
-
-		CommandLineParser parser = new DefaultParser();
-		CommandLine cl = null;
-		try {
-			cl = parser.parse(options, args);
-		} catch (ParseException e) {
-			throw new RuntimeException("Problem parsing command line options.",e);
-		}
-		
-		String compactFilename = null;  
-		if(cl.hasOption("c")) {
-			compactFilename = cl.getOptionValue("c");
-		} else {
-			printHelpAndExit(options);
-		}
-		
-		if(cl.hasOption("d")) {
-			detectorName = cl.getOptionValue("d");
-		} else {
-			printHelpAndExit(options);
-		}
-
-		if(cl.hasOption("r")) {
-			runNumber = Integer.parseInt(cl.getOptionValue("r"));
-		} else {
-			printHelpAndExit(options);
-		}
-
-		String compactFilenameNew = "compact_new.xml";
-		if(cl.hasOption("o")) {
-			compactFilenameNew = cl.getOptionValue("o");
-		}
-
-		
-		
-		File compactFile = new File(compactFilename);
-		
-		// read XML
-		SAXBuilder builder = new SAXBuilder();
-		Document compact_document = null;
-		try {
-			compact_document = (Document) builder.build(compactFile);
-		} catch (JDOMException | IOException e1) {
-			throw new RuntimeException("problem with JDOM ", e1);
-		}
-				
-		// read detector geometry
-		FileInputStream inCompact;
-		try {
-			inCompact = new FileInputStream(compactFile);
-		} catch (FileNotFoundException e) {
-			throw new RuntimeException("cannot open compact file",e);
-		}
-
-		GeometryReader reader = new GeometryReader();
-		Detector det;
-		try {
-			det = reader.read(inCompact);
-		} catch (IOException | JDOMException | ElementCreationException e) {
-			throw new RuntimeException("problem reading compact file",e);
-		}
-
-		
-		// set conditions in order to be able to determine which sensors are where in the geometry
-		setConditions(detectorName,runNumber);
-		
-		// Loop over all millepede input files and match parameters with detectors
-		
-		List<MilleParameterSet> list_det = new ArrayList<MilleParameterSet>();
-		
-		FileInputStream inMille = null;
-		BufferedReader brMille = null;
-		try {
-			for(String milleFilename : cl.getArgs()) {
-				inMille = new FileInputStream(milleFilename);
-				brMille = new BufferedReader(new InputStreamReader(inMille));
-				String line;
-				while((line = brMille.readLine()) != null) {
-					//System.out.printf("%s\n",line);
-					if(!line.contains("Parameter") && !line.contains("!")) {
-						
-						MilleParameter par = new MilleParameter(line);
-						//System.out.println(par.getXMLName() + " " + par.getValue());
-						
-						SiSensor detEle = getTrackerDetElement( det,  par);
-						if(detEle == null) {
-							System.out.println("Couldn't find detector for param " + par.getId());
-							System.exit(1);
-						}
-						System.out.println("Found detector  " + detEle.getName());
-						if(detEle.getClass().isInstance(SiSensor.class)) {
-							System.out.println("yeah");
-						}
-
-						// do we have it already?
-						MilleParameterSet useSet = null;
-						for(MilleParameterSet set : list_det) {
-							if(set.getDetector() == detEle) {
-								useSet = set;
-							}
-						}
-						
-						if (useSet == null) {
-							useSet = new MilleParameterSet(detEle);
-							list_det.add(useSet);
-						}
-						
-						//add the parameter
-						useSet.add(par);
-						
-						
-					}
-				}
-				brMille.close();
-			}
-		}
-		catch (IOException e) {
-			throw new RuntimeException("problem reading mille file",e);
-		}
-		
-		for(MilleParameterSet set : list_det) {
-			System.out.println("Detector " + set.getDetector().getName());
-			List<MilleParameter> pars = set.params;
-			for(MilleParameter p : pars) {
-				System.out.println(p.getXMLName() + " " + p.getValue());
-				Element node = findXMLNode(compact_document,p.getXMLName());
-				double value = 0.0;
-				if(p.getType() == 1){
-					value = set.getGlobalTranslation(p.getDim());
-				} else if(p.getType() == 2){
-					value = set.getGlobalRotation(p.getDim());
-				} else {
-					System.out.println("This type is illdefnied " + p.getType());
-					System.exit(1);
-				}
-				node.setAttribute("value", String.format("%.6f",value));
-			}
-			Hep3Vector u = getMeasuredCoordinate( (SiSensor )set.getDetector());
-			System.out.println("u  " + u.toString());
-			System.out.println("t (local)  " + set.getLocalTranslation().toString());
-			System.out.println("t (global) " + set.getGlobalTranslation().toString());
-			System.out.println("r (local)  " + set.getLocalRotation().toString());
-			System.out.println("r (global) " + set.getGlobalRotation().toString());
-			
-			
-		}
-
-		// Save new XML file
-		
-		XMLOutputter xmlOutput = new XMLOutputter();
-		// display nice 
-		//xmlOutput.setFormat(Format.getPrettyFormat());
-		try {
-			xmlOutput.output(compact_document, new FileWriter(compactFilenameNew));
-		} catch (IOException e) {
-			throw new RuntimeException("problem with xml output",e);
-		}
-			
-		
-		
-		
-		
-	}
-
-	private static Element findXMLNode(Document document, String name) {
-		Element rootNode = document.getRootElement();
-		List list = rootNode.getChildren("define");
-		for(int i = 0; i < list.size(); ++i ) {
-			Element node = (Element) list.get(i);
-			List llist = node.getChildren("constant");
-			//System.out.println("length of list " + llist.size());
-			for(int ii = 0; ii < llist.size(); ++ii ) {
-				Element nnode = (Element) llist.get(ii);
-				//System.out.println("node name " + nnode.getAttributeValue("name") + " " + nnode.getAttributeValue("value") );
-				//if(nnode.getAttributeValue("name").contains(name)) {
-				if(nnode.getAttributeValue("name").compareTo(name) ==0 ) {
-					return nnode;
-				}
-			}
-		}	
-		
-		return null;
-	}
-	
-	private static void setConditions(String detectorName, int run) {
-
-		try {
-			if(conditionsManager == null) {
-				conditionsManager = ConditionsManager.defaultInstance();				
-			}
-			conditionsManager.setDetector(detectorName, run);
-			
-		} catch (ConditionsNotFoundException e1) {
-			throw new RuntimeException("problem setting conditions",e1);
-		}
-		
-	}
-
-	private static SiSensor getTrackerDetElement(Detector det, MilleParameter par) {
-		List<SiSensor> sensors = det.getSubdetector("Tracker").getDetectorElement().findDescendants(SiSensor.class);
+    private static int runNumber = -1; //1351;
+    private static String detectorName = ""; //"HPS-TestRun-v7";
+    private static ConditionsManager conditionsManager = null;
+    
+    private static Options createCmdLineOpts() {
+        Options options = new Options();
+        options.addOption(new Option("c",true,"The path to the compact xml file."));
+        options.addOption(new Option("o",true,"The name of the new compact xml file."));
+        options.addOption(new Option("d",true,"Detector name."));
+        options.addOption(new Option("r",true,"Run number."));
+        
+        return options;
+    }
+    
+    private static void printHelpAndExit(Options options) {
+        HelpFormatter help = new HelpFormatter();
+        help.printHelp(" ", options);
+        System.exit(1);
+    }
+    
+    //private static buildDetector()
+
+    
+    
+    
+    
+    
+    private static class MilleParameterSet {
+        private IDetectorElement _det = null;
+         List<MilleParameter> params = new ArrayList<MilleParameter>();
+        public MilleParameterSet(IDetectorElement d) {
+            setDetector(d);
+        }
+        public void setDetector(IDetectorElement d) {
+            _det = d;
+        }
+        public IDetectorElement getDetector() {
+            return _det;
+        }
+        public void add(MilleParameter par) {
+            params.add(par);
+        }
+        public Hep3Vector getLocalTranslation() {
+            Map<String,Double> m = new HashMap<String,Double>();
+            for(MilleParameter p : params) {
+                if (p.getType() == 1) {
+                    if (p.getDim() == 1) m.put("u", p.getValue());
+                    else if(p.getDim() == 2) m.put("v", p.getValue());
+                    else m.put("w", p.getValue());
+                }
+            }
+            if(m.size() != 3) {
+                System.out.println("bad trans!!");
+                System.exit(1);
+            }
+            return new BasicHep3Vector(m.get("u"),m.get("v"),m.get("w"));
+             
+        }
+        public Hep3Vector getLocalRotation() {
+            Map<String,Double> m = new HashMap<String,Double>();
+            for(MilleParameter p : params) {
+                if (p.getType() == 2) {
+                    if (p.getDim() == 1) m.put("alpha",p.getValue());
+                    else if(p.getDim() == 2) m.put("beta", p.getValue());
+                    else m.put("gamma", p.getValue());
+                }
+            }
+            if(m.size() != 3) {
+                System.out.println("bad rot!!");
+                System.exit(1);
+            }
+            return new BasicHep3Vector(m.get("alpha"),m.get("beta"),m.get("gamma"));
+        }
+        public Hep3Vector getGlobalTranslation() {
+            ITransform3D localToGlobal = getLocalToGlobal();
+            return localToGlobal.getRotation().rotated(getLocalTranslation());
+        }
+        public double getGlobalTranslation(int d) {
+            return getGlobalTranslation().v()[d-1];
+        }
+        public Hep3Vector getGlobalRotation() {
+            ITransform3D localToGlobal = getLocalToGlobal();
+            return localToGlobal.getRotation().rotated(getLocalRotation());
+        }
+        public double getGlobalRotation(int d) {
+            return getGlobalRotation().v()[d-1];
+        }
+        public ITransform3D getLocalToGlobal() {
+            ITransform3D localToGlobal = ( (SiSensor) _det).getReadoutElectrodes(ChargeCarrier.HOLE).getLocalToGlobal();
+            return localToGlobal;
+        }       
+        
+    }
+    
+    public static void main(String[] args) {
+
+        // Setup command line input
+        Options options = createCmdLineOpts();
+        if (args.length == 0) {
+            printHelpAndExit(options);
+        }
+
+        CommandLineParser parser = new PosixParser();
+        CommandLine cl = null;
+        try {
+            cl = parser.parse(options, args);
+        } catch (ParseException e) {
+            throw new RuntimeException("Problem parsing command line options.",e);
+        }
+        
+        String compactFilename = null;  
+        if(cl.hasOption("c")) {
+            compactFilename = cl.getOptionValue("c");
+        } else {
+            printHelpAndExit(options);
+        }
+        
+        if(cl.hasOption("d")) {
+            detectorName = cl.getOptionValue("d");
+        } else {
+            printHelpAndExit(options);
+        }
+
+        if(cl.hasOption("r")) {
+            runNumber = Integer.parseInt(cl.getOptionValue("r"));
+        } else {
+            printHelpAndExit(options);
+        }
+
+        String compactFilenameNew = "compact_new.xml";
+        if(cl.hasOption("o")) {
+            compactFilenameNew = cl.getOptionValue("o");
+        }
+
+        
+        
+        File compactFile = new File(compactFilename);
+        
+        // read XML
+        SAXBuilder builder = new SAXBuilder();
+        Document compact_document = null;
+        try {
+            compact_document = (Document) builder.build(compactFile);
+        } catch (JDOMException | IOException e1) {
+            throw new RuntimeException("problem with JDOM ", e1);
+        }
+                
+        // read detector geometry
+        FileInputStream inCompact;
+        try {
+            inCompact = new FileInputStream(compactFile);
+        } catch (FileNotFoundException e) {
+            throw new RuntimeException("cannot open compact file",e);
+        }
+
+        GeometryReader reader = new GeometryReader();
+        Detector det;
+        try {
+            det = reader.read(inCompact);
+        } catch (IOException | JDOMException | ElementCreationException e) {
+            throw new RuntimeException("problem reading compact file",e);
+        }
+
+        
+        // set conditions in order to be able to determine which sensors are where in the geometry
+        setConditions(detectorName,runNumber);
+        
+        // Loop over all millepede input files and match parameters with detectors
+        
+        List<MilleParameterSet> list_det = new ArrayList<MilleParameterSet>();
+        
+        FileInputStream inMille = null;
+        BufferedReader brMille = null;
+        try {
+            for(String milleFilename : cl.getArgs()) {
+                inMille = new FileInputStream(milleFilename);
+                brMille = new BufferedReader(new InputStreamReader(inMille));
+                String line;
+                while((line = brMille.readLine()) != null) {
+                    //System.out.printf("%s\n",line);
+                    if(!line.contains("Parameter") && !line.contains("!")) {
+                        
+                        MilleParameter par = new MilleParameter(line);
+                        //System.out.println(par.getXMLName() + " " + par.getValue());
+                        
+                        SiSensor detEle = getTrackerDetElement( det,  par);
+                        if(detEle == null) {
+                            System.out.println("Couldn't find detector for param " + par.getId());
+                            System.exit(1);
+                        }
+                        System.out.println("Found detector  " + detEle.getName());
+                        if(detEle.getClass().isInstance(SiSensor.class)) {
+                            System.out.println("yeah");
+                        }
+
+                        // do we have it already?
+                        MilleParameterSet useSet = null;
+                        for(MilleParameterSet set : list_det) {
+                            if(set.getDetector() == detEle) {
+                                useSet = set;
+                            }
+                        }
+                        
+                        if (useSet == null) {
+                            useSet = new MilleParameterSet(detEle);
+                            list_det.add(useSet);
+                        }
+                        
+                        //add the parameter
+                        useSet.add(par);
+                        
+                        
+                    }
+                }
+                brMille.close();
+            }
+        }
+        catch (IOException e) {
+            throw new RuntimeException("problem reading mille file",e);
+        }
+        
+        for(MilleParameterSet set : list_det) {
+            System.out.println("Detector " + set.getDetector().getName());
+            List<MilleParameter> pars = set.params;
+            for(MilleParameter p : pars) {
+                System.out.println(p.getXMLName() + " " + p.getValue());
+                Element node = findXMLNode(compact_document,p.getXMLName());
+                double value = 0.0;
+                if(p.getType() == 1){
+                    value = set.getGlobalTranslation(p.getDim());
+                } else if(p.getType() == 2){
+                    value = set.getGlobalRotation(p.getDim());
+                } else {
+                    System.out.println("This type is illdefnied " + p.getType());
+                    System.exit(1);
+                }
+                node.setAttribute("value", String.format("%.6f",value));
+            }
+            Hep3Vector u = getMeasuredCoordinate( (SiSensor )set.getDetector());
+            System.out.println("u  " + u.toString());
+            System.out.println("t (local)  " + set.getLocalTranslation().toString());
+            System.out.println("t (global) " + set.getGlobalTranslation().toString());
+            System.out.println("r (local)  " + set.getLocalRotation().toString());
+            System.out.println("r (global) " + set.getGlobalRotation().toString());
+            
+            
+        }
+
+        // Save new XML file
+        
+        XMLOutputter xmlOutput = new XMLOutputter();
+        // display nice 
+        //xmlOutput.setFormat(Format.getPrettyFormat());
+        try {
+            xmlOutput.output(compact_document, new FileWriter(compactFilenameNew));
+        } catch (IOException e) {
+            throw new RuntimeException("problem with xml output",e);
+        }
+            
+        
+        
+        
+        
+    }
+
+    private static Element findXMLNode(Document document, String name) {
+        Element rootNode = document.getRootElement();
+        List list = rootNode.getChildren("define");
+        for(int i = 0; i < list.size(); ++i ) {
+            Element node = (Element) list.get(i);
+            List llist = node.getChildren("constant");
+            //System.out.println("length of list " + llist.size());
+            for(int ii = 0; ii < llist.size(); ++ii ) {
+                Element nnode = (Element) llist.get(ii);
+                //System.out.println("node name " + nnode.getAttributeValue("name") + " " + nnode.getAttributeValue("value") );
+                //if(nnode.getAttributeValue("name").contains(name)) {
+                if(nnode.getAttributeValue("name").compareTo(name) ==0 ) {
+                    return nnode;
+                }
+            }
+        }   
+        
+        return null;
+    }
+    
+    private static void setConditions(String detectorName, int run) {
+
+        try {
+            if(conditionsManager == null) {
+                conditionsManager = ConditionsManager.defaultInstance();                
+            }
+            conditionsManager.setDetector(detectorName, run);
+            
+        } catch (ConditionsNotFoundException e1) {
+            throw new RuntimeException("problem setting conditions",e1);
+        }
+        
+    }
+
+    private static SiSensor getTrackerDetElement(Detector det, MilleParameter par) {
+        List<SiSensor> sensors = det.getSubdetector("Tracker").getDetectorElement().findDescendants(SiSensor.class);
         //List<SiTrackerModule> modules = det.getDetectorElement().findDescendants(SiTrackerModule.class);
         //System.out.printf("%d sensors\n",sensors.size());
         for (SiSensor module: sensors) {
             // Create DAQ Maps
-        	boolean isTop = ((HpsSiSensor) module).isTopLayer();
-        	int h = par.getHalf();
-        	if ((isTop && h == 1) || (!isTop && h == 2)) {
-        		int layer = ((HpsSiSensor) module).getLayerNumber();
-        		if (layer == par.getSensor()) {
-        			//found match
-        			return module;
-        		}
-        	}
+            boolean isTop = ((HpsSiSensor) module).isTopLayer();
+            int h = par.getHalf();
+            if ((isTop && h == 1) || (!isTop && h == 2)) {
+                int layer = ((HpsSiSensor) module).getLayerNumber();
+                if (layer == par.getSensor()) {
+                    //found match
+                    return module;
+                }
+            }
         }
         return null;
-		
-	}
-	
-
-	
-	private static class DetectorList<K> extends ArrayList<DetAlignConstants> {
-		//List<DetAlignConstants> _detectors = new ArrayList<DetAlignConstants>();
-		public DetectorList() {
-		}
-		
-		public boolean contains(IDetectorElement detEle) {
-			return this.get(detEle) == null ? false : true;
-		}
-		
-		public DetAlignConstants get(IDetectorElement detEle) {
-			for(DetAlignConstants d : this) {
-				if (d == detEle) {
-					return d;
-				}
-			}
-			return null;
-		}
-		public void print() {
-			System.out.println("==== " + this.size() + " detectors has alignment corrections ====");
-			for(DetAlignConstants det : this) {
-				det.print();
-			}
-		}
-		
-	}
-	
-	
-	
-	private static Hep3Vector getTrackingMeasuredCoordinate(SiSensor sensor)
+        
+    }
+    
+
+    
+    private static class DetectorList<K> extends ArrayList<DetAlignConstants> {
+        //List<DetAlignConstants> _detectors = new ArrayList<DetAlignConstants>();
+        public DetectorList() {
+        }
+        
+        public boolean contains(IDetectorElement detEle) {
+            return this.get(detEle) == null ? false : true;
+        }
+        
+        public DetAlignConstants get(IDetectorElement detEle) {
+            for(DetAlignConstants d : this) {
+                if (d == detEle) {
+                    return d;
+                }
+            }
+            return null;
+        }
+        public void print() {
+            System.out.println("==== " + this.size() + " detectors has alignment corrections ====");
+            for(DetAlignConstants det : this) {
+                det.print();
+            }
+        }
+        
+    }
+    
+    
+    
+    private static Hep3Vector getTrackingMeasuredCoordinate(SiSensor sensor)
     {
         // p-side unit vector
         ITransform3D electrodes_to_global = sensor.getReadoutElectrodes(ChargeCarrier.HOLE).getLocalToGlobal();
@@ -411,8 +410,8 @@
         measuredCoordinate = VecOp.mult(VecOp.mult(CoordinateTransformations.getMatrix(),electrodes_to_global.getRotation().getRotationMatrix()), measuredCoordinate);
         return measuredCoordinate;
     }
-	
-	private static Hep3Vector getMeasuredCoordinate(SiSensor sensor)
+    
+    private static Hep3Vector getMeasuredCoordinate(SiSensor sensor)
     {
         // p-side unit vector
         ITransform3D electrodes_to_global = sensor.getReadoutElectrodes(ChargeCarrier.HOLE).getLocalToGlobal();
@@ -420,127 +419,127 @@
         measuredCoordinate = VecOp.mult(electrodes_to_global.getRotation().getRotationMatrix(), measuredCoordinate);
         return measuredCoordinate;
     }
-	
-	
-	
-	private static class SiSensorDetAlignConstants extends DetAlignConstants {
-		public SiSensorDetAlignConstants(IDetectorElement det) {
-			super(det);
-		}
-		public void transform() {
-			ITransform3D localToGlobal = null;
-			if(_det.getClass().isInstance(SiSensor.class)) {
-				localToGlobal = ( (SiSensor) _det).getReadoutElectrodes(ChargeCarrier.HOLE).getLocalToGlobal();
-			}
-			//Translation
-			Hep3Vector t_local = _constants.getTranslationVector();
-			Hep3Vector t_global = localToGlobal.getRotation().rotated(t_local);
-			_constants.addGlobalTranslation(t_global);
-			//Rotation
-			Hep3Vector r_local = _constants.getRotationVector();
-			Hep3Vector r_global = localToGlobal.getRotation().rotated(r_local);
-			_constants.addGlobalRotation(r_global);
-		}
-		
-	}
-	
-	private static abstract class DetAlignConstants {
-		protected IDetectorElement _det = null;
-		protected AlignConstants<String,Double> _constants = new AlignConstants<String,Double>();
-		public DetAlignConstants(IDetectorElement det) {
-			_det = det;
-		}
-		public abstract void transform();
-		public void add(MilleParameter par) {
-			this._constants.add(par);
-		}
-		public void print() {
-			System.out.println(_det.getName());
-			for(Entry<String, Double>  c : this._constants.entrySet()) {
-				System.out.println(c.getKey() + " " + c.getValue());
-			}
-			System.out.println("Local translation  " + _constants.getTranslationVector().toString());
-			System.out.println("Global translation " + _constants.getTranslationVectorGlobal().toString());
-			System.out.println("Local rotation     " + _constants.getRotationVector().toString());
-			System.out.println("Global rotation    " + _constants.getRotationVectorGlobal().toString());
-			
-
-		}
-			
-		
-	}
-	
-	
-	
-	private static class AlignConstants<K,V> extends HashMap<String,Double> {
-		List<MilleParameter> _pars = new ArrayList<MilleParameter>();
-		public AlignConstants() {
-			super();
-		}
-		public void add(MilleParameter p) {
-			_pars.add(p);
-			if (p.getType() == 1) {
-				if (p.getDim() == 1) this.put("u", p.getValue());
-				else if(p.getDim() == 2) this.put("v", p.getValue());
-				else this.put("w", p.getValue());
-			}
-			else {
-				if (p.getDim() == 1) this.put("alpha", p.getValue());
-				else if(p.getDim() == 2) this.put("beta", p.getValue());
-				else this.put("gamma", p.getValue());
-			}
-		}
-		public void print() {
-			for(Entry<String,Double> e : this.entrySet()) {
-				System.out.println(e.getKey() + " " + e.getValue());
-			}
-		}
-		public Hep3Vector getTranslationVector() {
-			if(!this.containsKey("u") || !this.containsKey("v") || !this.containsKey("w")) {
-				System.out.println("missing pars for translation");
-				print();
-				System.exit(1);
-			}
-			return new BasicHep3Vector(this.get("u"),this.get("v"),this.get("w"));
-		}
-		public Hep3Vector getTranslationVectorGlobal() {
-			if(!this.containsKey("x") || !this.containsKey("y") || !this.containsKey("z")) {
-				System.out.println("missing pars for global translation");
-				print();
-				System.exit(1);
-			}
-			return new BasicHep3Vector(this.get("x"),this.get("y"),this.get("z"));
-		}
-		public Hep3Vector getRotationVector() {
-			if(!this.containsKey("alpha") || !this.containsKey("beta") || !this.containsKey("gamma")) {
-				System.out.println("missing pars for rotation");
-				print();
-				System.exit(1);
-			}
-			return new BasicHep3Vector(this.get("alpha"),this.get("beta"),this.get("gamma"));
-		}
-		public Hep3Vector getRotationVectorGlobal() {
-			if(!this.containsKey("rx") || !this.containsKey("ry") || !this.containsKey("rz")) {
-				System.out.println("missing pars for global rotation");
-				print();
-				System.exit(1);
-			}
-			return new BasicHep3Vector(this.get("rx"),this.get("ry"),this.get("rz"));
-		}
-		private void addGlobalTranslation(Hep3Vector t) {
-			this.put("x", t.x()); 
-			this.put("y", t.y());
-			this.put("z", t.z());
-		}
-		private void addGlobalRotation(Hep3Vector t) {
-			this.put("rx", t.x()); 
-			this.put("ry", t.y());
-			this.put("rz", t.z());
-		}
-		
-		
-	}
-	
-	
+    
+    
+    
+    private static class SiSensorDetAlignConstants extends DetAlignConstants {
+        public SiSensorDetAlignConstants(IDetectorElement det) {
+            super(det);
+        }
+        public void transform() {
+            ITransform3D localToGlobal = null;
+            if(_det.getClass().isInstance(SiSensor.class)) {
+                localToGlobal = ( (SiSensor) _det).getReadoutElectrodes(ChargeCarrier.HOLE).getLocalToGlobal();
+            }
+            //Translation
+            Hep3Vector t_local = _constants.getTranslationVector();
+            Hep3Vector t_global = localToGlobal.getRotation().rotated(t_local);
+            _constants.addGlobalTranslation(t_global);
+            //Rotation
+            Hep3Vector r_local = _constants.getRotationVector();
+            Hep3Vector r_global = localToGlobal.getRotation().rotated(r_local);
+            _constants.addGlobalRotation(r_global);
+        }
+        
+    }
+    
+    private static abstract class DetAlignConstants {
+        protected IDetectorElement _det = null;
+        protected AlignConstants<String,Double> _constants = new AlignConstants<String,Double>();
+        public DetAlignConstants(IDetectorElement det) {
+            _det = det;
+        }
+        public abstract void transform();
+        public void add(MilleParameter par) {
+            this._constants.add(par);
+        }
+        public void print() {
+            System.out.println(_det.getName());
+            for(Entry<String, Double>  c : this._constants.entrySet()) {
+                System.out.println(c.getKey() + " " + c.getValue());
+            }
+            System.out.println("Local translation  " + _constants.getTranslationVector().toString());
+            System.out.println("Global translation " + _constants.getTranslationVectorGlobal().toString());
+            System.out.println("Local rotation     " + _constants.getRotationVector().toString());
+            System.out.println("Global rotation    " + _constants.getRotationVectorGlobal().toString());
+            
+
+        }
+            
+        
+    }
+    
+    
+    
+    private static class AlignConstants<K,V> extends HashMap<String,Double> {
+        List<MilleParameter> _pars = new ArrayList<MilleParameter>();
+        public AlignConstants() {
+            super();
+        }
+        public void add(MilleParameter p) {
+            _pars.add(p);
+            if (p.getType() == 1) {
+                if (p.getDim() == 1) this.put("u", p.getValue());
+                else if(p.getDim() == 2) this.put("v", p.getValue());
+                else this.put("w", p.getValue());
+            }
+            else {
+                if (p.getDim() == 1) this.put("alpha", p.getValue());
+                else if(p.getDim() == 2) this.put("beta", p.getValue());
+                else this.put("gamma", p.getValue());
+            }
+        }
+        public void print() {
+            for(Entry<String,Double> e : this.entrySet()) {
+                System.out.println(e.getKey() + " " + e.getValue());
+            }
+        }
+        public Hep3Vector getTranslationVector() {
+            if(!this.containsKey("u") || !this.containsKey("v") || !this.containsKey("w")) {
+                System.out.println("missing pars for translation");
+                print();
+                System.exit(1);
+            }
+            return new BasicHep3Vector(this.get("u"),this.get("v"),this.get("w"));
+        }
+        public Hep3Vector getTranslationVectorGlobal() {
+            if(!this.containsKey("x") || !this.containsKey("y") || !this.containsKey("z")) {
+                System.out.println("missing pars for global translation");
+                print();
+                System.exit(1);
+            }
+            return new BasicHep3Vector(this.get("x"),this.get("y"),this.get("z"));
+        }
+        public Hep3Vector getRotationVector() {
+            if(!this.containsKey("alpha") || !this.containsKey("beta") || !this.containsKey("gamma")) {
+                System.out.println("missing pars for rotation");
+                print();
+                System.exit(1);
+            }
+            return new BasicHep3Vector(this.get("alpha"),this.get("beta"),this.get("gamma"));
+        }
+        public Hep3Vector getRotationVectorGlobal() {
+            if(!this.containsKey("rx") || !this.containsKey("ry") || !this.containsKey("rz")) {
+                System.out.println("missing pars for global rotation");
+                print();
+                System.exit(1);
+            }
+            return new BasicHep3Vector(this.get("rx"),this.get("ry"),this.get("rz"));
+        }
+        private void addGlobalTranslation(Hep3Vector t) {
+            this.put("x", t.x()); 
+            this.put("y", t.y());
+            this.put("z", t.z());
+        }
+        private void addGlobalRotation(Hep3Vector t) {
+            this.put("rx", t.x()); 
+            this.put("ry", t.y());
+            this.put("rz", t.z());
+        }
+        
+        
+    }
+    
+    
 
 }

Modified: java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/svt/alignment/BuildMillepedeCompact.java
 =============================================================================
--- java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/svt/alignment/BuildMillepedeCompact.java	(original)
+++ java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/svt/alignment/BuildMillepedeCompact.java	Wed Apr 27 11:11:32 2016
@@ -6,22 +6,14 @@
  * created on 1/15/2014
  */
 
-import hep.physics.vec.BasicHep3Vector;
-import hep.physics.vec.Hep3Vector;
-import hep.physics.vec.VecOp;
-
 import java.io.BufferedReader;
 import java.io.File;
 import java.io.FileInputStream;
-import java.io.FileNotFoundException;
 import java.io.FileWriter;
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
 
 import org.apache.commons.cli.CommandLine;
 import org.apache.commons.cli.CommandLineParser;
@@ -29,252 +21,271 @@
 import org.apache.commons.cli.Option;
 import org.apache.commons.cli.Options;
 import org.apache.commons.cli.ParseException;
-import org.apache.commons.cli.DefaultParser;
-import org.hps.recon.tracking.CoordinateTransformations;
-import org.jdom.Attribute;
+import org.apache.commons.cli.PosixParser;
 import org.jdom.DataConversionException;
 import org.jdom.Document;
 import org.jdom.Element;
 import org.jdom.JDOMException;
 import org.jdom.input.SAXBuilder;
 import org.jdom.output.XMLOutputter;
-import org.lcsim.conditions.ConditionsManager;
-import org.lcsim.conditions.ConditionsManager.ConditionsNotFoundException;
-import org.lcsim.detector.IDetectorElement;
-import org.lcsim.detector.ITransform3D;
-import org.lcsim.detector.tracker.silicon.ChargeCarrier;
-import org.lcsim.detector.tracker.silicon.SiSensor;
-import org.lcsim.geometry.Detector;
-import org.lcsim.geometry.GeometryReader;
 import org.lcsim.geometry.compact.converter.MilleParameter;
-import org.lcsim.util.xml.ElementFactory.ElementCreationException;
 
 
 public class BuildMillepedeCompact {
 
-	private static String detectorName = "Tracker";
-	private static boolean replaceConstant = false;
+    private static String detectorName = "Tracker";
+    private static boolean replaceConstant = false;
     private static boolean calcNewValue = true;
     private static boolean ignoreBeamspot = true;
+    private static boolean flipRotationCorrection = false;
 
 
 
     private static Options createCmdLineOpts() {
-		Options options = new Options();
-		options.addOption(new Option("c",true,"The path to the compact xml file."));
-		options.addOption(new Option("o",true,"The name of the new compact xml file."));
-		options.addOption(new Option("r", false, "Replace correction instead of adding to it."));
+        Options options = new Options();
+        options.addOption(new Option("c",true,"The path to the compact xml file."));
+        options.addOption(new Option("o",true,"The name of the new compact xml file."));
+        options.addOption(new Option("r", false, "Replace correction instead of adding to it."));
         options.addOption(new Option("t", false, "Add a text string as a new value instead of adding to it."));
-		return options;
-	}
-	
-	private static void printHelpAndExit(Options options) {
-		HelpFormatter help = new HelpFormatter();
-		help.printHelp(" ", options);
-		System.exit(1);
-	}
-	
-		
-	public static void main(String[] args) {
-
-		// Setup command line input
-		Options options = createCmdLineOpts();
-		if (args.length == 0) {
-			printHelpAndExit(options);
-		}
-
-		CommandLineParser parser = new DefaultParser();
-		CommandLine cl = null;
-		try {
-			cl = parser.parse(options, args);
-		} catch (ParseException e) {
-			throw new RuntimeException("Problem parsing command line options.",e);
-		}
-		
-		String compactFilename = null;  
-		if(cl.hasOption("c")) {
-			compactFilename = cl.getOptionValue("c");
-		} else {
-			printHelpAndExit(options);
-		}
-		
-		String compactFilenameNew = "compact_new.xml";
-		if(cl.hasOption("o")) {
-			compactFilenameNew = cl.getOptionValue("o");
-		}
-		
-		
-		
-		if(cl.hasOption("r")) {
-		    replaceConstant = true;
-		}
-
-		if(cl.hasOption("t")) {
+        options.addOption(new Option("f",false, "Flip sign of rotation corrections."));
+        return options;
+    }
+    
+    private static void printHelpAndExit(Options options) {
+        HelpFormatter help = new HelpFormatter();
+        help.printHelp(" ", options);
+        System.exit(1);
+    }
+    
+        
+    public static void main(String[] args) {
+
+        // Setup command line input
+        Options options = createCmdLineOpts();
+        if (args.length == 0) {
+            printHelpAndExit(options);
+        }
+
+        CommandLineParser parser = new PosixParser();
+        CommandLine cl = null;
+        try {
+            cl = parser.parse(options, args);
+        } catch (ParseException e) {
+            throw new RuntimeException("Problem parsing command line options.",e);
+        }
+        
+        String compactFilename = null;  
+        if(cl.hasOption("c")) {
+            compactFilename = cl.getOptionValue("c");
+        } else {
+            printHelpAndExit(options);
+        }
+        
+        String compactFilenameNew = "compact_new.xml";
+        if(cl.hasOption("o")) {
+            compactFilenameNew = cl.getOptionValue("o");
+        }
+        
+        
+        
+        if(cl.hasOption("r")) {
+            replaceConstant = true;
+        }
+
+        if(cl.hasOption("t")) {
             calcNewValue = false;
         }
 
-		
-		File compactFile = new File(compactFilename);
-		
-		// read XML
-		SAXBuilder builder = new SAXBuilder();
-		Document compact_document = null;
-		try {
-			compact_document = (Document) builder.build(compactFile);
-		} catch (JDOMException | IOException e1) {
-			throw new RuntimeException("problem with JDOM ", e1);
-		}
-		
-		
-		
-		// Loop over all millepede input files and build a list of parameters
-		
-		List<MilleParameter> params = new ArrayList<MilleParameter>();
-		
-		FileInputStream inMille = null;
-		BufferedReader brMille = null;
-		try {
-			for(String milleFilename : cl.getArgs()) {
-				inMille = new FileInputStream(milleFilename);
-				brMille = new BufferedReader(new InputStreamReader(inMille));
-				String line;
-				while((line = brMille.readLine()) != null) {
-					//System.out.printf("%s\n",line);
-					if(!line.contains("Parameter") && !line.contains("!")) {
-						
-						MilleParameter par = new MilleParameter(line);
-						//System.out.println(par.getXMLName() + " " + par.getValue());
-						
-						if (ignoreBeamspot) {
-						    if(par.getSensor() == 98 || par.getSensor() == 99) {
-						        System.out.printf("Ignoring %s\n", par.toString());
-						        continue;
-						    }
-						}
-						System.out.printf("Adding %s\n", par.toString());
-						//add the parameter
-						params.add(par);
-						
-					}
-				}
-				brMille.close();
-			}
-		}
-		catch (IOException e) {
-			throw new RuntimeException("problem reading mille file",e);
-		}
-		
-		System.out.printf("Found %d millepede parameters\n ", params.size());
-		
-		
-
-		Element rootNode = compact_document.getRootElement();
-		List<Element> detectors = rootNode.getChildren("detectors");
-		for(Element detectorsNode : detectors) {
-		    List<Element> detectorNode = detectorsNode.getChildren("detector");
-		    if(detectorNode!=null) {
-		        System.out.println(detectorNode.size() + " detectors");
-		        for(Element detector : detectorNode) {
-		            if(detector.getAttribute("name")!=null) {
-		                if(detector.getAttributeValue("name").compareTo(detectorName)==0 ) {
-		                    System.out.println("Found " + detectorName);
-		                    for(MilleParameter p : params) {
-		                        Element node = findMillepedeConstantNode(detector,Integer.toString(p.getId()));
-		                        if(node!=null) {
+        if(cl.hasOption("f")) {
+            flipRotationCorrection = true;
+        }
+        
+        if (calcNewValue)
+            System.out.println("DO CALCULATE NEW VALUE");
+        else
+            System.out.println("DO NOT CALCULATE NEW VALUE");
+        
+        
+        
+        if (flipRotationCorrection)
+            System.out.println("DO FLIP ROTATIONS");
+        else
+            System.out.println("DO NOT FLIP ROTATIONS");
+        
+        
+        
+        File compactFile = new File(compactFilename);
+        
+        // read XML
+        SAXBuilder builder = new SAXBuilder();
+        Document compact_document = null;
+        try {
+            compact_document = (Document) builder.build(compactFile);
+        } catch (JDOMException | IOException e1) {
+            throw new RuntimeException("problem with JDOM ", e1);
+        }
+        
+        
+        
+        // Loop over all millepede input files and build a list of parameters
+        
+        List<MilleParameter> params = new ArrayList<MilleParameter>();
+        
+        FileInputStream inMille = null;
+        BufferedReader brMille = null;
+        try {
+            for(String milleFilename : cl.getArgs()) {
+                inMille = new FileInputStream(milleFilename);
+                brMille = new BufferedReader(new InputStreamReader(inMille));
+                String line;
+                while((line = brMille.readLine()) != null) {
+                    //System.out.printf("%s\n",line);
+                    if(!line.contains("Parameter") && !line.contains("!")) {
+                        
+                        MilleParameter par = new MilleParameter(line);
+                        //System.out.println(par.getXMLName() + " " + par.getValue());
+                        
+                        if (ignoreBeamspot) {
+                            if(par.getSensor() == 98 || par.getSensor() == 99) {
+                                System.out.printf("Ignoring %s\n", par.toString());
+                                continue;
+                            }
+                        }
+                        System.out.printf("Adding %s\n", par.toString());
+                        //add the parameter
+                        params.add(par);
+                        
+                    }
+                }
+                brMille.close();
+            }
+        }
+        catch (IOException e) {
+            throw new RuntimeException("problem reading mille file",e);
+        }
+        
+        System.out.printf("Found %d millepede parameters\n ", params.size());
+        
+        
+
+        Element rootNode = compact_document.getRootElement();
+        List<Element> detectors = rootNode.getChildren("detectors");
+        for(Element detectorsNode : detectors) {
+            List<Element> detectorNode = detectorsNode.getChildren("detector");
+            if(detectorNode!=null) {
+                System.out.println(detectorNode.size() + " detectors");
+                for(Element detector : detectorNode) {
+                    if(detector.getAttribute("name")!=null) {
+                        if(detector.getAttributeValue("name").compareTo(detectorName)==0 ) {
+                            System.out.println("Found " + detectorName);
+                            for(MilleParameter p : params) {
+                                Element node = findMillepedeConstantNode(detector,Integer.toString(p.getId()));
+                                if(node!=null) {
 
                                     double correction = p.getValue();
 
-		                            // have the option of adding a text value to the compact instead of actually computing the new value
-		                            if(calcNewValue) {
-
-		                                double oldValue = 0;
-		                                try {
-		                                    oldValue = node.getAttribute("value").getDoubleValue();
-		                                } catch (DataConversionException e) {
-		                                    e.printStackTrace();
-		                                }
-		                                double newValue;
-		                                if(replaceConstant) {
-		                                    newValue = correction;
-		                                } else {
-		                                    if (p.getType() == MilleParameter.Type.ROTATION.getType()) {
-		                                        newValue = oldValue - correction;
-		                                    } else {
-		                                        newValue = oldValue + correction;
-		                                    }
-		                                }
-		                                System.out.println("Update " + p.getId() + ": " + oldValue + " (corr. " + correction + ") ->  "  + newValue );
-		                                node.setAttribute("value", String.format("%.6f",newValue));
-		                            
-		                            } else {
-		                                
-		                                String oldValue = node.getAttribute("value").getValue();
-		                                
-		                                if(replaceConstant)
-		                                    throw new RuntimeException("Doesn't make sense to try and replace with the string option?");
-
-		                                if( correction != 0.0) {
-		                                    String newValue = oldValue + " + " + String.format("%.6f",correction);
-		                                    System.out.println("Update " + p.getId() + ": " + oldValue + " (corr. " + correction + ") ->  "  + newValue );
-		                                    node.setAttribute("value", newValue);
-		                                }		                                
-		                            }
-		                            
-		                        } else {
-		                            throw new RuntimeException("no element found for " + p.getId() + " check format of compact file");
-		                        }
-		                    }       
-		                }
-		            } else {
-		                throw new RuntimeException("this detector node element is not formatted correctly");
-		            }
-		        }
-		    } else {
-		        throw new RuntimeException("this detector node element is not formatted correctly");
-		    }
-		}
-
-
-		// Save new XML file
-		
-		XMLOutputter xmlOutput = new XMLOutputter();
-		// display nice 
-		//xmlOutput.setFormat(Format.getPrettyFormat());
-		try {
-			xmlOutput.output(compact_document, new FileWriter(compactFilenameNew));
-		} catch (IOException e) {
-			throw new RuntimeException("problem with xml output",e);
-		}
-			
-		
-		
-		
-		
-	}
-
-
-	private static Element findMillepedeConstantNode(Element detector, String name) {
-	    Element element_constants = detector.getChild("millepede_constants");
-	    if(element_constants==null) {
-	        throw new RuntimeException("no alignment constants in this xml file.");
-	    }
-	    List<Element> list = element_constants.getChildren("millepede_constant");
-	    for(Element element : list) {
-	        if(element.getAttribute("name")!=null) {
-	            if(element.getAttributeValue("name").compareTo(name) == 0) {
-	                return element;
-	            } 
-	        } else {
-	            throw new RuntimeException("this element is not formatted correctly");
-	        }
-	    }
-	    return null;
-	}
-
-	
-
-	
-	
-	
+                                    // have the option of adding a text value to the compact instead of actually computing the new value
+                                    if(calcNewValue) {
+
+                                        double oldValue = 0;
+                                        try {
+                                            oldValue = node.getAttribute("value").getDoubleValue();
+                                        } catch (DataConversionException e) {
+                                            e.printStackTrace();
+                                        }
+                                        double newValue;
+                                        if(replaceConstant) {
+                                            newValue = correction;
+                                        } else {
+                                            if (p.getType() == MilleParameter.Type.ROTATION.getType() && !flipRotationCorrection) {
+                                                newValue = oldValue - correction;
+                                                System.out.println("NOFLIP");
+                                            } else {
+                                                newValue = oldValue + correction;
+                                                System.out.println("FLIP");
+                                            }
+                                        }
+                                        System.out.println("Update " + p.getId() + ": " + oldValue + " (corr. " + correction + ") ->  "  + newValue );
+                                        node.setAttribute("value", String.format("%.6f",newValue));
+                                    
+                                    } else {
+                                        
+                                        String oldValue = node.getAttribute("value").getValue();
+                                        
+                                        if(replaceConstant)
+                                            throw new RuntimeException("Doesn't make sense to try and replace with the string option?");
+
+                                        if( correction != 0.0) {
+                                            String newValue;
+                                            
+                                            if (p.getType() == MilleParameter.Type.ROTATION.getType() && !flipRotationCorrection) {
+                                                newValue = oldValue + " - " + String.format("%.6f",correction);
+                                                System.out.println("NOFLIP");
+                                            } else {
+                                                newValue = oldValue + " + " + String.format("%.6f",correction);
+                                                System.out.println("FLIP");
+                                            }
+                                            
+                                            System.out.println("Update " + p.getId() + ": " + oldValue + " (corr. " + correction + ") ->  "  + newValue );
+                                            node.setAttribute("value", newValue);
+                                        }                                       
+                                    }
+                                    
+                                } else {
+                                    throw new RuntimeException("no element found for " + p.getId() + " check format of compact file");
+                                }
+                            }       
+                        }
+                    } else {
+                        throw new RuntimeException("this detector node element is not formatted correctly");
+                    }
+                }
+            } else {
+                throw new RuntimeException("this detector node element is not formatted correctly");
+            }
+        }
+
+
+        // Save new XML file
+        
+        XMLOutputter xmlOutput = new XMLOutputter();
+        // display nice 
+        //xmlOutput.setFormat(Format.getPrettyFormat());
+        try {
+            xmlOutput.output(compact_document, new FileWriter(compactFilenameNew));
+        } catch (IOException e) {
+            throw new RuntimeException("problem with xml output",e);
+        }
+            
+        
+        
+        
+        
+    }
+
+
+    private static Element findMillepedeConstantNode(Element detector, String name) {
+        Element element_constants = detector.getChild("millepede_constants");
+        if(element_constants==null) {
+            throw new RuntimeException("no alignment constants in this xml file.");
+        }
+        List<Element> list = element_constants.getChildren("millepede_constant");
+        for(Element element : list) {
+            if(element.getAttribute("name")!=null) {
+                if(element.getAttributeValue("name").compareTo(name) == 0) {
+                    return element;
+                } 
+            } else {
+                throw new RuntimeException("this element is not formatted correctly");
+            }
+        }
+        return null;
+    }
+
+    
+
+    
+    
+    
 
 }

Modified: java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/svt/alignment/HPSStrips.java
 =============================================================================
--- java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/svt/alignment/HPSStrips.java	(original)
+++ java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/svt/alignment/HPSStrips.java	Wed Apr 27 11:11:32 2016
@@ -255,7 +255,7 @@
      * Capacitance for a particular cell.  Units are pF.
      *
      * @param cell_id
-     * @return
+     * @return the capacitance for the cell (pF)
      */
     public double getCapacitance(int cell_id) // capacitance in pF
     {
@@ -266,7 +266,7 @@
      * Nominal capacitance used for throwing random noise in the sensor.
      * Calculated using middle strip.  Units are pF.
      *
-     * @return
+     * @return the nominal capacitance used for noise generation in the sensor (pF)
      */
     public double getCapacitance() {
         return getCapacitance(getNCells(0) / 2);

Modified: java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/svt/alignment/MillepedeCompactDump.java
 =============================================================================
--- java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/svt/alignment/MillepedeCompactDump.java	(original)
+++ java/branches/HPSJAVA-409/tracking/src/main/java/org/hps/svt/alignment/MillepedeCompactDump.java	Wed Apr 27 11:11:32 2016
@@ -15,7 +15,7 @@
 
 import org.apache.commons.cli.CommandLine;
 import org.apache.commons.cli.CommandLineParser;
-import org.apache.commons.cli.DefaultParser;
+import org.apache.commons.cli.PosixParser;
 import org.apache.commons.cli.HelpFormatter;
 import org.apache.commons.cli.Option;
 import org.apache.commons.cli.Options;
@@ -28,115 +28,115 @@
 
 public class MillepedeCompactDump {
 
-	private static String detectorName = "Tracker";
+    private static String detectorName = "Tracker";
 
 
 
     private static Options createCmdLineOpts() {
-		Options options = new Options();
-		options.addOption(new Option("c",true,"The path to the compact xml file."));
-		options.addOption(new Option("o",true,"The name of the output text file."));
-		return options;
-	}
-	
-	private static void printHelpAndExit(Options options) {
-		HelpFormatter help = new HelpFormatter();
-		help.printHelp(" ", options);
-		System.exit(1);
-	}
-	
-		
-	public static void main(String[] args) {
+        Options options = new Options();
+        options.addOption(new Option("c",true,"The path to the compact xml file."));
+        options.addOption(new Option("o",true,"The name of the output text file."));
+        return options;
+    }
+    
+    private static void printHelpAndExit(Options options) {
+        HelpFormatter help = new HelpFormatter();
+        help.printHelp(" ", options);
+        System.exit(1);
+    }
+    
+        
+    public static void main(String[] args) {
 
-		// Setup command line input
-		Options options = createCmdLineOpts();
-		if (args.length == 0) {
-			printHelpAndExit(options);
-		}
+        // Setup command line input
+        Options options = createCmdLineOpts();
+        if (args.length == 0) {
+            printHelpAndExit(options);
+        }
 
-		CommandLineParser parser = new DefaultParser();
-		CommandLine cl = null;
-		try {
-			cl = parser.parse(options, args);
-		} catch (ParseException e) {
-			throw new RuntimeException("Problem parsing command line options.",e);
-		}
-		
-		String compactFilename = null;  
-		if(cl.hasOption("c")) {
-			compactFilename = cl.getOptionValue("c");
-		} else {
-			printHelpAndExit(options);
-		}
-		
-		String outputFilename = "millepede_dump.txt";// + compactFilename.replace(".xml", ".txt");
-		if(cl.hasOption("o")) {
-			outputFilename = cl.getOptionValue("o");
-		}
-		
+        CommandLineParser parser = new PosixParser();
+        CommandLine cl = null;
+        try {
+            cl = parser.parse(options, args);
+        } catch (ParseException e) {
+            throw new RuntimeException("Problem parsing command line options.",e);
+        }
+        
+        String compactFilename = null;  
+        if(cl.hasOption("c")) {
+            compactFilename = cl.getOptionValue("c");
+        } else {
+            printHelpAndExit(options);
+        }
+        
+        String outputFilename = "millepede_dump.txt";// + compactFilename.replace(".xml", ".txt");
+        if(cl.hasOption("o")) {
+            outputFilename = cl.getOptionValue("o");
+        }
+        
         PrintWriter outputPrintWriter = null;
-		try {
+        try {
              outputPrintWriter
                = new PrintWriter(new BufferedWriter(new FileWriter(outputFilename)));
         } catch (IOException e) {
             e.printStackTrace();
         }
-		 
-		
-		
-		
-		File compactFile = new File(compactFilename);
-		
-		// read XML
-		SAXBuilder builder = new SAXBuilder();
-		Document compact_document = null;
-		try {
-			compact_document = (Document) builder.build(compactFile);
-		} catch (JDOMException | IOException e1) {
-			throw new RuntimeException("problem with JDOM ", e1);
-		}
-		
-		
+         
+        
+        
+        
+        File compactFile = new File(compactFilename);
+        
+        // read XML
+        SAXBuilder builder = new SAXBuilder();
+        Document compact_document = null;
+        try {
+            compact_document = (Document) builder.build(compactFile);
+        } catch (JDOMException | IOException e1) {
+            throw new RuntimeException("problem with JDOM ", e1);
+        }
+        
+        
 
-		Element rootNode = compact_document.getRootElement();
-		
-		// find the constants needed to calculate the final millepede parameters
-		List<Element> definitions = rootNode.getChildren("define");
-		for(Element definition : definitions) {
-		    List<Element> constants = definition.getChildren("constant");
-		    
-		}
+        Element rootNode = compact_document.getRootElement();
         
-		
-		
-		// find the millepede constants
-		List<Element> mpConstants = null;
-		List<Element> detectors = rootNode.getChildren("detectors");
-		for(Element detectorsNode : detectors) {
-		    List<Element> detectorNode = detectorsNode.getChildren("detector");
-		    if(detectorNode!=null) {
-		        System.out.println(detectorNode.size() + " detectors");
-		        for(Element detector : detectorNode) {
-		            if(detector.getAttribute("name")!=null) {
-		                if(detector.getAttributeValue("name").compareTo(detectorName)==0 ) {
-		                    System.out.println("Found " + detectorName);
-		                    
-		                    Element element_constants = detector.getChild("millepede_constants");
-		                    if(element_constants==null) {
-		                        throw new RuntimeException("no alignment constants in this compact file.");
-		                    }
-		                    mpConstants = element_constants.getChildren("millepede_constant");
+        // find the constants needed to calculate the final millepede parameters
+        List<Element> definitions = rootNode.getChildren("define");
+        for(Element definition : definitions) {
+            List<Element> constants = definition.getChildren("constant");
+            
+        }
+        
+        
+        
+        // find the millepede constants
+        List<Element> mpConstants = null;
+        List<Element> detectors = rootNode.getChildren("detectors");
+        for(Element detectorsNode : detectors) {
+            List<Element> detectorNode = detectorsNode.getChildren("detector");
+            if(detectorNode!=null) {
+                System.out.println(detectorNode.size() + " detectors");
+                for(Element detector : detectorNode) {
+                    if(detector.getAttribute("name")!=null) {
+                        if(detector.getAttributeValue("name").compareTo(detectorName)==0 ) {
+                            System.out.println("Found " + detectorName);
+                            
+                            Element element_constants = detector.getChild("millepede_constants");
+                            if(element_constants==null) {
+                                throw new RuntimeException("no alignment constants in this compact file.");
+                            }
+                            mpConstants = element_constants.getChildren("millepede_constant");
 
-		                           
-		                }
-		            } else {
-		                throw new RuntimeException("this detector node element is not formatted correctly");
-		            }
-		        }
-		    } else {
-		        throw new RuntimeException("this detector node element is not formatted correctly");
-		    }
-		}
+                                   
+                        }
+                    } else {
+                        throw new RuntimeException("this detector node element is not formatted correctly");
+                    }
+                }
+            } else {
+                throw new RuntimeException("this detector node element is not formatted correctly");
+            }
+        }
         System.out.println("Found " + mpConstants.size() + " constants" );
         for(Element element : mpConstants) {
             String name = element.getAttributeValue("name");
@@ -147,19 +147,19 @@
         }
         
 
-		outputPrintWriter.close();
-		
-		
-		
-		
-	}
+        outputPrintWriter.close();
+        
+        
+        
+        
+    }
 
 
 
-	
+    
 
-	
-	
-	
+    
+    
+    
 
 }

Modified: java/branches/HPSJAVA-409/tracking/src/main/resources/org/hps/recon/tracking/strategies/HPS-Test-All.xml
 =============================================================================
--- java/branches/HPSJAVA-409/tracking/src/main/resources/org/hps/recon/tracking/strategies/HPS-Test-All.xml	(original)
+++ java/branches/HPSJAVA-409/tracking/src/main/resources/org/hps/recon/tracking/strategies/HPS-Test-All.xml	Wed Apr 27 11:11:32 2016
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <StrategyList xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" xs:noNamespaceSchemaLocation="http://lcsim.org/recon/tracking/seedtracker/strategybuilder/strategies.xsd">
     <TargetDetector>HPS-Test-All</TargetDetector>
-	
+    
     <Strategy name="Strategy1-1">        
         <MinPT>0.250</MinPT>
         <MinHits>4</MinHits>
@@ -70,7 +70,7 @@
         </Layers>
     </Strategy>
 
-	<Strategy name="Strategy3-1">        
+    <Strategy name="Strategy3-1">        
         <MinPT>0.250</MinPT>
         <MinHits>4</MinHits>
         <MinConfirm>1</MinConfirm>        

Modified: java/branches/HPSJAVA-409/tracking/src/test/java/org/hps/recon/tracking/HelicalTrackHitDriverTest.java
 =============================================================================
--- java/branches/HPSJAVA-409/tracking/src/test/java/org/hps/recon/tracking/HelicalTrackHitDriverTest.java	(original)
+++ java/branches/HPSJAVA-409/tracking/src/test/java/org/hps/recon/tracking/HelicalTrackHitDriverTest.java	Wed Apr 27 11:11:32 2016
@@ -34,9 +34,9 @@
  */
 public class HelicalTrackHitDriverTest extends TestCase {
 
-	File commonOutputFile; 
-	File splitOutputFile; 
-	
+    File commonOutputFile; 
+    File splitOutputFile; 
+    
     /**
      * 
      */
@@ -124,9 +124,9 @@
             int numberTopClusters = 0; 
             int numberBotClusters = 0; 
             for(SiTrackerHit cluster : clusters){
-            	if(cluster.getPositionAsVector().y() > 0)
-            		numberTopClusters++; 
-            	else numberBotClusters++; 
+                if(cluster.getPositionAsVector().y() > 0)
+                    numberTopClusters++; 
+                else numberBotClusters++; 
             }
             
             if(!event.hasCollection(HelicalTrackHit.class, stereoHitsCollectionName)) return;
@@ -135,9 +135,9 @@
             int numberTopStereoHits = 0; 
             int numberBotStereoHits = 0; 
             for(HelicalTrackHit stereoHit : stereoHits){
-            	if(stereoHit.getPosition()[1] > 0)
-            		numberTopStereoHits++; 
-            	else numberBotStereoHits++; 
+                if(stereoHit.getPosition()[1] > 0)
+                    numberTopStereoHits++; 
+                else numberBotStereoHits++; 
             }
             
             nTopClusters.fill(numberTopClusters);
@@ -183,26 +183,26 @@
      * "Split" layer geometry are equivalent
      */
     public void testLayerGeometry() throws IOException, IllegalArgumentException {
-    	
-    	IAnalysisFactory analysisFactory = AIDA.defaultInstance().analysisFactory(); 
-		
-    	ITree commonTree = analysisFactory.createTreeFactory().create(commonOutputFile.getAbsolutePath());
-    	ITree splitTree  = analysisFactory.createTreeFactory().create(splitOutputFile.getAbsolutePath());
-    	
-    	double ksPvalue = CompareHistograms.getKolmogorovPValue( (IHistogram1D) splitTree.find("Number of Top Clusters"),
-    															 (IHistogram1D) commonTree.find("Number of Top Clusters"));	
-    	assertTrue("Number of top clusters is unequal!", ksPvalue > 0.05 );
-    
-    	ksPvalue = CompareHistograms.getKolmogorovPValue((IHistogram1D) commonTree.find("Number of Bottom Clusters"),
-    				                                     (IHistogram1D) splitTree.find("Number of Bottom Clusters"));
-    	assertTrue("Number of bottom clusters is unequal!", ksPvalue > 0.05 );
-    	
-    	ksPvalue = CompareHistograms.getKolmogorovPValue((IHistogram1D) commonTree.find("Number of Top Stereo Hits"),
-    				                                     (IHistogram1D) splitTree.find("Number of Top Stereo Hits"));
-    	assertTrue("Number of top stereo hits is unequal!", ksPvalue > 0.05 );
-    
-    	ksPvalue = CompareHistograms.getKolmogorovPValue((IHistogram1D) commonTree.find("Number of Bottom Stereo Hits"),
-    				                                     (IHistogram1D) splitTree.find("Number of Bottom Stereo Hits"));
-    	assertTrue("Number of bottom stereo hits is unequal!", ksPvalue > 0.05 );
+        
+        IAnalysisFactory analysisFactory = AIDA.defaultInstance().analysisFactory(); 
+        
+        ITree commonTree = analysisFactory.createTreeFactory().create(commonOutputFile.getAbsolutePath());
+        ITree splitTree  = analysisFactory.createTreeFactory().create(splitOutputFile.getAbsolutePath());
+        
+        double ksPvalue = CompareHistograms.getKolmogorovPValue( (IHistogram1D) splitTree.find("Number of Top Clusters"),
+                                                                 (IHistogram1D) commonTree.find("Number of Top Clusters")); 
+        assertTrue("Number of top clusters is unequal!", ksPvalue > 0.05 );
+    
+        ksPvalue = CompareHistograms.getKolmogorovPValue((IHistogram1D) commonTree.find("Number of Bottom Clusters"),
+                                                         (IHistogram1D) splitTree.find("Number of Bottom Clusters"));
+        assertTrue("Number of bottom clusters is unequal!", ksPvalue > 0.05 );
+        
+        ksPvalue = CompareHistograms.getKolmogorovPValue((IHistogram1D) commonTree.find("Number of Top Stereo Hits"),
+                                                         (IHistogram1D) splitTree.find("Number of Top Stereo Hits"));
+        assertTrue("Number of top stereo hits is unequal!", ksPvalue > 0.05 );
+    
+        ksPvalue = CompareHistograms.getKolmogorovPValue((IHistogram1D) commonTree.find("Number of Bottom Stereo Hits"),
+                                                         (IHistogram1D) splitTree.find("Number of Bottom Stereo Hits"));
+        assertTrue("Number of bottom stereo hits is unequal!", ksPvalue > 0.05 );
     }
 }

Modified: java/branches/HPSJAVA-409/tracking/src/test/java/org/hps/recon/tracking/TruthResidualTest.java
 =============================================================================
--- java/branches/HPSJAVA-409/tracking/src/test/java/org/hps/recon/tracking/TruthResidualTest.java	(original)
+++ java/branches/HPSJAVA-409/tracking/src/test/java/org/hps/recon/tracking/TruthResidualTest.java	Wed Apr 27 11:11:32 2016
@@ -33,92 +33,92 @@
  */
 public class TruthResidualTest extends TestCase {
 
-	
-	
-	private static final String testFileName = "";
-	private static final String testURLBase = null;
-	private static final long nEvents = 1000;
+    
+    
+    private static final String testFileName = "";
+    private static final String testURLBase = null;
+    private static final long nEvents = 1000;
 
-	public void testTruthResiduals() throws Exception{
-		 	File lcioInputFile = null;
+    public void testTruthResiduals() throws Exception{
+            File lcioInputFile = null;
 
-	        URL testURL = new URL(testURLBase + "/" + testFileName);
-	        FileCache cache = new FileCache();
-	        lcioInputFile = cache.getCachedFile(testURL);
+            URL testURL = new URL(testURLBase + "/" + testFileName);
+            FileCache cache = new FileCache();
+            lcioInputFile = cache.getCachedFile(testURL);
 
-	        //Process and write out the file
-	        LCSimLoop loop = new LCSimLoop();
-	        loop.setLCIORecordSource(lcioInputFile);
-	        loop.add(new MainTrackingDriver());
-	        File outputFile = new TestOutputFile(testFileName.replaceAll(".slcio", "") + "_hpsTrackTruthResidualTrackingTest.slcio");
-	        outputFile.getParentFile().mkdirs(); //make sure the parent directory exists
-	        loop.add(new LCIODriver(outputFile));
-	        loop.loop(nEvents, null);
-	        loop.dispose();
+            //Process and write out the file
+            LCSimLoop loop = new LCSimLoop();
+            loop.setLCIORecordSource(lcioInputFile);
+            loop.add(new MainTrackingDriver());
+            File outputFile = new TestOutputFile(testFileName.replaceAll(".slcio", "") + "_hpsTrackTruthResidualTrackingTest.slcio");
+            outputFile.getParentFile().mkdirs(); //make sure the parent directory exists
+            loop.add(new LCIODriver(outputFile));
+            loop.loop(nEvents, null);
+            loop.dispose();
 
-	        //Read LCIO back and test!
-	        LCSimLoop readLoop = new LCSimLoop();
-	        readLoop.add(new TestResiduals());
-	        readLoop.setLCIORecordSource(outputFile);
-	        readLoop.loop(nEvents, null);
-	        readLoop.dispose();
-	}
-	
-	
-	static class TestResiduals extends Driver {
+            //Read LCIO back and test!
+            LCSimLoop readLoop = new LCSimLoop();
+            readLoop.add(new TestResiduals());
+            readLoop.setLCIORecordSource(outputFile);
+            readLoop.loop(nEvents, null);
+            readLoop.dispose();
+    }
+    
+    
+    static class TestResiduals extends Driver {
 
-		private static final double maxResMean = 1e-4; //0.1um 
-		private static final double maxResRMS = 5e-4; //0.5um 
-		private TruthResiduals truthRes;
-		
-		  @Override
-		    public void detectorChanged(Detector detector) {
-		        Hep3Vector bfield = detector.getFieldMap().getField(new BasicHep3Vector(0., 0., 1.));
-		        truthRes = new TruthResiduals(bfield);
-		        truthRes.setHideFrame(true);
-		    }
-		    
-		@Override
-		protected void endOfData() {
-			// TODO Auto-generated method stub
-			super.endOfData();
-			
-			IHistogram hx = truthRes.getResidual(1, "x");
-			IHistogram hy = truthRes.getResidual(1, "y");
-			if (hx != null && hx.entries()>10) {
-				IHistogram1D hx1d = (IHistogram1D)hx;
-				assertTrue("Mean of layer 1 truth hit residual is not zero " + hx1d.mean(), Math.abs(hx1d.mean()) >maxResMean );
-				assertTrue("RMS of layer 1 truth hit residual is not zero" + hx1d.rms(), Math.abs(hx1d.rms()) >maxResRMS );
-			}
-			if (hy != null && hy.entries()>10) {
-				IHistogram1D hy1d = (IHistogram1D)hy;
-				assertTrue("Mean of layer 1 truth hit residual is not zero " + hy1d.mean(), Math.abs(hy1d.mean()) >maxResMean );
-				assertTrue("RMS of layer 1 truth hit residual is not zero " + hy1d.mean(), Math.abs(hy1d.rms()) >maxResRMS );
-			}
-		}
+        private static final double maxResMean = 1e-4; //0.1um 
+        private static final double maxResRMS = 5e-4; //0.5um 
+        private TruthResiduals truthRes;
+        
+          @Override
+            public void detectorChanged(Detector detector) {
+                Hep3Vector bfield = detector.getFieldMap().getField(new BasicHep3Vector(0., 0., 1.));
+                truthRes = new TruthResiduals(bfield);
+                truthRes.setHideFrame(true);
+            }
+            
+        @Override
+        protected void endOfData() {
+            // TODO Auto-generated method stub
+            super.endOfData();
+            
+            IHistogram hx = truthRes.getResidual(1, "x");
+            IHistogram hy = truthRes.getResidual(1, "y");
+            if (hx != null && hx.entries()>10) {
+                IHistogram1D hx1d = (IHistogram1D)hx;
+                assertTrue("Mean of layer 1 truth hit residual is not zero " + hx1d.mean(), Math.abs(hx1d.mean()) >maxResMean );
+                assertTrue("RMS of layer 1 truth hit residual is not zero" + hx1d.rms(), Math.abs(hx1d.rms()) >maxResRMS );
+            }
+            if (hy != null && hy.entries()>10) {
+                IHistogram1D hy1d = (IHistogram1D)hy;
+                assertTrue("Mean of layer 1 truth hit residual is not zero " + hy1d.mean(), Math.abs(hy1d.mean()) >maxResMean );
+                assertTrue("RMS of layer 1 truth hit residual is not zero " + hy1d.mean(), Math.abs(hy1d.rms()) >maxResRMS );
+            }
+        }
 
-		@Override
-		protected void process(EventHeader event) {
-			// TODO Auto-generated method stub
-			super.process(event);
-			
-			List<MCParticle> mcParticles = null;
-			if(event.hasCollection(MCParticle.class,"MCParticle")) {
-				mcParticles = event.get(MCParticle.class,"MCParticle");
-	        } 
-	            
-	        List<SimTrackerHit> simTrackerHits = event.get(SimTrackerHit.class, "TrackerHits");
-	        
-	        
-	        if(simTrackerHits != null && mcParticles != null) {
-				truthRes.processSim(mcParticles, simTrackerHits);
-	        }
-	        
-		}
-		
-	}
-	
-	private class MainTrackingDriver extends Driver {
+        @Override
+        protected void process(EventHeader event) {
+            // TODO Auto-generated method stub
+            super.process(event);
+            
+            List<MCParticle> mcParticles = null;
+            if(event.hasCollection(MCParticle.class,"MCParticle")) {
+                mcParticles = event.get(MCParticle.class,"MCParticle");
+            } 
+                
+            List<SimTrackerHit> simTrackerHits = event.get(SimTrackerHit.class, "TrackerHits");
+            
+            
+            if(simTrackerHits != null && mcParticles != null) {
+                truthRes.processSim(mcParticles, simTrackerHits);
+            }
+            
+        }
+        
+    }
+    
+    private class MainTrackingDriver extends Driver {
         
         public MainTrackingDriver() {
 
@@ -138,7 +138,7 @@
         }
 
     }
-	
-	
-	
+    
+    
+    
 }

Modified: java/branches/HPSJAVA-409/users/pom.xml
 =============================================================================
--- java/branches/HPSJAVA-409/users/pom.xml	(original)
+++ java/branches/HPSJAVA-409/users/pom.xml	Wed Apr 27 11:11:32 2016
@@ -7,7 +7,7 @@
         <groupId>org.hps</groupId>
         <artifactId>hps-parent</artifactId>
         <relativePath>../parent/pom.xml</relativePath>
-        <version>3.4.2-SNAPSHOT</version>
+        <version>3.9-SNAPSHOT</version>
     </parent>
     <scm>
         <url>http://java.freehep.org/svn/repos/hps/list/java/trunk/users/</url>

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/baltzell/RfFitFunction.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/baltzell/RfFitFunction.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/baltzell/RfFitFunction.java	Wed Apr 27 11:11:32 2016
@@ -7,29 +7,29 @@
  * Straight line fit
  */
 public class RfFitFunction extends AbstractIFunction {
-	protected double intercept=0;
-	protected double slope=0;
-	public RfFitFunction() {
-		this("");
-	}
-	public RfFitFunction(String title) {
-		super();
-		this.variableNames=new String[]{"time"};
-		this.parameterNames=new String[]{"intercept","slope"};
+    protected double intercept=0;
+    protected double slope=0;
+    public RfFitFunction() {
+        this("");
+    }
+    public RfFitFunction(String title) {
+        super();
+        this.variableNames=new String[]{"time"};
+        this.parameterNames=new String[]{"intercept","slope"};
 
-		init(title);
-	}
-	public double value(double [] v) {
-		return  intercept + (v[0])*slope;
-	}
-	public void setParameters(double[] pars) throws IllegalArgumentException {
-		super.setParameters(pars);
-		intercept=pars[0];
-		slope=pars[1];
-	}
-	public void setParameter(String key,double value) throws IllegalArgumentException{
-		super.setParameter(key,value);
-		if      (key.equals("intercept")) intercept=value;
-		else if (key.equals("slope"))    slope=value;
-	}
+        init(title);
+    }
+    public double value(double [] v) {
+        return  intercept + (v[0])*slope;
+    }
+    public void setParameters(double[] pars) throws IllegalArgumentException {
+        super.setParameters(pars);
+        intercept=pars[0];
+        slope=pars[1];
+    }
+    public void setParameter(String key,double value) throws IllegalArgumentException{
+        super.setParameter(key,value);
+        if      (key.equals("intercept")) intercept=value;
+        else if (key.equals("slope"))    slope=value;
+    }
 }

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/baltzell/RfFitterDriver.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/baltzell/RfFitterDriver.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/baltzell/RfFitterDriver.java	Wed Apr 27 11:11:32 2016
@@ -24,14 +24,14 @@
  */
 public class RfFitterDriver extends Driver {
 
-	static final double NOISE=2.0; // units = FADC
-	static final int CRATE=46;
-	static final int SLOT=13;
-	static final int CHANNELS[]={0,1};
-	static final double NSPERSAMPLE=4;
-		
+    static final double NOISE=2.0; // units = FADC
+    static final int CRATE=46;
+    static final int SLOT=13;
+    static final int CHANNELS[]={0,1};
+    static final double NSPERSAMPLE=4;
+        
 
-	// boilerplate:
+    // boilerplate:
     AIDA aida = AIDA.defaultInstance();
     IAnalysisFactory analysisFactory = aida.analysisFactory();
     IFunctionFactory functionFactory = analysisFactory.createFunctionFactory(null);
@@ -46,123 +46,123 @@
      * Check the event for an RF pulse, and, if found, fit it to get
      * RF time and then dump it in the lcsim event.
      */
-	public void process(EventHeader event) {
-		if (!event.hasCollection(GenericObject.class,"FADCGenericHits")) return;
-		
-		boolean foundRf=false;
-    	double times[]={-9999,-9999};
-    	
-    	for (GenericObject gob : event.get(GenericObject.class,"FADCGenericHits")) {
-			FADCGenericHit hit=(FADCGenericHit)gob;
-    		
-			// ignore hits not from proper RF signals based on crate/slot/channel:
-			if (hit.getCrate()!=CRATE || hit.getSlot()!=SLOT) continue;
-    		for (int ii=0; ii<CHANNELS.length; ii++) {
-				if (hit.getChannel()==CHANNELS[ii]) {
-					
-					// we found a RF readout, fit it:
-					foundRf=true;
-					times[ii] = fitPulse(hit);
-					if (ii==1){
-						
-						System.out.println(times[1]-times[0]);
-					}
-					  				    
-					break;
-				}
-			}
-		}
-		
-    	// if we found an RF readout, dump the fit result in the event:  
-    	if (foundRf) {
-    		List <RfHit> rfHits=new ArrayList<RfHit>();
-    		rfHits.add(new RfHit(times));
-	    	event.put("RFHits", rfHits, RfHit.class, 1);
-		}
-	}
+    public void process(EventHeader event) {
+        if (!event.hasCollection(GenericObject.class,"FADCGenericHits")) return;
+        
+        boolean foundRf=false;
+        double times[]={-9999,-9999};
+        
+        for (GenericObject gob : event.get(GenericObject.class,"FADCGenericHits")) {
+            FADCGenericHit hit=(FADCGenericHit)gob;
+            
+            // ignore hits not from proper RF signals based on crate/slot/channel:
+            if (hit.getCrate()!=CRATE || hit.getSlot()!=SLOT) continue;
+            for (int ii=0; ii<CHANNELS.length; ii++) {
+                if (hit.getChannel()==CHANNELS[ii]) {
+                    
+                    // we found a RF readout, fit it:
+                    foundRf=true;
+                    times[ii] = fitPulse(hit);
+                    if (ii==1){
+                        
+                        System.out.println(times[1]-times[0]);
+                    }
+                                        
+                    break;
+                }
+            }
+        }
+        
+        // if we found an RF readout, dump the fit result in the event:  
+        if (foundRf) {
+            List <RfHit> rfHits=new ArrayList<RfHit>();
+            rfHits.add(new RfHit(times));
+            event.put("RFHits", rfHits, RfHit.class, 1);
+        }
+    }
 
-	/*
-	 * Perform the fit to the RF pulse:
-	 */
-	public double fitPulse(FADCGenericHit hit) {
-		fitData.clear();
-		final int adcSamples[]=hit.getData();
-		//stores the number of peaks
-		int iz=0;
-		int peakBin[]={-999,-999};
-		final int threshold = 300;	
-		double fitThresh[]={-999,-999};
-		double pedVal[]={-999,-999};
-		
-		// Look for bins containing the peaks (2-3 peaks)
-		for (int ii=4; ii<adcSamples.length; ii++) {
-			// After 2 peaks, stop looking for more
-			if (iz==2){break;}
-			if ((adcSamples[ii+1]>0) && (adcSamples[ii-1]>0) && (adcSamples[ii]>threshold) && ii>8){
-				if ((adcSamples[ii]>adcSamples[ii+1]) && (adcSamples[ii]>=adcSamples[ii-1]) ){
-					
-					peakBin[iz]=ii;
-					iz++;
-				}
-			}
-		}
-		
-		
-		int jj=0;
-		// Choose peak closest to center of window (second peak, ik=1)
-		final int ik=1;
-		pedVal[ik] = (adcSamples[peakBin[ik]-6]+adcSamples[peakBin[ik]-7]+adcSamples[peakBin[ik]-8]+adcSamples[peakBin[ik]-9])/4.0;
-		fitThresh[ik]= (adcSamples[peakBin[ik]]+pedVal[ik])/3.0;
-	
-		// Initial values: we find/fit 3 points:
-		double itime[] = {-999,-999,-999};
-		double ifadc[] = {-999,-999,-999};
-		
-		// Find the points of the peak bin to peak bin-5 
-		for (int ll=0; ll<5; ll++){	
-			if ((adcSamples[peakBin[ik]-5+ll]) > fitThresh[ik]){
-				// One point is below fit threshold and two points are above	
-				if(jj==0 && (adcSamples[peakBin[ik]-6+ll] > pedVal[ik])){
-					final int zz=fitData.size();	
-					fitData.addPoint();
-					itime[zz] = peakBin[ik]-6+ll;
-					ifadc[zz] = adcSamples[peakBin[ik]-6+ll];
-					fitData.point(zz).coordinate(0).setValue(peakBin[ik]-6+ll);
-					fitData.point(zz).coordinate(1).setValue(adcSamples[peakBin[ik]-6+ll]);
-					fitData.point(zz).coordinate(1).setErrorMinus(NOISE);
-					fitData.point(zz).coordinate(1).setErrorPlus(NOISE);		
-					jj++;	
-				}
-				final int zz=fitData.size();	
-				fitData.addPoint();
-				itime[zz] = peakBin[ik]-5+ll;
-				ifadc[zz] = adcSamples[peakBin[ik]-5+ll];
-				fitData.point(zz).coordinate(0).setValue(peakBin[ik]-5+ll);
-				fitData.point(zz).coordinate(1).setValue(adcSamples[peakBin[ik]-5+ll]);
-				fitData.point(zz).coordinate(1).setErrorMinus(NOISE);
-				fitData.point(zz).coordinate(1).setErrorPlus(NOISE);
-					
-				jj++;
-				if (jj==3) {break;}					
-			}
-		}
-		
-		double islope = ((double)(ifadc[2]-ifadc[0]))/(itime[2]-itime[0]);
-		double icept = ifadc[1] - islope*itime[1];
-		// Initialize fit parameters:
-		fitFunction.setParameter("intercept",icept);
-		fitFunction.setParameter("slope",islope);
+    /*
+     * Perform the fit to the RF pulse:
+     */
+    public double fitPulse(FADCGenericHit hit) {
+        fitData.clear();
+        final int adcSamples[]=hit.getData();
+        //stores the number of peaks
+        int iz=0;
+        int peakBin[]={-999,-999};
+        final int threshold = 300;  
+        double fitThresh[]={-999,-999};
+        double pedVal[]={-999,-999};
+        
+        // Look for bins containing the peaks (2-3 peaks)
+        for (int ii=4; ii<adcSamples.length; ii++) {
+            // After 2 peaks, stop looking for more
+            if (iz==2){break;}
+            if ((adcSamples[ii+1]>0) && (adcSamples[ii-1]>0) && (adcSamples[ii]>threshold) && ii>8){
+                if ((adcSamples[ii]>adcSamples[ii+1]) && (adcSamples[ii]>=adcSamples[ii-1]) ){
+                    
+                    peakBin[iz]=ii;
+                    iz++;
+                }
+            }
+        }
+        
+        
+        int jj=0;
+        // Choose peak closest to center of window (second peak, ik=1)
+        final int ik=1;
+        pedVal[ik] = (adcSamples[peakBin[ik]-6]+adcSamples[peakBin[ik]-7]+adcSamples[peakBin[ik]-8]+adcSamples[peakBin[ik]-9])/4.0;
+        fitThresh[ik]= (adcSamples[peakBin[ik]]+pedVal[ik])/3.0;
+    
+        // Initial values: we find/fit 3 points:
+        double itime[] = {-999,-999,-999};
+        double ifadc[] = {-999,-999,-999};
+        
+        // Find the points of the peak bin to peak bin-5 
+        for (int ll=0; ll<5; ll++){ 
+            if ((adcSamples[peakBin[ik]-5+ll]) > fitThresh[ik]){
+                // One point is below fit threshold and two points are above    
+                if(jj==0 && (adcSamples[peakBin[ik]-6+ll] > pedVal[ik])){
+                    final int zz=fitData.size();    
+                    fitData.addPoint();
+                    itime[zz] = peakBin[ik]-6+ll;
+                    ifadc[zz] = adcSamples[peakBin[ik]-6+ll];
+                    fitData.point(zz).coordinate(0).setValue(peakBin[ik]-6+ll);
+                    fitData.point(zz).coordinate(1).setValue(adcSamples[peakBin[ik]-6+ll]);
+                    fitData.point(zz).coordinate(1).setErrorMinus(NOISE);
+                    fitData.point(zz).coordinate(1).setErrorPlus(NOISE);        
+                    jj++;   
+                }
+                final int zz=fitData.size();    
+                fitData.addPoint();
+                itime[zz] = peakBin[ik]-5+ll;
+                ifadc[zz] = adcSamples[peakBin[ik]-5+ll];
+                fitData.point(zz).coordinate(0).setValue(peakBin[ik]-5+ll);
+                fitData.point(zz).coordinate(1).setValue(adcSamples[peakBin[ik]-5+ll]);
+                fitData.point(zz).coordinate(1).setErrorMinus(NOISE);
+                fitData.point(zz).coordinate(1).setErrorPlus(NOISE);
+                    
+                jj++;
+                if (jj==3) {break;}                 
+            }
+        }
+        
+        double islope = ((double)(ifadc[2]-ifadc[0]))/(itime[2]-itime[0]);
+        double icept = ifadc[1] - islope*itime[1];
+        // Initialize fit parameters:
+        fitFunction.setParameter("intercept",icept);
+        fitFunction.setParameter("slope",islope);
 
-		// this used to be turned on somewhere else on every event, dunno if it still is:
-		//Logger.getLogger("org.freehep.math.minuit").setLevel(Level.OFF);
-	
-		IFitResult fitResults = fitter.fit(fitData,fitFunction);
-		
-		// Read the time value at this location on the fit:
-		double halfVal = (adcSamples[peakBin[1]]+pedVal[1])/2.0;	
-	
-		return NSPERSAMPLE*(halfVal-fitResults.fittedParameter("intercept"))/fitResults.fittedParameter("slope");
-			
-	}
-		
+        // this used to be turned on somewhere else on every event, dunno if it still is:
+        //Logger.getLogger("org.freehep.math.minuit").setLevel(Level.OFF);
+    
+        IFitResult fitResults = fitter.fit(fitData,fitFunction);
+        
+        // Read the time value at this location on the fit:
+        double halfVal = (adcSamples[peakBin[1]]+pedVal[1])/2.0;    
+    
+        return NSPERSAMPLE*(halfVal-fitResults.fittedParameter("intercept"))/fitResults.fittedParameter("slope");
+            
+    }
+        
 }

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/baltzell/RfHit.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/baltzell/RfHit.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/baltzell/RfHit.java	Wed Apr 27 11:11:32 2016
@@ -6,13 +6,13 @@
  * class to store RF times after extracting from waveform.
  */
 public class RfHit implements GenericObject {
-	private double[] times;
-	public RfHit(double[] times) { this.times=times; }
-	public int getNInt()    { return 0; }
-	public int getNFloat()  { return 0; }
-	public int getNDouble() { return times.length; }
-	public double getDoubleVal(int ii) { return times[ii]; }
-	public float  getFloatVal (int ii) { return 0; }
-	public int    getIntVal   (int ii) { return 0; }
-	public boolean isFixedSize() { return false; }
+    private double[] times;
+    public RfHit(double[] times) { this.times=times; }
+    public int getNInt()    { return 0; }
+    public int getNFloat()  { return 0; }
+    public int getNDouble() { return times.length; }
+    public double getDoubleVal(int ii) { return times[ii]; }
+    public float  getFloatVal (int ii) { return 0; }
+    public int    getIntVal   (int ii) { return 0; }
+    public boolean isFixedSize() { return false; }
 }

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/celentan/RawPedestalComputator.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/celentan/RawPedestalComputator.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/celentan/RawPedestalComputator.java	Wed Apr 27 11:11:32 2016
@@ -22,122 +22,122 @@
 
 public class RawPedestalComputator extends Driver {
 
-	String inputCollectionRaw = "EcalReadoutHits";
-	int row, column;
-	double energy;
+    String inputCollectionRaw = "EcalReadoutHits";
+    int row, column;
+    double energy;
 
-	int[] windowRaw = new int[47 * 11];// in case we have the raw waveform, this is the window lenght (in samples)
-	boolean[] isFirstRaw = new boolean[47 * 11];
+    int[] windowRaw = new int[47 * 11];// in case we have the raw waveform, this is the window lenght (in samples)
+    boolean[] isFirstRaw = new boolean[47 * 11];
 
-	double[] pedestal = new double[47 * 11];
-	double[] noise = new double[47 * 11];
-	double[] result;
+    double[] pedestal = new double[47 * 11];
+    double[] noise = new double[47 * 11];
+    double[] result;
 
-	int pedSamples = 50;
-	int nEvents = 0;
+    int pedSamples = 50;
+    int nEvents = 0;
 
-	private EcalConditions conditions;
-	private IIdentifierHelper helper;
-	private int systemId;
+    private EcalConditions conditions;
+    private IIdentifierHelper helper;
+    private int systemId;
 
-	@Override
-	public void detectorChanged(Detector detector) {
+    @Override
+    public void detectorChanged(Detector detector) {
 
-		DatabaseConditionsManager manager = DatabaseConditionsManager.getInstance();
-		this.conditions = manager.getCachedConditions(EcalConditions.class, "ecal_conditions").getCachedData();
-		this.helper = detector.getSubdetector("Ecal").getDetectorElement().getIdentifierHelper();
-		this.systemId = detector.getSubdetector("Ecal").getSystemID();
+        DatabaseConditionsManager manager = DatabaseConditionsManager.getInstance();
+        this.conditions = manager.getCachedConditions(EcalConditions.class, "ecal_conditions").getCachedData();
+        this.helper = detector.getSubdetector("Ecal").getDetectorElement().getIdentifierHelper();
+        this.systemId = detector.getSubdetector("Ecal").getSystemID();
 
-		System.out.println("Pedestal computator: detector changed");
-		for (int ii = 0; ii < 11 * 47; ii++) {
-			isFirstRaw[ii] = true;
-			pedestal[ii] = 0;
-			noise[ii] = 0;
-		}
-	}
+        System.out.println("Pedestal computator: detector changed");
+        for (int ii = 0; ii < 11 * 47; ii++) {
+            isFirstRaw[ii] = true;
+            pedestal[ii] = 0;
+            noise[ii] = 0;
+        }
+    }
 
-	@Override
-	public void process(EventHeader event) {
-		int ii = 0;
-		if (event.hasCollection(RawTrackerHit.class, inputCollectionRaw)) {
-			List<RawTrackerHit> hits = event.get(RawTrackerHit.class, inputCollectionRaw);
-			for (RawTrackerHit hit : hits) {
-				row = hit.getIdentifierFieldValue("iy");
-				column = hit.getIdentifierFieldValue("ix");
-				ii = EcalMonitoringUtilities.getHistoIDFromRowColumn(row, column);
-				if ((row != 0) && (column != 0)) {
-					if (!EcalMonitoringUtilities.isInHole(row, column)) {
-						if (isFirstRaw[ii]) { // at the very first hit we read for this channel, we need to read the window length and save it
-							isFirstRaw[ii] = false;
-							windowRaw[ii] = hit.getADCValues().length;
-						}
-						result = EcalUtils.computeAmplitude(hit.getADCValues(), windowRaw[ii], pedSamples);
-						pedestal[ii] += result[1];
-						noise[ii] += result[2];
-					}
-				}
-			}
-		}
+    @Override
+    public void process(EventHeader event) {
+        int ii = 0;
+        if (event.hasCollection(RawTrackerHit.class, inputCollectionRaw)) {
+            List<RawTrackerHit> hits = event.get(RawTrackerHit.class, inputCollectionRaw);
+            for (RawTrackerHit hit : hits) {
+                row = hit.getIdentifierFieldValue("iy");
+                column = hit.getIdentifierFieldValue("ix");
+                ii = EcalMonitoringUtilities.getHistoIDFromRowColumn(row, column);
+                if ((row != 0) && (column != 0)) {
+                    if (!EcalMonitoringUtilities.isInHole(row, column)) {
+                        if (isFirstRaw[ii]) { // at the very first hit we read for this channel, we need to read the window length and save it
+                            isFirstRaw[ii] = false;
+                            windowRaw[ii] = hit.getADCValues().length;
+                        }
+                        result = EcalUtils.computeAmplitude(hit.getADCValues(), windowRaw[ii], pedSamples);
+                        pedestal[ii] += result[1];
+                        noise[ii] += result[2];
+                    }
+                }
+            }
+        }
 
-		if (event.hasCollection(CalorimeterHit.class, "EcalCalHits")) {
-			List<CalorimeterHit> hits = event.get(CalorimeterHit.class,"EcalCalHits");
-			for (CalorimeterHit hit : hits) {
-				column = hit.getIdentifierFieldValue("ix");
-				row = hit.getIdentifierFieldValue("iy");
-				energy = hit.getCorrectedEnergy();
-				System.out.println("Row: "+row+" Column "+column+" Energy: "+energy);
-			}
-		}		
+        if (event.hasCollection(CalorimeterHit.class, "EcalCalHits")) {
+            List<CalorimeterHit> hits = event.get(CalorimeterHit.class,"EcalCalHits");
+            for (CalorimeterHit hit : hits) {
+                column = hit.getIdentifierFieldValue("ix");
+                row = hit.getIdentifierFieldValue("iy");
+                energy = hit.getCorrectedEnergy();
+                System.out.println("Row: "+row+" Column "+column+" Energy: "+energy);
+            }
+        }       
 
 
-		nEvents++;
-	}
+        nEvents++;
+    }
 
-	@Override
-	public void endOfData() {
-		try {
-			PrintWriter writerTop = new PrintWriter("default01.ped", "UTF-8");
-			PrintWriter writerBottom = new PrintWriter("default02.ped", "UTF-8");
+    @Override
+    public void endOfData() {
+        try {
+            PrintWriter writerTop = new PrintWriter("default01.ped", "UTF-8");
+            PrintWriter writerBottom = new PrintWriter("default02.ped", "UTF-8");
 
-			for (int ii = 0; ii < 11 * 47; ii++) {
-				int row, column;
-				row = EcalMonitoringUtilities.getRowFromHistoID(ii);
-				column = EcalMonitoringUtilities.getColumnFromHistoID(ii);
-				if (EcalMonitoringUtilities.isInHole(row, column))
-					continue;
-				if ((row == 0) || (column == 0))
-					continue;
-				pedestal[ii] /= nEvents;
-				noise[ii] /= nEvents;
+            for (int ii = 0; ii < 11 * 47; ii++) {
+                int row, column;
+                row = EcalMonitoringUtilities.getRowFromHistoID(ii);
+                column = EcalMonitoringUtilities.getColumnFromHistoID(ii);
+                if (EcalMonitoringUtilities.isInHole(row, column))
+                    continue;
+                if ((row == 0) || (column == 0))
+                    continue;
+                pedestal[ii] /= nEvents;
+                noise[ii] /= nEvents;
 
-				// FIXME: Is this right? --JM
-				EcalChannel ecalChannel = conditions.getChannelCollection().findChannel(new GeometryId(helper, new int[] {systemId, column, row}));
-				int crate = ecalChannel.getCrate();
-				int slot = ecalChannel.getSlot();
-				int channel = ecalChannel.getChannel();
+                // FIXME: Is this right? --JM
+                EcalChannel ecalChannel = conditions.getChannelCollection().findChannel(new GeometryId(helper, new int[] {systemId, column, row}));
+                int crate = ecalChannel.getCrate();
+                int slot = ecalChannel.getSlot();
+                int channel = ecalChannel.getChannel();
 
-				System.out.println(column + " " + row + " " + crate + " " + slot + " " + channel + " " + pedestal[ii] + " " + noise[ii]);
+                System.out.println(column + " " + row + " " + crate + " " + slot + " " + channel + " " + pedestal[ii] + " " + noise[ii]);
 
-				if (crate == 37) {
-					writerTop.print(slot + " " + channel + " " + (int) (Math.round(pedestal[ii])) + " " + (int) (Math.round(noise[ii])) + "\r\n");
-				} else if (crate == 39) {
-					writerBottom.print(slot + " " + channel + " " + (int) (Math.round(pedestal[ii])) + " " + (int) (Math.round(noise[ii])) + "\r\n");
-				}
+                if (crate == 37) {
+                    writerTop.print(slot + " " + channel + " " + (int) (Math.round(pedestal[ii])) + " " + (int) (Math.round(noise[ii])) + "\r\n");
+                } else if (crate == 39) {
+                    writerBottom.print(slot + " " + channel + " " + (int) (Math.round(pedestal[ii])) + " " + (int) (Math.round(noise[ii])) + "\r\n");
+                }
 
-			}
+            }
 
-			writerTop.close();
-			writerBottom.close();
-		} catch (FileNotFoundException fnfe) {
+            writerTop.close();
+            writerBottom.close();
+        } catch (FileNotFoundException fnfe) {
 
-			System.out.println(fnfe.getMessage());
+            System.out.println(fnfe.getMessage());
 
-		}
+        }
 
-		catch (IOException ioe) {
+        catch (IOException ioe) {
 
-			System.out.println(ioe.getMessage());
+            System.out.println(ioe.getMessage());
 
-		}
-	}
+        }
+    }
 }

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/celentan/StripChartTest.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/celentan/StripChartTest.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/celentan/StripChartTest.java	Wed Apr 27 11:11:32 2016
@@ -6,5 +6,5 @@
  */
 public class StripChartTest  {
            
-	int dummy;    
+    int dummy;    
 }

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/holly/ClusterDriver.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/holly/ClusterDriver.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/holly/ClusterDriver.java	Wed Apr 27 11:11:32 2016
@@ -84,8 +84,8 @@
      * @param correctionClusterCollectionName
      */
     public void setCorrectionClusterCollectionName(String correctionClusterCollectionName){
-    	this.correctionClusterCollectionName = correctionClusterCollectionName;
-    	getLogger().config("correctionClusterCollectionName = " + this.correctionClusterCollectionName);
+        this.correctionClusterCollectionName = correctionClusterCollectionName;
+        getLogger().config("correctionClusterCollectionName = " + this.correctionClusterCollectionName);
     }
     
     /**
@@ -147,7 +147,7 @@
      * @param copyClusterCollection
      */
     public void setCopyClusterCollection(boolean copyClusterCollection) {
-    	this.copyClusterCollection = copyClusterCollection;
+        this.copyClusterCollection = copyClusterCollection;
     }
            
     /**
@@ -267,9 +267,9 @@
                 event.put(outputClusterCollectionName, clusters, Cluster.class, flags);
                         
                 if (copyClusterCollection 
-                		&& event.hasCollection(Cluster.class, outputClusterCollectionName)){
-                	List<Cluster> clusterCopy = event.get(Cluster.class, outputClusterCollectionName);	
-                	event.put(correctionClusterCollectionName,clusterCopy,Cluster.class,flags);
+                        && event.hasCollection(Cluster.class, outputClusterCollectionName)){
+                    List<Cluster> clusterCopy = event.get(Cluster.class, outputClusterCollectionName);  
+                    event.put(correctionClusterCollectionName,clusterCopy,Cluster.class,flags);
                 }
                                
                 if (!this.writeClusterCollection) {

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/holly/EcalClusterICPosition.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/holly/EcalClusterICPosition.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/holly/EcalClusterICPosition.java	Wed Apr 27 11:11:32 2016
@@ -53,7 +53,7 @@
  *
  */
 public class EcalClusterICPosition extends Driver {
-	// File writer to output cluster results.
+    // File writer to output cluster results.
     FileWriter writeHits;
     // LCIO collection name for calorimeter hits.
     String ecalCollectionName="EcalCalHits";
@@ -95,7 +95,7 @@
 
     
     public void setTrackerCollectionName(String trackerCollectionName){
-    	this.trackerCollectionName = trackerCollectionName;
+        this.trackerCollectionName = trackerCollectionName;
     }
     
        
@@ -112,7 +112,7 @@
     }
     
     public void setRejectedHitName(String rejectedHitName){
-    	this.rejectedHitName = rejectedHitName;
+        this.rejectedHitName = rejectedHitName;
     }
     
     /**
@@ -176,7 +176,7 @@
     //get the list of Ecal scoring Tracker hits
     public ArrayList<SimTrackerHit> trackHits = new ArrayList<SimTrackerHit>();
     public void addTrackHit(SimTrackerHit trHit){
-    	trackHits.add(trHit);
+        trackHits.add(trHit);
     }
     
     // Make a map for quick calculation of the x-y position of crystal face
@@ -187,11 +187,11 @@
     
     //attempt for mc particle list
     public void addMCGen(MCParticle genMC){
-    	mcList.add(genMC);
+        mcList.add(genMC);
     }
     
     public void startOfData() {
-    	// Make sure that the calorimeter hit collection name is defined.
+        // Make sure that the calorimeter hit collection name is defined.
         if (ecalCollectionName == null) {
             throw new RuntimeException("The parameter ecalCollectionName was not set!");
         }
@@ -211,25 +211,25 @@
 
     public void detectorChanged(Detector detector) {
         // Get the calorimeter.
-    	HPSEcal3 ecal = (HPSEcal3) detector.getSubdetector(ecalName);
-    	
+        HPSEcal3 ecal = (HPSEcal3) detector.getSubdetector(ecalName);
+        
         // Store the map of neighbor crystals for the current calorimeter set-up.
         neighborMap = ecal.getNeighborMap();
     }
 
     public void process(EventHeader event) {
-    	// Make sure the current event contains calorimeter hits.
+        // Make sure the current event contains calorimeter hits.
         if (event.hasCollection(CalorimeterHit.class, ecalCollectionName)) {
-        	
-        	// Get generated hits
+            
+            // Get generated hits
             List<MCParticle> genPart = event.getMCParticles();
             for(MCParticle m : genPart){
-            	mcList.add(m);
+                mcList.add(m);
             }
             
             List<SimTrackerHit> trHit = event.get(SimTrackerHit.class, trackerCollectionName);
             for (SimTrackerHit t : trHit){
-            	trackHits.add(t);
+                trackHits.add(t);
             }
             
 
@@ -241,13 +241,13 @@
     }
 
     public void createClusters(EventHeader event) throws IOException {
-    	
-    	// Create a list to store the event hits in.
+        
+        // Create a list to store the event hits in.
         List<CalorimeterHit> hitList = new ArrayList<CalorimeterHit>();
         List<CalorimeterHit> baseList = event.get(CalorimeterHit.class, ecalCollectionName);
         for(CalorimeterHit r : baseList) {
-        	hitEnergyMap.put(r, (r.getCorrectedEnergy()+rNum.nextGaussian()*0.003));
-        	hitList.add(r);
+            hitEnergyMap.put(r, (r.getCorrectedEnergy()+rNum.nextGaussian()*0.003));
+            hitList.add(r);
         }
         
         // Create a list to store the newly created clusters in.
@@ -263,32 +263,32 @@
         // designated threshold.
         filterLoop:
         for(int index = hitList.size() - 1; index >= 0; index--) {
-        	// If the hit is below threshold or outside of time window, kill it.
-/*        	if((hitList.get(index).getCorrectedEnergy() < hitEnergyThreshold)||
-        			(timeCut && (hitList.get(index).getTime() < minTime || hitList.get(index).getTime() > (minTime + timeWindow)))) {
-        		rejectedHitList.add(hitList.get(index));
-        		hitList.remove(index);
-        	}*/
-        	if((hitEnergyMap.get(hitList.get(index))< hitEnergyThreshold)||
-        			(timeCut && (hitList.get(index).getTime() < minTime || hitList.get(index).getTime() > (minTime + timeWindow)))) {
-        		rejectedHitList.add(hitList.get(index));
-        		hitList.remove(index);
-        	}
-        	
-        	
-        	
-        	
-        	
-        	// Since the hits are sorted by energy from highest to
-        	// lowest, any hit that is above threshold means that all
-        	// subsequent hits will also be above threshold. Continue through
-        	// list to check in time window. 
-        	else { continue; }
-        }
-        
-    	// Create a map to connect the cell ID of a calorimeter crystal
+            // If the hit is below threshold or outside of time window, kill it.
+/*          if((hitList.get(index).getCorrectedEnergy() < hitEnergyThreshold)||
+                    (timeCut && (hitList.get(index).getTime() < minTime || hitList.get(index).getTime() > (minTime + timeWindow)))) {
+                rejectedHitList.add(hitList.get(index));
+                hitList.remove(index);
+            }*/
+            if((hitEnergyMap.get(hitList.get(index))< hitEnergyThreshold)||
+                    (timeCut && (hitList.get(index).getTime() < minTime || hitList.get(index).getTime() > (minTime + timeWindow)))) {
+                rejectedHitList.add(hitList.get(index));
+                hitList.remove(index);
+            }
+            
+            
+            
+            
+            
+            // Since the hits are sorted by energy from highest to
+            // lowest, any hit that is above threshold means that all
+            // subsequent hits will also be above threshold. Continue through
+            // list to check in time window. 
+            else { continue; }
+        }
+        
+        // Create a map to connect the cell ID of a calorimeter crystal
         // to the hit which occurred in that crystal.
-    	HashMap<Long, CalorimeterHit> hitMap = new HashMap<Long, CalorimeterHit>();
+        HashMap<Long, CalorimeterHit> hitMap = new HashMap<Long, CalorimeterHit>();
         for (CalorimeterHit hit : hitList) { hitMap.put(hit.getCellID(), hit); }
         
         // Map a crystal to a list of all clusters in which it is a member.
@@ -297,13 +297,13 @@
         // Map a crystal to the seed of the cluster of which it is a member.
         HashMap<CalorimeterHit, CalorimeterHit> hitSeedMap = new HashMap<CalorimeterHit, CalorimeterHit>();
         
-      	// Set containing hits immediately around a seed hit.
-      	HashSet<CalorimeterHit> surrSeedSet = new HashSet<CalorimeterHit>();
+        // Set containing hits immediately around a seed hit.
+        HashSet<CalorimeterHit> surrSeedSet = new HashSet<CalorimeterHit>();
         
         // Loop through all calorimeter hits to locate seeds and perform
         // first pass calculations for component and common hits.
         for (CalorimeterHit hit : hitList) {
-        	// Get the set of all neighboring crystals to the current hit.
+            // Get the set of all neighboring crystals to the current hit.
             Set<Long> neighbors = neighborMap.get(hit.getCellID());
             
             // Generate a list to store any neighboring hits in.
@@ -313,11 +313,11 @@
             // which corresponds to a neighbor, add it to the list of
             // neighboring hits.
             for (Long neighbor : neighbors) {
-            	// Get the neighboring hit.
-            	CalorimeterHit neighborHit = hitMap.get(neighbor);
-                        	
-            	// If it exists, add it to the list.
-            	if(neighborHit != null) { neighborHits.add(neighborHit); }
+                // Get the neighboring hit.
+                CalorimeterHit neighborHit = hitMap.get(neighbor);
+                            
+                // If it exists, add it to the list.
+                if(neighborHit != null) { neighborHits.add(neighborHit); }
             }
             
             // Track whether the current hit is a seed hit or not.
@@ -328,10 +328,10 @@
             // neighboring hits.
             seedHitLoop:
             for(CalorimeterHit neighbor : neighborHits) {
-            	if(!equalEnergies(hit, neighbor)) {
-            		isSeed = false;
-               		break seedHitLoop;
-            	}
+                if(!equalEnergies(hit, neighbor)) {
+                    isSeed = false;
+                    break seedHitLoop;
+                }
            
             }
             
@@ -343,22 +343,22 @@
             else {
                 // Sort through the list of neighboring hits.
                 for (CalorimeterHit neighborHit : neighborHits) {
-                	// Check whether the neighboring hit is a seed.
-                	if(hitSeedMap.get(neighborHit) == neighborHit) {
+                    // Check whether the neighboring hit is a seed.
+                    if(hitSeedMap.get(neighborHit) == neighborHit) {
                         // If the neighboring hit is a seed hit and the
                         // current hit has been associated with a cluster,
                         // then it is a common hit between its previous
                         // seed and the neighboring seed.
                         if (hitSeedMap.containsKey(hit)) {
-                        	// Check and see if a list of common seeds
-                        	// for this hit already exists or not.
-                        	List<CalorimeterHit> commonHitList = commonHits.get(hit);
-                        	
-                        	// If it does not, make a new one.
-                        	if(commonHitList == null) { commonHitList = new ArrayList<CalorimeterHit>(); }
-                        	
-                        	// Add the neighbors to the seeds to set of
-                        	// common seeds.
+                            // Check and see if a list of common seeds
+                            // for this hit already exists or not.
+                            List<CalorimeterHit> commonHitList = commonHits.get(hit);
+                            
+                            // If it does not, make a new one.
+                            if(commonHitList == null) { commonHitList = new ArrayList<CalorimeterHit>(); }
+                            
+                            // Add the neighbors to the seeds to set of
+                            // common seeds.
                             commonHitList.add(neighborHit);
                             commonHitList.add(hitSeedMap.get(hit));
 
@@ -368,14 +368,14 @@
                         }
                         
                         // If the neighboring hit is a seed hit and the
-                    	// current hit has not been added to a cluster yet
-                    	// associate it with the neighboring seed and note
+                        // current hit has not been added to a cluster yet
+                        // associate it with the neighboring seed and note
                         // that it has been clustered.
                         else {
-                          	hitSeedMap.put(hit, neighborHit);
-                        	surrSeedSet.add(hit);
+                            hitSeedMap.put(hit, neighborHit);
+                            surrSeedSet.add(hit);
                         }
-                	}
+                    }
                 }
             }
         } // End primary seed loop.
@@ -383,11 +383,11 @@
         // Performs second pass calculations for component hits.
         secondaryHitsLoop:
         for (CalorimeterHit secondaryHit : hitList) {
-        	// If the secondary hit is not associated with a seed, then
-        	// the rest of there is nothing further to be done.
-        	if(!hitSeedMap.containsKey(secondaryHit)) { continue secondaryHitsLoop; }
-        	
-        	// Get the secondary hit's neighboring crystals.
+            // If the secondary hit is not associated with a seed, then
+            // the rest of there is nothing further to be done.
+            if(!hitSeedMap.containsKey(secondaryHit)) { continue secondaryHitsLoop; }
+            
+            // Get the secondary hit's neighboring crystals.
             Set<Long> secondaryNeighbors = neighborMap.get(secondaryHit.getCellID());
             
             // Make a list to store the hits associated with the
@@ -396,27 +396,27 @@
             
             // Loop through the neighboring crystals.
             for (Long secondaryNeighbor : secondaryNeighbors) {
-            	// Get the hit associated with the neighboring crystal.
-            	CalorimeterHit secondaryNeighborHit = hitMap.get(secondaryNeighbor);
-            	
-            	// If the neighboring crystal exists and is not already
-            	// in a cluster, add it to the list of neighboring hits.
+                // Get the hit associated with the neighboring crystal.
+                CalorimeterHit secondaryNeighborHit = hitMap.get(secondaryNeighbor);
+                
+                // If the neighboring crystal exists and is not already
+                // in a cluster, add it to the list of neighboring hits.
                 if (secondaryNeighborHit != null && !hitSeedMap.containsKey(secondaryNeighborHit)) { //!clusteredHitSet.contains(secondaryNeighborHit)) {
-                	secondaryNeighborHits.add(secondaryNeighborHit);
+                    secondaryNeighborHits.add(secondaryNeighborHit);
                 }
             }
             
             // Loop over the secondary neighbor hits.
             for (CalorimeterHit secondaryNeighborHit : secondaryNeighborHits) {
-            	// If the neighboring hit is of lower energy than the
-            	// current secondary hit, then associate the neighboring
-            	// hit with the current secondary hit's seed.
-            	
-            	//  if (secondaryNeighborHit.getCorrectedEnergy() < secondaryHit.getCorrectedEnergy()) {
-            	if(!equalEnergies(secondaryNeighborHit, secondaryHit)) {
-                	hitSeedMap.put(secondaryNeighborHit, hitSeedMap.get(secondaryHit));
+                // If the neighboring hit is of lower energy than the
+                // current secondary hit, then associate the neighboring
+                // hit with the current secondary hit's seed.
+                
+                //  if (secondaryNeighborHit.getCorrectedEnergy() < secondaryHit.getCorrectedEnergy()) {
+                if(!equalEnergies(secondaryNeighborHit, secondaryHit)) {
+                    hitSeedMap.put(secondaryNeighborHit, hitSeedMap.get(secondaryHit));
                 }
-            	else {continue;}
+                else {continue;}
             }
         } // End component hits loop.
 
@@ -427,10 +427,10 @@
         // Performs second pass calculations for common hits.
         commonHitsLoop:
         for (CalorimeterHit clusteredHit : hitSeedMap.keySet()) {
-        	// Seed hits are never common hits and can be skipped.
-        	if(hitSeedMap.get(clusteredHit) == clusteredHit || surrSeedSet.contains(clusteredHit)) { continue commonHitsLoop; }
-        	
-    		// Get the current clustered hit's neighboring crystals.
+            // Seed hits are never common hits and can be skipped.
+            if(hitSeedMap.get(clusteredHit) == clusteredHit || surrSeedSet.contains(clusteredHit)) { continue commonHitsLoop; }
+            
+            // Get the current clustered hit's neighboring crystals.
             Set<Long> clusteredNeighbors = neighborMap.get(clusteredHit.getCellID());
             
             // Store a list of all the clustered hits neighboring
@@ -439,12 +439,12 @@
             
             // Loop through the neighbors and see if they have hits.
             for (Long neighbor : clusteredNeighbors) {
-            	// Get the hit associated with the neighbor.
-            	CalorimeterHit clusteredNeighborHit = hitMap.get(neighbor);
-            	
-            	// If it exists, add it to the neighboring hit list.
+                // Get the hit associated with the neighbor.
+                CalorimeterHit clusteredNeighborHit = hitMap.get(neighbor);
+                
+                // If it exists, add it to the neighboring hit list.
                 if (clusteredNeighborHit != null) {
-                	clusteredNeighborHits.add(clusteredNeighborHit);
+                    clusteredNeighborHits.add(clusteredNeighborHit);
                 }
             }
             
@@ -453,25 +453,25 @@
             
             // Loop over the clustered neighbor hits.
             for (CalorimeterHit clusteredNeighborHit : clusteredNeighborHits) {
-            	// Check to make sure that the clustered neighbor hit
-            	// is not already associated with the current clustered
-            	// hit's seed.
-            	
+                // Check to make sure that the clustered neighbor hit
+                // is not already associated with the current clustered
+                // hit's seed.
+                
                 if (hitSeedMap.get(clusteredNeighborHit) != clusteredHitSeed){
 
                     //if (clusteredHit.getCorrectedEnergy() < clusteredNeighborHit.getCorrectedEnergy()) {
-                	if(!equalEnergies(clusteredHit, clusteredNeighborHit)){
-                	// Check and see if a list of common seeds
-                    	// for this hit already exists or not.
-                    	List<CalorimeterHit> commonHitList = commonHits.get(clusteredHit);
-                    	
-                    	// If it does not, make a new one.
-                    	if(commonHitList == null) { commonHitList = new ArrayList<CalorimeterHit>(); }
-                    	
-                    	// Add the neighbors to the seeds to set of
-                    	// common seeds.
+                    if(!equalEnergies(clusteredHit, clusteredNeighborHit)){
+                    // Check and see if a list of common seeds
+                        // for this hit already exists or not.
+                        List<CalorimeterHit> commonHitList = commonHits.get(clusteredHit);
+                        
+                        // If it does not, make a new one.
+                        if(commonHitList == null) { commonHitList = new ArrayList<CalorimeterHit>(); }
+                        
+                        // Add the neighbors to the seeds to set of
+                        // common seeds.
                         commonHitList.add(clusteredHitSeed);
-                       	commonHitList.add(hitSeedMap.get(clusteredNeighborHit));
+                        commonHitList.add(hitSeedMap.get(clusteredNeighborHit));
                         
                         // Put the common seed list back into the set.
                         commonHits.put(clusteredHit, commonHitList);
@@ -485,7 +485,7 @@
         
         // Remove any common hits from the clustered hits collection.
         for(CalorimeterHit commonHit : commonHits.keySet()) {
-        	hitSeedMap.remove(commonHit);
+            hitSeedMap.remove(commonHit);
         }
         
         
@@ -501,7 +501,7 @@
         // Get energy of each cluster, excluding common hits
         for (CalorimeterHit iSeed : hitList) {
             if(hitSeedMap.get(iSeed) == iSeed) {
-            	seedEnergy.put(iSeed, 0.0);
+                seedEnergy.put(iSeed, 0.0);
             }
         }
         
@@ -517,24 +517,24 @@
         Map<CalorimeterHit, Double> seedEnergyTot = seedEnergy;
         
         for (Map.Entry<CalorimeterHit, List<CalorimeterHit>> entry1 : commonHits.entrySet()) {
-        	CalorimeterHit commonCell = entry1.getKey();
-        	CalorimeterHit seedA = entry1.getValue().get(0);
-        	CalorimeterHit seedB = entry1.getValue().get(1);    	
-        	double eFractionA = seedEnergy.get(seedA)/(seedEnergy.get(seedA)+seedEnergy.get(seedB));
-        	double eFractionB = seedEnergy.get(seedB)/(seedEnergy.get(seedA)+seedEnergy.get(seedB));
-        	double currEnergyA = seedEnergyTot.get(seedA);
-        	double currEnergyB = seedEnergyTot.get(seedB);
-        	currEnergyA += eFractionA * (hitEnergyMap.get(commonCell));
-        	currEnergyB += eFractionB * (hitEnergyMap.get(commonCell));
-
-        	seedEnergyTot.put(seedA, currEnergyA);
-        	seedEnergyTot.put(seedB, currEnergyB);
+            CalorimeterHit commonCell = entry1.getKey();
+            CalorimeterHit seedA = entry1.getValue().get(0);
+            CalorimeterHit seedB = entry1.getValue().get(1);        
+            double eFractionA = seedEnergy.get(seedA)/(seedEnergy.get(seedA)+seedEnergy.get(seedB));
+            double eFractionB = seedEnergy.get(seedB)/(seedEnergy.get(seedA)+seedEnergy.get(seedB));
+            double currEnergyA = seedEnergyTot.get(seedA);
+            double currEnergyB = seedEnergyTot.get(seedB);
+            currEnergyA += eFractionA * (hitEnergyMap.get(commonCell));
+            currEnergyB += eFractionB * (hitEnergyMap.get(commonCell));
+
+            seedEnergyTot.put(seedA, currEnergyA);
+            seedEnergyTot.put(seedB, currEnergyB);
         }
 
         // Choose only the highest energy cluster
          List<CalorimeterHit> seedList = new ArrayList<CalorimeterHit>();
         for (Map.Entry<CalorimeterHit, Double> entry1 : seedEnergyTot.entrySet()) {
-        	seedList.add(entry1.getKey());
+            seedList.add(entry1.getKey());
         }
         
         Collections.sort(seedList, new EnergyComparator());
@@ -550,64 +550,64 @@
         double w0 = 3.1;
         
         for (Map.Entry<CalorimeterHit, CalorimeterHit> entry1 : hitSeedMap.entrySet()) {
-        	CalorimeterHit eSeed1 = entry1.getValue();
-        	if(seedList.get(0)==eSeed1){// Check for if belonging to highest seed only.
-
-        		
-        		// Method 3 calculation.
-        		// Calculates x-y centroid for each crystal face
-//            	IGeometryInfo geom = entry1.getKey().getDetectorElement().getGeometry();
-//    	        double[] pos = geom.transformLocalToGlobal(VecOp.add(geom.transformGlobalToLocal(geom.getPosition()),(Hep3Vector)new BasicHep3Vector(0,0,-1*((Trd)geom.getLogicalVolume().getSolid()).getZHalfLength()))).v();
-    	       
-    	       ///////////////////////////////
-    	       // Get the hit indices as a Point.
-    	        int ix = entry1.getKey().getIdentifierFieldValue("ix");
-    	        int iy = entry1.getKey().getIdentifierFieldValue("iy");
-    	        Point hitIndex = new Point(ix, iy);
-
-    	        // Get the corrected position for this index pair.
-    	        Double[] position = correctedPositionMap.get(hitIndex);
-
-    	        // If the result is null, it hasn't been calculated yet.
-    	        if(position == null) {
-    	                // Calculate the corrected position.
-    	                IGeometryInfo geom = entry1.getKey().getDetectorElement().getGeometry();
-    	                double[] pos = geom.transformLocalToGlobal(VecOp.add(geom.transformGlobalToLocal(geom.getPosition()),(Hep3Vector)new BasicHep3Vector(0,0,-1*((Trd)geom.getLogicalVolume().getSolid()).getZHalfLength()))).v();
-    	                
-    	                // Convert the result to  a Double[] array.
-    	                position = new Double[3];
-    	                position[0] = pos[0];
-    	                position[1] = pos[1];
-    	                position[2] = pos[2];
-    	                
-    	                // Store the result in the map.
-    	                correctedPositionMap.put(hitIndex, position);
-//    	               writeHits.append("\t"+ix+"\t"+iy+"\t"+position[0]+"\t"+position[1]+"\n"); //write out slic crystal maps
-    	        }
-    	        ///////////////////////////////
-    	        // Method 3:
-        		eNumX += Math.max(0.0,(w0+Math.log((hitEnergyMap.get(entry1.getKey()))
-        				/seedEnergyTot.get(eSeed1))))*(correctedPositionMap.get(hitIndex)[0]/10.0);
-        		eNumY += Math.max(0.0,(w0+Math.log((hitEnergyMap.get(entry1.getKey()))
-        				/seedEnergyTot.get(eSeed1))))*(correctedPositionMap.get(hitIndex)[1]/10.0);
-        		eDen += Math.max(0.0, w0+Math.log((hitEnergyMap.get(entry1.getKey()))/
-        				seedEnergyTot.get(eSeed1)));
-        
-        		// Method 1:
-/*        		eNumX += (hitEnergyMap.get(entry1.getKey()))*correctedPositionMap.get(hitIndex)[0]/10.0;
-        		eNumY += (hitEnergyMap.get(entry1.getKey()))*correctedPositionMap.get(hitIndex)[1]/10.0;
-        		eDen += hitEnergyMap.get(entry1.getKey());
-*/        		
-        		
-        		
-        		//Method 2:
-/*        		eNumX += Math.log10(1000*(hitEnergyMap.get(entry1.getKey())))*correctedPositionMap.get(hitIndex)[0]/10.0;
-        		eNumY += Math.log10(1000*(hitEnergyMap.get(entry1.getKey())))*correctedPositionMap.get(hitIndex)[1]/10.0;
-        		eDen += Math.log10(1000*(hitEnergyMap.get(entry1.getKey())));
-*/        	
-        		crystalAngle = 0.967826*(eSeed1.getIdentifierFieldValue("ix"));
-
-        	}
+            CalorimeterHit eSeed1 = entry1.getValue();
+            if(seedList.get(0)==eSeed1){// Check for if belonging to highest seed only.
+
+                
+                // Method 3 calculation.
+                // Calculates x-y centroid for each crystal face
+//              IGeometryInfo geom = entry1.getKey().getDetectorElement().getGeometry();
+//              double[] pos = geom.transformLocalToGlobal(VecOp.add(geom.transformGlobalToLocal(geom.getPosition()),(Hep3Vector)new BasicHep3Vector(0,0,-1*((Trd)geom.getLogicalVolume().getSolid()).getZHalfLength()))).v();
+               
+               ///////////////////////////////
+               // Get the hit indices as a Point.
+                int ix = entry1.getKey().getIdentifierFieldValue("ix");
+                int iy = entry1.getKey().getIdentifierFieldValue("iy");
+                Point hitIndex = new Point(ix, iy);
+
+                // Get the corrected position for this index pair.
+                Double[] position = correctedPositionMap.get(hitIndex);
+
+                // If the result is null, it hasn't been calculated yet.
+                if(position == null) {
+                        // Calculate the corrected position.
+                        IGeometryInfo geom = entry1.getKey().getDetectorElement().getGeometry();
+                        double[] pos = geom.transformLocalToGlobal(VecOp.add(geom.transformGlobalToLocal(geom.getPosition()),(Hep3Vector)new BasicHep3Vector(0,0,-1*((Trd)geom.getLogicalVolume().getSolid()).getZHalfLength()))).v();
+                        
+                        // Convert the result to  a Double[] array.
+                        position = new Double[3];
+                        position[0] = pos[0];
+                        position[1] = pos[1];
+                        position[2] = pos[2];
+                        
+                        // Store the result in the map.
+                        correctedPositionMap.put(hitIndex, position);
+//                     writeHits.append("\t"+ix+"\t"+iy+"\t"+position[0]+"\t"+position[1]+"\n"); //write out slic crystal maps
+                }
+                ///////////////////////////////
+                // Method 3:
+                eNumX += Math.max(0.0,(w0+Math.log((hitEnergyMap.get(entry1.getKey()))
+                        /seedEnergyTot.get(eSeed1))))*(correctedPositionMap.get(hitIndex)[0]/10.0);
+                eNumY += Math.max(0.0,(w0+Math.log((hitEnergyMap.get(entry1.getKey()))
+                        /seedEnergyTot.get(eSeed1))))*(correctedPositionMap.get(hitIndex)[1]/10.0);
+                eDen += Math.max(0.0, w0+Math.log((hitEnergyMap.get(entry1.getKey()))/
+                        seedEnergyTot.get(eSeed1)));
+        
+                // Method 1:
+/*              eNumX += (hitEnergyMap.get(entry1.getKey()))*correctedPositionMap.get(hitIndex)[0]/10.0;
+                eNumY += (hitEnergyMap.get(entry1.getKey()))*correctedPositionMap.get(hitIndex)[1]/10.0;
+                eDen += hitEnergyMap.get(entry1.getKey());
+*/              
+                
+                
+                //Method 2:
+/*              eNumX += Math.log10(1000*(hitEnergyMap.get(entry1.getKey())))*correctedPositionMap.get(hitIndex)[0]/10.0;
+                eNumY += Math.log10(1000*(hitEnergyMap.get(entry1.getKey())))*correctedPositionMap.get(hitIndex)[1]/10.0;
+                eDen += Math.log10(1000*(hitEnergyMap.get(entry1.getKey())));
+*/          
+                crystalAngle = 0.967826*(eSeed1.getIdentifierFieldValue("ix"));
+
+            }
 
         }
         
@@ -621,36 +621,36 @@
         
         
         if(trackHits.size() != 0 ){
-        	
-	        // Calculates the final generated particle position
-	        double d0 = 139.3 - trackHits.get(0).getPositionVec().z()/10.0;
-	        double px = trackHits.get(0).getMomentum()[0];
-	        double py = trackHits.get(0).getMomentum()[1];
-	        double pz = trackHits.get(0).getMomentum()[2];
-	        double xpos = trackHits.get(0).getPosition()[0]/10.0;
-	        double ypos = trackHits.get(0).getPosition()[1]/10.0;
-	        
-	        double xGen = xpos + d0*px/pz;
-	        double yGen = ypos + d0*py/pz;
-	        
-	        boolean validNum = false;
-	        if((Math.abs(xCl)>0)&&(Math.abs(yCl)>0)&&(Math.abs(xGen)>0)&&(Math.abs(yGen)>0)){
-	        	validNum=true;
-	        }
-	        
-	        
-	       
-        	 //position fitting
-//        	        writeHits.append("\t"+seedList.get(0).getIdentifierFieldValue("ix")+"\t"+seedList.get(0).getIdentifierFieldValue("iy")+"\t"
-//        	 +xCl+"\t"+yCl+"\t"+xF+"\t"+yF+"\t"+mcList.get(0).getEnergy()+"\t"+crystalAngle+"\t"+ECl+"\n");
-        	  if(validNum==true){      
-//        	        writeHits.append("\t"+xCl+"\t"+yCl+"\t"+xGen+"\t"+yGen+"\t"+mcList.get(0).getEnergy()+"\t"+crystalAngle+"\t"+ECl+"\n");
-        	                	        
-        	  }    
-
-        	        }
-        	        
-   	        
+            
+            // Calculates the final generated particle position
+            double d0 = 139.3 - trackHits.get(0).getPositionVec().z()/10.0;
+            double px = trackHits.get(0).getMomentum()[0];
+            double py = trackHits.get(0).getMomentum()[1];
+            double pz = trackHits.get(0).getMomentum()[2];
+            double xpos = trackHits.get(0).getPosition()[0]/10.0;
+            double ypos = trackHits.get(0).getPosition()[1]/10.0;
+            
+            double xGen = xpos + d0*px/pz;
+            double yGen = ypos + d0*py/pz;
+            
+            boolean validNum = false;
+            if((Math.abs(xCl)>0)&&(Math.abs(yCl)>0)&&(Math.abs(xGen)>0)&&(Math.abs(yGen)>0)){
+                validNum=true;
+            }
+            
+            
+           
+             //position fitting
+//                  writeHits.append("\t"+seedList.get(0).getIdentifierFieldValue("ix")+"\t"+seedList.get(0).getIdentifierFieldValue("iy")+"\t"
+//           +xCl+"\t"+yCl+"\t"+xF+"\t"+yF+"\t"+mcList.get(0).getEnergy()+"\t"+crystalAngle+"\t"+ECl+"\n");
+              if(validNum==true){      
+//                  writeHits.append("\t"+xCl+"\t"+yCl+"\t"+xGen+"\t"+yGen+"\t"+mcList.get(0).getEnergy()+"\t"+crystalAngle+"\t"+ECl+"\n");
+                                        
+              }    
+
+                    }
+                    
+            
         }// end seedList.size != 0 
         
         int flag = 1 << LCIOConstants.CLBIT_HITS;
@@ -663,95 +663,95 @@
         
 
     public void endOfData() {
-    	// Close the event display output writer.
+        // Close the event display output writer.
         try { writeHits.close(); }
         catch (IOException e) { }
     }
     
   
     private static class EnergyComparator implements Comparator<CalorimeterHit> {
-    	/**
-    	 * Compares the first hit with respect to the second. This
-    	 * method will compare hits first by energy, and the spatially.
-    	 * In the case of equal energy hits, the hit closest to the
-    	 * beam gap and closest to the positron side of the detector
-    	 * will be selected. If all of these conditions are true, the
-    	 * hit with the positive y-index will be selected. Hits with
-    	 * all four conditions matching are the same hit.
-    	 * @param hit1 The hit to compare.
-    	 * @param hit2 The hit with respect to which the first should
-    	 * be compared.
-    	 */
+        /**
+         * Compares the first hit with respect to the second. This
+         * method will compare hits first by energy, and the spatially.
+         * In the case of equal energy hits, the hit closest to the
+         * beam gap and closest to the positron side of the detector
+         * will be selected. If all of these conditions are true, the
+         * hit with the positive y-index will be selected. Hits with
+         * all four conditions matching are the same hit.
+         * @param hit1 The hit to compare.
+         * @param hit2 The hit with respect to which the first should
+         * be compared.
+         */
     public int compare(CalorimeterHit hit1, CalorimeterHit hit2) {
-    	// Hits are sorted on a hierarchy by three conditions. First,
-    	// the hits with the highest energy come first. Next, they
-    	// are ranked by vertical proximity to the beam gap, and
-    	// lastly, they are sorted by horizontal proximity to the
-    	// positron side of the detector.
-    	
-    	// Get the hit energies.
-    	double[] e = { hit1.getCorrectedEnergy(), hit2.getCorrectedEnergy() };
-    	
-    	// Perform the energy comparison. The higher energy hit
-    	// will be ordered first.
-    	if(e[0] < e[1]) { return 1; }
-    	else if(e[0] > e[1]) { return -1; }
-    	
-    	// If the hits are the same energy, we must perform the
-    	// spatial comparisons.
-    	else {
-    		// Get the position with respect to the beam gap.
-    		int[] iy = { Math.abs(hit1.getIdentifierFieldValue("iy")), Math.abs(hit2.getIdentifierFieldValue("iy")) };
-    		
-    		// The closest hit is first.
-    		if(iy[0] > iy[1]) { return -1; }
-    		else if(iy[0] < iy[1]) { return 1; }
-    		
-    		// Hits that are identical in vertical distance from
-    		// beam gap and energy are differentiated with distance
-    		// horizontally from the positron side of the detector.
-    		else {
-        		// Get the position from the positron side.
-        		int[] ix = { hit1.getIdentifierFieldValue("ix"), hit2.getIdentifierFieldValue("ix") };
-        		
-        		// The closest hit is first.
-        		if(ix[0] > ix[1]) { return 1; }
-        		else if(ix[0] < ix[1]) { return -1; }
-    			
-        		// If all of these checks are the same, compare
-        		// the raw value for iy. If these are identical,
-        		// then the two hits are the same. Otherwise, sort
-        		// the numerical value of iy. (This removes the
-        		// issue where hits (x, y) and (x, -y) can have
-        		// the same energy and be otherwise seen as the
-        		// same hit from the above checks.
-        		else { return Integer.compare(hit1.getIdentifierFieldValue("iy"), hit2.getIdentifierFieldValue("iy")); }
-    		}
-    	}
+        // Hits are sorted on a hierarchy by three conditions. First,
+        // the hits with the highest energy come first. Next, they
+        // are ranked by vertical proximity to the beam gap, and
+        // lastly, they are sorted by horizontal proximity to the
+        // positron side of the detector.
+        
+        // Get the hit energies.
+        double[] e = { hit1.getCorrectedEnergy(), hit2.getCorrectedEnergy() };
+        
+        // Perform the energy comparison. The higher energy hit
+        // will be ordered first.
+        if(e[0] < e[1]) { return 1; }
+        else if(e[0] > e[1]) { return -1; }
+        
+        // If the hits are the same energy, we must perform the
+        // spatial comparisons.
+        else {
+            // Get the position with respect to the beam gap.
+            int[] iy = { Math.abs(hit1.getIdentifierFieldValue("iy")), Math.abs(hit2.getIdentifierFieldValue("iy")) };
+            
+            // The closest hit is first.
+            if(iy[0] > iy[1]) { return -1; }
+            else if(iy[0] < iy[1]) { return 1; }
+            
+            // Hits that are identical in vertical distance from
+            // beam gap and energy are differentiated with distance
+            // horizontally from the positron side of the detector.
+            else {
+                // Get the position from the positron side.
+                int[] ix = { hit1.getIdentifierFieldValue("ix"), hit2.getIdentifierFieldValue("ix") };
+                
+                // The closest hit is first.
+                if(ix[0] > ix[1]) { return 1; }
+                else if(ix[0] < ix[1]) { return -1; }
+                
+                // If all of these checks are the same, compare
+                // the raw value for iy. If these are identical,
+                // then the two hits are the same. Otherwise, sort
+                // the numerical value of iy. (This removes the
+                // issue where hits (x, y) and (x, -y) can have
+                // the same energy and be otherwise seen as the
+                // same hit from the above checks.
+                else { return Integer.compare(hit1.getIdentifierFieldValue("iy"), hit2.getIdentifierFieldValue("iy")); }
+            }
+        }
     }
 }
     
 
     // Handles pathological case where multiple neighboring crystals have EXACTLY the same energy.
     private boolean equalEnergies(CalorimeterHit hit, CalorimeterHit neighbor){
-    	boolean isSeed = true;
-    	
-    	int hix = hit.getIdentifierFieldValue("ix");
-    	int hiy = Math.abs(hit.getIdentifierFieldValue("iy"));
-    	int nix = neighbor.getIdentifierFieldValue("ix");
-    	int niy = Math.abs(neighbor.getIdentifierFieldValue("iy"));
-    	double hE = hit.getCorrectedEnergy();
-    	double nE = neighbor.getCorrectedEnergy();
-    	if(hE < nE) {
-    		isSeed = false;
-    	}
-    	else if((hE == nE) && (hiy > niy)) {
-    		isSeed = false;
-    	}
-    	else if((hE == nE) && (hiy == niy) && (hix > nix)) {
-    		isSeed = false;
-    	}
-    	return isSeed;	
+        boolean isSeed = true;
+        
+        int hix = hit.getIdentifierFieldValue("ix");
+        int hiy = Math.abs(hit.getIdentifierFieldValue("iy"));
+        int nix = neighbor.getIdentifierFieldValue("ix");
+        int niy = Math.abs(neighbor.getIdentifierFieldValue("iy"));
+        double hE = hit.getCorrectedEnergy();
+        double nE = neighbor.getCorrectedEnergy();
+        if(hE < nE) {
+            isSeed = false;
+        }
+        else if((hE == nE) && (hiy > niy)) {
+            isSeed = false;
+        }
+        else if((hE == nE) && (hiy == niy) && (hix > nix)) {
+            isSeed = false;
+        }
+        return isSeed;  
     }
     
     

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/holly/EcalClustererCosmics.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/holly/EcalClustererCosmics.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/holly/EcalClustererCosmics.java	Wed Apr 27 11:11:32 2016
@@ -124,13 +124,13 @@
 
         // Loop over ECal hits to find cluster seeds.
         for (CalorimeterHit hit : map.values()) {
-        //	int ix = hit.getIdentifierFieldValue("ix");
+        //  int ix = hit.getIdentifierFieldValue("ix");
          //   int iy = hit.getIdentifierFieldValue("iy");
       //      System.out.println("ix = "+ix);
       //      System.out.println("iy = "+iy);
             
-              	
-        	// Cut on min seed E.
+                
+            // Cut on min seed E.
             if (hit.getRawEnergy() < seedEMin) {
                 continue;
             }

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/holly/EcalRawConverter.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/holly/EcalRawConverter.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/holly/EcalRawConverter.java	Wed Apr 27 11:11:32 2016
@@ -106,42 +106,42 @@
     private EcalConditions ecalConditions = null;
 
     public EcalRawConverter() {
-    	// Track changes in the DAQ configuration.
-    	ConfigurationManager.addActionListener(new ActionListener() {
-			@Override
-			public void actionPerformed(ActionEvent e) {
-				// If the DAQ configuration should be used, load the
-				// relevant settings into the driver.
-				if(useDAQConfig) {
-					// Get the FADC configuration.
-					config = ConfigurationManager.getInstance().getFADCConfig();
-					
-					// Load the settings.
-					NSB = config.getNSB();
-					NSA = config.getNSA();
-					windowSamples = config.getWindowWidth() / 4;
-					
-					// Get the number of peaks.
-					if(config.getMode() == 1) {
-						nPeak = Integer.MAX_VALUE;
-					} else {
-						nPeak = config.getMaxPulses();
-					}
-					
-					// Print the FADC configuration.
-					System.out.println();
-					System.out.println();
-					System.out.printf("NSA            :: %d ns%n", NSA);
-					System.out.printf("NSB            :: %d ns%n", NSB);
-					System.out.printf("Window Samples :: %d clock-cycles%n", windowSamples);
-					System.out.printf("Max Peaks      :: %d peaks%n", nPeak);
-					System.out.println("======================================================================");
-					System.out.println("=== FADC Pulse-Processing Settings ===================================");
-					System.out.println("======================================================================");
-					config.printConfig();
-				}
-			}
-    	});
+        // Track changes in the DAQ configuration.
+        ConfigurationManager.addActionListener(new ActionListener() {
+            @Override
+            public void actionPerformed(ActionEvent e) {
+                // If the DAQ configuration should be used, load the
+                // relevant settings into the driver.
+                if(useDAQConfig) {
+                    // Get the FADC configuration.
+                    config = ConfigurationManager.getInstance().getFADCConfig();
+                    
+                    // Load the settings.
+                    NSB = config.getNSB();
+                    NSA = config.getNSA();
+                    windowSamples = config.getWindowWidth() / 4;
+                    
+                    // Get the number of peaks.
+                    if(config.getMode() == 1) {
+                        nPeak = Integer.MAX_VALUE;
+                    } else {
+                        nPeak = config.getMaxPulses();
+                    }
+                    
+                    // Print the FADC configuration.
+                    System.out.println();
+                    System.out.println();
+                    System.out.printf("NSA            :: %d ns%n", NSA);
+                    System.out.printf("NSB            :: %d ns%n", NSB);
+                    System.out.printf("Window Samples :: %d clock-cycles%n", windowSamples);
+                    System.out.printf("Max Peaks      :: %d peaks%n", nPeak);
+                    System.out.println("======================================================================");
+                    System.out.println("=== FADC Pulse-Processing Settings ===================================");
+                    System.out.println("======================================================================");
+                    config.printConfig(System.out);
+                }
+            }
+        });
     }
   
     public void setLeadingEdgeThreshold(double thresh) {
@@ -196,7 +196,7 @@
     }
     
     public void setUseDAQConfig(boolean state) {
-    	useDAQConfig = state;
+        useDAQConfig = state;
     }
 
     /*
@@ -206,10 +206,10 @@
         EcalChannelConstants channelData = findChannel(hit.getCellID());
         double pedestal;
         if(useDAQConfig) {
-    		//EcalChannel channel = ecalConditions.getChannelCollection().findGeometric(hit.getCellID());
-    		pedestal = config.getPedestal(hit.getCellID());
+            //EcalChannel channel = ecalConditions.getChannelCollection().findGeometric(hit.getCellID());
+            pedestal = config.getPedestal(hit.getCellID());
         } else {
-        	pedestal = channelData.getCalibration().getPedestal();
+            pedestal = channelData.getCalibration().getPedestal();
         }
         
         int sum = 0;
@@ -237,10 +237,10 @@
      * Choose whether to use static pedestal from database or running pedestal from mode-7.
      */
     public double getSingleSamplePedestal(EventHeader event,long cellID) {
-    	if(useDAQConfig) {
-    		//EcalChannel channel = ecalConditions.getChannelCollection().findGeometric(cellID);
-    		return config.getPedestal(cellID);
-    	}
+        if(useDAQConfig) {
+            //EcalChannel channel = ecalConditions.getChannelCollection().findGeometric(cellID);
+            return config.getPedestal(cellID);
+        }
         if (useRunningPedestal && event!=null) {
             if (event.hasItem("EcalRunningPedestals")) {
                 Map<EcalChannel, Double> runningPedMap = (Map<EcalChannel, Double>) event.get("EcalRunningPedestals");
@@ -409,12 +409,12 @@
         // threshold is pedestal plus threshold configuration parameter:
         final int absoluteThreshold;
         if(useDAQConfig) {
-        	//EcalChannel channel = ecalConditions.getChannelCollection().findGeometric(hit.getCellID());
-        	//int leadingEdgeThreshold = ConfigurationManager.getInstance().getFADCConfig().getThreshold(channel.getChannelId());
-        	int leadingEdgeThreshold = config.getThreshold(cellID);
-        	absoluteThreshold = (int) (getSingleSamplePedestal(event, cellID) + leadingEdgeThreshold);
+            //EcalChannel channel = ecalConditions.getChannelCollection().findGeometric(hit.getCellID());
+            //int leadingEdgeThreshold = ConfigurationManager.getInstance().getFADCConfig().getThreshold(channel.getChannelId());
+            int leadingEdgeThreshold = config.getThreshold(cellID);
+            absoluteThreshold = (int) (getSingleSamplePedestal(event, cellID) + leadingEdgeThreshold);
         } else {
-        	absoluteThreshold = (int) (getSingleSamplePedestal(event, cellID) + leadingEdgeThreshold);
+            absoluteThreshold = (int) (getSingleSamplePedestal(event, cellID) + leadingEdgeThreshold);
         }
         
         ArrayList <Integer> thresholdCrossings = new ArrayList<Integer>();
@@ -435,10 +435,10 @@
                 // search for next threshold crossing begins at end of this pulse:
                 if(useDAQConfig && ConfigurationManager.getInstance().getFADCConfig().getMode() == 1) {
                     // special case, emulating SSP:
-                	ii += 8;
+                    ii += 8;
                 } else {
                     // "normal" case, emulating FADC250:
-                	ii += NSA/nsPerSample - 1;
+                    ii += NSA/nsPerSample - 1;
                 }
 
                 // firmware limit on # of peaks:
@@ -532,8 +532,8 @@
         EcalChannelConstants channelData = findChannel(cellID);
         
         if(useDAQConfig) {
-        	//float gain = ConfigurationManager.getInstance().getFADCConfig().getGain(ecalConditions.getChannelCollection().findGeometric(cellID));
-        	return config.getGain(cellID) * adcSum * EcalUtils.MeV;
+            //float gain = ConfigurationManager.getInstance().getFADCConfig().getGain(ecalConditions.getChannelCollection().findGeometric(cellID));
+            return config.getGain(cellID) * adcSum * EcalUtils.MeV;
         }  else if(use2014Gain) {
             if (constantGain) {
                 return adcSum * EcalUtils.gainFactor * EcalUtils.ecalReadoutPeriod;

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/holly/HPSEcalClusterIC.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/holly/HPSEcalClusterIC.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/holly/HPSEcalClusterIC.java	Wed Apr 27 11:11:32 2016
@@ -55,11 +55,11 @@
     }
     
     public void addSharedHit(CalorimeterHit sharedHit) {
-    	sharedHitList.add(sharedHit);
+        sharedHitList.add(sharedHit);
     }
     
     public List<CalorimeterHit> getSharedHits() {
-    	return sharedHitList;
+        return sharedHitList;
     }
     
 //    public double[] getPosition() {
@@ -155,12 +155,12 @@
         for(int i=0;i<hits.size();i++)
         {
             CalorimeterHit hit = hits.get(i);
-            //	CalorimeterIDDecoder decoder = hit.getDecoder();
-            //	decoder.setID(hit.getCellID());
-            //	double[] pos = new double[3];
-            //	pos[0] = decoder.getX();
-            //	pos[1] = decoder.getY();
-            //	pos[2] = decoder.getZ();
+            //  CalorimeterIDDecoder decoder = hit.getDecoder();
+            //  decoder.setID(hit.getCellID());
+            //  double[] pos = new double[3];
+            //  pos[0] = decoder.getX();
+            //  pos[1] = decoder.getY();
+            //  pos[2] = decoder.getZ();
             //double[] pos = hit.getPosition();
             //Find position at shower max
             IGeometryInfo geom = hit.getDetectorElement().getGeometry();
@@ -296,104 +296,104 @@
             EV[1] = E2;
             EV[2] = E3;
             // Now calculate principal axes
-	    // For eigenvalue EV, the axis is (nx, ny, nz) where:
-	    //    (Exx - EV)nx + (Exy)ny + (Exz)nz = 0
-	    //    (Eyx)nx + (Eyy - EV)ny + (Eyz)nz = 0
-	    //    (Ezx)nx + (Ezy)ny + (Ezz - EV)nz = 0
-	    // Setting nx = 1, we have:
-	    //    (Exx - EV) + (Exy)ny + (Exz)nz = 0
-	    //    (Eyx) + (Eyy - EV)ny + (Eyz)nz = 0
-	    //    (Ezx) + (Ezy)ny + (Ezz - EV)nz = 0
-	    // and so
-	    //    (Exy)ny = EV - Exx - (Exz)nz  =>  ny = (EV - Exx - Exz*nz)/Exy
-	    // What if Exy = 0? Then provided Eyz is non-zero we can write:
-	    //    (Ezx) + (Ezy)ny + (Ezz - EV)nz = 0
-	    //    ny = (Exz - (Ezz-EV)*nz)/Eyz
-	    // What if Exy = 0 and Eyz = 0 but (Eyy - EV) is non-zero?
-	    //    (Eyy - EV)ny + (Eyz)nz = 0
-	    //    ny = -(Eyz*nz)/(Eyy-EV)
-
-	    // In the pathological case where Exz = Eyz = Ezz = 0:
-	    //    (Exx - EV)nx + (Exy)ny = 0  =>  ny/nx = -(Exx-EV)/Exy
-	    //    (Eyx)nx + (Eyy - EV)ny = 0  =>  ny/nx = -Eyx/(Eyy-EV)
-	    //    (EV)nz = 0
-	    // so
-	    //     -ny/nx = (EV-Exx)/Exy = Eyx/(EV-Eyy)
-	    // But watch out for order! Recalculate eigenvalues for this pathological case.
-	    //     (EV-Exx)(EV-Eyy) = Eyx*Exy
-	    //     EV^2 - EV(Exx+Eyy) + Exx*Eyy - Eyx*Exy = 0
-	    // 
-	    // In another pathological case, Exz = Exy = 0:
-	    //    (Exx - EV)nx = 0
-	    //    (Eyy - EV)ny + (Eyz)nz = 0 => ny/nz = -(Eyz)/(Eyy-EV)
-	    //    (Ezy)ny + (Ezz - EV)nz = 0 => ny/nz = -(Ezz-EV)/(Ezy)
-	    // so we cannot set nx = 1. Instead, write:
-	    //    -ny/nz = (Eyz)/(Eyy-EV) = (Ezz-EV)/(Ezy)
-	    // Then
-	    //    (Eyz)(Ezy) = (Eyy-EV)(Ezz-EV)
-	    //    (Eyz)^2 = (Eyy)(Ezz) - (Eyy)(EV) - (Ezz)(EV) + (EV)^2
-	    //    EV^2 - EV(Eyy+Ezz) + Eyy*Ezz - Eyz*Eyz = 0
-
-	    // Handle pathological case
-	    if (Exz == 0.0 && Eyz == 0.0) {
-		// Recompute eigenvectors.
-		EV[0] = 0.5*(Exx+Eyy) + 0.5*Math.sqrt((Exx+Eyy)*(Exx+Eyy) + 4.0*Exy*Exy);
-		EV[1] = 0.5*(Exx+Eyy) - 0.5*Math.sqrt((Exx+Eyy)*(Exx+Eyy) + 4.0*Exy*Exy);
-		EV[2] = 0.0;
-		for( int i = 0 ; i < 2 ; i++ ) {
-		    double nx_over_ny = Exy / (Exx-EV[i]);
-		    double nx_unnormalized = nx_over_ny;
-		    double ny_unnormalized = 1.0;
-		    double norm = Math.sqrt(nx_unnormalized*nx_unnormalized + ny_unnormalized*ny_unnormalized);
-		    mm_PA[i][0] = ny_unnormalized/norm;
-		    mm_PA[i][1] = nx_unnormalized/norm;
-		    mm_PA[i][2] = 0.0;
-		}
-		// ... and now set third eigenvector to the z direction:
-		mm_PA[2][0] = 0.0;
-		mm_PA[2][1] = 0.0;
-		mm_PA[2][2] = 1.0;
-	    } else if (Exz == 0.0 && Exy == 0.0) {
-		// Another pathological case
-		EV[0] = 0.5*(Eyy+Ezz) + 0.5*Math.sqrt((Eyy+Ezz)*(Eyy+Ezz) + 4.0*Eyz*Eyz);
-		EV[1] = 0.5*(Eyy+Ezz) - 0.5*Math.sqrt((Eyy+Ezz)*(Eyy+Ezz) + 4.0*Eyz*Eyz);
-		EV[2] = 0.0;
-		for( int i = 0 ; i < 2 ; i++ ) {
-		    double ny_over_nz = Eyz / (Eyy-EV[i]);
-		    double ny_unnormalized = ny_over_nz;
-		    double nz_unnormalized = 1.0;
-		    double norm = Math.sqrt(ny_unnormalized*ny_unnormalized + nz_unnormalized*nz_unnormalized);
-		    mm_PA[i][0] = nz_unnormalized/norm;
-		    mm_PA[i][1] = ny_unnormalized/norm;
-		    mm_PA[i][2] = 0.0;
-		}
-		mm_PA[2][0] = 0.0;
-		mm_PA[2][1] = 0.0;
-		mm_PA[2][2] = 1.0;
-	    } else {
-		for( int i = 0 ; i < 3 ; i++ )
-		    {
-			double[] C = new double[3];
-			C[0] = 1.0;
-			C[2] = (Exy*Exy + (Eyy - EV[i])*(EV[i] - Exx))/
-			    ((Eyy - EV[i])*Exz - Eyz*Exy);
-			C[1] = (EV[i] - Exx - Exz*C[2])/Exy;
-			if (Exy == 0.0) {
-			    // Recompute
-			    if (Eyz != 0.0) {
-				// ny = (Exz - (Ezz-EV)*nz)/Eyz
-				C[1] = (Exz - (Ezz-EV[i])*C[2])/Eyz;
-			    } else {
-				// ny = -(Eyz*nz)/(Eyy-EV)
-				C[1] = -(Eyz*C[2])/(Eyy-EV[i]);
-			    }
-			}
-			double norm = Math.sqrt(C[0]*C[0] + C[1]*C[1] + C[2]*C[2]);
-			mm_PA[i][0] = C[0]/norm;
-			mm_PA[i][1] = C[1]/norm;
-			mm_PA[i][2] = C[2]/norm;
-		    }
-	    }
+        // For eigenvalue EV, the axis is (nx, ny, nz) where:
+        //    (Exx - EV)nx + (Exy)ny + (Exz)nz = 0
+        //    (Eyx)nx + (Eyy - EV)ny + (Eyz)nz = 0
+        //    (Ezx)nx + (Ezy)ny + (Ezz - EV)nz = 0
+        // Setting nx = 1, we have:
+        //    (Exx - EV) + (Exy)ny + (Exz)nz = 0
+        //    (Eyx) + (Eyy - EV)ny + (Eyz)nz = 0
+        //    (Ezx) + (Ezy)ny + (Ezz - EV)nz = 0
+        // and so
+        //    (Exy)ny = EV - Exx - (Exz)nz  =>  ny = (EV - Exx - Exz*nz)/Exy
+        // What if Exy = 0? Then provided Eyz is non-zero we can write:
+        //    (Ezx) + (Ezy)ny + (Ezz - EV)nz = 0
+        //    ny = (Exz - (Ezz-EV)*nz)/Eyz
+        // What if Exy = 0 and Eyz = 0 but (Eyy - EV) is non-zero?
+        //    (Eyy - EV)ny + (Eyz)nz = 0
+        //    ny = -(Eyz*nz)/(Eyy-EV)
+
+        // In the pathological case where Exz = Eyz = Ezz = 0:
+        //    (Exx - EV)nx + (Exy)ny = 0  =>  ny/nx = -(Exx-EV)/Exy
+        //    (Eyx)nx + (Eyy - EV)ny = 0  =>  ny/nx = -Eyx/(Eyy-EV)
+        //    (EV)nz = 0
+        // so
+        //     -ny/nx = (EV-Exx)/Exy = Eyx/(EV-Eyy)
+        // But watch out for order! Recalculate eigenvalues for this pathological case.
+        //     (EV-Exx)(EV-Eyy) = Eyx*Exy
+        //     EV^2 - EV(Exx+Eyy) + Exx*Eyy - Eyx*Exy = 0
+        // 
+        // In another pathological case, Exz = Exy = 0:
+        //    (Exx - EV)nx = 0
+        //    (Eyy - EV)ny + (Eyz)nz = 0 => ny/nz = -(Eyz)/(Eyy-EV)
+        //    (Ezy)ny + (Ezz - EV)nz = 0 => ny/nz = -(Ezz-EV)/(Ezy)
+        // so we cannot set nx = 1. Instead, write:
+        //    -ny/nz = (Eyz)/(Eyy-EV) = (Ezz-EV)/(Ezy)
+        // Then
+        //    (Eyz)(Ezy) = (Eyy-EV)(Ezz-EV)
+        //    (Eyz)^2 = (Eyy)(Ezz) - (Eyy)(EV) - (Ezz)(EV) + (EV)^2
+        //    EV^2 - EV(Eyy+Ezz) + Eyy*Ezz - Eyz*Eyz = 0
+
+        // Handle pathological case
+        if (Exz == 0.0 && Eyz == 0.0) {
+        // Recompute eigenvectors.
+        EV[0] = 0.5*(Exx+Eyy) + 0.5*Math.sqrt((Exx+Eyy)*(Exx+Eyy) + 4.0*Exy*Exy);
+        EV[1] = 0.5*(Exx+Eyy) - 0.5*Math.sqrt((Exx+Eyy)*(Exx+Eyy) + 4.0*Exy*Exy);
+        EV[2] = 0.0;
+        for( int i = 0 ; i < 2 ; i++ ) {
+            double nx_over_ny = Exy / (Exx-EV[i]);
+            double nx_unnormalized = nx_over_ny;
+            double ny_unnormalized = 1.0;
+            double norm = Math.sqrt(nx_unnormalized*nx_unnormalized + ny_unnormalized*ny_unnormalized);
+            mm_PA[i][0] = ny_unnormalized/norm;
+            mm_PA[i][1] = nx_unnormalized/norm;
+            mm_PA[i][2] = 0.0;
+        }
+        // ... and now set third eigenvector to the z direction:
+        mm_PA[2][0] = 0.0;
+        mm_PA[2][1] = 0.0;
+        mm_PA[2][2] = 1.0;
+        } else if (Exz == 0.0 && Exy == 0.0) {
+        // Another pathological case
+        EV[0] = 0.5*(Eyy+Ezz) + 0.5*Math.sqrt((Eyy+Ezz)*(Eyy+Ezz) + 4.0*Eyz*Eyz);
+        EV[1] = 0.5*(Eyy+Ezz) - 0.5*Math.sqrt((Eyy+Ezz)*(Eyy+Ezz) + 4.0*Eyz*Eyz);
+        EV[2] = 0.0;
+        for( int i = 0 ; i < 2 ; i++ ) {
+            double ny_over_nz = Eyz / (Eyy-EV[i]);
+            double ny_unnormalized = ny_over_nz;
+            double nz_unnormalized = 1.0;
+            double norm = Math.sqrt(ny_unnormalized*ny_unnormalized + nz_unnormalized*nz_unnormalized);
+            mm_PA[i][0] = nz_unnormalized/norm;
+            mm_PA[i][1] = ny_unnormalized/norm;
+            mm_PA[i][2] = 0.0;
+        }
+        mm_PA[2][0] = 0.0;
+        mm_PA[2][1] = 0.0;
+        mm_PA[2][2] = 1.0;
+        } else {
+        for( int i = 0 ; i < 3 ; i++ )
+            {
+            double[] C = new double[3];
+            C[0] = 1.0;
+            C[2] = (Exy*Exy + (Eyy - EV[i])*(EV[i] - Exx))/
+                ((Eyy - EV[i])*Exz - Eyz*Exy);
+            C[1] = (EV[i] - Exx - Exz*C[2])/Exy;
+            if (Exy == 0.0) {
+                // Recompute
+                if (Eyz != 0.0) {
+                // ny = (Exz - (Ezz-EV)*nz)/Eyz
+                C[1] = (Exz - (Ezz-EV[i])*C[2])/Eyz;
+                } else {
+                // ny = -(Eyz*nz)/(Eyy-EV)
+                C[1] = -(Eyz*C[2])/(Eyy-EV[i]);
+                }
+            }
+            double norm = Math.sqrt(C[0]*C[0] + C[1]*C[1] + C[2]*C[2]);
+            mm_PA[i][0] = C[0]/norm;
+            mm_PA[i][1] = C[1]/norm;
+            mm_PA[i][2] = C[2]/norm;
+            }
+        }
         }
         mm_NE[0] = NE1;
         mm_NE[1] = NE2;
@@ -417,7 +417,7 @@
             double dr = Math.sqrt(  (position[0]+mm_PA[0][0])*(position[0]+mm_PA[0][0]) +
                     (position[1]+mm_PA[0][1])*(position[1]+mm_PA[0][1]) +
                     (position[2]+mm_PA[0][2])*(position[2]+mm_PA[0][2]) ) -
-                    Math.sqrt(	(position[0])*(position[0]) +
+                    Math.sqrt(  (position[0])*(position[0]) +
                     (position[1])*(position[1]) +
                     (position[2])*(position[2]) ) ;
             double sign = 1.;

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/jeremym/EvioFileScanner.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/jeremym/EvioFileScanner.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/jeremym/EvioFileScanner.java	Wed Apr 27 11:11:32 2016
@@ -28,7 +28,7 @@
 import org.apache.commons.cli.CommandLine;
 import org.apache.commons.cli.Options;
 import org.apache.commons.cli.ParseException;
-import org.apache.commons.cli.DefaultParser;
+import org.apache.commons.cli.PosixParser;
 import org.hps.conditions.database.ConnectionParameters;
 import org.hps.record.evio.EvioEventConstants;
 import org.hps.record.evio.EvioEventUtilities;
@@ -484,7 +484,7 @@
 
     final Set<Integer> acceptRuns = new HashSet<Integer>();
 
-    final DefaultParser parser = new DefaultParser();
+    final PosixParser parser = new PosixParser();
 
     boolean printSummary = false;
 

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/ClusterAnalysisDriver.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/ClusterAnalysisDriver.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/ClusterAnalysisDriver.java	Wed Apr 27 11:11:32 2016
@@ -11,84 +11,84 @@
 import org.lcsim.util.aida.AIDA;
 
 public class ClusterAnalysisDriver extends Driver {
-	// Analysis plots.
+    // Analysis plots.
     AIDA aida = AIDA.defaultInstance();
-	IHistogram1D clusterTotalEnergy;
-	IHistogram1D clusterSeedEnergy;
-	IHistogram1D clusterHitCount;
-	IHistogram2D clusterDistribution;
-	
-	IHistogram1D fClusterTotalEnergy;
-	IHistogram1D fClusterSeedEnergy;
-	IHistogram1D fClusterHitCount;
-	IHistogram2D fClusterDistribution;
-	
-	IHistogram1D nClusterTotalEnergy;
-	IHistogram1D nClusterSeedEnergy;
-	IHistogram1D nClusterHitCount;
-	IHistogram2D nClusterDistribution;
-	
-	// Hit collection names.
-	private String clusterCollectionName = "EcalClusters";
-	
-	public void setClusterCollectionName(String clusterCollectionName) {
-		this.clusterCollectionName = clusterCollectionName;
-	}
-	
-	@Override
-	public void startOfData() {
-		// Initialize the histograms.
-		clusterTotalEnergy = aida.histogram1D("Cluster Plot :: Cluster Total Energy", 110, 0.00, 2.2);
-		clusterSeedEnergy = aida.histogram1D("Cluster Plot :: Seed Hit Energy", 110, 0.00, 2.2);
-		clusterHitCount = aida.histogram1D("Cluster Plot :: Cluster Hit Count", 8, 1, 9);
-		clusterDistribution = aida.histogram2D("Cluster Plot :: Seed Hit Distribution", 46, -23, 23, 11, -5.5, 5.5);
-		
-		// Initialize the filtered histograms.
-		fClusterTotalEnergy = aida.histogram1D("Cluster Plot :: Cluster Total Energy (Over 100 MeV)", 110, 0.00, 2.2);
-		fClusterSeedEnergy = aida.histogram1D("Cluster Plot :: Seed Hit Energy (Over 100 MeV)", 110, 0.00, 2.2);
-		fClusterHitCount = aida.histogram1D("Cluster Plot :: Cluster Hit Count (Over 100 MeV)", 8, 1, 9);
-		fClusterDistribution = aida.histogram2D("Cluster Plot :: Seed Hit Distribution (Over 100 MeV)", 46, -23, 23, 11, -5.5, 5.5);
-		
-		// Initialize the more filtered histograms.
-		nClusterTotalEnergy = aida.histogram1D("Cluster Plot :: Cluster Total Energy (Over 100 MeV, > 1 Hit)", 110, 0.00, 2.2);
-		nClusterSeedEnergy = aida.histogram1D("Cluster Plot :: Seed Hit Energy (Over 100 MeV, > 1 Hit)", 110, 0.00, 2.2);
-		nClusterHitCount = aida.histogram1D("Cluster Plot :: Cluster Hit Count (Over 100 MeV, > 1 Hit)", 8, 1, 9);
-		nClusterDistribution = aida.histogram2D("Cluster Plot :: Seed Hit Distribution (Over 100 MeV, > 1 Hit)", 46, -23, 23, 11, -5.5, 5.5);
-	}
-	
-	public void process(EventHeader event) {
-		// Check if there exists a cluster collection.
-		if(event.hasCollection(Cluster.class, clusterCollectionName)) {
-			// Get the raw hit collection.
-			List<Cluster> clusterList = event.get(Cluster.class, clusterCollectionName);
-			
-			// Output the information on each hit to the histograms.
-			for(Cluster cluster : clusterList) {
-				// Get the x and y indices for the hits.
-				int ix = cluster.getCalorimeterHits().get(0).getIdentifierFieldValue("ix");
-				int iy = cluster.getCalorimeterHits().get(0).getIdentifierFieldValue("iy");
-				if(ix > 0) { ix = ix - 1; }
-				
-				// Write to the histograms.
-				clusterTotalEnergy.fill(cluster.getEnergy());
-				clusterSeedEnergy.fill(cluster.getCalorimeterHits().get(0).getCorrectedEnergy());
-				clusterHitCount.fill(cluster.getCalorimeterHits().size());
-				clusterDistribution.fill(ix, iy, 1.0);
-				
-				if(cluster.getCalorimeterHits().get(0).getCorrectedEnergy() > 0.100) {
-					fClusterTotalEnergy.fill(cluster.getEnergy());
-					fClusterSeedEnergy.fill(cluster.getCalorimeterHits().get(0).getCorrectedEnergy());
-					fClusterHitCount.fill(cluster.getCalorimeterHits().size());
-					fClusterDistribution.fill(ix, iy, 1.0);
-					
-					if(cluster.getCalorimeterHits().size() > 1) {
-						nClusterTotalEnergy.fill(cluster.getEnergy());
-						nClusterSeedEnergy.fill(cluster.getCalorimeterHits().get(0).getCorrectedEnergy());
-						nClusterHitCount.fill(cluster.getCalorimeterHits().size());
-						nClusterDistribution.fill(ix, iy, 1.0);
-					}
-				}
-			}
-		}
-	}
+    IHistogram1D clusterTotalEnergy;
+    IHistogram1D clusterSeedEnergy;
+    IHistogram1D clusterHitCount;
+    IHistogram2D clusterDistribution;
+    
+    IHistogram1D fClusterTotalEnergy;
+    IHistogram1D fClusterSeedEnergy;
+    IHistogram1D fClusterHitCount;
+    IHistogram2D fClusterDistribution;
+    
+    IHistogram1D nClusterTotalEnergy;
+    IHistogram1D nClusterSeedEnergy;
+    IHistogram1D nClusterHitCount;
+    IHistogram2D nClusterDistribution;
+    
+    // Hit collection names.
+    private String clusterCollectionName = "EcalClusters";
+    
+    public void setClusterCollectionName(String clusterCollectionName) {
+        this.clusterCollectionName = clusterCollectionName;
+    }
+    
+    @Override
+    public void startOfData() {
+        // Initialize the histograms.
+        clusterTotalEnergy = aida.histogram1D("Cluster Plot :: Cluster Total Energy", 110, 0.00, 2.2);
+        clusterSeedEnergy = aida.histogram1D("Cluster Plot :: Seed Hit Energy", 110, 0.00, 2.2);
+        clusterHitCount = aida.histogram1D("Cluster Plot :: Cluster Hit Count", 8, 1, 9);
+        clusterDistribution = aida.histogram2D("Cluster Plot :: Seed Hit Distribution", 46, -23, 23, 11, -5.5, 5.5);
+        
+        // Initialize the filtered histograms.
+        fClusterTotalEnergy = aida.histogram1D("Cluster Plot :: Cluster Total Energy (Over 100 MeV)", 110, 0.00, 2.2);
+        fClusterSeedEnergy = aida.histogram1D("Cluster Plot :: Seed Hit Energy (Over 100 MeV)", 110, 0.00, 2.2);
+        fClusterHitCount = aida.histogram1D("Cluster Plot :: Cluster Hit Count (Over 100 MeV)", 8, 1, 9);
+        fClusterDistribution = aida.histogram2D("Cluster Plot :: Seed Hit Distribution (Over 100 MeV)", 46, -23, 23, 11, -5.5, 5.5);
+        
+        // Initialize the more filtered histograms.
+        nClusterTotalEnergy = aida.histogram1D("Cluster Plot :: Cluster Total Energy (Over 100 MeV, > 1 Hit)", 110, 0.00, 2.2);
+        nClusterSeedEnergy = aida.histogram1D("Cluster Plot :: Seed Hit Energy (Over 100 MeV, > 1 Hit)", 110, 0.00, 2.2);
+        nClusterHitCount = aida.histogram1D("Cluster Plot :: Cluster Hit Count (Over 100 MeV, > 1 Hit)", 8, 1, 9);
+        nClusterDistribution = aida.histogram2D("Cluster Plot :: Seed Hit Distribution (Over 100 MeV, > 1 Hit)", 46, -23, 23, 11, -5.5, 5.5);
+    }
+    
+    public void process(EventHeader event) {
+        // Check if there exists a cluster collection.
+        if(event.hasCollection(Cluster.class, clusterCollectionName)) {
+            // Get the raw hit collection.
+            List<Cluster> clusterList = event.get(Cluster.class, clusterCollectionName);
+            
+            // Output the information on each hit to the histograms.
+            for(Cluster cluster : clusterList) {
+                // Get the x and y indices for the hits.
+                int ix = cluster.getCalorimeterHits().get(0).getIdentifierFieldValue("ix");
+                int iy = cluster.getCalorimeterHits().get(0).getIdentifierFieldValue("iy");
+                if(ix > 0) { ix = ix - 1; }
+                
+                // Write to the histograms.
+                clusterTotalEnergy.fill(cluster.getEnergy());
+                clusterSeedEnergy.fill(cluster.getCalorimeterHits().get(0).getCorrectedEnergy());
+                clusterHitCount.fill(cluster.getCalorimeterHits().size());
+                clusterDistribution.fill(ix, iy, 1.0);
+                
+                if(cluster.getCalorimeterHits().get(0).getCorrectedEnergy() > 0.100) {
+                    fClusterTotalEnergy.fill(cluster.getEnergy());
+                    fClusterSeedEnergy.fill(cluster.getCalorimeterHits().get(0).getCorrectedEnergy());
+                    fClusterHitCount.fill(cluster.getCalorimeterHits().size());
+                    fClusterDistribution.fill(ix, iy, 1.0);
+                    
+                    if(cluster.getCalorimeterHits().size() > 1) {
+                        nClusterTotalEnergy.fill(cluster.getEnergy());
+                        nClusterSeedEnergy.fill(cluster.getCalorimeterHits().get(0).getCorrectedEnergy());
+                        nClusterHitCount.fill(cluster.getCalorimeterHits().size());
+                        nClusterDistribution.fill(ix, iy, 1.0);
+                    }
+                }
+            }
+        }
+    }
 }

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/CountTriggersDriver.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/CountTriggersDriver.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/CountTriggersDriver.java	Wed Apr 27 11:11:32 2016
@@ -16,64 +16,64 @@
  * @author Kyle McCarty <[log in to unmask]>
  */
 public class CountTriggersDriver extends Driver {
-	// Store programmable parameters.
-	private String bankCollectionName = "TriggerBank";
-	
-	// Track the number of triggers seen for each trigger type.
-	private int[] triggers = new int[6];
-	private static final int PULSER   = 0;
-	private static final int SINGLES0 = 1;
-	private static final int SINGLES1 = 2;
-	private static final int PAIR0    = 3;
-	private static final int PAIR1    = 4;
-	private static final int COSMIC   = 5;
-	
-	/**
-	 * Outputs the total number of triggers seen for each trigger type.
-	 */
-	@Override
-	public void endOfData() {
-		System.out.println("Trigger Counts:");
-		System.out.printf("Singles 0 :: %d%n", triggers[SINGLES0]);
-		System.out.printf("Singles 1 :: %d%n", triggers[SINGLES1]);
-		System.out.printf("Pair 0    :: %d%n", triggers[PAIR0]);
-		System.out.printf("Pair 1    :: %d%n", triggers[PAIR1]);
-		System.out.printf("Pulser    :: %d%n", triggers[PULSER]);
-		System.out.printf("Cosmic    :: %d%n", triggers[COSMIC]);
-	}
-	
-	/**
-	 * Checks whether a trigger of each given type was seen by the TI
-	 * for each event and increments the total trigger count for that
-	 * type as appropriate.
-	 */
-	@Override
-	public void process(EventHeader event) {
-		// Extract the TI bank from the data stream.
-		TIData tiBank = null;
-		if(event.hasCollection(GenericObject.class, bankCollectionName)) {
-			// Get the bank list.
-			List<GenericObject> bankList = event.get(GenericObject.class, bankCollectionName);
-			
-			// Search through the banks and get the TI bank.
-			for(GenericObject obj : bankList) {
-				if(AbstractIntData.getTag(obj) == TIData.BANK_TAG) {
-					tiBank = new TIData(obj);
-				}
-			}
-		}
-		
-		// If there is no TI bank, the event can not be processed.
-		if(tiBank == null) {
-			return;
-		}
-		
-		// Otherwise, increment the relevant trigger counts.
-		if(tiBank.isPulserTrigger()) { triggers[PULSER]++; }
-		if(tiBank.isSingle0Trigger()) { triggers[SINGLES0]++; }
-		if(tiBank.isSingle1Trigger()) { triggers[SINGLES1]++; }
-		if(tiBank.isPair0Trigger()) { triggers[PAIR0]++; }
-		if(tiBank.isPair1Trigger()) { triggers[PAIR1]++; }
-		if(tiBank.isCalibTrigger()) { triggers[COSMIC]++; }
-	}
+    // Store programmable parameters.
+    private String bankCollectionName = "TriggerBank";
+    
+    // Track the number of triggers seen for each trigger type.
+    private int[] triggers = new int[6];
+    private static final int PULSER   = 0;
+    private static final int SINGLES0 = 1;
+    private static final int SINGLES1 = 2;
+    private static final int PAIR0    = 3;
+    private static final int PAIR1    = 4;
+    private static final int COSMIC   = 5;
+    
+    /**
+     * Outputs the total number of triggers seen for each trigger type.
+     */
+    @Override
+    public void endOfData() {
+        System.out.println("Trigger Counts:");
+        System.out.printf("Singles 0 :: %d%n", triggers[SINGLES0]);
+        System.out.printf("Singles 1 :: %d%n", triggers[SINGLES1]);
+        System.out.printf("Pair 0    :: %d%n", triggers[PAIR0]);
+        System.out.printf("Pair 1    :: %d%n", triggers[PAIR1]);
+        System.out.printf("Pulser    :: %d%n", triggers[PULSER]);
+        System.out.printf("Cosmic    :: %d%n", triggers[COSMIC]);
+    }
+    
+    /**
+     * Checks whether a trigger of each given type was seen by the TI
+     * for each event and increments the total trigger count for that
+     * type as appropriate.
+     */
+    @Override
+    public void process(EventHeader event) {
+        // Extract the TI bank from the data stream.
+        TIData tiBank = null;
+        if(event.hasCollection(GenericObject.class, bankCollectionName)) {
+            // Get the bank list.
+            List<GenericObject> bankList = event.get(GenericObject.class, bankCollectionName);
+            
+            // Search through the banks and get the TI bank.
+            for(GenericObject obj : bankList) {
+                if(AbstractIntData.getTag(obj) == TIData.BANK_TAG) {
+                    tiBank = new TIData(obj);
+                }
+            }
+        }
+        
+        // If there is no TI bank, the event can not be processed.
+        if(tiBank == null) {
+            return;
+        }
+        
+        // Otherwise, increment the relevant trigger counts.
+        if(tiBank.isPulserTrigger()) { triggers[PULSER]++; }
+        if(tiBank.isSingle0Trigger()) { triggers[SINGLES0]++; }
+        if(tiBank.isSingle1Trigger()) { triggers[SINGLES1]++; }
+        if(tiBank.isPair0Trigger()) { triggers[PAIR0]++; }
+        if(tiBank.isPair1Trigger()) { triggers[PAIR1]++; }
+        if(tiBank.isCalibTrigger()) { triggers[COSMIC]++; }
+    }
 }

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/EvioAnalysis.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/EvioAnalysis.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/EvioAnalysis.java	Wed Apr 27 11:11:32 2016
@@ -17,17 +17,17 @@
 import org.lcsim.util.aida.AIDA;
 
 public class EvioAnalysis extends Driver {
-	// Store index reference variables.
+    // Store index reference variables.
         private static final int RECON     = 0;
         private static final int SSP       = 1;
-	
-	// Create histogram arrays for cut distributions.
+    
+    // Create histogram arrays for cut distributions.
         private AIDA aida = AIDA.defaultInstance();
         private IHistogram1D[] clusterEnergyPlot = new IHistogram1D[2];
         private IHistogram1D[] clusterHitCountPlot = new IHistogram1D[2];
         private IHistogram1D[] clusterTimePlot = new IHistogram1D[2];
-	private IHistogram2D[] clusterSlopePlot = new IHistogram2D[2];
-	
+    private IHistogram2D[] clusterSlopePlot = new IHistogram2D[2];
+    
         private IHistogram1D[] pairClusterEnergyPlot = new IHistogram1D[2];
         private IHistogram1D[] pairHitCountPlot = new IHistogram1D[2];
         private IHistogram1D[] pairTimePlot = new IHistogram1D[2];
@@ -38,129 +38,129 @@
         private IHistogram1D[] pairCoplanarityPlot = new IHistogram1D[2];
         private IHistogram1D[] pairTriggerTimePlot = new IHistogram1D[2];
 
-	// Store programmable values.
-	private String clusterCollectionName = "EcalClusters";
-	private String bankCollectionName = "SSPData";
-	private double energySlopeParamF = 0.0055;
-	private double beamEnergy = 1.1;
-	
-	@Override
-	public void startOfData() {
-		// Store the plot source type name.
-		String[] plotType = new String[2];
-		plotType[RECON] = " (Recon)";
-		plotType[SSP] = " (SSP)";
-		
-		// Set the bin sizes based on the beam energy.
-		int bins = (int) beamEnergy * 100;
-		
-		for(int i = 0; i < 2; i++) {
-			// Instantiate the single cluster distribution plots.
-			clusterEnergyPlot[i] = aida.histogram1D("Raw/Cluster Energy" + plotType[i], bins, 0.0, beamEnergy);
-			clusterHitCountPlot[i] = aida.histogram1D("Raw/Cluster Hit Count" + plotType[i], 9, 0.5, 9.5);
-			clusterTimePlot[i] = aida.histogram1D("Raw/Cluster Time" + plotType[i], 100, 0, 400);
-			clusterSlopePlot[i] = aida.histogram2D("Raw/Cluster Energy Slope" + plotType[i], 300, 0.0, 3.0, 200, 0, 400);
-			
-			// Instantiate the cluster pair distribution plots.
-			pairSumPlot[i] = aida.histogram1D("Raw/Pair Energy Sum" + plotType[i], (int) 1.5 * bins, 0.0, 1.5 * beamEnergy);
-			pairSumEnergiesPlot[i] = aida.histogram2D("Raw/Pair 2D Energy Sum" + plotType[i], (int) 1.5 * bins, 0.0, 1.5 * beamEnergy, (int) 1.5 * bins, 0.0, 1.5 * beamEnergy);
-			pairDiffPlot[i] = aida.histogram1D("Raw/Pair Energy Difference" + plotType[i], bins, 0.0, beamEnergy);
-			pairSlopePlot[i] = aida.histogram1D("Raw/Pair Energy Slope" + plotType[i], 100, 0.0, 4.0);
-			pairCoplanarityPlot[i] = aida.histogram1D("Raw/Pair Coplanarity" + plotType[i], 180, 0.0, 180);
-		}
-	}
-	
-	@Override
-	public void process(EventHeader event) {
-		// Skip the event if there are no clusters.
-		if(!event.hasCollection(Cluster.class, clusterCollectionName) || !event.hasCollection(GenericObject.class, bankCollectionName)) {
-			return;
-		}
-		
-		// Get the list of clusters.
-		List<Cluster> clusters = event.get(Cluster.class, clusterCollectionName);
-		
-		// Get the SSP data bank.
-		List<GenericObject> bankList = event.get(GenericObject.class, bankCollectionName);
-		
-		// Get the SSP bank from the generic object bank list.
-		SSPData sspBank = null;
-		for(GenericObject obj : bankList) {
-			if(AbstractIntData.getTag(obj) == SSPData.BANK_TAG) {
-				sspBank = new SSPData(obj);
-			}
-		}
-		
-		// Make sure that the SSP bank was initialized.
-		if(sspBank == null) {
-			return;
-		}
-		
-		// Iterate over the reconstructed clusters and populate
-		// the singles plots.
-		for(Cluster cluster : clusters) {
-			// Get the cluster properties.
-			int hitCount = cluster.getCalorimeterHits().size();
-			double x = TriggerModule.getClusterX(cluster);
-			double z = TriggerModule.getClusterZ(cluster);
-			double slopeParamR = Math.sqrt((x * x) + (z * z));
-			
-			// Populate the plots.
-			clusterEnergyPlot[RECON].fill(cluster.getEnergy());
-			clusterHitCountPlot[RECON].fill(cluster.getCalorimeterHits().size());
-			clusterTimePlot[RECON].fill(cluster.getCalorimeterHits().get(0).getTime());
-			clusterSlopePlot[RECON].fill(cluster.getEnergy(), slopeParamR);
-		}
-		
-		// Get the list of pairs.
-		List<Cluster[]> pairs = makePairs(clusters);
-		
-		// Iterate over the pairs and populate the pair plots.
-		for(Cluster[] pair : pairs) {
-			pairSumPlot[RECON].fill(TriggerModule.getValueEnergySum(pair));
-			pairSumEnergiesPlot[RECON].fill(pair[0].getEnergy(), pair[1].getEnergy());
-			pairDiffPlot[RECON].fill(TriggerModule.getValueEnergyDifference(pair));
-			pairSlopePlot[RECON].fill(TriggerModule.getValueEnergySlope(pair, energySlopeParamF));
-			pairCoplanarityPlot[RECON].fill(TriggerModule.getValueCoplanarity(pair));
-		}
-	}
-	
-	private List<Cluster[]> makePairs(List<Cluster> clusters) {
-		// Create seperate lists for top and bottom clusters.
-		List<Cluster> topList = new ArrayList<Cluster>();
-		List<Cluster> bottomList = new ArrayList<Cluster>();
-		List<Cluster[]> pairList = new ArrayList<Cluster[]>();
-		
-		// Sort the clusters into the appropriate list.
-		for(Cluster cluster : clusters) {
-			if(cluster.getCalorimeterHits().get(0).getIdentifierFieldValue("iy") > 0) {
-				topList.add(cluster);
-			} else {
-				bottomList.add(cluster);
-			}
-		}
-		
-		// Create all possible cluster pairs.
-		for(Cluster topCluster : topList) {
-			for(Cluster bottomCluster : bottomList) {
-				Cluster[] pair = { topCluster, bottomCluster };
-				pairList.add(pair);
-			}
-		}
-		
-		// Return the list of cluster pairs.
-		return pairList;
-	}
-	
-	public void setClusterCollectionName(String clusterCollectionName) {
-		this.clusterCollectionName = clusterCollectionName;
-	}
-	
-	public void setBankCollectionName(String bankCollectionName) {
-		this.bankCollectionName = bankCollectionName;
-	}
-	
-	public void setEnergySlopeParamF(double energySlopeParamF) {
-		this.energySlopeParamF = energySlopeParamF;
-	}
+    // Store programmable values.
+    private String clusterCollectionName = "EcalClusters";
+    private String bankCollectionName = "SSPData";
+    private double energySlopeParamF = 0.0055;
+    private double beamEnergy = 1.1;
+    
+    @Override
+    public void startOfData() {
+        // Store the plot source type name.
+        String[] plotType = new String[2];
+        plotType[RECON] = " (Recon)";
+        plotType[SSP] = " (SSP)";
+        
+        // Set the bin sizes based on the beam energy.
+        int bins = (int) beamEnergy * 100;
+        
+        for(int i = 0; i < 2; i++) {
+            // Instantiate the single cluster distribution plots.
+            clusterEnergyPlot[i] = aida.histogram1D("Raw/Cluster Energy" + plotType[i], bins, 0.0, beamEnergy);
+            clusterHitCountPlot[i] = aida.histogram1D("Raw/Cluster Hit Count" + plotType[i], 9, 0.5, 9.5);
+            clusterTimePlot[i] = aida.histogram1D("Raw/Cluster Time" + plotType[i], 100, 0, 400);
+            clusterSlopePlot[i] = aida.histogram2D("Raw/Cluster Energy Slope" + plotType[i], 300, 0.0, 3.0, 200, 0, 400);
+            
+            // Instantiate the cluster pair distribution plots.
+            pairSumPlot[i] = aida.histogram1D("Raw/Pair Energy Sum" + plotType[i], (int) 1.5 * bins, 0.0, 1.5 * beamEnergy);
+            pairSumEnergiesPlot[i] = aida.histogram2D("Raw/Pair 2D Energy Sum" + plotType[i], (int) 1.5 * bins, 0.0, 1.5 * beamEnergy, (int) 1.5 * bins, 0.0, 1.5 * beamEnergy);
+            pairDiffPlot[i] = aida.histogram1D("Raw/Pair Energy Difference" + plotType[i], bins, 0.0, beamEnergy);
+            pairSlopePlot[i] = aida.histogram1D("Raw/Pair Energy Slope" + plotType[i], 100, 0.0, 4.0);
+            pairCoplanarityPlot[i] = aida.histogram1D("Raw/Pair Coplanarity" + plotType[i], 180, 0.0, 180);
+        }
+    }
+    
+    @Override
+    public void process(EventHeader event) {
+        // Skip the event if there are no clusters.
+        if(!event.hasCollection(Cluster.class, clusterCollectionName) || !event.hasCollection(GenericObject.class, bankCollectionName)) {
+            return;
+        }
+        
+        // Get the list of clusters.
+        List<Cluster> clusters = event.get(Cluster.class, clusterCollectionName);
+        
+        // Get the SSP data bank.
+        List<GenericObject> bankList = event.get(GenericObject.class, bankCollectionName);
+        
+        // Get the SSP bank from the generic object bank list.
+        SSPData sspBank = null;
+        for(GenericObject obj : bankList) {
+            if(AbstractIntData.getTag(obj) == SSPData.BANK_TAG) {
+                sspBank = new SSPData(obj);
+            }
+        }
+        
+        // Make sure that the SSP bank was initialized.
+        if(sspBank == null) {
+            return;
+        }
+        
+        // Iterate over the reconstructed clusters and populate
+        // the singles plots.
+        for(Cluster cluster : clusters) {
+            // Get the cluster properties.
+            int hitCount = cluster.getCalorimeterHits().size();
+            double x = TriggerModule.getClusterX(cluster);
+            double z = TriggerModule.getClusterZ(cluster);
+            double slopeParamR = Math.sqrt((x * x) + (z * z));
+            
+            // Populate the plots.
+            clusterEnergyPlot[RECON].fill(cluster.getEnergy());
+            clusterHitCountPlot[RECON].fill(cluster.getCalorimeterHits().size());
+            clusterTimePlot[RECON].fill(cluster.getCalorimeterHits().get(0).getTime());
+            clusterSlopePlot[RECON].fill(cluster.getEnergy(), slopeParamR);
+        }
+        
+        // Get the list of pairs.
+        List<Cluster[]> pairs = makePairs(clusters);
+        
+        // Iterate over the pairs and populate the pair plots.
+        for(Cluster[] pair : pairs) {
+            pairSumPlot[RECON].fill(TriggerModule.getValueEnergySum(pair));
+            pairSumEnergiesPlot[RECON].fill(pair[0].getEnergy(), pair[1].getEnergy());
+            pairDiffPlot[RECON].fill(TriggerModule.getValueEnergyDifference(pair));
+            pairSlopePlot[RECON].fill(TriggerModule.getValueEnergySlope(pair, energySlopeParamF));
+            pairCoplanarityPlot[RECON].fill(TriggerModule.getValueCoplanarity(pair));
+        }
+    }
+    
+    private List<Cluster[]> makePairs(List<Cluster> clusters) {
+        // Create seperate lists for top and bottom clusters.
+        List<Cluster> topList = new ArrayList<Cluster>();
+        List<Cluster> bottomList = new ArrayList<Cluster>();
+        List<Cluster[]> pairList = new ArrayList<Cluster[]>();
+        
+        // Sort the clusters into the appropriate list.
+        for(Cluster cluster : clusters) {
+            if(cluster.getCalorimeterHits().get(0).getIdentifierFieldValue("iy") > 0) {
+                topList.add(cluster);
+            } else {
+                bottomList.add(cluster);
+            }
+        }
+        
+        // Create all possible cluster pairs.
+        for(Cluster topCluster : topList) {
+            for(Cluster bottomCluster : bottomList) {
+                Cluster[] pair = { topCluster, bottomCluster };
+                pairList.add(pair);
+            }
+        }
+        
+        // Return the list of cluster pairs.
+        return pairList;
+    }
+    
+    public void setClusterCollectionName(String clusterCollectionName) {
+        this.clusterCollectionName = clusterCollectionName;
+    }
+    
+    public void setBankCollectionName(String bankCollectionName) {
+        this.bankCollectionName = bankCollectionName;
+    }
+    
+    public void setEnergySlopeParamF(double energySlopeParamF) {
+        this.energySlopeParamF = energySlopeParamF;
+    }
 }

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/FADCAnalysisDriver.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/FADCAnalysisDriver.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/FADCAnalysisDriver.java	Wed Apr 27 11:11:32 2016
@@ -11,82 +11,82 @@
 import org.lcsim.util.aida.AIDA;
 
 public class FADCAnalysisDriver extends Driver {
-	// Analysis plots.
+    // Analysis plots.
     AIDA aida = AIDA.defaultInstance();
-	IHistogram1D rawHitEnergy;
-	IHistogram1D fadcHitEnergy;
-	IHistogram2D rawHitDistribution;
-	IHistogram2D fadcHitDistribution;
-	IHistogram2D fadcFilteredHitDistribution;
-	IHistogram1D eventRawHitCount;
-	IHistogram1D eventFADCHitCount;
-	
-	// Hit collection names.
-	private String rawHitsCollectionName = "EcalHits";
-	private String fadcHitsCollectionName = "EcalCorrectedHits";
-	
-	public void setFadcHitsCollectionName(String fadcHitsCollectionName) {
-		this.fadcHitsCollectionName = fadcHitsCollectionName;
-	}
-	
-	public void setRawHitsCollectionName(String rawHitsCollectionName) {
-		this.rawHitsCollectionName = rawHitsCollectionName;
-	}
-	
-	@Override
-	public void startOfData() {
-		// Initialize the histograms.
-		rawHitEnergy = aida.histogram1D("FADC Plot :: Raw Hit Energy", 110, 0.00, 2.2);
-		fadcHitEnergy = aida.histogram1D("FADC Plot :: FADC Hit Energy", 80, 0.00, 1.6);
-		rawHitDistribution = aida.histogram2D("FADC Plot :: Raw Hit Distribution", 46, -23, 23, 11, -5.5, 5.5);
-		fadcHitDistribution = aida.histogram2D("FADC Plot :: FADC Hit Distribution", 46, -23, 23, 11, -5.5, 5.5);
-		fadcFilteredHitDistribution = aida.histogram2D("FADC Plot :: FADC Hit Distribution Over 100 MeV", 46, -23, 23, 11, -5.5, 5.5);
-		eventRawHitCount = aida.histogram1D("FADC Plot :: Event Raw Hit Count", 159, 1, 160);
-		eventFADCHitCount = aida.histogram1D("FADC Plot :: Event FADC Hit Count", 15, 1, 16);
-	}
-	
-	public void process(EventHeader event) {
-		// Check if there exists a raw hits collection.
-		if(event.hasCollection(CalorimeterHit.class, rawHitsCollectionName)) {
-			// Get the raw hit collection.
-			List<CalorimeterHit> hitList = event.get(CalorimeterHit.class, rawHitsCollectionName);
-			
-			// Output the information on each hit to the histograms.
-			for(CalorimeterHit hit : hitList) {
-				// Get the x and y indices for the hits.
-				int ix = hit.getIdentifierFieldValue("ix");
-				int iy = hit.getIdentifierFieldValue("iy");
-				if(ix > 0) { ix = ix - 1; }
-				
-				// Write to the histograms.
-				rawHitEnergy.fill(hit.getCorrectedEnergy());
-				rawHitDistribution.fill(ix, iy, 1.0);
-				
-				// If there are hits, fill the hit count histogram.
-				if(hitList.size() != 0) { eventRawHitCount.fill(hitList.size()); }
-			}
-		}
-		
-		// Check if there exists an FADC hits collection.
-		if(event.hasCollection(CalorimeterHit.class, fadcHitsCollectionName)) {
-			// Get the raw hit collection.
-			List<CalorimeterHit> hitList = event.get(CalorimeterHit.class, fadcHitsCollectionName);
-			
-			// Output the information on each hit to the histograms.
-			for(CalorimeterHit hit : hitList) {
-				// Get the x and y indices for the hits.
-				int ix = hit.getIdentifierFieldValue("ix");
-				int iy = hit.getIdentifierFieldValue("iy");
-				if(ix > 0) { ix = ix - 1; }
-				
-				// Write to the histograms.
-				fadcHitEnergy.fill(hit.getCorrectedEnergy());
-				fadcHitDistribution.fill(ix, iy, 1.0);
-				if(hit.getCorrectedEnergy() > 0.100) { fadcFilteredHitDistribution.fill(ix, iy, 1.0); }
-				
-				// If there are hits, fill the hit count histogram.
-				if(hitList.size() != 0) { eventFADCHitCount.fill(hitList.size()); }
-			}
-		}
-	}
+    IHistogram1D rawHitEnergy;
+    IHistogram1D fadcHitEnergy;
+    IHistogram2D rawHitDistribution;
+    IHistogram2D fadcHitDistribution;
+    IHistogram2D fadcFilteredHitDistribution;
+    IHistogram1D eventRawHitCount;
+    IHistogram1D eventFADCHitCount;
+    
+    // Hit collection names.
+    private String rawHitsCollectionName = "EcalHits";
+    private String fadcHitsCollectionName = "EcalCorrectedHits";
+    
+    public void setFadcHitsCollectionName(String fadcHitsCollectionName) {
+        this.fadcHitsCollectionName = fadcHitsCollectionName;
+    }
+    
+    public void setRawHitsCollectionName(String rawHitsCollectionName) {
+        this.rawHitsCollectionName = rawHitsCollectionName;
+    }
+    
+    @Override
+    public void startOfData() {
+        // Initialize the histograms.
+        rawHitEnergy = aida.histogram1D("FADC Plot :: Raw Hit Energy", 110, 0.00, 2.2);
+        fadcHitEnergy = aida.histogram1D("FADC Plot :: FADC Hit Energy", 80, 0.00, 1.6);
+        rawHitDistribution = aida.histogram2D("FADC Plot :: Raw Hit Distribution", 46, -23, 23, 11, -5.5, 5.5);
+        fadcHitDistribution = aida.histogram2D("FADC Plot :: FADC Hit Distribution", 46, -23, 23, 11, -5.5, 5.5);
+        fadcFilteredHitDistribution = aida.histogram2D("FADC Plot :: FADC Hit Distribution Over 100 MeV", 46, -23, 23, 11, -5.5, 5.5);
+        eventRawHitCount = aida.histogram1D("FADC Plot :: Event Raw Hit Count", 159, 1, 160);
+        eventFADCHitCount = aida.histogram1D("FADC Plot :: Event FADC Hit Count", 15, 1, 16);
+    }
+    
+    public void process(EventHeader event) {
+        // Check if there exists a raw hits collection.
+        if(event.hasCollection(CalorimeterHit.class, rawHitsCollectionName)) {
+            // Get the raw hit collection.
+            List<CalorimeterHit> hitList = event.get(CalorimeterHit.class, rawHitsCollectionName);
+            
+            // Output the information on each hit to the histograms.
+            for(CalorimeterHit hit : hitList) {
+                // Get the x and y indices for the hits.
+                int ix = hit.getIdentifierFieldValue("ix");
+                int iy = hit.getIdentifierFieldValue("iy");
+                if(ix > 0) { ix = ix - 1; }
+                
+                // Write to the histograms.
+                rawHitEnergy.fill(hit.getCorrectedEnergy());
+                rawHitDistribution.fill(ix, iy, 1.0);
+                
+                // If there are hits, fill the hit count histogram.
+                if(hitList.size() != 0) { eventRawHitCount.fill(hitList.size()); }
+            }
+        }
+        
+        // Check if there exists an FADC hits collection.
+        if(event.hasCollection(CalorimeterHit.class, fadcHitsCollectionName)) {
+            // Get the raw hit collection.
+            List<CalorimeterHit> hitList = event.get(CalorimeterHit.class, fadcHitsCollectionName);
+            
+            // Output the information on each hit to the histograms.
+            for(CalorimeterHit hit : hitList) {
+                // Get the x and y indices for the hits.
+                int ix = hit.getIdentifierFieldValue("ix");
+                int iy = hit.getIdentifierFieldValue("iy");
+                if(ix > 0) { ix = ix - 1; }
+                
+                // Write to the histograms.
+                fadcHitEnergy.fill(hit.getCorrectedEnergy());
+                fadcHitDistribution.fill(ix, iy, 1.0);
+                if(hit.getCorrectedEnergy() > 0.100) { fadcFilteredHitDistribution.fill(ix, iy, 1.0); }
+                
+                // If there are hits, fill the hit count histogram.
+                if(hitList.size() != 0) { eventFADCHitCount.fill(hitList.size()); }
+            }
+        }
+    }
 }

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/HPSEcalDataPlotsDriver.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/HPSEcalDataPlotsDriver.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/HPSEcalDataPlotsDriver.java	Wed Apr 27 11:11:32 2016
@@ -27,22 +27,22 @@
  * @author Kyle McCarty <[log in to unmask]>
  */
 public class HPSEcalDataPlotsDriver extends Driver {
-	private String plotsGroupName= "Data Plots";
-	private String bankCollectionName = "TriggerBank";
-	private String clusterCollectionName = "EcalClusters";
-	
-	private static final int PULSER   = 0;
-	private static final int SINGLES0 = 1;
-	private static final int SINGLES1 = 2;
-	private static final int PAIR0    = 3;
-	private static final int PAIR1    = 4;
-	
-	private static final int ALL       = 0;
-	private static final int EDGE      = 1;
-	private static final int FIDUCIAL = 2;
-	
-	private AIDA aida = AIDA.defaultInstance();
-	private IHistogram1D[][] clusterTotalEnergy = new IHistogram1D[5][3];
+    private String plotsGroupName= "Data Plots";
+    private String bankCollectionName = "TriggerBank";
+    private String clusterCollectionName = "EcalClusters";
+    
+    private static final int PULSER   = 0;
+    private static final int SINGLES0 = 1;
+    private static final int SINGLES1 = 2;
+    private static final int PAIR0    = 3;
+    private static final int PAIR1    = 4;
+    
+    private static final int ALL       = 0;
+    private static final int EDGE      = 1;
+    private static final int FIDUCIAL = 2;
+    
+    private AIDA aida = AIDA.defaultInstance();
+    private IHistogram1D[][] clusterTotalEnergy = new IHistogram1D[5][3];
     private IHistogram1D[][] clusterTime = new IHistogram1D[5][3];
     private IHistogram1D[][] clusterHitCount = new IHistogram1D[5][3];
     private IHistogram1D[][] clusterSeedEnergy = new IHistogram1D[5][3];
@@ -56,249 +56,249 @@
     private IHistogram2D[][] clusterSeedPosition = new IHistogram2D[5][3];
     private IHistogram2D[][] pairEnergySlope2D = new IHistogram2D[5][3];
     private IHistogram2D[][] pairCoplanarityEnergySum = new IHistogram2D[5][3];
-	
+    
     /**
      * Initializes the plots.
      */
-	@Override
-	public void startOfData() {
-		// Define trigger names.
-		String[] triggerNames = {
-			"Pulser", "Singles 0", "Singles 1", "Pair 0", "Pair 1"	
-		};
-		
-		// Define the positional names.
-		String[] positionNames = {
-				"All", "Edge", "Fiducial"
-		};
-		
-		// Instantiate the plots.
-		for(int i = 0; i < 5; i++) {
-			for(int j = 0; j < 3; j++) {
-				clusterTotalEnergy[i][j] = aida.histogram1D(plotsGroupName + "/" + triggerNames[i] + "/"
-						+ positionNames[j] + "/Cluster Total Energy", 150, 0.000, 1.500);
+    @Override
+    public void startOfData() {
+        // Define trigger names.
+        String[] triggerNames = {
+            "Pulser", "Singles 0", "Singles 1", "Pair 0", "Pair 1"  
+        };
+        
+        // Define the positional names.
+        String[] positionNames = {
+                "All", "Edge", "Fiducial"
+        };
+        
+        // Instantiate the plots.
+        for(int i = 0; i < 5; i++) {
+            for(int j = 0; j < 3; j++) {
+                clusterTotalEnergy[i][j] = aida.histogram1D(plotsGroupName + "/" + triggerNames[i] + "/"
+                        + positionNames[j] + "/Cluster Total Energy", 150, 0.000, 1.500);
                 clusterTime[i][j] = aida.histogram1D(plotsGroupName + "/" + triggerNames[i] + "/"
-						+ positionNames[j] + "/Cluster Hit Time", 100, 0.0, 100.0);
+                        + positionNames[j] + "/Cluster Hit Time", 100, 0.0, 100.0);
                 clusterHitCount[i][j] = aida.histogram1D(plotsGroupName + "/" + triggerNames[i] + "/"
-						+ positionNames[j] + "/Cluster Hit Count", 10, -0.5, 9.5);
+                        + positionNames[j] + "/Cluster Hit Count", 10, -0.5, 9.5);
                 clusterSeedEnergy[i][j] = aida.histogram1D(plotsGroupName + "/" + triggerNames[i] + "/"
-						+ positionNames[j] + "/Cluster Seed Energy", 150, 0.000, 1.500);
+                        + positionNames[j] + "/Cluster Seed Energy", 150, 0.000, 1.500);
                 pairEnergySum[i][j] = aida.histogram1D(plotsGroupName + "/" + triggerNames[i] + "/"
-						+ positionNames[j] + "/Pair Energy Sum", 150, 0.000, 1.500);
+                        + positionNames[j] + "/Pair Energy Sum", 150, 0.000, 1.500);
                 pairEnergyDifference[i][j] = aida.histogram1D(plotsGroupName + "/" + triggerNames[i] + "/"
-						+ positionNames[j] + "/Pair Energy Difference", 150, 0.000, 1.500);
+                        + positionNames[j] + "/Pair Energy Difference", 150, 0.000, 1.500);
                 pairEnergySlope[i][j] = aida.histogram1D(plotsGroupName + "/" + triggerNames[i] + "/"
-						+ positionNames[j] + "/Pair Energy Slope", 100, 0.000, 4.000);
+                        + positionNames[j] + "/Pair Energy Slope", 100, 0.000, 4.000);
                 pairCoplanarity[i][j] = aida.histogram1D(plotsGroupName + "/" + triggerNames[i] + "/"
-						+ positionNames[j] + "/Pair Coplanarity", 180, 0.000, 180);
+                        + positionNames[j] + "/Pair Coplanarity", 180, 0.000, 180);
                 pairTimeCoincidence[i][j] = aida.histogram1D(plotsGroupName + "/" + triggerNames[i] + "/"
-						+ positionNames[j] + "/Pair Time Coincidence", 80, 0, 20);
+                        + positionNames[j] + "/Pair Time Coincidence", 80, 0, 20);
                 
                 clusterSeedPosition[i][j] = aida.histogram2D(plotsGroupName + "/" + triggerNames[i] + "/"
-                		+ positionNames[j] + "/Cluster Seed Position", 46, -23, 23, 11, -5.5, 5.5);
+                        + positionNames[j] + "/Cluster Seed Position", 46, -23, 23, 11, -5.5, 5.5);
                 pairEnergySum2D[i][j] = aida.histogram2D(plotsGroupName + "/" + triggerNames[i] + "/"
-                		+ positionNames[j] + "/Pair Energy Sum 2D", 150, 0.000, 1.500, 150, 0.000, 1.500);
+                        + positionNames[j] + "/Pair Energy Sum 2D", 150, 0.000, 1.500, 150, 0.000, 1.500);
                 pairCoplanarityEnergySum[i][j] = aida.histogram2D(plotsGroupName + "/" + triggerNames[i] + "/"
-                		+ positionNames[j] + "/Pair Energy Sum vs. Coplanarity", 150, 0.000, 1.500, 180, 0, 180);
+                        + positionNames[j] + "/Pair Energy Sum vs. Coplanarity", 150, 0.000, 1.500, 180, 0, 180);
                 pairEnergySlope2D[i][j] = aida.histogram2D(plotsGroupName + "/" + triggerNames[i] + "/"
-                		+ positionNames[j] + "/Pair Energy Slope 2D", 75, 0.000, 1.500, 100, 0.0, 400.0);
-			}
-		}
-	}
-	
-	/**
-	 * Processes the event clusters and populates distribution charts
-	 * from them for each trigger. Also creates separate plots for the
-	 * edge and fiducial regions.
-	 * @param event - The event containing LCIO collections to be used
-	 * for plot population.
-	 */
-	@Override
-	public void process(EventHeader event) {
-		// Get the TI and SSP banks.
-		TIData tiBank = null;
-		SSPData sspBank = null;
-		if(event.hasCollection(GenericObject.class, bankCollectionName)) {
-			// Get the bank list.
-			List<GenericObject> bankList = event.get(GenericObject.class, bankCollectionName);
-			
-			// Search through the banks and get the SSP and TI banks.
-			for(GenericObject obj : bankList) {
-				// If this is an SSP bank, parse it.
-				if(AbstractIntData.getTag(obj) == SSPData.BANK_TAG) {
-					sspBank = new SSPData(obj);
-				}
-				
-				// Otherwise, if this is a TI bank, parse it.
-				else if(AbstractIntData.getTag(obj) == TIData.BANK_TAG) {
-					tiBank = new TIData(obj);
-				}
-			}
-		}
-		
-		// Get the list of clusters.
-		List<Cluster> clusters = null;
-		if(event.hasCollection(Cluster.class, clusterCollectionName)) {
-			clusters = event.get(Cluster.class, clusterCollectionName);
-		}
-		
-		// Require that all collections be initialized.
-		if(sspBank == null || tiBank == null || clusters == null) {
-			return;
-		}
-		
-		// Track which triggers are active.
-		boolean[] activeTrigger = new boolean[5];
-		activeTrigger[PULSER] = tiBank.isPulserTrigger();
-		activeTrigger[SINGLES0] = tiBank.isSingle0Trigger();
-		activeTrigger[SINGLES1] = tiBank.isSingle1Trigger();
-		activeTrigger[PAIR0] = tiBank.isPair0Trigger();
-		activeTrigger[PAIR1] = tiBank.isPair1Trigger();
-		
-		// Plot all cluster properties for each trigger.
-		for(Cluster cluster : clusters) {
-			// Check whether the cluster is a fiducial or edge cluster.
-			int positional = inFiducialRegion(cluster) ? FIDUCIAL : EDGE;
-			
-			// Fill the appropriate plots for each trigger with an
-			// active trigger bit for single clusters.
-			for(int i = 0; i < 5; i++) {
-				if(activeTrigger[i]) {
-					// Populate the ALL plots.
-					clusterSeedEnergy[i][ALL].fill(TriggerModule.getValueClusterSeedEnergy(cluster));
-					clusterTotalEnergy[i][ALL].fill(cluster.getEnergy());
-					clusterHitCount[i][ALL].fill(TriggerModule.getClusterHitCount(cluster));
-					clusterTime[i][ALL].fill(TriggerModule.getClusterTime(cluster));
-					clusterSeedPosition[i][ALL].fill(TriggerModule.getClusterXIndex(cluster),
-							TriggerModule.getClusterYIndex(cluster));
-					
-					// Populate the positional plots.
-					clusterSeedEnergy[i][positional].fill(TriggerModule.getValueClusterSeedEnergy(cluster));
-					clusterTotalEnergy[i][positional].fill(cluster.getEnergy());
-					clusterHitCount[i][positional].fill(TriggerModule.getClusterHitCount(cluster));
-					clusterTime[i][positional].fill(TriggerModule.getClusterTime(cluster));
-					clusterSeedPosition[i][positional].fill(TriggerModule.getClusterXIndex(cluster),
-							TriggerModule.getClusterYIndex(cluster));
-				}
-			}
-		}
-		
-		// Plot all pair properties for each trigger.
-		List<Cluster[]> pairs = TriggerModule.getTopBottomPairs(clusters, Cluster.class);
-		for(Cluster[] pair : pairs) {
-			// Check whether the cluster is a fiducial or edge cluster.
-			boolean[] isFiducial = {
-					inFiducialRegion(pair[0]),
-					inFiducialRegion(pair[1])
-			};
-			int positional = (isFiducial[0] && isFiducial[1]) ? FIDUCIAL : EDGE;
-			
-			// Fill the appropriate plots for each trigger with an
-			// active trigger bit for single clusters.
-			for(int i = 0; i < 5; i++) {
-				if(activeTrigger[i]) {
-					// Calculate the values.
-					double energySum = TriggerModule.getValueEnergySum(pair);
-					double energyDiff = TriggerModule.getValueEnergyDifference(pair);
-					double energySlope = TriggerModule.getValueEnergySlope(pair, 0.00550);
-					double coplanarity = TriggerModule.getValueCoplanarity(pair);
-					double timeCoincidence = TriggerModule.getValueTimeCoincidence(pair);
-					
-					// Get the energy slope values.
-					Cluster lowCluster = pair[0].getEnergy() < pair[1].getEnergy() ? pair[0] : pair[1];
-					double clusterDistance = TriggerModule.getClusterDistance(lowCluster);
-					
-					// Populate the ALL plots.
-					pairEnergySum[i][ALL].fill(energySum);
-					pairEnergyDifference[i][ALL].fill(energyDiff);
-					pairEnergySlope[i][ALL].fill(energySlope);
-					pairCoplanarity[i][ALL].fill(coplanarity);
-					pairTimeCoincidence[i][ALL].fill(timeCoincidence);
-					pairEnergySum2D[i][ALL].fill(pair[0].getEnergy(), pair[1].getEnergy());
-					pairCoplanarityEnergySum[i][ALL].fill(energySum, coplanarity);
-					pairEnergySlope2D[i][ALL].fill(lowCluster.getEnergy(), clusterDistance);
-					
-					// Populate the positional plots.
-					pairEnergySum[i][positional].fill(energySum);
-					pairEnergyDifference[i][positional].fill(energyDiff);
-					pairEnergySlope[i][positional].fill(energySlope);
-					pairCoplanarity[i][positional].fill(coplanarity);
-					pairTimeCoincidence[i][positional].fill(timeCoincidence);
-					pairEnergySum2D[i][positional].fill(pair[0].getEnergy(), pair[1].getEnergy());
-					pairCoplanarityEnergySum[i][positional].fill(energySum, coplanarity);
-					pairEnergySlope2D[i][positional].fill(lowCluster.getEnergy(), clusterDistance);
-				}
-			}
-		}
-	}
-	
-	/**
-	 * Indicates whether the argument cluster is located in the fiducial
-	 * region or not.
-	 * @param cluster - The cluster to check.
-	 * @return Returns <code>true</code> if the cluster is located in
-	 * the fiducial region and <code>false</code> otherwise.
-	 */
-	private static final boolean inFiducialRegion(Cluster cluster) {
-		// Get the x and y indices for the cluster.
-		int ix   = TriggerModule.getClusterXIndex(cluster);
-		int absx = Math.abs(TriggerModule.getClusterXIndex(cluster));
-		int absy = Math.abs(TriggerModule.getClusterYIndex(cluster));
-		
-		// Check if the cluster is on the top or the bottom of the
-		// calorimeter, as defined by |y| == 5. This is an edge cluster
-		// and is not in the fiducial region.
-		if(absy == 5) {
-			return false;
-		}
-		
-		// Check if the cluster is on the extreme left or right side
-		// of the calorimeter, as defined by |x| == 23. This is also
-		// and edge cluster is not in the fiducial region.
-		if(absx == 23) {
-			return false;
-		}
-		
-		// Check if the cluster is along the beam gap, as defined by
-		// |y| == 1. This is an internal edge cluster and is not in the
-		// fiducial region.
-		if(absy == 1) {
-			return false;
-		}
-		
-		// Lastly, check if the cluster falls along the beam hole, as
-		// defined by clusters with -11 <= x <= -1 and |y| == 2. This
-		// is not the fiducial region.
-		if(absy == 2 && ix <= -1 && ix >= -11) {
-			return false;
-		}
-		
-		// If all checks fail, the cluster is in the fiducial region.
-		return true;
-	}
-	
-	/**
-	 * Sets the name of the LCIO collection containing the clusters
-	 * that are to be plotted.
-	 * @param collection - The LCIO collection name.
-	 */
-	public void setClusterCollectionName(String collection) {
-		clusterCollectionName = collection;
-	}
-	
-	/**
-	 * Defines the name of the LCIO collection containing the TI bank.
-	 * @param collection - The LCIO collection name.
-	 */
-	public void setBankCollectionName(String collection) {
-		bankCollectionName = collection;
-	}
-	
-	/**
-	 * Sets the name of the super-group folder containing all plots.
-	 * @param name - The name of the plots folder.
-	 */
-	public void setPlotsGroupName(String name) {
-		plotsGroupName = name;
-	}
+                        + positionNames[j] + "/Pair Energy Slope 2D", 75, 0.000, 1.500, 100, 0.0, 400.0);
+            }
+        }
+    }
+    
+    /**
+     * Processes the event clusters and populates distribution charts
+     * from them for each trigger. Also creates separate plots for the
+     * edge and fiducial regions.
+     * @param event - The event containing LCIO collections to be used
+     * for plot population.
+     */
+    @Override
+    public void process(EventHeader event) {
+        // Get the TI and SSP banks.
+        TIData tiBank = null;
+        SSPData sspBank = null;
+        if(event.hasCollection(GenericObject.class, bankCollectionName)) {
+            // Get the bank list.
+            List<GenericObject> bankList = event.get(GenericObject.class, bankCollectionName);
+            
+            // Search through the banks and get the SSP and TI banks.
+            for(GenericObject obj : bankList) {
+                // If this is an SSP bank, parse it.
+                if(AbstractIntData.getTag(obj) == SSPData.BANK_TAG) {
+                    sspBank = new SSPData(obj);
+                }
+                
+                // Otherwise, if this is a TI bank, parse it.
+                else if(AbstractIntData.getTag(obj) == TIData.BANK_TAG) {
+                    tiBank = new TIData(obj);
+                }
+            }
+        }
+        
+        // Get the list of clusters.
+        List<Cluster> clusters = null;
+        if(event.hasCollection(Cluster.class, clusterCollectionName)) {
+            clusters = event.get(Cluster.class, clusterCollectionName);
+        }
+        
+        // Require that all collections be initialized.
+        if(sspBank == null || tiBank == null || clusters == null) {
+            return;
+        }
+        
+        // Track which triggers are active.
+        boolean[] activeTrigger = new boolean[5];
+        activeTrigger[PULSER] = tiBank.isPulserTrigger();
+        activeTrigger[SINGLES0] = tiBank.isSingle0Trigger();
+        activeTrigger[SINGLES1] = tiBank.isSingle1Trigger();
+        activeTrigger[PAIR0] = tiBank.isPair0Trigger();
+        activeTrigger[PAIR1] = tiBank.isPair1Trigger();
+        
+        // Plot all cluster properties for each trigger.
+        for(Cluster cluster : clusters) {
+            // Check whether the cluster is a fiducial or edge cluster.
+            int positional = inFiducialRegion(cluster) ? FIDUCIAL : EDGE;
+            
+            // Fill the appropriate plots for each trigger with an
+            // active trigger bit for single clusters.
+            for(int i = 0; i < 5; i++) {
+                if(activeTrigger[i]) {
+                    // Populate the ALL plots.
+                    clusterSeedEnergy[i][ALL].fill(TriggerModule.getValueClusterSeedEnergy(cluster));
+                    clusterTotalEnergy[i][ALL].fill(cluster.getEnergy());
+                    clusterHitCount[i][ALL].fill(TriggerModule.getClusterHitCount(cluster));
+                    clusterTime[i][ALL].fill(TriggerModule.getClusterTime(cluster));
+                    clusterSeedPosition[i][ALL].fill(TriggerModule.getClusterXIndex(cluster),
+                            TriggerModule.getClusterYIndex(cluster));
+                    
+                    // Populate the positional plots.
+                    clusterSeedEnergy[i][positional].fill(TriggerModule.getValueClusterSeedEnergy(cluster));
+                    clusterTotalEnergy[i][positional].fill(cluster.getEnergy());
+                    clusterHitCount[i][positional].fill(TriggerModule.getClusterHitCount(cluster));
+                    clusterTime[i][positional].fill(TriggerModule.getClusterTime(cluster));
+                    clusterSeedPosition[i][positional].fill(TriggerModule.getClusterXIndex(cluster),
+                            TriggerModule.getClusterYIndex(cluster));
+                }
+            }
+        }
+        
+        // Plot all pair properties for each trigger.
+        List<Cluster[]> pairs = TriggerModule.getTopBottomPairs(clusters, Cluster.class);
+        for(Cluster[] pair : pairs) {
+            // Check whether the cluster is a fiducial or edge cluster.
+            boolean[] isFiducial = {
+                    inFiducialRegion(pair[0]),
+                    inFiducialRegion(pair[1])
+            };
+            int positional = (isFiducial[0] && isFiducial[1]) ? FIDUCIAL : EDGE;
+            
+            // Fill the appropriate plots for each trigger with an
+            // active trigger bit for single clusters.
+            for(int i = 0; i < 5; i++) {
+                if(activeTrigger[i]) {
+                    // Calculate the values.
+                    double energySum = TriggerModule.getValueEnergySum(pair);
+                    double energyDiff = TriggerModule.getValueEnergyDifference(pair);
+                    double energySlope = TriggerModule.getValueEnergySlope(pair, 0.00550);
+                    double coplanarity = TriggerModule.getValueCoplanarity(pair);
+                    double timeCoincidence = TriggerModule.getValueTimeCoincidence(pair);
+                    
+                    // Get the energy slope values.
+                    Cluster lowCluster = pair[0].getEnergy() < pair[1].getEnergy() ? pair[0] : pair[1];
+                    double clusterDistance = TriggerModule.getClusterDistance(lowCluster);
+                    
+                    // Populate the ALL plots.
+                    pairEnergySum[i][ALL].fill(energySum);
+                    pairEnergyDifference[i][ALL].fill(energyDiff);
+                    pairEnergySlope[i][ALL].fill(energySlope);
+                    pairCoplanarity[i][ALL].fill(coplanarity);
+                    pairTimeCoincidence[i][ALL].fill(timeCoincidence);
+                    pairEnergySum2D[i][ALL].fill(pair[0].getEnergy(), pair[1].getEnergy());
+                    pairCoplanarityEnergySum[i][ALL].fill(energySum, coplanarity);
+                    pairEnergySlope2D[i][ALL].fill(lowCluster.getEnergy(), clusterDistance);
+                    
+                    // Populate the positional plots.
+                    pairEnergySum[i][positional].fill(energySum);
+                    pairEnergyDifference[i][positional].fill(energyDiff);
+                    pairEnergySlope[i][positional].fill(energySlope);
+                    pairCoplanarity[i][positional].fill(coplanarity);
+                    pairTimeCoincidence[i][positional].fill(timeCoincidence);
+                    pairEnergySum2D[i][positional].fill(pair[0].getEnergy(), pair[1].getEnergy());
+                    pairCoplanarityEnergySum[i][positional].fill(energySum, coplanarity);
+                    pairEnergySlope2D[i][positional].fill(lowCluster.getEnergy(), clusterDistance);
+                }
+            }
+        }
+    }
+    
+    /**
+     * Indicates whether the argument cluster is located in the fiducial
+     * region or not.
+     * @param cluster - The cluster to check.
+     * @return Returns <code>true</code> if the cluster is located in
+     * the fiducial region and <code>false</code> otherwise.
+     */
+    private static final boolean inFiducialRegion(Cluster cluster) {
+        // Get the x and y indices for the cluster.
+        int ix   = TriggerModule.getClusterXIndex(cluster);
+        int absx = Math.abs(TriggerModule.getClusterXIndex(cluster));
+        int absy = Math.abs(TriggerModule.getClusterYIndex(cluster));
+        
+        // Check if the cluster is on the top or the bottom of the
+        // calorimeter, as defined by |y| == 5. This is an edge cluster
+        // and is not in the fiducial region.
+        if(absy == 5) {
+            return false;
+        }
+        
+        // Check if the cluster is on the extreme left or right side
+        // of the calorimeter, as defined by |x| == 23. This is also
+        // and edge cluster is not in the fiducial region.
+        if(absx == 23) {
+            return false;
+        }
+        
+        // Check if the cluster is along the beam gap, as defined by
+        // |y| == 1. This is an internal edge cluster and is not in the
+        // fiducial region.
+        if(absy == 1) {
+            return false;
+        }
+        
+        // Lastly, check if the cluster falls along the beam hole, as
+        // defined by clusters with -11 <= x <= -1 and |y| == 2. This
+        // is not the fiducial region.
+        if(absy == 2 && ix <= -1 && ix >= -11) {
+            return false;
+        }
+        
+        // If all checks fail, the cluster is in the fiducial region.
+        return true;
+    }
+    
+    /**
+     * Sets the name of the LCIO collection containing the clusters
+     * that are to be plotted.
+     * @param collection - The LCIO collection name.
+     */
+    public void setClusterCollectionName(String collection) {
+        clusterCollectionName = collection;
+    }
+    
+    /**
+     * Defines the name of the LCIO collection containing the TI bank.
+     * @param collection - The LCIO collection name.
+     */
+    public void setBankCollectionName(String collection) {
+        bankCollectionName = collection;
+    }
+    
+    /**
+     * Sets the name of the super-group folder containing all plots.
+     * @param name - The name of the plots folder.
+     */
+    public void setPlotsGroupName(String name) {
+        plotsGroupName = name;
+    }
 }

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/InvariantMassPairDriver.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/InvariantMassPairDriver.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/InvariantMassPairDriver.java	Wed Apr 27 11:11:32 2016
@@ -15,255 +15,255 @@
 import org.lcsim.util.aida.AIDA;
 
 public class InvariantMassPairDriver extends Driver {
-	private int[] events = new int[3];
-	private TriggerModule[] trigger = new TriggerModule[2];
-	
-	private String gtpClusterCollectionName = "EcalClustersGTP";
-	private String particleCollectionName = "FinalStateParticles";
-	private String reconParticleCollectionName = "UnconstrainedV0Candidates";
-	
-	private AIDA aida = AIDA.defaultInstance();
-	private IHistogram1D electronEnergyHist = aida.histogram1D("Trident Analysis/Electron Energy", 150, 0.000, 1.500);
-	private IHistogram1D positronEnergyHist = aida.histogram1D("Trident Analysis/Positron Energy", 150, 0.000, 1.500);
-	private IHistogram1D pairEnergyHist = aida.histogram1D("Trident Analysis/Energy Sum Distribution", 220, 0.00, 2.200);
-	private IHistogram2D pair2DEnergyHist = aida.histogram2D("Trident Analysis/2D Energy Distribution", 55, 0, 1.1, 55, 0, 1.1);
-	private IHistogram1D pair1MassHist = aida.histogram1D("Trident Analysis/Particle Invariant Mass (1 Hit)", 240, 0.000, 0.120);
-	private IHistogram1D pair1ModMassHist = aida.histogram1D("Trident Analysis/Particle Invariant Mass (2 Hit)", 240, 0.000, 0.120);
-	private IHistogram1D elasticElectronEnergyHist = aida.histogram1D("Trident Analysis/Trident Electron Energy", 150, 0.000, 1.500);
-	private IHistogram1D elasticPositronEnergyHist = aida.histogram1D("Trident Analysis/Trident Positron Energy", 150, 0.000, 1.500);
-	
-	@Override
-	public void startOfData() {
-		// Instantiate the pair 1 trigger.
-		trigger[0] = new TriggerModule();
-		trigger[0].setCutValue(TriggerModule.CLUSTER_HIT_COUNT_LOW,       1);
-		trigger[0].setCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_LOW,    0.054);
-		trigger[0].setCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_HIGH,   0.630);
-		trigger[0].setCutValue(TriggerModule.PAIR_COPLANARITY_HIGH,       30);
-		trigger[0].setCutValue(TriggerModule.PAIR_ENERGY_DIFFERENCE_HIGH, 0.540);
-		trigger[0].setCutValue(TriggerModule.PAIR_ENERGY_SUM_LOW,         0.180);
-		trigger[0].setCutValue(TriggerModule.PAIR_ENERGY_SUM_HIGH,        0.860);
-		trigger[0].setCutValue(TriggerModule.PAIR_ENERGY_SLOPE_LOW,       0.600);
-		trigger[0].setCutValue(TriggerModule.PAIR_ENERGY_SLOPE_F,         0.0055);
-		trigger[0].setCutValue(TriggerModule.PAIR_TIME_COINCIDENCE,       12);
-		
-		// Instantiate the pair 1 trigger with a hit count cut of two.
-		trigger[1] = new TriggerModule();
-		trigger[1].setCutValue(TriggerModule.CLUSTER_HIT_COUNT_LOW,       2);
-		trigger[0].setCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_LOW,    0.054);
-		trigger[0].setCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_HIGH,   0.630);
-		trigger[0].setCutValue(TriggerModule.PAIR_COPLANARITY_HIGH,       30);
-		trigger[0].setCutValue(TriggerModule.PAIR_ENERGY_DIFFERENCE_HIGH, 0.540);
-		trigger[0].setCutValue(TriggerModule.PAIR_ENERGY_SUM_LOW,         0.180);
-		trigger[0].setCutValue(TriggerModule.PAIR_ENERGY_SUM_HIGH,        0.860);
-		trigger[0].setCutValue(TriggerModule.PAIR_ENERGY_SLOPE_LOW,       0.600);
-		trigger[1].setCutValue(TriggerModule.PAIR_ENERGY_SLOPE_F,         0.0055);
-		trigger[0].setCutValue(TriggerModule.PAIR_TIME_COINCIDENCE,       12);
-	}
-	
-	@Override
-	public void endOfData() {
-		System.out.printf("Pair 1     :: %d / %d%n", events[0], events[2]);
-		System.out.printf("Pair 1 Mod :: %d / %d%n", events[1], events[2]);
-	}
-	
-	@Override
-	public void process(EventHeader event) {
-		// Skip the event if there is no reconstructed particle list.
-		if(!event.hasCollection(ReconstructedParticle.class, particleCollectionName)) {
-			return;
-		}
-		
-		// Get a list of all tracks in the event.
-		List<ReconstructedParticle> trackList = event.get(ReconstructedParticle.class, particleCollectionName);
-		
-		// Plot the energies of the electrons and positrons.
-		for(ReconstructedParticle track : trackList) {
-			// Positive tracks are assumed to be positrons.
-			if(track.getCharge() > 0) {
-				positronEnergyHist.fill(track.getMomentum().magnitude());
-			}
-			
-			// Negative tracks are assumed to be electrons.
-			else if(track.getCharge() < 0) {
-				electronEnergyHist.fill(track.getMomentum().magnitude());
-			}
-		}
-		
-		// Get track pairs.
-		List<ReconstructedParticle[]> trackPairList = getTrackPairs(trackList);
-		
-		// Populate the pair plots.
-		trackPairLoop:
-		for(ReconstructedParticle[] trackPair : trackPairList) {
-			// Note the polarity of the tracks.
-			boolean[] trackIsPositive = {
-					trackPair[0].getCharge() > 0,
-					trackPair[1].getCharge() > 0
-			};
-			
-			// Require that one track be positive and one be negative.
-			if(!(trackIsPositive[0] ^ trackIsPositive[1])) {
-				continue trackPairLoop;
-			}
-			
-			// Populate the track pair plots.
-			pairEnergyHist.fill(VecOp.add(trackPair[0].getMomentum(), trackPair[1].getMomentum()).magnitude());
-			if(trackIsPositive[0]) {
-				pair2DEnergyHist.fill(trackPair[0].getMomentum().magnitude(), trackPair[1].getMomentum().magnitude());
-			} else {
-				pair2DEnergyHist.fill(trackPair[1].getMomentum().magnitude(), trackPair[0].getMomentum().magnitude());
-			}
-		}
-		
-		// Check that the event has a collection of GTP clusters.
-		if(!event.hasCollection(Cluster.class, gtpClusterCollectionName)) {
-			return;
-		}
-		
-		// Increment the total event count.
-		events[2]++;
-		
-		// Get the GTP clusters.
-		List<Cluster> clusters = event.get(Cluster.class, gtpClusterCollectionName);
-		
-		// Get the list of top/bottom pairs.
-		List<Cluster[]> pairs = getClusterPairs(clusters);
-		
-		// Iterate over the pairs and determine if any cluster passes
-		// pair 1 trigger or the pair 1 modified trigger.
-		boolean passedPair1 = false;
-		boolean passedPair1Mod = false;
-		pairLoop:
-		for(Cluster[] pair : pairs) {
-			// Check the cluster energy cut.
-			if(!trigger[0].clusterTotalEnergyCut(pair[0])) { continue pairLoop; }
-			if(!trigger[0].clusterTotalEnergyCut(pair[1])) { continue pairLoop; }
-			
-			// Check the pair cuts.
-			if(!trigger[0].pairCoplanarityCut(pair)) { continue pairLoop; }
-			if(!trigger[0].pairEnergyDifferenceCut(pair)) { continue pairLoop; }
-			if(!trigger[0].pairEnergySumCut(pair)) { continue pairLoop; }
-			if(!trigger[0].pairEnergySlopeCut(pair)) { continue pairLoop; }
-			
-			// Check if the pair passes the singles 0 hit count cut.
-			if(trigger[0].clusterHitCountCut(pair[0]) && trigger[0].clusterHitCountCut(pair[1])) {
-				// Note that a pair passed the pair 1 trigger.
-				passedPair1 = true;
-				
-				// Check whether the pair passed the modified pair 1
-				// trigger hit count cut.
-				if(trigger[1].clusterHitCountCut(pair[0]) && trigger[1].clusterHitCountCut(pair[1])) {
-					passedPair1Mod = true;
-				}
-			} else { continue pairLoop; }
-		}
-		
-		// If no pair passed the pair 1 cut, nothing further need be done.
-		if(!passedPair1) { return; }
-		
-		// Otherwise, increment the "passed pair 1" count and the
-		// "passed pair 1 mod" count, if appropriate.
-		events[0]++;
-		if(passedPair1Mod) { events[1]++; }
-		
-		// Get the collection of reconstructed V0 candidates.
-		List<ReconstructedParticle> candidateList = event.get(ReconstructedParticle.class, reconParticleCollectionName);
-		
-		// Populate the invariant mass plot.
-		candidateLoop:
-		for(ReconstructedParticle particle : candidateList) {
-			// Track the electron and positron momenta.
-			double electronMomentum = 0.0;
-			double positronMomentum = 0.0;
-			
-			// Check that it has component particles that meet the
-			// trident condition.
-			boolean seenPositive = false;
-			boolean seenNegative = false;
-			for(ReconstructedParticle track : particle.getParticles()) {
-				// Exactly one track must be negative. Its energy is
-				// disallowed from exceeding 900 MeV.
-				if(track.getCharge() < 0) {
-					// Reject a second negative particle.
-					if(seenNegative) { continue candidateLoop; }
-					
-					// Otherwise, note that one has been seen.
-					seenNegative = true;
-					electronMomentum = track.getMomentum().magnitude();
-					
-					// Reject electrons with a momentum exceeding 900 MeV.
-					if(track.getMomentum().magnitude() > 0.900) {
-						continue candidateLoop;
-					}
-				}
-				
-				// Exactly one track must be positive. Its energy is
-				// not constrained.
-				else if(track.getCharge() > 0) {
-					// Reject a second positive particle.
-					if(seenPositive) { continue candidateLoop; }
-					
-					// Otherwise, note that one has been seen.
-					seenPositive = true;
-					positronMomentum = track.getMomentum().magnitude();
-				}
-				
-				// Lastly, reject any particle that produced a photon.
-				else { continue candidateLoop; }
-			}
-			
-			// Populate the plots.
-			pair1MassHist.fill(particle.getMass());
-			elasticElectronEnergyHist.fill(electronMomentum);
-			elasticPositronEnergyHist.fill(positronMomentum);
-			if(passedPair1Mod) { pair1ModMassHist.fill(particle.getMass()); }
-		}
-	}
-	
-	/**
-	 * Creates a list of top/bottom cluster pairs.
-	 * @param clusters - A <code>List</code> collection of objects of
-	 * type <code>Cluster</code>.
-	 * @return Returns a <code>List</code> collection of 2-entry arrays
-	 * of <code>Cluster</code> objects representing top/bottom cluster
-	 * pairs. The first entry is always the top cluster.
-	 */
-	private static final List<Cluster[]> getClusterPairs(List<Cluster> clusters) {
-		// Separate the clusters into top and bottom clusters.
-		List<Cluster> topList = new ArrayList<Cluster>();
-		List<Cluster> botList = new ArrayList<Cluster>();
-		for(Cluster cluster : clusters) {
-			if(cluster.getCalorimeterHits().get(0).getIdentifierFieldValue("iy") > 0) {
-				topList.add(cluster);
-			}
-			else { botList.add(cluster); }
-		}
-		
-		// Create a list of all top/bottom pairs.
-		List<Cluster[]> pairs = new ArrayList<Cluster[]>();
-		for(Cluster topCluster : topList) {
-			for(Cluster botCluster : botList) {
-				pairs.add(new Cluster[] { topCluster, botCluster });
-			}
-		}
-		
-		// Return the list of cluster pairs.
-		return pairs;
-	}
-	
-	private static final List<ReconstructedParticle[]> getTrackPairs(List<ReconstructedParticle> trackList) {
-		// Create an empty list for the pairs.
-		List<ReconstructedParticle[]> pairs = new ArrayList<ReconstructedParticle[]>();
-		
-		// Add all possible pairs of tracks.
-		for(int i = 0; i < trackList.size(); i++) {
-			for(int j = i + 1; j < trackList.size(); j++) {
-				pairs.add(new ReconstructedParticle[] { trackList.get(i), trackList.get(j) });
-			}
-		}
-		
-		// Return the list of tracks.
-		return pairs;
-	}
+    private int[] events = new int[3];
+    private TriggerModule[] trigger = new TriggerModule[2];
+    
+    private String gtpClusterCollectionName = "EcalClustersGTP";
+    private String particleCollectionName = "FinalStateParticles";
+    private String reconParticleCollectionName = "UnconstrainedV0Candidates";
+    
+    private AIDA aida = AIDA.defaultInstance();
+    private IHistogram1D electronEnergyHist = aida.histogram1D("Trident Analysis/Electron Energy", 150, 0.000, 1.500);
+    private IHistogram1D positronEnergyHist = aida.histogram1D("Trident Analysis/Positron Energy", 150, 0.000, 1.500);
+    private IHistogram1D pairEnergyHist = aida.histogram1D("Trident Analysis/Energy Sum Distribution", 220, 0.00, 2.200);
+    private IHistogram2D pair2DEnergyHist = aida.histogram2D("Trident Analysis/2D Energy Distribution", 55, 0, 1.1, 55, 0, 1.1);
+    private IHistogram1D pair1MassHist = aida.histogram1D("Trident Analysis/Particle Invariant Mass (1 Hit)", 240, 0.000, 0.120);
+    private IHistogram1D pair1ModMassHist = aida.histogram1D("Trident Analysis/Particle Invariant Mass (2 Hit)", 240, 0.000, 0.120);
+    private IHistogram1D elasticElectronEnergyHist = aida.histogram1D("Trident Analysis/Trident Electron Energy", 150, 0.000, 1.500);
+    private IHistogram1D elasticPositronEnergyHist = aida.histogram1D("Trident Analysis/Trident Positron Energy", 150, 0.000, 1.500);
+    
+    @Override
+    public void startOfData() {
+        // Instantiate the pair 1 trigger.
+        trigger[0] = new TriggerModule();
+        trigger[0].setCutValue(TriggerModule.CLUSTER_HIT_COUNT_LOW,       1);
+        trigger[0].setCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_LOW,    0.054);
+        trigger[0].setCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_HIGH,   0.630);
+        trigger[0].setCutValue(TriggerModule.PAIR_COPLANARITY_HIGH,       30);
+        trigger[0].setCutValue(TriggerModule.PAIR_ENERGY_DIFFERENCE_HIGH, 0.540);
+        trigger[0].setCutValue(TriggerModule.PAIR_ENERGY_SUM_LOW,         0.180);
+        trigger[0].setCutValue(TriggerModule.PAIR_ENERGY_SUM_HIGH,        0.860);
+        trigger[0].setCutValue(TriggerModule.PAIR_ENERGY_SLOPE_LOW,       0.600);
+        trigger[0].setCutValue(TriggerModule.PAIR_ENERGY_SLOPE_F,         0.0055);
+        trigger[0].setCutValue(TriggerModule.PAIR_TIME_COINCIDENCE,       12);
+        
+        // Instantiate the pair 1 trigger with a hit count cut of two.
+        trigger[1] = new TriggerModule();
+        trigger[1].setCutValue(TriggerModule.CLUSTER_HIT_COUNT_LOW,       2);
+        trigger[0].setCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_LOW,    0.054);
+        trigger[0].setCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_HIGH,   0.630);
+        trigger[0].setCutValue(TriggerModule.PAIR_COPLANARITY_HIGH,       30);
+        trigger[0].setCutValue(TriggerModule.PAIR_ENERGY_DIFFERENCE_HIGH, 0.540);
+        trigger[0].setCutValue(TriggerModule.PAIR_ENERGY_SUM_LOW,         0.180);
+        trigger[0].setCutValue(TriggerModule.PAIR_ENERGY_SUM_HIGH,        0.860);
+        trigger[0].setCutValue(TriggerModule.PAIR_ENERGY_SLOPE_LOW,       0.600);
+        trigger[1].setCutValue(TriggerModule.PAIR_ENERGY_SLOPE_F,         0.0055);
+        trigger[0].setCutValue(TriggerModule.PAIR_TIME_COINCIDENCE,       12);
+    }
+    
+    @Override
+    public void endOfData() {
+        System.out.printf("Pair 1     :: %d / %d%n", events[0], events[2]);
+        System.out.printf("Pair 1 Mod :: %d / %d%n", events[1], events[2]);
+    }
+    
+    @Override
+    public void process(EventHeader event) {
+        // Skip the event if there is no reconstructed particle list.
+        if(!event.hasCollection(ReconstructedParticle.class, particleCollectionName)) {
+            return;
+        }
+        
+        // Get a list of all tracks in the event.
+        List<ReconstructedParticle> trackList = event.get(ReconstructedParticle.class, particleCollectionName);
+        
+        // Plot the energies of the electrons and positrons.
+        for(ReconstructedParticle track : trackList) {
+            // Positive tracks are assumed to be positrons.
+            if(track.getCharge() > 0) {
+                positronEnergyHist.fill(track.getMomentum().magnitude());
+            }
+            
+            // Negative tracks are assumed to be electrons.
+            else if(track.getCharge() < 0) {
+                electronEnergyHist.fill(track.getMomentum().magnitude());
+            }
+        }
+        
+        // Get track pairs.
+        List<ReconstructedParticle[]> trackPairList = getTrackPairs(trackList);
+        
+        // Populate the pair plots.
+        trackPairLoop:
+        for(ReconstructedParticle[] trackPair : trackPairList) {
+            // Note the polarity of the tracks.
+            boolean[] trackIsPositive = {
+                    trackPair[0].getCharge() > 0,
+                    trackPair[1].getCharge() > 0
+            };
+            
+            // Require that one track be positive and one be negative.
+            if(!(trackIsPositive[0] ^ trackIsPositive[1])) {
+                continue trackPairLoop;
+            }
+            
+            // Populate the track pair plots.
+            pairEnergyHist.fill(VecOp.add(trackPair[0].getMomentum(), trackPair[1].getMomentum()).magnitude());
+            if(trackIsPositive[0]) {
+                pair2DEnergyHist.fill(trackPair[0].getMomentum().magnitude(), trackPair[1].getMomentum().magnitude());
+            } else {
+                pair2DEnergyHist.fill(trackPair[1].getMomentum().magnitude(), trackPair[0].getMomentum().magnitude());
+            }
+        }
+        
+        // Check that the event has a collection of GTP clusters.
+        if(!event.hasCollection(Cluster.class, gtpClusterCollectionName)) {
+            return;
+        }
+        
+        // Increment the total event count.
+        events[2]++;
+        
+        // Get the GTP clusters.
+        List<Cluster> clusters = event.get(Cluster.class, gtpClusterCollectionName);
+        
+        // Get the list of top/bottom pairs.
+        List<Cluster[]> pairs = getClusterPairs(clusters);
+        
+        // Iterate over the pairs and determine if any cluster passes
+        // pair 1 trigger or the pair 1 modified trigger.
+        boolean passedPair1 = false;
+        boolean passedPair1Mod = false;
+        pairLoop:
+        for(Cluster[] pair : pairs) {
+            // Check the cluster energy cut.
+            if(!trigger[0].clusterTotalEnergyCut(pair[0])) { continue pairLoop; }
+            if(!trigger[0].clusterTotalEnergyCut(pair[1])) { continue pairLoop; }
+            
+            // Check the pair cuts.
+            if(!trigger[0].pairCoplanarityCut(pair)) { continue pairLoop; }
+            if(!trigger[0].pairEnergyDifferenceCut(pair)) { continue pairLoop; }
+            if(!trigger[0].pairEnergySumCut(pair)) { continue pairLoop; }
+            if(!trigger[0].pairEnergySlopeCut(pair)) { continue pairLoop; }
+            
+            // Check if the pair passes the singles 0 hit count cut.
+            if(trigger[0].clusterHitCountCut(pair[0]) && trigger[0].clusterHitCountCut(pair[1])) {
+                // Note that a pair passed the pair 1 trigger.
+                passedPair1 = true;
+                
+                // Check whether the pair passed the modified pair 1
+                // trigger hit count cut.
+                if(trigger[1].clusterHitCountCut(pair[0]) && trigger[1].clusterHitCountCut(pair[1])) {
+                    passedPair1Mod = true;
+                }
+            } else { continue pairLoop; }
+        }
+        
+        // If no pair passed the pair 1 cut, nothing further need be done.
+        if(!passedPair1) { return; }
+        
+        // Otherwise, increment the "passed pair 1" count and the
+        // "passed pair 1 mod" count, if appropriate.
+        events[0]++;
+        if(passedPair1Mod) { events[1]++; }
+        
+        // Get the collection of reconstructed V0 candidates.
+        List<ReconstructedParticle> candidateList = event.get(ReconstructedParticle.class, reconParticleCollectionName);
+        
+        // Populate the invariant mass plot.
+        candidateLoop:
+        for(ReconstructedParticle particle : candidateList) {
+            // Track the electron and positron momenta.
+            double electronMomentum = 0.0;
+            double positronMomentum = 0.0;
+            
+            // Check that it has component particles that meet the
+            // trident condition.
+            boolean seenPositive = false;
+            boolean seenNegative = false;
+            for(ReconstructedParticle track : particle.getParticles()) {
+                // Exactly one track must be negative. Its energy is
+                // disallowed from exceeding 900 MeV.
+                if(track.getCharge() < 0) {
+                    // Reject a second negative particle.
+                    if(seenNegative) { continue candidateLoop; }
+                    
+                    // Otherwise, note that one has been seen.
+                    seenNegative = true;
+                    electronMomentum = track.getMomentum().magnitude();
+                    
+                    // Reject electrons with a momentum exceeding 900 MeV.
+                    if(track.getMomentum().magnitude() > 0.900) {
+                        continue candidateLoop;
+                    }
+                }
+                
+                // Exactly one track must be positive. Its energy is
+                // not constrained.
+                else if(track.getCharge() > 0) {
+                    // Reject a second positive particle.
+                    if(seenPositive) { continue candidateLoop; }
+                    
+                    // Otherwise, note that one has been seen.
+                    seenPositive = true;
+                    positronMomentum = track.getMomentum().magnitude();
+                }
+                
+                // Lastly, reject any particle that produced a photon.
+                else { continue candidateLoop; }
+            }
+            
+            // Populate the plots.
+            pair1MassHist.fill(particle.getMass());
+            elasticElectronEnergyHist.fill(electronMomentum);
+            elasticPositronEnergyHist.fill(positronMomentum);
+            if(passedPair1Mod) { pair1ModMassHist.fill(particle.getMass()); }
+        }
+    }
+    
+    /**
+     * Creates a list of top/bottom cluster pairs.
+     * @param clusters - A <code>List</code> collection of objects of
+     * type <code>Cluster</code>.
+     * @return Returns a <code>List</code> collection of 2-entry arrays
+     * of <code>Cluster</code> objects representing top/bottom cluster
+     * pairs. The first entry is always the top cluster.
+     */
+    private static final List<Cluster[]> getClusterPairs(List<Cluster> clusters) {
+        // Separate the clusters into top and bottom clusters.
+        List<Cluster> topList = new ArrayList<Cluster>();
+        List<Cluster> botList = new ArrayList<Cluster>();
+        for(Cluster cluster : clusters) {
+            if(cluster.getCalorimeterHits().get(0).getIdentifierFieldValue("iy") > 0) {
+                topList.add(cluster);
+            }
+            else { botList.add(cluster); }
+        }
+        
+        // Create a list of all top/bottom pairs.
+        List<Cluster[]> pairs = new ArrayList<Cluster[]>();
+        for(Cluster topCluster : topList) {
+            for(Cluster botCluster : botList) {
+                pairs.add(new Cluster[] { topCluster, botCluster });
+            }
+        }
+        
+        // Return the list of cluster pairs.
+        return pairs;
+    }
+    
+    private static final List<ReconstructedParticle[]> getTrackPairs(List<ReconstructedParticle> trackList) {
+        // Create an empty list for the pairs.
+        List<ReconstructedParticle[]> pairs = new ArrayList<ReconstructedParticle[]>();
+        
+        // Add all possible pairs of tracks.
+        for(int i = 0; i < trackList.size(); i++) {
+            for(int j = i + 1; j < trackList.size(); j++) {
+                pairs.add(new ReconstructedParticle[] { trackList.get(i), trackList.get(j) });
+            }
+        }
+        
+        // Return the list of tracks.
+        return pairs;
+    }
 }

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/MTEAnalysis.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/MTEAnalysis.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/MTEAnalysis.java	Wed Apr 27 11:11:32 2016
@@ -24,145 +24,145 @@
 import org.lcsim.util.aida.AIDA;
 
 public class MTEAnalysis extends Driver {
-	// Define track LCIO information.
-	private boolean skipBadSVT = true;
-	private String bankCollectionName = "TriggerBank";
-	private String particleCollectionName = "FinalStateParticles";
-	private static final AIDA aida = AIDA.defaultInstance();
-	private IHistogram1D[] chargedTracksPlot = {
-			aida.histogram1D("MTE Analysis/Møller Event Tracks", 10, -0.5, 9.5),
-			aida.histogram1D("MTE Analysis/Trident Event Tracks", 10, -0.5, 9.5),
-			aida.histogram1D("MTE Analysis/Elastic Event Tracks", 10, -0.5, 9.5)
-	};
-	private IHistogram1D[] clusterCountPlot = {
-			aida.histogram1D("MTE Analysis/Møller Event Clusters", 10, -0.5, 9.5),
-			aida.histogram1D("MTE Analysis/Trident Event Clusters", 10, -0.5, 9.5),
-			aida.histogram1D("MTE Analysis/Elastic Event Clusters", 10, -0.5, 9.5)
-	};
-	private IHistogram1D[] energyPlot = {
-			aida.histogram1D("MTE Analysis/Møller Energy Sum Distribution", 220, 0, 2.2),
-			aida.histogram1D("MTE Analysis/Trident Energy Sum Distribution", 220, 0, 2.2),
-			aida.histogram1D("MTE Analysis/Elastic Energy Distribution", 110, 0, 1.5)
-	};
-	private IHistogram1D[] electronPlot = {
-			aida.histogram1D("MTE Analysis/Møller Electron Energy Distribution", 220, 0, 2.2),
-			aida.histogram1D("MTE Analysis/Trident Electron Energy Distribution", 220, 0, 2.2),
-	};
-	private IHistogram1D positronPlot = aida.histogram1D("MTE Analysis/Trident Positron Energy Distribution", 220, 0, 2.2);
-	private IHistogram2D[] energy2DPlot = {
-			aida.histogram2D("MTE Analysis/Møller 2D Energy Distribution", 55, 0, 1.1, 55, 0, 1.1),
-			aida.histogram2D("MTE Analysis/Trident 2D Energy Distribution", 55, 0, 1.1, 55, 0, 1.1),
-	};
-	private IHistogram1D timePlot = aida.histogram1D("MTE Analysis/Track Cluster Time Distribution", 4000, 0, 400);
-	private IHistogram1D timeCoincidencePlot = aida.histogram1D("MTE Analysis/Møller Time Coincidence Distribution", 1000, 0, 100);
-	private IHistogram1D timeCoincidenceAllCutsPlot = aida.histogram1D("MTE Analysis/Møller Time Coincidence Distribution (All Møller Cuts)", 1000, 0, 100);
-	private IHistogram1D negTrackCount = aida.histogram1D("MTE Analysis/All Negative Tracks", 10, -0.5, 9.5);
-	private IHistogram1D posTrackCount = aida.histogram1D("MTE Analysis/All Positive Event Tracks", 10, -0.5, 9.5);
-	private IHistogram1D chargedTrackCount = aida.histogram1D("MTE Analysis/All Event Event Tracks", 10, -0.5, 9.5);
-	
-	private IHistogram1D trInvariantMassAll            = aida.histogram1D("Trident/Invariant Mass",                     1500,   0.0,  1.5);
-	private IHistogram1D trInvariantMassFiducial       = aida.histogram1D("Trident/Invariant Mass (Fiducial Region)",   1500,   0.0,  1.5);
-	private IHistogram1D trTimeCoincidenceAll          = aida.histogram1D("Trident/Time Coincidence",                    300, -15.0, 15.0);
-	private IHistogram1D trTimeCoincidenceFiducial     = aida.histogram1D("Trident/Time Coincidence (Fiducial Region)",  300, -15.0, 15.0);
-	private IHistogram1D trEnergySumAll                = aida.histogram1D("Trident/Energy Sum",                          300,   0.0,  1.5);
-	private IHistogram1D trEnergySumFiducial           = aida.histogram1D("Trident/Energy Sum (Fiducial Region)",        300,   0.0,  1.5);
-	private IHistogram2D trEnergySum2DAll              = aida.histogram2D("Trident/First Cluster Energy vs. Second Cluster Energy",                   300, 0, 1.5, 300,   0, 1.5);
-	private IHistogram2D trEnergySum2DFiducial         = aida.histogram2D("Trident/First Cluster Energy vs. Second Cluster Energy (Fiducial Region)", 300, 0, 1.5, 300,   0, 1.5);
-	private IHistogram2D trSumCoplanarityAll           = aida.histogram2D("Trident/Hardware Coplanarity vs. Energy Sum",                              300, 0, 1.5, 115,   0, 180);
-	private IHistogram2D trSumCoplanarityFiducial      = aida.histogram2D("Trident/Hardware Coplanarity vs. Energy Sum (Fiducial Region)",            300, 0, 1.5, 115,   0, 180);
-	private IHistogram2D trSumCoplanarityCalcAll       = aida.histogram2D("Trident/Calculated Coplanarity vs. Energy Sum",                            300, 0, 1.5, 115, 130, 230);
-	private IHistogram2D trSumCoplanarityCalcFiducial  = aida.histogram2D("Trident/Calculated Coplanarity vs. Energy Sum (Fiducial Region)",          300, 0, 1.5, 115, 130, 230);
-	private IHistogram2D trTimeEnergyAll               = aida.histogram2D("Trident/Cluster Time vs. Cluster Energy",                                  300, 0, 1.5, 100,   0, 100);
-	private IHistogram2D trTimeEnergyFiducial          = aida.histogram2D("Trident/Cluster Time vs. Cluster Energy (Fiducial Region)",                300, 0, 1.5, 100,   0, 100);
-	
-	private TriggerPlotsModule allPlots = new TriggerPlotsModule("All");
-	private TriggerPlotsModule møllerPlots = new TriggerPlotsModule("Møller");
-	private TriggerPlotsModule tridentPlots = new TriggerPlotsModule("Trident");
-	private TriggerPlotsModule elasticPlots = new TriggerPlotsModule("Elastic");
-	private static final int MØLLER  = 0;
-	private static final int TRIDENT = 1;
-	private static final int ELASTIC = 2;
-	private boolean verbose = false;
-	private boolean excludeNoTrackEvents = false;
-	private double timeCoincidenceCut = Double.MAX_VALUE;
-	private Map<String, Integer> møllerBitMap = new HashMap<String, Integer>();
-	private Map<String, Integer> tridentBitMap = new HashMap<String, Integer>();
-	private Map<String, Integer> elasticBitMap = new HashMap<String, Integer>();
-	private int møllerEvents = 0;
-	private int tridentEvents = 0;
-	private int elasticEvents = 0;
-	private int totalEvents = 0;
-	private int pair1Events = 0;
-	private int pair0Events = 0;
-	private int singles1Events = 0;
-	private int singles0Events = 0;
-	private int pulserEvents = 0;
-	
-	@Override
-	public void startOfData() {
-		for(int s0 = 0; s0 <= 1; s0++) {
-			for(int s1 = 0; s1 <= 1; s1++) {
-				for(int p0 = 0; p0 <= 1; p0++) {
-					for(int p1 = 0; p1 <= 1; p1++) {
-						for(int pulser = 0; pulser <=1; pulser++) {
-							// Set each "trigger bit."
-							boolean s0bit = (s0 == 1);
-							boolean s1bit = (s1 == 1);
-							boolean p0bit = (p0 == 1);
-							boolean p1bit = (p1 == 1);
-							boolean pulserBit = (p1 == 1);
-							
-							// Generate the bit string.
-							String bitString = getBitString(s0bit, s1bit, p0bit, p1bit, pulserBit);
-							
-							// Set a default value of zero for this bit combination.
-							møllerBitMap.put(bitString, 1);
-							tridentBitMap.put(bitString, 1);
-							elasticBitMap.put(bitString, 1);
-						}
-					}
-				}
-			}
-		}
-	}
-	
-	@Override
-	public void endOfData() {
-		System.out.println("Møller  Events   :: " + møllerEvents);
-		System.out.println("Trident Events   :: " + tridentEvents);
-		System.out.println("Elastic Events   :: " + elasticEvents);
-		System.out.println("Total Events     :: " + totalEvents);
-		System.out.println("Pair 1 Events    :: " + pair1Events);
-		System.out.println("Pair 0 Events    :: " + pair0Events);
-		System.out.println("Singles 1 Events :: " + singles1Events);
-		System.out.println("Singles 0 Events :: " + singles0Events);
-		System.out.println("Pulser Events    :: " + pulserEvents);
-		
-		System.out.println("Plsr\tS0\tS1\tP0\tP1\tMøller");
-		for(Entry<String, Integer> entry : møllerBitMap.entrySet()) {
-			System.out.println(entry.getKey() + "\t" + entry.getValue());
-		}
-		
-		System.out.println("Plsr\tS0\tS1\tP0\tP1\tTrident");
-		for(Entry<String, Integer> entry : tridentBitMap.entrySet()) {
-			System.out.println(entry.getKey() + "\t" + entry.getValue());
-		}
-		
-		System.out.println("Plsr\tS0\tS1\tP0\tP1\tElastic");
-		for(Entry<String, Integer> entry : elasticBitMap.entrySet()) {
-			System.out.println(entry.getKey() + "\t" + entry.getValue());
-		}
-	}
-	
-	private static final String getBitString(boolean s0, boolean s1, boolean p0, boolean p1, boolean pulser) {
-		return String.format("%d\t%d\t%d\t%d\t%d", (pulser ? 1 : 0), (s0 ? 1 : 0), (s1 ? 1 : 0), (p0 ? 1 : 0), (p1 ? 1 : 0));
-	}
-	
-	@Override
-	public void process(EventHeader event) {
-		// Check whether the SVT was active in this event.
-		final String[] flagNames = { "svt_bias_good", "svt_burstmode_noise_good", "svt_position_good" };
-		boolean svtGood = true;
+    // Define track LCIO information.
+    private boolean skipBadSVT = true;
+    private String bankCollectionName = "TriggerBank";
+    private String particleCollectionName = "FinalStateParticles";
+    private static final AIDA aida = AIDA.defaultInstance();
+    private IHistogram1D[] chargedTracksPlot = {
+            aida.histogram1D("MTE Analysis/Møller Event Tracks", 10, -0.5, 9.5),
+            aida.histogram1D("MTE Analysis/Trident Event Tracks", 10, -0.5, 9.5),
+            aida.histogram1D("MTE Analysis/Elastic Event Tracks", 10, -0.5, 9.5)
+    };
+    private IHistogram1D[] clusterCountPlot = {
+            aida.histogram1D("MTE Analysis/Møller Event Clusters", 10, -0.5, 9.5),
+            aida.histogram1D("MTE Analysis/Trident Event Clusters", 10, -0.5, 9.5),
+            aida.histogram1D("MTE Analysis/Elastic Event Clusters", 10, -0.5, 9.5)
+    };
+    private IHistogram1D[] energyPlot = {
+            aida.histogram1D("MTE Analysis/Møller Energy Sum Distribution", 220, 0, 2.2),
+            aida.histogram1D("MTE Analysis/Trident Energy Sum Distribution", 220, 0, 2.2),
+            aida.histogram1D("MTE Analysis/Elastic Energy Distribution", 110, 0, 1.5)
+    };
+    private IHistogram1D[] electronPlot = {
+            aida.histogram1D("MTE Analysis/Møller Electron Energy Distribution", 220, 0, 2.2),
+            aida.histogram1D("MTE Analysis/Trident Electron Energy Distribution", 220, 0, 2.2),
+    };
+    private IHistogram1D positronPlot = aida.histogram1D("MTE Analysis/Trident Positron Energy Distribution", 220, 0, 2.2);
+    private IHistogram2D[] energy2DPlot = {
+            aida.histogram2D("MTE Analysis/Møller 2D Energy Distribution", 55, 0, 1.1, 55, 0, 1.1),
+            aida.histogram2D("MTE Analysis/Trident 2D Energy Distribution", 55, 0, 1.1, 55, 0, 1.1),
+    };
+    private IHistogram1D timePlot = aida.histogram1D("MTE Analysis/Track Cluster Time Distribution", 4000, 0, 400);
+    private IHistogram1D timeCoincidencePlot = aida.histogram1D("MTE Analysis/Møller Time Coincidence Distribution", 1000, 0, 100);
+    private IHistogram1D timeCoincidenceAllCutsPlot = aida.histogram1D("MTE Analysis/Møller Time Coincidence Distribution (All Møller Cuts)", 1000, 0, 100);
+    private IHistogram1D negTrackCount = aida.histogram1D("MTE Analysis/All Negative Tracks", 10, -0.5, 9.5);
+    private IHistogram1D posTrackCount = aida.histogram1D("MTE Analysis/All Positive Event Tracks", 10, -0.5, 9.5);
+    private IHistogram1D chargedTrackCount = aida.histogram1D("MTE Analysis/All Event Event Tracks", 10, -0.5, 9.5);
+    
+    private IHistogram1D trInvariantMassAll            = aida.histogram1D("Trident/Invariant Mass",                     1500,   0.0,  1.5);
+    private IHistogram1D trInvariantMassFiducial       = aida.histogram1D("Trident/Invariant Mass (Fiducial Region)",   1500,   0.0,  1.5);
+    private IHistogram1D trTimeCoincidenceAll          = aida.histogram1D("Trident/Time Coincidence",                    300, -15.0, 15.0);
+    private IHistogram1D trTimeCoincidenceFiducial     = aida.histogram1D("Trident/Time Coincidence (Fiducial Region)",  300, -15.0, 15.0);
+    private IHistogram1D trEnergySumAll                = aida.histogram1D("Trident/Energy Sum",                          300,   0.0,  1.5);
+    private IHistogram1D trEnergySumFiducial           = aida.histogram1D("Trident/Energy Sum (Fiducial Region)",        300,   0.0,  1.5);
+    private IHistogram2D trEnergySum2DAll              = aida.histogram2D("Trident/First Cluster Energy vs. Second Cluster Energy",                   300, 0, 1.5, 300,   0, 1.5);
+    private IHistogram2D trEnergySum2DFiducial         = aida.histogram2D("Trident/First Cluster Energy vs. Second Cluster Energy (Fiducial Region)", 300, 0, 1.5, 300,   0, 1.5);
+    private IHistogram2D trSumCoplanarityAll           = aida.histogram2D("Trident/Hardware Coplanarity vs. Energy Sum",                              300, 0, 1.5, 115,   0, 180);
+    private IHistogram2D trSumCoplanarityFiducial      = aida.histogram2D("Trident/Hardware Coplanarity vs. Energy Sum (Fiducial Region)",            300, 0, 1.5, 115,   0, 180);
+    private IHistogram2D trSumCoplanarityCalcAll       = aida.histogram2D("Trident/Calculated Coplanarity vs. Energy Sum",                            300, 0, 1.5, 115, 130, 230);
+    private IHistogram2D trSumCoplanarityCalcFiducial  = aida.histogram2D("Trident/Calculated Coplanarity vs. Energy Sum (Fiducial Region)",          300, 0, 1.5, 115, 130, 230);
+    private IHistogram2D trTimeEnergyAll               = aida.histogram2D("Trident/Cluster Time vs. Cluster Energy",                                  300, 0, 1.5, 100,   0, 100);
+    private IHistogram2D trTimeEnergyFiducial          = aida.histogram2D("Trident/Cluster Time vs. Cluster Energy (Fiducial Region)",                300, 0, 1.5, 100,   0, 100);
+    
+    private TriggerPlotsModule allPlots = new TriggerPlotsModule("All");
+    private TriggerPlotsModule møllerPlots = new TriggerPlotsModule("Møller");
+    private TriggerPlotsModule tridentPlots = new TriggerPlotsModule("Trident");
+    private TriggerPlotsModule elasticPlots = new TriggerPlotsModule("Elastic");
+    private static final int MØLLER  = 0;
+    private static final int TRIDENT = 1;
+    private static final int ELASTIC = 2;
+    private boolean verbose = false;
+    private boolean excludeNoTrackEvents = false;
+    private double timeCoincidenceCut = Double.MAX_VALUE;
+    private Map<String, Integer> møllerBitMap = new HashMap<String, Integer>();
+    private Map<String, Integer> tridentBitMap = new HashMap<String, Integer>();
+    private Map<String, Integer> elasticBitMap = new HashMap<String, Integer>();
+    private int møllerEvents = 0;
+    private int tridentEvents = 0;
+    private int elasticEvents = 0;
+    private int totalEvents = 0;
+    private int pair1Events = 0;
+    private int pair0Events = 0;
+    private int singles1Events = 0;
+    private int singles0Events = 0;
+    private int pulserEvents = 0;
+    
+    @Override
+    public void startOfData() {
+        for(int s0 = 0; s0 <= 1; s0++) {
+            for(int s1 = 0; s1 <= 1; s1++) {
+                for(int p0 = 0; p0 <= 1; p0++) {
+                    for(int p1 = 0; p1 <= 1; p1++) {
+                        for(int pulser = 0; pulser <=1; pulser++) {
+                            // Set each "trigger bit."
+                            boolean s0bit = (s0 == 1);
+                            boolean s1bit = (s1 == 1);
+                            boolean p0bit = (p0 == 1);
+                            boolean p1bit = (p1 == 1);
+                            boolean pulserBit = (p1 == 1);
+                            
+                            // Generate the bit string.
+                            String bitString = getBitString(s0bit, s1bit, p0bit, p1bit, pulserBit);
+                            
+                            // Set a default value of zero for this bit combination.
+                            møllerBitMap.put(bitString, 1);
+                            tridentBitMap.put(bitString, 1);
+                            elasticBitMap.put(bitString, 1);
+                        }
+                    }
+                }
+            }
+        }
+    }
+    
+    @Override
+    public void endOfData() {
+        System.out.println("Møller  Events   :: " + møllerEvents);
+        System.out.println("Trident Events   :: " + tridentEvents);
+        System.out.println("Elastic Events   :: " + elasticEvents);
+        System.out.println("Total Events     :: " + totalEvents);
+        System.out.println("Pair 1 Events    :: " + pair1Events);
+        System.out.println("Pair 0 Events    :: " + pair0Events);
+        System.out.println("Singles 1 Events :: " + singles1Events);
+        System.out.println("Singles 0 Events :: " + singles0Events);
+        System.out.println("Pulser Events    :: " + pulserEvents);
+        
+        System.out.println("Plsr\tS0\tS1\tP0\tP1\tMøller");
+        for(Entry<String, Integer> entry : møllerBitMap.entrySet()) {
+            System.out.println(entry.getKey() + "\t" + entry.getValue());
+        }
+        
+        System.out.println("Plsr\tS0\tS1\tP0\tP1\tTrident");
+        for(Entry<String, Integer> entry : tridentBitMap.entrySet()) {
+            System.out.println(entry.getKey() + "\t" + entry.getValue());
+        }
+        
+        System.out.println("Plsr\tS0\tS1\tP0\tP1\tElastic");
+        for(Entry<String, Integer> entry : elasticBitMap.entrySet()) {
+            System.out.println(entry.getKey() + "\t" + entry.getValue());
+        }
+    }
+    
+    private static final String getBitString(boolean s0, boolean s1, boolean p0, boolean p1, boolean pulser) {
+        return String.format("%d\t%d\t%d\t%d\t%d", (pulser ? 1 : 0), (s0 ? 1 : 0), (s1 ? 1 : 0), (p0 ? 1 : 0), (p1 ? 1 : 0));
+    }
+    
+    @Override
+    public void process(EventHeader event) {
+        // Check whether the SVT was active in this event.
+        final String[] flagNames = { "svt_bias_good", "svt_burstmode_noise_good", "svt_position_good" };
+        boolean svtGood = true;
         for(int i = 0; i < flagNames.length; i++) {
             int[] flag = event.getIntegerParameters().get(flagNames[i]);
             if(flag == null || flag[0] == 0) {
@@ -172,437 +172,437 @@
         
         // If the SVT was bad, then skip the event.
         if(!svtGood && skipBadSVT) {
-        	return;
-        }
-        
-		if(event.hasCollection(ReconstructedParticle.class, particleCollectionName)) {
-			// Get the list of tracks.
-			List<ReconstructedParticle> trackList = event.get(ReconstructedParticle.class, particleCollectionName);
-			
-			// Plot the time stamps of all tracks.
-			for(ReconstructedParticle track : trackList) {
-				if(track.getClusters().size() != 0) {
-					Cluster cluster = track.getClusters().get(0);
-					timePlot.fill(cluster.getCalorimeterHits().get(0).getTime());
-				}
-			}
-			
-			if(verbose) {
-				System.out.println(trackList.size() + " tracks found.");
-				for(ReconstructedParticle track : trackList) {
-					System.out.printf("Track :: Q = %4.1f; E = %6.3f%n",
-							track.getCharge(), track.getEnergy());
-				}
-			}
-			
-			// Populate the all cluster plots.
-			List<Cluster> topClusters = new ArrayList<Cluster>();
-			List<Cluster> botClusters = new ArrayList<Cluster>();
-			List<Cluster> clusters = event.get(Cluster.class, "EcalClusters");
-			for(Cluster cluster : clusters) {
-				allPlots.addCluster(cluster);
-				if(cluster.getCalorimeterHits().get(0).getIdentifierFieldValue("iy") > 0) { topClusters.add(cluster); }
-				else { botClusters.add(cluster); }
-			}
-			
-			// Make cluster pairs.
-			List<Cluster[]> clusterPairs = new ArrayList<Cluster[]>();
-			for(Cluster topCluster : topClusters) {
-				for(Cluster botCluster : botClusters) {
-					clusterPairs.add(new Cluster[] { topCluster, botCluster });
-				}
-			}
-			
-			// Populate the all cluster pair plots.
-			for(Cluster[] pair : clusterPairs) {
-				allPlots.addClusterPair(pair);
-			}
-			
-			// Check each of the event-type conditions.
-			boolean isMøller = false;
-			boolean isTrident = false;
-			boolean isElastic = false;
-			
-			// Produce all possible pairs of tracks.
-			List<ReconstructedParticle[]> pairList = getTrackPairs(trackList);
-			
-			// Check the Møller condition. A Møller event is expected
-			// to have two tracks, both negative, with a net energy
-			// within a certain band of the beam energy.
-			møllerTrackLoop:
-			for(ReconstructedParticle[] pair : pairList) {
-				// If trackless events are to be excluded, then require
-				// that each "track" have a real track.
-				if(excludeNoTrackEvents && (pair[0].getTracks().isEmpty() || pair[1].getTracks().isEmpty())) {
-					continue møllerTrackLoop;
-				}
-				
-				// Both tracks are required to be negatively charged.
-				if(pair[0].getCharge() >= 0 || pair[1].getCharge() >= 0) {
-					continue møllerTrackLoop;
-				}
-				
-				// Both tracks must have clusters associated with them.
-				Cluster[] trackClusters = new Cluster[2];
-				for(int i = 0; i < 2; i++) {
-					// Disallow tracks with no associated clusters.
-					if(pair[i].getClusters().size() == 0) {
-						continue møllerTrackLoop;
-					}
-					
-					// Store the first cluster associated with the track.
-					trackClusters[i] = pair[i].getClusters().get(0);
-				}
-				
-				// Require that the track clusters be within a certain
-				// time window of one another.
-				CalorimeterHit[] seeds = new CalorimeterHit[2];
-				seeds[0] = trackClusters[0].getCalorimeterHits().get(0);
-				seeds[1] = trackClusters[1].getCalorimeterHits().get(0);
-				timeCoincidencePlot.fill(Math.abs(seeds[0].getTime() - seeds[1].getTime()));
-				if(Math.abs(trackClusters[0].getCalorimeterHits().get(0).getTime() - trackClusters[1].getCalorimeterHits().get(0).getTime()) > timeCoincidenceCut) {
-					continue møllerTrackLoop;
-				}
-				
-				// Require both tracks to occur within the range of
-				// 36.5 and 49 ns.
-				if(seeds[0].getTime() < 36.5 || seeds[0].getTime() > 49) {
-					continue møllerTrackLoop;
-				} if(seeds[1].getTime() < 36.5 || seeds[1].getTime() > 49) {
-					continue møllerTrackLoop;
-				}
-				
-				// No track may have an energy that exceeds 900 MeV.
-				if(pair[0].getMomentum().magnitude() >= 0.900 || pair[1].getMomentum().magnitude() >= 0.900) {
-					continue møllerTrackLoop;
-				}
-				
-				// Get the energy sum.
-				double sum = VecOp.add(pair[0].getMomentum(), pair[1].getMomentum()).magnitude();
-				
-				// "Møller-like" track pairs must have energies within
-				// an allowed energy range.
-				if(sum < 0.800 || sum > 1.500) {
-					continue møllerTrackLoop;
-				}
-				
-				//timeCoincidenceAllCutsPlot.fill(Math.abs(seeds[0].getTime() - seeds[1].getTime()));
-				
-				// Note that this is a Møller event.
-				isMøller = true;
-				
-				// Populate the Møller plots.
-				energyPlot[MØLLER].fill(sum);
-				møllerPlots.addClusterPair(trackClusters);
-				electronPlot[MØLLER].fill(pair[0].getMomentum().magnitude());
-				electronPlot[MØLLER].fill(pair[1].getMomentum().magnitude());
-				energy2DPlot[MØLLER].fill(pair[0].getMomentum().magnitude(), pair[1].getMomentum().magnitude());
-			}
-			
-			// Check the elastic condition. Elastic events should be
-			// negatively and have an energy approximately equal to
-			// the beam energy.
-			elasticTrackLoop:
-			for(ReconstructedParticle track : trackList) {
-				// If trackless events are to be excluded, then require
-				// that the "track" has a real track.
-				if(excludeNoTrackEvents && track.getTracks().isEmpty()) {
-					continue elasticTrackLoop;
-				}
-				
-				// Check the elastic condition.
-				if(track.getCharge() < 0 && track.getMomentum().magnitude() >= 0.900) {
-					isElastic = true;
-					energyPlot[ELASTIC].fill(track.getMomentum().magnitude());
-					if(!track.getClusters().isEmpty()) {
-						elasticPlots.addCluster(track.getClusters().get(0));
-					}
-				}
-			}
-			
-			// Check the trident condition. Tridents are events that
-			// contain both one positive and one negative track.
-			tridentTrackLoop:
-			for(ReconstructedParticle[] pair : pairList) {
-				// If trackless events are to be excluded, then require
-				// that each "track" have a real track.
-				if(pair[0].getTracks().isEmpty() || pair[1].getTracks().isEmpty()) {
-					continue tridentTrackLoop;
-				}
-				
-				// Require that all tridents consist of a positive and
-				// negative pair.
-				boolean isPosNeg = (pair[0].getCharge() < 0 && pair[1].getCharge() > 0) || (pair[0].getCharge() > 0 && pair[1].getCharge() < 0);
-				if(!isPosNeg) { continue tridentTrackLoop; }
-				
-				// Both tracks must have clusters associated with them.
-				Cluster[] trackClusters = new Cluster[pair.length];
-				for(int i = 0; i < pair.length; i++) {
-					// Disallow tracks with no associated clusters.
-					if(pair[i].getClusters().size() == 0) {
-						continue tridentTrackLoop;
-					}
-					
-					// Store the first cluster associated with the track.
-					trackClusters[i] = pair[i].getClusters().get(0);
-				}
-				
-				// Make sure that the clusters are not the same.
-				if(trackClusters[0] == trackClusters[1]) {
-					continue tridentTrackLoop;
-				}
-				
-				// Require that tridents also be a top/bottom pair.
-				boolean isTopBot = (TriggerModule.getClusterYIndex(trackClusters[0]) > 0 && TriggerModule.getClusterYIndex(trackClusters[1]) < 0)
-						|| (TriggerModule.getClusterYIndex(trackClusters[0]) < 0 && TriggerModule.getClusterYIndex(trackClusters[1]) > 0);
-				if(!isTopBot) {
-					continue tridentTrackLoop;
-				}
-				
-				// Require that the track clusters be within a certain
-				// time window of one another.
-				CalorimeterHit[] seeds = new CalorimeterHit[2];
-				seeds[0] = trackClusters[0].getCalorimeterHits().get(0);
-				seeds[1] = trackClusters[1].getCalorimeterHits().get(0);
-				timeCoincidencePlot.fill(Math.abs(seeds[0].getTime() - seeds[1].getTime()));
-				if(Math.abs(trackClusters[0].getCalorimeterHits().get(0).getTime() - trackClusters[1].getCalorimeterHits().get(0).getTime()) > timeCoincidenceCut) {
-					continue tridentTrackLoop;
-				}
-				
-				// Require that the energy of the electron is below
-				// 900 MeV.
-				boolean electronNotElastic = (pair[0].getCharge() < 0 && pair[0].getMomentum().magnitude() < 0.900)
-						|| (pair[1].getCharge() < 0 && pair[1].getMomentum().magnitude() < 0.900);
-				if(!electronNotElastic) {
-					continue tridentTrackLoop;
-				}
-				
-				// If all tests are passed, this is a trident. Note
-				// this and populate the trident plots.
-				isTrident = true;
-				tridentPlots.addClusterPair(trackClusters);
-				if(pair[0].getCharge() > 0) {
-					positronPlot.fill(pair[1].getMomentum().magnitude());
-					electronPlot[TRIDENT].fill(pair[0].getMomentum().magnitude());
-				} else {
-					positronPlot.fill(pair[0].getMomentum().magnitude());
-					electronPlot[TRIDENT].fill(pair[1].getMomentum().magnitude());
-				}
-				energyPlot[TRIDENT].fill(VecOp.add(pair[0].getMomentum(), pair[1].getMomentum()).magnitude());
-				energy2DPlot[TRIDENT].fill(pair[0].getMomentum().magnitude(), pair[1].getMomentum().magnitude());
-				
-				// Track which clusters have already been added to the
-				// singles plot so that there are no repeats.
-				Set<Cluster> plotSet = new HashSet<Cluster>();
-				Set<Cluster> plotFiducial = new HashSet<Cluster>();
-				
-				// Fill the all pairs plots.
-				double pairEnergy = trackClusters[0].getEnergy() + trackClusters[1].getEnergy();
-				trEnergySumAll.fill(pairEnergy);
-				trEnergySum2DAll.fill(trackClusters[1].getEnergy(), trackClusters[0].getEnergy());
-				trTimeCoincidenceAll.fill(RafoAnalysis.getTimeConicidence(trackClusters));
-				trSumCoplanarityCalcAll.fill(pairEnergy, getCalculatedCoplanarity(trackClusters));
-				trSumCoplanarityAll.fill(pairEnergy, TriggerModule.getValueCoplanarity(trackClusters));
-				trInvariantMassAll.fill(RafoAnalysis.getInvariantMass(pair));
-				
-				// Fill the singles plots.
-				if(!plotSet.contains(trackClusters[0])) {
-					plotSet.add(trackClusters[0]);
-					trTimeEnergyAll.fill(trackClusters[0].getEnergy(), TriggerModule.getClusterTime(trackClusters[0]));
-				} if(!plotSet.contains(trackClusters[1])) {
-					plotSet.add(trackClusters[1]);
-					trTimeEnergyAll.fill(trackClusters[1].getEnergy(), TriggerModule.getClusterTime(trackClusters[1]));
-				}
-				
-				// Fill the fiducial plots if appropriate.
-				if(inFiducialRegion(trackClusters[0]) && inFiducialRegion(trackClusters[1])) {
-					trEnergySumFiducial.fill(pairEnergy);
-					trEnergySum2DFiducial.fill(trackClusters[1].getEnergy(), trackClusters[0].getEnergy());
-					trTimeCoincidenceFiducial.fill(RafoAnalysis.getTimeConicidence(trackClusters));
-					trSumCoplanarityCalcFiducial.fill(pairEnergy, getCalculatedCoplanarity(trackClusters));
-					trSumCoplanarityFiducial.fill(pairEnergy, TriggerModule.getValueCoplanarity(trackClusters));
-					trInvariantMassFiducial.fill(RafoAnalysis.getInvariantMass(pair));
-				}
-				
-				// Fill the singles fiducial plots if appropriate.
-				if(!plotFiducial.contains(trackClusters[0]) && inFiducialRegion(trackClusters[0])) {
-					plotFiducial.add(trackClusters[0]);
-					trTimeEnergyFiducial.fill(trackClusters[0].getEnergy(), TriggerModule.getClusterTime(trackClusters[0]));
-				} if(!plotFiducial.contains(trackClusters[1]) && inFiducialRegion(trackClusters[1])) {
-					plotFiducial.add(trackClusters[1]);
-					trTimeEnergyFiducial.fill(trackClusters[1].getEnergy(), TriggerModule.getClusterTime(trackClusters[1]));
-				}
-			}
-			
-			if(verbose) {
-				System.out.printf("\tMøller  :: %b%n", isMøller);
-				System.out.printf("\tTrident :: %b%n", isTrident);
-				System.out.printf("\tElastic :: %b%n", isElastic);
-				System.out.println();
-			}
-			
-			// Get the TI bits.
-			String bitString = null;
-			TIData tiBank = null;
-			List<GenericObject> bankList = event.get(GenericObject.class, bankCollectionName);
-			for(GenericObject obj : bankList) {
-				if(AbstractIntData.getTag(obj) == TIData.BANK_TAG) {
-					tiBank = new TIData(obj);
-					bitString = getBitString(tiBank.isPulserTrigger(), tiBank.isSingle0Trigger(),
-							tiBank.isSingle1Trigger(), tiBank.isPair0Trigger(), tiBank.isPair1Trigger());
-					
-					if(tiBank.isPair1Trigger()) {
-						pair1Events++;
-					} else if(tiBank.isPair0Trigger()) {
-						pair0Events++;
-					} else if(tiBank.isSingle1Trigger()) {
-						singles1Events++;
-					} else if(tiBank.isSingle0Trigger()) {
-						singles0Events++;
-					} else if(tiBank.isPulserTrigger()) {
-						pulserEvents++;
-					}
-				}
-			}
-			if(bitString == null) {
-				System.out.println("No TI data found!!");
-			}
-			
-			// Get the number of charged tracks in the event.
-			int tracks = 0;
-			int posTracks = 0;
-			int negTracks = 0;
-			for(ReconstructedParticle track : trackList) {
-				if(track.getCharge() != 0 && tiBank.isPulserTrigger()) {
-					if(excludeNoTrackEvents && !track.getTracks().isEmpty()) {
-						tracks++;
-						if(track.getCharge() > 0) { posTracks++; }
-						else { negTracks++; }
-					} else {
-						tracks++;
-						if(track.getCharge() > 0) { posTracks++; }
-						else { negTracks++; }
-					}
-				}
-			}
-			
-			// Populate the "all tracks" plots.
-			posTrackCount.fill(posTracks);
-			negTrackCount.fill(negTracks);
-			chargedTrackCount.fill(tracks);
-			
-			// Add the result to the appropriate plots and increment
-			// the appropriate trigger bit combination.
-			if(isMøller) {
-				møllerEvents++;
-				chargedTracksPlot[MØLLER].fill(tracks);
-				clusterCountPlot[MØLLER].fill(clusters.size());
-				
-				Integer val = møllerBitMap.get(bitString);
-				if(val == null) { møllerBitMap.put(bitString, 1); }
-				else { møllerBitMap.put(bitString, val + 1); }
-			} else if(isTrident) {
-				tridentEvents++;
-				chargedTracksPlot[TRIDENT].fill(tracks);
-				clusterCountPlot[TRIDENT].fill(clusters.size());
-				
-				Integer val = tridentBitMap.get(bitString);
-				if(val == null) { tridentBitMap.put(bitString, 1); }
-				else { tridentBitMap.put(bitString, val + 1); }
-			} else if(isElastic) {
-				elasticEvents++;
-				chargedTracksPlot[ELASTIC].fill(tracks);
-				clusterCountPlot[ELASTIC].fill(clusters.size());
-				
-				Integer val = elasticBitMap.get(bitString);
-				if(val == null) { elasticBitMap.put(bitString, 1); }
-				else { elasticBitMap.put(bitString, val + 1); }
-			}
-			totalEvents++;
-		}
-	}
-	
-	private static final double getCalculatedCoplanarity(Cluster[] pair) {
-		// Define the x- and y-coordinates of the clusters as well as
-		// calorimeter center.
-		final double ORIGIN_X = 42.52;
-		double x[] = { pair[0].getPosition()[0], pair[1].getPosition()[0] };
-		double y[] = { pair[0].getPosition()[1], pair[1].getPosition()[1] };
-		
+            return;
+        }
+        
+        if(event.hasCollection(ReconstructedParticle.class, particleCollectionName)) {
+            // Get the list of tracks.
+            List<ReconstructedParticle> trackList = event.get(ReconstructedParticle.class, particleCollectionName);
+            
+            // Plot the time stamps of all tracks.
+            for(ReconstructedParticle track : trackList) {
+                if(track.getClusters().size() != 0) {
+                    Cluster cluster = track.getClusters().get(0);
+                    timePlot.fill(cluster.getCalorimeterHits().get(0).getTime());
+                }
+            }
+            
+            if(verbose) {
+                System.out.println(trackList.size() + " tracks found.");
+                for(ReconstructedParticle track : trackList) {
+                    System.out.printf("Track :: Q = %4.1f; E = %6.3f%n",
+                            track.getCharge(), track.getEnergy());
+                }
+            }
+            
+            // Populate the all cluster plots.
+            List<Cluster> topClusters = new ArrayList<Cluster>();
+            List<Cluster> botClusters = new ArrayList<Cluster>();
+            List<Cluster> clusters = event.get(Cluster.class, "EcalClusters");
+            for(Cluster cluster : clusters) {
+                allPlots.addCluster(cluster);
+                if(cluster.getCalorimeterHits().get(0).getIdentifierFieldValue("iy") > 0) { topClusters.add(cluster); }
+                else { botClusters.add(cluster); }
+            }
+            
+            // Make cluster pairs.
+            List<Cluster[]> clusterPairs = new ArrayList<Cluster[]>();
+            for(Cluster topCluster : topClusters) {
+                for(Cluster botCluster : botClusters) {
+                    clusterPairs.add(new Cluster[] { topCluster, botCluster });
+                }
+            }
+            
+            // Populate the all cluster pair plots.
+            for(Cluster[] pair : clusterPairs) {
+                allPlots.addClusterPair(pair);
+            }
+            
+            // Check each of the event-type conditions.
+            boolean isMøller = false;
+            boolean isTrident = false;
+            boolean isElastic = false;
+            
+            // Produce all possible pairs of tracks.
+            List<ReconstructedParticle[]> pairList = getTrackPairs(trackList);
+            
+            // Check the Møller condition. A Møller event is expected
+            // to have two tracks, both negative, with a net energy
+            // within a certain band of the beam energy.
+            møllerTrackLoop:
+            for(ReconstructedParticle[] pair : pairList) {
+                // If trackless events are to be excluded, then require
+                // that each "track" have a real track.
+                if(excludeNoTrackEvents && (pair[0].getTracks().isEmpty() || pair[1].getTracks().isEmpty())) {
+                    continue møllerTrackLoop;
+                }
+                
+                // Both tracks are required to be negatively charged.
+                if(pair[0].getCharge() >= 0 || pair[1].getCharge() >= 0) {
+                    continue møllerTrackLoop;
+                }
+                
+                // Both tracks must have clusters associated with them.
+                Cluster[] trackClusters = new Cluster[2];
+                for(int i = 0; i < 2; i++) {
+                    // Disallow tracks with no associated clusters.
+                    if(pair[i].getClusters().size() == 0) {
+                        continue møllerTrackLoop;
+                    }
+                    
+                    // Store the first cluster associated with the track.
+                    trackClusters[i] = pair[i].getClusters().get(0);
+                }
+                
+                // Require that the track clusters be within a certain
+                // time window of one another.
+                CalorimeterHit[] seeds = new CalorimeterHit[2];
+                seeds[0] = trackClusters[0].getCalorimeterHits().get(0);
+                seeds[1] = trackClusters[1].getCalorimeterHits().get(0);
+                timeCoincidencePlot.fill(Math.abs(seeds[0].getTime() - seeds[1].getTime()));
+                if(Math.abs(trackClusters[0].getCalorimeterHits().get(0).getTime() - trackClusters[1].getCalorimeterHits().get(0).getTime()) > timeCoincidenceCut) {
+                    continue møllerTrackLoop;
+                }
+                
+                // Require both tracks to occur within the range of
+                // 36.5 and 49 ns.
+                if(seeds[0].getTime() < 36.5 || seeds[0].getTime() > 49) {
+                    continue møllerTrackLoop;
+                } if(seeds[1].getTime() < 36.5 || seeds[1].getTime() > 49) {
+                    continue møllerTrackLoop;
+                }
+                
+                // No track may have an energy that exceeds 900 MeV.
+                if(pair[0].getMomentum().magnitude() >= 0.900 || pair[1].getMomentum().magnitude() >= 0.900) {
+                    continue møllerTrackLoop;
+                }
+                
+                // Get the energy sum.
+                double sum = VecOp.add(pair[0].getMomentum(), pair[1].getMomentum()).magnitude();
+                
+                // "Møller-like" track pairs must have energies within
+                // an allowed energy range.
+                if(sum < 0.800 || sum > 1.500) {
+                    continue møllerTrackLoop;
+                }
+                
+                //timeCoincidenceAllCutsPlot.fill(Math.abs(seeds[0].getTime() - seeds[1].getTime()));
+                
+                // Note that this is a Møller event.
+                isMøller = true;
+                
+                // Populate the Møller plots.
+                energyPlot[MØLLER].fill(sum);
+                møllerPlots.addClusterPair(trackClusters);
+                electronPlot[MØLLER].fill(pair[0].getMomentum().magnitude());
+                electronPlot[MØLLER].fill(pair[1].getMomentum().magnitude());
+                energy2DPlot[MØLLER].fill(pair[0].getMomentum().magnitude(), pair[1].getMomentum().magnitude());
+            }
+            
+            // Check the elastic condition. Elastic events should be
+            // negatively and have an energy approximately equal to
+            // the beam energy.
+            elasticTrackLoop:
+            for(ReconstructedParticle track : trackList) {
+                // If trackless events are to be excluded, then require
+                // that the "track" has a real track.
+                if(excludeNoTrackEvents && track.getTracks().isEmpty()) {
+                    continue elasticTrackLoop;
+                }
+                
+                // Check the elastic condition.
+                if(track.getCharge() < 0 && track.getMomentum().magnitude() >= 0.900) {
+                    isElastic = true;
+                    energyPlot[ELASTIC].fill(track.getMomentum().magnitude());
+                    if(!track.getClusters().isEmpty()) {
+                        elasticPlots.addCluster(track.getClusters().get(0));
+                    }
+                }
+            }
+            
+            // Check the trident condition. Tridents are events that
+            // contain both one positive and one negative track.
+            tridentTrackLoop:
+            for(ReconstructedParticle[] pair : pairList) {
+                // If trackless events are to be excluded, then require
+                // that each "track" have a real track.
+                if(pair[0].getTracks().isEmpty() || pair[1].getTracks().isEmpty()) {
+                    continue tridentTrackLoop;
+                }
+                
+                // Require that all tridents consist of a positive and
+                // negative pair.
+                boolean isPosNeg = (pair[0].getCharge() < 0 && pair[1].getCharge() > 0) || (pair[0].getCharge() > 0 && pair[1].getCharge() < 0);
+                if(!isPosNeg) { continue tridentTrackLoop; }
+                
+                // Both tracks must have clusters associated with them.
+                Cluster[] trackClusters = new Cluster[pair.length];
+                for(int i = 0; i < pair.length; i++) {
+                    // Disallow tracks with no associated clusters.
+                    if(pair[i].getClusters().size() == 0) {
+                        continue tridentTrackLoop;
+                    }
+                    
+                    // Store the first cluster associated with the track.
+                    trackClusters[i] = pair[i].getClusters().get(0);
+                }
+                
+                // Make sure that the clusters are not the same.
+                if(trackClusters[0] == trackClusters[1]) {
+                    continue tridentTrackLoop;
+                }
+                
+                // Require that tridents also be a top/bottom pair.
+                boolean isTopBot = (TriggerModule.getClusterYIndex(trackClusters[0]) > 0 && TriggerModule.getClusterYIndex(trackClusters[1]) < 0)
+                        || (TriggerModule.getClusterYIndex(trackClusters[0]) < 0 && TriggerModule.getClusterYIndex(trackClusters[1]) > 0);
+                if(!isTopBot) {
+                    continue tridentTrackLoop;
+                }
+                
+                // Require that the track clusters be within a certain
+                // time window of one another.
+                CalorimeterHit[] seeds = new CalorimeterHit[2];
+                seeds[0] = trackClusters[0].getCalorimeterHits().get(0);
+                seeds[1] = trackClusters[1].getCalorimeterHits().get(0);
+                timeCoincidencePlot.fill(Math.abs(seeds[0].getTime() - seeds[1].getTime()));
+                if(Math.abs(trackClusters[0].getCalorimeterHits().get(0).getTime() - trackClusters[1].getCalorimeterHits().get(0).getTime()) > timeCoincidenceCut) {
+                    continue tridentTrackLoop;
+                }
+                
+                // Require that the energy of the electron is below
+                // 900 MeV.
+                boolean electronNotElastic = (pair[0].getCharge() < 0 && pair[0].getMomentum().magnitude() < 0.900)
+                        || (pair[1].getCharge() < 0 && pair[1].getMomentum().magnitude() < 0.900);
+                if(!electronNotElastic) {
+                    continue tridentTrackLoop;
+                }
+                
+                // If all tests are passed, this is a trident. Note
+                // this and populate the trident plots.
+                isTrident = true;
+                tridentPlots.addClusterPair(trackClusters);
+                if(pair[0].getCharge() > 0) {
+                    positronPlot.fill(pair[1].getMomentum().magnitude());
+                    electronPlot[TRIDENT].fill(pair[0].getMomentum().magnitude());
+                } else {
+                    positronPlot.fill(pair[0].getMomentum().magnitude());
+                    electronPlot[TRIDENT].fill(pair[1].getMomentum().magnitude());
+                }
+                energyPlot[TRIDENT].fill(VecOp.add(pair[0].getMomentum(), pair[1].getMomentum()).magnitude());
+                energy2DPlot[TRIDENT].fill(pair[0].getMomentum().magnitude(), pair[1].getMomentum().magnitude());
+                
+                // Track which clusters have already been added to the
+                // singles plot so that there are no repeats.
+                Set<Cluster> plotSet = new HashSet<Cluster>();
+                Set<Cluster> plotFiducial = new HashSet<Cluster>();
+                
+                // Fill the all pairs plots.
+                double pairEnergy = trackClusters[0].getEnergy() + trackClusters[1].getEnergy();
+                trEnergySumAll.fill(pairEnergy);
+                trEnergySum2DAll.fill(trackClusters[1].getEnergy(), trackClusters[0].getEnergy());
+                trTimeCoincidenceAll.fill(RafoAnalysis.getTimeConicidence(trackClusters));
+                trSumCoplanarityCalcAll.fill(pairEnergy, getCalculatedCoplanarity(trackClusters));
+                trSumCoplanarityAll.fill(pairEnergy, TriggerModule.getValueCoplanarity(trackClusters));
+                trInvariantMassAll.fill(RafoAnalysis.getInvariantMass(pair));
+                
+                // Fill the singles plots.
+                if(!plotSet.contains(trackClusters[0])) {
+                    plotSet.add(trackClusters[0]);
+                    trTimeEnergyAll.fill(trackClusters[0].getEnergy(), TriggerModule.getClusterTime(trackClusters[0]));
+                } if(!plotSet.contains(trackClusters[1])) {
+                    plotSet.add(trackClusters[1]);
+                    trTimeEnergyAll.fill(trackClusters[1].getEnergy(), TriggerModule.getClusterTime(trackClusters[1]));
+                }
+                
+                // Fill the fiducial plots if appropriate.
+                if(inFiducialRegion(trackClusters[0]) && inFiducialRegion(trackClusters[1])) {
+                    trEnergySumFiducial.fill(pairEnergy);
+                    trEnergySum2DFiducial.fill(trackClusters[1].getEnergy(), trackClusters[0].getEnergy());
+                    trTimeCoincidenceFiducial.fill(RafoAnalysis.getTimeConicidence(trackClusters));
+                    trSumCoplanarityCalcFiducial.fill(pairEnergy, getCalculatedCoplanarity(trackClusters));
+                    trSumCoplanarityFiducial.fill(pairEnergy, TriggerModule.getValueCoplanarity(trackClusters));
+                    trInvariantMassFiducial.fill(RafoAnalysis.getInvariantMass(pair));
+                }
+                
+                // Fill the singles fiducial plots if appropriate.
+                if(!plotFiducial.contains(trackClusters[0]) && inFiducialRegion(trackClusters[0])) {
+                    plotFiducial.add(trackClusters[0]);
+                    trTimeEnergyFiducial.fill(trackClusters[0].getEnergy(), TriggerModule.getClusterTime(trackClusters[0]));
+                } if(!plotFiducial.contains(trackClusters[1]) && inFiducialRegion(trackClusters[1])) {
+                    plotFiducial.add(trackClusters[1]);
+                    trTimeEnergyFiducial.fill(trackClusters[1].getEnergy(), TriggerModule.getClusterTime(trackClusters[1]));
+                }
+            }
+            
+            if(verbose) {
+                System.out.printf("\tMøller  :: %b%n", isMøller);
+                System.out.printf("\tTrident :: %b%n", isTrident);
+                System.out.printf("\tElastic :: %b%n", isElastic);
+                System.out.println();
+            }
+            
+            // Get the TI bits.
+            String bitString = null;
+            TIData tiBank = null;
+            List<GenericObject> bankList = event.get(GenericObject.class, bankCollectionName);
+            for(GenericObject obj : bankList) {
+                if(AbstractIntData.getTag(obj) == TIData.BANK_TAG) {
+                    tiBank = new TIData(obj);
+                    bitString = getBitString(tiBank.isPulserTrigger(), tiBank.isSingle0Trigger(),
+                            tiBank.isSingle1Trigger(), tiBank.isPair0Trigger(), tiBank.isPair1Trigger());
+                    
+                    if(tiBank.isPair1Trigger()) {
+                        pair1Events++;
+                    } else if(tiBank.isPair0Trigger()) {
+                        pair0Events++;
+                    } else if(tiBank.isSingle1Trigger()) {
+                        singles1Events++;
+                    } else if(tiBank.isSingle0Trigger()) {
+                        singles0Events++;
+                    } else if(tiBank.isPulserTrigger()) {
+                        pulserEvents++;
+                    }
+                }
+            }
+            if(bitString == null) {
+                System.out.println("No TI data found!!");
+            }
+            
+            // Get the number of charged tracks in the event.
+            int tracks = 0;
+            int posTracks = 0;
+            int negTracks = 0;
+            for(ReconstructedParticle track : trackList) {
+                if(track.getCharge() != 0 && tiBank.isPulserTrigger()) {
+                    if(excludeNoTrackEvents && !track.getTracks().isEmpty()) {
+                        tracks++;
+                        if(track.getCharge() > 0) { posTracks++; }
+                        else { negTracks++; }
+                    } else {
+                        tracks++;
+                        if(track.getCharge() > 0) { posTracks++; }
+                        else { negTracks++; }
+                    }
+                }
+            }
+            
+            // Populate the "all tracks" plots.
+            posTrackCount.fill(posTracks);
+            negTrackCount.fill(negTracks);
+            chargedTrackCount.fill(tracks);
+            
+            // Add the result to the appropriate plots and increment
+            // the appropriate trigger bit combination.
+            if(isMøller) {
+                møllerEvents++;
+                chargedTracksPlot[MØLLER].fill(tracks);
+                clusterCountPlot[MØLLER].fill(clusters.size());
+                
+                Integer val = møllerBitMap.get(bitString);
+                if(val == null) { møllerBitMap.put(bitString, 1); }
+                else { møllerBitMap.put(bitString, val + 1); }
+            } else if(isTrident) {
+                tridentEvents++;
+                chargedTracksPlot[TRIDENT].fill(tracks);
+                clusterCountPlot[TRIDENT].fill(clusters.size());
+                
+                Integer val = tridentBitMap.get(bitString);
+                if(val == null) { tridentBitMap.put(bitString, 1); }
+                else { tridentBitMap.put(bitString, val + 1); }
+            } else if(isElastic) {
+                elasticEvents++;
+                chargedTracksPlot[ELASTIC].fill(tracks);
+                clusterCountPlot[ELASTIC].fill(clusters.size());
+                
+                Integer val = elasticBitMap.get(bitString);
+                if(val == null) { elasticBitMap.put(bitString, 1); }
+                else { elasticBitMap.put(bitString, val + 1); }
+            }
+            totalEvents++;
+        }
+    }
+    
+    private static final double getCalculatedCoplanarity(Cluster[] pair) {
+        // Define the x- and y-coordinates of the clusters as well as
+        // calorimeter center.
+        final double ORIGIN_X = 42.52;
+        double x[] = { pair[0].getPosition()[0], pair[1].getPosition()[0] };
+        double y[] = { pair[0].getPosition()[1], pair[1].getPosition()[1] };
+        
         // Get the cluster angles.
         double[] clusterAngle = new double[2];
         for(int i = 0; i < 2; i++) {
-        	clusterAngle[i] = Math.atan2(y[i], x[i] - ORIGIN_X) * 180 / Math.PI;
-        	if(clusterAngle[i] <= 0) { clusterAngle[i] += 360; }
+            clusterAngle[i] = Math.atan2(y[i], x[i] - ORIGIN_X) * 180 / Math.PI;
+            if(clusterAngle[i] <= 0) { clusterAngle[i] += 360; }
         }
         
         // Calculate the coplanarity cut value.
         double clusterDiff = clusterAngle[0] - clusterAngle[1];
         return clusterDiff > 0 ? clusterDiff : clusterDiff + 360;
-	}
-	
-	public void setTimeCoincidenceCut(double value) {
-		timeCoincidenceCut = value;
-	}
-	
-	public void setExcludeNoTrackEvents(boolean state) {
-		excludeNoTrackEvents = state;
-	}
-	
-	public void setSkipBadSVT(boolean state) {
-		skipBadSVT = state;
-	}
-	
-	private static final boolean inFiducialRegion(Cluster cluster) {
-		// Get the x and y indices for the cluster.
-		int ix   = TriggerModule.getClusterXIndex(cluster);
-		int absx = Math.abs(TriggerModule.getClusterXIndex(cluster));
-		int absy = Math.abs(TriggerModule.getClusterYIndex(cluster));
-		
-		// Check if the cluster is on the top or the bottom of the
-		// calorimeter, as defined by |y| == 5. This is an edge cluster
-		// and is not in the fiducial region.
-		if(absy == 5) {
-			return false;
-		}
-		
-		// Check if the cluster is on the extreme left or right side
-		// of the calorimeter, as defined by |x| == 23. This is also
-		// and edge cluster is not in the fiducial region.
-		if(absx == 23) {
-			return false;
-		}
-		
-		// Check if the cluster is along the beam gap, as defined by
-		// |y| == 1. This is an internal edge cluster and is not in the
-		// fiducial region.
-		if(absy == 1) {
-			return false;
-		}
-		
-		// Lastly, check if the cluster falls along the beam hole, as
-		// defined by clusters with -11 <= x <= -1 and |y| == 2. This
-		// is not the fiducial region.
-		if(absy == 2 && ix <= -1 && ix >= -11) {
-			return false;
-		}
-		
-		// If all checks fail, the cluster is in the fiducial region.
-		return true;
-	}
-	
-	private static final List<ReconstructedParticle[]> getTrackPairs(List<ReconstructedParticle> trackList) {
-		// Create an empty list for the pairs.
-		List<ReconstructedParticle[]> pairs = new ArrayList<ReconstructedParticle[]>();
-		
-		// Add all possible pairs of tracks.
-		for(int i = 0; i < trackList.size(); i++) {
-			for(int j = i + 1; j < trackList.size(); j++) {
-				pairs.add(new ReconstructedParticle[] { trackList.get(i), trackList.get(j) });
-			}
-		}
-		
-		// Return the list of tracks.
-		return pairs;
-	}
+    }
+    
+    public void setTimeCoincidenceCut(double value) {
+        timeCoincidenceCut = value;
+    }
+    
+    public void setExcludeNoTrackEvents(boolean state) {
+        excludeNoTrackEvents = state;
+    }
+    
+    public void setSkipBadSVT(boolean state) {
+        skipBadSVT = state;
+    }
+    
+    private static final boolean inFiducialRegion(Cluster cluster) {
+        // Get the x and y indices for the cluster.
+        int ix   = TriggerModule.getClusterXIndex(cluster);
+        int absx = Math.abs(TriggerModule.getClusterXIndex(cluster));
+        int absy = Math.abs(TriggerModule.getClusterYIndex(cluster));
+        
+        // Check if the cluster is on the top or the bottom of the
+        // calorimeter, as defined by |y| == 5. This is an edge cluster
+        // and is not in the fiducial region.
+        if(absy == 5) {
+            return false;
+        }
+        
+        // Check if the cluster is on the extreme left or right side
+        // of the calorimeter, as defined by |x| == 23. This is also
+        // and edge cluster is not in the fiducial region.
+        if(absx == 23) {
+            return false;
+        }
+        
+        // Check if the cluster is along the beam gap, as defined by
+        // |y| == 1. This is an internal edge cluster and is not in the
+        // fiducial region.
+        if(absy == 1) {
+            return false;
+        }
+        
+        // Lastly, check if the cluster falls along the beam hole, as
+        // defined by clusters with -11 <= x <= -1 and |y| == 2. This
+        // is not the fiducial region.
+        if(absy == 2 && ix <= -1 && ix >= -11) {
+            return false;
+        }
+        
+        // If all checks fail, the cluster is in the fiducial region.
+        return true;
+    }
+    
+    private static final List<ReconstructedParticle[]> getTrackPairs(List<ReconstructedParticle> trackList) {
+        // Create an empty list for the pairs.
+        List<ReconstructedParticle[]> pairs = new ArrayList<ReconstructedParticle[]>();
+        
+        // Add all possible pairs of tracks.
+        for(int i = 0; i < trackList.size(); i++) {
+            for(int j = i + 1; j < trackList.size(); j++) {
+                pairs.add(new ReconstructedParticle[] { trackList.get(i), trackList.get(j) });
+            }
+        }
+        
+        // Return the list of tracks.
+        return pairs;
+    }
 }

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/MTETriggerPlotsFormatter.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/MTETriggerPlotsFormatter.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/MTETriggerPlotsFormatter.java	Wed Apr 27 11:11:32 2016
@@ -15,164 +15,164 @@
 
 
 public class MTETriggerPlotsFormatter {
-	public static void main(String[] args) throws IllegalArgumentException, IOException {
-		// Define the root directory for the plots.
-		String rootDir = "D:\\cygwin64\\home\\Kyle\\";
-		
-		// Define the new name of the file containing the trigger plots.
-		String plotFile = rootDir + "5772-ana.aida";
-		
-		// Get the plots file and open it.
-		IAnalysisFactory af = IAnalysisFactory.create();
-		ITree tree = af.createTreeFactory().create(plotFile);
-		if(tree == null) { throw new IllegalArgumentException("Unable to load plot file."); }
-		
-		// Define the 1D trigger plot names for Møllers and tridents.
-		String[] plotNames1D = { "Cluster Hit Count", "Cluster Seed Energy", "Cluster Total Energy",
-				"Pair Coplanarity", "Pair Energy Difference", "Pair Energy Slope", "Pair Energy Sum" };
-		String[] displayNames1D = { "Cluster Hit Count", "Cluster Seed Energy", "Cluster Total Energy",
-				"Pair Coplanarity", "Pair Energy Difference", "Pair Energy Slope", "Pair Energy Sum" };
-		String[] xAxisNames1D = { "Hit Count", "Seed Energy (GeV)", "Total Energy (GeV)",
-				"Coplanarity (Degrees)", "Energy Difference (GeV)", "Energy Slope (GeV)", "Energy Sum (GeV)" };
-		String yAxisName1D = "Count";
-		
-		// Define the 2D trigger plot names for Møllers and tridents.
-		String[] plotNames2D = { "Cluster Seed", "Pair Energy Sum 2D" };
-		String[] displayNames2D = { "Cluster Seed Distribution", "2D Energy Sum" };
-		String[] xAxisNames2D = { "x-Index", "Second Cluster Energy (GeV)" };
-		String[] yAxisNames2D = { "y-Index", "First Cluster Energy (GeV)" };
-		
-		// Define the 1D trigger plot names for elastics.
-		String[] plotNamesElastic1D = { "Cluster Hit Count", "Cluster Seed Energy", "Cluster Total Energy" };
-		String[] displayNamesElastic1D = { "Cluster Hit Count", "Cluster Seed Energy", "Cluster Total Energy" };
-		String[] xAxisNamesElastic1D = { "Hit Count", "Seed Energy (GeV)", "Total Energy (GeV)" };
-		String yAxisNameElastic1D = "Count";
-		
-		// Define the 2D trigger plot names for elastics.
-		String[] plotNamesElastic2D = { "Cluster Seed" };
-		String[] displayNamesElastic2D = { "Cluster Seed Distribution" };
-		String[] xAxisNamesElastic2D = { "x-Index" };
-		String[] yAxisNamesElastic2D = { "y-Index" };
-		
-		// Define the Møller, trident, and elastic prefixes.
-		String allPrefix = "All Trigger Plots/Pair Plots/";
-		String møllerPrefix = "Møller Trigger Plots/Pair Plots/";
-		String tridentPrefix = "Trident Trigger Plots/Pair Plots/";
-		String elasticPrefix = "Elastic Trigger Plots/Singles Plots/";
-		String allSinglesPrefix = "All Trigger Plots/Singles Plots/";
-		
-		// Define the plot type prefix.
-		String allTypeName = "All Pairs - ";
-		String møllerTypeName = "Møller - ";
-		String tridentTypeName = "Trident - ";
-		String elasticTypeName = "Elastic - ";
-		String allSinglesTypeName = "All Singles - ";
-		
-		// Define the plot type colors.
-		ColorStyle allColor = PlotsFormatter.ColorStyle.GREY;
-		ColorStyle møllerColor = PlotsFormatter.ColorStyle.MS_BLUE;
-		ColorStyle tridentColor = PlotsFormatter.ColorStyle.MS_ORANGE;
-		ColorStyle elasticColor = PlotsFormatter.ColorStyle.MS_GREEN;
-		
-		// Create a plot formatting module.
-		PlotFormatModule module = new PlotFormatModule();
-		
-		// Get the histograms and add them to the module. Start with the
-		// trident and Møller plots.
-		for(int i = 0; i < plotNames1D.length; i++) {
-			// Get the Møller and trident plots.
-			IHistogram1D allPlot = (IHistogram1D) tree.find(allPrefix + plotNames1D[i]);
-			IHistogram1D møllerPlot = (IHistogram1D) tree.find(møllerPrefix + plotNames1D[i]);
-			IHistogram1D tridentPlot = (IHistogram1D) tree.find(tridentPrefix + plotNames1D[i]);
-			
-			// Make a formatted plot for each.
-			FormattedPlot1D allFormattedPlot = new FormattedPlot1D(allPlot, allColor, xAxisNames1D[i], yAxisName1D, allTypeName + displayNames1D[i]);
-			FormattedPlot1D møllerFormattedPlot = new FormattedPlot1D(møllerPlot, møllerColor, xAxisNames1D[i], yAxisName1D, møllerTypeName + displayNames1D[i]);
-			FormattedPlot1D tridentFormattedPlot = new FormattedPlot1D(tridentPlot, tridentColor, xAxisNames1D[i], yAxisName1D, tridentTypeName + displayNames1D[i]);
-			
-			// Add them to the module.
-			module.addPlot1D(allFormattedPlot);
-			module.addPlot1D(møllerFormattedPlot);
-			module.addPlot1D(tridentFormattedPlot);
-		}
-		for(int i = 0; i < plotNames2D.length; i++) {
-			// Get the Møller and trident plots.
-			IHistogram2D allPlot = (IHistogram2D) tree.find(allPrefix + plotNames2D[i]);
-			IHistogram2D møllerPlot = (IHistogram2D) tree.find(møllerPrefix + plotNames2D[i]);
-			IHistogram2D tridentPlot = (IHistogram2D) tree.find(tridentPrefix + plotNames2D[i]);
-			
-			// Make a formatted plot for each.
-			FormattedPlot2D allFormattedPlot = new FormattedPlot2D(allPlot, i == 0 ? true : false, xAxisNames2D[i], yAxisNames2D[i], allTypeName + displayNames2D[i]);
-			FormattedPlot2D møllerFormattedPlot = new FormattedPlot2D(møllerPlot, i == 0 ? true : false, xAxisNames2D[i], yAxisNames2D[i], møllerTypeName + displayNames2D[i]);
-			FormattedPlot2D tridentFormattedPlot = new FormattedPlot2D(tridentPlot, i == 0 ? true : false, xAxisNames2D[i], yAxisNames2D[i], tridentTypeName + displayNames2D[i]);
-			
-			// Add them to the module.
-			module.addPlot2D(allFormattedPlot);
-			module.addPlot2D(møllerFormattedPlot);
-			module.addPlot2D(tridentFormattedPlot);
-		}
-		
-		// Get the histograms for the elastic plots and add them to the module.
-		for(int i = 0; i < plotNamesElastic1D.length; i++) {
-			// Get the Møller and trident plots.
-			IHistogram1D allPlot = (IHistogram1D) tree.find(allSinglesPrefix + plotNames1D[i]);
-			IHistogram1D elasticPlot = (IHistogram1D) tree.find(elasticPrefix + plotNames1D[i]);
-			
-			// Make a formatted plot for each.
-			FormattedPlot1D allFormattedPlot = new FormattedPlot1D(allPlot, allColor, xAxisNamesElastic1D[i], yAxisNameElastic1D,
-					allSinglesTypeName + displayNamesElastic1D[i]);
-			FormattedPlot1D elasticFormattedPlot = new FormattedPlot1D(elasticPlot, elasticColor, xAxisNamesElastic1D[i], yAxisNameElastic1D,
-					elasticTypeName + displayNamesElastic1D[i]);
-			
-			// Add them to the module.
-			module.addPlot1D(allFormattedPlot);
-			module.addPlot1D(elasticFormattedPlot);
-		}
-		for(int i = 0; i < plotNamesElastic2D.length; i++) {
-			// Get the Møller and trident plots.
-			IHistogram2D allPlot = (IHistogram2D) tree.find(allPrefix + plotNamesElastic2D[i]);
-			IHistogram2D elasticPlot = (IHistogram2D) tree.find(møllerPrefix + plotNamesElastic2D[i]);
-			
-			// Make a formatted plot for each.
-			FormattedPlot2D allFormattedPlot = new FormattedPlot2D(allPlot, i == 0 ? true : false, xAxisNamesElastic2D[i], yAxisNamesElastic2D[i],
-					allSinglesTypeName + plotNames2D[i]);
-			FormattedPlot2D elasticFormattedPlot = new FormattedPlot2D(elasticPlot, i == 0 ? true : false, xAxisNamesElastic2D[i], yAxisNamesElastic2D[i],
-					elasticTypeName + displayNamesElastic2D[i]);
-			
-			// Add them to the module.
-			module.addPlot2D(allFormattedPlot);
-			module.addPlot2D(elasticFormattedPlot);
-		}
-		
-		// Add the MTE plots to the module.
-		module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MTE Analysis/Elastic Energy Distribution"), elasticColor,
-				"Momentum (GeV)", "Count", "Elastic - Momentum"));
-		module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MTE Analysis/Elastic Event Tracks"), elasticColor,
-				"Tracks", "Count", "Elastic - Tracks in Event"));
-		
-		module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MTE Analysis/Møller Energy Sum Distribution"), møllerColor,
-				"Momentum Sum (GeV)", "Count", "Møller - Momentum Sum"));
-		module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MTE Analysis/Møller Electron Energy Distribution"), møllerColor,
-				"Momentum (GeV)", "Count", "Møller - Momentum (Electron)"));
-		module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MTE Analysis/Møller Time Coincidence Distribution (All Møller Cuts)"), møllerColor,
-				"Time (ns)", "Count", "Møller - Time Coincidence"));
-		module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MTE Analysis/Møller Event Tracks"), møllerColor,
-				"Tracks", "Count", "Møller - Tracks in Event"));
-		module.addPlot2D(new FormattedPlot2D((IHistogram2D) tree.find("MTE Analysis/Møller 2D Energy Distribution"), false,
-				"First Track Momentum (GeV)", "Second Track Momentum (GeV)", "Møller - 2D Momentum Sum"));
-		
-		module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MTE Analysis/Trident Energy Sum Distribution"), tridentColor,
-				"Momentum Sum (GeV)", "Count", "Trident - Momentum Sum"));
-		module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MTE Analysis/Trident Electron Energy Distribution"), tridentColor,
-				"Momentum (GeV)", "Count", "Trident - Momentum (Electron)"));
-		module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MTE Analysis/Trident Positron Energy Distribution"), tridentColor,
-				"Momentum (GeV)", "Count", "Trident - Momentum (Positron)"));
-		module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MTE Analysis/Trident Event Tracks"), tridentColor,
-				"Tracks", "Count", "Trident - Tracks in Event"));
-		module.addPlot2D(new FormattedPlot2D((IHistogram2D) tree.find("MTE Analysis/Trident 2D Energy Distribution"), false,
-				"First Track Momentum (GeV)", "Second Track Momentum (GeV)", "Trident - 2D Momentum Sum"));
-		
-		// Display the plots.
-		module.savePlots("C:\\Users\\Kyle\\Desktop\\EnergyShift\\TestPrint\\");
-	}
+    public static void main(String[] args) throws IllegalArgumentException, IOException {
+        // Define the root directory for the plots.
+        String rootDir = "D:\\cygwin64\\home\\Kyle\\";
+        
+        // Define the new name of the file containing the trigger plots.
+        String plotFile = rootDir + "5772-ana.aida";
+        
+        // Get the plots file and open it.
+        IAnalysisFactory af = IAnalysisFactory.create();
+        ITree tree = af.createTreeFactory().create(plotFile);
+        if(tree == null) { throw new IllegalArgumentException("Unable to load plot file."); }
+        
+        // Define the 1D trigger plot names for Møllers and tridents.
+        String[] plotNames1D = { "Cluster Hit Count", "Cluster Seed Energy", "Cluster Total Energy",
+                "Pair Coplanarity", "Pair Energy Difference", "Pair Energy Slope", "Pair Energy Sum" };
+        String[] displayNames1D = { "Cluster Hit Count", "Cluster Seed Energy", "Cluster Total Energy",
+                "Pair Coplanarity", "Pair Energy Difference", "Pair Energy Slope", "Pair Energy Sum" };
+        String[] xAxisNames1D = { "Hit Count", "Seed Energy (GeV)", "Total Energy (GeV)",
+                "Coplanarity (Degrees)", "Energy Difference (GeV)", "Energy Slope (GeV)", "Energy Sum (GeV)" };
+        String yAxisName1D = "Count";
+        
+        // Define the 2D trigger plot names for Møllers and tridents.
+        String[] plotNames2D = { "Cluster Seed", "Pair Energy Sum 2D" };
+        String[] displayNames2D = { "Cluster Seed Distribution", "2D Energy Sum" };
+        String[] xAxisNames2D = { "x-Index", "Second Cluster Energy (GeV)" };
+        String[] yAxisNames2D = { "y-Index", "First Cluster Energy (GeV)" };
+        
+        // Define the 1D trigger plot names for elastics.
+        String[] plotNamesElastic1D = { "Cluster Hit Count", "Cluster Seed Energy", "Cluster Total Energy" };
+        String[] displayNamesElastic1D = { "Cluster Hit Count", "Cluster Seed Energy", "Cluster Total Energy" };
+        String[] xAxisNamesElastic1D = { "Hit Count", "Seed Energy (GeV)", "Total Energy (GeV)" };
+        String yAxisNameElastic1D = "Count";
+        
+        // Define the 2D trigger plot names for elastics.
+        String[] plotNamesElastic2D = { "Cluster Seed" };
+        String[] displayNamesElastic2D = { "Cluster Seed Distribution" };
+        String[] xAxisNamesElastic2D = { "x-Index" };
+        String[] yAxisNamesElastic2D = { "y-Index" };
+        
+        // Define the Møller, trident, and elastic prefixes.
+        String allPrefix = "All Trigger Plots/Pair Plots/";
+        String møllerPrefix = "Møller Trigger Plots/Pair Plots/";
+        String tridentPrefix = "Trident Trigger Plots/Pair Plots/";
+        String elasticPrefix = "Elastic Trigger Plots/Singles Plots/";
+        String allSinglesPrefix = "All Trigger Plots/Singles Plots/";
+        
+        // Define the plot type prefix.
+        String allTypeName = "All Pairs - ";
+        String møllerTypeName = "Møller - ";
+        String tridentTypeName = "Trident - ";
+        String elasticTypeName = "Elastic - ";
+        String allSinglesTypeName = "All Singles - ";
+        
+        // Define the plot type colors.
+        ColorStyle allColor = PlotsFormatter.ColorStyle.GREY;
+        ColorStyle møllerColor = PlotsFormatter.ColorStyle.MS_BLUE;
+        ColorStyle tridentColor = PlotsFormatter.ColorStyle.MS_ORANGE;
+        ColorStyle elasticColor = PlotsFormatter.ColorStyle.MS_GREEN;
+        
+        // Create a plot formatting module.
+        PlotFormatModule module = new PlotFormatModule();
+        
+        // Get the histograms and add them to the module. Start with the
+        // trident and Møller plots.
+        for(int i = 0; i < plotNames1D.length; i++) {
+            // Get the Møller and trident plots.
+            IHistogram1D allPlot = (IHistogram1D) tree.find(allPrefix + plotNames1D[i]);
+            IHistogram1D møllerPlot = (IHistogram1D) tree.find(møllerPrefix + plotNames1D[i]);
+            IHistogram1D tridentPlot = (IHistogram1D) tree.find(tridentPrefix + plotNames1D[i]);
+            
+            // Make a formatted plot for each.
+            FormattedPlot1D allFormattedPlot = new FormattedPlot1D(allPlot, allColor, xAxisNames1D[i], yAxisName1D, allTypeName + displayNames1D[i]);
+            FormattedPlot1D møllerFormattedPlot = new FormattedPlot1D(møllerPlot, møllerColor, xAxisNames1D[i], yAxisName1D, møllerTypeName + displayNames1D[i]);
+            FormattedPlot1D tridentFormattedPlot = new FormattedPlot1D(tridentPlot, tridentColor, xAxisNames1D[i], yAxisName1D, tridentTypeName + displayNames1D[i]);
+            
+            // Add them to the module.
+            module.addPlot1D(allFormattedPlot);
+            module.addPlot1D(møllerFormattedPlot);
+            module.addPlot1D(tridentFormattedPlot);
+        }
+        for(int i = 0; i < plotNames2D.length; i++) {
+            // Get the Møller and trident plots.
+            IHistogram2D allPlot = (IHistogram2D) tree.find(allPrefix + plotNames2D[i]);
+            IHistogram2D møllerPlot = (IHistogram2D) tree.find(møllerPrefix + plotNames2D[i]);
+            IHistogram2D tridentPlot = (IHistogram2D) tree.find(tridentPrefix + plotNames2D[i]);
+            
+            // Make a formatted plot for each.
+            FormattedPlot2D allFormattedPlot = new FormattedPlot2D(allPlot, i == 0 ? true : false, xAxisNames2D[i], yAxisNames2D[i], allTypeName + displayNames2D[i]);
+            FormattedPlot2D møllerFormattedPlot = new FormattedPlot2D(møllerPlot, i == 0 ? true : false, xAxisNames2D[i], yAxisNames2D[i], møllerTypeName + displayNames2D[i]);
+            FormattedPlot2D tridentFormattedPlot = new FormattedPlot2D(tridentPlot, i == 0 ? true : false, xAxisNames2D[i], yAxisNames2D[i], tridentTypeName + displayNames2D[i]);
+            
+            // Add them to the module.
+            module.addPlot2D(allFormattedPlot);
+            module.addPlot2D(møllerFormattedPlot);
+            module.addPlot2D(tridentFormattedPlot);
+        }
+        
+        // Get the histograms for the elastic plots and add them to the module.
+        for(int i = 0; i < plotNamesElastic1D.length; i++) {
+            // Get the Møller and trident plots.
+            IHistogram1D allPlot = (IHistogram1D) tree.find(allSinglesPrefix + plotNames1D[i]);
+            IHistogram1D elasticPlot = (IHistogram1D) tree.find(elasticPrefix + plotNames1D[i]);
+            
+            // Make a formatted plot for each.
+            FormattedPlot1D allFormattedPlot = new FormattedPlot1D(allPlot, allColor, xAxisNamesElastic1D[i], yAxisNameElastic1D,
+                    allSinglesTypeName + displayNamesElastic1D[i]);
+            FormattedPlot1D elasticFormattedPlot = new FormattedPlot1D(elasticPlot, elasticColor, xAxisNamesElastic1D[i], yAxisNameElastic1D,
+                    elasticTypeName + displayNamesElastic1D[i]);
+            
+            // Add them to the module.
+            module.addPlot1D(allFormattedPlot);
+            module.addPlot1D(elasticFormattedPlot);
+        }
+        for(int i = 0; i < plotNamesElastic2D.length; i++) {
+            // Get the Møller and trident plots.
+            IHistogram2D allPlot = (IHistogram2D) tree.find(allPrefix + plotNamesElastic2D[i]);
+            IHistogram2D elasticPlot = (IHistogram2D) tree.find(møllerPrefix + plotNamesElastic2D[i]);
+            
+            // Make a formatted plot for each.
+            FormattedPlot2D allFormattedPlot = new FormattedPlot2D(allPlot, i == 0 ? true : false, xAxisNamesElastic2D[i], yAxisNamesElastic2D[i],
+                    allSinglesTypeName + plotNames2D[i]);
+            FormattedPlot2D elasticFormattedPlot = new FormattedPlot2D(elasticPlot, i == 0 ? true : false, xAxisNamesElastic2D[i], yAxisNamesElastic2D[i],
+                    elasticTypeName + displayNamesElastic2D[i]);
+            
+            // Add them to the module.
+            module.addPlot2D(allFormattedPlot);
+            module.addPlot2D(elasticFormattedPlot);
+        }
+        
+        // Add the MTE plots to the module.
+        module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MTE Analysis/Elastic Energy Distribution"), elasticColor,
+                "Momentum (GeV)", "Count", "Elastic - Momentum"));
+        module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MTE Analysis/Elastic Event Tracks"), elasticColor,
+                "Tracks", "Count", "Elastic - Tracks in Event"));
+        
+        module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MTE Analysis/Møller Energy Sum Distribution"), møllerColor,
+                "Momentum Sum (GeV)", "Count", "Møller - Momentum Sum"));
+        module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MTE Analysis/Møller Electron Energy Distribution"), møllerColor,
+                "Momentum (GeV)", "Count", "Møller - Momentum (Electron)"));
+        module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MTE Analysis/Møller Time Coincidence Distribution (All Møller Cuts)"), møllerColor,
+                "Time (ns)", "Count", "Møller - Time Coincidence"));
+        module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MTE Analysis/Møller Event Tracks"), møllerColor,
+                "Tracks", "Count", "Møller - Tracks in Event"));
+        module.addPlot2D(new FormattedPlot2D((IHistogram2D) tree.find("MTE Analysis/Møller 2D Energy Distribution"), false,
+                "First Track Momentum (GeV)", "Second Track Momentum (GeV)", "Møller - 2D Momentum Sum"));
+        
+        module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MTE Analysis/Trident Energy Sum Distribution"), tridentColor,
+                "Momentum Sum (GeV)", "Count", "Trident - Momentum Sum"));
+        module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MTE Analysis/Trident Electron Energy Distribution"), tridentColor,
+                "Momentum (GeV)", "Count", "Trident - Momentum (Electron)"));
+        module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MTE Analysis/Trident Positron Energy Distribution"), tridentColor,
+                "Momentum (GeV)", "Count", "Trident - Momentum (Positron)"));
+        module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MTE Analysis/Trident Event Tracks"), tridentColor,
+                "Tracks", "Count", "Trident - Tracks in Event"));
+        module.addPlot2D(new FormattedPlot2D((IHistogram2D) tree.find("MTE Analysis/Trident 2D Energy Distribution"), false,
+                "First Track Momentum (GeV)", "Second Track Momentum (GeV)", "Trident - 2D Momentum Sum"));
+        
+        // Display the plots.
+        module.savePlots("C:\\Users\\Kyle\\Desktop\\EnergyShift\\TestPrint\\");
+    }
 }

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/ParticleMCAnalysisDriver.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/ParticleMCAnalysisDriver.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/ParticleMCAnalysisDriver.java	Wed Apr 27 11:11:32 2016
@@ -13,136 +13,136 @@
 import org.lcsim.util.aida.AIDA;
 
 public class ParticleMCAnalysisDriver extends Driver {
-	// Store collection names.
-	private String particleCollectionName = "MCParticle";
-	
-	// Declare plots.
-	private AIDA aida = AIDA.defaultInstance();
-	private IHistogram1D chargedTracksPlot = aida.histogram1D("MC Analysis/Event Tracks", 10, -0.5, 9.5);
-	private IHistogram1D allPlot = aida.histogram1D("MC Analysis/Electron Energy Distribution", 110, 0, 1.1);
-	private IHistogram1D electronPlot = aida.histogram1D("MC Analysis/Electron Energy Distribution", 110, 0, 1.1);
-	private IHistogram1D positronPlot = aida.histogram1D("MC Analysis/Positron Energy Distribution", 110, 0, 1.1);
-	private IHistogram1D momentumXPlot = aida.histogram1D("MC Analysis/Particle x-Momentum Distribution", 110, 0.0, 1.1);
-	private IHistogram1D momentumYPlot = aida.histogram1D("MC Analysis/Particle y-Momentum Distribution", 110, 0.0, 1.1);
-	private IHistogram1D momentumZPlot = aida.histogram1D("MC Analysis/Particle z-Momentum Distribution", 110, 0.0, 1.1);
-	private IHistogram1D epAnglePlot = aida.histogram1D("MC Analysis/Positron\\Electron Pair Angle Distribution", 90, 0, 180);
-	private IHistogram1D eeAnglePlot = aida.histogram1D("MC Analysis/Electron\\Electron Pair Angle Distribution", 90, 0, 180);
-	private IHistogram1D epMomentumSumPlot = aida.histogram1D("MC Analysis/Positron\\Electron Momentum Sum Distribution", 220, 0, 2.2);
-	private IHistogram1D eeMomentumSumPlot = aida.histogram1D("MC Analysis/Electron\\Electron Momentum Sum Distribution", 220, 0, 2.2);
-	private IHistogram2D momentumPlot = aida.histogram2D("MC Analysis/Particle Momentum Distribution", 100, 0.0, 0.40, 110, 0.0, 0.40);
-	private IHistogram2D epMomentumSum2DPlot = aida.histogram2D("MC Analysis/Positron\\Electron 2D Momentum Distribution", 55, 0, 1.1, 55, 0, 1.1);
-	private IHistogram2D eeMomentumSum2DPlot = aida.histogram2D("MC Analysis/Electron\\Electron 2D Momentum Distribution", 55, 0, 1.1, 55, 0, 1.1);
-	
-	@Override
-	public void process(EventHeader event) {
-		// Skip the event if there is no Monte Carlo collection.
-		if(!event.hasCollection(MCParticle.class, particleCollectionName)) {
-			return;
-		}
-		
-		// Get the list of Monte Carlo particles.
-		List<MCParticle> particleList = event.get(MCParticle.class, particleCollectionName);
-		
-		// Track the positive and negative particles.
-		List<MCParticle> electronList = new ArrayList<MCParticle>();
-		List<MCParticle> positronList = new ArrayList<MCParticle>();
-		
-		// Count the number of particles in the event.
-		int chargedParticles = 0;
-		
-		// Iterate through the particles.
-		for(MCParticle particle : particleList) {
-			// Look at only t = 0 particles.
-			if(particle.getProductionTime() == 0) {
-				// Plot the x/y momentum of each particle.
-				momentumPlot.fill(particle.getMomentum().x(), particle.getMomentum().y());
-				
-				// If the particle is charged, increment the charged
-				// particle count.
-				if(particle.getCharge() > 0) {
-					chargedParticles++;
-				}
-				
-				// Get the particle momentum in each direction.
-				momentumXPlot.fill(particle.getMomentum().x());
-				momentumYPlot.fill(particle.getMomentum().y());
-				momentumZPlot.fill(particle.getMomentum().z());
-				
-				// Populate the general momentum plot.
-				allPlot.fill(particle.getMomentum().magnitude());
-				momentumPlot.fill(particle.getMomentum().x(), particle.getMomentum().y());
-				
-				// Store each particle based on its PID and populate
-				// the appropriate plot.
-				if(particle.getPDGID() == 11) {
-					electronList.add(particle);
-					electronPlot.fill(particle.getMomentum().magnitude());
-				} else if(particle.getPDGID() == -11) {
-					positronList.add(particle);
-					positronPlot.fill(particle.getMomentum().magnitude());
-				}
-			}
-		}
-		
-		// Populate the charged particles plot.
-		chargedTracksPlot.fill(chargedParticles);
-		
-		// Form all electron/positron pairs.
-		List<MCParticle[]> epPairList = new ArrayList<MCParticle[]>();
-		for(MCParticle electron : electronList) {
-			for(MCParticle positron : positronList) {
-				epPairList.add(new MCParticle[] { electron, positron });
-			}
-		}
-		
-		// Populate the positron/electron pair plots.
-		for(MCParticle[] pair : epPairList) {
-			epAnglePlot.fill(getVectorAngle(pair[0].getMomentum(), pair[1].getMomentum()));
-			epMomentumSumPlot.fill(getVectorSum(pair[0].getMomentum(), pair[1].getMomentum()));
-			epMomentumSum2DPlot.fill(pair[0].getMomentum().magnitude(), pair[1].getMomentum().magnitude());
-		}
-		
-		// Form all electron/electron pairs.
-		List<MCParticle[]> eePairList = new ArrayList<MCParticle[]>();
-		for(int i = 0; i < electronList.size(); i++) {
-			for(int j = i + 1; j < electronList.size(); j++) {
-				eePairList.add(new MCParticle[] { electronList.get(i), electronList.get(j) });
-			}
-		}
-		
-		// Populate the electron/electron pair plots.
-		for(MCParticle[] pair : eePairList) {
-			eeAnglePlot.fill(getVectorAngle(pair[0].getMomentum(), pair[1].getMomentum()));
-			eeMomentumSumPlot.fill(getVectorSum(pair[0].getMomentum(), pair[1].getMomentum()));
-			eeMomentumSum2DPlot.fill(pair[0].getMomentum().magnitude(), pair[1].getMomentum().magnitude());
-		}
-	}
-	
-	private static final double getVectorSum(Hep3Vector v1, Hep3Vector v2) {
-		// Calculate the sum of the sum of the vector components, squared.
-		double sum = 0;
-		for(int i = 0; i < 3; i++) {
-			double elementSum = v1.v()[i] + v2.v()[i];
-			sum += (elementSum * elementSum);
-		}
-		
-		// Return the square root of the sum.
-		return Math.sqrt(sum);
-	}
-	
-	private static final double getVectorAngle(Hep3Vector v1, Hep3Vector v2) {
-		// The vector angle is defined as Acos[(v1 · v2) / (‖v1‖ × ‖v2‖)]
-		return Math.acos(getDotProduct(v1, v2) / (v1.magnitude() * v2.magnitude())) / Math.PI * 180.0;
-	}
-	
-	private static final double getDotProduct(Hep3Vector v1, Hep3Vector v2) {
-		// Calculate the sum of the vector element products.
-		int product = 0;
-		for(int i = 0; i < 3; i++) {
-			product += (v1.v()[i] * v2.v()[i]);
-		}
-		
-		// Return the result.
-		return product;
-	}
+    // Store collection names.
+    private String particleCollectionName = "MCParticle";
+    
+    // Declare plots.
+    private AIDA aida = AIDA.defaultInstance();
+    private IHistogram1D chargedTracksPlot = aida.histogram1D("MC Analysis/Event Tracks", 10, -0.5, 9.5);
+    private IHistogram1D allPlot = aida.histogram1D("MC Analysis/Electron Energy Distribution", 110, 0, 1.1);
+    private IHistogram1D electronPlot = aida.histogram1D("MC Analysis/Electron Energy Distribution", 110, 0, 1.1);
+    private IHistogram1D positronPlot = aida.histogram1D("MC Analysis/Positron Energy Distribution", 110, 0, 1.1);
+    private IHistogram1D momentumXPlot = aida.histogram1D("MC Analysis/Particle x-Momentum Distribution", 110, 0.0, 1.1);
+    private IHistogram1D momentumYPlot = aida.histogram1D("MC Analysis/Particle y-Momentum Distribution", 110, 0.0, 1.1);
+    private IHistogram1D momentumZPlot = aida.histogram1D("MC Analysis/Particle z-Momentum Distribution", 110, 0.0, 1.1);
+    private IHistogram1D epAnglePlot = aida.histogram1D("MC Analysis/Positron\\Electron Pair Angle Distribution", 90, 0, 180);
+    private IHistogram1D eeAnglePlot = aida.histogram1D("MC Analysis/Electron\\Electron Pair Angle Distribution", 90, 0, 180);
+    private IHistogram1D epMomentumSumPlot = aida.histogram1D("MC Analysis/Positron\\Electron Momentum Sum Distribution", 220, 0, 2.2);
+    private IHistogram1D eeMomentumSumPlot = aida.histogram1D("MC Analysis/Electron\\Electron Momentum Sum Distribution", 220, 0, 2.2);
+    private IHistogram2D momentumPlot = aida.histogram2D("MC Analysis/Particle Momentum Distribution", 100, 0.0, 0.40, 110, 0.0, 0.40);
+    private IHistogram2D epMomentumSum2DPlot = aida.histogram2D("MC Analysis/Positron\\Electron 2D Momentum Distribution", 55, 0, 1.1, 55, 0, 1.1);
+    private IHistogram2D eeMomentumSum2DPlot = aida.histogram2D("MC Analysis/Electron\\Electron 2D Momentum Distribution", 55, 0, 1.1, 55, 0, 1.1);
+    
+    @Override
+    public void process(EventHeader event) {
+        // Skip the event if there is no Monte Carlo collection.
+        if(!event.hasCollection(MCParticle.class, particleCollectionName)) {
+            return;
+        }
+        
+        // Get the list of Monte Carlo particles.
+        List<MCParticle> particleList = event.get(MCParticle.class, particleCollectionName);
+        
+        // Track the positive and negative particles.
+        List<MCParticle> electronList = new ArrayList<MCParticle>();
+        List<MCParticle> positronList = new ArrayList<MCParticle>();
+        
+        // Count the number of particles in the event.
+        int chargedParticles = 0;
+        
+        // Iterate through the particles.
+        for(MCParticle particle : particleList) {
+            // Look at only t = 0 particles.
+            if(particle.getProductionTime() == 0) {
+                // Plot the x/y momentum of each particle.
+                momentumPlot.fill(particle.getMomentum().x(), particle.getMomentum().y());
+                
+                // If the particle is charged, increment the charged
+                // particle count.
+                if(particle.getCharge() > 0) {
+                    chargedParticles++;
+                }
+                
+                // Get the particle momentum in each direction.
+                momentumXPlot.fill(particle.getMomentum().x());
+                momentumYPlot.fill(particle.getMomentum().y());
+                momentumZPlot.fill(particle.getMomentum().z());
+                
+                // Populate the general momentum plot.
+                allPlot.fill(particle.getMomentum().magnitude());
+                momentumPlot.fill(particle.getMomentum().x(), particle.getMomentum().y());
+                
+                // Store each particle based on its PID and populate
+                // the appropriate plot.
+                if(particle.getPDGID() == 11) {
+                    electronList.add(particle);
+                    electronPlot.fill(particle.getMomentum().magnitude());
+                } else if(particle.getPDGID() == -11) {
+                    positronList.add(particle);
+                    positronPlot.fill(particle.getMomentum().magnitude());
+                }
+            }
+        }
+        
+        // Populate the charged particles plot.
+        chargedTracksPlot.fill(chargedParticles);
+        
+        // Form all electron/positron pairs.
+        List<MCParticle[]> epPairList = new ArrayList<MCParticle[]>();
+        for(MCParticle electron : electronList) {
+            for(MCParticle positron : positronList) {
+                epPairList.add(new MCParticle[] { electron, positron });
+            }
+        }
+        
+        // Populate the positron/electron pair plots.
+        for(MCParticle[] pair : epPairList) {
+            epAnglePlot.fill(getVectorAngle(pair[0].getMomentum(), pair[1].getMomentum()));
+            epMomentumSumPlot.fill(getVectorSum(pair[0].getMomentum(), pair[1].getMomentum()));
+            epMomentumSum2DPlot.fill(pair[0].getMomentum().magnitude(), pair[1].getMomentum().magnitude());
+        }
+        
+        // Form all electron/electron pairs.
+        List<MCParticle[]> eePairList = new ArrayList<MCParticle[]>();
+        for(int i = 0; i < electronList.size(); i++) {
+            for(int j = i + 1; j < electronList.size(); j++) {
+                eePairList.add(new MCParticle[] { electronList.get(i), electronList.get(j) });
+            }
+        }
+        
+        // Populate the electron/electron pair plots.
+        for(MCParticle[] pair : eePairList) {
+            eeAnglePlot.fill(getVectorAngle(pair[0].getMomentum(), pair[1].getMomentum()));
+            eeMomentumSumPlot.fill(getVectorSum(pair[0].getMomentum(), pair[1].getMomentum()));
+            eeMomentumSum2DPlot.fill(pair[0].getMomentum().magnitude(), pair[1].getMomentum().magnitude());
+        }
+    }
+    
+    private static final double getVectorSum(Hep3Vector v1, Hep3Vector v2) {
+        // Calculate the sum of the sum of the vector components, squared.
+        double sum = 0;
+        for(int i = 0; i < 3; i++) {
+            double elementSum = v1.v()[i] + v2.v()[i];
+            sum += (elementSum * elementSum);
+        }
+        
+        // Return the square root of the sum.
+        return Math.sqrt(sum);
+    }
+    
+    private static final double getVectorAngle(Hep3Vector v1, Hep3Vector v2) {
+        // The vector angle is defined as Acos[(v1 · v2) / (‖v1‖ × ‖v2‖)]
+        return Math.acos(getDotProduct(v1, v2) / (v1.magnitude() * v2.magnitude())) / Math.PI * 180.0;
+    }
+    
+    private static final double getDotProduct(Hep3Vector v1, Hep3Vector v2) {
+        // Calculate the sum of the vector element products.
+        int product = 0;
+        for(int i = 0; i < 3; i++) {
+            product += (v1.v()[i] * v2.v()[i]);
+        }
+        
+        // Return the result.
+        return product;
+    }
 }

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/PlotsFormatter.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/PlotsFormatter.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/PlotsFormatter.java	Wed Apr 27 11:11:32 2016
@@ -8,120 +8,120 @@
 import java.awt.Font;
 
 public class PlotsFormatter {
-	// Define plot fonts.
-	public static final Font BASIC_FONT = new Font("Calibri", Font.PLAIN, 30);
-	public static final Font AXIS_FONT  = new Font("Calibri", Font.BOLD,  35);
-	public static final Font TITLE_FONT = new Font("Calibri", Font.BOLD,  45);
-	
-	// Defines the color style options for plot data.
-	public static enum ColorStyle {
-		 MS_BLUE(new Color( 79, 129, 189), new Color( 36,  64,  97)), MS_ORANGE(new Color(247, 150,  70), new Color(152,  72,   6)),
-		  MS_RED(new Color(192,  80,  77), new Color( 99,  36,  35)),      GREY(new Color(166, 166, 166), new Color( 89,  89,  89)),
-		MS_GREEN(new Color(155, 187,  89), new Color( 79,  98,  40)),   CRIMSON(new Color(161,   0,   0), new Color(104,   0,   0)),
-		    RUST(new Color(161,  80,   0), new Color(105,  80,   0)),    YELLOW(new Color(161, 161,   0), new Color(122, 109,   8)),
-		  FOREST(new Color( 65, 102,   0), new Color( 37,  79,   0)),     GREEN(new Color(  7, 132,  70), new Color(  7,  82,  30)),
-		    TEAL(new Color(  0, 130, 130), new Color(  0,  90, 100)),  CERULEAN(new Color(  0,  86, 130), new Color(  0,  28,  83)),
-		    BLUE(new Color(  0,  33, 203), new Color(  0,   0, 137)),    INDIGO(new Color( 68,  10, 127), new Color(  0,   0,  61)),
-		  PURPLE(new Color(106,   0, 106), new Color( 63,   0,  56)),   FUSCHIA(new Color(119,   0,  60), new Color( 60,   0,  60));
-		
-		private final Color fillColor;
-		private final Color lineColor;
-		
-		private ColorStyle(Color fillColor, Color lineColor) {
-			this.fillColor = fillColor;
-			this.lineColor = lineColor;
-		}
-		
-		public Color getFillColor() { return fillColor; }
-		
-		public Color getLineColor() { return lineColor; }
-	};
-	
-	/**
-	 * Sets the plot display formatting for 1D plots.
-	 * @param region - The plotter region to format.
-	 * @param color - The data color settings to use.
-	 */
-	public static final void setDefault1DStyle(PlotterRegion region, ColorStyle[] color) {
-		// Get the names of each plot on in the region.
-		String[] dataNames = region.getAllDataNames();
-		
-		// Check whether this is an overlay plot. Overlay plots contain
-		// more than one data name.
-		boolean overlay = (dataNames.length > 1 ? true : false);
-		
-		// Iterate over each plot in the region.
-		for(int i = 0; i < dataNames.length; i++) {
-			// Set the overlay style if needed.
-			if(overlay) {
-				// Get the fill style for the current data type.
-				JASHist1DHistogramStyle fillStyle = (JASHist1DHistogramStyle) region.getDataForName(dataNames[i]).getStyle();
-				
-				// Set the histogram style to display thick-lined bars
-				// with no fill. The color is set by the "color" argument.
-				fillStyle.setHistogramFill(false);
-				fillStyle.setHistogramBarLineWidth(3);
-				fillStyle.setHistogramBarLineColor(color[i].getFillColor());
-				
-				// Set the legend text style.
-				region.getPlot().getLegend().setFont(new Font("Calibri", Font.PLAIN, 20));
-			}
-			
-			// Otherwise, set the fill style for a single plot.
-			else {
-				// Get the fill style for the current data type.
-				JASHist1DHistogramStyle fillStyle = (JASHist1DHistogramStyle) region.getDataForName(dataNames[i]).getStyle();
-				
-				// Set the histogram style to display thick-lined bars
-				// with a fill color. The colors are defined by the
-				// "color" argument.
-				fillStyle.setHistogramBarLineWidth(3);
-				fillStyle.setHistogramBarColor(color[i].getFillColor());
-				fillStyle.setHistogramBarLineColor(color[i].getLineColor());
-			}
-			
-			// Set the statistics box style.
-			region.getPlot().getStats().setVisible(true);
-			region.getPlot().getStats().setFont(BASIC_FONT);
-			
-			// Set the title font.
-			region.getPlot().getTitleObject().setFont(TITLE_FONT);
-			
-			// Set the axis tick-mark fonts.
-			region.getPlot().getXAxis().setFont(BASIC_FONT);
-			region.getPlot().getYAxis().setFont(BASIC_FONT);
-			region.getPlot().getXAxis().getLabelObject().setFont(AXIS_FONT);
-			region.getPlot().getYAxis().getLabelObject().setFont(AXIS_FONT);
-		}
-	}
-	
-	/**
-	 * Sets the plot display formatting for 1D plots.
-	 * @param region - The plotter region to format.
-	 */
-	public static final void setDefault2DStyle(PlotterRegion region, boolean logarithmic) {
-		// Get the fill style object. 2D plots should never be overlay
-		// plots, so there should only ever be one data name.
-		JASHist2DHistogramStyle fillStyle = (JASHist2DHistogramStyle) region.getDataForName(region.getAllDataNames()[0]).getStyle();
-		
-		// Set the fill style for a two-dimensional plot.
-		if(logarithmic) { fillStyle.setLogZ(true); }
-		fillStyle.setHistStyle(JASHist2DHistogramStyle.STYLE_COLORMAP);
-		fillStyle.setColorMapScheme(JASHist2DHistogramStyle.COLORMAP_RAINBOW);
-		
-		// Make the statistics box invisible.
-		region.getPlot().getStats().setVisible(false);
-		
-		// Set the general plot font (which is also the z-axis font).
-		region.getPlot().setFont(BASIC_FONT);
-		
-		// Set the title font.
-		region.getPlot().getTitleObject().setFont(TITLE_FONT);
-		
-		// Set the axis tick-mark fonts.
-		region.getPlot().getXAxis().setFont(BASIC_FONT);
-		region.getPlot().getYAxis().setFont(BASIC_FONT);
-		region.getPlot().getXAxis().getLabelObject().setFont(AXIS_FONT);
-		region.getPlot().getYAxis().getLabelObject().setFont(AXIS_FONT);
-	}
+    // Define plot fonts.
+    public static final Font BASIC_FONT = new Font("Calibri", Font.PLAIN, 30);
+    public static final Font AXIS_FONT  = new Font("Calibri", Font.BOLD,  35);
+    public static final Font TITLE_FONT = new Font("Calibri", Font.BOLD,  45);
+    
+    // Defines the color style options for plot data.
+    public static enum ColorStyle {
+         MS_BLUE(new Color( 79, 129, 189), new Color( 36,  64,  97)), MS_ORANGE(new Color(247, 150,  70), new Color(152,  72,   6)),
+          MS_RED(new Color(192,  80,  77), new Color( 99,  36,  35)),      GREY(new Color(166, 166, 166), new Color( 89,  89,  89)),
+        MS_GREEN(new Color(155, 187,  89), new Color( 79,  98,  40)),   CRIMSON(new Color(161,   0,   0), new Color(104,   0,   0)),
+            RUST(new Color(161,  80,   0), new Color(105,  80,   0)),    YELLOW(new Color(161, 161,   0), new Color(122, 109,   8)),
+          FOREST(new Color( 65, 102,   0), new Color( 37,  79,   0)),     GREEN(new Color(  7, 132,  70), new Color(  7,  82,  30)),
+            TEAL(new Color(  0, 130, 130), new Color(  0,  90, 100)),  CERULEAN(new Color(  0,  86, 130), new Color(  0,  28,  83)),
+            BLUE(new Color(  0,  33, 203), new Color(  0,   0, 137)),    INDIGO(new Color( 68,  10, 127), new Color(  0,   0,  61)),
+          PURPLE(new Color(106,   0, 106), new Color( 63,   0,  56)),   FUSCHIA(new Color(119,   0,  60), new Color( 60,   0,  60));
+        
+        private final Color fillColor;
+        private final Color lineColor;
+        
+        private ColorStyle(Color fillColor, Color lineColor) {
+            this.fillColor = fillColor;
+            this.lineColor = lineColor;
+        }
+        
+        public Color getFillColor() { return fillColor; }
+        
+        public Color getLineColor() { return lineColor; }
+    };
+    
+    /**
+     * Sets the plot display formatting for 1D plots.
+     * @param region - The plotter region to format.
+     * @param color - The data color settings to use.
+     */
+    public static final void setDefault1DStyle(PlotterRegion region, ColorStyle[] color) {
+        // Get the names of each plot on in the region.
+        String[] dataNames = region.getAllDataNames();
+        
+        // Check whether this is an overlay plot. Overlay plots contain
+        // more than one data name.
+        boolean overlay = (dataNames.length > 1 ? true : false);
+        
+        // Iterate over each plot in the region.
+        for(int i = 0; i < dataNames.length; i++) {
+            // Set the overlay style if needed.
+            if(overlay) {
+                // Get the fill style for the current data type.
+                JASHist1DHistogramStyle fillStyle = (JASHist1DHistogramStyle) region.getDataForName(dataNames[i]).getStyle();
+                
+                // Set the histogram style to display thick-lined bars
+                // with no fill. The color is set by the "color" argument.
+                fillStyle.setHistogramFill(false);
+                fillStyle.setHistogramBarLineWidth(3);
+                fillStyle.setHistogramBarLineColor(color[i].getFillColor());
+                
+                // Set the legend text style.
+                region.getPlot().getLegend().setFont(new Font("Calibri", Font.PLAIN, 20));
+            }
+            
+            // Otherwise, set the fill style for a single plot.
+            else {
+                // Get the fill style for the current data type.
+                JASHist1DHistogramStyle fillStyle = (JASHist1DHistogramStyle) region.getDataForName(dataNames[i]).getStyle();
+                
+                // Set the histogram style to display thick-lined bars
+                // with a fill color. The colors are defined by the
+                // "color" argument.
+                fillStyle.setHistogramBarLineWidth(3);
+                fillStyle.setHistogramBarColor(color[i].getFillColor());
+                fillStyle.setHistogramBarLineColor(color[i].getLineColor());
+            }
+            
+            // Set the statistics box style.
+            region.getPlot().getStats().setVisible(true);
+            region.getPlot().getStats().setFont(BASIC_FONT);
+            
+            // Set the title font.
+            region.getPlot().getTitleObject().setFont(TITLE_FONT);
+            
+            // Set the axis tick-mark fonts.
+            region.getPlot().getXAxis().setFont(BASIC_FONT);
+            region.getPlot().getYAxis().setFont(BASIC_FONT);
+            region.getPlot().getXAxis().getLabelObject().setFont(AXIS_FONT);
+            region.getPlot().getYAxis().getLabelObject().setFont(AXIS_FONT);
+        }
+    }
+    
+    /**
+     * Sets the plot display formatting for 1D plots.
+     * @param region - The plotter region to format.
+     */
+    public static final void setDefault2DStyle(PlotterRegion region, boolean logarithmic) {
+        // Get the fill style object. 2D plots should never be overlay
+        // plots, so there should only ever be one data name.
+        JASHist2DHistogramStyle fillStyle = (JASHist2DHistogramStyle) region.getDataForName(region.getAllDataNames()[0]).getStyle();
+        
+        // Set the fill style for a two-dimensional plot.
+        if(logarithmic) { fillStyle.setLogZ(true); }
+        fillStyle.setHistStyle(JASHist2DHistogramStyle.STYLE_COLORMAP);
+        fillStyle.setColorMapScheme(JASHist2DHistogramStyle.COLORMAP_RAINBOW);
+        
+        // Make the statistics box invisible.
+        region.getPlot().getStats().setVisible(false);
+        
+        // Set the general plot font (which is also the z-axis font).
+        region.getPlot().setFont(BASIC_FONT);
+        
+        // Set the title font.
+        region.getPlot().getTitleObject().setFont(TITLE_FONT);
+        
+        // Set the axis tick-mark fonts.
+        region.getPlot().getXAxis().setFont(BASIC_FONT);
+        region.getPlot().getYAxis().setFont(BASIC_FONT);
+        region.getPlot().getXAxis().getLabelObject().setFont(AXIS_FONT);
+        region.getPlot().getYAxis().getLabelObject().setFont(AXIS_FONT);
+    }
 }

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/RafoAnalysis.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/RafoAnalysis.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/RafoAnalysis.java	Wed Apr 27 11:11:32 2016
@@ -16,431 +16,431 @@
 import org.lcsim.util.aida.AIDA;
 
 public class RafoAnalysis extends Driver {
-	private boolean useGoodSVT = false;
-	private String clusterCollectionName = "EcalClustersCorr";
-	private String particleCollectionName = "FinalStateParticles";
-	
-	private AIDA aida = AIDA.defaultInstance();
-	private IHistogram1D t0TimeCoincidenceAll          = aida.histogram1D("Tier 0/Time Coincidence",                    300, -15.0, 15.0);
-	private IHistogram1D t0TimeCoincidenceFiducial     = aida.histogram1D("Tier 0/Time Coincidence (Fiducial Region)",  300, -15.0, 15.0);
-	private IHistogram1D t0EnergySumAll                = aida.histogram1D("Tier 0/Energy Sum",                          300,   0.0,  1.5);
-	private IHistogram1D t0EnergySumFiducial           = aida.histogram1D("Tier 0/Energy Sum (Fiducial Region)",        300,   0.0,  1.5);
-	private IHistogram1D t0InvariantMassAll            = aida.histogram1D("Tier 0/Invariant Mass",                     2200,   0.0,  1.1);
-	private IHistogram2D t0EnergySum2DAll              = aida.histogram2D("Tier 0/Top Cluster Energy vs. Bottom Cluster Energy",                   300, 0, 1.5, 300,   0, 1.5);
-	private IHistogram2D t0EnergySum2DFiducial         = aida.histogram2D("Tier 0/Top Cluster Energy vs. Bottom Cluster Energy (Fiducial Region)", 300, 0, 1.5, 300,   0, 1.5);
-	private IHistogram2D t0SumCoplanarityAll           = aida.histogram2D("Tier 0/Hardware Coplanarity vs. Energy Sum",                            300, 0, 1.5, 115,   0, 230);
-	private IHistogram2D t0SumCoplanarityFiducial      = aida.histogram2D("Tier 0/Hardware Coplanarity vs. Energy Sum (Fiducial Region)",          300, 0, 1.5, 115,   0, 230);
-	private IHistogram2D t0SumCoplanarityCalcAll       = aida.histogram2D("Tier 0/Calculated Coplanarity vs. Energy Sum",                          300, 0, 1.5, 115, 130, 230);
-	private IHistogram2D t0SumCoplanarityCalcFiducial  = aida.histogram2D("Tier 0/Calculated Coplanarity vs. Energy Sum (Fiducial Region)",        300, 0, 1.5, 115, 130, 230);
-	private IHistogram2D t0TimeEnergyAll               = aida.histogram2D("Tier 0/Cluster Time vs. Cluster Energy",                                300, 0, 1.5, 100,   0, 100);
-	private IHistogram2D t0TimeEnergyFiducial          = aida.histogram2D("Tier 0/Cluster Time vs. Cluster Energy (Fiducial Region)",              300, 0, 1.5, 100,   0, 100);
-	
-	private IHistogram1D t1TimeCoincidenceAll          = aida.histogram1D("Tier 1/Time Coincidence",                    300, -15.0, 15.0);
-	private IHistogram1D t1TimeCoincidenceFiducial     = aida.histogram1D("Tier 1/Time Coincidence (Fiducial Region)",  300, -15.0, 15.0);
-	private IHistogram1D t1EnergySumAll                = aida.histogram1D("Tier 1/Energy Sum",                          300,   0.0,  1.5);
-	private IHistogram1D t1EnergySumFiducial           = aida.histogram1D("Tier 1/Energy Sum (Fiducial Region)",        300,   0.0,  1.5);
-	private IHistogram1D t1InvariantMassAll            = aida.histogram1D("Tier 1/Invariant Mass",                     2200,   0.0,  1.1);
-	private IHistogram2D t1EnergySum2DAll              = aida.histogram2D("Tier 1/Top Cluster Energy vs. Bottom Cluster Energy",                   300, 0, 1.5, 300,   0, 1.5);
-	private IHistogram2D t1EnergySum2DFiducial         = aida.histogram2D("Tier 1/Top Cluster Energy vs. Bottom Cluster Energy (Fiducial Region)", 300, 0, 1.5, 300,   0, 1.5);
-	private IHistogram2D t1SumCoplanarityAll           = aida.histogram2D("Tier 1/Hardware Coplanarity vs. Energy Sum",                            300, 0, 1.5, 115,   0, 230);
-	private IHistogram2D t1SumCoplanarityFiducial      = aida.histogram2D("Tier 1/Hardware Coplanarity vs. Energy Sum (Fiducial Region)",          300, 0, 1.5, 115,   0, 230);
-	private IHistogram2D t1SumCoplanarityCalcAll       = aida.histogram2D("Tier 1/Calculated Coplanarity vs. Energy Sum",                          300, 0, 1.5, 115, 130, 230);
-	private IHistogram2D t1SumCoplanarityCalcFiducial  = aida.histogram2D("Tier 1/Calculated Coplanarity vs. Energy Sum (Fiducial Region)",        300, 0, 1.5, 115, 130, 230);
-	private IHistogram2D t1TimeEnergyAll               = aida.histogram2D("Tier 1/Cluster Time vs. Cluster Energy",                                300, 0, 1.5, 100, 0, 100);
-	private IHistogram2D t1TimeEnergyFiducial          = aida.histogram2D("Tier 1/Cluster Time vs. Cluster Energy (Fiducial Region)",              300, 0, 1.5, 100, 0, 100);
-	
-	private IHistogram1D t2TimeCoincidenceAll          = aida.histogram1D("Tier 2/Time Coincidence",                    300, -15.0, 15.0);
-	private IHistogram1D t2TimeCoincidenceFiducial     = aida.histogram1D("Tier 2/Time Coincidence (Fiducial Region)",  300, -15.0, 15.0);
-	private IHistogram1D t2EnergySumAll                = aida.histogram1D("Tier 2/Energy Sum",                          300,   0.0,  1.5);
-	private IHistogram1D t2EnergySumFiducial           = aida.histogram1D("Tier 2/Energy Sum (Fiducial Region)",        300,   0.0,  1.5);
-	private IHistogram1D t2InvariantMassAll            = aida.histogram1D("Tier 2/Invariant Mass",                     2200,   0.0,  1.1);
-	private IHistogram2D t2EnergySum2DAll              = aida.histogram2D("Tier 2/Top Cluster Energy vs. Bottom Cluster Energy",                   300, 0, 1.5, 300,   0, 1.5);
-	private IHistogram2D t2EnergySum2DFiducial         = aida.histogram2D("Tier 2/Top Cluster Energy vs. Bottom Cluster Energy (Fiducial Region)", 300, 0, 1.5, 300,   0, 1.5);
-	private IHistogram2D t2SumCoplanarityAll           = aida.histogram2D("Tier 2/Hardware Coplanarity vs. Energy Sum",                            300, 0, 1.5, 115,   0, 230);
-	private IHistogram2D t2SumCoplanarityFiducial      = aida.histogram2D("Tier 2/Hardware Coplanarity vs. Energy Sum (Fiducial Region)",          300, 0, 1.5, 115,   0, 230);
-	private IHistogram2D t2SumCoplanarityCalcAll       = aida.histogram2D("Tier 2/Calculated Coplanarity vs. Energy Sum",                          300, 0, 1.5, 115, 130, 230);
-	private IHistogram2D t2SumCoplanarityCalcFiducial  = aida.histogram2D("Tier 2/Calculated Coplanarity vs. Energy Sum (Fiducial Region)",        300, 0, 1.5, 115, 130, 230);
-	private IHistogram2D t2TimeEnergyAll               = aida.histogram2D("Tier 2/Cluster Time vs. Cluster Energy",                                300, 0, 1.5, 100,   0, 100);
-	private IHistogram2D t2TimeEnergyFiducial          = aida.histogram2D("Tier 2/Cluster Time vs. Cluster Energy (Fiducial Region)",              300, 0, 1.5, 100,   0, 100);
-	
-	private int t0Events = 0;
-	private int t1Events = 0;
-	private int t2Events = 0;
-	
-	@Override
-	public void endOfData() {
-		System.out.printf("Tier 0 Events: %d%n", t0Events);
-		System.out.printf("Tier 1 Events: %d%n", t1Events);
-		System.out.printf("Tier 2 Events: %d%n", t2Events);
-	}
-	
-	@Override
-	public void process(EventHeader event) {
-		// Check whether the SVT was active in this event.
-		final String[] flagNames = { "svt_bias_good", "svt_burstmode_noise_good", "svt_position_good" };
-		boolean svtGood = true;
+    private boolean useGoodSVT = false;
+    private String clusterCollectionName = "EcalClustersCorr";
+    private String particleCollectionName = "FinalStateParticles";
+    
+    private AIDA aida = AIDA.defaultInstance();
+    private IHistogram1D t0TimeCoincidenceAll          = aida.histogram1D("Tier 0/Time Coincidence",                    300, -15.0, 15.0);
+    private IHistogram1D t0TimeCoincidenceFiducial     = aida.histogram1D("Tier 0/Time Coincidence (Fiducial Region)",  300, -15.0, 15.0);
+    private IHistogram1D t0EnergySumAll                = aida.histogram1D("Tier 0/Energy Sum",                          300,   0.0,  1.5);
+    private IHistogram1D t0EnergySumFiducial           = aida.histogram1D("Tier 0/Energy Sum (Fiducial Region)",        300,   0.0,  1.5);
+    private IHistogram1D t0InvariantMassAll            = aida.histogram1D("Tier 0/Invariant Mass",                     2200,   0.0,  1.1);
+    private IHistogram2D t0EnergySum2DAll              = aida.histogram2D("Tier 0/Top Cluster Energy vs. Bottom Cluster Energy",                   300, 0, 1.5, 300,   0, 1.5);
+    private IHistogram2D t0EnergySum2DFiducial         = aida.histogram2D("Tier 0/Top Cluster Energy vs. Bottom Cluster Energy (Fiducial Region)", 300, 0, 1.5, 300,   0, 1.5);
+    private IHistogram2D t0SumCoplanarityAll           = aida.histogram2D("Tier 0/Hardware Coplanarity vs. Energy Sum",                            300, 0, 1.5, 115,   0, 230);
+    private IHistogram2D t0SumCoplanarityFiducial      = aida.histogram2D("Tier 0/Hardware Coplanarity vs. Energy Sum (Fiducial Region)",          300, 0, 1.5, 115,   0, 230);
+    private IHistogram2D t0SumCoplanarityCalcAll       = aida.histogram2D("Tier 0/Calculated Coplanarity vs. Energy Sum",                          300, 0, 1.5, 115, 130, 230);
+    private IHistogram2D t0SumCoplanarityCalcFiducial  = aida.histogram2D("Tier 0/Calculated Coplanarity vs. Energy Sum (Fiducial Region)",        300, 0, 1.5, 115, 130, 230);
+    private IHistogram2D t0TimeEnergyAll               = aida.histogram2D("Tier 0/Cluster Time vs. Cluster Energy",                                300, 0, 1.5, 100,   0, 100);
+    private IHistogram2D t0TimeEnergyFiducial          = aida.histogram2D("Tier 0/Cluster Time vs. Cluster Energy (Fiducial Region)",              300, 0, 1.5, 100,   0, 100);
+    
+    private IHistogram1D t1TimeCoincidenceAll          = aida.histogram1D("Tier 1/Time Coincidence",                    300, -15.0, 15.0);
+    private IHistogram1D t1TimeCoincidenceFiducial     = aida.histogram1D("Tier 1/Time Coincidence (Fiducial Region)",  300, -15.0, 15.0);
+    private IHistogram1D t1EnergySumAll                = aida.histogram1D("Tier 1/Energy Sum",                          300,   0.0,  1.5);
+    private IHistogram1D t1EnergySumFiducial           = aida.histogram1D("Tier 1/Energy Sum (Fiducial Region)",        300,   0.0,  1.5);
+    private IHistogram1D t1InvariantMassAll            = aida.histogram1D("Tier 1/Invariant Mass",                     2200,   0.0,  1.1);
+    private IHistogram2D t1EnergySum2DAll              = aida.histogram2D("Tier 1/Top Cluster Energy vs. Bottom Cluster Energy",                   300, 0, 1.5, 300,   0, 1.5);
+    private IHistogram2D t1EnergySum2DFiducial         = aida.histogram2D("Tier 1/Top Cluster Energy vs. Bottom Cluster Energy (Fiducial Region)", 300, 0, 1.5, 300,   0, 1.5);
+    private IHistogram2D t1SumCoplanarityAll           = aida.histogram2D("Tier 1/Hardware Coplanarity vs. Energy Sum",                            300, 0, 1.5, 115,   0, 230);
+    private IHistogram2D t1SumCoplanarityFiducial      = aida.histogram2D("Tier 1/Hardware Coplanarity vs. Energy Sum (Fiducial Region)",          300, 0, 1.5, 115,   0, 230);
+    private IHistogram2D t1SumCoplanarityCalcAll       = aida.histogram2D("Tier 1/Calculated Coplanarity vs. Energy Sum",                          300, 0, 1.5, 115, 130, 230);
+    private IHistogram2D t1SumCoplanarityCalcFiducial  = aida.histogram2D("Tier 1/Calculated Coplanarity vs. Energy Sum (Fiducial Region)",        300, 0, 1.5, 115, 130, 230);
+    private IHistogram2D t1TimeEnergyAll               = aida.histogram2D("Tier 1/Cluster Time vs. Cluster Energy",                                300, 0, 1.5, 100, 0, 100);
+    private IHistogram2D t1TimeEnergyFiducial          = aida.histogram2D("Tier 1/Cluster Time vs. Cluster Energy (Fiducial Region)",              300, 0, 1.5, 100, 0, 100);
+    
+    private IHistogram1D t2TimeCoincidenceAll          = aida.histogram1D("Tier 2/Time Coincidence",                    300, -15.0, 15.0);
+    private IHistogram1D t2TimeCoincidenceFiducial     = aida.histogram1D("Tier 2/Time Coincidence (Fiducial Region)",  300, -15.0, 15.0);
+    private IHistogram1D t2EnergySumAll                = aida.histogram1D("Tier 2/Energy Sum",                          300,   0.0,  1.5);
+    private IHistogram1D t2EnergySumFiducial           = aida.histogram1D("Tier 2/Energy Sum (Fiducial Region)",        300,   0.0,  1.5);
+    private IHistogram1D t2InvariantMassAll            = aida.histogram1D("Tier 2/Invariant Mass",                     2200,   0.0,  1.1);
+    private IHistogram2D t2EnergySum2DAll              = aida.histogram2D("Tier 2/Top Cluster Energy vs. Bottom Cluster Energy",                   300, 0, 1.5, 300,   0, 1.5);
+    private IHistogram2D t2EnergySum2DFiducial         = aida.histogram2D("Tier 2/Top Cluster Energy vs. Bottom Cluster Energy (Fiducial Region)", 300, 0, 1.5, 300,   0, 1.5);
+    private IHistogram2D t2SumCoplanarityAll           = aida.histogram2D("Tier 2/Hardware Coplanarity vs. Energy Sum",                            300, 0, 1.5, 115,   0, 230);
+    private IHistogram2D t2SumCoplanarityFiducial      = aida.histogram2D("Tier 2/Hardware Coplanarity vs. Energy Sum (Fiducial Region)",          300, 0, 1.5, 115,   0, 230);
+    private IHistogram2D t2SumCoplanarityCalcAll       = aida.histogram2D("Tier 2/Calculated Coplanarity vs. Energy Sum",                          300, 0, 1.5, 115, 130, 230);
+    private IHistogram2D t2SumCoplanarityCalcFiducial  = aida.histogram2D("Tier 2/Calculated Coplanarity vs. Energy Sum (Fiducial Region)",        300, 0, 1.5, 115, 130, 230);
+    private IHistogram2D t2TimeEnergyAll               = aida.histogram2D("Tier 2/Cluster Time vs. Cluster Energy",                                300, 0, 1.5, 100,   0, 100);
+    private IHistogram2D t2TimeEnergyFiducial          = aida.histogram2D("Tier 2/Cluster Time vs. Cluster Energy (Fiducial Region)",              300, 0, 1.5, 100,   0, 100);
+    
+    private int t0Events = 0;
+    private int t1Events = 0;
+    private int t2Events = 0;
+    
+    @Override
+    public void endOfData() {
+        System.out.printf("Tier 0 Events: %d%n", t0Events);
+        System.out.printf("Tier 1 Events: %d%n", t1Events);
+        System.out.printf("Tier 2 Events: %d%n", t2Events);
+    }
+    
+    @Override
+    public void process(EventHeader event) {
+        // Check whether the SVT was active in this event.
+        final String[] flagNames = { "svt_bias_good", "svt_burstmode_noise_good", "svt_position_good" };
+        boolean svtGood = true;
         for(int i = 0; i < flagNames.length; i++) {
             int[] flag = event.getIntegerParameters().get(flagNames[i]);
             if(flag == null || flag[0] == 0) {
                 svtGood = false;
             }
         }
-		
+        
         // If the SVT is not properly running, skip the event.
         if(!svtGood && useGoodSVT) { return; }
         
-		// Get the list of particles, if it exists.
-		List<ReconstructedParticle> trackList = null;
-		if(event.hasCollection(ReconstructedParticle.class, particleCollectionName)) {
-			trackList = event.get(ReconstructedParticle.class, particleCollectionName);
-		}
-		
-		// Get the list of clusters, if it exists.
-		List<Cluster> clusterList = null;
-		if(event.hasCollection(Cluster.class, clusterCollectionName)) {
-			clusterList = event.get(Cluster.class, clusterCollectionName);
-		}
-		
-		// Make sure that the cluster and track lists both exist.
-		if(clusterList == null || trackList == null) {
-			return;
-		}
-		
-		// Perform tier 1 analysis. This requires that there be at
-		// least one top/bottom cluster pair with a time difference
-		// of less then 4 ns.
-		double t1TimeThreshold = 1.5;
-		
-		// Get a list of cluster pairs.
-		List<Cluster[]> pairList = getClusterPairs(clusterList);
-		
-		// Iterate over the cluster pairs.
-		boolean t1Passed = false;
-		t1ClusterLoop:
-		for(Cluster[] pair : pairList) {
-			// Check that the time difference for the cluster pair
-			// meets the time cut.
-			if(TriggerModule.getValueTimeCoincidence(pair) <= t1TimeThreshold) {
-				// Note that the tier 1 analysis condition passed.
-				t1Passed = true;
-				
-				// Break from the loop.
-				break t1ClusterLoop;
-			}
-		}
-		
-		// Perform the additional checks for tier 2 analysis. This
-		// requires that there be at least one top/bottom track pair
-		// and that one track be positive and the other be negative.
-		
-		// Get a list of top and bottom track pairs.
-		List<ReconstructedParticle[]> trackPairList = getTrackPairs(trackList);
-		
-		// Check that at least one top/bottom track has one negative and
-		// one positive track.
-		boolean t2Passed = false;
-		t2TrackLoop:
-		for(ReconstructedParticle[] pair : trackPairList) {
-			if((pair[0].getCharge() > 0 && pair[1].getCharge() < 0) || (pair[0].getCharge() < 0 && pair[1].getCharge() > 0)) {
-				t2Passed = true;
-				break t2TrackLoop;
-			}
-		}
-		
-		// Populate the tier 0 analysis plot.
-		if(true) {
-			// Increment the number of tier 1 events found.
-			t0Events++;
-			
-			// Track which clusters have already been added to the
-			// singles plot so that there are no repeats.
-			Set<Cluster> plotSet = new HashSet<Cluster>(clusterList.size());
-			Set<Cluster> plotFiducial = new HashSet<Cluster>(clusterList.size());
-			
-			for(ReconstructedParticle[] pair : trackPairList) {
-				t0InvariantMassAll.fill(getInvariantMass(pair));
-			}
-			
-			for(Cluster[] pair : pairList) {
-				// Fill the all pairs plots.
-				double pairEnergy = pair[0].getEnergy() + pair[1].getEnergy();
-				t0EnergySumAll.fill(pairEnergy);
-				t0EnergySum2DAll.fill(pair[1].getEnergy(), pair[0].getEnergy());
-				t0TimeCoincidenceAll.fill(getTimeConicidence(pair));
-				t0SumCoplanarityCalcAll.fill(pairEnergy, getCalculatedCoplanarity(pair));
-				t0SumCoplanarityAll.fill(pairEnergy, TriggerModule.getValueCoplanarity(pair));
-				
-				// Fill the singles plots.
-				if(!plotSet.contains(pair[0])) {
-					plotSet.add(pair[0]);
-					t0TimeEnergyAll.fill(pair[0].getEnergy(), TriggerModule.getClusterTime(pair[0]));
-				} if(!plotSet.contains(pair[1])) {
-					plotSet.add(pair[1]);
-					t0TimeEnergyAll.fill(pair[1].getEnergy(), TriggerModule.getClusterTime(pair[1]));
-				}
-				
-				// Fill the fiducial plots if appropriate.
-				if(inFiducialRegion(pair[0]) && inFiducialRegion(pair[1])) {
-					t0EnergySumFiducial.fill(pairEnergy);
-					t0EnergySum2DFiducial.fill(pair[1].getEnergy(), pair[0].getEnergy());
-					t0TimeCoincidenceFiducial.fill(getTimeConicidence(pair));
-					t0SumCoplanarityCalcFiducial.fill(pairEnergy, getCalculatedCoplanarity(pair));
-					t0SumCoplanarityFiducial.fill(pairEnergy, TriggerModule.getValueCoplanarity(pair));
-				}
-				
-				// Fill the singles fiducial plots if appropriate.
-				if(!plotFiducial.contains(pair[0]) && inFiducialRegion(pair[0])) {
-					plotFiducial.add(pair[0]);
-					t0TimeEnergyFiducial.fill(pair[0].getEnergy(), TriggerModule.getClusterTime(pair[0]));
-				} if(!plotFiducial.contains(pair[1]) && inFiducialRegion(pair[1])) {
-					plotFiducial.add(pair[1]);
-					t0TimeEnergyFiducial.fill(pair[1].getEnergy(), TriggerModule.getClusterTime(pair[1]));
-				}
-			}
-		}
-		
-		// Populate the tier 1 analysis plots, if the conditions were met.
-		if(t1Passed) {
-			// Increment the number of tier 1 events found.
-			t1Events++;
-			
-			// Track which clusters have already been added to the
-			// singles plot so that there are no repeats.
-			Set<Cluster> plotSet = new HashSet<Cluster>(clusterList.size());
-			Set<Cluster> plotFiducial = new HashSet<Cluster>(clusterList.size());
-			
-			for(ReconstructedParticle[] pair : trackPairList) {
-				t1InvariantMassAll.fill(getInvariantMass(pair));
-			}
-			
-			for(Cluster[] pair : pairList) {
-				// Only include clusters that pass the time coincidence.
-				if(TriggerModule.getValueTimeCoincidence(pair) > t1TimeThreshold) {
-					continue;
-				}
-				
-				// Fill the all pairs plots.
-				double pairEnergy = pair[0].getEnergy() + pair[1].getEnergy();
-				t1EnergySumAll.fill(pairEnergy);
-				t1EnergySum2DAll.fill(pair[1].getEnergy(), pair[0].getEnergy());
-				t1TimeCoincidenceAll.fill(getTimeConicidence(pair));
-				t1SumCoplanarityCalcAll.fill(pairEnergy, getCalculatedCoplanarity(pair));
-				t1SumCoplanarityAll.fill(pairEnergy, TriggerModule.getValueCoplanarity(pair));
-				
-				// Fill the singles plots.
-				if(!plotSet.contains(pair[0])) {
-					plotSet.add(pair[0]);
-					t1TimeEnergyAll.fill(pair[0].getEnergy(), TriggerModule.getClusterTime(pair[0]));
-				} if(!plotSet.contains(pair[1])) {
-					plotSet.add(pair[1]);
-					t1TimeEnergyAll.fill(pair[1].getEnergy(), TriggerModule.getClusterTime(pair[1]));
-				}
-				
-				// Fill the fiducial plots if appropriate.
-				if(inFiducialRegion(pair[0]) && inFiducialRegion(pair[1])) {
-					t1EnergySumFiducial.fill(pairEnergy);
-					t1EnergySum2DFiducial.fill(pair[1].getEnergy(), pair[0].getEnergy());
-					t1TimeCoincidenceFiducial.fill(getTimeConicidence(pair));
-					t1SumCoplanarityCalcFiducial.fill(pairEnergy, getCalculatedCoplanarity(pair));
-					t1SumCoplanarityFiducial.fill(pairEnergy, TriggerModule.getValueCoplanarity(pair));
-				}
-				
-				// Fill the singles fiducial plots if appropriate.
-				if(!plotFiducial.contains(pair[0]) && inFiducialRegion(pair[0])) {
-					plotFiducial.add(pair[0]);
-					t1TimeEnergyFiducial.fill(pair[0].getEnergy(), TriggerModule.getClusterTime(pair[0]));
-				} if(!plotFiducial.contains(pair[1]) && inFiducialRegion(pair[1])) {
-					plotFiducial.add(pair[1]);
-					t1TimeEnergyFiducial.fill(pair[1].getEnergy(), TriggerModule.getClusterTime(pair[1]));
-				}
-			}
-		}
-		
-		// Populate the tier 2 analysis plots, if the conditions were met.
-		if(t1Passed && t2Passed) {
-			// Increment the number of tier 2 events found.
-			t2Events++;
-			
-			// Track which clusters have already been added to the
-			// singles plot so that there are no repeats.
-			Set<Cluster> plotSet = new HashSet<Cluster>(clusterList.size());
-			Set<Cluster> plotFiducial = new HashSet<Cluster>(clusterList.size());
-			
-			for(ReconstructedParticle[] pair : trackPairList) {
-				t2InvariantMassAll.fill(getInvariantMass(pair));
-			}
-			
-			for(Cluster[] pair : pairList) {
-				// Only include clusters that pass the time coincidence.
-				if(TriggerModule.getValueTimeCoincidence(pair) > t1TimeThreshold) {
-					continue;
-				}
-				
-				// Fill the all pairs plots.
-				double pairEnergy = pair[0].getEnergy() + pair[1].getEnergy();
-				t2EnergySumAll.fill(pairEnergy);
-				t2EnergySum2DAll.fill(pair[1].getEnergy(), pair[0].getEnergy());
-				t2TimeCoincidenceAll.fill(getTimeConicidence(pair));
-				t2SumCoplanarityCalcAll.fill(pairEnergy, getCalculatedCoplanarity(pair));
-				t2SumCoplanarityAll.fill(pairEnergy, TriggerModule.getValueCoplanarity(pair));
-				
-				// Fill the singles plots.
-				if(!plotSet.contains(pair[0])) {
-					plotSet.add(pair[0]);
-					t2TimeEnergyAll.fill(pair[0].getEnergy(), TriggerModule.getClusterTime(pair[0]));
-				} if(!plotSet.contains(pair[1])) {
-					plotSet.add(pair[1]);
-					t2TimeEnergyAll.fill(pair[1].getEnergy(), TriggerModule.getClusterTime(pair[1]));
-				}
-				
-				// Fill the fiducial plots if appropriate.
-				if(inFiducialRegion(pair[0]) && inFiducialRegion(pair[1])) {
-					t2EnergySumFiducial.fill(pairEnergy);
-					t2EnergySum2DFiducial.fill(pair[1].getEnergy(), pair[0].getEnergy());
-					t2TimeCoincidenceFiducial.fill(getTimeConicidence(pair));
-					t2SumCoplanarityCalcFiducial.fill(pairEnergy, getCalculatedCoplanarity(pair));
-					t2SumCoplanarityFiducial.fill(pairEnergy, TriggerModule.getValueCoplanarity(pair));
-				}
-				
-				// Fill the singles fiducial plots if appropriate.
-				if(!plotFiducial.contains(pair[0]) && inFiducialRegion(pair[0])) {
-					plotFiducial.add(pair[0]);
-					t2TimeEnergyFiducial.fill(pair[0].getEnergy(), TriggerModule.getClusterTime(pair[0]));
-				} if(!plotFiducial.contains(pair[1]) && inFiducialRegion(pair[1])) {
-					plotFiducial.add(pair[1]);
-					t2TimeEnergyFiducial.fill(pair[1].getEnergy(), TriggerModule.getClusterTime(pair[1]));
-				}
-			}
-		}
-	}
-	
-	public static final double getInvariantMass(ReconstructedParticle[] pair) {
-		// Get energy.
-		double[] energy = new double[2];
-		final double electronMassSquared = Math.pow(0.00051099891, 2);
-		energy[0] = Math.sqrt(pair[0].getMomentum().magnitudeSquared() + electronMassSquared);
-		energy[1] = Math.sqrt(pair[1].getMomentum().magnitudeSquared() + electronMassSquared);
-		
-		// Calculate the invariant mass.
-		return Math.sqrt(Math.pow(energy[0] + energy[1], 2) - Math.pow(pair[0].getMomentum().x() + pair[1].getMomentum().x(), 2)
-				+ Math.pow(pair[0].getMomentum().y() + pair[1].getMomentum().y(), 2) + Math.pow(pair[0].getMomentum().z() + pair[1].getMomentum().z(), 2));
-	}
-	
-	public static final double getCalculatedCoplanarity(Cluster[] pair) {
-		// Define the x- and y-coordinates of the clusters as well as
-		// calorimeter center.
-		final double ORIGIN_X = 42.52;
-		double x[] = { pair[0].getPosition()[0], pair[1].getPosition()[0] };
-		double y[] = { pair[0].getPosition()[1], pair[1].getPosition()[1] };
-		
+        // Get the list of particles, if it exists.
+        List<ReconstructedParticle> trackList = null;
+        if(event.hasCollection(ReconstructedParticle.class, particleCollectionName)) {
+            trackList = event.get(ReconstructedParticle.class, particleCollectionName);
+        }
+        
+        // Get the list of clusters, if it exists.
+        List<Cluster> clusterList = null;
+        if(event.hasCollection(Cluster.class, clusterCollectionName)) {
+            clusterList = event.get(Cluster.class, clusterCollectionName);
+        }
+        
+        // Make sure that the cluster and track lists both exist.
+        if(clusterList == null || trackList == null) {
+            return;
+        }
+        
+        // Perform tier 1 analysis. This requires that there be at
+        // least one top/bottom cluster pair with a time difference
+        // of less then 4 ns.
+        double t1TimeThreshold = 1.5;
+        
+        // Get a list of cluster pairs.
+        List<Cluster[]> pairList = getClusterPairs(clusterList);
+        
+        // Iterate over the cluster pairs.
+        boolean t1Passed = false;
+        t1ClusterLoop:
+        for(Cluster[] pair : pairList) {
+            // Check that the time difference for the cluster pair
+            // meets the time cut.
+            if(TriggerModule.getValueTimeCoincidence(pair) <= t1TimeThreshold) {
+                // Note that the tier 1 analysis condition passed.
+                t1Passed = true;
+                
+                // Break from the loop.
+                break t1ClusterLoop;
+            }
+        }
+        
+        // Perform the additional checks for tier 2 analysis. This
+        // requires that there be at least one top/bottom track pair
+        // and that one track be positive and the other be negative.
+        
+        // Get a list of top and bottom track pairs.
+        List<ReconstructedParticle[]> trackPairList = getTrackPairs(trackList);
+        
+        // Check that at least one top/bottom track has one negative and
+        // one positive track.
+        boolean t2Passed = false;
+        t2TrackLoop:
+        for(ReconstructedParticle[] pair : trackPairList) {
+            if((pair[0].getCharge() > 0 && pair[1].getCharge() < 0) || (pair[0].getCharge() < 0 && pair[1].getCharge() > 0)) {
+                t2Passed = true;
+                break t2TrackLoop;
+            }
+        }
+        
+        // Populate the tier 0 analysis plot.
+        if(true) {
+            // Increment the number of tier 1 events found.
+            t0Events++;
+            
+            // Track which clusters have already been added to the
+            // singles plot so that there are no repeats.
+            Set<Cluster> plotSet = new HashSet<Cluster>(clusterList.size());
+            Set<Cluster> plotFiducial = new HashSet<Cluster>(clusterList.size());
+            
+            for(ReconstructedParticle[] pair : trackPairList) {
+                t0InvariantMassAll.fill(getInvariantMass(pair));
+            }
+            
+            for(Cluster[] pair : pairList) {
+                // Fill the all pairs plots.
+                double pairEnergy = pair[0].getEnergy() + pair[1].getEnergy();
+                t0EnergySumAll.fill(pairEnergy);
+                t0EnergySum2DAll.fill(pair[1].getEnergy(), pair[0].getEnergy());
+                t0TimeCoincidenceAll.fill(getTimeConicidence(pair));
+                t0SumCoplanarityCalcAll.fill(pairEnergy, getCalculatedCoplanarity(pair));
+                t0SumCoplanarityAll.fill(pairEnergy, TriggerModule.getValueCoplanarity(pair));
+                
+                // Fill the singles plots.
+                if(!plotSet.contains(pair[0])) {
+                    plotSet.add(pair[0]);
+                    t0TimeEnergyAll.fill(pair[0].getEnergy(), TriggerModule.getClusterTime(pair[0]));
+                } if(!plotSet.contains(pair[1])) {
+                    plotSet.add(pair[1]);
+                    t0TimeEnergyAll.fill(pair[1].getEnergy(), TriggerModule.getClusterTime(pair[1]));
+                }
+                
+                // Fill the fiducial plots if appropriate.
+                if(inFiducialRegion(pair[0]) && inFiducialRegion(pair[1])) {
+                    t0EnergySumFiducial.fill(pairEnergy);
+                    t0EnergySum2DFiducial.fill(pair[1].getEnergy(), pair[0].getEnergy());
+                    t0TimeCoincidenceFiducial.fill(getTimeConicidence(pair));
+                    t0SumCoplanarityCalcFiducial.fill(pairEnergy, getCalculatedCoplanarity(pair));
+                    t0SumCoplanarityFiducial.fill(pairEnergy, TriggerModule.getValueCoplanarity(pair));
+                }
+                
+                // Fill the singles fiducial plots if appropriate.
+                if(!plotFiducial.contains(pair[0]) && inFiducialRegion(pair[0])) {
+                    plotFiducial.add(pair[0]);
+                    t0TimeEnergyFiducial.fill(pair[0].getEnergy(), TriggerModule.getClusterTime(pair[0]));
+                } if(!plotFiducial.contains(pair[1]) && inFiducialRegion(pair[1])) {
+                    plotFiducial.add(pair[1]);
+                    t0TimeEnergyFiducial.fill(pair[1].getEnergy(), TriggerModule.getClusterTime(pair[1]));
+                }
+            }
+        }
+        
+        // Populate the tier 1 analysis plots, if the conditions were met.
+        if(t1Passed) {
+            // Increment the number of tier 1 events found.
+            t1Events++;
+            
+            // Track which clusters have already been added to the
+            // singles plot so that there are no repeats.
+            Set<Cluster> plotSet = new HashSet<Cluster>(clusterList.size());
+            Set<Cluster> plotFiducial = new HashSet<Cluster>(clusterList.size());
+            
+            for(ReconstructedParticle[] pair : trackPairList) {
+                t1InvariantMassAll.fill(getInvariantMass(pair));
+            }
+            
+            for(Cluster[] pair : pairList) {
+                // Only include clusters that pass the time coincidence.
+                if(TriggerModule.getValueTimeCoincidence(pair) > t1TimeThreshold) {
+                    continue;
+                }
+                
+                // Fill the all pairs plots.
+                double pairEnergy = pair[0].getEnergy() + pair[1].getEnergy();
+                t1EnergySumAll.fill(pairEnergy);
+                t1EnergySum2DAll.fill(pair[1].getEnergy(), pair[0].getEnergy());
+                t1TimeCoincidenceAll.fill(getTimeConicidence(pair));
+                t1SumCoplanarityCalcAll.fill(pairEnergy, getCalculatedCoplanarity(pair));
+                t1SumCoplanarityAll.fill(pairEnergy, TriggerModule.getValueCoplanarity(pair));
+                
+                // Fill the singles plots.
+                if(!plotSet.contains(pair[0])) {
+                    plotSet.add(pair[0]);
+                    t1TimeEnergyAll.fill(pair[0].getEnergy(), TriggerModule.getClusterTime(pair[0]));
+                } if(!plotSet.contains(pair[1])) {
+                    plotSet.add(pair[1]);
+                    t1TimeEnergyAll.fill(pair[1].getEnergy(), TriggerModule.getClusterTime(pair[1]));
+                }
+                
+                // Fill the fiducial plots if appropriate.
+                if(inFiducialRegion(pair[0]) && inFiducialRegion(pair[1])) {
+                    t1EnergySumFiducial.fill(pairEnergy);
+                    t1EnergySum2DFiducial.fill(pair[1].getEnergy(), pair[0].getEnergy());
+                    t1TimeCoincidenceFiducial.fill(getTimeConicidence(pair));
+                    t1SumCoplanarityCalcFiducial.fill(pairEnergy, getCalculatedCoplanarity(pair));
+                    t1SumCoplanarityFiducial.fill(pairEnergy, TriggerModule.getValueCoplanarity(pair));
+                }
+                
+                // Fill the singles fiducial plots if appropriate.
+                if(!plotFiducial.contains(pair[0]) && inFiducialRegion(pair[0])) {
+                    plotFiducial.add(pair[0]);
+                    t1TimeEnergyFiducial.fill(pair[0].getEnergy(), TriggerModule.getClusterTime(pair[0]));
+                } if(!plotFiducial.contains(pair[1]) && inFiducialRegion(pair[1])) {
+                    plotFiducial.add(pair[1]);
+                    t1TimeEnergyFiducial.fill(pair[1].getEnergy(), TriggerModule.getClusterTime(pair[1]));
+                }
+            }
+        }
+        
+        // Populate the tier 2 analysis plots, if the conditions were met.
+        if(t1Passed && t2Passed) {
+            // Increment the number of tier 2 events found.
+            t2Events++;
+            
+            // Track which clusters have already been added to the
+            // singles plot so that there are no repeats.
+            Set<Cluster> plotSet = new HashSet<Cluster>(clusterList.size());
+            Set<Cluster> plotFiducial = new HashSet<Cluster>(clusterList.size());
+            
+            for(ReconstructedParticle[] pair : trackPairList) {
+                t2InvariantMassAll.fill(getInvariantMass(pair));
+            }
+            
+            for(Cluster[] pair : pairList) {
+                // Only include clusters that pass the time coincidence.
+                if(TriggerModule.getValueTimeCoincidence(pair) > t1TimeThreshold) {
+                    continue;
+                }
+                
+                // Fill the all pairs plots.
+                double pairEnergy = pair[0].getEnergy() + pair[1].getEnergy();
+                t2EnergySumAll.fill(pairEnergy);
+                t2EnergySum2DAll.fill(pair[1].getEnergy(), pair[0].getEnergy());
+                t2TimeCoincidenceAll.fill(getTimeConicidence(pair));
+                t2SumCoplanarityCalcAll.fill(pairEnergy, getCalculatedCoplanarity(pair));
+                t2SumCoplanarityAll.fill(pairEnergy, TriggerModule.getValueCoplanarity(pair));
+                
+                // Fill the singles plots.
+                if(!plotSet.contains(pair[0])) {
+                    plotSet.add(pair[0]);
+                    t2TimeEnergyAll.fill(pair[0].getEnergy(), TriggerModule.getClusterTime(pair[0]));
+                } if(!plotSet.contains(pair[1])) {
+                    plotSet.add(pair[1]);
+                    t2TimeEnergyAll.fill(pair[1].getEnergy(), TriggerModule.getClusterTime(pair[1]));
+                }
+                
+                // Fill the fiducial plots if appropriate.
+                if(inFiducialRegion(pair[0]) && inFiducialRegion(pair[1])) {
+                    t2EnergySumFiducial.fill(pairEnergy);
+                    t2EnergySum2DFiducial.fill(pair[1].getEnergy(), pair[0].getEnergy());
+                    t2TimeCoincidenceFiducial.fill(getTimeConicidence(pair));
+                    t2SumCoplanarityCalcFiducial.fill(pairEnergy, getCalculatedCoplanarity(pair));
+                    t2SumCoplanarityFiducial.fill(pairEnergy, TriggerModule.getValueCoplanarity(pair));
+                }
+                
+                // Fill the singles fiducial plots if appropriate.
+                if(!plotFiducial.contains(pair[0]) && inFiducialRegion(pair[0])) {
+                    plotFiducial.add(pair[0]);
+                    t2TimeEnergyFiducial.fill(pair[0].getEnergy(), TriggerModule.getClusterTime(pair[0]));
+                } if(!plotFiducial.contains(pair[1]) && inFiducialRegion(pair[1])) {
+                    plotFiducial.add(pair[1]);
+                    t2TimeEnergyFiducial.fill(pair[1].getEnergy(), TriggerModule.getClusterTime(pair[1]));
+                }
+            }
+        }
+    }
+    
+    public static final double getInvariantMass(ReconstructedParticle[] pair) {
+        // Get energy.
+        double[] energy = new double[2];
+        final double electronMassSquared = Math.pow(0.00051099891, 2);
+        energy[0] = Math.sqrt(pair[0].getMomentum().magnitudeSquared() + electronMassSquared);
+        energy[1] = Math.sqrt(pair[1].getMomentum().magnitudeSquared() + electronMassSquared);
+        
+        // Calculate the invariant mass.
+        return Math.sqrt(Math.pow(energy[0] + energy[1], 2) - Math.pow(pair[0].getMomentum().x() + pair[1].getMomentum().x(), 2)
+                + Math.pow(pair[0].getMomentum().y() + pair[1].getMomentum().y(), 2) + Math.pow(pair[0].getMomentum().z() + pair[1].getMomentum().z(), 2));
+    }
+    
+    public static final double getCalculatedCoplanarity(Cluster[] pair) {
+        // Define the x- and y-coordinates of the clusters as well as
+        // calorimeter center.
+        final double ORIGIN_X = 42.52;
+        double x[] = { pair[0].getPosition()[0], pair[1].getPosition()[0] };
+        double y[] = { pair[0].getPosition()[1], pair[1].getPosition()[1] };
+        
         // Get the cluster angles.
         double[] clusterAngle = new double[2];
         for(int i = 0; i < 2; i++) {
-        	clusterAngle[i] = Math.atan2(y[i], x[i] - ORIGIN_X) * 180 / Math.PI;
-        	if(clusterAngle[i] <= 0) { clusterAngle[i] += 360; }
+            clusterAngle[i] = Math.atan2(y[i], x[i] - ORIGIN_X) * 180 / Math.PI;
+            if(clusterAngle[i] <= 0) { clusterAngle[i] += 360; }
         }
         
         // Calculate the coplanarity cut value.
         double clusterDiff = clusterAngle[0] - clusterAngle[1];
         return clusterDiff > 0 ? clusterDiff : clusterDiff + 360;
-	}
-	
-	private static final boolean inFiducialRegion(Cluster cluster) {
-		// Get the x and y indices for the cluster.
-		int ix   = TriggerModule.getClusterXIndex(cluster);
-		int absx = Math.abs(TriggerModule.getClusterXIndex(cluster));
-		int absy = Math.abs(TriggerModule.getClusterYIndex(cluster));
-		
-		// Check if the cluster is on the top or the bottom of the
-		// calorimeter, as defined by |y| == 5. This is an edge cluster
-		// and is not in the fiducial region.
-		if(absy == 5) {
-			return false;
-		}
-		
-		// Check if the cluster is on the extreme left or right side
-		// of the calorimeter, as defined by |x| == 23. This is also
-		// and edge cluster is not in the fiducial region.
-		if(absx == 23) {
-			return false;
-		}
-		
-		// Check if the cluster is along the beam gap, as defined by
-		// |y| == 1. This is an internal edge cluster and is not in the
-		// fiducial region.
-		if(absy == 1) {
-			return false;
-		}
-		
-		// Lastly, check if the cluster falls along the beam hole, as
-		// defined by clusters with -11 <= x <= -1 and |y| == 2. This
-		// is not the fiducial region.
-		if(absy == 2 && ix <= -1 && ix >= -11) {
-			return false;
-		}
-		
-		// If all checks fail, the cluster is in the fiducial region.
-		return true;
-	}
-	
-	private static final List<ReconstructedParticle[]> getTrackPairs(List<ReconstructedParticle> tracks) {
-		// Separate the tracks into top and bottom tracks.
-		List<ReconstructedParticle> topList = new ArrayList<ReconstructedParticle>();
-		List<ReconstructedParticle> botList = new ArrayList<ReconstructedParticle>();
-		for(ReconstructedParticle track : tracks) {
-			// Make sure that the track actually contains tracks.
-			if(track.getTracks().size() > 0) {
-				// Use the tan(Λ) to differentiate "top" and "bottom"
-				// tracks from one another.
-				if(track.getTracks().get(0).getTrackStates().get(0).getTanLambda() > 0) {
-					topList.add(track);
-				} else {
-					botList.add(track);
-				}
-			}
-		}
-		
-		// Form all permutations of top and bottom tracks.
-		List<ReconstructedParticle[]> pairList = new ArrayList<ReconstructedParticle[]>();
-		for(ReconstructedParticle topTrack : topList) {
-			for(ReconstructedParticle botTrack : botList) {
-				pairList.add(new ReconstructedParticle[] { topTrack, botTrack });
-			}
-		}
-		
-		// Return the resulting cluster pairs.
-		return pairList;
-	}
-	
-	private static final List<Cluster[]> getClusterPairs(List<Cluster> clusters) {
-		// Separate the clusters into top and bottom clusters.
-		List<Cluster> topList = new ArrayList<Cluster>();
-		List<Cluster> botList = new ArrayList<Cluster>();
-		for(Cluster cluster : clusters) {
-			if(TriggerModule.getClusterYIndex(cluster) > 0) {
-				topList.add(cluster);
-			} else {
-				botList.add(cluster);
-			}
-		}
-		
-		// Form all permutations of top and bottom clusters.
-		List<Cluster[]> pairList = new ArrayList<Cluster[]>();
-		for(Cluster topCluster : topList) {
-			for(Cluster botCluster : botList) {
-				pairList.add(new Cluster[] { topCluster, botCluster });
-			}
-		}
-		
-		// Return the resulting cluster pairs.
-		return pairList;
-	}
-	
-	public static final double getTimeConicidence(Cluster[] pair) {
-		return TriggerModule.getClusterSeedHit(pair[1]).getTime() - TriggerModule.getClusterSeedHit(pair[0]).getTime();
-	}
-	
-	public void setUseGoodSVT(boolean state) {
-		useGoodSVT = state;
-	}
+    }
+    
+    private static final boolean inFiducialRegion(Cluster cluster) {
+        // Get the x and y indices for the cluster.
+        int ix   = TriggerModule.getClusterXIndex(cluster);
+        int absx = Math.abs(TriggerModule.getClusterXIndex(cluster));
+        int absy = Math.abs(TriggerModule.getClusterYIndex(cluster));
+        
+        // Check if the cluster is on the top or the bottom of the
+        // calorimeter, as defined by |y| == 5. This is an edge cluster
+        // and is not in the fiducial region.
+        if(absy == 5) {
+            return false;
+        }
+        
+        // Check if the cluster is on the extreme left or right side
+        // of the calorimeter, as defined by |x| == 23. This is also
+        // and edge cluster is not in the fiducial region.
+        if(absx == 23) {
+            return false;
+        }
+        
+        // Check if the cluster is along the beam gap, as defined by
+        // |y| == 1. This is an internal edge cluster and is not in the
+        // fiducial region.
+        if(absy == 1) {
+            return false;
+        }
+        
+        // Lastly, check if the cluster falls along the beam hole, as
+        // defined by clusters with -11 <= x <= -1 and |y| == 2. This
+        // is not the fiducial region.
+        if(absy == 2 && ix <= -1 && ix >= -11) {
+            return false;
+        }
+        
+        // If all checks fail, the cluster is in the fiducial region.
+        return true;
+    }
+    
+    private static final List<ReconstructedParticle[]> getTrackPairs(List<ReconstructedParticle> tracks) {
+        // Separate the tracks into top and bottom tracks.
+        List<ReconstructedParticle> topList = new ArrayList<ReconstructedParticle>();
+        List<ReconstructedParticle> botList = new ArrayList<ReconstructedParticle>();
+        for(ReconstructedParticle track : tracks) {
+            // Make sure that the track actually contains tracks.
+            if(track.getTracks().size() > 0) {
+                // Use the tan(Λ) to differentiate "top" and "bottom"
+                // tracks from one another.
+                if(track.getTracks().get(0).getTrackStates().get(0).getTanLambda() > 0) {
+                    topList.add(track);
+                } else {
+                    botList.add(track);
+                }
+            }
+        }
+        
+        // Form all permutations of top and bottom tracks.
+        List<ReconstructedParticle[]> pairList = new ArrayList<ReconstructedParticle[]>();
+        for(ReconstructedParticle topTrack : topList) {
+            for(ReconstructedParticle botTrack : botList) {
+                pairList.add(new ReconstructedParticle[] { topTrack, botTrack });
+            }
+        }
+        
+        // Return the resulting cluster pairs.
+        return pairList;
+    }
+    
+    private static final List<Cluster[]> getClusterPairs(List<Cluster> clusters) {
+        // Separate the clusters into top and bottom clusters.
+        List<Cluster> topList = new ArrayList<Cluster>();
+        List<Cluster> botList = new ArrayList<Cluster>();
+        for(Cluster cluster : clusters) {
+            if(TriggerModule.getClusterYIndex(cluster) > 0) {
+                topList.add(cluster);
+            } else {
+                botList.add(cluster);
+            }
+        }
+        
+        // Form all permutations of top and bottom clusters.
+        List<Cluster[]> pairList = new ArrayList<Cluster[]>();
+        for(Cluster topCluster : topList) {
+            for(Cluster botCluster : botList) {
+                pairList.add(new Cluster[] { topCluster, botCluster });
+            }
+        }
+        
+        // Return the resulting cluster pairs.
+        return pairList;
+    }
+    
+    public static final double getTimeConicidence(Cluster[] pair) {
+        return TriggerModule.getClusterSeedHit(pair[1]).getTime() - TriggerModule.getClusterSeedHit(pair[0]).getTime();
+    }
+    
+    public void setUseGoodSVT(boolean state) {
+        useGoodSVT = state;
+    }
 }

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/TridentTrackDriver.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/TridentTrackDriver.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/TridentTrackDriver.java	Wed Apr 27 11:11:32 2016
@@ -15,229 +15,229 @@
 import org.lcsim.util.aida.AIDA;
 
 public class TridentTrackDriver extends Driver {
-	private String finalStateCollectionName = "FinalStateParticles";
-	private String candidateCollectionName = "UnconstrainedV0Candidates";
-	
-	private int tracksCandidate = 0;
-	private int tracksFinalState = 0;
-	private int tracksCandidateCluster = 0;
-	private int tracksFinalStateCluster = 0;
-	
-	private static final int ANY_CLUSTER = 0;
-	private static final int HAS_CLUSTER = 1;
-	
-	private AIDA aida = AIDA.defaultInstance();
-	private IHistogram1D[] tracks = new IHistogram1D[2];
-	private IHistogram1D[] posTracks = new IHistogram1D[2];
-	private IHistogram1D[] negTracks = new IHistogram1D[2];
-	private IHistogram1D[] posMomentum = new IHistogram1D[2];
-	private IHistogram1D[] negMomentum = new IHistogram1D[2];
-	private IHistogram1D[] energySum = new IHistogram1D[2];
-	private IHistogram1D[] energyMomentumDiff = new IHistogram1D[2];
-	private IHistogram1D[] momentumSum = new IHistogram1D[2];
-	private IHistogram1D[] invariantMass = new IHistogram1D[2];
-	private IHistogram2D[] energySum2D = new IHistogram2D[2];
-	private IHistogram2D[] momentumSum2D = new IHistogram2D[2];
-	private IHistogram2D[] position = new IHistogram2D[2];
-	
-	@Override
-	public void startOfData() {
-		// Instantiate the "any cluster status" plots.
-		tracks[ANY_CLUSTER] = aida.histogram1D("Trident Analysis/All/Tracks in Event (All)", 7, -0.5, 6.5);
-		posTracks[ANY_CLUSTER] = aida.histogram1D("Trident Analysis/All/Tracks in Event (Positive)", 7, -0.5, 6.5);
-		negTracks[ANY_CLUSTER] = aida.histogram1D("Trident Analysis/All/Tracks in Event (Negative)", 7, -0.5, 6.5);
-		posMomentum[ANY_CLUSTER] = aida.histogram1D("Trident Analysis/All/Momentum (Positive)", 110, 0, 1.1);
-		negMomentum[ANY_CLUSTER] = aida.histogram1D("Trident Analysis/All/Momentum (Negative)", 110, 0, 1.1);
-		energySum[ANY_CLUSTER] = aida.histogram1D("Trident Analysis/All/Energy Sum", 55, 0, 2.2);
-		momentumSum[ANY_CLUSTER] = aida.histogram1D("Trident Analysis/All/Momentum Sum", 55, 0, 2.2);
-		energyMomentumDiff[ANY_CLUSTER] = aida.histogram1D("Trident Analysis/All/Energy-Momentum Difference", 55, 0, 2.2);
-		invariantMass[ANY_CLUSTER] = aida.histogram1D("Trident Analysis/All/Invariant Mass", 240, 0.000, 0.120);
-		energySum2D[ANY_CLUSTER] = aida.histogram2D("Trident Analysis/All/2D Energy Sum", 55, 0, 1.1, 55, 0, 1.1);
-		momentumSum2D[ANY_CLUSTER] = aida.histogram2D("Trident Analysis/All/2D Momentum Sum", 55, 0, 1.1, 55, 0, 1.1);
-		position[ANY_CLUSTER] = aida.histogram2D("Trident Analysis/All/Track Cluster Position", 46, -23, 23, 11, -5.5, 5.5);
-		
-		// Instantiate the "has a cluster" plots.
-		tracks[HAS_CLUSTER] = aida.histogram1D("Trident Analysis/Cluster/Tracks in Event (All)", 7, -0.5, 6.5);
-		posTracks[HAS_CLUSTER] = aida.histogram1D("Trident Analysis/Cluster/Tracks in Event (Positive)", 7, -0.5, 6.5);
-		negTracks[HAS_CLUSTER] = aida.histogram1D("Trident Analysis/Cluster/Tracks in Event (Negative)", 7, -0.5, 6.5);
-		posMomentum[HAS_CLUSTER] = aida.histogram1D("Trident Analysis/Cluster/Momentum (Positive)", 110, 0, 1.1);
-		negMomentum[HAS_CLUSTER] = aida.histogram1D("Trident Analysis/Cluster/Momentum (Negative)", 110, 0, 1.1);
-		energySum[HAS_CLUSTER] = aida.histogram1D("Trident Analysis/Cluster/Energy Sum", 55, 0, 2.2);
-		momentumSum[HAS_CLUSTER] = aida.histogram1D("Trident Analysis/Cluster/Momentum Sum", 55, 0, 2.2);
-		energyMomentumDiff[HAS_CLUSTER] = aida.histogram1D("Trident Analysis/Cluster/Energy-Momentum Difference", 55, 0, 2.2);
-		invariantMass[HAS_CLUSTER] = aida.histogram1D("Trident Analysis/Cluster/Invariant Mass", 240, 0.000, 0.120);
-		energySum2D[HAS_CLUSTER] = aida.histogram2D("Trident Analysis/Cluster/2D Energy Sum", 55, 0, 1.1, 55, 0, 1.1);
-		momentumSum2D[HAS_CLUSTER] = aida.histogram2D("Trident Analysis/Cluster/2D Momentum Sum", 55, 0, 1.1, 55, 0, 1.1);
-		position[HAS_CLUSTER] = aida.histogram2D("Trident Analysis/Cluster/Track Cluster Position", 46, -23, 23, 11, -5.5, 5.5);
-	}
-	
-	@Override
-	public void endOfData() {
-		System.out.printf("Tracks (Candidate)           :: %d%n", tracksCandidate);
-		System.out.printf("Tracks (Final State)         :: %d%n", tracksFinalState);
-		System.out.printf("Cluster Tracks (Candidate)   :: %d%n", tracksCandidateCluster);
-		System.out.printf("Cluster Tracks (Final State) :: %d%n", tracksFinalStateCluster);
-	}
-	
-	@Override
-	public void process(EventHeader event) {
-		// Check for final state particles.
-		if(event.hasCollection(ReconstructedParticle.class, finalStateCollectionName)) {
-			// Get the final state particles.
-			List<ReconstructedParticle> trackList = event.get(ReconstructedParticle.class, finalStateCollectionName);
-			
-			// Store the positive and negative tracks.
-			List<ReconstructedParticle> allTrackList = new ArrayList<ReconstructedParticle>();
-			List<ReconstructedParticle> posTrackList = new ArrayList<ReconstructedParticle>();
-			List<ReconstructedParticle> negTrackList = new ArrayList<ReconstructedParticle>();
-			
-			// Store the same tracks, but limited to those with clusters.
-			List<ReconstructedParticle> allClusterTrackList = new ArrayList<ReconstructedParticle>();
-			List<ReconstructedParticle> posClusterTrackList = new ArrayList<ReconstructedParticle>();
-			List<ReconstructedParticle> negClusterTrackList = new ArrayList<ReconstructedParticle>();
-			
-			// Iterate over the tracks and populate the lists.
-			for(ReconstructedParticle track : trackList) {
-				// Skip instances with no raw tracks.
-				if(track.getTracks().size() == 0) { continue; }
-				
-				// Add the cluster to the all track list.
-				allTrackList.add(track);
-				
-				// Track the number of cluster tracks.
-				tracksFinalState++;
-				if(!track.getClusters().isEmpty()) {
-					tracksFinalStateCluster++;
-				}
-				
-				// Process the track position plots.
-				Hep3Vector trackPosAtEcal = TrackUtils.extrapolateTrack(track.getTracks().get(0), 1394.5);
-				position[ANY_CLUSTER].fill(trackPosAtEcal.x(), trackPosAtEcal.y());
-				
-				// Process the tracks based on charge.
-				if(track.getCharge() > 0) {
-					// Increment the counters and populate the momentum plots.
-					posTrackList.add(track);
-					posMomentum[ANY_CLUSTER].fill(track.getMomentum().magnitude());
-					
-					// Repeat for the "has clusters" plots if necessary.
-					if(track.getClusters().size() > 0) {
-						// Increment the counters and populate the
-						// momentum plot.
-						posClusterTrackList.add(track);
-						allClusterTrackList.add(track);
-						posMomentum[HAS_CLUSTER].fill(track.getMomentum().magnitude());
-						
-						// Populate the cluster position plot.
-						//int ix = track.getClusters().get(0).getCalorimeterHits().get(0).getIdentifierFieldValue("ix");
-						//int iy = track.getClusters().get(0).getCalorimeterHits().get(0).getIdentifierFieldValue("iy");
-						position[HAS_CLUSTER].fill(trackPosAtEcal.x(), trackPosAtEcal.y());
-					}
-				} else if(track.getCharge() < 0) {
-					// Increment the counters and populate the momentum plots.
-					negTrackList.add(track);
-					negMomentum[ANY_CLUSTER].fill(track.getMomentum().magnitude());
-					
-					// Repeat for the "has clusters" plots if necessary.
-					if(track.getClusters().size() > 0) {
-						// Increment the counters and populate the
-						// momentum plot.
-						negClusterTrackList.add(track);
-						allClusterTrackList.add(track);
-						negMomentum[HAS_CLUSTER].fill(track.getMomentum().magnitude());
-						
-						// Populate the cluster position plot.
-						//int ix = track.getClusters().get(0).getCalorimeterHits().get(0).getIdentifierFieldValue("ix");
-						//int iy = track.getClusters().get(0).getCalorimeterHits().get(0).getIdentifierFieldValue("iy");
-						position[HAS_CLUSTER].fill(trackPosAtEcal.x(), trackPosAtEcal.y());
-					}
-				} else {
-					if(track.getClusters().size() > 0) {
-						// Increment the counter.
-						allClusterTrackList.add(track);
-						
-						// Populate the cluster position plot.
-						//int ix = track.getClusters().get(0).getCalorimeterHits().get(0).getIdentifierFieldValue("ix");
-						//int iy = track.getClusters().get(0).getCalorimeterHits().get(0).getIdentifierFieldValue("iy");
-						position[HAS_CLUSTER].fill(trackPosAtEcal.x(), trackPosAtEcal.y());
-					}
-				}
-			}
-			
-			// Populate the tracks per event plots.
-			tracks[ANY_CLUSTER].fill(allTrackList.size());
-			tracks[HAS_CLUSTER].fill(allClusterTrackList.size());
-			posTracks[ANY_CLUSTER].fill(posTrackList.size());
-			posTracks[HAS_CLUSTER].fill(posClusterTrackList.size());
-			negTracks[ANY_CLUSTER].fill(negTrackList.size());
-			negTracks[HAS_CLUSTER].fill(negClusterTrackList.size());
-			
-			/// Store track pairs.
-			List<ReconstructedParticle[]> pairList = new ArrayList<ReconstructedParticle[]>();
-			List<ReconstructedParticle[]> pairClusterList = new ArrayList<ReconstructedParticle[]>();
-			
-			// Form track pairs for all tracks.
-			for(ReconstructedParticle posTrack : posTrackList) {
-				for(ReconstructedParticle negTrack : negTrackList) {
-					pairList.add(new ReconstructedParticle[] { posTrack, negTrack });
-				}
-			}
-			
-			// Form track pairs for cluster tracks.
-			for(ReconstructedParticle posTrack : posClusterTrackList) {
-				for(ReconstructedParticle negTrack : negClusterTrackList) {
-					pairClusterList.add(new ReconstructedParticle[] { posTrack, negTrack });
-				}
-			}
-			
-			// Populate the track pair plots.
-			for(ReconstructedParticle[] pair : pairList) {
-				Hep3Vector pSum = new BasicHep3Vector(
-						pair[0].getMomentum().x() + pair[1].getMomentum().x(),
-						pair[0].getMomentum().y() + pair[1].getMomentum().y(),
-						pair[0].getMomentum().z() + pair[1].getMomentum().z());
-				
-				energySum[ANY_CLUSTER].fill(pair[0].getEnergy() + pair[1].getEnergy());
-				momentumSum[ANY_CLUSTER].fill(pSum.magnitude());
-				energySum2D[ANY_CLUSTER].fill(pair[0].getEnergy(), pair[1].getEnergy());
-				momentumSum2D[ANY_CLUSTER].fill(pair[0].getMomentum().magnitude(), pair[1].getMomentum().magnitude());
-				energyMomentumDiff[ANY_CLUSTER].fill(Math.abs((pair[0].getEnergy() + pair[1].getEnergy()) - pSum.magnitude()));
-			}
-			
-			// Populate the cluster track pair plots.
-			for(ReconstructedParticle[] pair : pairClusterList) {
-				Hep3Vector pSum = new BasicHep3Vector(
-						pair[0].getMomentum().x() + pair[1].getMomentum().x(),
-						pair[0].getMomentum().y() + pair[1].getMomentum().y(),
-						pair[0].getMomentum().z() + pair[1].getMomentum().z());
-				
-				energySum[HAS_CLUSTER].fill(pair[0].getEnergy() + pair[1].getEnergy());
-				momentumSum[HAS_CLUSTER].fill(pSum.magnitude());
-				energySum2D[HAS_CLUSTER].fill(pair[0].getEnergy(), pair[1].getEnergy());
-				momentumSum2D[HAS_CLUSTER].fill(pair[0].getMomentum().magnitude(), pair[1].getMomentum().magnitude());
-				energyMomentumDiff[HAS_CLUSTER].fill(Math.abs((pair[0].getEnergy() + pair[1].getEnergy()) - pSum.magnitude()));
-			}
-		}
-		
-		// Check for V0 candidates.
-		if(event.hasCollection(ReconstructedParticle.class, candidateCollectionName)) {
-			// Get the candidate particles.
-			List<ReconstructedParticle> trackList = event.get(ReconstructedParticle.class, candidateCollectionName);
-			
-			// Increment the counter.
-			tracksCandidate += trackList.size();
-			
-			// Increment the counter for cluster tracks.
-			for(ReconstructedParticle track : trackList) {
-				// Populate the invariant mass plot.
-				invariantMass[ANY_CLUSTER].fill(track.getMass());
-				
-				// Check for a cluster track.
-				if(track.getClusters().size() > 0) {
-					tracksCandidateCluster++;
-					invariantMass[HAS_CLUSTER].fill(track.getMass());
-				}
-			}
-		}
-	}
+    private String finalStateCollectionName = "FinalStateParticles";
+    private String candidateCollectionName = "UnconstrainedV0Candidates";
+    
+    private int tracksCandidate = 0;
+    private int tracksFinalState = 0;
+    private int tracksCandidateCluster = 0;
+    private int tracksFinalStateCluster = 0;
+    
+    private static final int ANY_CLUSTER = 0;
+    private static final int HAS_CLUSTER = 1;
+    
+    private AIDA aida = AIDA.defaultInstance();
+    private IHistogram1D[] tracks = new IHistogram1D[2];
+    private IHistogram1D[] posTracks = new IHistogram1D[2];
+    private IHistogram1D[] negTracks = new IHistogram1D[2];
+    private IHistogram1D[] posMomentum = new IHistogram1D[2];
+    private IHistogram1D[] negMomentum = new IHistogram1D[2];
+    private IHistogram1D[] energySum = new IHistogram1D[2];
+    private IHistogram1D[] energyMomentumDiff = new IHistogram1D[2];
+    private IHistogram1D[] momentumSum = new IHistogram1D[2];
+    private IHistogram1D[] invariantMass = new IHistogram1D[2];
+    private IHistogram2D[] energySum2D = new IHistogram2D[2];
+    private IHistogram2D[] momentumSum2D = new IHistogram2D[2];
+    private IHistogram2D[] position = new IHistogram2D[2];
+    
+    @Override
+    public void startOfData() {
+        // Instantiate the "any cluster status" plots.
+        tracks[ANY_CLUSTER] = aida.histogram1D("Trident Analysis/All/Tracks in Event (All)", 7, -0.5, 6.5);
+        posTracks[ANY_CLUSTER] = aida.histogram1D("Trident Analysis/All/Tracks in Event (Positive)", 7, -0.5, 6.5);
+        negTracks[ANY_CLUSTER] = aida.histogram1D("Trident Analysis/All/Tracks in Event (Negative)", 7, -0.5, 6.5);
+        posMomentum[ANY_CLUSTER] = aida.histogram1D("Trident Analysis/All/Momentum (Positive)", 110, 0, 1.1);
+        negMomentum[ANY_CLUSTER] = aida.histogram1D("Trident Analysis/All/Momentum (Negative)", 110, 0, 1.1);
+        energySum[ANY_CLUSTER] = aida.histogram1D("Trident Analysis/All/Energy Sum", 55, 0, 2.2);
+        momentumSum[ANY_CLUSTER] = aida.histogram1D("Trident Analysis/All/Momentum Sum", 55, 0, 2.2);
+        energyMomentumDiff[ANY_CLUSTER] = aida.histogram1D("Trident Analysis/All/Energy-Momentum Difference", 55, 0, 2.2);
+        invariantMass[ANY_CLUSTER] = aida.histogram1D("Trident Analysis/All/Invariant Mass", 240, 0.000, 0.120);
+        energySum2D[ANY_CLUSTER] = aida.histogram2D("Trident Analysis/All/2D Energy Sum", 55, 0, 1.1, 55, 0, 1.1);
+        momentumSum2D[ANY_CLUSTER] = aida.histogram2D("Trident Analysis/All/2D Momentum Sum", 55, 0, 1.1, 55, 0, 1.1);
+        position[ANY_CLUSTER] = aida.histogram2D("Trident Analysis/All/Track Cluster Position", 46, -23, 23, 11, -5.5, 5.5);
+        
+        // Instantiate the "has a cluster" plots.
+        tracks[HAS_CLUSTER] = aida.histogram1D("Trident Analysis/Cluster/Tracks in Event (All)", 7, -0.5, 6.5);
+        posTracks[HAS_CLUSTER] = aida.histogram1D("Trident Analysis/Cluster/Tracks in Event (Positive)", 7, -0.5, 6.5);
+        negTracks[HAS_CLUSTER] = aida.histogram1D("Trident Analysis/Cluster/Tracks in Event (Negative)", 7, -0.5, 6.5);
+        posMomentum[HAS_CLUSTER] = aida.histogram1D("Trident Analysis/Cluster/Momentum (Positive)", 110, 0, 1.1);
+        negMomentum[HAS_CLUSTER] = aida.histogram1D("Trident Analysis/Cluster/Momentum (Negative)", 110, 0, 1.1);
+        energySum[HAS_CLUSTER] = aida.histogram1D("Trident Analysis/Cluster/Energy Sum", 55, 0, 2.2);
+        momentumSum[HAS_CLUSTER] = aida.histogram1D("Trident Analysis/Cluster/Momentum Sum", 55, 0, 2.2);
+        energyMomentumDiff[HAS_CLUSTER] = aida.histogram1D("Trident Analysis/Cluster/Energy-Momentum Difference", 55, 0, 2.2);
+        invariantMass[HAS_CLUSTER] = aida.histogram1D("Trident Analysis/Cluster/Invariant Mass", 240, 0.000, 0.120);
+        energySum2D[HAS_CLUSTER] = aida.histogram2D("Trident Analysis/Cluster/2D Energy Sum", 55, 0, 1.1, 55, 0, 1.1);
+        momentumSum2D[HAS_CLUSTER] = aida.histogram2D("Trident Analysis/Cluster/2D Momentum Sum", 55, 0, 1.1, 55, 0, 1.1);
+        position[HAS_CLUSTER] = aida.histogram2D("Trident Analysis/Cluster/Track Cluster Position", 46, -23, 23, 11, -5.5, 5.5);
+    }
+    
+    @Override
+    public void endOfData() {
+        System.out.printf("Tracks (Candidate)           :: %d%n", tracksCandidate);
+        System.out.printf("Tracks (Final State)         :: %d%n", tracksFinalState);
+        System.out.printf("Cluster Tracks (Candidate)   :: %d%n", tracksCandidateCluster);
+        System.out.printf("Cluster Tracks (Final State) :: %d%n", tracksFinalStateCluster);
+    }
+    
+    @Override
+    public void process(EventHeader event) {
+        // Check for final state particles.
+        if(event.hasCollection(ReconstructedParticle.class, finalStateCollectionName)) {
+            // Get the final state particles.
+            List<ReconstructedParticle> trackList = event.get(ReconstructedParticle.class, finalStateCollectionName);
+            
+            // Store the positive and negative tracks.
+            List<ReconstructedParticle> allTrackList = new ArrayList<ReconstructedParticle>();
+            List<ReconstructedParticle> posTrackList = new ArrayList<ReconstructedParticle>();
+            List<ReconstructedParticle> negTrackList = new ArrayList<ReconstructedParticle>();
+            
+            // Store the same tracks, but limited to those with clusters.
+            List<ReconstructedParticle> allClusterTrackList = new ArrayList<ReconstructedParticle>();
+            List<ReconstructedParticle> posClusterTrackList = new ArrayList<ReconstructedParticle>();
+            List<ReconstructedParticle> negClusterTrackList = new ArrayList<ReconstructedParticle>();
+            
+            // Iterate over the tracks and populate the lists.
+            for(ReconstructedParticle track : trackList) {
+                // Skip instances with no raw tracks.
+                if(track.getTracks().size() == 0) { continue; }
+                
+                // Add the cluster to the all track list.
+                allTrackList.add(track);
+                
+                // Track the number of cluster tracks.
+                tracksFinalState++;
+                if(!track.getClusters().isEmpty()) {
+                    tracksFinalStateCluster++;
+                }
+                
+                // Process the track position plots.
+                Hep3Vector trackPosAtEcal = TrackUtils.extrapolateTrack(track.getTracks().get(0), 1394.5);
+                position[ANY_CLUSTER].fill(trackPosAtEcal.x(), trackPosAtEcal.y());
+                
+                // Process the tracks based on charge.
+                if(track.getCharge() > 0) {
+                    // Increment the counters and populate the momentum plots.
+                    posTrackList.add(track);
+                    posMomentum[ANY_CLUSTER].fill(track.getMomentum().magnitude());
+                    
+                    // Repeat for the "has clusters" plots if necessary.
+                    if(track.getClusters().size() > 0) {
+                        // Increment the counters and populate the
+                        // momentum plot.
+                        posClusterTrackList.add(track);
+                        allClusterTrackList.add(track);
+                        posMomentum[HAS_CLUSTER].fill(track.getMomentum().magnitude());
+                        
+                        // Populate the cluster position plot.
+                        //int ix = track.getClusters().get(0).getCalorimeterHits().get(0).getIdentifierFieldValue("ix");
+                        //int iy = track.getClusters().get(0).getCalorimeterHits().get(0).getIdentifierFieldValue("iy");
+                        position[HAS_CLUSTER].fill(trackPosAtEcal.x(), trackPosAtEcal.y());
+                    }
+                } else if(track.getCharge() < 0) {
+                    // Increment the counters and populate the momentum plots.
+                    negTrackList.add(track);
+                    negMomentum[ANY_CLUSTER].fill(track.getMomentum().magnitude());
+                    
+                    // Repeat for the "has clusters" plots if necessary.
+                    if(track.getClusters().size() > 0) {
+                        // Increment the counters and populate the
+                        // momentum plot.
+                        negClusterTrackList.add(track);
+                        allClusterTrackList.add(track);
+                        negMomentum[HAS_CLUSTER].fill(track.getMomentum().magnitude());
+                        
+                        // Populate the cluster position plot.
+                        //int ix = track.getClusters().get(0).getCalorimeterHits().get(0).getIdentifierFieldValue("ix");
+                        //int iy = track.getClusters().get(0).getCalorimeterHits().get(0).getIdentifierFieldValue("iy");
+                        position[HAS_CLUSTER].fill(trackPosAtEcal.x(), trackPosAtEcal.y());
+                    }
+                } else {
+                    if(track.getClusters().size() > 0) {
+                        // Increment the counter.
+                        allClusterTrackList.add(track);
+                        
+                        // Populate the cluster position plot.
+                        //int ix = track.getClusters().get(0).getCalorimeterHits().get(0).getIdentifierFieldValue("ix");
+                        //int iy = track.getClusters().get(0).getCalorimeterHits().get(0).getIdentifierFieldValue("iy");
+                        position[HAS_CLUSTER].fill(trackPosAtEcal.x(), trackPosAtEcal.y());
+                    }
+                }
+            }
+            
+            // Populate the tracks per event plots.
+            tracks[ANY_CLUSTER].fill(allTrackList.size());
+            tracks[HAS_CLUSTER].fill(allClusterTrackList.size());
+            posTracks[ANY_CLUSTER].fill(posTrackList.size());
+            posTracks[HAS_CLUSTER].fill(posClusterTrackList.size());
+            negTracks[ANY_CLUSTER].fill(negTrackList.size());
+            negTracks[HAS_CLUSTER].fill(negClusterTrackList.size());
+            
+            /// Store track pairs.
+            List<ReconstructedParticle[]> pairList = new ArrayList<ReconstructedParticle[]>();
+            List<ReconstructedParticle[]> pairClusterList = new ArrayList<ReconstructedParticle[]>();
+            
+            // Form track pairs for all tracks.
+            for(ReconstructedParticle posTrack : posTrackList) {
+                for(ReconstructedParticle negTrack : negTrackList) {
+                    pairList.add(new ReconstructedParticle[] { posTrack, negTrack });
+                }
+            }
+            
+            // Form track pairs for cluster tracks.
+            for(ReconstructedParticle posTrack : posClusterTrackList) {
+                for(ReconstructedParticle negTrack : negClusterTrackList) {
+                    pairClusterList.add(new ReconstructedParticle[] { posTrack, negTrack });
+                }
+            }
+            
+            // Populate the track pair plots.
+            for(ReconstructedParticle[] pair : pairList) {
+                Hep3Vector pSum = new BasicHep3Vector(
+                        pair[0].getMomentum().x() + pair[1].getMomentum().x(),
+                        pair[0].getMomentum().y() + pair[1].getMomentum().y(),
+                        pair[0].getMomentum().z() + pair[1].getMomentum().z());
+                
+                energySum[ANY_CLUSTER].fill(pair[0].getEnergy() + pair[1].getEnergy());
+                momentumSum[ANY_CLUSTER].fill(pSum.magnitude());
+                energySum2D[ANY_CLUSTER].fill(pair[0].getEnergy(), pair[1].getEnergy());
+                momentumSum2D[ANY_CLUSTER].fill(pair[0].getMomentum().magnitude(), pair[1].getMomentum().magnitude());
+                energyMomentumDiff[ANY_CLUSTER].fill(Math.abs((pair[0].getEnergy() + pair[1].getEnergy()) - pSum.magnitude()));
+            }
+            
+            // Populate the cluster track pair plots.
+            for(ReconstructedParticle[] pair : pairClusterList) {
+                Hep3Vector pSum = new BasicHep3Vector(
+                        pair[0].getMomentum().x() + pair[1].getMomentum().x(),
+                        pair[0].getMomentum().y() + pair[1].getMomentum().y(),
+                        pair[0].getMomentum().z() + pair[1].getMomentum().z());
+                
+                energySum[HAS_CLUSTER].fill(pair[0].getEnergy() + pair[1].getEnergy());
+                momentumSum[HAS_CLUSTER].fill(pSum.magnitude());
+                energySum2D[HAS_CLUSTER].fill(pair[0].getEnergy(), pair[1].getEnergy());
+                momentumSum2D[HAS_CLUSTER].fill(pair[0].getMomentum().magnitude(), pair[1].getMomentum().magnitude());
+                energyMomentumDiff[HAS_CLUSTER].fill(Math.abs((pair[0].getEnergy() + pair[1].getEnergy()) - pSum.magnitude()));
+            }
+        }
+        
+        // Check for V0 candidates.
+        if(event.hasCollection(ReconstructedParticle.class, candidateCollectionName)) {
+            // Get the candidate particles.
+            List<ReconstructedParticle> trackList = event.get(ReconstructedParticle.class, candidateCollectionName);
+            
+            // Increment the counter.
+            tracksCandidate += trackList.size();
+            
+            // Increment the counter for cluster tracks.
+            for(ReconstructedParticle track : trackList) {
+                // Populate the invariant mass plot.
+                invariantMass[ANY_CLUSTER].fill(track.getMass());
+                
+                // Check for a cluster track.
+                if(track.getClusters().size() > 0) {
+                    tracksCandidateCluster++;
+                    invariantMass[HAS_CLUSTER].fill(track.getMass());
+                }
+            }
+        }
+    }
 }

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/TriggerPlotsModule.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/TriggerPlotsModule.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/TriggerPlotsModule.java	Wed Apr 27 11:11:32 2016
@@ -8,8 +8,8 @@
 import org.lcsim.util.aida.AIDA;
 
 public class TriggerPlotsModule {
-	// Define plots.
-	private AIDA aida = AIDA.defaultInstance();
+    // Define plots.
+    private AIDA aida = AIDA.defaultInstance();
     private IHistogram1D singleSeedEnergy;
     private IHistogram1D singleHitCount;
     private IHistogram1D singleTotalEnergy;
@@ -25,43 +25,43 @@
     private IHistogram2D pairDistribution;
     private IHistogram2D pairEnergySum2D;
     
-	public TriggerPlotsModule(String moduleName) {
-		singleSeedEnergy     = aida.histogram1D(moduleName + " Trigger Plots/Singles Plots/Cluster Seed Energy",  176,   0.0,   1.1);
-		singleHitCount       = aida.histogram1D(moduleName + " Trigger Plots/Singles Plots/Cluster Hit Count",      9,   0.5,   9.5);
-		singleTotalEnergy    = aida.histogram1D(moduleName + " Trigger Plots/Singles Plots/Cluster Total Energy", 176,   0.0,   1.1);
-		singleDistribution   = aida.histogram2D(moduleName + " Trigger Plots/Singles Plots/Cluster Seed",          46, -23.0,  23.0,  11, -5.5, 5.5);
-		pairSeedEnergy       = aida.histogram1D(moduleName + " Trigger Plots/Pair Plots/Cluster Seed Energy",     176,   0.0,   1.1);
-		pairHitCount         = aida.histogram1D(moduleName + " Trigger Plots/Pair Plots/Cluster Hit Count",         9,   0.5,   9.5);
-		pairTotalEnergy      = aida.histogram1D(moduleName + " Trigger Plots/Pair Plots/Cluster Total Energy",    176,   0.0,   1.1);
-		pairEnergySum        = aida.histogram1D(moduleName + " Trigger Plots/Pair Plots/Pair Energy Sum",         176,   0.0,   2.2);
-		pairEnergyDifference = aida.histogram1D(moduleName + " Trigger Plots/Pair Plots/Pair Energy Difference",  176,   0.0,   1.1);
-		pairCoplanarity      = aida.histogram1D(moduleName + " Trigger Plots/Pair Plots/Pair Coplanarity",        180,   0.0, 180.0);
-		pairEnergySlope      = aida.histogram1D(moduleName + " Trigger Plots/Pair Plots/Pair Energy Slope",       200,   0.0,   3.0);
-		pairDistribution     = aida.histogram2D(moduleName + " Trigger Plots/Pair Plots/Cluster Seed",             46, -23.0,  23.0,  11, -5.5, 5.5);
-		pairEnergySum2D      = aida.histogram2D(moduleName + " Trigger Plots/Pair Plots/Pair Energy Sum 2D",      110,   0.0,   1.1, 110,  0.0, 1.1);
-	}
-	
-	public void addCluster(Cluster cluster) {
-		singleSeedEnergy.fill(TriggerModule.getValueClusterSeedEnergy(cluster));
-		singleHitCount.fill(TriggerModule.getValueClusterHitCount(cluster));
-		singleTotalEnergy.fill(TriggerModule.getValueClusterTotalEnergy(cluster));
-		singleDistribution.fill(TriggerModule.getClusterXIndex(cluster), TriggerModule.getClusterYIndex(cluster));
-	}
-	
-	public void addClusterPair(Cluster[] pair) {
-		// Populate the singles plots.
-		for(Cluster cluster : pair) {
-			pairSeedEnergy.fill(TriggerModule.getValueClusterSeedEnergy(cluster));
-			pairHitCount.fill(TriggerModule.getValueClusterHitCount(cluster));
-			pairTotalEnergy.fill(TriggerModule.getValueClusterTotalEnergy(cluster));
-			pairDistribution.fill(TriggerModule.getClusterXIndex(cluster), TriggerModule.getClusterYIndex(cluster));
-		}
-		
-		// Populate the pair plots.
-		pairEnergySum.fill(TriggerModule.getValueEnergySum(pair));
-		pairEnergyDifference.fill(TriggerModule.getValueEnergyDifference(pair));
-		pairCoplanarity.fill(TriggerModule.getValueCoplanarity(pair));
-		pairEnergySlope.fill(TriggerModule.getValueEnergySlope(pair, 0.0055));
-		pairEnergySum2D.fill(TriggerModule.getValueClusterTotalEnergy(pair[0]), TriggerModule.getValueClusterTotalEnergy(pair[1]));
-	}
+    public TriggerPlotsModule(String moduleName) {
+        singleSeedEnergy     = aida.histogram1D(moduleName + " Trigger Plots/Singles Plots/Cluster Seed Energy",  176,   0.0,   1.1);
+        singleHitCount       = aida.histogram1D(moduleName + " Trigger Plots/Singles Plots/Cluster Hit Count",      9,   0.5,   9.5);
+        singleTotalEnergy    = aida.histogram1D(moduleName + " Trigger Plots/Singles Plots/Cluster Total Energy", 176,   0.0,   1.1);
+        singleDistribution   = aida.histogram2D(moduleName + " Trigger Plots/Singles Plots/Cluster Seed",          46, -23.0,  23.0,  11, -5.5, 5.5);
+        pairSeedEnergy       = aida.histogram1D(moduleName + " Trigger Plots/Pair Plots/Cluster Seed Energy",     176,   0.0,   1.1);
+        pairHitCount         = aida.histogram1D(moduleName + " Trigger Plots/Pair Plots/Cluster Hit Count",         9,   0.5,   9.5);
+        pairTotalEnergy      = aida.histogram1D(moduleName + " Trigger Plots/Pair Plots/Cluster Total Energy",    176,   0.0,   1.1);
+        pairEnergySum        = aida.histogram1D(moduleName + " Trigger Plots/Pair Plots/Pair Energy Sum",         176,   0.0,   2.2);
+        pairEnergyDifference = aida.histogram1D(moduleName + " Trigger Plots/Pair Plots/Pair Energy Difference",  176,   0.0,   1.1);
+        pairCoplanarity      = aida.histogram1D(moduleName + " Trigger Plots/Pair Plots/Pair Coplanarity",        180,   0.0, 180.0);
+        pairEnergySlope      = aida.histogram1D(moduleName + " Trigger Plots/Pair Plots/Pair Energy Slope",       200,   0.0,   3.0);
+        pairDistribution     = aida.histogram2D(moduleName + " Trigger Plots/Pair Plots/Cluster Seed",             46, -23.0,  23.0,  11, -5.5, 5.5);
+        pairEnergySum2D      = aida.histogram2D(moduleName + " Trigger Plots/Pair Plots/Pair Energy Sum 2D",      110,   0.0,   1.1, 110,  0.0, 1.1);
+    }
+    
+    public void addCluster(Cluster cluster) {
+        singleSeedEnergy.fill(TriggerModule.getValueClusterSeedEnergy(cluster));
+        singleHitCount.fill(TriggerModule.getValueClusterHitCount(cluster));
+        singleTotalEnergy.fill(TriggerModule.getValueClusterTotalEnergy(cluster));
+        singleDistribution.fill(TriggerModule.getClusterXIndex(cluster), TriggerModule.getClusterYIndex(cluster));
+    }
+    
+    public void addClusterPair(Cluster[] pair) {
+        // Populate the singles plots.
+        for(Cluster cluster : pair) {
+            pairSeedEnergy.fill(TriggerModule.getValueClusterSeedEnergy(cluster));
+            pairHitCount.fill(TriggerModule.getValueClusterHitCount(cluster));
+            pairTotalEnergy.fill(TriggerModule.getValueClusterTotalEnergy(cluster));
+            pairDistribution.fill(TriggerModule.getClusterXIndex(cluster), TriggerModule.getClusterYIndex(cluster));
+        }
+        
+        // Populate the pair plots.
+        pairEnergySum.fill(TriggerModule.getValueEnergySum(pair));
+        pairEnergyDifference.fill(TriggerModule.getValueEnergyDifference(pair));
+        pairCoplanarity.fill(TriggerModule.getValueCoplanarity(pair));
+        pairEnergySlope.fill(TriggerModule.getValueEnergySlope(pair, 0.0055));
+        pairEnergySum2D.fill(TriggerModule.getValueClusterTotalEnergy(pair[0]), TriggerModule.getValueClusterTotalEnergy(pair[1]));
+    }
 }

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/TriggerProcessAnalysisDriver.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/TriggerProcessAnalysisDriver.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/TriggerProcessAnalysisDriver.java	Wed Apr 27 11:11:32 2016
@@ -21,768 +21,768 @@
 import org.lcsim.util.aida.AIDA;
 
 public class TriggerProcessAnalysisDriver extends Driver {
-	private int eventsProcessed = 0;
-	private int møllersProcessed = 0;
-	private boolean checkSVT = false;
-	private int tridentsProcessed = 0;
-	private int gblMøllersProcessed = 0;
-	private int gblTridentsProcessed = 0;
-	private double timeCoincidence = 2.5;
-	private double elasticThreshold = 0.800;
-	private double møllerLowerRange = 0.900;
-	private double møllerUpperRange = 1.200;
-	private AIDA aida = AIDA.defaultInstance();
-	private boolean checkTriggerTimeWindow = false;
-	private String clusterCollectionName = "EcalClustersCorr";
-	private String particleCollectionName = "FinalStateParticles";
-	
-	// Define trident cluster-track matched condition plots.
-	private IHistogram1D trctmInvariantMass = aida.histogram1D("Tridents CTMatched/Invariant Mass", 140, 0.0, 0.070);
-	private IHistogram1D trctmInstancesInEvent = aida.histogram1D("Tridents CTMatched/Instances in Event", 9, 0.5, 9.5);
-	private IHistogram1D trctmEnergySum1D = aida.histogram1D("Tridents CTMatched/Cluster Energy Sum", 150, 0.000, 1.500);
-	private IHistogram1D trctmMomentumSum1D = aida.histogram1D("Tridents CTMatched/Track Momentum Sum", 150, 0.000, 1.500);
-	private IHistogram1D trctmElectronEnergy = aida.histogram1D("Tridents CTMatched/Electron Cluster Energy", 150, 0.000, 1.500);
-	private IHistogram1D trctmElectronMomentum = aida.histogram1D("Tridents CTMatched/Electron Track Momentum", 150, 0.000, 1.500);
-	private IHistogram1D trctmPositronEnergy = aida.histogram1D("Tridents CTMatched/Positron Cluster Energy", 150, 0.000, 1.500);
-	private IHistogram1D trctmPositronMomentum = aida.histogram1D("Tridents CTMatched/Positron Track Momentum", 150, 0.000, 1.500);
-	private IHistogram1D trctmTimeCoincidence = aida.histogram1D("Tridents CTMatched/Time Coincidence", 100, -4, 4);
-	private IHistogram2D trctmClusterPosition = aida.histogram2D("Tridents CTMatched/Cluster Seed Position", 46, -23, 23, 11, -5.5, 5.5);
-	private IHistogram2D trctmEnergySum2D = aida.histogram2D("Tridents CTMatched/Cluster Energy Sum 2D", 300, 0.000, 1.500, 300, 0.000, 1.500);
-	private IHistogram2D trctmTrackPosition = aida.histogram2D("Tridents CTMatched/Extrapolated Track Position", 200, -400, 400, 55, -110, 110);
-	private IHistogram2D trctmMomentumSum2D = aida.histogram2D("Tridents CTMatched/Track Momentum Sum 2D", 300, 0.000, 1.500, 300, 0.000, 1.500);
-	private IHistogram2D trctmESumCoplanarity = aida.histogram2D("Tridents CTMatched/Cluster Energy Sum vs. Coplanarity", 300, 0.000, 1.500, 360, 0, 360);
-	private IHistogram2D trctmPSumCoplanarity = aida.histogram2D("Tridents CTMatched/Track Momentum Sum vs. Coplanarity", 300, 0.000, 1.500, 360, 0, 360);
-	
-	// Define the Møller cluster-track matched condition plots.
-	private IHistogram1D møctmInvariantMass = aida.histogram1D("Møller CTMatched/Invariant Mass", 140, 0.0, 0.070);
-	private IHistogram1D møctmInstancesInEvent = aida.histogram1D("Møller CTMatched/Instances in Event", 9, 0.5, 9.5);
-	private IHistogram1D møctmEnergySum1D = aida.histogram1D("Møller CTMatched/Cluster Energy Sum", 150, 0.000, 1.500);
-	private IHistogram1D møctmMomentumSum1D = aida.histogram1D("Møller CTMatched/Track Momentum Sum", 150, 0.000, 1.500);
-	private IHistogram1D møctmElectronEnergy = aida.histogram1D("Møller CTMatched/Electron Cluster Energy", 150, 0.000, 1.500);
-	private IHistogram1D møctmElectronMomentum = aida.histogram1D("Møller CTMatched/Electron Track Momentum", 150, 0.000, 1.500);
-	private IHistogram1D møctmTimeCoincidence = aida.histogram1D("Møller CTMatched/Time Coincidence", 100, -4, 4);
-	private IHistogram2D møctmClusterPosition = aida.histogram2D("Møller CTMatched/Cluster Seed Position", 46, -23, 23, 11, -5.5, 5.5);
-	private IHistogram2D møctmEnergySum2D = aida.histogram2D("Møller CTMatched/Cluster Energy Sum 2D", 300, 0.000, 1.500, 300, 0.000, 1.500);
-	private IHistogram2D møctmTrackPosition = aida.histogram2D("Møller CTMatched/Extrapolated Track Position", 200, -400, 400, 55, -110, 110);
-	private IHistogram2D møctmMomentumSum2D = aida.histogram2D("Møller CTMatched/Track Momentum Sum 2D", 300, 0.000, 1.500, 300, 0.000, 1.500);
-	private IHistogram2D møctmESumCoplanarity = aida.histogram2D("Møller CTMatched/Cluster Energy Sum vs. Coplanarity", 300, 0.000, 1.500, 360, 0, 360);
-	private IHistogram2D møctmPSumCoplanarity = aida.histogram2D("Møller CTMatched/Track Momentum Sum vs. Coplanarity", 300, 0.000, 1.500, 360, 0, 360);
-	
-	// Define the Møller track-only condition plots.
-	private IHistogram1D møgblTimeCoincidence = aida.histogram1D("Møller Track-Only/Time Coincidence", 100, -4, 4);
-	private IHistogram1D møgblInvariantMass = aida.histogram1D("Møller Track-Only/Invariant Mass", 140, 0.0, 0.070);
-	private IHistogram1D møgblInstancesInEvent = aida.histogram1D("Møller Track-Only/Instances in Event", 9, 0.5, 9.5);
-	private IHistogram1D møgblMomentumSum1D = aida.histogram1D("Møller Track-Only/Track Momentum Sum", 150, 0.000, 1.500);
-	private IHistogram1D møgblElectronMomentum = aida.histogram1D("Møller Track-Only/Electron Track Momentum", 150, 0.000, 1.500);
-	private IHistogram2D møgblTrackPosition = aida.histogram2D("Møller Track-Only/Extrapolated Track Position", 200, -400, 400, 55, -110, 110);
-	private IHistogram2D møgblMomentumSum2D = aida.histogram2D("Møller Track-Only/Track Momentum Sum 2D", 300, 0.000, 1.500, 300, 0.000, 1.500);
-	private IHistogram2D møgblPSumCoplanarity = aida.histogram2D("Møller Track-Only/Track Momentum Sum vs. Coplanarity", 300, 0.000, 1.500, 360, 0, 360);
-	
-	// Define the GBL trident condition plots.
-	private IHistogram1D trgblInvariantMass = aida.histogram1D("Tridents Track-Only/Invariant Mass", 140, 0.0, 0.070);
-	private IHistogram1D trgblInstancesInEvent = aida.histogram1D("Tridents Track-Only/Instances in Event", 9, 0.5, 9.5);
-	private IHistogram1D trgblMomentumSum1D = aida.histogram1D("Tridents Track-Only/Track Momentum Sum", 150, 0.000, 1.500);
-	private IHistogram1D trgblElectronMomentum = aida.histogram1D("Tridents Track-Only/Electron Track Momentum", 150, 0.000, 1.500);
-	private IHistogram1D trgblPositronMomentum = aida.histogram1D("Tridents Track-Only/Positron Track Momentum", 150, 0.000, 1.500);
-	private IHistogram1D trgblTimeCoincidence = aida.histogram1D("Tridents Track-Only/Time Coincidence", 100, -4, 4);
-	private IHistogram2D trgblTrackPosition = aida.histogram2D("Tridents Track-Only/Extrapolated Track Position", 200, -400, 400, 55, -110, 110);
-	private IHistogram2D trgblMomentumSum2D = aida.histogram2D("Tridents Track-Only/Track Momentum Sum 2D", 300, 0.000, 1.500, 300, 0.000, 1.500);
-	private IHistogram2D trgblPSumCoplanarity = aida.histogram2D("Tridents Track-Only/Track Momentum Sum vs. Coplanarity", 300, 0.000, 1.500, 360, 0, 360);
-	
-	@Override
-	public void endOfData() {
-		// Calculate the scaling factor for Hertz.
-		double scale = 19000.0 / eventsProcessed;
-		
-		System.out.println("Processed " + eventsProcessed + " events.");
-		System.out.println("Processed " + møllersProcessed + " Møller events");
-		System.out.println("\tAcceptance :: " + (100.0 * møllersProcessed / eventsProcessed) + "%");
-		System.out.println("\tRate       :: " + (møllersProcessed * scale) + " Hz");
-		
-		System.out.println("Processed " + tridentsProcessed + " trident events");
-		System.out.println("\tAcceptance :: " + (100.0 * tridentsProcessed / eventsProcessed) + "%");
-		System.out.println("\tRate       :: " + (tridentsProcessed * scale) + " Hz");
-		
-		System.out.println("Processed " + gblMøllersProcessed + " track-only Møller events");
-		System.out.println("\tAcceptance :: " + (100.0 * gblMøllersProcessed / eventsProcessed) + "%");
-		System.out.println("\tRate       :: " + (gblMøllersProcessed * scale) + " Hz");
-		
-		System.out.println("Processed " + gblTridentsProcessed + " Rafo trident events");
-		System.out.println("\tAcceptance :: " + (100.0 * gblTridentsProcessed / eventsProcessed) + "%");
-		System.out.println("\tRate       :: " + (gblTridentsProcessed * scale) + " Hz");
-	}
-	
-	@Override
-	public void process(EventHeader event) {
-		// Check whether the SVT was active in this event and, if so,
-		// skip it. This can be disabled through the steering file for
-		// Monte Carlo data, where the "SVT" is always active.
-		if(checkSVT) {
-			final String[] flagNames = { "svt_bias_good", "svt_burstmode_noise_good", "svt_position_good" };
-			boolean svtGood = true;
-	        for(int i = 0; i < flagNames.length; i++) {
-	            int[] flag = event.getIntegerParameters().get(flagNames[i]);
-	            if(flag == null || flag[0] == 0) {
-	                svtGood = false;
-	            }
-	        }
-	        if(!svtGood) { return; }
-		}
+    private int eventsProcessed = 0;
+    private int møllersProcessed = 0;
+    private boolean checkSVT = false;
+    private int tridentsProcessed = 0;
+    private int gblMøllersProcessed = 0;
+    private int gblTridentsProcessed = 0;
+    private double timeCoincidence = 2.5;
+    private double elasticThreshold = 0.800;
+    private double møllerLowerRange = 0.900;
+    private double møllerUpperRange = 1.200;
+    private AIDA aida = AIDA.defaultInstance();
+    private boolean checkTriggerTimeWindow = false;
+    private String clusterCollectionName = "EcalClustersCorr";
+    private String particleCollectionName = "FinalStateParticles";
+    
+    // Define trident cluster-track matched condition plots.
+    private IHistogram1D trctmInvariantMass = aida.histogram1D("Tridents CTMatched/Invariant Mass", 140, 0.0, 0.070);
+    private IHistogram1D trctmInstancesInEvent = aida.histogram1D("Tridents CTMatched/Instances in Event", 9, 0.5, 9.5);
+    private IHistogram1D trctmEnergySum1D = aida.histogram1D("Tridents CTMatched/Cluster Energy Sum", 150, 0.000, 1.500);
+    private IHistogram1D trctmMomentumSum1D = aida.histogram1D("Tridents CTMatched/Track Momentum Sum", 150, 0.000, 1.500);
+    private IHistogram1D trctmElectronEnergy = aida.histogram1D("Tridents CTMatched/Electron Cluster Energy", 150, 0.000, 1.500);
+    private IHistogram1D trctmElectronMomentum = aida.histogram1D("Tridents CTMatched/Electron Track Momentum", 150, 0.000, 1.500);
+    private IHistogram1D trctmPositronEnergy = aida.histogram1D("Tridents CTMatched/Positron Cluster Energy", 150, 0.000, 1.500);
+    private IHistogram1D trctmPositronMomentum = aida.histogram1D("Tridents CTMatched/Positron Track Momentum", 150, 0.000, 1.500);
+    private IHistogram1D trctmTimeCoincidence = aida.histogram1D("Tridents CTMatched/Time Coincidence", 100, -4, 4);
+    private IHistogram2D trctmClusterPosition = aida.histogram2D("Tridents CTMatched/Cluster Seed Position", 46, -23, 23, 11, -5.5, 5.5);
+    private IHistogram2D trctmEnergySum2D = aida.histogram2D("Tridents CTMatched/Cluster Energy Sum 2D", 300, 0.000, 1.500, 300, 0.000, 1.500);
+    private IHistogram2D trctmTrackPosition = aida.histogram2D("Tridents CTMatched/Extrapolated Track Position", 200, -400, 400, 55, -110, 110);
+    private IHistogram2D trctmMomentumSum2D = aida.histogram2D("Tridents CTMatched/Track Momentum Sum 2D", 300, 0.000, 1.500, 300, 0.000, 1.500);
+    private IHistogram2D trctmESumCoplanarity = aida.histogram2D("Tridents CTMatched/Cluster Energy Sum vs. Coplanarity", 300, 0.000, 1.500, 360, 0, 360);
+    private IHistogram2D trctmPSumCoplanarity = aida.histogram2D("Tridents CTMatched/Track Momentum Sum vs. Coplanarity", 300, 0.000, 1.500, 360, 0, 360);
+    
+    // Define the Møller cluster-track matched condition plots.
+    private IHistogram1D møctmInvariantMass = aida.histogram1D("Møller CTMatched/Invariant Mass", 140, 0.0, 0.070);
+    private IHistogram1D møctmInstancesInEvent = aida.histogram1D("Møller CTMatched/Instances in Event", 9, 0.5, 9.5);
+    private IHistogram1D møctmEnergySum1D = aida.histogram1D("Møller CTMatched/Cluster Energy Sum", 150, 0.000, 1.500);
+    private IHistogram1D møctmMomentumSum1D = aida.histogram1D("Møller CTMatched/Track Momentum Sum", 150, 0.000, 1.500);
+    private IHistogram1D møctmElectronEnergy = aida.histogram1D("Møller CTMatched/Electron Cluster Energy", 150, 0.000, 1.500);
+    private IHistogram1D møctmElectronMomentum = aida.histogram1D("Møller CTMatched/Electron Track Momentum", 150, 0.000, 1.500);
+    private IHistogram1D møctmTimeCoincidence = aida.histogram1D("Møller CTMatched/Time Coincidence", 100, -4, 4);
+    private IHistogram2D møctmClusterPosition = aida.histogram2D("Møller CTMatched/Cluster Seed Position", 46, -23, 23, 11, -5.5, 5.5);
+    private IHistogram2D møctmEnergySum2D = aida.histogram2D("Møller CTMatched/Cluster Energy Sum 2D", 300, 0.000, 1.500, 300, 0.000, 1.500);
+    private IHistogram2D møctmTrackPosition = aida.histogram2D("Møller CTMatched/Extrapolated Track Position", 200, -400, 400, 55, -110, 110);
+    private IHistogram2D møctmMomentumSum2D = aida.histogram2D("Møller CTMatched/Track Momentum Sum 2D", 300, 0.000, 1.500, 300, 0.000, 1.500);
+    private IHistogram2D møctmESumCoplanarity = aida.histogram2D("Møller CTMatched/Cluster Energy Sum vs. Coplanarity", 300, 0.000, 1.500, 360, 0, 360);
+    private IHistogram2D møctmPSumCoplanarity = aida.histogram2D("Møller CTMatched/Track Momentum Sum vs. Coplanarity", 300, 0.000, 1.500, 360, 0, 360);
+    
+    // Define the Møller track-only condition plots.
+    private IHistogram1D møgblTimeCoincidence = aida.histogram1D("Møller Track-Only/Time Coincidence", 100, -4, 4);
+    private IHistogram1D møgblInvariantMass = aida.histogram1D("Møller Track-Only/Invariant Mass", 140, 0.0, 0.070);
+    private IHistogram1D møgblInstancesInEvent = aida.histogram1D("Møller Track-Only/Instances in Event", 9, 0.5, 9.5);
+    private IHistogram1D møgblMomentumSum1D = aida.histogram1D("Møller Track-Only/Track Momentum Sum", 150, 0.000, 1.500);
+    private IHistogram1D møgblElectronMomentum = aida.histogram1D("Møller Track-Only/Electron Track Momentum", 150, 0.000, 1.500);
+    private IHistogram2D møgblTrackPosition = aida.histogram2D("Møller Track-Only/Extrapolated Track Position", 200, -400, 400, 55, -110, 110);
+    private IHistogram2D møgblMomentumSum2D = aida.histogram2D("Møller Track-Only/Track Momentum Sum 2D", 300, 0.000, 1.500, 300, 0.000, 1.500);
+    private IHistogram2D møgblPSumCoplanarity = aida.histogram2D("Møller Track-Only/Track Momentum Sum vs. Coplanarity", 300, 0.000, 1.500, 360, 0, 360);
+    
+    // Define the GBL trident condition plots.
+    private IHistogram1D trgblInvariantMass = aida.histogram1D("Tridents Track-Only/Invariant Mass", 140, 0.0, 0.070);
+    private IHistogram1D trgblInstancesInEvent = aida.histogram1D("Tridents Track-Only/Instances in Event", 9, 0.5, 9.5);
+    private IHistogram1D trgblMomentumSum1D = aida.histogram1D("Tridents Track-Only/Track Momentum Sum", 150, 0.000, 1.500);
+    private IHistogram1D trgblElectronMomentum = aida.histogram1D("Tridents Track-Only/Electron Track Momentum", 150, 0.000, 1.500);
+    private IHistogram1D trgblPositronMomentum = aida.histogram1D("Tridents Track-Only/Positron Track Momentum", 150, 0.000, 1.500);
+    private IHistogram1D trgblTimeCoincidence = aida.histogram1D("Tridents Track-Only/Time Coincidence", 100, -4, 4);
+    private IHistogram2D trgblTrackPosition = aida.histogram2D("Tridents Track-Only/Extrapolated Track Position", 200, -400, 400, 55, -110, 110);
+    private IHistogram2D trgblMomentumSum2D = aida.histogram2D("Tridents Track-Only/Track Momentum Sum 2D", 300, 0.000, 1.500, 300, 0.000, 1.500);
+    private IHistogram2D trgblPSumCoplanarity = aida.histogram2D("Tridents Track-Only/Track Momentum Sum vs. Coplanarity", 300, 0.000, 1.500, 360, 0, 360);
+    
+    @Override
+    public void endOfData() {
+        // Calculate the scaling factor for Hertz.
+        double scale = 19000.0 / eventsProcessed;
+        
+        System.out.println("Processed " + eventsProcessed + " events.");
+        System.out.println("Processed " + møllersProcessed + " Møller events");
+        System.out.println("\tAcceptance :: " + (100.0 * møllersProcessed / eventsProcessed) + "%");
+        System.out.println("\tRate       :: " + (møllersProcessed * scale) + " Hz");
+        
+        System.out.println("Processed " + tridentsProcessed + " trident events");
+        System.out.println("\tAcceptance :: " + (100.0 * tridentsProcessed / eventsProcessed) + "%");
+        System.out.println("\tRate       :: " + (tridentsProcessed * scale) + " Hz");
+        
+        System.out.println("Processed " + gblMøllersProcessed + " track-only Møller events");
+        System.out.println("\tAcceptance :: " + (100.0 * gblMøllersProcessed / eventsProcessed) + "%");
+        System.out.println("\tRate       :: " + (gblMøllersProcessed * scale) + " Hz");
+        
+        System.out.println("Processed " + gblTridentsProcessed + " Rafo trident events");
+        System.out.println("\tAcceptance :: " + (100.0 * gblTridentsProcessed / eventsProcessed) + "%");
+        System.out.println("\tRate       :: " + (gblTridentsProcessed * scale) + " Hz");
+    }
+    
+    @Override
+    public void process(EventHeader event) {
+        // Check whether the SVT was active in this event and, if so,
+        // skip it. This can be disabled through the steering file for
+        // Monte Carlo data, where the "SVT" is always active.
+        if(checkSVT) {
+            final String[] flagNames = { "svt_bias_good", "svt_burstmode_noise_good", "svt_position_good" };
+            boolean svtGood = true;
+            for(int i = 0; i < flagNames.length; i++) {
+                int[] flag = event.getIntegerParameters().get(flagNames[i]);
+                if(flag == null || flag[0] == 0) {
+                    svtGood = false;
+                }
+            }
+            if(!svtGood) { return; }
+        }
         
         // Track the number of events with good SVT.
         eventsProcessed++;
         
-		// Check if the event has a collection of tracks. If it exists,
+        // Check if the event has a collection of tracks. If it exists,
         // extract it. Otherwise, skip the event.
-		if(!event.hasCollection(ReconstructedParticle.class, particleCollectionName)) {
-			return;
-		}
-		List<ReconstructedParticle> trackList = event.get(ReconstructedParticle.class, particleCollectionName);
-		
-		// Check if the event has a collection of clusters. If it
-		// exists, extract it. Otherwise, skip the event.
-		if(!event.hasCollection(Cluster.class, clusterCollectionName)) {
-			return;
-		}
-		List<Cluster> clusterList = event.get(Cluster.class, clusterCollectionName);
-		
-		// Get cluster-track matched top/bottom pairs.
-		List<ReconstructedParticle[]> gblMatchedPairs = getTopBottomTracksGBL(trackList);
-		List<ReconstructedParticle[]> ctMatchedPairs  = getTopBottomTracksCTMatched(trackList);
-		
-		System.out.println("CTM Pairs :: " + ctMatchedPairs.size());
-		System.out.println("GBL Pairs :: " + gblMatchedPairs.size());
-		
-		// Get the trident and Møller tracks for the matched track
-		// and cluster pair condition sets.
-		List<ReconstructedParticle[]> møllers     = getMøllerTracksCTMatched(ctMatchedPairs);
-		List<ReconstructedParticle[]> møllersGBL  = getMøllerTracksGBL(gblMatchedPairs, event);
-		List<ReconstructedParticle[]> tridents    = getTridentTracksCTMatched(ctMatchedPairs);
-		List<ReconstructedParticle[]> tridentsGBL = getTridentClustersGBL(gblMatchedPairs, TriggerModule.getTopBottomPairs(clusterList, Cluster.class), event);
-		
-		// Track how many events had tridents and Møllers.
-		if(!møllers.isEmpty()) { møllersProcessed++; }
-		if(!tridents.isEmpty()) { tridentsProcessed++; }
-		if(!møllersGBL.isEmpty()) { gblMøllersProcessed++; }
-		if(!tridentsGBL.isEmpty()) { gblTridentsProcessed++; }
-		
-		// Produce Møller cluster-track matched plots.
-		møctmInstancesInEvent.fill(møllers.size());
-		for(ReconstructedParticle[] pair : møllers) {
-			// Get the track clusters.
-			Track[] tracks = { pair[0].getTracks().get(0), pair[1].getTracks().get(0) };
-			Cluster[] trackClusters = { pair[0].getClusters().get(0), pair[1].getClusters().get(0) };
-			
-			// Populate the cluster plots.
-			møctmElectronEnergy.fill(trackClusters[0].getEnergy());
-			møctmElectronEnergy.fill(trackClusters[1].getEnergy());
-			møctmEnergySum1D.fill(TriggerModule.getValueEnergySum(trackClusters));
-			møctmEnergySum2D.fill(trackClusters[0].getEnergy(), trackClusters[1].getEnergy());
-			møctmESumCoplanarity.fill(TriggerModule.getValueEnergySum(trackClusters), getCalculatedCoplanarity(trackClusters));
-			møctmTimeCoincidence.fill(TriggerModule.getClusterTime(trackClusters[0]) - TriggerModule.getClusterTime(trackClusters[1]));
-			møctmClusterPosition.fill(TriggerModule.getClusterXIndex(trackClusters[0]), TriggerModule.getClusterYIndex(trackClusters[0]));
-			møctmClusterPosition.fill(TriggerModule.getClusterXIndex(trackClusters[1]), TriggerModule.getClusterYIndex(trackClusters[1]));
-			
-			// Populate the momentum plots.
-			møctmInvariantMass.fill(getInvariantMass(pair));
-			møctmElectronMomentum.fill(pair[0].getMomentum().magnitude());
-			møctmElectronMomentum.fill(pair[1].getMomentum().magnitude());
-			møctmMomentumSum1D.fill(VecOp.add(pair[0].getMomentum(), pair[1].getMomentum()).magnitude());
-			møctmMomentumSum2D.fill(pair[0].getMomentum().magnitude(), pair[1].getMomentum().magnitude());
-			møctmTrackPosition.fill(TrackUtils.getTrackPositionAtEcal(tracks[0]).x(), TrackUtils.getTrackPositionAtEcal(tracks[0]).y());
-			møctmTrackPosition.fill(TrackUtils.getTrackPositionAtEcal(tracks[1]).x(), TrackUtils.getTrackPositionAtEcal(tracks[1]).y());
-			møctmPSumCoplanarity.fill(VecOp.add(pair[0].getMomentum(), pair[1].getMomentum()).magnitude(),
-					getCalculatedCoplanarity(new Track[] { pair[0].getTracks().get(0), pair[1].getTracks().get(0) }));
-		}
-		
-		// Produce trident cluster-track matched plots.
-		trctmInstancesInEvent.fill(tridents.size());
-		for(ReconstructedParticle[] pair : tridents) {
-			// Get the electron and positron tracks.
-			ReconstructedParticle electronTrack = pair[pair[0].getCharge() < 0 ? 0 : 1];
-			ReconstructedParticle positronTrack = pair[pair[0].getCharge() > 0 ? 0 : 1];
-			
-			// Get the track clusters.
-			Cluster electronCluster = electronTrack.getClusters().get(0);
-			Cluster positronCluster = positronTrack.getClusters().get(0);
-			Track[] tracks = { pair[0].getTracks().get(0), pair[1].getTracks().get(0) };
-			Cluster[] trackClusters = { pair[0].getClusters().get(0), pair[1].getClusters().get(0) };
-			
-			// Populate the cluster plots.
-			trctmElectronEnergy.fill(electronCluster.getEnergy());
-			trctmPositronEnergy.fill(positronCluster.getEnergy());
-			trctmEnergySum2D.fill(pair[0].getEnergy(), pair[1].getEnergy());
-			trctmEnergySum1D.fill(TriggerModule.getValueEnergySum(trackClusters));
-			trctmESumCoplanarity.fill(TriggerModule.getValueEnergySum(trackClusters), getCalculatedCoplanarity(trackClusters));
-			trctmTimeCoincidence.fill(TriggerModule.getClusterTime(trackClusters[0]) - TriggerModule.getClusterTime(trackClusters[1]));
-			trctmClusterPosition.fill(TriggerModule.getClusterXIndex(trackClusters[0]), TriggerModule.getClusterYIndex(trackClusters[0]));
-			trctmClusterPosition.fill(TriggerModule.getClusterXIndex(trackClusters[1]), TriggerModule.getClusterYIndex(trackClusters[1]));
-			
-			// Populate the momentum plots.
-			trctmInvariantMass.fill(getInvariantMass(pair));
-			trctmElectronMomentum.fill(electronTrack.getMomentum().magnitude());
-			trctmPositronMomentum.fill(positronTrack.getMomentum().magnitude());
-			trctmMomentumSum1D.fill(VecOp.add(pair[0].getMomentum(), pair[1].getMomentum()).magnitude());
-			trctmMomentumSum2D.fill(pair[0].getMomentum().magnitude(), pair[1].getMomentum().magnitude());
-			trctmTrackPosition.fill(TrackUtils.getTrackPositionAtEcal(tracks[0]).x(), TrackUtils.getTrackPositionAtEcal(tracks[0]).y());
-			trctmTrackPosition.fill(TrackUtils.getTrackPositionAtEcal(tracks[1]).x(), TrackUtils.getTrackPositionAtEcal(tracks[1]).y());
-			trctmPSumCoplanarity.fill(VecOp.add(pair[0].getMomentum(), pair[1].getMomentum()).magnitude(),
-					getCalculatedCoplanarity(new Track[] { pair[0].getTracks().get(0), pair[1].getTracks().get(0) }));
-		}
-		
-		// Produce the Møller track-only plots.
-		møgblInstancesInEvent.fill(møllersGBL.size());
-		RelationalTable<?, ?> hitToStrips = TrackUtils.getHitToStripsTable(event);
-		RelationalTable<?, ?> hitToRotated = TrackUtils.getHitToRotatedTable(event);
-		for(ReconstructedParticle pair[] : møllersGBL) {
-			// Get the tracks and track times.
-			Track[] tracks = { pair[0].getTracks().get(0), pair[1].getTracks().get(0) };
-			double times[] = {
-					TrackUtils.getTrackTime(tracks[0], hitToStrips, hitToRotated),
-					TrackUtils.getTrackTime(tracks[1], hitToStrips, hitToRotated)	
-			};
-			
-			// Fill the plots.
-			møgblTimeCoincidence.fill(times[0] - times[1]);
-			møgblInvariantMass.fill(getInvariantMass(pair));
-			møgblElectronMomentum.fill(pair[0].getMomentum().magnitude());
-			møgblElectronMomentum.fill(pair[1].getMomentum().magnitude());
-			møgblMomentumSum1D.fill(VecOp.add(pair[0].getMomentum(), pair[1].getMomentum()).magnitude());
-			møgblMomentumSum2D.fill(pair[0].getMomentum().magnitude(), pair[1].getMomentum().magnitude());
-			møgblTrackPosition.fill(TrackUtils.getTrackPositionAtEcal(tracks[0]).x(), TrackUtils.getTrackPositionAtEcal(tracks[0]).y());
-			møgblTrackPosition.fill(TrackUtils.getTrackPositionAtEcal(tracks[1]).x(), TrackUtils.getTrackPositionAtEcal(tracks[1]).y());
-			møgblPSumCoplanarity.fill(VecOp.add(pair[0].getMomentum(), pair[1].getMomentum()).magnitude(),
-					getCalculatedCoplanarity(new Track[] { pair[0].getTracks().get(0), pair[1].getTracks().get(0) }));
-		}
-		
-		// Produce track-only trident plots.
-		trgblInstancesInEvent.fill(tridentsGBL.size());
-		for(ReconstructedParticle[] pair : tridentsGBL) {
-			// Get the tracks and track times.
-			Track[] tracks = { pair[0].getTracks().get(0), pair[1].getTracks().get(0) };
-			double times[] = {
-					TrackUtils.getTrackTime(tracks[0], hitToStrips, hitToRotated),
-					TrackUtils.getTrackTime(tracks[1], hitToStrips, hitToRotated)	
-			};
-			
-			// Get the positron and the electron.
-			ReconstructedParticle positron = pair[0].getCharge() > 0 ? pair[0] : pair[1];
-			ReconstructedParticle electron = pair[0].getCharge() < 0 ? pair[0] : pair[1];
-			
-			// Fill the plots.
-			trgblTimeCoincidence.fill(times[0] - times[1]);
-			trgblInvariantMass.fill(getInvariantMass(pair));
-			trgblElectronMomentum.fill(electron.getMomentum().magnitude());
-			trgblPositronMomentum.fill(positron.getMomentum().magnitude());
-			trgblMomentumSum1D.fill(VecOp.add(pair[0].getMomentum(), pair[1].getMomentum()).magnitude());
-			trgblMomentumSum2D.fill(pair[0].getMomentum().magnitude(), pair[1].getMomentum().magnitude());
-			trgblTrackPosition.fill(TrackUtils.getTrackPositionAtEcal(tracks[0]).x(), TrackUtils.getTrackPositionAtEcal(tracks[0]).y());
-			trgblTrackPosition.fill(TrackUtils.getTrackPositionAtEcal(tracks[1]).x(), TrackUtils.getTrackPositionAtEcal(tracks[1]).y());
-			trgblPSumCoplanarity.fill(VecOp.add(pair[0].getMomentum(), pair[1].getMomentum()).magnitude(),
-					getCalculatedCoplanarity(new Track[] { pair[0].getTracks().get(0), pair[1].getTracks().get(0) }));
-		}
-	}
-	
-	public void setCheckSVT(boolean state) {
-		checkSVT = state;
-	}
-	
-	public void setCheckTriggerTimeWindow(boolean state) {
-		checkTriggerTimeWindow = state;
-	}
-	
-	/**
-	 * Gets a list of all possible GBL top/bottom track pairs. These
-	 * tracks are not guaranteed to have a matched cluster.
-	 * @param trackList - A list of all possible tracks.
-	 * @return Returns a list of track pairs.
-	 */
-	private static final List<ReconstructedParticle[]> getTopBottomTracksGBL(List<ReconstructedParticle> trackList) {
-		// Separate the tracks into top and bottom tracks based on
-		// the value of tan(Λ). Use only GBL tracks to avoid track
-		// duplication.
-		List<ReconstructedParticle> topTracks = new ArrayList<ReconstructedParticle>();
-		List<ReconstructedParticle> botTracks = new ArrayList<ReconstructedParticle>();
-		trackLoop:
-		for(ReconstructedParticle track : trackList) {
-			// Require that the ReconstructedParticle contain an actual
-			// Track object.
-			if(track.getTracks().isEmpty()) {
-				continue trackLoop;
-			}
-			
-			// Ignore tracks that are not GBL tracks.
-			if(!TrackType.isGBL(track.getType())) {
-				continue trackLoop;
-			}
-			
-			// If the above tests pass, the ReconstructedParticle has
-			// a track and is also a GBL track. Separate it into either
-			// a top or a bottom track based on its tan(Λ) value.
-			if(track.getTracks().get(0).getTrackStates().get(0).getTanLambda() > 0) {
-				topTracks.add(track);
-			} else {
-				botTracks.add(track);
-			}
-		}
-		
-		// Form all top/bottom pairs with the unique tracks.
-		List<ReconstructedParticle[]> pairList = new ArrayList<ReconstructedParticle[]>();
-		for(ReconstructedParticle topTrack : topTracks) {
-			for(ReconstructedParticle botTrack : botTracks) {
-				pairList.add(new ReconstructedParticle[] { topTrack, botTrack });
-			}
-		}
-		
-		// Return the result.
-		return pairList;
-	}
-	
-	/**
-	 * Produces pairs of tracks. The track pairs are required to be
-	 * matched to a cluster and the associated clusters must form a
-	 * top/bottom pair. If more than one track points to the same
-	 * cluster, only the first track is retained.
-	 * @param trackList - A list of all tracks.
-	 * @return Returns a list of track pairs meeting the aforementioned
-	 * conditions.
-	 */
-	private static final List<ReconstructedParticle[]> getTopBottomTracksCTMatched(List<ReconstructedParticle> trackList) {
-		// Track clusters that have already been seen to prevent clusters
-		// that have duplicate tracks from reappearing.
-		Set<Cluster> clusterSet = new HashSet<Cluster>();
-		
-		// Separate the tracks into top and bottom tracks based on
-		// the track cluster. Filter out tracks with no clusters.
-		List<ReconstructedParticle> topTracks = new ArrayList<ReconstructedParticle>();
-		List<ReconstructedParticle> botTracks = new ArrayList<ReconstructedParticle>();
-		trackLoop:
-		for(ReconstructedParticle track : trackList) {
-			// Check if the track has a cluster. If not, skip it.
-			if(track.getClusters().isEmpty()) {
-				continue trackLoop;
-			}
-			
-			// If the track doesn't have actual tracks, skip it.
-			if(track.getTracks().isEmpty()) {
-				continue trackLoop;
-			}
-			
-			// Check if the track cluster has already seen.
-			Cluster trackCluster = track.getClusters().get(0);
-			if(clusterSet.contains(trackCluster)) {
-				continue trackLoop;
-			}
-			
-			// If the track has a unique cluster, add it to the proper
-			// list based on the cluster y-index.
-			clusterSet.add(trackCluster);
-			if(TriggerModule.getClusterYIndex(trackCluster) > 0) {
-				topTracks.add(track);
-			} else {
-				botTracks.add(track);
-			}
-		}
-		
-		// Form all top/bottom pairs with the unique tracks.
-		List<ReconstructedParticle[]> pairList = new ArrayList<ReconstructedParticle[]>();
-		for(ReconstructedParticle topTrack : topTracks) {
-			for(ReconstructedParticle botTrack : botTracks) {
-				pairList.add(new ReconstructedParticle[] { topTrack, botTrack });
-			}
-		}
-		
-		// Return the result.
-		return pairList;
-	}
-	
-	private final List<ReconstructedParticle[]> getTridentClustersGBL(List<ReconstructedParticle[]> pairList, List<Cluster[]> clusterList, EventHeader event) {
-		// Store the set of track pairs that meet the trident condition.
-		List<ReconstructedParticle[]> tridentTracks = new ArrayList<ReconstructedParticle[]>();
-		
-		// Extract track relational tables from the event object.
-		RelationalTable<?, ?> hitToStrips = TrackUtils.getHitToStripsTable(event);
-		RelationalTable<?, ?> hitToRotated = TrackUtils.getHitToRotatedTable(event);
-		
-		// Tracks will not be considered for trident analysis unless there
-		// is at least one top/bottom cluster pair within the time window.
-		boolean passesClusterCondition = false;
-		tridentClusterLoop:
-		for(Cluster[] pair : clusterList) {
-			// Ignore clusters that are too far apart temporally.
-			if(TriggerModule.getValueTimeCoincidence(pair) > timeCoincidence) {
-				continue tridentClusterLoop;
-			}
-			
-			// Require that the cluster pair be top/bottom.
-			boolean hasTop = TriggerModule.getClusterYIndex(pair[0]) > 0 || TriggerModule.getClusterYIndex(pair[1]) > 0;
-			boolean hasBot = TriggerModule.getClusterYIndex(pair[0]) < 0 || TriggerModule.getClusterYIndex(pair[1]) < 0;
-			if(!hasTop || !hasBot) {
-				continue tridentClusterLoop;
-			}
-			
-			// If the cluster passes, mark that it has done so and skip
-			// the rest. Only one pair need pass.
-			passesClusterCondition = true;
-			break tridentClusterLoop;
-		}
-		
-		// If no cluster pair passed the cluster condition, no tracks
-		// are allowed to pass either.
-		if(!passesClusterCondition) {
-			return tridentTracks;
-		}
-		
-		// Next, check the track pair list. A track pair must have a
-		// positive and a negative track and must also be within the
-		// time coincidence window.
-		tridentTrackLoop:
-		for(ReconstructedParticle[] pair : pairList) {
-			// Check that there is at least one positive and one negative
-			// track in the pair.
-			boolean hasPositive = pair[0].getCharge() > 0 || pair[1].getCharge() > 0;
-			boolean hasNegative = pair[0].getCharge() < 0 || pair[1].getCharge() < 0;
-			if(!hasPositive || !hasNegative) {
-				break tridentTrackLoop;
-			}
-			
-			// Check that the track pair passes the time cut.
-			double times[] = {
-				TrackUtils.getTrackTime(pair[0].getTracks().get(0), hitToStrips, hitToRotated),
-				TrackUtils.getTrackTime(pair[1].getTracks().get(0), hitToStrips, hitToRotated)	
-			};
-			
-			if(Math.abs(times[0] - times[1]) > timeCoincidence) {
-				continue tridentTrackLoop;
-			}
-			
-			// Require that the negative track have less than the
-			// elastic threshold momentum to exclude elastic electrons.
-			if(pair[0].getCharge() < 0 && pair[0].getMomentum().magnitude() > elasticThreshold
-					|| pair[1].getCharge() < 0 && pair[1].getMomentum().magnitude() > elasticThreshold) {
-				continue tridentTrackLoop;
-			}
-			
-			// If the track passes both, it is considered a trident pair.
-			tridentTracks.add(pair);
-		}
-		
-		// Return the resultant pairs.
-		return tridentTracks;
-	}
-	
-	/**
-	 * Gets a list track pairs that meet the trident condition defined
-	 * using tracks with matched calorimeter clusters. A pair meets the
-	 * cluster/track matched trident condition is it meets the following:
-	 * <ul><li>Both tracks have matched clusters.</li>
-	 * <li>Has one positive track.</li>
-	 * <li>Has one negative track.</li>
-	 * <li>Clusters have a time coincidence of 2.5 ns or less.</li>
-	 * <li>The electron momentum is below 900 MeV.</li></ul>
-	 * @param pairList - A <code>List</code> collection of parameterized
-	 * type <code>ReconstructedParticle[]</code> containing all valid
-	 * top/bottom pairs of tracks with matched clusters. These will be
-	 * tested to see if they meet the process criteria.
-	 * @return Returns a list containing pairs of tracks that meet the
-	 * trident condition.
-	 */
-	private final List<ReconstructedParticle[]> getTridentTracksCTMatched(List<ReconstructedParticle[]> pairList) {
-		// Store the set of track pairs that meet the trident condition.
-		List<ReconstructedParticle[]> tridentTracks = new ArrayList<ReconstructedParticle[]>();
-		
-		// Loop over the filtered pair list and apply the trident
-		// condition test.
-		tridentLoop:
-		for(ReconstructedParticle[] pair : pairList) {
-			// There must be one positive and one negative track.
-			ReconstructedParticle electron = null;
-			ReconstructedParticle positron = null;
-			if(pair[0].getCharge() > 0) { positron = pair[0]; }
-			else if(pair[1].getCharge() > 0) { positron = pair[1]; }
-			if(pair[0].getCharge() < 0) { electron = pair[0]; }
-			else if(pair[1].getCharge() < 0) { electron = pair[1]; }
-			if(electron == null || positron == null) {
-				continue tridentLoop;
-			}
-			
-			// Make sure that the clusters are not the same. This should
-			// not actually ever be possible...
-			if(pair[0].getClusters().get(0) == pair[1].getClusters().get(0)) {
-				continue tridentLoop;
-			}
-			
-			// The clusters must within a limited time window.
-			/*
-			Cluster[] trackClusters = { pair[0].getClusters().get(0), pair[1].getClusters().get(0) };
-			if(TriggerModule.getValueTimeCoincidence(trackClusters) > timeCoincidence) {
-				continue tridentLoop;
-			}
-			*/
-			
-			// The clusters must be coincidental within an energy
-			// dependent coincidence window.
-			Cluster[] trackClusters = { pair[0].getClusters().get(0), pair[1].getClusters().get(0) };
-			if(!isCoincidental(trackClusters)) {
-				continue tridentLoop;
-			}
-			
-			// Require that the electron in the pair have an energy
-			// below the elastic threshold to exclude elastic electrons.
-			if(electron.getMomentum().magnitude() >= elasticThreshold) {
-				continue tridentLoop;
-			}
-			
-			// Require that all clusters occur within the trigger time
-			// window to exclude accidentals.
-			if(checkTriggerTimeWindow) {
-				if(!inTriggerWindow(trackClusters[0]) || !inTriggerWindow(trackClusters[1])) {
-					continue tridentLoop;
-				}
-			}
-			
-			// If all the above conditions are met, the pair is to be
-			// considered a trident pair. Add it to the list.
-			tridentTracks.add(pair);
-		}
-		
-		// Return the list of pairs that passed the condition.
-		return tridentTracks;
-	}
-	
-	private final List<ReconstructedParticle[]> getMøllerTracksGBL(List<ReconstructedParticle[]> pairList, EventHeader event) {
-		// Store the set of track pairs that meet the Møller condition.
-		List<ReconstructedParticle[]> møllerTracks = new ArrayList<ReconstructedParticle[]>();
-		
-		// Extract track relational tables from the event object.
-		RelationalTable<?, ?> hitToStrips = TrackUtils.getHitToStripsTable(event);
-		RelationalTable<?, ?> hitToRotated = TrackUtils.getHitToRotatedTable(event);
-		
-		// Loop over the filtered pair list and apply the Møller
-		// condition test.
-		møllerLoop:
-		for(ReconstructedParticle[] pair : pairList) {
-			// Both tracks must be negatively charged.
-			if(pair[0].getCharge() > 0 || pair[1].getCharge() > 0) {
-				continue møllerLoop;
-			}
-			
-			// The clusters must within a limited time window.
-			double times[] = {
-				TrackUtils.getTrackTime(pair[0].getTracks().get(0), hitToStrips, hitToRotated),
-				TrackUtils.getTrackTime(pair[1].getTracks().get(0), hitToStrips, hitToRotated)	
-			};
-			
-			if(Math.abs(times[0] - times[1]) > timeCoincidence) {
-				continue møllerLoop;
-			}
-			
-			// Require that the electrons in the pair have energies
-			// below the elastic threshold to exclude said electrons.
-			if(pair[0].getMomentum().magnitude() > elasticThreshold || pair[1].getMomentum().magnitude() > elasticThreshold) {
-				continue møllerLoop;
-			}
-			
-			// Require that the energy of the pair be within a range
-			// that is sufficiently "Møller-like."
-			double momentumSum = VecOp.add(pair[0].getMomentum(), pair[1].getMomentum()).magnitude();
-			if(momentumSum < møllerLowerRange || momentumSum > møllerUpperRange) {
-				continue møllerLoop;
-			}
-			
-			// If all the above conditions are met, the pair is to be
-			// considered a trident pair. Add it to the list.
-			møllerTracks.add(pair);
-		}
-		
-		// Return the list of pairs that passed the condition.
-		return møllerTracks;
-	}
-	
-	/**
-	 * Gets a list track pairs that meet the Møller condition defined
-	 * using tracks with matched calorimeter clusters. A pair meets the
-	 * cluster/track matched Møller condition is it meets the following:
-	 * <ul><li>Both tracks have matched clusters.</li>
-	 * <li>Both tracks are negative.</li>
-	 * <li>Clusters have a time coincidence of 2.5 ns or less.</li>
-	 * <li>The electron momenta are below 900 MeV.</li>
-	 * <li>The momentum sum of the tracks is in the range <code>800 MeV
-	 * ≤ p1 + p2 ≤ 1500 MeV</li></ul>
-	 * @param pairList - A <code>List</code> collection of parameterized
-	 * type <code>ReconstructedParticle[]</code> containing all valid
-	 * top/bottom pairs of tracks with matched clusters. These will be
-	 * tested to see if they meet the process criteria.
-	 * @return Returns a list containing pairs of tracks that meet the
-	 * Møller condition.
-	 */
-	private final List<ReconstructedParticle[]> getMøllerTracksCTMatched(List<ReconstructedParticle[]> pairList) {
-		// Store the set of track pairs that meet the Møller condition.
-		List<ReconstructedParticle[]> møllerTracks = new ArrayList<ReconstructedParticle[]>();
-		
-		// Loop over the filtered pair list and apply the Møller
-		// condition test.
-		møllerLoop:
-		for(ReconstructedParticle[] pair : pairList) {
-			// Both tracks must be negatively charged.
-			if(pair[0].getCharge() > 0 || pair[1].getCharge() > 0) {
-				continue møllerLoop;
-			}
-			
-			// The clusters must within a limited time window.
-			/*
-			Cluster[] trackClusters = { pair[0].getClusters().get(0), pair[1].getClusters().get(0) };
-			if(TriggerModule.getValueTimeCoincidence(trackClusters) > timeCoincidence) {
-				continue møllerLoop;
-			}
-			*/
-			
-			// The clusters must be coincidental within an energy
-			// dependent coincidence window.
-			Cluster[] trackClusters = { pair[0].getClusters().get(0), pair[1].getClusters().get(0) };
-			if(!isCoincidental(trackClusters)) {
-				continue møllerLoop;
-			}
-			
-			// Require that the electrons in the pair have energies
-			// below the elastic threshold to exclude said electrons.
-			if(pair[0].getMomentum().magnitude() > elasticThreshold || pair[1].getMomentum().magnitude() > elasticThreshold) {
-				continue møllerLoop;
-			}
-			
-			// Require that the energy of the pair be within a range
-			// that is sufficiently "Møller-like."
-			double momentumSum = VecOp.add(pair[0].getMomentum(), pair[1].getMomentum()).magnitude();
-			if(momentumSum < møllerLowerRange || momentumSum > møllerUpperRange) {
-				continue møllerLoop;
-			}
-			
-			// Require that all clusters occur within the trigger time
-			// window to exclude accidentals.
-			if(checkTriggerTimeWindow) {
-				if(!inTriggerWindow(trackClusters[0]) || !inTriggerWindow(trackClusters[1])) {
-					continue møllerLoop;
-				}
-			}
-			
-			// If all the above conditions are met, the pair is to be
-			// considered a trident pair. Add it to the list.
-			møllerTracks.add(pair);
-		}
-		
-		// Return the list of pairs that passed the condition.
-		return møllerTracks;
-	}
-	
-	/**
-	 * Calculates the approximate invariant mass for a pair of tracks
-	 * from their momentum. This assumes that the particles are either
-	 * electrons or positrons, and thusly have a sufficiently small
-	 * mass term that it can be safely excluded.
-	 * @param pair - The track pair for which to calculate the invariant
-	 * mass.
-	 * @return Returns the approximate invariant mass in units of GeV.
-	 */
-	private static final double getInvariantMass(ReconstructedParticle[] pair) {
-		// Get the momentum squared.
-		double p2 = Math.pow(pair[0].getMomentum().magnitude() + pair[1].getMomentum().magnitude(), 2);
-		
-		// Get the remaining terms.
-		double xPro = pair[0].getMomentum().x() + pair[1].getMomentum().x();
-		double yPro = pair[0].getMomentum().y() + pair[1].getMomentum().y();
-		double zPro = pair[0].getMomentum().z() + pair[1].getMomentum().z();
-		
-		// Calculate the invariant mass.
-		return Math.sqrt(p2 - Math.pow(xPro, 2) - Math.pow(yPro, 2) - Math.pow(zPro, 2));
-	}
-	
-	/**
-	 * Calculates the coplanarity angle between two points, specified
-	 * by a double array. The array must be of the format (x, y, z).
-	 * @param position - The first position array.
-	 * @param otherPosition - The second position array.
-	 * @return Returns the coplanarity angle between the points in units
-	 * of degrees.
-	 */
-	private static final double getCalculatedCoplanarity(double[] position, double[] otherPosition) {
-		// Define the x- and y-coordinates of the clusters as well as
-		// calorimeter center.
-		final double ORIGIN_X = 42.52;
-		double x[] = { position[0], otherPosition[0] };
-		double y[] = { position[1], otherPosition[1] };
-		
+        if(!event.hasCollection(ReconstructedParticle.class, particleCollectionName)) {
+            return;
+        }
+        List<ReconstructedParticle> trackList = event.get(ReconstructedParticle.class, particleCollectionName);
+        
+        // Check if the event has a collection of clusters. If it
+        // exists, extract it. Otherwise, skip the event.
+        if(!event.hasCollection(Cluster.class, clusterCollectionName)) {
+            return;
+        }
+        List<Cluster> clusterList = event.get(Cluster.class, clusterCollectionName);
+        
+        // Get cluster-track matched top/bottom pairs.
+        List<ReconstructedParticle[]> gblMatchedPairs = getTopBottomTracksGBL(trackList);
+        List<ReconstructedParticle[]> ctMatchedPairs  = getTopBottomTracksCTMatched(trackList);
+        
+        System.out.println("CTM Pairs :: " + ctMatchedPairs.size());
+        System.out.println("GBL Pairs :: " + gblMatchedPairs.size());
+        
+        // Get the trident and Møller tracks for the matched track
+        // and cluster pair condition sets.
+        List<ReconstructedParticle[]> møllers     = getMøllerTracksCTMatched(ctMatchedPairs);
+        List<ReconstructedParticle[]> møllersGBL  = getMøllerTracksGBL(gblMatchedPairs, event);
+        List<ReconstructedParticle[]> tridents    = getTridentTracksCTMatched(ctMatchedPairs);
+        List<ReconstructedParticle[]> tridentsGBL = getTridentClustersGBL(gblMatchedPairs, TriggerModule.getTopBottomPairs(clusterList, Cluster.class), event);
+        
+        // Track how many events had tridents and Møllers.
+        if(!møllers.isEmpty()) { møllersProcessed++; }
+        if(!tridents.isEmpty()) { tridentsProcessed++; }
+        if(!møllersGBL.isEmpty()) { gblMøllersProcessed++; }
+        if(!tridentsGBL.isEmpty()) { gblTridentsProcessed++; }
+        
+        // Produce Møller cluster-track matched plots.
+        møctmInstancesInEvent.fill(møllers.size());
+        for(ReconstructedParticle[] pair : møllers) {
+            // Get the track clusters.
+            Track[] tracks = { pair[0].getTracks().get(0), pair[1].getTracks().get(0) };
+            Cluster[] trackClusters = { pair[0].getClusters().get(0), pair[1].getClusters().get(0) };
+            
+            // Populate the cluster plots.
+            møctmElectronEnergy.fill(trackClusters[0].getEnergy());
+            møctmElectronEnergy.fill(trackClusters[1].getEnergy());
+            møctmEnergySum1D.fill(TriggerModule.getValueEnergySum(trackClusters));
+            møctmEnergySum2D.fill(trackClusters[0].getEnergy(), trackClusters[1].getEnergy());
+            møctmESumCoplanarity.fill(TriggerModule.getValueEnergySum(trackClusters), getCalculatedCoplanarity(trackClusters));
+            møctmTimeCoincidence.fill(TriggerModule.getClusterTime(trackClusters[0]) - TriggerModule.getClusterTime(trackClusters[1]));
+            møctmClusterPosition.fill(TriggerModule.getClusterXIndex(trackClusters[0]), TriggerModule.getClusterYIndex(trackClusters[0]));
+            møctmClusterPosition.fill(TriggerModule.getClusterXIndex(trackClusters[1]), TriggerModule.getClusterYIndex(trackClusters[1]));
+            
+            // Populate the momentum plots.
+            møctmInvariantMass.fill(getInvariantMass(pair));
+            møctmElectronMomentum.fill(pair[0].getMomentum().magnitude());
+            møctmElectronMomentum.fill(pair[1].getMomentum().magnitude());
+            møctmMomentumSum1D.fill(VecOp.add(pair[0].getMomentum(), pair[1].getMomentum()).magnitude());
+            møctmMomentumSum2D.fill(pair[0].getMomentum().magnitude(), pair[1].getMomentum().magnitude());
+            møctmTrackPosition.fill(TrackUtils.getTrackPositionAtEcal(tracks[0]).x(), TrackUtils.getTrackPositionAtEcal(tracks[0]).y());
+            møctmTrackPosition.fill(TrackUtils.getTrackPositionAtEcal(tracks[1]).x(), TrackUtils.getTrackPositionAtEcal(tracks[1]).y());
+            møctmPSumCoplanarity.fill(VecOp.add(pair[0].getMomentum(), pair[1].getMomentum()).magnitude(),
+                    getCalculatedCoplanarity(new Track[] { pair[0].getTracks().get(0), pair[1].getTracks().get(0) }));
+        }
+        
+        // Produce trident cluster-track matched plots.
+        trctmInstancesInEvent.fill(tridents.size());
+        for(ReconstructedParticle[] pair : tridents) {
+            // Get the electron and positron tracks.
+            ReconstructedParticle electronTrack = pair[pair[0].getCharge() < 0 ? 0 : 1];
+            ReconstructedParticle positronTrack = pair[pair[0].getCharge() > 0 ? 0 : 1];
+            
+            // Get the track clusters.
+            Cluster electronCluster = electronTrack.getClusters().get(0);
+            Cluster positronCluster = positronTrack.getClusters().get(0);
+            Track[] tracks = { pair[0].getTracks().get(0), pair[1].getTracks().get(0) };
+            Cluster[] trackClusters = { pair[0].getClusters().get(0), pair[1].getClusters().get(0) };
+            
+            // Populate the cluster plots.
+            trctmElectronEnergy.fill(electronCluster.getEnergy());
+            trctmPositronEnergy.fill(positronCluster.getEnergy());
+            trctmEnergySum2D.fill(pair[0].getEnergy(), pair[1].getEnergy());
+            trctmEnergySum1D.fill(TriggerModule.getValueEnergySum(trackClusters));
+            trctmESumCoplanarity.fill(TriggerModule.getValueEnergySum(trackClusters), getCalculatedCoplanarity(trackClusters));
+            trctmTimeCoincidence.fill(TriggerModule.getClusterTime(trackClusters[0]) - TriggerModule.getClusterTime(trackClusters[1]));
+            trctmClusterPosition.fill(TriggerModule.getClusterXIndex(trackClusters[0]), TriggerModule.getClusterYIndex(trackClusters[0]));
+            trctmClusterPosition.fill(TriggerModule.getClusterXIndex(trackClusters[1]), TriggerModule.getClusterYIndex(trackClusters[1]));
+            
+            // Populate the momentum plots.
+            trctmInvariantMass.fill(getInvariantMass(pair));
+            trctmElectronMomentum.fill(electronTrack.getMomentum().magnitude());
+            trctmPositronMomentum.fill(positronTrack.getMomentum().magnitude());
+            trctmMomentumSum1D.fill(VecOp.add(pair[0].getMomentum(), pair[1].getMomentum()).magnitude());
+            trctmMomentumSum2D.fill(pair[0].getMomentum().magnitude(), pair[1].getMomentum().magnitude());
+            trctmTrackPosition.fill(TrackUtils.getTrackPositionAtEcal(tracks[0]).x(), TrackUtils.getTrackPositionAtEcal(tracks[0]).y());
+            trctmTrackPosition.fill(TrackUtils.getTrackPositionAtEcal(tracks[1]).x(), TrackUtils.getTrackPositionAtEcal(tracks[1]).y());
+            trctmPSumCoplanarity.fill(VecOp.add(pair[0].getMomentum(), pair[1].getMomentum()).magnitude(),
+                    getCalculatedCoplanarity(new Track[] { pair[0].getTracks().get(0), pair[1].getTracks().get(0) }));
+        }
+        
+        // Produce the Møller track-only plots.
+        møgblInstancesInEvent.fill(møllersGBL.size());
+        RelationalTable<?, ?> hitToStrips = TrackUtils.getHitToStripsTable(event);
+        RelationalTable<?, ?> hitToRotated = TrackUtils.getHitToRotatedTable(event);
+        for(ReconstructedParticle pair[] : møllersGBL) {
+            // Get the tracks and track times.
+            Track[] tracks = { pair[0].getTracks().get(0), pair[1].getTracks().get(0) };
+            double times[] = {
+                    TrackUtils.getTrackTime(tracks[0], hitToStrips, hitToRotated),
+                    TrackUtils.getTrackTime(tracks[1], hitToStrips, hitToRotated)   
+            };
+            
+            // Fill the plots.
+            møgblTimeCoincidence.fill(times[0] - times[1]);
+            møgblInvariantMass.fill(getInvariantMass(pair));
+            møgblElectronMomentum.fill(pair[0].getMomentum().magnitude());
+            møgblElectronMomentum.fill(pair[1].getMomentum().magnitude());
+            møgblMomentumSum1D.fill(VecOp.add(pair[0].getMomentum(), pair[1].getMomentum()).magnitude());
+            møgblMomentumSum2D.fill(pair[0].getMomentum().magnitude(), pair[1].getMomentum().magnitude());
+            møgblTrackPosition.fill(TrackUtils.getTrackPositionAtEcal(tracks[0]).x(), TrackUtils.getTrackPositionAtEcal(tracks[0]).y());
+            møgblTrackPosition.fill(TrackUtils.getTrackPositionAtEcal(tracks[1]).x(), TrackUtils.getTrackPositionAtEcal(tracks[1]).y());
+            møgblPSumCoplanarity.fill(VecOp.add(pair[0].getMomentum(), pair[1].getMomentum()).magnitude(),
+                    getCalculatedCoplanarity(new Track[] { pair[0].getTracks().get(0), pair[1].getTracks().get(0) }));
+        }
+        
+        // Produce track-only trident plots.
+        trgblInstancesInEvent.fill(tridentsGBL.size());
+        for(ReconstructedParticle[] pair : tridentsGBL) {
+            // Get the tracks and track times.
+            Track[] tracks = { pair[0].getTracks().get(0), pair[1].getTracks().get(0) };
+            double times[] = {
+                    TrackUtils.getTrackTime(tracks[0], hitToStrips, hitToRotated),
+                    TrackUtils.getTrackTime(tracks[1], hitToStrips, hitToRotated)   
+            };
+            
+            // Get the positron and the electron.
+            ReconstructedParticle positron = pair[0].getCharge() > 0 ? pair[0] : pair[1];
+            ReconstructedParticle electron = pair[0].getCharge() < 0 ? pair[0] : pair[1];
+            
+            // Fill the plots.
+            trgblTimeCoincidence.fill(times[0] - times[1]);
+            trgblInvariantMass.fill(getInvariantMass(pair));
+            trgblElectronMomentum.fill(electron.getMomentum().magnitude());
+            trgblPositronMomentum.fill(positron.getMomentum().magnitude());
+            trgblMomentumSum1D.fill(VecOp.add(pair[0].getMomentum(), pair[1].getMomentum()).magnitude());
+            trgblMomentumSum2D.fill(pair[0].getMomentum().magnitude(), pair[1].getMomentum().magnitude());
+            trgblTrackPosition.fill(TrackUtils.getTrackPositionAtEcal(tracks[0]).x(), TrackUtils.getTrackPositionAtEcal(tracks[0]).y());
+            trgblTrackPosition.fill(TrackUtils.getTrackPositionAtEcal(tracks[1]).x(), TrackUtils.getTrackPositionAtEcal(tracks[1]).y());
+            trgblPSumCoplanarity.fill(VecOp.add(pair[0].getMomentum(), pair[1].getMomentum()).magnitude(),
+                    getCalculatedCoplanarity(new Track[] { pair[0].getTracks().get(0), pair[1].getTracks().get(0) }));
+        }
+    }
+    
+    public void setCheckSVT(boolean state) {
+        checkSVT = state;
+    }
+    
+    public void setCheckTriggerTimeWindow(boolean state) {
+        checkTriggerTimeWindow = state;
+    }
+    
+    /**
+     * Gets a list of all possible GBL top/bottom track pairs. These
+     * tracks are not guaranteed to have a matched cluster.
+     * @param trackList - A list of all possible tracks.
+     * @return Returns a list of track pairs.
+     */
+    private static final List<ReconstructedParticle[]> getTopBottomTracksGBL(List<ReconstructedParticle> trackList) {
+        // Separate the tracks into top and bottom tracks based on
+        // the value of tan(Λ). Use only GBL tracks to avoid track
+        // duplication.
+        List<ReconstructedParticle> topTracks = new ArrayList<ReconstructedParticle>();
+        List<ReconstructedParticle> botTracks = new ArrayList<ReconstructedParticle>();
+        trackLoop:
+        for(ReconstructedParticle track : trackList) {
+            // Require that the ReconstructedParticle contain an actual
+            // Track object.
+            if(track.getTracks().isEmpty()) {
+                continue trackLoop;
+            }
+            
+            // Ignore tracks that are not GBL tracks.
+            if(!TrackType.isGBL(track.getType())) {
+                continue trackLoop;
+            }
+            
+            // If the above tests pass, the ReconstructedParticle has
+            // a track and is also a GBL track. Separate it into either
+            // a top or a bottom track based on its tan(Λ) value.
+            if(track.getTracks().get(0).getTrackStates().get(0).getTanLambda() > 0) {
+                topTracks.add(track);
+            } else {
+                botTracks.add(track);
+            }
+        }
+        
+        // Form all top/bottom pairs with the unique tracks.
+        List<ReconstructedParticle[]> pairList = new ArrayList<ReconstructedParticle[]>();
+        for(ReconstructedParticle topTrack : topTracks) {
+            for(ReconstructedParticle botTrack : botTracks) {
+                pairList.add(new ReconstructedParticle[] { topTrack, botTrack });
+            }
+        }
+        
+        // Return the result.
+        return pairList;
+    }
+    
+    /**
+     * Produces pairs of tracks. The track pairs are required to be
+     * matched to a cluster and the associated clusters must form a
+     * top/bottom pair. If more than one track points to the same
+     * cluster, only the first track is retained.
+     * @param trackList - A list of all tracks.
+     * @return Returns a list of track pairs meeting the aforementioned
+     * conditions.
+     */
+    private static final List<ReconstructedParticle[]> getTopBottomTracksCTMatched(List<ReconstructedParticle> trackList) {
+        // Track clusters that have already been seen to prevent clusters
+        // that have duplicate tracks from reappearing.
+        Set<Cluster> clusterSet = new HashSet<Cluster>();
+        
+        // Separate the tracks into top and bottom tracks based on
+        // the track cluster. Filter out tracks with no clusters.
+        List<ReconstructedParticle> topTracks = new ArrayList<ReconstructedParticle>();
+        List<ReconstructedParticle> botTracks = new ArrayList<ReconstructedParticle>();
+        trackLoop:
+        for(ReconstructedParticle track : trackList) {
+            // Check if the track has a cluster. If not, skip it.
+            if(track.getClusters().isEmpty()) {
+                continue trackLoop;
+            }
+            
+            // If the track doesn't have actual tracks, skip it.
+            if(track.getTracks().isEmpty()) {
+                continue trackLoop;
+            }
+            
+            // Check if the track cluster has already seen.
+            Cluster trackCluster = track.getClusters().get(0);
+            if(clusterSet.contains(trackCluster)) {
+                continue trackLoop;
+            }
+            
+            // If the track has a unique cluster, add it to the proper
+            // list based on the cluster y-index.
+            clusterSet.add(trackCluster);
+            if(TriggerModule.getClusterYIndex(trackCluster) > 0) {
+                topTracks.add(track);
+            } else {
+                botTracks.add(track);
+            }
+        }
+        
+        // Form all top/bottom pairs with the unique tracks.
+        List<ReconstructedParticle[]> pairList = new ArrayList<ReconstructedParticle[]>();
+        for(ReconstructedParticle topTrack : topTracks) {
+            for(ReconstructedParticle botTrack : botTracks) {
+                pairList.add(new ReconstructedParticle[] { topTrack, botTrack });
+            }
+        }
+        
+        // Return the result.
+        return pairList;
+    }
+    
+    private final List<ReconstructedParticle[]> getTridentClustersGBL(List<ReconstructedParticle[]> pairList, List<Cluster[]> clusterList, EventHeader event) {
+        // Store the set of track pairs that meet the trident condition.
+        List<ReconstructedParticle[]> tridentTracks = new ArrayList<ReconstructedParticle[]>();
+        
+        // Extract track relational tables from the event object.
+        RelationalTable<?, ?> hitToStrips = TrackUtils.getHitToStripsTable(event);
+        RelationalTable<?, ?> hitToRotated = TrackUtils.getHitToRotatedTable(event);
+        
+        // Tracks will not be considered for trident analysis unless there
+        // is at least one top/bottom cluster pair within the time window.
+        boolean passesClusterCondition = false;
+        tridentClusterLoop:
+        for(Cluster[] pair : clusterList) {
+            // Ignore clusters that are too far apart temporally.
+            if(TriggerModule.getValueTimeCoincidence(pair) > timeCoincidence) {
+                continue tridentClusterLoop;
+            }
+            
+            // Require that the cluster pair be top/bottom.
+            boolean hasTop = TriggerModule.getClusterYIndex(pair[0]) > 0 || TriggerModule.getClusterYIndex(pair[1]) > 0;
+            boolean hasBot = TriggerModule.getClusterYIndex(pair[0]) < 0 || TriggerModule.getClusterYIndex(pair[1]) < 0;
+            if(!hasTop || !hasBot) {
+                continue tridentClusterLoop;
+            }
+            
+            // If the cluster passes, mark that it has done so and skip
+            // the rest. Only one pair need pass.
+            passesClusterCondition = true;
+            break tridentClusterLoop;
+        }
+        
+        // If no cluster pair passed the cluster condition, no tracks
+        // are allowed to pass either.
+        if(!passesClusterCondition) {
+            return tridentTracks;
+        }
+        
+        // Next, check the track pair list. A track pair must have a
+        // positive and a negative track and must also be within the
+        // time coincidence window.
+        tridentTrackLoop:
+        for(ReconstructedParticle[] pair : pairList) {
+            // Check that there is at least one positive and one negative
+            // track in the pair.
+            boolean hasPositive = pair[0].getCharge() > 0 || pair[1].getCharge() > 0;
+            boolean hasNegative = pair[0].getCharge() < 0 || pair[1].getCharge() < 0;
+            if(!hasPositive || !hasNegative) {
+                break tridentTrackLoop;
+            }
+            
+            // Check that the track pair passes the time cut.
+            double times[] = {
+                TrackUtils.getTrackTime(pair[0].getTracks().get(0), hitToStrips, hitToRotated),
+                TrackUtils.getTrackTime(pair[1].getTracks().get(0), hitToStrips, hitToRotated)  
+            };
+            
+            if(Math.abs(times[0] - times[1]) > timeCoincidence) {
+                continue tridentTrackLoop;
+            }
+            
+            // Require that the negative track have less than the
+            // elastic threshold momentum to exclude elastic electrons.
+            if(pair[0].getCharge() < 0 && pair[0].getMomentum().magnitude() > elasticThreshold
+                    || pair[1].getCharge() < 0 && pair[1].getMomentum().magnitude() > elasticThreshold) {
+                continue tridentTrackLoop;
+            }
+            
+            // If the track passes both, it is considered a trident pair.
+            tridentTracks.add(pair);
+        }
+        
+        // Return the resultant pairs.
+        return tridentTracks;
+    }
+    
+    /**
+     * Gets a list track pairs that meet the trident condition defined
+     * using tracks with matched calorimeter clusters. A pair meets the
+     * cluster/track matched trident condition is it meets the following:
+     * <ul><li>Both tracks have matched clusters.</li>
+     * <li>Has one positive track.</li>
+     * <li>Has one negative track.</li>
+     * <li>Clusters have a time coincidence of 2.5 ns or less.</li>
+     * <li>The electron momentum is below 900 MeV.</li></ul>
+     * @param pairList - A <code>List</code> collection of parameterized
+     * type <code>ReconstructedParticle[]</code> containing all valid
+     * top/bottom pairs of tracks with matched clusters. These will be
+     * tested to see if they meet the process criteria.
+     * @return Returns a list containing pairs of tracks that meet the
+     * trident condition.
+     */
+    private final List<ReconstructedParticle[]> getTridentTracksCTMatched(List<ReconstructedParticle[]> pairList) {
+        // Store the set of track pairs that meet the trident condition.
+        List<ReconstructedParticle[]> tridentTracks = new ArrayList<ReconstructedParticle[]>();
+        
+        // Loop over the filtered pair list and apply the trident
+        // condition test.
+        tridentLoop:
+        for(ReconstructedParticle[] pair : pairList) {
+            // There must be one positive and one negative track.
+            ReconstructedParticle electron = null;
+            ReconstructedParticle positron = null;
+            if(pair[0].getCharge() > 0) { positron = pair[0]; }
+            else if(pair[1].getCharge() > 0) { positron = pair[1]; }
+            if(pair[0].getCharge() < 0) { electron = pair[0]; }
+            else if(pair[1].getCharge() < 0) { electron = pair[1]; }
+            if(electron == null || positron == null) {
+                continue tridentLoop;
+            }
+            
+            // Make sure that the clusters are not the same. This should
+            // not actually ever be possible...
+            if(pair[0].getClusters().get(0) == pair[1].getClusters().get(0)) {
+                continue tridentLoop;
+            }
+            
+            // The clusters must within a limited time window.
+            /*
+            Cluster[] trackClusters = { pair[0].getClusters().get(0), pair[1].getClusters().get(0) };
+            if(TriggerModule.getValueTimeCoincidence(trackClusters) > timeCoincidence) {
+                continue tridentLoop;
+            }
+            */
+            
+            // The clusters must be coincidental within an energy
+            // dependent coincidence window.
+            Cluster[] trackClusters = { pair[0].getClusters().get(0), pair[1].getClusters().get(0) };
+            if(!isCoincidental(trackClusters)) {
+                continue tridentLoop;
+            }
+            
+            // Require that the electron in the pair have an energy
+            // below the elastic threshold to exclude elastic electrons.
+            if(electron.getMomentum().magnitude() >= elasticThreshold) {
+                continue tridentLoop;
+            }
+            
+            // Require that all clusters occur within the trigger time
+            // window to exclude accidentals.
+            if(checkTriggerTimeWindow) {
+                if(!inTriggerWindow(trackClusters[0]) || !inTriggerWindow(trackClusters[1])) {
+                    continue tridentLoop;
+                }
+            }
+            
+            // If all the above conditions are met, the pair is to be
+            // considered a trident pair. Add it to the list.
+            tridentTracks.add(pair);
+        }
+        
+        // Return the list of pairs that passed the condition.
+        return tridentTracks;
+    }
+    
+    private final List<ReconstructedParticle[]> getMøllerTracksGBL(List<ReconstructedParticle[]> pairList, EventHeader event) {
+        // Store the set of track pairs that meet the Møller condition.
+        List<ReconstructedParticle[]> møllerTracks = new ArrayList<ReconstructedParticle[]>();
+        
+        // Extract track relational tables from the event object.
+        RelationalTable<?, ?> hitToStrips = TrackUtils.getHitToStripsTable(event);
+        RelationalTable<?, ?> hitToRotated = TrackUtils.getHitToRotatedTable(event);
+        
+        // Loop over the filtered pair list and apply the Møller
+        // condition test.
+        møllerLoop:
+        for(ReconstructedParticle[] pair : pairList) {
+            // Both tracks must be negatively charged.
+            if(pair[0].getCharge() > 0 || pair[1].getCharge() > 0) {
+                continue møllerLoop;
+            }
+            
+            // The clusters must within a limited time window.
+            double times[] = {
+                TrackUtils.getTrackTime(pair[0].getTracks().get(0), hitToStrips, hitToRotated),
+                TrackUtils.getTrackTime(pair[1].getTracks().get(0), hitToStrips, hitToRotated)  
+            };
+            
+            if(Math.abs(times[0] - times[1]) > timeCoincidence) {
+                continue møllerLoop;
+            }
+            
+            // Require that the electrons in the pair have energies
+            // below the elastic threshold to exclude said electrons.
+            if(pair[0].getMomentum().magnitude() > elasticThreshold || pair[1].getMomentum().magnitude() > elasticThreshold) {
+                continue møllerLoop;
+            }
+            
+            // Require that the energy of the pair be within a range
+            // that is sufficiently "Møller-like."
+            double momentumSum = VecOp.add(pair[0].getMomentum(), pair[1].getMomentum()).magnitude();
+            if(momentumSum < møllerLowerRange || momentumSum > møllerUpperRange) {
+                continue møllerLoop;
+            }
+            
+            // If all the above conditions are met, the pair is to be
+            // considered a trident pair. Add it to the list.
+            møllerTracks.add(pair);
+        }
+        
+        // Return the list of pairs that passed the condition.
+        return møllerTracks;
+    }
+    
+    /**
+     * Gets a list track pairs that meet the Møller condition defined
+     * using tracks with matched calorimeter clusters. A pair meets the
+     * cluster/track matched Møller condition is it meets the following:
+     * <ul><li>Both tracks have matched clusters.</li>
+     * <li>Both tracks are negative.</li>
+     * <li>Clusters have a time coincidence of 2.5 ns or less.</li>
+     * <li>The electron momenta are below 900 MeV.</li>
+     * <li>The momentum sum of the tracks is in the range <code>800 MeV
+     * ≤ p1 + p2 ≤ 1500 MeV</li></ul>
+     * @param pairList - A <code>List</code> collection of parameterized
+     * type <code>ReconstructedParticle[]</code> containing all valid
+     * top/bottom pairs of tracks with matched clusters. These will be
+     * tested to see if they meet the process criteria.
+     * @return Returns a list containing pairs of tracks that meet the
+     * Møller condition.
+     */
+    private final List<ReconstructedParticle[]> getMøllerTracksCTMatched(List<ReconstructedParticle[]> pairList) {
+        // Store the set of track pairs that meet the Møller condition.
+        List<ReconstructedParticle[]> møllerTracks = new ArrayList<ReconstructedParticle[]>();
+        
+        // Loop over the filtered pair list and apply the Møller
+        // condition test.
+        møllerLoop:
+        for(ReconstructedParticle[] pair : pairList) {
+            // Both tracks must be negatively charged.
+            if(pair[0].getCharge() > 0 || pair[1].getCharge() > 0) {
+                continue møllerLoop;
+            }
+            
+            // The clusters must within a limited time window.
+            /*
+            Cluster[] trackClusters = { pair[0].getClusters().get(0), pair[1].getClusters().get(0) };
+            if(TriggerModule.getValueTimeCoincidence(trackClusters) > timeCoincidence) {
+                continue møllerLoop;
+            }
+            */
+            
+            // The clusters must be coincidental within an energy
+            // dependent coincidence window.
+            Cluster[] trackClusters = { pair[0].getClusters().get(0), pair[1].getClusters().get(0) };
+            if(!isCoincidental(trackClusters)) {
+                continue møllerLoop;
+            }
+            
+            // Require that the electrons in the pair have energies
+            // below the elastic threshold to exclude said electrons.
+            if(pair[0].getMomentum().magnitude() > elasticThreshold || pair[1].getMomentum().magnitude() > elasticThreshold) {
+                continue møllerLoop;
+            }
+            
+            // Require that the energy of the pair be within a range
+            // that is sufficiently "Møller-like."
+            double momentumSum = VecOp.add(pair[0].getMomentum(), pair[1].getMomentum()).magnitude();
+            if(momentumSum < møllerLowerRange || momentumSum > møllerUpperRange) {
+                continue møllerLoop;
+            }
+            
+            // Require that all clusters occur within the trigger time
+            // window to exclude accidentals.
+            if(checkTriggerTimeWindow) {
+                if(!inTriggerWindow(trackClusters[0]) || !inTriggerWindow(trackClusters[1])) {
+                    continue møllerLoop;
+                }
+            }
+            
+            // If all the above conditions are met, the pair is to be
+            // considered a trident pair. Add it to the list.
+            møllerTracks.add(pair);
+        }
+        
+        // Return the list of pairs that passed the condition.
+        return møllerTracks;
+    }
+    
+    /**
+     * Calculates the approximate invariant mass for a pair of tracks
+     * from their momentum. This assumes that the particles are either
+     * electrons or positrons, and thusly have a sufficiently small
+     * mass term that it can be safely excluded.
+     * @param pair - The track pair for which to calculate the invariant
+     * mass.
+     * @return Returns the approximate invariant mass in units of GeV.
+     */
+    private static final double getInvariantMass(ReconstructedParticle[] pair) {
+        // Get the momentum squared.
+        double p2 = Math.pow(pair[0].getMomentum().magnitude() + pair[1].getMomentum().magnitude(), 2);
+        
+        // Get the remaining terms.
+        double xPro = pair[0].getMomentum().x() + pair[1].getMomentum().x();
+        double yPro = pair[0].getMomentum().y() + pair[1].getMomentum().y();
+        double zPro = pair[0].getMomentum().z() + pair[1].getMomentum().z();
+        
+        // Calculate the invariant mass.
+        return Math.sqrt(p2 - Math.pow(xPro, 2) - Math.pow(yPro, 2) - Math.pow(zPro, 2));
+    }
+    
+    /**
+     * Calculates the coplanarity angle between two points, specified
+     * by a double array. The array must be of the format (x, y, z).
+     * @param position - The first position array.
+     * @param otherPosition - The second position array.
+     * @return Returns the coplanarity angle between the points in units
+     * of degrees.
+     */
+    private static final double getCalculatedCoplanarity(double[] position, double[] otherPosition) {
+        // Define the x- and y-coordinates of the clusters as well as
+        // calorimeter center.
+        final double ORIGIN_X = 42.52;
+        double x[] = { position[0], otherPosition[0] };
+        double y[] = { position[1], otherPosition[1] };
+        
         // Get the cluster angles.
         double[] clusterAngle = new double[2];
         for(int i = 0; i < 2; i++) {
-        	clusterAngle[i] = Math.atan2(y[i], x[i] - ORIGIN_X) * 180 / Math.PI;
-        	if(clusterAngle[i] <= 0) { clusterAngle[i] += 360; }
+            clusterAngle[i] = Math.atan2(y[i], x[i] - ORIGIN_X) * 180 / Math.PI;
+            if(clusterAngle[i] <= 0) { clusterAngle[i] += 360; }
         }
         
         // Calculate the coplanarity cut value.
         double clusterDiff = clusterAngle[0] - clusterAngle[1];
         return clusterDiff > 0 ? clusterDiff : clusterDiff + 360;
-	}
-	
-	/**
-	 * Calculates the coplanarity angle of a pair of clusters.
-	 * @param pair - The pair of clusters for which to calculate the
-	 * coplanarity angle.
-	 * @return Returns the coplanarity angle between the two clusters
-	 * in degrees.
-	 */
-	private static final double getCalculatedCoplanarity(Cluster[] pair) {
-		return getCalculatedCoplanarity(pair[0].getPosition(), pair[1].getPosition());
-	}
-	
-	/**
-	 * Calculates the coplanarity angle of a pair of tracks. The track
-	 * is extrapolated to the calorimeter face and its position there
-	 * used for the arguments in the calculation.
-	 * @param pair - The pair of tracks for which to calculate the
-	 * coplanarity angle.
-	 * @return Returns the coplanarity angle between the two tracks
-	 * in degrees.
-	 */
-	private static final double getCalculatedCoplanarity(Track[] pair) {
-		return getCalculatedCoplanarity(TrackUtils.getTrackPositionAtEcal(pair[0]).v(), TrackUtils.getTrackPositionAtEcal(pair[1]).v());
-	}
-	
-	private static final boolean inTriggerWindow(Cluster cluster) {
-		// Get the cluster time.
-		double clusterTime = TriggerModule.getClusterTime(cluster);
-		
-		// Check that it is within the allowed bounds.
-		return (35 <= clusterTime && clusterTime <= 50);
-	}
-	
-	private static final boolean isCoincidental(Cluster[] pair) {
-		// Get the energy sum and the time coincidence.
-		double energySum = pair[0].getEnergy() + pair[1].getEnergy();
-		double timeCoincidence = TriggerModule.getValueTimeCoincidence(pair);
-		
-		// Get the upper and lower bounds of the allowed range.
-		double mean = getTimeDependenceMean(energySum);
-		double threeSigma = 3.0 * getTimeDependenceSigma(energySum);
-		double lowerBound = mean - threeSigma;
-		double upperBound = mean + threeSigma;
-		
-		// Perform the time coincidence check.
-		return (lowerBound <= timeCoincidence && timeCoincidence <= upperBound);
-	}
-	
-	private static final double getTimeDependenceMean(double energySum) {
-		// Define the fit parameters.
-		double[] param = { 0.289337, -2.81998, 9.03475, -12.93, 8.71476, -2.26969 };
-		
-		// Calculate the mean.
-		return param[0] + energySum * (param[1] + energySum * (param[2] + energySum * (param[3] + energySum * (param[4] + energySum * (param[5])))));
-	}
-	
-	private static final double getTimeDependenceSigma(double energySum) {
-		// Define the fit parameters.
-		double[] param = { 4.3987, -24.2371, 68.9567, -98.2586, 67.562, -17.8987 };
-		
-		// Calculate the standard deviation.
-		return param[0] + energySum * (param[1] + energySum * (param[2] + energySum * (param[3] + energySum * (param[4] + energySum * (param[5])))));
-	}
+    }
+    
+    /**
+     * Calculates the coplanarity angle of a pair of clusters.
+     * @param pair - The pair of clusters for which to calculate the
+     * coplanarity angle.
+     * @return Returns the coplanarity angle between the two clusters
+     * in degrees.
+     */
+    private static final double getCalculatedCoplanarity(Cluster[] pair) {
+        return getCalculatedCoplanarity(pair[0].getPosition(), pair[1].getPosition());
+    }
+    
+    /**
+     * Calculates the coplanarity angle of a pair of tracks. The track
+     * is extrapolated to the calorimeter face and its position there
+     * used for the arguments in the calculation.
+     * @param pair - The pair of tracks for which to calculate the
+     * coplanarity angle.
+     * @return Returns the coplanarity angle between the two tracks
+     * in degrees.
+     */
+    private static final double getCalculatedCoplanarity(Track[] pair) {
+        return getCalculatedCoplanarity(TrackUtils.getTrackPositionAtEcal(pair[0]).v(), TrackUtils.getTrackPositionAtEcal(pair[1]).v());
+    }
+    
+    private static final boolean inTriggerWindow(Cluster cluster) {
+        // Get the cluster time.
+        double clusterTime = TriggerModule.getClusterTime(cluster);
+        
+        // Check that it is within the allowed bounds.
+        return (35 <= clusterTime && clusterTime <= 50);
+    }
+    
+    private static final boolean isCoincidental(Cluster[] pair) {
+        // Get the energy sum and the time coincidence.
+        double energySum = pair[0].getEnergy() + pair[1].getEnergy();
+        double timeCoincidence = TriggerModule.getValueTimeCoincidence(pair);
+        
+        // Get the upper and lower bounds of the allowed range.
+        double mean = getTimeDependenceMean(energySum);
+        double threeSigma = 3.0 * getTimeDependenceSigma(energySum);
+        double lowerBound = mean - threeSigma;
+        double upperBound = mean + threeSigma;
+        
+        // Perform the time coincidence check.
+        return (lowerBound <= timeCoincidence && timeCoincidence <= upperBound);
+    }
+    
+    private static final double getTimeDependenceMean(double energySum) {
+        // Define the fit parameters.
+        double[] param = { 0.289337, -2.81998, 9.03475, -12.93, 8.71476, -2.26969 };
+        
+        // Calculate the mean.
+        return param[0] + energySum * (param[1] + energySum * (param[2] + energySum * (param[3] + energySum * (param[4] + energySum * (param[5])))));
+    }
+    
+    private static final double getTimeDependenceSigma(double energySum) {
+        // Define the fit parameters.
+        double[] param = { 4.3987, -24.2371, 68.9567, -98.2586, 67.562, -17.8987 };
+        
+        // Calculate the standard deviation.
+        return param[0] + energySum * (param[1] + energySum * (param[2] + energySum * (param[3] + energySum * (param[4] + energySum * (param[5])))));
+    }
 }

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/plots/AddPlots.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/plots/AddPlots.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/plots/AddPlots.java	Wed Apr 27 11:11:32 2016
@@ -14,241 +14,241 @@
 import hep.aida.ITree;
 
 public class AddPlots {
-	
-	public static void main(String[] args) throws IllegalArgumentException, IOException {
-		// Define the root directory for the plots.
-		String rootDir = null;
-		
-		// Get the option identifier from the command arguments.
-		boolean isHelp = false;
-		boolean isFileList = false;
-		boolean isDirectory = false;
-		if(args.length > 0) {
-			if(args[0].compareTo("-h") == 0) { isHelp = true; }
-			else if(args[0].compareTo("-f") == 0) { isFileList = true; }
-			else if(args[0].compareTo("-d") == 0) { isDirectory = true; }
-		} else {
-			System.err.println("Insufficient arguments. See \"AddPlots -h\"");
-			System.exit(1);
-		}
-		
-		// Process the command line argument.
-		List<File> plotFiles = new ArrayList<File>();
-		if(isHelp) {
-			System.out.println("Usage:");
-			System.out.println("\tAddPlots -d [PLOT_DIRECTORY]");
-			System.out.println("\tAddPlots -f [PLOT_FILE] [PLOT_FILE] ...");
-			System.exit(0);
-		} else if(isDirectory) {
-			// Make sure that a directory is specified.
-			if(args.length < 2) {
-				System.err.println("Insufficient arguments. Must specify at least two files.");
-				System.exit(1);
-			}
-			
-			// Get the plot directory from the second argument.
-			File plotDirectory = new File(args[1]);
-			
-			// Verify that it exists and is a directory.
-			if(!plotDirectory.exists()) {
-				System.err.println("File path does not exist.");
-				System.exit(1);
-			} if(!plotDirectory.isDirectory()) {
-				System.err.println("Indicated path must be a directory.");
-				System.exit(1);
-			}
-			
-			// Store the root directory.
-			rootDir = plotDirectory.getAbsolutePath() + "/";
-			
-			// Extract the AIDA files from the directory.
-			for(File file : plotDirectory.listFiles()) {
-				System.out.println(file.getName());
-				int indexOfExtension = file.getName().lastIndexOf('.');
-				if(indexOfExtension == -1) { continue; }
-				if(file.getName().substring(indexOfExtension).compareToIgnoreCase(".aida") == 0) {
-					plotFiles.add(file);
-				}
-			}
-			
-			// Debug status print.
-			System.out.println("Processing plots in directory \"" + plotDirectory.getAbsolutePath() + "\"");
-		} else if(isFileList) {
-			// Make sure that at least one file was specified.
-			if(args.length < 3) {
-				System.err.println("Insufficient arguments. Must specify at least two files.");
-				System.exit(1);
-			}
-			
-			// Get the root directory.
-			rootDir = System.getProperty("user.dir") + "/";
-			
-			// Create and verify the specified files.
-			for(int i = 1; i < args.length; i++) {
-				// Create the file object and make sure that it exists.
-				File file = new File(args[i]);
-				if(!file.exists()) {
-					System.err.println("Specified file does not exist: " + args[i]);
-					System.exit(1);
-				}
-				
-				// Add it to the file list.
-				plotFiles.add(file);
-			}
-		} else {
-			System.err.println("Option \"" + args[0] + "\" is not recognized.");
-			System.exit(1);
-		}
-		
-		// Make sure that there are actually files.
-		if(plotFiles.isEmpty()) {
-			System.err.println("No AIDA files found!");
-			System.exit(1);
-		}
-		
-		// Get the plots file and open it.
-		IAnalysisFactory af = IAnalysisFactory.create();
-		ITree tree = af.createTreeFactory().create(plotFiles.get(0).getAbsolutePath());
-		if(tree == null) { throw new IllegalArgumentException("Unable to load plot file."); }
-		
-		// Get the histograms names.
-		List<String> objectNameList = getTreeFiles(tree);
-		
-		// Separate the plots into 1D and 2D plots and extract their
-		// bin sizes and other properties.
-		List<Integer> xBins1D = new ArrayList<Integer>();
-		List<Double> xBins1DMin = new ArrayList<Double>();
-		List<Double> xBins1DMax = new ArrayList<Double>();
-		List<Integer> xBins2D = new ArrayList<Integer>();
-		List<Double> xBins2DMin = new ArrayList<Double>();
-		List<Double> xBins2DMax = new ArrayList<Double>();
-		List<Integer> yBins2D = new ArrayList<Integer>();
-		List<Double> yBins2DMin = new ArrayList<Double>();
-		List<Double> yBins2DMax = new ArrayList<Double>();
-		List<String> histogramNames1D = new ArrayList<String>();
-		List<String> histogramNames2D = new ArrayList<String>();
-		for(String objectName : objectNameList) {
-			// Get the object.
-			IManagedObject object = tree.find(objectName);
-			
-			// If it is a 1D histogram, process it.
-			if(object instanceof IHistogram1D) {
-				// Add the object to the 1D histogram list.
-				histogramNames1D.add(objectName);
-				
-				// Get the bin size.
-				IHistogram1D plot = (IHistogram1D) object;
-				xBins1D.add(plot.axis().bins());
-				xBins1DMin.add(plot.axis().lowerEdge());
-				xBins1DMax.add(plot.axis().upperEdge());
-			}
-			
-			// If it is a 1D histogram, process it.
-			else if(object instanceof IHistogram2D) {
-				// Add the object to the 2D histogram list.
-				histogramNames2D.add(objectName);
-				
-				// Get the bin size.
-				IHistogram2D plot = (IHistogram2D) object;
-				xBins2D.add(plot.xAxis().bins());
-				xBins2DMin.add(plot.xAxis().lowerEdge());
-				xBins2DMax.add(plot.xAxis().upperEdge());
-				yBins2D.add(plot.yAxis().bins());
-				yBins2DMin.add(plot.yAxis().lowerEdge());
-				yBins2DMax.add(plot.yAxis().upperEdge());
-			}
-		}
-		
-		// Create plots corresponding to each of the plot objects.
-		AIDA aida = AIDA.defaultInstance();
-		List<IHistogram1D> histograms1D = new ArrayList<IHistogram1D>(histogramNames1D.size());
-		List<IHistogram2D> histograms2D = new ArrayList<IHistogram2D>(histogramNames2D.size());
-		for(int i = 0; i < histogramNames1D.size(); i++) {
-			IHistogram1D histogram = aida.histogram1D(histogramNames1D.get(i), xBins1D.get(i), xBins1DMin.get(i), xBins1DMax.get(i));
-			histograms1D.add(histogram);
-		}
-		for(int i = 0; i < histogramNames2D.size(); i++) {
-			IHistogram2D histogram = aida.histogram2D(histogramNames2D.get(i), xBins2D.get(i), xBins2DMin.get(i), xBins2DMax.get(i), yBins2D.get(i), yBins2DMin.get(i), yBins2DMax.get(i));
-			histograms2D.add(histogram);
-		}
-		
-		// Iterate over each file and add their entries to the compiled
-		// plots.
-		for(File file : plotFiles) {
-			// Open the file.
-			ITree fileTree = af.createTreeFactory().create(file.getAbsolutePath());
-			
-			// For each plot, get the equivalent plot from the file
-			// and add each bin entry to the compiled plot.
-			for(int i = 0; i < histogramNames1D.size(); i++) {
-				// Get the histogram object.
-				IHistogram1D histogram = (IHistogram1D) fileTree.find(histogramNames1D.get(i));
-				
-				// Iterate over the bins.
-				for(int x = 0; x < xBins1D.get(i); x++) {
-					// Get the entries in this bin and the bin average.
-					int entries = histogram.binEntries(x);
-					double average = histogram.binMean(x);
-					
-					// Add the entries to the compiled plot.
-					for(int j = 0; j < entries; j++) {
-						histograms1D.get(i).fill(average);
-					}
-				}
-			}
-			for(int i = 0; i < histogramNames2D.size(); i++) {
-				// Get the histogram object.
-				IHistogram2D histogram = (IHistogram2D) fileTree.find(histogramNames2D.get(i));
-				
-				// Iterate over the bins.
-				for(int x = 0; x < xBins2D.get(i); x++) {
-					for(int y = 0; y < yBins2D.get(i); y++) {
-						// Get the entries in this bin and the bin average.
-						int entries = histogram.binEntries(x, y);
-						double averageX = histogram.binMeanX(x, y);
-						double averageY = histogram.binMeanY(x, y);
-						
-						// Add the entries to the compiled plot.
-						for(int j = 0; j < entries; j++) {
-							histograms2D.get(i).fill(averageX, averageY);
-						}
-					}
-				}
-			}
-		}
-		
-		// Save the compiled plots to a new file.
-		aida.saveAs(rootDir + "compiled-plots.aida");
-		System.out.println("Plots written to path " + rootDir + "compiled-plots.aida");
-	}
-	
-	private static final List<String> getTreeFiles(ITree tree) {
-		return getTreeFiles(tree, "/");
-	}
-	
-	private static final List<String> getTreeFiles(ITree tree, String rootDir) {
-		// Make a list to contain the plot names.
-		List<String> list = new ArrayList<String>();
-		
-		// Iterate over the objects at the indicated directory of the tree.
-		String objectNames[] = tree.listObjectNames(rootDir);
-		for(String objectName : objectNames) {
-			// Convert the object name to a char array and check the
-			// last character. Directories end in '/'.
-			char[] plotChars = objectName.toCharArray();
-			
-			// If the object is a directory, process any objects inside
-			// of it as well.
-			if(plotChars[plotChars.length - 1] == '/') {
-				List<String> dirList = getTreeFiles(tree, objectName);
-				list.addAll(dirList);
-			}
-			
-			// Otherwise, just add the object to the list.
-			else { list.add(objectName); }
-		}
-		
-		// Return the compiled list.
-		return list;
-	}
+    
+    public static void main(String[] args) throws IllegalArgumentException, IOException {
+        // Define the root directory for the plots.
+        String rootDir = null;
+        
+        // Get the option identifier from the command arguments.
+        boolean isHelp = false;
+        boolean isFileList = false;
+        boolean isDirectory = false;
+        if(args.length > 0) {
+            if(args[0].compareTo("-h") == 0) { isHelp = true; }
+            else if(args[0].compareTo("-f") == 0) { isFileList = true; }
+            else if(args[0].compareTo("-d") == 0) { isDirectory = true; }
+        } else {
+            System.err.println("Insufficient arguments. See \"AddPlots -h\"");
+            System.exit(1);
+        }
+        
+        // Process the command line argument.
+        List<File> plotFiles = new ArrayList<File>();
+        if(isHelp) {
+            System.out.println("Usage:");
+            System.out.println("\tAddPlots -d [PLOT_DIRECTORY]");
+            System.out.println("\tAddPlots -f [PLOT_FILE] [PLOT_FILE] ...");
+            System.exit(0);
+        } else if(isDirectory) {
+            // Make sure that a directory is specified.
+            if(args.length < 2) {
+                System.err.println("Insufficient arguments. Must specify at least two files.");
+                System.exit(1);
+            }
+            
+            // Get the plot directory from the second argument.
+            File plotDirectory = new File(args[1]);
+            
+            // Verify that it exists and is a directory.
+            if(!plotDirectory.exists()) {
+                System.err.println("File path does not exist.");
+                System.exit(1);
+            } if(!plotDirectory.isDirectory()) {
+                System.err.println("Indicated path must be a directory.");
+                System.exit(1);
+            }
+            
+            // Store the root directory.
+            rootDir = plotDirectory.getAbsolutePath() + "/";
+            
+            // Extract the AIDA files from the directory.
+            for(File file : plotDirectory.listFiles()) {
+                System.out.println(file.getName());
+                int indexOfExtension = file.getName().lastIndexOf('.');
+                if(indexOfExtension == -1) { continue; }
+                if(file.getName().substring(indexOfExtension).compareToIgnoreCase(".aida") == 0) {
+                    plotFiles.add(file);
+                }
+            }
+            
+            // Debug status print.
+            System.out.println("Processing plots in directory \"" + plotDirectory.getAbsolutePath() + "\"");
+        } else if(isFileList) {
+            // Make sure that at least one file was specified.
+            if(args.length < 3) {
+                System.err.println("Insufficient arguments. Must specify at least two files.");
+                System.exit(1);
+            }
+            
+            // Get the root directory.
+            rootDir = System.getProperty("user.dir") + "/";
+            
+            // Create and verify the specified files.
+            for(int i = 1; i < args.length; i++) {
+                // Create the file object and make sure that it exists.
+                File file = new File(args[i]);
+                if(!file.exists()) {
+                    System.err.println("Specified file does not exist: " + args[i]);
+                    System.exit(1);
+                }
+                
+                // Add it to the file list.
+                plotFiles.add(file);
+            }
+        } else {
+            System.err.println("Option \"" + args[0] + "\" is not recognized.");
+            System.exit(1);
+        }
+        
+        // Make sure that there are actually files.
+        if(plotFiles.isEmpty()) {
+            System.err.println("No AIDA files found!");
+            System.exit(1);
+        }
+        
+        // Get the plots file and open it.
+        IAnalysisFactory af = IAnalysisFactory.create();
+        ITree tree = af.createTreeFactory().create(plotFiles.get(0).getAbsolutePath());
+        if(tree == null) { throw new IllegalArgumentException("Unable to load plot file."); }
+        
+        // Get the histograms names.
+        List<String> objectNameList = getTreeFiles(tree);
+        
+        // Separate the plots into 1D and 2D plots and extract their
+        // bin sizes and other properties.
+        List<Integer> xBins1D = new ArrayList<Integer>();
+        List<Double> xBins1DMin = new ArrayList<Double>();
+        List<Double> xBins1DMax = new ArrayList<Double>();
+        List<Integer> xBins2D = new ArrayList<Integer>();
+        List<Double> xBins2DMin = new ArrayList<Double>();
+        List<Double> xBins2DMax = new ArrayList<Double>();
+        List<Integer> yBins2D = new ArrayList<Integer>();
+        List<Double> yBins2DMin = new ArrayList<Double>();
+        List<Double> yBins2DMax = new ArrayList<Double>();
+        List<String> histogramNames1D = new ArrayList<String>();
+        List<String> histogramNames2D = new ArrayList<String>();
+        for(String objectName : objectNameList) {
+            // Get the object.
+            IManagedObject object = tree.find(objectName);
+            
+            // If it is a 1D histogram, process it.
+            if(object instanceof IHistogram1D) {
+                // Add the object to the 1D histogram list.
+                histogramNames1D.add(objectName);
+                
+                // Get the bin size.
+                IHistogram1D plot = (IHistogram1D) object;
+                xBins1D.add(plot.axis().bins());
+                xBins1DMin.add(plot.axis().lowerEdge());
+                xBins1DMax.add(plot.axis().upperEdge());
+            }
+            
+            // If it is a 1D histogram, process it.
+            else if(object instanceof IHistogram2D) {
+                // Add the object to the 2D histogram list.
+                histogramNames2D.add(objectName);
+                
+                // Get the bin size.
+                IHistogram2D plot = (IHistogram2D) object;
+                xBins2D.add(plot.xAxis().bins());
+                xBins2DMin.add(plot.xAxis().lowerEdge());
+                xBins2DMax.add(plot.xAxis().upperEdge());
+                yBins2D.add(plot.yAxis().bins());
+                yBins2DMin.add(plot.yAxis().lowerEdge());
+                yBins2DMax.add(plot.yAxis().upperEdge());
+            }
+        }
+        
+        // Create plots corresponding to each of the plot objects.
+        AIDA aida = AIDA.defaultInstance();
+        List<IHistogram1D> histograms1D = new ArrayList<IHistogram1D>(histogramNames1D.size());
+        List<IHistogram2D> histograms2D = new ArrayList<IHistogram2D>(histogramNames2D.size());
+        for(int i = 0; i < histogramNames1D.size(); i++) {
+            IHistogram1D histogram = aida.histogram1D(histogramNames1D.get(i), xBins1D.get(i), xBins1DMin.get(i), xBins1DMax.get(i));
+            histograms1D.add(histogram);
+        }
+        for(int i = 0; i < histogramNames2D.size(); i++) {
+            IHistogram2D histogram = aida.histogram2D(histogramNames2D.get(i), xBins2D.get(i), xBins2DMin.get(i), xBins2DMax.get(i), yBins2D.get(i), yBins2DMin.get(i), yBins2DMax.get(i));
+            histograms2D.add(histogram);
+        }
+        
+        // Iterate over each file and add their entries to the compiled
+        // plots.
+        for(File file : plotFiles) {
+            // Open the file.
+            ITree fileTree = af.createTreeFactory().create(file.getAbsolutePath());
+            
+            // For each plot, get the equivalent plot from the file
+            // and add each bin entry to the compiled plot.
+            for(int i = 0; i < histogramNames1D.size(); i++) {
+                // Get the histogram object.
+                IHistogram1D histogram = (IHistogram1D) fileTree.find(histogramNames1D.get(i));
+                
+                // Iterate over the bins.
+                for(int x = 0; x < xBins1D.get(i); x++) {
+                    // Get the entries in this bin and the bin average.
+                    int entries = histogram.binEntries(x);
+                    double average = histogram.binMean(x);
+                    
+                    // Add the entries to the compiled plot.
+                    for(int j = 0; j < entries; j++) {
+                        histograms1D.get(i).fill(average);
+                    }
+                }
+            }
+            for(int i = 0; i < histogramNames2D.size(); i++) {
+                // Get the histogram object.
+                IHistogram2D histogram = (IHistogram2D) fileTree.find(histogramNames2D.get(i));
+                
+                // Iterate over the bins.
+                for(int x = 0; x < xBins2D.get(i); x++) {
+                    for(int y = 0; y < yBins2D.get(i); y++) {
+                        // Get the entries in this bin and the bin average.
+                        int entries = histogram.binEntries(x, y);
+                        double averageX = histogram.binMeanX(x, y);
+                        double averageY = histogram.binMeanY(x, y);
+                        
+                        // Add the entries to the compiled plot.
+                        for(int j = 0; j < entries; j++) {
+                            histograms2D.get(i).fill(averageX, averageY);
+                        }
+                    }
+                }
+            }
+        }
+        
+        // Save the compiled plots to a new file.
+        aida.saveAs(rootDir + "compiled-plots.aida");
+        System.out.println("Plots written to path " + rootDir + "compiled-plots.aida");
+    }
+    
+    private static final List<String> getTreeFiles(ITree tree) {
+        return getTreeFiles(tree, "/");
+    }
+    
+    private static final List<String> getTreeFiles(ITree tree, String rootDir) {
+        // Make a list to contain the plot names.
+        List<String> list = new ArrayList<String>();
+        
+        // Iterate over the objects at the indicated directory of the tree.
+        String objectNames[] = tree.listObjectNames(rootDir);
+        for(String objectName : objectNames) {
+            // Convert the object name to a char array and check the
+            // last character. Directories end in '/'.
+            char[] plotChars = objectName.toCharArray();
+            
+            // If the object is a directory, process any objects inside
+            // of it as well.
+            if(plotChars[plotChars.length - 1] == '/') {
+                List<String> dirList = getTreeFiles(tree, objectName);
+                list.addAll(dirList);
+            }
+            
+            // Otherwise, just add the object to the list.
+            else { list.add(objectName); }
+        }
+        
+        // Return the compiled list.
+        return list;
+    }
 }

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/plots/FormattedPlot.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/plots/FormattedPlot.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/plots/FormattedPlot.java	Wed Apr 27 11:11:32 2016
@@ -1,25 +1,25 @@
 package org.hps.users.kmccarty.plots;
 
 public abstract class FormattedPlot {
-	private final String xAxis;
-	private final String yAxis;
-	private final String plotName;
-	
-	public FormattedPlot(String xAxis, String yAxis, String plotName) {
-		this.xAxis = xAxis;
-		this.yAxis = yAxis;
-		this.plotName = plotName;
-	}
-	
-	public String getPlotName() {
-		return plotName;
-	}
-	
-	public String getXAxisName() {
-		return xAxis;
-	}
-	
-	public String getYAxisName() {
-		return yAxis;
-	}
+    private final String xAxis;
+    private final String yAxis;
+    private final String plotName;
+    
+    public FormattedPlot(String xAxis, String yAxis, String plotName) {
+        this.xAxis = xAxis;
+        this.yAxis = yAxis;
+        this.plotName = plotName;
+    }
+    
+    public String getPlotName() {
+        return plotName;
+    }
+    
+    public String getXAxisName() {
+        return xAxis;
+    }
+    
+    public String getYAxisName() {
+        return yAxis;
+    }
 }

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/plots/FormattedPlot1D.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/plots/FormattedPlot1D.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/plots/FormattedPlot1D.java	Wed Apr 27 11:11:32 2016
@@ -5,37 +5,37 @@
 import hep.aida.IHistogram1D;
 
 public class FormattedPlot1D extends FormattedPlot {
-	private final ColorStyle style;
-	private final IHistogram1D plot;
-	private final double axisRange;
-	
-	public FormattedPlot1D(IHistogram1D plot, ColorStyle style, String xAxis, String yAxis, String plotName) {
-		super(xAxis, yAxis, plotName);
-		this.plot = plot;
-		this.style = style;
-		this.axisRange = -1;
-	}
-	
-	public FormattedPlot1D(IHistogram1D plot, ColorStyle style, String xAxis, String yAxis, String plotName, double axisRange) {
-		super(xAxis, yAxis, plotName);
-		this.plot = plot;
-		this.style = style;
-		this.axisRange = axisRange;
-	}
-	
-	public IHistogram1D getPlot() {
-		return plot;
-	}
-	
-	public ColorStyle getColorStyle() {
-		return style;
-	}
-	
-	public boolean definesAxisRange() {
-		return axisRange != -1;
-	}
-	
-	public double getAxisRange() {
-		return axisRange;
-	}
+    private final ColorStyle style;
+    private final IHistogram1D plot;
+    private final double axisRange;
+    
+    public FormattedPlot1D(IHistogram1D plot, ColorStyle style, String xAxis, String yAxis, String plotName) {
+        super(xAxis, yAxis, plotName);
+        this.plot = plot;
+        this.style = style;
+        this.axisRange = -1;
+    }
+    
+    public FormattedPlot1D(IHistogram1D plot, ColorStyle style, String xAxis, String yAxis, String plotName, double axisRange) {
+        super(xAxis, yAxis, plotName);
+        this.plot = plot;
+        this.style = style;
+        this.axisRange = axisRange;
+    }
+    
+    public IHistogram1D getPlot() {
+        return plot;
+    }
+    
+    public ColorStyle getColorStyle() {
+        return style;
+    }
+    
+    public boolean definesAxisRange() {
+        return axisRange != -1;
+    }
+    
+    public double getAxisRange() {
+        return axisRange;
+    }
 }

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/plots/FormattedPlot2D.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/plots/FormattedPlot2D.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/plots/FormattedPlot2D.java	Wed Apr 27 11:11:32 2016
@@ -3,48 +3,48 @@
 import hep.aida.IHistogram2D;
 
 public class FormattedPlot2D extends FormattedPlot {
-	private final IHistogram2D plot;
-	private final boolean logarithmic;
-	private final double xAxisRange;
-	private final double yAxisRange;
-	
-	public FormattedPlot2D(IHistogram2D plot, boolean logarithmic, String xAxis, String yAxis, String plotName) {
-		super(xAxis, yAxis, plotName);
-		this.plot = plot;
-		this.xAxisRange = -1;
-		this.yAxisRange = -1;
-		this.logarithmic = logarithmic;
-	}
-	
-	public FormattedPlot2D(IHistogram2D plot, boolean logarithmic, String xAxis, String yAxis, String plotName, double xAxisRange, double yAxisRange) {
-		super(xAxis, yAxis, plotName);
-		this.plot = plot;
-		this.xAxisRange = xAxisRange;
-		this.yAxisRange = yAxisRange;
-		this.logarithmic = logarithmic;
-	}
-	
-	public IHistogram2D getPlot() {
-		return plot;
-	}
-	
-	public boolean isLogarithmic() {
-		return logarithmic;
-	}
-	
-	public boolean definesXAxisRange() {
-		return xAxisRange != -1;
-	}
-	
-	public boolean definesYAxisRange() {
-		return yAxisRange != -1;
-	}
-	
-	public double getXAxisRange() {
-		return xAxisRange;
-	}
-	
-	public double getYAxisRange() {
-		return yAxisRange;
-	}
+    private final IHistogram2D plot;
+    private final boolean logarithmic;
+    private final double xAxisRange;
+    private final double yAxisRange;
+    
+    public FormattedPlot2D(IHistogram2D plot, boolean logarithmic, String xAxis, String yAxis, String plotName) {
+        super(xAxis, yAxis, plotName);
+        this.plot = plot;
+        this.xAxisRange = -1;
+        this.yAxisRange = -1;
+        this.logarithmic = logarithmic;
+    }
+    
+    public FormattedPlot2D(IHistogram2D plot, boolean logarithmic, String xAxis, String yAxis, String plotName, double xAxisRange, double yAxisRange) {
+        super(xAxis, yAxis, plotName);
+        this.plot = plot;
+        this.xAxisRange = xAxisRange;
+        this.yAxisRange = yAxisRange;
+        this.logarithmic = logarithmic;
+    }
+    
+    public IHistogram2D getPlot() {
+        return plot;
+    }
+    
+    public boolean isLogarithmic() {
+        return logarithmic;
+    }
+    
+    public boolean definesXAxisRange() {
+        return xAxisRange != -1;
+    }
+    
+    public boolean definesYAxisRange() {
+        return yAxisRange != -1;
+    }
+    
+    public double getXAxisRange() {
+        return xAxisRange;
+    }
+    
+    public double getYAxisRange() {
+        return yAxisRange;
+    }
 }

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/plots/PlotFormatModule.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/plots/PlotFormatModule.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/plots/PlotFormatModule.java	Wed Apr 27 11:11:32 2016
@@ -17,189 +17,189 @@
 import java.util.List;
 
 public class PlotFormatModule {
-	private String width = "2000";
-	private String height = "1200";
-	private List<FormattedPlot1D> formattedPlots1D = new ArrayList<FormattedPlot1D>();
-	private List<FormattedPlot2D> formattedPlots2D = new ArrayList<FormattedPlot2D>();
-	
-	public void addPlot1D(FormattedPlot1D plot) {
-		formattedPlots1D.add(plot);
-	}
-	
-	public void addPlot2D(FormattedPlot2D plot) {
-		formattedPlots2D.add(plot);
-	}
-	
-	public void setDisplayHeight(int height) {
-		this.height = "" + height;
-	}
-	
-	public void setDisplayWidth(int width) {
-		this.width = "" + width;
-	}
-	
-	public void displayPlots() {
-		try { processPlots(null); }
-		catch (IOException e) { e.printStackTrace(); }
-	}
-	
-	public void savePlots(String filePath) throws IOException {
-		processPlots(filePath);
-	}
-	
-	private void processPlots(String filePath) throws IOException {
-		// Create a plotter factory.
-		IAnalysisFactory af = IAnalysisFactory.create();
-		IPlotterFactory plotterFactory = af.createPlotterFactory();
-		
-		// Format and display the 1D plots.
-		for(FormattedPlot1D formattedPlot : formattedPlots1D) {
-			// Get the plot.
-			IHistogram1D plot = formattedPlot.getPlot();
-			
-			// Create a plotter and plotting region for the plot.
-			IPlotter plotter = plotterFactory.create(plot.title());
-			plotter.createRegions(1);
-			plotter.region(0).plot(plot);
-			
-			// Set the axis range.
-			PlotterRegion region = (PlotterRegion) plotter.region(0);
-			if(formattedPlot.definesAxisRange()) {
-				region.getPlot().getXAxis().setMax(formattedPlot.getAxisRange());
-			}
-			
-			// Format the axis labels.
-			region.getPlot().setTitle(formattedPlot.getPlotName());
-			region.getPlot().getXAxis().setLabel(formattedPlot.getXAxisName());
-			region.getPlot().getYAxis().setLabel(formattedPlot.getYAxisName());
-			
-			// Format the fonts and general plot presentation.
-			PlotsFormatter.setDefault1DStyle(region, new ColorStyle[] { formattedPlot.getColorStyle() });
-			
-			// Set the plotter dimensions.
-			plotter.setParameter("plotterWidth", width);
-			plotter.setParameter("plotterHeight", height);
-			
-			// If the file path is null, display the plots. Otherwise,
-			// save them to the destination folder.
-			if(filePath == null) { plotter.show(); }
-			else {
-				File plotFile = new File(filePath + formattedPlot.getPlotName() + ".png");
-				if(plotFile.exists()) { plotFile.delete(); }
-				plotter.writeToFile(filePath + formattedPlot.getPlotName() + ".png");
-				System.out.printf("Saved plot \"%s\" to path: %s%n", formattedPlot.getPlotName(), filePath + formattedPlot.getPlotName() + ".png");
-			}
-		}
-		
-		// Format and display the 2D plots.
-		for(FormattedPlot2D formattedPlot : formattedPlots2D) {
-			// Get the plot.
-			IHistogram2D plot = formattedPlot.getPlot();
-			
-			// Create a plotter and plotting region for the plot.
-			IPlotter plotter = plotterFactory.create(formattedPlot.getPlotName());
-			plotter.createRegions(1);
-			plotter.region(0).plot(plot);
-			
-			// Set the axis range.
-			PlotterRegion region = (PlotterRegion) plotter.region(0);
-			if(formattedPlot.definesXAxisRange()) {
-				region.getPlot().getXAxis().setMax(formattedPlot.getXAxisRange());
-			} if(formattedPlot.definesYAxisRange()) {
-				region.getPlot().getYAxis().setMax(formattedPlot.getYAxisRange());
-			}
-			
-			// Format the axis labels.
-			region.getPlot().setTitle(formattedPlot.getPlotName());
-			region.getPlot().getXAxis().setLabel(formattedPlot.getXAxisName());
-			region.getPlot().getYAxis().setLabel(formattedPlot.getYAxisName());
-			
-			// Format the fonts and general plot presentation.
-			PlotsFormatter.setDefault2DStyle(region, formattedPlot.isLogarithmic());
-			
-			// Set the plotter dimensions.
-			plotter.setParameter("plotterWidth", width);
-			plotter.setParameter("plotterHeight", height);
-			
-			// If the file path is null, display the plots. Otherwise,
-			// save them to the destination folder.
-			if(filePath == null) { plotter.show(); }
-			else {
-				File plotFile = new File(filePath + formattedPlot.getPlotName() + ".png");
-				if(plotFile.exists()) { plotFile.delete(); }
-				plotter.writeToFile(filePath + formattedPlot.getPlotName() + ".png");
-				System.out.printf("Saved plot \"%s\" to path: %s%n", formattedPlot.getPlotName(), filePath + formattedPlot.getPlotName() + ".png");
-			}
-		}
-	}
-	
-	public void exportPlots(String filePath) throws IOException {
-		// Export the 1D plots in a text format.
-		for(FormattedPlot1D plot : formattedPlots1D) {
-			exportPlot(filePath, plot);
-		}
-		
-		// Export the 2D plots in a text format.
-		for(FormattedPlot2D plot : formattedPlots2D) {
-			exportPlot(filePath, plot);
-		}
-	}
-	
-	private static final void exportPlot(String filePath, FormattedPlot plot) throws IOException {
-		// Check if this is a one or two dimensional plot.
-		boolean is1D = plot instanceof FormattedPlot1D;
-		
-		// Create a file object for the plot.
-		String plotPath = filePath + plot.getPlotName() + (is1D ? ".aida1D" : ".aida2D");
-		File datFile = new File(plotPath);
-		
-		// If the plot file already exists, delete it.
-		if(datFile.exists()) { datFile.delete(); }
-		
-		// Create a new file for the plot to occupy.
-		datFile.createNewFile();
-		
-		// Get the textual form of the plot.
-		String plotText = null;
-		if(is1D) { plotText = toTextFormat(((FormattedPlot1D) plot).getPlot()); }
-		else { plotText = toTextFormat(((FormattedPlot2D) plot).getPlot()); }
-		
-		// Write the plot text to the file.
-		BufferedWriter writer = new BufferedWriter(new FileWriter(datFile));
-		writer.write(plotText);
-		writer.close();
-		
-		// Note that the file was written.
-		System.out.printf("Plot \"%s\" was exported to path: %s%n", plot.getPlotName(), plotPath);
-	}
-	
-	private static final String toTextFormat(IHistogram1D plot) {
-		// Create a buffer to hold the converted plot.
-		StringBuffer buffer = new StringBuffer();
-		
-		// Iterate over the bins and output the plot in the format of
-		// "[BIN_MEAN] [BIN_VALUE]" with a tab delimiter.
-		for(int bin = 0; bin < plot.axis().bins(); bin++) {
-			buffer.append(String.format("%f\t%f%n", plot.binMean(bin), plot.binHeight(bin)));
-		}
-		
-		// Return the converted file.
-		return buffer.toString();
-	}
-	
-	private static final String toTextFormat(IHistogram2D plot) {
-		// Create a buffer to hold the converted plot.
-		StringBuffer buffer = new StringBuffer();
-		
-		// Iterate over the bins and output the plot in the format of
-		// "[X_BIN_MEAN] [Y_BIN_MEAN] [BIN_VALUE]" with a tab delimiter.
-		for(int xBin = 0; xBin < plot.xAxis().bins(); xBin++) {
-			for(int yBin = 0; yBin < plot.yAxis().bins(); yBin++) {
-				buffer.append(String.format("%f\t%f\t%f%n", plot.binMeanX(xBin, yBin), plot.binMeanY(xBin, yBin), plot.binHeight(xBin, yBin)));
-			}
-		}
-		
-		// Return the converted file.
-		return buffer.toString();
-	}
+    private String width = "2000";
+    private String height = "1200";
+    private List<FormattedPlot1D> formattedPlots1D = new ArrayList<FormattedPlot1D>();
+    private List<FormattedPlot2D> formattedPlots2D = new ArrayList<FormattedPlot2D>();
+    
+    public void addPlot1D(FormattedPlot1D plot) {
+        formattedPlots1D.add(plot);
+    }
+    
+    public void addPlot2D(FormattedPlot2D plot) {
+        formattedPlots2D.add(plot);
+    }
+    
+    public void setDisplayHeight(int height) {
+        this.height = "" + height;
+    }
+    
+    public void setDisplayWidth(int width) {
+        this.width = "" + width;
+    }
+    
+    public void displayPlots() {
+        try { processPlots(null); }
+        catch (IOException e) { e.printStackTrace(); }
+    }
+    
+    public void savePlots(String filePath) throws IOException {
+        processPlots(filePath);
+    }
+    
+    private void processPlots(String filePath) throws IOException {
+        // Create a plotter factory.
+        IAnalysisFactory af = IAnalysisFactory.create();
+        IPlotterFactory plotterFactory = af.createPlotterFactory();
+        
+        // Format and display the 1D plots.
+        for(FormattedPlot1D formattedPlot : formattedPlots1D) {
+            // Get the plot.
+            IHistogram1D plot = formattedPlot.getPlot();
+            
+            // Create a plotter and plotting region for the plot.
+            IPlotter plotter = plotterFactory.create(plot.title());
+            plotter.createRegions(1);
+            plotter.region(0).plot(plot);
+            
+            // Set the axis range.
+            PlotterRegion region = (PlotterRegion) plotter.region(0);
+            if(formattedPlot.definesAxisRange()) {
+                region.getPlot().getXAxis().setMax(formattedPlot.getAxisRange());
+            }
+            
+            // Format the axis labels.
+            region.getPlot().setTitle(formattedPlot.getPlotName());
+            region.getPlot().getXAxis().setLabel(formattedPlot.getXAxisName());
+            region.getPlot().getYAxis().setLabel(formattedPlot.getYAxisName());
+            
+            // Format the fonts and general plot presentation.
+            PlotsFormatter.setDefault1DStyle(region, new ColorStyle[] { formattedPlot.getColorStyle() });
+            
+            // Set the plotter dimensions.
+            plotter.setParameter("plotterWidth", width);
+            plotter.setParameter("plotterHeight", height);
+            
+            // If the file path is null, display the plots. Otherwise,
+            // save them to the destination folder.
+            if(filePath == null) { plotter.show(); }
+            else {
+                File plotFile = new File(filePath + formattedPlot.getPlotName() + ".png");
+                if(plotFile.exists()) { plotFile.delete(); }
+                plotter.writeToFile(filePath + formattedPlot.getPlotName() + ".png");
+                System.out.printf("Saved plot \"%s\" to path: %s%n", formattedPlot.getPlotName(), filePath + formattedPlot.getPlotName() + ".png");
+            }
+        }
+        
+        // Format and display the 2D plots.
+        for(FormattedPlot2D formattedPlot : formattedPlots2D) {
+            // Get the plot.
+            IHistogram2D plot = formattedPlot.getPlot();
+            
+            // Create a plotter and plotting region for the plot.
+            IPlotter plotter = plotterFactory.create(formattedPlot.getPlotName());
+            plotter.createRegions(1);
+            plotter.region(0).plot(plot);
+            
+            // Set the axis range.
+            PlotterRegion region = (PlotterRegion) plotter.region(0);
+            if(formattedPlot.definesXAxisRange()) {
+                region.getPlot().getXAxis().setMax(formattedPlot.getXAxisRange());
+            } if(formattedPlot.definesYAxisRange()) {
+                region.getPlot().getYAxis().setMax(formattedPlot.getYAxisRange());
+            }
+            
+            // Format the axis labels.
+            region.getPlot().setTitle(formattedPlot.getPlotName());
+            region.getPlot().getXAxis().setLabel(formattedPlot.getXAxisName());
+            region.getPlot().getYAxis().setLabel(formattedPlot.getYAxisName());
+            
+            // Format the fonts and general plot presentation.
+            PlotsFormatter.setDefault2DStyle(region, formattedPlot.isLogarithmic());
+            
+            // Set the plotter dimensions.
+            plotter.setParameter("plotterWidth", width);
+            plotter.setParameter("plotterHeight", height);
+            
+            // If the file path is null, display the plots. Otherwise,
+            // save them to the destination folder.
+            if(filePath == null) { plotter.show(); }
+            else {
+                File plotFile = new File(filePath + formattedPlot.getPlotName() + ".png");
+                if(plotFile.exists()) { plotFile.delete(); }
+                plotter.writeToFile(filePath + formattedPlot.getPlotName() + ".png");
+                System.out.printf("Saved plot \"%s\" to path: %s%n", formattedPlot.getPlotName(), filePath + formattedPlot.getPlotName() + ".png");
+            }
+        }
+    }
+    
+    public void exportPlots(String filePath) throws IOException {
+        // Export the 1D plots in a text format.
+        for(FormattedPlot1D plot : formattedPlots1D) {
+            exportPlot(filePath, plot);
+        }
+        
+        // Export the 2D plots in a text format.
+        for(FormattedPlot2D plot : formattedPlots2D) {
+            exportPlot(filePath, plot);
+        }
+    }
+    
+    private static final void exportPlot(String filePath, FormattedPlot plot) throws IOException {
+        // Check if this is a one or two dimensional plot.
+        boolean is1D = plot instanceof FormattedPlot1D;
+        
+        // Create a file object for the plot.
+        String plotPath = filePath + plot.getPlotName() + (is1D ? ".aida1D" : ".aida2D");
+        File datFile = new File(plotPath);
+        
+        // If the plot file already exists, delete it.
+        if(datFile.exists()) { datFile.delete(); }
+        
+        // Create a new file for the plot to occupy.
+        datFile.createNewFile();
+        
+        // Get the textual form of the plot.
+        String plotText = null;
+        if(is1D) { plotText = toTextFormat(((FormattedPlot1D) plot).getPlot()); }
+        else { plotText = toTextFormat(((FormattedPlot2D) plot).getPlot()); }
+        
+        // Write the plot text to the file.
+        BufferedWriter writer = new BufferedWriter(new FileWriter(datFile));
+        writer.write(plotText);
+        writer.close();
+        
+        // Note that the file was written.
+        System.out.printf("Plot \"%s\" was exported to path: %s%n", plot.getPlotName(), plotPath);
+    }
+    
+    private static final String toTextFormat(IHistogram1D plot) {
+        // Create a buffer to hold the converted plot.
+        StringBuffer buffer = new StringBuffer();
+        
+        // Iterate over the bins and output the plot in the format of
+        // "[BIN_MEAN] [BIN_VALUE]" with a tab delimiter.
+        for(int bin = 0; bin < plot.axis().bins(); bin++) {
+            buffer.append(String.format("%f\t%f%n", plot.binMean(bin), plot.binHeight(bin)));
+        }
+        
+        // Return the converted file.
+        return buffer.toString();
+    }
+    
+    private static final String toTextFormat(IHistogram2D plot) {
+        // Create a buffer to hold the converted plot.
+        StringBuffer buffer = new StringBuffer();
+        
+        // Iterate over the bins and output the plot in the format of
+        // "[X_BIN_MEAN] [Y_BIN_MEAN] [BIN_VALUE]" with a tab delimiter.
+        for(int xBin = 0; xBin < plot.xAxis().bins(); xBin++) {
+            for(int yBin = 0; yBin < plot.yAxis().bins(); yBin++) {
+                buffer.append(String.format("%f\t%f\t%f%n", plot.binMeanX(xBin, yBin), plot.binMeanY(xBin, yBin), plot.binHeight(xBin, yBin)));
+            }
+        }
+        
+        // Return the converted file.
+        return buffer.toString();
+    }
 }

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/plots/PlotsFormatter.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/plots/PlotsFormatter.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/plots/PlotsFormatter.java	Wed Apr 27 11:11:32 2016
@@ -8,120 +8,120 @@
 import java.awt.Font;
 
 public class PlotsFormatter {
-	// Define plot fonts.
-	public static final Font BASIC_FONT = new Font("Calibri", Font.PLAIN, 30);
-	public static final Font AXIS_FONT  = new Font("Calibri", Font.BOLD,  35);
-	public static final Font TITLE_FONT = new Font("Calibri", Font.BOLD,  45);
-	
-	// Defines the color style options for plot data.
-	public static enum ColorStyle {
-		 MS_BLUE(new Color( 79, 129, 189), new Color( 36,  64,  97)), MS_ORANGE(new Color(247, 150,  70), new Color(152,  72,   6)),
-		  MS_RED(new Color(192,  80,  77), new Color( 99,  36,  35)),      GREY(new Color(166, 166, 166), new Color( 89,  89,  89)),
-		MS_GREEN(new Color(155, 187,  89), new Color( 79,  98,  40)),   CRIMSON(new Color(161,   0,   0), new Color(104,   0,   0)),
-		    RUST(new Color(161,  80,   0), new Color(105,  80,   0)),    YELLOW(new Color(161, 161,   0), new Color(122, 109,   8)),
-		  FOREST(new Color( 65, 102,   0), new Color( 37,  79,   0)),     GREEN(new Color(  7, 132,  70), new Color(  7,  82,  30)),
-		    TEAL(new Color(  0, 130, 130), new Color(  0,  90, 100)),  CERULEAN(new Color(  0,  86, 130), new Color(  0,  28,  83)),
-		    BLUE(new Color(  0,  33, 203), new Color(  0,   0, 137)),    INDIGO(new Color( 68,  10, 127), new Color(  0,   0,  61)),
-		  PURPLE(new Color(106,   0, 106), new Color( 63,   0,  56)),   FUSCHIA(new Color(119,   0,  60), new Color( 60,   0,  60));
-		
-		private final Color fillColor;
-		private final Color lineColor;
-		
-		private ColorStyle(Color fillColor, Color lineColor) {
-			this.fillColor = fillColor;
-			this.lineColor = lineColor;
-		}
-		
-		public Color getFillColor() { return fillColor; }
-		
-		public Color getLineColor() { return lineColor; }
-	};
-	
-	/**
-	 * Sets the plot display formatting for 1D plots.
-	 * @param region - The plotter region to format.
-	 * @param color - The data color settings to use.
-	 */
-	public static final void setDefault1DStyle(PlotterRegion region, ColorStyle[] color) {
-		// Get the names of each plot on in the region.
-		String[] dataNames = region.getAllDataNames();
-		
-		// Check whether this is an overlay plot. Overlay plots contain
-		// more than one data name.
-		boolean overlay = (dataNames.length > 1 ? true : false);
-		
-		// Iterate over each plot in the region.
-		for(int i = 0; i < dataNames.length; i++) {
-			// Set the overlay style if needed.
-			if(overlay) {
-				// Get the fill style for the current data type.
-				JASHist1DHistogramStyle fillStyle = (JASHist1DHistogramStyle) region.getDataForName(dataNames[i]).getStyle();
-				
-				// Set the histogram style to display thick-lined bars
-				// with no fill. The color is set by the "color" argument.
-				fillStyle.setHistogramFill(false);
-				fillStyle.setHistogramBarLineWidth(3);
-				fillStyle.setHistogramBarLineColor(color[i].getFillColor());
-				
-				// Set the legend text style.
-				region.getPlot().getLegend().setFont(new Font("Calibri", Font.PLAIN, 20));
-			}
-			
-			// Otherwise, set the fill style for a single plot.
-			else {
-				// Get the fill style for the current data type.
-				JASHist1DHistogramStyle fillStyle = (JASHist1DHistogramStyle) region.getDataForName(dataNames[i]).getStyle();
-				
-				// Set the histogram style to display thick-lined bars
-				// with a fill color. The colors are defined by the
-				// "color" argument.
-				fillStyle.setHistogramBarLineWidth(3);
-				fillStyle.setHistogramBarColor(color[i].getFillColor());
-				fillStyle.setHistogramBarLineColor(color[i].getLineColor());
-			}
-			
-			// Set the statistics box style.
-			region.getPlot().getStats().setVisible(true);
-			region.getPlot().getStats().setFont(BASIC_FONT);
-			
-			// Set the title font.
-			region.getPlot().getTitleObject().setFont(TITLE_FONT);
-			
-			// Set the axis tick-mark fonts.
-			region.getPlot().getXAxis().setFont(BASIC_FONT);
-			region.getPlot().getYAxis().setFont(BASIC_FONT);
-			region.getPlot().getXAxis().getLabelObject().setFont(AXIS_FONT);
-			region.getPlot().getYAxis().getLabelObject().setFont(AXIS_FONT);
-		}
-	}
-	
-	/**
-	 * Sets the plot display formatting for 1D plots.
-	 * @param region - The plotter region to format.
-	 */
-	public static final void setDefault2DStyle(PlotterRegion region, boolean logarithmic) {
-		// Get the fill style object. 2D plots should never be overlay
-		// plots, so there should only ever be one data name.
-		JASHist2DHistogramStyle fillStyle = (JASHist2DHistogramStyle) region.getDataForName(region.getAllDataNames()[0]).getStyle();
-		
-		// Set the fill style for a two-dimensional plot.
-		if(logarithmic) { fillStyle.setLogZ(true); }
-		fillStyle.setHistStyle(JASHist2DHistogramStyle.STYLE_COLORMAP);
-		fillStyle.setColorMapScheme(JASHist2DHistogramStyle.COLORMAP_RAINBOW);
-		
-		// Make the statistics box invisible.
-		region.getPlot().getStats().setVisible(false);
-		
-		// Set the general plot font (which is also the z-axis font).
-		region.getPlot().setFont(BASIC_FONT);
-		
-		// Set the title font.
-		region.getPlot().getTitleObject().setFont(TITLE_FONT);
-		
-		// Set the axis tick-mark fonts.
-		region.getPlot().getXAxis().setFont(BASIC_FONT);
-		region.getPlot().getYAxis().setFont(BASIC_FONT);
-		region.getPlot().getXAxis().getLabelObject().setFont(AXIS_FONT);
-		region.getPlot().getYAxis().getLabelObject().setFont(AXIS_FONT);
-	}
+    // Define plot fonts.
+    public static final Font BASIC_FONT = new Font("Calibri", Font.PLAIN, 30);
+    public static final Font AXIS_FONT  = new Font("Calibri", Font.BOLD,  35);
+    public static final Font TITLE_FONT = new Font("Calibri", Font.BOLD,  45);
+    
+    // Defines the color style options for plot data.
+    public static enum ColorStyle {
+         MS_BLUE(new Color( 79, 129, 189), new Color( 36,  64,  97)), MS_ORANGE(new Color(247, 150,  70), new Color(152,  72,   6)),
+          MS_RED(new Color(192,  80,  77), new Color( 99,  36,  35)),      GREY(new Color(166, 166, 166), new Color( 89,  89,  89)),
+        MS_GREEN(new Color(155, 187,  89), new Color( 79,  98,  40)),   CRIMSON(new Color(161,   0,   0), new Color(104,   0,   0)),
+            RUST(new Color(161,  80,   0), new Color(105,  80,   0)),    YELLOW(new Color(161, 161,   0), new Color(122, 109,   8)),
+          FOREST(new Color( 65, 102,   0), new Color( 37,  79,   0)),     GREEN(new Color(  7, 132,  70), new Color(  7,  82,  30)),
+            TEAL(new Color(  0, 130, 130), new Color(  0,  90, 100)),  CERULEAN(new Color(  0,  86, 130), new Color(  0,  28,  83)),
+            BLUE(new Color(  0,  33, 203), new Color(  0,   0, 137)),    INDIGO(new Color( 68,  10, 127), new Color(  0,   0,  61)),
+          PURPLE(new Color(106,   0, 106), new Color( 63,   0,  56)),   FUSCHIA(new Color(119,   0,  60), new Color( 60,   0,  60));
+        
+        private final Color fillColor;
+        private final Color lineColor;
+        
+        private ColorStyle(Color fillColor, Color lineColor) {
+            this.fillColor = fillColor;
+            this.lineColor = lineColor;
+        }
+        
+        public Color getFillColor() { return fillColor; }
+        
+        public Color getLineColor() { return lineColor; }
+    };
+    
+    /**
+     * Sets the plot display formatting for 1D plots.
+     * @param region - The plotter region to format.
+     * @param color - The data color settings to use.
+     */
+    public static final void setDefault1DStyle(PlotterRegion region, ColorStyle[] color) {
+        // Get the names of each plot on in the region.
+        String[] dataNames = region.getAllDataNames();
+        
+        // Check whether this is an overlay plot. Overlay plots contain
+        // more than one data name.
+        boolean overlay = (dataNames.length > 1 ? true : false);
+        
+        // Iterate over each plot in the region.
+        for(int i = 0; i < dataNames.length; i++) {
+            // Set the overlay style if needed.
+            if(overlay) {
+                // Get the fill style for the current data type.
+                JASHist1DHistogramStyle fillStyle = (JASHist1DHistogramStyle) region.getDataForName(dataNames[i]).getStyle();
+                
+                // Set the histogram style to display thick-lined bars
+                // with no fill. The color is set by the "color" argument.
+                fillStyle.setHistogramFill(false);
+                fillStyle.setHistogramBarLineWidth(3);
+                fillStyle.setHistogramBarLineColor(color[i].getFillColor());
+                
+                // Set the legend text style.
+                region.getPlot().getLegend().setFont(new Font("Calibri", Font.PLAIN, 20));
+            }
+            
+            // Otherwise, set the fill style for a single plot.
+            else {
+                // Get the fill style for the current data type.
+                JASHist1DHistogramStyle fillStyle = (JASHist1DHistogramStyle) region.getDataForName(dataNames[i]).getStyle();
+                
+                // Set the histogram style to display thick-lined bars
+                // with a fill color. The colors are defined by the
+                // "color" argument.
+                fillStyle.setHistogramBarLineWidth(3);
+                fillStyle.setHistogramBarColor(color[i].getFillColor());
+                fillStyle.setHistogramBarLineColor(color[i].getLineColor());
+            }
+            
+            // Set the statistics box style.
+            region.getPlot().getStats().setVisible(true);
+            region.getPlot().getStats().setFont(BASIC_FONT);
+            
+            // Set the title font.
+            region.getPlot().getTitleObject().setFont(TITLE_FONT);
+            
+            // Set the axis tick-mark fonts.
+            region.getPlot().getXAxis().setFont(BASIC_FONT);
+            region.getPlot().getYAxis().setFont(BASIC_FONT);
+            region.getPlot().getXAxis().getLabelObject().setFont(AXIS_FONT);
+            region.getPlot().getYAxis().getLabelObject().setFont(AXIS_FONT);
+        }
+    }
+    
+    /**
+     * Sets the plot display formatting for 1D plots.
+     * @param region - The plotter region to format.
+     */
+    public static final void setDefault2DStyle(PlotterRegion region, boolean logarithmic) {
+        // Get the fill style object. 2D plots should never be overlay
+        // plots, so there should only ever be one data name.
+        JASHist2DHistogramStyle fillStyle = (JASHist2DHistogramStyle) region.getDataForName(region.getAllDataNames()[0]).getStyle();
+        
+        // Set the fill style for a two-dimensional plot.
+        if(logarithmic) { fillStyle.setLogZ(true); }
+        fillStyle.setHistStyle(JASHist2DHistogramStyle.STYLE_COLORMAP);
+        fillStyle.setColorMapScheme(JASHist2DHistogramStyle.COLORMAP_RAINBOW);
+        
+        // Make the statistics box invisible.
+        region.getPlot().getStats().setVisible(false);
+        
+        // Set the general plot font (which is also the z-axis font).
+        region.getPlot().setFont(BASIC_FONT);
+        
+        // Set the title font.
+        region.getPlot().getTitleObject().setFont(TITLE_FONT);
+        
+        // Set the axis tick-mark fonts.
+        region.getPlot().getXAxis().setFont(BASIC_FONT);
+        region.getPlot().getYAxis().setFont(BASIC_FONT);
+        region.getPlot().getXAxis().getLabelObject().setFont(AXIS_FONT);
+        region.getPlot().getYAxis().getLabelObject().setFont(AXIS_FONT);
+    }
 }

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/plots/formatter/InvariantMassPlotsFormatter.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/plots/formatter/InvariantMassPlotsFormatter.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/plots/formatter/InvariantMassPlotsFormatter.java	Wed Apr 27 11:11:32 2016
@@ -19,317 +19,317 @@
 import hep.aida.ref.plotter.PlotterRegion;
 
 public class InvariantMassPlotsFormatter {
-	// Define plot fonts.
-	private static final Font BASIC_FONT = new Font("Calibri", Font.PLAIN, 20);
-	private static final Font AXIS_FONT  = new Font("Calibri", Font.BOLD,  25);
-	private static final Font TITLE_FONT = new Font("Calibri", Font.BOLD,  35);
-	
-	// Defines the color style options for plot data.
-	private enum ColorStyle {
-		 MS_BLUE(new Color( 79, 129, 189), new Color( 36,  64,  97)), MS_ORANGE(new Color(247, 150,  70), new Color(152,  72,   6)),
-		  MS_RED(new Color(192,  80,  77), new Color( 99,  36,  35)),      GREY(new Color(166, 166, 166), new Color( 89,  89,  89)),
-		MS_GREEN(new Color(155, 187,  89), new Color( 79,  98,  40)),   CRIMSON(new Color(161,   0,   0), new Color(104,   0,   0)),
-		    RUST(new Color(161,  80,   0), new Color(105,  80,   0)),    YELLOW(new Color(161, 161,   0), new Color(122, 109,   8)),
-		  FOREST(new Color( 65, 102,   0), new Color( 37,  79,   0)),     GREEN(new Color(  7, 132,  70), new Color(  7,  82,  30)),
-		    TEAL(new Color(  0, 130, 130), new Color(  0,  90, 100)),  CERULEAN(new Color(  0,  86, 130), new Color(  0,  28,  83)),
-		    BLUE(new Color(  0,  33, 203), new Color(  0,   0, 137)),    INDIGO(new Color( 68,  10, 127), new Color(  0,   0,  61)),
-		  PURPLE(new Color(106,   0, 106), new Color( 63,   0,  56)),   FUSCHIA(new Color(119,   0,  60), new Color( 60,   0,  60));
-		
-		private final Color fillColor;
-		private final Color lineColor;
-		
-		private ColorStyle(Color fillColor, Color lineColor) {
-			this.fillColor = fillColor;
-			this.lineColor = lineColor;
-		}
-		
-		public Color getFillColor() { return fillColor; }
-		
-		public Color getLineColor() { return lineColor; }
-	};
-		
-	/**
-	 * Loads all plots in a file and formats them according to the
-	 * indicated style.
-	 * @param args - Unused default executable parameter.
-	 * @throws IOException Occurs if there is an issue opening the file.
-	 */
-	public static void main(String[] args) throws IOException {
-		// Define the root directory for the plots.
-		String rootDir = "D:\\cygwin64\\home\\Kyle\\";
-		
-		// Define the new name of the file containing the trigger plots.
-		String[] plotFile = {
-				rootDir + "temp.aida"
-		};
-		
-		// Define the run numbers for each file.
-		String[] runNumber = { "1 Hits", "2 Hits" };
-		
-		// Define the scaling factors for each plot.
-		double scaleFactor = 13.254;
-		
-		// Get the plots file and open it.
-		IAnalysisFactory af = IAnalysisFactory.create();
-		ITree[] tree = new ITree[plotFile.length];
-		for(int i = 0; i < plotFile.length; i++) {
-			tree[i] = af.createTreeFactory().create(plotFile[i]);
-			if(tree[i] == null) { throw new IllegalArgumentException("Unable to load plot file."); }
-		}
-		
-		// Get the histograms.
-		IHistogram1D[] invariantMassPlots = new IHistogram1D[3];
-		invariantMassPlots[0] = (IHistogram1D) tree[0].find("Trident Analysis/Particle Invariant Mass (1 Hit)");
-		invariantMassPlots[1] = (IHistogram1D) tree[0].find("Trident Analysis/Particle Invariant Mass (2 Hit)");
-		IHistogram1D electronEnergyPlot = (IHistogram1D) tree[0].find("Trident Analysis/Electron Energy");
-		IHistogram1D positronEnergyPlot = (IHistogram1D) tree[0].find("Trident Analysis/Positron Energy");
-		IHistogram1D energySumPlot = (IHistogram1D) tree[0].find("Trident Analysis/Energy Sum Distribution");
-		IHistogram2D energySum2DPlot = (IHistogram2D) tree[0].find("Trident Analysis/2D Energy Distribution");
-		IHistogram1D tridentElectronEnergyPlot = (IHistogram1D) tree[0].find("Trident Analysis/Trident Electron Energy");
-		IHistogram1D tridentPositronEnergyPlot = (IHistogram1D) tree[0].find("Trident Analysis/Trident Positron Energy");
-		
-		// Define the plot titles and arrays.
-		IHistogram[] plots = { electronEnergyPlot, positronEnergyPlot, energySumPlot, tridentElectronEnergyPlot, tridentPositronEnergyPlot };
-		String[] titles = { "Electron Energy", "Positron Energy", "Energy Sum", "Trident Electron Energy", "Trident Positron Energy" };
-		String[] xTitles = { "Energy (GeV)", "Energy (GeV)", "Energy Sum (GeV)", "Energy (GeV)", "Energy (GeV)" };
-		
-		// Re-bin the histograms to have 5-times larger bins. First,
-		// get the bin count and upper and lower bounds of the plot.
-		int bins = invariantMassPlots[0].axis().bins();
-		double low = invariantMassPlots[0].axis().binLowerEdge(0);
-		double high = invariantMassPlots[0].axis().binUpperEdge(invariantMassPlots[0].axis().bins() - 1);
-		
-		// Create new plots with the larger bin sizes.
-		AIDA aida = AIDA.defaultInstance();
-		IHistogram1D[] newPlot = new IHistogram1D[2];
-		newPlot[0] = aida.histogram1D("Particle Invariant Mass (1 Hit)", bins / 5, low, high);
-		newPlot[1] = aida.histogram1D("Particle Invariant Mass (2 Hit)", bins / 5, low, high);
-		
-		// Populate the new plots with the data from the old ones.
-		for(int j = 0; j < 2; j++) {
-			for(int i = 0; i < bins; i++) {
-				int entries = invariantMassPlots[j].binEntries(i);
-				double center = invariantMassPlots[j].axis().binCenter(i);
-				for(int k = 0; k < entries; k++) {
-					newPlot[j].fill(center);
-				}
-			}
-		}
-		
-		// Replace the old plots.
-		invariantMassPlots = newPlot;
-		
-		// Create a plotter factory.
-		IPlotterFactory plotterFactory = af.createPlotterFactory();
-		
-		// Format and display the basic histograms.
-		for(int i = 0; i < plots.length; i++) {
-			// Scale the histogram by the appropriate scaling factor.
-			plots[i].scale(1.0 / scaleFactor);
-			
-			// Create a plotter and plotting region for the plot.
-			IPlotter plotter = plotterFactory.create(titles[i]);
-			plotter.createRegions(1);
-			plotter.region(0).plot(plots[i]);
-			
-			// Format the axis labels.
-			PlotterRegion region = (PlotterRegion) plotter.region(0);
-			region.getPlot().setTitle(titles[i]);
-			region.getPlot().getXAxis().setLabel(xTitles[i]);
-			region.getPlot().getYAxis().setLabel("Rate (Hz)");
-			
-			// Format the fonts and general plot presentation.
-			setDefault1DStyle(region, new ColorStyle[] { ColorStyle.GREY });
-			
-			// Show the plot.
-			plotter.setParameter("plotterWidth", "2000");
-			plotter.setParameter("plotterHeight", "1200");
-			plotter.show();
-		}
-		
-		// Format and display the 2D histogram.
-		energySum2DPlot.scale(1.0 / scaleFactor);
-		IPlotter plotter2D = plotterFactory.create("2D Energy Sum");
-		plotter2D.createRegions(1);
-		plotter2D.region(0).plot(energySum2DPlot);
-		
-		// Format the axis labels.
-		PlotterRegion region2D = (PlotterRegion) plotter2D.region(0);
-		region2D.getPlot().setTitle("2D Energy Sum");
-		region2D.getPlot().getXAxis().setLabel("Electron Energy (GeV)");
-		region2D.getPlot().getYAxis().setLabel("Positron Energy (GeV)");
-		
-		// Format the fonts and general plot presentation.
-		setDefault2DStyle(region2D, false);
-		
-		// Show the plot.
-		plotter2D.setParameter("plotterWidth", "2000");
-		plotter2D.setParameter("plotterHeight", "1200");
-		plotter2D.show();
-		
-		// Format and display the histograms.
-		for(int i = 0; i < 2; i++) {
-			// Scale the histogram by the appropriate scaling factor.
-			invariantMassPlots[i].scale(1.0 / scaleFactor);
-			
-			// Create a plotter and plotting region for the plot.
-			IPlotter plotter = plotterFactory.create("Particle Invariant Mass (" + runNumber[i] + ")");
-			plotter.createRegions(1);
-			plotter.region(0).plot(invariantMassPlots[i]);
-			
-			// Format the axis labels.
-			PlotterRegion region = (PlotterRegion) plotter.region(0);
-			region.getPlot().setTitle("Particle Invariant Mass (" + runNumber[i] + ")");
-			region.getPlot().getXAxis().setLabel("Invariant Mass (GeV)");
-			region.getPlot().getYAxis().setLabel("Rate (Hz)");
-			
-			// Format the fonts and general plot presentation.
-			setDefault1DStyle(region, new ColorStyle[] { ColorStyle.GREY });
-			
-			// Show the plot.
-			plotter.setParameter("plotterWidth", "2000");
-			plotter.setParameter("plotterHeight", "1200");
-			plotter.show();
-		}
-		
-		// Note which plot is the numerator and which is the denominator.
-		int numerator   = 0;
-		int denominator = 1;
-		
-		// Create a new histogram to display the ratios of the rates.
-		IHistogram1D ratioPlot = AIDA.defaultInstance().histogram1D("Invariant Mass Ratio (" + runNumber[numerator] + " / "
-				+ runNumber[denominator] + ")", invariantMassPlots[0].axis().bins(),
-				invariantMassPlots[0].axis().lowerEdge(), invariantMassPlots[0].axis().upperEdge());
-		
-		// Iterate over each bin.
-		for(int bin = 0; bin < invariantMassPlots[0].axis().bins(); bin++) {
-			// Calculate the ratio.
-			double ratio = invariantMassPlots[numerator].binHeight(bin) / invariantMassPlots[denominator].binHeight(bin);
-			
-			// If the ratio is either not a number of infinite, skip
-			// this bin.
-			if(Double.isNaN(ratio) || Double.isInfinite(ratio)) { continue; }
-			
-			// Populate the ratio plot bin.
-			ratioPlot.fill(invariantMassPlots[0].axis().binCenter(bin), ratio);
-		}
-		
-		// Create a plotter and plotting region for the plot.
-		IPlotter plotter = plotterFactory.create("Invariant Mass Ratio (5411 / 5554)");
-		plotter.createRegions(1);
-		plotter.region(0).plot(ratioPlot);
-		
-		// Format the axis labels.
-		PlotterRegion region = (PlotterRegion) plotter.region(0);
-		region.getPlot().setTitle("Invariant Mass Ratio (" + runNumber[numerator] + " / " + runNumber[denominator] + ")");
-		region.getPlot().getXAxis().setLabel("Invariant Mass (GeV)");
-		region.getPlot().getXAxis().setMin(0.010);
-		region.getPlot().getXAxis().setMax(0.060);
-		region.getPlot().getYAxis().setLabel("Ratio");
-		
-		// Format the fonts and general plot presentation.
-		setDefault1DStyle(region, new ColorStyle[] { ColorStyle.GREY });
-		
-		// Disable the error bars.
-		JASHist1DHistogramStyle fillStyle = (JASHist1DHistogramStyle) region.getDataForName(region.getAllDataNames()[0]).getStyle();
-		fillStyle.setShowErrorBars(false);
-		
-		// Show the plot.
-		plotter.setParameter("plotterWidth", "2000");
-		plotter.setParameter("plotterHeight", "1200");
-		plotter.show();
-		
-		// Close the trees.
-		for(int i = 0; i < plotFile.length; i++) {
-			tree[i].close();
-		}
-	}
-	
-	/**
-	 * Sets the plot display formatting for 1D plots.
-	 * @param region - The plotter region to format.
-	 * @param color - The data color settings to use.
-	 */
-	private static final void setDefault1DStyle(PlotterRegion region, ColorStyle[] color) {
-		// Get the names of each plot on in the region.
-		String[] dataNames = region.getAllDataNames();
-		
-		// Check whether this is an overlay plot. Overlay plots contain
-		// more than one data name.
-		boolean overlay = (dataNames.length > 1 ? true : false);
-		
-		// Iterate over each plot in the region.
-		for(int i = 0; i < dataNames.length; i++) {
-			// Set the overlay style if needed.
-			if(overlay) {
-				// Get the fill style for the current data type.
-				JASHist1DHistogramStyle fillStyle = (JASHist1DHistogramStyle) region.getDataForName(dataNames[i]).getStyle();
-				
-				// Set the histogram style to display thick-lined bars
-				// with no fill. The color is set by the "color" argument.
-				fillStyle.setHistogramFill(false);
-				fillStyle.setHistogramBarLineWidth(3);
-				fillStyle.setHistogramBarLineColor(color[i].getFillColor());
-				
-				// Set the legend text style.
-				region.getPlot().getLegend().setFont(new Font("Calibri", Font.PLAIN, 20));
-			}
-			
-			// Otherwise, set the fill style for a single plot.
-			else {
-				// Get the fill style for the current data type.
-				JASHist1DHistogramStyle fillStyle = (JASHist1DHistogramStyle) region.getDataForName(dataNames[i]).getStyle();
-				
-				// Set the histogram style to display thick-lined bars
-				// with a fill color. The colors are defined by the
-				// "color" argument.
-				fillStyle.setHistogramBarLineWidth(3);
-				fillStyle.setHistogramBarColor(color[i].getFillColor());
-				fillStyle.setHistogramBarLineColor(color[i].getLineColor());
-			}
-			
-			// Set the statistics box style.
-			region.getPlot().getStats().setVisible(true);
-			region.getPlot().getStats().setFont(BASIC_FONT);
-			
-			// Set the title font.
-			region.getPlot().getTitleObject().setFont(TITLE_FONT);
-			
-			// Set the axis tick-mark fonts.
-			region.getPlot().getXAxis().setFont(BASIC_FONT);
-			region.getPlot().getYAxis().setFont(BASIC_FONT);
-			region.getPlot().getXAxis().getLabelObject().setFont(AXIS_FONT);
-			region.getPlot().getYAxis().getLabelObject().setFont(AXIS_FONT);
-		}
-	}
-	
-	/**
-	 * Sets the plot display formatting for 1D plots.
-	 * @param region - The plotter region to format.
-	 */
-	private static final void setDefault2DStyle(PlotterRegion region, boolean logarithmic) {
-		// Get the fill style object. 2D plots should never be overlay
-		// plots, so there should only ever be one data name.
-		JASHist2DHistogramStyle fillStyle = (JASHist2DHistogramStyle) region.getDataForName(region.getAllDataNames()[0]).getStyle();
-		
-		// Set the fill style for a two-dimensional plot.
-		if(logarithmic) { fillStyle.setLogZ(true); }
-		fillStyle.setHistStyle(JASHist2DHistogramStyle.STYLE_COLORMAP);
-		fillStyle.setColorMapScheme(JASHist2DHistogramStyle.COLORMAP_RAINBOW);
-		
-		// Make the statistics box invisible.
-		region.getPlot().getStats().setVisible(false);
-		
-		// Set the general plot font (which is also the z-axis font).
-		region.getPlot().setFont(BASIC_FONT);
-		
-		// Set the title font.
-		region.getPlot().getTitleObject().setFont(TITLE_FONT);
-		
-		// Set the axis tick-mark fonts.
-		region.getPlot().getXAxis().setFont(BASIC_FONT);
-		region.getPlot().getYAxis().setFont(BASIC_FONT);
-		region.getPlot().getXAxis().getLabelObject().setFont(AXIS_FONT);
-		region.getPlot().getYAxis().getLabelObject().setFont(AXIS_FONT);
-	}
+    // Define plot fonts.
+    private static final Font BASIC_FONT = new Font("Calibri", Font.PLAIN, 20);
+    private static final Font AXIS_FONT  = new Font("Calibri", Font.BOLD,  25);
+    private static final Font TITLE_FONT = new Font("Calibri", Font.BOLD,  35);
+    
+    // Defines the color style options for plot data.
+    private enum ColorStyle {
+         MS_BLUE(new Color( 79, 129, 189), new Color( 36,  64,  97)), MS_ORANGE(new Color(247, 150,  70), new Color(152,  72,   6)),
+          MS_RED(new Color(192,  80,  77), new Color( 99,  36,  35)),      GREY(new Color(166, 166, 166), new Color( 89,  89,  89)),
+        MS_GREEN(new Color(155, 187,  89), new Color( 79,  98,  40)),   CRIMSON(new Color(161,   0,   0), new Color(104,   0,   0)),
+            RUST(new Color(161,  80,   0), new Color(105,  80,   0)),    YELLOW(new Color(161, 161,   0), new Color(122, 109,   8)),
+          FOREST(new Color( 65, 102,   0), new Color( 37,  79,   0)),     GREEN(new Color(  7, 132,  70), new Color(  7,  82,  30)),
+            TEAL(new Color(  0, 130, 130), new Color(  0,  90, 100)),  CERULEAN(new Color(  0,  86, 130), new Color(  0,  28,  83)),
+            BLUE(new Color(  0,  33, 203), new Color(  0,   0, 137)),    INDIGO(new Color( 68,  10, 127), new Color(  0,   0,  61)),
+          PURPLE(new Color(106,   0, 106), new Color( 63,   0,  56)),   FUSCHIA(new Color(119,   0,  60), new Color( 60,   0,  60));
+        
+        private final Color fillColor;
+        private final Color lineColor;
+        
+        private ColorStyle(Color fillColor, Color lineColor) {
+            this.fillColor = fillColor;
+            this.lineColor = lineColor;
+        }
+        
+        public Color getFillColor() { return fillColor; }
+        
+        public Color getLineColor() { return lineColor; }
+    };
+        
+    /**
+     * Loads all plots in a file and formats them according to the
+     * indicated style.
+     * @param args - Unused default executable parameter.
+     * @throws IOException Occurs if there is an issue opening the file.
+     */
+    public static void main(String[] args) throws IOException {
+        // Define the root directory for the plots.
+        String rootDir = "D:\\cygwin64\\home\\Kyle\\";
+        
+        // Define the new name of the file containing the trigger plots.
+        String[] plotFile = {
+                rootDir + "temp.aida"
+        };
+        
+        // Define the run numbers for each file.
+        String[] runNumber = { "1 Hits", "2 Hits" };
+        
+        // Define the scaling factors for each plot.
+        double scaleFactor = 13.254;
+        
+        // Get the plots file and open it.
+        IAnalysisFactory af = IAnalysisFactory.create();
+        ITree[] tree = new ITree[plotFile.length];
+        for(int i = 0; i < plotFile.length; i++) {
+            tree[i] = af.createTreeFactory().create(plotFile[i]);
+            if(tree[i] == null) { throw new IllegalArgumentException("Unable to load plot file."); }
+        }
+        
+        // Get the histograms.
+        IHistogram1D[] invariantMassPlots = new IHistogram1D[3];
+        invariantMassPlots[0] = (IHistogram1D) tree[0].find("Trident Analysis/Particle Invariant Mass (1 Hit)");
+        invariantMassPlots[1] = (IHistogram1D) tree[0].find("Trident Analysis/Particle Invariant Mass (2 Hit)");
+        IHistogram1D electronEnergyPlot = (IHistogram1D) tree[0].find("Trident Analysis/Electron Energy");
+        IHistogram1D positronEnergyPlot = (IHistogram1D) tree[0].find("Trident Analysis/Positron Energy");
+        IHistogram1D energySumPlot = (IHistogram1D) tree[0].find("Trident Analysis/Energy Sum Distribution");
+        IHistogram2D energySum2DPlot = (IHistogram2D) tree[0].find("Trident Analysis/2D Energy Distribution");
+        IHistogram1D tridentElectronEnergyPlot = (IHistogram1D) tree[0].find("Trident Analysis/Trident Electron Energy");
+        IHistogram1D tridentPositronEnergyPlot = (IHistogram1D) tree[0].find("Trident Analysis/Trident Positron Energy");
+        
+        // Define the plot titles and arrays.
+        IHistogram[] plots = { electronEnergyPlot, positronEnergyPlot, energySumPlot, tridentElectronEnergyPlot, tridentPositronEnergyPlot };
+        String[] titles = { "Electron Energy", "Positron Energy", "Energy Sum", "Trident Electron Energy", "Trident Positron Energy" };
+        String[] xTitles = { "Energy (GeV)", "Energy (GeV)", "Energy Sum (GeV)", "Energy (GeV)", "Energy (GeV)" };
+        
+        // Re-bin the histograms to have 5-times larger bins. First,
+        // get the bin count and upper and lower bounds of the plot.
+        int bins = invariantMassPlots[0].axis().bins();
+        double low = invariantMassPlots[0].axis().binLowerEdge(0);
+        double high = invariantMassPlots[0].axis().binUpperEdge(invariantMassPlots[0].axis().bins() - 1);
+        
+        // Create new plots with the larger bin sizes.
+        AIDA aida = AIDA.defaultInstance();
+        IHistogram1D[] newPlot = new IHistogram1D[2];
+        newPlot[0] = aida.histogram1D("Particle Invariant Mass (1 Hit)", bins / 5, low, high);
+        newPlot[1] = aida.histogram1D("Particle Invariant Mass (2 Hit)", bins / 5, low, high);
+        
+        // Populate the new plots with the data from the old ones.
+        for(int j = 0; j < 2; j++) {
+            for(int i = 0; i < bins; i++) {
+                int entries = invariantMassPlots[j].binEntries(i);
+                double center = invariantMassPlots[j].axis().binCenter(i);
+                for(int k = 0; k < entries; k++) {
+                    newPlot[j].fill(center);
+                }
+            }
+        }
+        
+        // Replace the old plots.
+        invariantMassPlots = newPlot;
+        
+        // Create a plotter factory.
+        IPlotterFactory plotterFactory = af.createPlotterFactory();
+        
+        // Format and display the basic histograms.
+        for(int i = 0; i < plots.length; i++) {
+            // Scale the histogram by the appropriate scaling factor.
+            plots[i].scale(1.0 / scaleFactor);
+            
+            // Create a plotter and plotting region for the plot.
+            IPlotter plotter = plotterFactory.create(titles[i]);
+            plotter.createRegions(1);
+            plotter.region(0).plot(plots[i]);
+            
+            // Format the axis labels.
+            PlotterRegion region = (PlotterRegion) plotter.region(0);
+            region.getPlot().setTitle(titles[i]);
+            region.getPlot().getXAxis().setLabel(xTitles[i]);
+            region.getPlot().getYAxis().setLabel("Rate (Hz)");
+            
+            // Format the fonts and general plot presentation.
+            setDefault1DStyle(region, new ColorStyle[] { ColorStyle.GREY });
+            
+            // Show the plot.
+            plotter.setParameter("plotterWidth", "2000");
+            plotter.setParameter("plotterHeight", "1200");
+            plotter.show();
+        }
+        
+        // Format and display the 2D histogram.
+        energySum2DPlot.scale(1.0 / scaleFactor);
+        IPlotter plotter2D = plotterFactory.create("2D Energy Sum");
+        plotter2D.createRegions(1);
+        plotter2D.region(0).plot(energySum2DPlot);
+        
+        // Format the axis labels.
+        PlotterRegion region2D = (PlotterRegion) plotter2D.region(0);
+        region2D.getPlot().setTitle("2D Energy Sum");
+        region2D.getPlot().getXAxis().setLabel("Electron Energy (GeV)");
+        region2D.getPlot().getYAxis().setLabel("Positron Energy (GeV)");
+        
+        // Format the fonts and general plot presentation.
+        setDefault2DStyle(region2D, false);
+        
+        // Show the plot.
+        plotter2D.setParameter("plotterWidth", "2000");
+        plotter2D.setParameter("plotterHeight", "1200");
+        plotter2D.show();
+        
+        // Format and display the histograms.
+        for(int i = 0; i < 2; i++) {
+            // Scale the histogram by the appropriate scaling factor.
+            invariantMassPlots[i].scale(1.0 / scaleFactor);
+            
+            // Create a plotter and plotting region for the plot.
+            IPlotter plotter = plotterFactory.create("Particle Invariant Mass (" + runNumber[i] + ")");
+            plotter.createRegions(1);
+            plotter.region(0).plot(invariantMassPlots[i]);
+            
+            // Format the axis labels.
+            PlotterRegion region = (PlotterRegion) plotter.region(0);
+            region.getPlot().setTitle("Particle Invariant Mass (" + runNumber[i] + ")");
+            region.getPlot().getXAxis().setLabel("Invariant Mass (GeV)");
+            region.getPlot().getYAxis().setLabel("Rate (Hz)");
+            
+            // Format the fonts and general plot presentation.
+            setDefault1DStyle(region, new ColorStyle[] { ColorStyle.GREY });
+            
+            // Show the plot.
+            plotter.setParameter("plotterWidth", "2000");
+            plotter.setParameter("plotterHeight", "1200");
+            plotter.show();
+        }
+        
+        // Note which plot is the numerator and which is the denominator.
+        int numerator   = 0;
+        int denominator = 1;
+        
+        // Create a new histogram to display the ratios of the rates.
+        IHistogram1D ratioPlot = AIDA.defaultInstance().histogram1D("Invariant Mass Ratio (" + runNumber[numerator] + " / "
+                + runNumber[denominator] + ")", invariantMassPlots[0].axis().bins(),
+                invariantMassPlots[0].axis().lowerEdge(), invariantMassPlots[0].axis().upperEdge());
+        
+        // Iterate over each bin.
+        for(int bin = 0; bin < invariantMassPlots[0].axis().bins(); bin++) {
+            // Calculate the ratio.
+            double ratio = invariantMassPlots[numerator].binHeight(bin) / invariantMassPlots[denominator].binHeight(bin);
+            
+            // If the ratio is either not a number of infinite, skip
+            // this bin.
+            if(Double.isNaN(ratio) || Double.isInfinite(ratio)) { continue; }
+            
+            // Populate the ratio plot bin.
+            ratioPlot.fill(invariantMassPlots[0].axis().binCenter(bin), ratio);
+        }
+        
+        // Create a plotter and plotting region for the plot.
+        IPlotter plotter = plotterFactory.create("Invariant Mass Ratio (5411 / 5554)");
+        plotter.createRegions(1);
+        plotter.region(0).plot(ratioPlot);
+        
+        // Format the axis labels.
+        PlotterRegion region = (PlotterRegion) plotter.region(0);
+        region.getPlot().setTitle("Invariant Mass Ratio (" + runNumber[numerator] + " / " + runNumber[denominator] + ")");
+        region.getPlot().getXAxis().setLabel("Invariant Mass (GeV)");
+        region.getPlot().getXAxis().setMin(0.010);
+        region.getPlot().getXAxis().setMax(0.060);
+        region.getPlot().getYAxis().setLabel("Ratio");
+        
+        // Format the fonts and general plot presentation.
+        setDefault1DStyle(region, new ColorStyle[] { ColorStyle.GREY });
+        
+        // Disable the error bars.
+        JASHist1DHistogramStyle fillStyle = (JASHist1DHistogramStyle) region.getDataForName(region.getAllDataNames()[0]).getStyle();
+        fillStyle.setShowErrorBars(false);
+        
+        // Show the plot.
+        plotter.setParameter("plotterWidth", "2000");
+        plotter.setParameter("plotterHeight", "1200");
+        plotter.show();
+        
+        // Close the trees.
+        for(int i = 0; i < plotFile.length; i++) {
+            tree[i].close();
+        }
+    }
+    
+    /**
+     * Sets the plot display formatting for 1D plots.
+     * @param region - The plotter region to format.
+     * @param color - The data color settings to use.
+     */
+    private static final void setDefault1DStyle(PlotterRegion region, ColorStyle[] color) {
+        // Get the names of each plot on in the region.
+        String[] dataNames = region.getAllDataNames();
+        
+        // Check whether this is an overlay plot. Overlay plots contain
+        // more than one data name.
+        boolean overlay = (dataNames.length > 1 ? true : false);
+        
+        // Iterate over each plot in the region.
+        for(int i = 0; i < dataNames.length; i++) {
+            // Set the overlay style if needed.
+            if(overlay) {
+                // Get the fill style for the current data type.
+                JASHist1DHistogramStyle fillStyle = (JASHist1DHistogramStyle) region.getDataForName(dataNames[i]).getStyle();
+                
+                // Set the histogram style to display thick-lined bars
+                // with no fill. The color is set by the "color" argument.
+                fillStyle.setHistogramFill(false);
+                fillStyle.setHistogramBarLineWidth(3);
+                fillStyle.setHistogramBarLineColor(color[i].getFillColor());
+                
+                // Set the legend text style.
+                region.getPlot().getLegend().setFont(new Font("Calibri", Font.PLAIN, 20));
+            }
+            
+            // Otherwise, set the fill style for a single plot.
+            else {
+                // Get the fill style for the current data type.
+                JASHist1DHistogramStyle fillStyle = (JASHist1DHistogramStyle) region.getDataForName(dataNames[i]).getStyle();
+                
+                // Set the histogram style to display thick-lined bars
+                // with a fill color. The colors are defined by the
+                // "color" argument.
+                fillStyle.setHistogramBarLineWidth(3);
+                fillStyle.setHistogramBarColor(color[i].getFillColor());
+                fillStyle.setHistogramBarLineColor(color[i].getLineColor());
+            }
+            
+            // Set the statistics box style.
+            region.getPlot().getStats().setVisible(true);
+            region.getPlot().getStats().setFont(BASIC_FONT);
+            
+            // Set the title font.
+            region.getPlot().getTitleObject().setFont(TITLE_FONT);
+            
+            // Set the axis tick-mark fonts.
+            region.getPlot().getXAxis().setFont(BASIC_FONT);
+            region.getPlot().getYAxis().setFont(BASIC_FONT);
+            region.getPlot().getXAxis().getLabelObject().setFont(AXIS_FONT);
+            region.getPlot().getYAxis().getLabelObject().setFont(AXIS_FONT);
+        }
+    }
+    
+    /**
+     * Sets the plot display formatting for 1D plots.
+     * @param region - The plotter region to format.
+     */
+    private static final void setDefault2DStyle(PlotterRegion region, boolean logarithmic) {
+        // Get the fill style object. 2D plots should never be overlay
+        // plots, so there should only ever be one data name.
+        JASHist2DHistogramStyle fillStyle = (JASHist2DHistogramStyle) region.getDataForName(region.getAllDataNames()[0]).getStyle();
+        
+        // Set the fill style for a two-dimensional plot.
+        if(logarithmic) { fillStyle.setLogZ(true); }
+        fillStyle.setHistStyle(JASHist2DHistogramStyle.STYLE_COLORMAP);
+        fillStyle.setColorMapScheme(JASHist2DHistogramStyle.COLORMAP_RAINBOW);
+        
+        // Make the statistics box invisible.
+        region.getPlot().getStats().setVisible(false);
+        
+        // Set the general plot font (which is also the z-axis font).
+        region.getPlot().setFont(BASIC_FONT);
+        
+        // Set the title font.
+        region.getPlot().getTitleObject().setFont(TITLE_FONT);
+        
+        // Set the axis tick-mark fonts.
+        region.getPlot().getXAxis().setFont(BASIC_FONT);
+        region.getPlot().getYAxis().setFont(BASIC_FONT);
+        region.getPlot().getXAxis().getLabelObject().setFont(AXIS_FONT);
+        region.getPlot().getYAxis().getLabelObject().setFont(AXIS_FONT);
+    }
 }

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/plots/formatter/MTEPlotFormatter.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/plots/formatter/MTEPlotFormatter.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/plots/formatter/MTEPlotFormatter.java	Wed Apr 27 11:11:32 2016
@@ -19,308 +19,308 @@
 import hep.aida.ref.plotter.PlotterRegion;
 
 public class MTEPlotFormatter {
-	// Define plot fonts.
-	private static final Font BASIC_FONT = new Font("Calibri", Font.PLAIN, 20);
-	private static final Font AXIS_FONT  = new Font("Calibri", Font.BOLD,  25);
-	private static final Font TITLE_FONT = new Font("Calibri", Font.BOLD,  35);
-	
-	// Defines the color style options for plot data.
-	private enum ColorStyle {
-		 MS_BLUE(new Color( 79, 129, 189), new Color( 36,  64,  97)), MS_ORANGE(new Color(247, 150,  70), new Color(152,  72,   6)),
-		  MS_RED(new Color(192,  80,  77), new Color( 99,  36,  35)),      GREY(new Color(166, 166, 166), new Color( 89,  89,  89)),
-		MS_GREEN(new Color(155, 187,  89), new Color( 79,  98,  40)),   CRIMSON(new Color(161,   0,   0), new Color(104,   0,   0)),
-		    RUST(new Color(161,  80,   0), new Color(105,  80,   0)),    YELLOW(new Color(161, 161,   0), new Color(122, 109,   8)),
-		  FOREST(new Color( 65, 102,   0), new Color( 37,  79,   0)),     GREEN(new Color(  7, 132,  70), new Color(  7,  82,  30)),
-		    TEAL(new Color(  0, 130, 130), new Color(  0,  90, 100)),  CERULEAN(new Color(  0,  86, 130), new Color(  0,  28,  83)),
-		    BLUE(new Color(  0,  33, 203), new Color(  0,   0, 137)),    INDIGO(new Color( 68,  10, 127), new Color(  0,   0,  61)),
-		  PURPLE(new Color(106,   0, 106), new Color( 63,   0,  56)),   FUSCHIA(new Color(119,   0,  60), new Color( 60,   0,  60));
-		
-		private final Color fillColor;
-		private final Color lineColor;
-		
-		private ColorStyle(Color fillColor, Color lineColor) {
-			this.fillColor = fillColor;
-			this.lineColor = lineColor;
-		}
-		
-		public Color getFillColor() { return fillColor; }
-		
-		public Color getLineColor() { return lineColor; }
-	};
-		
-	/**
-	 * Loads all plots in a file and formats them according to the
-	 * indicated style.
-	 * @param args - Unused default executable parameter.
-	 * @throws IOException Occurs if there is an issue opening the file.
-	 */
-	public static void main(String[] args) throws IOException {
-		// Define the root directory for the plots.
-		String rootDir = "D:\\cygwin64\\home\\Kyle\\";
-		
-		// Define the new name of the file containing the trigger plots.
-		String plotFile = rootDir + "temp.aida";
-		
-		// Define the scaling factors for each plot.
-		double scaleFactor = 1;
-		
-		// Get the plots file and open it.
-		IAnalysisFactory af = IAnalysisFactory.create();
-		ITree tree = af.createTreeFactory().create(plotFile);
-		if(tree == null) { throw new IllegalArgumentException("Unable to load plot file."); }
-		
-		// Define index references for each event type.
-		int MOLLER  = 0;
-		int TRIDENT = 1;
-		int ELASTIC = 2;
-		
-		// Get the histograms.
-		IHistogram1D[] trackCountPlots = new IHistogram1D[3];
-		trackCountPlots[MOLLER]  = (IHistogram1D) tree.find("MTE Analysis/Møller Event Tracks");
-		trackCountPlots[TRIDENT] = (IHistogram1D) tree.find("MTE Analysis/Trident Event Tracks");
-		trackCountPlots[ELASTIC] = (IHistogram1D) tree.find("MTE Analysis/Elastic Event Tracks");
-		
-		IHistogram1D[] energyPlots = new IHistogram1D[3];
-		energyPlots[MOLLER]  = (IHistogram1D) tree.find("MTE Analysis/Møller Electron Energy Distribution");
-		energyPlots[TRIDENT] = (IHistogram1D) tree.find("MTE Analysis/Trident Electron Energy Distribution");
-		energyPlots[ELASTIC] = (IHistogram1D) tree.find("MTE Analysis/Elastic Energy Distribution");
-		
-		IHistogram1D[] energySumPlots = new IHistogram1D[2];
-		energySumPlots[MOLLER]  = (IHistogram1D) tree.find("MTE Analysis/Møller Energy Sum Distribution");
-		energySumPlots[TRIDENT] = (IHistogram1D) tree.find("MTE Analysis/Trident Energy Sum Distribution");
-		
-		IHistogram2D[] energy2DPlots = new IHistogram2D[2];
-		energy2DPlots[MOLLER]  = (IHistogram2D) tree.find("MTE Analysis/Møller 2D Energy Distribution");
-		energy2DPlots[TRIDENT] = (IHistogram2D) tree.find("MTE Analysis/Trident 2D Energy Distribution");
-		
-		// Create a plotter factory.
-		IPlotterFactory plotterFactory = af.createPlotterFactory();
-		
-		// Format the track count plots.
-		for(IHistogram1D trackCountPlot : trackCountPlots) {
-			// Create a plotter and plotting region for the plot.
-			IPlotter plotter = plotterFactory.create(trackCountPlot.title());
-			plotter.createRegions(1);
-			plotter.region(0).plot(trackCountPlot);
-			
-			// Format the axis labels.
-			PlotterRegion region = (PlotterRegion) plotter.region(0);
-			region.getPlot().setTitle(trackCountPlot.title());
-			region.getPlot().getXAxis().setLabel("Number of Tracks");
-			region.getPlot().getYAxis().setLabel("Count");
-			
-			// Format the fonts and general plot presentation.
-			setDefault1DStyle(region, new ColorStyle[] { ColorStyle.GREY });
-			
-			// Show the plot.
-			plotter.setParameter("plotterWidth", "2000");
-			plotter.setParameter("plotterHeight", "1200");
-			plotter.show();
-		}
-		
-		// Format the electron energy plots.
-		for(IHistogram1D energyPlot : energyPlots) {
-			// Create a plotter and plotting region for the plot.
-			IPlotter plotter = plotterFactory.create(energyPlot.title());
-			plotter.createRegions(1);
-			plotter.region(0).plot(energyPlot);
-			
-			// Format the axis labels.
-			PlotterRegion region = (PlotterRegion) plotter.region(0);
-			region.getPlot().setTitle(energyPlot.title());
-			region.getPlot().getXAxis().setLabel("Track Energy (GeV)");
-			region.getPlot().getYAxis().setLabel("Count");
-			
-			// Format the fonts and general plot presentation.
-			setDefault1DStyle(region, new ColorStyle[] { ColorStyle.GREY });
-			
-			// Show the plot.
-			plotter.setParameter("plotterWidth", "2000");
-			plotter.setParameter("plotterHeight", "1200");
-			plotter.show();
-		}
-		
-		// Format the energy sum plots.
-		for(IHistogram1D energySumPlot : energySumPlots) {
-			// Create a plotter and plotting region for the plot.
-			IPlotter plotter = plotterFactory.create(energySumPlot.title());
-			plotter.createRegions(1);
-			plotter.region(0).plot(energySumPlot);
-			
-			// Format the axis labels.
-			PlotterRegion region = (PlotterRegion) plotter.region(0);
-			region.getPlot().setTitle(energySumPlot.title());
-			region.getPlot().getXAxis().setLabel("Track Energy (GeV)");
-			region.getPlot().getYAxis().setLabel("Count");
-			
-			// Format the fonts and general plot presentation.
-			setDefault1DStyle(region, new ColorStyle[] { ColorStyle.GREY });
-			
-			// Show the plot.
-			plotter.setParameter("plotterWidth", "2000");
-			plotter.setParameter("plotterHeight", "1200");
-			plotter.show();
-		}
-		
-		// Format the 2D energy sum plots.
-		for(IHistogram2D energy2DPlot : energy2DPlots) {
-			// Create a plotter and plotting region for the plot.
-			IPlotter plotter = plotterFactory.create(energy2DPlot.title());
-			plotter.createRegions(1);
-			plotter.region(0).plot(energy2DPlot);
-			
-			// Format the axis labels.
-			PlotterRegion region = (PlotterRegion) plotter.region(0);
-			region.getPlot().setTitle(energy2DPlot.title());
-			region.getPlot().getXAxis().setLabel("First Track Energy (GeV)");
-			region.getPlot().getYAxis().setLabel("Second Track Energy (GeV)");
-			
-			
-			// Format the fonts and general plot presentation.
-			setDefault2DStyle(region, false);
-			
-			// Show the plot.
-			plotter.setParameter("plotterWidth", "2000");
-			plotter.setParameter("plotterHeight", "1200");
-			plotter.show();
-		}
-		
-		// Disable the error bars.
-		//JASHist1DHistogramStyle fillStyle = (JASHist1DHistogramStyle) region.getDataForName(region.getAllDataNames()[0]).getStyle();
-		//fillStyle.setShowErrorBars(false);
-		
-		// Close the tree.
-		tree.close();
-	}
-	
-	/**
-	 * Sets the plot display formatting for 1D plots.
-	 * @param region - The plotter region to format.
-	 * @param color - The data color settings to use.
-	 */
-	private static final void setDefault1DStyle(PlotterRegion region, ColorStyle[] color) {
-		// Get the names of each plot on in the region.
-		String[] dataNames = region.getAllDataNames();
-		
-		// Check whether this is an overlay plot. Overlay plots contain
-		// more than one data name.
-		boolean overlay = (dataNames.length > 1 ? true : false);
-		
-		// Iterate over each plot in the region.
-		for(int i = 0; i < dataNames.length; i++) {
-			// Set the overlay style if needed.
-			if(overlay) {
-				// Get the fill style for the current data type.
-				JASHist1DHistogramStyle fillStyle = (JASHist1DHistogramStyle) region.getDataForName(dataNames[i]).getStyle();
-				
-				// Set the histogram style to display thick-lined bars
-				// with no fill. The color is set by the "color" argument.
-				fillStyle.setHistogramFill(false);
-				fillStyle.setHistogramBarLineWidth(3);
-				fillStyle.setHistogramBarLineColor(color[i].getFillColor());
-				
-				// Set the legend text style.
-				region.getPlot().getLegend().setFont(new Font("Calibri", Font.PLAIN, 20));
-			}
-			
-			// Otherwise, set the fill style for a single plot.
-			else {
-				// Get the fill style for the current data type.
-				JASHist1DHistogramStyle fillStyle = (JASHist1DHistogramStyle) region.getDataForName(dataNames[i]).getStyle();
-				
-				// Set the histogram style to display thick-lined bars
-				// with a fill color. The colors are defined by the
-				// "color" argument.
-				fillStyle.setHistogramBarLineWidth(3);
-				fillStyle.setHistogramBarColor(color[i].getFillColor());
-				fillStyle.setHistogramBarLineColor(color[i].getLineColor());
-			}
-			
-			// Set the statistics box style.
-			region.getPlot().getStats().setVisible(true);
-			region.getPlot().getStats().setFont(BASIC_FONT);
-			
-			// Set the title font.
-			region.getPlot().getTitleObject().setFont(TITLE_FONT);
-			
-			// Set the axis tick-mark fonts.
-			region.getPlot().getXAxis().setFont(BASIC_FONT);
-			region.getPlot().getYAxis().setFont(BASIC_FONT);
-			region.getPlot().getXAxis().getLabelObject().setFont(AXIS_FONT);
-			region.getPlot().getYAxis().getLabelObject().setFont(AXIS_FONT);
-		}
-	}
-	
-	/**
-	 * Sets the plot display formatting for 1D plots.
-	 * @param region - The plotter region to format.
-	 */
-	private static final void setDefault2DStyle(PlotterRegion region, boolean logarithmic) {
-		// Get the fill style object. 2D plots should never be overlay
-		// plots, so there should only ever be one data name.
-		JASHist2DHistogramStyle fillStyle = (JASHist2DHistogramStyle) region.getDataForName(region.getAllDataNames()[0]).getStyle();
-		
-		// Set the fill style for a two-dimensional plot.
-		if(logarithmic) { fillStyle.setLogZ(true); }
-		fillStyle.setHistStyle(JASHist2DHistogramStyle.STYLE_COLORMAP);
-		fillStyle.setColorMapScheme(JASHist2DHistogramStyle.COLORMAP_RAINBOW);
-		
-		// Make the statistics box invisible.
-		region.getPlot().getStats().setVisible(false);
-		
-		// Set the general plot font (which is also the z-axis font).
-		region.getPlot().setFont(BASIC_FONT);
-		
-		// Set the title font.
-		region.getPlot().getTitleObject().setFont(TITLE_FONT);
-		
-		// Set the axis tick-mark fonts.
-		region.getPlot().getXAxis().setFont(BASIC_FONT);
-		region.getPlot().getYAxis().setFont(BASIC_FONT);
-		region.getPlot().getXAxis().getLabelObject().setFont(AXIS_FONT);
-		region.getPlot().getYAxis().getLabelObject().setFont(AXIS_FONT);
-	}
-	
-	/**
-	 * Recursive method that gets all object names from a tree that
-	 * are not directories. Method should not be called directly, but
-	 * rather called only through the <code>getHistograms(ITree)</code>
-	 * method.
-	 * @param tree - The tree from which to obtain the object names.
-	 * @param directory - The directory in which to search for objects.
-	 * @param list - The list in which to place the objects.
-	 * @return Returns the <code>List</code> collection that was given
-	 * as an argument.
-	 */
-	private static final List<String> getHistograms(ITree tree, String directory, List<String> list) {
-		// Get the list of objects in the directory.
-		String[] treeObjects = tree.listObjectNames(directory);
-		
-		// Print the objects.
-		for(String objectName : treeObjects) {
-			// Check if the object is a directory.
-			boolean isDirectory = isDirectory(objectName);
-			
-			// If the object is a directory, get the histograms from it.
-			if(isDirectory) {
-				getHistograms(tree, objectName, list);
-			}
-			
-			// If the object is a plot, add it to the list.
-			else { list.add(objectName); }
-		}
-		
-		// Return the list.
-		return list;
-	}
-	
-	/**
-	 * Checks whether a tree object is a directory.
-	 * @param object - The object to check.
-	 * @return Returns <code>true</code> if the object is a directory
-	 * and <code>false</code> otherwise.
-	 */
-	private static final boolean isDirectory(String object) {
-		return (object.toCharArray()[object.length() - 1] == '/');
-	}
+    // Define plot fonts.
+    private static final Font BASIC_FONT = new Font("Calibri", Font.PLAIN, 20);
+    private static final Font AXIS_FONT  = new Font("Calibri", Font.BOLD,  25);
+    private static final Font TITLE_FONT = new Font("Calibri", Font.BOLD,  35);
+    
+    // Defines the color style options for plot data.
+    private enum ColorStyle {
+         MS_BLUE(new Color( 79, 129, 189), new Color( 36,  64,  97)), MS_ORANGE(new Color(247, 150,  70), new Color(152,  72,   6)),
+          MS_RED(new Color(192,  80,  77), new Color( 99,  36,  35)),      GREY(new Color(166, 166, 166), new Color( 89,  89,  89)),
+        MS_GREEN(new Color(155, 187,  89), new Color( 79,  98,  40)),   CRIMSON(new Color(161,   0,   0), new Color(104,   0,   0)),
+            RUST(new Color(161,  80,   0), new Color(105,  80,   0)),    YELLOW(new Color(161, 161,   0), new Color(122, 109,   8)),
+          FOREST(new Color( 65, 102,   0), new Color( 37,  79,   0)),     GREEN(new Color(  7, 132,  70), new Color(  7,  82,  30)),
+            TEAL(new Color(  0, 130, 130), new Color(  0,  90, 100)),  CERULEAN(new Color(  0,  86, 130), new Color(  0,  28,  83)),
+            BLUE(new Color(  0,  33, 203), new Color(  0,   0, 137)),    INDIGO(new Color( 68,  10, 127), new Color(  0,   0,  61)),
+          PURPLE(new Color(106,   0, 106), new Color( 63,   0,  56)),   FUSCHIA(new Color(119,   0,  60), new Color( 60,   0,  60));
+        
+        private final Color fillColor;
+        private final Color lineColor;
+        
+        private ColorStyle(Color fillColor, Color lineColor) {
+            this.fillColor = fillColor;
+            this.lineColor = lineColor;
+        }
+        
+        public Color getFillColor() { return fillColor; }
+        
+        public Color getLineColor() { return lineColor; }
+    };
+        
+    /**
+     * Loads all plots in a file and formats them according to the
+     * indicated style.
+     * @param args - Unused default executable parameter.
+     * @throws IOException Occurs if there is an issue opening the file.
+     */
+    public static void main(String[] args) throws IOException {
+        // Define the root directory for the plots.
+        String rootDir = "D:\\cygwin64\\home\\Kyle\\";
+        
+        // Define the new name of the file containing the trigger plots.
+        String plotFile = rootDir + "temp.aida";
+        
+        // Define the scaling factors for each plot.
+        double scaleFactor = 1;
+        
+        // Get the plots file and open it.
+        IAnalysisFactory af = IAnalysisFactory.create();
+        ITree tree = af.createTreeFactory().create(plotFile);
+        if(tree == null) { throw new IllegalArgumentException("Unable to load plot file."); }
+        
+        // Define index references for each event type.
+        int MOLLER  = 0;
+        int TRIDENT = 1;
+        int ELASTIC = 2;
+        
+        // Get the histograms.
+        IHistogram1D[] trackCountPlots = new IHistogram1D[3];
+        trackCountPlots[MOLLER]  = (IHistogram1D) tree.find("MTE Analysis/Møller Event Tracks");
+        trackCountPlots[TRIDENT] = (IHistogram1D) tree.find("MTE Analysis/Trident Event Tracks");
+        trackCountPlots[ELASTIC] = (IHistogram1D) tree.find("MTE Analysis/Elastic Event Tracks");
+        
+        IHistogram1D[] energyPlots = new IHistogram1D[3];
+        energyPlots[MOLLER]  = (IHistogram1D) tree.find("MTE Analysis/Møller Electron Energy Distribution");
+        energyPlots[TRIDENT] = (IHistogram1D) tree.find("MTE Analysis/Trident Electron Energy Distribution");
+        energyPlots[ELASTIC] = (IHistogram1D) tree.find("MTE Analysis/Elastic Energy Distribution");
+        
+        IHistogram1D[] energySumPlots = new IHistogram1D[2];
+        energySumPlots[MOLLER]  = (IHistogram1D) tree.find("MTE Analysis/Møller Energy Sum Distribution");
+        energySumPlots[TRIDENT] = (IHistogram1D) tree.find("MTE Analysis/Trident Energy Sum Distribution");
+        
+        IHistogram2D[] energy2DPlots = new IHistogram2D[2];
+        energy2DPlots[MOLLER]  = (IHistogram2D) tree.find("MTE Analysis/Møller 2D Energy Distribution");
+        energy2DPlots[TRIDENT] = (IHistogram2D) tree.find("MTE Analysis/Trident 2D Energy Distribution");
+        
+        // Create a plotter factory.
+        IPlotterFactory plotterFactory = af.createPlotterFactory();
+        
+        // Format the track count plots.
+        for(IHistogram1D trackCountPlot : trackCountPlots) {
+            // Create a plotter and plotting region for the plot.
+            IPlotter plotter = plotterFactory.create(trackCountPlot.title());
+            plotter.createRegions(1);
+            plotter.region(0).plot(trackCountPlot);
+            
+            // Format the axis labels.
+            PlotterRegion region = (PlotterRegion) plotter.region(0);
+            region.getPlot().setTitle(trackCountPlot.title());
+            region.getPlot().getXAxis().setLabel("Number of Tracks");
+            region.getPlot().getYAxis().setLabel("Count");
+            
+            // Format the fonts and general plot presentation.
+            setDefault1DStyle(region, new ColorStyle[] { ColorStyle.GREY });
+            
+            // Show the plot.
+            plotter.setParameter("plotterWidth", "2000");
+            plotter.setParameter("plotterHeight", "1200");
+            plotter.show();
+        }
+        
+        // Format the electron energy plots.
+        for(IHistogram1D energyPlot : energyPlots) {
+            // Create a plotter and plotting region for the plot.
+            IPlotter plotter = plotterFactory.create(energyPlot.title());
+            plotter.createRegions(1);
+            plotter.region(0).plot(energyPlot);
+            
+            // Format the axis labels.
+            PlotterRegion region = (PlotterRegion) plotter.region(0);
+            region.getPlot().setTitle(energyPlot.title());
+            region.getPlot().getXAxis().setLabel("Track Energy (GeV)");
+            region.getPlot().getYAxis().setLabel("Count");
+            
+            // Format the fonts and general plot presentation.
+            setDefault1DStyle(region, new ColorStyle[] { ColorStyle.GREY });
+            
+            // Show the plot.
+            plotter.setParameter("plotterWidth", "2000");
+            plotter.setParameter("plotterHeight", "1200");
+            plotter.show();
+        }
+        
+        // Format the energy sum plots.
+        for(IHistogram1D energySumPlot : energySumPlots) {
+            // Create a plotter and plotting region for the plot.
+            IPlotter plotter = plotterFactory.create(energySumPlot.title());
+            plotter.createRegions(1);
+            plotter.region(0).plot(energySumPlot);
+            
+            // Format the axis labels.
+            PlotterRegion region = (PlotterRegion) plotter.region(0);
+            region.getPlot().setTitle(energySumPlot.title());
+            region.getPlot().getXAxis().setLabel("Track Energy (GeV)");
+            region.getPlot().getYAxis().setLabel("Count");
+            
+            // Format the fonts and general plot presentation.
+            setDefault1DStyle(region, new ColorStyle[] { ColorStyle.GREY });
+            
+            // Show the plot.
+            plotter.setParameter("plotterWidth", "2000");
+            plotter.setParameter("plotterHeight", "1200");
+            plotter.show();
+        }
+        
+        // Format the 2D energy sum plots.
+        for(IHistogram2D energy2DPlot : energy2DPlots) {
+            // Create a plotter and plotting region for the plot.
+            IPlotter plotter = plotterFactory.create(energy2DPlot.title());
+            plotter.createRegions(1);
+            plotter.region(0).plot(energy2DPlot);
+            
+            // Format the axis labels.
+            PlotterRegion region = (PlotterRegion) plotter.region(0);
+            region.getPlot().setTitle(energy2DPlot.title());
+            region.getPlot().getXAxis().setLabel("First Track Energy (GeV)");
+            region.getPlot().getYAxis().setLabel("Second Track Energy (GeV)");
+            
+            
+            // Format the fonts and general plot presentation.
+            setDefault2DStyle(region, false);
+            
+            // Show the plot.
+            plotter.setParameter("plotterWidth", "2000");
+            plotter.setParameter("plotterHeight", "1200");
+            plotter.show();
+        }
+        
+        // Disable the error bars.
+        //JASHist1DHistogramStyle fillStyle = (JASHist1DHistogramStyle) region.getDataForName(region.getAllDataNames()[0]).getStyle();
+        //fillStyle.setShowErrorBars(false);
+        
+        // Close the tree.
+        tree.close();
+    }
+    
+    /**
+     * Sets the plot display formatting for 1D plots.
+     * @param region - The plotter region to format.
+     * @param color - The data color settings to use.
+     */
+    private static final void setDefault1DStyle(PlotterRegion region, ColorStyle[] color) {
+        // Get the names of each plot on in the region.
+        String[] dataNames = region.getAllDataNames();
+        
+        // Check whether this is an overlay plot. Overlay plots contain
+        // more than one data name.
+        boolean overlay = (dataNames.length > 1 ? true : false);
+        
+        // Iterate over each plot in the region.
+        for(int i = 0; i < dataNames.length; i++) {
+            // Set the overlay style if needed.
+            if(overlay) {
+                // Get the fill style for the current data type.
+                JASHist1DHistogramStyle fillStyle = (JASHist1DHistogramStyle) region.getDataForName(dataNames[i]).getStyle();
+                
+                // Set the histogram style to display thick-lined bars
+                // with no fill. The color is set by the "color" argument.
+                fillStyle.setHistogramFill(false);
+                fillStyle.setHistogramBarLineWidth(3);
+                fillStyle.setHistogramBarLineColor(color[i].getFillColor());
+                
+                // Set the legend text style.
+                region.getPlot().getLegend().setFont(new Font("Calibri", Font.PLAIN, 20));
+            }
+            
+            // Otherwise, set the fill style for a single plot.
+            else {
+                // Get the fill style for the current data type.
+                JASHist1DHistogramStyle fillStyle = (JASHist1DHistogramStyle) region.getDataForName(dataNames[i]).getStyle();
+                
+                // Set the histogram style to display thick-lined bars
+                // with a fill color. The colors are defined by the
+                // "color" argument.
+                fillStyle.setHistogramBarLineWidth(3);
+                fillStyle.setHistogramBarColor(color[i].getFillColor());
+                fillStyle.setHistogramBarLineColor(color[i].getLineColor());
+            }
+            
+            // Set the statistics box style.
+            region.getPlot().getStats().setVisible(true);
+            region.getPlot().getStats().setFont(BASIC_FONT);
+            
+            // Set the title font.
+            region.getPlot().getTitleObject().setFont(TITLE_FONT);
+            
+            // Set the axis tick-mark fonts.
+            region.getPlot().getXAxis().setFont(BASIC_FONT);
+            region.getPlot().getYAxis().setFont(BASIC_FONT);
+            region.getPlot().getXAxis().getLabelObject().setFont(AXIS_FONT);
+            region.getPlot().getYAxis().getLabelObject().setFont(AXIS_FONT);
+        }
+    }
+    
+    /**
+     * Sets the plot display formatting for 1D plots.
+     * @param region - The plotter region to format.
+     */
+    private static final void setDefault2DStyle(PlotterRegion region, boolean logarithmic) {
+        // Get the fill style object. 2D plots should never be overlay
+        // plots, so there should only ever be one data name.
+        JASHist2DHistogramStyle fillStyle = (JASHist2DHistogramStyle) region.getDataForName(region.getAllDataNames()[0]).getStyle();
+        
+        // Set the fill style for a two-dimensional plot.
+        if(logarithmic) { fillStyle.setLogZ(true); }
+        fillStyle.setHistStyle(JASHist2DHistogramStyle.STYLE_COLORMAP);
+        fillStyle.setColorMapScheme(JASHist2DHistogramStyle.COLORMAP_RAINBOW);
+        
+        // Make the statistics box invisible.
+        region.getPlot().getStats().setVisible(false);
+        
+        // Set the general plot font (which is also the z-axis font).
+        region.getPlot().setFont(BASIC_FONT);
+        
+        // Set the title font.
+        region.getPlot().getTitleObject().setFont(TITLE_FONT);
+        
+        // Set the axis tick-mark fonts.
+        region.getPlot().getXAxis().setFont(BASIC_FONT);
+        region.getPlot().getYAxis().setFont(BASIC_FONT);
+        region.getPlot().getXAxis().getLabelObject().setFont(AXIS_FONT);
+        region.getPlot().getYAxis().getLabelObject().setFont(AXIS_FONT);
+    }
+    
+    /**
+     * Recursive method that gets all object names from a tree that
+     * are not directories. Method should not be called directly, but
+     * rather called only through the <code>getHistograms(ITree)</code>
+     * method.
+     * @param tree - The tree from which to obtain the object names.
+     * @param directory - The directory in which to search for objects.
+     * @param list - The list in which to place the objects.
+     * @return Returns the <code>List</code> collection that was given
+     * as an argument.
+     */
+    private static final List<String> getHistograms(ITree tree, String directory, List<String> list) {
+        // Get the list of objects in the directory.
+        String[] treeObjects = tree.listObjectNames(directory);
+        
+        // Print the objects.
+        for(String objectName : treeObjects) {
+            // Check if the object is a directory.
+            boolean isDirectory = isDirectory(objectName);
+            
+            // If the object is a directory, get the histograms from it.
+            if(isDirectory) {
+                getHistograms(tree, objectName, list);
+            }
+            
+            // If the object is a plot, add it to the list.
+            else { list.add(objectName); }
+        }
+        
+        // Return the list.
+        return list;
+    }
+    
+    /**
+     * Checks whether a tree object is a directory.
+     * @param object - The object to check.
+     * @return Returns <code>true</code> if the object is a directory
+     * and <code>false</code> otherwise.
+     */
+    private static final boolean isDirectory(String object) {
+        return (object.toCharArray()[object.length() - 1] == '/');
+    }
 }

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/plots/formatter/MTETriggerPlotsFormatter.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/plots/formatter/MTETriggerPlotsFormatter.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/plots/formatter/MTETriggerPlotsFormatter.java	Wed Apr 27 11:11:32 2016
@@ -15,164 +15,164 @@
 
 
 public class MTETriggerPlotsFormatter {
-	public static void main(String[] args) throws IllegalArgumentException, IOException {
-		// Define the root directory for the plots.
-		String rootDir = "D:\\cygwin64\\home\\Kyle\\";
-		
-		// Define the new name of the file containing the trigger plots.
-		String plotFile = rootDir + "5772-ana.aida";
-		
-		// Get the plots file and open it.
-		IAnalysisFactory af = IAnalysisFactory.create();
-		ITree tree = af.createTreeFactory().create(plotFile);
-		if(tree == null) { throw new IllegalArgumentException("Unable to load plot file."); }
-		
-		// Define the 1D trigger plot names for Møllers and tridents.
-		String[] plotNames1D = { "Cluster Hit Count", "Cluster Seed Energy", "Cluster Total Energy",
-				"Pair Coplanarity", "Pair Energy Difference", "Pair Energy Slope", "Pair Energy Sum" };
-		String[] displayNames1D = { "Cluster Hit Count", "Cluster Seed Energy", "Cluster Total Energy",
-				"Pair Coplanarity", "Pair Energy Difference", "Pair Energy Slope", "Pair Energy Sum" };
-		String[] xAxisNames1D = { "Hit Count", "Seed Energy (GeV)", "Total Energy (GeV)",
-				"Coplanarity (Degrees)", "Energy Difference (GeV)", "Energy Slope (GeV)", "Energy Sum (GeV)" };
-		String yAxisName1D = "Count";
-		
-		// Define the 2D trigger plot names for Møllers and tridents.
-		String[] plotNames2D = { "Cluster Seed", "Pair Energy Sum 2D" };
-		String[] displayNames2D = { "Cluster Seed Distribution", "2D Energy Sum" };
-		String[] xAxisNames2D = { "x-Index", "Second Cluster Energy (GeV)" };
-		String[] yAxisNames2D = { "y-Index", "First Cluster Energy (GeV)" };
-		
-		// Define the 1D trigger plot names for elastics.
-		String[] plotNamesElastic1D = { "Cluster Hit Count", "Cluster Seed Energy", "Cluster Total Energy" };
-		String[] displayNamesElastic1D = { "Cluster Hit Count", "Cluster Seed Energy", "Cluster Total Energy" };
-		String[] xAxisNamesElastic1D = { "Hit Count", "Seed Energy (GeV)", "Total Energy (GeV)" };
-		String yAxisNameElastic1D = "Count";
-		
-		// Define the 2D trigger plot names for elastics.
-		String[] plotNamesElastic2D = { "Cluster Seed" };
-		String[] displayNamesElastic2D = { "Cluster Seed Distribution" };
-		String[] xAxisNamesElastic2D = { "x-Index" };
-		String[] yAxisNamesElastic2D = { "y-Index" };
-		
-		// Define the Møller, trident, and elastic prefixes.
-		String allPrefix = "All Trigger Plots/Pair Plots/";
-		String møllerPrefix = "Møller Trigger Plots/Pair Plots/";
-		String tridentPrefix = "Trident Trigger Plots/Pair Plots/";
-		String elasticPrefix = "Elastic Trigger Plots/Singles Plots/";
-		String allSinglesPrefix = "All Trigger Plots/Singles Plots/";
-		
-		// Define the plot type prefix.
-		String allTypeName = "All Pairs - ";
-		String møllerTypeName = "Møller - ";
-		String tridentTypeName = "Trident - ";
-		String elasticTypeName = "Elastic - ";
-		String allSinglesTypeName = "All Singles - ";
-		
-		// Define the plot type colors.
-		ColorStyle allColor = PlotsFormatter.ColorStyle.GREY;
-		ColorStyle møllerColor = PlotsFormatter.ColorStyle.MS_BLUE;
-		ColorStyle tridentColor = PlotsFormatter.ColorStyle.MS_ORANGE;
-		ColorStyle elasticColor = PlotsFormatter.ColorStyle.MS_GREEN;
-		
-		// Create a plot formatting module.
-		PlotFormatModule module = new PlotFormatModule();
-		
-		// Get the histograms and add them to the module. Start with the
-		// trident and Møller plots.
-		for(int i = 0; i < plotNames1D.length; i++) {
-			// Get the Møller and trident plots.
-			IHistogram1D allPlot = (IHistogram1D) tree.find(allPrefix + plotNames1D[i]);
-			IHistogram1D møllerPlot = (IHistogram1D) tree.find(møllerPrefix + plotNames1D[i]);
-			IHistogram1D tridentPlot = (IHistogram1D) tree.find(tridentPrefix + plotNames1D[i]);
-			
-			// Make a formatted plot for each.
-			FormattedPlot1D allFormattedPlot = new FormattedPlot1D(allPlot, allColor, xAxisNames1D[i], yAxisName1D, allTypeName + displayNames1D[i]);
-			FormattedPlot1D møllerFormattedPlot = new FormattedPlot1D(møllerPlot, møllerColor, xAxisNames1D[i], yAxisName1D, møllerTypeName + displayNames1D[i]);
-			FormattedPlot1D tridentFormattedPlot = new FormattedPlot1D(tridentPlot, tridentColor, xAxisNames1D[i], yAxisName1D, tridentTypeName + displayNames1D[i]);
-			
-			// Add them to the module.
-			module.addPlot1D(allFormattedPlot);
-			module.addPlot1D(møllerFormattedPlot);
-			module.addPlot1D(tridentFormattedPlot);
-		}
-		for(int i = 0; i < plotNames2D.length; i++) {
-			// Get the Møller and trident plots.
-			IHistogram2D allPlot = (IHistogram2D) tree.find(allPrefix + plotNames2D[i]);
-			IHistogram2D møllerPlot = (IHistogram2D) tree.find(møllerPrefix + plotNames2D[i]);
-			IHistogram2D tridentPlot = (IHistogram2D) tree.find(tridentPrefix + plotNames2D[i]);
-			
-			// Make a formatted plot for each.
-			FormattedPlot2D allFormattedPlot = new FormattedPlot2D(allPlot, i == 0 ? true : false, xAxisNames2D[i], yAxisNames2D[i], allTypeName + displayNames2D[i]);
-			FormattedPlot2D møllerFormattedPlot = new FormattedPlot2D(møllerPlot, i == 0 ? true : false, xAxisNames2D[i], yAxisNames2D[i], møllerTypeName + displayNames2D[i]);
-			FormattedPlot2D tridentFormattedPlot = new FormattedPlot2D(tridentPlot, i == 0 ? true : false, xAxisNames2D[i], yAxisNames2D[i], tridentTypeName + displayNames2D[i]);
-			
-			// Add them to the module.
-			module.addPlot2D(allFormattedPlot);
-			module.addPlot2D(møllerFormattedPlot);
-			module.addPlot2D(tridentFormattedPlot);
-		}
-		
-		// Get the histograms for the elastic plots and add them to the module.
-		for(int i = 0; i < plotNamesElastic1D.length; i++) {
-			// Get the Møller and trident plots.
-			IHistogram1D allPlot = (IHistogram1D) tree.find(allSinglesPrefix + plotNames1D[i]);
-			IHistogram1D elasticPlot = (IHistogram1D) tree.find(elasticPrefix + plotNames1D[i]);
-			
-			// Make a formatted plot for each.
-			FormattedPlot1D allFormattedPlot = new FormattedPlot1D(allPlot, allColor, xAxisNamesElastic1D[i], yAxisNameElastic1D,
-					allSinglesTypeName + displayNamesElastic1D[i]);
-			FormattedPlot1D elasticFormattedPlot = new FormattedPlot1D(elasticPlot, elasticColor, xAxisNamesElastic1D[i], yAxisNameElastic1D,
-					elasticTypeName + displayNamesElastic1D[i]);
-			
-			// Add them to the module.
-			module.addPlot1D(allFormattedPlot);
-			module.addPlot1D(elasticFormattedPlot);
-		}
-		for(int i = 0; i < plotNamesElastic2D.length; i++) {
-			// Get the Møller and trident plots.
-			IHistogram2D allPlot = (IHistogram2D) tree.find(allPrefix + plotNamesElastic2D[i]);
-			IHistogram2D elasticPlot = (IHistogram2D) tree.find(møllerPrefix + plotNamesElastic2D[i]);
-			
-			// Make a formatted plot for each.
-			FormattedPlot2D allFormattedPlot = new FormattedPlot2D(allPlot, i == 0 ? true : false, xAxisNamesElastic2D[i], yAxisNamesElastic2D[i],
-					allSinglesTypeName + plotNames2D[i]);
-			FormattedPlot2D elasticFormattedPlot = new FormattedPlot2D(elasticPlot, i == 0 ? true : false, xAxisNamesElastic2D[i], yAxisNamesElastic2D[i],
-					elasticTypeName + displayNamesElastic2D[i]);
-			
-			// Add them to the module.
-			module.addPlot2D(allFormattedPlot);
-			module.addPlot2D(elasticFormattedPlot);
-		}
-		
-		// Add the MTE plots to the module.
-		module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MTE Analysis/Elastic Energy Distribution"), elasticColor,
-				"Momentum (GeV)", "Count", "Elastic - Momentum"));
-		module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MTE Analysis/Elastic Event Tracks"), elasticColor,
-				"Tracks", "Count", "Elastic - Tracks in Event"));
-		
-		module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MTE Analysis/Møller Energy Sum Distribution"), møllerColor,
-				"Momentum Sum (GeV)", "Count", "Møller - Momentum Sum"));
-		module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MTE Analysis/Møller Electron Energy Distribution"), møllerColor,
-				"Momentum (GeV)", "Count", "Møller - Momentum (Electron)"));
-		module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MTE Analysis/Møller Time Coincidence Distribution (All Møller Cuts)"), møllerColor,
-				"Time (ns)", "Count", "Møller - Time Coincidence"));
-		module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MTE Analysis/Møller Event Tracks"), møllerColor,
-				"Tracks", "Count", "Møller - Tracks in Event"));
-		module.addPlot2D(new FormattedPlot2D((IHistogram2D) tree.find("MTE Analysis/Møller 2D Energy Distribution"), false,
-				"First Track Momentum (GeV)", "Second Track Momentum (GeV)", "Møller - 2D Momentum Sum"));
-		
-		module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MTE Analysis/Trident Energy Sum Distribution"), tridentColor,
-				"Momentum Sum (GeV)", "Count", "Trident - Momentum Sum"));
-		module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MTE Analysis/Trident Electron Energy Distribution"), tridentColor,
-				"Momentum (GeV)", "Count", "Trident - Momentum (Electron)"));
-		module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MTE Analysis/Trident Positron Energy Distribution"), tridentColor,
-				"Momentum (GeV)", "Count", "Trident - Momentum (Positron)"));
-		module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MTE Analysis/Trident Event Tracks"), tridentColor,
-				"Tracks", "Count", "Trident - Tracks in Event"));
-		module.addPlot2D(new FormattedPlot2D((IHistogram2D) tree.find("MTE Analysis/Trident 2D Energy Distribution"), false,
-				"First Track Momentum (GeV)", "Second Track Momentum (GeV)", "Trident - 2D Momentum Sum"));
-		
-		// Display the plots.
-		module.savePlots("C:\\Users\\Kyle\\Desktop\\EnergyShift\\TestPrint\\");
-	}
+    public static void main(String[] args) throws IllegalArgumentException, IOException {
+        // Define the root directory for the plots.
+        String rootDir = "D:\\cygwin64\\home\\Kyle\\";
+        
+        // Define the new name of the file containing the trigger plots.
+        String plotFile = rootDir + "5772-ana.aida";
+        
+        // Get the plots file and open it.
+        IAnalysisFactory af = IAnalysisFactory.create();
+        ITree tree = af.createTreeFactory().create(plotFile);
+        if(tree == null) { throw new IllegalArgumentException("Unable to load plot file."); }
+        
+        // Define the 1D trigger plot names for Møllers and tridents.
+        String[] plotNames1D = { "Cluster Hit Count", "Cluster Seed Energy", "Cluster Total Energy",
+                "Pair Coplanarity", "Pair Energy Difference", "Pair Energy Slope", "Pair Energy Sum" };
+        String[] displayNames1D = { "Cluster Hit Count", "Cluster Seed Energy", "Cluster Total Energy",
+                "Pair Coplanarity", "Pair Energy Difference", "Pair Energy Slope", "Pair Energy Sum" };
+        String[] xAxisNames1D = { "Hit Count", "Seed Energy (GeV)", "Total Energy (GeV)",
+                "Coplanarity (Degrees)", "Energy Difference (GeV)", "Energy Slope (GeV)", "Energy Sum (GeV)" };
+        String yAxisName1D = "Count";
+        
+        // Define the 2D trigger plot names for Møllers and tridents.
+        String[] plotNames2D = { "Cluster Seed", "Pair Energy Sum 2D" };
+        String[] displayNames2D = { "Cluster Seed Distribution", "2D Energy Sum" };
+        String[] xAxisNames2D = { "x-Index", "Second Cluster Energy (GeV)" };
+        String[] yAxisNames2D = { "y-Index", "First Cluster Energy (GeV)" };
+        
+        // Define the 1D trigger plot names for elastics.
+        String[] plotNamesElastic1D = { "Cluster Hit Count", "Cluster Seed Energy", "Cluster Total Energy" };
+        String[] displayNamesElastic1D = { "Cluster Hit Count", "Cluster Seed Energy", "Cluster Total Energy" };
+        String[] xAxisNamesElastic1D = { "Hit Count", "Seed Energy (GeV)", "Total Energy (GeV)" };
+        String yAxisNameElastic1D = "Count";
+        
+        // Define the 2D trigger plot names for elastics.
+        String[] plotNamesElastic2D = { "Cluster Seed" };
+        String[] displayNamesElastic2D = { "Cluster Seed Distribution" };
+        String[] xAxisNamesElastic2D = { "x-Index" };
+        String[] yAxisNamesElastic2D = { "y-Index" };
+        
+        // Define the Møller, trident, and elastic prefixes.
+        String allPrefix = "All Trigger Plots/Pair Plots/";
+        String møllerPrefix = "Møller Trigger Plots/Pair Plots/";
+        String tridentPrefix = "Trident Trigger Plots/Pair Plots/";
+        String elasticPrefix = "Elastic Trigger Plots/Singles Plots/";
+        String allSinglesPrefix = "All Trigger Plots/Singles Plots/";
+        
+        // Define the plot type prefix.
+        String allTypeName = "All Pairs - ";
+        String møllerTypeName = "Møller - ";
+        String tridentTypeName = "Trident - ";
+        String elasticTypeName = "Elastic - ";
+        String allSinglesTypeName = "All Singles - ";
+        
+        // Define the plot type colors.
+        ColorStyle allColor = PlotsFormatter.ColorStyle.GREY;
+        ColorStyle møllerColor = PlotsFormatter.ColorStyle.MS_BLUE;
+        ColorStyle tridentColor = PlotsFormatter.ColorStyle.MS_ORANGE;
+        ColorStyle elasticColor = PlotsFormatter.ColorStyle.MS_GREEN;
+        
+        // Create a plot formatting module.
+        PlotFormatModule module = new PlotFormatModule();
+        
+        // Get the histograms and add them to the module. Start with the
+        // trident and Møller plots.
+        for(int i = 0; i < plotNames1D.length; i++) {
+            // Get the Møller and trident plots.
+            IHistogram1D allPlot = (IHistogram1D) tree.find(allPrefix + plotNames1D[i]);
+            IHistogram1D møllerPlot = (IHistogram1D) tree.find(møllerPrefix + plotNames1D[i]);
+            IHistogram1D tridentPlot = (IHistogram1D) tree.find(tridentPrefix + plotNames1D[i]);
+            
+            // Make a formatted plot for each.
+            FormattedPlot1D allFormattedPlot = new FormattedPlot1D(allPlot, allColor, xAxisNames1D[i], yAxisName1D, allTypeName + displayNames1D[i]);
+            FormattedPlot1D møllerFormattedPlot = new FormattedPlot1D(møllerPlot, møllerColor, xAxisNames1D[i], yAxisName1D, møllerTypeName + displayNames1D[i]);
+            FormattedPlot1D tridentFormattedPlot = new FormattedPlot1D(tridentPlot, tridentColor, xAxisNames1D[i], yAxisName1D, tridentTypeName + displayNames1D[i]);
+            
+            // Add them to the module.
+            module.addPlot1D(allFormattedPlot);
+            module.addPlot1D(møllerFormattedPlot);
+            module.addPlot1D(tridentFormattedPlot);
+        }
+        for(int i = 0; i < plotNames2D.length; i++) {
+            // Get the Møller and trident plots.
+            IHistogram2D allPlot = (IHistogram2D) tree.find(allPrefix + plotNames2D[i]);
+            IHistogram2D møllerPlot = (IHistogram2D) tree.find(møllerPrefix + plotNames2D[i]);
+            IHistogram2D tridentPlot = (IHistogram2D) tree.find(tridentPrefix + plotNames2D[i]);
+            
+            // Make a formatted plot for each.
+            FormattedPlot2D allFormattedPlot = new FormattedPlot2D(allPlot, i == 0 ? true : false, xAxisNames2D[i], yAxisNames2D[i], allTypeName + displayNames2D[i]);
+            FormattedPlot2D møllerFormattedPlot = new FormattedPlot2D(møllerPlot, i == 0 ? true : false, xAxisNames2D[i], yAxisNames2D[i], møllerTypeName + displayNames2D[i]);
+            FormattedPlot2D tridentFormattedPlot = new FormattedPlot2D(tridentPlot, i == 0 ? true : false, xAxisNames2D[i], yAxisNames2D[i], tridentTypeName + displayNames2D[i]);
+            
+            // Add them to the module.
+            module.addPlot2D(allFormattedPlot);
+            module.addPlot2D(møllerFormattedPlot);
+            module.addPlot2D(tridentFormattedPlot);
+        }
+        
+        // Get the histograms for the elastic plots and add them to the module.
+        for(int i = 0; i < plotNamesElastic1D.length; i++) {
+            // Get the Møller and trident plots.
+            IHistogram1D allPlot = (IHistogram1D) tree.find(allSinglesPrefix + plotNames1D[i]);
+            IHistogram1D elasticPlot = (IHistogram1D) tree.find(elasticPrefix + plotNames1D[i]);
+            
+            // Make a formatted plot for each.
+            FormattedPlot1D allFormattedPlot = new FormattedPlot1D(allPlot, allColor, xAxisNamesElastic1D[i], yAxisNameElastic1D,
+                    allSinglesTypeName + displayNamesElastic1D[i]);
+            FormattedPlot1D elasticFormattedPlot = new FormattedPlot1D(elasticPlot, elasticColor, xAxisNamesElastic1D[i], yAxisNameElastic1D,
+                    elasticTypeName + displayNamesElastic1D[i]);
+            
+            // Add them to the module.
+            module.addPlot1D(allFormattedPlot);
+            module.addPlot1D(elasticFormattedPlot);
+        }
+        for(int i = 0; i < plotNamesElastic2D.length; i++) {
+            // Get the Møller and trident plots.
+            IHistogram2D allPlot = (IHistogram2D) tree.find(allPrefix + plotNamesElastic2D[i]);
+            IHistogram2D elasticPlot = (IHistogram2D) tree.find(møllerPrefix + plotNamesElastic2D[i]);
+            
+            // Make a formatted plot for each.
+            FormattedPlot2D allFormattedPlot = new FormattedPlot2D(allPlot, i == 0 ? true : false, xAxisNamesElastic2D[i], yAxisNamesElastic2D[i],
+                    allSinglesTypeName + plotNames2D[i]);
+            FormattedPlot2D elasticFormattedPlot = new FormattedPlot2D(elasticPlot, i == 0 ? true : false, xAxisNamesElastic2D[i], yAxisNamesElastic2D[i],
+                    elasticTypeName + displayNamesElastic2D[i]);
+            
+            // Add them to the module.
+            module.addPlot2D(allFormattedPlot);
+            module.addPlot2D(elasticFormattedPlot);
+        }
+        
+        // Add the MTE plots to the module.
+        module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MTE Analysis/Elastic Energy Distribution"), elasticColor,
+                "Momentum (GeV)", "Count", "Elastic - Momentum"));
+        module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MTE Analysis/Elastic Event Tracks"), elasticColor,
+                "Tracks", "Count", "Elastic - Tracks in Event"));
+        
+        module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MTE Analysis/Møller Energy Sum Distribution"), møllerColor,
+                "Momentum Sum (GeV)", "Count", "Møller - Momentum Sum"));
+        module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MTE Analysis/Møller Electron Energy Distribution"), møllerColor,
+                "Momentum (GeV)", "Count", "Møller - Momentum (Electron)"));
+        module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MTE Analysis/Møller Time Coincidence Distribution (All Møller Cuts)"), møllerColor,
+                "Time (ns)", "Count", "Møller - Time Coincidence"));
+        module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MTE Analysis/Møller Event Tracks"), møllerColor,
+                "Tracks", "Count", "Møller - Tracks in Event"));
+        module.addPlot2D(new FormattedPlot2D((IHistogram2D) tree.find("MTE Analysis/Møller 2D Energy Distribution"), false,
+                "First Track Momentum (GeV)", "Second Track Momentum (GeV)", "Møller - 2D Momentum Sum"));
+        
+        module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MTE Analysis/Trident Energy Sum Distribution"), tridentColor,
+                "Momentum Sum (GeV)", "Count", "Trident - Momentum Sum"));
+        module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MTE Analysis/Trident Electron Energy Distribution"), tridentColor,
+                "Momentum (GeV)", "Count", "Trident - Momentum (Electron)"));
+        module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MTE Analysis/Trident Positron Energy Distribution"), tridentColor,
+                "Momentum (GeV)", "Count", "Trident - Momentum (Positron)"));
+        module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MTE Analysis/Trident Event Tracks"), tridentColor,
+                "Tracks", "Count", "Trident - Tracks in Event"));
+        module.addPlot2D(new FormattedPlot2D((IHistogram2D) tree.find("MTE Analysis/Trident 2D Energy Distribution"), false,
+                "First Track Momentum (GeV)", "Second Track Momentum (GeV)", "Trident - 2D Momentum Sum"));
+        
+        // Display the plots.
+        module.savePlots("C:\\Users\\Kyle\\Desktop\\EnergyShift\\TestPrint\\");
+    }
 }

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/plots/formatter/ParticleMCAnalysisPlotsFormatter.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/plots/formatter/ParticleMCAnalysisPlotsFormatter.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/plots/formatter/ParticleMCAnalysisPlotsFormatter.java	Wed Apr 27 11:11:32 2016
@@ -13,43 +13,43 @@
 import org.hps.users.kmccarty.plots.PlotsFormatter.ColorStyle;
 
 public class ParticleMCAnalysisPlotsFormatter {
-	public static void main(String[] args) throws IllegalArgumentException, IOException {
-		// Define the root directory for the plots.
-		String rootDir = "D:\\cygwin64\\home\\Kyle\\";
-		
-		// Define the new name of the file containing the trigger plots.
-		String plotFile = rootDir + "moller-mc-out_triggerPlots.aida";
-		
-		// Get the plots file and open it.
-		IAnalysisFactory af = IAnalysisFactory.create();
-		ITree tree = af.createTreeFactory().create(plotFile);
-		if(tree == null) { throw new IllegalArgumentException("Unable to load plot file."); }
-		
-		// Create a plot formatting module.
-		PlotFormatModule module = new PlotFormatModule();
-		
-		// Define the plot color.
-		ColorStyle plotColor = ColorStyle.MS_BLUE;
-		
-		// Define the plots to be read.
-		module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MC Analysis/Electron Energy Distribution"),
-				plotColor, "Electron Energy (GeV)", "Count", "Electron Energy Distribution"));
-		module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MC Analysis/Electron\\Electron Momentum Sum Distribution"),
-				plotColor, "Momentum Sum (GeV)", "Count", "Momentum Sum Distribution"));
-		module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MC Analysis/Electron\\Electron Pair Angle Distribution"),
-				plotColor, "Momentum Sum (GeV)", "Count", "Pair Angle Distribution"));
-		module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MC Analysis/Particle x-Momentum Distribution"),
-				plotColor, "Momentum (GeV)", "Count", "Particle x-Momentum Distribution"));
-		module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MC Analysis/Particle y-Momentum Distribution"),
-				plotColor, "Momentum (GeV)", "Count", "Particle y-Momentum Distribution"));
-		module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MC Analysis/Particle z-Momentum Distribution"),
-				plotColor, "Momentum (GeV)", "Count", "Particle z-Momentum Distribution"));
-		module.addPlot2D(new FormattedPlot2D((IHistogram2D) tree.find("MC Analysis/Electron\\Electron 2D Momentum Distribution"),
-				true, "Particle 1 Momentum (GeV)", "Particle 2 Momentum (GeV)", "2D Momentum Sum Distribution"));
-		module.addPlot2D(new FormattedPlot2D((IHistogram2D) tree.find("MC Analysis/Particle Momentum Distribution"),
-				true, "px (GeV)", "py (GeV)", "Particle x/y Momentum Distribution"));
-		
-		// Display the plots.
-		module.displayPlots();
-	}
+    public static void main(String[] args) throws IllegalArgumentException, IOException {
+        // Define the root directory for the plots.
+        String rootDir = "D:\\cygwin64\\home\\Kyle\\";
+        
+        // Define the new name of the file containing the trigger plots.
+        String plotFile = rootDir + "moller-mc-out_triggerPlots.aida";
+        
+        // Get the plots file and open it.
+        IAnalysisFactory af = IAnalysisFactory.create();
+        ITree tree = af.createTreeFactory().create(plotFile);
+        if(tree == null) { throw new IllegalArgumentException("Unable to load plot file."); }
+        
+        // Create a plot formatting module.
+        PlotFormatModule module = new PlotFormatModule();
+        
+        // Define the plot color.
+        ColorStyle plotColor = ColorStyle.MS_BLUE;
+        
+        // Define the plots to be read.
+        module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MC Analysis/Electron Energy Distribution"),
+                plotColor, "Electron Energy (GeV)", "Count", "Electron Energy Distribution"));
+        module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MC Analysis/Electron\\Electron Momentum Sum Distribution"),
+                plotColor, "Momentum Sum (GeV)", "Count", "Momentum Sum Distribution"));
+        module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MC Analysis/Electron\\Electron Pair Angle Distribution"),
+                plotColor, "Momentum Sum (GeV)", "Count", "Pair Angle Distribution"));
+        module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MC Analysis/Particle x-Momentum Distribution"),
+                plotColor, "Momentum (GeV)", "Count", "Particle x-Momentum Distribution"));
+        module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MC Analysis/Particle y-Momentum Distribution"),
+                plotColor, "Momentum (GeV)", "Count", "Particle y-Momentum Distribution"));
+        module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MC Analysis/Particle z-Momentum Distribution"),
+                plotColor, "Momentum (GeV)", "Count", "Particle z-Momentum Distribution"));
+        module.addPlot2D(new FormattedPlot2D((IHistogram2D) tree.find("MC Analysis/Electron\\Electron 2D Momentum Distribution"),
+                true, "Particle 1 Momentum (GeV)", "Particle 2 Momentum (GeV)", "2D Momentum Sum Distribution"));
+        module.addPlot2D(new FormattedPlot2D((IHistogram2D) tree.find("MC Analysis/Particle Momentum Distribution"),
+                true, "px (GeV)", "py (GeV)", "Particle x/y Momentum Distribution"));
+        
+        // Display the plots.
+        module.displayPlots();
+    }
 }

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/plots/formatter/RafoTridentFormatter.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/plots/formatter/RafoTridentFormatter.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/plots/formatter/RafoTridentFormatter.java	Wed Apr 27 11:11:32 2016
@@ -13,101 +13,101 @@
 import hep.aida.ITree;
 
 public class RafoTridentFormatter {
-	/**
-	 * Loads all plots in a file and formats them according to the
-	 * indicated style.
-	 * @param args - Unused default executable parameter.
-	 * @throws IOException Occurs if there is an issue opening the file.
-	 */
-	public static void main(String[] args) throws IOException {
-		// Define the root directory for the plots.
-		String rootDir = "D:\\cygwin64\\home\\Kyle\\";
-		
-		// Define the new name of the file containing the trigger plots.
-		String plotFile = rootDir + "mte-out.aida";
-		
-		// Get the plots file and open it.
-		IAnalysisFactory af = IAnalysisFactory.create();
-		ITree tree = af.createTreeFactory().create(plotFile);
-		if(tree == null) { throw new IllegalArgumentException("Unable to load plot file."); }
-		
-		// Declare the histogram names.
-		String energySumName = "Energy Sum";
-		String timeCoincidenceName = "Time Coincidence";
-		String timeEnergy2DName = "Cluster Time vs. Cluster Energy";
-		String hCoplanaritySum2DName = "Hardware Coplanarity vs. Energy Sum";
-		String coplanaritySum2DName = "Calculated Coplanarity vs. Energy Sum";
-		String energySum2DName = "Top Cluster Energy vs. Bottom Cluster Energy";
-		String fiducial = " (Fiducial Region)";
-		
-		// Get the histograms.
-		IHistogram1D[] energySum = {
-				(IHistogram1D) tree.find("Trident/" + energySumName),
-				(IHistogram1D) tree.find("Trident/" + energySumName + fiducial)
-		};
-		IHistogram1D[] timeCoincidence = {
-				(IHistogram1D) tree.find("Trident/" + timeCoincidenceName),
-				(IHistogram1D) tree.find("Trident/" + timeCoincidenceName + fiducial)
-		};
-		IHistogram2D[] coplanaritySum = {
-				(IHistogram2D) tree.find("Trident/" + coplanaritySum2DName),
-				(IHistogram2D) tree.find("Trident/" + coplanaritySum2DName + fiducial)
-		};
-		IHistogram2D[] hcoplanaritySum = {
-				(IHistogram2D) tree.find("Trident/" + hCoplanaritySum2DName),
-				(IHistogram2D) tree.find("Trident/" + hCoplanaritySum2DName + fiducial)
-		};
-		IHistogram2D[] energySum2D = {
-				(IHistogram2D) tree.find("Trident/" + energySum2DName),
-				(IHistogram2D) tree.find("Trident/" + energySum2DName + fiducial)
-		};
-		IHistogram2D[] timeEnergy = {
-				(IHistogram2D) tree.find("Trident/" + timeEnergy2DName),
-				(IHistogram2D) tree.find("Trident/" + timeEnergy2DName + fiducial)
-		};
-		
-		// Define the scaling factors for each plot.
-		double scaleFactor = 19000.0 / 9736969.0;
-		
-		// Define the plot titles and arrays for 1D plots.
-		IHistogram1D[][] plots = { energySum, timeCoincidence  };
-		String titles[] = { energySumName, timeCoincidenceName, coplanaritySum2DName, hCoplanaritySum2DName, energySum2DName, timeEnergy2DName };
-		String[] xTitles = { "Energy (GeV)", "Time Difference (ns)" };
-		String yTitle = "Rate (Hz)";
-		
-		// Define the plot titles and arrays for 2D plots.
-		IHistogram2D[][] plots2D = { coplanaritySum, hcoplanaritySum, energySum2D, timeEnergy };
-		String[] titles2D = { coplanaritySum2DName, hCoplanaritySum2DName, energySum2DName, timeEnergy2DName };
-		String[] xTitles2D = { "Coplanarity (Degrees)", "Coplanarity (Degrees)", "Top Cluster Energy (GeV)", "Time Coincidence (ns)" };
-		String[] yTitles2D = { "Energy Sum (GeV)", "Energy Sum (GeV)", "Bottom Cluster Energy (GeV)", "Energy Sum (GeV)" };
-		String zTitle2D = "Rate (Hz)";
-		
-		// Create a plot formatting module.
-		PlotFormatModule module = new PlotFormatModule();
-		
-		// Define the plot color.
-		ColorStyle plotColor = ColorStyle.MS_BLUE;
-		
-		// Define the plots to be read.
-		for(int i = 0; i < plots.length; i++) {
-			plots[i][0].scale(scaleFactor);
-			plots[i][1].scale(scaleFactor);
-			module.addPlot1D(new FormattedPlot1D(plots[i][0], plotColor, xTitles[i], yTitle, titles[i]));
-			module.addPlot1D(new FormattedPlot1D(plots[i][1], plotColor, xTitles[i],  yTitle, titles[i] + fiducial));
-		}
-		for(int i = 0; i < plots2D.length; i++) {
-			plots2D[i][0].scale(scaleFactor);
-			plots2D[i][1].scale(scaleFactor);
-			module.addPlot2D(new FormattedPlot2D(plots2D[i][0], false, xTitles2D[i], yTitles2D[i], titles2D[i]));
-			module.addPlot2D(new FormattedPlot2D(plots2D[i][1], false, xTitles2D[i], yTitles2D[i], titles2D[i] + fiducial));
-		}
-		
-		// Display the plots.
-		//module.displayPlots();
-		module.savePlots("C:\\Users\\Kyle\\Desktop\\EnergyShift\\run-5772\\RafoPlots\\");
-		module.exportPlots("C:\\Users\\Kyle\\Desktop\\EnergyShift\\run-5772\\RafoPlots\\");
-		
-		// Close the tree.
-		tree.close();
-	}
+    /**
+     * Loads all plots in a file and formats them according to the
+     * indicated style.
+     * @param args - Unused default executable parameter.
+     * @throws IOException Occurs if there is an issue opening the file.
+     */
+    public static void main(String[] args) throws IOException {
+        // Define the root directory for the plots.
+        String rootDir = "D:\\cygwin64\\home\\Kyle\\";
+        
+        // Define the new name of the file containing the trigger plots.
+        String plotFile = rootDir + "mte-out.aida";
+        
+        // Get the plots file and open it.
+        IAnalysisFactory af = IAnalysisFactory.create();
+        ITree tree = af.createTreeFactory().create(plotFile);
+        if(tree == null) { throw new IllegalArgumentException("Unable to load plot file."); }
+        
+        // Declare the histogram names.
+        String energySumName = "Energy Sum";
+        String timeCoincidenceName = "Time Coincidence";
+        String timeEnergy2DName = "Cluster Time vs. Cluster Energy";
+        String hCoplanaritySum2DName = "Hardware Coplanarity vs. Energy Sum";
+        String coplanaritySum2DName = "Calculated Coplanarity vs. Energy Sum";
+        String energySum2DName = "Top Cluster Energy vs. Bottom Cluster Energy";
+        String fiducial = " (Fiducial Region)";
+        
+        // Get the histograms.
+        IHistogram1D[] energySum = {
+                (IHistogram1D) tree.find("Trident/" + energySumName),
+                (IHistogram1D) tree.find("Trident/" + energySumName + fiducial)
+        };
+        IHistogram1D[] timeCoincidence = {
+                (IHistogram1D) tree.find("Trident/" + timeCoincidenceName),
+                (IHistogram1D) tree.find("Trident/" + timeCoincidenceName + fiducial)
+        };
+        IHistogram2D[] coplanaritySum = {
+                (IHistogram2D) tree.find("Trident/" + coplanaritySum2DName),
+                (IHistogram2D) tree.find("Trident/" + coplanaritySum2DName + fiducial)
+        };
+        IHistogram2D[] hcoplanaritySum = {
+                (IHistogram2D) tree.find("Trident/" + hCoplanaritySum2DName),
+                (IHistogram2D) tree.find("Trident/" + hCoplanaritySum2DName + fiducial)
+        };
+        IHistogram2D[] energySum2D = {
+                (IHistogram2D) tree.find("Trident/" + energySum2DName),
+                (IHistogram2D) tree.find("Trident/" + energySum2DName + fiducial)
+        };
+        IHistogram2D[] timeEnergy = {
+                (IHistogram2D) tree.find("Trident/" + timeEnergy2DName),
+                (IHistogram2D) tree.find("Trident/" + timeEnergy2DName + fiducial)
+        };
+        
+        // Define the scaling factors for each plot.
+        double scaleFactor = 19000.0 / 9736969.0;
+        
+        // Define the plot titles and arrays for 1D plots.
+        IHistogram1D[][] plots = { energySum, timeCoincidence  };
+        String titles[] = { energySumName, timeCoincidenceName, coplanaritySum2DName, hCoplanaritySum2DName, energySum2DName, timeEnergy2DName };
+        String[] xTitles = { "Energy (GeV)", "Time Difference (ns)" };
+        String yTitle = "Rate (Hz)";
+        
+        // Define the plot titles and arrays for 2D plots.
+        IHistogram2D[][] plots2D = { coplanaritySum, hcoplanaritySum, energySum2D, timeEnergy };
+        String[] titles2D = { coplanaritySum2DName, hCoplanaritySum2DName, energySum2DName, timeEnergy2DName };
+        String[] xTitles2D = { "Coplanarity (Degrees)", "Coplanarity (Degrees)", "Top Cluster Energy (GeV)", "Time Coincidence (ns)" };
+        String[] yTitles2D = { "Energy Sum (GeV)", "Energy Sum (GeV)", "Bottom Cluster Energy (GeV)", "Energy Sum (GeV)" };
+        String zTitle2D = "Rate (Hz)";
+        
+        // Create a plot formatting module.
+        PlotFormatModule module = new PlotFormatModule();
+        
+        // Define the plot color.
+        ColorStyle plotColor = ColorStyle.MS_BLUE;
+        
+        // Define the plots to be read.
+        for(int i = 0; i < plots.length; i++) {
+            plots[i][0].scale(scaleFactor);
+            plots[i][1].scale(scaleFactor);
+            module.addPlot1D(new FormattedPlot1D(plots[i][0], plotColor, xTitles[i], yTitle, titles[i]));
+            module.addPlot1D(new FormattedPlot1D(plots[i][1], plotColor, xTitles[i],  yTitle, titles[i] + fiducial));
+        }
+        for(int i = 0; i < plots2D.length; i++) {
+            plots2D[i][0].scale(scaleFactor);
+            plots2D[i][1].scale(scaleFactor);
+            module.addPlot2D(new FormattedPlot2D(plots2D[i][0], false, xTitles2D[i], yTitles2D[i], titles2D[i]));
+            module.addPlot2D(new FormattedPlot2D(plots2D[i][1], false, xTitles2D[i], yTitles2D[i], titles2D[i] + fiducial));
+        }
+        
+        // Display the plots.
+        //module.displayPlots();
+        module.savePlots("C:\\Users\\Kyle\\Desktop\\EnergyShift\\run-5772\\RafoPlots\\");
+        module.exportPlots("C:\\Users\\Kyle\\Desktop\\EnergyShift\\run-5772\\RafoPlots\\");
+        
+        // Close the tree.
+        tree.close();
+    }
 }

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/plots/formatter/SingleTriggerPlotsFormatter.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/plots/formatter/SingleTriggerPlotsFormatter.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/plots/formatter/SingleTriggerPlotsFormatter.java	Wed Apr 27 11:11:32 2016
@@ -13,151 +13,151 @@
 import hep.aida.ITree;
 
 public class SingleTriggerPlotsFormatter {
-	
-	public static void main(String[] args) throws IllegalArgumentException, IOException {
-		// Define the root directory for the plots.
-		String rootDir = "D:\\cygwin64\\home\\Kyle\\";
-		
-		// Define the new name of the file containing the trigger plots.
-		String plotFile = rootDir + "trident-readout-full.aida";
-		
-		// Get the plots file and open it.
-		IAnalysisFactory af = IAnalysisFactory.create();
-		ITree tree = af.createTreeFactory().create(plotFile);
-		if(tree == null) { throw new IllegalArgumentException("Unable to load plot file."); }
-		
-		// Define plots variables.
-		int UNCUT     = 0;
-		int TRIGGERED = 1;
-		String[] plotsDir = { "NoCuts/", "PassedAll/" };
-		int PLOT_HIT_COUNT      = 0;
-		int PLOT_SEED_ENERGY    = 1;
-		int PLOT_CLUSTER_ENERGY = 2;
-		int PLOT_COPLANARITY    = 3;
-		int PLOT_ENERGY_SUM     = 4;
-		int PLOT_ENERGY_DIFF    = 5;
-		int PLOT_ENERGY_SLOPE   = 6;
-		int PLOT_SEED_DIST      = 0;
-		int PLOT_ENERGY_SUM_2D  = 1;
-		
-		// Define the internal plot names.
-		String[] plotNameInternal1D = new String[7];
-		String[] plotNameInternal2D = new String[2];
-		plotNameInternal1D[PLOT_HIT_COUNT]      = "Cluster Hit Count";
-		plotNameInternal1D[PLOT_SEED_ENERGY]    = "Cluster Seed Energy";
-		plotNameInternal1D[PLOT_CLUSTER_ENERGY] = "Cluster Total Energy";
-		plotNameInternal1D[PLOT_COPLANARITY]    = "Pair Coplanarity";
-		plotNameInternal1D[PLOT_ENERGY_SUM]     = "Pair Energy Sum";
-		plotNameInternal1D[PLOT_ENERGY_DIFF]    = "Pair Energy Difference";
-		plotNameInternal1D[PLOT_ENERGY_SLOPE]   = "Pair Energy Slope";
-		plotNameInternal2D[PLOT_SEED_DIST]      = "Cluster Seed";
-		plotNameInternal2D[PLOT_ENERGY_SUM_2D]  = "Pair Energy Sum 2D";
-		
-		// Define the plot display names.
-		String[] plotName1D = new String[7];
-		String[] plotName2D = new String[2];
-		for(int j = 0; j < plotNameInternal1D.length; j++) {
-			plotName1D[j] = plotNameInternal1D[j];
-		}
-		for(int j = 0; j < plotNameInternal2D.length; j++) {
-			plotName2D[j] = plotNameInternal2D[j];
-		}
-		plotName1D[PLOT_ENERGY_SUM]    = "1D Pair Energy Sum";
-		plotName2D[PLOT_SEED_DIST]     = "Cluster Seed Distribution";
-		plotName2D[PLOT_ENERGY_SUM_2D] = "2D Pair Energy Sum";
-		
-		String[] xTitles1D = new String[plotName1D.length];
-		String[] xTitles2D = new String[plotName2D.length];
-		xTitles1D[PLOT_HIT_COUNT]      = "Hit Count";
-		xTitles1D[PLOT_SEED_ENERGY]    = "Seed Energy (GeV)";
-		xTitles1D[PLOT_CLUSTER_ENERGY] = "Cluster Energy (GeV)";
-		xTitles1D[PLOT_COPLANARITY]    = "Coplanarity Angle (Degrees)";
-		xTitles1D[PLOT_ENERGY_SUM]     = "Energy Sum (GeV)";
-		xTitles1D[PLOT_ENERGY_DIFF]    = "Energy Difference (GeV)";
-		xTitles1D[PLOT_ENERGY_SLOPE]   = "Energy Slope (GeV)";
-		xTitles2D[PLOT_SEED_DIST]      = "x-Index";
-		xTitles2D[PLOT_ENERGY_SUM_2D]  = "First Cluster Energy (GeV)";
-		String yTitle1D = "Count";
-		String[] yTitles2D = new String[plotName2D.length];
-		yTitles2D[PLOT_SEED_DIST]      = "y-Index";
-		yTitles2D[PLOT_ENERGY_SUM_2D]  = "Second Cluster Energy (GeV)";
-		
-		// Define axis ranges.
-		double[] axisRanges1D = new double[plotName1D.length];
-		axisRanges1D[PLOT_HIT_COUNT]      = -1;
-		axisRanges1D[PLOT_SEED_ENERGY]    = 1.1;
-		axisRanges1D[PLOT_CLUSTER_ENERGY] = 1.1;
-		axisRanges1D[PLOT_COPLANARITY]    = 180;
-		axisRanges1D[PLOT_ENERGY_SUM]     = 2.2;
-		axisRanges1D[PLOT_ENERGY_DIFF]    = 1.1;
-		axisRanges1D[PLOT_ENERGY_SLOPE]   = 2.4;
-		double[] xAxisRanges2D = new double[plotName2D.length];
-		double[] yAxisRanges2D = new double[plotName2D.length];
-		xAxisRanges2D[PLOT_SEED_DIST]      = -1;
-		xAxisRanges2D[PLOT_ENERGY_SUM_2D]  = 1.1;
-		yAxisRanges2D[PLOT_SEED_DIST]      = -1;
-		yAxisRanges2D[PLOT_ENERGY_SUM_2D]  = 1.1;
-		
-		// Define the plot names.
-		String[][] plotLocations1D = new String[plotsDir.length][plotNameInternal1D.length];
-		String[][] plotLocations2D = new String[plotsDir.length][plotNameInternal2D.length];
-		for(int i = 0; i < plotsDir.length; i++) {
-			for(int j = 0; j < plotNameInternal1D.length; j++) {
-				plotLocations1D[i][j] = plotsDir[i] + plotNameInternal1D[j];
-			}
-		}
-		for(int i = 0; i < plotsDir.length; i++) {
-			for(int j = 0; j < plotNameInternal2D.length; j++) {
-				plotLocations2D[i][j] = plotsDir[i] + plotNameInternal2D[j];
-			}
-		}
-		
-		// Create a plot formatting module.
-		PlotFormatModule module = new PlotFormatModule();
-		
-		// Load the plot objects.
-		for(int i = 0; i < plotName1D.length; i++) {
-			// Get the uncut and triggered plots.
-			IHistogram1D uncutPlot = (IHistogram1D) tree.find(plotLocations1D[UNCUT][i]);
-			IHistogram1D triggeredPlot = (IHistogram1D) tree.find(plotLocations1D[TRIGGERED][i] + " (Passed All Cuts)");
-			
-			// Make a formatted plot for each.
-			FormattedPlot1D uncutFormattedPlot;
-			FormattedPlot1D triggeredFormattedPlot;
-			if(axisRanges1D[i] != -1) {
-				uncutFormattedPlot = new FormattedPlot1D(uncutPlot, PlotsFormatter.ColorStyle.GREY, xTitles1D[i], yTitle1D, plotName1D[i] + " (No Cuts)", axisRanges1D[i]);
-				triggeredFormattedPlot = new FormattedPlot1D(triggeredPlot, PlotsFormatter.ColorStyle.MS_GREEN, xTitles1D[i], yTitle1D, plotName1D[i] + " (Triggered)", axisRanges1D[i]);
-			} else {
-				uncutFormattedPlot = new FormattedPlot1D(uncutPlot, PlotsFormatter.ColorStyle.GREY, xTitles1D[i], yTitle1D, plotName1D[i] + " (No Cuts)");
-				triggeredFormattedPlot = new FormattedPlot1D(triggeredPlot, PlotsFormatter.ColorStyle.MS_GREEN, xTitles1D[i], yTitle1D, plotName1D[i] + " (Triggered)");
-			}
-			
-			// Add the plots to the module.
-			module.addPlot1D(uncutFormattedPlot);
-			module.addPlot1D(triggeredFormattedPlot);
-		}
-		for(int i = 0; i < plotName2D.length; i++) {
-			// Get the uncut and triggered plots.
-			IHistogram2D uncutPlot = (IHistogram2D) tree.find(plotLocations2D[UNCUT][i]);
-			IHistogram2D triggeredPlot = (IHistogram2D) tree.find(plotLocations2D[TRIGGERED][i] + " (Passed All Cuts)");
-			
-			// Make a formatted plot for each.
-			FormattedPlot2D uncutFormattedPlot;
-			FormattedPlot2D triggeredFormattedPlot;
-			if(xAxisRanges2D[i] != -1) {
-				uncutFormattedPlot = new FormattedPlot2D(uncutPlot, true, xTitles2D[i], yTitles2D[i], plotName2D[i] + " (No Cuts)", xAxisRanges2D[i], yAxisRanges2D[i]);
-				triggeredFormattedPlot = new FormattedPlot2D(triggeredPlot, true, xTitles2D[i], yTitles2D[i], plotName2D[i] + " (Triggered)", xAxisRanges2D[i], yAxisRanges2D[i]);
-			} else {
-				uncutFormattedPlot = new FormattedPlot2D(uncutPlot, true, xTitles2D[i], yTitles2D[i], plotName2D[i] + " (No Cuts)");
-				triggeredFormattedPlot = new FormattedPlot2D(triggeredPlot, true, xTitles2D[i], yTitles2D[i], plotName2D[i] + " (Triggered)");
-			}
-			
-			// Add the plots to the module.
-			module.addPlot2D(uncutFormattedPlot);
-			module.addPlot2D(triggeredFormattedPlot);
-		}
-		
-		// Save the plots.
-		module.savePlots("C:\\Users\\Kyle\\Desktop\\EnergyShift\\MonteCarlo\\Trident\\Trigger\\");
-	}
+    
+    public static void main(String[] args) throws IllegalArgumentException, IOException {
+        // Define the root directory for the plots.
+        String rootDir = "D:\\cygwin64\\home\\Kyle\\";
+        
+        // Define the new name of the file containing the trigger plots.
+        String plotFile = rootDir + "trident-readout-full.aida";
+        
+        // Get the plots file and open it.
+        IAnalysisFactory af = IAnalysisFactory.create();
+        ITree tree = af.createTreeFactory().create(plotFile);
+        if(tree == null) { throw new IllegalArgumentException("Unable to load plot file."); }
+        
+        // Define plots variables.
+        int UNCUT     = 0;
+        int TRIGGERED = 1;
+        String[] plotsDir = { "NoCuts/", "PassedAll/" };
+        int PLOT_HIT_COUNT      = 0;
+        int PLOT_SEED_ENERGY    = 1;
+        int PLOT_CLUSTER_ENERGY = 2;
+        int PLOT_COPLANARITY    = 3;
+        int PLOT_ENERGY_SUM     = 4;
+        int PLOT_ENERGY_DIFF    = 5;
+        int PLOT_ENERGY_SLOPE   = 6;
+        int PLOT_SEED_DIST      = 0;
+        int PLOT_ENERGY_SUM_2D  = 1;
+        
+        // Define the internal plot names.
+        String[] plotNameInternal1D = new String[7];
+        String[] plotNameInternal2D = new String[2];
+        plotNameInternal1D[PLOT_HIT_COUNT]      = "Cluster Hit Count";
+        plotNameInternal1D[PLOT_SEED_ENERGY]    = "Cluster Seed Energy";
+        plotNameInternal1D[PLOT_CLUSTER_ENERGY] = "Cluster Total Energy";
+        plotNameInternal1D[PLOT_COPLANARITY]    = "Pair Coplanarity";
+        plotNameInternal1D[PLOT_ENERGY_SUM]     = "Pair Energy Sum";
+        plotNameInternal1D[PLOT_ENERGY_DIFF]    = "Pair Energy Difference";
+        plotNameInternal1D[PLOT_ENERGY_SLOPE]   = "Pair Energy Slope";
+        plotNameInternal2D[PLOT_SEED_DIST]      = "Cluster Seed";
+        plotNameInternal2D[PLOT_ENERGY_SUM_2D]  = "Pair Energy Sum 2D";
+        
+        // Define the plot display names.
+        String[] plotName1D = new String[7];
+        String[] plotName2D = new String[2];
+        for(int j = 0; j < plotNameInternal1D.length; j++) {
+            plotName1D[j] = plotNameInternal1D[j];
+        }
+        for(int j = 0; j < plotNameInternal2D.length; j++) {
+            plotName2D[j] = plotNameInternal2D[j];
+        }
+        plotName1D[PLOT_ENERGY_SUM]    = "1D Pair Energy Sum";
+        plotName2D[PLOT_SEED_DIST]     = "Cluster Seed Distribution";
+        plotName2D[PLOT_ENERGY_SUM_2D] = "2D Pair Energy Sum";
+        
+        String[] xTitles1D = new String[plotName1D.length];
+        String[] xTitles2D = new String[plotName2D.length];
+        xTitles1D[PLOT_HIT_COUNT]      = "Hit Count";
+        xTitles1D[PLOT_SEED_ENERGY]    = "Seed Energy (GeV)";
+        xTitles1D[PLOT_CLUSTER_ENERGY] = "Cluster Energy (GeV)";
+        xTitles1D[PLOT_COPLANARITY]    = "Coplanarity Angle (Degrees)";
+        xTitles1D[PLOT_ENERGY_SUM]     = "Energy Sum (GeV)";
+        xTitles1D[PLOT_ENERGY_DIFF]    = "Energy Difference (GeV)";
+        xTitles1D[PLOT_ENERGY_SLOPE]   = "Energy Slope (GeV)";
+        xTitles2D[PLOT_SEED_DIST]      = "x-Index";
+        xTitles2D[PLOT_ENERGY_SUM_2D]  = "First Cluster Energy (GeV)";
+        String yTitle1D = "Count";
+        String[] yTitles2D = new String[plotName2D.length];
+        yTitles2D[PLOT_SEED_DIST]      = "y-Index";
+        yTitles2D[PLOT_ENERGY_SUM_2D]  = "Second Cluster Energy (GeV)";
+        
+        // Define axis ranges.
+        double[] axisRanges1D = new double[plotName1D.length];
+        axisRanges1D[PLOT_HIT_COUNT]      = -1;
+        axisRanges1D[PLOT_SEED_ENERGY]    = 1.1;
+        axisRanges1D[PLOT_CLUSTER_ENERGY] = 1.1;
+        axisRanges1D[PLOT_COPLANARITY]    = 180;
+        axisRanges1D[PLOT_ENERGY_SUM]     = 2.2;
+        axisRanges1D[PLOT_ENERGY_DIFF]    = 1.1;
+        axisRanges1D[PLOT_ENERGY_SLOPE]   = 2.4;
+        double[] xAxisRanges2D = new double[plotName2D.length];
+        double[] yAxisRanges2D = new double[plotName2D.length];
+        xAxisRanges2D[PLOT_SEED_DIST]      = -1;
+        xAxisRanges2D[PLOT_ENERGY_SUM_2D]  = 1.1;
+        yAxisRanges2D[PLOT_SEED_DIST]      = -1;
+        yAxisRanges2D[PLOT_ENERGY_SUM_2D]  = 1.1;
+        
+        // Define the plot names.
+        String[][] plotLocations1D = new String[plotsDir.length][plotNameInternal1D.length];
+        String[][] plotLocations2D = new String[plotsDir.length][plotNameInternal2D.length];
+        for(int i = 0; i < plotsDir.length; i++) {
+            for(int j = 0; j < plotNameInternal1D.length; j++) {
+                plotLocations1D[i][j] = plotsDir[i] + plotNameInternal1D[j];
+            }
+        }
+        for(int i = 0; i < plotsDir.length; i++) {
+            for(int j = 0; j < plotNameInternal2D.length; j++) {
+                plotLocations2D[i][j] = plotsDir[i] + plotNameInternal2D[j];
+            }
+        }
+        
+        // Create a plot formatting module.
+        PlotFormatModule module = new PlotFormatModule();
+        
+        // Load the plot objects.
+        for(int i = 0; i < plotName1D.length; i++) {
+            // Get the uncut and triggered plots.
+            IHistogram1D uncutPlot = (IHistogram1D) tree.find(plotLocations1D[UNCUT][i]);
+            IHistogram1D triggeredPlot = (IHistogram1D) tree.find(plotLocations1D[TRIGGERED][i] + " (Passed All Cuts)");
+            
+            // Make a formatted plot for each.
+            FormattedPlot1D uncutFormattedPlot;
+            FormattedPlot1D triggeredFormattedPlot;
+            if(axisRanges1D[i] != -1) {
+                uncutFormattedPlot = new FormattedPlot1D(uncutPlot, PlotsFormatter.ColorStyle.GREY, xTitles1D[i], yTitle1D, plotName1D[i] + " (No Cuts)", axisRanges1D[i]);
+                triggeredFormattedPlot = new FormattedPlot1D(triggeredPlot, PlotsFormatter.ColorStyle.MS_GREEN, xTitles1D[i], yTitle1D, plotName1D[i] + " (Triggered)", axisRanges1D[i]);
+            } else {
+                uncutFormattedPlot = new FormattedPlot1D(uncutPlot, PlotsFormatter.ColorStyle.GREY, xTitles1D[i], yTitle1D, plotName1D[i] + " (No Cuts)");
+                triggeredFormattedPlot = new FormattedPlot1D(triggeredPlot, PlotsFormatter.ColorStyle.MS_GREEN, xTitles1D[i], yTitle1D, plotName1D[i] + " (Triggered)");
+            }
+            
+            // Add the plots to the module.
+            module.addPlot1D(uncutFormattedPlot);
+            module.addPlot1D(triggeredFormattedPlot);
+        }
+        for(int i = 0; i < plotName2D.length; i++) {
+            // Get the uncut and triggered plots.
+            IHistogram2D uncutPlot = (IHistogram2D) tree.find(plotLocations2D[UNCUT][i]);
+            IHistogram2D triggeredPlot = (IHistogram2D) tree.find(plotLocations2D[TRIGGERED][i] + " (Passed All Cuts)");
+            
+            // Make a formatted plot for each.
+            FormattedPlot2D uncutFormattedPlot;
+            FormattedPlot2D triggeredFormattedPlot;
+            if(xAxisRanges2D[i] != -1) {
+                uncutFormattedPlot = new FormattedPlot2D(uncutPlot, true, xTitles2D[i], yTitles2D[i], plotName2D[i] + " (No Cuts)", xAxisRanges2D[i], yAxisRanges2D[i]);
+                triggeredFormattedPlot = new FormattedPlot2D(triggeredPlot, true, xTitles2D[i], yTitles2D[i], plotName2D[i] + " (Triggered)", xAxisRanges2D[i], yAxisRanges2D[i]);
+            } else {
+                uncutFormattedPlot = new FormattedPlot2D(uncutPlot, true, xTitles2D[i], yTitles2D[i], plotName2D[i] + " (No Cuts)");
+                triggeredFormattedPlot = new FormattedPlot2D(triggeredPlot, true, xTitles2D[i], yTitles2D[i], plotName2D[i] + " (Triggered)");
+            }
+            
+            // Add the plots to the module.
+            module.addPlot2D(uncutFormattedPlot);
+            module.addPlot2D(triggeredFormattedPlot);
+        }
+        
+        // Save the plots.
+        module.savePlots("C:\\Users\\Kyle\\Desktop\\EnergyShift\\MonteCarlo\\Trident\\Trigger\\");
+    }
 }

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/plots/formatter/TridentTrackFormatter.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/plots/formatter/TridentTrackFormatter.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/plots/formatter/TridentTrackFormatter.java	Wed Apr 27 11:11:32 2016
@@ -16,187 +16,187 @@
 import hep.aida.ref.plotter.PlotterRegion;
 
 public class TridentTrackFormatter {
-	/**
-	 * Loads all plots in a file and formats them according to the
-	 * indicated style.
-	 * @param args - Unused default executable parameter.
-	 * @throws IOException Occurs if there is an issue opening the file.
-	 */
-	public static void main(String[] args) throws IOException {
-		// Define the root directory for the plots.
-		String rootDir = "D:\\cygwin64\\home\\Kyle\\tmp\\";
-		
-		// Define the new name of the file containing the trigger plots.
-		String plotFile = rootDir + "trident-out.aida";
-		
-		// Get the plots file and open it.
-		IAnalysisFactory af = IAnalysisFactory.create();
-		ITree tree = af.createTreeFactory().create(plotFile);
-		if(tree == null) { throw new IllegalArgumentException("Unable to load plot file."); }
-		
-		// Declare the histogram names.
-		String trackName = "Tracks in Event (All)";
-		String posTrackName = "Tracks in Event (Positive)";
-		String negTrackName = "Tracks in Event (Negative)";
-		String posMomentumName = "Momentum (Positive)";
-		String negMomentumName = "Momentum (Negative)";
-		String energySumName = "Energy Sum";
-		String momentumSumName = "Momentum Sum";
-		String energyMomentumDiffName = "Energy-Momentum Difference";
-		String invariantMassName = "Invariant Mass";
-		String energySum2DName = "2D Energy Sum";
-		String momentumSum2DName = "2D Momentum Sum";
-		String positionName = "Track Cluster Position";
-		
-		// Get the histograms.
-		IHistogram1D[] tracks = {
-				(IHistogram1D) tree.find("Trident Analysis/All/" + trackName),
-				(IHistogram1D) tree.find("Trident Analysis/Cluster/" + trackName)
-		};
-		IHistogram1D[] posTracks = {
-				(IHistogram1D) tree.find("Trident Analysis/All/" + posTrackName),
-				(IHistogram1D) tree.find("Trident Analysis/Cluster/" + posTrackName)
-		};
-		IHistogram1D[] negTracks = {
-				(IHistogram1D) tree.find("Trident Analysis/All/" + negTrackName),
-				(IHistogram1D) tree.find("Trident Analysis/Cluster/" + negTrackName)
-		};
-		IHistogram1D[] posMomentum = {
-				(IHistogram1D) tree.find("Trident Analysis/All/" + posMomentumName),
-				(IHistogram1D) tree.find("Trident Analysis/Cluster/" + posMomentumName)
-		};
-		IHistogram1D[] negMomentum = {
-				(IHistogram1D) tree.find("Trident Analysis/All/" + negMomentumName),
-				(IHistogram1D) tree.find("Trident Analysis/Cluster/" + negMomentumName)
-		};
-		IHistogram1D[] energySum = {
-				(IHistogram1D) tree.find("Trident Analysis/All/" + energySumName),
-				(IHistogram1D) tree.find("Trident Analysis/Cluster/" + energySumName)
-		};
-		IHistogram1D[] momentumSum = {
-				(IHistogram1D) tree.find("Trident Analysis/All/" + momentumSumName),
-				(IHistogram1D) tree.find("Trident Analysis/Cluster/" + momentumSumName)
-		};
-		IHistogram1D[] energyMomentumDiff = {
-				(IHistogram1D) tree.find("Trident Analysis/All/" + energyMomentumDiffName),
-				(IHistogram1D) tree.find("Trident Analysis/Cluster/" + energyMomentumDiffName)
-		};
-		IHistogram1D[] invariantMass = {
-				(IHistogram1D) tree.find("Trident Analysis/All/" + invariantMassName),
-				(IHistogram1D) tree.find("Trident Analysis/Cluster/" + invariantMassName)
-		};
-		IHistogram2D[] energySum2D = {
-				(IHistogram2D) tree.find("Trident Analysis/All/" + energySum2DName),
-				(IHistogram2D) tree.find("Trident Analysis/Cluster/" + energySum2DName)
-		};
-		IHistogram2D[] momentumSum2D = {
-				(IHistogram2D) tree.find("Trident Analysis/All/" + momentumSum2DName),
-				(IHistogram2D) tree.find("Trident Analysis/Cluster/" + momentumSum2DName)
-		};
-		IHistogram2D[] position = {
-				(IHistogram2D) tree.find("Trident Analysis/All/" + positionName),
-				(IHistogram2D) tree.find("Trident Analysis/Cluster/" + positionName)
-		};
-		
-		// Re-bin the histograms to have 5-times larger bins. First,
-		// get the bin count and upper and lower bounds of the plot.
-		int bins = invariantMass[0].axis().bins();
-		double low = invariantMass[0].axis().binLowerEdge(0);
-		double high = invariantMass[0].axis().binUpperEdge(invariantMass[0].axis().bins() - 1);
-		
-		// Create new plots with the larger bin sizes.
-		AIDA aida = AIDA.defaultInstance();
-		IHistogram1D[] newPlot = new IHistogram1D[2];
-		newPlot[0] = aida.histogram1D(invariantMassName, bins / 5, low, high);
-		newPlot[1] = aida.histogram1D("Cluster " + invariantMassName, bins / 5, low, high);
-		
-		// Populate the new plots with the data from the old ones.
-		for(int j = 0; j < 2; j++) {
-			for(int i = 0; i < bins; i++) {
-				int entries = invariantMass[j].binEntries(i);
-				double center = invariantMass[j].axis().binCenter(i);
-				for(int k = 0; k < entries; k++) {
-					newPlot[j].fill(center);
-				}
-			}
-		}
-		
-		// Replace the old plots.
-		invariantMass = newPlot;
-		
-		// Define the scaling factors for each plot.
-		double scaleFactor = 1;
-		
-		// Define the plot titles and arrays for 1D plots.
-		IHistogram[][] plots = { tracks, posTracks, negTracks, posMomentum, negMomentum, energySum, momentumSum, energyMomentumDiff, invariantMass };
-		String[] titles = { trackName, posTrackName, negTrackName, posMomentumName, negMomentumName, energySumName, momentumSumName,
-				energyMomentumDiffName, invariantMassName };
-		String[] xTitles = { "Tracks", "Tracks", "Tracks", "Momentum (GeV)", "Momentum (GeV)", "Energy Sum (GeV)", "Momentum Sum (GeV)",
-				"|E_Cluster - P_Track| (GeV)", "Invariant Mass (GeV)" };
-		String yTitle = "Count";
-		
-		// Define the plot titles and arrays for 2D plots.
-		IHistogram2D[][] plots2D = { energySum2D, momentumSum2D, position };
-		String[] titles2D = { energySum2DName, momentumSum2DName, positionName };
-		String[] xTitles2D = { "Positive Cluster Energy", "Positive Track Momentum", "x-Index" };
-		String[] yTitles2D = { "Negative Cluster Energy", "Negative Track Momentum", "y-Index" };
-		String zTitle2D = "Count";
-		
-		// Create a plotter factory.
-		IPlotterFactory plotterFactory = af.createPlotterFactory();
-		
-		// Format and display the basic histograms.
-		for(int i = 0; i < plots.length; i++) {
-			for(int j = 0; j < 2; j++) {
-				// Scale the histogram by the appropriate scaling factor.
-				plots[i][j].scale(1.0 / scaleFactor);
-				
-				// Create a plotter and plotting region for the plot.
-				IPlotter plotter = plotterFactory.create((j == 1 ? "Cluster " : "") + titles[i]);
-				plotter.createRegions(1);
-				plotter.region(0).plot(plots[i][j]);
-				
-				// Format the axis labels.
-				PlotterRegion region = (PlotterRegion) plotter.region(0);
-				region.getPlot().setTitle((j == 1 ? "Cluster " : "") + titles[i]);
-				region.getPlot().getXAxis().setLabel(xTitles[i]);
-				region.getPlot().getYAxis().setLabel(yTitle);
-				
-				// Format the fonts and general plot presentation.
-				PlotsFormatter.setDefault1DStyle(region, new ColorStyle[] { ColorStyle.GREY });
-				
-				// Show the plot.
-				plotter.setParameter("plotterWidth", "2000");
-				plotter.setParameter("plotterHeight", "1200");
-				plotter.show();
-			}
-		}
-		
-		// Format and display the 2D histogram.
-		for(int i = 0; i < plots2D.length; i++) {
-			for(int j = 0; j < 2; j++) {
-				plots2D[i][j].scale(1.0 / scaleFactor);
-				IPlotter plotter2D = plotterFactory.create((j == 1 ? "Cluster " : "") + titles2D[i]);
-				plotter2D.createRegions(1);
-				plotter2D.region(0).plot(plots2D[i][j]);
-				
-				// Format the axis labels.
-				PlotterRegion region2D = (PlotterRegion) plotter2D.region(0);
-				region2D.getPlot().setTitle((j == 1 ? "Cluster " : "") + titles2D[i]);
-				region2D.getPlot().getXAxis().setLabel(xTitles2D[i]);
-				region2D.getPlot().getYAxis().setLabel(yTitles2D[i]);
-				
-				// Format the fonts and general plot presentation.
-				PlotsFormatter.setDefault2DStyle(region2D, true);
-				
-				// Show the plot.
-				plotter2D.setParameter("plotterWidth", "2000");
-				plotter2D.setParameter("plotterHeight", "1200");
-				plotter2D.show();
-			}
-		}
-		
-		// Close the tree.
-		tree.close();
-	}
+    /**
+     * Loads all plots in a file and formats them according to the
+     * indicated style.
+     * @param args - Unused default executable parameter.
+     * @throws IOException Occurs if there is an issue opening the file.
+     */
+    public static void main(String[] args) throws IOException {
+        // Define the root directory for the plots.
+        String rootDir = "D:\\cygwin64\\home\\Kyle\\tmp\\";
+        
+        // Define the new name of the file containing the trigger plots.
+        String plotFile = rootDir + "trident-out.aida";
+        
+        // Get the plots file and open it.
+        IAnalysisFactory af = IAnalysisFactory.create();
+        ITree tree = af.createTreeFactory().create(plotFile);
+        if(tree == null) { throw new IllegalArgumentException("Unable to load plot file."); }
+        
+        // Declare the histogram names.
+        String trackName = "Tracks in Event (All)";
+        String posTrackName = "Tracks in Event (Positive)";
+        String negTrackName = "Tracks in Event (Negative)";
+        String posMomentumName = "Momentum (Positive)";
+        String negMomentumName = "Momentum (Negative)";
+        String energySumName = "Energy Sum";
+        String momentumSumName = "Momentum Sum";
+        String energyMomentumDiffName = "Energy-Momentum Difference";
+        String invariantMassName = "Invariant Mass";
+        String energySum2DName = "2D Energy Sum";
+        String momentumSum2DName = "2D Momentum Sum";
+        String positionName = "Track Cluster Position";
+        
+        // Get the histograms.
+        IHistogram1D[] tracks = {
+                (IHistogram1D) tree.find("Trident Analysis/All/" + trackName),
+                (IHistogram1D) tree.find("Trident Analysis/Cluster/" + trackName)
+        };
+        IHistogram1D[] posTracks = {
+                (IHistogram1D) tree.find("Trident Analysis/All/" + posTrackName),
+                (IHistogram1D) tree.find("Trident Analysis/Cluster/" + posTrackName)
+        };
+        IHistogram1D[] negTracks = {
+                (IHistogram1D) tree.find("Trident Analysis/All/" + negTrackName),
+                (IHistogram1D) tree.find("Trident Analysis/Cluster/" + negTrackName)
+        };
+        IHistogram1D[] posMomentum = {
+                (IHistogram1D) tree.find("Trident Analysis/All/" + posMomentumName),
+                (IHistogram1D) tree.find("Trident Analysis/Cluster/" + posMomentumName)
+        };
+        IHistogram1D[] negMomentum = {
+                (IHistogram1D) tree.find("Trident Analysis/All/" + negMomentumName),
+                (IHistogram1D) tree.find("Trident Analysis/Cluster/" + negMomentumName)
+        };
+        IHistogram1D[] energySum = {
+                (IHistogram1D) tree.find("Trident Analysis/All/" + energySumName),
+                (IHistogram1D) tree.find("Trident Analysis/Cluster/" + energySumName)
+        };
+        IHistogram1D[] momentumSum = {
+                (IHistogram1D) tree.find("Trident Analysis/All/" + momentumSumName),
+                (IHistogram1D) tree.find("Trident Analysis/Cluster/" + momentumSumName)
+        };
+        IHistogram1D[] energyMomentumDiff = {
+                (IHistogram1D) tree.find("Trident Analysis/All/" + energyMomentumDiffName),
+                (IHistogram1D) tree.find("Trident Analysis/Cluster/" + energyMomentumDiffName)
+        };
+        IHistogram1D[] invariantMass = {
+                (IHistogram1D) tree.find("Trident Analysis/All/" + invariantMassName),
+                (IHistogram1D) tree.find("Trident Analysis/Cluster/" + invariantMassName)
+        };
+        IHistogram2D[] energySum2D = {
+                (IHistogram2D) tree.find("Trident Analysis/All/" + energySum2DName),
+                (IHistogram2D) tree.find("Trident Analysis/Cluster/" + energySum2DName)
+        };
+        IHistogram2D[] momentumSum2D = {
+                (IHistogram2D) tree.find("Trident Analysis/All/" + momentumSum2DName),
+                (IHistogram2D) tree.find("Trident Analysis/Cluster/" + momentumSum2DName)
+        };
+        IHistogram2D[] position = {
+                (IHistogram2D) tree.find("Trident Analysis/All/" + positionName),
+                (IHistogram2D) tree.find("Trident Analysis/Cluster/" + positionName)
+        };
+        
+        // Re-bin the histograms to have 5-times larger bins. First,
+        // get the bin count and upper and lower bounds of the plot.
+        int bins = invariantMass[0].axis().bins();
+        double low = invariantMass[0].axis().binLowerEdge(0);
+        double high = invariantMass[0].axis().binUpperEdge(invariantMass[0].axis().bins() - 1);
+        
+        // Create new plots with the larger bin sizes.
+        AIDA aida = AIDA.defaultInstance();
+        IHistogram1D[] newPlot = new IHistogram1D[2];
+        newPlot[0] = aida.histogram1D(invariantMassName, bins / 5, low, high);
+        newPlot[1] = aida.histogram1D("Cluster " + invariantMassName, bins / 5, low, high);
+        
+        // Populate the new plots with the data from the old ones.
+        for(int j = 0; j < 2; j++) {
+            for(int i = 0; i < bins; i++) {
+                int entries = invariantMass[j].binEntries(i);
+                double center = invariantMass[j].axis().binCenter(i);
+                for(int k = 0; k < entries; k++) {
+                    newPlot[j].fill(center);
+                }
+            }
+        }
+        
+        // Replace the old plots.
+        invariantMass = newPlot;
+        
+        // Define the scaling factors for each plot.
+        double scaleFactor = 1;
+        
+        // Define the plot titles and arrays for 1D plots.
+        IHistogram[][] plots = { tracks, posTracks, negTracks, posMomentum, negMomentum, energySum, momentumSum, energyMomentumDiff, invariantMass };
+        String[] titles = { trackName, posTrackName, negTrackName, posMomentumName, negMomentumName, energySumName, momentumSumName,
+                energyMomentumDiffName, invariantMassName };
+        String[] xTitles = { "Tracks", "Tracks", "Tracks", "Momentum (GeV)", "Momentum (GeV)", "Energy Sum (GeV)", "Momentum Sum (GeV)",
+                "|E_Cluster - P_Track| (GeV)", "Invariant Mass (GeV)" };
+        String yTitle = "Count";
+        
+        // Define the plot titles and arrays for 2D plots.
+        IHistogram2D[][] plots2D = { energySum2D, momentumSum2D, position };
+        String[] titles2D = { energySum2DName, momentumSum2DName, positionName };
+        String[] xTitles2D = { "Positive Cluster Energy", "Positive Track Momentum", "x-Index" };
+        String[] yTitles2D = { "Negative Cluster Energy", "Negative Track Momentum", "y-Index" };
+        String zTitle2D = "Count";
+        
+        // Create a plotter factory.
+        IPlotterFactory plotterFactory = af.createPlotterFactory();
+        
+        // Format and display the basic histograms.
+        for(int i = 0; i < plots.length; i++) {
+            for(int j = 0; j < 2; j++) {
+                // Scale the histogram by the appropriate scaling factor.
+                plots[i][j].scale(1.0 / scaleFactor);
+                
+                // Create a plotter and plotting region for the plot.
+                IPlotter plotter = plotterFactory.create((j == 1 ? "Cluster " : "") + titles[i]);
+                plotter.createRegions(1);
+                plotter.region(0).plot(plots[i][j]);
+                
+                // Format the axis labels.
+                PlotterRegion region = (PlotterRegion) plotter.region(0);
+                region.getPlot().setTitle((j == 1 ? "Cluster " : "") + titles[i]);
+                region.getPlot().getXAxis().setLabel(xTitles[i]);
+                region.getPlot().getYAxis().setLabel(yTitle);
+                
+                // Format the fonts and general plot presentation.
+                PlotsFormatter.setDefault1DStyle(region, new ColorStyle[] { ColorStyle.GREY });
+                
+                // Show the plot.
+                plotter.setParameter("plotterWidth", "2000");
+                plotter.setParameter("plotterHeight", "1200");
+                plotter.show();
+            }
+        }
+        
+        // Format and display the 2D histogram.
+        for(int i = 0; i < plots2D.length; i++) {
+            for(int j = 0; j < 2; j++) {
+                plots2D[i][j].scale(1.0 / scaleFactor);
+                IPlotter plotter2D = plotterFactory.create((j == 1 ? "Cluster " : "") + titles2D[i]);
+                plotter2D.createRegions(1);
+                plotter2D.region(0).plot(plots2D[i][j]);
+                
+                // Format the axis labels.
+                PlotterRegion region2D = (PlotterRegion) plotter2D.region(0);
+                region2D.getPlot().setTitle((j == 1 ? "Cluster " : "") + titles2D[i]);
+                region2D.getPlot().getXAxis().setLabel(xTitles2D[i]);
+                region2D.getPlot().getYAxis().setLabel(yTitles2D[i]);
+                
+                // Format the fonts and general plot presentation.
+                PlotsFormatter.setDefault2DStyle(region2D, true);
+                
+                // Show the plot.
+                plotter2D.setParameter("plotterWidth", "2000");
+                plotter2D.setParameter("plotterHeight", "1200");
+                plotter2D.show();
+            }
+        }
+        
+        // Close the tree.
+        tree.close();
+    }
 }

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/plots/formatter/TriggerPlotsFormat.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/plots/formatter/TriggerPlotsFormat.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/kmccarty/plots/formatter/TriggerPlotsFormat.java	Wed Apr 27 11:11:32 2016
@@ -20,331 +20,331 @@
 import hep.aida.ref.plotter.PlotterRegion;
 
 public class TriggerPlotsFormat {
-	// Define plot fonts.
-	private static final Font BASIC_FONT = new Font("Calibri", Font.PLAIN, 20);
-	private static final Font AXIS_FONT  = new Font("Calibri", Font.BOLD,  25);
-	private static final Font TITLE_FONT = new Font("Calibri", Font.BOLD,  35);
-	
-	// Defines the color style options for plot data.
-	private enum ColorStyle {
-		 MS_BLUE(new Color( 79, 129, 189), new Color( 36,  64,  97)), MS_ORANGE(new Color(247, 150,  70), new Color(152,  72,   6)),
-		  MS_RED(new Color(192,  80,  77), new Color( 99,  36,  35)),      GREY(new Color(166, 166, 166), new Color( 89,  89,  89)),
-		MS_GREEN(new Color(155, 187,  89), new Color( 79,  98,  40)),   CRIMSON(new Color(161,   0,   0), new Color(104,   0,   0)),
-		    RUST(new Color(161,  80,   0), new Color(105,  80,   0)),    YELLOW(new Color(161, 161,   0), new Color(122, 109,   8)),
-		  FOREST(new Color( 65, 102,   0), new Color( 37,  79,   0)),     GREEN(new Color(  7, 132,  70), new Color(  7,  82,  30)),
-		    TEAL(new Color(  0, 130, 130), new Color(  0,  90, 100)),  CERULEAN(new Color(  0,  86, 130), new Color(  0,  28,  83)),
-		    BLUE(new Color(  0,  33, 203), new Color(  0,   0, 137)),    INDIGO(new Color( 68,  10, 127), new Color(  0,   0,  61)),
-		  PURPLE(new Color(106,   0, 106), new Color( 63,   0,  56)),   FUSCHIA(new Color(119,   0,  60), new Color( 60,   0,  60));
-		
-		private final Color fillColor;
-		private final Color lineColor;
-		
-		private ColorStyle(Color fillColor, Color lineColor) {
-			this.fillColor = fillColor;
-			this.lineColor = lineColor;
-		}
-		
-		public Color getFillColor() { return fillColor; }
-		
-		public Color getLineColor() { return lineColor; }
-	};
-		
-	/**
-	 * Loads all plots in a file and formats them according to the
-	 * indicated style.
-	 * @param args - Unused default executable parameter.
-	 * @throws IOException Occurs if there is an issue opening the file.
-	 */
-	public static void main(String[] args) throws IOException {
-		// Define the root directory for the plots.
-		String rootDir = "D:\\cygwin64\\home\\Kyle\\beam-plots\\base\\";
-		//String rootDir = "D:\\cygwin64\\home\\Kyle\\aprime-plots\\base\\readout-plots\\";
-		
-		// Define the new name of the file containing the trigger plots.
-		String[] plotFile = {
-				rootDir + "compiled-plots.aida"
-				//rootDir + "15-MeV\\compiled-plots.aida",
-				//rootDir + "20-MeV\\compiled-plots.aida",
-				//rootDir + "30-MeV\\compiled-plots.aida",
-				//rootDir + "40-MeV\\compiled-plots.aida",
-				//rootDir + "50-MeV\\compiled-plots.aida"
-		};
-		
-		// Define the names of each plot. This will be used for the
-		// legend in the case of multiple plots.
-		String[] treeName = {
-			"Background",
-			"15 MeV A'",
-			"20 MeV A'",
-			"30 MeV A'",
-			"40 MeV A'",
-			"50 MeV A'"
-		};
-		
-		// Define the color style for the plots.
-		ColorStyle[] dataColorStyle = {
-				ColorStyle.GREY,
-				ColorStyle.MS_GREEN,
-				ColorStyle.MS_BLUE,
-				ColorStyle.MS_ORANGE,
-				ColorStyle.MS_RED,
-				ColorStyle.TEAL,
-				ColorStyle.CRIMSON,
-				ColorStyle.FOREST
-		};
-		
-		// Get the plots file and open it.
-		IAnalysisFactory af = IAnalysisFactory.create();
-		ITree[] tree = new ITree[plotFile.length];
-		for(int i = 0; i < plotFile.length; i++) {
-			tree[i] = af.createTreeFactory().create(plotFile[i]);
-			if(tree[i] == null) { throw new IllegalArgumentException("Unable to load plot file."); }
-		}
-		
-		// Get a list of all the histograms in the file.
-		List<List<String>> treeHistograms = new ArrayList<List<String>>(plotFile.length);
-		for(int i = 0; i < plotFile.length; i++) {
-			treeHistograms.add(getHistograms(tree[i], "/NoCuts/"));//, "/PassedAll/"));
-		}
-		
-		// Create a plotter factory.
-		IPlotterFactory plotterFactory = af.createPlotterFactory();
-		
-		// Plot each histogram and format it.
-		for(String histogram : treeHistograms.get(0)) {
-			// Get the plot from the tree and verify that it is a 1D
-			// or 2D histogram. Other types are not supported.
-			IManagedObject histObject = tree[0].find(histogram);
-			if(!(histObject instanceof IHistogram1D) && !(histObject instanceof IHistogram2D)) {
-				continue;
-			}
-			
-			// Obtain the histogram object.
-			IBaseHistogram hist;
-			if(histObject instanceof IHistogram1D) { hist = (IHistogram1D) histObject; }
-			else { hist = (IHistogram2D) histObject; }
-			
-			// Define whether this is an overlay plot and whether
-			// this is a one or two dimensional plot.
-			boolean overlay = plotFile.length > 1;
-			boolean twoDimensional = hist instanceof IHistogram2D;
-			
-			// Generate the plotter and set its title. The plotter will
-			// use the title of the first tree's plot.
-			String plotTitle = hist.title();
-			IPlotter plotter = plotterFactory.create(plotTitle);
-			
-			// For single plots and one-dimensional overlay plots,
-			// there should only be a single plotter region.
-			if(!twoDimensional || !overlay) { plotter.createRegions(1); }
-			
-			// For two-dimensional overlay plots, create a region for
-			// each plot individually.
-			else { plotter.createRegions(2, (int) Math.ceil(plotFile.length / 2.0)); }
-			
-			// Find the histogram in each of the trees and plot them
-			// all on the same region.
-			for(int i = 0; i < plotFile.length; i++) {
-				// Get the histogram from the tree.
-				IManagedObject treeObject = tree[i].find(histogram);
-				IBaseHistogram treeHist;
-				if(treeObject instanceof IHistogram1D) { treeHist = (IHistogram1D) treeObject; }
-				else { treeHist = (IHistogram2D) treeObject; }
-				
-				// Display the plot.
-				if(treeHist != null) {
-					// Set the title of plot to the name associated with
-					// its tree. This ensures that the correct name will
-					// appear on the legend.
-					if(plotFile.length > 1) {
-						treeHist.setTitle(treeName[i]);
-					}
-					
-					// Plot the tree's data in the plotter region.
-					if(!twoDimensional || !overlay) { plotter.region(0).plot(treeHist); }
-					else {
-						plotter.region(i).plot(treeHist);
-						setDefault2DStyle(((PlotterRegion) plotter.region(i)), dataColorStyle);
-					}
-				}
-			}
-			
-			// Format the plot region.
-			if(!twoDimensional) { setDefault1DStyle(((PlotterRegion) plotter.region(0)), dataColorStyle); }
-			else { setDefault2DStyle(((PlotterRegion) plotter.region(0)), dataColorStyle); }
-			
-			// Show the plotter.
-			plotter.region(0).setTitle(plotTitle);
-			plotter.setParameter("plotterWidth", "750");
-			plotter.setParameter("plotterHeight", "600");
-			//plotter.setParameter("plotterWidth", "2000");
-			//plotter.setParameter("plotterHeight", "1200");
-			plotter.show();
-		}
-		
-		// Close the trees.
-		for(int i = 0; i < plotFile.length; i++) {
-			tree[i].close();
-		}
-	}
-	
-	/**
-	 * Sets the plot display formatting for 1D plots.
-	 * @param region - The plotter region to format.
-	 * @param color - The data color settings to use.
-	 */
-	private static final void setDefault1DStyle(PlotterRegion region, ColorStyle[] color) {
-		// Get the names of each plot on in the region.
-		String[] dataNames = region.getAllDataNames();
-		
-		// Check whether this is an overlay plot. Overlay plots contain
-		// more than one data name.
-		boolean overlay = (dataNames.length > 1 ? true : false);
-		
-		// Iterate over each plot in the region.
-		for(int i = 0; i < dataNames.length; i++) {
-			// Set the overlay style if needed.
-			if(overlay) {
-				// Get the fill style for the current data type.
-				JASHist1DHistogramStyle fillStyle = (JASHist1DHistogramStyle) region.getDataForName(dataNames[i]).getStyle();
-				
-				// Set the histogram style to display thick-lined bars
-				// with no fill. The color is set by the "color" argument.
-				fillStyle.setHistogramFill(false);
-				fillStyle.setHistogramBarLineWidth(3);
-				fillStyle.setHistogramBarLineColor(color[i].getFillColor());
-				
-				// Set the legend text style.
-				region.getPlot().getLegend().setFont(new Font("Calibri", Font.PLAIN, 20));
-			}
-			
-			// Otherwise, set the fill style for a single plot.
-			else {
-				// Get the fill style for the current data type.
-				JASHist1DHistogramStyle fillStyle = (JASHist1DHistogramStyle) region.getDataForName(dataNames[i]).getStyle();
-				
-				// Set the histogram style to display thick-lined bars
-				// with a fill color. The colors are defined by the
-				// "color" argument.
-				fillStyle.setHistogramBarLineWidth(3);
-				fillStyle.setHistogramBarColor(color[i].getFillColor());
-				fillStyle.setHistogramBarLineColor(color[i].getLineColor());
-			}
-			
-			// Set the statistics box style.
-			region.getPlot().getStats().setVisible(true);
-			region.getPlot().getStats().setFont(BASIC_FONT);
-			
-			// Set the title font.
-			region.getPlot().getTitleObject().setFont(TITLE_FONT);
-			
-			// Set generic axis titles.
-			region.getPlot().getXAxis().setLabel("Data Label (Unit)");
-			region.getPlot().getYAxis().setLabel("Count");
-			
-			// Set the axis tick-mark fonts.
-			region.getPlot().getXAxis().setFont(BASIC_FONT);
-			region.getPlot().getYAxis().setFont(BASIC_FONT);
-			region.getPlot().getXAxis().getLabelObject().setFont(AXIS_FONT);
-			region.getPlot().getYAxis().getLabelObject().setFont(AXIS_FONT);
-		}
-	}
-	
-	/**
-	 * Sets the plot display formatting for 1D plots.
-	 * @param region - The plotter region to format.
-	 * @param color - The data color settings to use.
-	 */
-	private static final void setDefault2DStyle(PlotterRegion region, ColorStyle[] color) {
-		// Get the fill style object. 2D plots should never be overlay
-		// plots, so there should only ever be one data name.
-		JASHist2DHistogramStyle fillStyle = (JASHist2DHistogramStyle) region.getDataForName(region.getAllDataNames()[0]).getStyle();
-		
-		// Set the fill style for a two-dimensional plot.
-		fillStyle.setLogZ(true);
-		fillStyle.setHistStyle(JASHist2DHistogramStyle.STYLE_COLORMAP);
-		fillStyle.setColorMapScheme(JASHist2DHistogramStyle.COLORMAP_RAINBOW);
-		
-		// Make the statistics box invisible.
-		region.getPlot().getStats().setVisible(false);
-		
-		// Set the general plot font (which is also the z-axis font).
-		region.getPlot().setFont(BASIC_FONT);
-		
-		// Set the title font.
-		region.getPlot().getTitleObject().setFont(TITLE_FONT);
-		
-		// Set generic axis titles.
-		region.getPlot().getXAxis().setLabel("Data Label (Unit)");
-		region.getPlot().getYAxis().setLabel("Data Label (Unit)");
-		
-		// Set the axis tick-mark fonts.
-		region.getPlot().getXAxis().setFont(BASIC_FONT);
-		region.getPlot().getYAxis().setFont(BASIC_FONT);
-		region.getPlot().getXAxis().getLabelObject().setFont(AXIS_FONT);
-		region.getPlot().getYAxis().getLabelObject().setFont(AXIS_FONT);
-	}
-	
-	/**
-	 * Gets a list of all objects that are not directories in a tree.
-	 * @param tree - The tree from which to extract the object names.
-	 * @return Returns the object names as <code>String</code> objects
-	 * in a <code>List</code> collection.
-	 */
-	private static final List<String> getHistograms(ITree tree) {
-		return getHistograms(tree, "/");
-	}
-	
-	/**
-	 * Gets a list of all objects that are not directories in a tree.
-	 * @param tree - The tree from which to extract the object names.
-	 * @return Returns the object names as <code>String</code> objects
-	 * in a <code>List</code> collection.
-	 */
-	private static final List<String> getHistograms(ITree tree, String rootDir) {
-		return getHistograms(tree, rootDir, new ArrayList<String>());
-	}
-	
-	/**
-	 * Recursive method that gets all object names from a tree that
-	 * are not directories. Method should not be called directly, but
-	 * rather called only through the <code>getHistograms(ITree)</code>
-	 * method.
-	 * @param tree - The tree from which to obtain the object names.
-	 * @param directory - The directory in which to search for objects.
-	 * @param list - The list in which to place the objects.
-	 * @return Returns the <code>List</code> collection that was given
-	 * as an argument.
-	 */
-	private static final List<String> getHistograms(ITree tree, String directory, List<String> list) {
-		// Get the list of objects in the directory.
-		String[] treeObjects = tree.listObjectNames(directory);
-		
-		// Print the objects.
-		for(String objectName : treeObjects) {
-			// Check if the object is a directory.
-			boolean isDirectory = isDirectory(objectName);
-			
-			// If the object is a directory, get the histograms from it.
-			if(isDirectory) {
-				getHistograms(tree, objectName, list);
-			}
-			
-			// If the object is a plot, add it to the list.
-			else { list.add(objectName); }
-		}
-		
-		// Return the list.
-		return list;
-	}
-	
-	/**
-	 * Checks whether a tree object is a directory.
-	 * @param object - The object to check.
-	 * @return Returns <code>true</code> if the object is a directory
-	 * and <code>false</code> otherwise.
-	 */
-	private static final boolean isDirectory(String object) {
-		return (object.toCharArray()[object.length() - 1] == '/');
-	}
+    // Define plot fonts.
+    private static final Font BASIC_FONT = new Font("Calibri", Font.PLAIN, 20);
+    private static final Font AXIS_FONT  = new Font("Calibri", Font.BOLD,  25);
+    private static final Font TITLE_FONT = new Font("Calibri", Font.BOLD,  35);
+    
+    // Defines the color style options for plot data.
+    private enum ColorStyle {
+         MS_BLUE(new Color( 79, 129, 189), new Color( 36,  64,  97)), MS_ORANGE(new Color(247, 150,  70), new Color(152,  72,   6)),
+          MS_RED(new Color(192,  80,  77), new Color( 99,  36,  35)),      GREY(new Color(166, 166, 166), new Color( 89,  89,  89)),
+        MS_GREEN(new Color(155, 187,  89), new Color( 79,  98,  40)),   CRIMSON(new Color(161,   0,   0), new Color(104,   0,   0)),
+            RUST(new Color(161,  80,   0), new Color(105,  80,   0)),    YELLOW(new Color(161, 161,   0), new Color(122, 109,   8)),
+          FOREST(new Color( 65, 102,   0), new Color( 37,  79,   0)),     GREEN(new Color(  7, 132,  70), new Color(  7,  82,  30)),
+            TEAL(new Color(  0, 130, 130), new Color(  0,  90, 100)),  CERULEAN(new Color(  0,  86, 130), new Color(  0,  28,  83)),
+            BLUE(new Color(  0,  33, 203), new Color(  0,   0, 137)),    INDIGO(new Color( 68,  10, 127), new Color(  0,   0,  61)),
+          PURPLE(new Color(106,   0, 106), new Color( 63,   0,  56)),   FUSCHIA(new Color(119,   0,  60), new Color( 60,   0,  60));
+        
+        private final Color fillColor;
+        private final Color lineColor;
+        
+        private ColorStyle(Color fillColor, Color lineColor) {
+            this.fillColor = fillColor;
+            this.lineColor = lineColor;
+        }
+        
+        public Color getFillColor() { return fillColor; }
+        
+        public Color getLineColor() { return lineColor; }
+    };
+        
+    /**
+     * Loads all plots in a file and formats them according to the
+     * indicated style.
+     * @param args - Unused default executable parameter.
+     * @throws IOException Occurs if there is an issue opening the file.
+     */
+    public static void main(String[] args) throws IOException {
+        // Define the root directory for the plots.
+        String rootDir = "D:\\cygwin64\\home\\Kyle\\beam-plots\\base\\";
+        //String rootDir = "D:\\cygwin64\\home\\Kyle\\aprime-plots\\base\\readout-plots\\";
+        
+        // Define the new name of the file containing the trigger plots.
+        String[] plotFile = {
+                rootDir + "compiled-plots.aida"
+                //rootDir + "15-MeV\\compiled-plots.aida",
+                //rootDir + "20-MeV\\compiled-plots.aida",
+                //rootDir + "30-MeV\\compiled-plots.aida",
+                //rootDir + "40-MeV\\compiled-plots.aida",
+                //rootDir + "50-MeV\\compiled-plots.aida"
+        };
+        
+        // Define the names of each plot. This will be used for the
+        // legend in the case of multiple plots.
+        String[] treeName = {
+            "Background",
+            "15 MeV A'",
+            "20 MeV A'",
+            "30 MeV A'",
+            "40 MeV A'",
+            "50 MeV A'"
+        };
+        
+        // Define the color style for the plots.
+        ColorStyle[] dataColorStyle = {
+                ColorStyle.GREY,
+                ColorStyle.MS_GREEN,
+                ColorStyle.MS_BLUE,
+                ColorStyle.MS_ORANGE,
+                ColorStyle.MS_RED,
+                ColorStyle.TEAL,
+                ColorStyle.CRIMSON,
+                ColorStyle.FOREST
+        };
+        
+        // Get the plots file and open it.
+        IAnalysisFactory af = IAnalysisFactory.create();
+        ITree[] tree = new ITree[plotFile.length];
+        for(int i = 0; i < plotFile.length; i++) {
+            tree[i] = af.createTreeFactory().create(plotFile[i]);
+            if(tree[i] == null) { throw new IllegalArgumentException("Unable to load plot file."); }
+        }
+        
+        // Get a list of all the histograms in the file.
+        List<List<String>> treeHistograms = new ArrayList<List<String>>(plotFile.length);
+        for(int i = 0; i < plotFile.length; i++) {
+            treeHistograms.add(getHistograms(tree[i], "/NoCuts/"));//, "/PassedAll/"));
+        }
+        
+        // Create a plotter factory.
+        IPlotterFactory plotterFactory = af.createPlotterFactory();
+        
+        // Plot each histogram and format it.
+        for(String histogram : treeHistograms.get(0)) {
+            // Get the plot from the tree and verify that it is a 1D
+            // or 2D histogram. Other types are not supported.
+            IManagedObject histObject = tree[0].find(histogram);
+            if(!(histObject instanceof IHistogram1D) && !(histObject instanceof IHistogram2D)) {
+                continue;
+            }
+            
+            // Obtain the histogram object.
+            IBaseHistogram hist;
+            if(histObject instanceof IHistogram1D) { hist = (IHistogram1D) histObject; }
+            else { hist = (IHistogram2D) histObject; }
+            
+            // Define whether this is an overlay plot and whether
+            // this is a one or two dimensional plot.
+            boolean overlay = plotFile.length > 1;
+            boolean twoDimensional = hist instanceof IHistogram2D;
+            
+            // Generate the plotter and set its title. The plotter will
+            // use the title of the first tree's plot.
+            String plotTitle = hist.title();
+            IPlotter plotter = plotterFactory.create(plotTitle);
+            
+            // For single plots and one-dimensional overlay plots,
+            // there should only be a single plotter region.
+            if(!twoDimensional || !overlay) { plotter.createRegions(1); }
+            
+            // For two-dimensional overlay plots, create a region for
+            // each plot individually.
+            else { plotter.createRegions(2, (int) Math.ceil(plotFile.length / 2.0)); }
+            
+            // Find the histogram in each of the trees and plot them
+            // all on the same region.
+            for(int i = 0; i < plotFile.length; i++) {
+                // Get the histogram from the tree.
+                IManagedObject treeObject = tree[i].find(histogram);
+                IBaseHistogram treeHist;
+                if(treeObject instanceof IHistogram1D) { treeHist = (IHistogram1D) treeObject; }
+                else { treeHist = (IHistogram2D) treeObject; }
+                
+                // Display the plot.
+                if(treeHist != null) {
+                    // Set the title of plot to the name associated with
+                    // its tree. This ensures that the correct name will
+                    // appear on the legend.
+                    if(plotFile.length > 1) {
+                        treeHist.setTitle(treeName[i]);
+                    }
+                    
+                    // Plot the tree's data in the plotter region.
+                    if(!twoDimensional || !overlay) { plotter.region(0).plot(treeHist); }
+                    else {
+                        plotter.region(i).plot(treeHist);
+                        setDefault2DStyle(((PlotterRegion) plotter.region(i)), dataColorStyle);
+                    }
+                }
+            }
+            
+            // Format the plot region.
+            if(!twoDimensional) { setDefault1DStyle(((PlotterRegion) plotter.region(0)), dataColorStyle); }
+            else { setDefault2DStyle(((PlotterRegion) plotter.region(0)), dataColorStyle); }
+            
+            // Show the plotter.
+            plotter.region(0).setTitle(plotTitle);
+            plotter.setParameter("plotterWidth", "750");
+            plotter.setParameter("plotterHeight", "600");
+            //plotter.setParameter("plotterWidth", "2000");
+            //plotter.setParameter("plotterHeight", "1200");
+            plotter.show();
+        }
+        
+        // Close the trees.
+        for(int i = 0; i < plotFile.length; i++) {
+            tree[i].close();
+        }
+    }
+    
+    /**
+     * Sets the plot display formatting for 1D plots.
+     * @param region - The plotter region to format.
+     * @param color - The data color settings to use.
+     */
+    private static final void setDefault1DStyle(PlotterRegion region, ColorStyle[] color) {
+        // Get the names of each plot on in the region.
+        String[] dataNames = region.getAllDataNames();
+        
+        // Check whether this is an overlay plot. Overlay plots contain
+        // more than one data name.
+        boolean overlay = (dataNames.length > 1 ? true : false);
+        
+        // Iterate over each plot in the region.
+        for(int i = 0; i < dataNames.length; i++) {
+            // Set the overlay style if needed.
+            if(overlay) {
+                // Get the fill style for the current data type.
+                JASHist1DHistogramStyle fillStyle = (JASHist1DHistogramStyle) region.getDataForName(dataNames[i]).getStyle();
+                
+                // Set the histogram style to display thick-lined bars
+                // with no fill. The color is set by the "color" argument.
+                fillStyle.setHistogramFill(false);
+                fillStyle.setHistogramBarLineWidth(3);
+                fillStyle.setHistogramBarLineColor(color[i].getFillColor());
+                
+                // Set the legend text style.
+                region.getPlot().getLegend().setFont(new Font("Calibri", Font.PLAIN, 20));
+            }
+            
+            // Otherwise, set the fill style for a single plot.
+            else {
+                // Get the fill style for the current data type.
+                JASHist1DHistogramStyle fillStyle = (JASHist1DHistogramStyle) region.getDataForName(dataNames[i]).getStyle();
+                
+                // Set the histogram style to display thick-lined bars
+                // with a fill color. The colors are defined by the
+                // "color" argument.
+                fillStyle.setHistogramBarLineWidth(3);
+                fillStyle.setHistogramBarColor(color[i].getFillColor());
+                fillStyle.setHistogramBarLineColor(color[i].getLineColor());
+            }
+            
+            // Set the statistics box style.
+            region.getPlot().getStats().setVisible(true);
+            region.getPlot().getStats().setFont(BASIC_FONT);
+            
+            // Set the title font.
+            region.getPlot().getTitleObject().setFont(TITLE_FONT);
+            
+            // Set generic axis titles.
+            region.getPlot().getXAxis().setLabel("Data Label (Unit)");
+            region.getPlot().getYAxis().setLabel("Count");
+            
+            // Set the axis tick-mark fonts.
+            region.getPlot().getXAxis().setFont(BASIC_FONT);
+            region.getPlot().getYAxis().setFont(BASIC_FONT);
+            region.getPlot().getXAxis().getLabelObject().setFont(AXIS_FONT);
+            region.getPlot().getYAxis().getLabelObject().setFont(AXIS_FONT);
+        }
+    }
+    
+    /**
+     * Sets the plot display formatting for 1D plots.
+     * @param region - The plotter region to format.
+     * @param color - The data color settings to use.
+     */
+    private static final void setDefault2DStyle(PlotterRegion region, ColorStyle[] color) {
+        // Get the fill style object. 2D plots should never be overlay
+        // plots, so there should only ever be one data name.
+        JASHist2DHistogramStyle fillStyle = (JASHist2DHistogramStyle) region.getDataForName(region.getAllDataNames()[0]).getStyle();
+        
+        // Set the fill style for a two-dimensional plot.
+        fillStyle.setLogZ(true);
+        fillStyle.setHistStyle(JASHist2DHistogramStyle.STYLE_COLORMAP);
+        fillStyle.setColorMapScheme(JASHist2DHistogramStyle.COLORMAP_RAINBOW);
+        
+        // Make the statistics box invisible.
+        region.getPlot().getStats().setVisible(false);
+        
+        // Set the general plot font (which is also the z-axis font).
+        region.getPlot().setFont(BASIC_FONT);
+        
+        // Set the title font.
+        region.getPlot().getTitleObject().setFont(TITLE_FONT);
+        
+        // Set generic axis titles.
+        region.getPlot().getXAxis().setLabel("Data Label (Unit)");
+        region.getPlot().getYAxis().setLabel("Data Label (Unit)");
+        
+        // Set the axis tick-mark fonts.
+        region.getPlot().getXAxis().setFont(BASIC_FONT);
+        region.getPlot().getYAxis().setFont(BASIC_FONT);
+        region.getPlot().getXAxis().getLabelObject().setFont(AXIS_FONT);
+        region.getPlot().getYAxis().getLabelObject().setFont(AXIS_FONT);
+    }
+    
+    /**
+     * Gets a list of all objects that are not directories in a tree.
+     * @param tree - The tree from which to extract the object names.
+     * @return Returns the object names as <code>String</code> objects
+     * in a <code>List</code> collection.
+     */
+    private static final List<String> getHistograms(ITree tree) {
+        return getHistograms(tree, "/");
+    }
+    
+    /**
+     * Gets a list of all objects that are not directories in a tree.
+     * @param tree - The tree from which to extract the object names.
+     * @return Returns the object names as <code>String</code> objects
+     * in a <code>List</code> collection.
+     */
+    private static final List<String> getHistograms(ITree tree, String rootDir) {
+        return getHistograms(tree, rootDir, new ArrayList<String>());
+    }
+    
+    /**
+     * Recursive method that gets all object names from a tree that
+     * are not directories. Method should not be called directly, but
+     * rather called only through the <code>getHistograms(ITree)</code>
+     * method.
+     * @param tree - The tree from which to obtain the object names.
+     * @param directory - The directory in which to search for objects.
+     * @param list - The list in which to place the objects.
+     * @return Returns the <code>List</code> collection that was given
+     * as an argument.
+     */
+    private static final List<String> getHistograms(ITree tree, String directory, List<String> list) {
+        // Get the list of objects in the directory.
+        String[] treeObjects = tree.listObjectNames(directory);
+        
+        // Print the objects.
+        for(String objectName : treeObjects) {
+            // Check if the object is a directory.
+            boolean isDirectory = isDirectory(objectName);
+            
+            // If the object is a directory, get the histograms from it.
+            if(isDirectory) {
+                getHistograms(tree, objectName, list);
+            }
+            
+            // If the object is a plot, add it to the list.
+            else { list.add(objectName); }
+        }
+        
+        // Return the list.
+        return list;
+    }
+    
+    /**
+     * Checks whether a tree object is a directory.
+     * @param object - The object to check.
+     * @return Returns <code>true</code> if the object is a directory
+     * and <code>false</code> otherwise.
+     */
+    private static final boolean isDirectory(String object) {
+        return (object.toCharArray()[object.length() - 1] == '/');
+    }
 }

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/luca/FADCVariableTriggerFEEDriver.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/luca/FADCVariableTriggerFEEDriver.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/luca/FADCVariableTriggerFEEDriver.java	Wed Apr 27 11:11:32 2016
@@ -25,64 +25,64 @@
     // ==================================================================
     // ==== Trigger Cut Default Parameters ==============================
     // ==================================================================
-    private int minHitCount = 1;								// Minimum required cluster hit count threshold. (Hits)			
-    private double seedEnergyHigh = Double.MAX_VALUE;			// Maximum allowed cluster seed energy. (GeV)
-    private double seedEnergyLow = Double.MIN_VALUE;			// Minimum required cluster seed energy. (GeV)
-    private double clusterEnergyHigh = 1.5 * EcalUtils.GeV;		// Maximum allowed cluster total energy. (GeV)
-    private double clusterEnergyLow = .1 * EcalUtils.GeV;		// Minimum required cluster total energy. (GeV)
-    private double energySumHigh = 1.9 * EcalUtils.GeV;			// Maximum allowed pair energy sum. (GeV)
-    private double energySumLow = 0.0 * EcalUtils.GeV;			// Minimum required pair energy sum. (GeV)
-    private double energyDifferenceHigh = 2.2 * EcalUtils.GeV;	// Maximum allowed pair energy difference. (GeV)
-    private double energySlopeLow = 1.1;						// Minimum required pair energy slope value.
-    private double coplanarityHigh = 35;						// Maximum allowed pair coplanarity deviation. (Degrees)
+    private int minHitCount = 1;                                // Minimum required cluster hit count threshold. (Hits)         
+    private double seedEnergyHigh = Double.MAX_VALUE;           // Maximum allowed cluster seed energy. (GeV)
+    private double seedEnergyLow = Double.MIN_VALUE;            // Minimum required cluster seed energy. (GeV)
+    private double clusterEnergyHigh = 1.5 * EcalUtils.GeV;     // Maximum allowed cluster total energy. (GeV)
+    private double clusterEnergyLow = .1 * EcalUtils.GeV;       // Minimum required cluster total energy. (GeV)
+    private double energySumHigh = 1.9 * EcalUtils.GeV;         // Maximum allowed pair energy sum. (GeV)
+    private double energySumLow = 0.0 * EcalUtils.GeV;          // Minimum required pair energy sum. (GeV)
+    private double energyDifferenceHigh = 2.2 * EcalUtils.GeV;  // Maximum allowed pair energy difference. (GeV)
+    private double energySlopeLow = 1.1;                        // Minimum required pair energy slope value.
+    private double coplanarityHigh = 35;                        // Maximum allowed pair coplanarity deviation. (Degrees)
     
     // ==================================================================
     // ==== Trigger General Default Parameters ==========================
     // ==================================================================
-    private String clusterCollectionName = "EcalClusters";		// Name for the LCIO cluster collection.
-    private int pairCoincidence = 2;							// Maximum allowed time difference between clusters. (4 ns clock-cycles)
-    private double energySlopeParamF = 0.005500;				// A parameter value used for the energy slope calculation.
-    private double originX = 1393.0 * Math.tan(0.03052);		// ECal mid-plane, defined by photon beam position (30.52 mrad) at ECal face (z=1393 mm)
-    private int backgroundLevel = -1;							// Automatically sets the cuts to achieve a predetermined background rate.
+    private String clusterCollectionName = "EcalClusters";      // Name for the LCIO cluster collection.
+    private int pairCoincidence = 2;                            // Maximum allowed time difference between clusters. (4 ns clock-cycles)
+    private double energySlopeParamF = 0.005500;                // A parameter value used for the energy slope calculation.
+    private double originX = 1393.0 * Math.tan(0.03052);        // ECal mid-plane, defined by photon beam position (30.52 mrad) at ECal face (z=1393 mm)
+    private int backgroundLevel = -1;                           // Automatically sets the cuts to achieve a predetermined background rate.
     
     // ==================================================================
     // ==== Driver Internal Variables ===================================
     // ==================================================================
-    private Queue<List<Cluster>> topClusterQueue = null;	// Store clusters on the top half of the calorimeter.
-    private Queue<List<Cluster>> botClusterQueue = null;	// Store clusters on the bottom half of the calorimeter.
-    private int allClusters = 0;								// Track the number of clusters processed.
-    private int allPairs = 0;									// Track the number of cluster pairs processed.
-    private int clusterTotalEnergyCount = 0;					// Track the clusters which pass the total energy cut.
-    private int clusterSeedEnergyCount = 0;						// Track the clusters which pass the seed energy cut.
-    private int clusterHitCountCount = 0;						// Track the clusters which pass the hit count cut.
-    private int pairEnergySumCount = 0;							// Track the pairs which pass the energy sum cut.
-    private int pairEnergyDifferenceCount = 0;					// Track the pairs which pass the energy difference cut.
-    private int pairEnergySlopeCount = 0;						// Track the pairs which pass the energy slope cut.
-    private int pairCoplanarityCount = 0;						// Track the pairs which pass the coplanarity cut.
+    private Queue<List<Cluster>> topClusterQueue = null;    // Store clusters on the top half of the calorimeter.
+    private Queue<List<Cluster>> botClusterQueue = null;    // Store clusters on the bottom half of the calorimeter.
+    private int allClusters = 0;                                // Track the number of clusters processed.
+    private int allPairs = 0;                                   // Track the number of cluster pairs processed.
+    private int clusterTotalEnergyCount = 0;                    // Track the clusters which pass the total energy cut.
+    private int clusterSeedEnergyCount = 0;                     // Track the clusters which pass the seed energy cut.
+    private int clusterHitCountCount = 0;                       // Track the clusters which pass the hit count cut.
+    private int pairEnergySumCount = 0;                         // Track the pairs which pass the energy sum cut.
+    private int pairEnergyDifferenceCount = 0;                  // Track the pairs which pass the energy difference cut.
+    private int pairEnergySlopeCount = 0;                       // Track the pairs which pass the energy slope cut.
+    private int pairCoplanarityCount = 0;                       // Track the pairs which pass the coplanarity cut.
     
     /**
      * Prints out the results of the trigger at the end of the run.
      */
     @Override
     public void endOfData() {
-    	// Print out the results of the trigger cuts.
-    	System.out.printf("Trigger Processing Results%n");
-    	System.out.printf("\tSingle-Cluster Cuts%n");
-    	System.out.printf("\t\tTotal Clusters Processed     :: %d%n", allClusters);
-    	System.out.printf("\t\tPassed Seed Energy Cut       :: %d%n", clusterSeedEnergyCount);
-    	System.out.printf("\t\tPassed Hit Count Cut         :: %d%n", clusterHitCountCount);
-    	System.out.printf("\t\tPassed Total Energy Cut      :: %d%n", clusterTotalEnergyCount);
-    	System.out.printf("%n");
-    	System.out.printf("\tCluster Pair Cuts%n");
-    	System.out.printf("\t\tTotal Pairs Processed        :: %d%n", allPairs);
-    	System.out.printf("\t\tPassed Energy Sum Cut        :: %d%n", pairEnergySumCount);
-    	System.out.printf("\t\tPassed Energy Difference Cut :: %d%n", pairEnergyDifferenceCount);
-    	System.out.printf("\t\tPassed Energy Slope Cut      :: %d%n", pairEnergySlopeCount);
-    	System.out.printf("\t\tPassed Coplanarity Cut       :: %d%n", pairCoplanarityCount);
-    	System.out.printf("%n");
-    	System.out.printf("\tTrigger Count :: %d%n", numTriggers);
-    	
-    	// Run the superclass method.
+        // Print out the results of the trigger cuts.
+        System.out.printf("Trigger Processing Results%n");
+        System.out.printf("\tSingle-Cluster Cuts%n");
+        System.out.printf("\t\tTotal Clusters Processed     :: %d%n", allClusters);
+        System.out.printf("\t\tPassed Seed Energy Cut       :: %d%n", clusterSeedEnergyCount);
+        System.out.printf("\t\tPassed Hit Count Cut         :: %d%n", clusterHitCountCount);
+        System.out.printf("\t\tPassed Total Energy Cut      :: %d%n", clusterTotalEnergyCount);
+        System.out.printf("%n");
+        System.out.printf("\tCluster Pair Cuts%n");
+        System.out.printf("\t\tTotal Pairs Processed        :: %d%n", allPairs);
+        System.out.printf("\t\tPassed Energy Sum Cut        :: %d%n", pairEnergySumCount);
+        System.out.printf("\t\tPassed Energy Difference Cut :: %d%n", pairEnergyDifferenceCount);
+        System.out.printf("\t\tPassed Energy Slope Cut      :: %d%n", pairEnergySlopeCount);
+        System.out.printf("\t\tPassed Coplanarity Cut       :: %d%n", pairCoplanarityCount);
+        System.out.printf("%n");
+        System.out.printf("\tTrigger Count :: %d%n", numTriggers);
+        
+        // Run the superclass method.
         super.endOfData();
     }
     
@@ -92,53 +92,53 @@
      */
     @Override
     public void process(EventHeader event) {
-    	// Process the list of clusters for the event, if it exists.
+        // Process the list of clusters for the event, if it exists.
         if (event.hasCollection(Cluster.class, clusterCollectionName)) {
-        	// Get the collection of clusters.
-        	List<Cluster> clusterList = event.get(Cluster.class, clusterCollectionName);
-        	
-        	// Create a list to hold clusters which pass the single
-        	// cluster cuts.
-        	List<Cluster> goodClusterList = new ArrayList<Cluster>(clusterList.size());
-        	
-        	// Sort through the cluster list and add clusters that pass
-        	// the single cluster cuts to the good list.
-        	clusterLoop:
-        	for(Cluster cluster : clusterList) {
-        		// Increment the number of processed clusters.
-        		allClusters++;
-        		
-        		// ==== Seed Hit Energy Cut ====================================
-        		// =============================================================
-        		// If the cluster fails the cut, skip to the next cluster.
-        		if(!clusterSeedEnergyCut(cluster)) { continue clusterLoop; }
-        		
-        		// Otherwise, note that it passed the cut.
-        		clusterSeedEnergyCount++;
-        		
-        		// ==== Cluster Hit Count Cut ==================================
-        		// =============================================================
-        		// If the cluster fails the cut, skip to the next cluster.
-        		if(!clusterHitCountCut(cluster)) { continue clusterLoop; }
-        		
-        		// Otherwise, note that it passed the cut.
-        		clusterHitCountCount++;
-        		
-        		// ==== Cluster Total Energy Cut ===============================
-        		// =============================================================
-        		// If the cluster fails the cut, skip to the next cluster.
-        		if(!clusterTotalEnergyCut(cluster)) { continue clusterLoop; }
-        		
-        		// Otherwise, note that it passed the cut.
-        		clusterTotalEnergyCount++;
-        		
-        		// A cluster that passes all of the single-cluster cuts
-        		// can be used in cluster pairs.
-        		goodClusterList.add(cluster);
-        	}
-        	
-        	// Put the good clusters into the cluster queue.
-        	updateClusterQueues(goodClusterList);
+            // Get the collection of clusters.
+            List<Cluster> clusterList = event.get(Cluster.class, clusterCollectionName);
+            
+            // Create a list to hold clusters which pass the single
+            // cluster cuts.
+            List<Cluster> goodClusterList = new ArrayList<Cluster>(clusterList.size());
+            
+            // Sort through the cluster list and add clusters that pass
+            // the single cluster cuts to the good list.
+            clusterLoop:
+            for(Cluster cluster : clusterList) {
+                // Increment the number of processed clusters.
+                allClusters++;
+                
+                // ==== Seed Hit Energy Cut ====================================
+                // =============================================================
+                // If the cluster fails the cut, skip to the next cluster.
+                if(!clusterSeedEnergyCut(cluster)) { continue clusterLoop; }
+                
+                // Otherwise, note that it passed the cut.
+                clusterSeedEnergyCount++;
+                
+                // ==== Cluster Hit Count Cut ==================================
+                // =============================================================
+                // If the cluster fails the cut, skip to the next cluster.
+                if(!clusterHitCountCut(cluster)) { continue clusterLoop; }
+                
+                // Otherwise, note that it passed the cut.
+                clusterHitCountCount++;
+                
+                // ==== Cluster Total Energy Cut ===============================
+                // =============================================================
+                // If the cluster fails the cut, skip to the next cluster.
+                if(!clusterTotalEnergyCut(cluster)) { continue clusterLoop; }
+                
+                // Otherwise, note that it passed the cut.
+                clusterTotalEnergyCount++;
+                
+                // A cluster that passes all of the single-cluster cuts
+                // can be used in cluster pairs.
+                goodClusterList.add(cluster);
+            }
+            
+            // Put the good clusters into the cluster queue.
+            updateClusterQueues(goodClusterList);
         }
         
         // Perform the superclass event processing.
@@ -152,7 +152,7 @@
      * be set. Actual background rates equal about (5 * backgroundLevel) kHz.
      */
     public void setBackgroundLevel(int backgroundLevel) {
-    	this.backgroundLevel = backgroundLevel;
+        this.backgroundLevel = backgroundLevel;
     }
     
     /**
@@ -215,7 +215,7 @@
      * @param energySlopeLow - The parameter value.
      */
     public void setEnergySlopeLow(double energySlopeLow) {
-    	this.energySlopeLow = energySlopeLow;
+        this.energySlopeLow = energySlopeLow;
     }
     
     /**
@@ -299,12 +299,12 @@
      */
     @Override
     public void startOfData() {
-    	// Make sure that a valid cluster collection name has been
-    	// defined. If it has not, throw an exception.
+        // Make sure that a valid cluster collection name has been
+        // defined. If it has not, throw an exception.
         if (clusterCollectionName == null) {
             throw new RuntimeException("The parameter clusterCollectionName was not set!");
         }
-    	
+        
         // Initialize the top and bottom cluster queues.
         topClusterQueue = new LinkedList<List<Cluster>>();
         botClusterQueue = new LinkedList<List<Cluster>>();
@@ -345,9 +345,9 @@
         for (Cluster botCluster : botClusterQueue.element()) {
             for (List<Cluster> topClusters : topClusterQueue) {
                 for (Cluster topCluster : topClusters) {
-                	// The first cluster in a pair should always be
-                	// the higher energy cluster. If the top cluster
-                	// is higher energy, it goes first.
+                    // The first cluster in a pair should always be
+                    // the higher energy cluster. If the top cluster
+                    // is higher energy, it goes first.
                     if (topCluster.getEnergy() > botCluster.getEnergy()) {
                         Cluster[] clusterPair = {topCluster, botCluster};
                         clusterPairs.add(clusterPair);
@@ -366,24 +366,24 @@
         return clusterPairs;
     }
     
-	/**
-	 * Determines if the event produces a trigger.
-	 * 
-	 * @return Returns <code>true</code> if the event produces a trigger
-	 * and <code>false</code> if it does not.
-	 */
-	@Override
-	protected boolean triggerDecision(EventHeader event) {
-    	// If there is a list of clusters present for this event,
-    	// check whether it passes the trigger conditions.
-    	if (event.hasCollection(Cluster.class, clusterCollectionName)) {
-        	return testTrigger();
+    /**
+     * Determines if the event produces a trigger.
+     * 
+     * @return Returns <code>true</code> if the event produces a trigger
+     * and <code>false</code> if it does not.
+     */
+    @Override
+    protected boolean triggerDecision(EventHeader event) {
+        // If there is a list of clusters present for this event,
+        // check whether it passes the trigger conditions.
+        if (event.hasCollection(Cluster.class, clusterCollectionName)) {
+            return testTrigger();
         }
         
         // Otherwise, this event can not produce a trigger and should
         // return false automatically.
         else { return false; }
-	}
+    }
     
     /**
      * Checks whether the argument cluster possesses the minimum
@@ -394,7 +394,7 @@
      * and <code>false</code> if the cluster does not.
      */
     private boolean clusterHitCountCut(Cluster cluster) {
-    	return (getValueClusterHitCount(cluster) >= minHitCount);
+        return (getValueClusterHitCount(cluster) >= minHitCount);
     }
     
     /**
@@ -406,12 +406,12 @@
      * and <code>false</code> if the cluster does not.
      */
     private boolean clusterSeedEnergyCut(Cluster cluster) {
-    	// Get the cluster seed energy.
-    	double energy = getValueClusterSeedEnergy(cluster);
-    	
-    	// Check that it is above the minimum threshold and below the
-    	// maximum threshold.
-    	return (energy < seedEnergyHigh) && (energy > seedEnergyLow);
+        // Get the cluster seed energy.
+        double energy = getValueClusterSeedEnergy(cluster);
+        
+        // Check that it is above the minimum threshold and below the
+        // maximum threshold.
+        return (energy < seedEnergyHigh) && (energy > seedEnergyLow);
     }
     
     /**
@@ -423,12 +423,12 @@
      * and <code>false</code> if the cluster does not.
      */
     private boolean clusterTotalEnergyCut(Cluster cluster) {
-    	// Get the total cluster energy.
-    	double energy = getValueClusterTotalEnergy(cluster);
-    	
-    	// Check that it is above the minimum threshold and below the
-    	// maximum threshold.
-    	return (energy < clusterEnergyHigh) && (energy > clusterEnergyLow);
+        // Get the total cluster energy.
+        double energy = getValueClusterTotalEnergy(cluster);
+        
+        // Check that it is above the minimum threshold and below the
+        // maximum threshold.
+        return (energy < clusterEnergyHigh) && (energy > clusterEnergyLow);
     }
     
     /**
@@ -450,7 +450,7 @@
      * @return Returns the cut value.
      */
     private double getValueClusterTotalEnergy(Cluster cluster) {
-    	return cluster.getEnergy();
+        return cluster.getEnergy();
     }
     
     /**
@@ -461,7 +461,7 @@
      * @return Returns the cut value.
      */
     private int getValueClusterHitCount(Cluster cluster) {
-    	return cluster.getCalorimeterHits().size();
+        return cluster.getCalorimeterHits().size();
     }
     
     /**
@@ -472,7 +472,7 @@
      * @return Returns the cut value.
      */
     private double getValueClusterSeedEnergy(Cluster cluster) {
-    	return cluster.getCalorimeterHits().get(0).getCorrectedEnergy();
+        return cluster.getCalorimeterHits().get(0).getCorrectedEnergy();
     }
     
     /**
@@ -483,16 +483,16 @@
      * @return Returns the cut value.
      */
     private double getValueCoplanarity(Cluster[] clusterPair) {
-    	// Get the cluster angles.
-    	double[] clusterAngle = new double[2];
-    	for(int i = 0; i < 2; i++) {
+        // Get the cluster angles.
+        double[] clusterAngle = new double[2];
+        for(int i = 0; i < 2; i++) {
             double position[] = clusterPair[i].getCalorimeterHits().get(0).getPosition();
             //clusterAngle[i] = Math.toDegrees(Math.atan2(position[1], position[0] - originX));
             //clusterAngle[i] = (clusterAngle[i] + 180.0) % 180.0;
             clusterAngle[i] = (Math.toDegrees(Math.atan2(position[1], position[0] - originX)) + 180.0) % 180.0;
-    	}
-    	
-    	// Calculate the coplanarity cut value.
+        }
+        
+        // Calculate the coplanarity cut value.
         return Math.abs(clusterAngle[1] - clusterAngle[0]);
     }
     
@@ -504,7 +504,7 @@
      * @return Returns the cut value.
      */
     private double getValueEnergyDifference(Cluster[] clusterPair) {
-    	return clusterPair[0].getEnergy() - clusterPair[1].getEnergy();
+        return clusterPair[0].getEnergy() - clusterPair[1].getEnergy();
     }
     
     /**
@@ -515,15 +515,15 @@
      * @return Returns the cut value.
      */
     private double getValueEnergySlope(Cluster[] clusterPair) {
-    	// E + R*F
-    	// Get the low energy cluster energy.
-    	double slopeParamE = clusterPair[1].getEnergy();
-    	
-    	// Get the low energy cluster radial distance.
-    	double slopeParamR = getClusterDistance(clusterPair[1]);
-    	
-    	// Calculate the energy slope.
-    	return slopeParamE + slopeParamR * energySlopeParamF;
+        // E + R*F
+        // Get the low energy cluster energy.
+        double slopeParamE = clusterPair[1].getEnergy();
+        
+        // Get the low energy cluster radial distance.
+        double slopeParamR = getClusterDistance(clusterPair[1]);
+        
+        // Calculate the energy slope.
+        return slopeParamE + slopeParamR * energySlopeParamF;
     }
     
     /**
@@ -534,7 +534,7 @@
      * @return Returns the cut value.
      */
     private double getValueEnergySum(Cluster[] clusterPair) {
-    	return clusterPair[0].getEnergy() + clusterPair[1].getEnergy();
+        return clusterPair[0].getEnergy() + clusterPair[1].getEnergy();
     }
     
     /**
@@ -570,7 +570,7 @@
      * @return true if pair is found, false otherwise
      */
     private boolean pairEnergySlopeCut(Cluster[] clusterPair) {
-    	return (getValueEnergySlope(clusterPair) > energySlopeLow);
+        return (getValueEnergySlope(clusterPair) > energySlopeLow);
     }
     
     /**
@@ -582,175 +582,175 @@
      * the cut and <code>false</code> if it does not.
      */
     private boolean pairEnergySumCut(Cluster[] clusterPair) {
-    	// Get the energy sum value.
-    	double energySum = getValueEnergySum(clusterPair);
-    	
-    	// Check that it is within the allowed range.
+        // Get the energy sum value.
+        double energySum = getValueEnergySum(clusterPair);
+        
+        // Check that it is within the allowed range.
         return (energySum < energySumHigh) && (energySum > energySumLow);
     }
-	
+    
     private void setBackgroundCuts(int backgroundLevel) {
-    	// Make sure that the background level is valid.
-    	if(backgroundLevel < 1 || backgroundLevel > 10) {
-    		throw new RuntimeException(String.format("Trigger cuts are undefined for background level %d.", backgroundLevel));
-    	}
-    	
-    	// Otherwise, set the trigger cuts. Certain cuts are constant
-    	// across all background levels.
-    	clusterEnergyLow = 0.000;
-    	seedEnergyLow = 0.100;
-    	
-    	// Set the variable values.
-    	if(backgroundLevel == 1) {
-    		clusterEnergyHigh = 1.700;
-    		seedEnergyHigh = 1.300;
-    		energySumLow = 0.400;
-    		energySumHigh = 2.00;
-    		energyDifferenceHigh = 1.500;
-    		energySlopeLow = 1.0;
-    		coplanarityHigh = 40;
-    		minHitCount = 2;
-    	} else if(backgroundLevel == 2) {
-    		clusterEnergyHigh = 1.600;
-    		seedEnergyHigh = 1.200;
-    		energySumLow = 0.300;
-    		energySumHigh = 2.00;
-    		energyDifferenceHigh = 1.400;
-    		energySlopeLow = 0.8;
-    		coplanarityHigh = 40;
-    		minHitCount = 2;
-    	} else if(backgroundLevel == 3) {
-    		clusterEnergyHigh = 1.600;
-    		seedEnergyHigh = 1.200;
-    		energySumLow = 0.200;
-    		energySumHigh = 2.000;
-    		energyDifferenceHigh = 1.400;
-    		energySlopeLow = 0.7;
-    		coplanarityHigh = 40;
-    		minHitCount = 2;
-    	} else if(backgroundLevel == 4) {
-    		clusterEnergyHigh = 1.500;
-    		seedEnergyHigh = 1.200;
-    		energySumLow = 0.500;
-    		energySumHigh = 1.950;
-    		energyDifferenceHigh = 1.400;
-    		energySlopeLow = 0.6;
-    		coplanarityHigh = 40;
-    		minHitCount = 2;
-    	} else if(backgroundLevel == 5) {
-    		clusterEnergyHigh = 1.500;
-    		seedEnergyHigh = 1.200;
-    		energySumLow = 0.400;
-    		energySumHigh = 2.000;
-    		energyDifferenceHigh = 1.400;
-    		energySlopeLow = 0.6;
-    		coplanarityHigh = 45;
-    		minHitCount = 2;
-    	} else if(backgroundLevel == 6) {
-    		clusterEnergyHigh = 1.500;
-    		seedEnergyHigh = 1.200;
-    		energySumLow = 0.200;
-    		energySumHigh = 1.950;
-    		energyDifferenceHigh = 1.400;
-    		energySlopeLow = 0.6;
-    		coplanarityHigh = 55;
-    		minHitCount = 2;
-    	} else if(backgroundLevel == 7) {
-    		clusterEnergyHigh = 1.700;
-    		seedEnergyHigh = 1.200;
-    		energySumLow = 0.200;
-    		energySumHigh = 2.000;
-    		energyDifferenceHigh = 1.500;
-    		energySlopeLow = 0.6;
-    		coplanarityHigh = 60;
-    		minHitCount = 2;
-    	} else if(backgroundLevel == 8) {
-    		clusterEnergyHigh = 1.700;
-    		seedEnergyHigh = 1.300;
-    		energySumLow = 0.200;
-    		energySumHigh = 2.000;
-    		energyDifferenceHigh = 1.500;
-    		energySlopeLow = 0.6;
-    		coplanarityHigh = 65;
-    		minHitCount = 2;
-    	} else if(backgroundLevel == 9) {
-    		clusterEnergyHigh = 1.500;
-    		seedEnergyHigh = 1.200;
-    		energySumLow = 0.400;
-    		energySumHigh = 1.950;
-    		energyDifferenceHigh = 1.400;
-    		energySlopeLow = 0.5;
-    		coplanarityHigh = 60;
-    		minHitCount = 2;
-    	} else if(backgroundLevel == 10) {
-    		clusterEnergyHigh = 1.500;
-    		seedEnergyHigh = 1.200;
-    		energySumLow = 0.400;
-    		energySumHigh = 2.000;
-    		energyDifferenceHigh = 1.400;
-    		energySlopeLow = 0.5;
-    		coplanarityHigh = 65;
-    		minHitCount = 2;
-    	}
-    }
-    
-	/**
-	 * Tests all of the current cluster pairs for triggers.
-	 * 
-	 * @return Returns <code>true</code> if one of the cluster pairs
-	 * passes all of the cluster cuts and <code>false</code> otherwise.
-	 */
+        // Make sure that the background level is valid.
+        if(backgroundLevel < 1 || backgroundLevel > 10) {
+            throw new RuntimeException(String.format("Trigger cuts are undefined for background level %d.", backgroundLevel));
+        }
+        
+        // Otherwise, set the trigger cuts. Certain cuts are constant
+        // across all background levels.
+        clusterEnergyLow = 0.000;
+        seedEnergyLow = 0.100;
+        
+        // Set the variable values.
+        if(backgroundLevel == 1) {
+            clusterEnergyHigh = 1.700;
+            seedEnergyHigh = 1.300;
+            energySumLow = 0.400;
+            energySumHigh = 2.00;
+            energyDifferenceHigh = 1.500;
+            energySlopeLow = 1.0;
+            coplanarityHigh = 40;
+            minHitCount = 2;
+        } else if(backgroundLevel == 2) {
+            clusterEnergyHigh = 1.600;
+            seedEnergyHigh = 1.200;
+            energySumLow = 0.300;
+            energySumHigh = 2.00;
+            energyDifferenceHigh = 1.400;
+            energySlopeLow = 0.8;
+            coplanarityHigh = 40;
+            minHitCount = 2;
+        } else if(backgroundLevel == 3) {
+            clusterEnergyHigh = 1.600;
+            seedEnergyHigh = 1.200;
+            energySumLow = 0.200;
+            energySumHigh = 2.000;
+            energyDifferenceHigh = 1.400;
+            energySlopeLow = 0.7;
+            coplanarityHigh = 40;
+            minHitCount = 2;
+        } else if(backgroundLevel == 4) {
+            clusterEnergyHigh = 1.500;
+            seedEnergyHigh = 1.200;
+            energySumLow = 0.500;
+            energySumHigh = 1.950;
+            energyDifferenceHigh = 1.400;
+            energySlopeLow = 0.6;
+            coplanarityHigh = 40;
+            minHitCount = 2;
+        } else if(backgroundLevel == 5) {
+            clusterEnergyHigh = 1.500;
+            seedEnergyHigh = 1.200;
+            energySumLow = 0.400;
+            energySumHigh = 2.000;
+            energyDifferenceHigh = 1.400;
+            energySlopeLow = 0.6;
+            coplanarityHigh = 45;
+            minHitCount = 2;
+        } else if(backgroundLevel == 6) {
+            clusterEnergyHigh = 1.500;
+            seedEnergyHigh = 1.200;
+            energySumLow = 0.200;
+            energySumHigh = 1.950;
+            energyDifferenceHigh = 1.400;
+            energySlopeLow = 0.6;
+            coplanarityHigh = 55;
+            minHitCount = 2;
+        } else if(backgroundLevel == 7) {
+            clusterEnergyHigh = 1.700;
+            seedEnergyHigh = 1.200;
+            energySumLow = 0.200;
+            energySumHigh = 2.000;
+            energyDifferenceHigh = 1.500;
+            energySlopeLow = 0.6;
+            coplanarityHigh = 60;
+            minHitCount = 2;
+        } else if(backgroundLevel == 8) {
+            clusterEnergyHigh = 1.700;
+            seedEnergyHigh = 1.300;
+            energySumLow = 0.200;
+            energySumHigh = 2.000;
+            energyDifferenceHigh = 1.500;
+            energySlopeLow = 0.6;
+            coplanarityHigh = 65;
+            minHitCount = 2;
+        } else if(backgroundLevel == 9) {
+            clusterEnergyHigh = 1.500;
+            seedEnergyHigh = 1.200;
+            energySumLow = 0.400;
+            energySumHigh = 1.950;
+            energyDifferenceHigh = 1.400;
+            energySlopeLow = 0.5;
+            coplanarityHigh = 60;
+            minHitCount = 2;
+        } else if(backgroundLevel == 10) {
+            clusterEnergyHigh = 1.500;
+            seedEnergyHigh = 1.200;
+            energySumLow = 0.400;
+            energySumHigh = 2.000;
+            energyDifferenceHigh = 1.400;
+            energySlopeLow = 0.5;
+            coplanarityHigh = 65;
+            minHitCount = 2;
+        }
+    }
+    
+    /**
+     * Tests all of the current cluster pairs for triggers.
+     * 
+     * @return Returns <code>true</code> if one of the cluster pairs
+     * passes all of the cluster cuts and <code>false</code> otherwise.
+     */
     private boolean testTrigger() {
-    	// Get the list of cluster pairs.
-    	List<Cluster[]> clusterPairs = getClusterPairsTopBot();
+        // Get the list of cluster pairs.
+        List<Cluster[]> clusterPairs = getClusterPairsTopBot();
         
         // Iterate over the cluster pairs and perform each of the cluster
         // pair cuts on them. A cluster pair that passes all of the
         // cuts registers as a trigger.
-    	pairLoop:
+        pairLoop:
         for (Cluster[] clusterPair : clusterPairs) {
-    		// Increment the number of processed cluster pairs.
-    		allPairs++;
-    		
-    		// ==== Pair Energy Sum Cut ====================================
-    		// =============================================================
-    		// If the cluster fails the cut, skip to the next pair.
-    		if(!pairEnergySumCut(clusterPair)) { continue pairLoop; }
-    		
-    		// Otherwise, note that it passed the cut.
-    		pairEnergySumCount++;
-        	
-    		// ==== Pair Energy Difference Cut =============================
-    		// =============================================================
-    		// If the cluster fails the cut, skip to the next pair.
-    		if(!pairEnergyDifferenceCut(clusterPair)) { continue pairLoop; }
-    		
-    		// Otherwise, note that it passed the cut.
-    		pairEnergyDifferenceCount++;
-    		
-    		// ==== Pair Energy Slope Cut ==================================
-    		// =============================================================
-    		// If the cluster fails the cut, skip to the next pair.
-    		//if(!energyDistanceCut(clusterPair)) { continue pairLoop; }
-    		if(!pairEnergySlopeCut(clusterPair)) { continue pairLoop; }
-    		
-    		// Otherwise, note that it passed the cut.
-    		pairEnergySlopeCount++;
-    		
-    		// ==== Pair Coplanarity Cut ===================================
-    		// =============================================================
-    		// If the cluster fails the cut, skip to the next pair.
-    		if(!pairCoplanarityCut(clusterPair)) { continue pairLoop; }
-    		
-    		// Otherwise, note that it passed the cut.
-    		pairCoplanarityCount++;
-    		
-    		// Clusters that pass all of the pair cuts produce a trigger.
-    		return true;
+            // Increment the number of processed cluster pairs.
+            allPairs++;
+            
+            // ==== Pair Energy Sum Cut ====================================
+            // =============================================================
+            // If the cluster fails the cut, skip to the next pair.
+            if(!pairEnergySumCut(clusterPair)) { continue pairLoop; }
+            
+            // Otherwise, note that it passed the cut.
+            pairEnergySumCount++;
+            
+            // ==== Pair Energy Difference Cut =============================
+            // =============================================================
+            // If the cluster fails the cut, skip to the next pair.
+            if(!pairEnergyDifferenceCut(clusterPair)) { continue pairLoop; }
+            
+            // Otherwise, note that it passed the cut.
+            pairEnergyDifferenceCount++;
+            
+            // ==== Pair Energy Slope Cut ==================================
+            // =============================================================
+            // If the cluster fails the cut, skip to the next pair.
+            //if(!energyDistanceCut(clusterPair)) { continue pairLoop; }
+            if(!pairEnergySlopeCut(clusterPair)) { continue pairLoop; }
+            
+            // Otherwise, note that it passed the cut.
+            pairEnergySlopeCount++;
+            
+            // ==== Pair Coplanarity Cut ===================================
+            // =============================================================
+            // If the cluster fails the cut, skip to the next pair.
+            if(!pairCoplanarityCut(clusterPair)) { continue pairLoop; }
+            
+            // Otherwise, note that it passed the cut.
+            pairCoplanarityCount++;
+            
+            // Clusters that pass all of the pair cuts produce a trigger.
+            return true;
         }
         
         // If the loop terminates without producing a trigger, there
-    	// are no cluster pairs which meet the trigger conditions.
+        // are no cluster pairs which meet the trigger conditions.
         return false;
     }
     
@@ -761,14 +761,14 @@
      * @param clusterList - The clusters to add to the queues.
      */
     private void updateClusterQueues(List<Cluster> clusterList) {
-    	// Create lists to store the top and bottom clusters.
+        // Create lists to store the top and bottom clusters.
         ArrayList<Cluster> topClusterList = new ArrayList<Cluster>();
         ArrayList<Cluster> botClusterList = new ArrayList<Cluster>();
         
         // Loop over the clusters in the cluster list.
         for (Cluster cluster : clusterList) {
-        	// If the cluster is on the top of the calorimeter, it
-        	// goes into the top cluster list.
+            // If the cluster is on the top of the calorimeter, it
+            // goes into the top cluster list.
             if (cluster.getCalorimeterHits().get(0).getIdentifierFieldValue("iy") > 0) {
                 topClusterList.add(cluster);
             }

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/luca/FEETrigger.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/luca/FEETrigger.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/luca/FEETrigger.java	Wed Apr 27 11:11:32 2016
@@ -15,209 +15,209 @@
  * @author Luca Colaneri
  */
 public class FEETrigger extends TriggerDriver {
-	// Store the LCIO cluster collection name.
-	private String clusterCollectionName = "EcalClusters";
-	
-	// Store the cluster total energy trigger threshold.
-	private double energyThreshold = 1.5;
-	
-	// Track the number of over-threshold clusters in each region.
-	private int zone1Count = 0;
-	private int zone2Count = 0;
-	private int zone3Count = 0;
-	
+    // Store the LCIO cluster collection name.
+    private String clusterCollectionName = "EcalClusters";
+    
+    // Store the cluster total energy trigger threshold.
+    private double energyThreshold = 1.5;
+    
+    // Track the number of over-threshold clusters in each region.
+    private int zone1Count = 0;
+    private int zone2Count = 0;
+    private int zone3Count = 0;
+    
     // The number of cluster over threshold that must occur in a region
-	// before a trigger occurs.
-	private int zone1Prescaling = 50;
-	private int zone2Prescaling = 10;
-	
-	/**
-	 * Sets the energy threshold required for a cluster to be counted.
-	 * 
-	 * @param energyThreshold - The energy threshold in GeV.
-	 */
-	public void setEnergyThreshold(int energyThreshold) {
-		this.energyThreshold = energyThreshold;
-	}
-	
-	/**
-	 * Sets the number of events over threshold which must occur in the
-	 * first region in order for a trigger to occur.
-	 * 
-	 * @param zone1Prescaling - The number of over-threshold clusters needed
-	 * for a trigger.
-	 */
-	public void setZone1Prescaling(int zone1Prescaling) {
-		this.zone1Prescaling = zone1Prescaling;
-	}
-	
-	/**
-	 * Sets the number of events over threshold which must occur in the
-	 * second region in order for a trigger to occur.
-	 * 
-	 * @param zone2Prescaling - The number of over-threshold clusters needed
-	 * for a trigger.
-	 */
-	public void setZone2Prescaling(int zone2Prescaling) {
-		this.zone2Prescaling = zone2Prescaling;
-	}
-	
-	/**
-	 * Checks if any clusters exist over the set energy threshold and,
-	 * if they do, increments the appropriate over-threshold count
-	 * variable for the zone in which the cluster resides.
-	 * 
-	 * @param event - The event from which clusters should be extracted.
-	 */
-	@Override
-	public void process(EventHeader event) {
-		if(event.hasCollection(Cluster.class, clusterCollectionName)) {
-			// Get the list of clusters from the event.
-			List<Cluster> clusterList = event.get(Cluster.class, clusterCollectionName);
-			
-			// Loop over the clusters and check for any that pass the threshold.
-			for(Cluster cluster : clusterList) {
-				// Check if the current cluster exceeds the energy
-				// threshold. If it does not, continue to the next
-				// cluster in the list.
-				if(cluster.getEnergy() > energyThreshold) {
-					// Get the x-index of the seed hit.
-					int ix = cluster.getCalorimeterHits().get(0).getIdentifierFieldValue("ix");
-					
-					// Determine in which region the cluster is located
-					// and increment the counter for that region. Zones
-					// are defined as:
-					// Zone 1 is -13 < ix < -4 and 14 < ix < 21  MISTAKE!!! it's all reversed!! remember!!!
-					// Zone 2 is -20 < ix < -14 and ix > 20
-					// Zone 3 is -23 <= ix < -18
+    // before a trigger occurs.
+    private int zone1Prescaling = 50;
+    private int zone2Prescaling = 10;
+    
+    /**
+     * Sets the energy threshold required for a cluster to be counted.
+     * 
+     * @param energyThreshold - The energy threshold in GeV.
+     */
+    public void setEnergyThreshold(int energyThreshold) {
+        this.energyThreshold = energyThreshold;
+    }
+    
+    /**
+     * Sets the number of events over threshold which must occur in the
+     * first region in order for a trigger to occur.
+     * 
+     * @param zone1Prescaling - The number of over-threshold clusters needed
+     * for a trigger.
+     */
+    public void setZone1Prescaling(int zone1Prescaling) {
+        this.zone1Prescaling = zone1Prescaling;
+    }
+    
+    /**
+     * Sets the number of events over threshold which must occur in the
+     * second region in order for a trigger to occur.
+     * 
+     * @param zone2Prescaling - The number of over-threshold clusters needed
+     * for a trigger.
+     */
+    public void setZone2Prescaling(int zone2Prescaling) {
+        this.zone2Prescaling = zone2Prescaling;
+    }
+    
+    /**
+     * Checks if any clusters exist over the set energy threshold and,
+     * if they do, increments the appropriate over-threshold count
+     * variable for the zone in which the cluster resides.
+     * 
+     * @param event - The event from which clusters should be extracted.
+     */
+    @Override
+    public void process(EventHeader event) {
+        if(event.hasCollection(Cluster.class, clusterCollectionName)) {
+            // Get the list of clusters from the event.
+            List<Cluster> clusterList = event.get(Cluster.class, clusterCollectionName);
+            
+            // Loop over the clusters and check for any that pass the threshold.
+            for(Cluster cluster : clusterList) {
+                // Check if the current cluster exceeds the energy
+                // threshold. If it does not, continue to the next
+                // cluster in the list.
+                if(cluster.getEnergy() > energyThreshold) {
+                    // Get the x-index of the seed hit.
+                    int ix = cluster.getCalorimeterHits().get(0).getIdentifierFieldValue("ix");
+                    
+                    // Determine in which region the cluster is located
+                    // and increment the counter for that region. Zones
+                    // are defined as:
+                    // Zone 1 is -13 < ix < -4 and 14 < ix < 21  MISTAKE!!! it's all reversed!! remember!!!
+                    // Zone 2 is -20 < ix < -14 and ix > 20
+                    // Zone 3 is -23 <= ix < -18
                                         //V3
                                         /*
-					if( ix > 18 || ix < -22) { zone3Count++; }
-					if(ix < 19 && ix  > 12 )  { zone2Count++; }
-					if((ix > 4 && ix < 13) || (ix > -23 && ix < -14)) { zone1Count++; }
+                    if( ix > 18 || ix < -22) { zone3Count++; }
+                    if(ix < 19 && ix  > 12 )  { zone2Count++; }
+                    if((ix > 4 && ix < 13) || (ix > -23 && ix < -14)) { zone1Count++; }
                                         */
                                         //V2
                                         /*
-					if( ix > 18 ) { zone3Count++; }
-					if(ix < 19 && ix  > 12 || ix <-20)  { zone2Count++; }
-					if((ix > 4 && ix < 13) || (ix > -21 && ix < -14)) { zone1Count++; }
+                    if( ix > 18 ) { zone3Count++; }
+                    if(ix < 19 && ix  > 12 || ix <-20)  { zone2Count++; }
+                    if((ix > 4 && ix < 13) || (ix > -21 && ix < -14)) { zone1Count++; }
                                         */
                                         
                                         //v4/*
                                         /*
                                         if( ix > 19 || ix < -22) { zone3Count++; }
-					if(ix < 20 && ix  > 12 || ix <-20 && ix > -23)  { zone2Count++; }
-					if((ix > 4 && ix < 13) || (ix > -21 && ix < -14)) { zone1Count++; }
+                    if(ix < 20 && ix  > 12 || ix <-20 && ix > -23)  { zone2Count++; }
+                    if((ix > 4 && ix < 13) || (ix > -21 && ix < -14)) { zone1Count++; }
                                         */
                                         //V prova
                                        /* 
-					if( ix != 50 ) { zone2Count++; }
-					*/
+                    if( ix != 50 ) { zone2Count++; }
+                    */
                                         //V6
                                         /*
                                         if( ix > 19 || ix < -22) { zone3Count++; }
-					if(ix < 20 && ix  > 8 || ix <-16 && ix > -23)  { zone2Count++; }
-					if((ix > 4 && ix < 9) || (ix > -17 && ix < -14)) { zone1Count++; }
+                    if(ix < 20 && ix  > 8 || ix <-16 && ix > -23)  { zone2Count++; }
+                    if((ix > 4 && ix < 9) || (ix > -17 && ix < -14)) { zone1Count++; }
                                         */
                                         //V7
                                         /*
                                         if( ix > 19 || ix < -22) { zone3Count++; }
-					if(ix < 20 && ix  > 15 )  { zone2Count++; }
-					if((ix > 5 && ix < 16) || (ix > -23 && ix < -14)) { zone1Count++; }
+                    if(ix < 20 && ix  > 15 )  { zone2Count++; }
+                    if((ix > 5 && ix < 16) || (ix > -23 && ix < -14)) { zone1Count++; }
                                         */
                                         //V8
                                         /*
                                         if( ix > 19 || ix < -17) { zone3Count++; } //x1
-					if(ix < 20 && ix  > 9 )  { zone2Count++; }//x10
-					if((ix > 5 && ix < 10) || (ix > -18 && ix < -14)) { zone1Count++; }    //x50
+                    if(ix < 20 && ix  > 9 )  { zone2Count++; }//x10
+                    if((ix > 5 && ix < 10) || (ix > -18 && ix < -14)) { zone1Count++; }    //x50
                                         }*/
                                          //V9
                                         /*
                                         if( ix > 19 || ix < -21) { zone3Count++; } //x1
-					if(ix < 20 && ix  > 9 || ix > -22 && ix <-17)  { zone2Count++; }//x10
-					if((ix > 5 && ix < 10) || (ix > -18 && ix < -14)) { zone1Count++; }    //x50
+                    if(ix < 20 && ix  > 9 || ix > -22 && ix <-17)  { zone2Count++; }//x10
+                    if((ix > 5 && ix < 10) || (ix > -18 && ix < -14)) { zone1Count++; }    //x50
                                         */ 
                                         //10
                                         
                                         /*
                                         if( ix > 19 || ix < -22) { zone3Count++; } //x1
-					if(ix < 20 && ix  > 9 || ix > -22 && ix <-17)  { zone2Count++; }//x10
-					if((ix > 5 && ix < 10) || (ix > -18 && ix < -14)) { zone1Count++; }    //x50
+                    if(ix < 20 && ix  > 9 || ix > -22 && ix <-17)  { zone2Count++; }//x10
+                    if((ix > 5 && ix < 10) || (ix > -18 && ix < -14)) { zone1Count++; }    //x50
                                         */
                                         
                                         //V11
                                         
                                         if( ix > 19 || ix < -22) { zone3Count++; } //x1
-					if(ix < 20 && ix  > 11 || ix > -22 && ix <-19)  { zone2Count++; }//x10
-					if((ix > 5 && ix < 12) || (ix > -20 && ix < -14)) { zone1Count++; }    //x50
+                    if(ix < 20 && ix  > 11 || ix > -22 && ix <-19)  { zone2Count++; }//x10
+                    if((ix > 5 && ix < 12) || (ix > -20 && ix < -14)) { zone1Count++; }    //x50
                                 
                                 }
-			}
-		}
-		
-		// Run the superclass event processing.
-		super.process(event);
-	}
-	
-	/**
-	 * Checks whether or not a trigger occurred.
-	 * 
-	 * @param event - The event on which to base the trigger decision.
-	 * @return Returns <code>true</code> if a trigger occurred and <code>
-	 * false</code> if a trigger did not.
-	 */
-	@Override
-	protected boolean triggerDecision(EventHeader event) {
-		// Check if the event has clusters. An event with no clusters
-		// should never result in a trigger.
-		if(event.hasCollection(Cluster.class, clusterCollectionName)) {
-			// Check if any of the zone counts are high enough to trigger.
-			return triggerTest();
-		}
-		
-		// Events without clusters can not trigger.
-		else { return false; }
-	}
-	
-	/**
-	 * Checks if any of the regional counts are sufficiently high to
-	 * register a trigger.
-	 * 
-	 * @return Returns <code>true</code> if a region has enough clusters
-	 * to trigger and <code>false</code> otherwise.
-	 */
-	private boolean triggerTest() {
-		// Track whether a trigger occurred.
-		boolean trigger = false;
-		
-		// If any clusters occur in zone 3, reset the count and note
-		// that a trigger occurred.
-		if(zone3Count > 0) {
-			zone3Count = 0;
+            }
+        }
+        
+        // Run the superclass event processing.
+        super.process(event);
+    }
+    
+    /**
+     * Checks whether or not a trigger occurred.
+     * 
+     * @param event - The event on which to base the trigger decision.
+     * @return Returns <code>true</code> if a trigger occurred and <code>
+     * false</code> if a trigger did not.
+     */
+    @Override
+    protected boolean triggerDecision(EventHeader event) {
+        // Check if the event has clusters. An event with no clusters
+        // should never result in a trigger.
+        if(event.hasCollection(Cluster.class, clusterCollectionName)) {
+            // Check if any of the zone counts are high enough to trigger.
+            return triggerTest();
+        }
+        
+        // Events without clusters can not trigger.
+        else { return false; }
+    }
+    
+    /**
+     * Checks if any of the regional counts are sufficiently high to
+     * register a trigger.
+     * 
+     * @return Returns <code>true</code> if a region has enough clusters
+     * to trigger and <code>false</code> otherwise.
+     */
+    private boolean triggerTest() {
+        // Track whether a trigger occurred.
+        boolean trigger = false;
+        
+        // If any clusters occur in zone 3, reset the count and note
+        // that a trigger occurred.
+        if(zone3Count > 0) {
+            zone3Count = 0;
                          if(zone2Count==zone2Prescaling){zone2Count=0;}
                          if(zone1Count==zone1Prescaling){zone1Count=0;}
-			trigger = true;
-		}
-		
-		// If zone 2 has sufficient clusters (100 by default) to
-		// trigger, reset its count and note that a trigger occurred.
-		else if(zone2Count == zone2Prescaling) {
-			zone2Count = 0;
+            trigger = true;
+        }
+        
+        // If zone 2 has sufficient clusters (100 by default) to
+        // trigger, reset its count and note that a trigger occurred.
+        else if(zone2Count == zone2Prescaling) {
+            zone2Count = 0;
                         if(zone3Count>0){zone3Count=0;}
                         if(zone1Count==zone1Prescaling){zone1Count=0;}
-			trigger = true;
-		}
-		
-		// If zone 3 has sufficient clusters (1000 by default) to
-		// trigger, reset its count and note that a trigger occurred.
-		else if(zone1Count == zone1Prescaling) {
-			zone1Count = 0;
+            trigger = true;
+        }
+        
+        // If zone 3 has sufficient clusters (1000 by default) to
+        // trigger, reset its count and note that a trigger occurred.
+        else if(zone1Count == zone1Prescaling) {
+            zone1Count = 0;
                         if(zone3Count>0){zone3Count=0;}
                         if(zone2Count==zone2Prescaling){zone2Count=0;}
-			trigger = true;
-		}
-		
-		// Return whether or not a trigger occurred.
-		return trigger;
-	}
+            trigger = true;
+        }
+        
+        // Return whether or not a trigger occurred.
+        return trigger;
+    }
 }

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/luca/FEETrigger2.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/luca/FEETrigger2.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/luca/FEETrigger2.java	Wed Apr 27 11:11:32 2016
@@ -15,159 +15,159 @@
  * @author Luca Colaneri
  */
 public class FEETrigger2 extends TriggerDriver {
-	// Store the LCIO cluster collection name.
-	private String clusterCollectionName = "EcalClusters";
-	
-	// Store the cluster total energy trigger threshold.
-	private double energyThreshold = 1.5;
-	
-	// Track the number of over-threshold clusters in each region.
-	private int zone1Count = 0;
-	private int zone2Count = 0;
-	private int zone3Count = 0;
+    // Store the LCIO cluster collection name.
+    private String clusterCollectionName = "EcalClusters";
+    
+    // Store the cluster total energy trigger threshold.
+    private double energyThreshold = 1.5;
+    
+    // Track the number of over-threshold clusters in each region.
+    private int zone1Count = 0;
+    private int zone2Count = 0;
+    private int zone3Count = 0;
         private int zone4Count = 0;
-	
+    
     // The number of cluster over threshold that must occur in a region
-	// before a trigger occurs.
-	private int zone1Prescaling = 1000;
-	private int zone2Prescaling = 70;
-	private int zone4Prescaling = 200;
-	/**
-	 * Sets the energy threshold required for a cluster to be counted.
-	 * 
-	 * @param energyThreshold - The energy threshold in GeV.
-	 */
-	public void setEnergyThreshold(int energyThreshold) {
-		this.energyThreshold = energyThreshold;
-	}
-	
-	/**
-	 * Sets the number of events over threshold which must occur in the
-	 * first region in order for a trigger to occur.
-	 * 
-	 * @param zone1Prescaling - The number of over-threshold clusters needed
-	 * for a trigger.
-	 */
-	public void setZone1Prescaling(int zone1Prescaling) {
-		this.zone1Prescaling = zone1Prescaling;
-	}
-	
-	/**
-	 * Sets the number of events over threshold which must occur in the
-	 * second region in order for a trigger to occur.
-	 * 
-	 * @param zone2Prescaling - The number of over-threshold clusters needed
-	 * for a trigger.
-	 */
-	public void setZone2Prescaling(int zone2Prescaling) {
-		this.zone2Prescaling = zone2Prescaling;
-	}
-	
-	/**
-	 * Checks if any clusters exist over the set energy threshold and,
-	 * if they do, increments the appropriate over-threshold count
-	 * variable for the zone in which the cluster resides.
-	 * 
-	 * @param event - The event from which clusters should be extracted.
-	 */
-	@Override
-	public void process(EventHeader event) {
-		if(event.hasCollection(Cluster.class, clusterCollectionName)) {
-			// Get the list of clusters from the event.
-			List<Cluster> clusterList = event.get(Cluster.class, clusterCollectionName);
-			
-			// Loop over the clusters and check for any that pass the threshold.
-			for(Cluster cluster : clusterList) {
-				// Check if the current cluster exceeds the energy
-				// threshold. If it does not, continue to the next
-				// cluster in the list.
-				if(cluster.getEnergy() > energyThreshold) {
-					// Get the x-index of the seed hit.
-					int ix = cluster.getCalorimeterHits().get(0).getIdentifierFieldValue("ix");
-					
-					// Determine in which region the cluster is located
-					// and increment the counter for that region. Zones
-					// are defined as:
-					// Zone 1 is -13 < ix < -4 and 14 < ix < 21
-					// Zone 2 is -20 < ix < -14 and ix > 20
-					// Zone 3 is -23 <= ix < -19
-					if(-23 <= ix && ix < -19) { zone3Count++; }
-					if((-20 < ix && ix < -14))  { zone2Count++; }
-					if((-13 < ix && ix < -4) || (14 < ix && ix < 21)) { zone1Count++; }
+    // before a trigger occurs.
+    private int zone1Prescaling = 1000;
+    private int zone2Prescaling = 70;
+    private int zone4Prescaling = 200;
+    /**
+     * Sets the energy threshold required for a cluster to be counted.
+     * 
+     * @param energyThreshold - The energy threshold in GeV.
+     */
+    public void setEnergyThreshold(int energyThreshold) {
+        this.energyThreshold = energyThreshold;
+    }
+    
+    /**
+     * Sets the number of events over threshold which must occur in the
+     * first region in order for a trigger to occur.
+     * 
+     * @param zone1Prescaling - The number of over-threshold clusters needed
+     * for a trigger.
+     */
+    public void setZone1Prescaling(int zone1Prescaling) {
+        this.zone1Prescaling = zone1Prescaling;
+    }
+    
+    /**
+     * Sets the number of events over threshold which must occur in the
+     * second region in order for a trigger to occur.
+     * 
+     * @param zone2Prescaling - The number of over-threshold clusters needed
+     * for a trigger.
+     */
+    public void setZone2Prescaling(int zone2Prescaling) {
+        this.zone2Prescaling = zone2Prescaling;
+    }
+    
+    /**
+     * Checks if any clusters exist over the set energy threshold and,
+     * if they do, increments the appropriate over-threshold count
+     * variable for the zone in which the cluster resides.
+     * 
+     * @param event - The event from which clusters should be extracted.
+     */
+    @Override
+    public void process(EventHeader event) {
+        if(event.hasCollection(Cluster.class, clusterCollectionName)) {
+            // Get the list of clusters from the event.
+            List<Cluster> clusterList = event.get(Cluster.class, clusterCollectionName);
+            
+            // Loop over the clusters and check for any that pass the threshold.
+            for(Cluster cluster : clusterList) {
+                // Check if the current cluster exceeds the energy
+                // threshold. If it does not, continue to the next
+                // cluster in the list.
+                if(cluster.getEnergy() > energyThreshold) {
+                    // Get the x-index of the seed hit.
+                    int ix = cluster.getCalorimeterHits().get(0).getIdentifierFieldValue("ix");
+                    
+                    // Determine in which region the cluster is located
+                    // and increment the counter for that region. Zones
+                    // are defined as:
+                    // Zone 1 is -13 < ix < -4 and 14 < ix < 21
+                    // Zone 2 is -20 < ix < -14 and ix > 20
+                    // Zone 3 is -23 <= ix < -19
+                    if(-23 <= ix && ix < -19) { zone3Count++; }
+                    if((-20 < ix && ix < -14))  { zone2Count++; }
+                    if((-13 < ix && ix < -4) || (14 < ix && ix < 21)) { zone1Count++; }
                                         if(ix>20){zone4Count++;}
-				}
-			}
-		}
-		
-		// Run the superclass event processing.
-		super.process(event);
-	}
-	
-	/**
-	 * Checks whether or not a trigger occurred.
-	 * 
-	 * @param event - The event on which to base the trigger decision.
-	 * @return Returns <code>true</code> if a trigger occurred and <code>
-	 * false</code> if a trigger did not.
-	 */
-	@Override
-	protected boolean triggerDecision(EventHeader event) {
-		// Check if the event has clusters. An event with no clusters
-		// should never result in a trigger.
-		if(event.hasCollection(Cluster.class, clusterCollectionName)) {
-			// Check if any of the zone counts are high enough to trigger.
-			return triggerTest();
-		}
-		
-		// Events without clusters can not trigger.
-		else { return false; }
-	}
-	
-	/**
-	 * Checks if any of the regional counts are sufficiently high to
-	 * register a trigger.
-	 * 
-	 * @return Returns <code>true</code> if a region has enough clusters
-	 * to trigger and <code>false</code> otherwise.
-	 */
-	private boolean triggerTest() {
-		// Track whether a trigger occurred.
-		boolean trigger = false;
-		
-		// If any clusters occur in zone 3, reset the count and note
-		// that a trigger occurred.
-		if(zone3Count > 0) {
-			zone3Count = 0;
+                }
+            }
+        }
+        
+        // Run the superclass event processing.
+        super.process(event);
+    }
+    
+    /**
+     * Checks whether or not a trigger occurred.
+     * 
+     * @param event - The event on which to base the trigger decision.
+     * @return Returns <code>true</code> if a trigger occurred and <code>
+     * false</code> if a trigger did not.
+     */
+    @Override
+    protected boolean triggerDecision(EventHeader event) {
+        // Check if the event has clusters. An event with no clusters
+        // should never result in a trigger.
+        if(event.hasCollection(Cluster.class, clusterCollectionName)) {
+            // Check if any of the zone counts are high enough to trigger.
+            return triggerTest();
+        }
+        
+        // Events without clusters can not trigger.
+        else { return false; }
+    }
+    
+    /**
+     * Checks if any of the regional counts are sufficiently high to
+     * register a trigger.
+     * 
+     * @return Returns <code>true</code> if a region has enough clusters
+     * to trigger and <code>false</code> otherwise.
+     */
+    private boolean triggerTest() {
+        // Track whether a trigger occurred.
+        boolean trigger = false;
+        
+        // If any clusters occur in zone 3, reset the count and note
+        // that a trigger occurred.
+        if(zone3Count > 0) {
+            zone3Count = 0;
                          if(zone2Count==zone2Prescaling){zone2Count=0;}
                          if(zone1Count==zone1Prescaling){zone1Count=0;}
-			trigger = true;
-		}
-		
-		// If zone 2 has sufficient clusters (100 by default) to
-		// trigger, reset its count and note that a trigger occurred.
-		else if(zone2Count == zone2Prescaling) {
-			zone2Count = 0;
+            trigger = true;
+        }
+        
+        // If zone 2 has sufficient clusters (100 by default) to
+        // trigger, reset its count and note that a trigger occurred.
+        else if(zone2Count == zone2Prescaling) {
+            zone2Count = 0;
                         if(zone3Count>0){zone3Count=0;}
                         if(zone1Count==zone1Prescaling){zone1Count=0;}
-			trigger = true;
-		}
-		
-		// If zone 3 has sufficient clusters (1000 by default) to
-		// trigger, reset its count and note that a trigger occurred.
-		else if(zone1Count == zone1Prescaling) {
-			zone1Count = 0;
+            trigger = true;
+        }
+        
+        // If zone 3 has sufficient clusters (1000 by default) to
+        // trigger, reset its count and note that a trigger occurred.
+        else if(zone1Count == zone1Prescaling) {
+            zone1Count = 0;
                         if(zone3Count>0){zone3Count=0;}
                         if(zone2Count==zone2Prescaling){zone2Count=0;}
-			trigger = true;
-		}
-		else if(zone4Count == zone4Prescaling) {
-			zone4Count = 0;
+            trigger = true;
+        }
+        else if(zone4Count == zone4Prescaling) {
+            zone4Count = 0;
                         if(zone3Count>0){zone3Count=0;}
                         if(zone2Count==zone2Prescaling){zone2Count=0;}
                         if(zone1Count==zone1Prescaling){zone1Count=0;}
-			trigger = true;
-		}
-		// Return whether or not a trigger occurred.
-		return trigger;
-	}
+            trigger = true;
+        }
+        // Return whether or not a trigger occurred.
+        return trigger;
+    }
 }

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/luca/LCIOReadScript.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/luca/LCIOReadScript.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/luca/LCIOReadScript.java	Wed Apr 27 11:11:32 2016
@@ -10,91 +10,91 @@
 import org.lcsim.lcio.LCIOWriter;
 
 public class LCIOReadScript {
-	public static void main(String[] args) {
-		// Make sure there arguments are valid.
-		if(args.length != 2) {
-			System.err.println("Error: Arguments must be [Input_File] [Output_File]");
-			System.exit(1);
-		}
-		
-		// Set the input/output files.
-		File inputFile = new File(args[0]);
-		File outputFile = new File(args[1]);
-		
-		// Make sure that the input file exists.
-		if(!inputFile.canRead()) {
-			System.err.println("Error: Input file can not be found.");
-			System.exit(1);
-		}
-		
-		// Create an LCIO reader to read it in.
-		LCIOReader reader = null;
-		try { reader = new LCIOReader(inputFile); }
-		catch(IOException e) {
-			e.printStackTrace();
-			System.exit(1);
-		}
-		
-		// Create an LCIO writer to output the new file.
-		LCIOWriter writer = null;
-		try { writer = new LCIOWriter(outputFile); }
-		catch(IOException e) {
-			e.printStackTrace();
-			System.exit(1);
-		}
-		
-		// Keep looping through events until there are no more.
-		while(true) {
-			// Try to get an event.
-			EventHeader event = null;
-			try { event = reader.read(); }
-			catch(IOException e) { }
-			
-			// If the event is still null, there either was no event
-			// or an error occurred.
-			if(event == null) { break; }
-			
-			// Get the event number to print a status update.
-			int num = event.getEventNumber();
-			if(num % 10000 == 0) { System.out.println("Parsing event " + num + "."); }
-			
-			// See if the MCParticle collection exists.
-			if(event.hasCollection(MCParticle.class, "MCParticle")) {
-				// Get the MCParticle collection from the event.
-				ArrayList<MCParticle> particleList = (ArrayList<MCParticle>) event.get(MCParticle.class, "MCParticle");
-				
-				// Remove the MCParticle collection from the event.
-				event.remove("MCParticle");
-				
-				// Make a new list for good particles which pass some test.
-				ArrayList<MCParticle> goodParticles = new ArrayList<MCParticle>();
-				
-				// Sort through the list of MCParticle objects in the
-				// full list and add good ones to the good list.
-				for(MCParticle p : particleList) {
-					if(p.getEnergy() >= 2.1) { goodParticles.add(p); }
-				}
-				
-				// Write the good particles back to the event.
-				event.put("MCParticle", goodParticles);
-			}
-			
-			// Write the event back out to the new file.
-			try { writer.write(event); }
-			catch(IOException e) {
-				e.printStackTrace();
-				System.exit(1);
-			}
-		}
-		
-		// Close the reader and writer.
-		try {
-			reader.close();
-			writer.close();
-		}
-		catch(IOException e) {
-			e.printStackTrace();
-			System.exit(1);
-		}
-	}
+    public static void main(String[] args) {
+        // Make sure there arguments are valid.
+        if(args.length != 2) {
+            System.err.println("Error: Arguments must be [Input_File] [Output_File]");
+            System.exit(1);
+        }
+        
+        // Set the input/output files.
+        File inputFile = new File(args[0]);
+        File outputFile = new File(args[1]);
+        
+        // Make sure that the input file exists.
+        if(!inputFile.canRead()) {
+            System.err.println("Error: Input file can not be found.");
+            System.exit(1);
+        }
+        
+        // Create an LCIO reader to read it in.
+        LCIOReader reader = null;
+        try { reader = new LCIOReader(inputFile); }
+        catch(IOException e) {
+            e.printStackTrace();
+            System.exit(1);
+        }
+        
+        // Create an LCIO writer to output the new file.
+        LCIOWriter writer = null;
+        try { writer = new LCIOWriter(outputFile); }
+        catch(IOException e) {
+            e.printStackTrace();
+            System.exit(1);
+        }
+        
+        // Keep looping through events until there are no more.
+        while(true) {
+            // Try to get an event.
+            EventHeader event = null;
+            try { event = reader.read(); }
+            catch(IOException e) { }
+            
+            // If the event is still null, there either was no event
+            // or an error occurred.
+            if(event == null) { break; }
+            
+            // Get the event number to print a status update.
+            int num = event.getEventNumber();
+            if(num % 10000 == 0) { System.out.println("Parsing event " + num + "."); }
+            
+            // See if the MCParticle collection exists.
+            if(event.hasCollection(MCParticle.class, "MCParticle")) {
+                // Get the MCParticle collection from the event.
+                ArrayList<MCParticle> particleList = (ArrayList<MCParticle>) event.get(MCParticle.class, "MCParticle");
+                
+                // Remove the MCParticle collection from the event.
+                event.remove("MCParticle");
+                
+                // Make a new list for good particles which pass some test.
+                ArrayList<MCParticle> goodParticles = new ArrayList<MCParticle>();
+                
+                // Sort through the list of MCParticle objects in the
+                // full list and add good ones to the good list.
+                for(MCParticle p : particleList) {
+                    if(p.getEnergy() >= 2.1) { goodParticles.add(p); }
+                }
+                
+                // Write the good particles back to the event.
+                event.put("MCParticle", goodParticles);
+            }
+            
+            // Write the event back out to the new file.
+            try { writer.write(event); }
+            catch(IOException e) {
+                e.printStackTrace();
+                System.exit(1);
+            }
+        }
+        
+        // Close the reader and writer.
+        try {
+            reader.close();
+            writer.close();
+        }
+        catch(IOException e) {
+            e.printStackTrace();
+            System.exit(1);
+        }
+    }
 }

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/luca/rate.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/luca/rate.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/luca/rate.java	Wed Apr 27 11:11:32 2016
@@ -435,15 +435,15 @@
      nevents++;
      
      
-    	/* natha's code for trigger
-    	List <AbstractIntData> aids = event.get(AbstractIntData.class, "TriggerBank");
-    	for (AbstractIntData aid : aids) {
-    		if (aid.getTag() == TIData.BANK_TAG) {
-    			TIData tt=(TIData)aid;
-    			if (!tt.isSingle1Trigger()) return;
+        /* natha's code for trigger
+        List <AbstractIntData> aids = event.get(AbstractIntData.class, "TriggerBank");
+        for (AbstractIntData aid : aids) {
+            if (aid.getTag() == TIData.BANK_TAG) {
+                TIData tt=(TIData)aid;
+                if (!tt.isSingle1Trigger()) return;
                         break;
-    		}
-    	}
+            }
+        }
      */ //nathans code for trigger end
      
     

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/luca/ratesim.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/luca/ratesim.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/luca/ratesim.java	Wed Apr 27 11:11:32 2016
@@ -238,15 +238,15 @@
      nevents++;
      
      
-    	/* natha's code for trigger
-    	List <AbstractIntData> aids = event.get(AbstractIntData.class, "TriggerBank");
-    	for (AbstractIntData aid : aids) {
-    		if (aid.getTag() == TIData.BANK_TAG) {
-    			TIData tt=(TIData)aid;
-    			if (!tt.isSingle1Trigger()) return;
+        /* natha's code for trigger
+        List <AbstractIntData> aids = event.get(AbstractIntData.class, "TriggerBank");
+        for (AbstractIntData aid : aids) {
+            if (aid.getTag() == TIData.BANK_TAG) {
+                TIData tt=(TIData)aid;
+                if (!tt.isSingle1Trigger()) return;
                         break;
-    		}
-    	}
+            }
+        }
      */ //nathans code for trigger end
      
     

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/meeg/FilterMCBunches.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/meeg/FilterMCBunches.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/meeg/FilterMCBunches.java	Wed Apr 27 11:11:32 2016
@@ -17,7 +17,7 @@
 import org.apache.commons.cli.Option;
 import org.apache.commons.cli.Options;
 import org.apache.commons.cli.ParseException;
-import org.apache.commons.cli.DefaultParser;
+import org.apache.commons.cli.PosixParser;
 import org.lcsim.event.EventHeader;
 import org.lcsim.event.MCParticle;
 import org.lcsim.event.RawCalorimeterHit;
@@ -70,7 +70,7 @@
     public static void main(String[] args) {
         // Set up command line parsing.
         Options options = createCommandLineOptions();
-        CommandLineParser parser = new DefaultParser();
+        CommandLineParser parser = new PosixParser();
 
         // Parse command line arguments.
         CommandLine cl = null;

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/meeg/HPSEcalAnalogPrintDriver.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/meeg/HPSEcalAnalogPrintDriver.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/meeg/HPSEcalAnalogPrintDriver.java	Wed Apr 27 11:11:32 2016
@@ -22,67 +22,67 @@
  */
 public class HPSEcalAnalogPrintDriver extends Driver {
 
-	Subdetector ecal;
-	IDDecoder dec;
-	String ecalName;
-	String ecalReadoutName = "EcalHits";
-	String ecalCollectionName = null;
-	String outputFileName;
-	PrintWriter outputStream = null;
-	int flags;
+    Subdetector ecal;
+    IDDecoder dec;
+    String ecalName;
+    String ecalReadoutName = "EcalHits";
+    String ecalCollectionName = null;
+    String outputFileName;
+    PrintWriter outputStream = null;
+    int flags;
 
-	public HPSEcalAnalogPrintDriver() {
-	}
+    public HPSEcalAnalogPrintDriver() {
+    }
 
-	public void setEcalCollectionName(String ecalCollectionName) {
-		this.ecalCollectionName = ecalCollectionName;
-	}
+    public void setEcalCollectionName(String ecalCollectionName) {
+        this.ecalCollectionName = ecalCollectionName;
+    }
 
-	public void setEcalName(String ecalName) {
-		this.ecalName = ecalName;
-	}
+    public void setEcalName(String ecalName) {
+        this.ecalName = ecalName;
+    }
 
-	public void setOutputFileName(String outputFileName) {
-		this.outputFileName = outputFileName;
-	}
+    public void setOutputFileName(String outputFileName) {
+        this.outputFileName = outputFileName;
+    }
 
-	@Override
-	public void startOfData() {
-		if (ecalCollectionName == null) {
-			throw new RuntimeException("The parameter ecalCollectionName was not set!");
-		}
+    @Override
+    public void startOfData() {
+        if (ecalCollectionName == null) {
+            throw new RuntimeException("The parameter ecalCollectionName was not set!");
+        }
 
-		if (ecalName == null) {
-			throw new RuntimeException("The parameter ecalName was not set!");
-		}
+        if (ecalName == null) {
+            throw new RuntimeException("The parameter ecalName was not set!");
+        }
 
-		if (outputFileName != null) {
-			try {
-				outputStream = new PrintWriter(outputFileName);
-			} catch (IOException ex) {
-				throw new RuntimeException("Invalid outputFilePath!");
-			}
-		} else {
-			outputStream = new PrintWriter(System.out, true);
-		}
-	}
+        if (outputFileName != null) {
+            try {
+                outputStream = new PrintWriter(outputFileName);
+            } catch (IOException ex) {
+                throw new RuntimeException("Invalid outputFilePath!");
+            }
+        } else {
+            outputStream = new PrintWriter(System.out, true);
+        }
+    }
 
-	public void detectorChanged(Detector detector) {
-		// Get the Subdetector.
-		ecal = (Subdetector) detector.getSubdetector(ecalName);
-		dec = ecal.getIDDecoder();
-	}
+    public void detectorChanged(Detector detector) {
+        // Get the Subdetector.
+        ecal = (Subdetector) detector.getSubdetector(ecalName);
+        dec = ecal.getIDDecoder();
+    }
 
-	@Override
-	public void process(EventHeader event) {
-		// Get the list of ECal hits.
-		if (event.hasCollection(CalorimeterHit.class, ecalCollectionName)) {
-			//outputStream.println("Reading RawTrackerHits from event " + event.getEventNumber());
-			List<CalorimeterHit> hits = event.get(CalorimeterHit.class, ecalCollectionName);
-			for (CalorimeterHit hit : hits) {
-				dec.setID(hit.getCellID());
-				outputStream.printf("%d\t%d\t%f\t%f\n", dec.getValue("ix"), dec.getValue("iy"), hit.getTime(), hit.getRawEnergy());
-			}
-		}
-	}
+    @Override
+    public void process(EventHeader event) {
+        // Get the list of ECal hits.
+        if (event.hasCollection(CalorimeterHit.class, ecalCollectionName)) {
+            //outputStream.println("Reading RawTrackerHits from event " + event.getEventNumber());
+            List<CalorimeterHit> hits = event.get(CalorimeterHit.class, ecalCollectionName);
+            for (CalorimeterHit hit : hits) {
+                dec.setID(hit.getCellID());
+                outputStream.printf("%d\t%d\t%f\t%f\n", dec.getValue("ix"), dec.getValue("iy"), hit.getTime(), hit.getRawEnergy());
+            }
+        }
+    }
 }

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/meeg/HPSEcalDigitalPrintDriver.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/meeg/HPSEcalDigitalPrintDriver.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/meeg/HPSEcalDigitalPrintDriver.java	Wed Apr 27 11:11:32 2016
@@ -22,70 +22,70 @@
  */
 public class HPSEcalDigitalPrintDriver extends Driver {
 
-	Subdetector ecal;
-	IDDecoder dec;
-	String ecalName = "Ecal";
-	String ecalReadoutName = "EcalHits";
-	String ecalCollectionName = "EcalRawHits";
-	String outputFileName;
-	PrintWriter outputStream = null;
-	int timeScale = 1;
-	int flags;
+    Subdetector ecal;
+    IDDecoder dec;
+    String ecalName = "Ecal";
+    String ecalReadoutName = "EcalHits";
+    String ecalCollectionName = "EcalRawHits";
+    String outputFileName;
+    PrintWriter outputStream = null;
+    int timeScale = 1;
+    int flags;
 
-	public HPSEcalDigitalPrintDriver() {
-	}
+    public HPSEcalDigitalPrintDriver() {
+    }
 
-	public void setTimeScale(int timeScale) {
-		this.timeScale = timeScale;
-	}
+    public void setTimeScale(int timeScale) {
+        this.timeScale = timeScale;
+    }
 
-	public void setEcalCollectionName(String ecalCollectionName) {
-		this.ecalCollectionName = ecalCollectionName;
-	}
+    public void setEcalCollectionName(String ecalCollectionName) {
+        this.ecalCollectionName = ecalCollectionName;
+    }
 
-	public void setEcalName(String ecalName) {
-		this.ecalName = ecalName;
-	}
+    public void setEcalName(String ecalName) {
+        this.ecalName = ecalName;
+    }
 
-	public void setOutputFileName(String outputFileName) {
-		this.outputFileName = outputFileName;
-	}
+    public void setOutputFileName(String outputFileName) {
+        this.outputFileName = outputFileName;
+    }
 
-	public void startOfData() {
-		if (ecalCollectionName == null) {
-			throw new RuntimeException("The parameter ecalCollectionName was not set!");
-		}
+    public void startOfData() {
+        if (ecalCollectionName == null) {
+            throw new RuntimeException("The parameter ecalCollectionName was not set!");
+        }
 
-		if (ecalName == null) {
-			throw new RuntimeException("The parameter ecalName was not set!");
-		}
+        if (ecalName == null) {
+            throw new RuntimeException("The parameter ecalName was not set!");
+        }
 
-		if (outputFileName != null) {
-			try {
-				outputStream = new PrintWriter(outputFileName);
-			} catch (IOException ex) {
-				throw new RuntimeException("Invalid outputFilePath!");
-			}
-		} else {
-			outputStream = new PrintWriter(System.out, true);
-		}
-	}
+        if (outputFileName != null) {
+            try {
+                outputStream = new PrintWriter(outputFileName);
+            } catch (IOException ex) {
+                throw new RuntimeException("Invalid outputFilePath!");
+            }
+        } else {
+            outputStream = new PrintWriter(System.out, true);
+        }
+    }
 
-	public void detectorChanged(Detector detector) {
-		// Get the Subdetector.
-		ecal = (Subdetector) detector.getSubdetector(ecalName);
-		dec = ecal.getIDDecoder();
-	}
+    public void detectorChanged(Detector detector) {
+        // Get the Subdetector.
+        ecal = (Subdetector) detector.getSubdetector(ecalName);
+        dec = ecal.getIDDecoder();
+    }
 
-	public void process(EventHeader event) {
-		// Get the list of ECal hits.
-		if (event.hasCollection(RawCalorimeterHit.class, ecalCollectionName)) {
-			List<RawCalorimeterHit> hits = event.get(RawCalorimeterHit.class, ecalCollectionName);
-			//outputStream.println("Reading RawCalorimeterHit from event " + event.getEventNumber());
-			for (RawCalorimeterHit hit : hits) {
-				dec.setID(hit.getCellID());
-				outputStream.printf("%d\t%d\t%d\t%d\n", dec.getValue("ix"), dec.getValue("iy"), hit.getTimeStamp() * timeScale, hit.getAmplitude());
-			}
-		}
-	}
+    public void process(EventHeader event) {
+        // Get the list of ECal hits.
+        if (event.hasCollection(RawCalorimeterHit.class, ecalCollectionName)) {
+            List<RawCalorimeterHit> hits = event.get(RawCalorimeterHit.class, ecalCollectionName);
+            //outputStream.println("Reading RawCalorimeterHit from event " + event.getEventNumber());
+            for (RawCalorimeterHit hit : hits) {
+                dec.setID(hit.getCellID());
+                outputStream.printf("%d\t%d\t%d\t%d\n", dec.getValue("ix"), dec.getValue("iy"), hit.getTimeStamp() * timeScale, hit.getAmplitude());
+            }
+        }
+    }
 }

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/meeg/HPSEcalRawTrackerHitPrintDriver.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/meeg/HPSEcalRawTrackerHitPrintDriver.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/meeg/HPSEcalRawTrackerHitPrintDriver.java	Wed Apr 27 11:11:32 2016
@@ -22,68 +22,68 @@
  */
 public class HPSEcalRawTrackerHitPrintDriver extends Driver {
 
-	Subdetector ecal;
-	IDDecoder dec;
-	String ecalName = "Ecal";
-	String ecalReadoutName = "EcalHits";
-	String ecalCollectionName = "EcalRawHits";
-	String outputFileName;
-	PrintWriter outputStream = null;
-	int flags;
+    Subdetector ecal;
+    IDDecoder dec;
+    String ecalName = "Ecal";
+    String ecalReadoutName = "EcalHits";
+    String ecalCollectionName = "EcalRawHits";
+    String outputFileName;
+    PrintWriter outputStream = null;
+    int flags;
 
-	public HPSEcalRawTrackerHitPrintDriver() {
-	}
+    public HPSEcalRawTrackerHitPrintDriver() {
+    }
 
-	public void setEcalCollectionName(String ecalCollectionName) {
-		this.ecalCollectionName = ecalCollectionName;
-	}
+    public void setEcalCollectionName(String ecalCollectionName) {
+        this.ecalCollectionName = ecalCollectionName;
+    }
 
-	public void setEcalName(String ecalName) {
-		this.ecalName = ecalName;
-	}
+    public void setEcalName(String ecalName) {
+        this.ecalName = ecalName;
+    }
 
-	public void setOutputFileName(String outputFileName) {
-		this.outputFileName = outputFileName;
-	}
+    public void setOutputFileName(String outputFileName) {
+        this.outputFileName = outputFileName;
+    }
 
-	public void startOfData() {
-		if (ecalCollectionName == null) {
-			throw new RuntimeException("The parameter ecalCollectionName was not set!");
-		}
+    public void startOfData() {
+        if (ecalCollectionName == null) {
+            throw new RuntimeException("The parameter ecalCollectionName was not set!");
+        }
 
-		if (ecalName == null) {
-			throw new RuntimeException("The parameter ecalName was not set!");
-		}
+        if (ecalName == null) {
+            throw new RuntimeException("The parameter ecalName was not set!");
+        }
 
-		if (outputFileName != null) {
-			try {
-				outputStream = new PrintWriter(outputFileName);
-			} catch (IOException ex) {
-				throw new RuntimeException("Invalid outputFilePath!");
-			}
-		} else {
-			outputStream = new PrintWriter(System.out, true);
-		}
-	}
+        if (outputFileName != null) {
+            try {
+                outputStream = new PrintWriter(outputFileName);
+            } catch (IOException ex) {
+                throw new RuntimeException("Invalid outputFilePath!");
+            }
+        } else {
+            outputStream = new PrintWriter(System.out, true);
+        }
+    }
 
-	public void detectorChanged(Detector detector) {
-		// Get the Subdetector.
-		ecal = (Subdetector) detector.getSubdetector(ecalName);
-		dec = ecal.getIDDecoder();
-	}
+    public void detectorChanged(Detector detector) {
+        // Get the Subdetector.
+        ecal = (Subdetector) detector.getSubdetector(ecalName);
+        dec = ecal.getIDDecoder();
+    }
 
-	public void process(EventHeader event) {
-		// Get the list of ECal hits.
-		if (event.hasCollection(RawTrackerHit.class, ecalCollectionName)) {
-			//outputStream.println("Reading RawTrackerHits from event " + event.getEventNumber());
-			List<RawTrackerHit> hits = event.get(RawTrackerHit.class, ecalCollectionName);
-			for (RawTrackerHit hit : hits) {
-				dec.setID(hit.getCellID());
-				outputStream.printf("%d\t%d\t%d\t%d\n", dec.getValue("ix"), dec.getValue("iy"), hit.getTime(), hit.getADCValues().length);
-				for (int i = 0; i < hit.getADCValues().length; i++) {
-					outputStream.printf("%d\n", hit.getADCValues()[i]);
-				}
-			}
-		}
-	}
+    public void process(EventHeader event) {
+        // Get the list of ECal hits.
+        if (event.hasCollection(RawTrackerHit.class, ecalCollectionName)) {
+            //outputStream.println("Reading RawTrackerHits from event " + event.getEventNumber());
+            List<RawTrackerHit> hits = event.get(RawTrackerHit.class, ecalCollectionName);
+            for (RawTrackerHit hit : hits) {
+                dec.setID(hit.getCellID());
+                outputStream.printf("%d\t%d\t%d\t%d\n", dec.getValue("ix"), dec.getValue("iy"), hit.getTime(), hit.getADCValues().length);
+                for (int i = 0; i < hit.getADCValues().length; i++) {
+                    outputStream.printf("%d\n", hit.getADCValues()[i]);
+                }
+            }
+        }
+    }
 }

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/meeg/HPSGenericRawTrackerHitPrintDriver.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/meeg/HPSGenericRawTrackerHitPrintDriver.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/meeg/HPSGenericRawTrackerHitPrintDriver.java	Wed Apr 27 11:11:32 2016
@@ -20,42 +20,42 @@
  */
 public class HPSGenericRawTrackerHitPrintDriver extends Driver {
 
-	String outputFileName;
-	PrintWriter outputStream = null;
+    String outputFileName;
+    PrintWriter outputStream = null;
 
-	public HPSGenericRawTrackerHitPrintDriver() {
-	}
+    public HPSGenericRawTrackerHitPrintDriver() {
+    }
 
-	public void setOutputFileName(String outputFileName) {
-		this.outputFileName = outputFileName;
-	}
+    public void setOutputFileName(String outputFileName) {
+        this.outputFileName = outputFileName;
+    }
 
-	public void startOfData() {
-		if (outputFileName != null) {
-			try {
-				outputStream = new PrintWriter(outputFileName);
-			} catch (IOException ex) {
-				throw new RuntimeException("Invalid outputFilePath!");
-			}
-		} else {
-			outputStream = new PrintWriter(System.out, true);
-		}
-	}
+    public void startOfData() {
+        if (outputFileName != null) {
+            try {
+                outputStream = new PrintWriter(outputFileName);
+            } catch (IOException ex) {
+                throw new RuntimeException("Invalid outputFilePath!");
+            }
+        } else {
+            outputStream = new PrintWriter(System.out, true);
+        }
+    }
 
-	public void process(EventHeader event) {
-		// Get the list of ECal hits.
-		if (event.hasCollection(RawTrackerHit.class)) {
-			//outputStream.println("Reading RawTrackerHits from event " + event.getEventNumber());
-			List<List<RawTrackerHit>> listOfLists = event.get(RawTrackerHit.class);
-			for (List<RawTrackerHit> hits : listOfLists) {
-				outputStream.printf("List with %d RawTrackerHits:\n", hits.size());
-				for (RawTrackerHit hit : hits) {
-					outputStream.printf("%d\t%d\n", hit.getCellID(), hit.getADCValues().length);
-					for (int i = 0; i < hit.getADCValues().length; i++) {
-						outputStream.printf("%d\n", hit.getADCValues()[i]);
-					}
-				}
-			}
-		}
-	}
+    public void process(EventHeader event) {
+        // Get the list of ECal hits.
+        if (event.hasCollection(RawTrackerHit.class)) {
+            //outputStream.println("Reading RawTrackerHits from event " + event.getEventNumber());
+            List<List<RawTrackerHit>> listOfLists = event.get(RawTrackerHit.class);
+            for (List<RawTrackerHit> hits : listOfLists) {
+                outputStream.printf("List with %d RawTrackerHits:\n", hits.size());
+                for (RawTrackerHit hit : hits) {
+                    outputStream.printf("%d\t%d\n", hit.getCellID(), hit.getADCValues().length);
+                    for (int i = 0; i < hit.getADCValues().length; i++) {
+                        outputStream.printf("%d\n", hit.getADCValues()[i]);
+                    }
+                }
+            }
+        }
+    }
 }

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/meeg/LCIOTrackAnalysis.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/meeg/LCIOTrackAnalysis.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/meeg/LCIOTrackAnalysis.java	Wed Apr 27 11:11:32 2016
@@ -24,7 +24,7 @@
  * @author Sho Uemura <[log in to unmask]>
  */
 // TODO: This is an exact duplicate of the class in the analysis.example package.
-//		 One of them should be sandboxed
+//       One of them should be sandboxed
 public class LCIOTrackAnalysis {
 
     protected Track track;

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/meeg/MergeMCBunches.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/meeg/MergeMCBunches.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/meeg/MergeMCBunches.java	Wed Apr 27 11:11:32 2016
@@ -13,7 +13,7 @@
 import org.apache.commons.cli.Option;
 import org.apache.commons.cli.Options;
 import org.apache.commons.cli.ParseException;
-import org.apache.commons.cli.DefaultParser;
+import org.apache.commons.cli.PosixParser;
 import org.lcsim.event.EventHeader;
 import org.lcsim.event.MCParticle;
 import org.lcsim.event.SimCalorimeterHit;
@@ -49,7 +49,7 @@
     public static void main(String[] args) {
         // Set up command line parsing.
         Options options = createCommandLineOptions();
-        CommandLineParser parser = new DefaultParser();
+        CommandLineParser parser = new PosixParser();
 
         // Parse command line arguments.
         CommandLine cl = null;
@@ -191,4 +191,4 @@
             throw new RuntimeException(e);
         }
     }
-}
+}

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/meeg/SvtChargeIntegrator.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/meeg/SvtChargeIntegrator.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/meeg/SvtChargeIntegrator.java	Wed Apr 27 11:11:32 2016
@@ -6,17 +6,19 @@
 import java.io.IOException;
 import java.text.SimpleDateFormat;
 import java.util.Date;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.TimeZone;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 import org.apache.commons.cli.CommandLine;
 import org.apache.commons.cli.CommandLineParser;
-import org.apache.commons.cli.DefaultParser;
 import org.apache.commons.cli.HelpFormatter;
 import org.apache.commons.cli.Option;
 import org.apache.commons.cli.Options;
 import org.apache.commons.cli.ParseException;
+import org.apache.commons.cli.PosixParser;
 import org.apache.commons.csv.CSVFormat;
 import org.apache.commons.csv.CSVParser;
 import org.apache.commons.csv.CSVRecord;
@@ -26,6 +28,7 @@
 import org.hps.conditions.svt.SvtBiasConstant.SvtBiasConstantCollection;
 import org.hps.conditions.svt.SvtMotorPosition;
 import org.hps.conditions.svt.SvtMotorPosition.SvtMotorPositionCollection;
+import org.hps.conditions.svt.SvtTimingConstants;
 import org.hps.run.database.RunManager;
 
 /**
@@ -35,9 +38,9 @@
 public class SvtChargeIntegrator {
 
     private static final double angleTolerance = 1e-4;
+    private static final double burstModeNoiseEfficiency = 0.965;
 
     /**
-     * Load SVT HV bias constants into the conditions database.
      *
      * @param args the command line arguments (requires a CSV run/file log file
      * and a MYA dump file.)
@@ -48,8 +51,9 @@
         options.addOption(new Option("r", false, "use per-run CSV log file (default is per-file)"));
         options.addOption(new Option("t", false, "use TI timestamp instead of Unix time (higher precision, but requires TI time offset in run DB)"));
         options.addOption(new Option("c", false, "get TI time offset from CSV log file instead of run DB"));
-
-        final CommandLineParser parser = new DefaultParser();
+        options.addOption(new Option("e", true, "header error file"));
+
+        final CommandLineParser parser = new PosixParser();
         CommandLine cl = null;
         try {
             cl = parser.parse(options, args);
@@ -61,6 +65,26 @@
         boolean useTI = cl.hasOption("t");
         boolean useCrawlerTI = cl.hasOption("c");
 
+        Map<Integer, Long> runErrorMap = new HashMap<Integer, Long>();
+        if (cl.hasOption("e")) {
+            try {
+                BufferedReader br = new BufferedReader(new FileReader(cl.getOptionValue("e")));
+                String line;
+                System.err.println("header error file header: " + br.readLine()); //discard the first line
+                while ((line = br.readLine()) != null) {
+                    String arr[] = line.split(" +");
+                    int run = Integer.parseInt(arr[1]);
+                    long errorTime = Long.parseLong(arr[4]);
+                    runErrorMap.put(run, errorTime);
+//                    System.out.format("%d %d\n", run, errorTime);
+                }
+            } catch (FileNotFoundException ex) {
+                Logger.getLogger(SvtChargeIntegrator.class.getName()).log(Level.SEVERE, null, ex);
+            } catch (IOException ex) {
+                Logger.getLogger(SvtChargeIntegrator.class.getName()).log(Level.SEVERE, null, ex);
+            }
+        }
+
         if (cl.getArgs().length != 2) {
             printUsage(options);
             return;
@@ -88,9 +112,9 @@
             String line;
             System.err.println("myaData header: " + br.readLine()); //discard the first line
             if (perRun) {
-                System.out.println("run_num\tnominal_position\tnEvents\ttotalQ\ttotalQ_withbias\ttotalQ_atnom\tgatedQ\tgatedQ_withbias\tgatedQ_atnom");
+                System.out.println("run_num\tnominal_position\tnEvents\ttotalQ\ttotalQ_withbias\ttotalQ_atnom\ttotalQ_noerror\tgatedQ\tgatedQ_withbias\tgatedQ_atnom\tgatedQ_noerror\tgoodQ\tgoodQ_withbias\tgoodQ_atnom\tgoodQ_noerror");
             } else {
-                System.out.println("run_num\tfile_num\tnominal_position\tnEvents\ttotalQ\ttotalQ_withbias\ttotalQ_atnom\tgatedQ\tgatedQ_withbias\tgatedQ_atnom");
+                System.out.println("run_num\tfile_num\tnominal_position\tnEvents\ttotalQ\ttotalQ_withbias\ttotalQ_atnom\ttotalQ_noerror\tgatedQ\tgatedQ_withbias\tgatedQ_atnom\tgatedQ_noerror\tgoodQ\tgoodQ_withbias\tgoodQ_atnom\tgoodQ_noerror");
             }
 
             int currentRun = 0;
@@ -98,6 +122,7 @@
             double nominalAngleBottom = -999;
             String nominalPosition = null;
             long tiTimeOffset = 0;
+            double efficiency = 0;
             SvtBiasConstantCollection svtBiasConstants = null;
             SvtMotorPositionCollection svtPositionConstants = null;
             SvtAlignmentConstant.SvtAlignmentConstantCollection alignmentConstants = null;
@@ -120,10 +145,10 @@
                 if (runNum != currentRun) {
                     if (useTI && !useCrawlerTI) {
                         RunManager.getRunManager().setRun(runNum);
-                        if (!RunManager.getRunManager().runExists() || RunManager.getRunManager().getTriggerConfig().getTiTimeOffset() == null) {
+                        if (!RunManager.getRunManager().runExists() || RunManager.getRunManager().getRunSummary().getTiTimeOffset() == null) {
                             continue;
                         }
-                        tiTimeOffset = RunManager.getRunManager().getTriggerConfig().getTiTimeOffset();
+                        tiTimeOffset = RunManager.getRunManager().getRunSummary().getTiTimeOffset();
                         if (tiTimeOffset == 0) {
                             continue;
                         }
@@ -169,7 +194,20 @@
                         alignmentConstants = null;
                         nominalPosition = "unknown";
                     }
-
+                    efficiency = burstModeNoiseEfficiency;
+                    SvtTimingConstants svtTimingConstants;
+                    try {
+                        svtTimingConstants = DatabaseConditionsManager.getInstance().getCachedConditions(SvtTimingConstants.SvtTimingConstantsCollection.class, "svt_timing_constants").getCachedData().get(0);
+                    } catch (Exception ex) {
+                        svtTimingConstants = null;
+                    }
+                    if (svtTimingConstants != null) {
+                        if (svtTimingConstants.getOffsetTime() > 27) {
+                            efficiency *= 2.0 / 3.0; // bad latency: drop 2 out of 6 trigger phases
+                        }// otherwise, we have good latency
+                    } else {
+                        efficiency = 0;
+                    }//no latency info in conditions: give up
                     currentRun = runNum;
                 }
 
@@ -194,22 +232,40 @@
                     if (firstTI == 0 || lastTI == 0) {
                         continue;
                     }
-                    startDate = new Date((long) ((firstTI + tiTimeOffset) / 1e6));
-                    endDate = new Date((long) ((lastTI + tiTimeOffset) / 1e6));
+                    startDate = new Date((firstTI + tiTimeOffset) / 1000000);
+                    endDate = new Date((lastTI + tiTimeOffset) / 1000000);
                 } else {
                     if (firstTime == 0 || lastTime == 0) {
                         continue;
                     }
                     startDate = new Date(firstTime * 1000);
                     endDate = new Date(lastTime * 1000);
+                }
+
+                Long errorTime = runErrorMap.get(runNum);
+                Date errorDate = null;
+                if (errorTime != null) {
+                    errorDate = new Date(errorTime / 1000000);
+                    boolean isGood = Math.abs(errorDate.getTime() - startDate.getTime()) < 10 * 60 * 60 * 1000; //10 hours
+                    if (!isGood && useTI) {
+                        errorDate = new Date((errorTime + tiTimeOffset) / 1000000);
+//                        boolean isPlusOffsetGood = Math.abs(errorDatePlusOffset.getTime() - startDate.getTime()) < 10 * 60 * 60 * 1000; //10 hours
+//                        System.out.format("%d, %d, %d: %s (good: %b), %s (good: %b)\n", runNum, errorTime, tiTimeOffset, errorDate, isGood, errorDatePlusOffset, isPlusOffsetGood);
+                    }
                 }
 
                 double totalCharge = 0;
                 double totalChargeWithBias = 0;
                 double totalChargeWithBiasAtNominal = 0;
+                double totalChargeWithBiasAtNominalNoError = 0;
                 double totalGatedCharge = 0;
                 double totalGatedChargeWithBias = 0;
                 double totalGatedChargeWithBiasAtNominal = 0;
+                double totalGatedChargeWithBiasAtNominalNoError = 0;
+                double totalGoodCharge = 0;
+                double totalGoodChargeWithBias = 0;
+                double totalGoodChargeWithBiasAtNominal = 0;
+                double totalGoodChargeWithBiasAtNominalNoError = 0;
                 br.mark(1000);
 
                 while ((line = br.readLine()) != null) {
@@ -268,27 +324,41 @@
                         long dtStart = Math.max(startDate.getTime(), lastDate.getTime());
                         long dtEnd = Math.min(date.getTime(), endDate.getTime());
                         double dt = (dtEnd - dtStart) / 1000.0;
+                        double errorDt = 0;
                         if (biasConstant != null) {
                             long biasStart = Math.max(dtStart, biasConstant.getStart());
                             long biasEnd = Math.min(dtEnd, biasConstant.getEnd());
-                            biasDt = (biasEnd - biasStart) / 1000.0;
+                            biasDt = Math.max(0, biasEnd - biasStart) / 1000.0;
                             if (positionConstant != null) {
                                 long positionStart = Math.max(biasStart, positionConstant.getStart());
                                 long positionEnd = Math.min(biasEnd, positionConstant.getEnd());
-                                positionDt = (positionEnd - positionStart) / 1000.0;
+                                positionDt = Math.max(0, positionEnd - positionStart) / 1000.0;
+
+                                long errorEnd = positionStart;
+                                if (errorDate == null) {
+                                    errorEnd = positionEnd;
+                                } else if (errorDate.getTime() > dtStart) {
+                                    errorEnd = Math.min(positionEnd, errorDate.getTime());
+                                }
+                                errorDt = Math.max(0, errorEnd - positionStart) / 1000.0;
                             }
                         }
-                        double dq = dt * current; // nC
-                        double dqGated = dt * current * livetime; // nC
 //                        System.out.format("start %d end %d date %d lastDate %d current %f dt %f\n", startDate.getTime(), endDate.getTime(), date.getTime(), lastDate.getTime(), current, dt);
-                        totalCharge += dq;
-                        totalGatedCharge += dqGated;
+                        totalCharge += dt * current; // nC
+                        totalGatedCharge += dt * current * livetime;
+                        totalGoodCharge += dt * current * livetime * efficiency;
                         if (biasGood) {
                             totalChargeWithBias += biasDt * current;
                             totalGatedChargeWithBias += biasDt * current * livetime;
+                            totalGoodChargeWithBias += biasDt * current * livetime * efficiency;
                             if (positionGood) {
                                 totalChargeWithBiasAtNominal += positionDt * current;
                                 totalGatedChargeWithBiasAtNominal += positionDt * current * livetime;
+                                totalGoodChargeWithBiasAtNominal += positionDt * current * livetime * efficiency;
+
+                                totalChargeWithBiasAtNominalNoError += errorDt * current;
+                                totalGatedChargeWithBiasAtNominalNoError += errorDt * current * livetime;
+                                totalGoodChargeWithBiasAtNominalNoError += errorDt * current * livetime * efficiency;
                             }
                         }
                     }
@@ -304,11 +374,11 @@
                 }
                 if (perRun) {
                     int nEvents = Integer.parseInt(record.get(9));
-                    System.out.format("%d\t%s\t%d\t%.3f\t%.3f\t%.3f\t%.3f\t%.3f\t%.3f\n", runNum, nominalPosition, nEvents, totalCharge, totalChargeWithBias, totalChargeWithBiasAtNominal, totalGatedCharge, totalGatedChargeWithBias, totalGatedChargeWithBiasAtNominal);
+                    System.out.format("%d\t%s\t%d\t%.3f\t%.3f\t%.3f\t%.3f\t%.3f\t%.3f\t%.3f\t%.3f\t%.3f\t%.3f\t%.3f\t%.3f\n", runNum, nominalPosition, nEvents, totalCharge, totalChargeWithBias, totalChargeWithBiasAtNominal, totalChargeWithBiasAtNominalNoError, totalGatedCharge, totalGatedChargeWithBias, totalGatedChargeWithBiasAtNominal, totalGatedChargeWithBiasAtNominalNoError, totalGoodCharge, totalGoodChargeWithBias, totalGoodChargeWithBiasAtNominal, totalGoodChargeWithBiasAtNominalNoError);
                 } else {
                     int fileNum = Integer.parseInt(record.get(1));
                     int nEvents = Integer.parseInt(record.get(2));
-                    System.out.format("%d\t%d\t%s\t%d\t%.3f\t%.3f\t%.3f\t%.3f\t%.3f\t%.3f\n", runNum, fileNum, nominalPosition, nEvents, totalCharge, totalChargeWithBias, totalChargeWithBiasAtNominal, totalGatedCharge, totalGatedChargeWithBias, totalGatedChargeWithBiasAtNominal);
+                    System.out.format("%d\t%d\t%s\t%d\t%.3f\t%.3f\t%.3f\t%.3f\t%.3f\t%.3f\t%.3f\t%.3f\t%.3f\t%.3f\t%.3f\t%.3f\n", runNum, fileNum, nominalPosition, nEvents, totalCharge, totalChargeWithBias, totalChargeWithBiasAtNominal, totalChargeWithBiasAtNominalNoError, totalGatedCharge, totalGatedChargeWithBias, totalGatedChargeWithBiasAtNominal, totalGatedChargeWithBiasAtNominalNoError, totalGoodCharge, totalGoodChargeWithBias, totalGoodChargeWithBiasAtNominal, totalGoodChargeWithBiasAtNominalNoError);
                 }
             }
         } catch (Exception ex) {

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/meeg/TridentMCFilter.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/meeg/TridentMCFilter.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/meeg/TridentMCFilter.java	Wed Apr 27 11:11:32 2016
@@ -16,8 +16,45 @@
  */
 public class TridentMCFilter extends EventReconFilter {
 
+    private boolean requireFrontHits = false;
+    private double minL12Kink = -1;
+    private double maxL12Kink = -1;
+    private double minL1Kink = -1;
+    private double maxL1Kink = -1;
+    private double minL2Kink = -1;
+    private double maxL2Kink = -1;
+
+    public void setMinL12Kink(double minL12Kink) {
+        this.minL12Kink = minL12Kink;
+    }
+
+    public void setMaxL12Kink(double maxL12Kink) {
+        this.maxL12Kink = maxL12Kink;
+    }
+
+    public void setMinL1Kink(double minL1Kink) {
+        this.minL1Kink = minL1Kink;
+    }
+
+    public void setMaxL1Kink(double maxL1Kink) {
+        this.maxL1Kink = maxL1Kink;
+    }
+
+    public void setMinL2Kink(double minL2Kink) {
+        this.minL2Kink = minL2Kink;
+    }
+
+    public void setMaxL2Kink(double maxL2Kink) {
+        this.maxL2Kink = maxL2Kink;
+    }
+
+    public void setRequireFrontHits(boolean requireFrontHits) {
+        this.requireFrontHits = requireFrontHits;
+    }
+
     @Override
     public void process(EventHeader event) {
+        incrementEventProcessed();
         List<MCParticle> MCParticles = event.getMCParticles();
 
         List<MCParticle> tridentParticles = null;
@@ -39,7 +76,11 @@
         int nElectronsWithTracks = 0, nPositronsWithTracks = 0;
         MCParticle electron = null, positron = null;
 
+        particleLoop:
         for (MCParticle particle : tridentParticles) {
+            if (!trackHitMap.containsKey(particle)) {
+                continue;
+            }
             Set<Integer> layers = trackHitMap.get(particle).keySet();
             int pairCount = 0;
             for (Integer layer : layers) {
@@ -47,31 +88,74 @@
                     pairCount++;
                 }
             }
-            boolean hasTrack = (pairCount >= 5);
+            if (pairCount < 5) {
+                continue;
+            }
+            if (requireFrontHits) {
+                for (int i = 1; i < 5; i++) {
+                    if (!layers.contains(i)) {
+                        continue particleLoop;
+                    }
+                }
+            }
 
-            if (hasTrack && particle.getCharge() < 0) {
+            if (particle.getCharge() < 0) {
                 nElectronsWithTracks++;
                 electron = particle;
             }
-            if (hasTrack && particle.getCharge() > 0) {
+            if (particle.getCharge() > 0) {
                 nPositronsWithTracks++;
                 positron = particle;
             }
         }
 
         if (electron == null || positron == null) {
-            System.out.println("not enough trident daughters with tracks");
+//            System.out.println("not enough trident daughters with tracks");
             skipEvent();
         }
 
         if (nElectronsWithTracks > 1 || nPositronsWithTracks > 1) {
-            System.out.println("too many trident daughters with tracks");
+//            System.out.println("too many trident daughters with tracks");
             skipEvent();
         }
 
-//        double deflection12_ele = KinkAnalysisDriver.deflection(trackHitMap.get(electron), 0, 4);
-//        double deflection12_pos = KinkAnalysisDriver.deflection(trackHitMap.get(positron), 0, 4);
+        double deflection12_ele = KinkAnalysisDriver.deflection(trackHitMap.get(electron), 0, 4);
+        double deflection12_pos = KinkAnalysisDriver.deflection(trackHitMap.get(positron), 0, 4);
+        double deflection1_ele = KinkAnalysisDriver.deflection(trackHitMap.get(electron), 0, 2);
+        double deflection1_pos = KinkAnalysisDriver.deflection(trackHitMap.get(positron), 0, 2);
+        double deflection2_ele = KinkAnalysisDriver.deflection(trackHitMap.get(electron), 2, 4);
+        double deflection2_pos = KinkAnalysisDriver.deflection(trackHitMap.get(positron), 2, 4);
+        if (minL12Kink > 0) {
+            if (Math.abs(deflection12_ele) < minL12Kink && Math.abs(deflection12_pos) < minL12Kink) {
+                skipEvent();
+            }
+        }
+        if (maxL12Kink > 0) {
+            if (Math.abs(deflection12_ele) > maxL12Kink || Math.abs(deflection12_pos) > maxL12Kink) {
+                skipEvent();
+            }
+        }
+        if (minL1Kink > 0) {
+            if (Math.abs(deflection1_ele) < minL1Kink && Math.abs(deflection1_pos) < minL1Kink) {
+                skipEvent();
+            }
+        }
+        if (maxL1Kink > 0) {
+            if (Math.abs(deflection1_ele) > maxL1Kink || Math.abs(deflection1_pos) > maxL1Kink) {
+                skipEvent();
+            }
+        }
+        if (minL2Kink > 0) {
+            if (Math.abs(deflection2_ele) < minL2Kink && Math.abs(deflection2_pos) < minL2Kink) {
+                skipEvent();
+            }
+        }
+        if (maxL2Kink > 0) {
+            if (Math.abs(deflection2_ele) > maxL2Kink || Math.abs(deflection2_pos) > maxL2Kink) {
+                skipEvent();
+            }
+        }
+
         incrementEventPassed();
-
     }
 }

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/mgraham/ExamplePlotter.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/mgraham/ExamplePlotter.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/mgraham/ExamplePlotter.java	Wed Apr 27 11:11:32 2016
@@ -4,6 +4,7 @@
 import hep.aida.IHistogram1D;
 import hep.aida.IPlotter;
 import hep.aida.IPlotterStyle;
+import hep.physics.vec.BasicHep3Vector;
 import hep.physics.vec.Hep3Vector;
 
 import java.io.IOException;
@@ -12,9 +13,10 @@
 import java.util.logging.Logger;
 
 import org.hps.recon.tracking.BeamlineConstants;
-import org.hps.recon.tracking.HPSTrack;
+import org.hps.recon.tracking.HpsHelicalTrackFit;
 import org.hps.recon.tracking.HelixConverter;
 import org.hps.recon.tracking.StraightLineTrack;
+import org.hps.recon.tracking.TrackUtils;
 import org.lcsim.event.EventHeader;
 import org.lcsim.event.Track;
 import org.lcsim.fit.helicaltrack.HelicalTrackFit;
@@ -76,15 +78,9 @@
             aida.histogram1D("Track Momentum (Pz)").fill(trk.getTrackStates().get(0).getMomentum()[0]);
             aida.histogram1D("Track Chi2").fill(trk.getChi2());
 
-            SeedTrack stEle = (SeedTrack) trk;
-            SeedCandidate seedEle = stEle.getSeedCandidate();
-            HelicalTrackFit ht = seedEle.getHelix();
-            HelixConverter converter = new HelixConverter(0);
-            StraightLineTrack slt = converter.Convert(ht);
-            HPSTrack hpstrack = new HPSTrack(ht);
-            Hep3Vector[] trkatconver = hpstrack.getPositionAtZMap(100, BeamlineConstants.HARP_POSITION_TESTRUN, 1);
-            aida.histogram1D("X (mm) @ Converter").fill(trkatconver[0].x()); // y tracker frame?
-            aida.histogram1D("Y (mm) @ Converter").fill(trkatconver[0].y()); // z tracker frame?
+            Hep3Vector trkatconver = new BasicHep3Vector(TrackUtils.extrapolateTrackUsingFieldMap(trk, 100.0, BeamlineConstants.HARP_POSITION_TESTRUN, 5.0, event.getDetector().getFieldMap()).getReferencePoint());
+            aida.histogram1D("X (mm) @ Converter").fill(trkatconver.x()); // y tracker frame?
+            aida.histogram1D("Y (mm) @ Converter").fill(trkatconver.y()); // z tracker frame?
 
         }
     }

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/mgraham/HPSTrackerHit.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/mgraham/HPSTrackerHit.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/mgraham/HPSTrackerHit.java	Wed Apr 27 11:11:32 2016
@@ -16,23 +16,23 @@
         double t0;
         double amp;                
       public HPSTrackerHit(
-    		long id,
-    		int time,
-    		short[] adcValues, double t0, double Amp) {
-    	this.cellId = id;
-    	this.packedID = new Identifier(id);
-    	this.time = time;
-    	this.adcValues = adcValues;
+            long id,
+            int time,
+            short[] adcValues, double t0, double Amp) {
+        this.cellId = id;
+        this.packedID = new Identifier(id);
+        this.time = time;
+        this.adcValues = adcValues;
         this.t0=t0;
         this.amp=Amp;        
     }
       
       public HPSTrackerHit(
-    		RawTrackerHit rth, double t0, double Amp) {
-    	this.cellId = rth.getCellID();
-    	this.packedID = new Identifier(rth.getCellID());
-    	this.time = rth.getTime();
-    	this.adcValues = rth.getADCValues();
+            RawTrackerHit rth, double t0, double Amp) {
+        this.cellId = rth.getCellID();
+        this.packedID = new Identifier(rth.getCellID());
+        this.time = rth.getTime();
+        this.adcValues = rth.getADCValues();
         this.t0=t0;
         this.amp=Amp;        
     }

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/mgraham/HelicalTrackHitResidualsDriver.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/mgraham/HelicalTrackHitResidualsDriver.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/mgraham/HelicalTrackHitResidualsDriver.java	Wed Apr 27 11:11:32 2016
@@ -16,10 +16,11 @@
 import java.util.logging.Logger;
 
 
+
 //===> import org.hps.conditions.deprecated.SvtUtils;
 import org.hps.recon.tracking.EventQuality;
 import org.hps.recon.tracking.TrackUtils;
-import org.hps.users.phansson.TrigRateDriver;
+import org.hps.users.phansson.testrun.TrigRateDriver;
 import org.lcsim.detector.tracker.silicon.HpsSiSensor;
 import org.lcsim.event.EventHeader;
 import org.lcsim.event.RawTrackerHit;

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/mgraham/SVTRawTrackerHitThresholdDriver.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/mgraham/SVTRawTrackerHitThresholdDriver.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/mgraham/SVTRawTrackerHitThresholdDriver.java	Wed Apr 27 11:11:32 2016
@@ -15,7 +15,7 @@
  * @author Matt Graham
  */
 // TODO: Check that this Driver works as expected after it was updated to use 
-// 		 the database conditions system.
+//       the database conditions system.
 public class SVTRawTrackerHitThresholdDriver extends Driver {
 
     private String rawTrackerHitCollectionName = "RawTrackerHitMaker_RawTrackerHits";

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/mgraham/TrackExtrapolationAnalysis.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/mgraham/TrackExtrapolationAnalysis.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/mgraham/TrackExtrapolationAnalysis.java	Wed Apr 27 11:11:32 2016
@@ -5,13 +5,14 @@
 import hep.aida.IHistogram2D;
 import hep.aida.IPlotter;
 import hep.aida.IPlotterStyle;
+import hep.physics.vec.BasicHep3Vector;
 import hep.physics.vec.Hep3Vector;
 
 import java.util.List;
 import java.util.Map;
 
 import org.hps.recon.tracking.BeamlineConstants;
-import org.hps.recon.tracking.HPSTrack;
+import org.hps.recon.tracking.HpsHelicalTrackFit;
 import org.hps.recon.tracking.HelixConverter;
 import org.hps.recon.tracking.StraightLineTrack;
 import org.hps.recon.tracking.TrackUtils;
@@ -99,10 +100,9 @@
                 charge = 0;//make plot look pretty
 //            System.out.println("Charge = " + charge + "; isTop = " + isTop);
 
-            HPSTrack hpstrk=null;
-                hpstrk = new HPSTrack(ht);
-//            Hep3Vector posAtConv = hpstrk.getPositionAtZ(zAtConverter, -101, -100, 0.1);
-            Hep3Vector posAtConv = hpstrk.getPositionAtZMap(100,BeamlineConstants.HARP_POSITION_TESTRUN , 5.0)[0];
+            HpsHelicalTrackFit hpstrk=null;
+                hpstrk = new HpsHelicalTrackFit(ht);
+                Hep3Vector posAtConv = new BasicHep3Vector(TrackUtils.extrapolateTrackUsingFieldMap(trk, 100, BeamlineConstants.HARP_POSITION_TESTRUN, 5.0, event.getDetector().getFieldMap()).getReferencePoint());
             double useThisx=posAtConv.x();
             double useThisy=posAtConv.y();
             
@@ -123,7 +123,7 @@
                 aida.histogram1D("Negative Y (mm) @ Converter").fill(useThisy);
             }
 //            Hep3Vector posAtConvShort = hpstrk.getPositionAtZ(zAtConverter, -0.1, 0, 0.01);
-            Hep3Vector posAtConvShort = hpstrk.getPositionAtZMap(0,BeamlineConstants.HARP_POSITION_TESTRUN, 5.0)[0];
+            Hep3Vector posAtConvShort = new BasicHep3Vector(TrackUtils.extrapolateTrackUsingFieldMap(trk, 0, BeamlineConstants.HARP_POSITION_TESTRUN, 5.0, event.getDetector().getFieldMap()).getReferencePoint());
             aida.histogram2D("Extrapolated X: short vs long fringe").fill(posAtConvShort.x(), posAtConv.x());
             aida.histogram2D("Extrapolated Y: short vs long fringe").fill(posAtConvShort.y(), posAtConv.y());
 
@@ -144,7 +144,8 @@
 //                Hep3Vector posAtEcalHPS = hpstrk.getPositionAtZMap(750,zCluster, 5.0);
                 double zCluster=clust.getPosition()[2];
  //               double zCluster=1450.0;
-                 Hep3Vector posAtEcalHPS = hpstrk.getPositionAtZMap(750,zCluster, 5.0)[0];
+                Hep3Vector posAtEcalHPS = new BasicHep3Vector(TrackUtils.extrapolateTrackUsingFieldMap(trk, 750, zCluster, 5.0, event.getDetector().getFieldMap()).getReferencePoint());
+
                 Hep3Vector posAtEcalExtend= TrackUtils.extrapolateTrack(trk,zCluster);
                 aida.histogram2D("ECal Extrapolation X :  HPS vs Extend").fill( posAtEcalExtend.y(),posAtEcalHPS.x()-posAtEcalExtend.y());
                 aida.histogram2D("ECal Extrapolation Y :  HPS vs Extend").fill( posAtEcalExtend.z(),posAtEcalHPS.y()-posAtEcalExtend.z());

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/mgraham/TwoTrackAnalysis.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/mgraham/TwoTrackAnalysis.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/mgraham/TwoTrackAnalysis.java	Wed Apr 27 11:11:32 2016
@@ -17,10 +17,12 @@
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
+import org.apache.commons.lang3.NotImplementedException;
 import org.hps.recon.tracking.BeamlineConstants;
-import org.hps.recon.tracking.HPSTrack;
+import org.hps.recon.tracking.HpsHelicalTrackFit;
 import org.hps.recon.tracking.HelixConverter;
 import org.hps.recon.tracking.StraightLineTrack;
+import org.hps.recon.tracking.TrackUtils;
 import org.lcsim.event.EventHeader;
 import org.lcsim.event.Track;
 import org.lcsim.event.TrackerHit;
@@ -273,10 +275,11 @@
             HelicalTrackFit ht = seedEle.getHelix();
             HelixConverter converter = new HelixConverter(0);
             StraightLineTrack slt = converter.Convert(ht);
-            HPSTrack hpstrack = new HPSTrack(ht);
-            Hep3Vector[] trkatconver = hpstrack.getPositionAtZMap(100, BeamlineConstants.HARP_POSITION_TESTRUN, 1);
-            aida.histogram1D("X (mm) @ Converter using Map").fill(trkatconver[0].x()); // y tracker frame?
-            aida.histogram1D("Y (mm) @ Converter using Map").fill(trkatconver[0].y()); // z tracker frame?
+            HpsHelicalTrackFit hpstrack = new HpsHelicalTrackFit(ht);
+            Hep3Vector trkatconver = new BasicHep3Vector(TrackUtils.extrapolateTrackUsingFieldMap(trk, 100, BeamlineConstants.HARP_POSITION_TESTRUN, 1, event.getDetector().getFieldMap()).getReferencePoint());
+
+            aida.histogram1D("X (mm) @ Converter using Map").fill(trkatconver.x()); // y tracker frame?
+            aida.histogram1D("Y (mm) @ Converter using Map").fill(trkatconver.y()); // z tracker frame?
             if (slt != null) {
                 aida.histogram1D("X (mm) @ Converter using SLT").fill(slt.getYZAtX(BeamlineConstants.HARP_POSITION_TESTRUN)[0]); // y tracker frame?
                 aida.histogram1D("Y (mm) @ Converter using SLT").fill(slt.getYZAtX(BeamlineConstants.HARP_POSITION_TESTRUN)[1]); // z tracker frame?
@@ -320,9 +323,9 @@
 //            HPSTrack hpstrack2 = new HPSTrack(ht2);
 //            Hep3Vector[] trkatconver2 = hpstrack2.getPositionAtZMap(100, BeamlineConstants.HARP_POSITION, 1);
 
-            HPSTrack hpstrack1 = new HPSTrack(ht1);
+            HpsHelicalTrackFit hpstrack1 = new HpsHelicalTrackFit(ht1);
             Hep3Vector[] trkatconver1 = {new BasicHep3Vector(), new BasicHep3Vector(0, 0, 0)};
-            HPSTrack hpstrack2 = new HPSTrack(ht2);
+            HpsHelicalTrackFit hpstrack2 = new HpsHelicalTrackFit(ht2);
             Hep3Vector[] trkatconver2 = {new BasicHep3Vector(), new BasicHep3Vector(0, 0, 0)};;
             if (isMC) {
                 double[] t1 = slt1.getYZAtX(BeamlineConstants.HARP_POSITION_TESTRUN);
@@ -330,8 +333,9 @@
                 trkatconver1[0] = new BasicHep3Vector(t1[0], t1[1], BeamlineConstants.HARP_POSITION_TESTRUN);
                 trkatconver2[0] = new BasicHep3Vector(t2[0], t2[1], BeamlineConstants.HARP_POSITION_TESTRUN);
             } else {
-                trkatconver1 = hpstrack1.getPositionAtZMap(100, BeamlineConstants.HARP_POSITION_TESTRUN, 1);
-                trkatconver2 = hpstrack2.getPositionAtZMap(100, BeamlineConstants.HARP_POSITION_TESTRUN, 1);
+                throw new NotImplementedException("Need to implement using TrackUtils to extrapolate tracks!");
+                //trkatconver1 = hpstrack1.getPositionAtZMap(100, BeamlineConstants.HARP_POSITION_TESTRUN, 1);
+                //trkatconver2 = hpstrack2.getPositionAtZMap(100, BeamlineConstants.HARP_POSITION_TESTRUN, 1);
             }
             List<TrackerHit> hitsOnTrack1 = trk1.getTrackerHits();
             int layer1;
@@ -508,9 +512,10 @@
                             posvec[1] = slt1.getYZAtX(z)[1];
                             posvec[2] = z;
                         } else {
-                            Hep3Vector[] trk1atz = hpstrack1.getPositionAtZMap(100, z, 1);
-                            posvec[0] = trk1atz[0].x();
-                            posvec[1] = trk1atz[0].y();
+                            Hep3Vector trk1atz = new BasicHep3Vector(TrackUtils.extrapolateTrackUsingFieldMap(trk1, 100, z, 1, event.getDetector().getFieldMap()).getReferencePoint());
+
+                            posvec[0] = trk1atz.x();
+                            posvec[1] = trk1atz.y();
                             posvec[2] = z;
                         }
                         Trk1.add(posvec);
@@ -592,9 +597,10 @@
                             posvec2[1] = slt2.getYZAtX(z)[1];
                             posvec2[2] = z;
                         } else {
-                            Hep3Vector[] trk2atz = hpstrack2.getPositionAtZMap(100, z, 1);
-                            posvec2[0] = trk2atz[0].x();
-                            posvec2[1] = trk2atz[0].y();
+                            Hep3Vector trk2atz = new BasicHep3Vector(TrackUtils.extrapolateTrackUsingFieldMap(trk2, 100, z, 1, event.getDetector().getFieldMap()).getReferencePoint());
+
+                            posvec2[0] = trk2atz.x();
+                            posvec2[1] = trk2atz.y();
                             posvec2[2] = z;
                         }
                         Trk2.add(posvec2);

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/omoreno/EcalScoringPlaneDriver.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/omoreno/EcalScoringPlaneDriver.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/omoreno/EcalScoringPlaneDriver.java	Wed Apr 27 11:11:32 2016
@@ -23,136 +23,136 @@
  */
 public class EcalScoringPlaneDriver extends Driver {
 
-	boolean verbose = false;
-	
-	// Collection Names
-	String ecalScoringPlaneHitsCollectionName = "TrackerHitsECal";
-	String tracksCollectionName = "MatchedTracks";
-	String trackToScoringPlaneHitRelationsName = "TrackToEcalScoringPlaneHitRelations";
-	String trackToMCParticleRelationsName = "TrackToMCParticleRelations";
-	
-	/**
-	 * Enable/disable verbose mode
-	 * 
-	 * @param verbose : set true to enable, false otherwise
-	 */
-	public void setVerbose(boolean verbose){
-		this.verbose = verbose; 
-	}
-	
-	@Override
-	protected void process(EventHeader event){
-		
-		// If the event doesn't have a collection of Tracks, skip it
-		if(!event.hasCollection(Track.class, tracksCollectionName)) return;
-		
-		// If the event doesn't have a collection of Ecal scoring plane hits, 
-		// skip it
-		if(!event.hasCollection(SimTrackerHit.class, ecalScoringPlaneHitsCollectionName)) return;
-		
-		// Get the collection of tracks from the event
-		List<Track> tracks = event.get(Track.class, tracksCollectionName);
-		
-		// Get the collection of Ecal scoring plane hits from the event
-		List<SimTrackerHit> scoringPlaneHits = event.get(SimTrackerHit.class, ecalScoringPlaneHitsCollectionName);
-		
-		// Create a collection to hold the scoring plane hits that were found to match
-		// a track
-		List<SimTrackerHit> matchedScoringPlaneHits = new ArrayList<SimTrackerHit>(); 
-		
-		// Create a collection of LCRelations between a track and the scoring plane hit
-		List<LCRelation> trackToScoringPlaneHitRelations = new ArrayList<LCRelation>();
-	
-		// Create a collection of LCRelations between a track and its corresponding MC particle
-		List<LCRelation> trackToMCParticleRelations = new ArrayList<LCRelation>();
-	
-		MCParticle particle = null;
-		for(Track track : tracks){
-		
-			// Get the MC particle associated with this track
-			particle = this.getMCParticleAssociatedWithTrack(track);
-			// If the MC particle is null, then the hits associated with the
-			// track did not have an MC particle associated with them
-			// TODO: Find out why some hits don't have any MC particles associated with them
-			if(particle == null) continue;
-		
-			// Add an LCRelation between the track and the corresponding MC particle
-			trackToMCParticleRelations.add(new BaseLCRelation(track, particle));
-			
-			// Loop over all of the scoring plane hits and check if the associated MC particle
-			// matches the one from the track
-			for(SimTrackerHit scoringPlaneHit : scoringPlaneHits){
-	
-				// If the MC particles don't match, move on to the next particle
-				if(!(scoringPlaneHit.getMCParticle() == particle)) continue; 
-					
-				this.printVerbose("Found a match between a track and a scoring plane hit.");
-				
-				// If a match is found, add the scoring plane hit to the list of matched hits and
-				// an LCRelation between the track and the scoring plane.
-				matchedScoringPlaneHits.add(scoringPlaneHit);
-				trackToScoringPlaneHitRelations.add(new BaseLCRelation(track, scoringPlaneHit));
-				
-				// Once a match is found, there is no need to loop through the rest of the list
-				break;
-			}
-		}
-		
-		// Store all of the collections in the event
-		event.put(ecalScoringPlaneHitsCollectionName, matchedScoringPlaneHits, SimTrackerHit.class, 0);
-		event.put(trackToScoringPlaneHitRelationsName, trackToScoringPlaneHitRelations, LCRelation.class, 0);
-		event.put(trackToMCParticleRelationsName, trackToMCParticleRelations, LCRelation.class, 0);
-	}
-	
-	/**
-	 * Print a message if verbose has been enabled.
-	 *  
-	 * @param message : message to print.
-	 */
-	private void printVerbose(String message){
-		if(verbose)
-			System.out.println(this.getClass().getSimpleName() + ": " + message);
-	}
-	
-	/**
-	 * Get the MC particle associated with a track.
-	 * 
-	 * @param track : Track to get the MC particle for
-	 * @return The MC particle associated with the track
-	 */
-	private MCParticle getMCParticleAssociatedWithTrack(Track track){
-		
-		Map <MCParticle, int[]>mcParticleMultiplicity = new HashMap<MCParticle, int[]>();
-		MCParticle particle;
-		for(TrackerHit hit : track.getTrackerHits()){
-		
-				// If one of the tracker hits doesn't have any MC particles associated
-				// with it, return null for now.
-				if(((HelicalTrackHit) hit).getMCParticles().size() == 0){
-					this.printVerbose("HelicalTrackHit is not associated with any MC particles.");
-					return null;
-				}
-				
-				particle = ((HelicalTrackHit) hit).getMCParticles().get(0);
-				if(!mcParticleMultiplicity.containsKey(particle)){
-					mcParticleMultiplicity.put(particle, new int[1]);
-					mcParticleMultiplicity.get(particle)[0] = 0;
-				}
-				
-				mcParticleMultiplicity.get(particle)[0]++;
-				
-		}
-		
-		// Look for the MC particle that occurs the most of the track
-		int maxValue = 0;
-		particle = null;
-		for(Map.Entry<MCParticle, int[]> entry : mcParticleMultiplicity.entrySet()){
-			if(maxValue < entry.getValue()[0]){
-				particle = entry.getKey();
-				maxValue = entry.getValue()[0];
-			}
-		}
-		
-		return particle;
-	}
+    boolean verbose = false;
+    
+    // Collection Names
+    String ecalScoringPlaneHitsCollectionName = "TrackerHitsECal";
+    String tracksCollectionName = "MatchedTracks";
+    String trackToScoringPlaneHitRelationsName = "TrackToEcalScoringPlaneHitRelations";
+    String trackToMCParticleRelationsName = "TrackToMCParticleRelations";
+    
+    /**
+     * Enable/disable verbose mode
+     * 
+     * @param verbose : set true to enable, false otherwise
+     */
+    public void setVerbose(boolean verbose){
+        this.verbose = verbose; 
+    }
+    
+    @Override
+    protected void process(EventHeader event){
+        
+        // If the event doesn't have a collection of Tracks, skip it
+        if(!event.hasCollection(Track.class, tracksCollectionName)) return;
+        
+        // If the event doesn't have a collection of Ecal scoring plane hits, 
+        // skip it
+        if(!event.hasCollection(SimTrackerHit.class, ecalScoringPlaneHitsCollectionName)) return;
+        
+        // Get the collection of tracks from the event
+        List<Track> tracks = event.get(Track.class, tracksCollectionName);
+        
+        // Get the collection of Ecal scoring plane hits from the event
+        List<SimTrackerHit> scoringPlaneHits = event.get(SimTrackerHit.class, ecalScoringPlaneHitsCollectionName);
+        
+        // Create a collection to hold the scoring plane hits that were found to match
+        // a track
+        List<SimTrackerHit> matchedScoringPlaneHits = new ArrayList<SimTrackerHit>(); 
+        
+        // Create a collection of LCRelations between a track and the scoring plane hit
+        List<LCRelation> trackToScoringPlaneHitRelations = new ArrayList<LCRelation>();
+    
+        // Create a collection of LCRelations between a track and its corresponding MC particle
+        List<LCRelation> trackToMCParticleRelations = new ArrayList<LCRelation>();
+    
+        MCParticle particle = null;
+        for(Track track : tracks){
+        
+            // Get the MC particle associated with this track
+            particle = this.getMCParticleAssociatedWithTrack(track);
+            // If the MC particle is null, then the hits associated with the
+            // track did not have an MC particle associated with them
+            // TODO: Find out why some hits don't have any MC particles associated with them
+            if(particle == null) continue;
+        
+            // Add an LCRelation between the track and the corresponding MC particle
+            trackToMCParticleRelations.add(new BaseLCRelation(track, particle));
+            
+            // Loop over all of the scoring plane hits and check if the associated MC particle
+            // matches the one from the track
+            for(SimTrackerHit scoringPlaneHit : scoringPlaneHits){
+    
+                // If the MC particles don't match, move on to the next particle
+                if(!(scoringPlaneHit.getMCParticle() == particle)) continue; 
+                    
+                this.printVerbose("Found a match between a track and a scoring plane hit.");
+                
+                // If a match is found, add the scoring plane hit to the list of matched hits and
+                // an LCRelation between the track and the scoring plane.
+                matchedScoringPlaneHits.add(scoringPlaneHit);
+                trackToScoringPlaneHitRelations.add(new BaseLCRelation(track, scoringPlaneHit));
+                
+                // Once a match is found, there is no need to loop through the rest of the list
+                break;
+            }
+        }
+        
+        // Store all of the collections in the event
+        event.put(ecalScoringPlaneHitsCollectionName, matchedScoringPlaneHits, SimTrackerHit.class, 0);
+        event.put(trackToScoringPlaneHitRelationsName, trackToScoringPlaneHitRelations, LCRelation.class, 0);
+        event.put(trackToMCParticleRelationsName, trackToMCParticleRelations, LCRelation.class, 0);
+    }
+    
+    /**
+     * Print a message if verbose has been enabled.
+     *  
+     * @param message : message to print.
+     */
+    private void printVerbose(String message){
+        if(verbose)
+            System.out.println(this.getClass().getSimpleName() + ": " + message);
+    }
+    
+    /**
+     * Get the MC particle associated with a track.
+     * 
+     * @param track : Track to get the MC particle for
+     * @return The MC particle associated with the track
+     */
+    private MCParticle getMCParticleAssociatedWithTrack(Track track){
+        
+        Map <MCParticle, int[]>mcParticleMultiplicity = new HashMap<MCParticle, int[]>();
+        MCParticle particle;
+        for(TrackerHit hit : track.getTrackerHits()){
+        
+                // If one of the tracker hits doesn't have any MC particles associated
+                // with it, return null for now.
+                if(((HelicalTrackHit) hit).getMCParticles().size() == 0){
+                    this.printVerbose("HelicalTrackHit is not associated with any MC particles.");
+                    return null;
+                }
+                
+                particle = ((HelicalTrackHit) hit).getMCParticles().get(0);
+                if(!mcParticleMultiplicity.containsKey(particle)){
+                    mcParticleMultiplicity.put(particle, new int[1]);
+                    mcParticleMultiplicity.get(particle)[0] = 0;
+                }
+                
+                mcParticleMultiplicity.get(particle)[0]++;
+                
+        }
+        
+        // Look for the MC particle that occurs the most of the track
+        int maxValue = 0;
+        particle = null;
+        for(Map.Entry<MCParticle, int[]> entry : mcParticleMultiplicity.entrySet()){
+            if(maxValue < entry.getValue()[0]){
+                particle = entry.getKey();
+                maxValue = entry.getValue()[0];
+            }
+        }
+        
+        return particle;
+    }
 }

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/omoreno/ExtrapolationAnalysis.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/omoreno/ExtrapolationAnalysis.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/omoreno/ExtrapolationAnalysis.java	Wed Apr 27 11:11:32 2016
@@ -30,312 +30,312 @@
  */
 public class ExtrapolationAnalysis  extends Driver {
 
-	AIDA aida = null;
-	List<IPlotter> plotters;
-
-	Hep3Vector bField = null;
-	
-	boolean verbose = false;
-	
-	// Collection Names
-	String matchedEcalScoringPlaneHitsCollectionName = "MatchedTrackerHitsEcal";
-	String trackToScoringPlaneHitRelationsName = "TrackToEcalScoringPlaneHitRelations";
-	String trackToMCParticleRelationsName = "TrackToMCParticleRelations";
-	
-	/**
-	 * Enable/disable verbose mode
-	 * 
-	 * @param verbose : true to enable, false otherwise
-	 */
-	public void setVerbose(boolean verbose){
-		this.verbose = verbose; 
-	}
-	
-	public void detectorChanged(Detector detector){
-		
-		// Get the magnetic field from the geometry
-		bField = detector.getFieldMap().getField(new BasicHep3Vector(0,0,0));
-		
-		//-----------------------//
-		//--- Setup all plots ---//
-		//-----------------------//
-		
-		// Setup AIDA
-		aida = AIDA.defaultInstance();
-		aida.tree().cd("/");
-	
-		// Instantiate a list to hold the collection of plotters
-		plotters = new ArrayList<IPlotter>();
-		IPlotter plotter = null; 
-		
-		//--- Plots of scoring plane positions ---//
-		//----------------------------------------//
-		plotter = PlotUtils.setupPlotter("Positions of Scoring plane hits matched to tracks", 2, 2);
-		PlotUtils.setup1DRegion(plotter, "Scoring plane hit position - x", 0, "x (mm)",
-				aida.histogram1D("Scoring plane hit position - x", 100, -400, 400));
-		PlotUtils.setup1DRegion(plotter, "Scoring plane hit position - y", 1, "y (mm)",
-				aida.histogram1D("Scoring plane hit position - y", 100, -200, 200));
-		PlotUtils.setup1DRegion(plotter, "Scoring plane hit position - z", 2, "z (mm)",
-				aida.histogram1D("Scoring plane hit position - z", 100, 1000, 1500));
-		PlotUtils.setup2DRegion(plotter, "Scoring plane hit position - x-y", 3, "x (mm)", "y (mm)", 
-				aida.histogram2D("Scoring plane hit position - x-y", 100, -400, 400, 100, -200, 200));
-		plotters.add(plotter);	
-
-		//--- Plots of residuals at scoring plane ---//
-		//-------------------------------------------//
-		plotter = PlotUtils.setupPlotter("Residuals at scoring plane", 3, 3);
-		PlotUtils.setup1DRegion(plotter, "Top tracks - Bend plane residuals at scoring plane", 0, "x_{ep} - x_{sp} (mm)",
-				aida.histogram1D("Top electron tracks - Bend plane residual at scoring plane", 60, -30, 30));
-		PlotUtils.setup1DRegion(plotter, "Top tracks - Bend plane residuals at scoring plane", 0, "x_{ep} - x_{sp} (mm)",
-				aida.histogram1D("Top positron tracks - Bend plane residual at scoring plane", 60, -30, 30));
-		PlotUtils.setup1DRegion(plotter, "Bottom tracks - Bend plane residuals at scoring plane", 1, "x_{ep} - x_{sp} (mm)",
-				aida.histogram1D("Bottom electron tracks - Bend plane residuals at scoring plane", 60, -30, 30));
-		PlotUtils.setup1DRegion(plotter, "Bottom tracks - Bend plane residuals at scoring plane", 1, "x_{ep} - x_{sp} (mm)",
-				aida.histogram1D("Bottom positron tracks - Bend plane residuals at scoring plane", 60, -30, 30));
-		PlotUtils.setup1DRegion(plotter, "Bend plane residuals at scoring plane", 2, "x_{ep} - x_{sp} (mm)",
-				aida.histogram1D("Bend plane residuals at scoring plane", 60, -30, 30));
-		PlotUtils.setup1DRegion(plotter, "Bend plane residuals at scoring plane", 2, "x_{ep} - x_{sp} (mm)",
-				aida.histogram1D("Bend plane residuals at scoring plane", 60, -30, 30));
-		PlotUtils.setup1DRegion(plotter, "Top tracks - Non-bend plane residuals at scoring plane", 3,"y_{ep} - y_{sp} (mm)", 
-				aida.histogram1D("Top electron tracks - Non-bend plane residuals at scoring plane", 30, -15, 15));
-		PlotUtils.setup1DRegion(plotter, "Top tracks - Non-bend plane residuals at scoring plane", 3,"y_{ep} - y_{sp} (mm)", 
-				aida.histogram1D("Top positron tracks - Non-bend plane residuals at scoring plane", 30, -15, 15));
-		PlotUtils.setup1DRegion(plotter, "Bottom tracks - Non-bend plane residuals at scoring plane", 4,"y_{ep} - y_{sp} (mm)", 
-				aida.histogram1D("Bottom electron tracks - Non-bend plane residuals at scoring plane", 30, -15, 15));
-		PlotUtils.setup1DRegion(plotter, "Bottom tracks - Non-bend plane residuals at scoring plane", 4,"y_{ep} - y_{sp} (mm)", 
-				aida.histogram1D("Bottom positron tracks - Non-bend plane residuals at scoring plane", 30, -15, 15));
-		PlotUtils.setup1DRegion(plotter, "Non-bend plane residuals at scoring plane", 5,"y_{ep} - y_{sp} (mm)", 
-				aida.histogram1D("Non-bend plane residuals at scoring plane", 30, -15, 15));
-		PlotUtils.setup1DRegion(plotter, "Top tracks - z residuals at scoring plane", 6, "z_{ep} - z_{sp} (mm)",
-				aida.histogram1D("Top electron tracks - z residuals at scoring plane", 10, -5, 5));
-		PlotUtils.setup1DRegion(plotter, "Top tracks - z residuals at scoring plane", 6, "z_{ep} - z_{sp} (mm)",
-				aida.histogram1D("Top positron tracks - z residuals at scoring plane", 10, -5, 5));
-		PlotUtils.setup1DRegion(plotter, "Bottom tracks - z residuals at scoring plane", 7, "z_{ep} - z_{sp} (mm)",
-				aida.histogram1D("Bottom electron tracks - z residuals at scoring plane", 10, -5, 5));
-		PlotUtils.setup1DRegion(plotter, "Bottom tracks - z residuals at scoring plane", 7, "z_{ep} - z_{sp} (mm)",
-				aida.histogram1D("Bottom positron tracks - z residuals at scoring plane", 10, -5, 5));
-		PlotUtils.setup1DRegion(plotter, "z residuals at scoring plane", 7, "z_{ep} - z_{sp} (mm)",
-				aida.histogram1D("z residuals at scoring plane", 10, -5, 5));
-		plotters.add(plotter);	
-		
-		//--- Plots of residuals at target ---//
-		//------------------------------------//
-		plotter = PlotUtils.setupPlotter("Residuals at target", 3, 3);
-		PlotUtils.setup1DRegion(plotter, "Top tracks - Bend plane residuals at target", 0, "x_{ep} - x_{t} (mm)",
-				aida.histogram1D("Top electron tracks - Bend plane residual at target", 40, -4, 4));
-		PlotUtils.setup1DRegion(plotter, "Top tracks - Bend plane residuals at target", 0, "x_{ep} - x_{t} (mm)",
-				aida.histogram1D("Top positron tracks - Bend plane residual at target", 40, -4, 4));
-		PlotUtils.setup1DRegion(plotter, "Bottom tracks - Bend plane residuals at target", 1, "x_{ep} - x_{t} (mm)",
-				aida.histogram1D("Bottom electron tracks - Bend plane residuals at target", 40, -4, 4));
-		PlotUtils.setup1DRegion(plotter, "Bottom tracks - Bend plane residuals at target", 1, "x_{ep} - x_{t} (mm)",
-				aida.histogram1D("Bottom positron tracks - Bend plane residuals at target", 40, -4, 4));
-		PlotUtils.setup1DRegion(plotter, "Bend plane residuals at target", 2, "x_{ep} - x_{t} (mm)",
-				aida.histogram1D("Bend plane residuals at target", 40, -4, 4));
-		PlotUtils.setup1DRegion(plotter, "Top tracks - Non-bend plane residuals at target", 3, "y_{ep} - y_{t} (mm)",
-				aida.histogram1D("Top electron tracks - Non-bend plane residuals at target", 20, -2, 2));
-		PlotUtils.setup1DRegion(plotter, "Top tracks - Non-bend plane residuals at target", 3, "y_{ep} - y_{t} (mm)",
-				aida.histogram1D("Top positron tracks - Non-bend plane residuals at target", 20, -2, 2));
-		PlotUtils.setup1DRegion(plotter, "Bottom tracks - Non-bend plane residuals at target", 4, "y_{ep} - y_{t} (mm)",
-				aida.histogram1D("Bottom electron tracks - Non-bend plane residuals at target", 20, -2, 2));
-		PlotUtils.setup1DRegion(plotter, "Bottom tracks - Non-bend plane residuals at target", 4, "y_{ep} - y_{t} (mm)",
-				aida.histogram1D("Bottom positron tracks - Non-bend plane residuals at target", 20, -2, 2));
-		PlotUtils.setup1DRegion(plotter, "Non-bend plane residuals at target", 5, "y_{ep} - y_{t} (mm)",
-				aida.histogram1D("Non-bend plane residuals at target", 20, -2, 2));
-		PlotUtils.setup1DRegion(plotter, "Top tracks - z residuals at target", 6, "z_{ep} - z_{t} (mm)",
-				aida.histogram1D("Top electron tracks - z residuals at target", 50, -5, 5));
-		PlotUtils.setup1DRegion(plotter, "Top tracks - z residuals at target", 6, "z_{ep} - z_{t} (mm)",
-				aida.histogram1D("Top positron tracks - z residuals at target", 50, -5, 5));
-		PlotUtils.setup1DRegion(plotter, "Bottom tracks - z residuals at target", 7, "z_{ep} - z_{t} (mm)",
-				aida.histogram1D("Bottom electron tracks - z residuals at target", 50, -5, 5));
-		PlotUtils.setup1DRegion(plotter, "Bottom tracks - z residuals at target", 7, "z_{ep} - z_{t} (mm)",
-				aida.histogram1D("Bottom positron tracks - z residuals at target", 50, -5, 5));
-		PlotUtils.setup1DRegion(plotter, "z residuals at target", 8, "z_{ep} - z_{t} (mm)",
-				aida.histogram1D("z residuals at target", 50, -5, 5));
-		plotters.add(plotter);	
-		
-		//--- Plot of residuals at scoring plane vs momentum ---//
-		//------------------------------------------------------//
-		plotter = PlotUtils.setupPlotter("Residuals vs Momentum", 2, 2);
-		PlotUtils.setup2DRegion(plotter, "Bend plane residuals vs momentum at scoring plane", 0, 
-				"Momentum (GeV)", "x_{ep} - x_{sp} (mm)",
-				aida.histogram2D("Bend plane residuals vs momentum at scoring plane", 5, 0, 2.5, 60, -30, 30));
-		PlotUtils.setup2DRegion(plotter, "Non-bend plane residuals vs momentum at scoring plane", 1, 
-				"Momentum (GeV)", "y_{ep} - y_{sp} (mm)",
-				aida.histogram2D("Non-bend plane residuals vs momentum at scoring plane", 5, 0, 2.5, 60, -30, 30));
-		PlotUtils.setup2DRegion(plotter, "Bend plane residuals vs momentum at target", 2, 
-				"Momentum (GeV)", "x_{ep} - x_{t} (mm)",
-				aida.histogram2D("Bend plane residuals vs momentum at target", 5, 0, 2.5, 60, -3, 3));
-		PlotUtils.setup2DRegion(plotter, "Non-bend plane residuals vs momentum at target", 3, 
-				"Momentum (GeV)", "y_{ep} - y_{t} (mm)",
-				aida.histogram2D("Non-bend plane residuals vs momentum at target", 5, 0, 2.5, 50, -2.5, 2.5));
-		plotters.add(plotter);
-		
-		for(IPlotter iPlotter : plotters){
-			iPlotter.show(); 
-		}
-		
-	}
-	
-	public void process(EventHeader event){
-	
-		// If the event doesn't contain an LCRelation between a track and its 
-		// corresponding ECal scoring plane hit, skip the event.
-		if(!event.hasCollection(LCRelation.class, trackToScoringPlaneHitRelationsName)) return;
-		
-		List<LCRelation> trackToScoringPlaneHitRelations = event.get(LCRelation.class, trackToScoringPlaneHitRelationsName);
-		
-		for(LCRelation trackToScoringPlaneHitRelation : trackToScoringPlaneHitRelations){
-		
-			// Get the track
-			Track track = (Track) trackToScoringPlaneHitRelation.getFrom();
-			
-			// Get the track momentum
-			double[] momentum = BaseTrackState.computeMomentum(track.getTrackStates().get(0), bField.y());
-			double p = Math.sqrt(momentum[0]*momentum[0] + momentum[1]*momentum[1] + momentum[2]*momentum[2]);
-			this.printVerbose("Track momentum: " + p);
-			
-			// Get the corresponding scoring plane hit
-			SimTrackerHit scoringPlaneHit = (SimTrackerHit) trackToScoringPlaneHitRelation.getTo();
-			Hep3Vector scoringPlaneHitPosition = scoringPlaneHit.getPositionVec();
-			this.printVerbose("Scoring plane hit position: " + scoringPlaneHitPosition.toString());
-			
-			// Fill the scoring plane position histograms
-			aida.histogram1D("Scoring plane hit position - x").fill(scoringPlaneHitPosition.x());
-			aida.histogram1D("Scoring plane hit position - y").fill(scoringPlaneHitPosition.y());
-			aida.histogram1D("Scoring plane hit position - z").fill(scoringPlaneHitPosition.z());
-			aida.histogram2D("Scoring plane hit position - x-y").fill(scoringPlaneHitPosition.x(), scoringPlaneHitPosition.y());
-		
-			// Extrapolate the track to the scoring plane position
-			Hep3Vector trackPositionAtScoringPlane = TrackUtils.extrapolateTrack(track, scoringPlaneHitPosition.z());
-			this.printVerbose("Extrapolated track position: " + trackPositionAtScoringPlane.toString());
-				
-			// Find the residual between the extrapolated track position and the scoring plane hit position
-			double deltaX = trackPositionAtScoringPlane.x() - scoringPlaneHitPosition.x();
-			double deltaY = trackPositionAtScoringPlane.y() - scoringPlaneHitPosition.y();
-			// This should be 0 but it serves as a sanity check.
-			double deltaZ = trackPositionAtScoringPlane.z() - scoringPlaneHitPosition.z();
-		
-			if(track.getTrackerHits().get(0).getPosition()[2] > 0){
-				if(track.getTrackStates().get(0).getOmega() > 0){
-					aida.histogram1D("Top positron tracks - Bend plane residual at scoring plane").fill(deltaX);
-					aida.histogram1D("Top positron tracks - Non-bend plane residuals at scoring plane").fill(deltaY);
-					aida.histogram1D("Top positron tracks - z residuals at scoring plane").fill(deltaZ);	
-				} else { 
-					aida.histogram1D("Top electron tracks - Bend plane residual at scoring plane").fill(deltaX);
-					aida.histogram1D("Top electron tracks - Non-bend plane residuals at scoring plane").fill(deltaY);
-					aida.histogram1D("Top electron tracks - z residuals at scoring plane").fill(deltaZ);	
-				}
-			} else { 
-				if(track.getTrackStates().get(0).getOmega() > 0){
-					aida.histogram1D("Bottom positron tracks - Bend plane residuals at scoring plane").fill(deltaX);
-					aida.histogram1D("Bottom positron tracks - Non-bend plane residuals at scoring plane").fill(deltaY);
-					aida.histogram1D("Bottom positron tracks - z residuals at scoring plane").fill(deltaZ);
-				} else { 
-					aida.histogram1D("Bottom electron tracks - Bend plane residuals at scoring plane").fill(deltaX);
-					aida.histogram1D("Bottom electron tracks - Non-bend plane residuals at scoring plane").fill(deltaY);
-					aida.histogram1D("Bottom electron tracks - z residuals at scoring plane").fill(deltaZ);
-				}
-			}
-
-			aida.histogram1D("Bend plane residuals at scoring plane").fill(deltaX);
-			aida.histogram1D("Non-bend plane residuals at scoring plane").fill(deltaY);
-			aida.histogram1D("z residuals at target").fill(deltaZ);
-			aida.histogram2D("Bend plane residuals vs momentum at scoring plane").fill(p, deltaX);
-			aida.histogram2D("Non-bend plane residuals vs momentum at scoring plane").fill(p, deltaY);
-		}
-		
-		if(!event.hasCollection(LCRelation.class, trackToMCParticleRelationsName)) return;
-		
-		List<LCRelation> trackToMCParticleRelations = event.get(LCRelation.class, trackToMCParticleRelationsName);
-		
-		for(LCRelation trackToMCParticleRelation : trackToMCParticleRelations){
-			
-			// Get the track
-			Track track = (Track) trackToMCParticleRelation.getFrom();
-			
-			// Get the track momentum
-			double[] momentum = BaseTrackState.computeMomentum(track.getTrackStates().get(0), bField.y());
-			double p = Math.sqrt(momentum[0]*momentum[0] + momentum[1]*momentum[1] + momentum[2]*momentum[2]);
-			this.printVerbose("Track momentum: " + p);
-
-			// Get the corresponding MC particle
-			MCParticle particle = (MCParticle) trackToMCParticleRelation.getTo();
-			
-			// Extrapolate the track to the origin
-			Hep3Vector trackPositionAtOrigin = TrackUtils.extrapolateTrack(track, particle.getOriginZ());
-			
-			// Find the residual between the extrapolated track and the position of the scoring plane at the origin
-			double deltaX = trackPositionAtOrigin.x() - particle.getOriginX();
-			double deltaY = trackPositionAtOrigin.y() - particle.getOriginY();
-			double deltaZ = trackPositionAtOrigin.z() - particle.getOriginZ();
-			
-			if(track.getTrackerHits().get(0).getPosition()[2] > 0){
-				if(track.getTrackStates().get(0).getOmega() > 0){
-					aida.histogram1D("Top positron tracks - Bend plane residual at target").fill(deltaX);
-					aida.histogram1D("Top positron tracks - Non-bend plane residuals at target").fill(deltaY);
-					aida.histogram1D("Top positron tracks - z residuals at target").fill(deltaZ);
-				} else { 
-					aida.histogram1D("Top electron tracks - Bend plane residual at target").fill(deltaX);
-					aida.histogram1D("Top electron tracks - Non-bend plane residuals at target").fill(deltaY);
-					aida.histogram1D("Top electron tracks - z residuals at target").fill(deltaZ);
-				}
-			} else { 
-				
-				if(track.getTrackStates().get(0).getOmega() > 0){
-					aida.histogram1D("Bottom positron tracks - Bend plane residuals at target").fill(deltaX);
-					aida.histogram1D("Bottom positron tracks - Non-bend plane residuals at target").fill(deltaY);
-					aida.histogram1D("Bottom positron tracks - z residuals at target").fill(deltaZ);
-				} else { 
-					aida.histogram1D("Bottom electron tracks - Bend plane residuals at target").fill(deltaX);
-					aida.histogram1D("Bottom electron tracks - Non-bend plane residuals at target").fill(deltaY);
-					aida.histogram1D("Bottom electron tracks - z residuals at target").fill(deltaZ);
-				}
-			}
-			
-			aida.histogram1D("Bend plane residuals at target").fill(deltaX);
-			aida.histogram1D("Non-bend plane residuals at target").fill(deltaY);
-			aida.histogram1D("z residuals at target").fill(deltaZ);
-			aida.histogram2D("Bend plane residuals vs momentum at target").fill(p, deltaX);
-			aida.histogram2D("Non-bend plane residuals vs momentum at target").fill(p, deltaY);
-		}
-	}
-	
-	@Override
-	protected void endOfData(){
-		
-		IHistogram2D histogram = aida.histogram2D("Bend plane residuals vs momentum at scoring plane");
-		int binsX = histogram.xAxis().bins();
-		for(int binX = 0; binX < binsX; binX++){
-			PlotUtils.getYProjection(binX, histogram);
-		}
-		
-		histogram = aida.histogram2D("Non-bend plane residuals vs momentum at scoring plane");
-		binsX = histogram.xAxis().bins();
-		for(int binX = 0; binX < binsX; binX++){
-			PlotUtils.getYProjection(binX, histogram);
-		}
-	
-		histogram = aida.histogram2D("Bend plane residuals vs momentum at target");
-		binsX = histogram.xAxis().bins();
-		for(int binX = 0; binX < binsX; binX++){
-			PlotUtils.getYProjection(binX, histogram);
-		}
-		
-		histogram = aida.histogram2D("Non-bend plane residuals vs momentum at target");
-		binsX = histogram.xAxis().bins();
-		for(int binX = 0; binX < binsX; binX++){
-			PlotUtils.getYProjection(binX, histogram);
-		}
-	}
-	
-	/**
-	 * Print a message if verbose has been enabled.
-	 *  
-	 * @param message : message to print.
-	 */
-	private void printVerbose(String message){
-		if(verbose)
-			System.out.println(this.getClass().getSimpleName() + ": " + message);
-	}
-	
+    AIDA aida = null;
+    List<IPlotter> plotters;
+
+    Hep3Vector bField = null;
+    
+    boolean verbose = false;
+    
+    // Collection Names
+    String matchedEcalScoringPlaneHitsCollectionName = "MatchedTrackerHitsEcal";
+    String trackToScoringPlaneHitRelationsName = "TrackToEcalScoringPlaneHitRelations";
+    String trackToMCParticleRelationsName = "TrackToMCParticleRelations";
+    
+    /**
+     * Enable/disable verbose mode
+     * 
+     * @param verbose : true to enable, false otherwise
+     */
+    public void setVerbose(boolean verbose){
+        this.verbose = verbose; 
+    }
+    
+    public void detectorChanged(Detector detector){
+        
+        // Get the magnetic field from the geometry
+        bField = detector.getFieldMap().getField(new BasicHep3Vector(0,0,0));
+        
+        //-----------------------//
+        //--- Setup all plots ---//
+        //-----------------------//
+        
+        // Setup AIDA
+        aida = AIDA.defaultInstance();
+        aida.tree().cd("/");
+    
+        // Instantiate a list to hold the collection of plotters
+        plotters = new ArrayList<IPlotter>();
+        IPlotter plotter = null; 
+        
+        //--- Plots of scoring plane positions ---//
+        //----------------------------------------//
+        plotter = PlotUtils.setupPlotter("Positions of Scoring plane hits matched to tracks", 2, 2);
+        PlotUtils.setup1DRegion(plotter, "Scoring plane hit position - x", 0, "x (mm)",
+                aida.histogram1D("Scoring plane hit position - x", 100, -400, 400));
+        PlotUtils.setup1DRegion(plotter, "Scoring plane hit position - y", 1, "y (mm)",
+                aida.histogram1D("Scoring plane hit position - y", 100, -200, 200));
+        PlotUtils.setup1DRegion(plotter, "Scoring plane hit position - z", 2, "z (mm)",
+                aida.histogram1D("Scoring plane hit position - z", 100, 1000, 1500));
+        PlotUtils.setup2DRegion(plotter, "Scoring plane hit position - x-y", 3, "x (mm)", "y (mm)", 
+                aida.histogram2D("Scoring plane hit position - x-y", 100, -400, 400, 100, -200, 200));
+        plotters.add(plotter);  
+
+        //--- Plots of residuals at scoring plane ---//
+        //-------------------------------------------//
+        plotter = PlotUtils.setupPlotter("Residuals at scoring plane", 3, 3);
+        PlotUtils.setup1DRegion(plotter, "Top tracks - Bend plane residuals at scoring plane", 0, "x_{ep} - x_{sp} (mm)",
+                aida.histogram1D("Top electron tracks - Bend plane residual at scoring plane", 60, -30, 30));
+        PlotUtils.setup1DRegion(plotter, "Top tracks - Bend plane residuals at scoring plane", 0, "x_{ep} - x_{sp} (mm)",
+                aida.histogram1D("Top positron tracks - Bend plane residual at scoring plane", 60, -30, 30));
+        PlotUtils.setup1DRegion(plotter, "Bottom tracks - Bend plane residuals at scoring plane", 1, "x_{ep} - x_{sp} (mm)",
+                aida.histogram1D("Bottom electron tracks - Bend plane residuals at scoring plane", 60, -30, 30));
+        PlotUtils.setup1DRegion(plotter, "Bottom tracks - Bend plane residuals at scoring plane", 1, "x_{ep} - x_{sp} (mm)",
+                aida.histogram1D("Bottom positron tracks - Bend plane residuals at scoring plane", 60, -30, 30));
+        PlotUtils.setup1DRegion(plotter, "Bend plane residuals at scoring plane", 2, "x_{ep} - x_{sp} (mm)",
+                aida.histogram1D("Bend plane residuals at scoring plane", 60, -30, 30));
+        PlotUtils.setup1DRegion(plotter, "Bend plane residuals at scoring plane", 2, "x_{ep} - x_{sp} (mm)",
+                aida.histogram1D("Bend plane residuals at scoring plane", 60, -30, 30));
+        PlotUtils.setup1DRegion(plotter, "Top tracks - Non-bend plane residuals at scoring plane", 3,"y_{ep} - y_{sp} (mm)", 
+                aida.histogram1D("Top electron tracks - Non-bend plane residuals at scoring plane", 30, -15, 15));
+        PlotUtils.setup1DRegion(plotter, "Top tracks - Non-bend plane residuals at scoring plane", 3,"y_{ep} - y_{sp} (mm)", 
+                aida.histogram1D("Top positron tracks - Non-bend plane residuals at scoring plane", 30, -15, 15));
+        PlotUtils.setup1DRegion(plotter, "Bottom tracks - Non-bend plane residuals at scoring plane", 4,"y_{ep} - y_{sp} (mm)", 
+                aida.histogram1D("Bottom electron tracks - Non-bend plane residuals at scoring plane", 30, -15, 15));
+        PlotUtils.setup1DRegion(plotter, "Bottom tracks - Non-bend plane residuals at scoring plane", 4,"y_{ep} - y_{sp} (mm)", 
+                aida.histogram1D("Bottom positron tracks - Non-bend plane residuals at scoring plane", 30, -15, 15));
+        PlotUtils.setup1DRegion(plotter, "Non-bend plane residuals at scoring plane", 5,"y_{ep} - y_{sp} (mm)", 
+                aida.histogram1D("Non-bend plane residuals at scoring plane", 30, -15, 15));
+        PlotUtils.setup1DRegion(plotter, "Top tracks - z residuals at scoring plane", 6, "z_{ep} - z_{sp} (mm)",
+                aida.histogram1D("Top electron tracks - z residuals at scoring plane", 10, -5, 5));
+        PlotUtils.setup1DRegion(plotter, "Top tracks - z residuals at scoring plane", 6, "z_{ep} - z_{sp} (mm)",
+                aida.histogram1D("Top positron tracks - z residuals at scoring plane", 10, -5, 5));
+        PlotUtils.setup1DRegion(plotter, "Bottom tracks - z residuals at scoring plane", 7, "z_{ep} - z_{sp} (mm)",
+                aida.histogram1D("Bottom electron tracks - z residuals at scoring plane", 10, -5, 5));
+        PlotUtils.setup1DRegion(plotter, "Bottom tracks - z residuals at scoring plane", 7, "z_{ep} - z_{sp} (mm)",
+                aida.histogram1D("Bottom positron tracks - z residuals at scoring plane", 10, -5, 5));
+        PlotUtils.setup1DRegion(plotter, "z residuals at scoring plane", 7, "z_{ep} - z_{sp} (mm)",
+                aida.histogram1D("z residuals at scoring plane", 10, -5, 5));
+        plotters.add(plotter);  
+        
+        //--- Plots of residuals at target ---//
+        //------------------------------------//
+        plotter = PlotUtils.setupPlotter("Residuals at target", 3, 3);
+        PlotUtils.setup1DRegion(plotter, "Top tracks - Bend plane residuals at target", 0, "x_{ep} - x_{t} (mm)",
+                aida.histogram1D("Top electron tracks - Bend plane residual at target", 40, -4, 4));
+        PlotUtils.setup1DRegion(plotter, "Top tracks - Bend plane residuals at target", 0, "x_{ep} - x_{t} (mm)",
+                aida.histogram1D("Top positron tracks - Bend plane residual at target", 40, -4, 4));
+        PlotUtils.setup1DRegion(plotter, "Bottom tracks - Bend plane residuals at target", 1, "x_{ep} - x_{t} (mm)",
+                aida.histogram1D("Bottom electron tracks - Bend plane residuals at target", 40, -4, 4));
+        PlotUtils.setup1DRegion(plotter, "Bottom tracks - Bend plane residuals at target", 1, "x_{ep} - x_{t} (mm)",
+                aida.histogram1D("Bottom positron tracks - Bend plane residuals at target", 40, -4, 4));
+        PlotUtils.setup1DRegion(plotter, "Bend plane residuals at target", 2, "x_{ep} - x_{t} (mm)",
+                aida.histogram1D("Bend plane residuals at target", 40, -4, 4));
+        PlotUtils.setup1DRegion(plotter, "Top tracks - Non-bend plane residuals at target", 3, "y_{ep} - y_{t} (mm)",
+                aida.histogram1D("Top electron tracks - Non-bend plane residuals at target", 20, -2, 2));
+        PlotUtils.setup1DRegion(plotter, "Top tracks - Non-bend plane residuals at target", 3, "y_{ep} - y_{t} (mm)",
+                aida.histogram1D("Top positron tracks - Non-bend plane residuals at target", 20, -2, 2));
+        PlotUtils.setup1DRegion(plotter, "Bottom tracks - Non-bend plane residuals at target", 4, "y_{ep} - y_{t} (mm)",
+                aida.histogram1D("Bottom electron tracks - Non-bend plane residuals at target", 20, -2, 2));
+        PlotUtils.setup1DRegion(plotter, "Bottom tracks - Non-bend plane residuals at target", 4, "y_{ep} - y_{t} (mm)",
+                aida.histogram1D("Bottom positron tracks - Non-bend plane residuals at target", 20, -2, 2));
+        PlotUtils.setup1DRegion(plotter, "Non-bend plane residuals at target", 5, "y_{ep} - y_{t} (mm)",
+                aida.histogram1D("Non-bend plane residuals at target", 20, -2, 2));
+        PlotUtils.setup1DRegion(plotter, "Top tracks - z residuals at target", 6, "z_{ep} - z_{t} (mm)",
+                aida.histogram1D("Top electron tracks - z residuals at target", 50, -5, 5));
+        PlotUtils.setup1DRegion(plotter, "Top tracks - z residuals at target", 6, "z_{ep} - z_{t} (mm)",
+                aida.histogram1D("Top positron tracks - z residuals at target", 50, -5, 5));
+        PlotUtils.setup1DRegion(plotter, "Bottom tracks - z residuals at target", 7, "z_{ep} - z_{t} (mm)",
+                aida.histogram1D("Bottom electron tracks - z residuals at target", 50, -5, 5));
+        PlotUtils.setup1DRegion(plotter, "Bottom tracks - z residuals at target", 7, "z_{ep} - z_{t} (mm)",
+                aida.histogram1D("Bottom positron tracks - z residuals at target", 50, -5, 5));
+        PlotUtils.setup1DRegion(plotter, "z residuals at target", 8, "z_{ep} - z_{t} (mm)",
+                aida.histogram1D("z residuals at target", 50, -5, 5));
+        plotters.add(plotter);  
+        
+        //--- Plot of residuals at scoring plane vs momentum ---//
+        //------------------------------------------------------//
+        plotter = PlotUtils.setupPlotter("Residuals vs Momentum", 2, 2);
+        PlotUtils.setup2DRegion(plotter, "Bend plane residuals vs momentum at scoring plane", 0, 
+                "Momentum (GeV)", "x_{ep} - x_{sp} (mm)",
+                aida.histogram2D("Bend plane residuals vs momentum at scoring plane", 5, 0, 2.5, 60, -30, 30));
+        PlotUtils.setup2DRegion(plotter, "Non-bend plane residuals vs momentum at scoring plane", 1, 
+                "Momentum (GeV)", "y_{ep} - y_{sp} (mm)",
+                aida.histogram2D("Non-bend plane residuals vs momentum at scoring plane", 5, 0, 2.5, 60, -30, 30));
+        PlotUtils.setup2DRegion(plotter, "Bend plane residuals vs momentum at target", 2, 
+                "Momentum (GeV)", "x_{ep} - x_{t} (mm)",
+                aida.histogram2D("Bend plane residuals vs momentum at target", 5, 0, 2.5, 60, -3, 3));
+        PlotUtils.setup2DRegion(plotter, "Non-bend plane residuals vs momentum at target", 3, 
+                "Momentum (GeV)", "y_{ep} - y_{t} (mm)",
+                aida.histogram2D("Non-bend plane residuals vs momentum at target", 5, 0, 2.5, 50, -2.5, 2.5));
+        plotters.add(plotter);
+        
+        for(IPlotter iPlotter : plotters){
+            iPlotter.show(); 
+        }
+        
+    }
+    
+    public void process(EventHeader event){
+    
+        // If the event doesn't contain an LCRelation between a track and its 
+        // corresponding ECal scoring plane hit, skip the event.
+        if(!event.hasCollection(LCRelation.class, trackToScoringPlaneHitRelationsName)) return;
+        
+        List<LCRelation> trackToScoringPlaneHitRelations = event.get(LCRelation.class, trackToScoringPlaneHitRelationsName);
+        
+        for(LCRelation trackToScoringPlaneHitRelation : trackToScoringPlaneHitRelations){
+        
+            // Get the track
+            Track track = (Track) trackToScoringPlaneHitRelation.getFrom();
+            
+            // Get the track momentum
+            double[] momentum = BaseTrackState.computeMomentum(track.getTrackStates().get(0), bField.y());
+            double p = Math.sqrt(momentum[0]*momentum[0] + momentum[1]*momentum[1] + momentum[2]*momentum[2]);
+            this.printVerbose("Track momentum: " + p);
+            
+            // Get the corresponding scoring plane hit
+            SimTrackerHit scoringPlaneHit = (SimTrackerHit) trackToScoringPlaneHitRelation.getTo();
+            Hep3Vector scoringPlaneHitPosition = scoringPlaneHit.getPositionVec();
+            this.printVerbose("Scoring plane hit position: " + scoringPlaneHitPosition.toString());
+            
+            // Fill the scoring plane position histograms
+            aida.histogram1D("Scoring plane hit position - x").fill(scoringPlaneHitPosition.x());
+            aida.histogram1D("Scoring plane hit position - y").fill(scoringPlaneHitPosition.y());
+            aida.histogram1D("Scoring plane hit position - z").fill(scoringPlaneHitPosition.z());
+            aida.histogram2D("Scoring plane hit position - x-y").fill(scoringPlaneHitPosition.x(), scoringPlaneHitPosition.y());
+        
+            // Extrapolate the track to the scoring plane position
+            Hep3Vector trackPositionAtScoringPlane = TrackUtils.extrapolateTrack(track, scoringPlaneHitPosition.z());
+            this.printVerbose("Extrapolated track position: " + trackPositionAtScoringPlane.toString());
+                
+            // Find the residual between the extrapolated track position and the scoring plane hit position
+            double deltaX = trackPositionAtScoringPlane.x() - scoringPlaneHitPosition.x();
+            double deltaY = trackPositionAtScoringPlane.y() - scoringPlaneHitPosition.y();
+            // This should be 0 but it serves as a sanity check.
+            double deltaZ = trackPositionAtScoringPlane.z() - scoringPlaneHitPosition.z();
+        
+            if(track.getTrackerHits().get(0).getPosition()[2] > 0){
+                if(track.getTrackStates().get(0).getOmega() > 0){
+                    aida.histogram1D("Top positron tracks - Bend plane residual at scoring plane").fill(deltaX);
+                    aida.histogram1D("Top positron tracks - Non-bend plane residuals at scoring plane").fill(deltaY);
+                    aida.histogram1D("Top positron tracks - z residuals at scoring plane").fill(deltaZ);    
+                } else { 
+                    aida.histogram1D("Top electron tracks - Bend plane residual at scoring plane").fill(deltaX);
+                    aida.histogram1D("Top electron tracks - Non-bend plane residuals at scoring plane").fill(deltaY);
+                    aida.histogram1D("Top electron tracks - z residuals at scoring plane").fill(deltaZ);    
+                }
+            } else { 
+                if(track.getTrackStates().get(0).getOmega() > 0){
+                    aida.histogram1D("Bottom positron tracks - Bend plane residuals at scoring plane").fill(deltaX);
+                    aida.histogram1D("Bottom positron tracks - Non-bend plane residuals at scoring plane").fill(deltaY);
+                    aida.histogram1D("Bottom positron tracks - z residuals at scoring plane").fill(deltaZ);
+                } else { 
+                    aida.histogram1D("Bottom electron tracks - Bend plane residuals at scoring plane").fill(deltaX);
+                    aida.histogram1D("Bottom electron tracks - Non-bend plane residuals at scoring plane").fill(deltaY);
+                    aida.histogram1D("Bottom electron tracks - z residuals at scoring plane").fill(deltaZ);
+                }
+            }
+
+            aida.histogram1D("Bend plane residuals at scoring plane").fill(deltaX);
+            aida.histogram1D("Non-bend plane residuals at scoring plane").fill(deltaY);
+            aida.histogram1D("z residuals at target").fill(deltaZ);
+            aida.histogram2D("Bend plane residuals vs momentum at scoring plane").fill(p, deltaX);
+            aida.histogram2D("Non-bend plane residuals vs momentum at scoring plane").fill(p, deltaY);
+        }
+        
+        if(!event.hasCollection(LCRelation.class, trackToMCParticleRelationsName)) return;
+        
+        List<LCRelation> trackToMCParticleRelations = event.get(LCRelation.class, trackToMCParticleRelationsName);
+        
+        for(LCRelation trackToMCParticleRelation : trackToMCParticleRelations){
+            
+            // Get the track
+            Track track = (Track) trackToMCParticleRelation.getFrom();
+            
+            // Get the track momentum
+            double[] momentum = BaseTrackState.computeMomentum(track.getTrackStates().get(0), bField.y());
+            double p = Math.sqrt(momentum[0]*momentum[0] + momentum[1]*momentum[1] + momentum[2]*momentum[2]);
+            this.printVerbose("Track momentum: " + p);
+
+            // Get the corresponding MC particle
+            MCParticle particle = (MCParticle) trackToMCParticleRelation.getTo();
+            
+            // Extrapolate the track to the origin
+            Hep3Vector trackPositionAtOrigin = TrackUtils.extrapolateTrack(track, particle.getOriginZ());
+            
+            // Find the residual between the extrapolated track and the position of the scoring plane at the origin
+            double deltaX = trackPositionAtOrigin.x() - particle.getOriginX();
+            double deltaY = trackPositionAtOrigin.y() - particle.getOriginY();
+            double deltaZ = trackPositionAtOrigin.z() - particle.getOriginZ();
+            
+            if(track.getTrackerHits().get(0).getPosition()[2] > 0){
+                if(track.getTrackStates().get(0).getOmega() > 0){
+                    aida.histogram1D("Top positron tracks - Bend plane residual at target").fill(deltaX);
+                    aida.histogram1D("Top positron tracks - Non-bend plane residuals at target").fill(deltaY);
+                    aida.histogram1D("Top positron tracks - z residuals at target").fill(deltaZ);
+                } else { 
+                    aida.histogram1D("Top electron tracks - Bend plane residual at target").fill(deltaX);
+                    aida.histogram1D("Top electron tracks - Non-bend plane residuals at target").fill(deltaY);
+                    aida.histogram1D("Top electron tracks - z residuals at target").fill(deltaZ);
+                }
+            } else { 
+                
+                if(track.getTrackStates().get(0).getOmega() > 0){
+                    aida.histogram1D("Bottom positron tracks - Bend plane residuals at target").fill(deltaX);
+                    aida.histogram1D("Bottom positron tracks - Non-bend plane residuals at target").fill(deltaY);
+                    aida.histogram1D("Bottom positron tracks - z residuals at target").fill(deltaZ);
+                } else { 
+                    aida.histogram1D("Bottom electron tracks - Bend plane residuals at target").fill(deltaX);
+                    aida.histogram1D("Bottom electron tracks - Non-bend plane residuals at target").fill(deltaY);
+                    aida.histogram1D("Bottom electron tracks - z residuals at target").fill(deltaZ);
+                }
+            }
+            
+            aida.histogram1D("Bend plane residuals at target").fill(deltaX);
+            aida.histogram1D("Non-bend plane residuals at target").fill(deltaY);
+            aida.histogram1D("z residuals at target").fill(deltaZ);
+            aida.histogram2D("Bend plane residuals vs momentum at target").fill(p, deltaX);
+            aida.histogram2D("Non-bend plane residuals vs momentum at target").fill(p, deltaY);
+        }
+    }
+    
+    @Override
+    protected void endOfData(){
+        
+        IHistogram2D histogram = aida.histogram2D("Bend plane residuals vs momentum at scoring plane");
+        int binsX = histogram.xAxis().bins();
+        for(int binX = 0; binX < binsX; binX++){
+            PlotUtils.getYProjection(binX, histogram);
+        }
+        
+        histogram = aida.histogram2D("Non-bend plane residuals vs momentum at scoring plane");
+        binsX = histogram.xAxis().bins();
+        for(int binX = 0; binX < binsX; binX++){
+            PlotUtils.getYProjection(binX, histogram);
+        }
+    
+        histogram = aida.histogram2D("Bend plane residuals vs momentum at target");
+        binsX = histogram.xAxis().bins();
+        for(int binX = 0; binX < binsX; binX++){
+            PlotUtils.getYProjection(binX, histogram);
+        }
+        
+        histogram = aida.histogram2D("Non-bend plane residuals vs momentum at target");
+        binsX = histogram.xAxis().bins();
+        for(int binX = 0; binX < binsX; binX++){
+            PlotUtils.getYProjection(binX, histogram);
+        }
+    }
+    
+    /**
+     * Print a message if verbose has been enabled.
+     *  
+     * @param message : message to print.
+     */
+    private void printVerbose(String message){
+        if(verbose)
+            System.out.println(this.getClass().getSimpleName() + ": " + message);
+    }
+    
 }

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/omoreno/LheToStdhep.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/omoreno/LheToStdhep.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/omoreno/LheToStdhep.java	Wed Apr 27 11:11:32 2016
@@ -15,7 +15,7 @@
 import org.apache.commons.cli.CommandLineParser;
 import org.apache.commons.cli.Options;
 import org.apache.commons.cli.ParseException;
-import org.apache.commons.cli.DefaultParser;
+import org.apache.commons.cli.PosixParser;
 import org.jdom.Document;
 import org.jdom.Element;
 import org.jdom.JDOMException;
@@ -32,248 +32,248 @@
  * TODO: Make this converter more generic.
  */
 public class LheToStdhep {
-	
-	private static final int N_PARTICLE_INDEX = 0;
-	private static final int PDG_ID_INDEX = 1;
-	private static final int STATUS_INDEX = 2; 
-	private static final int FIRST_MOTHER_INDEX = 3; 
-	private static final int SECOND_MOTHER_INDEX = 4; 
-	private static final int FIRST_DAUGHTER_INDEX = 5; 
-	private static final int SECOND_DAUGHTER_INDEX = 6; 
-	
-	private static double sigmaX = 0.2;
-	private static double sigmaY = 0.02;
-	private static double sigmaZ = 0.0;
-	
-	private static double offsetX = 0;
-	private static double offsetY = 0;
-	private static double offsetZ = 0.03;
-	
-	static int eventNumber = 0; 
-	
-	
-	public static void main(String[] args) throws IOException{
-
-		String lheFileName = null; 
-		String stdhepFileName = "output.stdhep";
-		
-		// Instantiate te command line parser
-		CommandLineParser parser = new DefaultParser(); 
-
-		// Create the Options
-		// TODO: Add ability to parse list of files.
-		// Allow a user to pass tag.gz files
-		Options options = new Options(); 
-		options.addOption("i", "input", true, "Input LHE file name");
-		options.addOption("o", "output", true, "Output Stdhep file name");
-		
-		try { 
-			// Parse the command line arguments
-			CommandLine line = parser.parse(options, args);
-			
-			// If the file is not specified, notify the user and exit the program
-			if(!line.hasOption("i")){
-				System.out.println("Please specify an LHE file to process");
-				System.exit(0);
-			}
-			lheFileName = line.getOptionValue("i");
-		
-			// Check if the user has specified the output file name and that the
-			// extension is stdhep.  If not, add the extension
-			if(line.hasOption("o")){
-				stdhepFileName = line.getOptionValue("o");
-			}
-		} catch(ParseException e){
-			System.out.println("Unexpected exception: " + e.getMessage());
-		}
-		
-		convertToStdhep(lheFileName, stdhepFileName);
-		
-	}
-
-	/**
-	 * 
-	 */
-	static private void convertToStdhep(String lheFileName, String stdhepFileName) throws IOException{
-		List<Element> events = readLhe(lheFileName);
-
-		StdhepWriter writer = new StdhepWriter(
-						   	stdhepFileName,
-						   	"Import Stdhep Events",
-						   	"Imported from LHE generated from MadGraph",
-						   	events.size()
-							);
-		writer.setCompatibilityMode(false);
-		
-		for(Element event : events){
-			writeEvent(event, writer);
-		}
-		writer.close();
-	}
-
-	/**
-	 * 
-	 */
-	private static List<Element> readLhe(String lheFileName){
-		
-		// Instantiate the SAX parser used to build the JDOM document
-		SAXBuilder builder = new SAXBuilder(); 
-		
-		// Open the lhe file
-		File lheFile = new File(lheFileName);
-			
-		// Parse the lhe file and build the JDOM document
-		Document document = null;
-		List<Element> eventNodes = null; 
-		try {
-			
-			document = (Document) builder.build(lheFile);
-			
-			// Get the root node
-			Element rootNode = document.getRootElement(); 
-			
-			// Get a list of all nodes of type event
-			eventNodes = rootNode.getChildren("event");
-		
-		} catch (JDOMException e) {
-			e.printStackTrace();
-			
-		} catch (IOException e) {
-			e.printStackTrace();
-		}
-		
-		return eventNodes; 
-	}
-
-	/**
-	 * 
-	 */
-	private static void writeEvent(Element event, StdhepWriter writer) throws IOException{
-		
-		int numberOfParticles = 0; 
-		int particleIndex = 0;
-		int pdgID[] = null; 
-		int particleStatus[] = null;
-		int motherParticles[] = null; 
-		int daughterParticles[] = null; 
-		double particleMomentum[] = null;
-		double particleVertex[] = null; 
-		
-		Random generator = new Random(); 
-		
-		eventNumber++; 
-		
-		System.out.println("#================================================#\n#");
-		System.out.println("# Event: " + eventNumber);
-		
-		
-		// Get the text within the event element node.  An element node contains
-		// information describing the event and it's particles.  The PDG ID of
-		// a particle along with it's kinematics is listed on it's own line.
-		// In order to parse the information for each particle, the text is 
-		// split using the newline character as a delimiter.  
-		String[] eventData = event.getTextTrim().split("\n");	
-	 
-		for(int datumIndex = 0; datumIndex < eventData.length; datumIndex++){
-			
-			// Split a line by whitespace
-			String[] eventTokens = eventData[datumIndex].split("\\s+");
-		
-			if(datumIndex == 0){
-				
-				numberOfParticles = Integer.valueOf(eventTokens[N_PARTICLE_INDEX]);
-				System.out.println("# Number of particles: " + numberOfParticles + "\n#");
-				System.out.println("#================================================#");
-		
-				// Reset all arrays used to build the Stdhep event
-				particleIndex = 0; 
-				particleStatus = new int[numberOfParticles];
-				pdgID = new int[numberOfParticles];
-				motherParticles = new int[numberOfParticles*2];
-				daughterParticles = new int[numberOfParticles*2];
-				particleMomentum = new double[numberOfParticles*5];
-				particleVertex = new double[numberOfParticles*4];
-			
-				continue;
-			}
-	
-			// Get the PDG ID of the particle
-			pdgID[particleIndex] = Integer.valueOf(eventTokens[PDG_ID_INDEX]);
-			
-			
-			System.out.println(">>> PDG ID: " + pdgID[particleIndex]);
-			
-			// Get the status of the particle (initial state = -1, final state = 1, resonance = 2)
-			particleStatus[particleIndex] = Integer.valueOf(eventTokens[STATUS_INDEX]);
-			if(particleStatus[particleIndex] == -1) particleStatus[particleIndex] = 3; 
-			System.out.println(">>>> Particle Status: " + particleStatus[particleIndex]);
-			
-			 // Get the mothers of a particle.  If the particle is a trident electron, then assign it
-			 // a mother value of 10 so it's distinguishable from the beam electron.
-			if(pdgID[particleIndex] == 611){
-				motherParticles[particleIndex*2] = 10;
-				// If the PDG ID is equal to 611/-611 (trident electron) change it back to 11/-11. 
-				// Otherwise, SLIC won't do anything with them.
-				pdgID[particleIndex] = 11;
-			} else if(pdgID[particleIndex] == -611){
-				motherParticles[particleIndex*2] = 10;
-				pdgID[particleIndex] = -11; 
-			} else {
-				motherParticles[particleIndex*2] = Integer.valueOf(eventTokens[FIRST_MOTHER_INDEX]);
-			}
-	        motherParticles[particleIndex*2 + 1] = Integer.valueOf(eventTokens[SECOND_MOTHER_INDEX]);
-	        System.out.println(">>>> Mothers: 1) " + motherParticles[particleIndex*2] + " 2) " + motherParticles[particleIndex*2 + 1]);
-	        
-	        // Get the daughter particles
-	        daughterParticles[particleIndex*2] = Integer.valueOf(eventTokens[FIRST_DAUGHTER_INDEX]);
-	        daughterParticles[particleIndex*2 + 1] = Integer.valueOf(eventTokens[SECOND_DAUGHTER_INDEX]);
-	        System.out.println(">>>> Daughter: 1) " + daughterParticles[particleIndex*2] + " 2) " + daughterParticles[particleIndex*2 + 1]);
-	        
-	        // Get the particle momentum, its mass and energy
-	        particleMomentum[particleIndex*5] = Double.valueOf(eventTokens[7]);		// px
-	        particleMomentum[particleIndex*5 + 1] = Double.valueOf(eventTokens[8]);	// py   
-	        particleMomentum[particleIndex*5 + 2] = Double.valueOf(eventTokens[9]); // pz
-	        particleMomentum[particleIndex*5 + 3] = Double.valueOf(eventTokens[10]); // Particle Energy
-	        particleMomentum[particleIndex*5 + 4] = Double.valueOf(eventTokens[11]); // Particle Mass
-	        
-	        // Rotate the particle by 30 mrad around the beam axis
-	        Hep3Vector rotatedMomentum = 
-	        		rotateToDetector(particleMomentum[particleIndex*5], 
-	        				particleMomentum[particleIndex*5+1], 
-	        				particleMomentum[particleIndex*5+1]);
-	        
-	        particleMomentum[particleIndex*5] = rotatedMomentum.x();
-	        particleMomentum[particleIndex*5 + 1] = rotatedMomentum.y();
-	        particleMomentum[particleIndex*5 + 2] = rotatedMomentum.z();
-
-	        // Set the origin of the particle
-	        Hep3Vector rotatedVertex = rotateToDetector(sigmaX*generator.nextGaussian() + offsetX, 
-	        		sigmaY*generator.nextGaussian() + offsetY, 
-	        		sigmaZ*generator.nextGaussian() + offsetZ);
-	        particleVertex[particleIndex*4] = rotatedVertex.x();
-	        particleVertex[particleIndex*4+1] = rotatedVertex.y();
-	        particleVertex[particleIndex*4+2] = rotatedVertex.z();
-	        particleVertex[particleIndex*4+3] = 0; 
-	        
-	        // Increment the particle number
-	        particleIndex++;
-	        
-			System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
-		}
-		
-		// Create the Stdhep event and write it 
-	    StdhepEvent stdhepEvent = new StdhepEvent(eventNumber, numberOfParticles, particleStatus, 
-	    		pdgID, motherParticles, daughterParticles, particleMomentum, particleVertex);
-	    writer.writeRecord(stdhepEvent);
-	}
-
-	/**
-	 * 
-	 */
-	private static Hep3Vector rotateToDetector(double x, double y, double z){
-		IRotation3D rotation = new RotationGeant(0.0, 0.03, 0.0);
-		Hep3Vector vector = new BasicHep3Vector(x, y, z);
-		return rotation.rotated(vector);
-	}
+    
+    private static final int N_PARTICLE_INDEX = 0;
+    private static final int PDG_ID_INDEX = 1;
+    private static final int STATUS_INDEX = 2; 
+    private static final int FIRST_MOTHER_INDEX = 3; 
+    private static final int SECOND_MOTHER_INDEX = 4; 
+    private static final int FIRST_DAUGHTER_INDEX = 5; 
+    private static final int SECOND_DAUGHTER_INDEX = 6; 
+    
+    private static double sigmaX = 0.2;
+    private static double sigmaY = 0.02;
+    private static double sigmaZ = 0.0;
+    
+    private static double offsetX = 0;
+    private static double offsetY = 0;
+    private static double offsetZ = 0.03;
+    
+    static int eventNumber = 0; 
+    
+    
+    public static void main(String[] args) throws IOException{
+
+        String lheFileName = null; 
+        String stdhepFileName = "output.stdhep";
+        
+        // Instantiate te command line parser
+        CommandLineParser parser = new PosixParser(); 
+
+        // Create the Options
+        // TODO: Add ability to parse list of files.
+        // Allow a user to pass tag.gz files
+        Options options = new Options(); 
+        options.addOption("i", "input", true, "Input LHE file name");
+        options.addOption("o", "output", true, "Output Stdhep file name");
+        
+        try { 
+            // Parse the command line arguments
+            CommandLine line = parser.parse(options, args);
+            
+            // If the file is not specified, notify the user and exit the program
+            if(!line.hasOption("i")){
+                System.out.println("Please specify an LHE file to process");
+                System.exit(0);
+            }
+            lheFileName = line.getOptionValue("i");
+        
+            // Check if the user has specified the output file name and that the
+            // extension is stdhep.  If not, add the extension
+            if(line.hasOption("o")){
+                stdhepFileName = line.getOptionValue("o");
+            }
+        } catch(ParseException e){
+            System.out.println("Unexpected exception: " + e.getMessage());
+        }
+        
+        convertToStdhep(lheFileName, stdhepFileName);
+        
+    }
+
+    /**
+     * 
+     */
+    static private void convertToStdhep(String lheFileName, String stdhepFileName) throws IOException{
+        List<Element> events = readLhe(lheFileName);
+
+        StdhepWriter writer = new StdhepWriter(
+                            stdhepFileName,
+                            "Import Stdhep Events",
+                            "Imported from LHE generated from MadGraph",
+                            events.size()
+                            );
+        writer.setCompatibilityMode(false);
+        
+        for(Element event : events){
+            writeEvent(event, writer);
+        }
+        writer.close();
+    }
+
+    /**
+     * 
+     */
+    private static List<Element> readLhe(String lheFileName){
+        
+        // Instantiate the SAX parser used to build the JDOM document
+        SAXBuilder builder = new SAXBuilder(); 
+        
+        // Open the lhe file
+        File lheFile = new File(lheFileName);
+            
+        // Parse the lhe file and build the JDOM document
+        Document document = null;
+        List<Element> eventNodes = null; 
+        try {
+            
+            document = (Document) builder.build(lheFile);
+            
+            // Get the root node
+            Element rootNode = document.getRootElement(); 
+            
+            // Get a list of all nodes of type event
+            eventNodes = rootNode.getChildren("event");
+        
+        } catch (JDOMException e) {
+            e.printStackTrace();
+            
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        
+        return eventNodes; 
+    }
+
+    /**
+     * 
+     */
+    private static void writeEvent(Element event, StdhepWriter writer) throws IOException{
+        
+        int numberOfParticles = 0; 
+        int particleIndex = 0;
+        int pdgID[] = null; 
+        int particleStatus[] = null;
+        int motherParticles[] = null; 
+        int daughterParticles[] = null; 
+        double particleMomentum[] = null;
+        double particleVertex[] = null; 
+        
+        Random generator = new Random(); 
+        
+        eventNumber++; 
+        
+        System.out.println("#================================================#\n#");
+        System.out.println("# Event: " + eventNumber);
+        
+        
+        // Get the text within the event element node.  An element node contains
+        // information describing the event and it's particles.  The PDG ID of
+        // a particle along with it's kinematics is listed on it's own line.
+        // In order to parse the information for each particle, the text is 
+        // split using the newline character as a delimiter.  
+        String[] eventData = event.getTextTrim().split("\n");   
+     
+        for(int datumIndex = 0; datumIndex < eventData.length; datumIndex++){
+            
+            // Split a line by whitespace
+            String[] eventTokens = eventData[datumIndex].split("\\s+");
+        
+            if(datumIndex == 0){
+                
+                numberOfParticles = Integer.valueOf(eventTokens[N_PARTICLE_INDEX]);
+                System.out.println("# Number of particles: " + numberOfParticles + "\n#");
+                System.out.println("#================================================#");
+        
+                // Reset all arrays used to build the Stdhep event
+                particleIndex = 0; 
+                particleStatus = new int[numberOfParticles];
+                pdgID = new int[numberOfParticles];
+                motherParticles = new int[numberOfParticles*2];
+                daughterParticles = new int[numberOfParticles*2];
+                particleMomentum = new double[numberOfParticles*5];
+                particleVertex = new double[numberOfParticles*4];
+            
+                continue;
+            }
+    
+            // Get the PDG ID of the particle
+            pdgID[particleIndex] = Integer.valueOf(eventTokens[PDG_ID_INDEX]);
+            
+            
+            System.out.println(">>> PDG ID: " + pdgID[particleIndex]);
+            
+            // Get the status of the particle (initial state = -1, final state = 1, resonance = 2)
+            particleStatus[particleIndex] = Integer.valueOf(eventTokens[STATUS_INDEX]);
+            if(particleStatus[particleIndex] == -1) particleStatus[particleIndex] = 3; 
+            System.out.println(">>>> Particle Status: " + particleStatus[particleIndex]);
+            
+             // Get the mothers of a particle.  If the particle is a trident electron, then assign it
+             // a mother value of 10 so it's distinguishable from the beam electron.
+            if(pdgID[particleIndex] == 611){
+                motherParticles[particleIndex*2] = 10;
+                // If the PDG ID is equal to 611/-611 (trident electron) change it back to 11/-11. 
+                // Otherwise, SLIC won't do anything with them.
+                pdgID[particleIndex] = 11;
+            } else if(pdgID[particleIndex] == -611){
+                motherParticles[particleIndex*2] = 10;
+                pdgID[particleIndex] = -11; 
+            } else {
+                motherParticles[particleIndex*2] = Integer.valueOf(eventTokens[FIRST_MOTHER_INDEX]);
+            }
+            motherParticles[particleIndex*2 + 1] = Integer.valueOf(eventTokens[SECOND_MOTHER_INDEX]);
+            System.out.println(">>>> Mothers: 1) " + motherParticles[particleIndex*2] + " 2) " + motherParticles[particleIndex*2 + 1]);
+            
+            // Get the daughter particles
+            daughterParticles[particleIndex*2] = Integer.valueOf(eventTokens[FIRST_DAUGHTER_INDEX]);
+            daughterParticles[particleIndex*2 + 1] = Integer.valueOf(eventTokens[SECOND_DAUGHTER_INDEX]);
+            System.out.println(">>>> Daughter: 1) " + daughterParticles[particleIndex*2] + " 2) " + daughterParticles[particleIndex*2 + 1]);
+            
+            // Get the particle momentum, its mass and energy
+            particleMomentum[particleIndex*5] = Double.valueOf(eventTokens[7]);     // px
+            particleMomentum[particleIndex*5 + 1] = Double.valueOf(eventTokens[8]); // py   
+            particleMomentum[particleIndex*5 + 2] = Double.valueOf(eventTokens[9]); // pz
+            particleMomentum[particleIndex*5 + 3] = Double.valueOf(eventTokens[10]); // Particle Energy
+            particleMomentum[particleIndex*5 + 4] = Double.valueOf(eventTokens[11]); // Particle Mass
+            
+            // Rotate the particle by 30 mrad around the beam axis
+            Hep3Vector rotatedMomentum = 
+                    rotateToDetector(particleMomentum[particleIndex*5], 
+                            particleMomentum[particleIndex*5+1], 
+                            particleMomentum[particleIndex*5+1]);
+            
+            particleMomentum[particleIndex*5] = rotatedMomentum.x();
+            particleMomentum[particleIndex*5 + 1] = rotatedMomentum.y();
+            particleMomentum[particleIndex*5 + 2] = rotatedMomentum.z();
+
+            // Set the origin of the particle
+            Hep3Vector rotatedVertex = rotateToDetector(sigmaX*generator.nextGaussian() + offsetX, 
+                    sigmaY*generator.nextGaussian() + offsetY, 
+                    sigmaZ*generator.nextGaussian() + offsetZ);
+            particleVertex[particleIndex*4] = rotatedVertex.x();
+            particleVertex[particleIndex*4+1] = rotatedVertex.y();
+            particleVertex[particleIndex*4+2] = rotatedVertex.z();
+            particleVertex[particleIndex*4+3] = 0; 
+            
+            // Increment the particle number
+            particleIndex++;
+            
+            System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
+        }
+        
+        // Create the Stdhep event and write it 
+        StdhepEvent stdhepEvent = new StdhepEvent(eventNumber, numberOfParticles, particleStatus, 
+                pdgID, motherParticles, daughterParticles, particleMomentum, particleVertex);
+        writer.writeRecord(stdhepEvent);
+    }
+
+    /**
+     * 
+     */
+    private static Hep3Vector rotateToDetector(double x, double y, double z){
+        IRotation3D rotation = new RotationGeant(0.0, 0.03, 0.0);
+        Hep3Vector vector = new BasicHep3Vector(x, y, z);
+        return rotation.rotated(vector);
+    }
 
 }

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/omoreno/PlotUtils.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/omoreno/PlotUtils.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/omoreno/PlotUtils.java	Wed Apr 27 11:11:32 2016
@@ -20,71 +20,71 @@
  */
 public class PlotUtils {
 
-	// Default ctor
-	public PlotUtils(){}	
+    // Default ctor
+    public PlotUtils(){}    
 
-	public static IPlotter setupPlotter(String title, int regionX, int regionY){
-	    IPlotter plotter = AIDA.defaultInstance().analysisFactory().createPlotterFactory().create(title);
-	    plotter.setTitle(title);
-	    
-	    if(regionX < 0 || regionY < 0) throw new RuntimeException("Region dimensions need to be greater than 0!");
-	    else if(regionX != 0 || regionY != 0) plotter.createRegions(regionX, regionY);
-	    
-	    plotter.style().statisticsBoxStyle().setVisible(false);
-	    plotter.style().dataStyle().errorBarStyle().setVisible(false);
-	    plotter.setParameter("plotterWidth", "800");
-	    plotter.setParameter("plotterHeight", "800");
-	    
-	    return plotter;
-	    
-	}
+    public static IPlotter setupPlotter(String title, int regionX, int regionY){
+        IPlotter plotter = AIDA.defaultInstance().analysisFactory().createPlotterFactory().create(title);
+        plotter.setTitle(title);
+        
+        if(regionX < 0 || regionY < 0) throw new RuntimeException("Region dimensions need to be greater than 0!");
+        else if(regionX != 0 || regionY != 0) plotter.createRegions(regionX, regionY);
+        
+        plotter.style().statisticsBoxStyle().setVisible(false);
+        plotter.style().dataStyle().errorBarStyle().setVisible(false);
+        plotter.setParameter("plotterWidth", "800");
+        plotter.setParameter("plotterHeight", "800");
+        
+        return plotter;
+        
+    }
     
     public static void setup2DRegion(IPlotter plotter, String title, int region, String xTitle, String yTitle, IHistogram2D histo){
-    	
-    	// Check if the specified region is valid
-    	if(region > plotter.numberOfRegions()) 
-    		throw new RuntimeException("Region is invalid! " + title + " contains " + plotter.numberOfRegions() + " regions");
-    	
-		plotter.region(region).style().xAxisStyle().setLabel(xTitle);
-		plotter.region(region).style().xAxisStyle().labelStyle().setFontSize(14);
-		plotter.region(region).style().yAxisStyle().setLabel(yTitle);
-		plotter.region(region).style().yAxisStyle().labelStyle().setFontSize(14);
-		plotter.region(region).style().xAxisStyle().setVisible(true);
-		plotter.region(region).style().yAxisStyle().setVisible(true);
-		plotter.region(region).style().setParameter("hist2DStyle", "colorMap");
-    	plotter.region(region).style().dataStyle().fillStyle().setParameter("colorMapScheme", "rainbow");
-    	
-    	if(histo != null) plotter.region(region).plot(histo);
+        
+        // Check if the specified region is valid
+        if(region > plotter.numberOfRegions()) 
+            throw new RuntimeException("Region is invalid! " + title + " contains " + plotter.numberOfRegions() + " regions");
+        
+        plotter.region(region).style().xAxisStyle().setLabel(xTitle);
+        plotter.region(region).style().xAxisStyle().labelStyle().setFontSize(14);
+        plotter.region(region).style().yAxisStyle().setLabel(yTitle);
+        plotter.region(region).style().yAxisStyle().labelStyle().setFontSize(14);
+        plotter.region(region).style().xAxisStyle().setVisible(true);
+        plotter.region(region).style().yAxisStyle().setVisible(true);
+        plotter.region(region).style().setParameter("hist2DStyle", "colorMap");
+        plotter.region(region).style().dataStyle().fillStyle().setParameter("colorMapScheme", "rainbow");
+        
+        if(histo != null) plotter.region(region).plot(histo);
     }
    
     public static void setup2DRegion(IPlotter plotter, String title, int region, String xTitle, String yTitle, ICloud2D cloud, IPlotterStyle style){
-    	
-    	// Check if the specified region is valid
-    	if(region > plotter.numberOfRegions()) 
-    		throw new RuntimeException("Region is invalid! " + title + " contains " + plotter.numberOfRegions() + " regions");
-    	
-		plotter.region(region).style().xAxisStyle().setLabel(xTitle);
-		plotter.region(region).style().xAxisStyle().labelStyle().setFontSize(14);
-		String[] pars = plotter.region(region).style().xAxisStyle().availableParameters();
-		plotter.region(region).style().yAxisStyle().setLabel(yTitle);
-		plotter.region(region).style().yAxisStyle().labelStyle().setFontSize(14);
-		plotter.region(region).style().xAxisStyle().setVisible(true);
-		plotter.region(region).style().yAxisStyle().setVisible(true);
-		plotter.region(region).style().setParameter("showAsScatterPlot", "true");
-    	
-    	if(cloud != null) plotter.region(region).plot(cloud, style);
+        
+        // Check if the specified region is valid
+        if(region > plotter.numberOfRegions()) 
+            throw new RuntimeException("Region is invalid! " + title + " contains " + plotter.numberOfRegions() + " regions");
+        
+        plotter.region(region).style().xAxisStyle().setLabel(xTitle);
+        plotter.region(region).style().xAxisStyle().labelStyle().setFontSize(14);
+        String[] pars = plotter.region(region).style().xAxisStyle().availableParameters();
+        plotter.region(region).style().yAxisStyle().setLabel(yTitle);
+        plotter.region(region).style().yAxisStyle().labelStyle().setFontSize(14);
+        plotter.region(region).style().xAxisStyle().setVisible(true);
+        plotter.region(region).style().yAxisStyle().setVisible(true);
+        plotter.region(region).style().setParameter("showAsScatterPlot", "true");
+        
+        if(cloud != null) plotter.region(region).plot(cloud, style);
     }
     
     
     public static void setup1DRegion(IPlotter plotter, String title, int region, String xTitle, IHistogram1D histo){
-    	
-		plotter.region(region).style().xAxisStyle().setLabel(xTitle);
-		plotter.region(region).style().xAxisStyle().labelStyle().setFontSize(14);
-		plotter.region(region).style().xAxisStyle().setVisible(true);
-		plotter.region(region).style().dataStyle().fillStyle().setVisible(false);
-		plotter.region(region).style().dataStyle().lineStyle().setThickness(3);
-		
-		if(histo != null) plotter.region(region).plot(histo);
+        
+        plotter.region(region).style().xAxisStyle().setLabel(xTitle);
+        plotter.region(region).style().xAxisStyle().labelStyle().setFontSize(14);
+        plotter.region(region).style().xAxisStyle().setVisible(true);
+        plotter.region(region).style().dataStyle().fillStyle().setVisible(false);
+        plotter.region(region).style().dataStyle().lineStyle().setThickness(3);
+        
+        if(histo != null) plotter.region(region).plot(histo);
     }
     
     /**
@@ -98,7 +98,7 @@
         int ix = (layer - 1) / 2;
         int iy = 0;
         if (!((HpsSiSensor) sensor).isTopLayer()){ 
-        	iy += 2;
+            iy += 2;
         }
         if (layer % 2 == 0) {
             iy += 1;
@@ -108,35 +108,35 @@
     }
    
     public static IHistogram1D getYProjection(int binX, IHistogram2D histogram){
-    	int binsY = histogram.yAxis().bins();
-    	double yMin = histogram.yAxis().lowerEdge();
-    	double yMax = histogram.yAxis().upperEdge(); 
-    	
-    	IHistogram1D projection 
-    		= AIDA.defaultInstance().histogram1D(histogram.title() + "_" + binX, binsY, yMin, yMax);
-    	projection.reset();
-    	
-    	double dataY = 0; 
-    	for(int binY = 0; binY < binsY; binY++){
-    		dataY = histogram.binEntries(binX, binY);
-    		projection.fill(yMin, dataY);
-    		yMin++;
-    	}
-    	
-    	return projection; 
+        int binsY = histogram.yAxis().bins();
+        double yMin = histogram.yAxis().lowerEdge();
+        double yMax = histogram.yAxis().upperEdge(); 
+        
+        IHistogram1D projection 
+            = AIDA.defaultInstance().histogram1D(histogram.title() + "_" + binX, binsY, yMin, yMax);
+        projection.reset();
+        
+        double dataY = 0; 
+        for(int binY = 0; binY < binsY; binY++){
+            dataY = histogram.binEntries(binX, binY);
+            projection.fill(yMin, dataY);
+            yMin++;
+        }
+        
+        return projection; 
     }
     
     public static double[] fitToGuassian(IHistogram1D histogram){
-    	
-    	double[] fitParameters = {0, 0};
-    	IFitter fitter = AIDA.defaultInstance().analysisFactory().createFitFactory().createFitter();
-    	IFitResult fitResult = fitter.fit(histogram, "g");
-    	int meanIndex  = fitResult.fittedFunction().indexOfParameter("mean");
-    	fitParameters[0] = fitResult.fittedParameters()[meanIndex];
+        
+        double[] fitParameters = {0, 0};
+        IFitter fitter = AIDA.defaultInstance().analysisFactory().createFitFactory().createFitter();
+        IFitResult fitResult = fitter.fit(histogram, "g");
+        int meanIndex  = fitResult.fittedFunction().indexOfParameter("mean");
+        fitParameters[0] = fitResult.fittedParameters()[meanIndex];
 
-    	int sigmaIndex  = fitResult.fittedFunction().indexOfParameter("sigma");
-    	fitParameters[1] = fitResult.fittedParameters()[sigmaIndex];
-    	
-		return fitParameters;
+        int sigmaIndex  = fitResult.fittedFunction().indexOfParameter("sigma");
+        fitParameters[1] = fitResult.fittedParameters()[sigmaIndex];
+        
+        return fitParameters;
     }
 }

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/omoreno/ReconstructedParticleChecker.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/omoreno/ReconstructedParticleChecker.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/omoreno/ReconstructedParticleChecker.java	Wed Apr 27 11:11:32 2016
@@ -29,92 +29,92 @@
  *
  */
 public class ReconstructedParticleChecker extends Driver {
-	
-	private AIDA aida; 
-	private List<IPlotter> plotters = new ArrayList<IPlotter>(); 
+    
+    private AIDA aida; 
+    private List<IPlotter> plotters = new ArrayList<IPlotter>(); 
 
-	IHistogram1D xPositionResidual;
-	IHistogram1D yPositionResidual;
-	IHistogram1D zPositionResidual;
-	IHistogram1D r;
-	
-	// Collection Names
-	private String finalStateParticlesCollectionName = "FinalStateParticles";
-	
-	boolean debug = true; 
-	int plotterIndex = 0; 
-	
-	public ReconstructedParticleChecker(){} 
-	
-	protected void detectorChanged(Detector detector){
-		super.detectorChanged(detector);
-		
-		// Setup AIDA
-		aida = AIDA.defaultInstance(); 
-		aida.tree().cd("/");
-		
-		plotters.add(PlotUtils.setupPlotter("Track-Cluster Position Residual", 2, 2));
-		xPositionResidual = aida.histogram1D("x Residual", 100, -100, 100);
-		yPositionResidual = aida.histogram1D("y Residual", 100, -100, 100);
-		zPositionResidual = aida.histogram1D("z Residual", 100, -100, 100);
-		r = aida.histogram1D("r", 100, -100, 100);
-		PlotUtils.setup1DRegion(plotters.get(plotterIndex), "x Residual", 0, "delta x [mm]", xPositionResidual);
-		PlotUtils.setup1DRegion(plotters.get(plotterIndex), "y Residual", 1, "delta y [mm]", yPositionResidual);
-		PlotUtils.setup1DRegion(plotters.get(plotterIndex), "z Residual", 2, "delta z [mm]", zPositionResidual);
-		PlotUtils.setup1DRegion(plotters.get(plotterIndex), "r", 3, "r [mm]", r);
-		
-		
-		for(IPlotter plotter : plotters){
-			plotter.show(); 
-		}
-	}
-	
-	public void process(EventHeader event){
-		
-		// If the event doesn't contain any final state reconstructed 
-		// particles, skip the event 
-		if(!event.hasCollection(ReconstructedParticle.class, finalStateParticlesCollectionName)){
-			this.printDebug("Event does not contain ReconstructedParticles");
-			return;
-		}
-		
-		// Get the collections of reconstructed final state particles from the
-		// event
-		List<ReconstructedParticle> finalStateParticles 
-			= event.get(ReconstructedParticle.class, finalStateParticlesCollectionName); 
-				
-	
-		// Loop over all of the reconstructed particles in the event
-		for(ReconstructedParticle finalStateParticle : finalStateParticles){
-			
-			// Get the list of clusters from the event
-			List<Cluster> ecalClusters = finalStateParticle.getClusters(); 
-				this.printDebug("Number of Ecal clusters: " + ecalClusters.size()); 
-			if(ecalClusters.isEmpty()){
-				this.printDebug("Number of Ecal clusters: " + ecalClusters.size()); 
-				this.printDebug("List of Ecal cluster is empty ... skipping");
-				continue; 
-			}
-			
-			// Get the list of tracks from the event
-			List<Track> tracks = finalStateParticle.getTracks(); 
-			if(tracks.isEmpty()){
-				this.printDebug("List of tracks is empty ... skipping");
-				continue; 
-			}
-		
-			Hep3Vector ecalPosition = new BasicHep3Vector(ecalClusters.get(0).getPosition()); 
-			Hep3Vector trackPositionAtEcal = TrackUtils.extrapolateTrack(tracks.get(0),ecalPosition.z()); 
-			xPositionResidual.fill(trackPositionAtEcal.x() - ecalPosition.x());
-			yPositionResidual.fill(trackPositionAtEcal.y() - ecalPosition.y());
-			zPositionResidual.fill(trackPositionAtEcal.z() - ecalPosition.z());
-			r.fill(VecOp.sub(trackPositionAtEcal, ecalPosition).magnitude());
-		}
-		
-	}
-	
-	private void printDebug(String debugMessage){
-		if(debug)
-			System.out.println(this.getClass().getSimpleName() + ": " + debugMessage); 
-	}
+    IHistogram1D xPositionResidual;
+    IHistogram1D yPositionResidual;
+    IHistogram1D zPositionResidual;
+    IHistogram1D r;
+    
+    // Collection Names
+    private String finalStateParticlesCollectionName = "FinalStateParticles";
+    
+    boolean debug = true; 
+    int plotterIndex = 0; 
+    
+    public ReconstructedParticleChecker(){} 
+    
+    protected void detectorChanged(Detector detector){
+        super.detectorChanged(detector);
+        
+        // Setup AIDA
+        aida = AIDA.defaultInstance(); 
+        aida.tree().cd("/");
+        
+        plotters.add(PlotUtils.setupPlotter("Track-Cluster Position Residual", 2, 2));
+        xPositionResidual = aida.histogram1D("x Residual", 100, -100, 100);
+        yPositionResidual = aida.histogram1D("y Residual", 100, -100, 100);
+        zPositionResidual = aida.histogram1D("z Residual", 100, -100, 100);
+        r = aida.histogram1D("r", 100, -100, 100);
+        PlotUtils.setup1DRegion(plotters.get(plotterIndex), "x Residual", 0, "delta x [mm]", xPositionResidual);
+        PlotUtils.setup1DRegion(plotters.get(plotterIndex), "y Residual", 1, "delta y [mm]", yPositionResidual);
+        PlotUtils.setup1DRegion(plotters.get(plotterIndex), "z Residual", 2, "delta z [mm]", zPositionResidual);
+        PlotUtils.setup1DRegion(plotters.get(plotterIndex), "r", 3, "r [mm]", r);
+        
+        
+        for(IPlotter plotter : plotters){
+            plotter.show(); 
+        }
+    }
+    
+    public void process(EventHeader event){
+        
+        // If the event doesn't contain any final state reconstructed 
+        // particles, skip the event 
+        if(!event.hasCollection(ReconstructedParticle.class, finalStateParticlesCollectionName)){
+            this.printDebug("Event does not contain ReconstructedParticles");
+            return;
+        }
+        
+        // Get the collections of reconstructed final state particles from the
+        // event
+        List<ReconstructedParticle> finalStateParticles 
+            = event.get(ReconstructedParticle.class, finalStateParticlesCollectionName); 
+                
+    
+        // Loop over all of the reconstructed particles in the event
+        for(ReconstructedParticle finalStateParticle : finalStateParticles){
+            
+            // Get the list of clusters from the event
+            List<Cluster> ecalClusters = finalStateParticle.getClusters(); 
+                this.printDebug("Number of Ecal clusters: " + ecalClusters.size()); 
+            if(ecalClusters.isEmpty()){
+                this.printDebug("Number of Ecal clusters: " + ecalClusters.size()); 
+                this.printDebug("List of Ecal cluster is empty ... skipping");
+                continue; 
+            }
+            
+            // Get the list of tracks from the event
+            List<Track> tracks = finalStateParticle.getTracks(); 
+            if(tracks.isEmpty()){
+                this.printDebug("List of tracks is empty ... skipping");
+                continue; 
+            }
+        
+            Hep3Vector ecalPosition = new BasicHep3Vector(ecalClusters.get(0).getPosition()); 
+            Hep3Vector trackPositionAtEcal = TrackUtils.extrapolateTrack(tracks.get(0),ecalPosition.z()); 
+            xPositionResidual.fill(trackPositionAtEcal.x() - ecalPosition.x());
+            yPositionResidual.fill(trackPositionAtEcal.y() - ecalPosition.y());
+            zPositionResidual.fill(trackPositionAtEcal.z() - ecalPosition.z());
+            r.fill(VecOp.sub(trackPositionAtEcal, ecalPosition).magnitude());
+        }
+        
+    }
+    
+    private void printDebug(String debugMessage){
+        if(debug)
+            System.out.println(this.getClass().getSimpleName() + ": " + debugMessage); 
+    }
 }

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/omoreno/SharedHitAnalysis.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/omoreno/SharedHitAnalysis.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/omoreno/SharedHitAnalysis.java	Wed Apr 27 11:11:32 2016
@@ -98,14 +98,14 @@
     }
     
     
-	protected void detectorChanged(Detector detector){
-
-	    for (int layer = 1; layer <= 6; layer++) { 
-	        
-	        topLayerToStereoHit.put(layer, new ArrayList<TrackerHit>());
-	        bottomLayerToStereoHit.put(layer, new ArrayList<TrackerHit>());
-	    }
-	    
+    protected void detectorChanged(Detector detector){
+
+        for (int layer = 1; layer <= 6; layer++) { 
+            
+            topLayerToStereoHit.put(layer, new ArrayList<TrackerHit>());
+            bottomLayerToStereoHit.put(layer, new ArrayList<TrackerHit>());
+        }
+        
         tree = IAnalysisFactory.create().createTreeFactory().create();
         histogramFactory = IAnalysisFactory.create().createHistogramFactory(tree);
         
@@ -159,18 +159,18 @@
         plotters.get("Track Parameters").region(4).plot(trackPlots.get("tan_lambda"), this.createStyle(1, "", ""));
         plotters.get("Track Parameters").region(4).plot(trackPlots.get("tan_lambda - shared strip hit"),  this.createStyle(2, "", ""));
         plotters.get("Track Parameters").region(4).plot(trackPlots.get("tan_lambda - l1 Isolation"),  this.createStyle(3, "", ""));
-	
-		for (IPlotter plotter : plotters.values()) { 
-			plotter.show();
-		}
-	}
-	
-	@SuppressWarnings({ "unchecked", "rawtypes" })
+    
+        for (IPlotter plotter : plotters.values()) { 
+            plotter.show();
+        }
+    }
+    
+    @SuppressWarnings({ "unchecked", "rawtypes" })
     public void process(EventHeader event){
 
         // If the event doesn't have any tracks, skip it    
-		if(!event.hasCollection(Track.class, trackCollectionName)) return;
-    	
+        if(!event.hasCollection(Track.class, trackCollectionName)) return;
+        
         // Get the collection of tracks from the event
         List<Track> tracks = event.get(Track.class, trackCollectionName);
         
@@ -198,13 +198,13 @@
         this.mapStereoHits(stereoHits);
         
         // Loop over all of the tracks in the event
-    	for(Track track : tracks){
-    	
-    	    boolean sharedHitTrack = false;
+        for(Track track : tracks){
+        
+            boolean sharedHitTrack = false;
            boolean l1Isolation = true;
-    	    
-    	    // Fill the track parameter plots
-    	    
+            
+            // Fill the track parameter plots
+            
             // Loop through all of the stereo hits associated with a track
             for (TrackerHit rotatedStereoHit : track.getTrackerHits()) { 
                
@@ -277,15 +277,15 @@
                 trackPlots.get("tan_lambda - l1 Isolation").fill(TrackUtils.getTanLambda(track));
                 trackPlots.get("chi2 - l1 Isolation").fill(track.getChi2());
             }
-    	}
-	}
-	
+        }
+    }
+    
     private void mapStereoHits(List<TrackerHit> stereoHits) { 
        
-	    for (int layer = 1; layer <= 6; layer++) { 
-	        topLayerToStereoHit.get(layer).clear();
-	        bottomLayerToStereoHit.get(layer).clear();;
-	    }
+        for (int layer = 1; layer <= 6; layer++) { 
+            topLayerToStereoHit.get(layer).clear();
+            bottomLayerToStereoHit.get(layer).clear();;
+        }
         
         for (TrackerHit stereoHit : stereoHits) {
             HpsSiSensor sensor = (HpsSiSensor) ((RawTrackerHit) stereoHit.getRawHits().get(0)).getDetectorElement();

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/omoreno/SvtClusterAnalysis.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/omoreno/SvtClusterAnalysis.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/omoreno/SvtClusterAnalysis.java	Wed Apr 27 11:11:32 2016
@@ -50,28 +50,28 @@
     // Plotting
     ITree tree; 
     IHistogramFactory histogramFactory; 
-	IPlotterFactory plotterFactory = IAnalysisFactory.create().createPlotterFactory();
-	protected Map<String, IPlotter> plotters = new HashMap<String, IPlotter>(); 
-	
-	// All clusters
-	private Map<String, IHistogram1D> clusterChargePlots = new HashMap<String, IHistogram1D>();
-	private Map<String, IHistogram1D> singleHitClusterChargePlots = new HashMap<String, IHistogram1D>();
-	private Map<String, IHistogram1D> multHitClusterChargePlots = new HashMap<String, IHistogram1D>();
-	private Map<String, IHistogram1D> signalToNoisePlots = new HashMap<String, IHistogram1D>();
-	private Map<String, IHistogram1D> singleHitSignalToNoisePlots = new HashMap<String, IHistogram1D>();
-	private Map<String, IHistogram1D> multHitSignalToNoisePlots = new HashMap<String, IHistogram1D>();
-	private Map<String, IHistogram1D> clusterSizePlots = new HashMap<String, IHistogram1D>();
-	private Map<String, IHistogram1D> clusterTimePlots = new HashMap<String, IHistogram1D>();
-	private Map<String, IHistogram2D> clusterChargeVsTimePlots = new HashMap<String, IHistogram2D>();
-
-	// Clusters on track
-	private Map<String, IHistogram1D> trackClusterChargePlots = new HashMap<String, IHistogram1D>();
-	private Map<String, IHistogram1D> trackHitSignalToNoisePlots = new HashMap<String, IHistogram1D>();
-	private Map<String, IHistogram1D> trackClusterTimePlots = new HashMap<String, IHistogram1D>();
-	private Map<String, IHistogram2D> trackClusterChargeVsMomentum = new HashMap<String, IHistogram2D>();
-	private Map<String, IHistogram2D> trackClusterChargeVsCosTheta = new HashMap<String, IHistogram2D>();
-	private Map<String, IHistogram2D> trackClusterChargeVsSinPhi = new HashMap<String, IHistogram2D>();
-	
+    IPlotterFactory plotterFactory = IAnalysisFactory.create().createPlotterFactory();
+    protected Map<String, IPlotter> plotters = new HashMap<String, IPlotter>(); 
+    
+    // All clusters
+    private Map<String, IHistogram1D> clusterChargePlots = new HashMap<String, IHistogram1D>();
+    private Map<String, IHistogram1D> singleHitClusterChargePlots = new HashMap<String, IHistogram1D>();
+    private Map<String, IHistogram1D> multHitClusterChargePlots = new HashMap<String, IHistogram1D>();
+    private Map<String, IHistogram1D> signalToNoisePlots = new HashMap<String, IHistogram1D>();
+    private Map<String, IHistogram1D> singleHitSignalToNoisePlots = new HashMap<String, IHistogram1D>();
+    private Map<String, IHistogram1D> multHitSignalToNoisePlots = new HashMap<String, IHistogram1D>();
+    private Map<String, IHistogram1D> clusterSizePlots = new HashMap<String, IHistogram1D>();
+    private Map<String, IHistogram1D> clusterTimePlots = new HashMap<String, IHistogram1D>();
+    private Map<String, IHistogram2D> clusterChargeVsTimePlots = new HashMap<String, IHistogram2D>();
+
+    // Clusters on track
+    private Map<String, IHistogram1D> trackClusterChargePlots = new HashMap<String, IHistogram1D>();
+    private Map<String, IHistogram1D> trackHitSignalToNoisePlots = new HashMap<String, IHistogram1D>();
+    private Map<String, IHistogram1D> trackClusterTimePlots = new HashMap<String, IHistogram1D>();
+    private Map<String, IHistogram2D> trackClusterChargeVsMomentum = new HashMap<String, IHistogram2D>();
+    private Map<String, IHistogram2D> trackClusterChargeVsCosTheta = new HashMap<String, IHistogram2D>();
+    private Map<String, IHistogram2D> trackClusterChargeVsSinPhi = new HashMap<String, IHistogram2D>();
+    
     // Detector name
     private static final String SUBDETECTOR_NAME = "Tracker";
     
@@ -92,29 +92,29 @@
     
     private int computePlotterRegion(HpsSiSensor sensor) {
 
-		if (sensor.getLayerNumber() < 7) {
-			if (sensor.isTopLayer()) {
-				return 6*(sensor.getLayerNumber() - 1); 
-			} else { 
-				return 6*(sensor.getLayerNumber() - 1) + 1;
-			} 
-		} else { 
-		
-			if (sensor.isTopLayer()) {
-				if (sensor.getSide() == HpsSiSensor.POSITRON_SIDE) {
-					return 6*(sensor.getLayerNumber() - 7) + 2;
-				} else { 
-					return 6*(sensor.getLayerNumber() - 7) + 3;
-				}
-			} else if (sensor.isBottomLayer()) {
-				if (sensor.getSide() == HpsSiSensor.POSITRON_SIDE) {
-					return 6*(sensor.getLayerNumber() - 7) + 4;
-				} else {
-					return 6*(sensor.getLayerNumber() - 7) + 5;
-				}
-			}
-		}
-		return -1; 
+        if (sensor.getLayerNumber() < 7) {
+            if (sensor.isTopLayer()) {
+                return 6*(sensor.getLayerNumber() - 1); 
+            } else { 
+                return 6*(sensor.getLayerNumber() - 1) + 1;
+            } 
+        } else { 
+        
+            if (sensor.isTopLayer()) {
+                if (sensor.getSide() == HpsSiSensor.POSITRON_SIDE) {
+                    return 6*(sensor.getLayerNumber() - 7) + 2;
+                } else { 
+                    return 6*(sensor.getLayerNumber() - 7) + 3;
+                }
+            } else if (sensor.isBottomLayer()) {
+                if (sensor.getSide() == HpsSiSensor.POSITRON_SIDE) {
+                    return 6*(sensor.getLayerNumber() - 7) + 4;
+                } else {
+                    return 6*(sensor.getLayerNumber() - 7) + 5;
+                }
+            }
+        }
+        return -1; 
     }
     
     protected void detectorChanged(Detector detector) {
@@ -249,12 +249,12 @@
                                                           .get(sensor.getName()));
         }
         
-		for (IPlotter plotter : plotters.values()) { 
-			plotter.show();
-		}
-    }
-
-	@SuppressWarnings({ "unchecked", "rawtypes" })
+        for (IPlotter plotter : plotters.values()) { 
+            plotter.show();
+        }
+    }
+
+    @SuppressWarnings({ "unchecked", "rawtypes" })
     public void process(EventHeader event) { 
      
         if (runNumber == -1) runNumber = event.getRunNumber();
@@ -354,18 +354,18 @@
         this.mapReconstructedParticlesToTracks(tracks, fsParticles);
        
         // Loop over all of the tracks in the event
-    	for(Track track : tracks){
+        for(Track track : tracks){
 
             // Calculate the momentum of the track
             double p = this.getReconstructedParticle(track).getMomentum().magnitude();
-    	    
-    	    for (TrackerHit rotatedStereoHit : track.getTrackerHits()) { 
-    	    
-    	        // Get the HelicalTrackHit corresponding to the RotatedHelicalTrackHit
-    	        // associated with a track
+            
+            for (TrackerHit rotatedStereoHit : track.getTrackerHits()) { 
+            
+                // Get the HelicalTrackHit corresponding to the RotatedHelicalTrackHit
+                // associated with a track
                 Set<TrackerHit> trackClusters = stereoHitToClusters.allFrom(hthToRotatedHth.from(rotatedStereoHit));
-    	        
-    	        for (TrackerHit trackCluster : trackClusters) { 
+                
+                for (TrackerHit trackCluster : trackClusters) { 
                 
                     // Get the raw hits composing this cluster and use them to calculate the amplitude of the hit
                     double amplitudeSum = 0;
@@ -405,9 +405,9 @@
                     trackClusterChargeVsCosTheta.get(sensor.getName()).fill(TrackUtils.getCosTheta(track), amplitudeSum);
                     trackClusterChargeVsSinPhi.get(sensor.getName()).fill(Math.sin(TrackUtils.getPhi0(track)), amplitudeSum);
                     //trackClusterTimePlots.get(sensor.getName()).fill(trackCluster.time());
-    	        }
-    	    }
-    	}
+                }
+            }
+        }
     }
     
     public void endOfData() { 

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/omoreno/SvtDataRates.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/omoreno/SvtDataRates.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/omoreno/SvtDataRates.java	Wed Apr 27 11:11:32 2016
@@ -12,81 +12,81 @@
 
 public class SvtDataRates extends Driver {
 
-	//Map<VOLUMES, double[]> rawHitsPerLayer = new HashMap<VOLUMES, double[]>(); 
-	double[][] rawHitsPerLayer = new double[12][4];
-	
-	//public enum VOLUMES { TOP, BOTTOM };
-	
-	// Collection Names
-	String rawTrackerHitCollectionName = "SVTRawTrackerHits";
+    //Map<VOLUMES, double[]> rawHitsPerLayer = new HashMap<VOLUMES, double[]>(); 
+    double[][] rawHitsPerLayer = new double[12][4];
+    
+    //public enum VOLUMES { TOP, BOTTOM };
+    
+    // Collection Names
+    String rawTrackerHitCollectionName = "SVTRawTrackerHits";
 
-	double totalEvents = 0; 
-	int totalLayersPerVolume = 0; 
-	
-	public SvtDataRates(){}
-	
-	//static { 
-	//	hep.aida.jfree.AnalysisFactory.register();
-	//}
-	
-	protected void detectorChanged(Detector detector){
-	
-		List<HpsSiSensor> sensors = detector.getDetectorElement().findDescendants(HpsSiSensor.class);
-		for(HpsSiSensor sensor : sensors){
-			this.printDebug("Layer: " + sensor.getLayerNumber() + " Module: " + sensor.getModuleNumber());
-		}
-		totalLayersPerVolume = sensors.size()/2;
-		//for(VOLUMES volume : VOLUMES.values()){
-		//	rawHitsPerLayer.put(volume, new double[totalLayersPerVolume]);
-		//}
-	}
-	
-	protected void process(EventHeader event){
-		
-		if(!event.hasCollection(RawTrackerHit.class, rawTrackerHitCollectionName)){
-			return;
-		}
-		
-		totalEvents++; 
-		
-		List<RawTrackerHit> rawHits = event.get(RawTrackerHit.class, rawTrackerHitCollectionName);
-		for(RawTrackerHit rawHit : rawHits){
-			
-			HpsSiSensor sensor = (HpsSiSensor) rawHit.getDetectorElement(); 
-			int layer = sensor.getLayerNumber();
-			int module = sensor.getModuleNumber();
-			//if(sensor.isTopLayer()){
-			//	rawHitsPerLayer.get(VOLUMES.TOP)[layer]++;
-			//} else { 
-			//	rawHitsPerLayer.get(VOLUMES.BOTTOM)[layer]++;
-			//}
-			
-			rawHitsPerLayer[layer-1][module]++;
-		}
-	}
-	
-	protected void endOfData(){
-	
-		//for(VOLUMES volume : VOLUMES.values()){
-			//System.out.println("Volume: " + volume);
-			//System.out.println("Hits per layer per event: ");
-			//for(int layer = 0; layer < totalLayersPerVolume; layer++){
-			//	System.out.println("Layer: " + (layer+1) + ": " + rawHitsPerLayer.get(volume)[layer]/totalEvents); 
-			//}
-		//}
-		
-		for(int layer = 0; layer < 12; layer++){
-			
-			for(int module = 0; module < 4; module++){
-				System.out.println("Layer: " + layer + 
-									" Module: " + module + 
-									" Hits Per Layer: " + rawHitsPerLayer[layer][module]/totalEvents); 
-			}
-		}
-	}
+    double totalEvents = 0; 
+    int totalLayersPerVolume = 0; 
+    
+    public SvtDataRates(){}
+    
+    //static { 
+    //  hep.aida.jfree.AnalysisFactory.register();
+    //}
+    
+    protected void detectorChanged(Detector detector){
+    
+        List<HpsSiSensor> sensors = detector.getDetectorElement().findDescendants(HpsSiSensor.class);
+        for(HpsSiSensor sensor : sensors){
+            this.printDebug("Layer: " + sensor.getLayerNumber() + " Module: " + sensor.getModuleNumber());
+        }
+        totalLayersPerVolume = sensors.size()/2;
+        //for(VOLUMES volume : VOLUMES.values()){
+        //  rawHitsPerLayer.put(volume, new double[totalLayersPerVolume]);
+        //}
+    }
+    
+    protected void process(EventHeader event){
+        
+        if(!event.hasCollection(RawTrackerHit.class, rawTrackerHitCollectionName)){
+            return;
+        }
+        
+        totalEvents++; 
+        
+        List<RawTrackerHit> rawHits = event.get(RawTrackerHit.class, rawTrackerHitCollectionName);
+        for(RawTrackerHit rawHit : rawHits){
+            
+            HpsSiSensor sensor = (HpsSiSensor) rawHit.getDetectorElement(); 
+            int layer = sensor.getLayerNumber();
+            int module = sensor.getModuleNumber();
+            //if(sensor.isTopLayer()){
+            //  rawHitsPerLayer.get(VOLUMES.TOP)[layer]++;
+            //} else { 
+            //  rawHitsPerLayer.get(VOLUMES.BOTTOM)[layer]++;
+            //}
+            
+            rawHitsPerLayer[layer-1][module]++;
+        }
+    }
+    
+    protected void endOfData(){
+    
+        //for(VOLUMES volume : VOLUMES.values()){
+            //System.out.println("Volume: " + volume);
+            //System.out.println("Hits per layer per event: ");
+            //for(int layer = 0; layer < totalLayersPerVolume; layer++){
+            //  System.out.println("Layer: " + (layer+1) + ": " + rawHitsPerLayer.get(volume)[layer]/totalEvents); 
+            //}
+        //}
+        
+        for(int layer = 0; layer < 12; layer++){
+            
+            for(int module = 0; module < 4; module++){
+                System.out.println("Layer: " + layer + 
+                                    " Module: " + module + 
+                                    " Hits Per Layer: " + rawHitsPerLayer[layer][module]/totalEvents); 
+            }
+        }
+    }
 
-	private void printDebug(String debugMessage){
-		System.out.println(this.getClass().getSimpleName() + ": " + debugMessage);
-	}
-	
+    private void printDebug(String debugMessage){
+        System.out.println(this.getClass().getSimpleName() + ": " + debugMessage);
+    }
+    
 }

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/omoreno/SvtHitCorrelations.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/omoreno/SvtHitCorrelations.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/omoreno/SvtHitCorrelations.java	Wed Apr 27 11:11:32 2016
@@ -28,12 +28,12 @@
  */
 public class SvtHitCorrelations extends Driver {
 
-	// TODO: Add documentation
-	static { 
-	    hep.aida.jfree.AnalysisFactory.register();
-	}
+    // TODO: Add documentation
+    static { 
+        hep.aida.jfree.AnalysisFactory.register();
+    }
    
-	// Plotting
+    // Plotting
     ITree tree; 
     IHistogramFactory histogramFactory;
     IPlotterFactory plotterFactory = IAnalysisFactory.create().createPlotterFactory();
@@ -59,46 +59,46 @@
     boolean enableBottomAxialAxial = false;
     boolean enableBottomAxialStereo = false;
     
-	/**
-	 * 
-	 */
-	public void setEnableTopAxialAxial(boolean enableTopAxialAxial){
-		this.enableTopAxialAxial = enableTopAxialAxial;
-	}
-
-	/**
-	 * 
-	 */
-	public void setEnableTopAxialStereo(boolean enableTopAxialStereo){
-	    this.enableTopAxialStereo = enableTopAxialStereo; 
-	}
-	
-	/**
-	 * 
-	 */
-	public void setEnableBottomAxialAxial(boolean enableBottomAxialAxial){
-		this.enableBottomAxialAxial = enableBottomAxialAxial;
-	}
-	
-	/**
-	 * 
-	 */
-	public void setEnableBottomAxialStereo(boolean enableBottomAxialStereo){
-	    this.enableBottomAxialStereo = enableBottomAxialStereo; 
-	}
-    
-	/**
-	 * 
-	 */
-	private int computePlotterRegion(HpsSiSensor firstSensor, HpsSiSensor secondSensor) {
-	    return (this.getLayerNumber(firstSensor) - 1) + (this.getLayerNumber(secondSensor) - 1)*6;    
-	}
-	
-	protected void detectorChanged(Detector detector){
-	   
+    /**
+     * 
+     */
+    public void setEnableTopAxialAxial(boolean enableTopAxialAxial){
+        this.enableTopAxialAxial = enableTopAxialAxial;
+    }
+
+    /**
+     * 
+     */
+    public void setEnableTopAxialStereo(boolean enableTopAxialStereo){
+        this.enableTopAxialStereo = enableTopAxialStereo; 
+    }
+    
+    /**
+     * 
+     */
+    public void setEnableBottomAxialAxial(boolean enableBottomAxialAxial){
+        this.enableBottomAxialAxial = enableBottomAxialAxial;
+    }
+    
+    /**
+     * 
+     */
+    public void setEnableBottomAxialStereo(boolean enableBottomAxialStereo){
+        this.enableBottomAxialStereo = enableBottomAxialStereo; 
+    }
+    
+    /**
+     * 
+     */
+    private int computePlotterRegion(HpsSiSensor firstSensor, HpsSiSensor secondSensor) {
+        return (this.getLayerNumber(firstSensor) - 1) + (this.getLayerNumber(secondSensor) - 1)*6;    
+    }
+    
+    protected void detectorChanged(Detector detector){
+       
         tree = IAnalysisFactory.create().createTreeFactory().create();
         histogramFactory = IAnalysisFactory.create().createHistogramFactory(tree);
-	
+    
         sensors = detector.getSubdetector(SUBDETECTOR_NAME).getDetectorElement().findDescendants(HpsSiSensor.class);
 
         if (sensors.size() == 0) {
@@ -178,55 +178,55 @@
         }
 
         for (IPlotter plotter : plotters.values()) plotter.show();
-	}
-	
-	public void process(EventHeader event){
-	
+    }
+    
+    public void process(EventHeader event){
+    
         if (runNumber == -1) runNumber = event.getRunNumber();
-	    
-		if(!event.hasCollection(RawTrackerHit.class, rawTrackerHitCollectionName)) return;
-	
-		List<RawTrackerHit> rawHits = event.get(RawTrackerHit.class, rawTrackerHitCollectionName);
-		
-		String plotName = "";
-		for(RawTrackerHit firstRawHit : rawHits){
-	
-			HpsSiSensor firstSensor = (HpsSiSensor) firstRawHit.getDetectorElement();
-			int firstChannel = firstRawHit.getIdentifierFieldValue("strip");
-			
-			for(RawTrackerHit secondRawHit : rawHits){
-			
-				HpsSiSensor secondSensor = (HpsSiSensor) secondRawHit.getDetectorElement();
-				int secondChannel = secondRawHit.getIdentifierFieldValue("strip");
-			
-				if(firstSensor.isTopLayer() && secondSensor.isTopLayer()){
-					if(enableTopAxialAxial && firstSensor.isAxial() && secondSensor.isAxial()){
-						
-					    plotName = "Top Axial Layer " + this.getLayerNumber(firstSensor) 
-					                + " vs Top Axial Layer " + this.getLayerNumber(secondSensor); 
-					    topAxialAxialPlots.get(plotName).fill(firstChannel, secondChannel);
-					} else if (enableTopAxialStereo && firstSensor.isAxial() && secondSensor.isStereo()) { 
-					    
-					    plotName = "Top Axial Layer " + this.getLayerNumber(firstSensor) 
-					                + " vs Top Stereo Layer " + this.getLayerNumber(secondSensor); 
-					    topAxialStereoPlots.get(plotName).fill(firstChannel, secondChannel);
-					}
-				} else if (firstSensor.isBottomLayer() && secondSensor.isBottomLayer()) { 
-					if(enableBottomAxialAxial && firstSensor.isAxial() && secondSensor.isAxial()){
-						
-					    plotName = "Bottom Axial Layer " + this.getLayerNumber(firstSensor) 
-					                + " vs Bottom Axial Layer " + this.getLayerNumber(secondSensor); 
-					    bottomAxialAxialPlots.get(plotName).fill(firstChannel, secondChannel);
-					} else if (enableBottomAxialStereo && firstSensor.isAxial() && secondSensor.isStereo()) { 
-					    
-					    plotName = "Bottom Axial Layer " + this.getLayerNumber(firstSensor) 
-					                + " vs Bottom Stereo Layer " + this.getLayerNumber(secondSensor); 
-					    bottomAxialStereoPlots.get(plotName).fill(firstChannel, secondChannel);
-					}
-				}
-			}
-		}
-	}
+        
+        if(!event.hasCollection(RawTrackerHit.class, rawTrackerHitCollectionName)) return;
+    
+        List<RawTrackerHit> rawHits = event.get(RawTrackerHit.class, rawTrackerHitCollectionName);
+        
+        String plotName = "";
+        for(RawTrackerHit firstRawHit : rawHits){
+    
+            HpsSiSensor firstSensor = (HpsSiSensor) firstRawHit.getDetectorElement();
+            int firstChannel = firstRawHit.getIdentifierFieldValue("strip");
+            
+            for(RawTrackerHit secondRawHit : rawHits){
+            
+                HpsSiSensor secondSensor = (HpsSiSensor) secondRawHit.getDetectorElement();
+                int secondChannel = secondRawHit.getIdentifierFieldValue("strip");
+            
+                if(firstSensor.isTopLayer() && secondSensor.isTopLayer()){
+                    if(enableTopAxialAxial && firstSensor.isAxial() && secondSensor.isAxial()){
+                        
+                        plotName = "Top Axial Layer " + this.getLayerNumber(firstSensor) 
+                                    + " vs Top Axial Layer " + this.getLayerNumber(secondSensor); 
+                        topAxialAxialPlots.get(plotName).fill(firstChannel, secondChannel);
+                    } else if (enableTopAxialStereo && firstSensor.isAxial() && secondSensor.isStereo()) { 
+                        
+                        plotName = "Top Axial Layer " + this.getLayerNumber(firstSensor) 
+                                    + " vs Top Stereo Layer " + this.getLayerNumber(secondSensor); 
+                        topAxialStereoPlots.get(plotName).fill(firstChannel, secondChannel);
+                    }
+                } else if (firstSensor.isBottomLayer() && secondSensor.isBottomLayer()) { 
+                    if(enableBottomAxialAxial && firstSensor.isAxial() && secondSensor.isAxial()){
+                        
+                        plotName = "Bottom Axial Layer " + this.getLayerNumber(firstSensor) 
+                                    + " vs Bottom Axial Layer " + this.getLayerNumber(secondSensor); 
+                        bottomAxialAxialPlots.get(plotName).fill(firstChannel, secondChannel);
+                    } else if (enableBottomAxialStereo && firstSensor.isAxial() && secondSensor.isStereo()) { 
+                        
+                        plotName = "Bottom Axial Layer " + this.getLayerNumber(firstSensor) 
+                                    + " vs Bottom Stereo Layer " + this.getLayerNumber(secondSensor); 
+                        bottomAxialStereoPlots.get(plotName).fill(firstChannel, secondChannel);
+                    }
+                }
+            }
+        }
+    }
 
     public void endOfData() { 
       
@@ -240,12 +240,12 @@
             e.printStackTrace();
         }
     }
-	
-	
-	private int getLayerNumber(HpsSiSensor sensor) {
-	   return (int) Math.ceil(((double) sensor.getLayerNumber())/2); 
-	}
-	
+    
+    
+    private int getLayerNumber(HpsSiSensor sensor) {
+       return (int) Math.ceil(((double) sensor.getLayerNumber())/2); 
+    }
+    
     IPlotterStyle createStyle(String xAxisTitle, String yAxisTitle) { 
        
         // Create a default style
@@ -279,5 +279,5 @@
        
         return style;
     }
-	
+    
 }

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/omoreno/SvtQA.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/omoreno/SvtQA.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/omoreno/SvtQA.java	Wed Apr 27 11:11:32 2016
@@ -54,7 +54,7 @@
 
     int channelNumber = 0;
     int plotterIndex = 0;
-    int apvNumber = 0;	
+    int apvNumber = 0;  
     double totalNumberEvents = 0;
     double totalNumberOfRawHitEvents = 0;
     double[] totalTopSamples = new double[6];
@@ -210,7 +210,7 @@
      * 
      */
     public void setEnableTotalNumberOfHitsPlots(boolean enableTotalNumberOfHitsPlots){
-    	this.enableTotalNumberOfHitsPlots = enableTotalNumberOfHitsPlots;
+        this.enableTotalNumberOfHitsPlots = enableTotalNumberOfHitsPlots;
     }
 
     /**
@@ -391,13 +391,13 @@
         }
         
         if(enableTotalNumberOfHitsPlots){
-        	title = "Total Number of RawTrackerHits";
-        	plotters.add(PlotUtils.setupPlotter(title, 0, 0));
-        	plotters.get(plotterIndex).style().statisticsBoxStyle().setVisible(true);
-        	histo1D = aida.histogram1D(title, 100, 0, 75);
-        	histos1D.add(histo1D);
-        	PlotUtils.setup1DRegion(plotters.get(plotterIndex), title, 0, "Number of RawTrackerHits", histo1D);
-        	plotterIndex++;
+            title = "Total Number of RawTrackerHits";
+            plotters.add(PlotUtils.setupPlotter(title, 0, 0));
+            plotters.get(plotterIndex).style().statisticsBoxStyle().setVisible(true);
+            histo1D = aida.histogram1D(title, 100, 0, 75);
+            histos1D.add(histo1D);
+            PlotUtils.setup1DRegion(plotters.get(plotterIndex), title, 0, "Number of RawTrackerHits", histo1D);
+            plotterIndex++;
         }
 
         for(IPlotter plotter : plotters) plotter.show();
@@ -488,7 +488,7 @@
                     aida.histogram1D(title).fill(sample);
                 }
                 title = "Shaper Signal Amplitude";
-                aida.histogram1D(title).fill(fit.getAmp());	    
+                aida.histogram1D(title).fill(fit.getAmp());     
                 System.out.println("Amplitude: " + fit.getAmp());
                 title="t0";
                 aida.histogram1D(title).fill(fit.getT0());
@@ -595,9 +595,9 @@
                                 topSamples[sampleN-1] += samples[sampleN-1] - sensor.getPedestal(channel, sampleN-1);
                             }
                             else{
-                            	aida.histogram2D("APV Sample Number vs Sample Amplitude - Bottom").fill(sampleN, samples[sampleN-1] - sensor.getPedestal(channel, sampleN-1));
-                            	totalBottomSamples[sampleN-1]++;
-                            	bottomSamples[sampleN-1] += samples[sampleN - 1] - sensor.getPedestal(channel, sampleN-1);
+                                aida.histogram2D("APV Sample Number vs Sample Amplitude - Bottom").fill(sampleN, samples[sampleN-1] - sensor.getPedestal(channel, sampleN-1));
+                                totalBottomSamples[sampleN-1]++;
+                                bottomSamples[sampleN-1] += samples[sampleN - 1] - sensor.getPedestal(channel, sampleN-1);
                             }
                         }
                     }
@@ -659,7 +659,7 @@
                         int channel = ((RawTrackerHit) hts.rawhits().get(0)).getIdentifierFieldValue("strip");
                         
                         if(sensorName.equals("all")){
-                        	aida.histogram2D(sensor.getName() + " - t0 Resolution vs Channel #").fill(channel, meanT0 - hts.time());
+                            aida.histogram2D(sensor.getName() + " - t0 Resolution vs Channel #").fill(channel, meanT0 - hts.time());
                         } else {
                         if(sensor.getName().equals(sensorName)){
                             aida.histogram1D(sensorName + " - Hit Time Resolution").fill(meanT0 - hts.time());
@@ -675,67 +675,67 @@
 
     @Override
         public void endOfData(){
-    		String title;
-    		
-
-    		
+            String title;
+            
+
+            
             String plotName;
-    		if(enableOccupancy){
-    			for(HpsSiSensor sensor : sensors){
-    				title = sensor.getName() + " - Occupancy";
-    				// Scale the hits per channel by the number of events
-    				aida.histogram1D(title).scale(1/totalNumberEvents);
-    				
-    				// Write the occupancies to a file
-    				if(sensor.isTopLayer()){
-    					plotName = outputFile + "_top_";
-    				} else { 
-    					plotName = outputFile + "_bottom_";
-    				}
-    				
-					if(sensor.getLayerNumber() < 10){
-						plotName += "0" + sensor.getLayerNumber() + ".dat";
-					} else {
-						plotName += sensor.getLayerNumber() + ".dat";
-					}
-    			
-	    			// Open the output files stream
-	                if(plotName != null){
-	                	try{
-	                		output = new BufferedWriter(new FileWriter(plotName)); 
-                			for(int channel = 0; channel < 640; channel++){
-                				output.write(channel + " " + aida.histogram1D(title).binHeight(channel) + "\n");
-                			}
-                			output.close();
-	                	} catch(Exception e) {
-	                		System.out.println(this.getClass().getSimpleName() + " :Error! " + e.getMessage());
-	                	}
-	                }
-    			}
-    		}
-    		
-    		if(enableT0Plots){
-    			int bins = aida.histogram1D(sensorName + " - Hit Time Resolution").axis().bins();
-    			for(int bin = 0; bin < bins; bin++){
-    				System.out.println(bin + "        " + aida.histogram1D(sensorName + " - Hit Time Resolution").binHeight(bin));
-    			}
-    		}
-    	
-            	
-            	/*
+            if(enableOccupancy){
                 for(HpsSiSensor sensor : sensors){
-                    	if(outputFile != null && sensorName.equals(sensor.getName())){
-                    		try{
-                    			for(int channel = 0; channel < 639; channel++){
-    								output.write(channel + " " + this.getOccupancy(sensor, channel) + "\n");
-    							}
-                    			output.close();
-                    		} catch(IOException e){
-                    			System.out.println(this.getClass().getSimpleName() + ": Error! " + e.getMessage());
-                    		}
-                    	}
-                	
-                	System.out.println("%===================================================================%");
+                    title = sensor.getName() + " - Occupancy";
+                    // Scale the hits per channel by the number of events
+                    aida.histogram1D(title).scale(1/totalNumberEvents);
+                    
+                    // Write the occupancies to a file
+                    if(sensor.isTopLayer()){
+                        plotName = outputFile + "_top_";
+                    } else { 
+                        plotName = outputFile + "_bottom_";
+                    }
+                    
+                    if(sensor.getLayerNumber() < 10){
+                        plotName += "0" + sensor.getLayerNumber() + ".dat";
+                    } else {
+                        plotName += sensor.getLayerNumber() + ".dat";
+                    }
+                
+                    // Open the output files stream
+                    if(plotName != null){
+                        try{
+                            output = new BufferedWriter(new FileWriter(plotName)); 
+                            for(int channel = 0; channel < 640; channel++){
+                                output.write(channel + " " + aida.histogram1D(title).binHeight(channel) + "\n");
+                            }
+                            output.close();
+                        } catch(Exception e) {
+                            System.out.println(this.getClass().getSimpleName() + " :Error! " + e.getMessage());
+                        }
+                    }
+                }
+            }
+            
+            if(enableT0Plots){
+                int bins = aida.histogram1D(sensorName + " - Hit Time Resolution").axis().bins();
+                for(int bin = 0; bin < bins; bin++){
+                    System.out.println(bin + "        " + aida.histogram1D(sensorName + " - Hit Time Resolution").binHeight(bin));
+                }
+            }
+        
+                
+                /*
+                for(HpsSiSensor sensor : sensors){
+                        if(outputFile != null && sensorName.equals(sensor.getName())){
+                            try{
+                                for(int channel = 0; channel < 639; channel++){
+                                    output.write(channel + " " + this.getOccupancy(sensor, channel) + "\n");
+                                }
+                                output.close();
+                            } catch(IOException e){
+                                System.out.println(this.getClass().getSimpleName() + ": Error! " + e.getMessage());
+                            }
+                        }
+                    
+                    System.out.println("%===================================================================%");
                     System.out.println(sensor.getName() + " Bad Channels");
                     System.out.println("%===================================================================%");
                     for(int index = 0; index < 640; index++){
@@ -769,21 +769,21 @@
             }
             
             if(enableSamples){
-            	double sigma = 0;
-            	double[] topMean = new double[6];
-            	double[] bottomMean = new double[6];
-            	
+                double sigma = 0;
+                double[] topMean = new double[6];
+                double[] bottomMean = new double[6];
+                
                 System.out.println("%===================================================================% \n");
-            	for(int index = 0; index < topSamples.length; index++){
-            		topMean[index] = topSamples[index]/totalTopSamples[index];
-            		System.out.println("Top sample " + index + " mean: " + topMean[index]);
-            	}
-            	
+                for(int index = 0; index < topSamples.length; index++){
+                    topMean[index] = topSamples[index]/totalTopSamples[index];
+                    System.out.println("Top sample " + index + " mean: " + topMean[index]);
+                }
+                
                 System.out.println("\n%===================================================================% \n");
-            	for(int index = 0; index < bottomSamples.length; index++){
-            		bottomMean[index] = bottomSamples[index]/totalBottomSamples[index];
-            		System.out.println("Bottom sample " + index + " mean: " + bottomMean[index]);
-            	}
+                for(int index = 0; index < bottomSamples.length; index++){
+                    bottomMean[index] = bottomSamples[index]/totalBottomSamples[index];
+                    System.out.println("Bottom sample " + index + " mean: " + bottomMean[index]);
+                }
                 System.out.println("\n%===================================================================% \n");
             }
         }

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/omoreno/SvtTrackAnalysis.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/omoreno/SvtTrackAnalysis.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/omoreno/SvtTrackAnalysis.java	Wed Apr 27 11:11:32 2016
@@ -46,8 +46,8 @@
     IPlotterFactory plotterFactory = IAnalysisFactory.create().createPlotterFactory();
     protected Map<String, IPlotter> plotters = new HashMap<String, IPlotter>();
     private Map<String, IHistogram1D> trackPlots = new HashMap<String, IHistogram1D>();
-	private Map<String, IHistogram1D> clusterChargePlots = new HashMap<String, IHistogram1D>();
-	private Map<String, IHistogram1D> clusterSizePlots = new HashMap<String, IHistogram1D>();
+    private Map<String, IHistogram1D> clusterChargePlots = new HashMap<String, IHistogram1D>();
+    private Map<String, IHistogram1D> clusterSizePlots = new HashMap<String, IHistogram1D>();
 
     private List<HpsSiSensor> sensors;
     private Map<RawTrackerHit, LCRelation> fittedRawTrackerHitMap 
@@ -64,67 +64,67 @@
 
     private int runNumber = -1; 
     
-	int npositive = 0;
-	int nnegative = 0;
-	double ntracks = 0;
-	double ntracksTop = 0;
-	double ntracksBottom = 0;
-	double nTwoTracks = 0;
-	double nevents = 0;
-
-	double d0Cut = -9999;
-	
-	// Flags 
-	boolean electronCut = false;
-	boolean positronCut = false;
-	
+    int npositive = 0;
+    int nnegative = 0;
+    double ntracks = 0;
+    double ntracksTop = 0;
+    double ntracksBottom = 0;
+    double nTwoTracks = 0;
+    double nevents = 0;
+
+    double d0Cut = -9999;
+    
+    // Flags 
+    boolean electronCut = false;
+    boolean positronCut = false;
+    
     /**
      *  Default Constructor
      */    
-	public SvtTrackAnalysis(){
-	}
-	
-	public void setEnableElectronCut(boolean electronCut) {
-	    this.electronCut = electronCut;
-	}
-
-	public void setEnablePositronCut(boolean positronCut) {
-	    this.positronCut = positronCut;
-	}
-
-	public void setD0Cut(double d0Cut) {
-	   this.d0Cut = d0Cut; 
-	}
-	
-	private int computePlotterRegion(HpsSiSensor sensor) {
-
-		if (sensor.getLayerNumber() < 7) {
-			if (sensor.isTopLayer()) {
-				return 6*(sensor.getLayerNumber() - 1); 
-			} else { 
-				return 6*(sensor.getLayerNumber() - 1) + 1;
-			} 
-		} else { 
-		
-			if (sensor.isTopLayer()) {
-				if (sensor.getSide() == HpsSiSensor.POSITRON_SIDE) {
-					return 6*(sensor.getLayerNumber() - 7) + 2;
-				} else { 
-					return 6*(sensor.getLayerNumber() - 7) + 3;
-				}
-			} else if (sensor.isBottomLayer()) {
-				if (sensor.getSide() == HpsSiSensor.POSITRON_SIDE) {
-					return 6*(sensor.getLayerNumber() - 7) + 4;
-				} else {
-					return 6*(sensor.getLayerNumber() - 7) + 5;
-				}
-			}
-		}
-		return -1; 
-    }
-	
-	protected void detectorChanged(Detector detector){
-	
+    public SvtTrackAnalysis(){
+    }
+    
+    public void setEnableElectronCut(boolean electronCut) {
+        this.electronCut = electronCut;
+    }
+
+    public void setEnablePositronCut(boolean positronCut) {
+        this.positronCut = positronCut;
+    }
+
+    public void setD0Cut(double d0Cut) {
+       this.d0Cut = d0Cut; 
+    }
+    
+    private int computePlotterRegion(HpsSiSensor sensor) {
+
+        if (sensor.getLayerNumber() < 7) {
+            if (sensor.isTopLayer()) {
+                return 6*(sensor.getLayerNumber() - 1); 
+            } else { 
+                return 6*(sensor.getLayerNumber() - 1) + 1;
+            } 
+        } else { 
+        
+            if (sensor.isTopLayer()) {
+                if (sensor.getSide() == HpsSiSensor.POSITRON_SIDE) {
+                    return 6*(sensor.getLayerNumber() - 7) + 2;
+                } else { 
+                    return 6*(sensor.getLayerNumber() - 7) + 3;
+                }
+            } else if (sensor.isBottomLayer()) {
+                if (sensor.getSide() == HpsSiSensor.POSITRON_SIDE) {
+                    return 6*(sensor.getLayerNumber() - 7) + 4;
+                } else {
+                    return 6*(sensor.getLayerNumber() - 7) + 5;
+                }
+            }
+        }
+        return -1; 
+    }
+    
+    protected void detectorChanged(Detector detector){
+    
         tree = IAnalysisFactory.create().createTreeFactory().create();
         histogramFactory = IAnalysisFactory.create().createHistogramFactory(tree);
         
@@ -195,66 +195,66 @@
             
         }
 
-		//--- Track Extrapolation ---//
-		//---------------------------//	
-		/*plotters.add(aida.analysisFactory().createPlotterFactory().create("Track Position at Ecal"));
-		plotters.get(nPlotters).region(0).plot(aida.histogram2D("Track Position at Ecal", 200, -350, 350, 200, -100, 100));
-		plotters.get(nPlotters).region(0).style().setParameter("hist2DStyle", "colorMap");
-    	plotters.get(nPlotters).region(0).style().dataStyle().fillStyle().setParameter("colorMapScheme", "rainbow");
+        //--- Track Extrapolation ---//
+        //---------------------------// 
+        /*plotters.add(aida.analysisFactory().createPlotterFactory().create("Track Position at Ecal"));
+        plotters.get(nPlotters).region(0).plot(aida.histogram2D("Track Position at Ecal", 200, -350, 350, 200, -100, 100));
+        plotters.get(nPlotters).region(0).style().setParameter("hist2DStyle", "colorMap");
+        plotters.get(nPlotters).region(0).style().dataStyle().fillStyle().setParameter("colorMapScheme", "rainbow");
         plotters.get(nPlotters).style().statisticsBoxStyle().setVisible(false);
         plotters.get(nPlotters).style();
-		nPlotters++;
+        nPlotters++;
         
         plotters.add(aida.analysisFactory().createPlotterFactory().create("Track Position at Harp"));
         plotters.get(nPlotters).region(0).plot(aida.histogram2D("Track Position at Harp", 200, -200, 200, 100, -50, 50));
-		plotters.get(nPlotters).region(0).style().setParameter("hist2DStyle", "colorMap");
-    	plotters.get(nPlotters).region(0).style().dataStyle().fillStyle().setParameter("colorMapScheme", "rainbow");
-        plotters.get(nPlotters).style().statisticsBoxStyle().setVisible(false);
-		nPlotters++;
+        plotters.get(nPlotters).region(0).style().setParameter("hist2DStyle", "colorMap");
+        plotters.get(nPlotters).region(0).style().dataStyle().fillStyle().setParameter("colorMapScheme", "rainbow");
+        plotters.get(nPlotters).style().statisticsBoxStyle().setVisible(false);
+        nPlotters++;
 
         plotters.add(aida.analysisFactory().createPlotterFactory().create("Track Position at Ecal: curvature < 0"));
         plotters.get(nPlotters).region(0).plot(aida.histogram2D("Track Position at Ecal: curvature < 0",200, -350, 350, 200, -100, 100));
-		plotters.get(nPlotters).region(0).style().setParameter("hist2DStyle", "colorMap");
-    	plotters.get(nPlotters).region(0).style().dataStyle().fillStyle().setParameter("colorMapScheme", "rainbow");
-        plotters.get(nPlotters).style().statisticsBoxStyle().setVisible(false);
-		nPlotters++;
-		
+        plotters.get(nPlotters).region(0).style().setParameter("hist2DStyle", "colorMap");
+        plotters.get(nPlotters).region(0).style().dataStyle().fillStyle().setParameter("colorMapScheme", "rainbow");
+        plotters.get(nPlotters).style().statisticsBoxStyle().setVisible(false);
+        nPlotters++;
+        
         plotters.add(aida.analysisFactory().createPlotterFactory().create("Track Position at Harp: curvature < 0"));
         plotters.get(nPlotters).region(0).plot(aida.histogram2D("Track Position at Harp: curvature < 0", 200, -200, 200, 100, -50, 50));
-		plotters.get(nPlotters).region(0).style().setParameter("hist2DStyle", "colorMap");
-    	plotters.get(nPlotters).region(0).style().dataStyle().fillStyle().setParameter("colorMapScheme", "rainbow");
-        plotters.get(nPlotters).style().statisticsBoxStyle().setVisible(false);
-		nPlotters++;
-		
+        plotters.get(nPlotters).region(0).style().setParameter("hist2DStyle", "colorMap");
+        plotters.get(nPlotters).region(0).style().dataStyle().fillStyle().setParameter("colorMapScheme", "rainbow");
+        plotters.get(nPlotters).style().statisticsBoxStyle().setVisible(false);
+        nPlotters++;
+        
         plotters.add(aida.analysisFactory().createPlotterFactory().create("Track Position at Ecal: curvature > 0"));
         plotters.get(nPlotters).region(0).plot(aida.histogram2D("Track Position at Ecal: curvature > 0", 200, -350, 350, 200, -100, 100));
-		plotters.get(nPlotters).region(0).style().setParameter("hist2DStyle", "colorMap");
-    	plotters.get(nPlotters).region(0).style().dataStyle().fillStyle().setParameter("colorMapScheme", "rainbow");
-        plotters.get(nPlotters).style().statisticsBoxStyle().setVisible(false);
-		nPlotters++;
-		
+        plotters.get(nPlotters).region(0).style().setParameter("hist2DStyle", "colorMap");
+        plotters.get(nPlotters).region(0).style().dataStyle().fillStyle().setParameter("colorMapScheme", "rainbow");
+        plotters.get(nPlotters).style().statisticsBoxStyle().setVisible(false);
+        nPlotters++;
+        
         plotters.add(aida.analysisFactory().createPlotterFactory().create("Track Position at Harp: curvature > 0"));
         plotters.get(nPlotters).region(0).plot(aida.histogram2D("Track Position at Harp: curvature > 0", 200, -200, 200, 100, -50, 50));
-		plotters.get(nPlotters).region(0).style().setParameter("hist2DStyle", "colorMap");
-    	plotters.get(nPlotters).region(0).style().dataStyle().fillStyle().setParameter("colorMapScheme", "rainbow");
-        plotters.get(nPlotters).style().statisticsBoxStyle().setVisible(false);
-		nPlotters++;
-		
-		plotters.add(aida.analysisFactory().createPlotterFactory().create("Track Position at Ecal: Two Tracks"));
-		plotters.get(nPlotters).region(0).plot(aida.histogram2D("Track Position at Ecal: Two Tracks", 200, -350, 350, 200, -100, 100));
-		plotters.get(nPlotters).region(0).style().setParameter("hist2DStyle", "colorMap");
-    	plotters.get(nPlotters).region(0).style().dataStyle().fillStyle().setParameter("colorMapScheme", "rainbow");
+        plotters.get(nPlotters).region(0).style().setParameter("hist2DStyle", "colorMap");
+        plotters.get(nPlotters).region(0).style().dataStyle().fillStyle().setParameter("colorMapScheme", "rainbow");
+        plotters.get(nPlotters).style().statisticsBoxStyle().setVisible(false);
+        nPlotters++;
+        
+        plotters.add(aida.analysisFactory().createPlotterFactory().create("Track Position at Ecal: Two Tracks"));
+        plotters.get(nPlotters).region(0).plot(aida.histogram2D("Track Position at Ecal: Two Tracks", 200, -350, 350, 200, -100, 100));
+        plotters.get(nPlotters).region(0).style().setParameter("hist2DStyle", "colorMap");
+        plotters.get(nPlotters).region(0).style().dataStyle().fillStyle().setParameter("colorMapScheme", "rainbow");
         plotters.get(nPlotters).style().statisticsBoxStyle().setVisible(false);
         plotters.get(nPlotters).style();
-		nPlotters++;
+        nPlotters++;
         
         plotters.add(aida.analysisFactory().createPlotterFactory().create("Track Position at Harp: Two Tracks"));
         plotters.get(nPlotters).region(0).plot(aida.histogram2D("Track Position at Harp: Two Tracks", 200, -200, 200, 100, -50, 50));
-		plotters.get(nPlotters).region(0).style().setParameter("hist2DStyle", "colorMap");
-    	plotters.get(nPlotters).region(0).style().dataStyle().fillStyle().setParameter("colorMapScheme", "rainbow");
-        plotters.get(nPlotters).style().statisticsBoxStyle().setVisible(false);
-		nPlotters++;
-		
+        plotters.get(nPlotters).region(0).style().setParameter("hist2DStyle", "colorMap");
+        plotters.get(nPlotters).region(0).style().dataStyle().fillStyle().setParameter("colorMapScheme", "rainbow");
+        plotters.get(nPlotters).style().statisticsBoxStyle().setVisible(false);
+        nPlotters++;
+        
         
         //--- Momentum ---//
         //----------------//
@@ -262,99 +262,99 @@
         plotters.get(nPlotters).region(0).plot(aida.histogram1D("Px", 100, 0, 5));
         plotters.get(nPlotters).style().statisticsBoxStyle().setVisible(false);
         plotters.get(nPlotters).style().dataStyle().errorBarStyle().setVisible(false);
-		nPlotters++;
+        nPlotters++;
         
         plotters.add(aida.analysisFactory().createPlotterFactory().create("Py"));
         plotters.get(nPlotters).region(0).plot(aida.histogram1D("Py", 100, 0, 5));
         plotters.get(nPlotters).style().statisticsBoxStyle().setVisible(false);
         plotters.get(nPlotters).style().dataStyle().errorBarStyle().setVisible(false);
-		nPlotters++;
+        nPlotters++;
         
         plotters.add(aida.analysisFactory().createPlotterFactory().create("Pz"));
         plotters.get(nPlotters).region(0).plot(aida.histogram1D("Pz", 100, 0, 5));
         plotters.get(nPlotters).style().statisticsBoxStyle().setVisible(false);
         plotters.get(nPlotters).style().dataStyle().errorBarStyle().setVisible(false);
-		nPlotters++;
-		
+        nPlotters++;
+        
         plotters.add(aida.analysisFactory().createPlotterFactory().create("Px: C > 0"));
         plotters.get(nPlotters).region(0).plot(aida.histogram1D("Px: C > 0", 100, 0, 5));
         plotters.get(nPlotters).style().statisticsBoxStyle().setVisible(false);
         plotters.get(nPlotters).style().dataStyle().errorBarStyle().setVisible(false);
-		nPlotters++;
+        nPlotters++;
         
         plotters.add(aida.analysisFactory().createPlotterFactory().create("Py: C > 0"));
         plotters.get(nPlotters).region(0).plot(aida.histogram1D("Py: C > 0", 100, 0, 5));
         plotters.get(nPlotters).style().statisticsBoxStyle().setVisible(false);
         plotters.get(nPlotters).style().dataStyle().errorBarStyle().setVisible(false);
-		nPlotters++;
+        nPlotters++;
         
         plotters.add(aida.analysisFactory().createPlotterFactory().create("Pz: C > 0"));
         plotters.get(nPlotters).region(0).plot(aida.histogram1D("Pz: C > 0", 100, 0, 5));
         plotters.get(nPlotters).style().statisticsBoxStyle().setVisible(false);
         plotters.get(nPlotters).style().dataStyle().errorBarStyle().setVisible(false);
-		nPlotters++;
-		
+        nPlotters++;
+        
         plotters.add(aida.analysisFactory().createPlotterFactory().create("Px: C < 0"));
         plotters.get(nPlotters).region(0).plot(aida.histogram1D("Px: C < 0", 100, 0, 5));
         plotters.get(nPlotters).style().statisticsBoxStyle().setVisible(false);
         plotters.get(nPlotters).style().dataStyle().errorBarStyle().setVisible(false);
-		nPlotters++;
+        nPlotters++;
         
         plotters.add(aida.analysisFactory().createPlotterFactory().create("Py: C < 0"));
         plotters.get(nPlotters).region(0).plot(aida.histogram1D("Py: C < 0", 100, 0, 5));
         plotters.get(nPlotters).style().statisticsBoxStyle().setVisible(false);
         plotters.get(nPlotters).style().dataStyle().errorBarStyle().setVisible(false);
-		nPlotters++;
+        nPlotters++;
         
         plotters.add(aida.analysisFactory().createPlotterFactory().create("Pz: C < 0"));
         plotters.get(nPlotters).region(0).plot(aida.histogram1D("Pz: C < 0", 100, 0, 5));
         plotters.get(nPlotters).style().statisticsBoxStyle().setVisible(false);
         plotters.get(nPlotters).style().dataStyle().errorBarStyle().setVisible(false);
-		nPlotters++;
-		
+        nPlotters++;
+        
         plotters.add(aida.analysisFactory().createPlotterFactory().create("Px: Two Tracks"));
         plotters.get(nPlotters).region(0).plot(aida.histogram1D("Px: Two Tracks", 100, 0, 5));
         plotters.get(nPlotters).style().statisticsBoxStyle().setVisible(false);
         plotters.get(nPlotters).style().dataStyle().errorBarStyle().setVisible(false);
-		nPlotters++;
+        nPlotters++;
         
         plotters.add(aida.analysisFactory().createPlotterFactory().create("E over P"));
         plotters.get(nPlotters).region(0).plot(aida.histogram1D("E over P", 100, 0, 5));
         plotters.get(nPlotters).style().statisticsBoxStyle().setVisible(false);
         plotters.get(nPlotters).style().dataStyle().errorBarStyle().setVisible(false);
-		nPlotters++;
-		   
-		plotters.add(aida.analysisFactory().createPlotterFactory().create("E versus P"));
-	    plotters.get(nPlotters).region(0).plot(aida.histogram2D("E versus P", 100, 0, 1500, 100, 0, 4000));
-	    plotters.get(nPlotters).region(0).style().setParameter("hist2DStyle", "colorMap");
-	    plotters.get(nPlotters).region(0).style().dataStyle().fillStyle().setParameter("colorMapScheme", "rainbow");
-	    plotters.get(nPlotters).style().statisticsBoxStyle().setVisible(false);
-	    nPlotters++;
+        nPlotters++;
+           
+        plotters.add(aida.analysisFactory().createPlotterFactory().create("E versus P"));
+        plotters.get(nPlotters).region(0).plot(aida.histogram2D("E versus P", 100, 0, 1500, 100, 0, 4000));
+        plotters.get(nPlotters).region(0).style().setParameter("hist2DStyle", "colorMap");
+        plotters.get(nPlotters).region(0).style().dataStyle().fillStyle().setParameter("colorMapScheme", "rainbow");
+        plotters.get(nPlotters).style().statisticsBoxStyle().setVisible(false);
+        nPlotters++;
         
         //--- Cluster Matching ---//
         //------------------------//        
         plotters.add(aida.analysisFactory().createPlotterFactory().create("XY Difference between Ecal Cluster and Track Position"));
         plotters.get(nPlotters).region(0).plot(aida.histogram2D("XY Difference between Ecal Cluster and Track Position", 200, -200, 200, 100, -50, 50));
-		plotters.get(nPlotters).region(0).style().setParameter("hist2DStyle", "colorMap");
-    	plotters.get(nPlotters).region(0).style().dataStyle().fillStyle().setParameter("colorMapScheme", "rainbow");
-        plotters.get(nPlotters).style().statisticsBoxStyle().setVisible(false);
-		nPlotters++;
-		*/
-		for (IPlotter plotter : plotters.values()) { 
-			plotter.show();
-		}
-	}
-	
-	@SuppressWarnings({ "unchecked", "rawtypes" })
+        plotters.get(nPlotters).region(0).style().setParameter("hist2DStyle", "colorMap");
+        plotters.get(nPlotters).region(0).style().dataStyle().fillStyle().setParameter("colorMapScheme", "rainbow");
+        plotters.get(nPlotters).style().statisticsBoxStyle().setVisible(false);
+        nPlotters++;
+        */
+        for (IPlotter plotter : plotters.values()) { 
+            plotter.show();
+        }
+    }
+    
+    @SuppressWarnings({ "unchecked", "rawtypes" })
     public void process(EventHeader event){
-		nevents++;
-
-		// Get the run number from the event
+        nevents++;
+
+        // Get the run number from the event
         if (runNumber == -1) runNumber = event.getRunNumber();
-		
+        
         // If the event doesn't have any tracks, skip it    
-		if(!event.hasCollection(Track.class, trackCollectionName)) return;
-    	
+        if(!event.hasCollection(Track.class, trackCollectionName)) return;
+        
         // Get the collection of tracks from the event
         List<Track> tracks = event.get(Track.class, trackCollectionName);
         
@@ -386,17 +386,17 @@
         trackPlots.get("Number of tracks").fill(tracks.size());
         
         // Loop over all of the tracks in the event
-    	for(Track track : tracks){
-    	    
-    	    if (TrackUtils.getR(track) < 0 && electronCut) continue;
-    	    
-    	    if (TrackUtils.getR(track) > 0 && positronCut) continue;
-    	    
-    	    if (d0Cut != -9999 && Math.abs(TrackUtils.getDoca(track)) < d0Cut) continue;
-    	    
-    	    trackPlots.get("Track charge").fill(TrackUtils.getR(track), 1);
-    
-    	    // Fill the track parameter plots
+        for(Track track : tracks){
+            
+            if (TrackUtils.getR(track) < 0 && electronCut) continue;
+            
+            if (TrackUtils.getR(track) > 0 && positronCut) continue;
+            
+            if (d0Cut != -9999 && Math.abs(TrackUtils.getDoca(track)) < d0Cut) continue;
+            
+            trackPlots.get("Track charge").fill(TrackUtils.getR(track), 1);
+    
+            // Fill the track parameter plots
             trackPlots.get("doca").fill(TrackUtils.getDoca(track));
             trackPlots.get("z0").fill(TrackUtils.getZ0(track));
             trackPlots.get("sin(phi0)").fill(TrackUtils.getPhi0(track));
@@ -444,8 +444,8 @@
             }
         }
     }
-	
-	public void endOfData() { 
+    
+    public void endOfData() { 
         
         String rootFile = "run" + runNumber + "_track_analysis.root";
         RootFileStore store = new RootFileStore(rootFile);
@@ -473,7 +473,7 @@
             fittedRawTrackerHitMap.put(FittedRawTrackerHit.getRawTrackerHit(fittedHit), fittedHit);
         }
     }
-	
+    
     /**
      * 
      * @param rawHit
@@ -489,101 +489,101 @@
 
             /*
             ntracks++;
-    		Hep3Vector positionEcal = TrackUtils.getTrackPositionAtEcal(track);
-    		System.out.println("Position at Ecal: " + positionEcal);
-    		Hep3Vector positionConverter = TrackUtils.extrapolateTrack(track,-700);
-    	
-    		aida.histogram2D("Track Position at Ecal").fill(positionEcal.y(), positionEcal.z());
-    		aida.histogram2D("Track Position at Harp").fill(positionConverter.y(), positionConverter.z());
-
-    		if(positionEcal.z() > 0 ) ntracksTop++;
-    		else if(positionEcal.z() < 0) ntracksBottom++;
+            Hep3Vector positionEcal = TrackUtils.getTrackPositionAtEcal(track);
+            System.out.println("Position at Ecal: " + positionEcal);
+            Hep3Vector positionConverter = TrackUtils.extrapolateTrack(track,-700);
+        
+            aida.histogram2D("Track Position at Ecal").fill(positionEcal.y(), positionEcal.z());
+            aida.histogram2D("Track Position at Harp").fill(positionConverter.y(), positionConverter.z());
+
+            if(positionEcal.z() > 0 ) ntracksTop++;
+            else if(positionEcal.z() < 0) ntracksBottom++;
             */
-    		
-    	
+            
+        
             /*    
-    		aida.histogram1D("Px").fill(track.getTrackStates().get(0).getMomentum()[0]);
-    		aida.histogram1D("Py").fill(track.getTrackStates().get(0).getMomentum()[1]);
-    		aida.histogram1D("Pz").fill(track.getTrackStates().get(0).getMomentum()[2]);
-    		aida.histogram1D("ChiSquared").fill(track.getChi2());
-    		
-    		if(Math.signum(TrackUtils.getR(track)) < 0){
-    			aida.histogram2D("Track Position at Ecal: curvature < 0").fill(positionEcal.y(), positionEcal.z());
-    			aida.histogram2D("Track Position at Harp: curvature < 0").fill(positionConverter.y(), positionConverter.z());
-        		aida.histogram1D("Px: C < 0").fill(track.getTrackStates().get(0).getMomentum()[0]);
-        		aida.histogram1D("Py: C < 0").fill(track.getTrackStates().get(0).getMomentum()[1]);
-        		aida.histogram1D("Pz: C < 0").fill(track.getTrackStates().get(0).getMomentum()[2]);
-        		nnegative++;
-    		} else if(Math.signum(TrackUtils.getR(track)) > 0){
-    			aida.histogram2D("Track Position at Ecal: curvature > 0").fill(positionEcal.y(), positionEcal.z());
-    			aida.histogram2D("Track Position at Harp: curvature > 0").fill(positionConverter.y(), positionConverter.z());
-        		aida.histogram1D("Px: C > 0").fill(track.getTrackStates().get(0).getMomentum()[0]);
-        		aida.histogram1D("Px: C > 0").fill(track.getTrackStates().get(0).getMomentum()[1]);
-        		aida.histogram1D("Px: C > 0").fill(track.getTrackStates().get(0).getMomentum()[2]);
-        		npositive++;
-    		}
-    		
-    		if(tracks.size() > 1){
-    			aida.histogram2D("Track Position at Ecal: Two Tracks").fill(positionEcal.y(), positionEcal.z());
-    			aida.histogram2D("Track Position at Harp: Two Tracks").fill(positionConverter.y(), positionConverter.z()); 
-    			aida.histogram1D("Px: Two Tracks").fill(track.getTrackStates().get(0).getMomentum()[0]);
-    			if(tracks.size() == 2) nTwoTracks++;
-    		}
-    		
-    		trackToEcalPosition.put(positionEcal, track);
-    		ecalPos.add(positionEcal);  		
-    	}
-    	
-    	if(!event.hasCollection(Cluster.class, "EcalClusters")) return;
-    	List<Cluster> clusters = event.get(Cluster.class, "EcalClusters");
-    	
-
-    	for(Hep3Vector ecalP : ecalPos){
-        	double xdiff = 1000; 
-        	double ydiff = 1000;
-    		for(Cluster cluster : clusters){
-    			double xd = ecalP.y() - cluster.getPosition()[0];
-    			double yd = ecalP.z() - cluster.getPosition()[1];  
-    			if(yd < ydiff){
-    				xdiff = xd;
-    				ydiff = yd;
-    				trackToCluster.put(trackToEcalPosition.get(ecalP),cluster);
-    			}
-    		}
-    		clusters.remove(trackToCluster.get(trackToEcalPosition.get(ecalP)));
-    		aida.histogram2D("XY Difference between Ecal Cluster and Track Position").fill(xdiff, ydiff);
-    	}
-    	
-    	for(Map.Entry<Track, Cluster> entry : trackToCluster.entrySet()){
-    		double Energy = entry.getValue().getEnergy();
-    		Track track = entry.getKey();
-    		double pTotal = Math.sqrt(track.getTrackStates().get(0).getMomentum()[0]*track.getTrackStates().get(0).getMomentum()[0] + track.getTrackStates().get(0).getMomentum()[1]*track.getTrackStates().get(0).getMomentum()[1] + track.getTrackStates().get(0).getMomentum()[2]*track.getTrackStates().get(0).getMomentum()[2]);
-    		
-    		double ep = Energy/(pTotal*1000);
-    		
-    		System.out.println("Energy: " + Energy + "P: " + pTotal + " E over P: " + ep);
-    		
-    		aida.histogram1D("E over P").fill(ep);
-    		aida.histogram2D("E versus P").fill(Energy, pTotal*1000);
-    	}
-    	
-    	for(Cluster cluster : clusters){
-    		double[] clusterPosition = cluster.getPosition();
-    		
-    		System.out.println("Cluster Position: [" + clusterPosition[0] + ", " + clusterPosition[1] + ", " + clusterPosition[2]+ "]");
-    	}
-    	
-    	double ratio = nnegative/npositive;
-    	System.out.println("Ratio of Negative to Position Tracks: " + ratio);
-	
-    	double tracksRatio = ntracks/nevents;
-    	double tracksTopRatio = ntracksTop/nevents;
-    	double tracksBottomRatio = ntracksBottom/nevents;
-    	double twoTrackRatio = nTwoTracks/nevents;
-    	System.out.println("Number of tracks per event: " + tracksRatio);
-    	System.out.println("Number of top tracks per event: " + tracksTopRatio);
-    	System.out.println("Number of bottom tracks per event: " + tracksBottomRatio);
-    	System.out.println("Number of two track events: " + twoTrackRatio);
-	}*/
-
-
+            aida.histogram1D("Px").fill(track.getTrackStates().get(0).getMomentum()[0]);
+            aida.histogram1D("Py").fill(track.getTrackStates().get(0).getMomentum()[1]);
+            aida.histogram1D("Pz").fill(track.getTrackStates().get(0).getMomentum()[2]);
+            aida.histogram1D("ChiSquared").fill(track.getChi2());
+            
+            if(Math.signum(TrackUtils.getR(track)) < 0){
+                aida.histogram2D("Track Position at Ecal: curvature < 0").fill(positionEcal.y(), positionEcal.z());
+                aida.histogram2D("Track Position at Harp: curvature < 0").fill(positionConverter.y(), positionConverter.z());
+                aida.histogram1D("Px: C < 0").fill(track.getTrackStates().get(0).getMomentum()[0]);
+                aida.histogram1D("Py: C < 0").fill(track.getTrackStates().get(0).getMomentum()[1]);
+                aida.histogram1D("Pz: C < 0").fill(track.getTrackStates().get(0).getMomentum()[2]);
+                nnegative++;
+            } else if(Math.signum(TrackUtils.getR(track)) > 0){
+                aida.histogram2D("Track Position at Ecal: curvature > 0").fill(positionEcal.y(), positionEcal.z());
+                aida.histogram2D("Track Position at Harp: curvature > 0").fill(positionConverter.y(), positionConverter.z());
+                aida.histogram1D("Px: C > 0").fill(track.getTrackStates().get(0).getMomentum()[0]);
+                aida.histogram1D("Px: C > 0").fill(track.getTrackStates().get(0).getMomentum()[1]);
+                aida.histogram1D("Px: C > 0").fill(track.getTrackStates().get(0).getMomentum()[2]);
+                npositive++;
+            }
+            
+            if(tracks.size() > 1){
+                aida.histogram2D("Track Position at Ecal: Two Tracks").fill(positionEcal.y(), positionEcal.z());
+                aida.histogram2D("Track Position at Harp: Two Tracks").fill(positionConverter.y(), positionConverter.z()); 
+                aida.histogram1D("Px: Two Tracks").fill(track.getTrackStates().get(0).getMomentum()[0]);
+                if(tracks.size() == 2) nTwoTracks++;
+            }
+            
+            trackToEcalPosition.put(positionEcal, track);
+            ecalPos.add(positionEcal);          
+        }
+        
+        if(!event.hasCollection(Cluster.class, "EcalClusters")) return;
+        List<Cluster> clusters = event.get(Cluster.class, "EcalClusters");
+        
+
+        for(Hep3Vector ecalP : ecalPos){
+            double xdiff = 1000; 
+            double ydiff = 1000;
+            for(Cluster cluster : clusters){
+                double xd = ecalP.y() - cluster.getPosition()[0];
+                double yd = ecalP.z() - cluster.getPosition()[1];  
+                if(yd < ydiff){
+                    xdiff = xd;
+                    ydiff = yd;
+                    trackToCluster.put(trackToEcalPosition.get(ecalP),cluster);
+                }
+            }
+            clusters.remove(trackToCluster.get(trackToEcalPosition.get(ecalP)));
+            aida.histogram2D("XY Difference between Ecal Cluster and Track Position").fill(xdiff, ydiff);
+        }
+        
+        for(Map.Entry<Track, Cluster> entry : trackToCluster.entrySet()){
+            double Energy = entry.getValue().getEnergy();
+            Track track = entry.getKey();
+            double pTotal = Math.sqrt(track.getTrackStates().get(0).getMomentum()[0]*track.getTrackStates().get(0).getMomentum()[0] + track.getTrackStates().get(0).getMomentum()[1]*track.getTrackStates().get(0).getMomentum()[1] + track.getTrackStates().get(0).getMomentum()[2]*track.getTrackStates().get(0).getMomentum()[2]);
+            
+            double ep = Energy/(pTotal*1000);
+            
+            System.out.println("Energy: " + Energy + "P: " + pTotal + " E over P: " + ep);
+            
+            aida.histogram1D("E over P").fill(ep);
+            aida.histogram2D("E versus P").fill(Energy, pTotal*1000);
+        }
+        
+        for(Cluster cluster : clusters){
+            double[] clusterPosition = cluster.getPosition();
+            
+            System.out.println("Cluster Position: [" + clusterPosition[0] + ", " + clusterPosition[1] + ", " + clusterPosition[2]+ "]");
+        }
+        
+        double ratio = nnegative/npositive;
+        System.out.println("Ratio of Negative to Position Tracks: " + ratio);
+    
+        double tracksRatio = ntracks/nevents;
+        double tracksTopRatio = ntracksTop/nevents;
+        double tracksBottomRatio = ntracksBottom/nevents;
+        double twoTrackRatio = nTwoTracks/nevents;
+        System.out.println("Number of tracks per event: " + tracksRatio);
+        System.out.println("Number of top tracks per event: " + tracksTopRatio);
+        System.out.println("Number of bottom tracks per event: " + tracksBottomRatio);
+        System.out.println("Number of two track events: " + twoTrackRatio);
+    }*/
+
+

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/omoreno/SvtTrackRecoEfficiency.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/omoreno/SvtTrackRecoEfficiency.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/omoreno/SvtTrackRecoEfficiency.java	Wed Apr 27 11:11:32 2016
@@ -100,7 +100,7 @@
      * Set the name of the file to output efficiency data to
      */
     public void setEfficiencyOutputFile(String efficiencyOutputFile){
-    	this.efficiencyOutputFile = efficiencyOutputFile;
+        this.efficiencyOutputFile = efficiencyOutputFile;
     }
 
     /**
@@ -124,31 +124,31 @@
      * @param message : debug message
      */
     private void printDebug(String message){
-    	if(debug){
-    		System.out.println(this.getClass().getSimpleName() + ": " + message);
-    	}
+        if(debug){
+            System.out.println(this.getClass().getSimpleName() + ": " + message);
+        }
     }
     
     /**
      * 
      */
     protected void detectorChanged(Detector detector){
-    	super.detectorChanged(detector);
-    	
-    	sensors = detector.getSubdetector("Tracker").getDetectorElement().findDescendants(HpsSiSensor.class);
-    	
+        super.detectorChanged(detector);
+        
+        sensors = detector.getSubdetector("Tracker").getDetectorElement().findDescendants(HpsSiSensor.class);
+        
         // setup AIDA
         aida = AIDA.defaultInstance();
         aida.tree().cd("/");
         
         // Open the output file stream
         if(efficiencyOutputFile != null && momentumOutputFile != null){
-        	try{
-        		efficiencyOutput = new BufferedWriter(new FileWriter(efficiencyOutputFile));
+            try{
+                efficiencyOutput = new BufferedWriter(new FileWriter(efficiencyOutputFile));
                 momentumOutput = new BufferedWriter(new FileWriter(momentumOutputFile));
-        	} catch(Exception e){
-        		System.out.println(this.getClass().getSimpleName() + ": Error! " + e.getMessage());
-        	}
+            } catch(Exception e){
+                System.out.println(this.getClass().getSimpleName() + ": Error! " + e.getMessage());
+            }
         }
         
         // Get the total number of SVT layers
@@ -164,28 +164,28 @@
         }
 
         if(trackingEfficiencyPlots){
-        	plotters.add(PlotUtils.setupPlotter("Track Momentum", 0, 0));
-        	histo1D.add(aida.histogram1D("Momentum - Reconstructed Tracks", 14, 0, 5.6));
-        	PlotUtils.setup1DRegion(plotters.get(plotterIndex), "Reconstructed Tracks", 0, "Momentum [GeV]", histo1D.get(histo1DIndex));
+            plotters.add(PlotUtils.setupPlotter("Track Momentum", 0, 0));
+            histo1D.add(aida.histogram1D("Momentum - Reconstructed Tracks", 14, 0, 5.6));
+            PlotUtils.setup1DRegion(plotters.get(plotterIndex), "Reconstructed Tracks", 0, "Momentum [GeV]", histo1D.get(histo1DIndex));
             histo1DIndex++;            
             histo1D.add(aida.histogram1D("Momentum - Findable Tracks", 14, 0, 5.6));
-        	PlotUtils.setup1DRegion(plotters.get(plotterIndex), "Findable Tracks", 0, "Momentum [GeV]", histo1D.get(histo1DIndex));
-        	plotterIndex++;
-        	histo1DIndex++;
+            PlotUtils.setup1DRegion(plotters.get(plotterIndex), "Findable Tracks", 0, "Momentum [GeV]", histo1D.get(histo1DIndex));
+            plotterIndex++;
+            histo1DIndex++;
         }
         
         for(IPlotter plotter : plotters){
-        	plotter.show();
+            plotter.show();
         }
     }
     
     private String samplesToString(short[] samples){
-    	String sampleList = "[ ";
-    	for(short sample : samples){
-    		sampleList += Short.toString(sample) + ", ";
-    	}
-    	sampleList += "]";
-    	return sampleList;
+        String sampleList = "[ ";
+        for(short sample : samples){
+            sampleList += Short.toString(sample) + ", ";
+        }
+        sampleList += "]";
+        return sampleList;
     }
 
     /**
@@ -196,7 +196,7 @@
     @Override
     protected void process(EventHeader event){
         
-    	// For now, only look at events with a single track
+        // For now, only look at events with a single track
         if(event.get(Track.class, trackCollectionName).size() > 1) return;
         eventNumber++;
 
@@ -204,46 +204,46 @@
         if(!event.hasCollection(SimTrackerHit.class, simTrackerHitCollectionName)) return;
         List<SimTrackerHit> simTrackerHits = event.get(SimTrackerHit.class, simTrackerHitCollectionName);
         this.printDebug("\nEvent " + eventNumber + " contains " + simTrackerHits.size() + " SimTrackerHits");
-    	// Loop through all SimTrackerHits and confirm that a corresponding RawTrackerHit was created
-    	for(SimTrackerHit simTrackHit : simTrackerHits){
-    		
-    		this.printDebug("SimTrackerHit Layer Number: " + simTrackHit.getLayerNumber());
-    	}
+        // Loop through all SimTrackerHits and confirm that a corresponding RawTrackerHit was created
+        for(SimTrackerHit simTrackHit : simTrackerHits){
+            
+            this.printDebug("SimTrackerHit Layer Number: " + simTrackHit.getLayerNumber());
+        }
 
         // Get the list of RawTrackerHits and add them to the sensor readout
         List<RawTrackerHit> rawHits = event.get(RawTrackerHit.class, rawTrackerHitCollectionName);
         String volume; 
         for(RawTrackerHit rawHit : rawHits){
-        	HpsSiSensor sensor = (HpsSiSensor) rawHit.getDetectorElement();
-        	if(sensor.isTopLayer()){
-        		volume = "Top Volume ";
-        	} else { 
-        		volume = "Bottom Volume ";
-        	}
-    		this.printDebug(volume + "RawTrackerHit Channel #: " + rawHit.getIdentifierFieldValue("strip") + " Layer Number: " + rawHit.getLayerNumber()
-    				+ " Samples: " + samplesToString(rawHit.getADCValues()));
+            HpsSiSensor sensor = (HpsSiSensor) rawHit.getDetectorElement();
+            if(sensor.isTopLayer()){
+                volume = "Top Volume ";
+            } else { 
+                volume = "Bottom Volume ";
+            }
+            this.printDebug(volume + "RawTrackerHit Channel #: " + rawHit.getIdentifierFieldValue("strip") + " Layer Number: " + rawHit.getLayerNumber()
+                    + " Samples: " + samplesToString(rawHit.getADCValues()));
             ((HpsSiSensor) rawHit.getDetectorElement()).getReadout().addHit(rawHit);
         }
         
         if(event.hasCollection(SiTrackerHit.class, siTrackerHitCollectionName)){
-        	List<SiTrackerHit> hitlist = event.get(SiTrackerHit.class, siTrackerHitCollectionName);
-        	for(SiTrackerHit siTrackerHit : hitlist){
-    			this.printDebug("Cluster is comprised by the following raw hits:");
-        		for(RawTrackerHit rawHit : siTrackerHit.getRawHits()){
-            		this.printDebug("RawTrackerHit Channel #: " + rawHit.getIdentifierFieldValue("strip") + " Layer Number: " + rawHit.getLayerNumber());
-        		}
-        	}
+            List<SiTrackerHit> hitlist = event.get(SiTrackerHit.class, siTrackerHitCollectionName);
+            for(SiTrackerHit siTrackerHit : hitlist){
+                this.printDebug("Cluster is comprised by the following raw hits:");
+                for(RawTrackerHit rawHit : siTrackerHit.getRawHits()){
+                    this.printDebug("RawTrackerHit Channel #: " + rawHit.getIdentifierFieldValue("strip") + " Layer Number: " + rawHit.getLayerNumber());
+                }
+            }
         }
         
         // Get the MC Particles associated with the SimTrackerHits
         List<MCParticle> mcParticles = event.getMCParticles();
         if(debug){
-        	String particleList = "[ ";
-        	for(MCParticle mcParticle : mcParticles){
-        		particleList += mcParticle.getPDGID() + ", ";
-        	}
-        	particleList += "]";
-        	this.printDebug("MC Particles: " + particleList);
+            String particleList = "[ ";
+            for(MCParticle mcParticle : mcParticles){
+                particleList += mcParticle.getPDGID() + ", ";
+            }
+            particleList += "]";
+            this.printDebug("MC Particles: " + particleList);
         }
         
         // Get the magnetic field
@@ -264,10 +264,10 @@
                 Set<SimTrackerHit> trackerHits = findable.getSimTrackerHits(mcParticle);
                 if(this.isSameSvtVolume(trackerHits)){
                     if(debug){
-                    	this.printDebug("Track is findable");
-                    	this.printDebug("MC particle momentum: " + mcParticle.getMomentum().toString());
-                    }
-                    	
+                        this.printDebug("Track is findable");
+                        this.printDebug("MC particle momentum: " + mcParticle.getMomentum().toString());
+                    }
+                        
                     findableTracks++;
                     trackIsFindable = true;      
                 }
@@ -303,8 +303,8 @@
         
         if(!mcParticles.isEmpty() && trackingEfficiencyPlots){
             // If the list still contains MC Particles, a matching track wasn't found
-        	this.printDebug("No matching track found");
-        	
+            this.printDebug("No matching track found");
+            
             // Check that all stereoHits were correctly assigned to an MCParticle
             for(MCParticle mcParticle : mcParticles){
                 
@@ -326,7 +326,7 @@
                 
                 // Determine if the MC particle passed through the top or bottom SVT volume
                 for(SimTrackerHit simHit : simHits){
-                	HpsSiSensor sensor = (HpsSiSensor) simHit.getDetectorElement();
+                    HpsSiSensor sensor = (HpsSiSensor) simHit.getDetectorElement();
                     if(sensor.isTopLayer()){
                         this.printDebug("MC Particle passed through the top layer");
                         isTopTrack = true;
@@ -376,7 +376,7 @@
     {
         int volumeIndex = 0;
         for(SimTrackerHit simTrackerHit : simTrackerHits){
-        	HpsSiSensor sensor = (HpsSiSensor) simTrackerHit.getDetectorElement();
+            HpsSiSensor sensor = (HpsSiSensor) simTrackerHit.getDetectorElement();
             if(sensor.isTopLayer()) volumeIndex++;
             else volumeIndex--;
         }
@@ -454,24 +454,24 @@
    @Override
    public void endOfData()
    { 
-	   
+       
        if(trackingEfficiencyPlots && efficiencyOutputFile != null && momentumOutputFile != null){
-	   	   try{ 
-	   		   int bins = aida.histogram1D("Momentum - Findable Tracks").axis().bins();
-	   		   for(int index = 0; index < bins; index++){
-	   			   if(aida.histogram1D("Momentum - Reconstructed Tracks").binEntries(index) == 0) efficiencyOutput.write(index + " " + 0 + "\n");
-	   			   else	efficiencyOutput.write(index + " " + aida.histogram1D("Momentum - Reconstructed Tracks").binEntries(index) + "\n");
-	   			   
+           try{ 
+               int bins = aida.histogram1D("Momentum - Findable Tracks").axis().bins();
+               for(int index = 0; index < bins; index++){
+                   if(aida.histogram1D("Momentum - Reconstructed Tracks").binEntries(index) == 0) efficiencyOutput.write(index + " " + 0 + "\n");
+                   else efficiencyOutput.write(index + " " + aida.histogram1D("Momentum - Reconstructed Tracks").binEntries(index) + "\n");
+                   
                    if(aida.histogram1D("Momentum - Findable Tracks").binEntries(index) == 0) momentumOutput.write(index + " " + 0 + "\n");
-	   			   else momentumOutput.write(index + " " + aida.histogram1D("Momentum - Findable Tracks").binEntries(index) + "\n");
-	   		   }
-	   		   efficiencyOutput.close();
+                   else momentumOutput.write(index + " " + aida.histogram1D("Momentum - Findable Tracks").binEntries(index) + "\n");
+               }
+               efficiencyOutput.close();
                momentumOutput.close();
-	   	   } catch(IOException e){
-	   		   System.out.println(this.getClass().getSimpleName() + ": Error! " + e.getMessage());
-	   	   }
+           } catch(IOException e){
+               System.out.println(this.getClass().getSimpleName() + ": Error! " + e.getMessage());
+           }
        } 
-	   
+       
         System.out.println("%===============================================================%");
         System.out.println("%============== Track Reconstruction Efficiencies ==============%");
         System.out.println("%===============================================================%\n%");

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/omoreno/TestRunTrackReconEfficiency.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/omoreno/TestRunTrackReconEfficiency.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/omoreno/TestRunTrackReconEfficiency.java	Wed Apr 27 11:11:32 2016
@@ -60,18 +60,18 @@
     boolean topTrigger = false;
      
     // Collection Names
-    String stereoHitCollectionName 		= "HelicalTrackHits";
-    String trackCollectionName 			= "MatchedTracks";
-    String ecalClustersCollectionName 	= "EcalClusters";
-    String triggerDataCollectionName 	= "TriggerBank";
+    String stereoHitCollectionName      = "HelicalTrackHits";
+    String trackCollectionName          = "MatchedTracks";
+    String ecalClustersCollectionName   = "EcalClusters";
+    String triggerDataCollectionName    = "TriggerBank";
     
     // Plots
     IHistogram1D findableTrackMomentum; 
     IHistogram1D totalTrackMomentum; 
-	IHistogram1D xPositionResidual;
-	IHistogram1D yPositionResidual;
-	IHistogram1D zPositionResidual;
-	IHistogram1D r;
+    IHistogram1D xPositionResidual;
+    IHistogram1D yPositionResidual;
+    IHistogram1D zPositionResidual;
+    IHistogram1D r;
 
     /**
      * Dflt Ctor
@@ -89,7 +89,7 @@
      * 
      */
     public void setThresholdEnergy(double thresholdEnergy){
-    	this.thresholdEnergy = thresholdEnergy;
+        this.thresholdEnergy = thresholdEnergy;
     }
 
     public void setClusterEnergyDifference(double energyDifference){ 
@@ -117,15 +117,15 @@
         plotterIndex++;
 
         // Create plot for diffence in track and cluster position
-		plotters.add(PlotUtils.setupPlotter("Track-Cluster Position Residual", 2, 2));
-		xPositionResidual = aida.histogram1D("x Residual", 100, -100, 100);
-		yPositionResidual = aida.histogram1D("y Residual", 100, -100, 100);
-		zPositionResidual = aida.histogram1D("z Residual", 100, -100, 100);
-		r = aida.histogram1D("r", 100, -100, 100);
-		PlotUtils.setup1DRegion(plotters.get(plotterIndex), "x Residual", 0, "delta x [mm]", xPositionResidual);
-		PlotUtils.setup1DRegion(plotters.get(plotterIndex), "y Residual", 1, "delta y [mm]", yPositionResidual);
-		PlotUtils.setup1DRegion(plotters.get(plotterIndex), "z Residual", 2, "delta z [mm]", zPositionResidual);
-		PlotUtils.setup1DRegion(plotters.get(plotterIndex), "r", 3, "r [mm]", r);
+        plotters.add(PlotUtils.setupPlotter("Track-Cluster Position Residual", 2, 2));
+        xPositionResidual = aida.histogram1D("x Residual", 100, -100, 100);
+        yPositionResidual = aida.histogram1D("y Residual", 100, -100, 100);
+        zPositionResidual = aida.histogram1D("z Residual", 100, -100, 100);
+        r = aida.histogram1D("r", 100, -100, 100);
+        PlotUtils.setup1DRegion(plotters.get(plotterIndex), "x Residual", 0, "delta x [mm]", xPositionResidual);
+        PlotUtils.setup1DRegion(plotters.get(plotterIndex), "y Residual", 1, "delta y [mm]", yPositionResidual);
+        PlotUtils.setup1DRegion(plotters.get(plotterIndex), "z Residual", 2, "delta z [mm]", zPositionResidual);
+        PlotUtils.setup1DRegion(plotters.get(plotterIndex), "r", 3, "r [mm]", r);
         plotterIndex++; 
 
         // Show all of the plotters
@@ -154,138 +154,138 @@
         // If the event has a single Ecal cluster satisfying the threshold cut, 
         // check if there is a track that is well matched to the cluster
         if(ecalClusters.size() == 1){
-        	Cluster ecalCluster = ecalClusters.get(0);
-        	
-        	// If the cluster is above the energy threshold, then the track should
-        	// be findable
-        	if(!isClusterAboveEnergyThreshold(ecalCluster)) return;
-        	findableSingleTracks++;
-        	
-        	double[] clusterPosition = ecalCluster.getPosition();
-        	
-        	if(clusterPosition[0] > 0 && clusterPosition[1] > 0) 	   findableSingleTracksQuad1++;
-        	else if(clusterPosition[0] < 0 && clusterPosition[1] > 0) findableSingleTracksQuad2++;
-        	else if(clusterPosition[0] < 0 && clusterPosition[1] < 0) findableSingleTracksQuad3++;
-        	else if(clusterPosition[0] > 0 && clusterPosition[1] < 0) findableSingleTracksQuad4++;	
-        	
-        	if(!isClusterMatchedToTrack(ecalCluster, tracks)) return;
-        	foundSingleTracks++;
-
-        	if(clusterPosition[0] > 0 && clusterPosition[1] > 0) 	   foundSingleTracksQuad1++;
-        	else if(clusterPosition[0] < 0 && clusterPosition[1] > 0) foundSingleTracksQuad2++;
-        	else if(clusterPosition[0] < 0 && clusterPosition[1] < 0) foundSingleTracksQuad3++;
-        	else if(clusterPosition[0] > 0 && clusterPosition[1] < 0) foundSingleTracksQuad4++;	
+            Cluster ecalCluster = ecalClusters.get(0);
+            
+            // If the cluster is above the energy threshold, then the track should
+            // be findable
+            if(!isClusterAboveEnergyThreshold(ecalCluster)) return;
+            findableSingleTracks++;
+            
+            double[] clusterPosition = ecalCluster.getPosition();
+            
+            if(clusterPosition[0] > 0 && clusterPosition[1] > 0)       findableSingleTracksQuad1++;
+            else if(clusterPosition[0] < 0 && clusterPosition[1] > 0) findableSingleTracksQuad2++;
+            else if(clusterPosition[0] < 0 && clusterPosition[1] < 0) findableSingleTracksQuad3++;
+            else if(clusterPosition[0] > 0 && clusterPosition[1] < 0) findableSingleTracksQuad4++;  
+            
+            if(!isClusterMatchedToTrack(ecalCluster, tracks)) return;
+            foundSingleTracks++;
+
+            if(clusterPosition[0] > 0 && clusterPosition[1] > 0)       foundSingleTracksQuad1++;
+            else if(clusterPosition[0] < 0 && clusterPosition[1] > 0) foundSingleTracksQuad2++;
+            else if(clusterPosition[0] < 0 && clusterPosition[1] < 0) foundSingleTracksQuad3++;
+            else if(clusterPosition[0] > 0 && clusterPosition[1] < 0) foundSingleTracksQuad4++; 
         }
         
         // Only look at events which have two Ecal cluster 
         if(ecalClusters.size() != 2) return;
 
         // Check that the Ecal clusters are in opposite Ecal volumes. If 
-       	// they don't, skip the event.
-       	if(!hasClustersInOppositeVolumes(ecalClusters)){
-       		this.printDebug("Ecal clusters are not in opposite volumes");
-       		return;
-       	}
-       	nOppositeVolume++;
+        // they don't, skip the event.
+        if(!hasClustersInOppositeVolumes(ecalClusters)){
+            this.printDebug("Ecal clusters are not in opposite volumes");
+            return;
+        }
+        nOppositeVolume++;
       
-       	// Check that the Ecal clusters lie within some pre-defined window. If
-       	// they don't, skip the event. 
+        // Check that the Ecal clusters lie within some pre-defined window. If
+        // they don't, skip the event. 
         if(!isClusterWithinWindow(ecalClusters.get(0)) || !isClusterWithinWindow(ecalClusters.get(1))){
-        		this.printDebug("Ecal cluster falls outside of window.");
-        		return;        	
+                this.printDebug("Ecal cluster falls outside of window.");
+                return;         
         }
         nWithinWindow++;
        
         // Check that the Ecal clusters are above the threshold energy.  If 
         // they don't, skip the event.
         if(!isClusterAboveEnergyThreshold(ecalClusters.get(0)) || !isClusterAboveEnergyThreshold(ecalClusters.get(1))){
-        		this.printDebug("Ecal cluster energies are below threshold.");
-        		return;        	        	
-        }
-       	nAboveThreshold++;
+                this.printDebug("Ecal cluster energies are below threshold.");
+                return;                     
+        }
+        nAboveThreshold++;
  
-       	// Check that the difference between the Ecal cluster energies is 
+        // Check that the difference between the Ecal cluster energies is 
         // reasonable
-       	double energyDiff = Math.abs(ecalClusters.get(0).getEnergy() - ecalClusters.get(1).getEnergy()); 
-       	if(energyDiff > energyDifference){
-       		this.printDebug("The energy difference between the two clusters is too great.");
-       		return;
-       	}
+        double energyDiff = Math.abs(ecalClusters.get(0).getEnergy() - ecalClusters.get(1).getEnergy()); 
+        if(energyDiff > energyDifference){
+            this.printDebug("The energy difference between the two clusters is too great.");
+            return;
+        }
        
         // Check if the event contains a collection of tracks.  If it doesn't,
         // move on to the next event.
         if(!event.hasCollection(Track.class, trackCollectionName)){
-        	this.printDebug("Event doesn't contain a collection of tracks!");
-        	return;
+            this.printDebug("Event doesn't contain a collection of tracks!");
+            return;
         }
 
 
         // If there are no tracks in the collection, move on to the next event. 
         if(tracks.isEmpty()){
-        	this.printDebug("Event doesn't contain any tracks!");
-        	return;  
+            this.printDebug("Event doesn't contain any tracks!");
+            return;  
         }
        
         // Sort the tracks by SVT volume
-    	topTracks = new ArrayList<Track>();
-    	botTracks = new ArrayList<Track>();
+        topTracks = new ArrayList<Track>();
+        botTracks = new ArrayList<Track>();
         for(Track track : tracks){
-    		if(track.getTrackStates().get(0).getZ0() > 0)  topTracks.add(track);
-    		else if(track.getTrackStates().get(0).getZ0() < 0) botTracks.add(track);
-    	}
-        
-       	// Get the trigger information from the event
-       	List<GenericObject> triggerData = event.get(GenericObject.class, triggerDataCollectionName);
-       	GenericObject triggerDatum = triggerData.get(0);
-       	if(triggerDatum.getIntVal(4) > 0){
-       		this.printDebug("Ecal triggered by top cluster");
-       		topTrigger = true;
-       	} else if(triggerDatum.getIntVal(5) > 0){
-       		this.printDebug("Ecal triggered by bottom cluster");       		
-       		topTrigger = false;
-       	}
-       	
-       	// Match a track to the trigger cluster
-       	Cluster matchedCluster = null; 
-       	for(Cluster ecalCluster : ecalClusters){
-       		if(ecalCluster.getPosition()[1] > 0 && topTrigger){
-       			if(!isClusterMatchedToTrack(ecalCluster, topTracks)){
-       				this.printDebug("Trigger cluster-track match was not found.");
-       				return;
-       			}
-       			matchedCluster = ecalCluster; 
-       			findableBottomTracks++;
-       			break;
-       		} else if( ecalCluster.getPosition()[1] < 0 && !topTrigger){
-       			if(!isClusterMatchedToTrack(ecalCluster, botTracks)){
-       				this.printDebug("Trigger cluster-track match was not found.");
-       				return;
-       			}
-       			matchedCluster = ecalCluster;
-       			findableTopTracks++;
-       			break;
-       		}
-       	}
-       	if(matchedCluster != null) ecalClusters.remove(matchedCluster);
-       	nTrigClusterTrackMatch++;
-       	
+            if(track.getTrackStates().get(0).getZ0() > 0)  topTracks.add(track);
+            else if(track.getTrackStates().get(0).getZ0() < 0) botTracks.add(track);
+        }
+        
+        // Get the trigger information from the event
+        List<GenericObject> triggerData = event.get(GenericObject.class, triggerDataCollectionName);
+        GenericObject triggerDatum = triggerData.get(0);
+        if(triggerDatum.getIntVal(4) > 0){
+            this.printDebug("Ecal triggered by top cluster");
+            topTrigger = true;
+        } else if(triggerDatum.getIntVal(5) > 0){
+            this.printDebug("Ecal triggered by bottom cluster");            
+            topTrigger = false;
+        }
+        
+        // Match a track to the trigger cluster
+        Cluster matchedCluster = null; 
+        for(Cluster ecalCluster : ecalClusters){
+            if(ecalCluster.getPosition()[1] > 0 && topTrigger){
+                if(!isClusterMatchedToTrack(ecalCluster, topTracks)){
+                    this.printDebug("Trigger cluster-track match was not found.");
+                    return;
+                }
+                matchedCluster = ecalCluster; 
+                findableBottomTracks++;
+                break;
+            } else if( ecalCluster.getPosition()[1] < 0 && !topTrigger){
+                if(!isClusterMatchedToTrack(ecalCluster, botTracks)){
+                    this.printDebug("Trigger cluster-track match was not found.");
+                    return;
+                }
+                matchedCluster = ecalCluster;
+                findableTopTracks++;
+                break;
+            }
+        }
+        if(matchedCluster != null) ecalClusters.remove(matchedCluster);
+        nTrigClusterTrackMatch++;
+        
         // If the cluster passes all requirements, then there is likely a track
         // associated with it
         findableTracks++;
         
         // Now check if a track is associated with the non-trigger cluster
         if(topTrigger){
-       			if(!isClusterMatchedToTrack(ecalClusters.get(0), botTracks)){
-       				this.printDebug("Non trigger cluster-track match was not found.");
-       				return;
-       			}
-       			totalBottomTracks++;
+                if(!isClusterMatchedToTrack(ecalClusters.get(0), botTracks)){
+                    this.printDebug("Non trigger cluster-track match was not found.");
+                    return;
+                }
+                totalBottomTracks++;
         } else if(!topTrigger){
-       			if(!isClusterMatchedToTrack(ecalClusters.get(0), topTracks)){
-       				this.printDebug("Non trigger cluster-track match was not found.");
-       				return;
-       			}        	       
-       			totalTopTracks++;
+                if(!isClusterMatchedToTrack(ecalClusters.get(0), topTracks)){
+                    this.printDebug("Non trigger cluster-track match was not found.");
+                    return;
+                }                  
+                totalTopTracks++;
         } 
         ++totalTracks; 
     }    
@@ -305,67 +305,67 @@
      * 
      */
     private boolean isClusterWithinWindow(Cluster clusterPosition){
-    	return true;
+        return true;
     }
     
     /**
      * 
      */
     private boolean isClusterAboveEnergyThreshold(Cluster ecalCluster){
-    	if(ecalCluster.getEnergy() > thresholdEnergy) return true;
-    	return false;
+        if(ecalCluster.getEnergy() > thresholdEnergy) return true;
+        return false;
     }
      
     /**
      * 
      */
     private boolean hasClustersInOppositeVolumes(List<Cluster> ecalClusters){
-    	this.printPosition(ecalClusters.get(0).getPosition());
-    	this.printPosition(ecalClusters.get(1).getPosition());
-    	if((ecalClusters.get(0).getPosition()[1] > 0 && ecalClusters.get(1).getPosition()[1] < 0)
-    			|| (ecalClusters.get(0).getPosition()[1] < 0 && ecalClusters.get(1).getPosition()[1] > 0)){
-    		return true; 	
-    	}
-    	return false;
+        this.printPosition(ecalClusters.get(0).getPosition());
+        this.printPosition(ecalClusters.get(1).getPosition());
+        if((ecalClusters.get(0).getPosition()[1] > 0 && ecalClusters.get(1).getPosition()[1] < 0)
+                || (ecalClusters.get(0).getPosition()[1] < 0 && ecalClusters.get(1).getPosition()[1] > 0)){
+            return true;    
+        }
+        return false;
     }
     
     /**
      * 
      */
     private boolean isClusterMatchedToTrack(Cluster cluster, List<Track> tracks){
-    	Hep3Vector clusterPos = new BasicHep3Vector(cluster.getPosition());
-    	double rMax = Double.MAX_VALUE;
-    	Track matchedTrack = null; 
-    	for(Track track : tracks){
-    		
-    		Hep3Vector trkPosAtShowerMax = TrackUtils.extrapolateTrack(track,clusterPos.z());
-    		if(Double.isNaN(trkPosAtShowerMax.x()) || Double.isNaN(trkPosAtShowerMax.y())){
-    			this.printDebug("Invalid track position");
-    			return false; 
-    		}
-    		this.printDebug("Track position at shower max: " + trkPosAtShowerMax.toString());
+        Hep3Vector clusterPos = new BasicHep3Vector(cluster.getPosition());
+        double rMax = Double.MAX_VALUE;
+        Track matchedTrack = null; 
+        for(Track track : tracks){
+            
+            Hep3Vector trkPosAtShowerMax = TrackUtils.extrapolateTrack(track,clusterPos.z());
+            if(Double.isNaN(trkPosAtShowerMax.x()) || Double.isNaN(trkPosAtShowerMax.y())){
+                this.printDebug("Invalid track position");
+                return false; 
+            }
+            this.printDebug("Track position at shower max: " + trkPosAtShowerMax.toString());
  
-    		// Find the distance between the track position at shower
-    		// max and the cluster position
-    		double r = VecOp.sub(trkPosAtShowerMax, clusterPos).magnitude();
-    		this.printDebug("Distance between Ecal cluster and track position at shower max: " + r + " mm");
-        	
-    		// Check if the track is the closest to the cluster.  If it is, then
-    		// save the track and contineu looping over all other tracks
-    		if (r < rMax /*&& r <= maxTrackClusterDistance*/) {
-    			rMax = r;
-    			matchedTrack = track;
-    		}
-    	}
-    	if(matchedTrack != null) return true;
-    	return false;
+            // Find the distance between the track position at shower
+            // max and the cluster position
+            double r = VecOp.sub(trkPosAtShowerMax, clusterPos).magnitude();
+            this.printDebug("Distance between Ecal cluster and track position at shower max: " + r + " mm");
+            
+            // Check if the track is the closest to the cluster.  If it is, then
+            // save the track and contineu looping over all other tracks
+            if (r < rMax /*&& r <= maxTrackClusterDistance*/) {
+                rMax = r;
+                matchedTrack = track;
+            }
+        }
+        if(matchedTrack != null) return true;
+        return false;
     }
     
     /**
      * 
      */
     private void printPosition(double[] position){
-    	this.printDebug("[ " + position[0] + ", " + position[1] + ", " + position[2] + " ]");
+        this.printDebug("[ " + position[0] + ", " + position[1] + ", " + position[2] + " ]");
     }
     
     
@@ -373,28 +373,28 @@
     public void endOfData(){ 
         System.out.println("%===================================================================% \n");
         if(findableSingleTracks > 0){
-        	System.out.println("% Total single track efficiency: " + foundSingleTracks + " / " + findableSingleTracks + " = " + (foundSingleTracks/findableSingleTracks)*100 + "%");
+            System.out.println("% Total single track efficiency: " + foundSingleTracks + " / " + findableSingleTracks + " = " + (foundSingleTracks/findableSingleTracks)*100 + "%");
         }
         if(findableSingleTracksQuad1 > 0){
-        	System.out.println("% Total single track efficiency - Quad 1: " + foundSingleTracksQuad1 + " / " + findableSingleTracksQuad1 + " = " + (foundSingleTracksQuad1/findableSingleTracksQuad1)*100 + "%");
+            System.out.println("% Total single track efficiency - Quad 1: " + foundSingleTracksQuad1 + " / " + findableSingleTracksQuad1 + " = " + (foundSingleTracksQuad1/findableSingleTracksQuad1)*100 + "%");
         }
         if(findableSingleTracksQuad2 > 0){
-        	System.out.println("% Total single track efficiency - Quad 2: " + foundSingleTracksQuad2 + " / " + findableSingleTracksQuad2 + " = " + (foundSingleTracksQuad2/findableSingleTracksQuad2)*100 + "%");
+            System.out.println("% Total single track efficiency - Quad 2: " + foundSingleTracksQuad2 + " / " + findableSingleTracksQuad2 + " = " + (foundSingleTracksQuad2/findableSingleTracksQuad2)*100 + "%");
         }
         if(findableSingleTracksQuad3 > 0){
-        	System.out.println("% Total single track efficiency - Quad 3: " + foundSingleTracksQuad3 + " / " + findableSingleTracksQuad3 + " = " + (foundSingleTracksQuad3/findableSingleTracksQuad3)*100 + "%");
+            System.out.println("% Total single track efficiency - Quad 3: " + foundSingleTracksQuad3 + " / " + findableSingleTracksQuad3 + " = " + (foundSingleTracksQuad3/findableSingleTracksQuad3)*100 + "%");
         }
         if(findableSingleTracksQuad4 > 0){
-        	System.out.println("% Total single track efficiency - Quad 4: " + foundSingleTracksQuad4 + " / " + findableSingleTracksQuad4 + " = " + (foundSingleTracksQuad4/findableSingleTracksQuad4)*100 + "%");
+            System.out.println("% Total single track efficiency - Quad 4: " + foundSingleTracksQuad4 + " / " + findableSingleTracksQuad4 + " = " + (foundSingleTracksQuad4/findableSingleTracksQuad4)*100 + "%");
         }
         if(nOppositeVolume > 0){
-        	System.out.println("% Total events passing opposite volume requirement: " + nOppositeVolume + " / " + eventNumber + " = " + (nOppositeVolume/eventNumber)*100 + "%");
+            System.out.println("% Total events passing opposite volume requirement: " + nOppositeVolume + " / " + eventNumber + " = " + (nOppositeVolume/eventNumber)*100 + "%");
         }
         if(nAboveThreshold > 0){
-        	System.out.println("% Total events with both clusters above energy threshold: " + nAboveThreshold + " / " + eventNumber + " = " + (nAboveThreshold/eventNumber)*100 + "%");
+            System.out.println("% Total events with both clusters above energy threshold: " + nAboveThreshold + " / " + eventNumber + " = " + (nAboveThreshold/eventNumber)*100 + "%");
         }
         if(nTrigClusterTrackMatch > 0){
-        	System.out.println("% Total events with a trigger cluster-track match: " + nTrigClusterTrackMatch + " / " + eventNumber + " = " + (nTrigClusterTrackMatch/eventNumber)*100 + "%");
+            System.out.println("% Total events with a trigger cluster-track match: " + nTrigClusterTrackMatch + " / " + eventNumber + " = " + (nTrigClusterTrackMatch/eventNumber)*100 + "%");
         }
         if(findableTracks > 0){
             System.out.println("% Total Track Reconstruction Efficiency: " + totalTracks + " / " + findableTracks + " = " + (totalTracks / findableTracks) * 100 + "%");

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/phansson/CmpGenToFittedTracksDriver.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/phansson/CmpGenToFittedTracksDriver.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/phansson/CmpGenToFittedTracksDriver.java	Wed Apr 27 11:11:32 2016
@@ -12,6 +12,7 @@
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
+import org.hps.users.phansson.testrun.TrigRateDriver;
 import org.lcsim.event.EventHeader;
 import org.lcsim.event.Track;
 import org.lcsim.event.TrackerHit;

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/phansson/DataTrackerFakeHitDriver.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/phansson/DataTrackerFakeHitDriver.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/phansson/DataTrackerFakeHitDriver.java	Wed Apr 27 11:11:32 2016
@@ -16,10 +16,12 @@
 import java.util.List;
 import java.util.Set;
 
+
 //===> import org.hps.conditions.deprecated.SvtUtils;
-import org.hps.recon.tracking.HPSTrack;
+import org.hps.recon.tracking.HpsHelicalTrackFit;
 import org.hps.recon.tracking.TrackUtils;
 import org.hps.recon.tracking.TrackerHitUtils;
+import org.hps.recon.tracking.WTrack;
 import org.lcsim.detector.IDetectorElement;
 import org.lcsim.detector.ITransform3D;
 import org.lcsim.detector.ITranslation3D;
@@ -194,12 +196,12 @@
 
 
         // Obtain the tracks from the event
-        if (!event.hasCollection(HPSTrack.class, trackCollectionName)) {
+        if (!event.hasCollection(HpsHelicalTrackFit.class, trackCollectionName)) {
             this.printDebug("No HPSTracks were found, skipping event");
             simHits = null;
             return;
         }
-        List<HPSTrack> tracks = event.get(HPSTrack.class, trackCollectionName);
+        List<HpsHelicalTrackFit> tracks = event.get(HpsHelicalTrackFit.class, trackCollectionName);
 
         if (debug) {
             System.out.println(this.getClass().getSimpleName() + ": found " + tracks.size() + " tracks (" + this.trackCollectionName + ")");
@@ -223,13 +225,13 @@
             System.out.println(this.getClass().getSimpleName() + ": Add hits for " + tracks.size() + " tracks (" + this.trackCollectionName + ")");
         }
 
-        for (HPSTrack helix : tracks) {
+        for (HpsHelicalTrackFit helix : tracks) {
             if (debug) {
                 System.out.println(this.getClass().getSimpleName() + ": trying to add hits for this track");
             }
 
             // Get the MC Particle associated with this track
-            MCParticle mcParticle = helix.getMCParticle();
+            MCParticle mcParticle = helix.getMcParticle();
 
             if (debug) {
                 System.out.println(this.getClass().getSimpleName() + helix.toString());
@@ -238,8 +240,8 @@
                 System.out.println(this.getClass().getSimpleName() + ": create a WTrack object");
             }
 
-            WTrack wtrack = new WTrack(helix, Math.abs(_bfield.z()), true); //remove sign from B-field (assumed to go along z-direction)
-
+            WTrack wtrack = new WTrack(helix, Math.abs(_bfield.z())); 
+            
             if (debug) {
                 System.out.println(this.getClass().getSimpleName() + ": " + wtrack.toString());
 

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/phansson/FastTrackResidualDriver.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/phansson/FastTrackResidualDriver.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/phansson/FastTrackResidualDriver.java	Wed Apr 27 11:11:32 2016
@@ -78,11 +78,11 @@
     }
     
     public void detectorChanged(Detector detector) {
-	// Get the Subdetector.
-	ecal = detector.getSubdetector(ecalName);
-
-	// Cache ref to decoder.
-	dec = ecal.getIDDecoder();
+    // Get the Subdetector.
+    ecal = detector.getSubdetector(ecalName);
+
+    // Cache ref to decoder.
+    dec = ecal.getIDDecoder();
         
         //Ecal geometry
         crystalX = (13.3 + 16.0) / 2;
@@ -793,7 +793,7 @@
                 style.setParameter("hist2DStyle", "colorMap");
                 style.dataStyle().fillStyle().setParameter("colorMapScheme", "rainbow");
                 ((PlotterRegion) plotter_ecalhitmult.region(idx)).getPlot().setAllowUserInteraction(false);
-		((PlotterRegion) plotter_ecalhitmult.region(idx)).getPlot().setAllowPopupMenus(false);
+        ((PlotterRegion) plotter_ecalhitmult.region(idx)).getPlot().setAllowPopupMenus(false);
           }
                
         

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/phansson/ParticleHelixProducer.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/phansson/ParticleHelixProducer.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/phansson/ParticleHelixProducer.java	Wed Apr 27 11:11:32 2016
@@ -13,7 +13,7 @@
 import java.util.List;
 
 import org.hps.analysis.ecal.HPSMCParticlePlotsDriver;
-import org.hps.recon.tracking.HPSTrack;
+import org.hps.recon.tracking.HpsHelicalTrackFit;
 import org.hps.recon.tracking.TrackerHitUtils;
 import org.lcsim.constants.Constants;
 import org.lcsim.event.EventHeader;
@@ -137,7 +137,7 @@
 
         //Make new tracks based on the MC particles
         //List<HelicalTrackFit> tracks = new ArrayList<HelicalTrackFit>();
-        List<HPSTrack> tracks = new ArrayList<HPSTrack>();
+        List<HpsHelicalTrackFit> tracks = new ArrayList<HpsHelicalTrackFit>();
 
         if (event.hasCollection(MCParticle.class)) {
             List<MCParticle> mcparticles = event.get(MCParticle.class).get(0);
@@ -251,7 +251,7 @@
                     pars[3] = hpc.getZ0();
                     pars[4] = hpc.getSlopeSZPlane();
                     //HelicalTrackFit htf = this.trackUtils.makeHelicalTrackFit(pars);
-                    HPSTrack htf = this.makeHPSTrack(pars, part);
+                    HpsHelicalTrackFit htf = this.makeHPSTrack(pars, part);
                     tracks.add(htf);
                     if (debug) {
                         System.out.println(this.getClass().getSimpleName() + ": MC particle created HelicalTrackFit " + htf.toString());
@@ -281,7 +281,7 @@
         }
 
         this.printDebug("created " + tracks.size() + " MC particle helix tracks");
-        event.put(this.trackOutputCollectionName, tracks, HPSTrack.class, 0);
+        event.put(this.trackOutputCollectionName, tracks, HpsHelicalTrackFit.class, 0);
         _totalTracks += tracks.size();
     }
 
@@ -292,9 +292,12 @@
      * @param mcParticle : MC particle associated to this HelicalTrackFit
      * @return HpsHelicalTrackFit :
      */
-    public HPSTrack makeHPSTrack(double[] helixParameters, MCParticle mcParticle) {
-        return new HPSTrack(helixParameters, new SymmetricMatrix(5), new double[2], new int[2],
-                new HashMap<HelicalTrackHit, Double>(), new HashMap<HelicalTrackHit, MultipleScatter>(), mcParticle);
+    public HpsHelicalTrackFit makeHPSTrack(double[] helixParameters, MCParticle mcParticle) {
+        HpsHelicalTrackFit helicalTrackFit = new HpsHelicalTrackFit(helixParameters, new SymmetricMatrix(5), new double[2], new int[2],
+                new HashMap<HelicalTrackHit, Double>(), new HashMap<HelicalTrackHit, MultipleScatter>());
+        helicalTrackFit.setMcParticle(mcParticle);
+        return  helicalTrackFit;
+        
     }
 
     /**

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/phansson/SimpleResiduals.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/phansson/SimpleResiduals.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/phansson/SimpleResiduals.java	Wed Apr 27 11:11:32 2016
@@ -98,11 +98,11 @@
     }
     
     public void detectorChanged(Detector detector) {
-	// Get the Subdetector.
-	ecal = detector.getSubdetector(ecalName);
-
-	// Cache ref to decoder.
-	dec = ecal.getIDDecoder();
+    // Get the Subdetector.
+    ecal = detector.getSubdetector(ecalName);
+
+    // Cache ref to decoder.
+    dec = ecal.getIDDecoder();
     }
     
     public SimpleResiduals() {

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/phansson/TrackingReconstructionPlots.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/phansson/TrackingReconstructionPlots.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/phansson/TrackingReconstructionPlots.java	Wed Apr 27 11:11:32 2016
@@ -50,7 +50,8 @@
 import org.lcsim.util.aida.AIDA;
 
 /**
- *
+ * Analysis class to check recon.
+ * 
  * @author phansson
  */
 public class TrackingReconstructionPlots extends Driver {
@@ -89,12 +90,10 @@
     IPlotter plotter55;
     IPlotter plotter6;
     IPlotter plotter66;
-    IPlotter plotter7;
     IPlotter plotter8;
     IPlotter plotter88;
     IPlotter plotter888;
     IPlotter plotter8888;
-    IPlotter plotter9;
     IPlotter top1;
     IPlotter top2;
     IPlotter top3;
@@ -114,11 +113,11 @@
     private boolean showPlots = true;
     private double _bfield;
     private static Logger LOGGER = Logger.getLogger(TrackingReconstructionPlots.class.getName());
+    private List<HpsSiSensor> sensors = new ArrayList<HpsSiSensor>();
 
     @Override
     protected void detectorChanged(Detector detector) {
         aida.tree().cd("/");
-        List<HpsSiSensor> sensors = new ArrayList<HpsSiSensor>();
         for(HpsSiSensor s : detector.getDetectorElement().findDescendants(HpsSiSensor.class)) {
             if(s.getName().startsWith("module_") && s.getName().endsWith("sensor0")) {
                 sensors.add(s);
@@ -128,833 +127,15 @@
         
         Hep3Vector bfieldvec = detector.getFieldMap().getField(new BasicHep3Vector(0., 0., 1.));
         _bfield = bfieldvec.y();
-
-        IAnalysisFactory fac = aida.analysisFactory();
-        plotter = fac.createPlotterFactory().create("HPS Tracking Plots");
-        plotter.setTitle("Momentum");
-        IPlotterStyle style = plotter.style();
-        style.dataStyle().fillStyle().setColor("yellow");
-        style.dataStyle().errorBarStyle().setVisible(false);
-        plotter.createRegions(2, 2);
-        //plotterFrame.addPlotter(plotter);
-
-        trkPx = aida.histogram1D("Track Momentum (Px)", 25, -0.25, 0.25);
-        IHistogram1D trkPy = aida.histogram1D("Track Momentum (Py)", 25, -0.5, 0.5);
-        IHistogram1D trkPz = aida.histogram1D("Track Momentum (Pz)", 25, 0, 1.5);
-        IHistogram1D trkChi2 = aida.histogram1D("Track Chi2", 25, 0, 25.0);
-
-        plotter.region(0).plot(trkPx);
-        plotter.region(1).plot(trkPy);
-        plotter.region(2).plot(trkPz);
-        plotter.region(3).plot(trkChi2);
-
-        if(showPlots) plotter.show();
-
-//   ******************************************************************
-        top1 = fac.createPlotterFactory().create("Top Tracking Plots");
-        top1.setTitle("Top Momentum");
-        IPlotterStyle stop1 = top1.style();
-        stop1.dataStyle().fillStyle().setColor("green");
-        stop1.dataStyle().errorBarStyle().setVisible(false);
-        top1.createRegions(2, 2);
-        //topFrame.addPlotter(top1);
-
-        IHistogram1D toptrkPx = aida.histogram1D("Top Track Momentum (Px)", 25, -0.25, 0.25);
-        IHistogram1D toptrkPy = aida.histogram1D("Top Track Momentum (Py)", 25, -0.5, 0.5);
-        IHistogram1D toptrkPz = aida.histogram1D("Top Track Momentum (Pz)", 25, 0, 1.5);
-        IHistogram1D toptrkChi2 = aida.histogram1D("Top Track Chi2", 25, 0, 25.0);
-
-        top1.region(0).plot(toptrkPx);
-        top1.region(1).plot(toptrkPy);
-        top1.region(2).plot(toptrkPz);
-        top1.region(3).plot(toptrkChi2);
-
-        if(showPlots) top1.show();
-
-        bot1 = fac.createPlotterFactory().create("Bottom Tracking Plots");
-        bot1.setTitle("Bottom Momentum");
-        IPlotterStyle sbot1 = bot1.style();
-        sbot1.dataStyle().fillStyle().setColor("blue");
-        sbot1.dataStyle().errorBarStyle().setVisible(false);
-        bot1.createRegions(2, 2);
-        //bottomFrame.addPlotter(bot1);
-
-        IHistogram1D bottrkPx = aida.histogram1D("Bottom Track Momentum (Px)", 25, -0.25, 0.25);
-        IHistogram1D bottrkPy = aida.histogram1D("Bottom Track Momentum (Py)", 25, -0.5, 0.5);
-        IHistogram1D bottrkPz = aida.histogram1D("Bottom Track Momentum (Pz)", 25, 0, 1.5);
-        IHistogram1D bottrkChi2 = aida.histogram1D("Bottom Track Chi2", 25, 0, 25.0);
-
-        bot1.region(0).plot(bottrkPx);
-        bot1.region(1).plot(bottrkPy);
-        bot1.region(2).plot(bottrkPz);
-        bot1.region(3).plot(bottrkChi2);
-
-        if(showPlots) bot1.show();
-
-//   ******************************************************************
-        IHistogram1D trkd0 = aida.histogram1D("d0 ", 25, -10.0, 10.0);
-        IHistogram1D trkphi = aida.histogram1D("sinphi ", 25, -0.2, 0.2);
-        IHistogram1D trkomega = aida.histogram1D("omega ", 25, -0.0025, 0.0025);
-        IHistogram1D trklam = aida.histogram1D("tan(lambda) ", 25, -0.1, 0.1);
-        IHistogram1D trkz0 = aida.histogram1D("z0 ", 25, -6.0, 6.0);
-
-        plotter22 = fac.createPlotterFactory().create("HPS Track Params");
-        plotter22.setTitle("Track parameters");
-        //plotterFrame.addPlotter(plotter22);
-        IPlotterStyle style22 = plotter22.style();
-        style22.dataStyle().fillStyle().setColor("yellow");
-        style22.dataStyle().errorBarStyle().setVisible(false);
-        plotter22.createRegions(2, 3);
-        plotter22.region(0).plot(trkd0);
-        plotter22.region(1).plot(trkphi);
-        plotter22.region(2).plot(trkomega);
-        plotter22.region(3).plot(trklam);
-        plotter22.region(4).plot(trkz0);
-        
-        if(showPlots) plotter22.show();
-
- //   ******************************************************************
-
-        
-         trkd0 = aida.histogram1D("d0 Top", 25, -10.0, 10.0);
-         trkphi = aida.histogram1D("sinphi Top", 25, -0.2, 0.2);
-         trkomega = aida.histogram1D("omega Top", 25, -0.0025, 0.0025);
-         trklam = aida.histogram1D("tan(lambda) Top", 25, -0.1, 0.1);
-         trkz0 = aida.histogram1D("z0 Top", 25, -6.0, 6.0);
-
-        plotter2221 = fac.createPlotterFactory().create("HPS Track Params");
-        plotter2221.setTitle("Track parameters");
-        //plotterFrame.addPlotter(plotter22);
-        IPlotterStyle style2221 = plotter2221.style();
-        style2221.dataStyle().fillStyle().setColor("yellow");
-        style2221.dataStyle().errorBarStyle().setVisible(false);
-        plotter2221.createRegions(2, 3);
-        plotter2221.region(0).plot(trkd0);
-        plotter2221.region(1).plot(trkphi);
-        plotter2221.region(2).plot(trkomega);
-        plotter2221.region(3).plot(trklam);
-        plotter2221.region(4).plot(trkz0);
-        
-        if(showPlots) plotter2221.show();
-        
-        
-   //   ******************************************************************
-
-        
-        trkd0 = aida.histogram1D("d0 Bottom", 25, -10.0, 10.0);
-        trkphi = aida.histogram1D("sinphi Bottom", 25, -0.2, 0.2);
-        trkomega = aida.histogram1D("omega Bottom", 25, -0.0025, 0.0025);
-        trklam = aida.histogram1D("tan(lambda) Bottom", 25, -0.1, 0.1);
-        trkz0 = aida.histogram1D("z0 Bottom", 25, -6.0, 6.0);
-
-       plotter2222 = fac.createPlotterFactory().create("HPS Track Params");
-       plotter2222.setTitle("Track parameters");
-       //plotterFrame.addPlotter(plotter22);
-       IPlotterStyle style2222 = plotter2222.style();
-       style2222.dataStyle().fillStyle().setColor("yellow");
-       style2222.dataStyle().errorBarStyle().setVisible(false);
-       plotter2222.createRegions(2, 3);
-       plotter2222.region(0).plot(trkd0);
-       plotter2222.region(1).plot(trkphi);
-       plotter2222.region(2).plot(trkomega);
-       plotter2222.region(3).plot(trklam);
-       plotter2222.region(4).plot(trkz0);
-       
-       if(showPlots) plotter2222.show();
-        
-        
-        
-   //   ******************************************************************
-
-        
-        plotter2 = fac.createPlotterFactory().create("HPS Tracking Plots");
-        plotter2.setTitle("Track extrapolation");
-        //plotterFrame.addPlotter(plotter2);
-        IPlotterStyle style2 = plotter2.style();
-        style2.dataStyle().fillStyle().setColor("yellow");
-        style2.dataStyle().errorBarStyle().setVisible(false);
-        plotter2.createRegions(2, 4);
-        IHistogram1D xAtConverter = aida.histogram1D("X (mm) @ Z=-60cm", 50, -50, 50);
-        IHistogram1D yAtConverter = aida.histogram1D("Y (mm) @ Z=-60cm", 50, -20, 20);
-        IHistogram1D xAtColl = aida.histogram1D("X (mm) @ Z=-150cm", 50, -200, 200);
-        IHistogram1D yAtColl = aida.histogram1D("Y (mm) @ Z=-150cm", 50, -200, 200);
-        IHistogram1D xAtEcal = aida.histogram1D("X (mm) @ ECAL", 50, -500, 500);
-        IHistogram1D yAtEcal = aida.histogram1D("Y (mm) @ ECAL", 50, -100, 100);
-        IHistogram1D xAtEcal2 = aida.histogram1D("X (mm) @ ECAL (Pz>1)", 50, -500, 500);
-        IHistogram1D yAtEcal2 = aida.histogram1D("Y (mm) @ ECAL (Pz>1)", 50, -100, 100);
-
-        plotter2.region(0).plot(xAtConverter);
-        plotter2.region(4).plot(yAtConverter);
-        plotter2.region(1).plot(xAtColl);
-        plotter2.region(5).plot(yAtColl);
-        plotter2.region(2).plot(xAtEcal);
-        plotter2.region(6).plot(yAtEcal);
-        plotter2.region(3).plot(xAtEcal2);
-        plotter2.region(7).plot(yAtEcal2);
-        
-        if(showPlots) plotter2.show();
-
-   //   ******************************************************************
-        
-        plotter222 = fac.createPlotterFactory().create("HPS Tracking Plots");
-        plotter222.setTitle("HPS Tracking Plots");
-        //plotterFrame.addPlotter(plotter222);
-        IPlotterStyle style222 = plotter222.style();
-        style222.dataStyle().fillStyle().setColor("yellow");
-        style222.dataStyle().errorBarStyle().setVisible(false);
-        plotter222.createRegions(2, 2);
-        
-        IHistogram1D nHits = aida.histogram1D("Hits per Track", 4, 3, 7);
-        nTracks = aida.histogram1D("Tracks per Event", 3, 0, 3);
-        IHistogram1D nHitsCluster = aida.histogram1D("Hits in Cluster (HitOnTrack)", 4, 0, 4);
-
-       
-        plotter222.region(0).plot(nHits);
-        plotter222.region(1).plot(nTracks);
-        plotter222.region(2).plot(nHitsCluster);
-        
-        if(showPlots) plotter222.show();
-   
-        
-   //   ******************************************************************
-        
-        plotter22299 = fac.createPlotterFactory().create("HPS Tracking Plots Top");
-        plotter22299.setTitle("HPS Tracking Plots Top");
-        //plotterFrame.addPlotter(plotter22299);
-        IPlotterStyle style22299 = plotter22299.style();
-        style22299.dataStyle().fillStyle().setColor("yellow");
-        style22299.dataStyle().errorBarStyle().setVisible(false);
-        plotter22299.createRegions(2, 2);
-        
-        IHistogram1D nHitsTop = aida.histogram1D("Hits per Track Top", 4, 3, 7);
-        nTracksTop = aida.histogram1D("Tracks per Event Top", 3, 0, 3);
-        IHistogram1D nHitsClusterTop = aida.histogram1D("Hits in Cluster (HitOnTrack) Top", 4, 0, 4);
-
-       
-        plotter22299.region(0).plot(nHitsTop);
-        plotter22299.region(1).plot(nTracksTop);
-        plotter22299.region(2).plot(nHitsClusterTop);
-        
-        if(showPlots) plotter22299.show();
-   
-//   ******************************************************************
-        
-        plotter22298 = fac.createPlotterFactory().create("HPS Tracking Plots Bottom");
-        plotter22298.setTitle("HPS Tracking Plots Bottom");
-        //plotterFrame.addPlotter(plotter22298);
-        IPlotterStyle style22298 = plotter22298.style();
-        style22298.dataStyle().fillStyle().setColor("yellow");
-        style22298.dataStyle().errorBarStyle().setVisible(false);
-        plotter22298.createRegions(2, 2);
-        
-        IHistogram1D nHitsBot = aida.histogram1D("Hits per Track Bot", 4, 3, 7);
-        nTracksBot = aida.histogram1D("Tracks per Event Bot", 3, 0, 3);
-        IHistogram1D nHitsClusterBot = aida.histogram1D("Hits in Cluster (HitOnTrack) Bot", 4, 0, 4);
-
-       
-        plotter22298.region(0).plot(nHitsBot);
-        plotter22298.region(1).plot(nTracksBot);
-        plotter22298.region(2).plot(nHitsClusterBot);
-        
-        if(showPlots) plotter22298.show();
-   
-        
-        //   ******************************************************************
-        
-        
-        plotter2223 = fac.createPlotterFactory().create("Cluster Amp Plots");
-        plotter2223.setTitle("Other");
-        //plotterFrame.addPlotter(plotter222);
-        IPlotterStyle style2223 = plotter2223.style();
-        style2223.dataStyle().fillStyle().setColor("yellow");
-        style2223.dataStyle().errorBarStyle().setVisible(false);
-        plotter2223.createRegions(2, 2);
-        
-       
-
-        IHistogram1D amp = aida.histogram1D("Amp (HitOnTrack)", 50, 0, 5000);
-        IHistogram1D ampcl = aida.histogram1D("Cluster Amp (HitOnTrack)", 50, 0, 5000);
-        IHistogram1D amp2 = aida.histogram1D("Amp Pz>0.8 (HitOnTrack)", 50, 0, 5000);
-        IHistogram1D ampcl2 = aida.histogram1D("Cluster Amp Pz>0.8 (HitOnTrack)", 50, 0, 5000);
-      
-        
-        plotter2223.region(0).plot(amp);
-        plotter2223.region(1).plot(amp2);
-        plotter2223.region(2).plot(ampcl);
-        plotter2223.region(3).plot(ampcl2);
-        
-        if(showPlots) plotter2223.show();
-   
-//   ******************************************************************
-        
-        
-        plotter2224 = fac.createPlotterFactory().create("t0 Plots");
-        plotter2224.setTitle("Other");
-        IPlotterStyle style2224 = plotter2224.style();
-        style2224.dataStyle().fillStyle().setColor("yellow");
-        style2224.dataStyle().errorBarStyle().setVisible(false);
-        plotter2224.createRegions(2, 2);
-                
-        IHistogram1D t0 = aida.histogram1D("t0 (HitOnTrack)", 50, -100, 100);
-        IHistogram1D t0cl = aida.histogram1D("Cluster t0 (HitOnTrack)", 50, -100, 100);
-        IHistogram1D t02 = aida.histogram1D("t0 Pz>0.8 (HitOnTrack)", 50, -100, 100);
-        IHistogram1D t0cl2 = aida.histogram1D("Cluster t0 Pz>0.8 (HitOnTrack)", 50, -100, 100);
-        
-        plotter2224.region(0).plot(t0);
-        plotter2224.region(1).plot(t0cl);
-        plotter2224.region(2).plot(t02);
-        plotter2224.region(3).plot(t0cl2);
-
-        if(showPlots) plotter2224.show();
-   
-        
-        //   ******************************************************************
-          
-        plotter3 = fac.createPlotterFactory().create("HPS Layer Residual Plots");
-        plotter3.setTitle("Layer Residuals");
-        //plotterFrame.addPlotter(plotter3);
-        IPlotterStyle style3 = plotter3.style();
-        style3.dataStyle().fillStyle().setColor("yellow");
-        style3.dataStyle().errorBarStyle().setVisible(false);
-        plotter3.createRegions(6, 2);
-
-       
-
-        IHistogram1D mod1ResX = aida.histogram1D("Layer 1 Residual X(mm)", 25, -1, 1);
-        IHistogram1D mod1ResY = aida.histogram1D("Layer 1 Residual Y(mm)", 25, -0.04, 0.04);
-
-        IHistogram1D mod2ResX = aida.histogram1D("Layer 2 Residual X(mm)", 25, -2, 2);
-        IHistogram1D mod2ResY = aida.histogram1D("Layer 2 Residual Y(mm)", 25, -1, 1);
-
-        IHistogram1D mod3ResX = aida.histogram1D("Layer 3 Residual X(mm)", 25, -2.5, 2.5);
-        IHistogram1D mod3ResY = aida.histogram1D("Layer 3 Residual Y(mm)", 25, -1.5, 1.5);
-
-        IHistogram1D mod4ResX = aida.histogram1D("Layer 4 Residual X(mm)", 25, -3.0, 3.0);
-        IHistogram1D mod4ResY = aida.histogram1D("Layer 4 Residual Y(mm)", 25, -2, 2);
-
-        IHistogram1D mod5ResX = aida.histogram1D("Layer 5 Residual X(mm)", 25, -4, 4);
-        IHistogram1D mod5ResY = aida.histogram1D("Layer 5 Residual Y(mm)", 25, -3, 3);
-
-        IHistogram1D mod6ResX = aida.histogram1D("Layer 6 Residual X(mm)", 25, -5, 5);
-        IHistogram1D mod6ResY = aida.histogram1D("Layer 6 Residual Y(mm)", 25, -3, 3);
-
-        plotter3.region(0).plot(mod1ResX);
-        plotter3.region(2).plot(mod2ResX);
-        plotter3.region(4).plot(mod3ResX);
-        plotter3.region(6).plot(mod4ResX);
-        plotter3.region(8).plot(mod5ResX);
-        plotter3.region(10).plot(mod6ResX);
-
-        plotter3.region(1).plot(mod1ResY);
-        plotter3.region(3).plot(mod2ResY);
-        plotter3.region(5).plot(mod3ResY);
-        plotter3.region(7).plot(mod4ResY);
-        plotter3.region(9).plot(mod5ResY);
-        plotter3.region(11).plot(mod6ResY);
-               
-        if(showPlots) plotter3.show();
-        
-        
-        
-        plotter3_11 = fac.createPlotterFactory().create("HPS Strip Residual Plots");
-        plotter3_11.setTitle("Strip Residuals (Top)");
-        //plotterFrame.addPlotter(plotter3_11);
-        IPlotterStyle style3_11 = plotter3_11.style();
-        style3_11.dataStyle().fillStyle().setColor("yellow");
-        style3_11.dataStyle().errorBarStyle().setVisible(false);
-        plotter3_11.createRegions(6, 6);
-        int i=0;
-        for(HpsSiSensor sensor : sensors) {
-            double min = 0.0;
-            double max = 0.0;
-            if(sensor.getName().contains("L1")) {
-                min=-0.04; max=0.04;
-            } else if(sensor.getName().contains("L2")) {
-                min=-1; max=1;
-            } else if(sensor.getName().contains("L3")) {
-                min=-1.5; max=1.5;
-            } else if(sensor.getName().contains("L4")) {
-                min=-3; max=3;
-            } else if(sensor.getName().contains("L5")) {
-                min=-4; max=4;
-            } else if(sensor.getName().contains("L6")) {
-                min=-5; max=5;
-            } else {
-                throw new RuntimeException("Invalid sensor name: " + sensor.getName());
-            }
-           IHistogram1D resX = aida.histogram1D(sensor.getName() + " strip residual (mm)", 50, min, max);
-            plotter3_11.region(i).plot(resX);
-            i++;
-        }
-
-        if(showPlots) plotter3_11.show();
-        
-
-        plotter3_1 = fac.createPlotterFactory().create("HPS Residual Plots (Single hit per layer)");
-        plotter3_1.setTitle("Residuals (Top)");
-        //plotterFrame.addPlotter(plotter3_1);
-        IPlotterStyle style3_1 = plotter3_1.style();
-        style3_1.dataStyle().fillStyle().setColor("yellow");
-        style3_1.dataStyle().errorBarStyle().setVisible(false);
-        plotter3_1.createRegions(6, 2);
-        
-        IHistogram1D mod1ResX_Top = aida.histogram1D("Layer 1 Residual X(mm) Top", 25, -1, 1);
-        IHistogram1D mod1ResY_Top = aida.histogram1D("Layer 1 Residual Y(mm) Top", 25, -0.04, 0.04);
-
-        IHistogram1D mod2ResX_Top = aida.histogram1D("Layer 2 Residual X(mm) Top", 25, -2, 2);
-        IHistogram1D mod2ResY_Top = aida.histogram1D("Layer 2 Residual Y(mm) Top", 25, -1, 1);
-
-        IHistogram1D mod3ResX_Top = aida.histogram1D("Layer 3 Residual X(mm) Top", 25, -2.5, 2.5);
-        IHistogram1D mod3ResY_Top = aida.histogram1D("Layer 3 Residual Y(mm) Top", 25, -1.5, 1.5);
-
-        IHistogram1D mod4ResX_Top = aida.histogram1D("Layer 4 Residual X(mm) Top", 25, -3.0, 3.0);
-        IHistogram1D mod4ResY_Top = aida.histogram1D("Layer 4 Residual Y(mm) Top", 25, -2, 2);
-
-        IHistogram1D mod5ResX_Top = aida.histogram1D("Layer 5 Residual X(mm) Top", 25, -4, 4);
-        IHistogram1D mod5ResY_Top = aida.histogram1D("Layer 5 Residual Y(mm) Top", 25, -3, 3);
-
-        IHistogram1D mod6ResX_Top = aida.histogram1D("Layer 6 Residual X(mm) Top", 25, -5, 5);
-        IHistogram1D mod6ResY_Top = aida.histogram1D("Layer 6 Residual Y(mm) Top", 25, -3, 3);
-
-        
-        plotter3_1.region(0).plot(mod1ResX_Top);
-        plotter3_1.region(2).plot(mod2ResX_Top);
-        plotter3_1.region(4).plot(mod3ResX_Top);
-        plotter3_1.region(6).plot(mod4ResX_Top);
-        plotter3_1.region(8).plot(mod5ResX_Top);
-        plotter3_1.region(10).plot(mod6ResX_Top);
-
-        plotter3_1.region(1).plot(mod1ResY_Top);
-        plotter3_1.region(3).plot(mod2ResY_Top);
-        plotter3_1.region(5).plot(mod3ResY_Top);
-        plotter3_1.region(7).plot(mod4ResY_Top);
-        plotter3_1.region(9).plot(mod5ResY_Top);
-        plotter3_1.region(11).plot(mod6ResY_Top);
-
-        if(showPlots) plotter3_1.show();
-        
-        plotter3_2 = fac.createPlotterFactory().create("HPS Residual Plots (Single strip cluster per layer)");
-        plotter3_2.setTitle("Residuals (Bottom)");
-        //plotterFrame.addPlotter(plotter3_2);
-        IPlotterStyle style3_2 = plotter3_2.style();
-        style3_2.dataStyle().fillStyle().setColor("yellow");
-        style3_2.dataStyle().errorBarStyle().setVisible(false);
-        plotter3_2.createRegions(6, 2);
-
-        IHistogram1D mod1ResX_Bottom = aida.histogram1D("Layer 1 Residual X(mm) Bottom", 25, -1, 1);
-        IHistogram1D mod1ResY_Bottom = aida.histogram1D("Layer 1 Residual Y(mm) Bottom", 25, -0.04, 0.04);
-
-        IHistogram1D mod2ResX_Bottom = aida.histogram1D("Layer 2 Residual X(mm) Bottom", 25, -2, 2);
-        IHistogram1D mod2ResY_Bottom = aida.histogram1D("Layer 2 Residual Y(mm) Bottom", 25, -1, 1);
-
-        IHistogram1D mod3ResX_Bottom = aida.histogram1D("Layer 3 Residual X(mm) Bottom", 25, -2.5, 2.5);
-        IHistogram1D mod3ResY_Bottom = aida.histogram1D("Layer 3 Residual Y(mm) Bottom", 25, -1.5, 1.5);
-
-        IHistogram1D mod4ResX_Bottom = aida.histogram1D("Layer 4 Residual X(mm) Bottom", 25, -3.0, 3.0);
-        IHistogram1D mod4ResY_Bottom = aida.histogram1D("Layer 4 Residual Y(mm) Bottom", 25, -2, 2);
-
-        IHistogram1D mod5ResX_Bottom = aida.histogram1D("Layer 5 Residual X(mm) Bottom", 25, -4, 4);
-        IHistogram1D mod5ResY_Bottom = aida.histogram1D("Layer 5 Residual Y(mm) Bottom", 25, -3, 3);
-
-        IHistogram1D mod6ResX_Bottom = aida.histogram1D("Layer 6 Residual X(mm) Bottom", 25, -5, 5);
-        IHistogram1D mod6ResY_Bottom = aida.histogram1D("Layer 6 Residual Y(mm) Bottom", 25, -3, 3);
-
-        plotter3_2.region(0).plot(mod1ResX_Bottom);
-        plotter3_2.region(2).plot(mod2ResX_Bottom);
-        plotter3_2.region(4).plot(mod3ResX_Bottom);
-        plotter3_2.region(6).plot(mod4ResX_Bottom);
-        plotter3_2.region(8).plot(mod5ResX_Bottom);
-        plotter3_2.region(10).plot(mod6ResX_Bottom);
-
-        plotter3_2.region(1).plot(mod1ResY_Bottom);
-        plotter3_2.region(3).plot(mod2ResY_Bottom);
-        plotter3_2.region(5).plot(mod3ResY_Bottom);
-        plotter3_2.region(7).plot(mod4ResY_Bottom);
-        plotter3_2.region(9).plot(mod5ResY_Bottom);
-        plotter3_2.region(11).plot(mod6ResY_Bottom);
-        
-        if(showPlots) plotter3_2.show();
-
-        plotter4 = fac.createPlotterFactory().create("HPS Track and ECal Plots");
-        plotter4.setTitle("Track and ECal Correlations");
-        //plotterFrame.addPlotter(plotter4);
-        IPlotterStyle style4 = plotter4.style();
-        style4.setParameter("hist2DStyle", "colorMap");
-        style4.dataStyle().fillStyle().setParameter("colorMapScheme", "rainbow");
-        style4.dataStyle().fillStyle().setColor("yellow");
-        style4.dataStyle().errorBarStyle().setVisible(false);
-        plotter4.createRegions(2, 3);
-
-        IHistogram2D eVsP = aida.histogram2D("Energy Vs Momentum", 50, 0, 0.50, 50, 0, 1.5);
-        IHistogram1D eOverP = aida.histogram1D("Energy Over Momentum", 50, 0, 2);
-
-        IHistogram1D distX = aida.histogram1D("deltaX", 50, -100, 100);
-        IHistogram1D distY = aida.histogram1D("deltaY", 50, -40, 40);
-
-        IHistogram2D xEcalVsTrk = aida.histogram2D("X ECal Vs Track", 100, -400, 400, 100, -400, 400);
-        IHistogram2D yEcalVsTrk = aida.histogram2D("Y ECal Vs Track", 100, -100, 100, 100, -100, 100);
-
-        plotter4.region(0).plot(eVsP);
-        plotter4.region(3).plot(eOverP);
-        plotter4.region(1).plot(distX);
-        plotter4.region(4).plot(distY);
-        plotter4.region(2).plot(xEcalVsTrk);
-        plotter4.region(5).plot(yEcalVsTrk);
-
-        if(showPlots) plotter4.show();
-
-        //   ******************************************************************
-        top2 = fac.createPlotterFactory().create("Top ECal Plots");
-        top2.setTitle("Top ECal Correlations");
-        IPlotterStyle stop2 = top2.style();
-        stop2.dataStyle().fillStyle().setColor("green");
-        stop2.dataStyle().errorBarStyle().setVisible(false);
-        stop2.setParameter("hist2DStyle", "colorMap");
-        stop2.dataStyle().fillStyle().setParameter("colorMapScheme", "rainbow");
-        top2.createRegions(2, 3);
-        //topFrame.addPlotter(top2);
-
-        IHistogram2D topeVsP = aida.histogram2D("Top Energy Vs Momentum", 50, 0, 0.500, 50, 0, 1.5);
-        IHistogram1D topeOverP = aida.histogram1D("Top Energy Over Momentum", 50, 0, 2);
-
-        IHistogram1D topdistX = aida.histogram1D("Top deltaX", 50, -100, 100);
-        IHistogram1D topdistY = aida.histogram1D("Top deltaY", 50, -40, 40);
-
-        IHistogram2D topxEcalVsTrk = aida.histogram2D("Top X ECal Vs Track", 100, -400, 400, 100, -100, 100);
-        IHistogram2D topyEcalVsTrk = aida.histogram2D("Top Y ECal Vs Track", 100, 0, 100, 100, 0, 100);
-
-        top2.region(0).plot(topeVsP);
-        top2.region(3).plot(topeOverP);
-        top2.region(1).plot(topdistX);
-        top2.region(4).plot(topdistY);
-        top2.region(2).plot(topxEcalVsTrk);
-        top2.region(5).plot(topyEcalVsTrk);
-
-        if(showPlots) top2.show();
-        
-        bot2 = fac.createPlotterFactory().create("Bottom ECal Plots");
-        bot2.setTitle("Bottom ECal Correlations");
-        IPlotterStyle sbot2 = bot2.style();
-        sbot2.dataStyle().fillStyle().setColor("green");
-        sbot2.dataStyle().errorBarStyle().setVisible(false);
-        sbot2.setParameter("hist2DStyle", "colorMap");
-        sbot2.dataStyle().fillStyle().setParameter("colorMapScheme", "rainbow");
-        bot2.createRegions(2, 3);
-        //bottomFrame.addPlotter(bot2);
-
-        IHistogram2D BottomeVsP = aida.histogram2D("Bottom Energy Vs Momentum", 50, 0, 0.500, 50, 0, 1.5);
-        IHistogram1D BottomeOverP = aida.histogram1D("Bottom Energy Over Momentum", 50, 0, 2);
-
-        IHistogram1D BottomdistX = aida.histogram1D("Bottom deltaX", 50, -100, 100);
-        IHistogram1D BottomdistY = aida.histogram1D("Bottom deltaY", 50, -40, 40);
-
-        IHistogram2D BottomxEcalVsTrk = aida.histogram2D("Bottom X ECal Vs Track", 100, -400, 400, 100, -400, 400);
-        IHistogram2D BottomyEcalVsTrk = aida.histogram2D("Bottom Y ECal Vs Track", 100, -100, 0, 100, -100, 0);
-
-        bot2.region(0).plot(BottomeVsP);
-        bot2.region(3).plot(BottomeOverP);
-        bot2.region(1).plot(BottomdistX);
-        bot2.region(4).plot(BottomdistY);
-        bot2.region(2).plot(BottomxEcalVsTrk);
-        bot2.region(5).plot(BottomyEcalVsTrk);
-
-        if(showPlots) bot2.show();
-        
-        
-        //   ******************************************************************
-        top3 = fac.createPlotterFactory().create("Top ECal Plots");
-        top3.setTitle("Top ECal More Correlations");
-        IPlotterStyle stop3 = top3.style();
-        stop3.dataStyle().fillStyle().setColor("green");
-        stop3.dataStyle().errorBarStyle().setVisible(false);
-        stop3.setParameter("hist2DStyle", "colorMap");
-        stop3.dataStyle().fillStyle().setParameter("colorMapScheme", "rainbow");
-        top3.createRegions(1, 2);
-        //topFrame.addPlotter(top3);
-
-        IHistogram2D topdistXvsX = aida.histogram2D("Top deltaX vs X", 51, -400, 400, 25, -100, 100);
-        IHistogram2D topdistYvsY = aida.histogram2D("Top deltaY vs Y", 51, 0, 100, 25, -40, 40);
-
-        top3.region(0).plot(topdistXvsX);
-        top3.region(1).plot(topdistYvsY);
-
-        if(showPlots) top3.show();
-        
-        bot3 = fac.createPlotterFactory().create("Bottom ECal Plots");
-        bot3.setTitle("Bottom ECal More Correlations");
-        IPlotterStyle sbot3 = bot3.style();
-        sbot3.dataStyle().fillStyle().setColor("green");
-        sbot3.dataStyle().errorBarStyle().setVisible(false);
-        sbot3.setParameter("hist2DStyle", "colorMap");
-        sbot3.dataStyle().fillStyle().setParameter("colorMapScheme", "rainbow");
-        bot3.createRegions(1, 2);
-        //bottomFrame.addPlotter(bot3);
-
-        IHistogram2D botdistXvsX = aida.histogram2D("Bottom deltaX vs X", 51, -400, 400, 25, -100, 100);
-        IHistogram2D botdistYvsY = aida.histogram2D("Bottom deltaY vs Y", 51, -100, 0, 25, -40, 40);
-
-        bot3.region(0).plot(botdistXvsX);
-        bot3.region(1).plot(botdistYvsY);
-
-        if(showPlots) bot3.show();
-        
-        //   ******************************************************************
-        top4 = fac.createPlotterFactory().create("Track Matching Plots");
-        top4.setTitle("Track Matching Plots");
-        IPlotterStyle stop4 = top4.style();
-        stop4.dataStyle().fillStyle().setColor("green");
-        stop4.dataStyle().errorBarStyle().setVisible(false);
-        stop4.setParameter("hist2DStyle", "colorMap");
-        stop4.dataStyle().fillStyle().setParameter("colorMapScheme", "rainbow");
-        top4.createRegions(2, 3);
-        //topFrame.addPlotter(top4);
-
-        IHistogram1D trackmatchN = aida.histogram1D("Tracks matched", 3, 0, 3);
-        IHistogram1D toptrackmatchN = aida.histogram1D("Tracks matched Top", 3, 0, 3);
-        IHistogram1D bottrackmatchN = aida.histogram1D("Tracks matched Bottom", 3, 0, 3);
-        IHistogram1D trackmatchN2 = aida.histogram1D("Tracks matched (Pz>0.8)", 3, 0, 3);
-        IHistogram1D toptrackmatchN2 = aida.histogram1D("Tracks matched Top (Pz>0.8)", 3, 0, 3);
-        IHistogram1D bottrackmatchN2 = aida.histogram1D("Tracks matched Bottom (Pz>0.8)", 3, 0, 3);
-        
-        top4.region(0).plot(trackmatchN);
-        top4.region(1).plot(toptrackmatchN);
-        top4.region(2).plot(bottrackmatchN);
-        top4.region(3).plot(trackmatchN2);
-        top4.region(4).plot(toptrackmatchN2);
-        top4.region(5).plot(bottrackmatchN2);
-
-        if(showPlots) top4.show();
-        
-        //   ******************************************************************
-        top44 = fac.createPlotterFactory().create("e+e- Plots");
-        top44.setTitle("e+e- Plots");
-        IPlotterStyle stop44 = top44.style();
-        stop44.dataStyle().fillStyle().setColor("green");
-        stop44.dataStyle().errorBarStyle().setVisible(false);
-        stop44.setParameter("hist2DStyle", "colorMap");
-        stop44.dataStyle().fillStyle().setParameter("colorMapScheme", "rainbow");
-        top44.createRegions(2,4);
-        //topFrame.addPlotter(top44);
-
-        IHistogram2D trackPCorr = aida.histogram2D("p(e-) vs p(e+) max", 25, 0, 1.2, 25, 0, 1.2);
-        IHistogram1D ne = aida.histogram1D("n(e-)", 3, 0, 3);
-        IHistogram1D np = aida.histogram1D("n(e+)", 3, 0, 3);
-        IHistogram1D pem = aida.histogram1D("p(e-) max", 25, 0, 1.5);
-        IHistogram1D pe = aida.histogram1D("p(e-)", 25, 0, 1.5);
-        IHistogram1D ppm = aida.histogram1D("p(e+) max", 25, 0, 1.5);
-        IHistogram1D pp = aida.histogram1D("p(e+)", 25, 0, 1.5);
-        
-        top44.region(0).plot(trackPCorr);
-        top44.region(1).plot(ne);
-        top44.region(2).plot(np);
-        top44.region(3).plot(pe);
-        top44.region(4).plot(pp);
-        top44.region(5).plot(pem);
-        top44.region(6).plot(ppm);
-        
-        if(showPlots) top44.show();
-        
-        
-        
-//   ******************************************************************
-        plotter5 = fac.createPlotterFactory().create("HPS Hit Positions");
-        plotter5.setTitle("Hit Positions:  Top");
-        //plotterFrame.addPlotter(plotter5);
-        IPlotterStyle style5 = plotter5.style();
-        style5.setParameter("hist2DStyle", "colorMap");
-        style5.dataStyle().fillStyle().setParameter("colorMapScheme", "rainbow");
-        style5.dataStyle().fillStyle().setColor("yellow");
-        style5.dataStyle().errorBarStyle().setVisible(false);
-        plotter5.createRegions(1, 2);
-
-        IHistogram2D l1Pos = aida.histogram2D("Layer 1 HTH Position:  Top", 50, -55, 55, 55, -25, 25);
-        IHistogram2D l7Pos = aida.histogram2D("Layer 7 HTH Position:  Top", 50, -55, 55, 55, -25, 25);
-
-        plotter5.region(0).plot(l1Pos);
-        plotter5.region(1).plot(l7Pos);
-        
-        if(showPlots) plotter5.show();
-        
-        plotter5_1 = fac.createPlotterFactory().create("HPS Hit Positions");
-        plotter5_1.setTitle("Hit Positions:  Bottom");
-        //plotterFrame.addPlotter(plotter5_1);
-        IPlotterStyle style5_1 = plotter5_1.style();
-        style5_1.setParameter("hist2DStyle", "colorMap");
-        style5_1.dataStyle().fillStyle().setParameter("colorMapScheme", "rainbow");
-        style5_1.dataStyle().fillStyle().setColor("yellow");
-        style5_1.dataStyle().errorBarStyle().setVisible(false);
-        plotter5_1.createRegions(1, 2);
-
-        
-        IHistogram2D l1PosBot = aida.histogram2D("Layer 1 HTH Position:  Bottom", 50, -55, 55, 55, -25, 25);
-        IHistogram2D l7PosBot = aida.histogram2D("Layer 7 HTH Position:  Bottom", 50, -55, 55, 55, -25, 25);
-        plotter5_1.region(0).plot(l1PosBot);
-        plotter5_1.region(1).plot(l7PosBot);
-
-        if(showPlots) plotter5_1.show();
-
-        plotter55 = fac.createPlotterFactory().create("HPS Hit Positions");
-        plotter55.setTitle("Helical Track Hits");
-        //plotterFrame.addPlotter(plotter55);
-        IPlotterStyle style55 = plotter55.style();
-        style55.dataStyle().fillStyle().setColor("Green");
-        style55.dataStyle().errorBarStyle().setVisible(false);
-        style55.dataStyle().markerStyle().setSize(20);
-        plotter55.createRegions(1, 2);
-
-        IProfile avgLayersTopPlot = aida.profile1D("Number of Stereo Hits per layer in Top Half", 13, 0, 13);
-        IProfile avgLayersBottomPlot = aida.profile1D("Number of Stereo Hits per layer in Bottom Half", 13, 0, 13);
-
-        plotter55.region(0).plot(avgLayersTopPlot);
-        plotter55.region(1).plot(avgLayersBottomPlot);
-
-        if(showPlots) plotter55.show();
-
-        plotter6 = fac.createPlotterFactory().create("HPS ECAL Hit Positions");
-        plotter6.setTitle("ECAL Positions");
-        //plotterFrame.addPlotter(plotter6);
-        IPlotterStyle style6 = plotter6.style();
-        style6.setParameter("hist2DStyle", "colorMap");
-        style6.dataStyle().fillStyle().setParameter("colorMapScheme", "rainbow");
-        style6.dataStyle().fillStyle().setColor("yellow");
-        style6.dataStyle().errorBarStyle().setVisible(false);
-        plotter6.createRegions(4, 2);
-
-        IHistogram2D topECal = aida.histogram2D("Top ECal Cluster Position", 50, -400, 400, 10, 0, 100);
-        IHistogram2D botECal = aida.histogram2D("Bottom ECal Cluster Position", 50, -400, 400, 10, -100, 0);
-        IHistogram2D topECal1 = aida.histogram2D("Top ECal Cluster Position (>0 tracks)", 50, -400, 400, 10, 0, 100);
-        IHistogram2D botECal1 = aida.histogram2D("Bottom ECal Cluster Position (>0 tracks)", 50, -400, 400, 10, -100, 0);
-        IHistogram2D topECal2 = aida.histogram2D("Top ECal Cluster Position (E>0.1,>0 tracks)", 50, -400, 400, 10, 0, 100);
-        IHistogram2D botECal2 = aida.histogram2D("Bottom ECal Cluster Position (E>0.1,>0 tracks)", 50, -400, 400, 10, -100, 0);
-        IHistogram2D topECal3 = aida.histogram2D("Top ECal Cluster Position w_E (E>0.1,>0 tracks)", 50, -400, 400, 10, 0, 100);
-        IHistogram2D botECal3 = aida.histogram2D("Bottom ECal Cluster Position w_E (E>0.1,>0 tracks)", 50, -400, 400, 10, -100, 0);
-
-        plotter6.region(0).plot(topECal);
-        plotter6.region(1).plot(botECal);
-        plotter6.region(2).plot(topECal1);
-        plotter6.region(3).plot(botECal1);
-        plotter6.region(4).plot(topECal2);
-        plotter6.region(5).plot(botECal2);
-        plotter6.region(6).plot(topECal3);
-        plotter6.region(7).plot(botECal3);
-        
-        if(showPlots) plotter6.show();
-        
-        
-        plotter66 = fac.createPlotterFactory().create("HPS ECAL Basic Plots");
-        plotter66.setTitle("ECAL Basic Plots");
-        //plotterFrame.addPlotter(plotter6);
-        IPlotterStyle style66 = plotter66.style();
-        style66.dataStyle().fillStyle().setColor("yellow");
-        style66.dataStyle().errorBarStyle().setVisible(false);
-        plotter66.createRegions(2, 2);
-
-        IHistogram1D topECalE = aida.histogram1D("Top ECal Cluster Energy", 50, 0, 2);
-        IHistogram1D botECalE = aida.histogram1D("Bottom ECal Cluster Energy", 50, 0, 2);
-        IHistogram1D topECalN = aida.histogram1D("Number of Clusters Top", 6, 0, 6);
-        IHistogram1D botECalN = aida.histogram1D("Number of Clusters Bot", 6, 0, 6);
-        
-        plotter66.region(0).plot(topECalE);
-        plotter66.region(1).plot(botECalE);
-        plotter66.region(2).plot(botECalN);
-        plotter66.region(3).plot(topECalN);
-        
-        if(showPlots) plotter66.show();
-        
-        
-        plotter7 = fac.createPlotterFactory().create("HPS ECAL Hit Positions");
-        plotter7.setTitle("Basic Misc Stuff");
-        //plotterFrame.addPlotter(plotter7);
-        IPlotterStyle style7 = plotter7.style();
-        style7.setParameter("hist2DStyle", "colorMap");
-        style7.dataStyle().fillStyle().setParameter("colorMapScheme", "rainbow");
-        style7.dataStyle().fillStyle().setColor("yellow");
-        style7.dataStyle().errorBarStyle().setVisible(false);
-        plotter7.createRegions(2, 2);
-
-        IHistogram2D quadrants = aida.histogram2D("Charge vs Slope", 2, -1, 1, 2, -1, 1);
-        plotter7.region(0).plot(quadrants);
-        
-        if(showPlots) plotter7.show();
-        
-        plotter8 = fac.createPlotterFactory().create("HPS Strip Hit From Stereo Multiplicity");
-        plotter8.setTitle("Strip Hit Multiplicity");
-        //plotterFrame.addPlotter(plotter8);
-        IPlotterStyle style8 = plotter8.style();
-        style8.dataStyle().fillStyle().setColor("yellow");
-        style8.dataStyle().errorBarStyle().setVisible(false);
-        plotter8.createRegions(6, 6);
-        i=0;
-        for(SiSensor sensor : sensors) {
-            IHistogram1D resX = aida.histogram1D(sensor.getName() + " strip hits from stereo", 10, 0, 10);
-            plotter8.region(i).plot(resX);
-            i++;
-        }
-
-        if(showPlots) plotter8.show();
-        
-        plotter88 = fac.createPlotterFactory().create("HPS Strip Hit Multiplicity");
-        plotter88.setTitle("Strip Hit Multiplicity");
-        //plotterFrame.addPlotter(plotter88);
-        plotter88.setStyle(style8);
-        plotter88.createRegions(6, 6);
-        i=0;
-        for(SiSensor sensor : sensors) {
-            IHistogram1D resX = aida.histogram1D(sensor.getName() + " strip hits", 10, 0, 10);
-            plotter88.region(i).plot(resX);
-            i++;
-        }
-
-        if(showPlots) plotter88.show();
-        
-        
-        plotter9 = fac.createPlotterFactory().create("HPS Strip Hit On Track Multiplicity");
-        plotter9.setTitle("Strip Hit Multiplicity");
-        //plotterFrame.addPlotter(plotter9);
-        IPlotterStyle style9 = plotter9.style();
-        style9.dataStyle().fillStyle().setColor("yellow");
-        style9.dataStyle().errorBarStyle().setVisible(false);
-        plotter9.createRegions(6, 6);
-        i=0;
-        for(SiSensor sensor : sensors) {
-            IHistogram1D resX = aida.histogram1D(sensor.getName() + " strip hits on track", 3, 0, 3);
-            plotter9.region(i).plot(resX);
-            i++;
-        }
-
-        if(showPlots) plotter9.show();
-        
-        
-        plotter888 = fac.createPlotterFactory().create("HPS Strip Hit Isolation");
-        plotter888.setTitle("Strip Hit Isolation");
-        //plotterFrame.addPlotter(plotter88);
-        plotter888.setStyle(style8);
-        plotter888.createRegions(6, 6);
-        i=0;
-        for(SiSensor sensor : sensors) {
-            IHistogram1D resX = aida.histogram1D(sensor.getName() + " strip hits iso", 50, 0, 5);
-            plotter888.region(i).plot(resX);
-            i++;
-        }
-
-        if(showPlots) plotter888.show();
-        
-        plotter8888 = fac.createPlotterFactory().create("HPS Strip Hit On Track Isolation");
-        plotter8888.setTitle("Strip Hit On Track Isolation");
-        //plotterFrame.addPlotter(plotter88);
-        plotter8888.setStyle(style8);
-        plotter8888.createRegions(6, 6);
-        i=0;
-        for(SiSensor sensor : sensors) {
-            IHistogram1D resX = aida.histogram1D(sensor.getName() + " strip hits iso on track", 50, 0, 5);
-            plotter8888.region(i).plot(resX);
-            i++;
-        }
-
-        if(showPlots) plotter8888.show();
-
-
+        
+        setupPlots();
     }
+    
+    
+    
+    
+    
+    
 
     public TrackingReconstructionPlots() {
         LOGGER.setLevel(Level.WARNING);
@@ -1170,13 +351,8 @@
 
             int isTop = -1;
             if (trk.getTrackerHits().get(0).getPosition()[2] > 0) {
-                isTop = 0;//make plot look pretty
-            }
-            int charge = trk.getCharge();
-            if (charge > 0) {
-                charge = 0;//make plot look pretty
-            }//            System.out.println("Charge = " + charge + "; isTop = " + isTop);
-            aida.histogram2D("Charge vs Slope").fill(charge, isTop);
+                isTop = 0;
+            }
             if (isTop == 0) {
                 aida.histogram1D("Top Track Momentum (Px)").fill(trk.getTrackStates().get(0).getMomentum()[1]);
                 aida.histogram1D("Top Track Momentum (Py)").fill(trk.getTrackStates().get(0).getMomentum()[2]);
@@ -1304,8 +480,6 @@
                     layersBot[htc.Layer() - 1]++;
                     Hep3Vector sensorPos = ((SiSensor) ((RawTrackerHit) htc.getRawHits().get(0)).getDetectorElement()).getGeometry().getPosition();
                     if (htc.Layer() == 1) {
-//                    System.out.println(sensorPos.toString());
-//                    System.out.println("Hit X = " + x + "; Hit Y = " + y);
                         aida.histogram2D("Layer 1 HTH Position:  Bottom").fill(x - sensorPos.x(), y - sensorPos.y());
                     }
                     if (htc.Layer() == 7) {
@@ -1319,7 +493,7 @@
                         double clusterSum = 0;
                         double clusterT0 = 0;
                         int nHitsCluster = 0;
-                                
+                        
                         for (RawTrackerHit rawHit : (List<RawTrackerHit>) hts.rawhits()) {
                             if(event.hasCollection(LCRelation.class, "SVTFittedRawTrackerHits")) {
                                 List<LCRelation> fittedHits = event.get(LCRelation.class, "SVTFittedRawTrackerHits");
@@ -1361,7 +535,6 @@
             }
             
             for(Map.Entry<HpsSiSensor,Integer> sensor : stripHitsOnTrack.entrySet()) {
-                aida.histogram1D(sensor.getKey().getName() + " strip hits on track").fill(sensor.getValue());
                 aida.histogram1D(sensor.getKey().getName() + " strip hits iso on track").fill(stripHitsIsoOnTrack.get(sensor.getKey()));
             }
             
@@ -1645,6 +818,813 @@
 
 
     
+    
+private void setupPlots() {
+        
+        
+        IAnalysisFactory fac = aida.analysisFactory();
+        plotter = fac.createPlotterFactory().create("HPS Tracking Plots");
+        plotter.setTitle("Momentum");
+        IPlotterStyle style = plotter.style();
+        style.dataStyle().fillStyle().setColor("yellow");
+        style.dataStyle().errorBarStyle().setVisible(false);
+        plotter.createRegions(2, 2);
+        //plotterFrame.addPlotter(plotter);
+
+        trkPx = aida.histogram1D("Track Momentum (Px)", 25, -0.25, 0.25);
+        IHistogram1D trkPy = aida.histogram1D("Track Momentum (Py)", 25, -0.5, 0.5);
+        IHistogram1D trkPz = aida.histogram1D("Track Momentum (Pz)", 25, 0, 1.5);
+        IHistogram1D trkChi2 = aida.histogram1D("Track Chi2", 25, 0, 25.0);
+
+        plotter.region(0).plot(trkPx);
+        plotter.region(1).plot(trkPy);
+        plotter.region(2).plot(trkPz);
+        plotter.region(3).plot(trkChi2);
+
+        if(showPlots) plotter.show();
+
+//   ******************************************************************
+        top1 = fac.createPlotterFactory().create("Top Tracking Plots");
+        top1.setTitle("Top Momentum");
+        IPlotterStyle stop1 = top1.style();
+        stop1.dataStyle().fillStyle().setColor("green");
+        stop1.dataStyle().errorBarStyle().setVisible(false);
+        top1.createRegions(2, 2);
+        //topFrame.addPlotter(top1);
+
+        IHistogram1D toptrkPx = aida.histogram1D("Top Track Momentum (Px)", 25, -0.25, 0.25);
+        IHistogram1D toptrkPy = aida.histogram1D("Top Track Momentum (Py)", 25, -0.5, 0.5);
+        IHistogram1D toptrkPz = aida.histogram1D("Top Track Momentum (Pz)", 25, 0, 1.5);
+        IHistogram1D toptrkChi2 = aida.histogram1D("Top Track Chi2", 25, 0, 25.0);
+
+        top1.region(0).plot(toptrkPx);
+        top1.region(1).plot(toptrkPy);
+        top1.region(2).plot(toptrkPz);
+        top1.region(3).plot(toptrkChi2);
+
+        if(showPlots) top1.show();
+
+        bot1 = fac.createPlotterFactory().create("Bottom Tracking Plots");
+        bot1.setTitle("Bottom Momentum");
+        IPlotterStyle sbot1 = bot1.style();
+        sbot1.dataStyle().fillStyle().setColor("blue");
+        sbot1.dataStyle().errorBarStyle().setVisible(false);
+        bot1.createRegions(2, 2);
+        //bottomFrame.addPlotter(bot1);
+
+        IHistogram1D bottrkPx = aida.histogram1D("Bottom Track Momentum (Px)", 25, -0.25, 0.25);
+        IHistogram1D bottrkPy = aida.histogram1D("Bottom Track Momentum (Py)", 25, -0.5, 0.5);
+        IHistogram1D bottrkPz = aida.histogram1D("Bottom Track Momentum (Pz)", 25, 0, 1.5);
+        IHistogram1D bottrkChi2 = aida.histogram1D("Bottom Track Chi2", 25, 0, 25.0);
+
+        bot1.region(0).plot(bottrkPx);
+        bot1.region(1).plot(bottrkPy);
+        bot1.region(2).plot(bottrkPz);
+        bot1.region(3).plot(bottrkChi2);
+
+        if(showPlots) bot1.show();
+
+//   ******************************************************************
+        IHistogram1D trkd0 = aida.histogram1D("d0 ", 25, -10.0, 10.0);
+        IHistogram1D trkphi = aida.histogram1D("sinphi ", 25, -0.2, 0.2);
+        IHistogram1D trkomega = aida.histogram1D("omega ", 25, -0.0025, 0.0025);
+        IHistogram1D trklam = aida.histogram1D("tan(lambda) ", 25, -0.1, 0.1);
+        IHistogram1D trkz0 = aida.histogram1D("z0 ", 25, -6.0, 6.0);
+
+        plotter22 = fac.createPlotterFactory().create("HPS Track Params");
+        plotter22.setTitle("Track parameters");
+        //plotterFrame.addPlotter(plotter22);
+        IPlotterStyle style22 = plotter22.style();
+        style22.dataStyle().fillStyle().setColor("yellow");
+        style22.dataStyle().errorBarStyle().setVisible(false);
+        plotter22.createRegions(2, 3);
+        plotter22.region(0).plot(trkd0);
+        plotter22.region(1).plot(trkphi);
+        plotter22.region(2).plot(trkomega);
+        plotter22.region(3).plot(trklam);
+        plotter22.region(4).plot(trkz0);
+        
+        if(showPlots) plotter22.show();
+
+ //   ******************************************************************
+
+        
+         trkd0 = aida.histogram1D("d0 Top", 25, -10.0, 10.0);
+         trkphi = aida.histogram1D("sinphi Top", 25, -0.2, 0.2);
+         trkomega = aida.histogram1D("omega Top", 25, -0.0025, 0.0025);
+         trklam = aida.histogram1D("tan(lambda) Top", 25, -0.1, 0.1);
+         trkz0 = aida.histogram1D("z0 Top", 25, -6.0, 6.0);
+
+        plotter2221 = fac.createPlotterFactory().create("HPS Track Params");
+        plotter2221.setTitle("Track parameters");
+        //plotterFrame.addPlotter(plotter22);
+        IPlotterStyle style2221 = plotter2221.style();
+        style2221.dataStyle().fillStyle().setColor("yellow");
+        style2221.dataStyle().errorBarStyle().setVisible(false);
+        plotter2221.createRegions(2, 3);
+        plotter2221.region(0).plot(trkd0);
+        plotter2221.region(1).plot(trkphi);
+        plotter2221.region(2).plot(trkomega);
+        plotter2221.region(3).plot(trklam);
+        plotter2221.region(4).plot(trkz0);
+        
+        if(showPlots) plotter2221.show();
+        
+        
+   //   ******************************************************************
+
+        
+        trkd0 = aida.histogram1D("d0 Bottom", 25, -10.0, 10.0);
+        trkphi = aida.histogram1D("sinphi Bottom", 25, -0.2, 0.2);
+        trkomega = aida.histogram1D("omega Bottom", 25, -0.0025, 0.0025);
+        trklam = aida.histogram1D("tan(lambda) Bottom", 25, -0.1, 0.1);
+        trkz0 = aida.histogram1D("z0 Bottom", 25, -6.0, 6.0);
+
+       plotter2222 = fac.createPlotterFactory().create("HPS Track Params");
+       plotter2222.setTitle("Track parameters");
+       //plotterFrame.addPlotter(plotter22);
+       IPlotterStyle style2222 = plotter2222.style();
+       style2222.dataStyle().fillStyle().setColor("yellow");
+       style2222.dataStyle().errorBarStyle().setVisible(false);
+       plotter2222.createRegions(2, 3);
+       plotter2222.region(0).plot(trkd0);
+       plotter2222.region(1).plot(trkphi);
+       plotter2222.region(2).plot(trkomega);
+       plotter2222.region(3).plot(trklam);
+       plotter2222.region(4).plot(trkz0);
+       
+       if(showPlots) plotter2222.show();
+        
+        
+        
+   //   ******************************************************************
+
+        
+        plotter2 = fac.createPlotterFactory().create("HPS Tracking Plots");
+        plotter2.setTitle("Track extrapolation");
+        //plotterFrame.addPlotter(plotter2);
+        IPlotterStyle style2 = plotter2.style();
+        style2.dataStyle().fillStyle().setColor("yellow");
+        style2.dataStyle().errorBarStyle().setVisible(false);
+        plotter2.createRegions(2, 4);
+        IHistogram1D xAtConverter = aida.histogram1D("X (mm) @ Z=-60cm", 50, -50, 50);
+        IHistogram1D yAtConverter = aida.histogram1D("Y (mm) @ Z=-60cm", 50, -20, 20);
+        IHistogram1D xAtColl = aida.histogram1D("X (mm) @ Z=-150cm", 50, -200, 200);
+        IHistogram1D yAtColl = aida.histogram1D("Y (mm) @ Z=-150cm", 50, -200, 200);
+        IHistogram1D xAtEcal = aida.histogram1D("X (mm) @ ECAL", 50, -500, 500);
+        IHistogram1D yAtEcal = aida.histogram1D("Y (mm) @ ECAL", 50, -100, 100);
+        IHistogram1D xAtEcal2 = aida.histogram1D("X (mm) @ ECAL (Pz>1)", 50, -500, 500);
+        IHistogram1D yAtEcal2 = aida.histogram1D("Y (mm) @ ECAL (Pz>1)", 50, -100, 100);
+
+        plotter2.region(0).plot(xAtConverter);
+        plotter2.region(4).plot(yAtConverter);
+        plotter2.region(1).plot(xAtColl);
+        plotter2.region(5).plot(yAtColl);
+        plotter2.region(2).plot(xAtEcal);
+        plotter2.region(6).plot(yAtEcal);
+        plotter2.region(3).plot(xAtEcal2);
+        plotter2.region(7).plot(yAtEcal2);
+        
+        if(showPlots) plotter2.show();
+
+   //   ******************************************************************
+        
+        plotter222 = fac.createPlotterFactory().create("HPS Tracking Plots");
+        plotter222.setTitle("HPS Tracking Plots");
+        //plotterFrame.addPlotter(plotter222);
+        IPlotterStyle style222 = plotter222.style();
+        style222.dataStyle().fillStyle().setColor("yellow");
+        style222.dataStyle().errorBarStyle().setVisible(false);
+        plotter222.createRegions(2, 2);
+        
+        IHistogram1D nHits = aida.histogram1D("Hits per Track", 4, 3, 7);
+        nTracks = aida.histogram1D("Tracks per Event", 3, 0, 3);
+        IHistogram1D nHitsCluster = aida.histogram1D("Hits in Cluster (HitOnTrack)", 4, 0, 4);
+
+       
+        plotter222.region(0).plot(nHits);
+        plotter222.region(1).plot(nTracks);
+        plotter222.region(2).plot(nHitsCluster);
+        
+        if(showPlots) plotter222.show();
+   
+        
+   //   ******************************************************************
+        
+        plotter22299 = fac.createPlotterFactory().create("HPS Tracking Plots Top");
+        plotter22299.setTitle("HPS Tracking Plots Top");
+        //plotterFrame.addPlotter(plotter22299);
+        IPlotterStyle style22299 = plotter22299.style();
+        style22299.dataStyle().fillStyle().setColor("yellow");
+        style22299.dataStyle().errorBarStyle().setVisible(false);
+        plotter22299.createRegions(2, 2);
+        
+        IHistogram1D nHitsTop = aida.histogram1D("Hits per Track Top", 4, 3, 7);
+        nTracksTop = aida.histogram1D("Tracks per Event Top", 3, 0, 3);
+        IHistogram1D nHitsClusterTop = aida.histogram1D("Hits in Cluster (HitOnTrack) Top", 4, 0, 4);
+
+       
+        plotter22299.region(0).plot(nHitsTop);
+        plotter22299.region(1).plot(nTracksTop);
+        plotter22299.region(2).plot(nHitsClusterTop);
+        
+        if(showPlots) plotter22299.show();
+   
+//   ******************************************************************
+        
+        plotter22298 = fac.createPlotterFactory().create("HPS Tracking Plots Bottom");
+        plotter22298.setTitle("HPS Tracking Plots Bottom");
+        //plotterFrame.addPlotter(plotter22298);
+        IPlotterStyle style22298 = plotter22298.style();
+        style22298.dataStyle().fillStyle().setColor("yellow");
+        style22298.dataStyle().errorBarStyle().setVisible(false);
+        plotter22298.createRegions(2, 2);
+        
+        IHistogram1D nHitsBot = aida.histogram1D("Hits per Track Bot", 4, 3, 7);
+        nTracksBot = aida.histogram1D("Tracks per Event Bot", 3, 0, 3);
+        IHistogram1D nHitsClusterBot = aida.histogram1D("Hits in Cluster (HitOnTrack) Bot", 4, 0, 4);
+
+       
+        plotter22298.region(0).plot(nHitsBot);
+        plotter22298.region(1).plot(nTracksBot);
+        plotter22298.region(2).plot(nHitsClusterBot);
+        
+        if(showPlots) plotter22298.show();
+   
+        
+        //   ******************************************************************
+        
+        
+        plotter2223 = fac.createPlotterFactory().create("Cluster Amp Plots");
+        plotter2223.setTitle("Other");
+        //plotterFrame.addPlotter(plotter222);
+        IPlotterStyle style2223 = plotter2223.style();
+        style2223.dataStyle().fillStyle().setColor("yellow");
+        style2223.dataStyle().errorBarStyle().setVisible(false);
+        plotter2223.createRegions(2, 2);
+        
+       
+
+        IHistogram1D amp = aida.histogram1D("Amp (HitOnTrack)", 50, 0, 5000);
+        IHistogram1D ampcl = aida.histogram1D("Cluster Amp (HitOnTrack)", 50, 0, 5000);
+        IHistogram1D amp2 = aida.histogram1D("Amp Pz>0.8 (HitOnTrack)", 50, 0, 5000);
+        IHistogram1D ampcl2 = aida.histogram1D("Cluster Amp Pz>0.8 (HitOnTrack)", 50, 0, 5000);
+      
+        
+        plotter2223.region(0).plot(amp);
+        plotter2223.region(1).plot(amp2);
+        plotter2223.region(2).plot(ampcl);
+        plotter2223.region(3).plot(ampcl2);
+        
+        if(showPlots) plotter2223.show();
+   
+//   ******************************************************************
+        
+        
+        plotter2224 = fac.createPlotterFactory().create("t0 Plots");
+        plotter2224.setTitle("Other");
+        IPlotterStyle style2224 = plotter2224.style();
+        style2224.dataStyle().fillStyle().setColor("yellow");
+        style2224.dataStyle().errorBarStyle().setVisible(false);
+        plotter2224.createRegions(2, 2);
+                
+        IHistogram1D t0 = aida.histogram1D("t0 (HitOnTrack)", 50, -100, 100);
+        IHistogram1D t0cl = aida.histogram1D("Cluster t0 (HitOnTrack)", 50, -100, 100);
+        IHistogram1D t02 = aida.histogram1D("t0 Pz>0.8 (HitOnTrack)", 50, -100, 100);
+        IHistogram1D t0cl2 = aida.histogram1D("Cluster t0 Pz>0.8 (HitOnTrack)", 50, -100, 100);
+        
+        plotter2224.region(0).plot(t0);
+        plotter2224.region(1).plot(t0cl);
+        plotter2224.region(2).plot(t02);
+        plotter2224.region(3).plot(t0cl2);
+
+        if(showPlots) plotter2224.show();
+   
+        
+        //   ******************************************************************
+          
+        plotter3 = fac.createPlotterFactory().create("HPS Layer Residual Plots");
+        plotter3.setTitle("Layer Residuals");
+        //plotterFrame.addPlotter(plotter3);
+        IPlotterStyle style3 = plotter3.style();
+        style3.dataStyle().fillStyle().setColor("yellow");
+        style3.dataStyle().errorBarStyle().setVisible(false);
+        plotter3.createRegions(6, 2);
+
+       
+
+        IHistogram1D mod1ResX = aida.histogram1D("Layer 1 Residual X(mm)", 25, -1, 1);
+        IHistogram1D mod1ResY = aida.histogram1D("Layer 1 Residual Y(mm)", 25, -0.04, 0.04);
+
+        IHistogram1D mod2ResX = aida.histogram1D("Layer 2 Residual X(mm)", 25, -2, 2);
+        IHistogram1D mod2ResY = aida.histogram1D("Layer 2 Residual Y(mm)", 25, -1, 1);
+
+        IHistogram1D mod3ResX = aida.histogram1D("Layer 3 Residual X(mm)", 25, -2.5, 2.5);
+        IHistogram1D mod3ResY = aida.histogram1D("Layer 3 Residual Y(mm)", 25, -1.5, 1.5);
+
+        IHistogram1D mod4ResX = aida.histogram1D("Layer 4 Residual X(mm)", 25, -3.0, 3.0);
+        IHistogram1D mod4ResY = aida.histogram1D("Layer 4 Residual Y(mm)", 25, -2, 2);
+
+        IHistogram1D mod5ResX = aida.histogram1D("Layer 5 Residual X(mm)", 25, -4, 4);
+        IHistogram1D mod5ResY = aida.histogram1D("Layer 5 Residual Y(mm)", 25, -3, 3);
+
+        IHistogram1D mod6ResX = aida.histogram1D("Layer 6 Residual X(mm)", 25, -5, 5);
+        IHistogram1D mod6ResY = aida.histogram1D("Layer 6 Residual Y(mm)", 25, -3, 3);
+
+        plotter3.region(0).plot(mod1ResX);
+        plotter3.region(2).plot(mod2ResX);
+        plotter3.region(4).plot(mod3ResX);
+        plotter3.region(6).plot(mod4ResX);
+        plotter3.region(8).plot(mod5ResX);
+        plotter3.region(10).plot(mod6ResX);
+
+        plotter3.region(1).plot(mod1ResY);
+        plotter3.region(3).plot(mod2ResY);
+        plotter3.region(5).plot(mod3ResY);
+        plotter3.region(7).plot(mod4ResY);
+        plotter3.region(9).plot(mod5ResY);
+        plotter3.region(11).plot(mod6ResY);
+               
+        if(showPlots) plotter3.show();
+        
+        
+        
+        plotter3_11 = fac.createPlotterFactory().create("HPS Strip Residual Plots");
+        plotter3_11.setTitle("Strip Residuals (Top)");
+        //plotterFrame.addPlotter(plotter3_11);
+        IPlotterStyle style3_11 = plotter3_11.style();
+        style3_11.dataStyle().fillStyle().setColor("yellow");
+        style3_11.dataStyle().errorBarStyle().setVisible(false);
+        plotter3_11.createRegions(6, 6);
+        int i=0;
+        for(HpsSiSensor sensor : sensors) {
+            double min = 0.0;
+            double max = 0.0;
+            if(sensor.getName().contains("L1")) {
+                min=-0.04; max=0.04;
+            } else if(sensor.getName().contains("L2")) {
+                min=-1; max=1;
+            } else if(sensor.getName().contains("L3")) {
+                min=-1.5; max=1.5;
+            } else if(sensor.getName().contains("L4")) {
+                min=-3; max=3;
+            } else if(sensor.getName().contains("L5")) {
+                min=-4; max=4;
+            } else if(sensor.getName().contains("L6")) {
+                min=-5; max=5;
+            } else {
+                throw new RuntimeException("Invalid sensor name: " + sensor.getName());
+            }
+           IHistogram1D resX = aida.histogram1D(sensor.getName() + " strip residual (mm)", 50, min, max);
+            plotter3_11.region(i).plot(resX);
+            i++;
+        }
+
+        if(showPlots) plotter3_11.show();
+        
+
+        plotter3_1 = fac.createPlotterFactory().create("HPS Residual Plots (Single hit per layer)");
+        plotter3_1.setTitle("Residuals (Top)");
+        //plotterFrame.addPlotter(plotter3_1);
+        IPlotterStyle style3_1 = plotter3_1.style();
+        style3_1.dataStyle().fillStyle().setColor("yellow");
+        style3_1.dataStyle().errorBarStyle().setVisible(false);
+        plotter3_1.createRegions(6, 2);
+        
+        IHistogram1D mod1ResX_Top = aida.histogram1D("Layer 1 Residual X(mm) Top", 25, -1, 1);
+        IHistogram1D mod1ResY_Top = aida.histogram1D("Layer 1 Residual Y(mm) Top", 25, -0.04, 0.04);
+
+        IHistogram1D mod2ResX_Top = aida.histogram1D("Layer 2 Residual X(mm) Top", 25, -2, 2);
+        IHistogram1D mod2ResY_Top = aida.histogram1D("Layer 2 Residual Y(mm) Top", 25, -1, 1);
+
+        IHistogram1D mod3ResX_Top = aida.histogram1D("Layer 3 Residual X(mm) Top", 25, -2.5, 2.5);
+        IHistogram1D mod3ResY_Top = aida.histogram1D("Layer 3 Residual Y(mm) Top", 25, -1.5, 1.5);
+
+        IHistogram1D mod4ResX_Top = aida.histogram1D("Layer 4 Residual X(mm) Top", 25, -3.0, 3.0);
+        IHistogram1D mod4ResY_Top = aida.histogram1D("Layer 4 Residual Y(mm) Top", 25, -2, 2);
+
+        IHistogram1D mod5ResX_Top = aida.histogram1D("Layer 5 Residual X(mm) Top", 25, -4, 4);
+        IHistogram1D mod5ResY_Top = aida.histogram1D("Layer 5 Residual Y(mm) Top", 25, -3, 3);
+
+        IHistogram1D mod6ResX_Top = aida.histogram1D("Layer 6 Residual X(mm) Top", 25, -5, 5);
+        IHistogram1D mod6ResY_Top = aida.histogram1D("Layer 6 Residual Y(mm) Top", 25, -3, 3);
+
+        
+        plotter3_1.region(0).plot(mod1ResX_Top);
+        plotter3_1.region(2).plot(mod2ResX_Top);
+        plotter3_1.region(4).plot(mod3ResX_Top);
+        plotter3_1.region(6).plot(mod4ResX_Top);
+        plotter3_1.region(8).plot(mod5ResX_Top);
+        plotter3_1.region(10).plot(mod6ResX_Top);
+
+        plotter3_1.region(1).plot(mod1ResY_Top);
+        plotter3_1.region(3).plot(mod2ResY_Top);
+        plotter3_1.region(5).plot(mod3ResY_Top);
+        plotter3_1.region(7).plot(mod4ResY_Top);
+        plotter3_1.region(9).plot(mod5ResY_Top);
+        plotter3_1.region(11).plot(mod6ResY_Top);
+
+        if(showPlots) plotter3_1.show();
+        
+        plotter3_2 = fac.createPlotterFactory().create("HPS Residual Plots (Single strip cluster per layer)");
+        plotter3_2.setTitle("Residuals (Bottom)");
+        //plotterFrame.addPlotter(plotter3_2);
+        IPlotterStyle style3_2 = plotter3_2.style();
+        style3_2.dataStyle().fillStyle().setColor("yellow");
+        style3_2.dataStyle().errorBarStyle().setVisible(false);
+        plotter3_2.createRegions(6, 2);
+
+        IHistogram1D mod1ResX_Bottom = aida.histogram1D("Layer 1 Residual X(mm) Bottom", 25, -1, 1);
+        IHistogram1D mod1ResY_Bottom = aida.histogram1D("Layer 1 Residual Y(mm) Bottom", 25, -0.04, 0.04);
+
+        IHistogram1D mod2ResX_Bottom = aida.histogram1D("Layer 2 Residual X(mm) Bottom", 25, -2, 2);
+        IHistogram1D mod2ResY_Bottom = aida.histogram1D("Layer 2 Residual Y(mm) Bottom", 25, -1, 1);
+
+        IHistogram1D mod3ResX_Bottom = aida.histogram1D("Layer 3 Residual X(mm) Bottom", 25, -2.5, 2.5);
+        IHistogram1D mod3ResY_Bottom = aida.histogram1D("Layer 3 Residual Y(mm) Bottom", 25, -1.5, 1.5);
+
+        IHistogram1D mod4ResX_Bottom = aida.histogram1D("Layer 4 Residual X(mm) Bottom", 25, -3.0, 3.0);
+        IHistogram1D mod4ResY_Bottom = aida.histogram1D("Layer 4 Residual Y(mm) Bottom", 25, -2, 2);
+
+        IHistogram1D mod5ResX_Bottom = aida.histogram1D("Layer 5 Residual X(mm) Bottom", 25, -4, 4);
+        IHistogram1D mod5ResY_Bottom = aida.histogram1D("Layer 5 Residual Y(mm) Bottom", 25, -3, 3);
+
+        IHistogram1D mod6ResX_Bottom = aida.histogram1D("Layer 6 Residual X(mm) Bottom", 25, -5, 5);
+        IHistogram1D mod6ResY_Bottom = aida.histogram1D("Layer 6 Residual Y(mm) Bottom", 25, -3, 3);
+
+        plotter3_2.region(0).plot(mod1ResX_Bottom);
+        plotter3_2.region(2).plot(mod2ResX_Bottom);
+        plotter3_2.region(4).plot(mod3ResX_Bottom);
+        plotter3_2.region(6).plot(mod4ResX_Bottom);
+        plotter3_2.region(8).plot(mod5ResX_Bottom);
+        plotter3_2.region(10).plot(mod6ResX_Bottom);
+
+        plotter3_2.region(1).plot(mod1ResY_Bottom);
+        plotter3_2.region(3).plot(mod2ResY_Bottom);
+        plotter3_2.region(5).plot(mod3ResY_Bottom);
+        plotter3_2.region(7).plot(mod4ResY_Bottom);
+        plotter3_2.region(9).plot(mod5ResY_Bottom);
+        plotter3_2.region(11).plot(mod6ResY_Bottom);
+        
+        if(showPlots) plotter3_2.show();
+
+        plotter4 = fac.createPlotterFactory().create("HPS Track and ECal Plots");
+        plotter4.setTitle("Track and ECal Correlations");
+        //plotterFrame.addPlotter(plotter4);
+        IPlotterStyle style4 = plotter4.style();
+        style4.setParameter("hist2DStyle", "colorMap");
+        style4.dataStyle().fillStyle().setParameter("colorMapScheme", "rainbow");
+        style4.dataStyle().fillStyle().setColor("yellow");
+        style4.dataStyle().errorBarStyle().setVisible(false);
+        plotter4.createRegions(2, 3);
+
+        IHistogram2D eVsP = aida.histogram2D("Energy Vs Momentum", 50, 0, 0.50, 50, 0, 1.5);
+        IHistogram1D eOverP = aida.histogram1D("Energy Over Momentum", 50, 0, 2);
+
+        IHistogram1D distX = aida.histogram1D("deltaX", 50, -100, 100);
+        IHistogram1D distY = aida.histogram1D("deltaY", 50, -40, 40);
+
+        IHistogram2D xEcalVsTrk = aida.histogram2D("X ECal Vs Track", 100, -400, 400, 100, -400, 400);
+        IHistogram2D yEcalVsTrk = aida.histogram2D("Y ECal Vs Track", 100, -100, 100, 100, -100, 100);
+
+        plotter4.region(0).plot(eVsP);
+        plotter4.region(3).plot(eOverP);
+        plotter4.region(1).plot(distX);
+        plotter4.region(4).plot(distY);
+        plotter4.region(2).plot(xEcalVsTrk);
+        plotter4.region(5).plot(yEcalVsTrk);
+
+        if(showPlots) plotter4.show();
+
+        //   ******************************************************************
+        top2 = fac.createPlotterFactory().create("Top ECal Plots");
+        top2.setTitle("Top ECal Correlations");
+        IPlotterStyle stop2 = top2.style();
+        stop2.dataStyle().fillStyle().setColor("green");
+        stop2.dataStyle().errorBarStyle().setVisible(false);
+        stop2.setParameter("hist2DStyle", "colorMap");
+        stop2.dataStyle().fillStyle().setParameter("colorMapScheme", "rainbow");
+        top2.createRegions(2, 3);
+        //topFrame.addPlotter(top2);
+
+        IHistogram2D topeVsP = aida.histogram2D("Top Energy Vs Momentum", 50, 0, 0.500, 50, 0, 1.5);
+        IHistogram1D topeOverP = aida.histogram1D("Top Energy Over Momentum", 50, 0, 2);
+
+        IHistogram1D topdistX = aida.histogram1D("Top deltaX", 50, -100, 100);
+        IHistogram1D topdistY = aida.histogram1D("Top deltaY", 50, -40, 40);
+
+        IHistogram2D topxEcalVsTrk = aida.histogram2D("Top X ECal Vs Track", 100, -400, 400, 100, -100, 100);
+        IHistogram2D topyEcalVsTrk = aida.histogram2D("Top Y ECal Vs Track", 100, 0, 100, 100, 0, 100);
+
+        top2.region(0).plot(topeVsP);
+        top2.region(3).plot(topeOverP);
+        top2.region(1).plot(topdistX);
+        top2.region(4).plot(topdistY);
+        top2.region(2).plot(topxEcalVsTrk);
+        top2.region(5).plot(topyEcalVsTrk);
+
+        if(showPlots) top2.show();
+        
+        bot2 = fac.createPlotterFactory().create("Bottom ECal Plots");
+        bot2.setTitle("Bottom ECal Correlations");
+        IPlotterStyle sbot2 = bot2.style();
+        sbot2.dataStyle().fillStyle().setColor("green");
+        sbot2.dataStyle().errorBarStyle().setVisible(false);
+        sbot2.setParameter("hist2DStyle", "colorMap");
+        sbot2.dataStyle().fillStyle().setParameter("colorMapScheme", "rainbow");
+        bot2.createRegions(2, 3);
+        //bottomFrame.addPlotter(bot2);
+
+        IHistogram2D BottomeVsP = aida.histogram2D("Bottom Energy Vs Momentum", 50, 0, 0.500, 50, 0, 1.5);
+        IHistogram1D BottomeOverP = aida.histogram1D("Bottom Energy Over Momentum", 50, 0, 2);
+
+        IHistogram1D BottomdistX = aida.histogram1D("Bottom deltaX", 50, -100, 100);
+        IHistogram1D BottomdistY = aida.histogram1D("Bottom deltaY", 50, -40, 40);
+
+        IHistogram2D BottomxEcalVsTrk = aida.histogram2D("Bottom X ECal Vs Track", 100, -400, 400, 100, -400, 400);
+        IHistogram2D BottomyEcalVsTrk = aida.histogram2D("Bottom Y ECal Vs Track", 100, -100, 0, 100, -100, 0);
+
+        bot2.region(0).plot(BottomeVsP);
+        bot2.region(3).plot(BottomeOverP);
+        bot2.region(1).plot(BottomdistX);
+        bot2.region(4).plot(BottomdistY);
+        bot2.region(2).plot(BottomxEcalVsTrk);
+        bot2.region(5).plot(BottomyEcalVsTrk);
+
+        if(showPlots) bot2.show();
+        
+        
+        //   ******************************************************************
+        top3 = fac.createPlotterFactory().create("Top ECal Plots");
+        top3.setTitle("Top ECal More Correlations");
+        IPlotterStyle stop3 = top3.style();
+        stop3.dataStyle().fillStyle().setColor("green");
+        stop3.dataStyle().errorBarStyle().setVisible(false);
+        stop3.setParameter("hist2DStyle", "colorMap");
+        stop3.dataStyle().fillStyle().setParameter("colorMapScheme", "rainbow");
+        top3.createRegions(1, 2);
+        //topFrame.addPlotter(top3);
+
+        IHistogram2D topdistXvsX = aida.histogram2D("Top deltaX vs X", 51, -400, 400, 25, -100, 100);
+        IHistogram2D topdistYvsY = aida.histogram2D("Top deltaY vs Y", 51, 0, 100, 25, -40, 40);
+
+        top3.region(0).plot(topdistXvsX);
+        top3.region(1).plot(topdistYvsY);
+
+        if(showPlots) top3.show();
+        
+        bot3 = fac.createPlotterFactory().create("Bottom ECal Plots");
+        bot3.setTitle("Bottom ECal More Correlations");
+        IPlotterStyle sbot3 = bot3.style();
+        sbot3.dataStyle().fillStyle().setColor("green");
+        sbot3.dataStyle().errorBarStyle().setVisible(false);
+        sbot3.setParameter("hist2DStyle", "colorMap");
+        sbot3.dataStyle().fillStyle().setParameter("colorMapScheme", "rainbow");
+        bot3.createRegions(1, 2);
+        //bottomFrame.addPlotter(bot3);
+
+        IHistogram2D botdistXvsX = aida.histogram2D("Bottom deltaX vs X", 51, -400, 400, 25, -100, 100);
+        IHistogram2D botdistYvsY = aida.histogram2D("Bottom deltaY vs Y", 51, -100, 0, 25, -40, 40);
+
+        bot3.region(0).plot(botdistXvsX);
+        bot3.region(1).plot(botdistYvsY);
+
+        if(showPlots) bot3.show();
+        
+        //   ******************************************************************
+        top4 = fac.createPlotterFactory().create("Track Matching Plots");
+        top4.setTitle("Track Matching Plots");
+        IPlotterStyle stop4 = top4.style();
+        stop4.dataStyle().fillStyle().setColor("green");
+        stop4.dataStyle().errorBarStyle().setVisible(false);
+        stop4.setParameter("hist2DStyle", "colorMap");
+        stop4.dataStyle().fillStyle().setParameter("colorMapScheme", "rainbow");
+        top4.createRegions(2, 3);
+        //topFrame.addPlotter(top4);
+
+        IHistogram1D trackmatchN = aida.histogram1D("Tracks matched", 3, 0, 3);
+        IHistogram1D toptrackmatchN = aida.histogram1D("Tracks matched Top", 3, 0, 3);
+        IHistogram1D bottrackmatchN = aida.histogram1D("Tracks matched Bottom", 3, 0, 3);
+        IHistogram1D trackmatchN2 = aida.histogram1D("Tracks matched (Pz>0.8)", 3, 0, 3);
+        IHistogram1D toptrackmatchN2 = aida.histogram1D("Tracks matched Top (Pz>0.8)", 3, 0, 3);
+        IHistogram1D bottrackmatchN2 = aida.histogram1D("Tracks matched Bottom (Pz>0.8)", 3, 0, 3);
+        
+        top4.region(0).plot(trackmatchN);
+        top4.region(1).plot(toptrackmatchN);
+        top4.region(2).plot(bottrackmatchN);
+        top4.region(3).plot(trackmatchN2);
+        top4.region(4).plot(toptrackmatchN2);
+        top4.region(5).plot(bottrackmatchN2);
+
+        if(showPlots) top4.show();
+        
+        //   ******************************************************************
+        top44 = fac.createPlotterFactory().create("e+e- Plots");
+        top44.setTitle("e+e- Plots");
+        IPlotterStyle stop44 = top44.style();
+        stop44.dataStyle().fillStyle().setColor("green");
+        stop44.dataStyle().errorBarStyle().setVisible(false);
+        stop44.setParameter("hist2DStyle", "colorMap");
+        stop44.dataStyle().fillStyle().setParameter("colorMapScheme", "rainbow");
+        top44.createRegions(2,4);
+        //topFrame.addPlotter(top44);
+
+        IHistogram2D trackPCorr = aida.histogram2D("p(e-) vs p(e+) max", 25, 0, 1.2, 25, 0, 1.2);
+        IHistogram1D ne = aida.histogram1D("n(e-)", 3, 0, 3);
+        IHistogram1D np = aida.histogram1D("n(e+)", 3, 0, 3);
+        IHistogram1D pem = aida.histogram1D("p(e-) max", 25, 0, 1.5);
+        IHistogram1D pe = aida.histogram1D("p(e-)", 25, 0, 1.5);
+        IHistogram1D ppm = aida.histogram1D("p(e+) max", 25, 0, 1.5);
+        IHistogram1D pp = aida.histogram1D("p(e+)", 25, 0, 1.5);
+        
+        top44.region(0).plot(trackPCorr);
+        top44.region(1).plot(ne);
+        top44.region(2).plot(np);
+        top44.region(3).plot(pe);
+        top44.region(4).plot(pp);
+        top44.region(5).plot(pem);
+        top44.region(6).plot(ppm);
+        
+        if(showPlots) top44.show();
+        
+        
+        
+//   ******************************************************************
+        plotter5 = fac.createPlotterFactory().create("HPS Hit Positions");
+        plotter5.setTitle("Hit Positions:  Top");
+        //plotterFrame.addPlotter(plotter5);
+        IPlotterStyle style5 = plotter5.style();
+        style5.setParameter("hist2DStyle", "colorMap");
+        style5.dataStyle().fillStyle().setParameter("colorMapScheme", "rainbow");
+        style5.dataStyle().fillStyle().setColor("yellow");
+        style5.dataStyle().errorBarStyle().setVisible(false);
+        plotter5.createRegions(1, 2);
+
+        IHistogram2D l1Pos = aida.histogram2D("Layer 1 HTH Position:  Top", 50, -55, 55, 55, -25, 25);
+        IHistogram2D l7Pos = aida.histogram2D("Layer 7 HTH Position:  Top", 50, -55, 55, 55, -25, 25);
+
+        plotter5.region(0).plot(l1Pos);
+        plotter5.region(1).plot(l7Pos);
+        
+        if(showPlots) plotter5.show();
+        
+        plotter5_1 = fac.createPlotterFactory().create("HPS Hit Positions");
+        plotter5_1.setTitle("Hit Positions:  Bottom");
+        //plotterFrame.addPlotter(plotter5_1);
+        IPlotterStyle style5_1 = plotter5_1.style();
+        style5_1.setParameter("hist2DStyle", "colorMap");
+        style5_1.dataStyle().fillStyle().setParameter("colorMapScheme", "rainbow");
+        style5_1.dataStyle().fillStyle().setColor("yellow");
+        style5_1.dataStyle().errorBarStyle().setVisible(false);
+        plotter5_1.createRegions(1, 2);
+
+        
+        IHistogram2D l1PosBot = aida.histogram2D("Layer 1 HTH Position:  Bottom", 50, -55, 55, 55, -25, 25);
+        IHistogram2D l7PosBot = aida.histogram2D("Layer 7 HTH Position:  Bottom", 50, -55, 55, 55, -25, 25);
+        plotter5_1.region(0).plot(l1PosBot);
+        plotter5_1.region(1).plot(l7PosBot);
+
+        if(showPlots) plotter5_1.show();
+
+        plotter55 = fac.createPlotterFactory().create("HPS Hit Positions");
+        plotter55.setTitle("Helical Track Hits");
+        //plotterFrame.addPlotter(plotter55);
+        IPlotterStyle style55 = plotter55.style();
+        style55.dataStyle().fillStyle().setColor("Green");
+        style55.dataStyle().errorBarStyle().setVisible(false);
+        style55.dataStyle().markerStyle().setSize(20);
+        plotter55.createRegions(1, 2);
+
+        IProfile avgLayersTopPlot = aida.profile1D("Number of Stereo Hits per layer in Top Half", 13, 0, 13);
+        IProfile avgLayersBottomPlot = aida.profile1D("Number of Stereo Hits per layer in Bottom Half", 13, 0, 13);
+
+        plotter55.region(0).plot(avgLayersTopPlot);
+        plotter55.region(1).plot(avgLayersBottomPlot);
+
+        if(showPlots) plotter55.show();
+
+        plotter6 = fac.createPlotterFactory().create("HPS ECAL Hit Positions");
+        plotter6.setTitle("ECAL Positions");
+        //plotterFrame.addPlotter(plotter6);
+        IPlotterStyle style6 = plotter6.style();
+        style6.setParameter("hist2DStyle", "colorMap");
+        style6.dataStyle().fillStyle().setParameter("colorMapScheme", "rainbow");
+        style6.dataStyle().fillStyle().setColor("yellow");
+        style6.dataStyle().errorBarStyle().setVisible(false);
+        plotter6.createRegions(4, 2);
+
+        IHistogram2D topECal = aida.histogram2D("Top ECal Cluster Position", 50, -400, 400, 10, 0, 100);
+        IHistogram2D botECal = aida.histogram2D("Bottom ECal Cluster Position", 50, -400, 400, 10, -100, 0);
+        IHistogram2D topECal1 = aida.histogram2D("Top ECal Cluster Position (>0 tracks)", 50, -400, 400, 10, 0, 100);
+        IHistogram2D botECal1 = aida.histogram2D("Bottom ECal Cluster Position (>0 tracks)", 50, -400, 400, 10, -100, 0);
+        IHistogram2D topECal2 = aida.histogram2D("Top ECal Cluster Position (E>0.1,>0 tracks)", 50, -400, 400, 10, 0, 100);
+        IHistogram2D botECal2 = aida.histogram2D("Bottom ECal Cluster Position (E>0.1,>0 tracks)", 50, -400, 400, 10, -100, 0);
+        IHistogram2D topECal3 = aida.histogram2D("Top ECal Cluster Position w_E (E>0.1,>0 tracks)", 50, -400, 400, 10, 0, 100);
+        IHistogram2D botECal3 = aida.histogram2D("Bottom ECal Cluster Position w_E (E>0.1,>0 tracks)", 50, -400, 400, 10, -100, 0);
+
+        plotter6.region(0).plot(topECal);
+        plotter6.region(1).plot(botECal);
+        plotter6.region(2).plot(topECal1);
+        plotter6.region(3).plot(botECal1);
+        plotter6.region(4).plot(topECal2);
+        plotter6.region(5).plot(botECal2);
+        plotter6.region(6).plot(topECal3);
+        plotter6.region(7).plot(botECal3);
+        
+        if(showPlots) plotter6.show();
+        
+        
+        plotter66 = fac.createPlotterFactory().create("HPS ECAL Basic Plots");
+        plotter66.setTitle("ECAL Basic Plots");
+        //plotterFrame.addPlotter(plotter6);
+        IPlotterStyle style66 = plotter66.style();
+        style66.dataStyle().fillStyle().setColor("yellow");
+        style66.dataStyle().errorBarStyle().setVisible(false);
+        plotter66.createRegions(2, 2);
+
+        IHistogram1D topECalE = aida.histogram1D("Top ECal Cluster Energy", 50, 0, 2);
+        IHistogram1D botECalE = aida.histogram1D("Bottom ECal Cluster Energy", 50, 0, 2);
+        IHistogram1D topECalN = aida.histogram1D("Number of Clusters Top", 6, 0, 6);
+        IHistogram1D botECalN = aida.histogram1D("Number of Clusters Bot", 6, 0, 6);
+        
+        plotter66.region(0).plot(topECalE);
+        plotter66.region(1).plot(botECalE);
+        plotter66.region(2).plot(botECalN);
+        plotter66.region(3).plot(topECalN);
+        
+        if(showPlots) plotter66.show();
+        
+        
+        
+        
+        plotter8 = fac.createPlotterFactory().create("HPS Strip Hit From Stereo Multiplicity");
+        plotter8.setTitle("Strip Hit Multiplicity");
+        //plotterFrame.addPlotter(plotter8);
+        IPlotterStyle style8 = plotter8.style();
+        style8.dataStyle().fillStyle().setColor("yellow");
+        style8.dataStyle().errorBarStyle().setVisible(false);
+        plotter8.createRegions(6, 6);
+        i=0;
+        for(SiSensor sensor : sensors) {
+            IHistogram1D resX = aida.histogram1D(sensor.getName() + " strip hits from stereo", 10, 0, 10);
+            plotter8.region(i).plot(resX);
+            i++;
+        }
+
+        if(showPlots) plotter8.show();
+        
+        plotter88 = fac.createPlotterFactory().create("HPS Strip Hit Multiplicity");
+        plotter88.setTitle("Strip Hit Multiplicity");
+        //plotterFrame.addPlotter(plotter88);
+        plotter88.setStyle(style8);
+        plotter88.createRegions(6, 6);
+        i=0;
+        for(SiSensor sensor : sensors) {
+            IHistogram1D resX = aida.histogram1D(sensor.getName() + " strip hits", 10, 0, 10);
+            plotter88.region(i).plot(resX);
+            i++;
+        }
+
+        if(showPlots) plotter88.show();
+        
+        
+        
+        
+        
+        plotter888 = fac.createPlotterFactory().create("HPS Strip Hit Isolation");
+        plotter888.setTitle("Strip Hit Isolation");
+        //plotterFrame.addPlotter(plotter88);
+        plotter888.setStyle(style8);
+        plotter888.createRegions(6, 6);
+        i=0;
+        for(SiSensor sensor : sensors) {
+            IHistogram1D resX = aida.histogram1D(sensor.getName() + " strip hits iso", 50, 0, 5);
+            plotter888.region(i).plot(resX);
+            i++;
+        }
+
+        if(showPlots) plotter888.show();
+        
+        plotter8888 = fac.createPlotterFactory().create("HPS Strip Hit On Track Isolation");
+        plotter8888.setTitle("Strip Hit On Track Isolation");
+        //plotterFrame.addPlotter(plotter88);
+        plotter8888.setStyle(style8);
+        plotter8888.createRegions(6, 6);
+        i=0;
+        for(SiSensor sensor : sensors) {
+            IHistogram1D resX = aida.histogram1D(sensor.getName() + " strip hits iso on track", 50, 0, 5);
+            plotter8888.region(i).plot(resX);
+            i++;
+        }
+
+        if(showPlots) plotter8888.show();
+
+
+    }
+    
+    
+    
+    
     private Cluster findClosestCluster(Hep3Vector posonhelix, List<Cluster> clusters) {
         Cluster closest = null;
         double minDist = 9999;

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/phansson/TriggerTurnOnAnalysis.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/phansson/TriggerTurnOnAnalysis.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/phansson/TriggerTurnOnAnalysis.java	Wed Apr 27 11:11:32 2016
@@ -10,12 +10,15 @@
 import hep.aida.IHistogramFactory;
 import hep.aida.IPlotter;
 import hep.physics.vec.Hep3Vector;
+
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.logging.Level;
 import java.util.logging.Logger;
+
 import org.hps.analysis.ecal.HPSMCParticlePlotsDriver;
+import org.hps.users.phansson.testrun.TrigRateDriver;
 import org.lcsim.event.Cluster;
 import org.lcsim.event.EventHeader;
 import org.lcsim.event.GenericObject;

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/phansson/TruthMomentumResolutionDriver.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/phansson/TruthMomentumResolutionDriver.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/phansson/TruthMomentumResolutionDriver.java	Wed Apr 27 11:11:32 2016
@@ -18,6 +18,7 @@
 import java.util.logging.Logger;
 
 import org.hps.analysis.ecal.HPSMCParticlePlotsDriver;
+import org.hps.users.phansson.testrun.TrigRateDriver;
 import org.lcsim.constants.Constants;
 import org.lcsim.event.EventHeader;
 import org.lcsim.event.MCParticle;

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/rafo/test1.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/rafo/test1.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/rafo/test1.java	Wed Apr 27 11:11:32 2016
@@ -4,15 +4,15 @@
 import org.lcsim.util.Driver;
 
 public class test1 extends Driver {
-	private int clusterID;
+    private int clusterID;
     
-	public void process(EventHeader event) {
-    	System.out.println("The cluster ID = " + clusterID);
-	}
+    public void process(EventHeader event) {
+        System.out.println("The cluster ID = " + clusterID);
+    }
     
-	public void setClusterID(int clusterID) {
-    	this.clusterID = clusterID;
-	}
+    public void setClusterID(int clusterID) {
+        this.clusterID = clusterID;
+    }
 }
 
 

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/spaul/GetChargeFromScalersMultirun.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/spaul/GetChargeFromScalersMultirun.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/spaul/GetChargeFromScalersMultirun.java	Wed Apr 27 11:11:32 2016
@@ -18,144 +18,144 @@
  *
  */
 public class GetChargeFromScalersMultirun {
-	private static ArrayList<String> runs;
-	private static ArrayList<Date> starts;
-	private static ArrayList<Date> ends;
+    private static ArrayList<String> runs;
+    private static ArrayList<Date> starts;
+    private static ArrayList<Date> ends;
 
-	public static void main(String[] arg) throws FileNotFoundException, ParseException{
-		String inputFile = arg[0];
-		String timingInfoFile = arg[1];
-		String outputFile = arg[2];
-		
-		
-		readTimingInfoFile(timingInfoFile);
-		
-		Map map = getCharges(runs, starts, ends, inputFile);
-		mergeBiasIntervals(map);
-		
-		ArrayList<String> keys = new ArrayList(map.keySet());
-		Collections.sort(keys);
-		
-		
-		PrintWriter pw = new PrintWriter(new File(outputFile));
-		for(String s : keys){
-			pw.println(s + "\t" + map.get(s));
-			System.out.println(s + "\t" + map.get(s));
-		}
-		pw.close();
-	}
+    public static void main(String[] arg) throws FileNotFoundException, ParseException{
+        String inputFile = arg[0];
+        String timingInfoFile = arg[1];
+        String outputFile = arg[2];
+        
+        
+        readTimingInfoFile(timingInfoFile);
+        
+        Map map = getCharges(runs, starts, ends, inputFile);
+        mergeBiasIntervals(map);
+        
+        ArrayList<String> keys = new ArrayList(map.keySet());
+        Collections.sort(keys);
+        
+        
+        PrintWriter pw = new PrintWriter(new File(outputFile));
+        for(String s : keys){
+            pw.println(s + "\t" + map.get(s));
+            System.out.println(s + "\t" + map.get(s));
+        }
+        pw.close();
+    }
 
-	static void readTimingInfoFile(String s) throws FileNotFoundException, ParseException{
-		Scanner scanner = new Scanner(new File(s));
-		scanner.useDelimiter("[\n\t]");
-		runs = new ArrayList();
-		starts = new ArrayList();
-		ends = new ArrayList();
-		DateFormat df = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss z");
-		
-		while(scanner.hasNext()){
-			runs.add(scanner.next());
-			String n = scanner.next();
-			if(n.matches("\\d+"))
-				starts.add(new Date(Long.parseLong(n)));
-			else 
-				starts.add(df.parse(n));
-			n = scanner.next();
-			if(n.matches("\\d+"))
-				ends.add(new Date(Long.parseLong(n)));
-			else 
-				ends.add(df.parse(n));
-			
-		}
-		scanner.close();
-	}
-	
-	
-	
-	
-	
-	/**
-	 * returns charge in microCoulombs
-	 * @param runs names of the runs   
-	 * @param starts starting times of the runs
-	 * @param ends ending times of the runs
-	 * @param file the mya file that we need to use
-	 * @return a map relating the runs to the charges (uC).  
-	 * @throws FileNotFoundException
-	 */
-	
-	static Map<String, Double> getCharges(ArrayList<String> runs, ArrayList<Date> starts, ArrayList<Date> ends, String file) throws FileNotFoundException{
-		Scanner s = new Scanner(new File(file));
-		HashMap<String, Double> map = new HashMap();
-		long prev = 0;
-		long time = 0;
-		for(int i = 0; i< runs.size(); i++){
-			long endt = ends.get(i).getTime();
-			long startt = starts.get(i).getTime();
-			
-			double charge = 0;
-			boolean started = false;
-			double prevval = 0;
-			if(time > endt){
-				s.close();
-				s = new Scanner(new File(file));
-			}
-			inner : while(s.hasNext()){
-				String var = s.next();
-				prev = time;
-				time = s.nextLong()*1000; //convert from s to ms
+    static void readTimingInfoFile(String s) throws FileNotFoundException, ParseException{
+        Scanner scanner = new Scanner(new File(s));
+        scanner.useDelimiter("[\n\t]");
+        runs = new ArrayList();
+        starts = new ArrayList();
+        ends = new ArrayList();
+        DateFormat df = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss z");
+        
+        while(scanner.hasNext()){
+            runs.add(scanner.next());
+            String n = scanner.next();
+            if(n.matches("\\d+"))
+                starts.add(new Date(Long.parseLong(n)));
+            else 
+                starts.add(df.parse(n));
+            n = scanner.next();
+            if(n.matches("\\d+"))
+                ends.add(new Date(Long.parseLong(n)));
+            else 
+                ends.add(df.parse(n));
+            
+        }
+        scanner.close();
+    }
+    
+    
+    
+    
+    
+    /**
+     * returns charge in microCoulombs
+     * @param runs names of the runs   
+     * @param starts starting times of the runs
+     * @param ends ending times of the runs
+     * @param file the mya file that we need to use
+     * @return a map relating the runs to the charges (uC).  
+     * @throws FileNotFoundException
+     */
+    
+    static Map<String, Double> getCharges(ArrayList<String> runs, ArrayList<Date> starts, ArrayList<Date> ends, String file) throws FileNotFoundException{
+        Scanner s = new Scanner(new File(file));
+        HashMap<String, Double> map = new HashMap();
+        long prev = 0;
+        long time = 0;
+        for(int i = 0; i< runs.size(); i++){
+            long endt = ends.get(i).getTime();
+            long startt = starts.get(i).getTime();
+            
+            double charge = 0;
+            boolean started = false;
+            double prevval = 0;
+            if(time > endt){
+                s.close();
+                s = new Scanner(new File(file));
+            }
+            inner : while(s.hasNext()){
+                String var = s.next();
+                prev = time;
+                time = s.nextLong()*1000; //convert from s to ms
 
-				double val = s.nextDouble();
-				if(!var.equals("scaler_calc1"))
-					continue;
-				
-				if(!started && time> startt){ //first sample in the run
-					charge += (val)/2.*(time-startt);
-					started= true;
-				}
-				
-				else if(time > startt && endt > time){ //middle samples in the run
-					charge += (val/*+prevval*/)/*/2.*/*(time-prev);
-					
-				}
-				
-				if(endt < time){ //last sample that is in the run
-					charge += (/*prev*/val)/2.*(endt-prev);
-					break inner;
-				}
-				prevval = val;
-			}
-			charge/=1e6;
-			map.put(runs.get(i), charge);
-		}
-		s.close();
-		return map;
+                double val = s.nextDouble();
+                if(!var.equals("scaler_calc1"))
+                    continue;
+                
+                if(!started && time> startt){ //first sample in the run
+                    charge += (val)/2.*(time-startt);
+                    started= true;
+                }
+                
+                else if(time > startt && endt > time){ //middle samples in the run
+                    charge += (val/*+prevval*/)/*/2.*/*(time-prev);
+                    
+                }
+                
+                if(endt < time){ //last sample that is in the run
+                    charge += (/*prev*/val)/2.*(endt-prev);
+                    break inner;
+                }
+                prevval = val;
+            }
+            charge/=1e6;
+            map.put(runs.get(i), charge);
+        }
+        s.close();
+        return map;
 
-	}
-	
-	/**
-	 * If the subsections of the runs in which the bias is on are labeled according to a scheme,
-	they will be added together.  
-	for instance, 5779a, 5779b, 5779c, etc. will be added up as 5779bias.   
-	 * @param map the map of run names (and portions of runs that have bias labeled as [run number][a,b,c,d...],
-	 * corresponding to the total charge in that run (or piece of a run).  
-	 */
-	static void mergeBiasIntervals(Map<String, Double> map){
-		Map<String, Double> map2 = new HashMap();
-		for(Map.Entry<String, Double> entry : map.entrySet()){
-			String key1 = entry.getKey();
-			if(!entry.getKey().matches("\\d+a"))
-					continue;
-			double charge = entry.getValue();
-			for(Map.Entry<String, Double> entry2 : map.entrySet()){
-				if(entry2.getKey().matches(key1.substring(0, 4) + "[b-z]"))
-						charge += entry2.getValue();
-			}
-			map2.put(key1.substring(0, 4) + "bias", charge);
-			
-		}
-		for(Map.Entry<String, Double> e : map2.entrySet()){
-			map.put(e.getKey(), e.getValue());
-		}
-	}
+    }
+    
+    /**
+     * If the subsections of the runs in which the bias is on are labeled according to a scheme,
+    they will be added together.  
+    for instance, 5779a, 5779b, 5779c, etc. will be added up as 5779bias.   
+     * @param map the map of run names (and portions of runs that have bias labeled as [run number][a,b,c,d...],
+     * corresponding to the total charge in that run (or piece of a run).  
+     */
+    static void mergeBiasIntervals(Map<String, Double> map){
+        Map<String, Double> map2 = new HashMap();
+        for(Map.Entry<String, Double> entry : map.entrySet()){
+            String key1 = entry.getKey();
+            if(!entry.getKey().matches("\\d+a"))
+                    continue;
+            double charge = entry.getValue();
+            for(Map.Entry<String, Double> entry2 : map.entrySet()){
+                if(entry2.getKey().matches(key1.substring(0, 4) + "[b-z]"))
+                        charge += entry2.getValue();
+            }
+            map2.put(key1.substring(0, 4) + "bias", charge);
+            
+        }
+        for(Map.Entry<String, Double> e : map2.entrySet()){
+            map.put(e.getKey(), e.getValue());
+        }
+    }
 }

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/spaul/HitrateHistograms.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/spaul/HitrateHistograms.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/spaul/HitrateHistograms.java	Wed Apr 27 11:11:32 2016
@@ -19,109 +19,109 @@
 import org.lcsim.util.Driver;
 
 public class HitrateHistograms extends Driver{
-	HashMap<String, IHistogram2D[]> hist2d = new HashMap<String, IHistogram2D[]>();
+    HashMap<String, IHistogram2D[]> hist2d = new HashMap<String, IHistogram2D[]>();
 
-	IAnalysisFactory af = IAnalysisFactory.create();
-	IHistogramFactory hf = af.createHistogramFactory(af.createTreeFactory().create());
-	IPlotterFactory pf = af.createPlotterFactory();
-	public HitrateHistograms(){
-		addHistograms2D("Ecal", 1, -30, 30, -8, 16);
-		addHistograms2D("muon", 8, -30, 30, -8, 16);
+    IAnalysisFactory af = IAnalysisFactory.create();
+    IHistogramFactory hf = af.createHistogramFactory(af.createTreeFactory().create());
+    IPlotterFactory pf = af.createPlotterFactory();
+    public HitrateHistograms(){
+        addHistograms2D("Ecal", 1, -30, 30, -8, 16);
+        addHistograms2D("muon", 8, -30, 30, -8, 16);
 
-		try {
-			ecalDecoder = new IDDecoder(new IDDescriptor("system:0:6,layer:6:2,ix:8:-8,iy:16:-6"));
-		} catch (IDException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
-		}
+        try {
+            ecalDecoder = new IDDecoder(new IDDescriptor("system:0:6,layer:6:2,ix:8:-8,iy:16:-6"));
+        } catch (IDException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
 
 
 
-	}
-	private void addHistograms2D(String detector, int nLayers, int ixMin, int ixMax,  int iyMin, int iyMax){
-		IPlotter plotter1 = pf.create("detector");
-		int nx = (int)Math.ceil(Math.sqrt(nLayers));
-		int ny = (int)Math.ceil(nLayers/(double)nx);
-		plotter1.createRegions(nx, ny);
+    }
+    private void addHistograms2D(String detector, int nLayers, int ixMin, int ixMax,  int iyMin, int iyMax){
+        IPlotter plotter1 = pf.create("detector");
+        int nx = (int)Math.ceil(Math.sqrt(nLayers));
+        int ny = (int)Math.ceil(nLayers/(double)nx);
+        plotter1.createRegions(nx, ny);
 
-		hist2d.put(detector,new IHistogram2D[nLayers]);
-		for(int i = 0; i< nLayers; i++){
-			hist2d.get(detector)[i] 
-			                     = hf.createHistogram2D(detector + " layer " + (i+1), ixMax-ixMin, ixMin, ixMax, iyMax-iyMin, iyMin, iyMax);
-			plotter1.region(i).plot(hist2d.get(detector)[i]);
+        hist2d.put(detector,new IHistogram2D[nLayers]);
+        for(int i = 0; i< nLayers; i++){
+            hist2d.get(detector)[i] 
+                                 = hf.createHistogram2D(detector + " layer " + (i+1), ixMax-ixMin, ixMin, ixMax, iyMax-iyMin, iyMin, iyMax);
+            plotter1.region(i).plot(hist2d.get(detector)[i]);
 
-		}
-	}
+        }
+    }
 
 
-	IDDecoder ecalDecoder;
-	private float recency;
+    IDDecoder ecalDecoder;
+    private float recency;
 
-	public void process(EventHeader header){
+    public void process(EventHeader header){
 
 
-		//System.out.println(header.keys());
+        //System.out.println(header.keys());
 
 
-		for(SIOSimCalorimeterHit hit: header.get(SIOSimCalorimeterHit.class,"EcalHits")){
-			int fieldCount = hit.getIDDecoder().getFieldCount();
-			ecalDecoder.setID(hit.getCellID());
-			int ix = ecalDecoder.getValue("ix");
-			int iy = ecalDecoder.getValue("iy");
-			int layer = ecalDecoder.getValue("layer");
-			hist2d.get("Ecal")[layer].fill(ix, iy);
-		}
-		
-		
-		/*if(recency != 0)
-		for(IHistogram2D[] hists : hist2d.values()){
-			for(IHistogram2D hist : hists){
-				hf.
-			}
-		}*/
-		//}
-	}
-	/**
-	 * "recency" is a parameter used to determine how to time-weight the 
-	 * histogram so that the more recent events are more highly weighted.
-	 * A recency of zero means that there is no time weightedness.
-	 * A recency of R means that each event is weighted by a factor of (1-R)^n,
-	 * where n is the number of events that have taken place since the event shown.
-	 * @param recency
-	 */
-	//public void setRecency(float recency){
-	//this.recency = recency;
-	//}
+        for(SIOSimCalorimeterHit hit: header.get(SIOSimCalorimeterHit.class,"EcalHits")){
+            int fieldCount = hit.getIDDecoder().getFieldCount();
+            ecalDecoder.setID(hit.getCellID());
+            int ix = ecalDecoder.getValue("ix");
+            int iy = ecalDecoder.getValue("iy");
+            int layer = ecalDecoder.getValue("layer");
+            hist2d.get("Ecal")[layer].fill(ix, iy);
+        }
+        
+        
+        /*if(recency != 0)
+        for(IHistogram2D[] hists : hist2d.values()){
+            for(IHistogram2D hist : hists){
+                hf.
+            }
+        }*/
+        //}
+    }
+    /**
+     * "recency" is a parameter used to determine how to time-weight the 
+     * histogram so that the more recent events are more highly weighted.
+     * A recency of zero means that there is no time weightedness.
+     * A recency of R means that each event is weighted by a factor of (1-R)^n,
+     * where n is the number of events that have taken place since the event shown.
+     * @param recency
+     */
+    //public void setRecency(float recency){
+    //this.recency = recency;
+    //}
 
-	public void startOfData(){
+    public void startOfData(){
 
-	}
-	public void endOfData(){
+    }
+    public void endOfData(){
 
-		for(String name : hist2d.keySet()){
-			IHistogram2D[] hists = hist2d.get(name);
-			System.out.println(name);
-			for(int i = 0; i< hists.length; i++){
-				double max = hists[i].maxBinHeight();
-				double total = hists[i].sumAllBinHeights();
-				double ratioPercent = 100.*max/(double)total;
-				System.out.printf("  layer %d: %.2f %% of hits were in the most populated bin\n",i, ratioPercent);
-			}
-		}
-	}
-	public static void main(String arg[]) throws IOException{
-		LCIOReader lcReader = new LCIOReader(new File(arg[0]));
-		HitrateHistograms driver = new HitrateHistograms();
-		driver.startOfData();
-		for(int i=0;i<1000;i++){
-			EventHeader event = lcReader.read();
+        for(String name : hist2d.keySet()){
+            IHistogram2D[] hists = hist2d.get(name);
+            System.out.println(name);
+            for(int i = 0; i< hists.length; i++){
+                double max = hists[i].maxBinHeight();
+                double total = hists[i].sumAllBinHeights();
+                double ratioPercent = 100.*max/(double)total;
+                System.out.printf("  layer %d: %.2f %% of hits were in the most populated bin\n",i, ratioPercent);
+            }
+        }
+    }
+    public static void main(String arg[]) throws IOException{
+        LCIOReader lcReader = new LCIOReader(new File(arg[0]));
+        HitrateHistograms driver = new HitrateHistograms();
+        driver.startOfData();
+        for(int i=0;i<1000;i++){
+            EventHeader event = lcReader.read();
 
-			if(event == null)
-				break;
-			driver.process(event);
+            if(event == null)
+                break;
+            driver.process(event);
 
-		}
-		driver.endOfData();
-	}
+        }
+        driver.endOfData();
+    }
 
 }

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/spaul/PulserFilter.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/spaul/PulserFilter.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/spaul/PulserFilter.java	Wed Apr 27 11:11:32 2016
@@ -25,65 +25,65 @@
 
 public class PulserFilter extends Driver{
 
-	public void process(EventHeader event) {
+    public void process(EventHeader event) {
 
-		// only keep pulser triggers:
-		if (!event.hasCollection(GenericObject.class,"TriggerBank"))
-			throw new Driver.NextEventException();
-		boolean isPulser=false;
-		for (GenericObject gob : event.get(GenericObject.class,"TriggerBank"))
-		{
-			if (!(AbstractIntData.getTag(gob) == TIData.BANK_TAG)) continue;
-			TIData tid = new TIData(gob);
-			if (tid.isPulserTrigger())
-			{
-				isPulser=true;
-				break;
-			}
-		}
+        // only keep pulser triggers:
+        if (!event.hasCollection(GenericObject.class,"TriggerBank"))
+            throw new Driver.NextEventException();
+        boolean isPulser=false;
+        for (GenericObject gob : event.get(GenericObject.class,"TriggerBank"))
+        {
+            if (!(AbstractIntData.getTag(gob) == TIData.BANK_TAG)) continue;
+            TIData tid = new TIData(gob);
+            if (tid.isPulserTrigger())
+            {
+                isPulser=true;
+                break;
+            }
+        }
 
-		// don't drop any events with EPICS data or scalers data
-		// (could also do this via event tag=31)
-		final EpicsData edata = EpicsData.read(event);
-		if (edata != null) return;
-		ScalerData sdata = ScalerData.read(event);
-		if(sdata != null) return;
+        // don't drop any events with EPICS data or scalers data
+        // (could also do this via event tag=31)
+        final EpicsData edata = EpicsData.read(event);
+        if (edata != null) return;
+        ScalerData sdata = ScalerData.read(event);
+        if(sdata != null) return;
 
-		if (!isPulser) throw new Driver.NextEventException();
+        if (!isPulser) throw new Driver.NextEventException();
 
 
-	}
+    }
 
-	public static void main(String arg[]) throws IOException{
-		ConditionsDriver hack = new ConditionsDriver();
-		hack.setDetectorName("HPS-EngRun2015-Nominal-v1");
-		hack.setFreeze(true);
-		hack.setRunNumber(Integer.parseInt(arg[2]));
-		hack.initialize();
-		PulserFilter pf = new PulserFilter();
-		LCIOWriter writer = new LCIOWriter(arg[1]);
-		File file = new File(arg[0]);
-		LCIOReader reader = new LCIOReader(file);
-		System.out.println(file.getPath());
+    public static void main(String arg[]) throws IOException{
+        ConditionsDriver hack = new ConditionsDriver();
+        hack.setDetectorName("HPS-EngRun2015-Nominal-v1");
+        hack.setFreeze(true);
+        hack.setRunNumber(Integer.parseInt(arg[2]));
+        hack.initialize();
+        PulserFilter pf = new PulserFilter();
+        LCIOWriter writer = new LCIOWriter(arg[1]);
+        File file = new File(arg[0]);
+        LCIOReader reader = new LCIOReader(file);
+        System.out.println(file.getPath());
 
-		try{
-			while(true){
-				try{
-					EventHeader eh = reader.read();
-					if(eh.getEventNumber() %100 == 0)
-						System.out.println(eh.getEventNumber());
-					pf.process(eh);
-					writer.write(eh);
-				}catch(Driver.NextEventException e){
+        try{
+            while(true){
+                try{
+                    EventHeader eh = reader.read();
+                    if(eh.getEventNumber() %100 == 0)
+                        System.out.println(eh.getEventNumber());
+                    pf.process(eh);
+                    writer.write(eh);
+                }catch(Driver.NextEventException e){
 
-				}
-			}
-		}catch(IOException e){
-			e.printStackTrace();
-			reader.close();
-		}
+                }
+            }
+        }catch(IOException e){
+            e.printStackTrace();
+            reader.close();
+        }
 
 
-		writer.close();
-	}
+        writer.close();
+    }
 }

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/spaul/StyleUtil.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/spaul/StyleUtil.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/spaul/StyleUtil.java	Wed Apr 27 11:11:32 2016
@@ -1,56 +1,195 @@
 package org.hps.users.spaul;
 
+import java.awt.Component;
+import java.awt.Graphics2D;
+import java.awt.image.BufferedImage;
+import java.io.File;
 import java.util.Arrays;
+import java.util.Random;
 
-import hep.aida.IAnalysisFactory;
-import hep.aida.IFunction;
-import hep.aida.IPlotterRegion;
+import javax.imageio.ImageIO;
+
+import hep.aida.*;
+import hep.aida.ref.plotter.PlotterUtilities;
 
 public class StyleUtil {
-	
-	public static void stylize(IPlotterRegion r, String title, String lx, String ly, double xmin, double xmax, double ymin, double ymax){
-		r.setTitle(title);
-		stylize(r, lx, ly);
-		r.setXLimits(xmin, xmax);
-		r.setYLimits(ymin, ymax);
-	}
-	public static void stylize(IPlotterRegion r, String title, String lx, String ly){
-		r.setTitle(title);
-		stylize(r, lx, ly);
-	}
-	public static void stylize(IPlotterRegion r, String lx, String ly){
-		
-		r.style().titleStyle().textStyle().setFontSize(22);
-		r.style().xAxisStyle().setLabel(lx);
-		r.style().xAxisStyle().labelStyle().setFontSize(16);
-		r.style().xAxisStyle().tickLabelStyle().setFontSize(14);
-		r.style().yAxisStyle().setLabel(ly);
-		r.style().yAxisStyle().labelStyle().setFontSize(16);
-		r.style().yAxisStyle().tickLabelStyle().setFontSize(14);
-		r.style().statisticsBoxStyle().setParameter("backgroundColor", "white");
-		r.style().statisticsBoxStyle().boxStyle().backgroundStyle().setColor("White");
-		r.style().statisticsBoxStyle().boxStyle().backgroundStyle().setParameter("color", "white");
-		r.style().statisticsBoxStyle().boxStyle().backgroundStyle().setOpacity(100);
-		System.out.println(Arrays.toString(r.style().dataStyle().availableParameters()));
-		r.style().dataStyle().fillStyle().setParameter("colorMapScheme", "rainbow");
-		r.style().dataStyle().fillStyle().setParameter("showZeroHeightBins", "false");
-		//r.style().dataStyle().setParameter("showDataInStatisticsBox", "false");
-		r.style().setParameter("hist2DStyle", "colorMap");
-		//r.style().dataBoxStyle()
-	}
-	static void addHorizontalLine(IPlotterRegion r, double y, String name){
-		IAnalysisFactory af = IAnalysisFactory.create();
-		IFunction f = af.createFunctionFactory(af.createTreeFactory().create()).createFunctionByName(name, "p0");
-		f.setParameter("p0", y);
-		r.plot(f);
-	}
-	public static void addParabola(IPlotterRegion region, double p0,
-			double p1, double p2, String string) {
-		IAnalysisFactory af = IAnalysisFactory.create();
-		IFunction f = af.createFunctionFactory(af.createTreeFactory().create()).createFunctionByName(string, "p2");
-		f.setParameter("p0", p0);
-		f.setParameter("p1", p1);
-		f.setParameter("p2", p2);
-		region.plot(f);
-	}
+    
+    public static void stylize(IPlotterRegion r, String title, String lx, String ly, double xmin, double xmax, double ymin, double ymax){
+        r.setTitle(title);
+        stylize(r, lx, ly);
+        r.setXLimits(xmin, xmax);
+        r.setYLimits(ymin, ymax);
+    }
+    public static void stylize(IPlotterRegion r, String title, String lx, String ly){
+        r.setTitle(title);
+        stylize(r, lx, ly);
+    }
+    public static void stylize(IPlotterRegion r, String lx, String ly){
+        
+        r.style().titleStyle().textStyle().setFontSize(22);
+        r.style().xAxisStyle().setLabel(lx);
+        r.style().xAxisStyle().labelStyle().setFontSize(16);
+        r.style().xAxisStyle().tickLabelStyle().setFontSize(14);
+        r.style().yAxisStyle().setLabel(ly);
+        r.style().yAxisStyle().labelStyle().setFontSize(16);
+        r.style().yAxisStyle().tickLabelStyle().setFontSize(14);
+        //  r.style().statisticsBoxStyle().set;
+        //debugPrint());
+        r.style().legendBoxStyle().textStyle().setFontSize(16);
+        r.style().statisticsBoxStyle().textStyle().setFontSize(16);
+        
+        //r.style().dataStyle().showInLegendBox(false);
+        
+        r.style().legendBoxStyle().boxStyle().foregroundStyle().setOpacity(1.0);
+        r.style().dataStyle().fillStyle().setParameter("colorMapScheme", "rainbow");
+        r.style().dataStyle().fillStyle().setParameter("showZeroHeightBins", "false");
+        //debugPrint(r.style().dataStyle().availableParameters()));
+        //r.style().dataStyle().setParameter("showDataInStatisticsBox", "false");
+        r.style().setParameter("hist2DStyle", "colorMap");
+        //r.style().dataBoxStyle()
+    }
+    public static void addHorizontalLine(IPlotterRegion r, double y, String name){
+        IAnalysisFactory af = IAnalysisFactory.create();
+        IFunction f = af.createFunctionFactory(af.createTreeFactory().create()).createFunctionByName(name, "p0");
+        f.setParameter("p0", y);
+        r.plot(f);
+    }
+    public static void addParabola(IPlotterRegion region, double p0,
+            double p1, double p2, String string) {
+        IAnalysisFactory af = IAnalysisFactory.create();
+        IFunction f = af.createFunctionFactory(af.createTreeFactory().create()).createFunctionByName(string, "p2");
+        f.setParameter("p0", p0);
+        f.setParameter("p1", p1);
+        f.setParameter("p2", p2);
+        region.plot(f);
+    }
+    public static void noFillHistogramBars(IPlotterRegion region) {
+        region.style().dataStyle().setParameter("fillHistogramBars", "false");
+        region.style().dataStyle().fillStyle().setVisible(false);
+        
+
+        region.style().dataStyle().lineStyle().setParameter("colorRotateMethod", "regionOverlayIndex");
+        region.style().dataStyle().lineStyle().setParameter("colorRotate", "black, red, green, blue");
+        region.style().dataStyle().lineStyle().setParameter("thickness", "3");
+        region.style().dataStyle().outlineStyle().setParameter("colorRotateMethod", "regionOverlayIndex");
+        //debug = true;
+        debugPrint(region.style().dataStyle().outlineStyle().availableParameters());
+        region.style().dataStyle().outlineStyle().setParameter("colorRotate", "black, red, green, blue");
+        region.style().dataStyle().outlineStyle().setParameter("thickness", "3");
+        region.style().dataStyle().errorBarStyle().setVisible(false);
+        debugPrint(region.style().dataStyle().lineStyle().availableParameterOptions("colorRotateMethod"));
+    }
+    public static void setSize(IPlotter p, int width, int height){
+        p.setParameter("plotterWidth", width +"");
+        p.setParameter("plotterHeight", height +"");
+    }
+    
+    public static void setLog(IPlotterRegion r){
+
+        r.style().yAxisStyle().setParameter("scale", "log");
+        r.style().gridStyle().setUnits(100);
+        debugPrint(r.style().gridStyle().availableParameters()); 
+        
+    }
+    static boolean debug = false;
+    static void debugPrint(String[] stuff){
+        if(debug){
+            System.out.println(Arrays.toString(stuff));
+        }
+    }
+    public static void main(String arg[]){
+        IAnalysisFactory af = IAnalysisFactory.create();
+        IHistogramFactory hf = af.createHistogramFactory(af.createTreeFactory().create());
+        
+        IPlotter p = af.createPlotterFactory().create();
+        debugPrint(p.availableParameters());
+        p.createRegions(1, 2);
+        IHistogram1D h1 = hf.createHistogram1D("blah", 100, -5, 5);
+        IHistogram1D h2 = hf.createHistogram1D("bleh", 100, -5, 5);
+        Random random = new Random();
+        for(int i = 0; i< 100000; i++){
+            h1.fill(random.nextGaussian());
+            h2.fill(random.nextGaussian()*2);
+        }
+        hideLegendAndStats(p.region(1));
+        noFillHistogramBars(p.region(0));
+        stylize(p.region(0), "title", "x axis label", "y axis label");
+        stylize(p.region(1), "stuff", "x axis label", "y axis label");
+        p.region(0).plot(h1);
+        p.region(0).plot(h2);
+        
+
+        IHistogram2D h3 = hf.createHistogram2D("blah", 100, -5, 5, 100, -5,5);
+        
+        for(int i = 0; i< 100000; i++){
+            h3.fill(random.nextGaussian(), random.nextGaussian());
+        }
+        
+        p.region(1).plot(h3);
+        
+        
+        
+        p.show();
+        
+        p = af.createPlotterFactory().create();
+        debugPrint(p.availableParameters());
+        p.createRegions(1, 2);
+        
+        p.region(0).plot(h1);
+        setLog(p.region(0));
+        
+        
+        
+        p.show();
+    }
+    public static void hideLegendAndStats(IPlotterRegion r){
+        r.style().statisticsBoxStyle().setVisible(false);
+        r.style().legendBoxStyle().setVisible(false);
+    }
+    public static IPlotterStyle smoothCurveStyle(IPlotterFactory pf) {
+        IPlotterStyle style = pf.createPlotterStyle();
+        debugPrint(style.dataStyle().availableParameters());
+        
+        style.dataStyle().markerStyle().setVisible(false);
+        
+        return style;
+    }
+    public static void writeToFile(IPlotter plotter, String filename, String filetype){
+        //JFrame frame = new JFrame()
+        //if(plotter.)
+        //plotter.hide();
+        //plotter.show();
+        //PlotterUtilities.writeToFile(plotter, filename, filetype, null);
+        try {
+            
+            
+            //PlotterUtilities.writeToFile(plotter, filename, filetype, null);
+            Thread.sleep(1000);
+            Component c = PlotterUtilities.componentForPlotter(plotter);
+            int width = Integer.parseInt(plotter.parameterValue("plotterWidth"));
+            int height = Integer.parseInt(plotter.parameterValue("plotterHeight"));
+            if(width <= 0){
+                width = 300;
+                plotter.setParameter("plotterWidth", Integer.toString(width));
+            }
+            if(height <= 0){
+                height = 300;
+
+                plotter.setParameter("plotterHeight", Integer.toString(height));
+            }
+            
+            c.setSize(width, height);
+            BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
+            Graphics2D graphics2D = image.createGraphics();
+            c.paint(graphics2D);
+            ImageIO.write(image,filetype, new File(filename));
+            Runtime.getRuntime().exec("open " + filename);
+            System.out.println("saved");
+            
+        } catch (Exception e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+        
+    }
 }

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/spaul/SumEverything.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/spaul/SumEverything.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/spaul/SumEverything.java	Wed Apr 27 11:11:32 2016
@@ -2,6 +2,10 @@
 
 import java.io.File;
 import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+import org.lcsim.util.aida.AIDA;
 
 import hep.aida.IAnalysisFactory;
 import hep.aida.IHistogram1D;
@@ -15,75 +19,163 @@
 // full of aida output files.  Then add up all of the histograms in each sub folder,
 // and put the sums in separate files in a folder called "sums"
 public class SumEverything {
-	public static void main(String arg[]) throws IllegalArgumentException, IOException{
-		if(arg.length > 1){
-			twoArg(arg[0], arg[1]);
-		}
-		else{
-			oneArg(arg[0]);
-		}
-	}
-	static void oneArg(String indir) throws IllegalArgumentException, IOException{
-		File outdir = new File(indir + "/sums");
-		outdir.mkdir();
-		for(File subdirf : new File(indir).listFiles()){
-			String subdir = subdirf.getAbsolutePath();
-			if(subdir.matches(".*/sums/?"))
-				continue;
-			String split[] = subdir.split("/");
-			String outfile = indir + "/sums/" + split[split.length-1] + ".aida";
-			twoArg(subdir, outfile);
-		}
-		new File(indir + "/sums/total.aida").delete();
-		twoArg(outdir.getAbsolutePath(), indir + "/sums/total.aida");
-		
-	}
+    public static void main(String arg[]) throws IllegalArgumentException, IOException{
+        if(arg.length == 2){
+            twoArg(arg[0], arg[1]);
+        }
+        else if(arg.length == 1){
+            oneArg(arg[0]);
+        }
+        else 
+            polyArg(arg);
+    }
+    static void oneArg(final String indir) throws IllegalArgumentException, IOException{
+        File outdir = new File(indir + "/sums");
+        outdir.mkdir();
+        ArrayList<Thread> threads = new ArrayList<Thread>();
+        for(final File subdirf : new File(indir).listFiles()){
+            Thread t = new Thread(){
+                public void run(){
 
-	static void twoArg(String indir, String out) throws IllegalArgumentException, IOException{
-		IAnalysisFactory af = IAnalysisFactory.create();
-		ITreeFactory tf = af.createTreeFactory();
-		new File(out).delete();
-		ITree tree0 = tf.create(out, "xml", false, true);
-		IHistogramFactory hf = af.createHistogramFactory(tree0);
-		
+                    String subdir = subdirf.getAbsolutePath();
+                    if(subdir.matches(".*/sums/?"))
+                        return;
+                    String split[] = subdir.split("/");
+                    String outfile = indir + "/sums/" + split[split.length-1] + ".aida";
+                    try {
+                        twoArg(subdir, outfile);
+                    } catch (IllegalArgumentException e) {
+                        // TODO Auto-generated catch block
+                        e.printStackTrace();
+                    } catch (IOException e) {
+                        // TODO Auto-generated catch block
+                        e.printStackTrace();
+                    }
+                }
+            };
+            threads.add(t);
+            t.start();
+        }
+        for(Thread t : threads){
+            try {
+                t.join();
+            } catch (InterruptedException e) {
+                // TODO Auto-generated catch block
+                e.printStackTrace();
+            }
+        }
+        new File(indir + "/sums/total.aida").delete();
+        twoArg(outdir.getAbsolutePath(), indir + "/sums/total.aida");
 
-		int j = 0;
-		for(File s : new File(indir).listFiles()){
-			ITree tree = af.createTreeFactory().create(s.getAbsolutePath(),"xml");
+    }
 
-			
-			if(j == 0){
-				String [] names = tree.listObjectNames();
-				tree0.mount("/tmp", tree, "/");
-				for(String name : names){
-					Object o = tree.find(name);
-					if(o instanceof IHistogram1D || o instanceof IHistogram2D)
-						tree0.cp("/tmp/" + name, name);
-				}
-				tree0.unmount("/tmp");
-				tree.close();
-				
-			}
-			else{
-				//tree.
-				String [] names = tree.listObjectNames();
-				tree0.mount("/tmp", tree, "/");
-				for(String name : names){
-					Object o = tree.find(name);
-					if(o instanceof IHistogram1D)
-						((IHistogram1D)tree0.find(name)).add((IHistogram1D)o);
-					if(o instanceof IHistogram2D)
-						((IHistogram2D)tree0.find(name)).add((IHistogram2D)o);
-				}
-				tree0.unmount("/tmp");
-				tree.close();
-			}
 
-			tree.close();
-			j++;
-			System.out.println(j + " files have been read");
-		}
-		tree0.commit();
-	}
+
+    static void twoArg(String indir, String out) throws IllegalArgumentException, IOException{
+
+        run(new File(indir).listFiles(), out);
+    }
+    static void run(File[] files, String out) throws IllegalArgumentException, IOException{
+        
+        long timeStart = System.currentTimeMillis();
+        IAnalysisFactory af = IAnalysisFactory.create();
+        //AIDA.defaultInstance().
+        ITreeFactory tf = af.createTreeFactory();
+        new File(out).delete();
+        ITree outtree = tf.createTree(out, "xml", ITreeFactory.RECREATE);
+        IHistogramFactory hf = af.createHistogramFactory(outtree);
+        int j = 0;
+        String names[] = null;
+        for(File s : files){
+            System.gc();
+            if(!s.getAbsolutePath().endsWith("aida"))
+                continue;
+            try{
+                
+                ITree tree = tf.createTree(s.getAbsolutePath(), "xml", ITreeFactory.READONLY);//.create(s.getAbsolutePath(),"xml");
+
+
+                if(j == 0){
+                    names = tree.listObjectNames("/", true);
+                    System.out.println(Arrays.toString(names));
+                    //outtree.mount("/tmp", tree, "/");
+                    for(String name : names){
+                        if(name.endsWith("/")){
+                            outtree.mkdirs(name);
+                            continue;
+                        }
+                        Object o = tree.find(name);
+                        if(o instanceof IHistogram1D)
+                            hf.createCopy(name,(IHistogram1D)o);
+                        if(o instanceof IHistogram2D)
+                            hf.createCopy(name,(IHistogram2D)o);
+                        
+                    }
+                    //outtree.unmount("/tmp");
+                    //tree.close();
+
+                }
+                else{
+                    //tree.
+                    //String [] names = tree.listObjectNames("/", true);
+                    //outtree.mount("/tmp", tree, "/");
+                    //System.out.println(Arrays.toString(names));
+                    for(String name : names){
+                        if(name.endsWith("/"))
+                            continue;
+                        Object o = null;
+                        try{
+                            o = tree.find(name);
+                        } catch(IllegalArgumentException e){
+                            System.err.println("couldn't find object called " + name +  " in file " + s);
+                            throw e;
+                        }
+                        if(o instanceof IHistogram1D){
+                            if(((IHistogram1D)o).allEntries() != 0)
+                            ((IHistogram1D)outtree.find(name)).add((IHistogram1D)o);
+                        }
+                        if(o instanceof IHistogram2D)
+                            if(((IHistogram2D)o).allEntries() != 0)
+                            ((IHistogram2D)outtree.find(name)).add((IHistogram2D)o);
+                    }
+                    //outtree.unmount("/tmp");
+                    //tree.close();
+                }
+
+                tree.close();
+                j++;
+                System.out.println(j + " files have been read (" +(System.currentTimeMillis()-timeStart)/j + " ms per file)");
+
+            } catch(IllegalArgumentException e){
+                //print the filename
+                System.out.println("Exception happened at file " + s.getAbsolutePath());
+
+                e.printStackTrace();
+            }
+
+        }
+        outtree.commit();
+        System.out.println("summed file " + out +" commited.  Total time = " + (System.currentTimeMillis()-timeStart)/1000 + " seconds");
+    
+    }
+
+    static void polyArg(String[] arg) throws IllegalArgumentException, IOException{
+        ArrayList<File> files = new ArrayList<File>();
+        boolean nextIsOutput = false;
+        for(String a : arg){
+            if(a.equals("-o")){
+                nextIsOutput = true; 
+                continue;
+            }
+            if(nextIsOutput){
+                run(files.toArray(new File[0]), a);
+                nextIsOutput = false;
+                files.clear();
+                continue;
+            }
+            files.add(new File(a));
+
+        }
+    }
 }
 

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/spaul/feecc/BinGenerator.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/spaul/feecc/BinGenerator.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/spaul/feecc/BinGenerator.java	Wed Apr 27 11:11:32 2016
@@ -5,76 +5,86 @@
 import java.io.PrintWriter;
 
 public class BinGenerator {
-	public static void main(String arg[]) throws FileNotFoundException{
-		int nBins = 20;
+    public static void main(String arg[]) throws FileNotFoundException{
+        int nBins = 32;
 
-		PrintStream pw = new PrintStream("generatedbins.txt");
-		pw.println(nBins);
-		double[] thetaBins = getThetaBins(nBins);
-		for(int i = 0; i< nBins; i++){
-			double thetaMin = thetaBins[i];
-			double thetaMax = thetaBins[i+1];
-			double phiBounds[] = getPhiBounds(thetaMin, thetaMax);
-			pw.printf("%d %.4f %.4f ", phiBounds.length/2, thetaMin, thetaMax);
-			for(int j = 0; j< phiBounds.length; j++){
-				pw.printf("%.4f ", phiBounds[j]);
-			}
-			pw.println();
-		}
-		ShowCustomBinning.main(new String[]{"generatedbins.txt"});
+        PrintStream pw = new PrintStream("generatedbins.txt");
+        pw.println(nBins);
+        double[] thetaBins = getThetaBins(nBins);
+        for(int i = 0; i< nBins; i++){
+            double thetaMin = thetaBins[i];
+            double thetaMax = thetaBins[i+1];
+            double phiBounds[] = getPhiBounds(thetaMin, thetaMax);
+            pw.printf("%d %.4f %.4f ", phiBounds.length/2, thetaMin, thetaMax);
+            for(int j = 0; j< phiBounds.length; j++){
+                pw.printf("%.4f ", phiBounds[j]);
+            }
+            pw.println();
+        }
+        ShowCustomBinning.main(new String[]{"generatedbins.txt"});
 
-	}
+    }
 
-	private static double[] getThetaBins(int nBins){
-		/*double thetaMin = 0.035;
-		double dTheta = .2/nBins;
-		double[] bins = new double[nBins +1];
-		for(int i = 0; i< nBins+1; i++){
-			bins[i] = thetaMin+dTheta*i;
-		}
-		return bins; */
-		double thetaMax = .145;
-		double thetaMin = .035;
+    private static double[] getThetaBins(int nBins){
+        /*double thetaMin = 0.035;
+        double dTheta = .2/nBins;
+        double[] bins = new double[nBins +1];
+        for(int i = 0; i< nBins+1; i++){
+            bins[i] = thetaMin+dTheta*i;
+        }
+        return bins; */
+        double thetaMax = .200;
+        double thetaMin = .040;
 
-		double[] bins = new double[nBins +1];
-		double xMin = 1/(thetaMax*thetaMax);
-		double xMax = 1/(thetaMin*thetaMin);
-		for(int i = 0; i< nBins+1; i++){
-			double x = xMax - i*(xMax-xMin)/nBins;
-			bins[i] = Math.pow(x, -.5);
-		}
-		return bins;
-	}
-	private static double[] getPhiBounds(double thetaMin, double thetaMax){
-		double phiBins[] = new double[6];
-		double dphi = .01; 
-		int edgeNumber = 0;
+        double[] bins = new double[nBins +1];
+        for(int i = 0; i<nBins+1; i++){
+            bins[i] = thetaMin+i*(thetaMax-thetaMin)/nBins;
+        }
+        return bins;
+        /*double xMin = 1/(thetaMax*thetaMax);
+        double xMax = 1/(thetaMin*thetaMin);
+        for(int i = 0; i< nBins+1; i++){
+            double x = xMax - i*(xMax-xMin)/nBins;
+            bins[i] = Math.pow(x, -.5);
+        }
+        return bins;*/
+    }
+    private static double[] getPhiBounds(double thetaMin, double thetaMax){
+        double phiBins[] = new double[6];
+        double dphi = .01; 
+        int edgeNumber = 0;
 
-		boolean prevInRange = false;
-		for(double phi = 0; phi< 3.14; phi+= dphi){
-			boolean inRange = EcalUtil.fid_ECal_spherical(thetaMin, phi) && EcalUtil.fid_ECal_spherical(thetaMax, phi)
-								&& EcalUtil.fid_ECal_spherical(thetaMin, -phi) && EcalUtil.fid_ECal_spherical(thetaMax, -phi);
-			if(inRange && !prevInRange)
-				phiBins[edgeNumber++] = phi;
-			if(prevInRange && !inRange)
-				phiBins[edgeNumber++] = phi-dphi;
-			prevInRange = inRange;	
-		}
-		if(phiBins[2] == 0)
-			return new double[]{phiBins[0], phiBins[1]};
-		if(phiBins[4] == 0)
-			return new double[]{phiBins[0], phiBins[1],phiBins[2], phiBins[3]};
-		
-		//3 segments: choose the largest two
-		if(phiBins[4] != 0 && phiBins[1] - phiBins[0] > phiBins[3]-phiBins[2] && phiBins[5] - phiBins[4] > phiBins[3]-phiBins[2]){
-			return new double[]{phiBins[0], phiBins[1],phiBins[4], phiBins[5]};
-		}
-		if(phiBins[4] != 0 && phiBins[3] - phiBins[2] > phiBins[1]-phiBins[0] && phiBins[5] - phiBins[4] > phiBins[1]-phiBins[0]){
-			return new double[]{phiBins[2], phiBins[3],phiBins[4], phiBins[5]};
-		}
-		return new double[]{phiBins[0], phiBins[1],phiBins[2], phiBins[3]};
-		
-		
-	}
+        boolean prevInRange = false;
+        for(double phi = 0; phi< 3.14; phi+= dphi){
+            
+            // make the angular cuts on the tracks such that the particles that go into that cut 
+            // are expected to be within 4 mm (~= 2 times the angular resolution of 1.5 mrad) of 
+            // the ecal cuts.  
+            double d = 4;
+            
+            boolean inRange = EcalUtil.fid_ECal_spherical_more_strict(thetaMin, phi, d) && EcalUtil.fid_ECal_spherical_more_strict(thetaMax, phi, d)
+                                && EcalUtil.fid_ECal_spherical_more_strict(thetaMin, -phi, d) && EcalUtil.fid_ECal_spherical_more_strict(thetaMax, -phi, d);
+            if(inRange && !prevInRange)
+                phiBins[edgeNumber++] = phi;
+            if(prevInRange && !inRange)
+                phiBins[edgeNumber++] = phi-dphi;
+            prevInRange = inRange;  
+        }
+        if(phiBins[2] == 0)
+            return new double[]{phiBins[0], phiBins[1]};
+        if(phiBins[4] == 0)
+            return new double[]{phiBins[0], phiBins[1],phiBins[2], phiBins[3]};
+        
+        //3 segments: choose the largest two
+        if(phiBins[4] != 0 && phiBins[1] - phiBins[0] > phiBins[3]-phiBins[2] && phiBins[5] - phiBins[4] > phiBins[3]-phiBins[2]){
+            return new double[]{phiBins[0], phiBins[1],phiBins[4], phiBins[5]};
+        }
+        if(phiBins[4] != 0 && phiBins[3] - phiBins[2] > phiBins[1]-phiBins[0] && phiBins[5] - phiBins[4] > phiBins[1]-phiBins[0]){
+            return new double[]{phiBins[2], phiBins[3],phiBins[4], phiBins[5]};
+        }
+        return new double[]{phiBins[0], phiBins[1],phiBins[2], phiBins[3]};
+        
+        
+    }
 
 }

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/spaul/feecc/CustomBinning.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/spaul/feecc/CustomBinning.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/spaul/feecc/CustomBinning.java	Wed Apr 27 11:11:32 2016
@@ -5,92 +5,76 @@
 import java.util.Scanner;
 
 public class CustomBinning {
-	public CustomBinning(File f) throws FileNotFoundException{
-		Scanner s = new Scanner(f);
+    public CustomBinning(File f) throws FileNotFoundException{
+        Scanner s = new Scanner(f);
 
-		nTheta = s.nextInt();  //number of bins in theta;
-		thetaMax = new double[nTheta];
-		thetaMin = new double[nTheta];
-		
-		phiMax = new double[nTheta][];
-		phiMin = new double[nTheta][];
-		int i = 0;
-		while(s.hasNext()){ //new row
-			int nPhi = s.nextInt();
-			thetaMin[i] = s.nextDouble();
-			thetaMax[i] = s.nextDouble();
-			
-			phiMax[i] = new double[nPhi];
-			phiMin[i] = new double[nPhi];
-			for(int j = 0; j<nPhi; j++){
-				phiMin[i][j] = s.nextDouble();
-				phiMax[i][j] = s.nextDouble();
-			}
-			i++;
-		}
-	}
-	double[][] phiMax;
-	double[][] phiMin;
-	public double thetaMax[], thetaMin[];
-	public int nTheta;
+        nTheta = s.nextInt();  //number of bins in theta;
+        thetaMax = new double[nTheta];
+        thetaMin = new double[nTheta];
+        
+        phiMax = new double[nTheta][];
+        phiMin = new double[nTheta][];
+        int i = 0;
+        while(s.hasNext()){ //new row
+            int nPhi = s.nextInt();
+            thetaMin[i] = s.nextDouble();
+            thetaMax[i] = s.nextDouble();
+            
+            phiMax[i] = new double[nPhi];
+            phiMin[i] = new double[nPhi];
+            for(int j = 0; j<nPhi; j++){
+                phiMin[i][j] = s.nextDouble();
+                phiMax[i][j] = s.nextDouble();
+            }
+            i++;
+        }
+    }
+    double[][] phiMax;
+    double[][] phiMin;
+    public double thetaMax[], thetaMin[];
+    public int nTheta;
 
-	double getSteradians(int binNumber){
-		double t1 = thetaMin[binNumber];
-		double t2 = thetaMax[binNumber];
-		double dCos = Math.cos(t1)-Math.cos(t2);
-		double dPhiTot = 0;
-		for(int i = 0; i< phiMax[binNumber].length; i++){
-			dPhiTot += phiMax[binNumber][i]-phiMin[binNumber][i];
-		}
-		return 2*dPhiTot*dCos;  //factor of two because top and bottom
-	}
-	boolean inRange(double theta, double phi){
-		phi = Math.abs(phi);
-		/*int i =(int) Math.floor((theta-theta0)/deltaTheta);
-		if(i>= nTheta || i<0)
-			return false;*/
-		if(theta > thetaMax[nTheta-1] || theta < thetaMin[0])
-			return false;
-		int i;
-		boolean found = false;
-		for(i = 0; i< nTheta; i++){
-			if(theta > thetaMin[i] && theta < thetaMax[i]){
-				found = true;
-				break;
-			}
-		}
-		if(!found)
-			return false;
-		
-		for(int j = 0; j<phiMax[i].length; j++){
-			if(phi>phiMin[i][j] && phi< phiMax[i][j])
-				return true;
-		}
-		return false;
+    double getSteradians(int binNumber){
+        double t1 = thetaMin[binNumber];
+        double t2 = thetaMax[binNumber];
+        double dCos = Math.cos(t1)-Math.cos(t2);
+        double dPhiTot = 0;
+        for(int i = 0; i< phiMax[binNumber].length; i++){
+            dPhiTot += phiMax[binNumber][i]-phiMin[binNumber][i];
+        }
+        return 2*dPhiTot*dCos;  //factor of two because top and bottom
+    }
+    boolean inRange(double theta, double phi){
+        phi = Math.abs(phi);
+        /*int i =(int) Math.floor((theta-theta0)/deltaTheta);
+        if(i>= nTheta || i<0)
+            return false;*/
+        if(theta > thetaMax[nTheta-1] || theta < thetaMin[0])
+            return false;
+        int i;
+        boolean found = false;
+        for(i = 0; i< nTheta; i++){
+            if(theta > thetaMin[i] && theta < thetaMax[i]){
+                found = true;
+                break;
+            }
+        }
+        if(!found)
+            return false;
+        
+        for(int j = 0; j<phiMax[i].length; j++){
+            if(phi>phiMin[i][j] && phi< phiMax[i][j])
+                return true;
+        }
+        return false;
 
-	}
-	public double getTotSteradians() {
-		double tot = 0;
-		for(int i = 0; i<nTheta; i++){
-			tot += getSteradians(i);
-		}
-		return tot;
-	}
-	/**
-	 * @param bin
-	 * @param a = 2E/M
-	 * @return the integral of 1/sin^4(th/2)*cos^2(th/2)/(1+a*sin^2(th/2)) times dPhi,
-	 * which appears in the integral of mott scattering.
-	 */
-	public double mottIntegralFactor(double a, int bin){
-		double dPhi = 0;
-		for(int i = 0; i< phiMax[bin].length; i++)
-			dPhi += 2*(phiMax[bin][0] - phiMin[bin][0]); //factor of 2 from top and bottom
-		
-		double csc2 = Math.pow(Math.sin(thetaMax[bin]/2), -2);
-		double Imax = (-csc2+(1+a)*Math.log(a+2*csc2));
-		       csc2 = Math.pow(Math.sin(thetaMin[bin]/2), -2);
-		double Imin = (-csc2+(1+a)*Math.log(a+2*csc2));
-		return 2*dPhi*(Imax-Imin);
-	}
+    }
+    public double getTotSteradians() {
+        double tot = 0;
+        for(int i = 0; i<nTheta; i++){
+            tot += getSteradians(i);
+        }
+        return tot;
+    }
+
 }

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/spaul/feecc/DisplayHistograms.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/spaul/feecc/DisplayHistograms.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/spaul/feecc/DisplayHistograms.java	Wed Apr 27 11:11:32 2016
@@ -3,7 +3,8 @@
 import java.io.IOException;
 
 public class DisplayHistograms {
-	public static void main(String arg[]) throws IllegalArgumentException, IOException{
-		MakeHistograms.main(new String[]{arg[0]});
-	}
+    public static void main(String arg[]) throws IllegalArgumentException, IOException{
+        //System.out.println("dognabo");
+        MakeHistograms.main(new String[]{arg[0]});
+    }
 }

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/spaul/feecc/EcalUtil.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/spaul/feecc/EcalUtil.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/spaul/feecc/EcalUtil.java	Wed Apr 27 11:11:32 2016
@@ -12,153 +12,232 @@
 import org.lcsim.event.Cluster;
 
 public class EcalUtil {
-	/**
-	 * Holly's algorithm.  
-	 * @param x x position of cluster
-	 * @param y y position of cluster
-	 * @param e energy of cluster
-	 * @param pid type of particle (11 = electron; -1 = positron)
-	 * @return array of doubles
-	 * <br> [0] theta = atan(py/pz)
-	 * <br> [1] phi = atan(px/pz) 
-	 */
-	static double [] toHollysCoordinates(double x, double y, double e, int pid){
-		if(pid == 11){
-			return new double[]{0.00071 * y +0.000357, 0.00071*x + 0.00003055*e + 0.04572/e +0.0006196};
-		} else if(pid == -11){
-			return new double[]{0.00071 * y +0.000357, 0.00071*x - 0.0006465*e + 0.045757/e +0.003465};
-		}
-		return null;
-	}
-	
-	static double getSteradians(double x, double y, double e,int pid, double dA){
-		double thetaPhi[] = toHollysCoordinates(x, y, e, pid);
-		return .00071*.00071*dA/Math.sqrt(thetaPhi[0]*thetaPhi[0]+ thetaPhi[1]*thetaPhi[1]+1);
-	}
-	
-	static boolean isSeedEdge(Cluster c){
-		CalorimeterHit seedhit  = (CalorimeterHit)c.getCalorimeterHits().get(0);
-		//	seedhit
-		int ix = seedhit.getIdentifierFieldValue("ix");
-		int iy = seedhit.getIdentifierFieldValue("iy");
-
-		//seedhit.get
-		return isEdge(ix, iy);
-	}
-	static boolean isEdge(int ix, int iy){
-		if(iy == 5 || iy == 1 || iy == -1 || iy == -5)
-			return true;
-		if(ix == -23 || ix == 23)
-			return true;
-		if((iy == 2 || iy == -2) && (ix >=-11 && ix <= -1))
-			return true;
-		return false;
-	}
-	public static boolean fid_ECal(Cluster c){
-		return fid_ECal(c.getPosition()[0], c.getPosition()[1]);
-	}
-	public static boolean fid_ECal(double x, double y)
-	{
-		y = Math.abs(y);
-
-		boolean in_fid = false;
-		double x_edge_low = -262.74;
-		double x_edge_high = 347.7;
-		double y_edge_low = 33.54;
-		double y_edge_high = 75.18;
-
-		double x_gap_low = -106.66;
-		double x_gap_high = 42.17;
-		double y_gap_high = 47.18;
-
-		y = Math.abs(y);
-
-		if( x > x_edge_low && x < x_edge_high && y > y_edge_low && y < y_edge_high )
-		{
-			if( !(x > x_gap_low && x < x_gap_high && y > y_edge_low && y < y_gap_high) )
-			{
-				in_fid = true;
-			}
-		}
-
-		return in_fid;
-	}
-	static double[] toSphericalFromBeam(double pxpz, double pypz){
-		double x = pxpz, y = pypz, z = 1;
-		double beamTilt = .03057;
-		double xtemp = Math.cos(beamTilt)*x - Math.sin(beamTilt)*z;
-		double ztemp = Math.cos(beamTilt)*z + Math.sin(beamTilt)*x;
-		double ytemp = y;
-		
-		double theta = Math.atan(Math.hypot(xtemp, ytemp)/ ztemp);
-		double phi = Math.atan2(ytemp, xtemp);
-		
-		
-		return new double[]{theta, phi};
-	}
-	static Map<Integer, double[]> map = new HashMap();
-	static void readMap() throws FileNotFoundException{
-		Scanner s = new Scanner(new File("ecal_positions.txt"));
-
-		
-		while(s.hasNext()){
-			int ix =s.nextInt();
-			int iy = s.nextInt();
-			double x = s.nextDouble();
-			double y =s.nextDouble();
-			map.put(ix+100*iy, new double[]{x, y});
-			
-		}
-		s.close();
-	}
-	static double getArea(int ix, int iy){
-		int ixp = ix+1;
-		if(ixp == 0)
-			ixp = 1;
-		int ixm = ix-1;
-		if(ixm == 0)
-			ixm = -1;
-		double[] plus = map.get(ixp+100*(iy+1));
-		double[] minus = map.get(ixm+100*(iy-1));
-		return (plus[0]-minus[0])*(plus[1]-minus[1])/4;
-	}
-	
-	public static double[] getThetaPhiSpherical(double x,double y){
-		double hcoord[] = toHollysCoordinates(x,y, 1.056, 11);
-		return toSphericalFromBeam(Math.tan(hcoord[1]),Math.tan(hcoord[0]));
-	}
-	/*beam tilt*/
-	static double tilt = .03057;
-	//assuming FEE electron.
-
-	public static double[] getXY(double theta, double phi){
-		
-		double ux = Math.cos(phi)*Math.sin(theta)*Math.cos(tilt)+Math.cos(theta)*Math.sin(tilt);
-		double uy = Math.sin(phi)*Math.sin(theta);
-		double uz = Math.cos(theta)*Math.cos(tilt)-Math.cos(phi)*Math.sin(theta)*Math.sin(tilt);
-		double pxpz = ux/uz;
-		double pypz = uy/uz;
-		//holly's coordinates:
-		double h1 = Math.atan(pypz);
-		double h2 = Math.atan(pxpz);
-		//0.00071 * y +0.000357,
-		//0.00071*x + 0.00003055*e + 0.04572/e +0.0006196
-		double y = (h1-0.000357)/0.00071;
-		double e = 1.056;
-		double x = (h2 - 0.00003055*e - 0.04572/e -0.0006196)/0.00071;
-		return new double[]{x,y};
-	}
-	public static boolean fid_ECal_spherical(double theta, double phi){
-		double[] xy = getXY(theta, phi);
-		double x = xy[0];
-		double y = xy[1];
-		return fid_ECal(x, y);
-	}
-	public static void main(String arg[]){
-		double x = 0, y = 0;
-		double sp[] = getThetaPhiSpherical(x,y); 
-		System.out.println(Arrays.toString(getXY(sp[0], sp[1])));
-	}
+    
+    static int[] getCrystalIndex(Cluster c){
+        if(map == null){
+            try{
+                readMap();
+            }catch(Exception e){
+                e.printStackTrace();
+            }
+        }
+        c.getPosition();
+        int bestix = 0, bestiy = 0;
+        double bestdist = 100000;
+
+        double cx = c.getPosition()[0];
+        double cy = c.getPosition()[1];
+        for(int ix = -23; ix<= 23; ix++){
+            if(!map.containsKey(200+ix))
+                continue;
+            double x = map.get(200+ix)[0];
+            if(Math.abs(x-cx)<bestdist){
+                bestdist = Math.abs(x-cx);
+                bestix = ix;
+            }
+        }
+        
+        bestdist = 100000;
+        for(int iy = -5; iy<= 5; iy++){
+            if(!map.containsKey(100*iy + bestix))
+                continue;
+            double y = map.get(100*iy + bestix)[1];
+            if(Math.abs(y-cy)<bestdist){
+                bestdist = Math.abs(y-cy);
+                bestiy = iy;
+            }
+        }
+        return new int[]{bestix, bestiy}; 
+    }
+    
+    
+    /**
+     * Holly's algorithm.  
+     * @param x x position of cluster
+     * @param y y position of cluster
+     * @param e energy of cluster
+     * @param pid type of particle (11 = electron; -1 = positron)
+     * @return array of doubles
+     * <br> [0] theta = atan(py/pz)
+     * <br> [1] phi = atan(px/pz) 
+     */
+    static double [] toHollysCoordinates(double x, double y, double e, int pid){
+        if(pid == 11){
+            return new double[]{0.00071 * y +0.000357, 0.00071*x + 0.00003055*e + 0.04572/e +0.0006196};
+        } else if(pid == -11){
+            return new double[]{0.00071 * y +0.000357, 0.00071*x - 0.0006465*e + 0.045757/e +0.003465};
+        }
+        return null;
+    }
+    
+    static double getSteradians(double x, double y, double e,int pid, double dA){
+        double thetaPhi[] = toHollysCoordinates(x, y, e, pid);
+        return .00071*.00071*dA/Math.sqrt(thetaPhi[0]*thetaPhi[0]+ thetaPhi[1]*thetaPhi[1]+1);
+    }
+    
+    static boolean isSeedEdge(Cluster c){
+        CalorimeterHit seedhit  = (CalorimeterHit)c.getCalorimeterHits().get(0);
+        //  seedhit
+        int ix = seedhit.getIdentifierFieldValue("ix");
+        int iy = seedhit.getIdentifierFieldValue("iy");
+
+        //seedhit.get
+        return isEdge(ix, iy);
+    }
+    static boolean isEdge(int ix, int iy){
+        if(iy == 5 || iy == 1 || iy == -1 || iy == -5)
+            return true;
+        if(ix == -23 || ix == 23)
+            return true;
+        if((iy == 2 || iy == -2) && (ix >=-11 && ix <= -1))
+            return true;
+        return false;
+    }
+    public static boolean fid_ECal(Cluster c){
+        return fid_ECal(c.getPosition()[0], c.getPosition()[1]);
+    }
+    public static boolean fid_ECal(double x, double y)
+    {
+        y = Math.abs(y);
+
+        boolean in_fid = false;
+        double x_edge_low = -262.74;
+        double x_edge_high = 347.7;
+        double y_edge_low = 33.54;
+        double y_edge_high = 75.18;
+
+        double x_gap_low = -106.66;
+        double x_gap_high = 42.17;
+        double y_gap_high = 47.18;
+
+        y = Math.abs(y);
+
+        if( x > x_edge_low && x < x_edge_high && y > y_edge_low && y < y_edge_high )
+        {
+            if( !(x > x_gap_low && x < x_gap_high && y > y_edge_low && y < y_gap_high) )
+            {
+                in_fid = true;
+            }
+        }
+
+        return in_fid;
+    }
+    /**
+     * 
+     * @param x
+     * @param y
+     * @param d the additional distance from the edge of the ecal in addition
+     *       to what is required by fid_Cal(double, double)
+     * @return
+     */
+    public static boolean fid_ecal_more_strict(double x, double y, double d){
+        y = Math.abs(y);
+
+        boolean in_fid = false;
+         
+        double x_edge_low = -262.74 + d;
+        double x_edge_high = 347.7 - d;
+        double y_edge_low = 33.54 + d;
+        double y_edge_high = 75.18 - d;
+
+        double x_gap_low = -106.66 - d;
+        double x_gap_high = 42.17 + d;
+        double y_gap_high = 47.18 + d;
+
+        y = Math.abs(y);
+
+        if( x > x_edge_low && x < x_edge_high && y > y_edge_low && y < y_edge_high )
+        {
+            if( !(x > x_gap_low && x < x_gap_high && y > y_edge_low && y < y_gap_high) )
+            {
+                in_fid = true;
+            }
+        }
+
+        return in_fid;
+    }
+    static double[] toSphericalFromBeam(double pxpz, double pypz){
+        double x = pxpz, y = pypz, z = 1;
+        double beamTilt = .03057;
+        double xtemp = Math.cos(beamTilt)*x - Math.sin(beamTilt)*z;
+        double ztemp = Math.cos(beamTilt)*z + Math.sin(beamTilt)*x;
+        double ytemp = y;
+        
+        double theta = Math.atan(Math.hypot(xtemp, ytemp)/ ztemp);
+        double phi = Math.atan2(ytemp, xtemp);
+        
+        
+        return new double[]{theta, phi};
+    }
+    static Map<Integer, double[]> map ;
+    static void readMap() throws FileNotFoundException{
+        Scanner s = new Scanner(new File(System.getenv("HOME") + "/ecal_positions.txt"));
+        map = new HashMap();
+        
+        while(s.hasNext()){
+            int ix =s.nextInt();
+            int iy = s.nextInt();
+            double x = s.nextDouble();
+            double y =s.nextDouble();
+            map.put(ix+100*iy, new double[]{x, y});
+            
+        }
+        s.close();
+    }
+    static double getArea(int ix, int iy){
+        int ixp = ix+1;
+        if(ixp == 0)
+            ixp = 1;
+        int ixm = ix-1;
+        if(ixm == 0)
+            ixm = -1;
+        double[] plus = map.get(ixp+100*(iy+1));
+        double[] minus = map.get(ixm+100*(iy-1));
+        return (plus[0]-minus[0])*(plus[1]-minus[1])/4;
+    }
+    
+    public static double[] getThetaPhiSpherical(double x,double y){
+        double hcoord[] = toHollysCoordinates(x,y, 1.056, 11);
+        return toSphericalFromBeam(Math.tan(hcoord[1]),Math.tan(hcoord[0]));
+    }
+    /*beam tilt*/
+    static double tilt = .03057;
+    //assuming FEE electron.
+
+    public static double[] getXY(double theta, double phi){
+        
+        double ux = Math.cos(phi)*Math.sin(theta)*Math.cos(tilt)+Math.cos(theta)*Math.sin(tilt);
+        double uy = Math.sin(phi)*Math.sin(theta);
+        double uz = Math.cos(theta)*Math.cos(tilt)-Math.cos(phi)*Math.sin(theta)*Math.sin(tilt);
+        double pxpz = ux/uz;
+        double pypz = uy/uz;
+        //holly's coordinates:
+        double h1 = Math.atan(pypz);
+        double h2 = Math.atan(pxpz);
+        //0.00071 * y +0.000357,
+        //0.00071*x + 0.00003055*e + 0.04572/e +0.0006196
+        double y = (h1-0.000357)/0.00071;
+        double e = 1.056;
+        double x = (h2 - 0.00003055*e - 0.04572/e -0.0006196)/0.00071;
+        return new double[]{x,y};
+    }
+    public static boolean fid_ECal_spherical(double theta, double phi){
+        double[] xy = getXY(theta, phi);
+        double x = xy[0];
+        double y = xy[1];
+        return fid_ECal(x, y);
+    }
+    public static boolean fid_ECal_spherical_more_strict(double theta, double phi, double d){
+        double[] xy = getXY(theta, phi);
+        double x = xy[0];
+        double y = xy[1];
+        return fid_ecal_more_strict(x, y, d);
+    }
+    public static void main(String arg[]){
+        double x = 0, y = 0;
+        double sp[] = getThetaPhiSpherical(x,y); 
+        System.out.println(Arrays.toString(getXY(sp[0], sp[1])));
+    }
 }
-	
-
+    
+

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/spaul/feecc/MakeHistograms.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/spaul/feecc/MakeHistograms.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/spaul/feecc/MakeHistograms.java	Wed Apr 27 11:11:32 2016
@@ -2,12 +2,15 @@
 
 import java.io.File;
 import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.Date;
 import java.util.List;
 
 import org.hps.conditions.ConditionsDriver;
+import org.hps.recon.tracking.TrackType;
 import org.hps.record.triggerbank.AbstractIntData;
 import org.hps.record.triggerbank.TIData;
 import org.lcsim.event.CalorimeterHit;
@@ -15,9 +18,12 @@
 import org.lcsim.event.EventHeader;
 import org.lcsim.event.GenericObject;
 import org.lcsim.event.ReconstructedParticle;
+import org.lcsim.event.Track;
+import org.lcsim.event.TrackState;
 import org.lcsim.lcio.LCIOReader;
 
 import hep.aida.IAnalysisFactory;
+import hep.aida.IDataPointSetFactory;
 import hep.aida.IHistogram1D;
 import hep.aida.IHistogram2D;
 import hep.aida.IHistogramFactory;
@@ -29,232 +35,448 @@
 import org.hps.users.spaul.StyleUtil;
 
 public class MakeHistograms {
-	static boolean display = false;
-	static CustomBinning cb;
-	public static void main(String arg[]) throws IllegalArgumentException, IOException{
-		if(arg.length == 1){
-			File file = new File(arg[0]);
-			String path = arg[0];
-			if(file.isDirectory()){
-				org.hps.users.spaul.SumEverything.main(new String[]{path, "temp.aida"});
-				path = "temp.aida";
-			}
-			IAnalysisFactory af = IAnalysisFactory.create();
-			 ITreeFactory tf = af.createTreeFactory();
-			ITree tree0 = tf.create(path, "xml");
-			extractHistograms(tree0);
-			setupPlotter(af);
-			
-		} else{
-
-			String input = arg[0];
-			String output = arg[1];
-			cb = new CustomBinning(new File(arg[2]));
-			if(arg.length == 5)
-				display = true;
-			IAnalysisFactory af = IAnalysisFactory.create();
-			ITree tree = af.createTreeFactory().create(output,"xml",false,true);
-			IHistogramFactory hf = af.createHistogramFactory(tree);
-			setupHistograms(hf);
-			if(display){
-				setupPlotter(af);
-			}
-			ConditionsDriver hack = new ConditionsDriver();
-			//hack.setXmlConfigResource("/u/group/hps/hps_soft/detector-data/detectors/HPS-EngRun2015-Nominal-v3");
-			hack.setDetectorName("HPS-EngRun2015-Nominal-v3");
-			hack.setFreeze(true);
-			hack.setRunNumber(Integer.parseInt(arg[3]));
-			hack.initialize();
-			LCIOReader reader = new LCIOReader(new File(input));
-			//reader.open(input);
-			//reader.
-			EventHeader event = reader.read();
-			int nEvents = 0;
-			try{
-				outer : while(event != null){
-					processEvent(event);
-
-					//System.out.println(Q2);
-
-					event = reader.read();
-				}
-			} catch (Exception e){
-				e.printStackTrace();
-			}
-			tree.commit();
-			tree.close();
-		}
-
-	}
-	
-	static IHistogram2D h1, h2, h2a, h2b, h2c;
-	static IHistogram2D h4,h4a;
-	static IHistogram1D h3, h3a;
-	static IHistogram1D h5, h6;
-	
-	private static void extractHistograms(ITree tree0) {
-		h2 = (IHistogram2D) tree0.find("theta vs phi");
-		h2a = (IHistogram2D) tree0.find("theta vs phi cut");
-		h2b = (IHistogram2D) tree0.find("theta vs phi cut alt");
-		h2c = (IHistogram2D) tree0.find("theta vs phi alt");
-		
-		h3 = (IHistogram1D) tree0.find("theta");
-		h4 = (IHistogram2D) tree0.find("px\\/pz vs py\\/pz");
-		h4a = (IHistogram2D) tree0.find("px\\/pz vs py\\/pz cut");
-		h5 = (IHistogram1D) tree0.find("energy");
-		
-	}
-	static void setupHistograms(IHistogramFactory hf){
-		//h1 = hf.createHistogram2D("px\\/pz vs py\\/pz", 160, -.16, .24, 160, -.2, .2);
-		
-		
-		
-		
-		h2 = hf.createHistogram2D("theta vs phi", 300, 0, .3, 314, -3.14, 3.14);
-		
-		h2a = hf.createHistogram2D("theta vs phi cut", 300, 0, .3, 314, -3.14, 3.14);
-
-		double thetaBins[] = new double[cb.nTheta+1];
-		for(int i = 0; i<cb.nTheta; i++){
-			thetaBins[i] = cb.thetaMin[i];
-		}
-		
-		thetaBins[thetaBins.length-1] = cb.thetaMax[cb.nTheta-1];
-
-		double phiBins[] = new double[315];
-		for(int i = 0; i<315; i++){
-			phiBins[i] = i/50.-3.14;  //every 10 mrad;
-		}
-		
-		//identical to h2a, except different binning
-		h2b = hf.createHistogram2D("theta vs phi cut alt", "theta vs phi cut alt", thetaBins, phiBins);
-		h2c = hf.createHistogram2D("theta vs phi alt", "theta vs phi alt", thetaBins, phiBins);
-		
-		h3 = hf.createHistogram1D("theta", "theta", thetaBins);
-
-		h4 = hf.createHistogram2D("px\\/pz vs py\\/pz", 160, -.16, .24, 160, -.2, .2);
-		h4a = hf.createHistogram2D("px\\/pz vs py\\/pz cut", 160, -.16, .24, 160, -.2, .2);
-		
-		h5 = hf.createHistogram1D("energy", 75, 0, 1.5);
-	}
-	static void setupPlotter(IAnalysisFactory af){
-		IPlotterFactory pf = af.createPlotterFactory();
-		IPlotter p = pf.create();
-		p.createRegions(2,2);
-		p.region(0).plot(h2);
-
-		StyleUtil.stylize(p.region(0), "theta", "phi");
-		p.region(1).plot(h2a);
-		StyleUtil.stylize(p.region(1), "theta", "phi");
-		p.region(2).plot(h3);
-		StyleUtil.stylize(p.region(2), "theta", "# of particles");
-		p.region(3).plot(h5);
-		StyleUtil.stylize(p.region(3), "energy", "# of particles");
-		
-		p.show();
-		//new window for the next plot
-		IPlotter p2 = pf.create();
-		p2.region(0).plot(h2b);
-		StyleUtil.stylize(p2.region(0), "theta", "phi");
-		
-		p2.show();
-		
-		//new window for the next plot
-		IPlotter p3 = pf.create();
-		p3.region(0).plot(h2c);
-		StyleUtil.stylize(p3.region(0), "theta", "phi");
-		
-		p3.show();
-		
-		//new window for the next plot
-		IPlotter p4 = pf.create();
-		p4.region(0).plot(h4);
-		StyleUtil.stylize(p4.region(0), "px/pz", "py/pz");
-		
-		p4.show();
-		
-		//new window for the next plot
-		IPlotter p5 = pf.create();
-		p5.region(0).plot(h4a);
-		StyleUtil.stylize(p5.region(0), "px/pz", "py/pz");
-		
-		p5.show();
-	}
-	private static void processEvent(EventHeader event) {
-		if(event.getEventNumber() %1000 == 0)
-			System.out.println("event number " + event.getEventNumber());
-		
-		for (GenericObject gob : event.get(GenericObject.class,"TriggerBank"))
-		{
-			if (!(AbstractIntData.getTag(gob) == TIData.BANK_TAG)) continue;
-			TIData tid = new TIData(gob);
-			if (!tid.isSingle1Trigger())
-			{
-				return;
-			}
-		}
-		List<ReconstructedParticle> particles = event.get(ReconstructedParticle.class, "FinalStateParticles");
-
-		for(ReconstructedParticle p : particles){
-
-			boolean isGood = addParticle(p);
-
-
-		}
-	}
-
-	static double eMin = .8;
-	static double eMax = 1.2;
-	static double beamEnergy = 1.057;
-
-	static double beamTilt = .03057;
-	static double maxChi2 = 50;
-	static boolean addParticle(ReconstructedParticle part){
-		
-		if(part.getTracks().size() == 0)
-			return false;
-		if(part.getTracks().get(0).getChi2()>maxChi2){
-			return false;
-		}
-		if(part.getClusters().size() == 0)
-			return false;
-		Cluster c = part.getClusters().get(0);
-		double time = c.getCalorimeterHits().get(0).getTime();
-		if(EcalUtil.fid_ECal(c)){
-			if(c.getCalorimeterHits().size() < 3)
-				return false;
-			if(time>40 && time <48)
-				h5.fill(c.getEnergy());
-			if(c.getEnergy() > eMin && c.getEnergy() < eMax && (time >40 && time < 48)) {
-
-				Hep3Vector p = part.getMomentum();
-				
-				double px = p.x(), pz = p.z();
-				double pxtilt = px*Math.cos(beamTilt)-pz*Math.sin(beamTilt);
-				double py = p.y();
-				double pztilt = pz*Math.cos(beamTilt)+px*Math.sin(beamTilt);
-
-				double theta = Math.atan(Math.hypot(pxtilt, py)/pztilt);
-				double phi =Math.atan2(py, pxtilt);
-
-				h2.fill(theta, phi);
-				h2c.fill(theta, phi);
-				
-				h4.fill(px/pz, py/pz);
-				
-				if(cb.inRange(theta, phi)){
-					h2a.fill(theta, phi);
-					h2b.fill(theta, phi);
-					h3.fill(theta);
-					h4a.fill(px/pz, py/pz);
-				}
-
-
-				return true;
-			}
-
-		}
-		return false;
-	}
-
+    
+    
+    
+    static boolean display = false;
+    static CustomBinning cb;
+    public static void main(String arg[]) throws IllegalArgumentException, IOException{
+        if(arg.length == 1){
+            File file = new File(arg[0]);
+            String path = arg[0];
+            if(file.isDirectory()){
+                org.hps.users.spaul.SumEverything.main(new String[]{path, "temp.aida"});
+                path = "temp.aida";
+            }
+            IAnalysisFactory af = IAnalysisFactory.create();
+            ITreeFactory tf = af.createTreeFactory();
+            ITree tree0 = tf.create(path, "xml");
+            extractHistograms(tree0);
+            setupPlotter(af);
+
+        } else{
+
+            String input = arg[0];
+            String output = arg[1];
+            cb = new CustomBinning(new File(arg[2]));
+            if(arg[arg.length -1].equals("display"))
+                display = true;
+            IAnalysisFactory af = IAnalysisFactory.create();
+            ITree tree = af.createTreeFactory().create(output,"xml",false,true);
+            IHistogramFactory hf = af.createHistogramFactory(tree);
+            setupHistograms(hf);
+            if(display){
+                setupPlotter(af);
+            }
+            ConditionsDriver hack = new ConditionsDriver();
+            //hack.setXmlConfigResource("/u/group/hps/hps_soft/detector-data/detectors/HPS-EngRun2015-Nominal-v3");
+            hack.setDetectorName("HPS-EngRun2015-Nominal-v3");
+            hack.setFreeze(true);
+            hack.setRunNumber(Integer.parseInt(arg[3]));
+            
+            hack.initialize();
+            beamTiltY = Double.parseDouble(arg[4]);
+            beamTiltX = Double.parseDouble(arg[5]);
+            LCIOReader reader = new LCIOReader(new File(input));
+            //reader.open(input);
+            //reader.
+            EventHeader event = reader.read();
+            int nEvents = 0;
+            try{
+                outer : while(event != null){
+                    processEvent(event);
+
+                    //System.out.println(Q2);
+
+                    event = reader.read();
+                }
+            } catch (Exception e){
+                e.printStackTrace();
+            }
+            tree.commit();
+            tree.close();
+        }
+
+    }
+
+    static IHistogram2D h1, h2, h2a, h2b, h2c;
+    static IHistogram2D h4,h4a;
+    static IHistogram1D h3, /*h3a,*/ h3_t, h3_b;
+    static IHistogram1D h5, h5a; 
+    //static IHistogram2D h6, h6a;
+    static IHistogram1D h7, h7a;
+    static IHistogram1D h8;
+    static IHistogram1D h9_t, h9_b;
+    static IHistogram1D h10_t, h10_b;
+    private static IHistogram1D h4y;
+
+    private static void extractHistograms(ITree tree0) {
+        h1 = (IHistogram2D) tree0.find("theta vs energy");
+
+        h2 = (IHistogram2D) tree0.find("theta vs phi");
+        h2a = (IHistogram2D) tree0.find("theta vs phi cut");
+        h2b = (IHistogram2D) tree0.find("theta vs phi cut alt");
+        h2c = (IHistogram2D) tree0.find("theta vs phi alt");
+
+        h3 = (IHistogram1D) tree0.find("theta");
+        //h3a = (IHistogram1D) tree0.find("theta isolated ");
+        h3_t = (IHistogram1D) tree0.find("theta top");
+        h3_b = (IHistogram1D) tree0.find("theta bottom");
+        
+        h4 = (IHistogram2D) tree0.find("px\\/pz vs py\\/pz");
+        h4a = (IHistogram2D) tree0.find("px\\/pz vs py\\/pz cut");
+        System.out.println(h4a.xAxis().bins());
+        h5 = (IHistogram1D) tree0.find("energy top");
+        h5 = (IHistogram1D) tree0.find("energy bottom");
+
+//      h6 = (IHistogram2D) tree0.find("cluster");
+//      h6a = (IHistogram2D) tree0.find("cluster matched");
+        h7 = (IHistogram1D) tree0.find("y top");
+        h7a = (IHistogram1D) tree0.find("y bottom");
+        h8 = (IHistogram1D) tree0.find("seed energy");
+        
+
+        h9_t = (IHistogram1D) tree0.find("pz top");
+        h9_b = (IHistogram1D) tree0.find("pz bottom");
+        
+
+        h10_t = (IHistogram1D) tree0.find("clustsize top");
+        h10_b = (IHistogram1D) tree0.find("clustsize bottom");
+
+    }
+    static void setupHistograms(IHistogramFactory hf){
+        //h1 = hf.createHistogram2D("px\\/pz vs py\\/pz", 160, -.16, .24, 160, -.2, .2);
+
+
+
+
+        h2 = hf.createHistogram2D("theta vs phi", 300, 0, .3, 314, -3.14, 3.14);
+
+        h2a = hf.createHistogram2D("theta vs phi cut", 300, 0, .3, 314, -3.14, 3.14);
+
+        double thetaBins[] = new double[cb.nTheta+1];
+        for(int i = 0; i<cb.nTheta; i++){
+            thetaBins[i] = cb.thetaMin[i];
+        }
+
+        thetaBins[thetaBins.length-1] = cb.thetaMax[cb.nTheta-1];
+
+        double phiBins[] = new double[315];
+        for(int i = 0; i<315; i++){
+            phiBins[i] = i/50.-3.14;  //every 10 mrad;
+        }
+
+        double eBins[] = new double[66];
+        for(int i = 0; i<66; i++){
+            eBins[i] = i/50.;  //every 20 MeV up to 1300 MeV
+        }
+
+
+        h1 = hf.createHistogram2D("theta vs energy", "theta vs energy", thetaBins, eBins);
+
+
+        //identical to h2a, except different binning
+        h2b = hf.createHistogram2D("theta vs phi cut alt", "theta vs phi cut alt", thetaBins, phiBins);
+        h2c = hf.createHistogram2D("theta vs phi alt", "theta vs phi alt", thetaBins, phiBins);
+
+        h3 = hf.createHistogram1D("theta", "theta", thetaBins);
+//      h3a = hf.createHistogram1D("theta isolated ", "theta isolated", thetaBins);
+
+        h3_t = hf.createHistogram1D("theta top", "theta top", thetaBins);
+        h3_b = hf.createHistogram1D("theta bottom", "theta bottom", thetaBins);
+
+        
+        h4 = hf.createHistogram2D("px\\/pz vs py\\/pz", 300, -.16, .24, 300, -.2, .2);
+        h4a = hf.createHistogram2D("px\\/pz vs py\\/pz cut", 300, -.16, .24, 300, -.2, .2);
+        h4y = hf.createHistogram1D("py\\pz", 1200, -.06, .06);
+        
+        h5 = hf.createHistogram1D("energy top", 75, 0, 1.5);
+        h5a = hf.createHistogram1D("energy bottom", 75, 0, 1.5);
+        
+
+        h9_t = hf.createHistogram1D("pz top", 75, 0, 1.5);
+        h9_b = hf.createHistogram1D("pz bottom", 75, 0, 1.5);
+        
+//      h6 = hf.createHistogram2D("cluster", 47, -23.5, 23.5, 11, -5.5, 5.5);
+//      h6a = hf.createHistogram2D("cluster matched", 47, -23.5, 23.5, 11, -5.5, 5.5);
+
+        h7 = hf.createHistogram1D("y top", 500, 0, 100);
+
+        h7a = hf.createHistogram1D("y bottom", 500, 0, 100);
+
+        h8 = hf.createHistogram1D("seed energy", 120, 0, 1.2);
+        
+        h10_t = hf.createHistogram1D("clustsize top", 10,0, 10);
+        h10_b = hf.createHistogram1D("clustsize bottom", 10,0, 10);
+    }
+    static void setupPlotter(IAnalysisFactory af){
+        IPlotterFactory pf = af.createPlotterFactory();
+        IPlotter p = pf.create();
+        p.createRegions(2,2);
+        p.region(0).plot(h2);
+        StyleUtil.stylize(p.region(0), "theta", "phi");
+//      p.region(1).plot(h3a);
+        StyleUtil.stylize(p.region(1), "theta", "# of particles");
+        p.region(2).plot(h9_t);
+        p.region(2).plot(h9_b);
+        StyleUtil.noFillHistogramBars(p.region(2));
+        StyleUtil.stylize(p.region(2), "pztilt" ,"pztilt", "# of particles");
+        p.region(3).plot(h5);
+        p.region(3).plot(h5a);
+        StyleUtil.noFillHistogramBars(p.region(3));
+        StyleUtil.stylize(p.region(3), "energy", "# of particles");
+
+        p.show();
+        
+        //new window for the next plot
+        IPlotter p2 = pf.create();
+        p2.region(0).plot(h2b);
+        //IDataPointSetFactory dpsf = af.createDataPointSetFactory(af.createTreeFactory().create());
+
+        StyleUtil.stylize(p2.region(0), "theta", "phi");
+
+        p2.show();
+
+        //new window for the next plot
+        IPlotter p3 = pf.create();
+        p3.region(0).plot(h2c);
+        StyleUtil.stylize(p3.region(0), "theta", "phi");
+
+        p3.show();
+
+        //new window for the next plot
+        IPlotter p4 = pf.create();
+        p4.region(0).plot(h4);
+        StyleUtil.stylize(p4.region(0), "px/pz", "py/pz");
+
+        p4.show();
+
+        //new window for the next plot
+        IPlotter p5 = pf.create();
+        p5.region(0).plot(h4a);
+        StyleUtil.stylize(p5.region(0), "px/pz", "py/pz");
+
+        p5.show();
+
+        IPlotter p6 = pf.create("efficiency");
+        p6.createRegions(1,2);
+//      p6.region(0).plot(h6);
+        StyleUtil.stylize(p6.region(0), "ix", "iy");
+//      p6.region(1).plot(h6a);
+        StyleUtil.stylize(p6.region(1), "ix", "iy");
+        p6.show();
+
+        IPlotter p7 = pf.create("theta vs energy");
+        //p6.createRegions(1,2);
+        p7.region(0).plot(h1);
+        StyleUtil.stylize(p7.region(0), "theta", "energy");
+        //      StyleUtil.stylize(p6.region(1), "ix", "iy");
+        p7.show();
+
+        IPlotter p8 = pf.create("y");
+        //p6.createRegions(1,2);
+        p8.region(0).plot(h7);
+        p8.region(0).plot(h7a);
+        StyleUtil.stylize(p8.region(0), "y", "# of particles");
+        //      StyleUtil.stylize(p6.region(1), "ix", "iy");
+        p8.show();
+        
+        IPlotter p9 = pf.create("theta: top vs. bottom");
+        //p6.createRegions(1,2);
+        p9.region(0).plot(h3_t);
+        p9.region(0).plot(h3_b);
+        StyleUtil.stylize(p9.region(0), "theta", "theta", "# of particles");
+        StyleUtil.noFillHistogramBars(p9.region(0));
+                //StyleUtil.stylize(p6.region(1), "ix", "iy");
+        p9.show();
+        
+        IPlotter p10 = pf.create("seed energy");
+        //p6.createRegions(1,2);
+        p10.createRegions(2,1);
+        p10.region(0).plot(h8);
+        StyleUtil.stylize(p10.region(0), "seed energy", "seed energy (GeV)", "# of particles");
+        
+        p10.region(1).plot(h10_t);
+        p10.region(1).plot(h10_b);
+        StyleUtil.noFillHistogramBars(p10.region(1));
+        StyleUtil.stylize(p10.region(1), "clust size", "n ecal hits", "# of particles");
+        
+        //StyleUtil.noFillHistogramBars(p10.region(0));
+                //StyleUtil.stylize(p6.region(1), "ix", "iy");
+        p10.show();
+
+    }
+    private static void processEvent(EventHeader event) {
+        if(event.getEventNumber() %10000 == 0)
+            System.out.println("event number " + event.getEventNumber());
+
+        for (GenericObject gob : event.get(GenericObject.class,"TriggerBank"))
+        {
+            if (!(AbstractIntData.getTag(gob) == TIData.BANK_TAG)) continue;
+            TIData tid = new TIData(gob);
+            if (!tid.isSingle1Trigger())
+            {
+                return;
+            }
+        }
+        List<ReconstructedParticle> particles = event.get(ReconstructedParticle.class, "FinalStateParticles");
+        particles = RemoveDuplicateParticles.removeDuplicateParticles(particles);
+        outer : for(ReconstructedParticle p : particles){
+            
+
+            boolean isGood = addParticle(p);
+            
+
+        }
+        
+    }
+
+    
+
+    static double eMin = .8;
+    static double eMax = 1.2;
+    static double beamEnergy = 1.057;
+
+    static double beamTiltX = .03057;
+    static double beamTiltY;
+    static double maxChi2 = 50;
+    //maximum difference between the reconstructed energy and momentum
+    static double maxdE = .5;
+
+    static double seedEnergyCut = .4;
+
+
+    static boolean addParticle(ReconstructedParticle part){
+        if(part.getTracks().size() != 0){
+            if(part.getMomentum().magnitudeSquared() > .8
+                    && part.getTracks().get(0).getChi2() > maxChi2){
+                h4y.fill(part.getMomentum().y()/part.getMomentum().z());
+            }
+        }
+        if(part.getCharge() != -1)
+            return false;
+        if(part.getClusters().size() == 0)
+            return false;
+        Cluster c = part.getClusters().get(0);
+        double time = c.getCalorimeterHits().get(0).getTime();
+
+        if(!(time>40 && time <50))
+            return false;
+        double seedEnergy = 0;
+        for(CalorimeterHit hit : c.getCalorimeterHits()){
+            if(hit.getCorrectedEnergy() > seedEnergy)
+                seedEnergy = hit.getCorrectedEnergy();
+        }
+        h8.fill(seedEnergy);
+        
+        
+        if(seedEnergy < seedEnergyCut)
+            return false;
+        
+        if(c.getPosition()[1] > 0){
+            h10_t.fill(c.getSize());
+        }
+        else{ 
+            h10_b.fill(c.getSize());
+        }
+        
+        
+        if(c.getCalorimeterHits().size() < 3)
+            return false;
+        
+
+        if(c.getEnergy() > eMin && c.getEnergy() < eMax){
+            if(c.getPosition()[1] > 0)
+                h7.fill(c.getPosition()[1]);
+            else if(c.getPosition()[1] < 0)
+                h7a.fill(-c.getPosition()[1]);
+        }
+        
+        if(EcalUtil.fid_ECal(c)){
+            
+            if(c.getPosition()[1] > 0){
+                h5.fill(c.getEnergy());
+            }
+            else{ 
+                h5a.fill(c.getEnergy());
+            }
+            if(part.getTracks().size() == 0)
+                return false;
+            Track t = part.getTracks().get(0);
+            if(t.getChi2()>maxChi2){
+                return false;
+            }
+            if(!TrackType.isGBL(t.getType()))
+                return false;
+            
+            
+            
+            Hep3Vector p = part.getMomentum();
+
+
+
+            double px = p.x(), pz = p.z();
+            double pxtilt = px*Math.cos(beamTiltX)-pz*Math.sin(beamTiltX);
+            double py = p.y();
+            double pztilt = pz*Math.cos(beamTiltX)+px*Math.sin(beamTiltX);
+            
+            double pytilt = py*Math.cos(beamTiltY)-pztilt*Math.sin(beamTiltY);
+            pztilt = pz*Math.cos(beamTiltY) + pytilt*Math.sin(beamTiltY);
+
+            if(Math.abs(pztilt - c.getEnergy()) > maxdE)
+                return false;
+            if(c.getPosition()[1] > 0)
+                h9_t.fill(pztilt);
+            else
+                h9_b.fill(pztilt);
+
+            double theta = Math.atan(Math.hypot(pxtilt, pytilt)/pztilt);
+            double phi =Math.atan2(pytilt, pxtilt);
+            boolean inRange = cb.inRange(theta, phi);
+            if(inRange)
+                h1.fill(theta, c.getEnergy());
+
+
+
+            if(c.getEnergy() > eMin && c.getEnergy() < eMax) {
+
+
+
+                h2.fill(theta, phi);
+                h2c.fill(theta, phi);
+
+                h4.fill(px/pz, py/pz);
+                //h4y.fill(py/pz);
+
+                if(inRange){
+
+                    //System.out.println(c.getEnergy() + " " + t.getType());
+                    /*for(TrackState ts : t.getTrackStates()){
+                        if(ts.getLocation() == TrackState.AtIP)
+                            System.out.println(Arrays.toString( 
+                                    ts.getReferencePoint()));
+                    }*/
+                    h2a.fill(theta, phi);
+                    h2b.fill(theta, phi);
+                    
+                    h3.fill(theta);
+                    if(py > 0)
+                        h3_t.fill(theta);
+                    else 
+                        h3_b.fill(theta);
+                    //if(h3_t.sumBinHeights()+h3_b.sumBinHeights() != h3.sumBinHeights())
+                        //System.out.println("NABO ERROR");
+                    
+                    
+                    h4a.fill(px/pz, py/pz);
+                }
+
+
+                return true;
+            }
+
+        }
+        return false;
+    }
+    
 }

Modified: java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/spaul/feecc/ShowCustomBinning.java
 =============================================================================
--- java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/spaul/feecc/ShowCustomBinning.java	(original)
+++ java/branches/HPSJAVA-409/users/src/main/java/org/hps/users/spaul/feecc/ShowCustomBinning.java	Wed Apr 27 11:11:32 2016
@@ -2,10 +2,16 @@
 
 import java.awt.Canvas;
 import java.awt.Color;
+import java.awt.Container;
+import java.awt.Font;
 import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.image.BufferedImage;
 import java.io.File;
 import java.io.FileNotFoundException;
-
+import java.io.IOException;
+
+import javax.imageio.ImageIO;
 import javax.swing.JFrame;
 
 import hep.aida.IAnalysisFactory;
@@ -18,201 +24,277 @@
 import hep.aida.ITreeFactory;
 
 public class ShowCustomBinning extends Canvas{
-	/**
-	 * show Rafo's fiducial cuts translated into rotated theta and phi, 
-	 * and overlay this with my bins in x and y.  
-	 * @param arg
-	 * @throws FileNotFoundException 
-	 */
-	public static void main(String arg[]) throws FileNotFoundException{
-		JFrame frame = new JFrame();
-		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
-		frame.add(new ShowCustomBinning(new File(arg[0])));
-		frame.setSize(800, 800);
-		frame.setVisible(true);
-		
-	}
-	public void paint(Graphics g){
-		drawEcalOutline(g);
-		drawFidEcalOutline(g);
-		drawCustomBinRectangles(g);
-	}
-	
-	void drawFidEcalOutline(Graphics g){
-		g.setColor(Color.GRAY);
-		double x_edge_low = -262.74;
-		double x_edge_high = 347.7;
-		double y_edge_low = 33.54;
-		double y_edge_high = 75.18;
-
-		double x_gap_low = -106.66;
-		double x_gap_high = 42.17;
-		double y_gap_high = 47.18;
-		double x1,y1, x2, y2;
-		double nPoints = 500;
-		for(int i = 0; i< nPoints-1; i++){
-			x1 = x_gap_high+i/nPoints*(x_edge_high-x_gap_high);
-			x2 = x_gap_high+(i+1)/nPoints*(x_edge_high-x_gap_high);
-			y1 = y_edge_low;
-			y2 = y1;
-			drawEcalFaceLine(g, x1, y1, x2, y2);
-			drawEcalFaceLine(g, x1, -y1, x2, -y2);
-			
-			
-			x1 = x_edge_low+i/nPoints*(x_gap_low-x_edge_low);
-			x2 = x_edge_low+(i+1)/nPoints*(x_gap_low-x_edge_low);
-			y1 = y2 = y_edge_low;
-			drawEcalFaceLine(g, x1, y1, x2, y2);
-			drawEcalFaceLine(g, x1, -y1, x2, -y2);
-			
-			
-			
-			x1 = x_gap_low+i/nPoints*(x_gap_high-x_gap_low);
-			x2 = x_gap_low+(i+1)/nPoints*(x_gap_high-x_gap_low);
-			y1 = y2 = y_gap_high;
-			drawEcalFaceLine(g, x1, y1, x2, y2);
-			drawEcalFaceLine(g, x1, -y1, x2, -y2);
-			
-			x1 = x_edge_low+i/nPoints*(x_edge_high-x_edge_low);
-			x2 = x_edge_low+(i+1)/nPoints*(x_edge_high-x_edge_low);
-			y1 = y2 = y_edge_high;
-			drawEcalFaceLine(g, x1, y1, x2, y2);
-			drawEcalFaceLine(g, x1, -y1, x2, -y2);
-		}
-		drawEcalFaceLine(g, x_gap_low, y_edge_low, x_gap_low, y_gap_high);
-		drawEcalFaceLine(g, x_gap_high, y_edge_low, x_gap_high, y_gap_high);
-
-		drawEcalFaceLine(g, x_edge_low, y_edge_low, x_edge_low, y_edge_high);
-		drawEcalFaceLine(g, x_edge_high, y_edge_low, x_edge_high, y_edge_high);
-		
-
-		drawEcalFaceLine(g, x_gap_low, -y_edge_low, x_gap_low, -y_gap_high);
-		drawEcalFaceLine(g, x_gap_high, -y_edge_low, x_gap_high, -y_gap_high);
-
-		drawEcalFaceLine(g, x_edge_low, -y_edge_low, x_edge_low, -y_edge_high);
-		drawEcalFaceLine(g, x_edge_high, -y_edge_low, x_edge_high, -y_edge_high);
-	
-	}
-	
-	void drawEcalOutline(Graphics g){
-		g.setColor(Color.BLACK);
-		double x_edge_low = -276.50;
-		double x_edge_high = 361.55;
-		double y_edge_low = 20.17;
-		double y_edge_high = 89;
-
-		double x_gap_low = -93.30;
-		double x_gap_high = 28.93;
-		double y_gap_high = 33.12;
-		double x1,y1, x2, y2;
-		double nPoints = 500;
-		for(int i = 0; i< nPoints-1; i++){
-			x1 = x_gap_high+i/nPoints*(x_edge_high-x_gap_high);
-			x2 = x_gap_high+(i+1)/nPoints*(x_edge_high-x_gap_high);
-			y1 = y_edge_low;
-			y2 = y1;
-			drawEcalFaceLine(g, x1, y1, x2, y2);
-			drawEcalFaceLine(g, x1, -y1, x2, -y2);
-			
-			
-			x1 = x_edge_low+i/nPoints*(x_gap_low-x_edge_low);
-			x2 = x_edge_low+(i+1)/nPoints*(x_gap_low-x_edge_low);
-			y1 = y2 = y_edge_low;
-			drawEcalFaceLine(g, x1, y1, x2, y2);
-			drawEcalFaceLine(g, x1, -y1, x2, -y2);
-			
-			
-			
-			x1 = x_gap_low+i/nPoints*(x_gap_high-x_gap_low);
-			x2 = x_gap_low+(i+1)/nPoints*(x_gap_high-x_gap_low);
-			y1 = y2 = y_gap_high;
-			drawEcalFaceLine(g, x1, y1, x2, y2);
-			drawEcalFaceLine(g, x1, -y1, x2, -y2);
-			
-			x1 = x_edge_low+i/nPoints*(x_edge_high-x_edge_low);
-			x2 = x_edge_low+(i+1)/nPoints*(x_edge_high-x_edge_low);
-			y1 = y2 = y_edge_high;
-			drawEcalFaceLine(g, x1, y1, x2, y2);
-			drawEcalFaceLine(g, x1, -y1, x2, -y2);
-		}
-		drawEcalFaceLine(g, x_gap_low, y_edge_low, x_gap_low, y_gap_high);
-		drawEcalFaceLine(g, x_gap_high, y_edge_low, x_gap_high, y_gap_high);
-
-		drawEcalFaceLine(g, x_edge_low, y_edge_low, x_edge_low, y_edge_high);
-		drawEcalFaceLine(g, x_edge_high, y_edge_low, x_edge_high, y_edge_high);
-		
-
-		drawEcalFaceLine(g, x_gap_low, -y_edge_low, x_gap_low, -y_gap_high);
-		drawEcalFaceLine(g, x_gap_high, -y_edge_low, x_gap_high, -y_gap_high);
-
-		drawEcalFaceLine(g, x_edge_low, -y_edge_low, x_edge_low, -y_edge_high);
-		drawEcalFaceLine(g, x_edge_high, -y_edge_low, x_edge_high, -y_edge_high);
-	}
-	
-	CustomBinning binning;
-	
-	ShowCustomBinning(File file) throws FileNotFoundException{
-		this.binning = new CustomBinning(file);
-		print(this.binning);
-	}
-	Color altBin1 = new Color(0, 0, 128);
-	Color altBin2 = new Color(0,128,0);
-	void drawCustomBinRectangles(Graphics g){
-		for(int i = 0; i<binning.nTheta; i++){
-			g.setColor(i%2 == 0 ? altBin1 : altBin2);
-			for(int j = 0; j<binning.phiMax[i].length; j++){
-				double phi1 = binning.phiMax[i][j];
-				double phi2 = binning.phiMin[i][j];
-				double theta1 = binning.thetaMin[i];
-				double theta2 = binning.thetaMax[i];
-				
-				int x =getX(theta1)+1, y = getY(phi1), w =  getX(theta2)-getX(theta1), h = getY(phi2)-getY(phi1);
-				g.drawRect(x, y, w, h);
-				 x =getX(theta1)+1; y = getY(-phi2); w =  getX(theta2)-getX(theta1); h = getY(-phi1)-getY(-phi2);
-
-				g.drawRect(x, y, w, h);
-				
-				
-			}
-		}
-	}
-	
-	
-	void drawEcalFaceLine(Graphics g, double x1, double y1, double x2, double y2){
-
-		double[] polar1 = EcalUtil.getThetaPhiSpherical(x1, y1);
-		double[] polar2 = EcalUtil.getThetaPhiSpherical(x2, y2);
-		g.drawLine(getX(polar1[0]), getY(polar1[1]), getX(polar2[0]), getY(polar2[1]));
-		
-	}
-	int getX(double theta){
-		return (int)(this.getWidth()*theta/.3);
-	}
-	int getY(double phi){
-		return (int)(this.getHeight()*(3.2-phi)/6.4);
-	}
-	static void print(CustomBinning binning){
-		System.out.println("  Bin \\# &	$\\theta_{\\textrm{min}}$ &	$\\theta_{\\textrm{max}}$ & $\\phi_{\\textrm{min 1}}$ &	$\\phi_{\\textrm{max 1}}$ & $\\phi_{\\textrm{min 2}}$ & $\\phi_{\\textrm{max 2}}$ & Solid angle  \\\\");
-		for(int i = 0; i<binning.nTheta; i++){
-			if(binning.phiMax[i].length == 1)
-				System.out.printf("%d & %.0f & %.0f & %.0f & %.0f & -- & -- & %.0f \\\\\n",
-					i+1,
-					binning.thetaMin[i]*1000,
-					binning.thetaMax[i]*1000,
-					binning.phiMin[i][0]*1000,
-					binning.phiMax[i][0]*1000.,
-					binning.getSteradians(i)*1e6);
-			if(binning.phiMax[i].length == 2)
-				System.out.printf("%d & %.0f & %.0f & %.0f & %.0f & %.0f & %.0f & %.0f \\\\\n",
-					i+1,
-					binning.thetaMin[i]*1000,
-					binning.thetaMax[i]*1000,
-					binning.phiMin[i][0]*1000,
-					binning.phiMax[i][0]*1000,
-					binning.phiMin[i][1]*1000,
-					binning.phiMax[i][1]*1000,
-					binning.getSteradians(i)*1e6);
-		}
-		System.out.println("total " + binning.getTotSteradians()*1e6 + " microsteradians");
-	} 
+    /**
+     * show Rafo's fiducial cuts translated into rotated theta and phi, 
+     * and overlay this with my bins in x and y.  
+     * @param arg
+     * @throws FileNotFoundException 
+     */
+    public static void main(String arg[]) throws FileNotFoundException{
+        JFrame frame = new JFrame();
+        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+        Canvas c = new ShowCustomBinning(new File(arg[0]));
+        String outdir = arg[1];
+        frame.add(c);
+        frame.setSize(1200, 800);
+        frame.setVisible(true);
+        
+        
+        try {
+            BufferedImage im = new BufferedImage(c.getWidth(), c.getHeight(), BufferedImage.TYPE_INT_ARGB);
+            c.paint(im.getGraphics());
+            ImageIO.write(im, "PNG", new File(outdir +"/bins.png"));
+        } catch (IOException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+        
+        frame = new JFrame();
+        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+        c = new ShowCustomBinningXY(new File(arg[0]));
+        frame.add(c);
+        frame.setSize(1200, 615);
+        frame.setVisible(true);
+        
+        try {
+            BufferedImage im = new BufferedImage(c.getWidth(), c.getHeight(), BufferedImage.TYPE_INT_ARGB);
+            c.paint(im.getGraphics());
+            ImageIO.write(im, "PNG", new File(outdir + "/bins_xy.png"));
+        } catch (IOException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+    }
+    public void paint(Graphics g){
+        g.setFont(new Font(Font.DIALOG, Font.PLAIN, 24));
+        
+        drawEcalOutline(g);
+        drawFidEcalOutline(g);
+        drawCustomBinRectangles(g);
+        g.setColor(Color.BLACK);
+        drawXAxis(g);
+        drawYAxis(g);
+    }
+    
+    void drawFidEcalOutline(Graphics g){
+        g.setColor(Color.GRAY);
+        double x_edge_low = -262.74;
+        double x_edge_high = 347.7;
+        double y_edge_low = 33.54;
+        double y_edge_high = 75.18;
+
+        double x_gap_low = -106.66;
+        double x_gap_high = 42.17;
+        double y_gap_high = 47.18;
+        double x1,y1, x2, y2;
+        double nPoints = 500;
+        for(int i = 0; i< nPoints-1; i++){
+            x1 = x_gap_high+i/nPoints*(x_edge_high-x_gap_high);
+            x2 = x_gap_high+(i+1)/nPoints*(x_edge_high-x_gap_high);
+            y1 = y_edge_low;
+            y2 = y1;
+            drawEcalFaceLine(g, x1, y1, x2, y2);
+            drawEcalFaceLine(g, x1, -y1, x2, -y2);
+            
+            
+            x1 = x_edge_low+i/nPoints*(x_gap_low-x_edge_low);
+            x2 = x_edge_low+(i+1)/nPoints*(x_gap_low-x_edge_low);
+            y1 = y2 = y_edge_low;
+            drawEcalFaceLine(g, x1, y1, x2, y2);
+            drawEcalFaceLine(g, x1, -y1, x2, -y2);
+            
+            
+            
+            x1 = x_gap_low+i/nPoints*(x_gap_high-x_gap_low);
+            x2 = x_gap_low+(i+1)/nPoints*(x_gap_high-x_gap_low);
+            y1 = y2 = y_gap_high;
+            drawEcalFaceLine(g, x1, y1, x2, y2);
+            drawEcalFaceLine(g, x1, -y1, x2, -y2);
+            
+            x1 = x_edge_low+i/nPoints*(x_edge_high-x_edge_low);
+            x2 = x_edge_low+(i+1)/nPoints*(x_edge_high-x_edge_low);
+            y1 = y2 = y_edge_high;
+            drawEcalFaceLine(g, x1, y1, x2, y2);
+            drawEcalFaceLine(g, x1, -y1, x2, -y2);
+        }
+        drawEcalFaceLine(g, x_gap_low, y_edge_low, x_gap_low, y_gap_high);
+        drawEcalFaceLine(g, x_gap_high, y_edge_low, x_gap_high, y_gap_high);
+
+        drawEcalFaceLine(g, x_edge_low, y_edge_low, x_edge_low, y_edge_high);
+        drawEcalFaceLine(g, x_edge_high, y_edge_low, x_edge_high, y_edge_high);
+        
+
+        drawEcalFaceLine(g, x_gap_low, -y_edge_low, x_gap_low, -y_gap_high);
+        drawEcalFaceLine(g, x_gap_high, -y_edge_low, x_gap_high, -y_gap_high);
+
+        drawEcalFaceLine(g, x_edge_low, -y_edge_low, x_edge_low, -y_edge_high);
+        drawEcalFaceLine(g, x_edge_high, -y_edge_low, x_edge_high, -y_edge_high);
+    
+    }
+    
+    void drawEcalOutline(Graphics g){
+        /*double x_edge_low = -262.74;
+        double x_edge_high = 347.7;
+        double y_edge_low = 33.54;
+        double y_edge_high = 75.18;
+
+        double x_gap_low = -106.66;
+        double x_gap_high = 42.17;
+        double y_gap_high = 47.18;*/
+        
+        g.setColor(Color.BLACK);
+        double x_edge_low = -269.56;
+        double x_edge_high = 354.52;
+        double y_edge_low = 26.72;
+        double y_edge_high = 82;
+
+        double x_gap_low = -99.84;
+        double x_gap_high = 33.35;
+        double y_gap_high = 40.36;
+        double x1,y1, x2, y2;
+        double nPoints = 500;
+        for(int i = 0; i< nPoints-1; i++){
+            x1 = x_gap_high+i/nPoints*(x_edge_high-x_gap_high);
+            x2 = x_gap_high+(i+1)/nPoints*(x_edge_high-x_gap_high);
+            y1 = y_edge_low;
+            y2 = y1;
+            drawEcalFaceLine(g, x1, y1, x2, y2);
+            drawEcalFaceLine(g, x1, -y1, x2, -y2);
+            
+            
+            x1 = x_edge_low+i/nPoints*(x_gap_low-x_edge_low);
+            x2 = x_edge_low+(i+1)/nPoints*(x_gap_low-x_edge_low);
+            y1 = y2 = y_edge_low;
+            drawEcalFaceLine(g, x1, y1, x2, y2);
+            drawEcalFaceLine(g, x1, -y1, x2, -y2);
+            
+            
+            
+            x1 = x_gap_low+i/nPoints*(x_gap_high-x_gap_low);
+            x2 = x_gap_low+(i+1)/nPoints*(x_gap_high-x_gap_low);
+            y1 = y2 = y_gap_high;
+            drawEcalFaceLine(g, x1, y1, x2, y2);
+            drawEcalFaceLine(g, x1, -y1, x2, -y2);
+            
+            x1 = x_edge_low+i/nPoints*(x_edge_high-x_edge_low);
+            x2 = x_edge_low+(i+1)/nPoints*(x_edge_high-x_edge_low);
+            y1 = y2 = y_edge_high;
+            drawEcalFaceLine(g, x1, y1, x2, y2);
+            drawEcalFaceLine(g, x1, -y1, x2, -y2);
+        }
+        drawEcalFaceLine(g, x_gap_low, y_edge_low, x_gap_low, y_gap_high);
+        drawEcalFaceLine(g, x_gap_high, y_edge_low, x_gap_high, y_gap_high);
+
+        drawEcalFaceLine(g, x_edge_low, y_edge_low, x_edge_low, y_edge_high);
+        drawEcalFaceLine(g, x_edge_high, y_edge_low, x_edge_high, y_edge_high);
+        
+
+        drawEcalFaceLine(g, x_gap_low, -y_edge_low, x_gap_low, -y_gap_high);
+        drawEcalFaceLine(g, x_gap_high, -y_edge_low, x_gap_high, -y_gap_high);
+
+        drawEcalFaceLine(g, x_edge_low, -y_edge_low, x_edge_low, -y_edge_high);
+        drawEcalFaceLine(g, x_edge_high, -y_edge_low, x_edge_high, -y_edge_high);
+    }
+    
+    CustomBinning binning;
+    
+    ShowCustomBinning(File file) throws FileNotFoundException{
+        this.binning = new CustomBinning(file);
+        print(this.binning);
+    }
+    Color altBin1 = new Color(0, 0, 128);
+    Color altBin2 = new Color(0,128,0);
+    Color fillBin1 = new Color(196, 196, 255);
+    Color fillBin2 = new Color(196,255,196);
+    void drawCustomBinRectangles(Graphics g){
+        for(int i = 0; i<binning.nTheta; i++){
+            g.setColor(i%2 == 0 ? altBin1 : altBin2);
+            for(int j = 0; j<binning.phiMax[i].length; j++){
+                double phi1 = binning.phiMax[i][j];
+                double phi2 = binning.phiMin[i][j];
+                double theta1 = binning.thetaMin[i];
+                double theta2 = binning.thetaMax[i];
+                
+                int x =getX(theta1)+1, y = getY(phi1), w =  getX(theta2)-getX(theta1), h = getY(phi2)-getY(phi1);
+
+                g.setColor(i%2 == 0 ? fillBin1 : fillBin2);
+                g.fillRect(x, y, w, h);
+                g.setColor(i%2 == 0 ? altBin1 : altBin2);
+                g.drawRect(x, y, w, h);
+                 x =getX(theta1)+1; y = getY(-phi2); w =  getX(theta2)-getX(theta1); h = getY(-phi1)-getY(-phi2);
+                 g.setColor(i%2 == 0 ? fillBin1 : fillBin2);
+                    g.fillRect(x, y, w, h);
+                    g.setColor(i%2 == 0 ? altBin1 : altBin2);
+                    g.drawRect(x, y, w, h);
+            }
+            
+        }
+    }
+    void drawXAxis(Graphics g){
+        //x axis
+        g.drawString("θ", getX(.28), getY(0) - 40);
+        g.drawLine(getX(0), getY(0), getX(.28), getY(0));
+        for(int i = 0; i< 28; i++){
+            if(i%5 == 0 && i != 0){
+                g.drawString(i/100.+"", getX(i/100.)-15, getY(0)-20);
+                g.drawLine(getX(i/100.), getY(0), getX(i/100.), getY(0)-15);
+            }
+            g.drawLine(getX(i/100.), getY(0), getX(i/100.), getY(0)-5);
+        }
+    }
+    void drawYAxis(Graphics g){
+        g.drawString("φ", getX(0)+70, getY(3));
+        g.drawLine(getX(0), getY(-3), getX(0), getY(3));
+        for(int i = -30; i<= 30; i++){
+            if(i%5 == 0 && i != 0){
+                g.drawString(i/10.+"", getX(0)+20, getY(i/10.) + 5);
+
+                g.drawLine(getX(0), getY(i/10.), getX(0) + 15, getY(i/10.));
+            }
+            if(i == 0){
+                //g.drawString(i/10.+"", getX(0)+10, getY(i/10.) - 15);
+            }
+            g.drawLine(getX(0), getY(i/10.), getX(0) + 5, getY(i/10.));
+        }
+    }
+    
+    
+    void drawEcalFaceLine(Graphics g, double x1, double y1, double x2, double y2){
+
+        double[] polar1 = EcalUtil.getThetaPhiSpherical(x1, y1);
+        double[] polar2 = EcalUtil.getThetaPhiSpherical(x2, y2);
+        g.drawLine(getX(polar1[0]), getY(polar1[1]), getX(polar2[0]), getY(polar2[1]));
+        
+    }
+    int getX(double theta){
+        return (int)(this.getWidth()*theta/.3)+left_margin;
+    }
+    int left_margin = 20;
+    int getY(double phi){
+        return (int)(this.getHeight()*(3.2-phi)/6.4);
+    }
+    static void print(CustomBinning binning){
+        System.out.println("  Bin \\# & $\\theta_{\\textrm{min}}$ & $\\theta_{\\textrm{max}}$ & $\\phi_{\\textrm{min 1}}$ & $\\phi_{\\textrm{max 1}}$ & $\\phi_{\\textrm{min 2}}$ & $\\phi_{\\textrm{max 2}}$ & Solid angle  \\\\");
+        for(int i = 0; i<binning.nTheta; i++){
+            if(binning.phiMax[i].length == 1)
+                System.out.printf("%d & %.0f & %.0f & %.0f & %.0f & -- & -- & %.0f \\\\\n",
+                    i+1,
+                    binning.thetaMin[i]*1000,
+                    binning.thetaMax[i]*1000,
+                    binning.phiMin[i][0]*1000,
+                    binning.phiMax[i][0]*1000.,
+                    binning.getSteradians(i)*1e6);
+            if(binning.phiMax[i].length == 2)
+                System.out.printf("%d & %.0f & %.0f & %.0f & %.0f & %.0f & %.0f & %.0f \\\\\n",
+                    i+1,
+                    binning.thetaMin[i]*1000,
+                    binning.thetaMax[i]*1000,
+                    binning.phiMin[i][0]*1000,
+                    binning.phiMax[i][0]*1000,
+                    binning.phiMin[i][1]*1000,
+                    binning.phiMax[i][1]*1000,
+                    binning.getSteradians(i)*1e6);
+        }
+        System.out.println("total " + binning.getTotSteradians()*1e6 + " microsteradians");
+    } 
 }

Modified: java/branches/HPSJAVA-409/util/pom.xml
 =============================================================================
--- java/branches/HPSJAVA-409/util/pom.xml	(original)
+++ java/branches/HPSJAVA-409/util/pom.xml	Wed Apr 27 11:11:32 2016
@@ -7,7 +7,7 @@
         <groupId>org.hps</groupId>
         <artifactId>hps-parent</artifactId>
         <relativePath>../parent/pom.xml</relativePath>
-        <version>3.4.2-SNAPSHOT</version>
+        <version>3.9-SNAPSHOT</version>
     </parent>
     <scm>
         <url>http://java.freehep.org/svn/repos/hps/list/java/trunk/util/</url>

Modified: java/branches/HPSJAVA-409/util/src/main/java/org/hps/util/CalculateAcceptanceFromMadGraph.java
 =============================================================================
--- java/branches/HPSJAVA-409/util/src/main/java/org/hps/util/CalculateAcceptanceFromMadGraph.java	(original)
+++ java/branches/HPSJAVA-409/util/src/main/java/org/hps/util/CalculateAcceptanceFromMadGraph.java	Wed Apr 27 11:11:32 2016
@@ -21,7 +21,7 @@
 import org.apache.commons.cli.Option;
 import org.apache.commons.cli.Options;
 import org.apache.commons.cli.ParseException;
-import org.apache.commons.cli.DefaultParser;
+import org.apache.commons.cli.PosixParser;
 import org.lcsim.fit.helicaltrack.HelixParamCalculator;
 
 public class CalculateAcceptanceFromMadGraph {
@@ -165,7 +165,7 @@
         // Set up command line parsing.
         Options options = createCommandLineOptions();
 
-        CommandLineParser parser = new DefaultParser();
+        CommandLineParser parser = new PosixParser();
 
         // Parse command line arguments.
         CommandLine cl = null;

Modified: java/branches/HPSJAVA-409/util/src/main/java/org/hps/util/ConvertToStdhep.java
 =============================================================================
--- java/branches/HPSJAVA-409/util/src/main/java/org/hps/util/ConvertToStdhep.java	(original)
+++ java/branches/HPSJAVA-409/util/src/main/java/org/hps/util/ConvertToStdhep.java	Wed Apr 27 11:11:32 2016
@@ -15,7 +15,6 @@
 import java.util.ArrayList;
 import java.util.List;
 
-import hep.io.stdhep.StdhepBeginRun;
 import hep.io.stdhep.StdhepEndRun;
 import hep.io.stdhep.StdhepEvent;
 import hep.io.stdhep.StdhepWriter;
@@ -31,7 +30,7 @@
 import org.apache.commons.cli.Option;
 import org.apache.commons.cli.Options;
 import org.apache.commons.cli.ParseException;
-import org.apache.commons.cli.DefaultParser;
+import org.apache.commons.cli.PosixParser;
 import org.lcsim.detector.IRotation3D;
 import org.lcsim.detector.RotationGeant;
 
@@ -95,7 +94,7 @@
         // Set up command line parsing.
         Options options = createCommandLineOptions();
 
-        CommandLineParser parser = new DefaultParser();
+        CommandLineParser parser = new PosixParser();
 
         // Parse command line arguments.
         CommandLine cl = null;
@@ -502,10 +501,10 @@
     }*/
 
     static private double getDecayLength(double gamma){
-    	Random generator = new Random();
-    	double a = generator.nextDouble();
-    	double l = -gamma*_declength*Math.log(1-a);
-    	return l; 
+        Random generator = new Random();
+        double a = generator.nextDouble();
+        double l = -gamma*_declength*Math.log(1-a);
+        return l; 
     }
     
     /*
@@ -724,7 +723,7 @@
                     double gamma = ApEnergy / ApMass;
                     if (expDecay) {
                         decLen = getDecayLength(gamma);
-                    	// decLen = getDecayLength(maxWght, gamma);
+                        // decLen = getDecayLength(maxWght, gamma);
                     }
                     if (flatDecay) {
                         decLen = generator.nextDouble() * maxLen;

Modified: java/branches/HPSJAVA-409/util/src/main/java/org/hps/util/DumpLHEEventsToASCII.java
 =============================================================================
--- java/branches/HPSJAVA-409/util/src/main/java/org/hps/util/DumpLHEEventsToASCII.java	(original)
+++ java/branches/HPSJAVA-409/util/src/main/java/org/hps/util/DumpLHEEventsToASCII.java	Wed Apr 27 11:11:32 2016
@@ -26,7 +26,7 @@
 import org.apache.commons.cli.Option;
 import org.apache.commons.cli.Options;
 import org.apache.commons.cli.ParseException;
-import org.apache.commons.cli.DefaultParser;
+import org.apache.commons.cli.PosixParser;
 import org.lcsim.detector.IRotation3D;
 import org.lcsim.detector.RotationGeant;
 
@@ -89,7 +89,7 @@
         // Set up command line parsing.
         Options options = createCommandLineOptions();
 
-        CommandLineParser parser = new DefaultParser();
+        CommandLineParser parser = new PosixParser();
 
         // Parse command line arguments.
         CommandLine cl = null;
@@ -108,7 +108,7 @@
         String sigyString = String.valueOf(sigy);
         eptString = convertDecimal(eptString);
         if (cl.hasOption("t")) {
-	    trident=true;
+        trident=true;
         }
         if (cl.hasOption("m")) {
             massString = cl.getOptionValue("m");
@@ -475,7 +475,7 @@
             throw new RuntimeException("Unexpected entry for number of particles");
         }
         int nhep = nums.get(0).intValue();
-	//        System.out.println("Number of particles for event " + nevhep + ": " + nhep);
+    //        System.out.println("Number of particles for event " + nevhep + ": " + nhep);
 
         double decLen = 0;
         double maxWght = 0;
@@ -503,14 +503,14 @@
             if (vals.size() != 13) {
                 throw new RuntimeException("Unexpected entry for a particle");
             }
-	    idhepTmp = vals.get(0).intValue();
-//	    System.out.println(idhepTmp);
+        idhepTmp = vals.get(0).intValue();
+//      System.out.println(idhepTmp);
             if (vals.get(1).intValue() == 9) {//apparently, vertices aren't counted in nhep
-		nhep++;
-	    }
+        nhep++;
+        }
 
             if (vals.get(1).intValue() == 1) {//ignore initial  & intermediate state particles
-		//		System.out.println("Ok...good"+idhepTmp);
+        //      System.out.println("Ok...good"+idhepTmp);
 
 
 
@@ -523,8 +523,8 @@
                         phepRec[j] = vals.get(j + 6);
                     if (idhepTmp == -623){
                         phepNuc[j] = vals.get(j + 6);
-			//			System.out.println("Found the recoil nucleus");
-		    }
+            //          System.out.println("Found the recoil nucleus");
+            }
                 }
 
 

Modified: java/branches/HPSJAVA-409/util/src/main/java/org/hps/util/LCIOFilterDriver.java
 =============================================================================
--- java/branches/HPSJAVA-409/util/src/main/java/org/hps/util/LCIOFilterDriver.java	(original)
+++ java/branches/HPSJAVA-409/util/src/main/java/org/hps/util/LCIOFilterDriver.java	Wed Apr 27 11:11:32 2016
@@ -5,7 +5,6 @@
 package org.hps.util;
 import java.io.IOException;
 import org.lcsim.event.EventHeader;
-import org.lcsim.event.Track;
 import org.lcsim.util.Driver;
 import org.lcsim.lcio.LCIOWriter;
 

Modified: java/branches/HPSJAVA-409/util/src/main/java/org/hps/util/MergeBunches.java
 =============================================================================
--- java/branches/HPSJAVA-409/util/src/main/java/org/hps/util/MergeBunches.java	(original)
+++ java/branches/HPSJAVA-409/util/src/main/java/org/hps/util/MergeBunches.java	Wed Apr 27 11:11:32 2016
@@ -34,7 +34,6 @@
 import org.lcsim.lcio.LCIOUtil;
 import org.lcsim.lcio.LCIOWriter;
 import org.lcsim.lcio.SIOMCParticle;
-import org.lcsim.util.loop.LCIODriver;
 
 public class MergeBunches extends Driver {
 
@@ -455,7 +454,6 @@
      * Copies an mc particle and stores it together with  the copy in a map.
      * Adds it to the list of mc particles as well as the overlay mc particles.
      * Also copies and keeps all ancestors.
-     * @param event
      * @param particle
      */
     protected void addOverlayMcParticle(MCParticle particle) {

Top of Message | Previous Page | Permalink

Advanced Options


Options

Log In

Log In

Get Password

Get Password


Search Archives

Search Archives


Subscribe or Unsubscribe

Subscribe or Unsubscribe


Archives

November 2017
August 2017
July 2017
January 2017
December 2016
November 2016
October 2016
September 2016
August 2016
July 2016
June 2016
May 2016
April 2016
March 2016
February 2016
January 2016
December 2015
November 2015
October 2015
September 2015
August 2015
July 2015
June 2015
May 2015
April 2015
March 2015
February 2015
January 2015
December 2014
November 2014
October 2014
September 2014
August 2014
July 2014
June 2014
May 2014
April 2014
March 2014
February 2014
January 2014
December 2013
November 2013

ATOM RSS1 RSS2



LISTSERV.SLAC.STANFORD.EDU

Secured by F-Secure Anti-Virus CataList Email List Search Powered by the LISTSERV Email List Manager

Privacy Notice, Security Notice and Terms of Use