Author: [log in to unmask] Date: Wed Mar 25 14:43:27 2015 New Revision: 2555 Log: Merge in r2364 through r2554 to prod branch. Added: java/branches/prod/analysis/src/main/java/org/hps/analysis/trigger/event/TriggerPlotsModule.java - copied unchanged from r2554, java/trunk/analysis/src/main/java/org/hps/analysis/trigger/event/TriggerPlotsModule.java java/branches/prod/conditions/src/main/java/org/hps/conditions/svt/DaqMapHandler.java - copied unchanged from r2554, java/trunk/conditions/src/main/java/org/hps/conditions/svt/DaqMapHandler.java java/branches/prod/conditions/src/main/java/org/hps/conditions/svt/SvtConditionsLoader.java - copied unchanged from r2554, java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtConditionsLoader.java java/branches/prod/conditions/src/main/java/org/hps/conditions/svt/SvtConditionsReader.java - copied unchanged from r2554, java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtConditionsReader.java java/branches/prod/ecal-recon/src/main/java/org/hps/recon/ecal/daqconfig/ - copied from r2554, java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/daqconfig/ java/branches/prod/ecal-recon/src/main/java/org/hps/recon/ecal/triggerbank/ - copied from r2554, java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/triggerbank/ java/branches/prod/evio/src/main/java/org/hps/evio/BasicPhysicsEventBuilder.java - copied unchanged from r2554, java/trunk/evio/src/main/java/org/hps/evio/BasicPhysicsEventBuilder.java java/branches/prod/evio/src/test/java/org/hps/evio/EpicsScalarDataTest.java - copied unchanged from r2554, java/trunk/evio/src/test/java/org/hps/evio/EpicsScalarDataTest.java java/branches/prod/evio/src/test/java/org/hps/evio/ScalarsTest.java - copied unchanged from r2554, java/trunk/evio/src/test/java/org/hps/evio/ScalarsTest.java java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/ConditionsCollectionTableModel.java - copied unchanged from r2554, java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/ConditionsCollectionTableModel.java java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/ConditionsPanel.java - copied unchanged from r2554, java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/ConditionsPanel.java java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/EventDashboard.java - copied unchanged from r2554, java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/EventDashboard.java java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/SystemStatusEventsTable.java - copied unchanged from r2554, java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/SystemStatusEventsTable.java java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/SystemStatusPanel.java - copied unchanged from r2554, java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/SystemStatusPanel.java java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/util/AIDAServer.java - copied unchanged from r2554, java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/util/AIDAServer.java java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/util/EventTagFilter.java - copied unchanged from r2554, java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/util/EventTagFilter.java java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/util/MonitoringApplicationEventBuilder.java - copied unchanged from r2554, java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/util/MonitoringApplicationEventBuilder.java java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/util/PhysicsSyncEventStation.java - copied unchanged from r2554, java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/util/PhysicsSyncEventStation.java java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/util/PreStartEtStation.java - copied unchanged from r2554, java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/util/PreStartEtStation.java java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/util/RunnableEtStation.java - copied unchanged from r2554, java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/util/RunnableEtStation.java java/branches/prod/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/svt/SamplesPlots.java - copied unchanged from r2554, java/trunk/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/svt/SamplesPlots.java java/branches/prod/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/svt/SvtHitPlots.java - copied unchanged from r2554, java/trunk/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/svt/SvtHitPlots.java java/branches/prod/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/EcalLedSequenceMonitor.java - copied unchanged from r2554, java/trunk/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/EcalLedSequenceMonitor.java java/branches/prod/monitoring-util/src/main/java/org/hps/monitoring/plotting/PlotterRegistry.java - copied unchanged from r2554, java/trunk/monitoring-util/src/main/java/org/hps/monitoring/plotting/PlotterRegistry.java java/branches/prod/monitoring-util/src/main/java/org/hps/monitoring/plotting/ValueProvider.java - copied unchanged from r2554, java/trunk/monitoring-util/src/main/java/org/hps/monitoring/plotting/ValueProvider.java java/branches/prod/monitoring-util/src/main/java/org/hps/monitoring/subsys/SystemStatisticsListener.java - copied unchanged from r2554, java/trunk/monitoring-util/src/main/java/org/hps/monitoring/subsys/SystemStatisticsListener.java java/branches/prod/record-util/src/main/java/org/hps/record/epics/ - copied from r2554, java/trunk/record-util/src/main/java/org/hps/record/epics/ java/branches/prod/record-util/src/main/java/org/hps/record/et/EtStationThread.java - copied unchanged from r2554, java/trunk/record-util/src/main/java/org/hps/record/et/EtStationThread.java java/branches/prod/record-util/src/main/java/org/hps/record/et/PreStartProcessor.java - copied unchanged from r2554, java/trunk/record-util/src/main/java/org/hps/record/et/PreStartProcessor.java java/branches/prod/record-util/src/main/java/org/hps/record/et/SyncEventProcessor.java - copied unchanged from r2554, java/trunk/record-util/src/main/java/org/hps/record/et/SyncEventProcessor.java java/branches/prod/record-util/src/main/java/org/hps/record/scalars/ - copied from r2554, java/trunk/record-util/src/main/java/org/hps/record/scalars/ java/branches/prod/steering-files/src/main/resources/org/hps/steering/monitoring/EcalLedSequenceMonitor.lcsim - copied unchanged from r2554, java/trunk/steering-files/src/main/resources/org/hps/steering/monitoring/EcalLedSequenceMonitor.lcsim java/branches/prod/steering-files/src/main/resources/org/hps/steering/readout/CommRun2014TightPairs.lcsim - copied unchanged from r2554, java/trunk/steering-files/src/main/resources/org/hps/steering/readout/CommRun2014TightPairs.lcsim java/branches/prod/steering-files/src/main/resources/org/hps/steering/readout/EngineeringRun2014PrescaledTriggers.lcsim - copied unchanged from r2554, java/trunk/steering-files/src/main/resources/org/hps/steering/readout/EngineeringRun2014PrescaledTriggers.lcsim java/branches/prod/steering-files/src/main/resources/org/hps/steering/users/holly/ECalSimReadout.lcsim - copied unchanged from r2554, java/trunk/steering-files/src/main/resources/org/hps/steering/users/holly/ECalSimReadout.lcsim java/branches/prod/steering-files/src/main/resources/org/hps/steering/users/holly/QuickEcalReadout.lcsim - copied unchanged from r2554, java/trunk/steering-files/src/main/resources/org/hps/steering/users/holly/QuickEcalReadout.lcsim java/branches/prod/steering-files/src/main/resources/org/hps/steering/users/mgraham/NoTimeNoTriggerReadout.lcsim - copied unchanged from r2554, java/trunk/steering-files/src/main/resources/org/hps/steering/users/mgraham/NoTimeNoTriggerReadout.lcsim Removed: java/branches/prod/conditions/src/main/java/org/hps/conditions/deprecated/ java/branches/prod/ecal-readout-sim/src/main/java/org/hps/readout/ecal/TriggerModule.java java/branches/prod/ecal-readout-sim/src/main/java/org/hps/readout/ecal/daqconfig/ java/branches/prod/ecal-readout-sim/src/main/java/org/hps/readout/ecal/triggerbank/ java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/RunPanel.java java/branches/prod/record-util/src/test/java/org/ java/branches/prod/steering-files/src/main/resources/org/hps/steering/readout/CommRun2014LoosePairs.lcsim java/branches/prod/steering-files/src/main/resources/org/hps/steering/users/celentan/LedAnalysis.lcsim java/branches/prod/users/src/main/java/org/hps/users/celentan/LedAnalysis.java Modified: java/branches/prod/ (props changed) java/branches/prod/analysis/src/main/java/org/hps/analysis/ecal/EcalHitPlots.java java/branches/prod/analysis/src/main/java/org/hps/analysis/trigger/TriggerDiagnosticDriver.java java/branches/prod/analysis/src/main/java/org/hps/analysis/trigger/event/ClusterMatchEvent.java java/branches/prod/analysis/src/main/java/org/hps/analysis/trigger/event/ClusterMatchStatus.java java/branches/prod/analysis/src/main/java/org/hps/analysis/trigger/event/ClusterMatchedPair.java java/branches/prod/analysis/src/main/java/org/hps/analysis/trigger/event/TriggerEfficiencyModule.java java/branches/prod/analysis/src/main/java/org/hps/analysis/trigger/event/TriggerMatchEvent.java java/branches/prod/analysis/src/main/java/org/hps/analysis/trigger/event/TriggerMatchStatus.java java/branches/prod/analysis/src/main/java/org/hps/analysis/trigger/event/TriggerMatchedPair.java java/branches/prod/analysis/src/main/java/org/hps/analysis/trigger/event/TriggerStatModule.java java/branches/prod/analysis/src/main/java/org/hps/analysis/trigger/util/PairTrigger.java java/branches/prod/analysis/src/main/java/org/hps/analysis/trigger/util/SinglesTrigger.java java/branches/prod/analysis/src/main/java/org/hps/analysis/trigger/util/TriggerDiagnosticUtil.java java/branches/prod/conditions/src/main/java/org/hps/conditions/api/AbstractConditionsObjectCollection.java java/branches/prod/conditions/src/main/java/org/hps/conditions/api/ConditionsObject.java java/branches/prod/conditions/src/main/java/org/hps/conditions/api/ConditionsObjectCollection.java java/branches/prod/conditions/src/main/java/org/hps/conditions/database/ConditionsObjectConverter.java java/branches/prod/conditions/src/main/java/org/hps/conditions/database/DatabaseConditionsManager.java java/branches/prod/conditions/src/main/java/org/hps/conditions/database/TableMetaData.java java/branches/prod/conditions/src/main/java/org/hps/conditions/database/TableRegistry.java java/branches/prod/conditions/src/main/java/org/hps/conditions/ecal/EcalBadChannel.java java/branches/prod/conditions/src/main/java/org/hps/conditions/ecal/EcalCalibration.java java/branches/prod/conditions/src/main/java/org/hps/conditions/ecal/EcalChannel.java java/branches/prod/conditions/src/main/java/org/hps/conditions/ecal/EcalGain.java java/branches/prod/conditions/src/main/java/org/hps/conditions/ecal/EcalLed.java java/branches/prod/conditions/src/main/java/org/hps/conditions/ecal/EcalLedCalibration.java java/branches/prod/conditions/src/main/java/org/hps/conditions/ecal/EcalTimeShift.java java/branches/prod/conditions/src/main/java/org/hps/conditions/svt/AbstractSvtChannel.java java/branches/prod/conditions/src/main/java/org/hps/conditions/svt/AbstractSvtDaqMapping.java java/branches/prod/conditions/src/main/java/org/hps/conditions/svt/CalibrationHandler.java java/branches/prod/conditions/src/main/java/org/hps/conditions/svt/SvtChannel.java java/branches/prod/conditions/src/main/java/org/hps/conditions/svt/SvtDaqMapping.java java/branches/prod/conditions/src/main/java/org/hps/conditions/svt/SvtDetectorSetup.java java/branches/prod/conditions/src/main/java/org/hps/conditions/svt/TestRunSvtChannel.java java/branches/prod/conditions/src/test/java/org/hps/conditions/EngRunConditionsTest.java java/branches/prod/detector-data/detectors/HPS-ECalCommissioning-v2/detector.properties java/branches/prod/ecal-readout-sim/src/main/java/org/hps/readout/ecal/FADCEcalReadoutDriver.java java/branches/prod/ecal-readout-sim/src/main/java/org/hps/readout/ecal/FADCPrimaryTriggerDriver.java java/branches/prod/ecal-readout-sim/src/main/java/org/hps/readout/ecal/SinglesTriggerDriver.java java/branches/prod/ecal-readout-sim/src/main/java/org/hps/readout/ecal/TestRunTriggerDriver.java java/branches/prod/ecal-readout-sim/src/main/java/org/hps/readout/ecal/TriggerDriver.java java/branches/prod/ecal-recon/src/main/java/org/hps/recon/ecal/EcalPedestalCalculator.java java/branches/prod/ecal-recon/src/main/java/org/hps/recon/ecal/EcalRawConverter.java java/branches/prod/ecal-recon/src/main/java/org/hps/recon/ecal/EcalRawConverterDriver.java java/branches/prod/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/ClusterDriver.java java/branches/prod/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/GTPOnlineClusterDriver.java java/branches/prod/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/GTPOnlineClusterer.java java/branches/prod/evio/pom.xml java/branches/prod/evio/src/main/java/org/hps/evio/LCSimEngRunEventBuilder.java java/branches/prod/evio/src/main/java/org/hps/evio/LCSimTestRunEventBuilder.java java/branches/prod/evio/src/main/java/org/hps/evio/SVTHitWriter.java java/branches/prod/evio/src/main/java/org/hps/evio/TestRunSvtEvioReader.java java/branches/prod/evio/src/main/java/org/hps/evio/TestRunTriggeredReconToLcio.java java/branches/prod/evio/src/main/java/org/hps/evio/TriggerConfigEvioReader.java java/branches/prod/evio/src/main/java/org/hps/evio/TriggerDataWriter.java java/branches/prod/monitoring-app/ (props changed) java/branches/prod/monitoring-app/pom.xml java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/AbstractFieldsPanel.java java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/Commands.java java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/ConnectionSettingsPanel.java java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/ConnectionStatusPanel.java java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/DatePanel.java java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/EventButtonsPanel.java java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/EventProcessing.java java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/JobSettingsPanel.java java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/LogLevelFilterComboBox.java java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/LogPanel.java java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/LogTable.java java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/Main.java java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/MenuBar.java java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/MonitoringApplication.java java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/MonitoringApplicationFrame.java java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/PlotInfoPanel.java java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/PlotPanel.java java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/SettingsPanel.java java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/SystemStatusTable.java java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/TriggerDiagnosticsPanel.java java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/model/ConfigurationModel.java java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/model/ConnectionStatus.java java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/model/ConnectionStatusModel.java java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/model/RunModel.java java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/util/ErrorHandler.java java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/util/ResourceUtil.java java/branches/prod/monitoring-app/src/main/resources/org/hps/monitoring/config/default_config.prop java/branches/prod/monitoring-app/src/main/scripts/evio_file_producer.sh java/branches/prod/monitoring-app/src/main/scripts/start_et_ring.sh java/branches/prod/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/svt/SensorOccupancyPlotsDriver.java java/branches/prod/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/svt/SvtTimingInPlots.java java/branches/prod/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/trackrecon/TrackTimePlots.java java/branches/prod/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/EcalClusterPlots.java java/branches/prod/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/EcalEventDisplay.java java/branches/prod/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/EcalEventDisplayWithRawWaveform.java java/branches/prod/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/EcalHitPlots.java java/branches/prod/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/EcalMonitoringPlots.java java/branches/prod/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/EcalMonitoringUtilities.java java/branches/prod/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/EcalPedestalViewer.java java/branches/prod/monitoring-util/src/main/java/org/hps/monitoring/plotting/MonitoringPlotFactory.java java/branches/prod/monitoring-util/src/main/java/org/hps/monitoring/plotting/StripChartBuilder.java java/branches/prod/monitoring-util/src/main/java/org/hps/monitoring/plotting/StripChartUpdater.java java/branches/prod/monitoring-util/src/main/java/org/hps/monitoring/subsys/StatusCode.java java/branches/prod/monitoring-util/src/main/java/org/hps/monitoring/subsys/SystemStatistics.java java/branches/prod/monitoring-util/src/main/java/org/hps/monitoring/subsys/SystemStatisticsImpl.java java/branches/prod/monitoring-util/src/main/java/org/hps/monitoring/subsys/SystemStatusImpl.java java/branches/prod/monitoring-util/src/main/java/org/hps/monitoring/subsys/ecal/EcalPedestalMonitor.java java/branches/prod/monitoring-util/src/main/java/org/hps/monitoring/subsys/ecal/EcalStripChartTestDriver.java java/branches/prod/monitoring-util/src/main/java/org/hps/monitoring/subsys/et/EtSystemStripCharts.java java/branches/prod/monitoring-util/src/main/java/org/hps/monitoring/trigger/ClusterTablePanel.java java/branches/prod/monitoring-util/src/main/java/org/hps/monitoring/trigger/TableTextModel.java java/branches/prod/record-util/src/main/java/org/hps/record/RecordProcessingException.java java/branches/prod/record-util/src/main/java/org/hps/record/composite/CompositeLoop.java java/branches/prod/record-util/src/main/java/org/hps/record/composite/CompositeLoopConfiguration.java java/branches/prod/record-util/src/main/java/org/hps/record/evio/EvioEventConstants.java java/branches/prod/record-util/src/main/java/org/hps/record/evio/EvioEventUtilities.java java/branches/prod/record-util/src/main/java/org/hps/record/evio/EvioFileProducer.java java/branches/prod/steering-files/src/main/resources/org/hps/steering/monitoring/ECalLedCommissioning.lcsim java/branches/prod/steering-files/src/main/resources/org/hps/steering/monitoring/EcalMonitoringFinal.lcsim java/branches/prod/steering-files/src/main/resources/org/hps/steering/monitoring/TriggerDiagnosticsMonitoring.lcsim java/branches/prod/steering-files/src/main/resources/org/hps/steering/users/celentan/LedAnalysisFromEvio.lcsim java/branches/prod/steering-files/src/main/resources/org/hps/steering/users/mgraham/AlignmentMonitorTest.lcsim java/branches/prod/tracking/src/main/java/org/hps/readout/svt/SimpleSvtReadout.java java/branches/prod/users/src/main/java/org/hps/users/celentan/DummyDriverRaw.java java/branches/prod/users/src/main/java/org/hps/users/phansson/ROOTFlatTupleDriver.java Modified: java/branches/prod/analysis/src/main/java/org/hps/analysis/ecal/EcalHitPlots.java ============================================================================= --- java/branches/prod/analysis/src/main/java/org/hps/analysis/ecal/EcalHitPlots.java (original) +++ java/branches/prod/analysis/src/main/java/org/hps/analysis/ecal/EcalHitPlots.java Wed Mar 25 14:43:27 2015 @@ -4,11 +4,13 @@ import hep.aida.IHistogram2D; import hep.aida.IPlotter; import hep.aida.IPlotterFactory; + import java.util.List; -import org.hps.readout.ecal.triggerbank.AbstractIntData; -import org.hps.readout.ecal.triggerbank.SSPData; -import org.hps.readout.ecal.triggerbank.TestRunTriggerData; + import org.hps.recon.ecal.ECalUtils; +import org.hps.recon.ecal.triggerbank.AbstractIntData; +import org.hps.recon.ecal.triggerbank.SSPData; +import org.hps.recon.ecal.triggerbank.TestRunTriggerData; import org.lcsim.event.CalorimeterHit; import org.lcsim.event.EventHeader; import org.lcsim.event.GenericObject; Modified: java/branches/prod/analysis/src/main/java/org/hps/analysis/trigger/TriggerDiagnosticDriver.java ============================================================================= --- java/branches/prod/analysis/src/main/java/org/hps/analysis/trigger/TriggerDiagnosticDriver.java (original) +++ java/branches/prod/analysis/src/main/java/org/hps/analysis/trigger/TriggerDiagnosticDriver.java Wed Mar 25 14:43:27 2015 @@ -1,10 +1,14 @@ package org.hps.analysis.trigger; + +import hep.aida.IHistogram1D; +import hep.aida.IHistogram2D; import java.awt.Point; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.ArrayList; import java.util.Calendar; +import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -18,28 +22,32 @@ import org.hps.analysis.trigger.event.TriggerEfficiencyModule; import org.hps.analysis.trigger.event.TriggerMatchEvent; import org.hps.analysis.trigger.event.TriggerMatchStatus; +import org.hps.analysis.trigger.event.TriggerPlotsModule; import org.hps.analysis.trigger.util.OutputLogger; import org.hps.analysis.trigger.util.Pair; import org.hps.analysis.trigger.util.PairTrigger; import org.hps.analysis.trigger.util.SinglesTrigger; import org.hps.analysis.trigger.util.Trigger; import org.hps.analysis.trigger.util.TriggerDiagnosticUtil; -import org.hps.readout.ecal.TriggerModule; -import org.hps.readout.ecal.daqconfig.ConfigurationManager; -import org.hps.readout.ecal.daqconfig.DAQConfig; -import org.hps.readout.ecal.triggerbank.AbstractIntData; -import org.hps.readout.ecal.triggerbank.SSPCluster; -import org.hps.readout.ecal.triggerbank.SSPData; -import org.hps.readout.ecal.triggerbank.SSPNumberedTrigger; -import org.hps.readout.ecal.triggerbank.SSPPairTrigger; -import org.hps.readout.ecal.triggerbank.SSPSinglesTrigger; -import org.hps.readout.ecal.triggerbank.SSPTrigger; -import org.hps.readout.ecal.triggerbank.TIData; +import org.hps.recon.ecal.daqconfig.ConfigurationManager; +import org.hps.recon.ecal.daqconfig.DAQConfig; +import org.hps.recon.ecal.daqconfig.PairTriggerConfig; +import org.hps.recon.ecal.daqconfig.SinglesTriggerConfig; +import org.hps.recon.ecal.triggerbank.AbstractIntData; +import org.hps.recon.ecal.triggerbank.SSPCluster; +import org.hps.recon.ecal.triggerbank.SSPData; +import org.hps.recon.ecal.triggerbank.SSPNumberedTrigger; +import org.hps.recon.ecal.triggerbank.SSPPairTrigger; +import org.hps.recon.ecal.triggerbank.SSPSinglesTrigger; +import org.hps.recon.ecal.triggerbank.SSPTrigger; +import org.hps.recon.ecal.triggerbank.TIData; +import org.hps.recon.ecal.triggerbank.TriggerModule; import org.lcsim.event.CalorimeterHit; import org.lcsim.event.Cluster; import org.lcsim.event.EventHeader; import org.lcsim.event.GenericObject; import org.lcsim.util.Driver; +import org.lcsim.util.aida.AIDA; public class TriggerDiagnosticDriver extends Driver { // Store the LCIO collection names for the needed objects. @@ -62,6 +70,10 @@ private int activeTrigger = -1; 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; @@ -69,13 +81,14 @@ private int windowWidth = 200; private int hitAcceptance = 1; private int noiseThreshold = 50; + private double energyAcceptance = 0.003; private long localWindowStart = 0; private boolean readDAQConfig = false; - private double energyAcceptance = 0.03; private int localWindowThreshold = 10 * 1000; private boolean performClusterVerification = true; private boolean performSinglesTriggerVerification = true; private boolean performPairTriggerVerification = true; + private boolean enforceTimeCompliance = false; // Efficiency tracking variables. private ClusterMatchStatus clusterRunStats = new ClusterMatchStatus(); @@ -103,7 +116,8 @@ private boolean printSinglesTriggerInternalFail = true; private boolean printPairTriggerEfficiencyFail = true; private boolean printPairTriggerInternalFail = true; - + private int printResultsEveryNEvents = 100000; + // 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; @@ -113,12 +127,101 @@ 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("cluster/Recon Cluster Hit Count (All)", 9, 0.5, 9.5), + aida.histogram1D("cluster/Recon Cluster Hit Count (Matched)", 9, 0.5, 9.5), + aida.histogram1D("cluster/Recon Cluster Hit Count (Failed)", 9, 0.5, 9.5) + }, + { + aida.histogram1D("cluster/SSP Cluster Hit Count (All)", 9, 0.5, 9.5), + aida.histogram1D("cluster/SSP Cluster Hit Count (Matched)", 9, 0.5, 9.5), + aida.histogram1D("cluster/SSP Cluster Hit Count (Failed)", 9, 0.5, 9.5) + } + }; + private IHistogram1D[][] clusterEnergyPlot = { + { + aida.histogram1D("cluster/Recon Cluster Energy (All)", 300, 0.0, 3.0), + aida.histogram1D("cluster/Recon Cluster Energy (Matched)", 300, 0.0, 3.0), + aida.histogram1D("cluster/Recon Cluster Energy (Failed)", 300, 0.0, 3.0) + }, + { + aida.histogram1D("cluster/SSP Cluster Energy (All)", 300, 0.0, 3.0), + aida.histogram1D("cluster/SSP Cluster Energy (Matched)", 300, 0.0, 3.0), + aida.histogram1D("cluster/SSP Cluster Energy (Failed)", 300, 0.0, 3.0) + } + }; + private IHistogram1D[][] clusterTimePlot = { + { + aida.histogram1D("cluster/Recon Cluster Time (All)", 115, 0, 460), + aida.histogram1D("cluster/Recon Cluster Time (Matched)", 115, 0, 460), + aida.histogram1D("cluster/Recon Cluster Time (Failed)", 115, 0, 460) + }, + { + aida.histogram1D("cluster/SSP Cluster Time (All)", 115, 0, 460), + aida.histogram1D("cluster/SSP Cluster Time (Matched)", 115, 0, 460), + aida.histogram1D("cluster/SSP Cluster Time (Failed)", 115, 0, 460) + } + }; + private IHistogram2D[][] clusterPositionPlot = { + { + aida.histogram2D("cluster/Recon Cluster Position (All)", 47, -23.5, 23.5, 11, -5.5, 5.5), + aida.histogram2D("cluster/Recon Cluster Position (Matched)", 47, -23.5, 23.5, 11, -5.5, 5.5), + aida.histogram2D("cluster/Recon Cluster Position (Failed)", 47, -23.5, 23.5, 11, -5.5, 5.5) + }, + { + aida.histogram2D("cluster/SSP Cluster Position (All)", 47, -23.5, 23.5, 11, -5.5, 5.5), + aida.histogram2D("cluster/SSP Cluster Position (Matched)", 47, -23.5, 23.5, 11, -5.5, 5.5), + aida.histogram2D("cluster/SSP Cluster Position (Failed)", 47, -23.5, 23.5, 11, -5.5, 5.5) + } + }; + private IHistogram2D[] energyhitDiffPlot = { + aida.histogram2D("cluster/Recon-SSP Energy-Hit Difference (All)", 21, -0.010, 0.010, 6, -3, 3), + aida.histogram2D("cluster/Recon-SSP Energy-Hit Difference (Matched)", 21, -0.010, 0.010, 6, -3, 3), + aida.histogram2D("cluster/Recon-SSP Energy-Hit Difference (Failed)", 21, -0.010, 0.010, 6, -3, 3) + }; + /** * 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) { @@ -127,6 +230,10 @@ 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()); @@ -137,6 +244,33 @@ 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(); + } + // Print a DAQ configuration settings header. System.out.println(); System.out.println(); @@ -154,51 +288,6 @@ System.out.println("======================================================================"); System.out.println("=== Cluster/Trigger Verification Settings ============================"); System.out.println("======================================================================"); - - // Set the FADC settings. - nsa = 100; - nsb = 20; - windowWidth = 400; - - /* - // Define the first singles trigger. - singlesTrigger[0] = new TriggerModule(); - singlesTrigger[0].setCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_LOW, 0.010); - singlesTrigger[0].setCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_HIGH, 8.191); - singlesTrigger[0].setCutValue(TriggerModule.CLUSTER_HIT_COUNT_LOW, 2); - - // Define the second singles trigger. - singlesTrigger[1] = new TriggerModule(); - singlesTrigger[1].setCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_LOW, 0.010); - singlesTrigger[1].setCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_HIGH, 0.050); - singlesTrigger[1].setCutValue(TriggerModule.CLUSTER_HIT_COUNT_LOW, 2); - - // Define the first pairs trigger. - pairsTrigger[0] = new TriggerModule(); - pairsTrigger[0].setCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_LOW, 0.020); - pairsTrigger[0].setCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_HIGH, 0.055); - pairsTrigger[0].setCutValue(TriggerModule.CLUSTER_HIT_COUNT_LOW, 1); - pairsTrigger[0].setCutValue(TriggerModule.PAIR_ENERGY_SUM_LOW, 0.010); - pairsTrigger[0].setCutValue(TriggerModule.PAIR_ENERGY_SUM_HIGH, 2.000); - pairsTrigger[0].setCutValue(TriggerModule.PAIR_ENERGY_DIFFERENCE_HIGH, 1.200); - pairsTrigger[0].setCutValue(TriggerModule.PAIR_ENERGY_SLOPE_LOW, 0.400); - pairsTrigger[0].setCutValue(TriggerModule.PAIR_ENERGY_SLOPE_F, 0.0055); - pairsTrigger[0].setCutValue(TriggerModule.PAIR_COPLANARITY_HIGH, 40); - pairsTrigger[0].setCutValue(TriggerModule.PAIR_TIME_COINCIDENCE, 16); - - // Define the second pairs trigger. - pairsTrigger[1] = new TriggerModule(); - pairsTrigger[1].setCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_LOW, 0.010); - pairsTrigger[1].setCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_HIGH, 1.800); - pairsTrigger[1].setCutValue(TriggerModule.CLUSTER_HIT_COUNT_LOW, 2); - pairsTrigger[1].setCutValue(TriggerModule.PAIR_ENERGY_SUM_LOW, 0.020); - pairsTrigger[1].setCutValue(TriggerModule.PAIR_ENERGY_SUM_HIGH, 2.000); - pairsTrigger[1].setCutValue(TriggerModule.PAIR_ENERGY_DIFFERENCE_HIGH, 1.200); - pairsTrigger[1].setCutValue(TriggerModule.PAIR_ENERGY_SLOPE_LOW, 0.400); - pairsTrigger[1].setCutValue(TriggerModule.PAIR_ENERGY_SLOPE_F, 0.0055); - pairsTrigger[1].setCutValue(TriggerModule.PAIR_COPLANARITY_HIGH, 40); - pairsTrigger[1].setCutValue(TriggerModule.PAIR_TIME_COINCIDENCE, 16); - */ // Define the first singles trigger. singlesTrigger[0] = new TriggerModule(); @@ -255,6 +344,10 @@ */ @Override public void endOfData() { + PrintResults(); + } + + public void PrintResults() { // Print the cluster/trigger verification header. System.out.println(); System.out.println(); @@ -263,17 +356,48 @@ System.out.println("======================================================================"); // Print the general event failure rate. - System.out.println("Event Failure Rate:"); - System.out.printf("\tNoise Events :: %d / %d (%7.3f%%)%n", + int headSpaces = getPrintSpaces(totalEvents, triggerRunStats[0].getEventsOfTypeSeen(0), triggerRunStats[0].getEventsOfTypeSeen(1), + triggerRunStats[1].getEventsOfTypeSeen(0), triggerRunStats[1].getEventsOfTypeSeen(1)); + 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", noiseEvents, totalEvents, (100.0 * noiseEvents / totalEvents)); - System.out.printf("\tCluster Events Failed :: %d / %d (%7.3f%%)%n", + System.out.printf("\tCluster Events Failed :: %" + headSpaces + "d / %" + headSpaces + "d (%7.3f%%)%n", failedClusterEvents, totalEvents, (100.0 * failedClusterEvents / totalEvents)); - System.out.printf("\tSingles Events Failed :: %d / %d (%7.3f%%)%n", + System.out.printf("\tSingles Events Failed :: %" + headSpaces + "d / %" + headSpaces + "d (%7.3f%%)%n", failedSinglesEvents, totalEvents, (100.0 * failedSinglesEvents / totalEvents)); - System.out.printf("\tPair Events Failed :: %d / %d (%7.3f%%)%n", + System.out.printf("\tPair Events Failed :: %" + headSpaces + "d / %" + headSpaces + "d (%7.3f%%)%n", failedPairEvents, totalEvents, (100.0 * failedPairEvents / totalEvents)); + // Print out how many events were triggered by a type along + // with how many were verified. + System.out.println(); + System.out.println("Event Triggering Type Verification:"); + System.out.printf("\tSingles Trigger 1 :: %" + headSpaces + "d / %" + headSpaces + "d", + triggerRunStats[0].getEventsOfTypeSeen(0), triggerRunStats[0].getEventsOfType(0)); + if(triggerRunStats[0].getEventsOfType(0) != 0) { + System.out.printf(" (%7.3f%%)%n", (100.0 * triggerRunStats[0].getEventsOfTypeSeen(0) / triggerRunStats[0].getEventsOfType(0))); + } else { System.out.println(); } + System.out.printf("\tSingles Trigger 2 :: %" + headSpaces + "d / %" + headSpaces + "d", + triggerRunStats[0].getEventsOfTypeSeen(1), triggerRunStats[0].getEventsOfType(1)); + if(triggerRunStats[0].getEventsOfType(0) != 0) { + System.out.printf(" (%7.3f%%)%n", (100.0 * triggerRunStats[0].getEventsOfTypeSeen(1) / triggerRunStats[0].getEventsOfType(1))); + } else { System.out.println(); } + System.out.printf("\tPair Trigger 1 :: %" + headSpaces + "d / %" + headSpaces + "d", + triggerRunStats[1].getEventsOfTypeSeen(0), triggerRunStats[0].getEventsOfType(0)); + if(triggerRunStats[1].getEventsOfType(0) != 0) { + System.out.printf(" (%7.3f%%)%n", (100.0 * triggerRunStats[1].getEventsOfTypeSeen(0) / triggerRunStats[1].getEventsOfType(0))); + } else { System.out.println(); } + System.out.printf("\tPair Trigger 2 :: %" + headSpaces + "d / %" + headSpaces + "d", + triggerRunStats[1].getEventsOfTypeSeen(1), triggerRunStats[0].getEventsOfType(1)); + if(triggerRunStats[1].getEventsOfType(0) != 0) { + System.out.printf(" (%7.3f%%)%n", (100.0 * triggerRunStats[1].getEventsOfTypeSeen(1) / triggerRunStats[1].getEventsOfType(1))); + } else { System.out.println(); } + // Print the cluster verification data. + System.out.println(); System.out.println("Cluster Verification:"); System.out.printf("\tRecon Clusters :: %d%n", clusterRunStats.getReconClusterCount()); System.out.printf("\tSSP Clusters :: %d%n", clusterRunStats.getSSPClusterCount()); @@ -282,7 +406,7 @@ System.out.printf("\tFailed (Energy) :: %d%n", clusterRunStats.getEnergyFailures()); System.out.printf("\tFailed (Hit Count) :: %d%n", clusterRunStats.getHitCountFailures()); if(clusterRunStats.getReconClusterCount() == 0) { System.out.printf("\tCluster Efficiency :: N/A%n"); } - else { System.out.printf("\tCluster Efficiency :: %7.3f%%%n", 100.0 * clusterRunStats.getMatches() / clusterRunStats.getReconClusterCount()); } + else { System.out.printf("\tCluster Efficiency :: %7.3f%%%n", 100.0 * clusterRunStats.getMatches() / clusterRunStats.getReconClusterCount()); } // Print the trigger verification data. for(int triggerType = 0; triggerType < 2; triggerType++) { @@ -310,61 +434,67 @@ else { System.out.printf("(%7.3f%%)%n" , (100.0 * triggerRunStats[triggerType].getMatchedReconTriggers() / triggerRunStats[triggerType].getReconTriggerCount())); } // Print the individual cut performances. - int halfSSPTriggers = triggerRunStats[triggerType].getSSPSimTriggerCount() / 2; if(triggerType == 0) { for(int triggerNum = 0; triggerNum < 2; triggerNum++) { + int sspTriggerCount = triggerRunStats[0].getTotalSSPTriggers(triggerNum); + System.out.println(); + System.out.printf("\tTrigger %d Individual Cut Failure Rate:%n", (triggerNum + 1)); + if(sspTriggerCount == 0) { + System.out.printf("\t\tUmatched Triggers :: %" + spaces + "d%n", triggerRunStats[0].getUnmatchedTriggers(triggerNum)); + System.out.printf("\t\tCluster Energy Lower Bound :: %" + spaces + "d / %" + spaces + "d%n", + triggerRunStats[0].getCutFailures(triggerNum, ENERGY_MIN), sspTriggerCount); + System.out.printf("\t\tCluster Energy Upper Bound :: %" + spaces + "d / %" + spaces + "d%n", + triggerRunStats[0].getCutFailures(triggerNum, ENERGY_MAX), sspTriggerCount); + System.out.printf("\t\tCluster Hit Count :: %" + spaces + "d / %" + spaces + "d%n", + triggerRunStats[0].getCutFailures(triggerNum, HIT_COUNT), sspTriggerCount); + } else { + System.out.printf("\t\tUmatched Triggers :: %" + spaces + "d%n", triggerRunStats[0].getUnmatchedTriggers(triggerNum)); + System.out.printf("\t\tCluster Energy Lower Bound :: %" + spaces + "d / %" + spaces + "d (%7.3f%%)%n", + triggerRunStats[0].getCutFailures(triggerNum, ENERGY_MIN), sspTriggerCount, + (100.0 * triggerRunStats[0].getCutFailures(triggerNum, ENERGY_MIN) / sspTriggerCount)); + System.out.printf("\t\tCluster Energy Upper Bound :: %" + spaces + "d / %" + spaces + "d (%7.3f%%)%n", + triggerRunStats[0].getCutFailures(triggerNum, ENERGY_MAX), sspTriggerCount, + (100.0 * triggerRunStats[0].getCutFailures(triggerNum, ENERGY_MAX) / sspTriggerCount)); + System.out.printf("\t\tCluster Hit Count :: %" + spaces + "d / %" + spaces + "d (%7.3f%%)%n", + triggerRunStats[0].getCutFailures(triggerNum, HIT_COUNT), sspTriggerCount, + (100.0 * triggerRunStats[0].getCutFailures(triggerNum, HIT_COUNT) / sspTriggerCount)); + } + } + } else { + for(int triggerNum = 0; triggerNum < 2; triggerNum++) { + int sspTriggerCount = triggerRunStats[1].getTotalSSPTriggers(triggerNum); System.out.println(); System.out.printf("\tTrigger %d Individual Cut Failure Rate:%n", (triggerNum + 1)); - if(triggerRunStats[0].getSSPSimTriggerCount() == 0) { - System.out.printf("\t\tCluster Energy Lower Bound :: %" + spaces + "d / %" + spaces + "d%n", - triggerRunStats[0].getCutFailures(triggerNum, ENERGY_MIN), halfSSPTriggers); - System.out.printf("\t\tCluster Energy Upper Bound :: %" + spaces + "d / %" + spaces + "d%n", - triggerRunStats[0].getCutFailures(triggerNum, ENERGY_MAX), halfSSPTriggers); - System.out.printf("\t\tCluster Hit Count :: %" + spaces + "d / %" + spaces + "d%n", - triggerRunStats[0].getCutFailures(triggerNum, HIT_COUNT), halfSSPTriggers); + if(sspTriggerCount == 0) { + System.out.printf("\t\tUmatched Triggers :: %" + spaces + "d%n", triggerRunStats[1].getUnmatchedTriggers(triggerNum)); + System.out.printf("\t\tPair Energy Sum :: %" + spaces + "d / %" + spaces + "d%n", + triggerRunStats[1].getCutFailures(triggerNum, ENERGY_SUM), sspTriggerCount); + System.out.printf("\t\tPair Energy Difference :: %" + spaces + "d / %" + spaces + "d%n", + triggerRunStats[1].getCutFailures(triggerNum, ENERGY_DIFF), sspTriggerCount); + System.out.printf("\t\tPair Energy Slope :: %" + spaces + "d / %" + spaces + "d%n", + triggerRunStats[1].getCutFailures(triggerNum, ENERGY_SLOPE), sspTriggerCount); + System.out.printf("\t\tPair Coplanarity :: %" + spaces + "d / %" + spaces + "d%n", + triggerRunStats[1].getCutFailures(triggerNum, COPLANARITY), sspTriggerCount); } else { - System.out.printf("\t\tCluster Energy Lower Bound :: %" + spaces + "d / %" + spaces + "d (%7.3f%%)%n", - triggerRunStats[0].getCutFailures(triggerNum, ENERGY_MIN), halfSSPTriggers, - (100.0 * triggerRunStats[0].getCutFailures(triggerNum, ENERGY_MIN) / halfSSPTriggers)); - System.out.printf("\t\tCluster Energy Upper Bound :: %" + spaces + "d / %" + spaces + "d (%7.3f%%)%n", - triggerRunStats[0].getCutFailures(triggerNum, ENERGY_MAX), halfSSPTriggers, - (100.0 * triggerRunStats[0].getCutFailures(triggerNum, ENERGY_MAX) / halfSSPTriggers)); - System.out.printf("\t\tCluster Hit Count :: %" + spaces + "d / %" + spaces + "d (%7.3f%%)%n", - triggerRunStats[0].getCutFailures(triggerNum, HIT_COUNT), halfSSPTriggers, - (100.0 * triggerRunStats[0].getCutFailures(triggerNum, HIT_COUNT) / halfSSPTriggers)); + System.out.printf("\t\tUmatched Triggers :: %" + spaces + "d%n", triggerRunStats[1].getUnmatchedTriggers(triggerNum)); + System.out.printf("\t\tPair Energy Sum :: %" + spaces + "d / %" + spaces + "d (%7.3f%%)%n", + triggerRunStats[1].getCutFailures(triggerNum, ENERGY_SUM), sspTriggerCount, + (100.0 * triggerRunStats[1].getCutFailures(triggerNum, ENERGY_SUM) / sspTriggerCount)); + System.out.printf("\t\tPair Energy Difference :: %" + spaces + "d / %" + spaces + "d (%7.3f%%)%n", + triggerRunStats[1].getCutFailures(triggerNum, ENERGY_DIFF), sspTriggerCount, + (100.0 * triggerRunStats[1].getCutFailures(triggerNum, ENERGY_DIFF) / sspTriggerCount)); + System.out.printf("\t\tPair Energy Slope :: %" + spaces + "d / %" + spaces + "d (%7.3f%%)%n", + triggerRunStats[1].getCutFailures(triggerNum, ENERGY_SLOPE), sspTriggerCount, + (100.0 * triggerRunStats[1].getCutFailures(triggerNum, ENERGY_SLOPE) / sspTriggerCount)); + System.out.printf("\t\tPair Coplanarity :: %" + spaces + "d / %" + spaces + "d (%7.3f%%)%n", + triggerRunStats[1].getCutFailures(triggerNum, COPLANARITY), sspTriggerCount, + (100.0 * triggerRunStats[1].getCutFailures(triggerNum, COPLANARITY) / sspTriggerCount)); } } - } else { - for(int triggerNum = 0; triggerNum < 2; triggerNum++) { - System.out.println(); - System.out.printf("\tTrigger %d Individual Cut Failure Rate:%n", (triggerNum + 1)); - if(triggerRunStats[1].getSSPSimTriggerCount() == 0) { - System.out.printf("\t\tPair Energy Sum :: %" + spaces + "d / %" + spaces + "d%n", - triggerRunStats[1].getCutFailures(triggerNum, ENERGY_SUM), halfSSPTriggers); - System.out.printf("\t\tPair Energy Difference :: %" + spaces + "d / %" + spaces + "d%n", - triggerRunStats[1].getCutFailures(triggerNum, ENERGY_DIFF), halfSSPTriggers); - System.out.printf("\t\tPair Energy Slope :: %" + spaces + "d / %" + spaces + "d%n", - triggerRunStats[1].getCutFailures(triggerNum, ENERGY_SLOPE), halfSSPTriggers); - System.out.printf("\t\tPair Coplanarity :: %" + spaces + "d / %" + spaces + "d%n", - triggerRunStats[1].getCutFailures(triggerNum, COPLANARITY), halfSSPTriggers); - } else { - System.out.printf("\t\tPair Energy Sum :: %" + spaces + "d / %" + spaces + "d (%7.3f%%)%n", - triggerRunStats[1].getCutFailures(triggerNum, ENERGY_SUM), halfSSPTriggers, - (100.0 * triggerRunStats[1].getCutFailures(triggerNum, ENERGY_SUM) / halfSSPTriggers)); - System.out.printf("\t\tPair Energy Difference :: %" + spaces + "d / %" + spaces + "d (%7.3f%%)%n", - triggerRunStats[1].getCutFailures(triggerNum, ENERGY_DIFF), halfSSPTriggers, - (100.0 * triggerRunStats[1].getCutFailures(triggerNum, ENERGY_DIFF) / halfSSPTriggers)); - System.out.printf("\t\tPair Energy Slope :: %" + spaces + "d / %" + spaces + "d (%7.3f%%)%n", - triggerRunStats[1].getCutFailures(triggerNum, ENERGY_SLOPE), halfSSPTriggers, - (100.0 * triggerRunStats[1].getCutFailures(triggerNum, ENERGY_SLOPE) / halfSSPTriggers)); - System.out.printf("\t\tPair Coplanarity :: %" + spaces + "d / %" + spaces + "d (%7.3f%%)%n", - triggerRunStats[1].getCutFailures(triggerNum, COPLANARITY), halfSSPTriggers, - (100.0 * triggerRunStats[1].getCutFailures(triggerNum, COPLANARITY) / halfSSPTriggers)); - } - } - } - } - + } + } + + System.out.println(); this.efficiencyRunStats.printModule(); } @@ -374,7 +504,7 @@ @Override public void process(EventHeader event) { // ========================================================== - // ==== Initialize the Event ================================ + // ==== Event Pre-Initialization ============================ // ========================================================== // If DAQ settings are to be used, check if they are initialized @@ -385,14 +515,12 @@ } } - // Print the verification header. - OutputLogger.printNewLine(2); - OutputLogger.println("======================================================================"); - OutputLogger.println("==== Cluster/Trigger Verification ===================================="); - OutputLogger.println("======================================================================"); - // Increment the total event count. totalEvents++; + + if(totalEvents%printResultsEveryNEvents == 0){ + PrintResults(); + } // Reset the output buffer and print flags. clusterFail = false; @@ -400,12 +528,61 @@ 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 ================================ + // ========================================================== + + // Print the verification header. + OutputLogger.printNewLine(2); + OutputLogger.println("======================================================================"); + OutputLogger.println("==== Cluster/Trigger Verification ===================================="); + OutputLogger.println("======================================================================"); // ========================================================== // ==== Obtain SSP and TI Banks ============================= // ========================================================== + + // Output the event number and information. + OutputLogger.printf("Event Number %d (%d)%n", totalEvents, event.getEventNumber()); // Get the SSP clusters. if(event.hasCollection(GenericObject.class, bankCollectionName)) { @@ -441,6 +618,9 @@ } else if(tiBank.isCalibTrigger()) { OutputLogger.println("Trigger type :: Cosmic"); activeTrigger = TriggerDiagnosticUtil.TRIGGER_COSMIC; + } else { + System.err.println("TriggerDiagnosticDriver: Skipping event; no TI trigger source found."); + return; } } } @@ -454,6 +634,12 @@ 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; } @@ -523,7 +709,6 @@ reconClusters.add(reconCluster); OutputLogger.println(" [ verifiable ]"); } else { OutputLogger.println(" [ unverifiable ]"); } - } // Output the number of verifiable clusters found. @@ -576,10 +761,10 @@ (pairInternalFail && printPairTriggerInternalFail) || (pairEfficiencyFail && printPairTriggerEfficiencyFail)) { OutputLogger.printLog(); - } - - - + } + + + // ========================================================== // ==== Process Local Tracked Variables ===================== // ========================================================== @@ -604,6 +789,10 @@ localWindowStart = Calendar.getInstance().getTimeInMillis(); } } + + public void setPrintResultsEveryNEvents(int N) { + printResultsEveryNEvents = N; + } public void setPrintOnClusterFailure(boolean state) { printClusterFail = state; @@ -653,8 +842,16 @@ energyAcceptance = window; } + public void setEnforceStrictTimeCompliance(boolean state) { + enforceTimeCompliance = state; + } + public void setReadDAQConfig(boolean state) { readDAQConfig = state; + } + + public void setLocalWindowThresholdMilliseconds(int localWindowThreshold) { + this.localWindowThreshold = localWindowThreshold; } /** @@ -679,15 +876,164 @@ OutputLogger.println("=== Cluster Verification ============================================="); OutputLogger.println("======================================================================"); + + + // ========================================================== + // ==== Perform Cluster Matching ============================ + // ========================================================== + // Track the number of cluster pairs that were matched and that // failed by failure type. ClusterMatchEvent event = new ClusterMatchEvent(); - - - // ========================================================== - // ==== Produce the Cluster Position Mappings =============== - // ========================================================== + if(enforceTimeCompliance) { + event = matchClustersTimeCompliant(reconClusters, sspClusters, energyAcceptance, hitAcceptance); + } else { + event = matchClusters(reconClusters, sspClusters, energyAcceptance, hitAcceptance); + } + + // Add the event results to the global results. + clusterRunStats.addEvent(event, reconClusters, sspClusters); + clusterLocalStats.addEvent(event, reconClusters, sspClusters); + + + + // ========================================================== + // ==== 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.getMatchedPairs().size() != 0) { + // Iterate over the matched pairs. + for(ClusterMatchedPair pair : event.getMatchedPairs()) { + // 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.getMatchedPairs()) { + 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 ClusterMatchEvent 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. + ClusterMatchEvent event = new ClusterMatchEvent(); // Create maps to link cluster position to the list of clusters // that were found at that location. @@ -726,12 +1072,6 @@ // Add the cluster to the list. sspList.add(sspCluster); } - - - - // ========================================================== - // ==== Perform Cluster Matching ============================ - // ========================================================== // For each reconstructed cluster, attempt to match the clusters // with SSP clusters at the same position. @@ -749,17 +1089,11 @@ // reason of position. The remainder of the loop may be // skipped, since there is nothing to check. if(sspList == null || sspList.isEmpty()) { - clusterFail = true; for(Cluster cluster : reconList) { event.pairFailPosition(cluster, null); } continue positionLoop; } - - // If there are more reconstructed clusters than there are - // SSP clusters, than a number equal to the difference must - // fail by means of positions. - if(sspList.size() < reconList.size()) { clusterFail = true; } // Get all possible permutations of SSP clusters. List<List<Pair<Cluster, SSPCluster>>> permutations = getPermutations(reconList, sspList); @@ -794,20 +1128,31 @@ // 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"); - perm.pairFailPosition(pair.getFirstElement(), pair.getSecondElement()); + + // 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() * (1 - energyAcceptance) && - pair.getSecondElement().getEnergy() <= pair.getFirstElement().getEnergy() * (1 + energyAcceptance)) { + 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() - hitAcceptance && - pair.getSecondElement().getHitCount() <= pair.getFirstElement().getCalorimeterHits().size() + hitAcceptance) { + 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"); @@ -844,69 +1189,113 @@ event.addEvent(bestPerm); } // End Crystal Position Loop - // Add the event results to the global results. - clusterRunStats.addEvent(event, reconClusters, sspClusters); - clusterLocalStats.addEvent(event, reconClusters, sspClusters); - - - - // ========================================================== - // ==== 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()) { + // 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 ClusterMatchEvent 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. + ClusterMatchEvent event = new ClusterMatchEvent(); + + // 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) { - OutputLogger.printf("\t%s%n", TriggerDiagnosticUtil.clusterToString(sspCluster)); - } - } else { OutputLogger.println("\tNone"); } - - // Print the matched clusters. - OutputLogger.println("Matched Clusters:"); - if(event.getMatchedPairs().size() != 0) { - // Iterate over the matched pairs. - for(ClusterMatchedPair pair : event.getMatchedPairs()) { - // 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"); } - - // Get the number of position failures. - int failPosition = event.getPositionFailures(); - if(sspClusters == null || sspClusters.isEmpty()) { - failPosition = (reconClusters == null ? 0 : reconClusters.size()); - } - - // 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", failPosition); - 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.getMatches() - reconClusters.size() != 0) { - clusterFail = true; - } + // 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; } /** @@ -1002,9 +1391,9 @@ 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 :: %s%n", + OutputLogger.printf("\tTrigger %d :: %s :: %3.0f :: %s%n", (triggerNum + 1), triggerPositionString(simTrigger), - simTrigger.toString()); + getTriggerTime(simTrigger), simTrigger.toString()); } } if(sspTriggerList.get(0).size() + sspTriggerList.get(1).size() == 0) { @@ -1015,9 +1404,9 @@ 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 :: %s%n", + OutputLogger.printf("\tTrigger %d :: %s :: %3.0f :: %s%n", (triggerNum + 1), triggerPositionString(simTrigger), - simTrigger.toString()); + getTriggerTime(simTrigger), simTrigger.toString()); } } if(reconTriggerList.get(0).size() + reconTriggerList.get(1).size() == 0) { @@ -1053,42 +1442,85 @@ // Iterate over the triggers. OutputLogger.println(); - OutputLogger.println("SSP Reported Trigger --> SSP Cluster Trigger Match Status"); + OutputLogger.println("Matching SSP Reported Triggers to SSP Simulated Triggers:"); for(SSPNumberedTrigger sspTrigger : sspTriggers) { // Get the trigger information. int triggerNum = sspTrigger.isFirstTrigger() ? 0 : 1; - boolean matchedTrigger = false; + OutputLogger.printf("\t%s%n", sspTrigger.toString()); // Iterate over the SSP cluster simulated triggers and // look for a trigger that matches. matchLoop: for(Trigger<?> simTrigger : sspTriggerList.get(triggerNum)) { - // If the current SSP trigger has already been - // matched, skip it. - if(sspTriggerSet.contains(sspTrigger)) { continue matchLoop; } - - // Otherwise, check whether the reconstructed SSP - // cluster trigger matches the SSP trigger. - if(compareTriggers(sspTrigger, simTrigger)) { - matchedTrigger = true; - sspTriggerSet.add(sspTrigger); - simTriggerSet.add(simTrigger); - event.matchedSSPPair(simTrigger, sspTrigger); - break matchLoop; - } - - OutputLogger.printf("\t%s :: Matched: %5b%n", sspTrigger.toString(), matchedTrigger); + // 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); + event.matchedSSPPair(simTrigger, sspTrigger); + 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. - simLoop: + 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)) { continue simLoop; } + 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); @@ -1099,18 +1531,27 @@ 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)) { continue reportedLoop; } + if(sspTriggerSet.contains(sspTrigger)) { + OutputLogger.printf("[ %-15s ]%n", "failed; matched"); + continue reportedLoop; + } // Check each of the cuts. boolean[] tempMatchedCut = triggerCutMatch(simTrigger, sspTrigger); @@ -1119,6 +1560,7 @@ // 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. @@ -1126,18 +1568,27 @@ 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; } + event.matchedSSPPair(simTrigger, bestMatch, matchedCut); + OutputLogger.printf("\t\tTrigger %d :: %s :: %3.0f :: %s", + (triggerNum + 1), triggerPositionString(simTrigger), + getTriggerTime(simTrigger), simTrigger.toString()); + OutputLogger.println(" --> No Valid Match Found"); } else { event.matchedSSPPair(simTrigger, bestMatch, matchedCut); + OutputLogger.printf("\t\tTrigger %d :: %s :: %3.0f :: %s", + (triggerNum + 1), triggerPositionString(simTrigger), + getTriggerTime(simTrigger), simTrigger.toString()); + OutputLogger.println(" --> " + bestMatchText); } } } @@ -1156,12 +1607,31 @@ OutputLogger.println("Recon Cluster Trigger --> SSP Reported Trigger Match Status"); for(int triggerNum = 0; triggerNum < 2; triggerNum++) { for(Trigger<?> simTrigger : reconTriggerList.get(triggerNum)) { + // If the trigger number and type align with the event + // trigger type, mark that it was seen. + if(triggerNum == 1) { + if(activeTrigger == TriggerDiagnosticUtil.TRIGGER_SINGLES_1 && isSingles) { + event.setSawEventType(true); + } else if(activeTrigger == TriggerDiagnosticUtil.TRIGGER_PAIR_1 && !isSingles) { + event.setSawEventType(true); + } + } else { + if(activeTrigger == TriggerDiagnosticUtil.TRIGGER_SINGLES_2 && isSingles) { + event.setSawEventType(true); + } else if(activeTrigger == TriggerDiagnosticUtil.TRIGGER_PAIR_2 && !isSingles) { + event.setSawEventType(true); + } + } 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()); @@ -1182,10 +1652,6 @@ } // Test each cut. - String[][] cutNames = { - { "E_min", "E_max", "hit count", "null" }, - { "E_sum", "E_diff", "E_slope", "coplanar" } - }; int typeIndex = isSingles ? 0 : 1; boolean[] matchedCuts = triggerCutMatch(simTrigger, sspTrigger); for(int cutIndex = 0; cutIndex < matchedCuts.length; cutIndex++) { @@ -1200,8 +1666,12 @@ sspTriggerSet.add(sspTrigger); event.matchedReconPair(simTrigger, sspTrigger); OutputLogger.print(" [ success ]%n"); + globalTriggerPlots.matchedTrigger(simTrigger); + matched = true; break matchLoop; } + + if(!matched) { globalTriggerPlots.failedTrigger(simTrigger); } } } @@ -1213,14 +1683,19 @@ // 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 halfSimTriggers = sspSimTriggers / 2; + int[] sspTriggerCount = { sspTriggerList.get(0).size(), sspTriggerList.get(1).size() }; // Print event statistics. OutputLogger.println(); OutputLogger.println("Event Statistics:"); + OutputLogger.printf("\tSaw Triggering Event Type :: "); + if(activeTrigger == TriggerDiagnosticUtil.TRIGGER_COSMIC || activeTrigger == TriggerDiagnosticUtil.TRIGGER_PULSER) { + OutputLogger.println("Unsupported for Cosmic/Pulser"); + } else { + OutputLogger.println("" + event.sawEventType()); + } 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()); @@ -1245,23 +1720,26 @@ 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", event.getCutFailures(triggerNum, ENERGY_MIN), halfSimTriggers); - OutputLogger.printf("\tCluster Energy Upper Bound :: %d / %d%n", event.getCutFailures(triggerNum, ENERGY_MAX), halfSimTriggers); - OutputLogger.printf("\tCluster Hit Count :: %d / %d%n", event.getCutFailures(triggerNum, HIT_COUNT), halfSimTriggers); + OutputLogger.printf("\tCluster Energy Lower Bound :: %d / %d%n", event.getCutFailures(triggerNum, ENERGY_MIN), sspTriggerCount[triggerNum]); + OutputLogger.printf("\tCluster Energy Upper Bound :: %d / %d%n", event.getCutFailures(triggerNum, ENERGY_MAX), sspTriggerCount[triggerNum]); + OutputLogger.printf("\tCluster Hit Count :: %d / %d%n", event.getCutFailures(triggerNum, HIT_COUNT), sspTriggerCount[triggerNum]); } else { OutputLogger.printf("\tCluster Energy Lower Bound :: %d / %d (%3.0f%%)%n", - event.getCutFailures(triggerNum, ENERGY_MIN), halfSimTriggers, (100.0 * event.getCutFailures(triggerNum, ENERGY_MIN) / halfSimTriggers)); + event.getCutFailures(triggerNum, ENERGY_MIN), sspTriggerCount[triggerNum], + (100.0 * event.getCutFailures(triggerNum, ENERGY_MIN) / sspTriggerCount[triggerNum])); OutputLogger.printf("\tCluster Energy Upper Bound :: %d / %d (%3.0f%%)%n", - event.getCutFailures(triggerNum, ENERGY_MAX), halfSimTriggers, (100.0 * event.getCutFailures(triggerNum, ENERGY_MAX) / halfSimTriggers)); + event.getCutFailures(triggerNum, ENERGY_MAX), sspTriggerCount[triggerNum], + (100.0 * event.getCutFailures(triggerNum, ENERGY_MAX) / sspTriggerCount[triggerNum])); OutputLogger.printf("\tCluster Hit Count :: %d / %d (%3.0f%%)%n", - event.getCutFailures(triggerNum, HIT_COUNT), halfSimTriggers, (100.0 * event.getCutFailures(triggerNum, HIT_COUNT) / halfSimTriggers)); + event.getCutFailures(triggerNum, HIT_COUNT), sspTriggerCount[triggerNum], + (100.0 * event.getCutFailures(triggerNum, HIT_COUNT) / sspTriggerCount[triggerNum])); } OutputLogger.printf("\tExcess Reported Triggers :: %d%n", sspReportedExtras / 2); } // Update the global trigger tracking variables. - triggerRunStats[0].addEvent(event, reconTriggerList, sspTriggerList, sspTriggers); - triggerLocalStats[0].addEvent(event, reconTriggerList, sspTriggerList, sspTriggers); + triggerRunStats[0].addEvent(activeTrigger, event, reconTriggerList, sspTriggerList, sspTriggers); + triggerLocalStats[0].addEvent(activeTrigger, event, reconTriggerList, sspTriggerList, sspTriggers); efficiencyRunStats.addSinglesTriggers(activeTrigger, reconTriggerList); efficiencyLocalStats.addSinglesTriggers(activeTrigger, reconTriggerList); efficiencyRunStats.addEvent(activeTrigger, event); @@ -1270,27 +1748,31 @@ for(int triggerNum = 0; triggerNum < 2; triggerNum++) { OutputLogger.println(); OutputLogger.printf("Trigger %d Individual Cut Failure Rate:%n", (triggerNum + 1)); - if(sspSimTriggers == 0) { - OutputLogger.printf("\tPair Energy Sum :: %d / %d%n", event.getCutFailures(triggerNum, ENERGY_SUM), halfSimTriggers); - OutputLogger.printf("\tPair Energy Difference :: %d / %d%n", event.getCutFailures(triggerNum, ENERGY_DIFF), halfSimTriggers); - OutputLogger.printf("\tPair Energy Slope :: %d / %d%n", event.getCutFailures(triggerNum, ENERGY_SLOPE), halfSimTriggers); - OutputLogger.printf("\tPair Coplanarity :: %d / %d%n", event.getCutFailures(triggerNum, COPLANARITY), halfSimTriggers); + if(sspTriggerCount[triggerNum] == 0) { + OutputLogger.printf("\tPair Energy Sum :: %d / %d%n", event.getCutFailures(triggerNum, ENERGY_SUM), sspTriggerCount[triggerNum]); + OutputLogger.printf("\tPair Energy Difference :: %d / %d%n", event.getCutFailures(triggerNum, ENERGY_DIFF), sspTriggerCount[triggerNum]); + OutputLogger.printf("\tPair Energy Slope :: %d / %d%n", event.getCutFailures(triggerNum, ENERGY_SLOPE), sspTriggerCount[triggerNum]); + OutputLogger.printf("\tPair Coplanarity :: %d / %d%n", event.getCutFailures(triggerNum, COPLANARITY), sspTriggerCount[triggerNum]); } else { OutputLogger.printf("\tPair Energy Sum :: %d / %d (%3.0f%%)%n", - event.getCutFailures(triggerNum, ENERGY_SUM), halfSimTriggers, (100.0 * event.getCutFailures(triggerNum, ENERGY_SUM) / halfSimTriggers)); + event.getCutFailures(triggerNum, ENERGY_SUM), sspTriggerCount[triggerNum], + (100.0 * event.getCutFailures(triggerNum, ENERGY_SUM) / sspTriggerCount[triggerNum])); OutputLogger.printf("\tPair Energy Difference :: %d / %d (%3.0f%%)%n", - event.getCutFailures(triggerNum, ENERGY_DIFF), halfSimTriggers, (100.0 * event.getCutFailures(triggerNum, ENERGY_DIFF) / halfSimTriggers)); + event.getCutFailures(triggerNum, ENERGY_DIFF), sspTriggerCount[triggerNum], + (100.0 * event.getCutFailures(triggerNum, ENERGY_DIFF) / sspTriggerCount[triggerNum])); OutputLogger.printf("\tPair Energy Slope :: %d / %d (%3.0f%%)%n", - event.getCutFailures(triggerNum, ENERGY_SLOPE), halfSimTriggers, (100.0 * event.getCutFailures(triggerNum, ENERGY_SLOPE) / halfSimTriggers)); + event.getCutFailures(triggerNum, ENERGY_SLOPE), sspTriggerCount[triggerNum], + (100.0 * event.getCutFailures(triggerNum, ENERGY_SLOPE) / sspTriggerCount[triggerNum])); OutputLogger.printf("\tPair Coplanarity :: %d / %d (%3.0f%%)%n", - event.getCutFailures(triggerNum, COPLANARITY), halfSimTriggers, (100.0 * event.getCutFailures(triggerNum, COPLANARITY) / halfSimTriggers)); + event.getCutFailures(triggerNum, COPLANARITY), sspTriggerCount[triggerNum], + (100.0 * event.getCutFailures(triggerNum, COPLANARITY) / sspTriggerCount[triggerNum])); } OutputLogger.printf("\tExcess Reported Triggers :: %d%n", sspReportedExtras / 2); } // Update the global trigger tracking variables. - triggerRunStats[1].addEvent(event, reconTriggerList, sspTriggerList, sspTriggers); - triggerLocalStats[1].addEvent(event, reconTriggerList, sspTriggerList, sspTriggers); + triggerRunStats[1].addEvent(activeTrigger, event, reconTriggerList, sspTriggerList, sspTriggers); + triggerLocalStats[1].addEvent(activeTrigger, event, reconTriggerList, sspTriggerList, sspTriggers); efficiencyRunStats.addPairTriggers(activeTrigger, reconTriggerList); efficiencyLocalStats.addSinglesTriggers(activeTrigger, reconTriggerList); efficiencyRunStats.addEvent(activeTrigger, event); @@ -1298,9 +1780,12 @@ } // Note whether the was a trigger match failure. - if((event.getMatchedReconTriggers() - reconSimTriggers != 0) || (event.getMatchedSSPTriggers() - sspSimTriggers != 0)) { + if(event.getMatchedReconTriggers() - reconSimTriggers != 0) { if(isSingles) { singlesEfficiencyFail = true; } else { pairEfficiencyFail = true; } + } if(event.getMatchedSSPTriggers() - sspSimTriggers != 0) { + if(isSingles) { singlesInternalFail = true; } + else { pairInternalFail = true; } } } @@ -1312,6 +1797,7 @@ // Run the SSP clusters through the singles trigger to determine // whether they pass it or not. for(SSPCluster cluster : sspClusters) { + triggerLoop: for(int triggerNum = 0; triggerNum < 2; triggerNum++) { // For a cluster to have formed it is assumed to have passed // the cluster seed energy cuts. This can not be verified @@ -1332,7 +1818,19 @@ trigger.setStateClusterEnergyHigh(passClusterHigh); trigger.setStateHitCount(passHitCount); - // Store the trigger. + // 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; + } + + // If all the necessary checks passed, store the new + // trigger for verification. sspSinglesTriggers.get(triggerNum).add(trigger); } } @@ -1341,6 +1839,7 @@ // to determine whether they pass it or not. for(Cluster cluster : reconClusters) { // Simulate each of the cluster singles triggers. + triggerLoop: for(int triggerNum = 0; triggerNum < 2; triggerNum++) { // For a cluster to have formed it is assumed to have passed // the cluster seed energy cuts. This can not be verified @@ -1360,6 +1859,17 @@ 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. reconSinglesTriggers.get(triggerNum).add(trigger); @@ -1417,13 +1927,13 @@ // Simulate the pair triggers and record the results. for(Cluster[] reconPair : reconPairs) { // Simulate each of the cluster pair triggers. - reconTriggerLoop: + pairTriggerLoop: for(int triggerIndex = 0; triggerIndex < 2; triggerIndex++) { // 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 reconTriggerLoop; + continue pairTriggerLoop; } // For a cluster to have formed it is assumed to have passed @@ -1460,6 +1970,25 @@ 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. reconPairsTriggers.get(triggerIndex).add(trigger); } @@ -1509,6 +2038,25 @@ 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. sspPairsTriggers.get(triggerIndex).add(trigger); } @@ -1524,8 +2072,9 @@ private void logSettings() { // Output general settings. System.out.println("Cluster Verification Settings"); - System.out.printf("\tEnergy Threshold :: %1.2f%%%n", energyAcceptance); - System.out.printf("\tHit Threshold :: %1d%n", hitAcceptance); + 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"); @@ -1544,28 +2093,45 @@ 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++) { - System.out.printf("Singles Trigger %d Settings%n", (i + 1)); - System.out.printf("\tCluster Energy Low :: %.3f GeV%n", singlesTrigger[i].getCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_LOW)); - System.out.printf("\tCluster Energy High :: %.3f GeV%n", singlesTrigger[i].getCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_HIGH)); - System.out.printf("\tCluster Hit Count :: %.0f hits%n", singlesTrigger[i].getCutValue(TriggerModule.CLUSTER_HIT_COUNT_LOW)); + // 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%n", (i + 1)); - System.out.printf("\tCluster Energy Low :: %.3f GeV%n", pairsTrigger[i].getCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_LOW)); - System.out.printf("\tCluster Energy High :: %.3f GeV%n", pairsTrigger[i].getCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_HIGH)); - System.out.printf("\tCluster Hit Count :: %.0f hits%n", pairsTrigger[i].getCutValue(TriggerModule.CLUSTER_HIT_COUNT_LOW)); - System.out.printf("\tPair Energy Sum Low :: %.3f GeV%n", pairsTrigger[i].getCutValue(TriggerModule.PAIR_ENERGY_SUM_LOW)); - System.out.printf("\tPair Energy Sum Low :: %.3f GeV%n", pairsTrigger[i].getCutValue(TriggerModule.PAIR_ENERGY_SUM_HIGH)); - System.out.printf("\tPair Energy Difference :: %.3f GeV%n", pairsTrigger[i].getCutValue(TriggerModule.PAIR_ENERGY_DIFFERENCE_HIGH)); - System.out.printf("\tPair Energy Slope :: %.3f GeV%n", pairsTrigger[i].getCutValue(TriggerModule.PAIR_ENERGY_SLOPE_LOW)); - System.out.printf("\tPair Energy Slope F :: %.3f GeV / mm%n", pairsTrigger[i].getCutValue(TriggerModule.PAIR_ENERGY_SLOPE_F)); - System.out.printf("\tPair Coplanarity :: %.0f Degrees%n", pairsTrigger[i].getCutValue(TriggerModule.PAIR_COPLANARITY_HIGH)); - System.out.printf("\tPair Time Coincidence :: %.0f ns%n", pairsTrigger[i].getCutValue(TriggerModule.PAIR_TIME_COINCIDENCE)); + 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(); } } @@ -1578,122 +2144,6 @@ */ private final boolean isVerifiable(Cluster reconCluster) { return TriggerDiagnosticUtil.isVerifiable(reconCluster, nsa, nsb, windowWidth); - } - - /** - * Compares an SSP trigger with a simulated trigger. Note that only - * certain class combinations are supported. Triggers of the type - * <code>SSPSinglesTrigger</code> may be compared with triggers of - * the type <code>SinglesTrigger<SSPCluster></code> and triggers of - * the type <code>SSPPairTrigger</code> may be compared to either - * <code>PairTrigger<SSPCluster[]></code> triggers objects. - * @param bankTrigger - The SSP bank trigger. - * @param simTrigger - The simulated trigger. - * @return Returns <code>true</code> if the triggers are valid - * matches and <code>false</code> if they are not. - * @throws IllegalArgumentException Occurs if the trigger types - * are not of a supported type. - */ - @SuppressWarnings("unchecked") - private static final boolean compareTriggers(SSPNumberedTrigger bankTrigger, Trigger<?> simTrigger) throws IllegalArgumentException { - // Get the classes of the arguments. This is used to check the - // generic type of the Trigger<?> object, and means that the - // "unchecked" warnings can be safely ignored. - Object source = simTrigger.getTriggerSource(); - - // If the combination of classes is supported, pass the triggers - // to the appropriate handler. - if(bankTrigger instanceof SSPSinglesTrigger && simTrigger instanceof SinglesTrigger && source instanceof SSPCluster) { - return compareSSPSinglesTriggers((SSPSinglesTrigger) bankTrigger, (SinglesTrigger<SSPCluster>) simTrigger); - } else if(bankTrigger instanceof SSPPairTrigger && simTrigger instanceof PairTrigger && source instanceof SSPCluster[]) { - return compareSSPPairTriggers((SSPPairTrigger) bankTrigger, (PairTrigger<SSPCluster[]>) simTrigger); - } - - // Otherwise, the trigger combination is not supported. Produce - // and exception. - throw new IllegalArgumentException(String.format("Trigger type \"%s\" can not be compared to trigger type \"%s\" with source type \"%s\".", - bankTrigger.getClass().getSimpleName(), simTrigger.getClass().getSimpleName(), source.getClass().getSimpleName())); - } - - /** - * Compares a trigger from the SSP bank to a trigger simulated on - * an SSP cluster. - * @param bankTrigger - The trigger from the SSP bank. - * @param simTrigger - The trigger from the simulation. - * @return Returns <code>true</code> if the triggers match and - * <code>false</code> if they do not. - */ - private static final boolean compareSSPSinglesTriggers(SSPSinglesTrigger bankTrigger, SinglesTrigger<SSPCluster> simTrigger) { - // The bank trigger and simulated trigger must have the same - // time. This is equivalent to the time of the triggering cluster. - if(bankTrigger.getTime() != simTrigger.getTriggerSource().getTime()) { - return false; - } - - // If the time stamp is the same, check that the trigger flags - // are all the same. Start with cluster energy low. - if(bankTrigger.passCutEnergyMin() != simTrigger.getStateClusterEnergyLow()) { - return false; - } - - // Check cluster energy high. - if(bankTrigger.passCutEnergyMax() != simTrigger.getStateClusterEnergyHigh()) { - return false; - } - - // Check cluster hit count. - if(bankTrigger.passCutHitCount() != simTrigger.getStateHitCount()) { - return false; - } - - // If all of the tests are successful, the triggers match. - return true; - } - - /** - * Compares a trigger from the SSP bank to a trigger simulated on - * an SSP cluster. - * @param bankTrigger - The trigger from the SSP bank. - * @param simTrigger - The trigger from the simulation. - * @return Returns <code>true</code> if the triggers match and - * <code>false</code> if they do not. - */ - private static final boolean compareSSPPairTriggers(SSPPairTrigger bankTrigger, PairTrigger<SSPCluster[]> simTrigger) { - // Get the time of the bottom cluster in the pair. - int simTime = 0; - if(simTrigger.getTriggerSource()[0].getYIndex() < 0) { - simTime = simTrigger.getTriggerSource()[0].getTime(); - } else { - simTime = simTrigger.getTriggerSource()[1].getTime(); - } - - // The bank trigger and simulated trigger must have the same - // time. This is equivalent to the time of the triggering cluster. - if(bankTrigger.getTime() != simTime) { return false; } - - // If the time stamp is the same, check that the trigger flags - // are all the same. Start with energy sum. - if(bankTrigger.passCutEnergySum() != simTrigger.getStateEnergySum()) { - return false; - } - - // Check pair energy difference. - if(bankTrigger.passCutEnergyDifference() != simTrigger.getStateEnergyDifference()) { - return false; - } - - // Check pair energy slope. - if(bankTrigger.passCutEnergySlope() != simTrigger.getStateEnergySlope()) { - return false; - } - - // Check pair coplanarity. - if(bankTrigger.passCutCoplanarity() != simTrigger.getStateCoplanarity()) { - return false; - } - - // If all of the tests are successful, the triggers match. - return true; } /** Modified: java/branches/prod/analysis/src/main/java/org/hps/analysis/trigger/event/ClusterMatchEvent.java ============================================================================= --- java/branches/prod/analysis/src/main/java/org/hps/analysis/trigger/event/ClusterMatchEvent.java (original) +++ java/branches/prod/analysis/src/main/java/org/hps/analysis/trigger/event/ClusterMatchEvent.java Wed Mar 25 14:43:27 2015 @@ -3,7 +3,7 @@ import java.util.ArrayList; import java.util.List; -import org.hps.readout.ecal.triggerbank.SSPCluster; +import org.hps.recon.ecal.triggerbank.SSPCluster; import org.hps.analysis.trigger.util.TriggerDiagnosticUtil; import org.lcsim.event.Cluster; @@ -21,6 +21,7 @@ private int failPosition = 0; private int failEnergy = 0; private int failHitCount = 0; + private int failTime = 0; // Store all of the pairs. private List<ClusterMatchedPair> pairList = new ArrayList<ClusterMatchedPair>(); @@ -46,6 +47,7 @@ if(cmp.isPositionFailState()) { failPosition++; } if(cmp.isEnergyFailState()) { failEnergy++; } if(cmp.isHitCountFailState()) { failHitCount++; } + if(cmp.isTimeFailState()) { failTime++; } } } @@ -100,6 +102,26 @@ } /** + * 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; + } + + /** + * 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); + } + + /** * Adds a reconstructed/SSP cluster pair and marks it as having an * energy fail state. * @param reconCluster - The reconstructed cluster. @@ -134,6 +156,17 @@ /** * 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) { + failTime++; + 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. Modified: java/branches/prod/analysis/src/main/java/org/hps/analysis/trigger/event/ClusterMatchStatus.java ============================================================================= --- java/branches/prod/analysis/src/main/java/org/hps/analysis/trigger/event/ClusterMatchStatus.java (original) +++ java/branches/prod/analysis/src/main/java/org/hps/analysis/trigger/event/ClusterMatchStatus.java Wed Mar 25 14:43:27 2015 @@ -1,12 +1,8 @@ package org.hps.analysis.trigger.event; -import java.awt.Point; -import java.util.HashMap; import java.util.List; -import java.util.Map; -import org.hps.analysis.trigger.util.TriggerDiagnosticUtil; -import org.hps.readout.ecal.triggerbank.SSPCluster; +import org.hps.recon.ecal.triggerbank.SSPCluster; import org.lcsim.event.Cluster; /** @@ -16,27 +12,6 @@ * @author Kyle McCarty */ public class ClusterMatchStatus extends ClusterStatModule { - // Plot binning values. - private static final int TIME_BIN = 4; - private static final double ENERGY_BIN = 0.01; - private static final int TIME_BIN_HALF = TIME_BIN / 2; - private static final double ENERGY_BIN_HALF = ENERGY_BIN / 2; - - // Track plotting values for reconstructed and SSP clusters. - private Map<Integer, Integer> sspHitCountBins = new HashMap<Integer, Integer>(); - private Map<Integer, Integer> reconHitCountBins = new HashMap<Integer, Integer>(); - private Map<Point, Integer> sspPositionBins = new HashMap<Point, Integer>(); - private Map<Point, Integer> reconPositionBins = new HashMap<Point, Integer>(); - private Map<Integer, Integer> sspEnergyBins = new HashMap<Integer, Integer>(); - private Map<Integer, Integer> reconEnergyBins = new HashMap<Integer, Integer>(); - - // Track plotting values for cluster matching results. - private Map<Point, Integer> failPositionBins = new HashMap<Point, Integer>(); - private Map<Point, Integer> allHenergyBins = new HashMap<Point, Integer>(); - private Map<Point, Integer> failHenergyBins = new HashMap<Point, Integer>(); - private Map<Integer, Integer> allTimeBins = new HashMap<Integer, Integer>(); - private Map<Integer, Integer> failTimeBins = new HashMap<Integer, Integer>(); - public void addEvent(ClusterMatchEvent event, List<Cluster> reconClusters, List<SSPCluster> sspClusters) { // Update the number of reconstructed and SSP clusters // that have been seen so far. @@ -57,91 +32,6 @@ if(sspClusters == null || sspClusters.isEmpty()) { failPosition += (reconClusters == null ? 0 : reconClusters.size()); } - - // Update the plotting information for reconstructed clusters. - for(Cluster cluster : reconClusters) { - // Update the hit count bin data. - Integer hitCountCount = reconHitCountBins.get(cluster.getCalorimeterHits().size()); - if(hitCountCount == null) { reconHitCountBins.put(cluster.getCalorimeterHits().size(), 1); } - else { reconHitCountBins.put(cluster.getCalorimeterHits().size(), hitCountCount + 1); } - - // Update the position bin data. - Point clusterPosition = TriggerDiagnosticUtil.getClusterPosition(cluster); - Integer positionCount = reconPositionBins.get(clusterPosition); - if(positionCount == null) { reconPositionBins.put(clusterPosition, 1); } - else { reconPositionBins.put(clusterPosition, positionCount + 1); } - - // Update the energy bin data. - int energyBin = (int) Math.floor(cluster.getEnergy() / ENERGY_BIN); - Integer energyCount = reconEnergyBins.get(energyBin); - if(energyCount == null) { reconEnergyBins.put(energyBin, 1); } - else { reconEnergyBins.put(energyBin, energyCount + 1); } - } - - // Update the plotting information for SSP clusters. - for(SSPCluster cluster : sspClusters) { - // Update the hit count bin data. - Integer hitCountCount = sspHitCountBins.get(cluster.getHitCount()); - if(hitCountCount == null) { sspHitCountBins.put(cluster.getHitCount(), 1); } - else { sspHitCountBins.put(cluster.getHitCount(), hitCountCount + 1); } - - // Update the position bin data. - Point clusterPosition = TriggerDiagnosticUtil.getClusterPosition(cluster); - Integer positionCount = sspPositionBins.get(clusterPosition); - if(positionCount == null) { sspPositionBins.put(clusterPosition, 1); } - else { sspPositionBins.put(clusterPosition, positionCount + 1); } - - // Update the energy bin data. - int energyBin = (int) Math.floor(cluster.getEnergy() / ENERGY_BIN); - Integer energyCount = sspEnergyBins.get(energyBin); - if(energyCount == null) { sspEnergyBins.put(energyBin, 1); } - else { sspEnergyBins.put(energyBin, energyCount + 1); } - } - - // Update the plotting information for SSP/reconstructed cluster - // pairs. - pairLoop: - for(ClusterMatchedPair pair : event.getMatchedPairs()) { - // If one of the pairs is null, then it is unmatched cluster - // and may be skipped. - if(pair.getReconstructedCluster() == null || pair.getSSPCluster() == null) { - continue pairLoop; - } - - // Populate the bins for the "all" plots. - // Update the match time plots. - int timeBin = (int) Math.floor(TriggerDiagnosticUtil.getClusterTime(pair.getReconstructedCluster()) / TIME_BIN); - Integer timeCount = allTimeBins.get(timeBin); - if(timeCount == null) { allTimeBins.put(timeBin, 1); } - else { allTimeBins.put(timeBin, timeCount + 1); } - - // Update the energy/hit difference plots. - int hitBin = getHitCountDifference(pair.getSSPCluster(), pair.getReconstructedCluster()); - int energyBin = (int) Math.floor(getEnergyPercentDifference(pair.getSSPCluster(), pair.getReconstructedCluster()) / ENERGY_BIN); - Point henergyBin = new Point(hitBin, energyBin); - Integer henergyCount = allHenergyBins.get(henergyBin); - if(henergyCount == null) { allHenergyBins.put(henergyBin, 1); } - else { allHenergyBins.put(henergyBin, henergyCount + 1); } - - // Populate the bins for the "fail" plots. - if(!pair.isMatch()) { - // Update the failed cluster position bins. - Point clusterPosition = TriggerDiagnosticUtil.getClusterPosition(pair.getReconstructedCluster()); - Integer positionCount = failPositionBins.get(clusterPosition); - if(positionCount == null) { failPositionBins.put(clusterPosition, 1); } - else { failPositionBins.put(clusterPosition, positionCount + 1); } - - // Update the failed match time plots. - timeCount = failTimeBins.get(timeBin); - if(timeCount == null) { failTimeBins.put(timeBin, 1); } - else { failTimeBins.put(timeBin, timeCount + 1); } - - // Update the failed energy/hit difference plots. - henergyCount = failHenergyBins.get(henergyBin); - if(henergyCount == null) { failHenergyBins.put(henergyBin, 1); } - else { failHenergyBins.put(henergyBin, henergyCount + 1); } - } - } } /** @@ -150,21 +40,7 @@ */ @Override public void clear() { - // Clear statistical data. super.clear(); - - // Clear plot collections. - sspHitCountBins.clear(); - reconHitCountBins.clear(); - sspPositionBins.clear(); - reconPositionBins.clear(); - sspEnergyBins.clear(); - reconEnergyBins.clear(); - failPositionBins.clear(); - allHenergyBins.clear(); - failHenergyBins.clear(); - allTimeBins.clear(); - failTimeBins.clear(); } /** @@ -175,26 +51,4 @@ public ClusterStatModule cloneStatModule() { return new ClusterStatModule(this); } - - /** - * Solves the equation <code>|E_ssp / E_recon|</code>. - * @param sspCluster - The SSP cluster. - * @param reconCluster - The reconstructed cluster. - * @return Returns the solution to the equation as a <code>double - * </code> primitive. - */ - private static final double getEnergyPercentDifference(SSPCluster sspCluster, Cluster reconCluster) { - return Math.abs((sspCluster.getEnergy() / reconCluster.getEnergy())); - } - - /** - * Gets the difference in hit count between an SSP cluster and a - * reconstructed cluster. - * @param sspCluster - The SSP cluster. - * @param reconCluster - The reconstructed cluster. - * @return Returns the difference as an <code>int</code> primitive. - */ - private static final int getHitCountDifference(SSPCluster sspCluster, Cluster reconCluster) { - return sspCluster.getHitCount() - TriggerDiagnosticUtil.getHitCount(reconCluster); - } } Modified: java/branches/prod/analysis/src/main/java/org/hps/analysis/trigger/event/ClusterMatchedPair.java ============================================================================= --- java/branches/prod/analysis/src/main/java/org/hps/analysis/trigger/event/ClusterMatchedPair.java (original) +++ java/branches/prod/analysis/src/main/java/org/hps/analysis/trigger/event/ClusterMatchedPair.java Wed Mar 25 14:43:27 2015 @@ -2,7 +2,7 @@ import org.hps.analysis.trigger.util.Pair; import org.hps.analysis.trigger.util.TriggerDiagnosticUtil; -import org.hps.readout.ecal.triggerbank.SSPCluster; +import org.hps.recon.ecal.triggerbank.SSPCluster; import org.lcsim.event.Cluster; /** @@ -97,13 +97,23 @@ } /** - * Indicates whether the recon/SSP pair failed to match due to a - * the cluster positions not aligning. + * 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); } /** Modified: java/branches/prod/analysis/src/main/java/org/hps/analysis/trigger/event/TriggerEfficiencyModule.java ============================================================================= --- java/branches/prod/analysis/src/main/java/org/hps/analysis/trigger/event/TriggerEfficiencyModule.java (original) +++ java/branches/prod/analysis/src/main/java/org/hps/analysis/trigger/event/TriggerEfficiencyModule.java Wed Mar 25 14:43:27 2015 @@ -6,7 +6,7 @@ import org.hps.analysis.trigger.util.Pair; import org.hps.analysis.trigger.util.PairTrigger; import org.hps.analysis.trigger.util.SinglesTrigger; -import org.hps.readout.ecal.triggerbank.SSPNumberedTrigger; +import org.hps.recon.ecal.triggerbank.SSPNumberedTrigger; import org.hps.analysis.trigger.util.Trigger; import org.hps.analysis.trigger.util.TriggerDiagnosticUtil; Modified: java/branches/prod/analysis/src/main/java/org/hps/analysis/trigger/event/TriggerMatchEvent.java ============================================================================= --- java/branches/prod/analysis/src/main/java/org/hps/analysis/trigger/event/TriggerMatchEvent.java (original) +++ java/branches/prod/analysis/src/main/java/org/hps/analysis/trigger/event/TriggerMatchEvent.java Wed Mar 25 14:43:27 2015 @@ -5,7 +5,7 @@ import org.hps.analysis.trigger.util.Pair; import org.hps.analysis.trigger.util.Trigger; -import org.hps.readout.ecal.triggerbank.SSPNumberedTrigger; +import org.hps.recon.ecal.triggerbank.SSPNumberedTrigger; /** * Tracks trigger pairs that were matched within an event. This can also @@ -19,10 +19,14 @@ private int[] sspInternalMatched = new int[2]; private int[] reconTriggersMatched = new int[2]; private int[][] triggerComp = new int[4][2]; + private int[] unmatchedTriggers = new int[2]; // Track the matched trigger pairs. private List<TriggerMatchedPair> sspPairList = new ArrayList<TriggerMatchedPair>(); private List<Pair<Trigger<?>, SSPNumberedTrigger>> reconPairList = new ArrayList<Pair<Trigger<?>, SSPNumberedTrigger>>(); + + // Track whether the event triggering type was seen. + private boolean sawEventType = false; /** * Gets the number of times a cut of the given cut ID failed when @@ -34,7 +38,7 @@ */ public int getCutFailures(int triggerNumber, int cutID) { // Validate the arguments. - if(triggerNumber !=0 && triggerNumber != 1) { + if(triggerNumber != 0 && triggerNumber != 1) { throw new IndexOutOfBoundsException("Trigger number must be 0 or 1."); } if(cutID < 0 || cutID > 3) { throw new IndexOutOfBoundsException(String.format("Cut ID \"%d\" is not valid.", cutID)); @@ -45,12 +49,29 @@ } /** + * Gets the number of triggers for this trigger for which there + * were no matches. + * @param triggerNum - The trigger for which to get the value. + * @return Returns the number of triggers that failed to match as + * an <code>int</code>. + */ + public int getUnmatchedTriggers(int triggerNum) { + // Validate the arguments. + if(triggerNum != 0 && triggerNum != 1) { + throw new IndexOutOfBoundsException("Trigger number must be 0 or 1."); + } + + // Return the requested cut value. + return unmatchedTriggers[triggerNum]; + } + + /** * Gets the number of reconstructed cluster triggers that were * matched successfully. * @return Returns the value as an <code>int</code> primitive. */ public int getMatchedReconTriggers() { - return reconPairList.size(); + return reconTriggersMatched[0] + reconTriggersMatched[1]; } /** @@ -61,7 +82,7 @@ */ public int getMatchedReconTriggers(int triggerNumber) { // Validate the arguments. - if(triggerNumber !=0 && triggerNumber != 1) { + if(triggerNumber != 0 && triggerNumber != 1) { throw new IndexOutOfBoundsException("Trigger number must be 0 or 1."); } @@ -75,7 +96,7 @@ * @return Returns the value as an <code>int</code> primitive. */ public int getMatchedSSPTriggers() { - return sspPairList.size(); + return sspInternalMatched[0] + sspInternalMatched[1]; } /** @@ -86,7 +107,7 @@ */ public int getMatchedSSPTriggers(int triggerNumber) { // Validate the arguments. - if(triggerNumber !=0 && triggerNumber != 1) { + if(triggerNumber != 0 && triggerNumber != 1) { throw new IndexOutOfBoundsException("Trigger number must be 0 or 1."); } @@ -122,12 +143,8 @@ * @param sspTrigger - The SSP bank trigger. */ public void matchedSSPPair(Trigger<?> simTrigger, SSPNumberedTrigger sspTrigger) { - // A null SSP trigger means that no match was found. This is - // treated as a failure due to time, which is not tracked. - if(sspTrigger != null) { - sspInternalMatched[sspTrigger.isFirstTrigger() ? 0 : 1]++; - sspPairList.add(new TriggerMatchedPair(simTrigger, sspTrigger, new boolean[] { true, true, true, true })); - } + sspInternalMatched[sspTrigger.isFirstTrigger() ? 0 : 1]++; + sspPairList.add(new TriggerMatchedPair(simTrigger, sspTrigger, new boolean[] { true, true, true, true })); } /** @@ -139,28 +156,31 @@ * which did not. */ public void matchedSSPPair(Trigger<?> simTrigger, SSPNumberedTrigger sspTrigger, boolean[] cutsMatched) { - // Store the full cut array. - boolean[] cutArray = cutsMatched; - - // If the array is size 3, it is the a singles trigger. Update - // it to an array of size 4 for compatibility. - if(cutsMatched.length == 3) { - boolean[] tempArray = { true, true, true, true }; - for(int cutIndex = 0; cutIndex < cutsMatched.length; cutIndex++) { - tempArray[cutIndex] = cutsMatched[cutIndex]; - } - cutArray = tempArray; + // The cut values must be stored in an array of size four, but + // singles triggers use arrays of size 3. If the array is not + // of the appropriate size, resize it. + boolean[] cutArray; + if(cutsMatched == null) { + cutArray = new boolean[] { false, false, false, false }; + } else if(cutsMatched.length == 4) { + cutArray = cutsMatched; + } else { + cutArray = new boolean[] { cutsMatched[0], cutsMatched[1], cutsMatched[2], true }; } // Add the trigger pair to the list. TriggerMatchedPair triggerPair = new TriggerMatchedPair(simTrigger, sspTrigger, cutArray); sspPairList.add(triggerPair); + // If the argument cut array was null, then this trigger was + // not actually matched. Track this. + int triggerNum = triggerPair.isFirstTrigger() ? 0 : 1; + if(cutsMatched == null) { unmatchedTriggers[triggerNum]++; } + // Track which cuts have failed. boolean isMatched = true; - int triggerNum = triggerPair.isFirstTrigger() ? 0 : 1; - for(int cutIndex = 0; cutIndex < cutsMatched.length; cutIndex++) { - if(!cutsMatched[cutIndex]) { + for(int cutIndex = 0; cutIndex < cutArray.length; cutIndex++) { + if(!cutArray[cutIndex]) { triggerComp[cutIndex][triggerNum]++; isMatched = false; } @@ -169,4 +189,24 @@ // If all the cuts are true, then the trigger pair is a match. if(isMatched) { sspInternalMatched[triggerNum]++; } } + + /** + * Indicates whether an event of the type that caused the event + * readout was seen. + * @return Returns <code>true</code> if an event was seen and + * <code>false</code> otherwise. + */ + public boolean sawEventType() { + return sawEventType; + } + + /** + * Sets whether a simulated trigger of the type that caused the + * event readout was seen. + * @param state - <code>true</code> indicates that the trigger type + * was seen and <code>false</code> that it was not. + */ + public void setSawEventType(boolean state) { + sawEventType = state; + } } Modified: java/branches/prod/analysis/src/main/java/org/hps/analysis/trigger/event/TriggerMatchStatus.java ============================================================================= --- java/branches/prod/analysis/src/main/java/org/hps/analysis/trigger/event/TriggerMatchStatus.java (original) +++ java/branches/prod/analysis/src/main/java/org/hps/analysis/trigger/event/TriggerMatchStatus.java Wed Mar 25 14:43:27 2015 @@ -3,7 +3,8 @@ import java.util.List; import org.hps.analysis.trigger.util.Trigger; -import org.hps.readout.ecal.triggerbank.SSPNumberedTrigger; +import org.hps.analysis.trigger.util.TriggerDiagnosticUtil; +import org.hps.recon.ecal.triggerbank.SSPNumberedTrigger; /** * Tracks the trigger diagnostic statistics for trigger matching. @@ -11,6 +12,10 @@ * @author Kyle McCarty <[log in to unmask]> */ public class TriggerMatchStatus extends TriggerStatModule { + // Track the number of triggers seen. + private int[] sspTriggersSeen = new int[2]; + private int[] reconTriggersSeen = new int[2]; + /** * Adds the statistical data stored in a trigger comparison event * into this status tracking module. @@ -19,8 +24,15 @@ * @param sspSimTriggers - A list of simulated SSP cluster triggers. * @param sspBankTriggers - A list of SSP bank triggers. */ - public void addEvent(TriggerMatchEvent event, List<List<? extends Trigger<?>>> reconTriggers, + public void addEvent(int eventType, TriggerMatchEvent event, List<List<? extends Trigger<?>>> reconTriggers, List<List<? extends Trigger<?>>> sspSimTriggers, List<? extends SSPNumberedTrigger> sspBankTriggers) { + // Increment the event type count. + if(eventType == TriggerDiagnosticUtil.TRIGGER_SINGLES_1 || eventType == TriggerDiagnosticUtil.TRIGGER_PAIR_1) { + triggerTypesSeen[0]++; + } else if(eventType == TriggerDiagnosticUtil.TRIGGER_SINGLES_2 || eventType == TriggerDiagnosticUtil.TRIGGER_PAIR_2) { + triggerTypesSeen[1]++; + } + // Check if there are more bank triggers than there are // simulated SSP triggers. int sspTriggerDiff = sspBankTriggers.size() - sspSimTriggers.size(); @@ -34,8 +46,16 @@ this.reconTriggers += reconTriggers.get(0).size() + reconTriggers.get(1).size(); reportedTriggers += sspBankTriggers.size(); + // Fill the specific trigger counters. + for(int triggerNum = 0; triggerNum < 2; triggerNum++) { + sspTriggersSeen[triggerNum] += sspSimTriggers.get(triggerNum).size(); + reconTriggersSeen[triggerNum] += reconTriggers.get(triggerNum).size(); + } + // Increment the count for each cut failure type. for(int triggerNum = 0; triggerNum < 2; triggerNum++) { + unmatchedTriggers[triggerNum] += event.getUnmatchedTriggers(triggerNum); + for(int cutIndex = 0; cutIndex < 4; cutIndex++) { triggerComp[cutIndex][triggerNum] += event.getCutFailures(triggerNum, cutIndex); } @@ -45,6 +65,16 @@ for(int triggerNum = 0; triggerNum < 2; triggerNum++) { sspInternalMatched[triggerNum] += event.getMatchedSSPTriggers(triggerNum); reconTriggersMatched[triggerNum] += event.getMatchedReconTriggers(triggerNum); + } + + // Check if a trigger of the right time was found. + // Get the trigger number and type. + if(event.sawEventType()) { + if(eventType == TriggerDiagnosticUtil.TRIGGER_SINGLES_1 || eventType == TriggerDiagnosticUtil.TRIGGER_PAIR_1) { + triggerTypesFound[0]++; + } else if(eventType == TriggerDiagnosticUtil.TRIGGER_SINGLES_2 || eventType == TriggerDiagnosticUtil.TRIGGER_PAIR_2) { + triggerTypesFound[1]++; + } } } @@ -62,4 +92,52 @@ public TriggerStatModule cloneStatModule() { return new TriggerStatModule(this); } + + /** + * Gets the number of reconstructed triggers seen for a specific + * trigger number. + * @param triggerNum - The trigger number. + * @return Returns the total number of reconstructed triggers seen + * by the indicated trigger number. + */ + public int getTotalReconTriggers(int triggerNum) { + return getSSPTriggerCount(false, triggerNum); + } + + /** + * Gets the number of SSP bank triggers seen for a specific trigger + * number. + * @param triggerNum - The trigger number. + * @return Returns the total number of SSP bank triggers seen by + * the indicated trigger number. + */ + public int getTotalSSPTriggers(int triggerNum) { + return getSSPTriggerCount(true, triggerNum); + } + + /** + * Gets the total number of triggers seen for a specific trigger + * source type and number. + * @param isSSP - Whether the trigger source is SSP bank clusters. + * @param triggerNum - The trigger number. + * @return Returns the trigger count. + */ + private final int getSSPTriggerCount(boolean isSSP, int triggerNum) { + // Make sure the trigger number is valid. + validateTriggerNumber(triggerNum); + + // Return the triggers. + if(isSSP) { return sspTriggersSeen[triggerNum]; } + else { return reconTriggersSeen[triggerNum]; } + } + + /** + * Produces an exception if the trigger number argument is invalid. + * @param triggerNum - The trigger number to validate. + */ + private static final void validateTriggerNumber(int triggerNum) { + if(triggerNum < 0 || triggerNum > 2) { + throw new IndexOutOfBoundsException(String.format("Trigger number \"%d\" is invalid", triggerNum)); + } + } } Modified: java/branches/prod/analysis/src/main/java/org/hps/analysis/trigger/event/TriggerMatchedPair.java ============================================================================= --- java/branches/prod/analysis/src/main/java/org/hps/analysis/trigger/event/TriggerMatchedPair.java (original) +++ java/branches/prod/analysis/src/main/java/org/hps/analysis/trigger/event/TriggerMatchedPair.java Wed Mar 25 14:43:27 2015 @@ -4,9 +4,9 @@ import org.hps.analysis.trigger.util.PairTrigger; import org.hps.analysis.trigger.util.SinglesTrigger; import org.hps.analysis.trigger.util.Trigger; -import org.hps.readout.ecal.triggerbank.SSPNumberedTrigger; -import org.hps.readout.ecal.triggerbank.SSPPairTrigger; -import org.hps.readout.ecal.triggerbank.SSPSinglesTrigger; +import org.hps.recon.ecal.triggerbank.SSPNumberedTrigger; +import org.hps.recon.ecal.triggerbank.SSPPairTrigger; +import org.hps.recon.ecal.triggerbank.SSPSinglesTrigger; /** * Stores a pair of one simulated trigger and one SSP bank trigger that @@ -80,7 +80,11 @@ * object. */ public Class<?> getSimulatedTriggerType() { - return getFirstElement().getTriggerSource().getClass(); + if(getFirstElement() != null) { + return getFirstElement().getTriggerSource().getClass(); + } else { + return null; + } } /** @@ -99,7 +103,11 @@ * first trigger and <code>false</code> otherwise. */ public boolean isFirstTrigger() { - return getSecondElement().isFirstTrigger(); + if(getSecondElement() != null) { + return getSecondElement().isFirstTrigger(); + } else { + return getFirstElement().getTriggerNumber() == 0 ? true : false; + } } /** @@ -108,7 +116,7 @@ * triggers and <code>false</code> otherwise. */ public boolean isPairTrigger() { - if(getFirstElement() instanceof PairTrigger && getSecondElement() instanceof SSPPairTrigger) { + if(getFirstElement() instanceof PairTrigger || getSecondElement() instanceof SSPPairTrigger) { return true; } else { return false; @@ -122,7 +130,7 @@ * second trigger and <code>false</code> otherwise. */ public boolean isSecondTrigger() { - return getSecondElement().isSecondTrigger(); + return !isFirstTrigger(); } /** @@ -131,7 +139,7 @@ * triggers and <code>false</code> otherwise. */ public boolean isSinglesTrigger() { - if(getFirstElement() instanceof SinglesTrigger && getSecondElement() instanceof SSPSinglesTrigger) { + if(getFirstElement() instanceof SinglesTrigger || getSecondElement() instanceof SSPSinglesTrigger) { return true; } else { return false; Modified: java/branches/prod/analysis/src/main/java/org/hps/analysis/trigger/event/TriggerStatModule.java ============================================================================= --- java/branches/prod/analysis/src/main/java/org/hps/analysis/trigger/event/TriggerStatModule.java (original) +++ java/branches/prod/analysis/src/main/java/org/hps/analysis/trigger/event/TriggerStatModule.java Wed Mar 25 14:43:27 2015 @@ -15,7 +15,9 @@ protected int[] sspInternalMatched = new int[2]; protected int[] reconTriggersMatched = new int[2]; protected int[][] triggerComp = new int[4][2]; - + protected int[] unmatchedTriggers = new int[2]; + protected int[] triggerTypesSeen = new int[2]; + protected int[] triggerTypesFound = new int[2]; /** * Instantiates a <code>TriggerStatModule</code> with no statistics @@ -40,6 +42,13 @@ for(int i = 0; i < reconTriggersMatched.length; i++) { reconTriggersMatched[i] = base.reconTriggersMatched[i]; } + for(int i = 0; i < triggerTypesSeen.length; i++) { + triggerTypesSeen[i] = base.triggerTypesSeen[i]; + triggerTypesFound[i] = base.triggerTypesFound[i]; + } + for(int i = 0; i < unmatchedTriggers.length; i++) { + unmatchedTriggers[i] = base.unmatchedTriggers[i]; + } for(int i = 0; i < triggerComp.length; i++) { for(int j = 0; j < triggerComp[i].length; j++) { triggerComp[i][j] = base.triggerComp[i][j]; @@ -82,6 +91,40 @@ } /** + * Gets the number of events that were readout due to a trigger + * of the indicated type. + * @param triggerType - The type of trigger. + * @return Returns the number of events readout because of the + * trigger type as an <code>int</code>. + */ + public int getEventsOfType(int triggerNum) { + // Make sure that the trigger type is defined. + if(triggerNum < 0 || triggerNum > 1) { + throw new IndexOutOfBoundsException(String.format("Trigger number \"%d\" is not valid.", triggerNum)); + } + + // Return the number of events that were trigger by this type. + return triggerTypesSeen[triggerNum]; + } + + /** + * Gets the number of events that were readout due to a trigger + * of the indicated type where a reconstructed cluster simulated + * trigger of that type existed. + * @param triggerType - The type of trigger. + * @return Returns the number of events as an <code>int</code>. + */ + public int getEventsOfTypeSeen(int triggerNum) { + // Make sure that the trigger type is defined. + if(triggerNum < 0 || triggerNum > 1) { + throw new IndexOutOfBoundsException(String.format("Trigger number \"%d\" is not valid.", triggerNum)); + } + + // Return the number of events that were trigger by this type. + return triggerTypesFound[triggerNum]; + } + + /** * Gets the number of SSP bank triggers that were reported in excess * of the number of simulated SSP triggers seen. * @return Returns the value as an <code>int</code> primitive. @@ -163,4 +206,21 @@ public int getSSPBankTriggerCount() { return reportedTriggers; } + + /** + * Gets the number of triggers for this trigger for which there + * were no matches. + * @param triggerNum - The trigger for which to get the value. + * @return Returns the number of triggers that failed to match as + * an <code>int</code>. + */ + public int getUnmatchedTriggers(int triggerNum) { + // Validate the arguments. + if(triggerNum != 0 && triggerNum != 1) { + throw new IndexOutOfBoundsException("Trigger number must be 0 or 1."); + } + + // Return the requested cut value. + return unmatchedTriggers[triggerNum]; + } } Modified: java/branches/prod/analysis/src/main/java/org/hps/analysis/trigger/util/PairTrigger.java ============================================================================= --- java/branches/prod/analysis/src/main/java/org/hps/analysis/trigger/util/PairTrigger.java (original) +++ java/branches/prod/analysis/src/main/java/org/hps/analysis/trigger/util/PairTrigger.java Wed Mar 25 14:43:27 2015 @@ -1,6 +1,6 @@ package org.hps.analysis.trigger.util; -import org.hps.readout.ecal.TriggerModule; +import org.hps.recon.ecal.triggerbank.TriggerModule; public class PairTrigger<E> extends SinglesTrigger<E> { // Define the supported trigger cuts. @@ -65,7 +65,7 @@ * <code>false</code> otherwise. */ public boolean getStateEnergyDifference() { - return getCutState(PAIR_ENERGY_SUM_HIGH); + return getCutState(PAIR_ENERGY_DIFFERENCE_HIGH); } /** Modified: java/branches/prod/analysis/src/main/java/org/hps/analysis/trigger/util/SinglesTrigger.java ============================================================================= --- java/branches/prod/analysis/src/main/java/org/hps/analysis/trigger/util/SinglesTrigger.java (original) +++ java/branches/prod/analysis/src/main/java/org/hps/analysis/trigger/util/SinglesTrigger.java Wed Mar 25 14:43:27 2015 @@ -1,6 +1,6 @@ package org.hps.analysis.trigger.util; -import org.hps.readout.ecal.TriggerModule; +import org.hps.recon.ecal.triggerbank.TriggerModule; public class SinglesTrigger<E> extends Trigger<E> { // Define the supported trigger cuts. Modified: java/branches/prod/analysis/src/main/java/org/hps/analysis/trigger/util/TriggerDiagnosticUtil.java ============================================================================= --- java/branches/prod/analysis/src/main/java/org/hps/analysis/trigger/util/TriggerDiagnosticUtil.java (original) +++ java/branches/prod/analysis/src/main/java/org/hps/analysis/trigger/util/TriggerDiagnosticUtil.java Wed Mar 25 14:43:27 2015 @@ -2,7 +2,7 @@ import java.awt.Point; -import org.hps.readout.ecal.triggerbank.SSPCluster; +import org.hps.recon.ecal.triggerbank.SSPCluster; import org.lcsim.event.CalorimeterHit; import org.lcsim.event.Cluster; @@ -19,7 +19,8 @@ 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_UNKNOWN = 4; + 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; Modified: java/branches/prod/conditions/src/main/java/org/hps/conditions/api/AbstractConditionsObjectCollection.java ============================================================================= --- java/branches/prod/conditions/src/main/java/org/hps/conditions/api/AbstractConditionsObjectCollection.java (original) +++ java/branches/prod/conditions/src/main/java/org/hps/conditions/api/AbstractConditionsObjectCollection.java Wed Mar 25 14:43:27 2015 @@ -8,6 +8,7 @@ import java.util.LinkedHashSet; import java.util.List; +import org.hps.conditions.api.ConditionsObject.DefaultConditionsObjectComparator; import org.hps.conditions.database.DatabaseConditionsManager; import org.hps.conditions.database.TableMetaData; @@ -201,7 +202,37 @@ * @param comparator The comparator to use for the sort. * @return A sorted list of the objects. */ + @SuppressWarnings("unchecked") public AbstractConditionsObjectCollection<ObjectType> sorted(Comparator<ObjectType> comparator) { - throw new UnsupportedOperationException("This method is not implemented."); + List<ObjectType> objects = new ArrayList<ObjectType>(this); + Collections.sort(objects, comparator); + AbstractConditionsObjectCollection<ObjectType> collection = null; + try { + collection = (AbstractConditionsObjectCollection<ObjectType>) getClass().newInstance(); + } catch (InstantiationException | IllegalAccessException e) { + throw new RuntimeException(e); + } + collection.addAll(objects); + return collection; + } + + public void sort() { + AbstractConditionsObjectCollection<ObjectType> sortedCollection = sorted(); + this.clear(); + this.addAll(sortedCollection); + } + + public AbstractConditionsObjectCollection<ObjectType> sorted() { + List<ObjectType> objects = new ArrayList<ObjectType>(this); + Collections.sort(objects, new DefaultConditionsObjectComparator()); + AbstractConditionsObjectCollection<ObjectType> collection = null; + try { + // FIXME: This is kind of ugly. + collection = (AbstractConditionsObjectCollection<ObjectType>) getClass().newInstance(); + } catch (InstantiationException | IllegalAccessException e) { + throw new RuntimeException(e); + } + collection.addAll(objects); + return collection; } } Modified: java/branches/prod/conditions/src/main/java/org/hps/conditions/api/ConditionsObject.java ============================================================================= --- java/branches/prod/conditions/src/main/java/org/hps/conditions/api/ConditionsObject.java (original) +++ java/branches/prod/conditions/src/main/java/org/hps/conditions/api/ConditionsObject.java Wed Mar 25 14:43:27 2015 @@ -1,4 +1,6 @@ package org.hps.conditions.api; + +import java.util.Comparator; /** * This is an ORM interface for accessing conditions database information by @@ -63,4 +65,16 @@ * @return True if record is new. */ public boolean isNew(); + + static class DefaultConditionsObjectComparator implements Comparator<ConditionsObject> { + public int compare(ConditionsObject o1, ConditionsObject o2) { + if (o1.getRowId() < o2.getRowId()) { + return -1; + } else if (o1.getRowId() > o2.getRowId()) { + return 1; + } else { + return 0; + } + } + } } Modified: java/branches/prod/conditions/src/main/java/org/hps/conditions/api/ConditionsObjectCollection.java ============================================================================= --- java/branches/prod/conditions/src/main/java/org/hps/conditions/api/ConditionsObjectCollection.java (original) +++ java/branches/prod/conditions/src/main/java/org/hps/conditions/api/ConditionsObjectCollection.java Wed Mar 25 14:43:27 2015 @@ -68,4 +68,8 @@ * @return A sorted list of the objects. */ public AbstractConditionsObjectCollection<ObjectType> sorted(Comparator<ObjectType> comparator); + + public void sort(); + + public AbstractConditionsObjectCollection<ObjectType> sorted(); } Modified: java/branches/prod/conditions/src/main/java/org/hps/conditions/database/ConditionsObjectConverter.java ============================================================================= --- java/branches/prod/conditions/src/main/java/org/hps/conditions/database/ConditionsObjectConverter.java (original) +++ java/branches/prod/conditions/src/main/java/org/hps/conditions/database/ConditionsObjectConverter.java Wed Mar 25 14:43:27 2015 @@ -76,6 +76,11 @@ // Get the TableMetaData from the table name. TableMetaData tableMetaData = databaseConditionsManager.findTableMetaData(name); + + // Throw an exception if the table name does not map to a known type. + if (tableMetaData == null) { + throw new RuntimeException(new ConditionsObjectException("No table information found for name: " + name)); + } // Get the ConditionsRecordCollection with the run number assignments. ConditionsRecordCollection conditionsRecords = databaseConditionsManager.findConditionsRecords(name); Modified: java/branches/prod/conditions/src/main/java/org/hps/conditions/database/DatabaseConditionsManager.java ============================================================================= --- java/branches/prod/conditions/src/main/java/org/hps/conditions/database/DatabaseConditionsManager.java (original) +++ java/branches/prod/conditions/src/main/java/org/hps/conditions/database/DatabaseConditionsManager.java Wed Mar 25 14:43:27 2015 @@ -12,8 +12,10 @@ import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map.Entry; +import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; @@ -62,7 +64,7 @@ public final class DatabaseConditionsManager extends ConditionsManagerImplementation { // Initialize logger. - private static Logger logger = LogUtil.create(DatabaseConditionsManager.class.getName(), new DefaultLogFormatter(), Level.INFO); + private static Logger logger = LogUtil.create(DatabaseConditionsManager.class.getName(), new DefaultLogFormatter(), Level.FINE); // Global registry of conditions converters. private ConverterRegistry converters = ConverterRegistry.create(); @@ -131,6 +133,33 @@ registerConditionsConverter(converter); } addConditionsListener(svtSetup); + } + + /** + * Get the static instance of this class. + * @return The static instance of the manager. + */ + public synchronized static DatabaseConditionsManager getInstance() { + + logger.finer("getting conditions manager instance"); + + // Is there no manager installed yet? + if (!ConditionsManager.isSetup() || !(ConditionsManager.defaultInstance() instanceof DatabaseConditionsManager)) { + logger.finer("creating new instance"); + // Create a new instance if necessary, which will install it globally as the default. + new DatabaseConditionsManager(); + } + + // Get the instance back from the default conditions system and check that the type is correct now. + ConditionsManager manager = ConditionsManager.defaultInstance(); + if (!(manager instanceof DatabaseConditionsManager)) { + logger.severe("default conditions manager has wrong type"); + throw new RuntimeException("Default conditions manager has the wrong type: " + ConditionsManager.defaultInstance().getClass().getName()); + } + + logger.finer("returning conditions manager instance"); + + return (DatabaseConditionsManager) manager; } /** @@ -145,35 +174,10 @@ } /** - * Get the static instance of this class. - * @return The static instance of the manager. - */ - public static DatabaseConditionsManager getInstance() { - - logger.fine("setting up new conditions manager instance"); - - // Is there no manager installed yet? - if (!ConditionsManager.isSetup()) { - // Create a new instance if necessary. - new DatabaseConditionsManager(); - } - - // Get the instance back from the default conditions system and check that the type is correct. - ConditionsManager manager = ConditionsManager.defaultInstance(); - if (!(manager instanceof DatabaseConditionsManager)) { - throw new RuntimeException("The default ConditionsManager has the wrong type."); - } - - logger.fine("instance initialized succesfully"); - - return (DatabaseConditionsManager) manager; - } - - /** * Open the database connection. * @return True if a connection was opened; false if using an existing connection. */ - public boolean openConnection() { + public synchronized boolean openConnection() { boolean openedConnection = false; if (!isConnected) { // Do the connection parameters need to be figured out automatically? @@ -207,7 +211,7 @@ /** * Close the database connection. */ - public void closeConnection() { + public synchronized void closeConnection() { logger.fine("closing connection"); if (connection != null) { try { @@ -228,7 +232,7 @@ * based on the flag. Otherwise, it should be left open. * @param connectionOpened True to close the connection; false to leave it open. */ - public void closeConnection(boolean connectionOpened) { + public synchronized void closeConnection(boolean connectionOpened) { if (connectionOpened) { closeConnection(); } @@ -265,7 +269,7 @@ * needs to be updated. */ @Override - public void setDetector(String detectorName, int runNumber) throws ConditionsNotFoundException { + public synchronized void setDetector(String detectorName, int runNumber) throws ConditionsNotFoundException { logger.finest("setDetector " + detectorName + " with run number " + runNumber); @@ -367,7 +371,7 @@ * @param tableName The name of the table. * @return The next collection ID. */ - public int getNextCollectionID(String tableName) { + public synchronized int getNextCollectionID(String tableName) { boolean openedConnection = openConnection(); ResultSet resultSet = selectQuery("SELECT MAX(collection_id)+1 FROM " + tableName); int collectionId = 1; @@ -533,7 +537,7 @@ * This method can be called to "freeze" the conditions system so that * any subsequent updates to run number or detector name will be ignored. */ - public void freeze() { + public synchronized void freeze() { if (getDetector() != null && getRun() != -1) { isFrozen = true; logger.config("conditions system is frozen"); @@ -545,7 +549,7 @@ /** * Un-freeze the conditions system so that updates will be received again. */ - public void unfreeze() { + public synchronized void unfreeze() { isFrozen = false; logger.info("conditions system unfrozen"); } @@ -701,6 +705,39 @@ public boolean isInitialized() { return isInitialized; } + + /** + * Get the set of unique conditions tags from the conditions table. + * @return The list of unique conditions tags. + */ + public Set<String> getTags() { + logger.fine("getting list of available conditions tags"); + boolean openedConnection = openConnection(); + Set<String> tags = new LinkedHashSet<String>(); + ResultSet rs = selectQuery("select distinct(tag) from conditions where tag is not null order by tag"); + try { + while (rs.next()) { + tags.add(rs.getString(1)); + } + } catch (SQLException e) { + throw new RuntimeException(e); + } + try { + rs.close(); + } catch (SQLException e) { + logger.log(Level.WARNING, "error closing ResultSet", e); + } + StringBuffer buffer = new StringBuffer(); + buffer.append("found unique conditions tags ..."); + for (String tag : tags) { + buffer.append(tag + " "); + } + buffer.setLength(buffer.length() - 1); + buffer.append('\n'); + logger.fine(buffer.toString()); + closeConnection(openedConnection); + return tags; + } /* ******************************* @@ -713,7 +750,7 @@ * configuration and loading of conditions onto the Detector. */ private void initialize(String detectorName, int runNumber) throws ConditionsNotFoundException { - + logger.config("initializing with detector " + detectorName + " and run " + runNumber); // Is not configured yet? Modified: java/branches/prod/conditions/src/main/java/org/hps/conditions/database/TableMetaData.java ============================================================================= --- java/branches/prod/conditions/src/main/java/org/hps/conditions/database/TableMetaData.java (original) +++ java/branches/prod/conditions/src/main/java/org/hps/conditions/database/TableMetaData.java Wed Mar 25 14:43:27 2015 @@ -1,12 +1,15 @@ package org.hps.conditions.database; import java.util.ArrayList; +import java.util.HashMap; import java.util.LinkedHashSet; import java.util.List; +import java.util.Map; import java.util.Set; import org.hps.conditions.api.AbstractConditionsObjectCollection; import org.hps.conditions.api.ConditionsObject; +import org.hps.conditions.api.ConditionsObjectCollection; /** * <p> @@ -30,6 +33,7 @@ protected Class<? extends ConditionsObject> objectClass; protected Class<? extends AbstractConditionsObjectCollection<?>> collectionClass; protected Set<String> fieldNames = new LinkedHashSet<String>(); + protected Map<String, Class<?>> fieldTypes; /** * The fully qualified constructor. @@ -37,19 +41,53 @@ * @param objectClass The type of object for the data mapping. * @param collectionClass The type of collection for the data mapping. */ - public TableMetaData(String key, String tableName, Class<? extends ConditionsObject> objectClass, Class<? extends AbstractConditionsObjectCollection<?>> collectionClass) { + /* + public TableMetaData( + String key, + String tableName, + Class<? extends ConditionsObject> objectClass, + Class<? extends AbstractConditionsObjectCollection<?>> collectionClass, + Map<String, Class<?>> fieldTypes) { + this.key = key; this.tableName = tableName; this.objectClass = objectClass; this.collectionClass = collectionClass; + this.fieldTypes = fieldTypes; } + */ - public TableMetaData(String key, String tableName, Class<? extends ConditionsObject> objectClass, Class<? extends AbstractConditionsObjectCollection<?>> collectionClass, Set<String> fieldNames) { + public TableMetaData( + String key, + String tableName, + Class<? extends ConditionsObject> objectClass, + Class<? extends AbstractConditionsObjectCollection<?>> collectionClass, + Set<String> fieldNames, + Map<String, Class<?>> fieldTypes) { + if (key == null) { + throw new IllegalArgumentException("key is null"); + } + if (tableName == null) { + throw new IllegalArgumentException("tableName is null"); + } + if (objectClass == null) { + throw new IllegalArgumentException("objectClass is null"); + } + if (fieldNames == null) { + throw new IllegalArgumentException("fieldNames is null"); + } + if (collectionClass == null) { + throw new IllegalArgumentException("collectionClass is null"); + } + if (fieldTypes == null) { + throw new IllegalArgumentException("fieldTypes is null"); + } this.key = key; this.tableName = tableName; this.objectClass = objectClass; this.collectionClass = collectionClass; this.fieldNames = fieldNames; + this.fieldTypes = fieldTypes; } /** @@ -77,15 +115,11 @@ } /** - * Add a field. - * @param name The name of the field. + * Get the type of the field called <code>fieldName</code>. + * @return The type of the field. */ - void addField(String name) { - fieldNames.add(name); - } - - void addFields(List<String> names) { - fieldNames.addAll(names); + public Class<?> getFieldType(String fieldName) { + return fieldTypes.get(fieldName); } /** @@ -106,15 +140,11 @@ } static public List<TableMetaData> findByObjectType(List<TableMetaData> tableMetaDataList, Class<? extends ConditionsObject> objectType) { - System.out.println("findByObjectType - " + objectType.getCanonicalName()); List<TableMetaData> list = new ArrayList<TableMetaData>(); for (TableMetaData tableMetaData : tableMetaDataList) { - System.out.println("comparing to " + tableMetaData.getObjectClass().getCanonicalName()); if (tableMetaData.getObjectClass().equals(objectType)) { - System.out.println("found match"); + list.add(tableMetaData); - } else { - System.out.println("does not match"); } } return list; Modified: java/branches/prod/conditions/src/main/java/org/hps/conditions/database/TableRegistry.java ============================================================================= --- java/branches/prod/conditions/src/main/java/org/hps/conditions/database/TableRegistry.java (original) +++ java/branches/prod/conditions/src/main/java/org/hps/conditions/database/TableRegistry.java Wed Mar 25 14:43:27 2015 @@ -1,8 +1,11 @@ package org.hps.conditions.database; +import java.lang.annotation.Annotation; +import java.lang.reflect.Method; import java.util.ArrayList; import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Set; import org.hps.conditions.api.AbstractConditionsObjectCollection; @@ -42,13 +45,32 @@ static TableRegistry create() { TableRegistry registry = new TableRegistry(); for (Class<? extends ConditionsObject> objectType : ConditionsObjectUtilities.findConditionsObjectTypes()) { + + // Get the collection type. Class<? extends AbstractConditionsObjectCollection<?>> collectionType = ConditionsObjectUtilities.getCollectionType(objectType); + + // Get the list of field names. Set<String> fieldNames = ConditionsObjectUtilities.getFieldNames(objectType); - for (String name : ConditionsObjectUtilities.getTableNames(objectType)) { - + + // Create map of fields to their types. + Map<String, Class<?>> fieldTypes = new HashMap<String, Class<?>>(); + for (Method method : objectType.getMethods()) { + if (!method.getReturnType().equals(Void.TYPE)) { + for (Annotation annotation : method.getAnnotations()) { + if (annotation.annotationType().equals(Field.class)) { + Field field = (Field) annotation; + for (String fieldName : field.names()) { + fieldTypes.put(fieldName, method.getReturnType()); + } + } + } + } + } + + for (String name : ConditionsObjectUtilities.getTableNames(objectType)) { // Create a meta data mapping for each table name in the class description. - TableMetaData data = new TableMetaData(name, name, objectType, collectionType, fieldNames); + TableMetaData data = new TableMetaData(name, name, objectType, collectionType, fieldNames, fieldTypes); registry.put(name, data); registry.objectTypeMap.add(objectType, data); registry.collectionTypeMap.add(collectionType, data); Modified: java/branches/prod/conditions/src/main/java/org/hps/conditions/ecal/EcalBadChannel.java ============================================================================= --- java/branches/prod/conditions/src/main/java/org/hps/conditions/ecal/EcalBadChannel.java (original) +++ java/branches/prod/conditions/src/main/java/org/hps/conditions/ecal/EcalBadChannel.java Wed Mar 25 14:43:27 2015 @@ -1,4 +1,6 @@ package org.hps.conditions.ecal; + +import java.util.Comparator; import org.hps.conditions.api.AbstractConditionsObject; import org.hps.conditions.api.AbstractConditionsObjectCollection; @@ -16,14 +18,30 @@ public final class EcalBadChannel extends AbstractConditionsObject { public static class EcalBadChannelCollection extends AbstractConditionsObjectCollection<EcalBadChannel> { + + public AbstractConditionsObjectCollection<EcalBadChannel> sorted() { + return sorted(new ChannelIdComparator()); + } + + class ChannelIdComparator implements Comparator<EcalBadChannel> { + public int compare(EcalBadChannel o1, EcalBadChannel o2) { + if (o1.getChannelId() < o2.getChannelId()) { + return -1; + } else if (o1.getChannelId() > o2.getChannelId()) { + return 1; + } else { + return 0; + } + } + } } - + /** - * Get the channel ID of the bad channel. - * @return The channel ID of the bad channel. + * Get the ECAL channel ID. + * @return The ECAL channel ID. */ @Field(names = {"ecal_channel_id"}) public int getChannelId() { - return getFieldValue("ecal_channel_id"); + return getFieldValue("ecal_channel_id"); } -} +} Modified: java/branches/prod/conditions/src/main/java/org/hps/conditions/ecal/EcalCalibration.java ============================================================================= --- java/branches/prod/conditions/src/main/java/org/hps/conditions/ecal/EcalCalibration.java (original) +++ java/branches/prod/conditions/src/main/java/org/hps/conditions/ecal/EcalCalibration.java Wed Mar 25 14:43:27 2015 @@ -1,4 +1,6 @@ package org.hps.conditions.ecal; + +import java.util.Comparator; import org.hps.conditions.api.AbstractConditionsObject; import org.hps.conditions.api.AbstractConditionsObjectCollection; @@ -21,8 +23,24 @@ public final class EcalCalibration extends AbstractConditionsObject { public static class EcalCalibrationCollection extends AbstractConditionsObjectCollection<EcalCalibration> { + + public AbstractConditionsObjectCollection<EcalCalibration> sorted() { + return sorted(new ChannelIdComparator()); + } + + class ChannelIdComparator implements Comparator<EcalCalibration> { + public int compare(EcalCalibration o1, EcalCalibration o2) { + if (o1.getChannelId() < o2.getChannelId()) { + return -1; + } else if (o1.getChannelId() > o2.getChannelId()) { + return 1; + } else { + return 0; + } + } + } } - + public EcalCalibration() { } @@ -33,12 +51,12 @@ } /** - * Get the channel ID. - * @return The channel ID. + * Get the ECAL channel ID. + * @return The ECAL channel ID. */ @Field(names = {"ecal_channel_id"}) public int getChannelId() { - return getFieldValue("ecal_channel_id"); + return getFieldValue("ecal_channel_id"); } /** Modified: java/branches/prod/conditions/src/main/java/org/hps/conditions/ecal/EcalChannel.java ============================================================================= --- java/branches/prod/conditions/src/main/java/org/hps/conditions/ecal/EcalChannel.java (original) +++ java/branches/prod/conditions/src/main/java/org/hps/conditions/ecal/EcalChannel.java Wed Mar 25 14:43:27 2015 @@ -1,10 +1,7 @@ package org.hps.conditions.ecal; -import java.util.ArrayList; -import java.util.Collections; import java.util.Comparator; import java.util.HashMap; -import java.util.List; import java.util.Map; import org.hps.conditions.api.AbstractConditionsObject; @@ -137,20 +134,6 @@ } } - private static final class ChannelIdComparator implements Comparator<EcalChannel> { - - public int compare(EcalChannel c1, EcalChannel c2) { - if (c1.getChannelId() < c2.getChannelId()) { - return -1; - } else if (c1.getChannelId() > c2.getChannelId()) { - return 1; - } else { - return 0; - } - } - - } - DaqId createDaqId() { return new DaqId(new int[] { getCrate(), getSlot(), getChannel() }); } @@ -254,16 +237,22 @@ */ public EcalChannel findDaq(long id) { return daqMap.get(id); - } - - /** - * Get a list of channels sorted by channel ID. - * @return A list of channels sorted by channel ID. - */ - public List<EcalChannel> sortedByChannelId() { - List<EcalChannel> channelList = new ArrayList<EcalChannel>(this); - Collections.sort(channelList, new ChannelIdComparator()); - return channelList; + } + + public AbstractConditionsObjectCollection<EcalChannel> sorted() { + return sorted(new ChannelIdComparator()); + } + + class ChannelIdComparator implements Comparator<EcalChannel> { + public int compare(EcalChannel c1, EcalChannel c2) { + if (c1.getChannelId() < c2.getChannelId()) { + return -1; + } else if (c1.getChannelId() > c2.getChannelId()) { + return 1; + } else { + return 0; + } + } } } Modified: java/branches/prod/conditions/src/main/java/org/hps/conditions/ecal/EcalGain.java ============================================================================= --- java/branches/prod/conditions/src/main/java/org/hps/conditions/ecal/EcalGain.java (original) +++ java/branches/prod/conditions/src/main/java/org/hps/conditions/ecal/EcalGain.java Wed Mar 25 14:43:27 2015 @@ -1,4 +1,6 @@ package org.hps.conditions.ecal; + +import java.util.Comparator; import org.hps.conditions.api.AbstractConditionsObject; import org.hps.conditions.api.AbstractConditionsObjectCollection; @@ -17,8 +19,26 @@ public final class EcalGain extends AbstractConditionsObject { public static class EcalGainCollection extends AbstractConditionsObjectCollection<EcalGain> { + + public AbstractConditionsObjectCollection<EcalGain> sorted() { + return sorted(new ChannelIdComparator()); + } + + class ChannelIdComparator implements Comparator<EcalGain> { + public int compare(EcalGain o1, EcalGain o2) { + if (o1.getChannelId() < o2.getChannelId()) { + return -1; + } else if (o1.getChannelId() > o2.getChannelId()) { + return 1; + } else { + return 0; + } + } + + } } - + + /** * Get the gain value in units of MeV/ADC count. * @return The gain value. Modified: java/branches/prod/conditions/src/main/java/org/hps/conditions/ecal/EcalLed.java ============================================================================= --- java/branches/prod/conditions/src/main/java/org/hps/conditions/ecal/EcalLed.java (original) +++ java/branches/prod/conditions/src/main/java/org/hps/conditions/ecal/EcalLed.java Wed Mar 25 14:43:27 2015 @@ -1,4 +1,6 @@ package org.hps.conditions.ecal; + +import java.util.Comparator; import org.hps.conditions.api.AbstractConditionsObject; import org.hps.conditions.api.AbstractConditionsObjectCollection; @@ -6,6 +8,7 @@ import org.hps.conditions.database.Field; import org.hps.conditions.database.MultipleCollectionsAction; import org.hps.conditions.database.Table; +import org.hps.conditions.ecal.EcalGain.EcalGainCollection.ChannelIdComparator; /** * A conditions class for representing the setup of the LED system in the ECAL @@ -20,6 +23,22 @@ * Generic collection class for these objects. */ public static class EcalLedCollection extends AbstractConditionsObjectCollection<EcalLed> { + public AbstractConditionsObjectCollection<EcalLed> sorted() { + return sorted(new ChannelIdComparator()); + } + + class ChannelIdComparator implements Comparator<EcalLed> { + public int compare(EcalLed o1, EcalLed o2) { + if (o1.getEcalChannelId() < o2.getEcalChannelId()) { + return -1; + } else if (o1.getEcalChannelId() > o2.getEcalChannelId()) { + return 1; + } else { + return 0; + } + } + + } } /** Modified: java/branches/prod/conditions/src/main/java/org/hps/conditions/ecal/EcalLedCalibration.java ============================================================================= --- java/branches/prod/conditions/src/main/java/org/hps/conditions/ecal/EcalLedCalibration.java (original) +++ java/branches/prod/conditions/src/main/java/org/hps/conditions/ecal/EcalLedCalibration.java Wed Mar 25 14:43:27 2015 @@ -15,6 +15,9 @@ * Generic collection class for these objects. */ public static class EcalLedCalibrationCollection extends AbstractConditionsObjectCollection<EcalLedCalibration> { + } + + public EcalLedCalibration() { } public EcalLedCalibration(int channelId, double mean, double rms) { Modified: java/branches/prod/conditions/src/main/java/org/hps/conditions/ecal/EcalTimeShift.java ============================================================================= --- java/branches/prod/conditions/src/main/java/org/hps/conditions/ecal/EcalTimeShift.java (original) +++ java/branches/prod/conditions/src/main/java/org/hps/conditions/ecal/EcalTimeShift.java Wed Mar 25 14:43:27 2015 @@ -1,4 +1,6 @@ package org.hps.conditions.ecal; + +import java.util.Comparator; import org.hps.conditions.api.AbstractConditionsObject; import org.hps.conditions.api.AbstractConditionsObjectCollection; @@ -6,6 +8,7 @@ import org.hps.conditions.database.Field; import org.hps.conditions.database.MultipleCollectionsAction; import org.hps.conditions.database.Table; +import org.hps.conditions.ecal.EcalCalibration.EcalCalibrationCollection.ChannelIdComparator; /** * This class represents a time shift calibration value for an ECAL channel. @@ -19,6 +22,21 @@ * A collection of {@link EcalTimeShift} objects. */ public static class EcalTimeShiftCollection extends AbstractConditionsObjectCollection<EcalTimeShift> { + public AbstractConditionsObjectCollection<EcalTimeShift> sorted() { + return sorted(new ChannelIdComparator()); + } + + class ChannelIdComparator implements Comparator<EcalTimeShift> { + public int compare(EcalTimeShift o1, EcalTimeShift o2) { + if (o1.getChannelId() < o2.getChannelId()) { + return -1; + } else if (o1.getChannelId() > o2.getChannelId()) { + return 1; + } else { + return 0; + } + } + } } /** Modified: java/branches/prod/conditions/src/main/java/org/hps/conditions/svt/AbstractSvtChannel.java ============================================================================= --- java/branches/prod/conditions/src/main/java/org/hps/conditions/svt/AbstractSvtChannel.java (original) +++ java/branches/prod/conditions/src/main/java/org/hps/conditions/svt/AbstractSvtChannel.java Wed Mar 25 14:43:27 2015 @@ -24,10 +24,10 @@ Map<Integer, T> channelMap = new HashMap<Integer, T>(); /** - * Add a channel of type extending {@link AbstractSvtChannel} to the - * channel map + * Add a channel of type extending {@link AbstractSvtChannel} to the + * channel map * - * @param A channel of a type extending {@link AbstractSvtChannel} + * @param A channel of a type extending {@link AbstractSvtChannel} */ public boolean add(T channel) { @@ -42,29 +42,29 @@ } /** - * Find a channel of type extending {@link AbstractSvtChannel} using the - * channel ID + * Find a channel of type extending {@link AbstractSvtChannel} using the + * channel ID * - * @param channelID - * @return An SVT channel of type extending {@link AbstractSvtChannel} + * @param channelID + * @return An SVT channel of type extending {@link AbstractSvtChannel} */ public T findChannel(int channelID) { return channelMap.get(channelID); } /** - * Find the collection of channels of type extending - * {@link AbstractSvtChannel} that match a DAQ pair. + * Find the collection of channels of type extending + * {@link AbstractSvtChannel} that match a DAQ pair. * - * @param pair The DAQ pair. - * @return The channels matching the DAQ pair or null if not found. + * @param pair The DAQ pair. + * @return The channels matching the DAQ pair or null if not found. */ public abstract Collection<T> find(Pair<Integer, Integer> pair); /** - * Convert this object to a human readable string. + * Convert this object to a human readable string. * - * @return This object converted to a string. + * @return This object converted to a string. */ public String toString() { StringBuffer buff = new StringBuffer(); @@ -76,9 +76,9 @@ } /** - * Get the channel ID. + * Get the channel ID. * - * @return The channel ID. + * @return The SVT channel ID. */ @Field(names = {"channel_id"}) public int getChannelID() { @@ -86,12 +86,30 @@ } /** - * Get the channel number. This is different from the ID. + * Get the channel number (0-639). This is different from the ID. * - * @return The channel number. + * @return The channel number. */ @Field(names = {"channel"}) public int getChannel() { return getFieldValue("channel"); } + + /** + * Set the channel ID. + * + * @param channelID : The SVT channel ID + */ + public void setChannelID(int channelID) { + this.setFieldValue("channel_id", channelID); + } + + /** + * Set the channel number (0-639). This is different from the ID. + * + * @param channel : The channel number + */ + public void setChannel(int channel) { + this.setFieldValue("channel", channel); + } } Modified: java/branches/prod/conditions/src/main/java/org/hps/conditions/svt/AbstractSvtDaqMapping.java ============================================================================= --- java/branches/prod/conditions/src/main/java/org/hps/conditions/svt/AbstractSvtDaqMapping.java (original) +++ java/branches/prod/conditions/src/main/java/org/hps/conditions/svt/AbstractSvtDaqMapping.java Wed Mar 25 14:43:27 2015 @@ -14,8 +14,6 @@ */ public abstract class AbstractSvtDaqMapping extends AbstractConditionsObject { - public static abstract class AbstractSvtDaqMappingCollection<T extends AbstractSvtDaqMapping> extends AbstractConditionsObjectCollection<T> { - /** * Flag values for top or bottom half. */ @@ -27,6 +25,9 @@ */ public static final String AXIAL = "A"; public static final String STEREO = "S"; + + public static abstract class AbstractSvtDaqMappingCollection<T extends AbstractSvtDaqMapping> extends AbstractConditionsObjectCollection<T> { + /** * Get a DAQ pair for the given {@link HpsSiSensor} @@ -48,18 +49,68 @@ } + /** + * Get the SVT half (TOP or BOTTOM) that the sensor belongs to. + * + * @return SVT half (TOP or BOTTOM) + */ @Field(names = {"svt_half"}) public String getSvtHalf() { return getFieldValue("svt_half"); } + /** + * Get the SVT sensor layer number (1-10 for test run and 1-12 for + * engineering run). + * + * @return SVT sensor layer number + */ @Field(names = {"layer"}) public int getLayerNumber() { return getFieldValue("layer"); } + + /** + * Get the orientation of an SVT sensor (AXIAL or STEREO). + * + * @param orientation : Orientation of an SVT sensor (AXIAL or STEREO) + */ @Field(names = {"orientation"}) public String getOrientation() { return getFieldValue("orientation"); } + + /** + * Set the SVT half (TOP or BOTTOM) that the sensor belongs to. + * + * @param svtHalf : SVT half (TOP or BOTTOM) + */ + public void setSvtHalf(String svtHalf) { + if (!svtHalf.equals(AbstractSvtDaqMapping.TOP_HALF) && !svtHalf.equals(AbstractSvtDaqMapping.BOTTOM_HALF)) + throw new RuntimeException("[ " + this.getClass().getSimpleName() + " ]: Invalid value of SVT half."); + this.setFieldValue("svt_half", svtHalf); + + } + + /** + * Set the SVT sensor layer number (1-10 for test run and 1-12 for + * engineering run). + * + * @param layer : SVT sensor layer number + */ + public void setLayerNumber(int layer) { + this.setFieldValue("layer", layer); + } + + /** + * Set the orientation of an SVT sensor (AXIAL or STEREO). + * + * @param orientation : Orientation of an SVT sensor (AXIAL or STEREO) + */ + public void setOrientation(String orientation) { + if (!orientation.equals(AbstractSvtDaqMapping.AXIAL) && !orientation.equals(AbstractSvtDaqMapping.STEREO)) + throw new RuntimeException("[ " + this.getClass().getSimpleName() + " ]: Invalid orientation of sensor."); + this.setFieldValue("orientation", orientation); + } } Modified: java/branches/prod/conditions/src/main/java/org/hps/conditions/svt/CalibrationHandler.java ============================================================================= --- java/branches/prod/conditions/src/main/java/org/hps/conditions/svt/CalibrationHandler.java (original) +++ java/branches/prod/conditions/src/main/java/org/hps/conditions/svt/CalibrationHandler.java Wed Mar 25 14:43:27 2015 @@ -1,8 +1,14 @@ package org.hps.conditions.svt; + +import java.util.logging.Level; +import java.util.logging.Logger; import org.xml.sax.helpers.DefaultHandler; import org.xml.sax.Attributes; import org.xml.sax.SAXException; + +import org.lcsim.util.log.DefaultLogFormatter; +import org.lcsim.util.log.LogUtil; import org.hps.conditions.svt.SvtChannel.SvtChannelCollection; import org.hps.conditions.svt.SvtCalibration.SvtCalibrationCollection; @@ -14,6 +20,11 @@ * @author Omar Moreno <[log in to unmask]> */ class CalibrationHandler extends DefaultHandler { + + + // Initialize the logger + private static Logger logger = LogUtil.create(SvtConditionsLoader.class.getSimpleName(), + new DefaultLogFormatter(), Level.INFO); // List of SVT channels private SvtChannelCollection svtChannels; @@ -39,12 +50,17 @@ // Noise sample ID (0-5) int noiseSampleID = 0; + // Flag denoting whether the calibrations of a given channel should be + // loaded into the conditions DB. If a channel is found to be missing + // baseline or noise values, is will be marked invalid. + boolean isValidChannel = false; + /** * Default Constructor */ public CalibrationHandler() { - svtChannels = DatabaseConditionsManager.getInstance() - .getSvtConditions().getChannelMap(); + svtChannels = (SvtChannelCollection) DatabaseConditionsManager.getInstance() + .getCachedConditions(SvtChannelCollection.class, "svt_channels").getCachedData(); } /** @@ -63,15 +79,15 @@ switch (qName) { case "Feb": febID = Integer.parseInt(attributes.getValue("id")); - System.out.println("FEB ID: " + febID); break; case "Hybrid": hybridID = Integer.parseInt(attributes.getValue("id")); - System.out.println("Hybrid ID: " + hybridID); + logger.info("Processing calibrations for FEB " + febID + " Hybrid " + hybridID); break; case "channel": channel = Integer.parseInt(attributes.getValue("id")); calibration = new SvtCalibration(svtChannels.findChannelID(febID, hybridID, channel)); + isValidChannel = false; break; case "baseline": baselineSampleID = Integer.parseInt(attributes.getValue("id")); @@ -96,13 +112,16 @@ switch (qName) { case "channel": + if (!isValidChannel) break; calibrations.add(calibration); break; case "baseline": - calibration.setPedestal(baselineSampleID, Double.parseDouble(content)); + calibration.setPedestal(baselineSampleID, Double.parseDouble(content)); + isValidChannel = true; break; case "noise": calibration.setNoise(baselineSampleID, Double.parseDouble(content)); + isValidChannel = true; break; } } Modified: java/branches/prod/conditions/src/main/java/org/hps/conditions/svt/SvtChannel.java ============================================================================= --- java/branches/prod/conditions/src/main/java/org/hps/conditions/svt/SvtChannel.java (original) +++ java/branches/prod/conditions/src/main/java/org/hps/conditions/svt/SvtChannel.java Wed Mar 25 14:43:27 2015 @@ -20,12 +20,38 @@ @Converter(multipleCollectionsAction = MultipleCollectionsAction.LAST_CREATED) public final class SvtChannel extends AbstractSvtChannel { + /** + * + */ + public SvtChannel() { + } + + /** + * Constructor + * + * @param channelID : The SVT channel ID + * @param febID : The Front End Board (FEB) ID (0-9) + * @param febHybridID : The hybrid ID (0-3) + * @param channel : The channel number (0-639) + */ + public SvtChannel(int channelID, int febID, int febHybridID, int channel) { + if (!this.isValidFeb(febID) + || !this.isValidFebHybridID(febHybridID) + || !this.isValidPhysicalChannel(channel)) { + throw new RuntimeException("Invalid FEB ID, FEB hybrid ID or physical channel number is being used."); + } + this.setChannelID(channelID); + this.setFebID(febID); + this.setFebHybridID(febHybridID); + this.setChannel(channel); + } + public static class SvtChannelCollection extends AbstractSvtChannel.AbstractSvtChannelCollection<SvtChannel> { /** - * Find channels that match a DAQ pair (FEB ID, FEB Hybrid ID). + * Find channels that match a DAQ pair (FEB ID, FEB Hybrid ID). * - * @param pair : The DAQ pair consiting of a FEB ID and FEB Hybrid ID. - * @return The channels matching the DAQ pair or null if ?not found. + * @param pair : The DAQ pair consiting of a FEB ID and FEB Hybrid ID. + * @return The channels matching the DAQ pair or null if ?not found. */ @Override public Collection<SvtChannel> find(Pair<Integer, Integer> pair) { @@ -41,13 +67,13 @@ } /** - * Get the SVT channel ID associated with a given FEB ID/Hybrid ID/physical channel. + * Get the SVT channel ID associated with a given FEB ID/Hybrid ID/physical channel. * - * @param febID : The FEB ID - * @param febHybridID : The FEB hybrid ID - * @param channel : The physical channel number - * @return The SVT channel ID - * @throws {@link RuntimeException} if the channel ID can't be found + * @param febID : The FEB ID + * @param febHybridID : The FEB hybrid ID + * @param channel : The physical channel number + * @return The SVT channel ID + * @throws {@link RuntimeException} if the channel ID can't be found */ public int findChannelID(int febID, int febHybridID, int channel) { for (SvtChannel svtChannel : this) { @@ -61,9 +87,9 @@ } /** - * Get the FEB ID associated with this SVT channel ID. + * Get the FEB ID associated with this SVT channel ID. * - * @return The FEB ID. + * @return The FEB ID. */ @Field(names = { "feb_id" }) public int getFebID() { @@ -71,9 +97,9 @@ } /** - * Get the FEB hybrid ID associated with this SVT channel ID. + * Get the FEB hybrid ID associated with this SVT channel ID. * - * @return The FEB hybrid ID. + * @return The FEB hybrid ID. */ @Field(names = { "feb_hybrid_id" }) public int getFebHybridID() { @@ -81,8 +107,58 @@ } /** - * Implementation of equals. - * @return True if the object equals this one; false if not. + * Set the FEB ID associated with this SVT channel ID. + * + * @param febID : The FEB ID + */ + public void setFebID(int febID) { + this.setFieldValue("feb_id", febID); + } + + /** + * Set the FEB hybrid ID associated with this SVT channel ID. + * + * @param febHybridID : The FEB hybrid ID + */ + public void setFebHybridID(int febHybridID) { + this.setFieldValue("feb_hybrid_id", febHybridID); + } + + /** + * Checks if a FEB ID is valid + * + * @param febID : The Front End Board (FEB) ID + * @return True if the FEB ID lies within the range 0-9, false otherwise + */ + public boolean isValidFeb(int febID) { + return (febID >= 0 && febID <= 9) ? true : false; + } + + /** + * Checks if a Front End Board hybrid ID is valid + * + * @param febHybridID : The hybrid ID + * @return True if the hybrid ID lies within the range 0-3, false otherwise + */ + public boolean isValidFebHybridID(int febHybridID) { + return (febHybridID >= 0 && febHybridID <= 3) ? true : false; + } + + /** + * Checks if a physical channel number is valid + * + * @param channel : The physical channel number + * @return True if the channel number lies within the range 0-639, false + * otherwise + */ + public boolean isValidPhysicalChannel(int channel) { + return (channel >= 0 && channel <= 639) ? true : false; + } + + /** + * Implementation of equals. + * + * @return True if the object equals this one; false if not. */ public boolean equals(Object o) { if (o == null) Modified: java/branches/prod/conditions/src/main/java/org/hps/conditions/svt/SvtDaqMapping.java ============================================================================= --- java/branches/prod/conditions/src/main/java/org/hps/conditions/svt/SvtDaqMapping.java (original) +++ java/branches/prod/conditions/src/main/java/org/hps/conditions/svt/SvtDaqMapping.java Wed Mar 25 14:43:27 2015 @@ -14,9 +14,32 @@ * @author Omar Moreno <[log in to unmask]> */ @Table(names = {"svt_daq_map"}) -@Converter(multipleCollectionsAction = MultipleCollectionsAction.ERROR) +@Converter(multipleCollectionsAction = MultipleCollectionsAction.LAST_CREATED) public class SvtDaqMapping extends AbstractSvtDaqMapping { + + /** + * Constants describing the side of a sensor + */ + public static final String ELECTRON = "ELECTRON"; + public static final String POSITRON = "POSITRON"; + /** + * Default Constructor + */ + public SvtDaqMapping() { + } + + /** + * Constructor + * + * @param febID : The Front End Board (FEB) ID (0-9) + * @param febHybridID : The FEB hybrid ID (0-3) + */ + public SvtDaqMapping(int febID, int febHybridID) { + this.setFebID(febID); + this.setFebHybridID(febHybridID); + } + public static class SvtDaqMappingCollection extends AbstractSvtDaqMappingCollection<SvtDaqMapping> { /** @@ -100,18 +123,62 @@ } } + /** + * Get the Front End Board (FEB) ID. + * + * @return The FEB ID + */ @Field(names = {"feb_id"}) public int getFebID() { return getFieldValue("feb_id"); } + /** + * Get the Front End Board (FEB) hybrid ID. + * + * @param The FEB hybrid ID + */ @Field(names = {"feb_hybrid_id"}) public int getFebHybridID() { return getFieldValue("feb_hybrid_id"); } + /** + * Get the side of the sensor (ELECTRON or POSITRON). + * + * @param sensor side (ELECTRON or POSITRON) + */ @Field(names = {"side"}) public String getSide() { return getFieldValue("side"); } + + /** + * Set the Front End Board (FEB) ID. + * + * @param febID : FEB ID + */ + public void setFebID(int febID) { + this.setFieldValue("feb_id", febID); + } + + /** + * Set the Front End Board (FEB) hybrid ID. + * + * @param febHybridID : FEB hybrid ID + */ + public void setFebHybridID(int febHybridID) { + this.setFieldValue("feb_hybrid_id", febHybridID); + } + + /** + * Set the side of the sensor (ELECTRON or POSITRON). + * + * @param side : sensor side (ELECTRON or POSITRON) + */ + public void setSide(String side) { + if (!side.equals(SvtDaqMapping.ELECTRON) && !side.equals(SvtDaqMapping.POSITRON)) + throw new RuntimeException("[ " + this.getClass().getSimpleName() + " ]: Invalid value for sensor side."); + this.setFieldValue("side", side); + } } Modified: java/branches/prod/conditions/src/main/java/org/hps/conditions/svt/SvtDetectorSetup.java ============================================================================= --- java/branches/prod/conditions/src/main/java/org/hps/conditions/svt/SvtDetectorSetup.java (original) +++ java/branches/prod/conditions/src/main/java/org/hps/conditions/svt/SvtDetectorSetup.java Wed Mar 25 14:43:27 2015 @@ -112,9 +112,9 @@ // Set the orientation of the sensor String orientation = daqMap.getOrientation(daqPair); - if (orientation != null && orientation.contentEquals(SvtDaqMappingCollection.AXIAL)) { + if (orientation != null && orientation.contentEquals(SvtDaqMapping.AXIAL)) { sensor.setAxial(true); - } else if (orientation != null && orientation.contains(SvtDaqMappingCollection.STEREO)) { + } else if (orientation != null && orientation.contains(SvtDaqMapping.STEREO)) { sensor.setStereo(true); } @@ -194,9 +194,9 @@ // Set the orientation of the sensor String orientation = daqMap.getOrientation(daqPair); - if (orientation != null && orientation.contentEquals(TestRunSvtDaqMappingCollection.AXIAL)) { + if (orientation != null && orientation.contentEquals(TestRunSvtDaqMapping.AXIAL)) { sensor.setAxial(true); - } else if (orientation != null && orientation.contains(TestRunSvtDaqMappingCollection.STEREO)) { + } else if (orientation != null && orientation.contains(TestRunSvtDaqMapping.STEREO)) { sensor.setStereo(true); } Modified: java/branches/prod/conditions/src/main/java/org/hps/conditions/svt/TestRunSvtChannel.java ============================================================================= --- java/branches/prod/conditions/src/main/java/org/hps/conditions/svt/TestRunSvtChannel.java (original) +++ java/branches/prod/conditions/src/main/java/org/hps/conditions/svt/TestRunSvtChannel.java Wed Mar 25 14:43:27 2015 @@ -11,7 +11,7 @@ import org.hps.util.Pair; @Table(names = {"test_run_svt_channels"}) -@Converter(multipleCollectionsAction = MultipleCollectionsAction.ERROR) +@Converter(multipleCollectionsAction = MultipleCollectionsAction.LAST_CREATED) public final class TestRunSvtChannel extends AbstractSvtChannel { public static class TestRunSvtChannelCollection extends AbstractSvtChannel.AbstractSvtChannelCollection<TestRunSvtChannel> { Modified: java/branches/prod/conditions/src/test/java/org/hps/conditions/EngRunConditionsTest.java ============================================================================= --- java/branches/prod/conditions/src/test/java/org/hps/conditions/EngRunConditionsTest.java (original) +++ java/branches/prod/conditions/src/test/java/org/hps/conditions/EngRunConditionsTest.java Wed Mar 25 14:43:27 2015 @@ -109,7 +109,7 @@ ecalConditions = conditionsManager.getCachedConditions(EcalConditions.class, "ecal_conditions").getCachedData(); Set<EcalChannelConstants> channelConstants = new LinkedHashSet<EcalChannelConstants>(); - for (EcalChannel channel : ecalConditions.getChannelCollection().sortedByChannelId()) { + for (EcalChannel channel : ecalConditions.getChannelCollection().sorted()) { channelConstants.add(ecalConditions.getChannelConstants(channel)); } assertEquals("Wrong number of channel constants.", nChannels, channelConstants.size()); Modified: java/branches/prod/detector-data/detectors/HPS-ECalCommissioning-v2/detector.properties ============================================================================= --- java/branches/prod/detector-data/detectors/HPS-ECalCommissioning-v2/detector.properties (original) +++ java/branches/prod/detector-data/detectors/HPS-ECalCommissioning-v2/detector.properties Wed Mar 25 14:43:27 2015 @@ -1 +1 @@ -name: HPS-ECalCommissioning-v3 +name: HPS-ECalCommissioning-v2 Modified: java/branches/prod/ecal-readout-sim/src/main/java/org/hps/readout/ecal/FADCEcalReadoutDriver.java ============================================================================= --- java/branches/prod/ecal-readout-sim/src/main/java/org/hps/readout/ecal/FADCEcalReadoutDriver.java (original) +++ java/branches/prod/ecal-readout-sim/src/main/java/org/hps/readout/ecal/FADCEcalReadoutDriver.java Wed Mar 25 14:43:27 2015 @@ -92,9 +92,16 @@ private double fixedGain = -1; private boolean constantTriggerWindow = true; private boolean addNoise = false; - private double pePerMeV = 2.0; //photoelectrons per MeV, used to calculate noise + + // 32.8 p.e./MeV = New detector in 2014 + // 2 p.e./MeV = Test Run detector + private double pePerMeV = 32.8; //photoelectrons per MeV, used to calculate noise + //switch between test run and 2014 definitions of gain constants - private boolean use2014Gain = true; + // true = ONLY simulation studies in 2014 + // false = Test Run data/simulations and 2014+ Detector's real data + private boolean use2014Gain = false; + //switch between three pulse shape functions private PulseShape pulseShape = PulseShape.ThreePole; @@ -448,9 +455,11 @@ //add preamp noise and photoelectron Poisson noise in quadrature double noise; if (use2014Gain) { - noise = Math.sqrt(Math.pow(channelData.getCalibration().getNoise() * channelData.getGain().getGain() * ECalUtils.gainFactor * ECalUtils.ecalReadoutPeriod, 2) + hit.getRawEnergy() / (ECalUtils.lightYield * ECalUtils.quantumEff * ECalUtils.surfRatio)); + noise = Math.sqrt(Math.pow(channelData.getCalibration().getNoise() * channelData.getGain().getGain() * ECalUtils.gainFactor * ECalUtils.ecalReadoutPeriod, 2) + + hit.getRawEnergy() / (ECalUtils.lightYield * ECalUtils.quantumEff * ECalUtils.surfRatio)); } else { - noise = Math.sqrt(Math.pow(channelData.getCalibration().getNoise() * channelData.getGain().getGain() * ECalUtils.MeV, 2) + hit.getRawEnergy() * ECalUtils.MeV / pePerMeV); + noise = Math.sqrt(Math.pow(channelData.getCalibration().getNoise() * channelData.getGain().getGain() * ECalUtils.MeV, 2) + + hit.getRawEnergy() * ECalUtils.MeV / pePerMeV); } energyAmplitude += RandomGaussian.getGaussian(0, noise); } Modified: java/branches/prod/ecal-readout-sim/src/main/java/org/hps/readout/ecal/FADCPrimaryTriggerDriver.java ============================================================================= --- java/branches/prod/ecal-readout-sim/src/main/java/org/hps/readout/ecal/FADCPrimaryTriggerDriver.java (original) +++ java/branches/prod/ecal-readout-sim/src/main/java/org/hps/readout/ecal/FADCPrimaryTriggerDriver.java Wed Mar 25 14:43:27 2015 @@ -9,6 +9,7 @@ import java.util.Queue; import org.hps.recon.ecal.ECalUtils; +import org.hps.recon.ecal.triggerbank.TriggerModule; import org.lcsim.event.Cluster; import org.lcsim.event.EventHeader; import org.lcsim.util.aida.AIDA; @@ -703,4 +704,14 @@ topClusterQueue.remove(); botClusterQueue.remove(); } + + /** + * Sets all cut values for the trigger using a string argument with + * the format "clusterMin clusterMax hitMin sumMin sumMax diffMax + * slopeMin slopeF coplanarMax timeDiffMax". + * @param cuts - The cut string. + */ + public void setCuts(String cuts) { + triggerModule.setCutValues(false, cuts); + } } Modified: java/branches/prod/ecal-readout-sim/src/main/java/org/hps/readout/ecal/SinglesTriggerDriver.java ============================================================================= --- java/branches/prod/ecal-readout-sim/src/main/java/org/hps/readout/ecal/SinglesTriggerDriver.java (original) +++ java/branches/prod/ecal-readout-sim/src/main/java/org/hps/readout/ecal/SinglesTriggerDriver.java Wed Mar 25 14:43:27 2015 @@ -5,6 +5,7 @@ import java.util.List; +import org.hps.recon.ecal.triggerbank.TriggerModule; import org.lcsim.event.Cluster; import org.lcsim.event.EventHeader; import org.lcsim.util.aida.AIDA; @@ -21,8 +22,7 @@ */ public class SinglesTriggerDriver extends TriggerDriver { // Cut Values - private TriggerModule triggerModule = new TriggerModule(2.0, 0.125, - 6.600, 0.200, 6.600, 0.000, 13.200, 6.600, 0.0, 360, 0.0055); + private TriggerModule triggerModule = new TriggerModule(); // LCIO Collection Names private String clusterCollectionName = "EcalClusters"; @@ -69,6 +69,9 @@ */ @Override protected boolean triggerDecision(EventHeader event) { + // Track whether triggering cluster was seen. + boolean passTrigger = false; + // Check that there is a cluster object collection. if(event.hasCollection(Cluster.class, clusterCollectionName)) { // Get the list of hits. @@ -92,6 +95,9 @@ continue triggerLoop; } + // A trigger was seen. Note it. + passTrigger = true; + // Get the x and y indices. int ix = cluster.getCalorimeterHits().get(0).getIdentifierFieldValue("ix"); int iy = cluster.getCalorimeterHits().get(0).getIdentifierFieldValue("iy"); @@ -105,9 +111,8 @@ } } - // If there were either no passing hits or not hits at all, - // then there is also no trigger. - return false; + // Return whether a triggering cluster was seen. + return passTrigger; } /** @@ -162,4 +167,13 @@ public void setClusterCollectionName(String clusterCollectionName) { this.clusterCollectionName = clusterCollectionName; } + + /** + * Sets all cut values for the trigger using a string argument with + * the format "Emin Emax Nmin". + * @param cuts - The cut string. + */ + public void setCuts(String cuts) { + triggerModule.setCutValues(true, cuts); + } } Modified: java/branches/prod/ecal-readout-sim/src/main/java/org/hps/readout/ecal/TestRunTriggerDriver.java ============================================================================= --- java/branches/prod/ecal-readout-sim/src/main/java/org/hps/readout/ecal/TestRunTriggerDriver.java (original) +++ java/branches/prod/ecal-readout-sim/src/main/java/org/hps/readout/ecal/TestRunTriggerDriver.java Wed Mar 25 14:43:27 2015 @@ -2,7 +2,8 @@ import java.util.ArrayList; import java.util.List; -import org.hps.readout.ecal.triggerbank.TestRunTriggerData; + +import org.hps.recon.ecal.triggerbank.TestRunTriggerData; import org.lcsim.event.Cluster; import org.lcsim.event.EventHeader; Modified: java/branches/prod/ecal-readout-sim/src/main/java/org/hps/readout/ecal/TriggerDriver.java ============================================================================= --- java/branches/prod/ecal-readout-sim/src/main/java/org/hps/readout/ecal/TriggerDriver.java (original) +++ java/branches/prod/ecal-readout-sim/src/main/java/org/hps/readout/ecal/TriggerDriver.java Wed Mar 25 14:43:27 2015 @@ -9,8 +9,8 @@ import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; -import org.hps.readout.ecal.triggerbank.TestRunTriggerData; - + +import org.hps.recon.ecal.triggerbank.TestRunTriggerData; import org.lcsim.event.EventHeader; import org.lcsim.lcio.LCIOWriter; Modified: java/branches/prod/ecal-recon/src/main/java/org/hps/recon/ecal/EcalPedestalCalculator.java ============================================================================= --- java/branches/prod/ecal-recon/src/main/java/org/hps/recon/ecal/EcalPedestalCalculator.java (original) +++ java/branches/prod/ecal-recon/src/main/java/org/hps/recon/ecal/EcalPedestalCalculator.java Wed Mar 25 14:43:27 2015 @@ -7,6 +7,8 @@ import java.io.IOException; import java.sql.SQLException; import java.text.DecimalFormat; +import java.text.SimpleDateFormat; +import java.util.Date; import org.hps.conditions.api.ConditionsObjectException; import org.hps.conditions.api.ConditionsRecord; @@ -90,22 +92,31 @@ userInput=cc.readLine("Enter filename prefix, or just press RETURN ..."); if (userInput==null || userInput.length()==0 || userInput=="") { String home=System.getenv().get("HOME"); - outputFilePrefix = home+"/EcalPedestalCalculator_"+runNumber+"_"; + outputFilePrefix = home+"/EcalPedestals/EcalPedestalCalculator_"+runNumber+"_"; } else { outputFilePrefix = userInput; } + + String date = new SimpleDateFormat("yyyy-MM-dd-hh-mm").format(new Date()); + outputFilePrefix += date+"_"; if (writeFileForDAQ) writeFileForDAQ(outputFilePrefix); if (writeFileForDB) writeFileForDB(outputFilePrefix); - System.err.println("\n\n***************************************************************\n"); + System.out.println("\n\n***************************************************************\n"); userInput=cc.readLine(String.format("Enter 'YES' to write conditions database for run range [%s,%s] ...",runNumber,runNumberMax)); System.out.println("***********"+userInput+"********"); + boolean uploadToDB=false; if (userInput!=null && userInput.equals("YES")) { userInput=cc.readLine("Really?"); if (userInput!=null && userInput.equals("YES")) { - uploadToDB(); - } + uploadToDB=true; + } + } + if (uploadToDB) { + uploadToDB(); + } else { + System.out.println("!!!!!!!!!!!!!!!!!!!!!!! Not Writing Database !!!!!!!!!!!!!!!!!!!!!!!!!!"); } } Modified: java/branches/prod/ecal-recon/src/main/java/org/hps/recon/ecal/EcalRawConverter.java ============================================================================= --- java/branches/prod/ecal-recon/src/main/java/org/hps/recon/ecal/EcalRawConverter.java (original) +++ java/branches/prod/ecal-recon/src/main/java/org/hps/recon/ecal/EcalRawConverter.java Wed Mar 25 14:43:27 2015 @@ -1,6 +1,7 @@ package org.hps.recon.ecal; -import java.awt.List; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; import java.util.ArrayList; import java.util.Map; @@ -8,6 +9,8 @@ import org.hps.conditions.ecal.EcalChannel; import org.hps.conditions.ecal.EcalChannelConstants; import org.hps.conditions.ecal.EcalConditions; +import org.hps.recon.ecal.daqconfig.ConfigurationManager; +import org.hps.recon.ecal.daqconfig.FADCConfig; import org.lcsim.event.CalorimeterHit; import org.lcsim.event.EventHeader; import org.lcsim.event.GenericObject; @@ -22,10 +25,8 @@ * objects with energy information. * * @author Sho Uemura <[log in to unmask]> - * @author Jeremy McCormick <[log in to unmask]> * @author Andrea Celentano <[log in to unmask]> * @author Nathan Baltzell <[log in to unmask]> - * * * baltzell: New in 2015: (default behavior is still unchanged) * @@ -36,9 +37,6 @@ * * Pedestal subtracting clipped pulses more correctly for all Modes. * - * Changed threshold cut for Mode-1 to >= instead of > to emulate SSP instead of - * FADC firmware for trigger diagnostics. - * * Implemented finding multiple peaks for Mode-1. * * Implemented conversion of Mode-1 to Mode-7 with high-resolution timing. @@ -53,6 +51,8 @@ private boolean constantGain = false; private double gain; private boolean use2014Gain = true; + private boolean useDAQConfig = false; + private FADCConfig config = null; /* * The time for one FADC sample (units = ns). @@ -66,7 +66,7 @@ * * The default value of 12 is what we used for most of the 2014 run. */ - private double leadingEdgeThreshold=12; + private double leadingEdgeThreshold = 12; /* * Integration range after (NSA) and before (NSB) threshold crossing. Units=ns, @@ -75,8 +75,8 @@ * * The default values of 20/100 are what we had during the entire 2014 run. */ - private int NSB=20; - private int NSA=100; + private int NSB = 20; + private int NSA = 100; /* * The number of samples in the FADC readout window. Needed in order to @@ -87,48 +87,89 @@ * the old behavior which assumed integration range was constant. * */ - private int windowSamples=-1; + private int windowSamples = -1; /* * The maximum number of peaks to be searched for. */ - private int nPeak=3; + private int nPeak = 3; /* * Convert Mode-1 into Mode-7, else Mode-3. */ - private boolean mode7=false; + private boolean mode7 = false; 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(); + } + } + }); + } + public void setLeadingEdgeThreshold(double thresh) { leadingEdgeThreshold=thresh; } + public void setNSA(int nsa) { if (NSA%nsPerSample !=0 || NSA<0) { throw new RuntimeException("NSA must be multiples of 4ns and non-negative."); } NSA=nsa; } + public void setNSB(int nsb) { if (NSB%nsPerSample !=0 || NSB<0) { throw new RuntimeException("NSB must be multiples of 4ns and non-negative."); } NSB=nsb; } + public void setWindowSamples(int windowSamples) { this.windowSamples=windowSamples; } + public void setNPeak(int nPeak) { if (nPeak<1 || nPeak>3) { throw new RuntimeException("Npeak must be 1, 2, or 3."); } this.nPeak=nPeak; } + public void setMode7(boolean mode7) { this.mode7=mode7; @@ -150,13 +191,24 @@ public void setUseTimeWalkCorrection(boolean useTimeWalkCorrection) { this.useTimeWalkCorrection=useTimeWalkCorrection; } + + public void setUseDAQConfig(boolean state) { + useDAQConfig = state; + } /* * This should probably be deprecated. It just integrates the entire window. */ public int sumADC(RawTrackerHit hit) { EcalChannelConstants channelData = findChannel(hit.getCellID()); - double pedestal = channelData.getCalibration().getPedestal(); + double pedestal; + if(useDAQConfig) { + //EcalChannel channel = ecalConditions.getChannelCollection().findGeometric(hit.getCellID()); + pedestal = config.getPedestal(hit.getCellID()); + } else { + pedestal = channelData.getCalibration().getPedestal(); + } + int sum = 0; short samples[] = hit.getADCValues(); for (int isample = 0; isample < samples.length; ++isample) { @@ -182,11 +234,13 @@ * 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 (useRunningPedestal && event!=null) { if (event.hasItem("EcalRunningPedestals")) { - Map<EcalChannel, Double> runningPedMap= - (Map<EcalChannel, Double>) - event.get("EcalRunningPedestals"); + Map<EcalChannel, Double> runningPedMap = (Map<EcalChannel, Double>) event.get("EcalRunningPedestals"); EcalChannel chan = ecalConditions.getChannelCollection().findGeometric(cellID); if (!runningPedMap.containsKey(chan)){ System.err.println("************** Missing Pedestal"); @@ -228,7 +282,7 @@ /* - * Emulate the FADC250 firmware emulation Mode-1 waveform to a Mode-3/7 pulse, + * Emulate the FADC250 firmware in conversion of Mode-1 waveform to a Mode-3/7 pulse, * given a time for threshold crossing. */ public double[] convertWaveformToPulse(RawTrackerHit hit,int thresholdCrossing,boolean mode7) { @@ -245,12 +299,17 @@ lastSample = thresholdCrossing + NSA/nsPerSample - 1; } - // mode-7 min and max: + // mode-7's minimum/pedestal (average of first 4 samples): double minADC=0; + for (int jj=0; jj<4; jj++) minADC += samples[jj]; + // does the firmware's conversion of min to int occur before or after time calculation? undocumented. + minADC=(int)(minADC/4); + + // mode-7's max pulse height: double maxADC=0; int sampleMaxADC=0; - // pulse integral: + // mode-3/7's pulse integral: short sumADC = 0; for (int jj=firstSample; jj<=lastSample; jj++) { @@ -261,11 +320,8 @@ // integrate pulse: sumADC += samples[jj]; - // compute "minimum" at beginning of window: - if (jj<4) minADC+=samples[jj]; - // find pulse maximum: - if (jj>firstSample && jj<samples.length-5) { + if (jj>firstSample && jj<samples.length-5) { // The "5" here is a firmware constant. if (samples[jj+1]<samples[jj]) { sampleMaxADC=jj; maxADC=samples[jj]; @@ -273,15 +329,13 @@ } } - // minADC is the average of first four samples: - minADC/=4; - // pulse time with 4ns resolution: double pulseTime=thresholdCrossing*nsPerSample; // calculate Mode-7 high-resolution time: if (mode7) { if (thresholdCrossing < 4) { + // special case where firmware sets max to zero and time to 4ns time. maxADC=0; } else if (maxADC>0) { @@ -293,10 +347,12 @@ double a1 = maxADC; double slope = (a1-a0)/(t1-t0); double halfMax = (maxADC+minADC)/2; + // this is not rigorously firmware-correct, need to find halfMax-crossing. double tmpTime = t1 - (a1 - halfMax) / slope; if (slope>0 && tmpTime>0) { pulseTime = tmpTime; } + // else another special firmware case } } @@ -317,55 +373,64 @@ * TODO: Generate GenericObject (and corresponding LCRelation) to store min and max * to fully emulate mode-7. This is less important for now. * - * NOTE: March 7, 2015. Threshold crossing requirement currently emulates the current - * SSP firmware (>=) instead of FADC firmware (>) to aid trigger studies. Firmware will - * be changed to make them identical. But for now this code prefers SSP over FADC. - */ - public ArrayList <CalorimeterHit> HitDtoA(EventHeader event,RawTrackerHit hit) { - + */ + public ArrayList <CalorimeterHit> HitDtoA(EventHeader event, RawTrackerHit hit) { final long cellID = hit.getCellID(); final short samples[] = hit.getADCValues(); - if (samples.length==0) return null; + if(samples.length == 0) return null; // threshold is pedestal plus threshold configuration parameter: - final int absoluteThreshold = (int)(getSingleSamplePedestal(event,cellID)+leadingEdgeThreshold); - + 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); + } else { + absoluteThreshold = (int) (getSingleSamplePedestal(event, cellID) + leadingEdgeThreshold); + } + ArrayList <Integer> thresholdCrossings = new ArrayList<Integer>(); // special case, first sample is above threshold: - if (samples[0] >= absoluteThreshold) { // SSP/FADC firmware discrepancy. + if (samples[0] > absoluteThreshold) { thresholdCrossings.add(0); } - + // search for threshold crossings: - for (int ii = 1; ii < samples.length; ++ii) { - if ( samples[ii] >= absoluteThreshold && - samples[ii-1] < absoluteThreshold) // SSP/FADC firmware discrepancy. - { + for(int ii = 1; ii < samples.length; ++ii) { + if ( samples[ii] > absoluteThreshold && + samples[ii-1] <= absoluteThreshold) { + // found one: thresholdCrossings.add(ii); // search for next threshold crossing begins at end of this pulse: - ii += NSA/nsPerSample-1; + if(useDAQConfig && ConfigurationManager.getInstance().getFADCConfig().getMode() == 1) { + // special case, emulating SSP: + ii += 8; + } else { + // "normal" case, emulating FADC250: + ii += NSA/nsPerSample - 1; + } // firmware limit on # of peaks: if (thresholdCrossings.size() >= nPeak) break; } } - + // make hits - ArrayList <CalorimeterHit> newHits=new ArrayList<CalorimeterHit>(); - for (int thresholdCrossing : thresholdCrossings) { - + ArrayList <CalorimeterHit> newHits = new ArrayList<CalorimeterHit>(); + for(int thresholdCrossing : thresholdCrossings) { // do pulse integral: - final double[] data = convertWaveformToPulse(hit,thresholdCrossing,mode7); + final double[] data = convertWaveformToPulse(hit, thresholdCrossing, mode7); double time = data[0]; double sum = data[1]; final double min = data[2]; // TODO: stick min and max in a GenericObject with an final double max = data[3]; // LCRelation to finish mode-7 emulation // do pedestal subtraction: - sum -= getPulsePedestal(event,cellID,samples.length,thresholdCrossing); + sum -= getPulsePedestal(event, cellID, samples.length, thresholdCrossing); // do gain scaling: double energy = adcToEnergy(sum, cellID); @@ -421,7 +486,7 @@ // Get the channel data. EcalChannelConstants channelData = findChannel(id); int amplitude; - double pedestal = getPulsePedestal(null,id,windowSamples,(int)hit.getTime()/nsPerSample); + double pedestal = getPulsePedestal(null, id, windowSamples, (int) hit.getTime() / nsPerSample); if (constantGain) { amplitude = (int) Math.round((hit.getRawEnergy() / ECalUtils.MeV) / gain + pedestal); } else { @@ -438,15 +503,18 @@ // Get the channel data. EcalChannelConstants channelData = findChannel(cellID); - - if (use2014Gain) { + + if(useDAQConfig) { + //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; } else { return channelData.getGain().getGain() * adcSum * ECalUtils.gainFactor * ECalUtils.ecalReadoutPeriod; // should not be used for the moment (2014/02) } } else { - if (constantGain) { + if(constantGain) { return gain * adcSum * ECalUtils.MeV; } else { return channelData.getGain().getGain() * adcSum * ECalUtils.MeV; //gain is defined as MeV/integrated ADC Modified: java/branches/prod/ecal-recon/src/main/java/org/hps/recon/ecal/EcalRawConverterDriver.java ============================================================================= --- java/branches/prod/ecal-recon/src/main/java/org/hps/recon/ecal/EcalRawConverterDriver.java (original) +++ java/branches/prod/ecal-recon/src/main/java/org/hps/recon/ecal/EcalRawConverterDriver.java Wed Mar 25 14:43:27 2015 @@ -6,6 +6,7 @@ import org.hps.conditions.database.DatabaseConditionsManager; import org.hps.conditions.ecal.EcalChannelConstants; import org.hps.conditions.ecal.EcalConditions; +import org.hps.recon.ecal.daqconfig.ConfigurationManager; import org.lcsim.event.CalorimeterHit; import org.lcsim.event.EventHeader; import org.lcsim.event.GenericObject; @@ -17,10 +18,6 @@ import org.lcsim.util.Driver; /** - * - * @version $Id: HPSEcalRawConverterDriver.java,v 1.2 2012/05/03 00:17:54 - * phansson Exp $ - * baltzell * * * baltzell New in 2015: (default behavior is unchanged) @@ -52,6 +49,7 @@ private boolean runBackwards = false; private boolean useTimestamps = false; private boolean useTruthTime = false; + private boolean useDAQConfig = false; private boolean emulateFirmware = false; @@ -59,77 +57,243 @@ converter = new EcalRawConverter(); } + /** + * Set to <code>true</code> to use "2014" gain formula:<br/> + * <pre>channelGain * adcSum * gainFactor * readoutPeriod</pre> + * <p> + * This formula is deprecated and should generally not be used. + * + * @param use2014Gain True to use 2014 gain formulation. + */ public void setUse2014Gain(boolean use2014Gain) { converter.setUse2014Gain(use2014Gain); } + /** + * Set to <code>true</code> to apply time walk correction from {@link EcalTimeWalk#correctTimeWalk(double, double)}. + * <p> + * This is only applicable to Mode-3 data. + * + * @param useTimeWalkCorrection True to apply time walk correction. + */ public void setUseTimeWalkCorrection(boolean useTimeWalkCorrection) { converter.setUseTimeWalkCorrection(useTimeWalkCorrection); } + + /** + * Set to <code>true</code> to use a running pedestal calibration from mode 7 data. + * <p> + * The running pedestal values are retrieved from the event collection "EcalRunningPedestals" + * which is a <code>Map</code> between {@link org.hps.conditions.ecal.EcalChannel} objects + * are their average pedestal. + * + * @param useRunningPedestal True to use a running pedestal value. + */ public void setUseRunningPedestal(boolean useRunningPedestal) { converter.setUseRunningPedestal(useRunningPedestal); } + /** + * Set to <code>true</code> to generate a {@link org.lcsim.event.CalorimeterHit} + * collection which is a conversion from energy to raw signals. + * + * @param runBackwards True to run the procedure backwards. + */ public void setRunBackwards(boolean runBackwards) { this.runBackwards = runBackwards; } + /** + * Set to <code>true</code> to drop hits that are mapped to a hard-coded + * bad FADC configuration from the Test Run. + * + * @param dropBadFADC True to drop hits mapped to a bad FADC. + */ public void setDropBadFADC(boolean dropBadFADC) { this.dropBadFADC = dropBadFADC; } + /** + * Set a minimum energy threshold in GeV for created {@link org.lcsim.event.CalorimeterHit} + * objects to be written into the output collection. + * @param threshold The minimum energy threshold in GeV. + */ public void setThreshold(double threshold) { this.threshold = threshold; } + /** + * Set to <code>true</code> to use Mode-7 emulation in calculations. + * False is Mode-3. + * + * @param mode7 True to use Mode-7 emulation in calculations. + */ public void setEmulateMode7(boolean mode7) { converter.setMode7(mode7); } + + /** + * Set to <code>true</code> to emulate firmware conversion of Mode-1 to Mode-3/7 data. + * + * @param emulateFirmware True to use firmware emulation. + */ public void setEmulateFirmware(boolean emulateFirmware) { this.emulateFirmware = emulateFirmware; } + + /** + * Set the leading-edge threshold in ADC counts, relative to pedestal, for pulse-finding + * and time determination. + * <p> + * Used to convert Mode-1 readout into Mode-3 or Mode-7 data that is usable by clustering. + * + * @param threshold The leading edge threshold in ADC counts. + */ public void setLeadingEdgeThreshold(double threshold) { converter.setLeadingEdgeThreshold(threshold); } + + /** + * Set the number of samples in the FADC readout window. + * <p> + * This is needed in order to properly pedestal-correct clipped pulses for mode-3 and mode-7. + * It is ignored for mode-1 input, since this data already includes the number of samples. + * <p> + * A non-positive number disables pulse-clipped pedestals and reverts to the old behavior which + * assumed that the integration range was constant. + * + * @param windowSamples The number of samples in the FADC readout window. + */ public void setWindowSamples(int windowSamples) { converter.setWindowSamples(windowSamples); } + + /** + * Set the integration range in nanoseconds after the threshold crossing. + * <p> + * These numbers must be multiples of 4 nanoseconds. + * <p> + * This value is used for pulse integration in Mode-1, and pedestal subtraction in all modes. + * + * @param nsa The number of nanoseconds after the threshold crossing. + * @see #setNsb(int) + */ public void setNsa(int nsa) { converter.setNSA(nsa); } + + /** + * Set the integration range in nanoseconds before the threshold crossing. + * <p> + * These numbers must be multiples of 4 nanoseconds. + * <p> + * This value is used for pulse integration in Mode-1, and pedestal subtraction in all modes. + * + * @param nsb The number of nanoseconds after the threshold crossing. + * @see #setNsa(int) + */ public void setNsb(int nsb) { converter.setNSB(nsb); } + + /** + * Set the maximum number of peaks to search for in the signal, + * which must be between 1 and 3, inclusive. + * @param nPeak The maximum number of peaks to search for in the signal. + */ public void setNPeak(int nPeak) { converter.setNPeak(nPeak); } + /** + * Set a constant gain factor in the converter for all channels. + * @param gain The constant gain value. + */ public void setGain(double gain) { converter.setGain(gain); } + /** + * Set the {@link org.lcsim.event.CalorimeterHit} collection name, + * which is used as input in "normal" mode and output when running + * "backwards". + * + * @param ecalCollectionName The <code>CalorimeterHit</code> collection name. + * @see #runBackwards + */ public void setEcalCollectionName(String ecalCollectionName) { this.ecalCollectionName = ecalCollectionName; } + /** + * Set the raw collection name which is used as output in "normal" mode + * and input when running "backwards". + * <p> + * Depending on the Driver configuration, this could be a collection + * of {@link org.lcsim.event.RawTrackerHit} objects for Mode-1 + * or {@link org.lcsim.event.RawCalorimeterHit} objects for Mode-3 + * or Mode-7. + * + * @param rawCollectionName The raw collection name. + */ public void setRawCollectionName(String rawCollectionName) { this.rawCollectionName = rawCollectionName; } + /** + * Set to <code>true</code> to ignore data from channels that + * are flagged as "bad" in the conditions system. + * @param apply True to ignore bad channels. + */ public void setApplyBadCrystalMap(boolean apply) { this.applyBadCrystalMap = apply; } + /** + * Set to <code>true</code> to turn on debug output. + * @param debug True to turn on debug output. + */ public void setDebug(boolean debug) { this.debug = debug; } + /** + * Set to <code>true</code> to use timestamp information from the ECal or trigger. + * @param useTimestamps True to use timestamp information. + */ + // FIXME: What does this actually do? What calculations does it affect? public void setUseTimestamps(boolean useTimestamps) { this.useTimestamps = useTimestamps; } + /** + * Set to <code>true</code> to use MC truth information. + * @param useTruthTime True to use MC truth information. + */ + // FIXME: What does this actually do? What calculations does it affect? public void setUseTruthTime(boolean useTruthTime) { this.useTruthTime = useTruthTime; + } + + /** + * Sets whether the driver should use the DAQ configuration from + * EvIO file for its parameters. If activated, the converter will + * obtain gains, thresholds, pedestals, the window size, and the + * pulse integration window from the EvIO file. This will replace + * and overwrite any manually defined settings.<br/> + * <br/> + * Note that if this setting is active, the driver will not output + * any data until a DAQ configuration has been read from the data + * stream. + * @param state - <code>true</code> indicates that the configuration + * should be read from the DAQ data in an EvIO file. Setting this + * to <code>false</code> will cause the driver to use its regular + * manually-defined settings and pull gains and pedestals from the + * conditions database. + */ + public void setUseDAQConfig(boolean state) { + useDAQConfig = state; + converter.setUseDAQConfig(state); } @Override @@ -185,6 +349,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; + } + final int SYSTEM_TRIGGER = 0; final int SYSTEM_TRACKER = 1; final int SYSTEM_ECAL = 2; Modified: java/branches/prod/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/ClusterDriver.java ============================================================================= --- java/branches/prod/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/ClusterDriver.java (original) +++ java/branches/prod/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/ClusterDriver.java Wed Mar 25 14:43:27 2015 @@ -249,7 +249,7 @@ } } } else { - getLogger().severe("The input hit collection " + this.inputHitCollectionName + " is missing from the event."); + getLogger().info("The input hit collection " + this.inputHitCollectionName + " is missing from the event."); if (this.raiseErrorNoHitCollection) { throw new RuntimeException("The expected input hit collection is missing from the event."); } Modified: java/branches/prod/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/GTPOnlineClusterDriver.java ============================================================================= --- java/branches/prod/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/GTPOnlineClusterDriver.java (original) +++ java/branches/prod/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/GTPOnlineClusterDriver.java Wed Mar 25 14:43:27 2015 @@ -1,4 +1,11 @@ package org.hps.recon.ecal.cluster; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import org.hps.recon.ecal.daqconfig.ConfigurationManager; +import org.hps.recon.ecal.daqconfig.GTPConfig; +import org.lcsim.event.EventHeader; /** * Class <code>GTPOnlineClusterDriver</code> allows parameters for the @@ -7,16 +14,47 @@ * @author Kyle McCarty <[log in to unmask]> */ public class GTPOnlineClusterDriver extends ClusterDriver { - // Store the clustering algorithm. private final GTPOnlineClusterer gtp; + private boolean useDAQConfig = false; /** * Instantiates a new clustering algorithm using the readout * variant of the GTP clustering algorithm. */ public GTPOnlineClusterDriver() { + // 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 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); + } } /** @@ -25,19 +63,7 @@ @Override public void startOfData() { // VERBOSE :: Output the driver settings. - if(gtp.isVerbose()) { - // 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()); - } + if(gtp.isVerbose()) { logSettings(); } } /** @@ -80,4 +106,31 @@ public void setVerbose(boolean verbose) { gtp.setVerbose(verbose); } + + /** + * Sets whether GTP settings should be drawn from the EvIO data + * DAQ configuration or read from the steering file. + * @param state - <code>true</code> means that DAQ configuration + * will be used and <code>false</code> that it will not. + */ + public void setUseDAQConfig(boolean 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()); + } } Modified: java/branches/prod/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/GTPOnlineClusterer.java ============================================================================= --- java/branches/prod/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/GTPOnlineClusterer.java (original) +++ java/branches/prod/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/GTPOnlineClusterer.java Wed Mar 25 14:43:27 2015 @@ -158,30 +158,37 @@ // Iterate over the other hits and if the are within // the clustering spatiotemporal window, compare their // energies. + hitLoop: for(CalorimeterHit hit : hitList) { - // Do not perform the comparison if the hit is the - // current potential seed. - if(hit != seed) { - // Check if the hit is within the spatiotemporal - // clustering window. - if(withinTimeVerificationWindow(seed, hit) && withinSpatialWindow(seed, hit)) { - // Check if the hit invalidates the potential - // seed. - if(isValidSeed(seed, hit)) { - // Make sure that the hit is also within - // the hit add window; this may not be - // the same as the verification window - // if the asymmetric window is active. - if(withinTimeClusteringWindow(seed, hit)) { - protoCluster.addHit(hit); - } + // 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)) { + // Check if the hit invalidates the potential + // seed. + if(isValidSeed(seed, hit)) { + // Make sure that the hit is also within + // the hit add window; this may not be + // the same as the verification window + // if the asymmetric window is active. + if(withinTimeClusteringWindow(seed, hit)) { + protoCluster.addHit(hit); } - - // If it is not, then skip the rest of the - // loop; the potential seed is not really - // a seed. - else { continue seedLoop; } } + + // If it is not, then skip the rest of the + // loop; the potential seed is not really + // a seed. + else { continue seedLoop; } } } @@ -308,20 +315,37 @@ * <code>false</code> otherwise. */ private boolean withinSpatialWindow(CalorimeterHit seed, CalorimeterHit hit) { - // Get the x-indices of each hit. - int six = seed.getIdentifierFieldValue("ix"); - int hix = hit.getIdentifierFieldValue("ix"); - - // Check that the x indices are either the same or within a - // range of one of one another. - if((six == hix) || (six + 1 == hix) || (six - 1 == hix)) { - // Get the y-indices of each hit. - int siy = seed.getIdentifierFieldValue("iy"); - int hiy = hit.getIdentifierFieldValue("iy"); + // Get the y-indices of each hit. + int siy = seed.getIdentifierFieldValue("iy"); + int hiy = hit.getIdentifierFieldValue("iy"); + + // Ensure that the y-indices are either the same or are within + // one of one another. + if((siy == hiy) || (siy + 1 == hiy) || (siy - 1 == hiy)) { + // Get the x-indices of each hit. + int six = seed.getIdentifierFieldValue("ix"); + int hix = hit.getIdentifierFieldValue("ix"); - // Ensure that the y-indices are either the same or are - // within one of one another. - return (siy == hiy) || (siy + 1 == hiy) || (siy - 1 == hiy); + // If the x-indices are the same or within one of each other + // then the crystals are within the spatial window of one + // another. + if((six == hix) || (six + 1 == hix) || (six - 1 == hix)) { + return true; + } + + // Otherwise, check for the special case where ix = 1 is + // 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. + if((six == -1 && hix == 1) || (six == 1 && hix == -1)) { + return true; + } + + // Any other combination that reaches this point is not + // a valid combination. + else { return false; } + } } // If the x-index comparison fails, return false. Modified: java/branches/prod/evio/pom.xml ============================================================================= --- java/branches/prod/evio/pom.xml (original) +++ java/branches/prod/evio/pom.xml Wed Mar 25 14:43:27 2015 @@ -20,6 +20,10 @@ <groupId>org.hps</groupId> <artifactId>hps-tracking</artifactId> </dependency> + <dependency> + <groupId>org.hps</groupId> + <artifactId>hps-record-util</artifactId> + </dependency> </dependencies> <build> <plugins> @@ -29,6 +33,8 @@ <configuration> <excludes> <exclude>org/hps/evio/LCSimEngRunEventBuilderTest.java</exclude> + <exclude>org/hps/evio/SvtEvioReaderTest.java</exclude> + <exclude>org/hps/evio/TestRunSvtEvioReaderTest.java</exclude> </excludes> <trimStackTrace>true</trimStackTrace> </configuration> Modified: java/branches/prod/evio/src/main/java/org/hps/evio/LCSimEngRunEventBuilder.java ============================================================================= --- java/branches/prod/evio/src/main/java/org/hps/evio/LCSimEngRunEventBuilder.java (original) +++ java/branches/prod/evio/src/main/java/org/hps/evio/LCSimEngRunEventBuilder.java Wed Mar 25 14:43:27 2015 @@ -5,39 +5,47 @@ import java.util.logging.Level; import java.util.logging.Logger; -import org.jlab.coda.jevio.BaseStructure; +import org.hps.recon.ecal.triggerbank.AbstractIntData; +import org.hps.recon.ecal.triggerbank.SSPData; +import org.hps.recon.ecal.triggerbank.TIData; +import org.hps.record.epics.EpicsEvioProcessor; +import org.hps.record.epics.EpicsScalarData; +import org.hps.record.evio.EvioEventUtilities; +import org.hps.record.scalars.ScalarData; +import org.hps.record.scalars.ScalarsEvioProcessor; import org.jlab.coda.jevio.EvioEvent; - import org.lcsim.event.EventHeader; -import org.hps.readout.ecal.daqconfig.EvioDAQParser; -import org.hps.readout.ecal.triggerbank.AbstractIntData; -import org.hps.readout.ecal.triggerbank.SSPData; -import org.hps.readout.ecal.triggerbank.TIData; -import org.hps.record.evio.EvioEventUtilities; - - /** - * Build LCSim events from EVIO data. + * This is the {@link org.hps.record.LCSimEventBuilder} implementation for the Engineering Run and the Commissioning Run. + * <p> + * It has several modifications from the Test Run builder including different values for certain bank tags. + * <p> + * Additionally, this builder will write DAQ config information, EPICS control data, and scalar bank data into the output LCSim events if these banks are present in the EVIO data. * * @author Sho Uemura <[log in to unmask]> * @author Jeremy McCormick <[log in to unmask]> */ public class LCSimEngRunEventBuilder extends LCSimTestRunEventBuilder { - + TriggerConfigEvioReader triggerConfigReader = null; - + + EpicsEvioProcessor epicsProcessor = new EpicsEvioProcessor(); + EpicsScalarData epicsData; + + ScalarsEvioProcessor scalarProcessor = new ScalarsEvioProcessor(); + ScalarData scalarData; + public LCSimEngRunEventBuilder() { ecalReader.setTopBankTag(0x25); ecalReader.setBotBankTag(0x27); - svtReader = new SvtEvioReader(); - sspCrateBankTag = 0x2E; //A.C. modification after Sergey's confirmation + svtReader = new SvtEvioReader(); + sspCrateBankTag = 0x2E; // A.C. modification after Sergey's confirmation sspBankTag = 0xe10c; intBanks = new ArrayList<IntBankDefinition>(); - intBanks.add(new IntBankDefinition(SSPData.class, new int[]{sspCrateBankTag, sspBankTag})); - intBanks.add(new IntBankDefinition(TIData.class, new int[]{sspCrateBankTag, 0xe10a})); + intBanks.add(new IntBankDefinition(SSPData.class, new int[] { sspCrateBankTag, sspBankTag })); + intBanks.add(new IntBankDefinition(TIData.class, new int[] { sspCrateBankTag, 0xe10a })); // ecalReader = new ECalEvioReader(0x25, 0x27); - triggerConfigReader = new TriggerConfigEvioReader(); } @@ -53,6 +61,37 @@ } @Override + public void readEvioEvent(EvioEvent evioEvent) { + super.readEvioEvent(evioEvent); + + // Create EPICS data if this is an EPICS control event. + if (EvioEventUtilities.isEpicsEvent(evioEvent)) { + createEpicsScalarData(evioEvent); + } + } + + /** + * Create and cache an {@link org.hps.record.epics.EpicsScalarData} object. + * @param evioEvent The EVIO event data. + */ + void createEpicsScalarData(EvioEvent evioEvent) { + epicsProcessor.process(evioEvent); + epicsData = epicsProcessor.getEpicsScalarData(); + } + + /** + * Write EVIO scalar data into the LCSim event, if it exists. + * @param evioEvent The EVIO event data. + * @param lcsimEvent The output LCSim event. + */ + void writeScalarData(EvioEvent evioEvent, EventHeader lcsimEvent) { + scalarProcessor.process(evioEvent); + if (scalarProcessor.getScalarData() != null) { + scalarProcessor.getScalarData().write(lcsimEvent); + } + } + + @Override public EventHeader makeLCSimEvent(EvioEvent evioEvent) { if (!EvioEventUtilities.isPhysicsEvent(evioEvent)) { throw new RuntimeException("Not a physics event: event tag " + evioEvent.getHeader().getTag()); @@ -60,10 +99,10 @@ // Create a new LCSimEvent. EventHeader lcsimEvent = getEventData(evioEvent); - - // Put DAQ Configuration info into lcsimEvent - triggerConfigReader.getDAQConfig(evioEvent,lcsimEvent); - + + // Put DAQ Configuration info into lcsimEvent. + triggerConfigReader.getDAQConfig(evioEvent, lcsimEvent); + // Make RawCalorimeterHit collection, combining top and bottom section // of ECal into one list. try { @@ -72,16 +111,23 @@ Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, "Error making ECal hits", e); } - // Make SVT RawTrackerHits + // FIXME: This is commented out for now while SVT is not integrated. + // Make SVT RawTrackerHits. // try { // svtReader.makeHits(evioEvent, lcsimEvent); // } catch (Exception e) { - // Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, - // "Error making SVT hits", e); + // Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, "Error making SVT hits", e); // } + + // Write the current EPICS data into this event. + if (epicsData != null) { + epicsData.write(lcsimEvent); + epicsData = null; + } + + // Write scalars into the event, if they exist in this EVIO data. + writeScalarData(evioEvent, lcsimEvent); + return lcsimEvent; } - - - -} +} Modified: java/branches/prod/evio/src/main/java/org/hps/evio/LCSimTestRunEventBuilder.java ============================================================================= --- java/branches/prod/evio/src/main/java/org/hps/evio/LCSimTestRunEventBuilder.java (original) +++ java/branches/prod/evio/src/main/java/org/hps/evio/LCSimTestRunEventBuilder.java Wed Mar 25 14:43:27 2015 @@ -5,8 +5,9 @@ import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; -import org.hps.readout.ecal.triggerbank.AbstractIntData; -import org.hps.readout.ecal.triggerbank.TestRunTriggerData; + +import org.hps.recon.ecal.triggerbank.AbstractIntData; +import org.hps.recon.ecal.triggerbank.TestRunTriggerData; import org.hps.record.LCSimEventBuilder; import org.hps.record.evio.EvioEventConstants; import org.hps.record.evio.EvioEventUtilities; @@ -27,8 +28,8 @@ */ public class LCSimTestRunEventBuilder implements LCSimEventBuilder, ConditionsListener { - ECalEvioReader ecalReader = null; - AbstractSvtEvioReader svtReader = null; + protected ECalEvioReader ecalReader = null; + protected AbstractSvtEvioReader svtReader = null; protected long time = 0; //most recent event time (ns), taken from prestart and end events, and trigger banks (if any) protected int sspCrateBankTag = 0x1; //bank ID of the crate containing the SSP protected int sspBankTag = 0xe106; //SSP bank's tag Modified: java/branches/prod/evio/src/main/java/org/hps/evio/SVTHitWriter.java ============================================================================= --- java/branches/prod/evio/src/main/java/org/hps/evio/SVTHitWriter.java (original) +++ java/branches/prod/evio/src/main/java/org/hps/evio/SVTHitWriter.java Wed Mar 25 14:43:27 2015 @@ -1,29 +1,28 @@ package org.hps.evio; + +import static org.hps.evio.EventConstants.SVT_BANK_NUMBER; +import static org.hps.evio.EventConstants.SVT_BANK_TAG; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +//===> import org.hps.conditions.deprecated.SvtUtils; +import org.hps.readout.svt.FpgaData; +import org.hps.readout.svt.HPSSVTConstants; +import org.hps.readout.svt.SVTData; import org.jlab.coda.jevio.DataType; import org.jlab.coda.jevio.EventBuilder; import org.jlab.coda.jevio.EvioBank; import org.jlab.coda.jevio.EvioException; +import org.lcsim.detector.tracker.silicon.HpsSiSensor; import org.lcsim.detector.tracker.silicon.HpsTestRunSiSensor; -import org.lcsim.detector.tracker.silicon.SiSensor; -import org.lcsim.detector.tracker.silicon.HpsSiSensor; import org.lcsim.event.EventHeader; import org.lcsim.event.LCRelation; import org.lcsim.event.RawTrackerHit; import org.lcsim.geometry.Subdetector; import org.lcsim.lcio.LCIOConstants; -//===> import org.hps.conditions.deprecated.SvtUtils; -import org.hps.readout.svt.FpgaData; -import org.hps.readout.svt.HPSSVTConstants; -import org.hps.readout.svt.SVTData; - -import static org.hps.evio.EventConstants.SVT_BANK_NUMBER; -import static org.hps.evio.EventConstants.SVT_BANK_TAG; /** * Modified: java/branches/prod/evio/src/main/java/org/hps/evio/TestRunSvtEvioReader.java ============================================================================= --- java/branches/prod/evio/src/main/java/org/hps/evio/TestRunSvtEvioReader.java (original) +++ java/branches/prod/evio/src/main/java/org/hps/evio/TestRunSvtEvioReader.java Wed Mar 25 14:43:27 2015 @@ -2,15 +2,12 @@ import java.util.List; +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.RawTrackerHit; -import org.lcsim.event.base.BaseRawTrackerHit; import org.lcsim.geometry.Subdetector; -import org.hps.util.Pair; - -import static org.hps.evio.EventConstants.TEST_RUN_SVT_BANK_TAG; /** * Test run SVT EVIO reader used to convert SVT bank integer data to LCIO Modified: java/branches/prod/evio/src/main/java/org/hps/evio/TestRunTriggeredReconToLcio.java ============================================================================= --- java/branches/prod/evio/src/main/java/org/hps/evio/TestRunTriggeredReconToLcio.java (original) +++ java/branches/prod/evio/src/main/java/org/hps/evio/TestRunTriggeredReconToLcio.java Wed Mar 25 14:43:27 2015 @@ -161,7 +161,9 @@ if (event.hasCollection(SimCalorimeterHit.class, ecalCollectionName) && !event.get(SimCalorimeterHit.class, ecalCollectionName).isEmpty()) { mcParticles = event.getMCParticles(); ecalHits = event.get(SimCalorimeterHit.class, ecalCollectionName); - trackerHits = event.get(SimTrackerHit.class, trackerCollectionName); + if (event.hasCollection(SimTrackerHit.class, trackerCollectionName)) { + trackerHits = event.get(SimTrackerHit.class, trackerCollectionName); + } if (event.hasCollection(SimTrackerHit.class, ecalScoringPlaneHitsCollectionName)) { ecalScoringPlaneHits = event.get(SimTrackerHit.class, ecalScoringPlaneHitsCollectionName); } @@ -170,7 +172,9 @@ if (event.hasCollection(MCParticle.class)) { triggerMCParticles = event.getMCParticles(); triggerECalHits = event.get(SimCalorimeterHit.class, ecalCollectionName); - triggerTrackerHits = event.get(SimTrackerHit.class, trackerCollectionName); + if (event.hasCollection(SimTrackerHit.class, trackerCollectionName)) { + triggerTrackerHits = event.get(SimTrackerHit.class, trackerCollectionName); + } if (event.hasCollection(SimTrackerHit.class, ecalScoringPlaneHitsCollectionName)) { triggerECalScoringPlaneHits = event.get(SimTrackerHit.class, ecalScoringPlaneHitsCollectionName); } Modified: java/branches/prod/evio/src/main/java/org/hps/evio/TriggerConfigEvioReader.java ============================================================================= --- java/branches/prod/evio/src/main/java/org/hps/evio/TriggerConfigEvioReader.java (original) +++ java/branches/prod/evio/src/main/java/org/hps/evio/TriggerConfigEvioReader.java Wed Mar 25 14:43:27 2015 @@ -5,7 +5,7 @@ import java.util.logging.Level; import java.util.logging.Logger; -import org.hps.readout.ecal.daqconfig.EvioDAQParser; +import org.hps.recon.ecal.daqconfig.EvioDAQParser; import org.jlab.coda.jevio.BaseStructure; import org.jlab.coda.jevio.EvioEvent; import org.lcsim.event.EventHeader; Modified: java/branches/prod/evio/src/main/java/org/hps/evio/TriggerDataWriter.java ============================================================================= --- java/branches/prod/evio/src/main/java/org/hps/evio/TriggerDataWriter.java (original) +++ java/branches/prod/evio/src/main/java/org/hps/evio/TriggerDataWriter.java Wed Mar 25 14:43:27 2015 @@ -1,8 +1,9 @@ package org.hps.evio; import java.util.List; -import org.hps.readout.ecal.triggerbank.AbstractIntData; -import org.hps.readout.ecal.triggerbank.TestRunTriggerData; + +import org.hps.recon.ecal.triggerbank.AbstractIntData; +import org.hps.recon.ecal.triggerbank.TestRunTriggerData; import org.jlab.coda.jevio.BaseStructure; import org.jlab.coda.jevio.DataType; import org.jlab.coda.jevio.EventBuilder; Modified: java/branches/prod/monitoring-app/pom.xml ============================================================================= --- java/branches/prod/monitoring-app/pom.xml (original) +++ java/branches/prod/monitoring-app/pom.xml Wed Mar 25 14:43:27 2015 @@ -111,6 +111,10 @@ </dependency> <dependency> <groupId>org.hps</groupId> + <artifactId>hps-ecal-recon</artifactId> + </dependency> + <dependency> + <groupId>org.hps</groupId> <artifactId>hps-monitoring-drivers</artifactId> </dependency> <dependency> @@ -130,5 +134,20 @@ <artifactId>jlfgr</artifactId> <version>1.0</version> </dependency> + <dependency> + <groupId>org.freehep</groupId> + <artifactId>freehep-jaida-remote</artifactId> + <version>3.4.11</version> + <exclusions> + <exclusion> + <groupId>org.jdom</groupId> + <artifactId>jdom</artifactId> + </exclusion> + <exclusion> + <groupId>commons-math</groupId> + <artifactId>commons-math</artifactId> + </exclusion> + </exclusions> + </dependency> </dependencies> -</project> +</project> Modified: java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/AbstractFieldsPanel.java ============================================================================= --- java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/AbstractFieldsPanel.java (original) +++ java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/AbstractFieldsPanel.java Wed Mar 25 14:43:27 2015 @@ -11,6 +11,7 @@ import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JComboBox; +import javax.swing.JComponent; import javax.swing.JFormattedTextField; import javax.swing.JLabel; import javax.swing.JPanel; @@ -136,7 +137,7 @@ c.gridy = currY; c.insets = insets; c.anchor = GridBagConstraints.WEST; - JLabel waitModeLabel = new JLabel(name + ":"); + JLabel waitModeLabel = new JLabel(name); waitModeLabel.setHorizontalAlignment(JLabel.LEFT); add(waitModeLabel, c); @@ -278,6 +279,33 @@ return configurationModel; } + /** + * Add a labeled JComponent to the panel. + * @param name The label text. + * @param component The component to add. + */ + void addComponent(String name, JComponent component) { + + // Add the label. + GridBagConstraints c = new GridBagConstraints(); + c.gridx = 0; + c.gridy = currY; + c.insets = insets; + c.anchor = GridBagConstraints.WEST; + JLabel label = new JLabel(name + ":"); + add(label, c); + + // Add the component. + c = new GridBagConstraints(); + c.gridx = 1; + c.gridy = currY; + c.insets = insets; + c.anchor = GridBagConstraints.EAST; + add(component, c); + + ++currY; + } + boolean accept(PropertyChangeEvent evt) { if (evt.getPropertyName().equals("ancestor")) { return false; Modified: java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/Commands.java ============================================================================= --- java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/Commands.java (original) +++ java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/Commands.java Wed Mar 25 14:43:27 2015 @@ -34,14 +34,25 @@ // Save a screenshot static final String SAVE_SCREENSHOT = "saveScreenshot"; - // Save the plots + // Plotting actions static final String SAVE_PLOTS = "savePlots"; static final String CLEAR_PLOTS = "resetPlots"; + static final String SAVE_SELECTED_PLOTS = "saveSelectedPlots"; + // Exit the application. static final String EXIT = "exit"; + + // Log to file or standard print stream. + static final String LOG_TO_FILE = "logToFile"; + static final String LOG_TO_TERMINAL = "logToTerminal"; - static final String LOG_LEVEL_FILTER_CHANGED = "logLevelFilterChanged"; - + static final String LOG_LEVEL_FILTER_CHANGED = "logLevelFilterChanged"; + + static final String CONDITIONS_TAG_CHANGED = "conditionsTagChanged"; + + static final String START_AIDA_SERVER = "startAIDAServer"; + static final String STOP_AIDA_SERVER = "stopAIDAServer"; + //////////////////////////////////////////// static final String BLOCKING_CHANGED = "blockingChanged"; static final String CHOOSE_COMPACT_FILE = "chooseCompactFile"; @@ -59,10 +70,7 @@ static final String FREEZE_CONDITIONS_CHANGED = "freezeConditionsChanged"; static final String LOG_LEVEL_CHANGED = "logLevelChanged"; - static final String LOG_TO_FILE = "logToFile"; - static final String LOG_TO_FILE_CHANGED = "logToFileChanged"; - static final String LOG_TO_TERMINAL = "logToTerminal"; - + static final String PROCESSING_STAGE_CHANGED = "processingStageChanged"; static final String SAVE_LOG_TABLE = "saveLogTable"; static final String SELECT_LOG_FILE = "logToFile"; Modified: java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/ConnectionSettingsPanel.java ============================================================================= --- java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/ConnectionSettingsPanel.java (original) +++ java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/ConnectionSettingsPanel.java Wed Mar 25 14:43:27 2015 @@ -1,20 +1,4 @@ package org.hps.monitoring.application; - -import static org.hps.monitoring.application.Commands.BLOCKING_CHANGED; -import static org.hps.monitoring.application.Commands.VERBOSE_CHANGED; -import static org.hps.monitoring.application.Commands.WAIT_MODE_CHANGED; -import static org.hps.monitoring.application.model.ConfigurationModel.BLOCKING_PROPERTY; -import static org.hps.monitoring.application.model.ConfigurationModel.CHUNK_SIZE_PROPERTY; -import static org.hps.monitoring.application.model.ConfigurationModel.ET_NAME_PROPERTY; -import static org.hps.monitoring.application.model.ConfigurationModel.HOST_PROPERTY; -import static org.hps.monitoring.application.model.ConfigurationModel.PORT_PROPERTY; -import static org.hps.monitoring.application.model.ConfigurationModel.PRESCALE_PROPERTY; -import static org.hps.monitoring.application.model.ConfigurationModel.QUEUE_SIZE_PROPERTY; -import static org.hps.monitoring.application.model.ConfigurationModel.STATION_NAME_PROPERTY; -import static org.hps.monitoring.application.model.ConfigurationModel.STATION_POSITION_PROPERTY; -import static org.hps.monitoring.application.model.ConfigurationModel.VERBOSE_PROPERTY; -import static org.hps.monitoring.application.model.ConfigurationModel.WAIT_MODE_PROPERTY; -import static org.hps.monitoring.application.model.ConfigurationModel.WAIT_TIME_PROPERTY; import java.awt.GridBagLayout; import java.awt.Insets; @@ -72,11 +56,11 @@ portField.addPropertyChangeListener("value", this); blockingCheckBox = addCheckBox("Blocking", false, true); - blockingCheckBox.setActionCommand(BLOCKING_CHANGED); + blockingCheckBox.setActionCommand(Commands.BLOCKING_CHANGED); blockingCheckBox.addActionListener(this); verboseCheckBox = addCheckBox("Verbose", false, true); - verboseCheckBox.setActionCommand(VERBOSE_CHANGED); + verboseCheckBox.setActionCommand(Commands.VERBOSE_CHANGED); verboseCheckBox.addActionListener(this); stationNameField = addField("Station Name", 10); @@ -92,7 +76,7 @@ stationPositionField.addPropertyChangeListener("value", this); waitModeComboBox = addComboBox("Wait Mode", waitModes); - waitModeComboBox.setActionCommand(WAIT_MODE_CHANGED); + waitModeComboBox.setActionCommand(Commands.WAIT_MODE_CHANGED); waitModeComboBox.addActionListener(this); waitTimeField = addField("Wait Time [microseconds]", 8); @@ -130,29 +114,29 @@ configurationModel.removePropertyChangeListener(this); try { Object value = evt.getNewValue(); - if (evt.getPropertyName().equals(ET_NAME_PROPERTY)) { + if (evt.getPropertyName().equals(ConfigurationModel.ET_NAME_PROPERTY)) { etNameField.setText((String) value); - } else if (evt.getPropertyName().equals(HOST_PROPERTY)) { + } else if (evt.getPropertyName().equals(ConfigurationModel.HOST_PROPERTY)) { hostField.setText((String) value); - } else if (evt.getPropertyName().equals(PORT_PROPERTY)) { + } else if (evt.getPropertyName().equals(ConfigurationModel.PORT_PROPERTY)) { portField.setText(value.toString()); - } else if (evt.getPropertyName().equals(BLOCKING_PROPERTY)) { + } else if (evt.getPropertyName().equals(ConfigurationModel.BLOCKING_PROPERTY)) { blockingCheckBox.setSelected((Boolean) value); - } else if (evt.getPropertyName().equals(VERBOSE_PROPERTY)) { + } else if (evt.getPropertyName().equals(ConfigurationModel.VERBOSE_PROPERTY)) { verboseCheckBox.setSelected((Boolean) value); - } else if (evt.getPropertyName().equals(STATION_NAME_PROPERTY)) { + } else if (evt.getPropertyName().equals(ConfigurationModel.STATION_NAME_PROPERTY)) { stationNameField.setText((String) value); - } else if (evt.getPropertyName().equals(CHUNK_SIZE_PROPERTY)) { + } else if (evt.getPropertyName().equals(ConfigurationModel.CHUNK_SIZE_PROPERTY)) { chunkSizeField.setText(value.toString()); - } else if (evt.getPropertyName().equals(QUEUE_SIZE_PROPERTY)) { + } else if (evt.getPropertyName().equals(ConfigurationModel.QUEUE_SIZE_PROPERTY)) { queueSizeField.setText(value.toString()); - } else if (evt.getPropertyName().equals(STATION_POSITION_PROPERTY)) { + } else if (evt.getPropertyName().equals(ConfigurationModel.STATION_POSITION_PROPERTY)) { stationPositionField.setText(value.toString()); - } else if (evt.getPropertyName().equals(WAIT_MODE_PROPERTY)) { + } else if (evt.getPropertyName().equals(ConfigurationModel.WAIT_MODE_PROPERTY)) { waitModeComboBox.setSelectedItem(((Mode) value).name()); - } else if (evt.getPropertyName().equals(WAIT_TIME_PROPERTY)) { + } else if (evt.getPropertyName().equals(ConfigurationModel.WAIT_TIME_PROPERTY)) { waitTimeField.setText(value.toString()); - } else if (evt.getPropertyName().equals(PRESCALE_PROPERTY)) { + } else if (evt.getPropertyName().equals(ConfigurationModel.PRESCALE_PROPERTY)) { prescaleField.setText(value.toString()); } } finally { @@ -166,18 +150,9 @@ */ @Override public void propertyChange(PropertyChangeEvent evt) { - if (!accept(evt)) { return; - } - - //System.out.println("ConnectionSettingsPanel.propertyChange"); - //System.out.println(" src: " + evt.getSource()); - //System.out.println(" propName: " + evt.getPropertyName()); - //System.out.println(" oldValue: " + evt.getOldValue()); - //System.out.println(" newValue: " + evt.getNewValue()); - //System.out.println(" propValue: " + evt.getPropagationId()); - + } Object source = evt.getSource(); configurationModel.removePropertyChangeListener(this); try { @@ -210,11 +185,11 @@ */ @Override public void actionPerformed(ActionEvent e) { - if (WAIT_MODE_CHANGED.equals(e.getActionCommand())) { + if (Commands.WAIT_MODE_CHANGED.equals(e.getActionCommand())) { configurationModel.setWaitMode(Mode.valueOf((String) waitModeComboBox.getSelectedItem())); - } else if (BLOCKING_CHANGED.equals(e.getActionCommand())) { + } else if (Commands.BLOCKING_CHANGED.equals(e.getActionCommand())) { configurationModel.setBlocking(blockingCheckBox.isSelected()); - } else if (VERBOSE_CHANGED.equals(e.getActionCommand())) { + } else if (Commands.VERBOSE_CHANGED.equals(e.getActionCommand())) { configurationModel.setVerbose(verboseCheckBox.isSelected()); } } Modified: java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/ConnectionStatusPanel.java ============================================================================= --- java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/ConnectionStatusPanel.java (original) +++ java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/ConnectionStatusPanel.java Wed Mar 25 14:43:27 2015 @@ -45,7 +45,6 @@ setMinimumSize(new Dimension(PANEL_WIDTH, PANEL_HEIGHT)); setLayout(new GridBagLayout()); - // setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED)); GridBagConstraints c = new GridBagConstraints(); c.weightx = c.weighty = 1.0; Modified: java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/DatePanel.java ============================================================================= --- java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/DatePanel.java (original) +++ java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/DatePanel.java Wed Mar 25 14:43:27 2015 @@ -9,7 +9,7 @@ */ class DatePanel extends FieldPanel { - private SimpleDateFormat dateFormat = new SimpleDateFormat("MMMM-dd-yyyy HH:mm:ss"); + private SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); DatePanel(String fieldName, String defaultValue, int size, boolean editable) { super(fieldName, defaultValue, size, editable); Modified: java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/EventButtonsPanel.java ============================================================================= --- java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/EventButtonsPanel.java (original) +++ java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/EventButtonsPanel.java Wed Mar 25 14:43:27 2015 @@ -80,10 +80,21 @@ resumeButton.setEnabled(false); connectButton.setActionCommand(Commands.CONNECT); connectButton.setIcon(disconnectedIcon); - } else { + connectButton.setToolTipText("Start new session"); + connectButton.setEnabled(true); + } else if (status.equals(ConnectionStatus.DISCONNECTING)) { + nextButton.setEnabled(false); + pauseButton.setEnabled(false); + resumeButton.setEnabled(false); + connectButton.setEnabled(false); + } else if (status.equals(ConnectionStatus.CONNECTED)) { + nextButton.setEnabled(false); pauseButton.setEnabled(true); + resumeButton.setEnabled(false); connectButton.setActionCommand(Commands.DISCONNECT); connectButton.setIcon(connectedIcon); + connectButton.setToolTipText("Disconnect from session"); + connectButton.setEnabled(true); } } Modified: java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/EventProcessing.java ============================================================================= --- java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/EventProcessing.java (original) +++ java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/EventProcessing.java Wed Mar 25 14:43:27 2015 @@ -4,6 +4,7 @@ import java.io.File; import java.io.IOException; import java.io.InputStream; +import java.util.ArrayList; import java.util.List; import java.util.logging.Logger; @@ -14,6 +15,9 @@ import org.hps.monitoring.application.model.ConnectionStatus; import org.hps.monitoring.application.model.SteeringType; import org.hps.monitoring.application.util.EtSystemUtil; +import org.hps.monitoring.application.util.PhysicsSyncEventStation; +import org.hps.monitoring.application.util.PreStartEtStation; +import org.hps.monitoring.application.util.RunnableEtStation; import org.hps.monitoring.subsys.et.EtSystemMonitor; import org.hps.monitoring.subsys.et.EtSystemStripCharts; import org.hps.record.LCSimEventBuilder; @@ -24,24 +28,30 @@ import org.hps.record.enums.DataSourceType; import org.hps.record.et.EtConnection; import org.hps.record.evio.EvioDetectorConditionsProcessor; +import org.jlab.coda.et.EtSystem; +import org.jlab.coda.et.exception.EtClosedException; +import org.jlab.coda.et.exception.EtException; +import org.lcsim.conditions.ConditionsListener; import org.lcsim.conditions.ConditionsManager; import org.lcsim.conditions.ConditionsReader; import org.lcsim.util.Driver; /** - * This class encapsulates all of the logic involved with processing events - * and managing the related state and objects within the monitoring application. + * This class encapsulates all of the logic involved with processing events and managing the related + * state and objects within the monitoring application. * * @author Jeremy McCormick <[log in to unmask]> */ class EventProcessing { - + MonitoringApplication application; Logger logger; SessionState sessionState; List<CompositeRecordProcessor> processors; List<Driver> drivers; - + List<ConditionsListener> conditionsListeners; + int stationPosition; + /** * This class is used to organize the objects for an event processing session. */ @@ -51,62 +61,89 @@ CompositeLoop loop; EventProcessingThread processingThread; Thread sessionWatchdogThread; + ThreadGroup stationThreadGroup = new ThreadGroup("Station Threads"); + List<RunnableEtStation> stations = new ArrayList<RunnableEtStation>(); EtConnection connection; } - - /** - * Initialize with reference to the current monitoring application - * and a list of extra processors to add to the loop after - * configuration. + + /** + * Initialize with reference to the current monitoring application and a list of extra + * processors to add to the loop after configuration. * @param application The current monitoring application. * @param processors A list of processors to add after configuration is performed. */ EventProcessing( MonitoringApplication application, - List<CompositeRecordProcessor> processors, - List<Driver> drivers) { + List<CompositeRecordProcessor> processors, + List<Driver> drivers, + List<ConditionsListener> conditionsListeners) { this.application = application; - this.sessionState = new SessionState(); + this.sessionState = new SessionState(); this.logger = MonitoringApplication.logger; this.processors = processors; this.drivers = drivers; + this.conditionsListeners = conditionsListeners; + this.stationPosition = application.configurationModel.getStationPosition(); } + int getNextStationPosition() { + this.stationPosition += 1; + return this.stationPosition; + } + /** * Setup this class from the global configuration. * @param configurationModel The global configuration. */ void setup(ConfigurationModel configurationModel) { - MonitoringApplication.logger.info("setting up LCSim"); + + // Setup LCSim from the configuration. + setupLcsim(configurationModel); + + // Now setup the CompositeLoop. + setupLoop(configurationModel); + } + + /** + * @param configurationModel + */ + private void setupLcsim(ConfigurationModel configurationModel) { + MonitoringApplication.logger.info("setting up lcsim"); // Get steering resource or file as a String parameter. String steering = null; SteeringType steeringType = configurationModel.getSteeringType(); - if (steeringType.equals(SteeringType.FILE)) - try { - steering = configurationModel.getSteeringFile().getCanonicalPath(); - } catch (IOException e) { - throw new RuntimeException(e); - } - else + if (steeringType.equals(SteeringType.FILE)) { + steering = configurationModel.getSteeringFile(); + } else { steering = configurationModel.getSteeringResource(); - - MonitoringApplication.logger.config("Set steering to " + steering + " with type " + (steeringType == SteeringType.RESOURCE ? "RESOURCE" : "FILE")); + } + + MonitoringApplication.logger.config("set steering " + steering + " with type " + (steeringType == SteeringType.RESOURCE ? "RESOURCE" : "FILE")); try { - // Create and the job manager. The conditions manager is instantiated from this call but not configured. + // Create and the job manager. The conditions manager is instantiated from this call but + // not configured. sessionState.jobManager = new JobManager(); - + + // Add conditions listeners after new database conditions manager is initialized from + // job manager. + DatabaseConditionsManager conditionsManager = DatabaseConditionsManager.getInstance(); + for (ConditionsListener conditionsListener : conditionsListeners) { + logger.config("adding conditions listener " + conditionsListener.getClass().getName()); + conditionsManager.addConditionsListener(conditionsListener); + } + if (configurationModel.hasValidProperty(ConfigurationModel.DETECTOR_ALIAS_PROPERTY)) { - // Set a detector alias. + // Set a detector alias. ConditionsReader.addAlias(configurationModel.getDetectorName(), "file://" + configurationModel.getDetectorAlias()); 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! createEventBuilder(configurationModel); - + // Configure the job manager for the XML steering. sessionState.jobManager.setPerformDryRun(true); if (steeringType == SteeringType.RESOURCE) { @@ -114,21 +151,27 @@ } else if (steeringType.equals(SteeringType.FILE)) { setupSteeringFile(steering); } - + + // Set conditions tag. + if (configurationModel.hasValidProperty(ConfigurationModel.CONDITIONS_TAG_PROPERTY) && !configurationModel.getConditionsTag().equals("")) { + logger.config("conditions tag is set to " + configurationModel.getConditionsTag()); + } else { + 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)) { int userRunNumber = configurationModel.getUserRunNumber(); String detectorName = configurationModel.getDetectorName(); - DatabaseConditionsManager conditionsManager = DatabaseConditionsManager.getInstance(); logger.config("setting user run number " + userRunNumber + " with detector " + detectorName); conditionsManager.setDetector(configurationModel.getDetectorName(), userRunNumber); if (configurationModel.hasPropertyKey(ConfigurationModel.FREEZE_CONDITIONS_PROPERTY)) { - // Freeze the conditions system to ignore run numbers from the events. - logger.config("user configured to freeze conditions system from monitoring app"); + // Freeze the conditions system to ignore run numbers from the events. + logger.config("user configured to freeze conditions system"); conditionsManager.freeze(); } else { // Allow run numbers to be picked up from the events. - logger.config("user run number specified but conditions system is NOT frozen"); + logger.config("user run number provided but conditions system is NOT frozen"); conditionsManager.unfreeze(); } } @@ -136,18 +179,15 @@ logger.info("lcsim setup was successful"); } catch (Throwable t) { - // Catch all errors and rethrow them as RuntimeExceptions. + // Catch all errors and re-throw them as RuntimeExceptions. application.errorHandler.setError(t).setMessage("Error setting up LCSim.").printStackTrace().raiseException(); } - - // Now setup the CompositeLoop. - setupLoop(configurationModel); - } - + } + /** * Create the event builder for converting EVIO events to LCSim. */ - void createEventBuilder(ConfigurationModel configurationModel) { + private void createEventBuilder(ConfigurationModel configurationModel) { // Get the class for the event builder. String eventBuilderClassName = configurationModel.getEventBuilderClassName(); @@ -162,12 +202,12 @@ // Add the builder as a listener so it is notified when conditions change. ConditionsManager.defaultInstance().addConditionsListener(sessionState.eventBuilder); } - + /** * Setup the loop from the global configuration. * @param configurationModel The global configuration. */ - void setupLoop(ConfigurationModel configurationModel) { + private void setupLoop(ConfigurationModel configurationModel) { CompositeLoopConfiguration loopConfig = new CompositeLoopConfiguration() .setStopOnEndRun(configurationModel.getDisconnectOnEndRun()) @@ -181,13 +221,12 @@ if (configurationModel.hasValidProperty(ConfigurationModel.MAX_EVENTS_PROPERTY)) { long maxEvents = configurationModel.getMaxEvents(); if (maxEvents > 0L) { - //logger.config("processing will stop after max events: " + maxEvents); loopConfig.setMaxRecords(maxEvents); } } - + // Add all Drivers from the JobManager. - for (Driver driver : sessionState.jobManager.getDriverExecList()) { + for (Driver driver : sessionState.jobManager.getDriverExecList()) { loopConfig.add(driver); logger.config("added Driver " + driver.getName() + " to job"); } @@ -205,30 +244,30 @@ } // Add extra CompositeRecordProcessors to the loop config. - for (CompositeRecordProcessor processor : processors) { - loopConfig.add(processor); + for (CompositeRecordProcessor processor : processors) { + loopConfig.add(processor); logger.config("added extra processor " + processor.getClass().getSimpleName() + " to job"); } - + // Add extra Drivers to the loop config. - for (Driver driver : drivers) { + for (Driver driver : drivers) { loopConfig.add(driver); logger.config("added extra Driver " + driver.getName() + " to job"); } - - // Enable conditions system activation from EVIO event information. + + // Enable conditions system activation from EVIO event data in case the PRESTART is missed. logger.config("added EvioDetectorConditionsProcessor to job with detector " + configurationModel.getDetectorName()); loopConfig.add(new EvioDetectorConditionsProcessor(configurationModel.getDetectorName())); // Create the CompositeLoop with the configuration. - sessionState.loop = new CompositeLoop(loopConfig); - } - + sessionState.loop = new CompositeLoop(loopConfig); + } + /** * Setup a steering file on disk. * @param steering The steering file. */ - void setupSteeringFile(String steering) { + private void setupSteeringFile(String steering) { sessionState.jobManager.setup(new File(steering)); } @@ -237,81 +276,133 @@ * @param steering The steering resource. * @throws IOException if there is a problem setting up or accessing the resource. */ - void setupSteeringResource(String steering) throws IOException { + private void setupSteeringResource(String steering) throws IOException { InputStream is = this.getClass().getClassLoader().getResourceAsStream(steering); if (is == null) throw new IOException("Steering resource is not accessible or does not exist."); sessionState.jobManager.setup(is); is.close(); } - - /** - * Stop the event processing by executing a <code>STOP</code> command on the record loop and - * killing the event processing thread. This is executed after the ET system is disconnected so - * that the event processing does not potentially hang in a call to - * <code>EtSystem.getEvents()</code> forever. - */ + synchronized void stop() { - logger.info("event processing is stopping"); + // Kill session watchdog thread. + killWatchdogThread(); + + // Wake up all ET stations to unblock the system and make sure secondary stations are detached. + //wakeUpEtStations() + // Wake up the primary ET station doing the event processing. + logger.finest("waking up event processing station ..."); + try { + if (sessionState.connection != null) { + if (sessionState.connection.getEtSystem() != null) { + sessionState.connection.getEtSystem().wakeUpAll(sessionState.connection.getEtStation()); + logger.finest("event processing station woken up"); + } + } + } catch (IOException | EtException | EtClosedException e) { + e.printStackTrace(); + } - // Disconnect from ET system. + // Stop the event processing now that ET system is unblocked. + logger.fine("sending STOP command to loop ..."); + sessionState.loop.execute(Command.STOP); + logger.fine("loop got command STOP"); + + // Cleanup the event processing thread since it was told to stop now. + try { + logger.fine("waiting for event processing thread to end ..."); + sessionState.processingThread.join(); + logger.fine("event processing thread ended"); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + // Notify of last error that occurred in event processing. + if (sessionState.loop.getLastError() != null) { + // Log the error. + application.errorHandler.setError(sessionState.loop.getLastError()).log(); + } + + // Invalidate the loop. + sessionState.loop = null; + + // Disconnect from the ET system. disconnect(); - // Is the event processing thread not null? - if (sessionState.processingThread != null) { - - // Is the event processing thread actually still alive? - if (sessionState.processingThread.isAlive()) { - - // Request the event processing loop to execute stop. - sessionState.loop.execute(Command.STOP); - - try { - logger.info("waiting for event processing thread to finish"); - // This should always work, because the ET system is disconnected before this. - sessionState.processingThread.join(); - logger.info("event processing thread finished"); - } catch (InterruptedException e) { - // Don't know when this would ever happen. - e.printStackTrace(); + // Invalidate the event processing object so it is unusable now. + invalidate(); + } + + /** + * Wake up all ET stations associated with event processing. + */ + private void wakeUpEtStations() { + if (sessionState.connection != null) { + logger.fine("waking up ET stations ..."); + + // Wake up secondary ET stations. + for (RunnableEtStation station : sessionState.stations) { + if (station.getEtStation().isUsable()) { + // Wake up the station which will automatically trigger a detach. + try { + logger.finest("waking up " + station.getEtStation().getName() + " ..."); + sessionState.connection.getEtSystem().wakeUpAll(station.getEtStation()); + logger.finest(station.getEtStation().getName() + " woken up"); + } catch (IOException | EtException | EtClosedException e) { + e.printStackTrace(); + } } } - // Notify of last error that occurred in event processing. - if (sessionState.loop.getLastError() != null) { - application.errorHandler.setError(sessionState.loop.getLastError()).log().printStackTrace(); - } - - // Set the event processing thread to null as it is unusable now. - sessionState.processingThread = null; - } - - // Set the loop to null as a new one will be created for next session. - sessionState.loop = null; - - logger.info("event processing stopped"); - } - - /** - * Start event processing on the event processing thread - * and start the watchdog thread. + // Wait for station threads to die after being woken up. + while (sessionState.stationThreadGroup.activeCount() != 0) { + logger.finest("waiting for station threads to die ..."); + Object lock = new Object(); + synchronized (lock) { + try { + lock.wait(500); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + + logger.finest("destroying station thread group"); + sessionState.stationThreadGroup.destroy(); + logger.finest("station thread group destroyed"); + + // Wake up the primary ET station doing the event processing. + logger.finest("waking up event processing station ..."); + try { + sessionState.connection.getEtSystem().wakeUpAll(sessionState.connection.getEtStation()); + logger.finest("event processing station woken up"); + } catch (IOException | EtException | EtClosedException e) { + e.printStackTrace(); + } + + logger.finest("ET stations woken up"); + } + } + + /** + * Start event processing on the event processing thread and start the watchdog thread. */ synchronized void start() { - + logger.fine("event processing threads are starting"); - + // Start the event processing thread. sessionState.processingThread = new EventProcessingThread(sessionState.loop); sessionState.processingThread.start(); - + // Start the watchdog thread which will auto-disconnect when event processing is done. sessionState.sessionWatchdogThread = new SessionWatchdogThread(sessionState.processingThread); sessionState.sessionWatchdogThread.start(); - + logger.fine("started event processing threads"); } - + /** * Notify the event processor to pause processing. */ @@ -323,7 +414,7 @@ } logger.finest("paused"); } - + /** * Get next event if in pause mode. */ @@ -336,7 +427,7 @@ } logger.finest("got next event"); } - + /** * Resume processing events from pause mode. */ @@ -344,19 +435,19 @@ logger.finest("resuming"); if (application.connectionModel.getPaused()) { // Notify event processor to continue. - sessionState.loop.resume(); + sessionState.loop.resume(); application.connectionModel.setPaused(false); } logger.finest("resumed"); } - + /** * Interrupt and join to the processing watchdog thread. */ synchronized void killWatchdogThread() { - logger.fine("killing watchdog thread"); // Is the session watchdog thread not null? if (sessionState.sessionWatchdogThread != null) { + logger.finest("killing watchdog thread ..."); // Is the thread still alive? if (sessionState.sessionWatchdogThread.isAlive()) { // Interrupt the thread which should cause it to stop. @@ -371,24 +462,26 @@ } // Set the thread object to null. sessionState.sessionWatchdogThread = null; - } - logger.fine("watchdog thread killed"); - } - + logger.finest("watchdog thread killed"); + } + } + /** * Cleanup the ET connection. */ synchronized void closeEtConnection() { - logger.fine("closing ET connection"); if (sessionState.connection != null) { + logger.fine("closing ET connection"); if (sessionState.connection.getEtSystem().alive()) { + logger.finest("cleaning up the connection ..."); sessionState.connection.cleanup(); + logger.finest("connection cleanup successful"); } sessionState.connection = null; - } - logger.fine("ET connection closed"); - } - + logger.fine("ET connection closed"); + } + } + /** * True if the processing thread is active. * @return True if processing thread is active. @@ -396,74 +489,109 @@ boolean isActive() { return sessionState.processingThread != null && sessionState.processingThread.isAlive(); } - + /** * Connect to the ET system using the current connection settings. */ - synchronized void connect() throws IOException { - logger.fine("connecting to ET system"); + synchronized void connect() throws IOException { // Setup the network connection if using an ET server. if (usingEtServer()) { // Create a connection to the ET server. try { + logger.fine("connecting to ET system ..."); + + // Create the main ET system connection. createEtConnection(); + + // Add an attachment that listens for DAQ configuration changes via physics SYNC events. + //createPhysicsSyncStation(); + + // Add an attachment that listens for PRESTART events. + //createPreStartStation(); + } catch (Exception e) { throw new IOException(e); } + + logger.fine("ET system is connected"); } else { // This is when a direct file source is used and ET is not needed. application.connectionModel.setConnectionStatus(ConnectionStatus.CONNECTED); } - logger.fine("ET system is connected"); - } - + + } + /** * True if using an ET server. * @return True if using an ET server. */ boolean usingEtServer() { return application.configurationModel.getDataSourceType().equals(DataSourceType.ET_SERVER); - } - - /** - * Create a connection to an ET system using current parameters from the GUI. If successful, the - * application's ConnectionStatus is changed to CONNECTED. - */ - void createEtConnection() { + } + + /** + * Create a connection to an ET system using current parameters from the GUI. + */ + synchronized void createEtConnection() { // Setup connection to ET system. sessionState.connection = EtSystemUtil.createEtConnection(application.configurationModel); if (sessionState.connection != null) { // Set status to connected as there is now a live ET connection. application.connectionModel.setConnectionStatus(ConnectionStatus.CONNECTED); - //logger.info("successfully connected to ET system"); } else { application.errorHandler.setError(new RuntimeException("Failed to create ET connection.")).log().printStackTrace().raiseException(); } } + + /** + * Create the ET that listens for DAQ configuration change via SYNC events. + */ + private void createPhysicsSyncStation() { + logger.fine("creating physics SYNC station ..."); + PhysicsSyncEventStation configStation = new PhysicsSyncEventStation( + this.sessionState.connection.getEtSystem(), + this.sessionState.connection.getEtStation().getName() + "_PhysicsSync", + getNextStationPosition()); + sessionState.stations.add(configStation); + new Thread(sessionState.stationThreadGroup, configStation).start(); + logger.fine("physics SYNC station created"); + } /** - * Disconnect from the current ET session with a particular status. + * Create the ET station that listens for GO events in order to initialize the conditions system. + */ + private void createPreStartStation() { + logger.fine("creating PRESTART station ..."); + String detectorName = this.application.configurationModel.getDetectorName(); + EtSystem system = this.sessionState.connection.getEtSystem(); + String stationName = this.sessionState.connection.getEtStation().getName() + "_PreStart"; + int order = getNextStationPosition(); + PreStartEtStation preStartStation = new PreStartEtStation( + detectorName, + system, + stationName, + order); + sessionState.stations.add(preStartStation); + new Thread(sessionState.stationThreadGroup, preStartStation).start(); + logger.fine("PRESTART station created"); + } + + /** + * Disconnect from the current ET session. * @param status The connection status. */ synchronized void disconnect() { - - logger.fine("disconnecting"); - - // Kill the session watch dog thread. - killWatchdogThread(); - + // Cleanup the ET connection. closeEtConnection(); - + // Change application state to disconnected. application.connectionModel.setConnectionStatus(ConnectionStatus.DISCONNECTED); - - logger.fine("disconnected"); - } - - /** - * This class notifies the application to disconnect if the event processing thread completes. + } + + /** + * This class notifies the application to disconnect if the event processing thread completes. */ class SessionWatchdogThread extends Thread { @@ -472,19 +600,39 @@ SessionWatchdogThread(Thread processingThread) { this.processingThread = processingThread; } - + public void run() { try { - // When the event processing thread finishes, the session should be stopped and a - // disconnect should occur. + // This thread waits on the event processing thread to die. processingThread.join(); - + // Activate a disconnect using the ActionEvent which is used by the disconnect button. + logger.finest("processing thread ended so automatic disconnect is happening"); application.actionPerformed(new ActionEvent(Thread.currentThread(), 0, Commands.DISCONNECT)); - + } catch (InterruptedException e) { + logger.finest("SessionWatchdogThread got interrupted"); // This happens when the thread is interrupted by the user pressing the disconnect button. - } - } + } + } + } + + void invalidate() { + + this.application = null; + this.conditionsListeners = null; + this.drivers = null; + this.logger = null; + this.processors = null; + + this.sessionState.jobManager = null; + this.sessionState.eventBuilder = null; + this.sessionState.loop = null; + this.sessionState.processingThread = null; + this.sessionState.sessionWatchdogThread = null; + this.sessionState.stationThreadGroup = null; + this.sessionState.stations = null; + this.sessionState.connection = null; + this.sessionState = null; } } Modified: java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/JobSettingsPanel.java ============================================================================= --- java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/JobSettingsPanel.java (original) +++ java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/JobSettingsPanel.java Wed Mar 25 14:43:27 2015 @@ -1,7 +1,4 @@ package org.hps.monitoring.application; - -import static org.hps.monitoring.application.Commands.*; -import static org.hps.monitoring.application.model.ConfigurationModel.*; import java.awt.GridBagLayout; import java.awt.Insets; @@ -18,11 +15,13 @@ import javax.swing.JComboBox; import javax.swing.JFileChooser; import javax.swing.JTextField; +import javax.swing.border.EmptyBorder; import javax.swing.filechooser.FileFilter; import org.hps.monitoring.application.model.ConfigurationModel; import org.hps.monitoring.application.model.SteeringType; import org.hps.monitoring.application.util.ResourceUtil; +import org.hps.record.enums.ProcessingStage; import org.jdom.Document; import org.jdom.Element; import org.jdom.JDOMException; @@ -32,22 +31,26 @@ * This is the GUI panel for setting job parameters. It is connected to the global configuration via * a {@link org.hps.monitoring.model.ConfigurationModel} object. */ +// FIXME: Combo boxes should use explicit types. class JobSettingsPanel extends AbstractFieldsPanel { private JComboBox<?> steeringResourcesComboBox; private JTextField steeringFileField; private JComboBox<?> steeringTypeComboBox; + private JComboBox<ProcessingStage> processingStageComboBox; private JComboBox<String> detectorNameComboBox; private JTextField detectorAliasField; + private JComboBox<String> conditionsTagComboBox; private JComboBox<String> eventBuilderComboBox; private JTextField userRunNumberField; private JCheckBox freezeConditionsCheckBox; private JTextField maxEventsField; private JCheckBox disconnectOnErrorCheckBox; - private JCheckBox disconnectOnEndRunCheckBox; - private JTextField logFileNameField; + private JCheckBox disconnectOnEndRunCheckBox; private JComboBox<?> logLevelComboBox; private JCheckBox logToFileCheckbox; + private JTextField logFileNameField; + private JTextField aidaServerNameField; // The package where steering resources must be located. static final String STEERING_PACKAGE = "org/hps/steering/monitoring/"; @@ -68,17 +71,22 @@ /** * Class constructor. */ - JobSettingsPanel() { - - super(new Insets(4, 2, 2, 4), true); - + JobSettingsPanel(ConfigurationModel model) { + + super(new Insets(5, 3, 3, 5), true); + + setBorder(new EmptyBorder(10, 10, 10, 10)); + setLayout(new GridBagLayout()); + + // Listen on changes to the configuration which will then be automatically pushed to the GUI. + model.addPropertyChangeListener(this); steeringResourcesComboBox = addComboBoxMultiline("Steering File Resource", ResourceUtil.findSteeringResources(STEERING_PACKAGE)); - steeringResourcesComboBox.setActionCommand(STEERING_RESOURCE_CHANGED); + steeringResourcesComboBox.setActionCommand(Commands.STEERING_RESOURCE_CHANGED); steeringResourcesComboBox.addActionListener(this); - steeringFileField = addField("Steering File", 35); + steeringFileField = addField("Steering File", 50); steeringFileField.addPropertyChangeListener("value", this); JButton steeringFileButton = addButton("Select Steering File"); @@ -86,15 +94,20 @@ steeringFileButton.addActionListener(this); steeringTypeComboBox = addComboBox("Steering Type", new String[] { SteeringType.RESOURCE.name(), SteeringType.FILE.name() }); - steeringTypeComboBox.setActionCommand(STEERING_TYPE_CHANGED); + steeringTypeComboBox.setActionCommand(Commands.STEERING_TYPE_CHANGED); steeringTypeComboBox.addActionListener(this); + processingStageComboBox = new JComboBox<ProcessingStage>(ProcessingStage.values()); + addComponent("Processing Stage", processingStageComboBox); + processingStageComboBox.setActionCommand(Commands.PROCESSING_STAGE_CHANGED); + processingStageComboBox.addActionListener(this); + detectorNameComboBox = addComboBox("Detector Name", ResourceUtil.findDetectorNames()); - detectorNameComboBox.setActionCommand(DETECTOR_NAME_CHANGED); + detectorNameComboBox.setActionCommand(Commands.DETECTOR_NAME_CHANGED); detectorNameComboBox.addActionListener(this); detectorAliasField = addField("Detector Resources Directory", "", 35, true); - detectorAliasField.setActionCommand(DETECTOR_ALIAS_CHANGED); + detectorAliasField.setActionCommand(Commands.DETECTOR_ALIAS_CHANGED); detectorAliasField.addPropertyChangeListener("value", this); detectorAliasField.addActionListener(this); @@ -102,15 +115,23 @@ compactXmlButton.setActionCommand(Commands.CHOOSE_COMPACT_FILE); compactXmlButton.addActionListener(this); - userRunNumberField = addField("User Run Number", "", 10, false); + userRunNumberField = addField("User Run Number", "", 10, true); userRunNumberField.addPropertyChangeListener("value", this); - userRunNumberField.setActionCommand(USER_RUN_NUMBER_CHANGED); + userRunNumberField.setActionCommand(Commands.USER_RUN_NUMBER_CHANGED); userRunNumberField.setEnabled(true); userRunNumberField.setEditable(true); - + + conditionsTagComboBox = addComboBox("Conditions Tag", ResourceUtil.getConditionsTags()); + conditionsTagComboBox.addItem(""); + conditionsTagComboBox.setSelectedItem(""); + conditionsTagComboBox.setActionCommand(Commands.CONDITIONS_TAG_CHANGED); + conditionsTagComboBox.addActionListener(this); + conditionsTagComboBox.setEditable(false); + conditionsTagComboBox.setEnabled(true); + freezeConditionsCheckBox = addCheckBox("Freeze detector conditions", false, true); freezeConditionsCheckBox.addActionListener(this); - freezeConditionsCheckBox.setActionCommand(FREEZE_CONDITIONS_CHANGED); + freezeConditionsCheckBox.setActionCommand(Commands.FREEZE_CONDITIONS_CHANGED); maxEventsField = addField("Max Events", "-1", 10, false); maxEventsField.addPropertyChangeListener("value", this); @@ -119,15 +140,15 @@ eventBuilderComboBox = addComboBox("LCSim Event Builder", ResourceUtil.findEventBuilderClassNames()); eventBuilderComboBox.setSize(24, eventBuilderComboBox.getPreferredSize().height); - eventBuilderComboBox.setActionCommand(EVENT_BUILDER_CHANGED); + eventBuilderComboBox.setActionCommand(Commands.EVENT_BUILDER_CHANGED); eventBuilderComboBox.addActionListener(this); disconnectOnErrorCheckBox = addCheckBox("Disconnect on error", false, true); - disconnectOnErrorCheckBox.setActionCommand(DISCONNECT_ON_ERROR_CHANGED); + disconnectOnErrorCheckBox.setActionCommand(Commands.DISCONNECT_ON_ERROR_CHANGED); disconnectOnErrorCheckBox.addActionListener(this); disconnectOnEndRunCheckBox = addCheckBox("Disconnect on end run", false, true); - disconnectOnEndRunCheckBox.setActionCommand(DISCONNECT_ON_END_RUN_CHANGED); + disconnectOnEndRunCheckBox.setActionCommand(Commands.DISCONNECT_ON_END_RUN_CHANGED); disconnectOnEndRunCheckBox.addActionListener(this); logLevelComboBox = addComboBox("Log Level", LOG_LEVELS); @@ -136,11 +157,12 @@ logToFileCheckbox = addCheckBox("Log to File", false, false); logToFileCheckbox.setEnabled(false); - logToFileCheckbox.setActionCommand(LOG_TO_FILE_CHANGED); - logToFileCheckbox.addActionListener(this); - - logFileNameField = addField("Log File", "", "Full path to log file.", 30, false); - logFileNameField.addPropertyChangeListener("value", this); + + logFileNameField = addField("Log File Name", "", "Full path to log file", 50, false); + logFileNameField.setEditable(false); + + aidaServerNameField = addField("AIDA Server Name", "", "Name of AIDA server", 30, true); + aidaServerNameField.addPropertyChangeListener("value", this); } @Override @@ -152,8 +174,6 @@ * Attaches the ActionListener from the main app to specific GUI components in this class. */ public void addActionListener(ActionListener listener) { - logFileNameField.addActionListener(listener); - logToFileCheckbox.addActionListener(listener); steeringResourcesComboBox.addActionListener(listener); freezeConditionsCheckBox.addActionListener(listener); } @@ -171,6 +191,7 @@ try { checkSteeringFile(file); configurationModel.setSteeringFile(file.getCanonicalPath()); + configurationModel.setSteeringType(SteeringType.FILE); } catch (IOException | JDOMException e) { throw new RuntimeException("Error parsing the selected steering file.", e); } @@ -234,53 +255,52 @@ @Override public void actionPerformed(ActionEvent event) { - - //System.out.println("JobSettingsPanel.actionPerformed - " + event.getActionCommand()); - //System.out.println(" source: " + event.getSource()); - try { configurationModel.removePropertyChangeListener(this); + String command = event.getActionCommand(); if (event.getActionCommand().equals(Commands.CHOOSE_STEERING_FILE)) { chooseSteeringFile(); } else if (event.getActionCommand().equals(Commands.CHOOSE_COMPACT_FILE)) { chooseCompactFile(); - } else if (DISCONNECT_ON_ERROR_CHANGED.equals(event.getActionCommand())) { + } else if (Commands.DISCONNECT_ON_ERROR_CHANGED.equals(command)) { configurationModel.setDisconnectOnError(disconnectOnErrorCheckBox.isSelected()); - } else if (DISCONNECT_ON_END_RUN_CHANGED.equals(event.getActionCommand())) { + } else if (Commands.DISCONNECT_ON_END_RUN_CHANGED.equals(command)) { configurationModel.setDisconnectOnEndRun(disconnectOnEndRunCheckBox.isSelected()); - } else if (STEERING_TYPE_CHANGED.equals(event.getActionCommand())) { + } else if (Commands.STEERING_TYPE_CHANGED.equals(command)) { configurationModel.setSteeringType(SteeringType.valueOf((String) steeringTypeComboBox.getSelectedItem())); - } else if (STEERING_RESOURCE_CHANGED.equals(event.getActionCommand())) { + } else if (Commands.STEERING_RESOURCE_CHANGED.equals(command)) { configurationModel.setSteeringResource((String) steeringResourcesComboBox.getSelectedItem()); - } else if (LOG_TO_FILE_CHANGED.equals(event.getActionCommand())) { - configurationModel.setLogToFile(logToFileCheckbox.isSelected()); - } else if (LOG_LEVEL_CHANGED.equals(event.getActionCommand())) { + } else if (Commands.LOG_LEVEL_CHANGED.equals(command)) { configurationModel.setLogLevel(Level.parse((String) logLevelComboBox.getSelectedItem())); - } else if (EVENT_BUILDER_CHANGED.equals(event.getActionCommand())) { + } else if (Commands.EVENT_BUILDER_CHANGED.equals(command)) { configurationModel.setEventBuilderClassName((String) eventBuilderComboBox.getSelectedItem()); - } else if (DETECTOR_NAME_CHANGED.equals(event.getActionCommand())) { + } else if (Commands.DETECTOR_NAME_CHANGED.equals(command)) { try { configurationModel.setDetectorName((String) detectorNameComboBox.getSelectedItem()); } catch (Exception exception) { exception.printStackTrace(); } - } else if (FREEZE_CONDITIONS_CHANGED.equals(event.getActionCommand())) { - if (configurationModel.hasPropertyKey(USER_RUN_NUMBER_PROPERTY) && configurationModel.getUserRunNumber() != null) { + } else if (Commands.FREEZE_CONDITIONS_CHANGED.equals(command)) { + if (configurationModel.hasPropertyKey(ConfigurationModel.USER_RUN_NUMBER_PROPERTY) && configurationModel.getUserRunNumber() != null) { configurationModel.setFreezeConditions(freezeConditionsCheckBox.isSelected()); } else { throw new IllegalArgumentException("Conditions system may only be frozen if there is a valid user run number."); } - } else if (DETECTOR_ALIAS_CHANGED.equals(event.getActionCommand())) { + } else if (Commands.DETECTOR_ALIAS_CHANGED.equals(command)) { configurationModel.setDetectorName(detectorAliasField.getText()); - } + } else if (Commands.CONDITIONS_TAG_CHANGED.equals(command)) { + configurationModel.setConditionsTag((String) conditionsTagComboBox.getSelectedItem()); + } else if (Commands.PROCESSING_STAGE_CHANGED.equals(command)) { + configurationModel.setProcessingStage((ProcessingStage) processingStageComboBox.getSelectedItem()); + } } finally { configurationModel.addPropertyChangeListener(this); } } /** - * Updates the configuration with changes from the GUI component values. The changes from the - * GUI are distinguishable by their component object. + * Updates the configuration with changes from the GUI component values. + * The changes from the GUI are distinguishable by their component object. */ @Override public void propertyChange(PropertyChangeEvent evt) { @@ -289,23 +309,18 @@ Object source = evt.getSource(); if (source == steeringFileField) { configurationModel.setSteeringFile(steeringFileField.getText()); - } else if (source == logFileNameField) { - configurationModel.setLogFileName(logFileNameField.getText()); } else if (source == userRunNumberField) { // Is run number being reset to null or empty? if (userRunNumberField.getText() == null || userRunNumberField.getText().isEmpty()) { - // System.out.println("resetting user run number back to null"); // Update the model to null user run number and do not freeze the conditions system. configurationModel.setUserRunNumber(null); configurationModel.setFreezeConditions(false); } else { try { - // System.out.println("setting new user run number " + evt.getNewValue()); // Parse the run number. Need to catch errors because it might be an invalid string. int userRunNumber = Integer.parseInt(userRunNumberField.getText()); configurationModel.setUserRunNumber(userRunNumber); configurationModel.setFreezeConditions(true); - System.out.println("successfully set run number to userRunNumber"); } catch (NumberFormatException e) { System.out.println("bad number format so ignoring user run number " + evt.getNewValue()); userRunNumberField.setText((String) evt.getOldValue()); @@ -314,8 +329,26 @@ } } else if (source == maxEventsField) { configurationModel.setMaxEvents(Long.parseLong(maxEventsField.getText())); - System.out.println("setMaxEvents - " + configurationModel.getMaxEvents()); - } + //System.out.println("setMaxEvents - " + configurationModel.getMaxEvents()); + } else if (source == aidaServerNameField) { + configurationModel.setAIDAServerName(aidaServerNameField.getText()); + } else if (evt.getPropertyName().equals(ConfigurationModel.LOG_TO_FILE_PROPERTY)) { + // This is getting the log to file prop change from the ConfigurationModel to update a read only component. + Boolean logToFile = (Boolean) evt.getNewValue(); + if (logToFile != null) { + logToFileCheckbox.setSelected(logToFile); + } + } else if (evt.getPropertyName().equals(ConfigurationModel.LOG_FILE_NAME_PROPERTY)) { + // This is getting the log file name prop change from the ConfigurationModel to update a read only component. + String logFileName = (String) evt.getNewValue(); + if (logFileName != null && logFileName.length() > 0) { + logFileNameField.setText(logFileName); + } else { + logFileNameField.setText(""); + } + } else if (evt.getPropertyName().equals(ConfigurationModel.CONDITIONS_TAG_PROPERTY)) { + conditionsTagComboBox.setSelectedItem(evt.getNewValue()); + } } finally { configurationModel.addPropertyChangeListener(this); } @@ -328,57 +361,56 @@ private class JobSettingsChangeListener implements PropertyChangeListener { @Override public void propertyChange(PropertyChangeEvent evt) { - //System.out.println("JobSettingsChangeListener.propertyChange"); - //System.out.println(" src: " + evt.getSource()); - //System.out.println(" propName: " + evt.getPropertyName()); - //System.out.println(" oldValue: " + evt.getOldValue()); - //System.out.println(" newValue: " + evt.getNewValue()); - //System.out.println(" propId: " + evt.getPropagationId()); if (evt.getSource() instanceof ConfigurationModel) { Object value = evt.getNewValue(); + String property = evt.getPropertyName(); configurationModel.removePropertyChangeListener(this); try { - if (evt.getPropertyName().equals(DETECTOR_NAME_PROPERTY)) { + if (property.equals(ConfigurationModel.DETECTOR_NAME_PROPERTY)) { detectorNameComboBox.setSelectedItem((String) value); - } else if (evt.getPropertyName().equals(DETECTOR_ALIAS_PROPERTY)) { + } else if (property.equals(ConfigurationModel.DETECTOR_ALIAS_PROPERTY)) { detectorAliasField.setText((String) value); - } else if (evt.getPropertyName().equals(DISCONNECT_ON_ERROR_PROPERTY)) { + } else if (property.equals(ConfigurationModel.DISCONNECT_ON_ERROR_PROPERTY)) { disconnectOnErrorCheckBox.setSelected((Boolean) value); - } else if (evt.getPropertyName().equals(DISCONNECT_ON_END_RUN_PROPERTY)) { + } else if (property.equals(ConfigurationModel.DISCONNECT_ON_END_RUN_PROPERTY)) { disconnectOnEndRunCheckBox.setSelected((Boolean) value); - } else if (evt.getPropertyName().equals(EVENT_BUILDER_PROPERTY)) { + } else if (property.equals(ConfigurationModel.EVENT_BUILDER_PROPERTY)) { eventBuilderComboBox.setSelectedItem((String) value); - } else if (evt.getPropertyName().equals(LOG_FILE_NAME_PROPERTY)) { + } else if (property.equals(ConfigurationModel.LOG_FILE_NAME_PROPERTY)) { logFileNameField.setText((String) value); - } else if (evt.getPropertyName().equals(LOG_LEVEL_PROPERTY)) { + } else if (property.equals(ConfigurationModel.LOG_LEVEL_PROPERTY)) { logLevelComboBox.setSelectedItem(value.toString()); - } else if (evt.getPropertyName().equals(LOG_TO_FILE_PROPERTY)) { + } else if (property.equals(ConfigurationModel.LOG_TO_FILE_PROPERTY)) { logToFileCheckbox.setSelected((Boolean) value); - } else if (evt.getPropertyName().equals(STEERING_TYPE_PROPERTY)) { + } else if (property.equals(ConfigurationModel.STEERING_TYPE_PROPERTY)) { steeringTypeComboBox.setSelectedIndex(((SteeringType) value).ordinal()); - } else if (evt.getPropertyName().equals(STEERING_FILE_PROPERTY)) { + } else if (property.equals(ConfigurationModel.STEERING_FILE_PROPERTY)) { if (value != null) { - steeringFileField.setText((String) value); + steeringFileField.setText((String) evt.getNewValue()); } else { // A null value here is actually okay and means this field should be reset to have no value. steeringFileField.setText(null); } - } else if (evt.getPropertyName().equals(STEERING_RESOURCE_PROPERTY)) { + } else if (property.equals(ConfigurationModel.STEERING_RESOURCE_PROPERTY)) { steeringResourcesComboBox.setSelectedItem(value); - } else if (evt.getPropertyName().equals(USER_RUN_NUMBER_PROPERTY)) { + } else if (property.equals(ConfigurationModel.USER_RUN_NUMBER_PROPERTY)) { if (value != null) { userRunNumberField.setText(Integer.toString((int) value)); } else { userRunNumberField.setText(null); } - } else if (evt.getPropertyName().equals(FREEZE_CONDITIONS_PROPERTY)) { + } else if (property.equals(ConfigurationModel.FREEZE_CONDITIONS_PROPERTY)) { if (value != null) { freezeConditionsCheckBox.setSelected((Boolean) value); } - } else if (evt.getPropertyName().equals(MAX_EVENTS_PROPERTY)) { + } else if (property.equals(ConfigurationModel.MAX_EVENTS_PROPERTY)) { if (value != null) { maxEventsField.setText(value.toString()); } + } else if (property.equals(ConfigurationModel.PROCESSING_STAGE_PROPERTY)) { + processingStageComboBox.setSelectedItem(evt.getNewValue()); + } else if (property.equals(ConfigurationModel.AIDA_SERVER_NAME_PROPERTY)) { + aidaServerNameField.setText((String) evt.getNewValue()); } } finally { configurationModel.addPropertyChangeListener(this); Modified: java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/LogLevelFilterComboBox.java ============================================================================= --- java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/LogLevelFilterComboBox.java (original) +++ java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/LogLevelFilterComboBox.java Wed Mar 25 14:43:27 2015 @@ -13,10 +13,10 @@ import org.hps.monitoring.application.model.ConfigurationModel; /** - * + * This is a combo box used to filter the log table messages by level. * @author Jeremy McCormick <[log in to unmask]> */ -public class LogLevelFilterComboBox extends JComboBox<Level> implements ActionListener, PropertyChangeListener { +class LogLevelFilterComboBox extends JComboBox<Level> implements ActionListener, PropertyChangeListener { ConfigurationModel configurationModel; Modified: java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/LogPanel.java ============================================================================= --- java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/LogPanel.java (original) +++ java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/LogPanel.java Wed Mar 25 14:43:27 2015 @@ -17,11 +17,16 @@ * This is a simple GUI component for the log table and its controls. * @author Jeremy McCormick <[log in to unmask]> */ -public class LogPanel extends JPanel { +class LogPanel extends JPanel{ LogTable logTable; + LogLevelFilterComboBox logFilterComboBox; + + ConfigurationModel configurationModel; LogPanel(ConfigurationModel configurationModel, ActionListener listener) { + + this.configurationModel = configurationModel; setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS)); @@ -31,8 +36,8 @@ controlsPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 10, 5)); JLabel label = new JLabel("Log Level Filter"); - LogLevelFilterComboBox logFilterComboBox = new LogLevelFilterComboBox(configurationModel); - logFilterComboBox.setToolTipText("Messages below this level will be filtered out."); + logFilterComboBox = new LogLevelFilterComboBox(configurationModel); + logFilterComboBox.setToolTipText("Messages below this level will be filtered out."); controlsPanel.add(label); controlsPanel.add(logFilterComboBox); @@ -51,5 +56,5 @@ add(controlsPanel, BorderLayout.PAGE_START); add(tablePane, BorderLayout.PAGE_END); - } + } } Modified: java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/LogTable.java ============================================================================= --- java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/LogTable.java (original) +++ java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/LogTable.java Wed Mar 25 14:43:27 2015 @@ -30,7 +30,7 @@ Level filterLevel = Level.ALL; - final static SimpleDateFormat formatter = new SimpleDateFormat("MMMM-dd-yyyy HH:mm:ss.SSS"); + final static SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); LogTable(ConfigurationModel configurationModel) { configurationModel.addPropertyChangeListener(this); @@ -132,5 +132,5 @@ filterLevel = (Level) event.getNewValue(); model.fireTableDataChanged(); } - } + } } Modified: java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/Main.java ============================================================================= --- java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/Main.java (original) +++ java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/Main.java Wed Mar 25 14:43:27 2015 @@ -10,7 +10,6 @@ import org.apache.commons.cli.ParseException; import org.apache.commons.cli.PosixParser; import org.hps.monitoring.application.model.Configuration; - /** * This is the front-end for running the monitoring app via a {@link #main(String[])} method. Modified: java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/MenuBar.java ============================================================================= --- java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/MenuBar.java (original) +++ java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/MenuBar.java Wed Mar 25 14:43:27 2015 @@ -1,18 +1,4 @@ package org.hps.monitoring.application; - -import static org.hps.monitoring.application.Commands.EXIT; -import static org.hps.monitoring.application.Commands.CLOSE_FILE; -import static org.hps.monitoring.application.Commands.OPEN_FILE; -import static org.hps.monitoring.application.Commands.CLEAR_PLOTS; -import static org.hps.monitoring.application.Commands.SAVE_PLOTS; -import static org.hps.monitoring.application.Commands.LOAD_SETTINGS; -import static org.hps.monitoring.application.Commands.LOAD_DEFAULT_SETTINGS; -import static org.hps.monitoring.application.Commands.SAVE_SCREENSHOT; -import static org.hps.monitoring.application.Commands.SAVE_SETTINGS; -import static org.hps.monitoring.application.Commands.SHOW_SETTINGS; -import static org.hps.monitoring.application.Commands.DEFAULT_WINDOW; -import static org.hps.monitoring.application.Commands.MAXIMIZE_WINDOW; -import static org.hps.monitoring.application.Commands.MINIMIZE_WINDOW; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; @@ -39,37 +25,39 @@ JMenuItem closeFileItem; JMenuItem openFileItem; JMenu settingsMenu; - ConfigurationModel configurationModel; + JMenuItem logItem; + JMenuItem serverItem; + ConfigurationModel configurationModel; MenuBar(ConfigurationModel configurationModel, ConnectionStatusModel connectionModel, ActionListener listener) { - - // Do not need to listen for changes on this model. - this.configurationModel = configurationModel; + + this.configurationModel = configurationModel; + this.configurationModel.addPropertyChangeListener(this); // Need to listen for connection status changes. - connectionModel.addPropertyChangeListener(this); - + connectionModel.addPropertyChangeListener(this); + JMenu fileMenu = new JMenu("File"); fileMenu.setMnemonic(KeyEvent.VK_F); add(fileMenu); openFileItem = new JMenuItem("Open File ..."); openFileItem.setMnemonic(KeyEvent.VK_P); - openFileItem.setActionCommand(OPEN_FILE); + openFileItem.setActionCommand(Commands.OPEN_FILE); openFileItem.addActionListener(listener); openFileItem.setToolTipText("Open an EVIO or LCIO data file"); fileMenu.add(openFileItem); closeFileItem = new JMenuItem("Close File"); closeFileItem.setMnemonic(KeyEvent.VK_C); - closeFileItem.setActionCommand(CLOSE_FILE); + closeFileItem.setActionCommand(Commands.CLOSE_FILE); closeFileItem.addActionListener(listener); closeFileItem.setToolTipText("Close the current file data source"); fileMenu.add(closeFileItem); JMenuItem exitItem = new JMenuItem("Exit"); exitItem.setMnemonic(KeyEvent.VK_X); - exitItem.setActionCommand(EXIT); + exitItem.setActionCommand(Commands.EXIT); exitItem.addActionListener(listener); exitItem.setToolTipText("Exit from the application"); fileMenu.add(exitItem); @@ -80,7 +68,7 @@ JMenuItem settingsItem = new JMenuItem("Open Settings Window ..."); settingsItem.setMnemonic(KeyEvent.VK_O); - settingsItem.setActionCommand(SHOW_SETTINGS); + settingsItem.setActionCommand(Commands.SHOW_SETTINGS); settingsItem.addActionListener(listener); settingsItem.setToolTipText("Show settings dialog"); settingsMenu.add(settingsItem); @@ -88,21 +76,21 @@ JMenuItem loadConfigItem = new JMenuItem("Load Settings ..."); loadConfigItem.addActionListener(listener); loadConfigItem.setMnemonic(KeyEvent.VK_L); - loadConfigItem.setActionCommand(LOAD_SETTINGS); + loadConfigItem.setActionCommand(Commands.LOAD_SETTINGS); loadConfigItem.setToolTipText("Load settings from a properties file"); settingsMenu.add(loadConfigItem); JMenuItem saveConfigItem = new JMenuItem("Save Settings ..."); saveConfigItem.addActionListener(listener); saveConfigItem.setMnemonic(KeyEvent.VK_S); - saveConfigItem.setActionCommand(SAVE_SETTINGS); + saveConfigItem.setActionCommand(Commands.SAVE_SETTINGS); saveConfigItem.setToolTipText("Save configuration to a properties file"); settingsMenu.add(saveConfigItem); JMenuItem defaultSettingsItem = new JMenuItem("Load Default Settings"); defaultSettingsItem.addActionListener(listener); defaultSettingsItem.setMnemonic(KeyEvent.VK_D); - defaultSettingsItem.setActionCommand(LOAD_DEFAULT_SETTINGS); + defaultSettingsItem.setActionCommand(Commands.LOAD_DEFAULT_SETTINGS); defaultSettingsItem.setToolTipText("Load the default settings"); settingsMenu.add(defaultSettingsItem); @@ -112,7 +100,7 @@ JMenuItem savePlotsItem = new JMenuItem("Save Plots ..."); savePlotsItem.setMnemonic(KeyEvent.VK_S); - savePlotsItem.setActionCommand(SAVE_PLOTS); + savePlotsItem.setActionCommand(Commands.SAVE_PLOTS); savePlotsItem.addActionListener(listener); savePlotsItem.setEnabled(true); savePlotsItem.setToolTipText("Save plots to AIDA file"); @@ -120,7 +108,7 @@ JMenuItem clearPlotsItem = new JMenuItem("Clear plots"); clearPlotsItem.setMnemonic(KeyEvent.VK_C); - clearPlotsItem.setActionCommand(CLEAR_PLOTS); + clearPlotsItem.setActionCommand(Commands.CLEAR_PLOTS); clearPlotsItem.addActionListener(listener); clearPlotsItem.setEnabled(true); clearPlotsItem.setToolTipText("Clear the AIDA plots"); @@ -132,19 +120,35 @@ JMenuItem screenshotItem = new JMenuItem("Save Screenshot ..."); screenshotItem.setMnemonic(KeyEvent.VK_S); - screenshotItem.setActionCommand(SAVE_SCREENSHOT); + screenshotItem.setActionCommand(Commands.SAVE_SCREENSHOT); screenshotItem.addActionListener(listener); screenshotItem.setEnabled(true); screenshotItem.setToolTipText("Save a screenshot to a graphics file"); toolsMenu.add(screenshotItem); + logItem = new JMenuItem("Log to File ..."); + logItem.setMnemonic(KeyEvent.VK_R); + logItem.setActionCommand(Commands.LOG_TO_FILE); + logItem.addActionListener(listener); + logItem.setEnabled(true); + logItem.setToolTipText("Redirect System.out to a file instead of terminal"); + toolsMenu.add(logItem); + + serverItem = new JMenuItem("Start AIDA Server ..."); + serverItem.setMnemonic(KeyEvent.VK_A); + serverItem.setActionCommand(Commands.START_AIDA_SERVER); + serverItem.setEnabled(true); + serverItem.setToolTipText("Start AIDA RMI Server"); + serverItem.addActionListener(listener); + toolsMenu.add(serverItem); + JMenu windowMenu = new JMenu("Window"); windowMenu.setMnemonic(KeyEvent.VK_W); add(windowMenu); JMenuItem maximizeItem = new JMenuItem("Maximize"); maximizeItem.setMnemonic(KeyEvent.VK_M); - maximizeItem.setActionCommand(MAXIMIZE_WINDOW); + maximizeItem.setActionCommand(Commands.MAXIMIZE_WINDOW); maximizeItem.addActionListener(listener); maximizeItem.setEnabled(true); maximizeItem.setToolTipText("Maximize the application window"); @@ -152,7 +156,7 @@ JMenuItem minimizeItem = new JMenuItem("Minimize"); minimizeItem.setMnemonic(KeyEvent.VK_I); - minimizeItem.setActionCommand(MINIMIZE_WINDOW); + minimizeItem.setActionCommand(Commands.MINIMIZE_WINDOW); minimizeItem.addActionListener(listener); minimizeItem.setEnabled(true); minimizeItem.setToolTipText("Minimize the application window"); @@ -160,68 +164,38 @@ JMenuItem defaultsItem = new JMenuItem("Restore Defaults"); defaultsItem.setMnemonic(KeyEvent.VK_D); - defaultsItem.setActionCommand(DEFAULT_WINDOW); + defaultsItem.setActionCommand(Commands.DEFAULT_WINDOW); defaultsItem.addActionListener(listener); defaultsItem.setEnabled(true); defaultsItem.setToolTipText("Restore the window defaults"); - windowMenu.add(defaultsItem); - - /* - - JMenu logMenu = new JMenu("Log"); - logMenu.setMnemonic(KeyEvent.VK_L); - add(logMenu); - - logItem = new JMenuItem("Redirect to File ..."); - logItem.setMnemonic(KeyEvent.VK_F); - logItem.setActionCommand(CHOOSE_LOG_FILE); - //logItem.addActionListener(this); - logItem.setEnabled(true); - logItem.setToolTipText("Redirect std out and err to a file."); - logMenu.add(logItem); - - terminalItem = new JMenuItem("Redirect to Terminal"); - terminalItem.setMnemonic(KeyEvent.VK_T); - terminalItem.setActionCommand(LOG_TO_TERMINAL); - //terminalItem.addActionListener(this); - terminalItem.setEnabled(false); - terminalItem.setToolTipText("Redirect std out and err back to the terminal."); - logMenu.add(terminalItem); - - JMenuItem saveLogItem = new JMenuItem("Save Log Table to File ..."); - saveLogItem.setMnemonic(KeyEvent.VK_S); - saveLogItem.setActionCommand(SAVE_LOG_TABLE); - //saveLogItem.addActionListener(this); - saveLogItem.setToolTipText("Save the log records to a tab delimited text file."); - logMenu.add(saveLogItem); - - JMenuItem clearLogItem = new JMenuItem("Clear Log Table"); - //clearLogItem.addActionListener(this); - clearLogItem.setMnemonic(KeyEvent.VK_C); - clearLogItem.setActionCommand(CLEAR_LOG_TABLE); - clearLogItem.setToolTipText("Clear the log table of all messages."); - logMenu.add(clearLogItem); - - JMenu utilMenu = new JMenu("Util"); - plotsMenu.setMnemonic(KeyEvent.VK_U); - add(utilMenu); - - JMenuItem screenshotItem = new JMenuItem("Take a Screenshot ..."); - screenshotItem.setMnemonic(KeyEvent.VK_N); - screenshotItem.setActionCommand(SCREENSHOT); - //screenshotItem.addActionListener(this); - screenshotItem.setToolTipText("Save a screenshot to file"); - utilMenu.add(screenshotItem); - */ + windowMenu.add(defaultsItem); } @Override public void propertyChange(PropertyChangeEvent evt) { - if (evt.getPropertyName().equals(ConnectionStatusModel.CONNECTION_STATUS_PROPERTY)) { - ConnectionStatus status = (ConnectionStatus) evt.getNewValue(); - boolean connected = status.equals(ConnectionStatus.CONNECTED); - closeFileItem.setEnabled(!connected); - openFileItem.setEnabled(!connected); + configurationModel.removePropertyChangeListener(this); + try { + if (evt.getPropertyName().equals(ConnectionStatusModel.CONNECTION_STATUS_PROPERTY)) { + ConnectionStatus status = (ConnectionStatus) evt.getNewValue(); + boolean connected = status.equals(ConnectionStatus.CONNECTED); + closeFileItem.setEnabled(!connected); + openFileItem.setEnabled(!connected); + } else if (evt.getPropertyName().equals(ConfigurationModel.LOG_TO_FILE_PROPERTY)) { + Boolean logToFile = (Boolean) evt.getNewValue(); + if (logToFile == true) { + // Toggle log item state to send to terminal. + logItem.setText("Log to Terminal ..."); + logItem.setActionCommand(Commands.LOG_TO_TERMINAL); + logItem.setToolTipText("Log messages to the terminal"); + } else { + // Toggle log item state to send to file. + logItem.setText("Log to File ..."); + logItem.setActionCommand(Commands.LOG_TO_FILE); + logItem.setToolTipText("Log messages to a file"); + } + } + } finally { + configurationModel.addPropertyChangeListener(this); } } @@ -234,6 +208,17 @@ closeFileItem.setEnabled(false); } } - } - + } + + void startAIDAServer() { + serverItem.setActionCommand(Commands.STOP_AIDA_SERVER); + serverItem.setText("Stop AIDA Server"); + serverItem.setToolTipText("Stop the remote AIDA server"); + } + + void stopAIDAServer() { + serverItem.setActionCommand(Commands.START_AIDA_SERVER); + serverItem.setText("Start AIDA Server"); + serverItem.setToolTipText("Start the remote AIDA server"); + } } Modified: java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/MonitoringApplication.java ============================================================================= --- java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/MonitoringApplication.java (original) +++ java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/MonitoringApplication.java Wed Mar 25 14:43:27 2015 @@ -3,18 +3,20 @@ import hep.aida.jfree.AnalysisFactory; import hep.aida.jfree.plotter.PlotterRegion; import hep.aida.jfree.plotter.PlotterRegionListener; - -import java.awt.Dimension; -import java.awt.Rectangle; -import java.awt.Robot; -import java.awt.Toolkit; +import hep.aida.ref.remote.rmi.client.RmiStoreFactory; + import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.awt.event.WindowEvent; +import java.awt.event.WindowListener; import java.awt.image.BufferedImage; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; import java.io.IOException; +import java.io.OutputStream; import java.io.PrintStream; import java.util.ArrayList; import java.util.List; @@ -32,25 +34,25 @@ import javax.swing.filechooser.FileFilter; import javax.swing.filechooser.FileNameExtensionFilter; -import org.hps.conditions.database.DatabaseConditionsManager; import org.hps.monitoring.application.DataSourceComboBox.DataSourceItem; import org.hps.monitoring.application.LogTable.LogRecordModel; import org.hps.monitoring.application.model.Configuration; import org.hps.monitoring.application.model.ConfigurationModel; +import org.hps.monitoring.application.model.ConnectionStatus; import org.hps.monitoring.application.model.ConnectionStatusModel; import org.hps.monitoring.application.model.RunModel; +import org.hps.monitoring.application.util.AIDAServer; import org.hps.monitoring.application.util.DialogUtil; import org.hps.monitoring.application.util.ErrorHandler; import org.hps.monitoring.application.util.EvioFileFilter; import org.hps.monitoring.application.util.TableExporter; import org.hps.monitoring.plotting.MonitoringAnalysisFactory; import org.hps.monitoring.plotting.MonitoringPlotFactory; -import org.hps.monitoring.subsys.StatusCode; import org.hps.monitoring.subsys.SystemStatus; -import org.hps.monitoring.subsys.SystemStatusListener; import org.hps.monitoring.subsys.SystemStatusRegistry; import org.hps.record.composite.CompositeRecordProcessor; import org.hps.record.enums.DataSourceType; +import org.lcsim.conditions.ConditionsListener; import org.lcsim.util.Driver; import org.lcsim.util.aida.AIDA; import org.lcsim.util.log.DefaultLogFormatter; @@ -58,12 +60,11 @@ /** * This is the primary class that implements the monitoring GUI application. * It should not be used directly. Instead the {@link Main} class should be - * used from the command line or via the supplied script built automatically - * by Maven. + * used from the command line. * * @author Jeremy McCormick <[log in to unmask]> */ -final class MonitoringApplication implements ActionListener, PropertyChangeListener, SystemStatusListener { +final class MonitoringApplication implements ActionListener, PropertyChangeListener { // Statically initialize logging, which will be fully setup later. static final Logger logger; @@ -73,13 +74,16 @@ static final Level DEFAULT_LEVEL = Level.ALL; // Default log stream. - PrintStream logStream = System.out; + MonitoringApplicationStreamHandler streamHandler; + LogHandler logHandler; + PrintStream sysOut = System.out; + PrintStream sysErr = System.err; // Application error handling. - final ErrorHandler errorHandler; + ErrorHandler errorHandler; // The main GUI components inside a JFrame. - final MonitoringApplicationFrame frame; + MonitoringApplicationFrame frame; // The primary data models. final RunModel runModel = new RunModel(); @@ -98,6 +102,9 @@ // Filters for opening files. static final FileFilter lcioFilter = new FileNameExtensionFilter("LCIO files", "slcio"); static final EvioFileFilter evioFilter = new EvioFileFilter(); + + AIDAServer server = new AIDAServer("hps-monitoring-app"); + static final RmiStoreFactory rsf = new RmiStoreFactory(); /** * Default log handler. @@ -125,43 +132,120 @@ LogTable getLogTable() { return frame.logPanel.logTable; } - + + class MonitoringApplicationStreamHandler extends StreamHandler { + + MonitoringApplicationStreamHandler(PrintStream ps) { + super(ps, new DefaultLogFormatter()); + } + + public void publish(LogRecord record) { + super.publish(record); + flush(); + } + + public void setOutputStream(OutputStream out) { + super.setOutputStream(out); + } + } + /** * Instantiate and show the monitoring application with the given configuration. * @param configuration The Configuration object containing application settings. */ MonitoringApplication(Configuration configuration) { - - // Setup the main GUI component. - frame = new MonitoringApplicationFrame(this); - - // Setup the error handler. - errorHandler = new ErrorHandler(frame, logger); + + try { + + // Setup the main GUI component. + frame = new MonitoringApplicationFrame(this); + + // Add window listener to perform clean shutdown. + frame.addWindowListener(new WindowListener() { + + @Override + public void windowOpened(WindowEvent e) { + } + + @Override + public void windowClosing(WindowEvent e) { + } + + @Override + public void windowClosed(WindowEvent e) { + exit(); + } + + @Override + public void windowIconified(WindowEvent e) { + } + + @Override + public void windowDeiconified(WindowEvent e) { + } + + @Override + public void windowActivated(WindowEvent e) { + } + + @Override + public void windowDeactivated(WindowEvent e) { + } + }); + + // Setup the error handler. + errorHandler = new ErrorHandler(frame, logger); - // Add this class as a listener on the configuration model. - configurationModel.addPropertyChangeListener(this); - - // Setup the logger. - setupLogger(); + // Add this class as a listener on the configuration model. + configurationModel.addPropertyChangeListener(this); + + // Setup the logger. + setupLogger(); - // Setup AIDA plotting and connect it to the GUI. - setupAida(); - - // Set the configuration. - if (configuration != null) { - // There was a user specified configuration. - this.configuration = configuration; - } else { - // Use the default configuration. - this.configuration = new Configuration(DEFAULT_CONFIGURATION); - } + // Setup AIDA plotting and connect it to the GUI. + setupAida(); + + // Set the configuration. + if (configuration != null) { + // There was a user specified configuration. + this.configuration = configuration; + } else { + // Use the default configuration. + this.configuration = new Configuration(DEFAULT_CONFIGURATION); + } - // Load the configuration. - loadConfiguration(this.configuration); - - logger.info("application initialized successfully"); - } - + // Load the configuration. + loadConfiguration(this.configuration); + + frame.setEnabled(true); + + logger.info("application initialized successfully"); + + } catch (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!"); + DialogUtil.showErrorDialog(null, "Error Starting Monitoring Application", "Monitoring application failed to initialize."); + e.printStackTrace(); + System.exit(1); + } + } + + /** + * Setup the logger. + */ + void setupLogger() { + logger.setUseParentHandlers(false); + logHandler = new LogHandler(); + logger.addHandler(logHandler); + streamHandler = new MonitoringApplicationStreamHandler(System.out); + logger.addHandler(streamHandler); + for (Handler handler : logger.getHandlers()) { + handler.setLevel(DEFAULT_LEVEL); + } + logger.setLevel(DEFAULT_LEVEL); + logger.info("logging initialized"); + } + /** * Static utility method for creating new instance. * @param configuration The application settings. @@ -177,7 +261,9 @@ */ @Override public void propertyChange(PropertyChangeEvent evt) { - // TODO: Handle log level configuration change here. + if (evt.getPropertyName().equals(ConfigurationModel.LOG_LEVEL_PROPERTY)) { + setLogLevel(); + } } /** @@ -186,50 +272,59 @@ */ public void actionPerformed(ActionEvent e) { - String cmd = e.getActionCommand(); - if (Commands.CONNECT.equals(cmd)) { + logger.finest("actionPerformed - " + e.getActionCommand()); + + String command = e.getActionCommand(); + if (Commands.CONNECT.equals(command)) { startSession(); - } else if (Commands.DISCONNECT.equals(cmd)) { - processing.stop(); - } else if (Commands.SAVE_PLOTS.equals(cmd)) { + } else if (Commands.DISCONNECT.equals(command)) { + runDisconnectThread(); + } else if (Commands.SAVE_PLOTS.equals(command)) { savePlots(); - } else if (Commands.EXIT.equals(cmd)) { - exit(); - } else if (Commands.PAUSE.equals(cmd)) { + } else if (Commands.EXIT.equals(command)) { + // This will trigger the window closing action that cleans everything up. + frame.dispose(); + } else if (Commands.PAUSE.equals(command)) { processing.pause(); - } else if (Commands.NEXT.equals(cmd)) { + } else if (Commands.NEXT.equals(command)) { processing.next(); - } else if (Commands.RESUME.equals(cmd)) { + } else if (Commands.RESUME.equals(command)) { processing.resume(); - } else if (Commands.SHOW_SETTINGS.equals(cmd)) { + } else if (Commands.SHOW_SETTINGS.equals(command)) { showSettingsDialog(); - } else if (Commands.LOAD_SETTINGS.equals(cmd)) { + } else if (Commands.LOAD_SETTINGS.equals(command)) { loadSettings(); - } else if (Commands.SAVE_SETTINGS.equals(cmd)) { + } else if (Commands.SAVE_SETTINGS.equals(command)) { saveSettings(); - } else if (Commands.CLEAR_PLOTS.equals(cmd)) { + } else if (Commands.CLEAR_PLOTS.equals(command)) { clearPlots(); - } else if (Commands.LOAD_DEFAULT_SETTINGS.equals(cmd)) { + } else if (Commands.LOAD_DEFAULT_SETTINGS.equals(command)) { loadDefaultSettings(); - } else if (Commands.OPEN_FILE.equals(cmd)) { + } else if (Commands.OPEN_FILE.equals(command)) { openFile(); - } else if (Commands.DEFAULT_WINDOW.equals(cmd)) { + } else if (Commands.DEFAULT_WINDOW.equals(command)) { restoreDefaultWindow(); - } else if (Commands.MAXIMIZE_WINDOW.equals(cmd)) { + } else if (Commands.MAXIMIZE_WINDOW.equals(command)) { maximizeWindow(); - } else if (Commands.MINIMIZE_WINDOW.equals(cmd)) { + } else if (Commands.MINIMIZE_WINDOW.equals(command)) { minimizeWindow(); - } else if (Commands.CLOSE_FILE.equals(cmd)) { + } else if (Commands.CLOSE_FILE.equals(command)) { closeFile(); - } else if (Commands.SAVE_SCREENSHOT.equals(cmd)) { + } else if (Commands.SAVE_SCREENSHOT.equals(command)) { saveScreenshot(); - } else if (Commands.LOG_LEVEL_CHANGED.equals(cmd)) { - setLogLevel(); - } else if (Commands.SAVE_LOG_TABLE.equals(cmd)) { + } else if (Commands.SAVE_LOG_TABLE.equals(command)) { saveLogTable(); - } else if (Commands.CLEAR_LOG_TABLE.equals(cmd)) { + } else if (Commands.CLEAR_LOG_TABLE.equals(command)) { getLogRecordModel().clear(); - } + } else if (Commands.LOG_TO_FILE.equals(command)) { + chooseLogFile(); + } else if (Commands.LOG_TO_TERMINAL.equals(command)) { + logToTerminal(); + } else if (Commands.START_AIDA_SERVER.equals(command)) { + startAIDAServer(); + } else if (Commands.STOP_AIDA_SERVER.equals(command)) { + stopAIDAServer(); + } } /** @@ -255,26 +350,7 @@ // Perform global configuration of the JFreeChart back end. AnalysisFactory.configure(); } - - /** - * Setup the logger. - */ - void setupLogger() { - logger.setUseParentHandlers(false); - logger.addHandler(new LogHandler()); - logger.addHandler(new StreamHandler(logStream, new DefaultLogFormatter()) { - public void publish(LogRecord record) { - super.publish(record); - flush(); - } - }); - for (Handler handler : logger.getHandlers()) { - handler.setLevel(DEFAULT_LEVEL); - } - logger.setLevel(DEFAULT_LEVEL); - logger.info("logging initialized"); - } - + /** * This method sets the configuration on the model, which fires a change for every property. * @param configuration The new configuration. @@ -296,11 +372,14 @@ * Reset the plots and clear the tabs in the plot window. */ void resetPlots() { - + + // Clear global list of registered plotters. + MonitoringPlotFactory.getPlotterRegistry().clear(); + // Clear the static AIDA tree in case plots are hanging around from previous sessions. AIDA.defaultInstance().clearAll(); - // Reset plot panel which removes all tabs. + // Reset plot panel which removes all its tabs. frame.plotPanel.reset(); logger.info("plots were cleared"); @@ -310,43 +389,20 @@ * Configure the system status monitor panel for a new job. */ void setupSystemStatusMonitor() { + // Clear the system status monitor table. - frame.systemStatusTable.getTableModel().clear(); + frame.systemStatusPanel.clear(); // Get the global registry of SystemStatus objects. SystemStatusRegistry registry = SystemStatusRegistry.getSystemStatusRegistery(); // Process the SystemStatus objects. for (SystemStatus systemStatus : registry.getSystemStatuses()) { - // Add a row to the table for every SystemStatus. - frame.systemStatusTable.getTableModel().addSystemStatus(systemStatus); - - // Add this class as a listener so all status changes can be logged. - systemStatus.addListener(this); + // This will add the status to the two tables. + frame.systemStatusPanel.addSystemStatus(systemStatus); } logger.info("system status monitor initialized successfully"); - } - - /** - * Hook for logging all status changes from the system status monitor. - */ - @Override - public void statusChanged(SystemStatus status) { - - // Choose the appropriate log level. - Level level = Level.FINE; - if (status.getStatusCode().equals(Level.WARNING)) { - level = Level.WARNING; - } else if (status.getStatusCode().ordinal() >= StatusCode.ERROR.ordinal()) { - level = Level.SEVERE; - } - - // Log all status changes. - logger.log(level, "STATUS, " + "subsys: " + status.getSubsystem() + ", " - + "code: " + status.getStatusCode().name() - + ", " + "descr: " + status.getDescription() - + ", " + "mesg: " + status.getMessage()); } /** @@ -368,13 +424,18 @@ // List of extra composite record processors including the updater for the RunPanel. List<CompositeRecordProcessor> processors = new ArrayList<CompositeRecordProcessor>(); - processors.add(frame.runPanel.new RunPanelUpdater()); - + processors.add(frame.dashboardPanel.new EventDashboardUpdater()); + + // Add Driver to update the trigger diagnostics tables. List<Driver> drivers = new ArrayList<Driver>(); drivers.add(frame.triggerPanel.new TriggerDiagnosticGUIDriver()); - - // Initialize event processing with the list of processors and reference to the application. - processing = new EventProcessing(this, processors, drivers); + + // Add listener to push conditions changes to conditions panel. + List<ConditionsListener> conditionsListeners = new ArrayList<ConditionsListener>(); + conditionsListeners.add(frame.conditionsPanel.new ConditionsPanelListener()); + + // Instantiate the event processing wrapper. + processing = new EventProcessing(this, processors, drivers, conditionsListeners); // Connect to the ET system, if applicable. processing.connect(); @@ -387,7 +448,7 @@ // Setup the system status monitor table. setupSystemStatusMonitor(); - // Start the event processing thread. + // Start the event processing thread. processing.start(); logger.info("new session successfully initialized"); @@ -406,17 +467,17 @@ } /** - * Exit from the application. + * Exit from the application from exit menu item or hitting close window button. */ void exit() { - if (processing != null && processing.isActive()) { + if (connectionModel.isConnected()) { processing.stop(); } - frame.setVisible(false); + logHandler.setLevel(Level.OFF); logger.info("exiting the application"); - logger.getHandlers()[0].flush(); + streamHandler.flush(); System.exit(0); - } + } /** * Save AIDA plots to a file using a file chooser. @@ -570,6 +631,7 @@ /** * Save a screenshot to a file using a file chooser. */ + // FIXME: This might need to be on a new thread to allow the GUI to redraw w/o chooser visible. void saveScreenshot() { JFileChooser fc = new JFileChooser(); fc.setAcceptAllFileFilterUsed(false); @@ -584,8 +646,17 @@ if (!fileName.endsWith("." + format)) { fileName += "." + format; } + frame.repaint(); + Object lock = new Object(); + synchronized (lock) { + try { + lock.wait(500); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } writeScreenshot(fileName, format); - DialogUtil.showInfoDialog(frame, "Screenshot Saved", "Screenshot was saved to file."); + DialogUtil.showInfoDialog(frame, "Screenshot Saved", "Screenshot was saved to file" + '\n' + fileName); logger.info("saved screenshot to " + fileName); } } @@ -595,15 +666,13 @@ * @param fileName The name of the output file. */ void writeScreenshot(String fileName, String format) { - Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); - Rectangle screenRectangle = new Rectangle(screenSize); + BufferedImage image = new BufferedImage(frame.getWidth(), frame.getHeight(), BufferedImage.TYPE_INT_RGB); + frame.paint(image.getGraphics()); try { - Robot robot = new Robot(); - BufferedImage image = robot.createScreenCapture(screenRectangle); ImageIO.write(image, format, new File(fileName)); - } catch (Exception e) { - errorHandler.setError(e).setMessage("Failed to take screenshot.").printStackTrace().log().showErrorDialog(); - } + } catch (IOException e) { + errorHandler.setError(e).setMessage("Failed to save screenshot.").printStackTrace().log().showErrorDialog(); + } } /** @@ -644,4 +713,129 @@ void saveLogTable() { saveTable(frame.logPanel.logTable); } + + /** + * Redirect <code>System.out</code> and <code>System.err</code> to file chosen + * by a file chooser. + */ + void chooseLogFile() { + JFileChooser fc = new JFileChooser(); + fc.setAcceptAllFileFilterUsed(false); + fc.setDialogTitle("Save Log Messages to File"); + fc.setCurrentDirectory(new File(".")); + int r = fc.showSaveDialog(frame); + if (r == JFileChooser.APPROVE_OPTION) { + String fileName = fc.getSelectedFile().getPath(); + if (new File(fileName).exists()) { + DialogUtil.showErrorDialog(frame, "File Exists", "File already exists."); + } else { + logToFile(new File(fileName)); + } + } + } + + /** + * Redirect <code>System.out</code> and <code>System.err</code> to a file. + * @param file The output log file. + * @throws FileNotFoundException if the file does not exist. + */ + void logToFile(File file) { + try { + + // Create the output file stream. + PrintStream fileStream = new PrintStream(new FileOutputStream(file.getPath())); + System.setOut(fileStream); + System.setErr(fileStream); + + // Flush the current handler, but do NOT close here or System.out gets clobbered! + streamHandler.flush(); + + // Replace the current handler with one using the file stream. + logger.removeHandler(streamHandler); + streamHandler = new MonitoringApplicationStreamHandler(fileStream); + streamHandler.setLevel(logger.getLevel()); + logger.addHandler(streamHandler); + + // Set the properties on the model. + configurationModel.setLogFileName(file.getPath()); + configurationModel.setLogToFile(true); + + logger.info("Saving log messages to " + configurationModel.getLogFileName()); + DialogUtil.showInfoDialog(frame, "Logging to File", + "Log messages redirected to file" + '\n' + configurationModel.getLogFileName()); + + } catch (FileNotFoundException e) { + errorHandler.setError(e).log().showErrorDialog(); + } + } + + /** + * Send <code>System.out</code> and <code>System.err</code> back to the terminal, + * e.g. if they were previously sent to a file. + */ + void logToTerminal() { + + // Reset System.out and err back to original streams. + System.setOut(sysOut); + System.setErr(sysErr); + + // Flush and close the current handler, which is using a file stream. + streamHandler.flush(); + streamHandler.close(); + + // Replace the handler with the one printing to the terminal. + logger.removeHandler(streamHandler); + streamHandler = new MonitoringApplicationStreamHandler(System.out); + streamHandler.setLevel(logger.getLevel()); + logger.addHandler(streamHandler); + + logger.log(Level.INFO, "log messages redirected to terminal"); + + // Update the model to indicate logging to file has been disabled. + configurationModel.setLogToFile(false); + + DialogUtil.showInfoDialog(frame, "Log to Terminal", "Log messages will be sent to the terminal."); + } + + /** + * Start the AIDA server instance. + */ + void startAIDAServer() { + if (configurationModel.hasValidProperty(ConfigurationModel.AIDA_SERVER_NAME_PROPERTY)) { + server.setName(configurationModel.getAIDAServerName()); + } + boolean started = server.start(); + if (started) { + frame.menu.startAIDAServer(); + logger.info("AIDA server started at " + server.getName()); + DialogUtil.showInfoDialog(frame, "AIDA Server Started", "The remote AIDA server started successfully."); + } else { + logger.warning("AIDA server failed to start"); + DialogUtil.showErrorDialog(frame, "Failed to Start AIDA Server", "The remote AIDA server failed to start."); + } + } + + /** + * Stop the AIDA server instance. + */ + void stopAIDAServer() { + server.disconnect(); + frame.menu.stopAIDAServer(); + logger.info("AIDA server was stopped"); + DialogUtil.showInfoDialog(frame, "AIDA Server Stopped", "The AIDA server was stopped."); + } + + /** + * + */ + void runDisconnectThread() { + new Thread() { + public void run() { + logger.fine("disconnect thread is running ..."); + connectionModel.setConnectionStatus(ConnectionStatus.DISCONNECTING); + MonitoringApplication.this.processing.stop(); + logger.fine("disconnect thread finished!"); + } + }.run(); + } } Modified: java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/MonitoringApplicationFrame.java ============================================================================= --- java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/MonitoringApplicationFrame.java (original) +++ java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/MonitoringApplicationFrame.java Wed Mar 25 14:43:27 2015 @@ -3,14 +3,11 @@ import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.FlowLayout; -import java.awt.GraphicsConfiguration; +import java.awt.GraphicsEnvironment; import java.awt.Rectangle; -import javax.swing.BoxLayout; -import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JPanel; -import javax.swing.JScrollPane; import javax.swing.JSeparator; import javax.swing.JSplitPane; import javax.swing.JTabbedPane; @@ -23,13 +20,15 @@ */ class MonitoringApplicationFrame extends JFrame { - RunPanel runPanel; + EventDashboard dashboardPanel; PlotPanel plotPanel; PlotInfoPanel plotInfoPanel; LogPanel logPanel; - SystemStatusTable systemStatusTable; JPanel buttonsPanel; TriggerDiagnosticsPanel triggerPanel; + ConditionsPanel conditionsPanel; + SystemStatusPanel systemStatusPanel; + MenuBar menu; JSplitPane mainSplitPane; JSplitPane rightSplitPane; @@ -38,14 +37,10 @@ DataSourceComboBox dataSourceComboBox; SettingsDialog settingsDialog; - - // Proportional layout parameters relative to the screen size. - static final double FULL_SIZE = 1.0; - static final double TOP_PANEL_HEIGHT = 0.05; - static final double BOTTOM_PANEL_HEIGHT = FULL_SIZE - TOP_PANEL_HEIGHT; - static final double LEFT_PANEL_WIDTH = 0.3; - static final double RIGHT_PANEL_WIDTH = FULL_SIZE - LEFT_PANEL_WIDTH; - static final double PLOT_PANEL_HEIGHT = 0.8; + + static final Rectangle BOUNDS = GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds(); + static final int PIXEL_WIDTH_MAX = (int) BOUNDS.getWidth(); + static final int PIXEL_HEIGHT_MAX = (int) BOUNDS.getHeight(); /** * @@ -53,20 +48,22 @@ */ public MonitoringApplicationFrame( MonitoringApplication application) { + + // Disable interaction until specifically enabled externally after initialization. + setEnabled(false); // Create the content panel. JPanel contentPanel = new JPanel(); setContentPane(contentPanel); - contentPanel.setLayout(new BoxLayout(contentPanel, BoxLayout.Y_AXIS)); + contentPanel.setLayout(new BorderLayout()); contentPanel.setOpaque(true); - setProportionalSize(contentPanel, FULL_SIZE, FULL_SIZE); - + contentPanel.setPreferredSize(new Dimension(PIXEL_WIDTH_MAX, PIXEL_HEIGHT_MAX)); + // Create the top panel. JPanel topPanel = new JPanel(); topPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 20, 0)); - setProportionalSize(topPanel, FULL_SIZE, TOP_PANEL_HEIGHT); - contentPanel.add(topPanel); - + contentPanel.add(topPanel, BorderLayout.NORTH); + // Create the connection status panel. JPanel connectionPanel = new ConnectionStatusPanel(application.connectionModel); topPanel.add(connectionPanel); @@ -82,7 +79,6 @@ // Add vertical separator. sep = new JSeparator(SwingConstants.VERTICAL); - sep.setPreferredSize(new Dimension(5, topPanel.getPreferredSize().height)); topPanel.add(sep); // Add the data source combo box. @@ -92,16 +88,14 @@ // Create the bottom panel. JPanel bottomPanel = new JPanel(); bottomPanel.setLayout(new BorderLayout()); - setProportionalSize(bottomPanel, FULL_SIZE, BOTTOM_PANEL_HEIGHT); - contentPanel.add(bottomPanel); - + contentPanel.add(bottomPanel, BorderLayout.CENTER); + // Create the left panel. JPanel leftPanel = new JPanel(); leftPanel.setLayout(new BorderLayout()); - setProportionalSize(leftPanel, LEFT_PANEL_WIDTH, FULL_SIZE); - + // Create the run dashboard. - runPanel = new RunPanel(application.runModel); + dashboardPanel = new EventDashboard(application.runModel); // Create the tabbed pane for content in bottom of left panel such as log table and system monitor. JTabbedPane tableTabbedPane = new JTabbedPane(); @@ -111,76 +105,58 @@ tableTabbedPane.addTab("Log Messages", logPanel); // Create the system monitor. - systemStatusTable = new SystemStatusTable(); - tableTabbedPane.addTab("System Status Monitor", new JScrollPane(systemStatusTable)); + //systemStatusTable = new SystemStatusTable(); + systemStatusPanel = new SystemStatusPanel(); + tableTabbedPane.addTab("System Status Monitor", systemStatusPanel); // Add the trigger diagnostics tables. triggerPanel = new TriggerDiagnosticsPanel(); tableTabbedPane.addTab("Trigger Diagnostics", triggerPanel); + // Add the conditions panel. + conditionsPanel = new ConditionsPanel(); + tableTabbedPane.addTab("Detector Conditions", conditionsPanel); + // Vertical split pane in left panel. - leftSplitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, runPanel, tableTabbedPane); - leftSplitPane.setResizeWeight(0.5); + leftSplitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, dashboardPanel, tableTabbedPane); + leftSplitPane.setDividerLocation(250); leftPanel.add(leftSplitPane, BorderLayout.CENTER); // Create the right panel. JPanel rightPanel = new JPanel(); rightPanel.setLayout(new BorderLayout()); - + // Create the plot info panel. plotInfoPanel = new PlotInfoPanel(); // Create the plot panel. - plotPanel = new PlotPanel(); - plotPanel.setVisible(true); // DEBUG - setProportionalSize(plotPanel, RIGHT_PANEL_WIDTH, PLOT_PANEL_HEIGHT); + plotPanel = new PlotPanel(); + plotInfoPanel.saveButton.addActionListener(plotPanel); // Create the right panel vertical split pane for displaying plots and their information and statistics. rightSplitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, plotPanel, plotInfoPanel); - setProportionalSize(rightSplitPane, RIGHT_PANEL_WIDTH, FULL_SIZE); - rightSplitPane.setResizeWeight(0.8); + rightSplitPane.setResizeWeight(0.7); rightPanel.add(rightSplitPane, BorderLayout.CENTER); // Create the main horizontal split pane for dividing the left and right panels. mainSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, leftPanel, rightPanel); - mainSplitPane.setResizeWeight(0.15); + mainSplitPane.setDividerLocation(PIXEL_WIDTH_MAX / 2); bottomPanel.add(mainSplitPane, BorderLayout.CENTER); // Create the menu bar. - MenuBar menu = new MenuBar(application.configurationModel, application.connectionModel, application); + menu = new MenuBar(application.configurationModel, application.connectionModel, application); setJMenuBar(menu); dataSourceComboBox.addActionListener(menu); - + + // Setup the settings dialog box (invisible until activated). + settingsDialog = new SettingsDialog(application.configurationModel, application); + // Setup the frame now that all components have been added. pack(); setExtendedState(JFrame.MAXIMIZED_BOTH); - setVisible(true); - - // Setup the settings dialog box. - settingsDialog = new SettingsDialog(application.configurationModel, application); + setVisible(true); } - - /** - * Set the size of a Swing component using proportions of the current screen bounds. - * @param component The component to resize. - * @param scaleX The X scaling (must be between 0 and 1). - * @param scaleY The Y scaling (must be between 0 and 1). - * @param setSize Call the setSize method as well as setPreferredSize (which is the default). - * @return - */ - void setProportionalSize(JComponent component, double scaleX, double scaleY) { - GraphicsConfiguration graphics = this.getGraphicsConfiguration(); - Rectangle bounds = graphics.getBounds(); - if (scaleX < 0 || scaleX > 1) { - throw new IllegalArgumentException("scaleX must be > 0 and <= 1."); - } - if (scaleY < 0 || scaleY > 1) { - throw new IllegalArgumentException("scaleY must be > 0 and <= 1."); - } - Dimension scaledDimension = new Dimension((int)(bounds.getWidth() * scaleX), (int)(bounds.getHeight() * scaleY)); - component.setPreferredSize(scaledDimension); - } - + /** * Restore default window settings. */ Modified: java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/PlotInfoPanel.java ============================================================================= --- java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/PlotInfoPanel.java (original) +++ java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/PlotInfoPanel.java Wed Mar 25 14:43:27 2015 @@ -15,10 +15,10 @@ import hep.aida.ref.function.FunctionDispatcher; import hep.aida.ref.function.FunctionListener; +import java.awt.Color; import java.awt.Component; -import java.awt.GridBagConstraints; -import java.awt.GridBagLayout; -import java.awt.Insets; +import java.awt.Dimension; +import java.awt.FlowLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.EventObject; @@ -27,6 +27,8 @@ import java.util.TimerTask; import javax.swing.BorderFactory; +import javax.swing.BoxLayout; +import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JList; import javax.swing.JPanel; @@ -38,15 +40,17 @@ /** * <p> * This is a GUI component for showing the statistics and other information about an AIDA plot - * when it is clicked on in the monitoring app. + * when it is clicked on in the monitoring application. * <p> - * The information is updated dynamically via the <code>AIDAObserver</code> API on the AIDA object. + * The information in the table is updated dynamically via the <code>AIDAObserver</code> API on the AIDA object. */ class PlotInfoPanel extends JPanel implements AIDAListener, ActionListener, FunctionListener { JComboBox<Object> plotComboBox; JTable infoTable = new JTable(); DefaultTableModel model; + JButton saveButton; + PlotterRegion currentRegion; Object currentObject; static final int INSET_SIZE = 5; @@ -63,11 +67,18 @@ */ @SuppressWarnings("unchecked") PlotInfoPanel() { - - setLayout(new GridBagLayout()); - setBorder(BorderFactory.createEmptyBorder(BORDER_SIZE, BORDER_SIZE, BORDER_SIZE, BORDER_SIZE)); - - GridBagConstraints c; + + setLayout(new FlowLayout(FlowLayout.LEFT)); + + JPanel leftPanel = new JPanel(); + leftPanel.setLayout(new BoxLayout(leftPanel, BoxLayout.PAGE_AXIS)); + + JPanel buttonPanel = new JPanel(); + saveButton = new JButton("Save Plots ..."); + saveButton.setActionCommand(Commands.SAVE_SELECTED_PLOTS); + buttonPanel.add(saveButton); + //c.anchor = GridBagConstraints.NORTHWEST; + leftPanel.add(buttonPanel); plotComboBox = new JComboBox<Object>(); plotComboBox.setActionCommand(PLOT_SELECTED); @@ -85,26 +96,17 @@ } }); plotComboBox.addActionListener(this); - c = new GridBagConstraints(); - c.gridx = 0; - c.gridy = 0; - c.fill = GridBagConstraints.HORIZONTAL; - c.insets = new Insets(0, 0, INSET_SIZE, 0); - add(plotComboBox, c); - + leftPanel.add(plotComboBox); + String data[][] = new String[0][0]; model = new DefaultTableModel(data, COLUMN_NAMES); infoTable.setModel(model); - - // FIXME: Are these adequate column size settings? Could prob be bigger... infoTable.getColumn("Field").setMinWidth(25); infoTable.getColumn("Value").setMinWidth(20); - - c = new GridBagConstraints(); - c.gridx = 0; - c.gridy = 1; - c.fill = GridBagConstraints.BOTH; - add(infoTable, c); + infoTable.setMinimumSize(new Dimension(100, 200)); + leftPanel.add(infoTable); + + add(leftPanel); } /** Modified: java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/PlotPanel.java ============================================================================= --- java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/PlotPanel.java (original) +++ java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/PlotPanel.java Wed Mar 25 14:43:27 2015 @@ -1,15 +1,26 @@ package org.hps.monitoring.application; +import hep.aida.IPlotter; + import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.File; +import java.io.IOException; +import javax.swing.JFileChooser; import javax.swing.JPanel; import javax.swing.JTabbedPane; +import org.hps.monitoring.application.util.DialogUtil; +import org.hps.monitoring.plotting.MonitoringPlotFactory; + /** - * This is the panel containing the monitoring plots. + * This is the panel containing the tabs with the monitoring plots. * @author Jeremy McCormick <[log in to unmask]> */ -class PlotPanel extends JPanel { +class PlotPanel extends JPanel implements ActionListener { private JTabbedPane plotPane; @@ -23,8 +34,55 @@ JTabbedPane getPlotPane() { return plotPane; } + + /** + * Get the indices of the current selected tabs. + * @return The indices of the current tabs. + */ + int[] getSelectedTabs() { + int[] indices = new int[2]; + indices[0] = plotPane.getSelectedIndex(); + Component component = plotPane.getSelectedComponent(); + if (component instanceof JTabbedPane) { + indices[1] = ((JTabbedPane)component).getSelectedIndex(); + } + return indices; + } + + public void actionPerformed(ActionEvent event) { + if (event.getActionCommand().equals(Commands.SAVE_SELECTED_PLOTS)) { + int[] indices = getSelectedTabs(); + IPlotter plotter = MonitoringPlotFactory.getPlotterRegistry().find(indices[0], indices[1]); + if (plotter != null) { + savePlotter(plotter); + } else { + DialogUtil.showErrorDialog(this, "Error Finding Plots", "No plots found in selected tab."); + } + } + } + + static final String DEFAULT_FORMAT = "png"; + void savePlotter(IPlotter plotter) { + JFileChooser fc = new JFileChooser(); + fc.setAcceptAllFileFilterUsed(false); + fc.setDialogTitle("Save Plots - " + plotter.title()); + fc.setCurrentDirectory(new File(".")); + int r = fc.showSaveDialog(this); + if (r == JFileChooser.APPROVE_OPTION) { + String path = fc.getSelectedFile().getPath(); + if (path.lastIndexOf(".") == -1) { + path += "." + DEFAULT_FORMAT; + } + try { + plotter.writeToFile(path); + } catch (IOException e) { + e.printStackTrace(); + DialogUtil.showErrorDialog(this, "Error Saving Plots", "There was an error saving the plots."); + } + } + } void reset() { - plotPane.removeAll(); - } + plotPane.removeAll(); + } } Modified: java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/SettingsPanel.java ============================================================================= --- java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/SettingsPanel.java (original) +++ java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/SettingsPanel.java Wed Mar 25 14:43:27 2015 @@ -31,7 +31,7 @@ this.parent = parent; connectionPanel = new ConnectionSettingsPanel(); - jobPanel = new JobSettingsPanel(); + jobPanel = new JobSettingsPanel(configurationModel); // Push configuration to sub-components. connectionPanel.setConfigurationModel(configurationModel); @@ -55,7 +55,6 @@ add(Box.createRigidArea(new Dimension(1, 5))); JPanel buttonsPanel = new JPanel(); buttonsPanel.add(okayButton); - //buttonsPanel.add(defaultsButton); buttonsPanel.setLayout(new FlowLayout()); add(buttonsPanel); add(Box.createRigidArea(new Dimension(1, 5))); Modified: java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/SystemStatusTable.java ============================================================================= --- java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/SystemStatusTable.java (original) +++ java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/SystemStatusTable.java Wed Mar 25 14:43:27 2015 @@ -1,8 +1,5 @@ package org.hps.monitoring.application; -import static org.hps.monitoring.application.model.SystemStatusTableModel.*; - -import java.awt.Color; import java.awt.Component; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; @@ -19,8 +16,7 @@ import org.hps.monitoring.subsys.StatusCode; /** - * A GUI window for showing changes to {@link org.hps.monitoring.subsys.SystemStatus} objects using - * a <code>JTable</code>. + * This table shows the current state of {@link org.hps.monitoring.subsys.SystemStatus} objects. */ class SystemStatusTable extends JTable { @@ -39,34 +35,13 @@ // Color code the cell by its status. StatusCode statusCode = StatusCode.valueOf((String) value); - if (statusCode.ordinal() >= StatusCode.ERROR.ordinal()) { - // Any type of error is red. - label.setBackground(Color.RED); - } else if (statusCode.equals(StatusCode.WARNING)) { - // Warnings are yellow. - label.setBackground(Color.YELLOW); - } else if (statusCode.equals(StatusCode.OKAY)) { - // Okay is green. - label.setBackground(Color.GREEN); - } else if (statusCode.equals(StatusCode.OFFLINE)) { - // Offline is orange. - label.setBackground(Color.ORANGE); - } else if (statusCode.equals(StatusCode.UNKNOWN)) { - // Unknown is gray. - label.setBackground(Color.GRAY); - } else if (statusCode.equals(StatusCode.CLEARED)) { - // Cleared is light gray. - label.setBackground(Color.LIGHT_GRAY); - } else { - // Default is white, though this shouldn't happen! - label.setBackground(Color.WHITE); - } + label.setBackground(statusCode.getColor()); return label; } }); // Date formatting for last changed. - getColumnModel().getColumn(LAST_CHANGED_COL).setCellRenderer(new DefaultTableCellRenderer() { + getColumnModel().getColumn(SystemStatusTableModel.LAST_CHANGED_COL).setCellRenderer(new DefaultTableCellRenderer() { final SimpleDateFormat dateFormat = new SimpleDateFormat("MMMM-dd-yyyy HH:mm:ss.SSS"); @@ -80,16 +55,16 @@ }); // Button for clearing system statuses. - getColumnModel().getColumn(RESET_COL).setCellRenderer(new ButtonRenderer("Clear")); + getColumnModel().getColumn(SystemStatusTableModel.RESET_COL).setCellRenderer(new ButtonRenderer("Clear")); addMouseListener(new JTableButtonMouseListener(this)); getColumn("Clearable").setWidth(0); getColumn("Clearable").setMinWidth(0); getColumn("Clearable").setMaxWidth(0); // Column widths. - getColumnModel().getColumn(ACTIVE_COL).setPreferredWidth(8); - getColumnModel().getColumn(STATUS_COL).setPreferredWidth(10); - getColumnModel().getColumn(SYSTEM_COL).setPreferredWidth(10); + getColumnModel().getColumn(SystemStatusTableModel.ACTIVE_COL).setPreferredWidth(8); + getColumnModel().getColumn(SystemStatusTableModel.STATUS_COL).setPreferredWidth(10); + getColumnModel().getColumn(SystemStatusTableModel.SYSTEM_COL).setPreferredWidth(10); // TODO: Add default width setting for every column. setAutoCreateRowSorter(true); @@ -109,7 +84,7 @@ } public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { - boolean clearable = (Boolean) table.getModel().getValueAt(row, CLEARABLE_COL); + boolean clearable = (Boolean) table.getModel().getValueAt(row, SystemStatusTableModel.CLEARABLE_COL); if (clearable) return this; else Modified: java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/TriggerDiagnosticsPanel.java ============================================================================= --- java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/TriggerDiagnosticsPanel.java (original) +++ java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/TriggerDiagnosticsPanel.java Wed Mar 25 14:43:27 2015 @@ -21,7 +21,7 @@ * * @author Jeremy McCormick <[log in to unmask]> */ -public class TriggerDiagnosticsPanel extends JPanel { +class TriggerDiagnosticsPanel extends JPanel { JTabbedPane tabs = new JTabbedPane(); ClusterTablePanel clusterPanel = new ClusterTablePanel(); @@ -70,9 +70,7 @@ for (DiagnosticUpdatable update : updateList) { update.updatePanel(snapshot); } - } else { - System.out.println("no diag snapshot in event"); - } + } } void setDiagnosticCollectionName(String name) { Modified: java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/model/ConfigurationModel.java ============================================================================= --- java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/model/ConfigurationModel.java (original) +++ java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/model/ConfigurationModel.java Wed Mar 25 14:43:27 2015 @@ -1,6 +1,5 @@ package org.hps.monitoring.application.model; -import java.io.File; import java.util.logging.Level; import org.hps.record.enums.DataSourceType; @@ -16,6 +15,8 @@ Configuration configuration; // Job setting properties. + public static final String AIDA_SERVER_NAME_PROPERTY = "AIDAServerName"; + public static final String CONDITIONS_TAG_PROPERTY = "ConditionsTag"; public static final String DETECTOR_NAME_PROPERTY = "DetectorName"; public static final String DETECTOR_ALIAS_PROPERTY = "DetectorAlias"; public static final String DISCONNECT_ON_ERROR_PROPERTY = "DisconnectOnError"; @@ -104,18 +105,14 @@ firePropertyChange(STEERING_TYPE_PROPERTY, oldValue, getSteeringType()); } - public File getSteeringFile() { - if (configuration.hasKey(STEERING_FILE_PROPERTY)) { - return new File(configuration.get(STEERING_FILE_PROPERTY)); - } else { - return null; - } + public String getSteeringFile() { + return configuration.get(STEERING_FILE_PROPERTY); } public void setSteeringFile(String steeringFile) { - File oldValue = getSteeringFile(); + String oldValue = getSteeringFile(); configuration.set(STEERING_FILE_PROPERTY, steeringFile); - firePropertyChange(STEERING_FILE_PROPERTY, oldValue, getSteeringFile().getPath()); + firePropertyChange(STEERING_FILE_PROPERTY, oldValue, getSteeringFile()); } public String getSteeringResource() { @@ -391,6 +388,26 @@ public String getEtPath() { return getEtName() + "@" + getHost() + ":" + getPort(); + } + + public void setConditionsTag(String conditionsTag) { + String oldValue = getConditionsTag(); + configuration.set(CONDITIONS_TAG_PROPERTY, conditionsTag); + firePropertyChange(CONDITIONS_TAG_PROPERTY, oldValue, getConditionsTag()); + } + + public String getConditionsTag() { + return configuration.get(CONDITIONS_TAG_PROPERTY); + } + + public void setAIDAServerName(String AIDAServerName) { + String oldValue = getAIDAServerName(); + configuration.set(AIDA_SERVER_NAME_PROPERTY, AIDAServerName); + firePropertyChange(AIDA_SERVER_NAME_PROPERTY, oldValue, getAIDAServerName()); + } + + public String getAIDAServerName() { + return configuration.get(AIDA_SERVER_NAME_PROPERTY); } public void remove(String property) { Modified: java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/model/ConnectionStatus.java ============================================================================= --- java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/model/ConnectionStatus.java (original) +++ java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/model/ConnectionStatus.java Wed Mar 25 14:43:27 2015 @@ -10,6 +10,7 @@ public enum ConnectionStatus { DISCONNECTED(Color.RED), + DISCONNECTING(Color.YELLOW), CONNECTED(Color.GREEN); Color color; Modified: java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/model/ConnectionStatusModel.java ============================================================================= --- java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/model/ConnectionStatusModel.java (original) +++ java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/model/ConnectionStatusModel.java Wed Mar 25 14:43:27 2015 @@ -50,4 +50,16 @@ listener.propertyChange(new PropertyChangeEvent(this, PAUSED_PROPERTY, oldValue, this.paused)); } } + + public boolean isConnected() { + return this.connectionStatus == ConnectionStatus.CONNECTED; + } + + public boolean isDisconnected() { + return this.connectionStatus == ConnectionStatus.DISCONNECTED; + } + + public boolean isDisconnecting() { + return this.connectionStatus == ConnectionStatus.DISCONNECTING; + } } Modified: java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/model/RunModel.java ============================================================================= --- java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/model/RunModel.java (original) +++ java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/model/RunModel.java Wed Mar 25 14:43:27 2015 @@ -3,7 +3,7 @@ import java.util.Date; /** - * Backing model for run information that shows in the {@link org.hps.monitoring.application.RunPanel}. + * Backing model for run information that shows in the {@link org.hps.monitoring.application.EventDashboard}. */ public final class RunModel extends AbstractModel { Modified: java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/util/ErrorHandler.java ============================================================================= --- java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/util/ErrorHandler.java (original) +++ java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/util/ErrorHandler.java Wed Mar 25 14:43:27 2015 @@ -85,7 +85,7 @@ * @return This object. */ public ErrorHandler log() { - logger.log(Level.SEVERE, message); + logger.log(Level.SEVERE, message, error); return this; } Modified: java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/util/ResourceUtil.java ============================================================================= --- java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/util/ResourceUtil.java (original) +++ java/branches/prod/monitoring-app/src/main/java/org/hps/monitoring/application/util/ResourceUtil.java Wed Mar 25 14:43:27 2015 @@ -14,6 +14,7 @@ import java.util.jar.JarEntry; import java.util.jar.JarFile; +import org.hps.conditions.database.DatabaseConditionsManager; import org.hps.record.LCSimEventBuilder; import org.reflections.Reflections; @@ -116,4 +117,8 @@ Collections.sort(detectorNames); return detectorNames.toArray(new String[detectorNames.size()]); } + + public static String[] getConditionsTags() { + return DatabaseConditionsManager.getInstance().getTags().toArray(new String[] {}); + } } Modified: java/branches/prod/monitoring-app/src/main/resources/org/hps/monitoring/config/default_config.prop ============================================================================= --- java/branches/prod/monitoring-app/src/main/resources/org/hps/monitoring/config/default_config.prop (original) +++ java/branches/prod/monitoring-app/src/main/resources/org/hps/monitoring/config/default_config.prop Wed Mar 25 14:43:27 2015 @@ -2,8 +2,9 @@ # Monitoring Application configuration # job settings +AIDAServerName=hps-monitoring-app DetectorName=HPS-Proposal2014-v8-6pt6 -DisconnectOnError=false +DisconnectOnError=true DisconnectOnEndRun=true EventBuilderClassName=org.hps.evio.LCSimEngRunEventBuilder #LogFileName= @@ -19,20 +20,18 @@ DataSourceType=ET_SERVER #DataSourcePath= ProcessingStage=LCIO - + # ET connection settings +# FIXME: These should really all be prepended by 'Et' so their purpose is clear. Blocking=false EtName=ETBuffer ChunkSize=1 Host=localhost Port=11111 StationPosition=1 -# Prescale was 1 -Prescale=0 +Prescale=1 QueueSize=0 StationName=MY_STATION Verbose=false WaitMode=TIMED -WaitTime=1000000000 - -SaveLayout=false; +WaitTime=1000000000 Modified: java/branches/prod/monitoring-app/src/main/scripts/evio_file_producer.sh ============================================================================= --- java/branches/prod/monitoring-app/src/main/scripts/evio_file_producer.sh (original) +++ java/branches/prod/monitoring-app/src/main/scripts/evio_file_producer.sh Wed Mar 25 14:43:27 2015 @@ -14,6 +14,6 @@ # Run the file producer, sending any additional arguments to the command. #prod="java -classpath $classpath org.hps.evio.EvioFileProducer -e ${eviofile} -f ETBuffer -host localhost -s 10000 -d 100 $@" -prod="java -classpath $classpath org.hps.record.evio.EvioFileProducer -e ${eviofile} -f ETBuffer -host localhost -s 100000 $@" +prod="java -classpath $classpath org.hps.record.evio.EvioFileProducer -e ${eviofile} -f ETBuffer -host localhost -s 200000 $@" echo $prod exec $prod Modified: java/branches/prod/monitoring-app/src/main/scripts/start_et_ring.sh ============================================================================= --- java/branches/prod/monitoring-app/src/main/scripts/start_et_ring.sh (original) +++ java/branches/prod/monitoring-app/src/main/scripts/start_et_ring.sh Wed Mar 25 14:43:27 2015 @@ -15,6 +15,6 @@ fi # Start the ET ring, sending any script arguments to the end of the command. -server="java -Xmx1024m -classpath $classpath org.jlab.coda.et.apps.StartEt -f $buffer_file -s 100000 -v $@" +server="java -Xmx1024m -classpath $classpath org.jlab.coda.et.apps.StartEt -f $buffer_file -s 200000 -v $@" echo "$server" exec $server Modified: java/branches/prod/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/svt/SensorOccupancyPlotsDriver.java ============================================================================= --- java/branches/prod/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/svt/SensorOccupancyPlotsDriver.java (original) +++ java/branches/prod/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/svt/SensorOccupancyPlotsDriver.java Wed Mar 25 14:43:27 2015 @@ -5,13 +5,14 @@ import hep.aida.IHistogramFactory; import hep.aida.IPlotter; import hep.aida.IPlotterFactory; +import hep.aida.IPlotterStyle; +import hep.aida.ref.plotter.style.registry.StyleRegistry; +import java.awt.Color; import java.util.HashMap; import java.util.List; import java.util.Map; -import org.lcsim.detector.identifier.IIdentifier; -import org.lcsim.detector.identifier.IIdentifierHelper; import org.lcsim.detector.tracker.silicon.HpsSiSensor; import org.lcsim.event.EventHeader; import org.lcsim.event.RawTrackerHit; @@ -19,32 +20,34 @@ import org.lcsim.util.Driver; /** - * This Driver makes plots of sensor occupancies across a run. It is intended to - * be used with the monitoring system. + * This Driver makes plots of sensor occupancies across a run. It is intended to be used with the + * monitoring system. * - * @author Jeremy McCormick <[log in to unmask]> - * @author Omar Moreno <[log in to unmask]> + * @author Jeremy McCormick <[log in to unmask]> + * @author Omar Moreno <[log in to unmask]> */ public class SensorOccupancyPlotsDriver extends Driver { // TODO: Add documentation // TODO: Set plot styles - - static IHistogramFactory histogramFactory = IAnalysisFactory.create().createHistogramFactory(null); - IPlotterFactory plotterFactory = IAnalysisFactory.create().createPlotterFactory(); - - protected Map<String, IPlotter> plotters = new HashMap<String, IPlotter>(); - protected Map<HpsSiSensor, IHistogram1D> occupancyPlots = new HashMap<HpsSiSensor, IHistogram1D>(); - protected Map<HpsSiSensor, int[]> occupancyMap = new HashMap<HpsSiSensor, int[]>(); + + static IHistogramFactory histogramFactory = IAnalysisFactory.create().createHistogramFactory(null); + IPlotterFactory plotterFactory = IAnalysisFactory.create().createPlotterFactory(); + static StyleRegistry styleRegistry = StyleRegistry.getStyleRegistry(); + + protected Map<String, IPlotter> plotters = new HashMap<String, IPlotter>(); + protected Map<HpsSiSensor, IHistogram1D> occupancyPlots = new HashMap<HpsSiSensor, IHistogram1D>(); + protected Map<HpsSiSensor, int[]> occupancyMap = new HashMap<HpsSiSensor, int[]>(); private List<HpsSiSensor> sensors; - + private static final String SUBDETECTOR_NAME = "Tracker"; private String rawTrackerHitCollectionName = "SVTRawTrackerHits"; private int eventCount = 0; private int eventRefreshRate = 1; - public SensorOccupancyPlotsDriver() {} + public SensorOccupancyPlotsDriver() { + } public void setRawTrackerHitCollectionName(String rawTrackerHitCollectionName) { this.rawTrackerHitCollectionName = rawTrackerHitCollectionName; @@ -56,83 +59,92 @@ 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) { - - sensors - = detector.getSubdetector(SUBDETECTOR_NAME).getDetectorElement().findDescendants(HpsSiSensor.class); - + + sensors = detector.getSubdetector(SUBDETECTOR_NAME).getDetectorElement().findDescendants(HpsSiSensor.class); + if (sensors.size() == 0) { throw new RuntimeException("No sensors were found in this detector."); } plotters.put("Occupancy", plotterFactory.create("Occupancy")); - plotters.get("Occupancy").createRegions(6,6); - - for (HpsSiSensor sensor : sensors) { - occupancyPlots.put(sensor, histogramFactory.createHistogram1D(sensor.getName() + " - Occupancy", 640, 0, 640)); - plotters.get("Occupancy").region(this.computePlotterRegion(sensor)) - .plot(occupancyPlots.get(sensor)); + plotters.get("Occupancy").createRegions(6, 6); + + for (HpsSiSensor sensor : sensors) { + occupancyPlots.put(sensor, histogramFactory.createHistogram1D(sensor.getName() + " - Occupancy", 640, 0, 640)); + plotters.get("Occupancy").region(this.computePlotterRegion(sensor)).plot(occupancyPlots.get(sensor), createPlotterStyle()); occupancyMap.put(sensor, new int[640]); - } - - for (IPlotter plotter : plotters.values()) { - plotter.show(); - } + } + + for (IPlotter plotter : plotters.values()) { + plotter.show(); + } } public void process(EventHeader event) { - - if (!event.hasCollection(RawTrackerHit.class, rawTrackerHitCollectionName)) - return; - eventCount++; - + if (!event.hasCollection(RawTrackerHit.class, rawTrackerHitCollectionName)) + return; + + eventCount++; + // Get RawTrackerHit collection from event. List<RawTrackerHit> rawHits = event.get(RawTrackerHit.class, rawTrackerHitCollectionName); - // Increment strip hit count. - for (RawTrackerHit rawHit : rawHits) { - int[] strips = occupancyMap.get((HpsSiSensor) rawHit.getDetectorElement()); - strips[rawHit.getIdentifierFieldValue("strip")] += 1; - } + // Increment strip hit count. + for (RawTrackerHit rawHit : rawHits) { + int[] strips = occupancyMap.get((HpsSiSensor) rawHit.getDetectorElement()); + strips[rawHit.getIdentifierFieldValue("strip")] += 1; + } - // Plot strip occupancies. - if (eventCount % eventRefreshRate == 0) { - for (HpsSiSensor sensor : sensors) { - int[] strips = occupancyMap.get(sensor); - for (int i = 0; i < strips.length; i++) { - double stripOccupancy = (double) strips[i] / (double) eventCount; - if (stripOccupancy != 0) { - occupancyPlots.get(sensor).fill(i, stripOccupancy); - } - } - } - } + // Plot strip occupancies. + if (eventCount % eventRefreshRate == 0) { + for (HpsSiSensor sensor : sensors) { + int[] strips = occupancyMap.get(sensor); + for (int i = 0; i < strips.length; i++) { + double stripOccupancy = (double) strips[i] / (double) eventCount; + if (stripOccupancy != 0) { + occupancyPlots.get(sensor).fill(i, stripOccupancy); + } + } + } + } + } + + static IPlotterStyle createPlotterStyle() { + IPlotterStyle style = styleRegistry.getStore("DefaultStyleStore").getStyle("DefaultHistogram1DStyle"); + style.dataStyle().lineStyle().setVisible(false); + style.dataStyle().outlineStyle().setVisible(false); + style.dataStyle().fillStyle().setVisible(true); + style.dataStyle().fillStyle().setColor("blue"); + style.legendBoxStyle().setVisible(false); + style.dataStyle().errorBarStyle().setVisible(false); + return style; } } Modified: java/branches/prod/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/svt/SvtTimingInPlots.java ============================================================================= --- java/branches/prod/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/svt/SvtTimingInPlots.java (original) +++ java/branches/prod/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/svt/SvtTimingInPlots.java Wed Mar 25 14:43:27 2015 @@ -9,6 +9,7 @@ import hep.aida.IHistogram1D; import hep.aida.IPlotter; import hep.aida.IPlotterFactory; +import hep.aida.IPlotterStyle; import org.lcsim.util.Driver; import org.lcsim.detector.tracker.silicon.HpsSiSensor; @@ -17,8 +18,8 @@ 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; /** * Monitoring driver that will be used when 'timing in' the SVT. @@ -27,14 +28,24 @@ * @author Omar Moreno <[log in to unmask]> */ public class SvtTimingInPlots extends Driver { - + // TODO: Add documentation // TODO: Set plot styles - + + static { + hep.aida.jfree.AnalysisFactory.register(); + } + static IHistogramFactory histogramFactory = IAnalysisFactory.create().createHistogramFactory(null); IPlotterFactory plotterFactory = IAnalysisFactory.create().createPlotterFactory(); protected Map<String, IPlotter> plotters = new HashMap<String, IPlotter>(); protected Map<SiSensor, IHistogram1D> t0Plots = new HashMap<SiSensor, IHistogram1D>(); + protected Map<SiSensor, IHistogram1D> amplitudePlots = new HashMap<SiSensor, IHistogram1D>(); + protected Map<SiSensor, IHistogram1D> chi2Plots = new HashMap<SiSensor, IHistogram1D>(); + protected Map<Integer, List<RawTrackerHit>> topRawHitsPerLayer = new HashMap<Integer, List<RawTrackerHit>>(); + protected Map<Integer, List<RawTrackerHit>> botRawHitsPerLayer = new HashMap<Integer, List<RawTrackerHit>>(); + IPlotterStyle style = null; + private int computePlotterRegion(HpsSiSensor sensor) { @@ -64,33 +75,53 @@ return -1; } - - protected void detectorChanged(Detector detector) { - + List<HpsSiSensor> sensors = detector.getSubdetector("Tracker").getDetectorElement().findDescendants(HpsSiSensor.class); - //--- t0 Plots ---// - //----------------// plotters.put("L1-L3 t0", plotterFactory.create("L1-L3 t0")); plotters.get("L1-L3 t0").createRegions(6,2); plotters.put("L4-L6 t0", plotterFactory.create("L4-L6 t0")); plotters.get("L4-L6 t0").createRegions(6,4); - int index = 0; + + plotters.put("L1-L3 Amplitude", plotterFactory.create("L1-L3 Amplitude")); + plotters.get("L1-L3 Amplitude").createRegions(6,2); + + plotters.put("L4-L6 Amplitude", plotterFactory.create("L4-L6 Amplitude")); + plotters.get("L4-L6 Amplitude").createRegions(6,4); + + plotters.put("L1-L3 Chi^2 Probability", plotterFactory.create("L1-L3 Chi^2 Probability")); + plotters.get("L1-L3 Chi^2 Probability").createRegions(6,2); + + plotters.put("L4-L6 Chi^2 Probability", plotterFactory.create("L1-L3 Chi^2 Probability")); + plotters.get("L4-L6 Chi^2 Probability").createRegions(6,4); + for (HpsSiSensor sensor : sensors) { t0Plots.put(sensor,histogramFactory.createHistogram1D(sensor.getName() + " - t0",75, -50, 100.0)); + amplitudePlots.put(sensor, histogramFactory.createHistogram1D(sensor.getName() + " - Amplitude", 200, 0, 2000)); + chi2Plots.put(sensor, histogramFactory.createHistogram1D(sensor.getName() + " - Chi^2 Probability", 20, 0, 1)); + if (sensor.getLayerNumber() < 7) { plotters.get("L1-L3 t0").region(this.computePlotterRegion(sensor)) .plot(t0Plots.get(sensor)); + plotters.get("L1-L3 Amplitude").region(this.computePlotterRegion(sensor)) + .plot(amplitudePlots.get(sensor)); + plotters.get("L1-L3 Chi^2 Probability").region(this.computePlotterRegion(sensor)) + .plot(chi2Plots.get(sensor)); + } else { plotters.get("L4-L6 t0").region(this.computePlotterRegion(sensor)) .plot(t0Plots.get(sensor)); + plotters.get("L4-L6 Amplitude").region(this.computePlotterRegion(sensor)) + .plot(amplitudePlots.get(sensor)); + plotters.get("L4-L6 Chi^2 Probability").region(this.computePlotterRegion(sensor)) + .plot(chi2Plots.get(sensor)); } } - + for (IPlotter plotter : plotters.values()) { plotter.show(); } @@ -103,14 +134,23 @@ List<LCRelation> fittedHits = event.get(LCRelation.class, "SVTFittedRawTrackerHits"); - for (LCRelation fittedHit : fittedHits) { + RawTrackerHit rawHit = (RawTrackerHit) fittedHit.getFrom(); + HpsSiSensor sensor - = (HpsSiSensor) ((RawTrackerHit) fittedHit.getFrom()).getDetectorElement(); + = (HpsSiSensor) rawHit.getDetectorElement(); double t0 = FittedRawTrackerHit.getT0(fittedHit); t0Plots.get(sensor).fill(t0); + + double amplitude = FittedRawTrackerHit.getAmp(fittedHit); + amplitudePlots.get(sensor).fill(amplitude); + + double chi2Prob = ShapeFitParameters.getChiProb(FittedRawTrackerHit.getShapeFitParameters(fittedHit)); + chi2Plots.get(sensor).fill(chi2Prob); + + } } } Modified: java/branches/prod/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/trackrecon/TrackTimePlots.java ============================================================================= --- java/branches/prod/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/trackrecon/TrackTimePlots.java (original) +++ java/branches/prod/monitoring-drivers/src/main/java/org/hps/monitoring/drivers/trackrecon/TrackTimePlots.java Wed Mar 25 14:43:27 2015 @@ -6,9 +6,11 @@ import hep.aida.IPlotterFactory; import hep.aida.IPlotterStyle; import hep.aida.ref.plotter.PlotterRegion; + import java.util.List; -import org.hps.readout.ecal.triggerbank.AbstractIntData; -import org.hps.readout.ecal.triggerbank.TestRunTriggerData; + +import org.hps.recon.ecal.triggerbank.AbstractIntData; +import org.hps.recon.ecal.triggerbank.TestRunTriggerData; import org.lcsim.detector.tracker.silicon.DopedSilicon; import org.lcsim.detector.tracker.silicon.HpsSiSensor; import org.lcsim.event.EventHeader; Modified: java/branches/prod/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/EcalClusterPlots.java ============================================================================= --- java/branches/prod/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/EcalClusterPlots.java (original) +++ java/branches/prod/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/EcalClusterPlots.java Wed Mar 25 14:43:27 2015 @@ -9,8 +9,8 @@ import java.util.List; import org.apache.commons.math.stat.StatUtils; -import org.hps.readout.ecal.TriggerModule; import org.hps.recon.ecal.ECalUtils; +import org.hps.recon.ecal.triggerbank.TriggerModule; import org.lcsim.event.CalorimeterHit; import org.lcsim.event.Cluster; import org.lcsim.event.EventHeader; @@ -35,9 +35,7 @@ * <li>The third sub-tab shows the time distribution of the cluster * (Histogram1D), taken from the mean of the times forming the cluster, * as well as the RMS (Histogram1D).</li> - * <li>The fourth sub-tab is a larger version of the the cluster centers - * distribution.</li> - * <li>The fifth tab displays the cluster pair distribution for the + * <li>The fourth tab displays the cluster pair distribution for the * energy sum, energy difference, energy slope, and coplanarity cuts * for all top/bottom pairs received. It also displays the average x- * and y-coordinates for the pairs.</li> @@ -56,7 +54,7 @@ private boolean logScale = false; private AIDA aida = AIDA.defaultInstance(); private double maxE = 5000 * ECalUtils.MeV; - private IPlotter[] plotter = new IPlotter[5]; + private IPlotter[] plotter = new IPlotter[4]; private String clusterCollectionName = "EcalClusters"; // Monitoring plot variables. @@ -79,10 +77,9 @@ private static final int TAB_CLUSTER_COUNT = 0; private static final int TAB_CLUSTER_ENERGY = 1; private static final int TAB_CLUSTER_TIME = 2; - private static final int TAB_CLUSTER_CENTER = 3; - private static final int TAB_CLUSTER_PAIR = 4; + private static final int TAB_CLUSTER_PAIR = 3; private static final String[] TAB_NAMES = { "Cluster Count Plots", "Cluster Energy Plots", - "Cluster Time Plots", "Cluster Center Plot", "Cluster Pair Plots" }; + "Cluster Time Plots", "Cluster Pair Plots" }; /** * Resets all of the plots for the new detector. @@ -136,13 +133,7 @@ plotter[TAB_CLUSTER_TIME].createRegions(1, 2); plotter[TAB_CLUSTER_TIME].region(0).plot(clusterTimes); plotter[TAB_CLUSTER_TIME].region(1).plot(clusterTimeSigma); - - // Define the Cluster Center tab. - plotter[TAB_CLUSTER_CENTER].createRegion(); - plotter[TAB_CLUSTER_CENTER].region(0).plot(edgePlot); - plotter[TAB_CLUSTER_CENTER].style().setParameter("hist2DStyle", "colorMap"); - plotter[TAB_CLUSTER_CENTER].style().dataStyle().fillStyle().setParameter("colorMapScheme", "rainbow"); - + // Create the Cluster Pair tab. plotter[TAB_CLUSTER_PAIR].createRegions(2, 3); plotter[TAB_CLUSTER_PAIR].region(0).plot(pairEnergySum); Modified: java/branches/prod/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/EcalEventDisplay.java ============================================================================= --- java/branches/prod/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/EcalEventDisplay.java (original) +++ java/branches/prod/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/EcalEventDisplay.java Wed Mar 25 14:43:27 2015 @@ -39,200 +39,200 @@ * <li>If the user clicks on a crystal, the corresponding energy and time * distributions (both of type <code>IHistogram1D</code>) are shown in * the last panel of the monitoring application, as well as a 2D histogram - * (hit time vs. hit energy). Finally, if available, the raw waveshape (in - * mV) is displayed.</li> + * (hit time vs. hit energy).The fourth panel reports energy for the crystal.</li> * * @author Andrea Celentano */ public class EcalEventDisplay extends Driver implements CrystalListener, ActionListener { - // Class variables. - private static final int NUM_CHANNELS = 11 * 47; - - // Plotter objects and variables. - private IPlotter plotter; - private IPlotterFactory plotterFactory; - private AIDA aida = AIDA.defaultInstance(); - - // LCIO Collection names. - private String inputCollection = "EcalCalHits"; - private String clusterCollection = "EcalClusters"; - private String inputCollectionRaw = "EcalReadoutHits"; - - // Channel plot lists. - private ArrayList<IHistogram1D> channelEnergyPlot; - private ArrayList<IHistogram1D> clusterEnergyPlot; - private ArrayList<IHistogram1D> channelTimePlot; - //private ArrayList<IHistogram1D> channelRawWaveform; - 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. - - // Plot style and title variables. - private static final String NO_TITLE = ""; - //private static final String SIGNAL_TIME_TITLE = "Time (ns)"; - private static final String HIT_TIME_TITLE = "Hit Time (ns)"; - //private static final String SIGNAL_DATA_STYLE_COLOR = "orange"; - //private static final String RAW_WAVEFORM_TITLE = "Raw Waveform"; - private static final String HIT_ENERGY_TITLE = "Hit Energy (GeV)"; - private static final String CLUSTER_ENERGY_TITLE = "Cluster Energy (GeV)"; - //private static final String SIGNAL_AMPLITUDE_TITLE = "Signal Amplitude (mV)"; - - /** - * Sets the upper bound of the energy scales used by the driver. - * Energy units are in GeV. - * @param maxEch - The energy scale upper bound. - */ - public void setMaxEch(double maxEch) { - this.maxEch = maxEch; - } - - /** - * Sets the lower bound of the energy scales used by the driver. - * Energy units are in GeV. - * @param minEch - The lower energy scale bound. - */ - public void setMinEch(double minEch) { - this.minEch = minEch; - } - - public void setPedSamples(int pedSamples) { - this.pedSamples = pedSamples; - } - /** - * Sets the LCIO collection name for the processed calorimeter hits. - * @param inputCollection - The LCIO collection name. - */ - public void setInputCollection(String inputCollection) { - this.inputCollection = inputCollection; - } - - /** - * Sets the LCIO collection name for the raw waveform hits. - * @param inputCollectionRaw - The LCIO collection name. - */ - public void setInputCollectionRaw(String inputCollectionRaw) { - this.inputCollectionRaw = inputCollectionRaw; - } - - /** - * Sets the LCIO collection name for calorimeter clusters. - * @param inputClusterCollection - The LCIO collection name. - */ - public void setInputClusterCollection(String inputClusterCollection) { - this.clusterCollection = inputClusterCollection; - } - - /** - * Sets the rate at which the GUI updates its elements, - * @param eventRefreshRate - The rate at which the GUI should be - * updated, in seconds. - */ - public void setEventRefreshRate(int eventRefreshRate) { - this.eventRefreshRate = eventRefreshRate; - } - - /** - * Sets whether the event display should be cleared after event - * or whether it should retain the previously displayed results. - * @param resetOnUpdate - <code>true</code> means that the event - * display should be cleared on each update and <code>false</code> - * that it should not. - */ - public void setResetOnUpdate(boolean resetOnUpdate) { - this.resetOnUpdate = resetOnUpdate; - } - - /** - * Initializes the single channel monitoring plots for all crystal - * channels and defines the plotter region that contains them. - */ - @Override - public void detectorChanged(Detector detector) { - // Reset the AIDA tree directory. - aida.tree().cd("/"); - - // Store histograms for the crystals. - channelEnergyPlot = new ArrayList<IHistogram1D>(NUM_CHANNELS); - channelTimePlot = new ArrayList<IHistogram1D>(NUM_CHANNELS); - //channelRawWaveform = new ArrayList<IHistogram1D>(NUM_CHANNELS); - clusterEnergyPlot = new ArrayList<IHistogram1D>(NUM_CHANNELS); - channelTimeVsEnergyPlot = new ArrayList<IHistogram2D>(NUM_CHANNELS); - - // Create the histograms for single channel energy and time - // distribution. - for(int ii = 0; ii < NUM_CHANNELS; ii++) { - // The above instruction is a terrible hack, just to fill - // the arrayList with all the elements. They'll be initialized - // properly during the event readout, Since we want to account - // for possibly different raw waveform dimensions! - - //Get the x and y indices for the current channel. - int row = EcalMonitoringUtilities.getRowFromHistoID(ii); - int column = EcalMonitoringUtilities.getColumnFromHistoID(ii); - - // Initialize the histograms for the current crystal channel. - channelEnergyPlot.add(aida.histogram1D(detector.getDetectorName() + " : " - + inputCollection + " : Hit Energy : " + column + " " + row - + ": " + ii, 100, -0.2, maxEch)); - channelTimePlot.add(aida.histogram1D(detector.getDetectorName() + " : " - + inputCollection + " : Hit Time : " + column + " " + row + ": " - + ii, 100, 0, 400)); - channelTimeVsEnergyPlot.add(aida.histogram2D(detector.getDetectorName() - + " : " + inputCollection + " : Hit Time Vs Energy : " + column - + " " + row + ": " + ii, 100, 0, 400, 100, -0.2, maxEch)); - //channelRawWaveform.add(aida.histogram1D(detector.getDetectorName() + " : " - // + inputCollection + " : Hit Energy : " + column + " " + row + ": " + ii)); - clusterEnergyPlot.add(aida.histogram1D(detector.getDetectorName() + " : " - + inputCollection + " : Cluster Energy : " + column + " " + row - + ": " + ii, 100, -0.2, maxEch)); - - // Note that no raw waveform has yet been read for this - // crystal/channel. - windowRaw[ii] = 1; - isFirstRaw[ii] = true; - } - - // Define the plot region that will display the single channel - // plots in the monitoring application. - plotterFactory = aida.analysisFactory().createPlotterFactory("Single Channel"); - plotter = plotterFactory.create("Single Channel"); - pstyle = this.createDefaultStyle(); - plotter.setTitle(""); - plotter.createRegions(2,2); - - // Define the first plot region. - pstyle.xAxisStyle().setLabel(HIT_ENERGY_TITLE); - pstyle.yAxisStyle().setLabel(NO_TITLE); - plotter.region(0).plot(channelEnergyPlot.get(0), pstyle); - - // Define the second plot region. - pstyle.xAxisStyle().setLabel(HIT_TIME_TITLE); - pstyle.yAxisStyle().setLabel(NO_TITLE); - plotter.region(1).plot(channelTimePlot.get(0), pstyle); - - // Define the third plot region; this encompasses the time vs. - // energy plots. - pstyle.xAxisStyle().setLabel(HIT_TIME_TITLE); - pstyle.yAxisStyle().setLabel(HIT_ENERGY_TITLE); - plotter.region(2).plot(channelTimeVsEnergyPlot.get(0), pstyle); - - // Define the fourth plot region; this encompasses the cluster - // energy for each channel. - pstyle.xAxisStyle().setLabel(CLUSTER_ENERGY_TITLE); - pstyle.yAxisStyle().setLabel(NO_TITLE); - plotter.region(3).plot(clusterEnergyPlot.get(0), pstyle); - - /** + // Class variables. + private static final int NUM_CHANNELS = 11 * 47; + + // Plotter objects and variables. + private IPlotter plotter; + private IPlotterFactory plotterFactory; + private AIDA aida = AIDA.defaultInstance(); + + // LCIO Collection names. + private String inputCollection = "EcalCalHits"; + private String clusterCollection = "EcalClusters"; + private String inputCollectionRaw = "EcalReadoutHits"; + + // Channel plot lists. + private ArrayList<IHistogram1D> channelEnergyPlot; + private ArrayList<IHistogram1D> clusterEnergyPlot; + private ArrayList<IHistogram1D> channelTimePlot; + //private ArrayList<IHistogram1D> channelRawWaveform; + 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. + + // Plot style and title variables. + private static final String NO_TITLE = ""; + //private static final String SIGNAL_TIME_TITLE = "Time (ns)"; + private static final String HIT_TIME_TITLE = "Hit Time (ns)"; + //private static final String SIGNAL_DATA_STYLE_COLOR = "orange"; + //private static final String RAW_WAVEFORM_TITLE = "Raw Waveform"; + private static final String HIT_ENERGY_TITLE = "Hit Energy (GeV)"; + private static final String CLUSTER_ENERGY_TITLE = "Cluster Energy (GeV)"; + private String detectorName; + //private static final String SIGNAL_AMPLITUDE_TITLE = "Signal Amplitude (mV)"; + + /** + * Sets the upper bound of the energy scales used by the driver. + * Energy units are in GeV. + * @param maxEch - The energy scale upper bound. + */ + public void setMaxEch(double maxEch) { + this.maxEch = maxEch; + } + + /** + * Sets the lower bound of the energy scales used by the driver. + * Energy units are in GeV. + * @param minEch - The lower energy scale bound. + */ + public void setMinEch(double minEch) { + this.minEch = minEch; + } + + public void setPedSamples(int pedSamples) { + this.pedSamples = pedSamples; + } + /** + * Sets the LCIO collection name for the processed calorimeter hits. + * @param inputCollection - The LCIO collection name. + */ + public void setInputCollection(String inputCollection) { + this.inputCollection = inputCollection; + } + + /** + * Sets the LCIO collection name for the raw waveform hits. + * @param inputCollectionRaw - The LCIO collection name. + */ + public void setInputCollectionRaw(String inputCollectionRaw) { + this.inputCollectionRaw = inputCollectionRaw; + } + + /** + * Sets the LCIO collection name for calorimeter clusters. + * @param inputClusterCollection - The LCIO collection name. + */ + public void setInputClusterCollection(String inputClusterCollection) { + this.clusterCollection = inputClusterCollection; + } + + /** + * Sets the rate at which the GUI updates its elements, + * @param eventRefreshRate - The rate at which the GUI should be + * updated, in seconds. + */ + public void setEventRefreshRate(int eventRefreshRate) { + this.eventRefreshRate = eventRefreshRate; + } + + /** + * Sets whether the event display should be cleared after event + * or whether it should retain the previously displayed results. + * @param resetOnUpdate - <code>true</code> means that the event + * display should be cleared on each update and <code>false</code> + * that it should not. + */ + public void setResetOnUpdate(boolean resetOnUpdate) { + this.resetOnUpdate = resetOnUpdate; + } + + /** + * Initializes the single channel monitoring plots for all crystal + * channels and defines the plotter region that contains them. + */ + @Override + public void detectorChanged(Detector detector) { + // Reset the AIDA tree directory. + aida.tree().cd("/"); + detectorName=detector.getName(); + // Store histograms for the crystals. + channelEnergyPlot = new ArrayList<IHistogram1D>(NUM_CHANNELS); + channelTimePlot = new ArrayList<IHistogram1D>(NUM_CHANNELS); + //channelRawWaveform = new ArrayList<IHistogram1D>(NUM_CHANNELS); + clusterEnergyPlot = new ArrayList<IHistogram1D>(NUM_CHANNELS); + channelTimeVsEnergyPlot = new ArrayList<IHistogram2D>(NUM_CHANNELS); + + // Create the histograms for single channel energy and time + // distribution. + for(int ii = 0; ii < NUM_CHANNELS; ii++) { + // The above instruction is a terrible hack, just to fill + // the arrayList with all the elements. They'll be initialized + // properly during the event readout, Since we want to account + // for possibly different raw waveform dimensions! + + //Get the x and y indices for the current channel. + int row = EcalMonitoringUtilities.getRowFromHistoID(ii); + int column = EcalMonitoringUtilities.getColumnFromHistoID(ii); + + // Initialize the histograms for the current crystal channel. + channelEnergyPlot.add(aida.histogram1D(detectorName + " : " + + inputCollection + " : Hit Energy : " + column + " " + row + + ": " + ii, 100, -0.2, maxEch)); + channelTimePlot.add(aida.histogram1D(detectorName + " : " + + inputCollection + " : Hit Time : " + column + " " + row + ": " + + ii, 100, 0, 400)); + channelTimeVsEnergyPlot.add(aida.histogram2D(detectorName + + " : " + inputCollection + " : Hit Time Vs Energy : " + column + + " " + row + ": " + ii, 100, 0, 400, 100, -0.2, maxEch)); + //channelRawWaveform.add(aida.histogram1D(detector.getDetectorName() + " : " + // + inputCollection + " : Hit Energy : " + column + " " + row + ": " + ii)); + clusterEnergyPlot.add(aida.histogram1D(detectorName + " : " + + inputCollection + " : Cluster Energy : " + column + " " + row + + ": " + ii, 100, -0.2, maxEch)); + + // Note that no raw waveform has yet been read for this + // crystal/channel. + windowRaw[ii] = 1; + isFirstRaw[ii] = true; + } + + // Define the plot region that will display the single channel + // plots in the monitoring application. + plotterFactory = aida.analysisFactory().createPlotterFactory("Single Channel"); + plotter = plotterFactory.create("Single Channel"); + pstyle = this.createDefaultStyle(); + plotter.setTitle(""); + plotter.createRegions(2,2); + + // Define the first plot region. + pstyle.xAxisStyle().setLabel(HIT_ENERGY_TITLE); + pstyle.yAxisStyle().setLabel(NO_TITLE); + plotter.region(0).plot(channelEnergyPlot.get(0), pstyle); + + // Define the second plot region. + pstyle.xAxisStyle().setLabel(HIT_TIME_TITLE); + pstyle.yAxisStyle().setLabel(NO_TITLE); + plotter.region(1).plot(channelTimePlot.get(0), pstyle); + + // Define the third plot region; this encompasses the time vs. + // energy plots. + pstyle.xAxisStyle().setLabel(HIT_TIME_TITLE); + pstyle.yAxisStyle().setLabel(HIT_ENERGY_TITLE); + plotter.region(2).plot(channelTimeVsEnergyPlot.get(0), pstyle); + + // Define the fourth plot region; this encompasses the cluster + // energy for each channel. + pstyle.xAxisStyle().setLabel(CLUSTER_ENERGY_TITLE); + pstyle.yAxisStyle().setLabel(NO_TITLE); + plotter.region(3).plot(clusterEnergyPlot.get(0), pstyle); + + /** // Define the fourth plot region; this encompasses the raw // wave form plots. pstyle.xAxisStyle().setLabel(RAW_WAVEFORM_TITLE); @@ -241,160 +241,205 @@ pstyle.dataStyle().markerStyle().setColor(SIGNAL_DATA_STYLE_COLOR); pstyle.dataStyle().errorBarStyle().setVisible(false); plotter.region(3).plot(channelRawWaveform.get(0), pstyle); - **/ - - // Display the plot region. - plotter.show(); - - // Set the time tracker variables. - lastEventTime = 0; - } - - /** - * Initializes the <code>Viewer</code> for the single event display. - * If a configuration file is available, then it is used by the - * <code>Viewer</code> to display hardware configuration mappings. - * Otherwise, this is excluded. - */ - @Override - public void startOfData() { - // Check if the configuration mapping file exists. - File config = new File("ecal-mapping-config.csv"); - - // If the file exists, load the viewer that will display it. - if(config.exists() && config.canRead()) { - // Account for IO read errors. Only load this version if - // the data file can be read successfully. - try { viewer = new PDataEventViewer(config.getAbsolutePath()); } - - // Otherwise, open the regular version. - catch (IOException e) { viewer = new PEventViewer(); } - } - - // If the file is not present, then just load the normal version. - else { viewer = new PEventViewer(); } - - // Set the viewer properties. - viewer.setScaleMinimum(minEch); - viewer.setScaleMaximum(maxEch); - viewer.addCrystalListener(this); - - // Make the Viewer object visible. - viewer.setVisible(true); - } - - /** - * Hides the single event display and disposes it from memory. - */ - @Override - public void endOfData() { - viewer.setVisible(false); - viewer.dispose(); - } - - @Override - public void process(EventHeader event){ - // Check whether enough time has passed to perform an update - // on the event display. - boolean update = false; - long currentTime = System.currentTimeMillis() / 1000; - if((currentTime - lastEventTime) > eventRefreshRate){ - lastEventTime = currentTime; - update = true; - } - - // If an update should be made, perform the update. - if(update && resetOnUpdate) { viewer.resetDisplay(); } - - // If the event has calorimeter hit objects... - if(event.hasCollection(CalorimeterHit.class, inputCollection)) { - // Get the list of calorimeter hits. - List<CalorimeterHit> hits = event.get(CalorimeterHit.class, inputCollection); - - // For each of the calorimeter hits... - for (CalorimeterHit hit : hits) { - // Get the x and y indices for the current hit. - int ix = hit.getIdentifierFieldValue("ix"); - int iy = hit.getIdentifierFieldValue("iy"); - - if (iy != 0 && ix != 0) { - // Get the histogram index for the hit. - int id = EcalMonitoringUtilities.getHistoIDFromRowColumn(iy, ix); - - // If the hit has energy, populate the plots. - if(hit.getCorrectedEnergy() > 0) { - channelEnergyPlot.get(id).fill(hit.getCorrectedEnergy()); - channelTimePlot.get(id).fill(hit.getTime()); - channelTimeVsEnergyPlot.get(id).fill(hit.getTime(), hit.getCorrectedEnergy()); - } - - // If an update to the event display should be - // performed, give it the hits. - if(update) { viewer.addHit(hit); } - } - } - } - - // If there are clusters in the event... - if (event.hasCollection(Cluster.class, clusterCollection)) { - // Get the list of clusters. - List<Cluster> clusters = event.get(Cluster.class, clusterCollection); - - // Iterate over the clusters and add them to the event - // display if appropriate. - for (Cluster cluster : clusters) { - // Get the ix and iy indices for the seed. - int ix = cluster.getCalorimeterHits().get(0).getIdentifierFieldValue("ix"); - int iy = cluster.getCalorimeterHits().get(0).getIdentifierFieldValue("iy"); - - // Get the histogram index for the hit. - int id = EcalMonitoringUtilities.getHistoIDFromRowColumn(iy, ix); - - // Add the cluster energy to the plot. - if(cluster.getEnergy() > 0.0) { - clusterEnergyPlot.get(id).fill(cluster.getEnergy()); - } - - // If an update is needed, add the cluster to the viewer. - if(update) { viewer.addCluster(cluster); } - } - } - - /** + **/ + + // Display the plot region. + plotter.show(); + + // Set the time tracker variables. + lastEventTime = 0; + } + + /** + * Initializes the <code>Viewer</code> for the single event display. + * If a configuration file is available, then it is used by the + * <code>Viewer</code> to display hardware configuration mappings. + * Otherwise, this is excluded. + */ + @Override + public void startOfData() { + // Check if the configuration mapping file exists. + File config = new File("ecal-mapping-config.csv"); + + // If the file exists, load the viewer that will display it. + if(config.exists() && config.canRead()) { + // Account for IO read errors. Only load this version if + // the data file can be read successfully. + try { viewer = new PDataEventViewer(config.getAbsolutePath()); } + + // Otherwise, open the regular version. + catch (IOException e) { viewer = new PEventViewer(); } + } + + // If the file is not present, then just load the normal version. + else { viewer = new PEventViewer(); } + + // Set the viewer properties. + viewer.setScaleMinimum(minEch); + viewer.setScaleMaximum(maxEch); + viewer.addCrystalListener(this); + + // Make the Viewer object visible. + viewer.setVisible(true); + } + + /** + * Hides the single event display and disposes it from memory. + * Also removes histograms from aida tree. We do not want them in the output aida file, if any.. + */ + @Override + public void endOfData() { + viewer.setVisible(false); + viewer.dispose(); + + int row,column; + String hName; + System.out.println("EcalEventDisplay endOfData clear histograms"); + for(int ii = 0; ii < NUM_CHANNELS; ii++) { + // The above instruction is a terrible hack, just to fill + // the arrayList with all the elements. They'll be initialized + // properly during the event readout, Since we want to account + // for possibly different raw waveform dimensions! + + //Get the x and y indices for the current channel. + row = EcalMonitoringUtilities.getRowFromHistoID(ii); + column = EcalMonitoringUtilities.getColumnFromHistoID(ii); + hName=detectorName + " : " + + inputCollection + " : Hit Energy : " + column + " " + row + + ": " + ii; + aida.tree().rm(hName); + + hName=detectorName + " : " + + inputCollection + " : Hit Time : " + column + " " + row + ": " + + ii; + aida.tree().rm(hName); + + hName=detectorName+ " : " + inputCollection + " : Hit Time Vs Energy : " + column + + " " + row + ": " + ii; + aida.tree().rm(hName); + + + if (isFirstRaw[ii]==false){ + hName=detectorName+ + " : " + inputCollectionRaw + " : Raw Waveform : " + column + " " + + row + ": " + ii; + aida.tree().rm(hName); + + } + + } + System.out.println("EcalEventDisplay endOfData clear histograms done"); + + + + + + + } + + @Override + public void process(EventHeader event){ + // Check whether enough time has passed to perform an update + // on the event display. + boolean update = false; + long currentTime = System.currentTimeMillis() / 1000; + if((currentTime - lastEventTime) > eventRefreshRate){ + lastEventTime = currentTime; + update = true; + } + + // If an update should be made, perform the update. + if(update && resetOnUpdate) { viewer.resetDisplay(); } + + // If the event has calorimeter hit objects... + if(event.hasCollection(CalorimeterHit.class, inputCollection)) { + // Get the list of calorimeter hits. + List<CalorimeterHit> hits = event.get(CalorimeterHit.class, inputCollection); + + // For each of the calorimeter hits... + for (CalorimeterHit hit : hits) { + // Get the x and y indices for the current hit. + int ix = hit.getIdentifierFieldValue("ix"); + int iy = hit.getIdentifierFieldValue("iy"); + + if (iy != 0 && ix != 0) { + // Get the histogram index for the hit. + int id = EcalMonitoringUtilities.getHistoIDFromRowColumn(iy, ix); + + // If the hit has energy, populate the plots. + if(hit.getCorrectedEnergy() > 0) { + channelEnergyPlot.get(id).fill(hit.getCorrectedEnergy()); + channelTimePlot.get(id).fill(hit.getTime()); + channelTimeVsEnergyPlot.get(id).fill(hit.getTime(), hit.getCorrectedEnergy()); + } + + // If an update to the event display should be + // performed, give it the hits. + if(update) { viewer.addHit(hit); } + } + } + } + + // If there are clusters in the event... + if (event.hasCollection(Cluster.class, clusterCollection)) { + // Get the list of clusters. + List<Cluster> clusters = event.get(Cluster.class, clusterCollection); + + // Iterate over the clusters and add them to the event + // display if appropriate. + for (Cluster cluster : clusters) { + // Get the ix and iy indices for the seed. + int ix = cluster.getCalorimeterHits().get(0).getIdentifierFieldValue("ix"); + int iy = cluster.getCalorimeterHits().get(0).getIdentifierFieldValue("iy"); + + // Get the histogram index for the hit. + int id = EcalMonitoringUtilities.getHistoIDFromRowColumn(iy, ix); + + // Add the cluster energy to the plot. + if(cluster.getEnergy() > 0.0) { + clusterEnergyPlot.get(id).fill(cluster.getEnergy()); + } + + // If an update is needed, add the cluster to the viewer. + if(update) { viewer.addCluster(cluster); } + } + } + + /** // Plot the raw waveform only if raw tracker hit exist in the // event. if (event.hasCollection(RawTrackerHit.class, inputCollectionRaw)){ // Get the list of raw tracker hits. List<RawTrackerHit> hits = event.get(RawTrackerHit.class, inputCollectionRaw); - + // Process each raw tracker hit. for (RawTrackerHit hit : hits) { // Get the x and y indices for the hit. int ix = hit.getIdentifierFieldValue("ix"); int iy = hit.getIdentifierFieldValue("iy"); - + if(iy != 0 && ix != 0) { if(!ECalUtils.isInHole(iy, ix)) { // Get the crystal ID for the current hit. int id = ECalUtils.getHistoIDFromRowColumn(iy, ix); - + // The window is length is not known by default. // If this is the first hit, read the window // length and initialize the plot. if(isFirstRaw[id]) { // Note that this plot is initialized. isFirstRaw[id] = false; - + // Set the waveform array. windowRaw[id] = hit.getADCValues().length; - + // Initialize the waveform plot. channelRawWaveform.set(id, aida.histogram1D(detector.getDetectorName() + " : " + inputCollectionRaw + " : Raw Waveform : " + ix + " " + iy + ": " + id, windowRaw[id], -0.5 * ECalUtils.ecalReadoutPeriod, (-0.5 + windowRaw[id]) * ECalUtils.ecalReadoutPeriod)); } - + // If the plot should be updated, do so. if(update) { channelRawWaveform.get(id).reset(); @@ -412,60 +457,60 @@ } } } - **/ - - // Update the single event display. - if(update) { viewer.updateDisplay(); } - } - - @Override - public void actionPerformed(ActionEvent ae) { } - - @Override - public void crystalActivated(CrystalEvent e) { } - - @Override - public void crystalDeactivated(CrystalEvent e) { } - - /** - * Updates the monitoring plots for the crystal that was clicked. - */ - @Override - public void crystalClicked(CrystalEvent e) { - // Get the crystal that was clicked in the LCSim coordinate system. - Point ecalPoint = Viewer.toEcalPoint(e.getCrystalID()); - - // Make sure that the clicked crystal is valid. Necessary?? - if((ecalPoint.x != 0) && (ecalPoint.y != 0)) - if (!EcalMonitoringUtilities.isInHole(ecalPoint.y, ecalPoint.x)) { - // Get the crystal ID. - int id = EcalMonitoringUtilities.getHistoIDFromRowColumn(ecalPoint.y, ecalPoint.x); - - // Clear and replot region 0 for the new crystal. - plotter.region(0).clear(); - pstyle.xAxisStyle().setLabel(HIT_ENERGY_TITLE); - pstyle.yAxisStyle().setLabel(NO_TITLE); - plotter.region(0).plot(channelEnergyPlot.get(id), pstyle); - - // Clear and replot region 1 for the new crystal. - plotter.region(1).clear(); - pstyle.xAxisStyle().setLabel(HIT_TIME_TITLE); - pstyle.yAxisStyle().setLabel(NO_TITLE); - plotter.region(1).plot(channelTimePlot.get(id), pstyle); - - // Clear and replot region 2 for the new crystal. - plotter.region(2).clear(); - pstyle.xAxisStyle().setLabel(HIT_TIME_TITLE); - pstyle.yAxisStyle().setLabel(HIT_ENERGY_TITLE); - plotter.region(2).plot(channelTimeVsEnergyPlot.get(id), pstyle); - - // Process and plot the region 3 plot. - plotter.region(3).clear(); - pstyle.xAxisStyle().setLabel(CLUSTER_ENERGY_TITLE); - pstyle.yAxisStyle().setLabel(NO_TITLE); - plotter.region(3).plot(clusterEnergyPlot.get(id), pstyle); - - /** + **/ + + // Update the single event display. + if(update) { viewer.updateDisplay(); } + } + + @Override + public void actionPerformed(ActionEvent ae) { } + + @Override + public void crystalActivated(CrystalEvent e) { } + + @Override + public void crystalDeactivated(CrystalEvent e) { } + + /** + * Updates the monitoring plots for the crystal that was clicked. + */ + @Override + public void crystalClicked(CrystalEvent e) { + // Get the crystal that was clicked in the LCSim coordinate system. + Point ecalPoint = Viewer.toEcalPoint(e.getCrystalID()); + + // Make sure that the clicked crystal is valid. Necessary?? + if((ecalPoint.x != 0) && (ecalPoint.y != 0)) + if (!EcalMonitoringUtilities.isInHole(ecalPoint.y, ecalPoint.x)) { + // Get the crystal ID. + int id = EcalMonitoringUtilities.getHistoIDFromRowColumn(ecalPoint.y, ecalPoint.x); + + // Clear and replot region 0 for the new crystal. + plotter.region(0).clear(); + pstyle.xAxisStyle().setLabel(HIT_ENERGY_TITLE); + pstyle.yAxisStyle().setLabel(NO_TITLE); + plotter.region(0).plot(channelEnergyPlot.get(id), pstyle); + + // Clear and replot region 1 for the new crystal. + plotter.region(1).clear(); + pstyle.xAxisStyle().setLabel(HIT_TIME_TITLE); + pstyle.yAxisStyle().setLabel(NO_TITLE); + plotter.region(1).plot(channelTimePlot.get(id), pstyle); + + // Clear and replot region 2 for the new crystal. + plotter.region(2).clear(); + pstyle.xAxisStyle().setLabel(HIT_TIME_TITLE); + pstyle.yAxisStyle().setLabel(HIT_ENERGY_TITLE); + plotter.region(2).plot(channelTimeVsEnergyPlot.get(id), pstyle); + + // Process and plot the region 3 plot. + plotter.region(3).clear(); + pstyle.xAxisStyle().setLabel(CLUSTER_ENERGY_TITLE); + pstyle.yAxisStyle().setLabel(NO_TITLE); + plotter.region(3).plot(clusterEnergyPlot.get(id), pstyle); + + /** // Process and plot the region 3 plot. if(!isFirstRaw[id]) { pstyle.yAxisStyle().setLabel(SIGNAL_AMPLITUDE_TITLE); @@ -479,47 +524,47 @@ pstyle.yAxisStyle().setLabel(""); } plotter.region(3).plot(channelRawWaveform.get(id), pstyle); - **/ - } - } - - /** - * Initializes the default style for plots. - * @return Returns an <code>IPlotterStyle</code> object that - * represents the default style for plots. - */ - public IPlotterStyle createDefaultStyle() { - IPlotterStyle pstyle = plotterFactory.createPlotterStyle(); - // Set the appearance of the axes. - 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); - - // Set color settings. - pstyle.dataStyle().fillStyle().setParameter("colorMapScheme", "rainbow"); - pstyle.dataStyle().fillStyle().setParameter("showZeroHeightBins", Boolean.FALSE.toString()); - pstyle.dataStyle().errorBarStyle().setVisible(false); - pstyle.setParameter("hist2DStyle", "colorMap"); - - // Force auto range to zero. - pstyle.yAxisStyle().setParameter("allowZeroSuppression", "false"); - pstyle.xAxisStyle().setParameter("allowZeroSuppression", "false"); - - // Set the title style. - pstyle.titleStyle().textStyle().setFontSize(20); - - // Draw caps on error bars. - pstyle.dataStyle().errorBarStyle().setParameter("errorBarDecoration", (new Float(1.0f)).toString()); - - // Turn off grid lines until explicitly enabled. - pstyle.gridStyle().setVisible(false); - - // Return the style. - return pstyle; - } + **/ + } + } + + /** + * Initializes the default style for plots. + * @return Returns an <code>IPlotterStyle</code> object that + * represents the default style for plots. + */ + public IPlotterStyle createDefaultStyle() { + IPlotterStyle pstyle = plotterFactory.createPlotterStyle(); + // Set the appearance of the axes. + 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); + + // Set color settings. + pstyle.dataStyle().fillStyle().setParameter("colorMapScheme", "rainbow"); + pstyle.dataStyle().fillStyle().setParameter("showZeroHeightBins", Boolean.FALSE.toString()); + pstyle.dataStyle().errorBarStyle().setVisible(false); + pstyle.setParameter("hist2DStyle", "colorMap"); + + // Force auto range to zero. + pstyle.yAxisStyle().setParameter("allowZeroSuppression", "false"); + pstyle.xAxisStyle().setParameter("allowZeroSuppression", "false"); + + // Set the title style. + pstyle.titleStyle().textStyle().setFontSize(20); + + // Draw caps on error bars. + pstyle.dataStyle().errorBarStyle().setParameter("errorBarDecoration", (new Float(1.0f)).toString()); + + // Turn off grid lines until explicitly enabled. + pstyle.gridStyle().setVisible(false); + + // Return the style. + return pstyle; + } } Modified: java/branches/prod/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/EcalEventDisplayWithRawWaveform.java ============================================================================= --- java/branches/prod/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/EcalEventDisplayWithRawWaveform.java (original) +++ java/branches/prod/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/EcalEventDisplayWithRawWaveform.java Wed Mar 25 14:43:27 2015 @@ -20,7 +20,6 @@ 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; @@ -89,6 +88,7 @@ private static final String HIT_ENERGY_TITLE = "Hit Energy (GeV)"; private static final String CLUSTER_ENERGY_TITLE = "Cluster Energy (GeV)"; private static final String SIGNAL_AMPLITUDE_TITLE = "Signal Amplitude (mV)"; + private String detectorName; /** * Sets the upper bound of the energy scales used by the driver. @@ -161,6 +161,7 @@ */ @Override public void detectorChanged(Detector detector) { + detectorName=detector.getName(); // Reset the AIDA tree directory. aida.tree().cd("/"); @@ -184,18 +185,18 @@ int column = EcalMonitoringUtilities.getColumnFromHistoID(ii); // Initialize the histograms for the current crystal channel. - channelEnergyPlot.add(aida.histogram1D(detector.getDetectorName() + " : " + channelEnergyPlot.add(aida.histogram1D(detectorName + " : " + inputCollection + " : Hit Energy : " + column + " " + row + ": " + ii, 100, -0.2, maxEch)); - channelTimePlot.add(aida.histogram1D(detector.getDetectorName() + " : " + channelTimePlot.add(aida.histogram1D(detectorName + " : " + inputCollection + " : Hit Time : " + column + " " + row + ": " + ii, 100, 0, 400)); - channelTimeVsEnergyPlot.add(aida.histogram2D(detector.getDetectorName() + channelTimeVsEnergyPlot.add(aida.histogram2D(detectorName + " : " + inputCollection + " : Hit Time Vs Energy : " + column + " " + row + ": " + ii, 100, 0, 400, 100, -0.2, maxEch)); - channelRawWaveform.add(aida.histogram1D(detector.getDetectorName() + " : " + channelRawWaveform.add(aida.histogram1D(detectorName + " : " + inputCollection + " : Hit Energy : " + column + " " + row + ": " + ii)); - clusterEnergyPlot.add(aida.histogram1D(detector.getDetectorName() + " : " + clusterEnergyPlot.add(aida.histogram1D(detectorName + " : " + inputCollection + " : Cluster Energy : " + column + " " + row + ": " + ii, 100, -0.2, maxEch)); @@ -289,6 +290,50 @@ public void endOfData() { viewer.setVisible(false); viewer.dispose(); + + + + int row,column; + String hName; + System.out.println("EcalEventDisplay endOfData clear histograms"); + for(int ii = 0; ii < NUM_CHANNELS; ii++) { + // The above instruction is a terrible hack, just to fill + // the arrayList with all the elements. They'll be initialized + // properly during the event readout, Since we want to account + // for possibly different raw waveform dimensions! + + //Get the x and y indices for the current channel. + row = EcalMonitoringUtilities.getRowFromHistoID(ii); + column = EcalMonitoringUtilities.getColumnFromHistoID(ii); + hName=detectorName + " : " + + inputCollection + " : Hit Energy : " + column + " " + row + + ": " + ii; + aida.tree().rm(hName); + + hName=detectorName + " : " + + inputCollection + " : Hit Time : " + column + " " + row + ": " + + ii; + aida.tree().rm(hName); + + hName=detectorName+ " : " + inputCollection + " : Hit Time Vs Energy : " + column + + " " + row + ": " + ii; + aida.tree().rm(hName); + + hName=detectorName + " : " + + inputCollection + " : Cluster Energy : " + column + " " + row + + ": " + ii; + aida.tree().rm(hName); + + hName=detectorName + " : " + + inputCollection + " : Cluster Energy : " + column + " " + row + + ": " + ii; + aida.tree().rm(hName); + + + } + System.out.println("EcalEventDisplay endOfData clear histograms done"); + + } @Override Modified: java/branches/prod/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/EcalHitPlots.java ============================================================================= --- java/branches/prod/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/EcalHitPlots.java (original) +++ java/branches/prod/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/EcalHitPlots.java Wed Mar 25 14:43:27 2015 @@ -9,13 +9,13 @@ import java.util.List; import org.hps.recon.ecal.ECalUtils; +import org.hps.recon.ecal.triggerbank.SSPData; import org.lcsim.event.CalorimeterHit; import org.lcsim.event.EventHeader; import org.lcsim.event.GenericObject; import org.lcsim.geometry.Detector; import org.lcsim.util.Driver; import org.lcsim.util.aida.AIDA; -//import org.jfree.chart.ChartPanel; /** * The driver <code>EcalHitPlots</code> implements the histogram shown to the user @@ -45,20 +45,19 @@ IHistogram1D topTimePlot, botTimePlot, orTimePlot; IHistogram1D topTrigTimePlot, botTrigTimePlot, orTrigTimePlot; IHistogram2D topTimePlot2D, botTimePlot2D, orTimePlot2D; - // IHistogram2D topX, botX, topY, botY; -// IHistogram2D hitNumberPlot; -// IHistogram2D occupancyPlot; - - + IHistogram2D hitNumberPlot; + IHistogram2D occupancyPlot; + + IPlotterFactory plotterFactory; - + int eventn = 0; double maxE = 5000 * ECalUtils.MeV; - + boolean logScale = false; boolean hide = false; - + public void setInputCollection(String inputCollection) { this.inputCollection = inputCollection; } @@ -66,7 +65,7 @@ public void setMaxE(double maxE) { this.maxE = maxE; } - + public void setLogScale(boolean logScale) { this.logScale = logScale; @@ -74,35 +73,36 @@ @Override protected void detectorChanged(Detector detector) { - + System.out.println("Detector changed called: "+ detector.getClass().getName()); aida.tree().cd("/"); plotterFactory = aida.analysisFactory().createPlotterFactory("Ecal Hit Plots"); - - + + // Setup plots. - hitCountPlot = aida.histogram1D(detector.getDetectorName() + " : " + inputCollection + " : Hit Count In Event", 10, -0.5, 9.5); - hitTimePlot = aida.histogram1D(detector.getDetectorName() + " : " + inputCollection + " : Hit Time", 100, 0 * 4.0, 100 * 4.0); - // hitNumberPlot = aida.histogram2D(detector.getDetectorName() + " : " + inputCollection + " : Hit Count"); - // occupancyPlot = aida.histogram2D(detector.getDetectorName() + " : " + inputCollection + " : Occupancy"); + hitCountPlot = aida.histogram1D(detector.getDetectorName() + " : " + inputCollection + " : Hit Count In Event", 30, -0.5, 29.5); + hitNumberPlot = aida.histogram2D(detector.getDetectorName() + " : " + inputCollection + " : Hit Rate KHz"); + occupancyPlot = aida.histogram2D(detector.getDetectorName() + " : " + inputCollection + " : Occupancy"); topTimePlot = aida.histogram1D(detector.getDetectorName() + " : " + inputCollection + " : First Hit Time, Top", 100, 0, 100 * 4.0); botTimePlot = aida.histogram1D(detector.getDetectorName() + " : " + inputCollection + " : First Hit Time, Bottom", 100, 0, 100 * 4.0); orTimePlot = aida.histogram1D(detector.getDetectorName() + " : " + inputCollection + " : First Hit Time, Or", 100, 0, 100 * 4.0); - topTrigTimePlot = aida.histogram1D(detector.getDetectorName() + " : " + inputCollection + " : Trigger Time, Top", 1024, 0, 4096); - botTrigTimePlot = aida.histogram1D(detector.getDetectorName() + " : " + inputCollection + " : Trigger Time, Bottom", 1024, 0, 4096); + + hitTimePlot = aida.histogram1D(detector.getDetectorName() + " : " + inputCollection + " : Hit Time", 100, 0 * 4.0, 100 * 4.0); + topTrigTimePlot = aida.histogram1D(detector.getDetectorName() + " : " + inputCollection + " : Trigger Time, Top", 101, -2, 402); + botTrigTimePlot = aida.histogram1D(detector.getDetectorName() + " : " + inputCollection + " : Trigger Time, Bottom", 101, -2, 402); orTrigTimePlot = aida.histogram1D(detector.getDetectorName() + " : " + inputCollection + " : Trigger Time, Or", 1024, 0, 4096); - topTimePlot2D = aida.histogram2D(detector.getDetectorName() + " : " + inputCollection + " : Hit Time vs. Trig Time, Top", 100, 0, 100 * 4.0, 512, 0, 4096); - botTimePlot2D = aida.histogram2D(detector.getDetectorName() + " : " + inputCollection + " : Hit Time vs. Trig Time, Bottom", 100, 0, 100 * 4.0, 512, 0, 4096); - orTimePlot2D = aida.histogram2D(detector.getDetectorName() + " : " + inputCollection + " : Hit Time vs. Trig Time, Or", 100, 0, 100 * 4.0, 512, 0, 4096); + topTimePlot2D = aida.histogram2D(detector.getDetectorName() + " : " + inputCollection + " : Hit Time vs. Trig Time, Top", 100, 0, 100 * 4.0, 101, -2, 402); + botTimePlot2D = aida.histogram2D(detector.getDetectorName() + " : " + inputCollection + " : Hit Time vs. Trig Time, Bottom", 100, 0, 100 * 4.0, 101, -2, 402); + orTimePlot2D = aida.histogram2D(detector.getDetectorName() + " : " + inputCollection + " : Hit Time vs. Trig Time, Or", 100, 0, 100 * 4.0, 101, -2, 402); hitEnergyPlot = aida.histogram1D(detector.getDetectorName() + " : " + inputCollection + " : Hit Energy", 100, -0.1, maxE); hitMaxEnergyPlot = aida.histogram1D(detector.getDetectorName() + " : " + inputCollection + " : Maximum Hit Energy In Event", 100, -0.1, maxE); - - + + // Setup the plotter. plotter = plotterFactory.create("Hit Counts"); plotter.setTitle("Hit Counts"); @@ -110,65 +110,65 @@ pstyle.setParameter("hist2DStyle", "colorMap"); pstyle.dataStyle().fillStyle().setParameter("colorMapScheme", "rainbow"); pstyle.dataStyle().fillStyle().setParameter("showZeroHeightBins",Boolean.FALSE.toString()); - - + + // Create the plotter regions. plotter.createRegions(2,2); -// plotter.region(0).plot(hitNumberPlot); + plotter.region(0).plot(hitNumberPlot); plotter.region(1).plot(hitTimePlot,pstyle); -// plotter.region(2).plot(occupancyPlot,pstyle); + plotter.region(2).plot(occupancyPlot,pstyle); plotter.region(3).plot(hitCountPlot,pstyle); - - - + + + if (logScale){ - pstyle.zAxisStyle().setParameter("scale", "log"); + pstyle.zAxisStyle().setParameter("scale", "log"); } else pstyle.zAxisStyle().setParameter("scale", "lin"); -// plotter.region(0).plot(hitNumberPlot,pstyle); - - + // plotter.region(0).plot(hitNumberPlot,pstyle); + + // Setup the plotter. plotter2 = plotterFactory.create("Hit Energies"); plotter2.setTitle("Hit Energies"); pstyle.zAxisStyle().setParameter("scale", "lin"); - + if (logScale) { - pstyle.yAxisStyle().setParameter("scale", "log"); + pstyle.yAxisStyle().setParameter("scale", "log"); } else pstyle.yAxisStyle().setParameter("scale", "lin"); // Create the plotter regions. plotter2.createRegions(1, 2); plotter2.region(0).plot(hitEnergyPlot,pstyle); plotter2.region(1).plot(hitMaxEnergyPlot,pstyle); - + plotter3 = plotterFactory.create("Hit Times"); plotter3.setTitle("Hit Times"); plotter3.createRegions(3, 3); - + if (logScale) { - pstyle.yAxisStyle().setParameter("scale", "log"); - } - else pstyle.yAxisStyle().setParameter("scale", "lin"); - + pstyle.yAxisStyle().setParameter("scale", "log"); + } + else pstyle.yAxisStyle().setParameter("scale", "lin"); + plotter3.region(0).plot(topTimePlot,pstyle); plotter3.region(1).plot(botTimePlot,pstyle); plotter3.region(2).plot(orTimePlot,pstyle); plotter3.region(3).plot(topTrigTimePlot,pstyle); plotter3.region(4).plot(botTrigTimePlot,pstyle); plotter3.region(5).plot(orTrigTimePlot,pstyle); - + pstyle.yAxisStyle().setParameter("scale", "lin"); if (logScale){ - pstyle.zAxisStyle().setParameter("scale", "log"); + pstyle.zAxisStyle().setParameter("scale", "log"); } else pstyle.zAxisStyle().setParameter("scale", "lin"); - + plotter3.region(6).plot(topTimePlot2D,pstyle); plotter3.region(7).plot(botTimePlot2D,pstyle); plotter3.region(8).plot(orTimePlot2D,pstyle); - - + + if (!hide) { plotter.show(); plotter2.show(); @@ -178,28 +178,29 @@ @Override public void process(EventHeader event) { - - + + int orTrigTime=4097; int topTrigTime=4097; int botTrigTime=4097; - + if (event.hasCollection(GenericObject.class, "TriggerBank")) { List<GenericObject> triggerList = event.get(GenericObject.class, "TriggerBank"); if (!triggerList.isEmpty()) { GenericObject triggerData = triggerList.get(0); -/* mgraham12/14/2014 ...comment this out for now as it seems to through a null pointer + if (triggerData instanceof SSPData){ orTrigTime=((SSPData)triggerData).getOrTrig(); topTrigTime=((SSPData)triggerData).getTopTrig(); botTrigTime =((SSPData)triggerData).getBotTrig(); - + + orTrigTimePlot.fill(orTrigTime); topTrigTimePlot.fill(topTrigTime); botTrigTimePlot.fill(botTrigTime); - + } - */ + }//end if triggerList isEmpty } @@ -215,11 +216,11 @@ double orTime = Double.POSITIVE_INFINITY; for (CalorimeterHit hit : hits) { - + hitEnergyPlot.fill(hit.getRawEnergy()); hitTimePlot.fill(hit.getTime()); - - + + if (hit.getTime() < orTime) { orTime = hit.getTime(); } @@ -233,7 +234,7 @@ maxEnergy = hit.getRawEnergy(); } } - + if (orTime != Double.POSITIVE_INFINITY) { orTimePlot.fill(orTime); orTimePlot2D.fill(orTime, orTrigTime); @@ -247,22 +248,6 @@ botTimePlot2D.fill(botTime, botTrigTime); } hitMaxEnergyPlot.fill(maxEnergy); - - for (int i = 0; i < hits.size(); i++) { - CalorimeterHit hit1 = hits.get(i); - int x1 = hit1.getIdentifierFieldValue("ix"); - int y1 = hit1.getIdentifierFieldValue("iy"); - for (int j = i + 1; j < hits.size(); j++) { - CalorimeterHit hit2 = hits.get(j); - int x2 = hit2.getIdentifierFieldValue("ix"); - int y2 = hit2.getIdentifierFieldValue("iy"); - if ((Math.abs(x1 - x2) <= 1 || x1 * x2 == -1) && (Math.abs(y1 - y2) <= 1)) { - if (x1 != x2 || y1 != y2) { - // edgePlot.fill((x1 + x2) / 2.0, (y1 + y2) / 2.0); - } - } - } - } } else { hitCountPlot.fill(0); } @@ -277,54 +262,54 @@ { this.hide=hide; } - - + + /** - * Initializes the default style for plots. - * @return Returns an <code>IPlotterStyle</code> object that - * represents the default style for plots. - */ - public IPlotterStyle createDefaultStyle() { - IPlotterStyle pstyle = plotterFactory.createPlotterStyle(); - // Set the appearance of the axes. - 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); - - // Set color settings. - pstyle.dataStyle().fillStyle().setParameter("colorMapScheme", "rainbow"); - pstyle.dataStyle().fillStyle().setParameter("showZeroHeightBins", Boolean.FALSE.toString()); - pstyle.dataStyle().errorBarStyle().setVisible(false); - pstyle.setParameter("hist2DStyle", "colorMap"); - - // Force auto range to zero. - pstyle.yAxisStyle().setParameter("allowZeroSuppression", "false"); - pstyle.xAxisStyle().setParameter("allowZeroSuppression", "false"); - - // Set the title style. - pstyle.titleStyle().textStyle().setFontSize(20); - - // Draw caps on error bars. - pstyle.dataStyle().errorBarStyle().setParameter("errorBarDecoration", (new Float(1.0f)).toString()); - - // Turn off grid lines until explicitly enabled. - pstyle.gridStyle().setVisible(false); - - // Return the style. - return pstyle; - } - - - - - - - + * Initializes the default style for plots. + * @return Returns an <code>IPlotterStyle</code> object that + * represents the default style for plots. + */ + public IPlotterStyle createDefaultStyle() { + IPlotterStyle pstyle = plotterFactory.createPlotterStyle(); + // Set the appearance of the axes. + 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); + + // Set color settings. + pstyle.dataStyle().fillStyle().setParameter("colorMapScheme", "rainbow"); + pstyle.dataStyle().fillStyle().setParameter("showZeroHeightBins", Boolean.FALSE.toString()); + pstyle.dataStyle().errorBarStyle().setVisible(false); + pstyle.setParameter("hist2DStyle", "colorMap"); + + // Force auto range to zero. + pstyle.yAxisStyle().setParameter("allowZeroSuppression", "false"); + pstyle.xAxisStyle().setParameter("allowZeroSuppression", "false"); + + // Set the title style. + pstyle.titleStyle().textStyle().setFontSize(20); + + // Draw caps on error bars. + pstyle.dataStyle().errorBarStyle().setParameter("errorBarDecoration", (new Float(1.0f)).toString()); + + // Turn off grid lines until explicitly enabled. + pstyle.gridStyle().setVisible(false); + + // Return the style. + return pstyle; + } + + + + + + + } - + Modified: java/branches/prod/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/EcalMonitoringPlots.java ============================================================================= --- java/branches/prod/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/EcalMonitoringPlots.java (original) +++ java/branches/prod/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/EcalMonitoringPlots.java Wed Mar 25 14:43:27 2015 @@ -42,10 +42,12 @@ IHistogram2D clusterCountDrawPlot; int eventRefreshRate = 1; int eventn = 0; + int thisEventN,prevEventN; + boolean hide = false; - boolean accumulateHits = false; long thisTime,prevTime; - + double thisEventTime,prevEventTime; + public EcalMonitoringPlots() { } @@ -61,9 +63,7 @@ this.hide = hide; } - public void setAccumulateHits(boolean accumulateHits) { - this.accumulateHits = accumulateHits; - } + /** * Set the refresh rate for histograms in this driver * @param eventRefreshRate: the refresh rate, defined as number of events to accumulate before @@ -80,21 +80,20 @@ // Setup plots. aida.tree().cd("/"); String hitCountDrawPlotTitle; - if (accumulateHits) hitCountDrawPlotTitle = detector.getDetectorName() + " : " + inputCollection + " : Hit Count (accumulated)"; - else hitCountDrawPlotTitle = detector.getDetectorName() + " : " + inputCollection + " : Hit Count (refreshed)"; - - hitCountDrawPlot = aida.histogram2D(hitCountDrawPlotTitle, 47, -23.5, 23.5, 11, -5.5, 5.5); - hitCountFillPlot = makeCopy(hitCountDrawPlot); + hitCountDrawPlotTitle = detector.getDetectorName() + " : " + inputCollection + " : Hit Rate KHz"; + + hitCountDrawPlot = aida.histogram2D(hitCountDrawPlotTitle, 47, -23.5, 23.5, 11, -5.5, 5.5); + hitCountFillPlot = makeCopy(hitCountDrawPlot); occupancyDrawPlot = aida.histogram2D(detector.getDetectorName() + " : " + inputCollection + " : Occupancy", 47, -23.5, 23.5, 11, -5.5, 5.5); - clusterCountDrawPlot = aida.histogram2D(detector.getDetectorName() + " : " + clusterCollection + " : Cluster Center Count", 47, -23.5, 23.5, 11, -5.5, 5.5); + clusterCountDrawPlot = aida.histogram2D(detector.getDetectorName() + " : " + clusterCollection + " : Cluster Rate KHz", 47, -23.5, 23.5, 11, -5.5, 5.5); clusterCountFillPlot = makeCopy(clusterCountDrawPlot); - + NoccupancyFill=1; //to avoid a "NaN" at beginning for (int ii = 0; ii < (11 * 47); ii++) { int row = EcalMonitoringUtilities.getRowFromHistoID(ii); int column = EcalMonitoringUtilities.getColumnFromHistoID(ii); - occupancyFill[ii]=0; + occupancyFill[ii]=0.; } // Create the plotter regions. @@ -122,24 +121,18 @@ } prevTime=0; //init the time thisTime=0; //init the time + + thisEventN=0; + prevEventN=0; + + thisEventTime=0; + prevEventTime=0; } public void process(EventHeader event) { int nhits = 0; int chits[] = new int[11 * 47]; - /* - * if (event.hasCollection(BaseRawCalorimeterHit.class, inputCollection)) { - * List<BassRawCalorimeterHit> hits = event.get(BaseRawCalorimeterHit.class, - * inputCollection); for (BaseRawCalorimeterHit hit : hits) { int - * column=hit.getIdentifierFieldValue("ix"); int row=hit.getIdentifierFieldValue("iy"); int - * id=EcalMonitoringUtils.getHistoIDFromRowColumn(row, column); - * hitCountFillPlot.fill(column,row); chits[id]++; nhits++; } } if - * (event.hasCollection(RawTrackerHit.class, inputCollection)) { List<RawTrackerHit> hits = - * event.get(RawTrackerHit.class, inputCollection); for (RawTrackerHit hit : hits) { int - * column=hit.getIdentifierFieldValue("ix"); int row=hit.getIdentifierFieldValue("iy"); int - * id=EcalMonitoringUtils.getHistoIDFromRowColumn(row, column); - * hitCountFillPlot.fill(column,row); chits[id]++; nhits++; } } - */ + if (event.hasCollection(CalorimeterHit.class, inputCollection)) { List<CalorimeterHit> hits = event.get(CalorimeterHit.class, inputCollection); for (CalorimeterHit hit : hits) { @@ -148,15 +141,15 @@ int id = EcalMonitoringUtilities.getHistoIDFromRowColumn(row, column); hitCountFillPlot.fill(column, row); { - chits[id]++; - nhits++; + chits[id]++; + nhits++; } } } if (nhits > 0) { for (int ii = 0; ii < (11 * 47); ii++) { - occupancyFill[ii]+=1.*chits[ii]/nhits; + occupancyFill[ii]+=(1.*chits[ii])/nhits; } } @@ -166,16 +159,32 @@ clusterCountFillPlot.fill(cluster.getCalorimeterHits().get(0).getIdentifierFieldValue("ix"), cluster.getCalorimeterHits().get(0).getIdentifierFieldValue("iy")); } } - + thisTime=System.currentTimeMillis()/1000; - + thisEventN=event.getEventNumber(); + thisEventTime=event.getTimeStamp()/1E9; if ((thisTime-prevTime)>eventRefreshRate){ - prevTime=thisTime; - redraw(); - NoccupancyFill=0; + double scale=1.; + + if (NoccupancyFill>0){ + scale=(thisEventN-prevEventN)/NoccupancyFill; + scale=scale/(thisEventTime-prevEventTime); + scale/=1000. ; //do KHz + } + //System.out.println("Event: "+thisEventN+" "+prevEventN); + //System.out.println("Time: "+thisEventTime+" "+prevEventTime); + // System.out.println("Monitor: "+thisTime+" "+prevTime+" "+NoccupancyFill); + + hitCountFillPlot.scale(scale); + clusterCountFillPlot.scale(scale); + redraw(); + prevTime=thisTime; + prevEventN=thisEventN; + prevEventTime=thisEventTime; + NoccupancyFill=0; } else{ - NoccupancyFill++; + NoccupancyFill++; } } @@ -190,22 +199,21 @@ plotter.region(0).clear(); plotter.region(0).plot(hitCountDrawPlot); plotter.region(0).refresh(); - - if (!accumulateHits){ - hitCountFillPlot.reset(); - } + hitCountFillPlot.reset(); + clusterCountDrawPlot.reset(); clusterCountDrawPlot.add(clusterCountFillPlot); plotter.region(1).clear(); plotter.region(1).plot(clusterCountDrawPlot); plotter.region(1).refresh(); - + clusterCountFillPlot.reset(); + occupancyDrawPlot.reset(); for (int id = 0; id < (47 * 11); id++) { int row = EcalMonitoringUtilities.getRowFromHistoID(id); int column = EcalMonitoringUtilities.getColumnFromHistoID(id); double mean = occupancyFill[id]/NoccupancyFill; - + occupancyFill[id]=0; if ((row != 0) && (column != 0) && (!EcalMonitoringUtilities.isInHole(row, column))) occupancyDrawPlot.fill(column, row, mean); Modified: java/branches/prod/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/EcalMonitoringUtilities.java ============================================================================= --- java/branches/prod/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/EcalMonitoringUtilities.java (original) +++ java/branches/prod/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/EcalMonitoringUtilities.java Wed Mar 25 14:43:27 2015 @@ -35,6 +35,8 @@ return true; } } + else if (row == 0) return true; + else if (column ==0) return true; return false; } Modified: java/branches/prod/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/EcalPedestalViewer.java ============================================================================= --- java/branches/prod/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/EcalPedestalViewer.java (original) +++ java/branches/prod/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/EcalPedestalViewer.java Wed Mar 25 14:43:27 2015 @@ -31,7 +31,7 @@ public class EcalPedestalViewer extends Driver implements CrystalListener, ActionListener { // this has to match the one in EcalPedstalCalculator: - private String histoNameFormat = "Ecal/Pedestals/Mode7/ped%3d"; + private String histoNameFormat = "Ecal/Pedestals/Mode7/ped%03d"; private AIDA aida = AIDA.defaultInstance(); private IPlotter plotter; @@ -39,12 +39,33 @@ 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(1,1); + 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 @@ -78,8 +99,12 @@ if (hist==null) { System.err.println("Running the Driver?"); } else { - plotter.region(0).clear(); - plotter.region(0).plot(hist,pstyle); + 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); } } Modified: java/branches/prod/monitoring-util/src/main/java/org/hps/monitoring/plotting/MonitoringPlotFactory.java ============================================================================= --- java/branches/prod/monitoring-util/src/main/java/org/hps/monitoring/plotting/MonitoringPlotFactory.java (original) +++ java/branches/prod/monitoring-util/src/main/java/org/hps/monitoring/plotting/MonitoringPlotFactory.java Wed Mar 25 14:43:27 2015 @@ -13,6 +13,7 @@ import org.jfree.chart.ChartPanel; import org.jfree.chart.JFreeChart; +import org.jfree.data.time.RegularTimePeriod; /** * This class implements an AIDA <code>IPlotterFactory</code> for the monitoring application. It @@ -22,7 +23,10 @@ * by the MonitoringApplication before any calls to AIDA are made from Drivers. */ public class MonitoringPlotFactory extends PlotterFactory { - + + // Global plotter registry. + static PlotterRegistry plotters = new PlotterRegistry(); + // The name of the factory which will be used in naming tabs in the monitoring app. String name = null; @@ -32,14 +36,22 @@ // Root pane where this factory's top-level tab will be inserted. private static JTabbedPane rootPane = null; + // The region listener for handling mouse clicks in a region. private static PlotterRegionListener regionListener; - + + // The current tab index. + int tabIndex; + + /** + * Set the plot region listener. + * @param regionListener The plot region listener. + */ public static void setPlotterRegionListener(PlotterRegionListener regionListener) { MonitoringPlotFactory.regionListener = regionListener; } /** - * Class constructor. + * Class constructor for unnamed factory. */ MonitoringPlotFactory() { super(); @@ -50,7 +62,7 @@ } /** - * Class constructor. + * Class constructor for named factory. * @param name The name of the factory. */ MonitoringPlotFactory(String name) { @@ -62,11 +74,16 @@ addPlotterRegionListener(regionListener); } + /** + * Setup the root GUI pane of this factory for display of plots in tabs. + * @param name The tab's label. + */ private void setupRootPane(String name) { // FIXME: Hack to disregard call from an AIDA related class. if (!(new RuntimeException()).getStackTrace()[2].getClassName().equals("hep.aida.ref.plotter.style.registry.StyleStoreXMLReader")) { rootPane.addTab(name, tabs); - rootPane.setTabComponentAt(rootPane.getTabCount() - 1, new JLabel(name)); + tabIndex = rootPane.getTabCount() - 1; + rootPane.setTabComponentAt(tabIndex, new JLabel(name)); } } @@ -97,36 +114,90 @@ MonitoringPlotFactory.rootPane = rootPane; } + /** + * Setup a plotter tab. + * @param plotterName The name of the plotter. + * @param plotter The IPlotter which will plot into the tab. + */ private void setupPlotterTab(String plotterName, IPlotter plotter) { + + // Setup the plotter's GUI pane and tab. JPanel plotterPanel = new JPanel(new BorderLayout()); plotterPanel.add(PlotterUtilities.componentForPlotter(plotter), BorderLayout.CENTER); tabs.addTab(plotterName, plotterPanel); - tabs.setTabComponentAt(tabs.getTabCount() - 1, new JLabel(plotterName)); - } - + int plotterIndex = tabs.getTabCount() - 1; + tabs.setTabComponentAt(plotterIndex, new JLabel(plotterName)); + + // Register plotter globally with its tab indices. + plotters.register(plotter, tabIndex, plotterIndex); + } + + /** + * Add a <code>JFreeChart</code> to one of the tabs. + * @param chart The JFreeChart object to add. + */ private void addChart(JFreeChart chart) { ChartPanel panel = new ChartPanel(chart); tabs.addTab(chart.getTitle().getText(), panel); tabs.setTabComponentAt(tabs.getTabCount() - 1, new JLabel(chart.getTitle().getText())); } - - /** - * Create a strip chart using a JFreeChart implementation. It will be automatically updated from - * a {@link StripChartUpdater}. Similar to AIDA plots, the chart will be given a sub-tab in the - * tab of this factory. - * - * @param title The title of the chart. - * @param yAxisLabel The y axis label. - * @param size The buffer size of the series which determines how much data displays. - * @param updater The updater which will update the chart in real time. - * @return The modified <tt>StripChartUpdater</tt> which points to the new chart. - */ - public StripChartUpdater createStripChart(String title, String yAxisLabel, int size, StripChartUpdater updater) { - JFreeChart stripChart = StripChartBuilder.createDynamicTimeSeriesChart(title, yAxisLabel, size); - stripChart.getLegend().setVisible(false); /* Legend turned off for now. */ - addChart(stripChart); - updater.setChart(stripChart); + + /** + * This creates a strip chart with full parameter settings, which will automatically + * update at a certain time interval. + * @param name The title of the chart. + * @param rangeLabel The range axis label text. + * @param seriesCount The number of series in the data set. + * @param seriesNames The names of the series (if non-null the length must match seriesCount). + * @param itemCount The maximum number of items in the series. + * @param timeBase The time unit for updates. + * @param valueProvider The interface for providing the series values. + * @param rangeView The view in the domain axis around the current data point (applied to plus and minus). + * @return The StripChartUpdater for the chart. + */ + public StripChartUpdater createStripChart( + String name, + String rangeLabel, + int seriesCount, + String[] seriesNames, + int itemCount, + RegularTimePeriod timeBase, + ValueProvider valueProvider, + long rangeView) { + StripChartUpdater updater = StripChartBuilder.createDynamicTimeSeriesChart( + name, + rangeLabel, + seriesCount, + seriesNames, + itemCount, + timeBase, + valueProvider, + rangeView); + addChart(updater.getChart()); return updater; + } + + /** + * Create a strip chart with simple parameter settings. + * @param name The title of the strip chart. + * @param seriesCount The number of series in the data set. + * @param timeBase The time interval for updating. + * @param valueProvider The interface for providing values. + * @return The StripChartUpdater for the chart. + */ + public StripChartUpdater createStripChart( + String name, + int seriesCount, + RegularTimePeriod timeBase, + ValueProvider valueProvider) { + return createStripChart( + name, "Values", + seriesCount, + null, + 9999, + timeBase, + valueProvider, + 10000L); } /** @@ -143,5 +214,24 @@ stripChart.getLegend().setVisible(false); /* Legend turned off for now. */ addChart(stripChart); return stripChart; - } -} + } + + public JFreeChart createTimeSeriesChart( + String title, + String yAxisLabel, + int seriesCount, + String[] datasetNames, + double rangeSize) { + JFreeChart chart = StripChartBuilder.createTimeSeriesChart(title, yAxisLabel, seriesCount, datasetNames, rangeSize); + addChart(chart); + return chart; + } + + /** + * Get the global registry of plotters. + * @return The global plotter registry. + */ + public static PlotterRegistry getPlotterRegistry() { + return plotters; + } +} Modified: java/branches/prod/monitoring-util/src/main/java/org/hps/monitoring/plotting/StripChartBuilder.java ============================================================================= --- java/branches/prod/monitoring-util/src/main/java/org/hps/monitoring/plotting/StripChartBuilder.java (original) +++ java/branches/prod/monitoring-util/src/main/java/org/hps/monitoring/plotting/StripChartBuilder.java Wed Mar 25 14:43:27 2015 @@ -1,45 +1,90 @@ package org.hps.monitoring.plotting; - -import java.util.Date; import org.jfree.chart.ChartFactory; import org.jfree.chart.JFreeChart; import org.jfree.chart.axis.NumberAxis; import org.jfree.chart.plot.XYPlot; import org.jfree.data.time.DynamicTimeSeriesCollection; -import org.jfree.data.time.Second; +import org.jfree.data.time.RegularTimePeriod; import org.jfree.data.time.TimeSeries; import org.jfree.data.time.TimeSeriesCollection; /** - * Utility methods for building strip charts using JFreeChart backend. + * Utility methods for building strip charts using JFreeChart back end. */ public final class StripChartBuilder { private StripChartBuilder() { } - - /** - * This creates a strip chart that will be updated at fixed intervals from a timer. - * @param title - * @param yAxisLabel - * @param size - * @return - */ - public static JFreeChart createDynamicTimeSeriesChart(String title, String yAxisLabel, int size) { - final DynamicTimeSeriesCollection dataset = new DynamicTimeSeriesCollection(1, size, new Second()); - dataset.setTimeBase(new Second(new Date())); - dataset.addSeries(new float[] {}, 0, "Default Dataset"); - - final JFreeChart result = ChartFactory.createTimeSeriesChart(title, "hh:mm:ss", yAxisLabel, dataset, true, true, false); - final XYPlot plot = result.getXYPlot(); - plot.getDomainAxis().setAutoRange(true); - NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis(); - rangeAxis.setAutoRange(true); - rangeAxis.setAutoRangeIncludesZero(true); - return result; + + /** + * Create a strip chart with simple parameter settings. + * @param name The title of the strip chart. + * @param seriesCount The number of series in the data set. + * @param timeBase The time interval for updating. + * @param valueProvider The interface for providing values. + * @return The StripChartUpdater for the chart. + */ + static StripChartUpdater createDynamicTimeSeriesChart( + String name, + int seriesCount, + RegularTimePeriod timeBase, + ValueProvider valueProvider) { + return createDynamicTimeSeriesChart(name, "Values", seriesCount, null, 9999, timeBase, valueProvider, 10000L); } - + + /** + * This creates a strip chart with full parameter settings, which will automatically + * update at a certain time interval. + * @param name The title of the chart. + * @param rangeLabel The range axis label text. + * @param seriesCount The number of series in the data set. + * @param seriesNames The names of the series (if non-null the length must match seriesCount). + * @param itemCount The maximum number of items in the series. + * @param timeBase The time unit for updates. + * @param valueProvider The interface for providing the series values. + * @param rangeView The view in the domain axis around the current data point (milliseconds). + * @return The StripChartUpdater for the chart. + */ + static StripChartUpdater createDynamicTimeSeriesChart( + String name, + String rangeLabel, + int seriesCount, + String[] seriesNames, + int itemCount, + RegularTimePeriod timeBase, + ValueProvider valueProvider, + long rangeView) { + + if (seriesNames != null && seriesCount != seriesNames.length) { + throw new IllegalArgumentException("seriesNames is wrong length"); + } + final DynamicTimeSeriesCollection dataset = new DynamicTimeSeriesCollection(seriesCount, itemCount, timeBase); + dataset.setTimeBase(timeBase); + for (int series = 0; series < seriesCount; series++) { + String seriesName = name + " " + series; + if (seriesNames != null) { + seriesName = seriesNames[series]; + } + dataset.addSeries(new float[] {}, series, seriesName); + } + + final JFreeChart chart = ChartFactory.createTimeSeriesChart(name, "hh:mm:ss", rangeLabel, dataset, false, false, false); + + chart.getXYPlot().getRangeAxis().setAutoRange(true); + + StripChartUpdater updater = new StripChartUpdater( + chart, + valueProvider, + rangeView, + timeBase + ); + + updater.start(); + + return updater; + } + /** * This should be used when the time period for updating is variable. * @@ -47,13 +92,18 @@ * * <code>sensorSeries.add(new Minute(new Date()), newData);</code> * - * @param title - * @param yAxisLabel - * @param maxAge - * @param maxCount - * @return - */ - public static JFreeChart createTimeSeriesChart(String title, String yAxisLabel, int maxAge, int maxCount, int rangeSize) { + * @param title The title of the chart. + * @param yAxisLabel The range axis label. + * @param maxAge The maximum age of an item. + * @param maxCount The maximum count of items in the single data set series. + * @return The chart that was created. + */ + static JFreeChart createTimeSeriesChart( + String title, + String yAxisLabel, + int maxAge, + int maxCount, + int rangeSize) { TimeSeriesCollection dataset = new TimeSeriesCollection(); TimeSeries timeSeries = new TimeSeries("Default Dataset"); @@ -61,7 +111,14 @@ timeSeries.setMaximumItemCount(maxCount); dataset.addSeries(timeSeries); - final JFreeChart result = ChartFactory.createTimeSeriesChart(title, "hh:mm:ss", yAxisLabel, dataset, true, true, false); + final JFreeChart result = ChartFactory.createTimeSeriesChart( + title, + "hh:mm:ss", + yAxisLabel, + dataset, + true, + false, + false); final XYPlot plot = result.getXYPlot(); plot.getDomainAxis().setAutoRange(true); plot.getDomainAxis().setAutoRangeMinimumSize(rangeSize); @@ -69,6 +126,75 @@ rangeAxis.setAutoRange(true); rangeAxis.setAutoRangeIncludesZero(true); return result; - } - + } + + /** + * <p> + * This can be used to create a strip chart with multiple <code>TimeSeries</code> + * in the data set. + * <p> + * To update a chart of this type, use the following types of method calls: + * <pre> + * dataset.getSeries(0).add(new Second(time), value1); + * dataset.getSeries(1).add(new Second(time), value2); + * </pre> + * <p> + * It is not updated manually but will refresh will values are added to the backing dataset. + * + * @param title The title of the chart. + * @param yAxisLabel The range axis label. + * @param seriesCount The number of series in the dataset. + * @param datasetNames The names of the datasets (can be null to use defaults). + * @param rangeSize The range of values to show for auto-ranging in domain axis (in milliseconds). + * @return The chart that was created. + */ + static JFreeChart createTimeSeriesChart( + String title, + String yAxisLabel, + int seriesCount, + String[] datasetNames, + double rangeSize) { + + // If dataset names are given, the length must match the number of series requested. + if (datasetNames != null && seriesCount != datasetNames.length) { + throw new IllegalArgumentException("datasetNames has wrong length: " + datasetNames.length); + } + + // Create the dataset and add empty series to it. + TimeSeriesCollection dataset = new TimeSeriesCollection(); + for (int i = 0; i < seriesCount; i++) { + + // Uses title for dataset names if none given explicitly. + String datasetName = title; + + if (datasetNames != null) { + // Use the explicitly given dataset names. + datasetName = datasetNames[i]; + } + TimeSeries timeSeries = new TimeSeries(datasetName); + dataset.addSeries(timeSeries); + } + + // Create the chart. + final JFreeChart result = ChartFactory.createTimeSeriesChart( + title, + "hh:mm:ss", + yAxisLabel, + dataset, + true, + false, + false); + final XYPlot plot = result.getXYPlot(); + + // Configure range axis. + NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis(); + rangeAxis.setAutoRange(true); + rangeAxis.setAutoRangeIncludesZero(true); + + // Configure domain axis. + plot.getDomainAxis().setAutoRange(true); + plot.getDomainAxis().setAutoRangeMinimumSize(rangeSize); + + return result; + } } Modified: java/branches/prod/monitoring-util/src/main/java/org/hps/monitoring/plotting/StripChartUpdater.java ============================================================================= --- java/branches/prod/monitoring-util/src/main/java/org/hps/monitoring/plotting/StripChartUpdater.java (original) +++ java/branches/prod/monitoring-util/src/main/java/org/hps/monitoring/plotting/StripChartUpdater.java Wed Mar 25 14:43:27 2015 @@ -1,38 +1,67 @@ package org.hps.monitoring.plotting; +import java.util.Date; import java.util.Timer; import java.util.TimerTask; import org.jfree.chart.JFreeChart; +import org.jfree.chart.axis.DateAxis; import org.jfree.data.time.DynamicTimeSeriesCollection; +import org.jfree.data.time.RegularTimePeriod; /** * An abstract <tt>TimerTask</tt> to update a strip chart at a regular interval. */ -public abstract class StripChartUpdater extends TimerTask { +public class StripChartUpdater { + + final JFreeChart chart; + final DateAxis domainAxis; + final DynamicTimeSeriesCollection dataset; + final Timer timer; + final TimerTask task; + final Long rangeMillis; + final ValueProvider valueProvider; + long updateInterval; + + StripChartUpdater(JFreeChart chart, ValueProvider valueProvider, Long rangeMillis, RegularTimePeriod timeBase) { + this.chart = chart; + this.domainAxis = (DateAxis) chart.getXYPlot().getDomainAxis(); + this.dataset = (DynamicTimeSeriesCollection) chart.getXYPlot().getDataset(); + this.rangeMillis = rangeMillis; + this.updateInterval = timeBase.getLastMillisecond() - timeBase.getFirstMillisecond(); + this.valueProvider = valueProvider; + timer = new Timer(chart.getTitle().getText() + " Timer"); + task = new TimerTask() { + + @Override + public void run() { + StripChartUpdater.this.chart.setNotify(false); + + dataset.advanceTime(); + long time = dataset.getNewestTime().getEnd().getTime(); + + float values[] = StripChartUpdater.this.valueProvider.getValues(); + dataset.appendData(values); + + domainAxis.setRange( + new Date(time - StripChartUpdater.this.rangeMillis), + new Date(time + updateInterval)); - DynamicTimeSeriesCollection dataset; - long updateIntervalMillis = 1000; - - public StripChartUpdater() { + StripChartUpdater.this.chart.setNotify(true); + StripChartUpdater.this.chart.fireChartChanged(); + } + }; } - - public void setChart(JFreeChart chart) { - this.dataset = (DynamicTimeSeriesCollection) chart.getXYPlot().getDataset(); + + JFreeChart getChart() { + return chart; } - - public void setUpdateIntervalMillis(long updateIntervalMillis) { - this.updateIntervalMillis = updateIntervalMillis; + + void start() { + timer.scheduleAtFixedRate(task, 0, updateInterval); + } + + public void stop() { + timer.cancel(); } - - public void run() { - dataset.advanceTime(); - dataset.appendData(new float[] { nextValue() }); - } - - public void schedule(Timer timer) { - timer.schedule(this, 0, updateIntervalMillis); - } - - public abstract float nextValue(); } Modified: java/branches/prod/monitoring-util/src/main/java/org/hps/monitoring/subsys/StatusCode.java ============================================================================= --- java/branches/prod/monitoring-util/src/main/java/org/hps/monitoring/subsys/StatusCode.java (original) +++ java/branches/prod/monitoring-util/src/main/java/org/hps/monitoring/subsys/StatusCode.java Wed Mar 25 14:43:27 2015 @@ -1,16 +1,29 @@ package org.hps.monitoring.subsys; + +import java.awt.Color; /** * Code that represents a sub-system status. */ public enum StatusCode { - OKAY, - UNKNOWN, - CLEARED, - OFFLINE, - INFO, - WARNING, - ERROR, - ALARM, - HALT; + + OKAY(Color.GREEN), + UNKNOWN(Color.GRAY), + CLEARED(Color.LIGHT_GRAY), + OFFLINE(Color.ORANGE), + INFO(Color.WHITE), + WARNING(Color.YELLOW), + ERROR(Color.RED), + ALARM(Color.RED), + HALT(Color.RED); + + Color color; + + StatusCode(Color color) { + this.color = color; + } + + public Color getColor() { + return color; + } } Modified: java/branches/prod/monitoring-util/src/main/java/org/hps/monitoring/subsys/SystemStatistics.java ============================================================================= --- java/branches/prod/monitoring-util/src/main/java/org/hps/monitoring/subsys/SystemStatistics.java (original) +++ java/branches/prod/monitoring-util/src/main/java/org/hps/monitoring/subsys/SystemStatistics.java Wed Mar 25 14:43:27 2015 @@ -1,7 +1,6 @@ package org.hps.monitoring.subsys; import java.io.PrintStream; -import java.util.TimerTask; /** * This is an interface for a set of basic statistics about an online event processing system. @@ -12,13 +11,20 @@ * Set the desired timer tick length in millis. * @param tickLengthMillis The desired tick length in millis. */ - void setTickLengthMillis(long tickLengthMillis); + void setNominalTickLengthMillis(long tickLengthMillis); /** - * Get the nominal length of one tick in millis. Actual ticks lengths may vary slightly. + * Get the nominal length of one tick in millis. + * Actual tick lengths lengths may vary slightly. * @return The nominal tick length in millis. */ - long getTickLengthMillis(); + long getNominalTickLengthMillis(); + + /** + * Get the end of the tick in Unix time (milliseconds since the epoch). + * @return The tick end in Unix time. + */ + long getTickEndTimeMillis(); /** * Start the timer thread for accumulating statistics. @@ -106,6 +112,13 @@ * @return The data rate in [bytes/second]. */ public double getBytesPerSecond(); + + /** + * Get the immediate data rate which is the amount of data in megabytes received in the current tick + * over the time elapsed in the tick. + * @return The data rate in [bytes/second]. + */ + public double getMegabytesPerSecond(); /** * Get the number of milliseconds since the last tick. @@ -124,10 +137,10 @@ * @param ps The PrintStream for display. */ void printTick(PrintStream ps); - + /** - * Add subtask which will execute right before a new tick. - * @param subtask The subtask to execute. + * + * @param listener */ - void addSubTask(TimerTask subtask); + void addSystemStatisticsListener(SystemStatisticsListener listener); } Modified: java/branches/prod/monitoring-util/src/main/java/org/hps/monitoring/subsys/SystemStatisticsImpl.java ============================================================================= --- java/branches/prod/monitoring-util/src/main/java/org/hps/monitoring/subsys/SystemStatisticsImpl.java (original) +++ java/branches/prod/monitoring-util/src/main/java/org/hps/monitoring/subsys/SystemStatisticsImpl.java Wed Mar 25 14:43:27 2015 @@ -7,52 +7,53 @@ import java.util.Timer; import java.util.TimerTask; -import org.hps.monitoring.plotting.StripChartUpdater; +import org.hps.monitoring.plotting.ValueProvider; /** * Implementation of {@link SystemStatistics}. */ -// FIXME: Rolling averages need to happen over a greater time period like 30 seconds -// instead of 1 second, because otherwise the statistics don't look right. public class SystemStatisticsImpl implements SystemStatistics { - long tickLengthMillis = 1000; // default is one second tick - long sessionElapsedMillis; + long nominalTickLengthMillis = 1000; // default is 1 second tick + long tickStartTimeMillis; + long tickEndTimeMillis; + + long eventsInTick; + long bytesInTick; + long startTimeMillis; long stopTimeMillis; - long eventsSinceTick; - long bytesSinceTick; + long totalEvents; long totalBytes; - long tickStartMillis; - long tickElapsedMillis; + static final long Kb = 1 * 1024; static final long Mb = Kb * 1024; static final double milliToSecond = 0.001; static final DecimalFormat decimalFormat = new DecimalFormat("#.####"); Timer timer; - List<TimerTask> subtasks = new ArrayList<TimerTask>(); - + + List<SystemStatisticsListener> listeners = new ArrayList<SystemStatisticsListener>(); + @Override public void update(int size) { addEvent(); addData(size); - updateElapsedTime(); - } - - @Override - public void setTickLengthMillis(long tickLengthMillis) { - this.tickLengthMillis = tickLengthMillis; - } - - @Override - public long getTickLengthMillis() { - return tickLengthMillis; + } + + @Override + public void setNominalTickLengthMillis(long tickLengthMillis) { + this.nominalTickLengthMillis = tickLengthMillis; + } + + @Override + public long getNominalTickLengthMillis() { + return nominalTickLengthMillis; } @Override public long getTotalElapsedMillis() { - return sessionElapsedMillis; + return System.currentTimeMillis() - startTimeMillis; } @Override @@ -67,7 +68,12 @@ @Override public long getTickElapsedMillis() { - return tickElapsedMillis; + return System.currentTimeMillis() - tickStartTimeMillis; + } + + @Override + public long getTickEndTimeMillis() { + return tickEndTimeMillis; } /** @@ -76,7 +82,7 @@ @Override public long getEventsReceived() { - return eventsSinceTick; + return eventsInTick; } @Override @@ -86,10 +92,11 @@ @Override public double getEventsPerSecond() { - if (eventsSinceTick > 0 && tickElapsedMillis > 0) - return (double) eventsSinceTick / millisToSeconds(tickElapsedMillis); - else + if (eventsInTick > 0 && getTickElapsedMillis() > 0) { + return (double) eventsInTick / millisToSeconds(getTickElapsedMillis()); + } else { return 0.; + } } @Override @@ -107,7 +114,7 @@ @Override public long getBytesReceived() { - return bytesSinceTick; + return bytesInTick; } @Override @@ -126,34 +133,59 @@ @Override public double getBytesPerSecond() { - if (bytesSinceTick > 0 && tickElapsedMillis > 0) - return (double) bytesSinceTick / millisToSeconds(tickElapsedMillis); + if (bytesInTick > 0 && getTickElapsedMillis() > 0) + return (double) bytesInTick / millisToSeconds(getTickElapsedMillis()); else return 0.; } - + + @Override + public double getMegabytesPerSecond() { + double bytes = getBytesPerSecond(); + if (bytes > 0) { + return bytesToMb(bytes); + } else { + return 0; + } + } + @Override public void start() { - // Set time variables. + // Set session start time variables. long currentTimeMillis = System.currentTimeMillis(); startTimeMillis = currentTimeMillis; - tickStartMillis = currentTimeMillis; - - // Start Timer task which executes at tick length. + tickStartTimeMillis = currentTimeMillis; + + // Notify listeners of start. + for (SystemStatisticsListener listener : listeners) { + listener.started(this); + } + + // Start timer task which executes at the nominal tick length to calculate statistics periodically. TimerTask task = new TimerTask() { public void run() { - - // Run sub-tasks. - for (TimerTask subtask : subtasks) { - subtask.run(); - } - + + // End the current tick. + endTick(); + + // Start the new tick. nextTick(); } }; timer = new Timer(); - timer.schedule(task, 0, tickLengthMillis); + timer.schedule(task, 0, nominalTickLengthMillis); + } + + void endTick() { + + // Set absolute end time of current tick. + this.tickEndTimeMillis = System.currentTimeMillis(); + + // Activate listeners. + for (SystemStatisticsListener listener : listeners) { + listener.endTick(this); + } } @Override @@ -166,8 +198,17 @@ // Set stop time. stopTimeMillis = System.currentTimeMillis(); - } - + + // Notify listeners of stop. + for (SystemStatisticsListener listener : listeners) { + listener.stopped(this); + } + } + + public void addSystemStatisticsListener(SystemStatisticsListener listener) { + listeners.add(listener); + } + @Override public void printSession(PrintStream ps) { ps.println("session statistics ..."); @@ -185,115 +226,104 @@ ps.println(" eventsSinceTick = " + this.getEventsReceived()); ps.println(" bytesSinceTick = " + this.getBytesReceived()); } - - @Override - public void addSubTask(TimerTask subtask) { - this.subtasks.add(subtask); - } - + void addEvent() { - eventsSinceTick += 1; + eventsInTick += 1; totalEvents += 1; } void addData(int size) { - bytesSinceTick += size; + bytesInTick += size; totalBytes += size; - } - - void updateElapsedTime() { - tickElapsedMillis = System.currentTimeMillis() - tickStartMillis; - sessionElapsedMillis = System.currentTimeMillis() - startTimeMillis; } // Bytes to megabytes to 2 decimal places. static final double bytesToMb(long size) { return Double.parseDouble(decimalFormat.format((double) size / Mb)); } + + // Bytes to megabytes to 2 decimal places. + static final double bytesToMb(double size) { + return Double.parseDouble(decimalFormat.format(size / Mb)); + } static final double millisToSeconds(long millis) { return ((double) millis) / 1000.; } synchronized void nextTick() { - eventsSinceTick = 0; - bytesSinceTick = 0; - tickElapsedMillis = 0; - tickStartMillis = System.currentTimeMillis(); - } - - public abstract class SystemStatisticsUpdater extends StripChartUpdater { - SystemStatisticsUpdater() { - addSubTask(this); - } - } - - public class AverageEventsPerSecondUpdater extends SystemStatisticsUpdater { - - @Override - public float nextValue() { - return (float) getAverageEventsPerSecond(); - } - } - - public class EventsPerSecondUpdater extends SystemStatisticsUpdater { - - @Override - public float nextValue() { - return (float) getEventsPerSecond(); + eventsInTick = 0; + bytesInTick = 0; + tickStartTimeMillis = System.currentTimeMillis(); + } + + public abstract class SystemStatisticsProvider implements ValueProvider { + } + + public class AverageEventsPerSecondProvider extends SystemStatisticsProvider { + + @Override + public float[] getValues() { + return new float[] {(float) getAverageEventsPerSecond()}; + } + } + + public class EventsPerSecondProvider extends SystemStatisticsProvider { + + @Override + public float[] getValues() { + return new float[] {(float) getEventsPerSecond()}; } } - public class EventsReceivedUpdater extends SystemStatisticsUpdater { - - @Override - public float nextValue() { - return getEventsReceived(); - } - } - - public class TotalEventsUpdater extends SystemStatisticsUpdater { - @Override - public float nextValue() { - return getTotalEvents(); - } - } - - public class BytesReceivedUpdater extends SystemStatisticsUpdater { - @Override - public float nextValue() { - return getBytesReceived(); - } - } - - public class AverageMegabytesPerSecondUpdater extends SystemStatisticsUpdater { - @Override - public float nextValue() { - return (float) getAverageMegabytesPerSecond(); - } - } - - public class TotalMegabytesUpdater extends SystemStatisticsUpdater { - @Override - public float nextValue() { - return (float) getTotalMegabytes(); - } - } - - public class BytesPerSecondUpdater extends SystemStatisticsUpdater { - - @Override - public float nextValue() { - return (float) getBytesPerSecond(); - } - } - - public class MegabytesPerSecondUpdater extends SystemStatisticsUpdater { - @Override - public float nextValue() { - return (float) getBytesPerSecond() / 1000000; - } - } - - -} + public class EventsReceivedProvider extends SystemStatisticsProvider { + + @Override + public float[] getValues() { + return new float[] {getEventsReceived()}; + } + } + + public class TotalEventsProvider extends SystemStatisticsProvider { + @Override + public float[] getValues() { + return new float[] {getTotalEvents()}; + } + } + + public class BytesReceivedProvider extends SystemStatisticsProvider { + @Override + public float[] getValues() { + return new float[]{getBytesReceived()}; + } + } + + public class AverageMegabytesPerSecondProvider extends SystemStatisticsProvider { + @Override + public float[] getValues() { + return new float[] {(float) getAverageMegabytesPerSecond()}; + } + } + + public class TotalMegabytesProvider extends SystemStatisticsProvider { + @Override + public float[] getValues() { + return new float[] {(float) getTotalMegabytes()}; + } + } + + public class BytesPerSecondProvider extends SystemStatisticsProvider { + + @Override + public float[] getValues() { + return new float[] {(float) getBytesPerSecond()}; + } + } + + public class MegabytesPerSecondProvider extends SystemStatisticsProvider { + @Override + public float[] getValues() { + return new float[] {(float) getBytesPerSecond() / 1000000}; + } + } +} Modified: java/branches/prod/monitoring-util/src/main/java/org/hps/monitoring/subsys/SystemStatusImpl.java ============================================================================= --- java/branches/prod/monitoring-util/src/main/java/org/hps/monitoring/subsys/SystemStatusImpl.java (original) +++ java/branches/prod/monitoring-util/src/main/java/org/hps/monitoring/subsys/SystemStatusImpl.java Wed Mar 25 14:43:27 2015 @@ -8,14 +8,16 @@ */ public final class SystemStatusImpl implements SystemStatus { + StatusCode code = StatusCode.UNKNOWN; + Subsystem systemName; + String message; + String description; long lastChangedMillis; - String message; + boolean active = true; + boolean clearable; + List<SystemStatusListener> listeners = new ArrayList<SystemStatusListener>(); - final Subsystem systemName; - final String description; - boolean active = true; - final boolean clearable; /** * Fully qualified constructor. @@ -29,6 +31,36 @@ this.clearable = clearable; setLastChangedTime(); SystemStatusRegistry.getSystemStatusRegistery().register(this); + } + + /** + * Copy constructor from implementation class. + * The list of listeners is NOT copied. + * @param status The status to copy. + */ + public SystemStatusImpl(SystemStatusImpl status) { + this.code = status.code; + this.systemName = status.systemName; + this.message = status.message; + this.description = status.description; + this.lastChangedMillis = status.lastChangedMillis; + this.active = status.active; + this.clearable = status.clearable; + } + + /** + * Copy constructor from interface. + * The list of listeners is NOT copied. + * @param status The status to copy. + */ + public SystemStatusImpl(SystemStatus status) { + this.code = status.getStatusCode(); + this.systemName = status.getSubsystem(); + this.message = status.getMessage(); + this.description = status.getDescription(); + this.lastChangedMillis = status.getLastChangedMillis(); + this.active = status.isActive(); + this.clearable = status.isClearable(); } @Override @@ -97,5 +129,5 @@ @Override public boolean isClearable() { return clearable; - } + } } Modified: java/branches/prod/monitoring-util/src/main/java/org/hps/monitoring/subsys/ecal/EcalPedestalMonitor.java ============================================================================= --- java/branches/prod/monitoring-util/src/main/java/org/hps/monitoring/subsys/ecal/EcalPedestalMonitor.java (original) +++ java/branches/prod/monitoring-util/src/main/java/org/hps/monitoring/subsys/ecal/EcalPedestalMonitor.java Wed Mar 25 14:43:27 2015 @@ -1,108 +1,66 @@ package org.hps.monitoring.subsys.ecal; +import java.util.ArrayList; import java.util.Date; import java.util.HashMap; +import java.util.List; import java.util.Map; import org.hps.conditions.database.DatabaseConditionsManager; import org.hps.conditions.ecal.EcalChannel; import org.hps.conditions.ecal.EcalConditions; import org.hps.monitoring.plotting.MonitoringPlotFactory; -import org.hps.monitoring.plotting.StripChartUtil; import org.jfree.chart.JFreeChart; -import org.jfree.data.time.Millisecond; -import org.jfree.data.time.TimeSeries; +import org.jfree.chart.axis.DateAxis; +import org.jfree.data.time.Second; +import org.jfree.data.time.TimeSeriesCollection; import org.lcsim.event.EventHeader; import org.lcsim.geometry.Detector; import org.lcsim.util.Driver; import org.lcsim.util.aida.AIDA; + /* * Reads output of org.hps.recon.ecal.RunningPedestalDriver and makes strip charts. - * - * Are we going to lose/reinitialize these plots when run ends? - * Or can we keep on going off ET-ring across runs? * * Baltzell */ public class EcalPedestalMonitor extends Driver { - long previousTime; + static final int REFRESH_RATE = 10*1000; // units = ms + static final double DOMAIN_SIZE = 4*60*60*1000; // x-axis range (ms) + static final int crates[]={1,2}; + static final int slots[]={3,4,5,6,7,8,9,14,15,16,17,18,19,20}; + static final String slotNames[]={"Sl3","Sl4","Sl5","Sl6","Sl7","Sl8","Sl9","Sl14","Sl15","Sl16","Sl17","Sl18","Sl19","Sl20"}; + static final String collectionName = "EcalRunningPedestals"; + long currentTime; - int refreshRate=1000; // units = ms - + long previousTime=0; int nDetectorChanges=0; - - int maxAge = 999999999; - int maxCount = 100000; - int rangeSize = 100000; - - // None of this "works": - //int maxAge = 86400000; // 1 day (units ms) - //int maxCount = 999999999;//(int)maxAge/refreshRate; - //int rangeSize = 999999999;//maxAge; // what is this? - - final int crates[]={1,2}; - final int slots[]={3,4,5,6,7,8,9,14,15,16,17,18,19,20}; + private EcalConditions ecalConditions = null; + List<JFreeChart> charts = new ArrayList<JFreeChart>(); + MonitoringPlotFactory plotFactory = + (MonitoringPlotFactory) AIDA.defaultInstance().analysisFactory().createPlotterFactory("ECal Pedestal Monitoring"); - String collectionName = "EcalRunningPedestals"; - - MonitoringPlotFactory plotFactory = (MonitoringPlotFactory) AIDA.defaultInstance() - .analysisFactory().createPlotterFactory("ECal Pedestal Monitoring"); - - Map<Integer, Map<Integer, JFreeChart>> stripCharts = new HashMap<Integer, Map<Integer, JFreeChart>>(); - Map<Integer, Map<Integer, TimeSeries>> stripCharts2 = new HashMap<Integer, Map<Integer, TimeSeries>>(); - - private EcalConditions ecalConditions = null; - - public void startOfData() { - //plotFactory.createStripChart("X","Y",maxAge,maxCount,rangeSize); - plotFactory.create().show(); - - //System.out.println("---------------------------- "+maxCount); - } - - @Override public void detectorChanged(Detector detector) { - - // this would defeat the purpose. if (nDetectorChanges++ > 0) return; - - currentTime=0; - previousTime=0; - ecalConditions = DatabaseConditionsManager.getInstance().getEcalConditions(); - - // put them in order: for (int crate : crates) { - stripCharts.put(crate,new HashMap<Integer, JFreeChart>()); - stripCharts2.put(crate,new HashMap<Integer, TimeSeries>()); - for (int slot : slots) { - - final double ped=getAveragePedestal(crate,slot); - - String name = String.format("C%dS%02d",crate,slot); - JFreeChart stripChart = plotFactory.createStripChart(name,"asdf", - maxAge,maxCount,rangeSize); -// stripChart.getXYPlot().getRangeAxis().setRange(70,140); -// stripChart.getXYPlot().getRangeAxis().setFixedAutoRange(10); -// stripChart.getXYPlot().getRangeAxis().setAutoRange(true); - stripChart.getXYPlot().getRangeAxis().setRangeAboutValue(ped,10); - stripCharts.get(crate).put(slot,stripChart); - stripCharts2.get(crate).put(slot,StripChartUtil.getTimeSeries(stripChart)); - } + charts.add(plotFactory.createTimeSeriesChart( + "Crate " + crate, + "Offset Pedestal (ADC)", + slots.length, slotNames, + DOMAIN_SIZE)); } } - + @Override public void process(EventHeader event) { - if (!event.hasItem(collectionName)) { - return; - } + if (!event.hasItem(collectionName)) return; - currentTime=System.currentTimeMillis(); - if (currentTime - previousTime < refreshRate) return; - previousTime=currentTime; + currentTime = System.currentTimeMillis(); + if (currentTime - previousTime < REFRESH_RATE) return; + previousTime = currentTime; // get the running pedestals: Map<EcalChannel, Double> peds = (Map<EcalChannel, Double>) event.get(collectionName); @@ -110,6 +68,7 @@ // tally slot pedestals: Map<Integer, Map<Integer, Double>> pedsum = new HashMap<Integer, Map<Integer, Double>>(); Map<Integer, Map<Integer, Integer>> npedsum = new HashMap<Integer, Map<Integer, Integer>>(); + for (EcalChannel cc : peds.keySet()) { final Double ped = peds.get(cc); final int crate = cc.getCrate(); @@ -131,17 +90,24 @@ } // fill strip charts: + long now = System.currentTimeMillis(); for (int crate : pedsum.keySet()) { - for (int slot : pedsum.get(crate).keySet()) { - - final double ped = pedsum.get(crate).get(slot) / npedsum.get(crate).get(slot); - stripCharts2.get(crate).get(slot).add(new Millisecond(new Date()),ped); + TimeSeriesCollection cc=getTimeSeriesCollection(crate-1); + JFreeChart chart=charts.get(crate-1); + DateAxis ax=(DateAxis)chart.getXYPlot().getDomainAxis(); + ax.setRange(now-DOMAIN_SIZE,now); + for (int slot=0; slot<slots.length; slot++) { + double ped = pedsum.get(crate).get(slots[slot]) / npedsum.get(crate).get(slots[slot]); + ped -= getAveragePedestal(crate,slots[slot])-slot+9; + cc.getSeries(slot).addOrUpdate(new Second(new Date()),ped); } } - } - + TimeSeriesCollection getTimeSeriesCollection(int chartIndex) { + return (TimeSeriesCollection) charts.get(chartIndex).getXYPlot().getDataset(); + } + public EcalChannel findChannel(int crate, int slot, int chan) { for (EcalChannel cc : ecalConditions.getChannelCollection()) { if (crate == cc.getCrate() && slot == cc.getSlot() && chan == cc.getChannel()) { Modified: java/branches/prod/monitoring-util/src/main/java/org/hps/monitoring/subsys/ecal/EcalStripChartTestDriver.java ============================================================================= --- java/branches/prod/monitoring-util/src/main/java/org/hps/monitoring/subsys/ecal/EcalStripChartTestDriver.java (original) +++ java/branches/prod/monitoring-util/src/main/java/org/hps/monitoring/subsys/ecal/EcalStripChartTestDriver.java Wed Mar 25 14:43:27 2015 @@ -1,13 +1,9 @@ package org.hps.monitoring.subsys.ecal; -import java.util.Date; -import java.util.TimerTask; - import org.hps.monitoring.plotting.MonitoringPlotFactory; -import org.hps.monitoring.plotting.StripChartUtil; -import org.jfree.chart.JFreeChart; -import org.jfree.data.time.Millisecond; -import org.jfree.data.time.TimeSeries; +import org.hps.monitoring.plotting.StripChartUpdater; +import org.hps.monitoring.plotting.ValueProvider; +import org.jfree.data.time.Second; import org.lcsim.event.EventHeader; import org.lcsim.event.RawCalorimeterHit; import org.lcsim.util.Driver; @@ -21,22 +17,27 @@ int eventInterval = 1000; static String collectionName = "EcalReadoutHits"; - MonitoringPlotFactory plotFactory = (MonitoringPlotFactory) AIDA.defaultInstance().analysisFactory().createPlotterFactory("ECAL System Monitoring"); - TimeSeries series; - JFreeChart stripChart; - TimerTask updateTask; + MonitoringPlotFactory plotFactory = + (MonitoringPlotFactory) AIDA.defaultInstance().analysisFactory().createPlotterFactory("ECAL System Monitoring"); + EventHeader currentEvent; int hits; + int events; - + double averageHits; + + StripChartUpdater updater; + public void startOfData() { - stripChart = plotFactory.createStripChart("Average ECAL Hits per " + eventInterval + " Events", "Hits", 99999999, /* - * max - * age - */ - 1000, /* max count */ - 100000 /* range size */); - series = StripChartUtil.getTimeSeries(stripChart); + plotFactory.createStripChart( + "Average ECAL Hits per " + eventInterval + " Events", + "Hits", + 1, + new String[] { "Date" }, + 1, + new Second(), + new AverageHitsProvider(), + 20000L); } public void process(EventHeader event) { @@ -44,10 +45,19 @@ ++events; hits += size; if (event.getEventNumber() % eventInterval == 0) { - double averageHits = (double) hits / (double) events; - series.add(new Millisecond(new Date()), averageHits); + averageHits = (double) hits / (double) events; hits = 0; events = 0; } } + + public void endOfData() { + updater.stop(); + } + + class AverageHitsProvider implements ValueProvider { + public float[] getValues() { + return new float[] {(float) averageHits}; + } + } } Modified: java/branches/prod/monitoring-util/src/main/java/org/hps/monitoring/subsys/et/EtSystemStripCharts.java ============================================================================= --- java/branches/prod/monitoring-util/src/main/java/org/hps/monitoring/subsys/et/EtSystemStripCharts.java (original) +++ java/branches/prod/monitoring-util/src/main/java/org/hps/monitoring/subsys/et/EtSystemStripCharts.java Wed Mar 25 14:43:27 2015 @@ -1,33 +1,95 @@ +/** + * + */ package org.hps.monitoring.subsys.et; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + import org.hps.monitoring.plotting.MonitoringPlotFactory; +import org.hps.monitoring.subsys.SystemStatistics; import org.hps.monitoring.subsys.SystemStatisticsImpl; +import org.hps.monitoring.subsys.SystemStatisticsListener; import org.hps.record.et.EtEventProcessor; +import org.jfree.chart.JFreeChart; +import org.jfree.data.time.Second; +import org.jfree.data.time.TimeSeriesCollection; import org.jlab.coda.et.EtEvent; import org.lcsim.util.aida.AIDA; /** - * A basic set of strip charts for monitoring the ET system. + * This will show a series of strip charts from ET system performance statistics + * such as event and data rates. + * + * @author Jeremy McCormick <[log in to unmask]> */ -public final class EtSystemStripCharts extends EtEventProcessor { +public class EtSystemStripCharts extends EtEventProcessor implements SystemStatisticsListener { + // The system statistics. SystemStatisticsImpl stats = new SystemStatisticsImpl(); - MonitoringPlotFactory plotFactory = (MonitoringPlotFactory) AIDA.defaultInstance().analysisFactory().createPlotterFactory("ET System Monitoring"); - - public EtSystemStripCharts() { - stats.setTickLengthMillis(2000); + + // Plotting API. + MonitoringPlotFactory plotFactory = + (MonitoringPlotFactory) AIDA.defaultInstance().analysisFactory().createPlotterFactory("ET System Monitoring"); + + // List of charts. + List<JFreeChart> charts = new ArrayList<JFreeChart>(); + + // Range size in milliseconds. + static final double RANGE_SIZE = 200000; + + // Chart collection indices. + static final int DATA_RATE_COLLECTION_INDEX = 0; + static final int TOTAL_DATA_COLLECTION_INDEX = 1; + static final int EVENT_RATE_COLLECTION_INDEX = 2; + static final int TOTAL_EVENTS_COLLECTION_INDEX = 3; + + public EtSystemStripCharts() { + // Set 2 seconds between statistics updates. + stats.setNominalTickLengthMillis(1000); } /** * Setup the strip charts for ET system monitoring and start accumulating statistics. */ @Override - public void startJob() { - plotFactory.createStripChart("Data Rate", "MB / second", 100, stats.new MegabytesPerSecondUpdater()); - plotFactory.createStripChart("Total Data", "Megabytes", 100, stats.new TotalMegabytesUpdater()); - plotFactory.createStripChart("Event Rate", "Events / second", 100, stats.new EventsPerSecondUpdater()); - plotFactory.createStripChart("Total Events", "Number of Events", 100, stats.new TotalEventsUpdater()); + public void startJob() { + + // Register this class as a listener to activate update at end of statistics clock tick. + stats.addSystemStatisticsListener(this); + + // Start systems statistics task. stats.start(); + } + + /** + * Create the strip charts for plotting the basic ET system statistics. + */ + private void createStripCharts() { + + // Data rate and average data reate in megabytes per second. + charts.add(plotFactory.createTimeSeriesChart( + "Data Rate", + "MB / second", + 2, + new String[] { "Data Rate", "Average Data Rate" }, + RANGE_SIZE)); + + // Total megabytes received. + charts.add(plotFactory.createTimeSeriesChart("Total Data", "Megabytes", 1, null, RANGE_SIZE)); + + // Event rate and average event rate in hertz. + charts.add(plotFactory.createTimeSeriesChart( + "Event Rate", + "Hz", + 2, + new String[] { "Event Rate", "Average Event Rate" }, + RANGE_SIZE)); + + // Total number of events received. + charts.add(plotFactory.createTimeSeriesChart("Total Events", "Number of Events", 1, null, RANGE_SIZE)); + } @Override @@ -35,8 +97,47 @@ stats.update(event.getLength()); } - @Override public void endJob() { + // Stop system statistics task. stats.stop(); } -} + + TimeSeriesCollection getTimeSeriesCollection(int chartIndex) { + return (TimeSeriesCollection) charts.get(chartIndex).getXYPlot().getDataset(); + } + + /** + * Hook for updating the charts at end of statistics clock tick. + * @param stats The statistics with the system information. + */ + @Override + public void endTick(SystemStatistics stats) { + + Date now = new Date(stats.getTickEndTimeMillis()); + + getTimeSeriesCollection(DATA_RATE_COLLECTION_INDEX).getSeries(0).addOrUpdate( + new Second(now), stats.getMegabytesPerSecond()); + getTimeSeriesCollection(DATA_RATE_COLLECTION_INDEX).getSeries(1).addOrUpdate( + new Second(now), stats.getAverageMegabytesPerSecond()); + + getTimeSeriesCollection(TOTAL_DATA_COLLECTION_INDEX).getSeries(0).addOrUpdate( + new Second(now), stats.getTotalMegabytes()); + + getTimeSeriesCollection(EVENT_RATE_COLLECTION_INDEX).getSeries(0).addOrUpdate( + new Second(now), stats.getEventsPerSecond()); + getTimeSeriesCollection(EVENT_RATE_COLLECTION_INDEX).getSeries(1).addOrUpdate( + new Second(now), stats.getAverageEventsPerSecond()); + + getTimeSeriesCollection(TOTAL_EVENTS_COLLECTION_INDEX).getSeries(0).addOrUpdate( + new Second(now), stats.getTotalEvents()); + } + + @Override + public void started(SystemStatistics stats) { + createStripCharts(); + } + + @Override + public void stopped(SystemStatistics stats) { + } +} Modified: java/branches/prod/monitoring-util/src/main/java/org/hps/monitoring/trigger/ClusterTablePanel.java ============================================================================= --- java/branches/prod/monitoring-util/src/main/java/org/hps/monitoring/trigger/ClusterTablePanel.java (original) +++ java/branches/prod/monitoring-util/src/main/java/org/hps/monitoring/trigger/ClusterTablePanel.java Wed Mar 25 14:43:27 2015 @@ -82,11 +82,6 @@ setGlobalRowValue(ROW_RECON_COUNT, String.format(countFormat, clusterValue[2])); setGlobalRowValue(ROW_SSP_COUNT, String.format(countFormat, clusterValue[3])); - - System.out.printf("(row = %d, col = %d) --> %s%n", ROW_RECON_COUNT, 1, String.format(countFormat, clusterValue[0])); - System.out.printf("(row = %d, col = %d) --> %s%n", ROW_SSP_COUNT, 1, String.format(countFormat, clusterValue[1])); - - // Output the tracked statistical data. int total; String percentFormat = "%" + spaces + "d / %" + spaces + "d (%7.3f)"; @@ -112,12 +107,6 @@ 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)); - - - System.out.printf("(row = %d, col = %d) --> %s%n", ROW_MATCHED, 1, String.format(percentFormat, statValue[0], total, 100.0 * statValue[0] / total)); - System.out.printf("(row = %d, col = %d) --> %s%n", ROW_FAILED_POSITION, 1, String.format(percentFormat, statValue[1], total, 100.0 * statValue[1] / total)); - System.out.printf("(row = %d, col = %d) --> %s%n", ROW_FAILED_ENERGY, 1, String.format(percentFormat, statValue[2], total, 100.0 * statValue[2] / total)); - System.out.printf("(row = %d, col = %d) --> %s%n", ROW_FAILED_HIT_COUNT, 1, String.format(percentFormat, statValue[3], total, 100.0 * statValue[3] / total)); } } } Modified: java/branches/prod/monitoring-util/src/main/java/org/hps/monitoring/trigger/TableTextModel.java ============================================================================= --- java/branches/prod/monitoring-util/src/main/java/org/hps/monitoring/trigger/TableTextModel.java (original) +++ java/branches/prod/monitoring-util/src/main/java/org/hps/monitoring/trigger/TableTextModel.java Wed Mar 25 14:43:27 2015 @@ -81,6 +81,9 @@ // Set the value. values[rowIndex][columnIndex] = value; + + // Update the table. + this.fireTableCellUpdated(rowIndex, columnIndex); } /** Modified: java/branches/prod/record-util/src/main/java/org/hps/record/RecordProcessingException.java ============================================================================= --- java/branches/prod/record-util/src/main/java/org/hps/record/RecordProcessingException.java (original) +++ java/branches/prod/record-util/src/main/java/org/hps/record/RecordProcessingException.java Wed Mar 25 14:43:27 2015 @@ -11,4 +11,8 @@ super(message, x); } + public RecordProcessingException(String message) { + super(message); + } + } Modified: java/branches/prod/record-util/src/main/java/org/hps/record/composite/CompositeLoop.java ============================================================================= --- java/branches/prod/record-util/src/main/java/org/hps/record/composite/CompositeLoop.java (original) +++ java/branches/prod/record-util/src/main/java/org/hps/record/composite/CompositeLoop.java Wed Mar 25 14:43:27 2015 @@ -15,9 +15,15 @@ import org.hps.record.enums.ProcessingStage; import org.hps.record.et.EtEventProcessor; import org.hps.record.et.EtEventSource; -import org.hps.record.et.EtEventSource.EtSourceException; import org.hps.record.evio.EvioEventProcessor; import org.hps.record.evio.EvioFileSource; +import org.jlab.coda.et.exception.EtBusyException; +import org.jlab.coda.et.exception.EtClosedException; +import org.jlab.coda.et.exception.EtDeadException; +import org.jlab.coda.et.exception.EtEmptyException; +import org.jlab.coda.et.exception.EtException; +import org.jlab.coda.et.exception.EtTimeoutException; +import org.jlab.coda.et.exception.EtWakeUpException; import org.lcsim.util.Driver; import org.lcsim.util.loop.LCIOEventSource; @@ -149,8 +155,8 @@ Throwable cause = x.getCause(); if (cause instanceof MaxRecordsException || cause instanceof EndRunException || - cause instanceof EtSourceException || - cause instanceof NoSuchRecordException) { + cause instanceof NoSuchRecordException || + isEtReadException(cause)) { // These types of exceptions are never ignored. return false; } else { @@ -160,6 +166,21 @@ } } return false; + } + + /** + * True if the Throwable is a type that can be thrown by the ET + * system when it is attempting to read events from the server. + * The <code>IOException</code> type is ignored but can actually + * be thrown. + * @param e The Exception. + * @return True if the object can be thrown by ET event reading. + */ + private static boolean isEtReadException(Throwable e) { + return e instanceof EtException || e instanceof EtDeadException + || e instanceof EtClosedException || e instanceof EtEmptyException + || e instanceof EtBusyException || e instanceof EtTimeoutException + || e instanceof EtWakeUpException; } /** Modified: java/branches/prod/record-util/src/main/java/org/hps/record/composite/CompositeLoopConfiguration.java ============================================================================= --- java/branches/prod/record-util/src/main/java/org/hps/record/composite/CompositeLoopConfiguration.java (original) +++ java/branches/prod/record-util/src/main/java/org/hps/record/composite/CompositeLoopConfiguration.java Wed Mar 25 14:43:27 2015 @@ -39,7 +39,6 @@ EtConnection connection = null; RecordSource recordSource = null; LCSimEventBuilder eventBuilder = null; - String detectorName = null; // Event processors. List<EvioEventProcessor> evioProcessors = new ArrayList<EvioEventProcessor>(); @@ -119,17 +118,7 @@ this.eventBuilder = eventBuilder; return this; } - - /** - * Set the name of the detector definition to be used e.g. from detector-data/detectors dir. - * @param detectorName The name of the detector. - * @return This object. - */ - public CompositeLoopConfiguration setDetectorName(String detectorName) { - this.detectorName = detectorName; - return this; - } - + /** * Set whether the loop will stop when event processing errors occur. * Certain types of errors are considered fatal or are used to control Modified: java/branches/prod/record-util/src/main/java/org/hps/record/evio/EvioEventConstants.java ============================================================================= --- java/branches/prod/record-util/src/main/java/org/hps/record/evio/EvioEventConstants.java (original) +++ java/branches/prod/record-util/src/main/java/org/hps/record/evio/EvioEventConstants.java Wed Mar 25 14:43:27 2015 @@ -2,19 +2,31 @@ public class EvioEventConstants { + // This is the old tag for physics events. public static final int PHYSICS_EVENT_TAG = 1; + + // CODA control event tags. public static final int SYNC_EVENT_TAG = 16; public static final int PRESTART_EVENT_TAG = 17; public static final int GO_EVENT_TAG = 18; public static final int PAUSE_EVENT_TAG = 19; public static final int END_EVENT_TAG = 20; + // Special tag for events with EPICS scalars. + public static final int EPICS_EVENT_TAG = 31; + + // Event tags greater than or equal to this will be physics events. + public static final int PHYSICS_START_TAG = 32; + public static final int EVENTID_BANK_TAG = 0xC000; - + + // Bank tag for header bank with run and event numbers in physics events. public static final int HEAD_BANK_TAG = 0xe10F; - public static final int EPICS_EVENT_TAG = 31; + public static final int EPICS_BANK_TAG = 57620; public static final int EPICS_BANK_TAG_2s = -1; public static final int EPICS_BANK_TAG_20s = -1; + //public static final int EPICS_BANK_TAG_2s = -1; + //public static final int EPICS_BANK_TAG_20s = -1; } Modified: java/branches/prod/record-util/src/main/java/org/hps/record/evio/EvioEventUtilities.java ============================================================================= --- java/branches/prod/record-util/src/main/java/org/hps/record/evio/EvioEventUtilities.java (original) +++ java/branches/prod/record-util/src/main/java/org/hps/record/evio/EvioEventUtilities.java Wed Mar 25 14:43:27 2015 @@ -1,11 +1,6 @@ package org.hps.record.evio; -import static org.hps.record.evio.EvioEventConstants.END_EVENT_TAG; -import static org.hps.record.evio.EvioEventConstants.GO_EVENT_TAG; -import static org.hps.record.evio.EvioEventConstants.PAUSE_EVENT_TAG; -import static org.hps.record.evio.EvioEventConstants.PHYSICS_EVENT_TAG; -import static org.hps.record.evio.EvioEventConstants.PRESTART_EVENT_TAG; -import static org.hps.record.evio.EvioEventConstants.SYNC_EVENT_TAG; +import static org.hps.record.evio.EvioEventConstants.*; import org.jlab.coda.jevio.BaseStructure; import org.jlab.coda.jevio.EvioEvent; @@ -19,6 +14,15 @@ public final class EvioEventUtilities { private EvioEventUtilities() { + } + + /** + * Get the event tag from the header bank. + * @param event The input EvioEvent. + * @return The event tag from the header bank. + */ + public static int getEventTag(EvioEvent event) { + return event.getHeader().getTag(); } /** @@ -69,7 +73,7 @@ * @return True if this event is a physics event. */ public static boolean isPhysicsEvent(EvioEvent event) { - return (event.getHeader().getTag() >= SYNC_EVENT_TAG+16 || + return (event.getHeader().getTag() >= PHYSICS_START_TAG || event.getHeader().getTag() < SYNC_EVENT_TAG); // return event.getHeader().getTag() == PHYSICS_EVENT_TAG; } @@ -82,6 +86,29 @@ */ public static boolean isSyncEvent(EvioEvent event) { return event.getHeader().getTag() == SYNC_EVENT_TAG; + } + + /** + * Check if this event is an EPICS event containing scalar data. + * + * @param event The EvioEvent. + * @return True if this event is an EPICS event. + */ + public static boolean isEpicsEvent(EvioEvent event) { + return event.getHeader().getTag() == EPICS_EVENT_TAG; + } + + /** + * True if <code>event</code> is an EVIO control event. + * @return True if event is a control event. + */ + public static boolean isControlEvent(EvioEvent event) { + return isPreStartEvent(event) || + isGoEvent(event) || + isPauseEvent(event) || + isEndEvent(event) || + isSyncEvent(event) || + isEpicsEvent(event); } /** @@ -108,7 +135,7 @@ if (data != null) { //found the data in the top-level bank return data; } else { //data is not in event bank; look for the data bank whose tag matches the event type - for (BaseStructure bank : event.getChildren()) { + for (BaseStructure bank : event.getChildrenList()) { if (bank.getHeader().getTag() == eventTag) { return bank.getIntData(); //return whatever int data this bank has } @@ -125,9 +152,9 @@ */ public static BaseStructure getHeadBank(EvioEvent evioEvent) { if (evioEvent.getChildCount() > 0) { - for (BaseStructure topBank : evioEvent.getChildren()) { - if (topBank.getChildren() != null) { - for (BaseStructure nestedBank : topBank.getChildren()) { + for (BaseStructure topBank : evioEvent.getChildrenList()) { + if (topBank.getChildrenList() != null) { + for (BaseStructure nestedBank : topBank.getChildrenList()) { if (nestedBank.getHeader().getTag() == EvioEventConstants.HEAD_BANK_TAG) { return nestedBank; } @@ -137,4 +164,24 @@ } return null; } + + /** + * Get the run number from an EVIO event. + * @return The run number. + */ + public static int getRunNumber(EvioEvent event) { + if (isControlEvent(event)) { + return getControlEventData(event)[1]; + } else if (isPhysicsEvent(event)) { + 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()); + } + } } Modified: java/branches/prod/record-util/src/main/java/org/hps/record/evio/EvioFileProducer.java ============================================================================= --- java/branches/prod/record-util/src/main/java/org/hps/record/evio/EvioFileProducer.java (original) +++ java/branches/prod/record-util/src/main/java/org/hps/record/evio/EvioFileProducer.java Wed Mar 25 14:43:27 2015 @@ -5,6 +5,7 @@ import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import org.jlab.coda.et.EtAttachment; @@ -228,6 +229,8 @@ if (debug) { System.out.println("new events - size=" + size + "; group=" + group); } + + int eventTag = EvioEventUtilities.getEventTag(event); // Create a new array of ET events. This always has one event. mevs = sys.newEvents( @@ -238,7 +241,12 @@ 1, // number of events size, // size of event but overwritten later group); // group number; default value is arbitrary - + + // Create control data array for event selection. + int[] control = new int[EtConstants.stationSelectInts]; + Arrays.fill(control, eventTag); + mevs[0].setControl(control); + // Delay for X millis if applicable. if (delay > 0) { Thread.sleep(delay); Modified: java/branches/prod/steering-files/src/main/resources/org/hps/steering/monitoring/ECalLedCommissioning.lcsim ============================================================================= --- java/branches/prod/steering-files/src/main/resources/org/hps/steering/monitoring/ECalLedCommissioning.lcsim (original) +++ java/branches/prod/steering-files/src/main/resources/org/hps/steering/monitoring/ECalLedCommissioning.lcsim Wed Mar 25 14:43:27 2015 @@ -19,7 +19,7 @@ <inputCollectionRaw>EcalReadoutHits</inputCollectionRaw> <inputClusterCollection>EcalClusters</inputClusterCollection> <pedSamples>20</pedSamples> - <maxEch>10.0</maxEch> + <maxEch>5.0</maxEch> <minEch>0.005</minEch> <eventRefreshRate>5</eventRefreshRate> </driver> Modified: java/branches/prod/steering-files/src/main/resources/org/hps/steering/monitoring/EcalMonitoringFinal.lcsim ============================================================================= --- java/branches/prod/steering-files/src/main/resources/org/hps/steering/monitoring/EcalMonitoringFinal.lcsim (original) +++ java/branches/prod/steering-files/src/main/resources/org/hps/steering/monitoring/EcalMonitoringFinal.lcsim Wed Mar 25 14:43:27 2015 @@ -8,12 +8,17 @@ <execute> <!-- <driver name="EventMarkerDriver"/> --> <driver name="EcalRawConverter" /> - <driver name="EcalClusterer" /> + <driver name="DAQConfig"/> + <driver name="DAQConfigDriver" /> +<!-- <driver name="EcalClusterer" /> --><!-- This is done elsewhere! --> + <driver name="GTPTestDriver" /> + <driver name="TriggerDiagnostics" /> <driver name="EcalMonitoringPlots" /> <!-- General plots --> <driver name="EcalHitPlots" /> <!-- Single hit distributions --> <driver name="EcalClusterPlots" /> <!-- Clusters distributions --> <driver name="EcalDaqPlots" /> <!-- DAQ Plots --> <driver name="EcalEventDisplay" /> <!-- Ecal event display --> + <driver name="ClockDriver" /> <!-- <driver name="EcalWindowPlots"/> --> <!-- <driver name="EcalEvsX"/> --> <!-- <driver name="TriggerPlots"/> --> @@ -24,23 +29,69 @@ <driver name="EventMarkerDriver" type="org.lcsim.job.EventMarkerDriver"> <eventInterval>1</eventInterval> </driver> + <driver name="DAQConfig" type="org.hps.recon.ecal.daqconfig.DAQConfigDriver"/> + + <driver name="DAQConfigDriver" type="org.hps.recon.ecal.daqconfig.DAQConfigDriver"> + </driver> + <driver name="EcalRawConverter" type="org.hps.recon.ecal.EcalRawConverterDriver"> - <applyBadCrystalMap>false</applyBadCrystalMap> + <ecalCollectionName>EcalCalHits</ecalCollectionName> <use2014Gain>false</use2014Gain> + <useTimestamps>false</useTimestamps> + <useTruthTime>false</useTruthTime> + <useRunningPedestal>false</useRunningPedestal> + <useTimeWalkCorrection>false</useTimeWalkCorrection> + <emulateFirmware>true</emulateFirmware> + <emulateMode7>false</emulateMode7> + <leadingEdgeThreshold>12</leadingEdgeThreshold> + <nsa>100</nsa> + <nsb>20</nsb> + <nPeak>3</nPeak> </driver> - <driver name="EcalClusterer" type="org.hps.recon.ecal.cluster.GTPOnlineClusterDriver"> + <driver name="GTPTestDriver" type="org.hps.recon.ecal.cluster.GTPOnlineClusterDriver"> + <inputHitCollectionName>EcalCalHits</inputHitCollectionName> + <!-- <seedEnergyThreshold>0.500</seedEnergyThreshold> + <windowBefore>3</windowBefore> + <windowAfter>3</windowAfter> --> + <seedEnergyThreshold>0.010</seedEnergyThreshold> + <windowBefore>2</windowBefore> + <windowAfter>2</windowAfter> + <useDAQConfig>true</useDAQConfig> <verbose>false</verbose> + </driver> + + <driver name="TriggerDiagnostics" type="org.hps.analysis.trigger.TriggerDiagnosticDriver"> + <printResultsEveryNEvents>10000</printResultsEveryNEvents> + <hitAcceptanceWindow>0</hitAcceptanceWindow> + <noiseThresholdCount>100</noiseThresholdCount> + <energyAcceptanceWindow>0.009</energyAcceptanceWindow> + <printOnClusterFailure>false</printOnClusterFailure> + <printOnSinglesSSPFailure>false</printOnSinglesSSPFailure> + <printOnSinglesEfficiencyFailure>false</printOnSinglesEfficiencyFailure> + <printOnPairSSPFailure>false</printOnPairSSPFailure> + <printOnPairEfficiencyFailure>false</printOnPairEfficiencyFailure> + <enforceStrictTimeCompliance>true</enforceStrictTimeCompliance> <!-- Set to false for mode-7 --> + <readDAQConfig>true</readDAQConfig> + <verbose>false</verbose> + </driver> + + <driver name="GUIDiagnostics" type="org.hps.monitoring.trigger.TriggerDiagnosticGUIDriver"/> + + <driver name="EcalClusterer" type="org.hps.recon.ecal.cluster.ReconClusterDriver"> <logLevel>WARNING</logLevel> - <windowAfter>2</windowAfter> - <windowBefore>2</windowBefore> - <seedEnergyThreshold>0.100</seedEnergyThreshold> - <inputHitCollectionName>EcalCalHits</inputHitCollectionName> <outputClusterCollectionName>EcalClusters</outputClusterCollectionName> + <hitEnergyThreshold>0.01</hitEnergyThreshold> + <seedEnergyThreshold>0.100</seedEnergyThreshold> + <clusterEnergyThreshold>0.200</clusterEnergyThreshold> + <minTime>0.0</minTime> + <timeWindow>25.0</timeWindow> + <useTimeCut>true</useTimeCut> + <writeRejectedHitCollection>false</writeRejectedHitCollection> </driver> + <driver name="EcalMonitoringPlots" type="org.hps.monitoring.ecal.plots.EcalMonitoringPlots"> <inputCollection>EcalCalHits</inputCollection> <eventRefreshRate>5</eventRefreshRate> - <accumulateHits>false</accumulateHits> </driver> <driver name="EcalHitPlots" type="org.hps.monitoring.ecal.plots.EcalHitPlots"> <inputCollection>EcalCalHits</inputCollection> @@ -63,28 +114,6 @@ <minEch>0.005</minEch> <eventRefreshRate>1</eventRefreshRate> </driver> - <!--<driver name="EcalClusterer" type="org.hps.recon.ecal.HPSEcalCTPClusterer"> --> - - <!-- <driver name="EcalEvsX" type="org.hps.monitoring.ecal.EcalEvsX"> - <targetZ>674</targetZ> - <inputCollection>EcalClusters</inputCollection> - </driver> --> - - <!-- <driver name="EcalWindowPlots" type="org.hps.monitoring.drivers.ecal.plots.EcalWindowPlots"> - <inputCollection>EcalReadoutHits</inputCollection> - </driver> --> - - <!-- <driver name="EcalPedestalPlots" type="org.hps.monitoring.drivers.ecal.EcalPedestalPlots"> - <inputCollection>EcalCalHits</inputCollection> - <eventRefreshRate>100</eventRefreshRate> - </driver> --> - - <!-- <driver name="TriggerPlots" type="org.hps.monitoring.ecal.TriggerPlots"> - <clusterEnergyCut>0.500</clusterEnergyCut> - </driver> --> - - <!-- <driver name="AidaSaveDriver" type="org.lcsim.job.AidaSaveDriver"> - <outputFileName>triggerEPlots</outputFileName> - </driver> --> + <driver name="ClockDriver" type="org.hps.readout.ecal.ClockDriver" /> </drivers> </lcsim> Modified: java/branches/prod/steering-files/src/main/resources/org/hps/steering/monitoring/TriggerDiagnosticsMonitoring.lcsim ============================================================================= --- java/branches/prod/steering-files/src/main/resources/org/hps/steering/monitoring/TriggerDiagnosticsMonitoring.lcsim (original) +++ java/branches/prod/steering-files/src/main/resources/org/hps/steering/monitoring/TriggerDiagnosticsMonitoring.lcsim Wed Mar 25 14:43:27 2015 @@ -5,24 +5,16 @@ <printDriversDetailed>false</printDriversDetailed> </control> <execute> - <driver name="EventMarkerDriver" /> - <driver name="ConditionsDriver" /> - <driver name="DAQConfig" /> + <!-- <driver name="EventMarkerDriver" /> --> <driver name="EcalRawConverter" /> <driver name="GTPTestDriver" /> <driver name="TriggerDiagnostics" /> - <!-- <driver name="AidaSaveDriver" /> --> <driver name="ClockDriver" /> - <!-- <driver name="CleanupDriver" /> --> </execute> <drivers> <driver name="EventMarkerDriver" type="org.lcsim.job.EventMarkerDriver"> - <eventInterval>1000</eventInterval> + <eventInterval>1</eventInterval> </driver> - <driver name="ConditionsDriver" type="org.hps.conditions.ConditionsDriver"> - <tag>pass0</tag> - </driver> - <driver name="DAQConfig" type="org.hps.readout.ecal.daqconfig.DAQConfigDriver" /> <driver name="EcalRawConverter" type="org.hps.recon.ecal.EcalRawConverterDriver"> <ecalCollectionName>EcalCalHits</ecalCollectionName> <use2014Gain>false</use2014Gain> @@ -37,13 +29,16 @@ </driver> <driver name="GTPTestDriver" type="org.hps.recon.ecal.cluster.GTPOnlineClusterDriver"> <inputHitCollectionName>EcalCalHits</inputHitCollectionName> + <!-- <seedEnergyThreshold>0.500</seedEnergyThreshold> <windowBefore>3</windowBefore> <windowAfter>3</windowAfter> - <!-- <seedEnergyThreshold>0.010</seedEnergyThreshold> + --> + <!-- cuts used for GTP --> + <seedEnergyThreshold>0.010</seedEnergyThreshold> <windowBefore>2</windowBefore> <windowAfter>2</windowAfter> - <verbose>true</verbose> --> + <verbose>false</verbose> </driver> <driver name="TriggerDiagnostics" type="org.hps.analysis.trigger.TriggerDiagnosticDriver"> <noiseThresholdCount>100</noiseThresholdCount> @@ -51,18 +46,12 @@ <printOnSinglesSSPFailure>false</printOnSinglesSSPFailure> <printOnSinglesEfficiencyFailure>false</printOnSinglesEfficiencyFailure> <printOnPairSSPFailure>false</printOnPairSSPFailure> - <printOnPairEfficiencyFailure>false</printOnPairEfficiencyFailure> - <!-- <readDAQConfig>true</readDAQConfig> --> + <printOnPairEfficiencyFailure>false</printOnPairEfficiencyFailure> + <readDAQConfig>true</readDAQConfig> <verbose>true</verbose> + <!-- determines snapshot readout time which is set to 1 second here --> + <localWindowThresholdMilliseconds>1000</localWindowThresholdMilliseconds> </driver> -<!-- - <driver name="AidaSaveDriver" type="org.lcsim.job.AidaSaveDriver"> - <outputFileName>${outputFile}_triggerPlots</outputFileName> - </driver> - --> <driver name="ClockDriver" type="org.hps.readout.ecal.ClockDriver" /> - <driver name="CleanupDriver" type="org.lcsim.recon.tracking.digitization.sisim.config.ReadoutCleanupDriver"> - <collectionNames>TrackerHits</collectionNames> - </driver> </drivers> </lcsim> Modified: java/branches/prod/steering-files/src/main/resources/org/hps/steering/users/celentan/LedAnalysisFromEvio.lcsim ============================================================================= --- java/branches/prod/steering-files/src/main/resources/org/hps/steering/users/celentan/LedAnalysisFromEvio.lcsim (original) +++ java/branches/prod/steering-files/src/main/resources/org/hps/steering/users/celentan/LedAnalysisFromEvio.lcsim Wed Mar 25 14:43:27 2015 @@ -30,6 +30,7 @@ </driver> <driver name="LedAnalysisDriver" type="org.hps.users.celentan.LedAnalysis"> <useRawEnergy>true</useRawEnergy> + <energyCut>5</energyCut> </driver> <driver name="AidaSaveDriver" type="org.lcsim.job.AidaSaveDriver"> <outputFileName>${outputFile}.aida</outputFileName> Modified: java/branches/prod/steering-files/src/main/resources/org/hps/steering/users/mgraham/AlignmentMonitorTest.lcsim ============================================================================= --- java/branches/prod/steering-files/src/main/resources/org/hps/steering/users/mgraham/AlignmentMonitorTest.lcsim (original) +++ java/branches/prod/steering-files/src/main/resources/org/hps/steering/users/mgraham/AlignmentMonitorTest.lcsim Wed Mar 25 14:43:27 2015 @@ -5,16 +5,16 @@ <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="TrackerDigiDriver"/> +<!-- <driver name="TrackerDigiDriver"/> --> <!-- the 3 drivers below are for reading out 6-sample ADC data --> -<!-- <driver name="RawTrackerHitSensorSetup" /> + <driver name="RawTrackerHitSensorSetup" /> <driver name="RawTrackerHitFitterDriver" /> - <driver name="TrackerHitDriver" /> --> + <driver name="TrackerHitDriver" /> <driver name="HelicalTrackHitDriver" /> <driver name="TrackerL1to3ReconDriver"/> <driver name="TrackerL4to6ReconDriver"/> <!-- <driver name="TrackDataDriver"/> - <driver name="EcalRawConverter" /> + <driver name="EcalRawConverter" /> <driver name="EcalClusterer" /> <driver name="ReconParticle" /> <driver name="TrackingMonitoring" /> @@ -46,7 +46,6 @@ <useTimestamps>false</useTimestamps> <correctT0Shift>false</correctT0Shift> <useTruthTime>false</useTruthTime> - <subtractTOF>false</subtractTOF> <debug>false</debug> </driver> <driver name="TrackerHitDriver" type="org.hps.recon.tracking.DataTrackerHitDriver"> @@ -61,11 +60,10 @@ </driver> <driver name="TrackerL1to3ReconDriver" type="org.hps.recon.tracking.TrackerReconDriver"> <debug>false</debug> -<!-- <strategyResource>/org/hps/recon/tracking/strategies/HPS-Full.xml</strategyResource> --> <trackCollectionName>L1to3Tracks</trackCollectionName> <strategyResource>/org/hps/recon/tracking/strategies/HPS-Full-L1-3.xml</strategyResource> </driver> - <driver name="TrackerL4to6ReconDriver" type="org.hps.recon.tracking.TrackerReconDriver"> + <driver name="TrackerL4to6ReconDriver" type="org.hps.recon.tracking.TrackerReconDriver"> <debug>false</debug> <trackCollectionName>L4to6Tracks</trackCollectionName> <strategyResource>/org/hps/recon/tracking/strategies/HPS-Full-L4-6.xml</strategyResource> @@ -81,19 +79,7 @@ </driver> <driver name="ReconParticle" type="org.hps.recon.particle.HpsReconParticleDriver"> <debug>false</debug> - </driver> - <driver name="BSTrackReconParticle" type="org.hps.recon.particle.HpsReconParticleDriver"> - <debug>true</debug> - <tracksCollectionName>BeamSpotTracks</tracksCollectionName> - <finalStateParticlesColName>BSFinalStateParticles</finalStateParticlesColName> - <unconstrainedV0CandidatesColName>BSUnconstrainedV0Candidates</unconstrainedV0CandidatesColName> - <beamConV0CandidatesColName>BSBeamspotConstrainedV0Candidates</beamConV0CandidatesColName> - <targetConV0CandidatesColName>BSTargetConstrainedV0Candidates</targetConV0CandidatesColName> - <unconstrainedV0VerticesColName>BSUnconstrainedV0Vertices</unconstrainedV0VerticesColName> - <beamConV0VerticesColName>BSBeamspotConstrainedV0Vertices</beamConV0VerticesColName> - <targetConV0VerticesColName>BSTargetConstrainedV0Vertices</targetConV0VerticesColName> - </driver> - + </driver> <driver name="TrackingMonitoring" type="org.hps.monitoring.drivers.trackrecon.TrackingReconPlots"> <outputPlots>tracking</outputPlots> </driver> @@ -103,7 +89,7 @@ <driver name="V0Monitoring" type="org.hps.monitoring.drivers.trackrecon.V0ReconPlots"> <outputPlots>v0recon</outputPlots> </driver> - <driver name="SVTAlignment" type="org.hps.monitoring.drivers.trackrecon.SVTOpeningAlignment"> + <driver name="SVTAlignment" type="org.hps.monitoring.drivers.trackrecon.SVTOpeningAlignment"> <outputPlots>alignment</outputPlots> </driver> Modified: java/branches/prod/tracking/src/main/java/org/hps/readout/svt/SimpleSvtReadout.java ============================================================================= --- java/branches/prod/tracking/src/main/java/org/hps/readout/svt/SimpleSvtReadout.java (original) +++ java/branches/prod/tracking/src/main/java/org/hps/readout/svt/SimpleSvtReadout.java Wed Mar 25 14:43:27 2015 @@ -198,8 +198,10 @@ for (int sampleN = 0; sampleN < 6; sampleN++) { double time = sampleN * HPSSVTConstants.SAMPLING_INTERVAL - timeOffset; double tp = sensor.getShapeFitParameters(channel)[HpsSiSensor.TP_INDEX]; - signal[sampleN] = amplitude * pulseAmplitude(time, tp); + signal[sampleN] += amplitude * pulseAmplitude(time, tp);//add the pulse to the pedestal samples[sampleN] = (short) Math.round(signal[sampleN]); + if (verbosity >= 1) + System.out.println("\t\tMaking samples: sample#" + sampleN + " has " + samples[sampleN] + " ADC counts"); } long channel_id = sensor.makeChannelID(channel); @@ -290,15 +292,18 @@ private boolean readoutCuts(RawTrackerHit hit) { if (enableThresholdCut && !samplesAboveThreshold(hit)) { - //System.out.println("Failed threshold cut"); + if (verbosity > 1) + System.out.println("Failed threshold cut"); return false; } if (enablePileupCut && !pileupCut(hit)) { - //System.out.println("Failed pileup cut"); + if (verbosity > 1) + System.out.println("Failed pileup cut"); return false; } if (dropBadChannels && !badChannelCut(hit)) { - //System.out.println("Failed bad channel cut"); + if (verbosity > 1) + System.out.println("Failed bad channel cut"); return false; } return true; @@ -325,19 +330,18 @@ for (int sampleN = 0; sampleN < samples.length; sampleN++) { pedestal = sensor.getPedestal(channel, sampleN); noise = sensor.getNoise(channel, sampleN); - //System.out.format("%d, %d\n", samples[sampleN] - pedestal, noise * 3.0); - if (samples[sampleN] - pedestal > noise * noiseThreshold) { + if (verbosity > 1) + System.out.format("%f, %f\n", samples[sampleN] - pedestal, noise * noiseThreshold); + if (samples[sampleN] - pedestal > noise * noiseThreshold) count++; - } } return count >= samplesAboveThreshold; } @Override protected void processTrigger(EventHeader event) { - if (noPileup) { + if (noPileup) return; - } //System.out.println("Got trigger"); // Create a list to hold the analog data @@ -438,20 +442,18 @@ @Override public int compareTo(Object o) { double deltaT = time - ((StripHit) o).time; - if (deltaT > 0) { + if (deltaT > 0) return 1; - } else if (deltaT < 0) { + else if (deltaT < 0) return -1; - } else { + else return 0; - } } } private double pulseAmplitude(double time, double tp) { - if (time <= 0.0) { + if (time <= 0.0) return 0.0; - } return (time / tp) * Math.exp(1.0 - time / tp); } Modified: java/branches/prod/users/src/main/java/org/hps/users/celentan/DummyDriverRaw.java ============================================================================= --- java/branches/prod/users/src/main/java/org/hps/users/celentan/DummyDriverRaw.java (original) +++ java/branches/prod/users/src/main/java/org/hps/users/celentan/DummyDriverRaw.java Wed Mar 25 14:43:27 2015 @@ -6,10 +6,9 @@ import org.lcsim.geometry.Detector; import org.lcsim.util.Driver; import org.lcsim.util.aida.AIDA; - -import org.hps.readout.ecal.triggerbank.SSPData; -import org.hps.readout.ecal.triggerbank.AbstractIntData; import org.hps.recon.ecal.ECalUtils; +import org.hps.recon.ecal.triggerbank.AbstractIntData; +import org.hps.recon.ecal.triggerbank.SSPData; import org.lcsim.event.CalorimeterHit; import org.lcsim.event.EventHeader; import org.lcsim.event.GenericObject; Modified: java/branches/prod/users/src/main/java/org/hps/users/phansson/ROOTFlatTupleDriver.java ============================================================================= --- java/branches/prod/users/src/main/java/org/hps/users/phansson/ROOTFlatTupleDriver.java (original) +++ java/branches/prod/users/src/main/java/org/hps/users/phansson/ROOTFlatTupleDriver.java Wed Mar 25 14:43:27 2015 @@ -7,6 +7,7 @@ import hep.physics.vec.BasicHep3Vector; import hep.physics.vec.Hep3Vector; import hep.physics.vec.VecOp; + import java.io.File; import java.io.FileWriter; import java.io.IOException; @@ -18,9 +19,10 @@ import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; + import org.hps.analysis.ecal.HPSMCParticlePlotsDriver; -import org.hps.readout.ecal.triggerbank.AbstractIntData; -import org.hps.readout.ecal.triggerbank.TestRunTriggerData; +import org.hps.recon.ecal.triggerbank.AbstractIntData; +import org.hps.recon.ecal.triggerbank.TestRunTriggerData; import org.hps.recon.tracking.BeamlineConstants; import org.hps.recon.tracking.EventQuality; import org.hps.recon.tracking.HPSTrack;