From f55fbfce38350f9083f7385f015f40de6c47389d Mon Sep 17 00:00:00 2001 From: gobbo_a Date: Thu, 11 Aug 2022 16:24:40 +0200 Subject: [PATCH] Creation --- config/config.properties | 49 + config/devices.properties | 0 config/mail.properties | 9 + config/plugins.properties | 1 + config/preferences.json | 123 + config/setup.properties | 25 + devices/CamServer.properties | 25 + devices/CurrentCamera.properties | 25 + devices/cam_server.properties | 5 + plugins/ScreenPanel10.form | 1347 ++++++++ plugins/ScreenPanel10.java | 4712 ++++++++++++++++++++++++++++ script/.DS_Store | Bin 0 -> 6148 bytes script/local.groovy | 3 + script/local.js | 4 + script/local.py | 100 + script/processing.py | 306 ++ script/test/import_zmqw.py | 24 + script/test/test_pipeline1.py | 15 + script/test/test_proc.py | 9 + script/test/test_stream_out.py | 35 + script/tools/dump_camera_stream.py | 19 + 21 files changed, 6836 insertions(+) create mode 100644 config/config.properties create mode 100644 config/devices.properties create mode 100644 config/mail.properties create mode 100644 config/plugins.properties create mode 100644 config/preferences.json create mode 100644 config/setup.properties create mode 100644 devices/CamServer.properties create mode 100644 devices/CurrentCamera.properties create mode 100644 devices/cam_server.properties create mode 100644 plugins/ScreenPanel10.form create mode 100644 plugins/ScreenPanel10.java create mode 100644 script/.DS_Store create mode 100644 script/local.groovy create mode 100644 script/local.js create mode 100644 script/local.py create mode 100644 script/processing.py create mode 100644 script/test/import_zmqw.py create mode 100644 script/test/test_pipeline1.py create mode 100644 script/test/test_proc.py create mode 100644 script/test/test_stream_out.py create mode 100644 script/tools/dump_camera_stream.py diff --git a/config/config.properties b/config/config.properties new file mode 100644 index 0000000..02e3df1 --- /dev/null +++ b/config/config.properties @@ -0,0 +1,49 @@ +#Thu Aug 11 16:23:50 CEST 2022 +autoSaveScanData=true +simulation=false +dataScanSaveOutput=false +userAuthenticator= +dataScanSaveScript=false +notifiedTasks= +parallelInitialization=false +fdaSerialization=false +dataTransferPath= +saveConsoleSessionFiles=false +hostName= +disableEmbeddedAttributes=false +serverPort=8080 +versionTrackingEnabled=true +dataPath={data}/{year}_{month}/{date}/{date}_{time}_{name} +serverEnabled=false +depthDimension=0 +logLevel=Fine +dataLayout=default +disableDataFileLogs=false +sessionHandling=Off +terminalEnabled=false +notificationLevel=Off +terminalPort=3579 +dataTransferUser= +versionTrackingLogin= +noBytecodeFiles=false +versionTrackingRemote= +logDaysToLive=-1 +logLevelConsole=Off +filePermissionsConfig=Default +scanStreamerPort=-1 +dataScanSaveSetpoints=false +versionTrackingManual=false +dataTransferMode=Off +userManagement=false +instanceName=PIDE +dataServerPort=-1 +hideServerMessages=false +dataScanReleaseRecords=false +dataScanPreserveTypes=false +dataScanFlushRecords=false +filePermissionsLogs=Default +logPath={logs}/{date}_{time} +filePermissionsScripts=Default +filePermissionsData=Default +dataProvider=h5 +saveCommandStatistics=false diff --git a/config/devices.properties b/config/devices.properties new file mode 100644 index 0000000..e69de29 diff --git a/config/mail.properties b/config/mail.properties new file mode 100644 index 0000000..c206323 --- /dev/null +++ b/config/mail.properties @@ -0,0 +1,9 @@ +#Wed Aug 10 10:57:13 CEST 2022 +auth=None +from= +host= +port=0 +pwd= +smsSuffix=@sms.switch.ch +to= +usr= diff --git a/config/plugins.properties b/config/plugins.properties new file mode 100644 index 0000000..a51a153 --- /dev/null +++ b/config/plugins.properties @@ -0,0 +1 @@ +ScreenPanel10.java=enabled diff --git a/config/preferences.json b/config/preferences.json new file mode 100644 index 0000000..5c4919a --- /dev/null +++ b/config/preferences.json @@ -0,0 +1,123 @@ +{ + "fontShellPanel" : { + "name" : "Monospaced", + "style" : 0, + "size" : 13 + }, + "fontShellCommand" : { + "name" : "SansSerif", + "style" : 0, + "size" : 13 + }, + "fontOutput" : { + "name" : "Monospaced", + "style" : 0, + "size" : 13 + }, + "fontEditor" : { + "name" : "Monospaced", + "style" : 0, + "size" : 13 + }, + "fontPlotLabel" : { + "name" : "SansSerif", + "style" : 0, + "size" : 11 + }, + "fontPlotTick" : { + "name" : "SansSerif", + "style" : 0, + "size" : 10 + }, + "fontPlotTitle" : { + "name" : "SansSerif", + "style" : 1, + "size" : 13 + }, + "fontTerminal" : { + "name" : "Menlo", + "style" : 0, + "size" : 14 + }, + "tabSize" : 4, + "contentWidth" : 0, + "editorBackground" : null, + "editorForeground" : null, + "simpleEditor" : false, + "hideEditorLineNumbers" : false, + "hideEditorContextMenu" : false, + "consoleLocation" : "Left", + "dataPanelLocation" : "Status", + "openDataFilesInDocTab" : false, + "noVariableEvaluationPropagation" : false, + "processingScripts" : [ ], + "asyncViewersUpdate" : false, + "scanPlotDisabled" : false, + "scanTableDisabled" : false, + "cachedDataPanel" : false, + "dataExtensions" : null, + "dataSubFiles" : null, + "hideFileName" : false, + "showEmergencyStop" : false, + "showHomingButtons" : false, + "showJogButtons" : false, + "hideScanPanel" : false, + "hideOutputPanel" : false, + "showXScanFileBrowser" : false, + "showQueueBrowser" : false, + "backgroundRendering" : false, + "showImageStatusBar" : true, + "persistRendererWindows" : false, + "defaultRendererColormap" : "Grayscale", + "linePlot" : "ch.psi.pshell.plot.LinePlotJFree", + "matrixPlot" : "ch.psi.pshell.plot.MatrixPlotJFree", + "surfacePlot" : null, + "timePlot" : "ch.psi.pshell.plot.TimePlotJFree", + "plotsDetached" : false, + "plotLayout" : "Vertical", + "quality" : "High", + "defaultPlotColormap" : "Temperature", + "markerSize" : 0, + "plotBackground" : null, + "gridColor" : null, + "outlineColor" : null, + "disableOffscreenBuffer" : false, + "defaultPanels" : [ { + "deviceClassName" : "ch.psi.pshell.epics.Scaler", + "panelClassName" : "ch.psi.pshell.swing.ScalerPanel" + }, { + "deviceClassName" : "ch.psi.pshell.epics.Scienta", + "panelClassName" : "ch.psi.pshell.swing.ScientaPanel" + }, { + "deviceClassName" : "ch.psi.pshell.device.Motor", + "panelClassName" : "ch.psi.pshell.swing.MotorPanel" + }, { + "deviceClassName" : "ch.psi.pshell.device.MasterPositioner", + "panelClassName" : "ch.psi.pshell.swing.MasterPositionerPanel" + }, { + "deviceClassName" : "ch.psi.pshell.device.ProcessVariable", + "panelClassName" : "ch.psi.pshell.swing.ProcessVariablePanel" + }, { + "deviceClassName" : "ch.psi.pshell.device.MotorGroup", + "panelClassName" : "ch.psi.pshell.swing.MotorGroupPanel" + }, { + "deviceClassName" : "ch.psi.pshell.device.DiscretePositioner", + "panelClassName" : "ch.psi.pshell.swing.DiscretePositionerPanel" + }, { + "deviceClassName" : "ch.psi.pshell.device.Camera", + "panelClassName" : "ch.psi.pshell.swing.CameraPanel" + }, { + "deviceClassName" : "ch.psi.pshell.device.Slit", + "panelClassName" : "ch.psi.pshell.swing.SlitPanel" + }, { + "deviceClassName" : "ch.psi.pshell.device.HistogramGenerator", + "panelClassName" : "ch.psi.pshell.swing.HistogramGeneratorPanel" + }, { + "deviceClassName" : "ch.psi.pshell.device.ReadonlyRegister$ReadonlyRegisterArray", + "panelClassName" : "ch.psi.pshell.swing.DeviceValueChart" + }, { + "deviceClassName" : "ch.psi.pshell.device.ReadonlyRegister$ReadonlyRegisterMatrix", + "panelClassName" : "ch.psi.pshell.swing.DeviceValueChart" + } ], + "scriptPopupDialog" : "None" +} \ No newline at end of file diff --git a/config/setup.properties b/config/setup.properties new file mode 100644 index 0000000..ce1fc15 --- /dev/null +++ b/config/setup.properties @@ -0,0 +1,25 @@ +#Wed Aug 10 10:57:13 CEST 2022 +configFile={config}/config.properties +configFileDevices={config}/devices.properties +configFilePlugins={config}/plugins.properties +configFileSessions={config}/sessions.properties +configFileSettings={config}/settings.properties +configFileTasks={config}/tasks.properties +configFileVariables={config}/variables.properties +configPath={home}/config +consoleSessionsPath={sessions}/console +contextPath={outp}/context +dataPath={outp}/data +devicesPath={home}/devices +extensionsPath={home}/extensions +imagesPath={outp}/images +libraryPath={script}; {script}/Lib +logPath={outp}/log +pluginsPath={home}/plugins +queuePath={script} +scriptPath={home}/script +scriptType=cpy +sessionsPath={outp}/sessions +userSessionsPath={sessions}/user +wwwPath={home}/www +xscanPath={script} diff --git a/devices/CamServer.properties b/devices/CamServer.properties new file mode 100644 index 0000000..e8a295d --- /dev/null +++ b/devices/CamServer.properties @@ -0,0 +1,25 @@ +#Wed Aug 10 11:25:14 CEST 2022 +spatialCalOffsetY=NaN +spatialCalOffsetX=NaN +colormapLogarithmic=false +scale=1.0 +grayscale=false +spatialCalScaleX=NaN +spatialCalScaleY=NaN +colormapMax=NaN +rescaleOffset=0.0 +roiWidth=-1 +colormap=Grayscale +invert=false +colormapMin=NaN +rotation=0.0 +rotationCrop=false +rescaleFactor=1.0 +spatialCalUnits=mm +flipVertically=false +roiHeight=-1 +flipHorizontally=false +colormapAutomatic=false +roiY=0 +roiX=0 +transpose=false diff --git a/devices/CurrentCamera.properties b/devices/CurrentCamera.properties new file mode 100644 index 0000000..065c22b --- /dev/null +++ b/devices/CurrentCamera.properties @@ -0,0 +1,25 @@ +#Wed Aug 10 12:34:59 CEST 2022 +spatialCalOffsetY=-485.427166868422 +spatialCalOffsetX=-638.5965043983313 +colormapLogarithmic=false +scale=1.0 +grayscale=false +spatialCalScaleX=-35.21126791588346 +spatialCalScaleY=-48.38709170854271 +colormapMax=255.0 +rescaleOffset=0.0 +roiWidth=-1 +colormap=Flame +invert=false +colormapMin=0.0 +rotation=0.0 +rotationCrop=false +rescaleFactor=1.0 +spatialCalUnits=mm +flipVertically=false +roiHeight=-1 +flipHorizontally=false +colormapAutomatic=true +roiY=0 +roiX=0 +transpose=false diff --git a/devices/cam_server.properties b/devices/cam_server.properties new file mode 100644 index 0000000..2f38dc5 --- /dev/null +++ b/devices/cam_server.properties @@ -0,0 +1,5 @@ +#Thu Aug 11 14:19:59 CEST 2022 +socketType=SUB +keepListeningOnStop=false +byteBufferAllocator=false +parallelHandlerProcessing=true diff --git a/plugins/ScreenPanel10.form b/plugins/ScreenPanel10.form new file mode 100644 index 0000000..c169e3f --- /dev/null +++ b/plugins/ScreenPanel10.form @@ -0,0 +1,1347 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/ScreenPanel10.java b/plugins/ScreenPanel10.java new file mode 100644 index 0000000..ab33276 --- /dev/null +++ b/plugins/ScreenPanel10.java @@ -0,0 +1,4712 @@ +/* + * Copyright (c) 2014 Paul Scherrer Institute. All rights reserved. + */ + +import ch.psi.pshell.bs.CameraServer; +import ch.psi.pshell.core.Context; +import java.io.IOException; +import java.nio.file.Paths; +import javax.swing.DefaultComboBoxModel; +import ch.psi.pshell.ui.Panel; +import ch.psi.pshell.imaging.ImageListener; +import ch.psi.utils.State; +import ch.psi.utils.Chrono; +import ch.psi.utils.swing.SwingUtils; +import ch.psi.utils.swing.TextEditor; +import ch.psi.pshell.bs.PipelineServer; +import ch.psi.pshell.bs.StreamValue; +import ch.psi.pshell.core.JsonSerializer; +import ch.psi.pshell.data.DataManager; +import ch.psi.pshell.device.Device; +import ch.psi.pshell.device.Readable.ReadableArray; +import ch.psi.pshell.device.Readable.ReadableNumber; +import ch.psi.pshell.device.ReadableRegister.ReadableRegisterArray; +import ch.psi.pshell.device.ReadableRegister.ReadableRegisterNumber; +import ch.psi.pshell.epics.ChannelInteger; +import ch.psi.pshell.epics.DiscretePositioner; +import ch.psi.pshell.epics.Epics; +import ch.psi.pshell.imaging.Colormap; +import ch.psi.pshell.imaging.ColormapSource; +import ch.psi.pshell.imaging.ColormapSource.ColormapSourceConfig; +import ch.psi.pshell.ui.App; +import ch.psi.pshell.imaging.Data; +import ch.psi.pshell.imaging.DimensionDouble; +import ch.psi.pshell.imaging.Histogram; +import ch.psi.pshell.imaging.ImageBuffer; +import ch.psi.pshell.imaging.Overlay; +import ch.psi.pshell.imaging.Overlays; +import ch.psi.pshell.imaging.Overlays.Text; +import ch.psi.pshell.imaging.Pen; +import ch.psi.pshell.imaging.PointDouble; +import ch.psi.pshell.imaging.Renderer; +import ch.psi.pshell.imaging.RendererListener; +import ch.psi.pshell.imaging.RendererMode; +import ch.psi.pshell.imaging.Source; +import ch.psi.pshell.scripting.InterpreterResult; +import ch.psi.pshell.scripting.ScriptManager; +import ch.psi.pshell.swing.DeviceValueChart; +import ch.psi.pshell.swing.ValueSelection; +import ch.psi.pshell.swing.ValueSelection.ValueSelectionListener; +import ch.psi.pshell.ui.Console; +import ch.psi.utils.Arr; +import ch.psi.utils.ArrayProperties; +import ch.psi.utils.Config; +import ch.psi.utils.Convert; +import ch.psi.utils.Str; +import ch.psi.utils.swing.Editor.EditorDialog; +import ch.psi.utils.swing.MainFrame; +import ch.psi.utils.swing.StandardDialog; +import ch.psi.utils.swing.StandardDialog.StandardDialogListener; +import ch.psi.utils.swing.SwingUtils.OptionResult; +import ch.psi.utils.swing.SwingUtils.OptionType; +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Toolkit; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.StringSelection; +import java.awt.datatransfer.Transferable; +import java.awt.event.ActionEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.FileInputStream; +import java.lang.reflect.Array; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.swing.ImageIcon; +import javax.swing.JButton; +import javax.swing.JComboBox; +import javax.swing.JComponent; +import javax.swing.JDialog; +import javax.swing.JLabel; +import javax.swing.JMenuItem; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JSpinner; +import javax.swing.JTable; +import javax.swing.JTextField; +import javax.swing.ListSelectionModel; +import javax.swing.SpinnerNumberModel; +import javax.swing.SwingUtilities; +import javax.swing.event.PopupMenuEvent; +import javax.swing.event.PopupMenuListener; +import javax.swing.table.DefaultTableModel; +import org.apache.commons.math3.analysis.function.Gaussian; +import org.apache.commons.math3.fitting.GaussianCurveFitter; +import org.apache.commons.math3.fitting.PolynomialCurveFitter; +import org.apache.commons.math3.fitting.WeightedObservedPoint; +import org.apache.commons.math3.stat.descriptive.DescriptiveStatistics; + +/** + * + */ +public class ScreenPanel10 extends Panel { + + public static final String ARG_TYPE = "cam_type"; + public static final String ARG_LIST = "cam_list"; + public static final String ARG_ALIAS = "alias"; + + public static final String LASER_TYPE = "Laser"; + public static final String ELECTRONS_TYPE = "Electrons"; + public static final String PHOTONICS_TYPE = "Photonics"; + public static final String TWO_PULSES_TYPE = "2Pulses"; + + public static final int STACK_RETRIES = 10; + + final String CAMERA_DEVICE_NAME = "CurrentCamera"; + boolean useServerStats = true; + String userOverlaysConfigFile; + ColormapSource camera; + PipelineServer server; + String cameraName; + String cameraAlias; + int polling = 1000; + Overlay marker = null; + JDialog histogramDialog; + DiscretePositioner screen; + DiscretePositioner filter; + boolean showFit; + boolean showProfile; + Overlay[] userOv; + Overlay[] fitOv; + Overlay[] profileOv; + Overlay errorOverlay; + boolean requestCameraListUpdate; + boolean goodRegion; + boolean slicing; + String serverUrl; + String camServerUrl; + String instanceName; + Overlay titleOv = null; + Overlay backgOv = null; + boolean persistCameraState; + Map> groups; + Map aliases; + final Logger logger; + List types; + boolean isUrl; + boolean isPipeline; + + public class CameraState extends Config { + + public boolean valid; + public boolean showSidePanel; + public boolean showProfile; + public boolean showFit; + public boolean showReticle; + public boolean showScale; + public boolean showTitle; + public double zoom; + public RendererMode mode; + public boolean colormapAutomatic; + public double colormapMin; + public double colormapMax; + public Colormap colormap; + public boolean colormapLogarithmic; + + String getFile() { + if (camera == null) { + return null; + } + return getContext().getSetup().expandPath("{context}/screen_panel/" + cameraName + ".properties"); + } + } + + void loadCameraState() { + if (persistCameraState) { + try { + CameraState state = new CameraState(); + state.load(state.getFile()); + if (state.valid) { + buttonSidePanel.setSelected(state.showSidePanel); + buttonSidePanelActionPerformed(null); + buttonProfile.setSelected(state.showProfile); + buttonProfileActionPerformed(null); + buttonFit.setSelected(state.showFit); + buttonFitActionPerformed(null); + buttonReticle.setSelected(state.showReticle); + buttonReticleActionPerformed(null); + buttonScale.setSelected(state.showScale); + buttonScaleActionPerformed(null); + buttonTitle.setSelected(state.showTitle); + buttonTitleActionPerformed(null); + renderer.setMode(state.mode); + renderer.setZoom(state.zoom); + if (camera instanceof ColormapSource) { + camera.getConfig().colormap = state.colormap; + camera.getConfig().colormapAutomatic = state.colormapAutomatic; + camera.getConfig().colormapLogarithmic = state.colormapLogarithmic; + camera.getConfig().colormapMax = state.colormapMax; + camera.getConfig().colormapMin = state.colormapMin; + updateColormap(); + } + } + } catch (Exception ex) { + ex.printStackTrace(); + } + } + } + + void saveCameraState() { + if (persistCameraState) { + try { + CameraState state = new CameraState(); + state.valid = true; + if (camera instanceof ColormapSource) { + state.colormap = camera.getConfig().colormap; + state.colormapAutomatic = camera.getConfig().colormapAutomatic; + state.colormapLogarithmic = camera.getConfig().colormapLogarithmic; + state.colormapMax = camera.getConfig().colormapMax; + state.colormapMin = camera.getConfig().colormapMin; + } + state.mode = renderer.getMode(); + state.zoom = renderer.getZoom(); + + state.showSidePanel = buttonSidePanel.isSelected(); + state.showProfile = buttonProfile.isSelected(); + state.showFit = buttonFit.isSelected(); + state.showReticle = buttonReticle.isSelected(); + state.showScale = buttonScale.isSelected(); + state.showTitle = buttonTitle.isSelected(); + + state.save(state.getFile()); + } catch (Exception ex) { + ex.printStackTrace(); + } + } + } + + String pipelineSuffix = "_sp"; + + Double getServerDouble(String name) { + return (Double) Convert.toDouble(server.getValue(name)); + } + + double[] getServerDoubleArray(String name) { + return (double[]) Convert.toDouble(server.getValue(name)); + } + + class ImageData { + + ImageData() { + if (server != null) { + cache = server.getStream().take(); + String prefix = goodRegion ? "gr_" : ""; + x_fit_mean = getDouble(prefix + "x_fit_mean"); + y_fit_mean = getDouble(prefix + "y_fit_mean"); + x_fit_standard_deviation = getDouble(prefix + "x_fit_standard_deviation"); + y_fit_standard_deviation = getDouble(prefix + "y_fit_standard_deviation"); + x_fit_gauss_function = getDoubleArray(prefix + "x_fit_gauss_function"); + y_fit_gauss_function = getDoubleArray(prefix + "y_fit_gauss_function"); + x_profile = getDoubleArray("x_profile"); + y_profile = getDoubleArray("y_profile"); + x_center_of_mass = getDouble("x_center_of_mass"); + y_center_of_mass = getDouble("y_center_of_mass"); + x_rms = getDouble("x_rms"); + y_rms = getDouble("y_rms"); + if (goodRegion) { + double[] gX2 = new double[x_profile.length]; + Arrays.fill(gX2, Double.NaN); + try { + double[] axis = getDoubleArray("x_axis"); + gr_x_axis = getDoubleArray("gr_x_axis"); + double x = gr_x_axis[0]; + gr_size_x = x_fit_gauss_function.length; + //If gr axis values are not identical, calculate the index... + gr_pos_x = (int) ((renderer.getCalibration() != null) ? renderer.getCalibration().convertToImageX(x) : x); + //But prefer checking the value to avoid raounding errors + for (int i=0;i imageBuffer = new ArrayList(); + Frame currentFrame; + int imageBufferLenght = 1; + Text imagePauseOverlay; + final Console console; + + public ScreenPanel10() { + logger = Logger.getLogger(getClass().getName()); + try { + initComponents(); + panelPulse.setVisible(false); + panelScreen.setVisible(false); + panelFilter.setVisible(false); + spinnerBackground.setVisible(false); + spinnerThreshold.setVisible(false); + btFixColormapRange.setVisible(false); + setGoodRegionOptionsVisible(false); + setSlicingOptionsVisible(false); + setRotationOptionsVisible(false); + setAveragingOptionsVisible(false); + JComponent editor = spinnerSlOrientation.getEditor(); + if (editor instanceof JSpinner.DefaultEditor) { + ((JSpinner.DefaultEditor) editor).getTextField().setHorizontalAlignment(JTextField.RIGHT); + } + renderer.setPersistenceFile(Paths.get(getContext().getSetup().getContextPath(), "Renderer_Cameras.bin")); + //setPersistedComponents(new Component[]{buttonServer, buttonDirect}); + setPersistedComponents(new Component[]{buttonTitle}); + comboCameras.setEnabled(false); + comboType.setEnabled(false); + if (App.hasArgument(ARG_LIST)){ + comboType.setVisible(false); + labelType.setVisible(false); + } + if (App.hasArgument(ARG_TYPE)){ + types = new ArrayList<>(); + for (String token : App.getArgumentValue(ARG_TYPE).split(",")){ + if (!token.isBlank()){ + types.add(token.trim()); + } + } + } + + SwingUtils.setEnumCombo(comboColormap, Colormap.class); + if (App.hasArgument("poll")) { + try { + polling = Integer.valueOf(App.getArgumentValue("poll")); + } catch (Exception ex) { + ex.printStackTrace(); + } + } + if (App.hasArgument("zoom")) { + try { + renderer.setDefaultZoom(Double.valueOf(App.getArgumentValue("zoom"))); + renderer.resetZoom(); + } catch (Exception ex) { + ex.printStackTrace(); + } + } + if (App.hasArgument("buf")) { + try { + imageBufferLenght = Integer.valueOf(App.getArgumentValue("buf")); + } catch (Exception ex) { + ex.printStackTrace(); + } + } + + if (App.hasArgument("usr_ov")) { + try { + userOverlaysConfigFile = App.getArgumentValue("usr_ov"); + } catch (Exception ex) { + ex.printStackTrace(); + } + } + + if (App.hasArgument("srv_url")) { + serverUrl = App.getArgumentValue("srv_url"); + } + + if (App.hasArgument("cam_srv_url")) { + camServerUrl = App.getArgumentValue("cam_srv_url"); + } + + if (App.hasArgument("calc")) { + useServerStats = false; + } + + if (App.hasArgument("persist")) { + persistCameraState = true; + } + + if (App.hasArgument("suffix")) { + pipelineSuffix = App.getArgumentValue("suffix"); + } + + renderer.setProfileNormalized(true); + renderer.setShowProfileLimits(false); + + JMenuItem menuCalibrate = new JMenuItem("Calibrate..."); + menuCalibrate.addActionListener((ActionEvent e) -> { + try { + calibrate(); + } catch (Exception ex) { + showException(ex); + } + }); + + JMenuItem menuRendererConfig = new JMenuItem("Renderer Parameters"); + menuRendererConfig.addActionListener((ActionEvent e) -> { + try { + if (camera != null) { + this.showDeviceConfigDialog(camera, false); + } + } catch (Exception ex) { + showException(ex); + } + }); + + JMenuItem menuCameraConfig = new JMenuItem("Camera Configurarion"); + menuCameraConfig.addActionListener((ActionEvent e) -> { + try { + if (camera != null) { + String cameraConfigJson = null; + String cameraServerUrl = (camServerUrl == null) ? server.getUrl().substring(0, server.getUrl().length() - 1) + "8" : camServerUrl; + try (CameraServer srv = newCameraServer()) { + //TODO: replace into encodeMultiline + cameraConfigJson = JsonSerializer.encode(srv.getConfig(cameraName), true); + } + + TextEditor configEditor = new TextEditor(); + configEditor.setText(cameraConfigJson); + configEditor.setReadOnly(true); + configEditor.setTitle(cameraName); + EditorDialog dlg = configEditor.getDialog(getTopLevel(), false); + dlg.setSize(480, 640); + dlg.setVisible(true); + SwingUtils.centerComponent(getTopLevel(), dlg); + } + } catch (Exception ex) { + showException(ex); + } + }); + + JMenuItem menuSetImageBufferSize = new JMenuItem("Set Stack Size..."); + menuSetImageBufferSize.addActionListener((ActionEvent e) -> { + try { + String ret = SwingUtils.getString(getTopLevel(), "Enter size of image buffer: ", String.valueOf(imageBufferLenght)); + if (ret != null) { + this.setImageBufferSize(Integer.valueOf(ret)); + } + } catch (Exception ex) { + showException(ex); + } + }); + + JMenuItem menuSaveStack = new JMenuItem("Save Stack"); + menuSaveStack.addActionListener((ActionEvent e) -> { + try { + boolean completeOnly = true; + boolean badFormat = false; + boolean incomplete = false; + + while ((incomplete=((imageBuffer.size() < imageBufferLenght) && completeOnly)) || (badFormat = !hasSameFormat(imageBuffer))){ + if (incomplete){ + OptionResult ret = SwingUtils.showOption(getTopLevel(), "Save Stack", String.format("Stack is not complete (%d/%d images). Wait for completion?", imageBuffer.size(), imageBufferLenght), OptionType.YesNoCancel); + if (ret == OptionResult.Cancel){ + return; + } + if (ret == OptionResult.Yes){ + for (int i=0; i { + renderer.abortSelection(); + if (server != null) { + final Overlays.Rect selection = new Overlays.Rect(renderer.getPenMovingOverlay()); + renderer.addListener(new RendererListener() { + @Override + public void onSelectionFinished(Renderer renderer, Overlay overlay) { + try { + renderer.setShowReticle(false); + Rectangle roi = overlay.isFixed() ? renderer.toImageCoord(overlay.getBounds()) : overlay.getBounds(); + if (server.isRoiEnabled()) { + int[] cur = server.getRoi(); + server.setRoi(new int[]{roi.x + cur[0], roi.y + cur[1], roi.width, roi.height}); + } else { + server.setRoi(new int[]{roi.x, roi.y, roi.width, roi.height}); + } + } catch (Exception ex) { + } finally { + renderer.removeListener(this); + } + } + + @Override + public void onSelectionAborted(Renderer renderer, Overlay overlay) { + renderer.removeListener(this); + } + }); + selection.setFixed(true); + renderer.startSelection(selection); + } + }); + + JMenuItem menuResetROI = new JMenuItem("Reset ROI"); + menuResetROI.addActionListener((ActionEvent e) -> { + renderer.abortSelection(); + if (server != null) { + try { + renderer.setShowReticle(false); + server.resetRoi(); + } catch (IOException ex) { + showException(ex); + } + } + }); + + renderer.getPopupMenu().addSeparator(); + renderer.getPopupMenu().add(menuRendererConfig); + renderer.getPopupMenu().add(menuCameraConfig); + renderer.getPopupMenu().add(menuSetImageBufferSize); + renderer.getPopupMenu().add(menuSaveStack); + renderer.getPopupMenu().addSeparator(); + renderer.getPopupMenu().add(menuCalibrate); + renderer.getPopupMenu().addSeparator(); + renderer.getPopupMenu().add(menuSetROI); + renderer.getPopupMenu().add(menuResetROI); + renderer.getPopupMenu().addPopupMenuListener(new PopupMenuListener() { + @Override + public void popupMenuWillBecomeVisible(PopupMenuEvent e) { + menuResetROI.setEnabled(server != null); + menuSetROI.setEnabled(server != null); + menuCalibrate.setVisible(server != null); + menuCalibrate.setEnabled((calibrationDialolg == null) || (!calibrationDialolg.isShowing())); + menuSaveStack.setEnabled(imageBufferLenght > 0); + menuSetImageBufferSize.setEnabled(!renderer.isPaused()); + } + + @Override + public void popupMenuWillBecomeInvisible(PopupMenuEvent e) { + } + + @Override + public void popupMenuCanceled(PopupMenuEvent e) { + } + }); + renderer.getPopupMenu().setVisible(false); + buttonScale.setSelected(renderer.getShowColormapScale()); + clearMarker(); + + showFit = buttonFit.isSelected(); + showProfile = buttonProfile.isSelected(); + + pauseSelection.setVisible(false); + pauseSelection.setMinValue(1); + pauseSelection.addListener(new ValueSelectionListener() { + @Override + public void onValueChanged(ValueSelection origin, double value, boolean editing) { + if (editing && (value >= 1) && (value <= imageBuffer.size())) { + updatePause(); + } + } + }); + renderer.addListener(new RendererListener() { + @Override + public void onMoveFinished(Renderer renderer, Overlay overlay) { + if (overlay == marker) { + try { + onMarkerChanged(); + } catch (IOException ex) { + logger.log(Level.WARNING, null, ex); + } + } + } + }); + if (MainFrame.isDark()) { + //textState.setDisabledTextColor(textState.getForeground()); + } + + } catch (Exception ex) { + ex.printStackTrace(); + } + + console = (!App.hasArgument("console")) ? null : new Console() { + + @Override + protected void onConsoleCommand(String command) { + String[] tokens = command.split(" "); + if (tokens.length > 0){ + try { + if (tokens[0].equals("cam")) { + if (!tokens[1].equals(comboCameras.getSelectedItem())) { + setComboTypeSelection("All"); + updateCameraList(); + comboCameras.setSelectedItem(tokens[1]); + if (!tokens[1].equals(comboCameras.getSelectedItem())) { + comboCameras.setSelectedItem(""); + throw new Exception("Invalid camera name : " + tokens[1]); + } + System.out.println("Console set camera: " + tokens[1]); + } + } else if (tokens[0].equals("pip")) { + initPipeline(tokens[1]); + } else if (tokens[0].equals("str")) { + initStream(tokens[1]); + } else if (tokens[0].equals("stop")) { + initCamera(""); + } else { + System.err.println("Invalid command: " + command); + } + } catch (Exception ex) { + System.err.println(ex); + } + } + } + }; + } + + @Override + public void onStart() { + super.onStart(); + updateDialogTitle(); + if (App.hasArgument("console")) { + console.start(); + } + } + + @Override + public void onStop() { + try { + if (camera != null) { + saveCameraState(); + camera.close(); + camera = null; + server = null; + updateButtons(); + } + } catch (Exception ex) { + ex.printStackTrace(); + } + try { + if (console != null) { + console.stop(); + } + } catch (Exception ex) { + ex.printStackTrace(); + } + super.onStop(); + } + + //Overridable callbacks + @Override + public void onInitialize(int runCount) { + comboCameras.setEnabled(false); + comboType.setEnabled(false); + + String[] types = new String[]{"All"}; + try (CameraServer srv = newCameraServer()) { + groups = srv.getCameraGroups(); + types = Arr.insert(Arr.sort(groups.keySet().toArray(new String[0])), "All", 0); + aliases = srv.getCameraAliases(); + } catch (Exception ex){ + groups = null; + aliases = null; + } + if (this.types!=null){ + types = this.types.toArray(new String[0]); + } + comboType.setModel(new javax.swing.DefaultComboBoxModel(types)); + + comboCameras.setEnabled(true); + comboType.setEnabled(true); + setComboCameraSelection(null); + if (Arr.containsEqual(types, "All")){ + setComboTypeSelection("All"); + } + updateCameraList(); + + try{ + if (App.hasArgument("s")) { + initSimulation(); + } else if (App.hasArgument("str")) { + initStream(App.getArgumentValue("str")); + } else if (App.hasArgument("pip")) { + initPipeline(App.getArgumentValue("pip")); + } else { + if (comboCameras.getModel().getSize() > 0) { + if (App.hasArgument("cam")) { + initCamera(App.getArgumentValue("cam")); + } + } + } + } catch (Exception ex) { + ex.printStackTrace(); + } + updateButtons(); + startTimer(1000); + } + + public void initCamera(String camera) throws IOException, InterruptedException{ + setComboCameraSelection(camera); + comboCamerasActionPerformed(null); + } + + public void initStream(String url) throws IOException, InterruptedException{ + setComboCameraSelection(""); + if (!url.contains("//")){ + url="tcp://" + url; + } + setCamera(url); + } + + public void initPipeline(String url) throws IOException, InterruptedException{ + setComboCameraSelection(""); + if (!url.contains("//")){ + url="cs://" + url; + } + setCamera(url); + } + + public void initSimulation() throws IOException, InterruptedException{ + renderer.setDevice((Source) getDevice("image")); + renderer.setAutoScroll(true); + ((Source) getDevice("image")).addListener(new ImageListener() { + @Override + public void onImage(Object o, BufferedImage bi, Data data) { + manageFit(bi, data); + manageUserOverlays(bi, data); + } + + @Override + public void onError(Object o, Exception ex) { + } + } + ); + } + + boolean isVisible(String camera) { + return ((comboType.getSelectedItem().toString().toLowerCase().equals("all")) || (getCameraTypes(camera).contains(comboType.getSelectedItem()))); + } + + DefaultComboBoxModel getCameraList() throws Exception { + DefaultComboBoxModel model = new DefaultComboBoxModel(); + if (App.hasArgument(ARG_LIST)){ + List lists = App.getArgumentValues(ARG_LIST); + for (String list: lists){ + String[] tokens = list.split(","); + for (String token : tokens){ + if (!token.isBlank()){ + model.addElement(token.trim()); + } + } + } + } else { + try (CameraServer srv = newCameraServer()) { + List cameras = srv.getCameras(); + Collections.sort(cameras); + if (App.hasArgument(ARG_ALIAS) && (aliases!=null)){ + if ("only".equals(App.getArgumentValue(ARG_ALIAS))){ + cameras = new ArrayList(); + } + cameras.addAll(0, aliases.keySet()); + } + for (String camera : cameras) { + if (isVisible(camera)) { + model.addElement(camera); + } + } + } + } + if (App.hasArgument("cam")) { + String camera = App.getArgumentValue("cam"); + if (model.getIndexOf(camera) < 0) { + if (isVisible(camera)) { + model.addElement(camera); + } + } + } + model.addElement(""); + + return model; + } + + PipelineServer newServer() throws IOException { + if (serverUrl != null) { + System.out.println("Connecting to server: " + serverUrl); + server = new PipelineServer(CAMERA_DEVICE_NAME, serverUrl); + } else { + System.out.println("Connecting to server"); + server = new PipelineServer(CAMERA_DEVICE_NAME); + } + updateButtons(); + return server; + } + + CameraServer newCameraServer() throws IOException, InterruptedException { + String cameraServerUrl = (camServerUrl == null) ? server.getUrl().substring(0, server.getUrl().length() - 1) + "8" : camServerUrl; + CameraServer srv = new CameraServer("CamServer", cameraServerUrl); + srv.initialize(); + return srv; + } + + boolean updatingCameraSelection; + + void setComboCameraSelection(Object selection) { + updatingCameraSelection = true; + try { + comboCameras.setSelectedItem(selection); + } finally { + updatingCameraSelection = false; + } + } + + void setComboTypeSelection(Object selection) { + updatingCameraSelection = true; + try { + comboType.setSelectedItem(selection); + } finally { + updatingCameraSelection = false; + } + } + + void updateCameraList() { + try { + String selected = (String) comboCameras.getSelectedItem(); + comboCameras.setModel(getCameraList()); + if ((selected != null) && (((DefaultComboBoxModel) comboCameras.getModel()).getIndexOf(selected) > 0)){ + setComboCameraSelection(selected); + } else{ + setComboCameraSelection(""); + } + } catch (Exception ex) { + ex.printStackTrace(); + } finally { + updateButtons(); + } + } + + final Object lockOverlays = new Object(); + + void manageFit(BufferedImage bi, Data data) { + Overlay[][] fo = null; + if ((showFit || showProfile)) { + try { + fo = getFitOverlays(data); + } catch (Exception ex) { + System.err.println(ex); + } + } + synchronized (lockOverlays) { + fo = (fo == null) ? new Overlay[][]{null, null} : fo; + renderer.updateOverlays(fo[0], profileOv); + profileOv = fo[0]; + renderer.updateOverlays(fo[1], fitOv); + fitOv = fo[1]; + } + } + + void manageUserOverlays(BufferedImage bi, Data data) { + Overlay[] fo = (bi == null) ? null : getUserOverlays(data); + synchronized (lockOverlays) { + renderer.updateOverlays(fo, userOv); + userOv = fo; + } + } + + void updateDialogTitle() { + if (App.isDetached()) { + getTopLevel().setTitle(cameraName == null ? "ScreenPanel" : cameraName); + } + } + + void manageTitleOverlay() { + Overlay to = null; + String text = cameraAlias; + if ((buttonTitle.isSelected()) && (text != null)) { + Font font = new Font("Arial", Font.PLAIN, 28); + to = new Text(renderer.getPenErrorText(), text, font, new Point(-SwingUtils.getTextSize(text, renderer.getGraphics().getFontMetrics(font)).width - 14, 26)); + to.setFixed(true); + to.setAnchor(Overlay.ANCHOR_VIEWPORT_OR_IMAGE_TOP_RIGHT); + } + + synchronized (lockOverlays) { + renderer.updateOverlays(to, titleOv); + titleOv = to; + } + } + + + void manageOverlayErrorOverlay(boolean error) { + if ((error) != (backgOv != null)){ + + Overlay bo = null; + if (error){ + String text = "Invalid image background"; + Font font = new Font("Arial", Font.PLAIN, 14); + bo = new Text(renderer.getPenErrorText(), text, font, new Point(-SwingUtils.getTextSize(text, renderer.getGraphics().getFontMetrics(font)).width - 14, 46)); + bo.setFixed(true); + bo.setAnchor(Overlay.ANCHOR_VIEWPORT_OR_IMAGE_TOP_RIGHT); + } + synchronized (lockOverlays) { + renderer.updateOverlays(bo,backgOv); + backgOv = bo; + } + } + } + + + @Override + public void onStateChange(State state, State former) { + + } + + @Override + public void onExecutedFile(String fileName, Object result) { + } + + //Callback to perform update - in event thread + @Override + protected void doUpdate() { + } + + Thread devicesInitTask; + + void setCamera(String cameraName) throws IOException, InterruptedException { + System.out.println("Initializing: " + cameraName); + isUrl = (cameraName!=null) && cameraName.startsWith("tcp://"); + isPipeline = (cameraName!=null) && cameraName.startsWith("cs://"); + if (isPipeline) { + cameraName = cameraName.substring(cameraName.lastIndexOf("/") + 1); + } + //panelPipeline.setVisible(!isUrl); + //panelCameraSelection.setVisible(!isUrl); + parseUserOverlays(); + errorOverlay = null; + lastMarkerPos = null; + lastFrame = null; + lastPipelinePars = null; + + if (dataTableDialog != null) { + dataTableDialog.dispose(); + dataTableDialog = null; + } + dataTableModel = null; + + if (calibrationDialolg != null) { + calibrationDialolg.dispose(); + calibrationDialolg = null; + } + + boolean was_server = false; + if (camera != null) { + saveCameraState(); + //camera.removeAllListeners(); + was_server = (server != null); + camera.close(); + camera = null; + server = null; + } + updateButtons(); + instanceName = null; + renderer.setDevice(null); + renderer.setShowReticle(false); + renderer.removeOverlays(fitOv); + renderer.removeOverlays(profileOv); + renderer.removeOverlays(userOv); + renderer.clear(); + renderer.resetZoom(); + + cameraAlias = cameraName; + if ((aliases!=null) && (cameraName!=null) && (aliases.containsKey(cameraName))){ + cameraName = aliases.get(cameraName); + System.out.println("Camera name is alias to: " + cameraName); + } + + boolean changed = !String.valueOf(cameraName).equals(this.cameraName); + this.cameraName = cameraName; + + if (changed) { + spinnerBackground.setVisible(false); + spinnerThreshold.setVisible(false); + checkThreshold.setEnabled(false); + checkRotation.setEnabled(false); + checkAveraging.setEnabled(false); + checkGoodRegion.setEnabled(false); + setGoodRegionOptionsVisible(false); + setSlicingOptionsVisible(false); + setRotationOptionsVisible(false); + setAveragingOptionsVisible(false); + } + synchronized (imageBuffer) { + currentFrame = null; + imageBuffer.clear(); + } + if (changed) { + checkBackground.setEnabled(false); + if ((devicesInitTask != null) && (devicesInitTask.isAlive())) { + devicesInitTask.interrupt(); + } + if (screen != null) { + screen.close(); + screen = null; + } + if (filter != null) { + filter.close(); + filter = null; + } + if (renderer.isPaused()) { + renderer.resume(); + removePauseOverlay(); + pauseSelection.setVisible(false); + panelCameraSelection.setVisible(true); + } + } + manageTitleOverlay(); + updateDialogTitle(); + + if (cameraName == null) { + return; + } + try { + + camera = newServer(); + camera.getConfig().flipHorizontally = false; + camera.getConfig().flipVertically = false; + camera.getConfig().rotation = 0.0; + camera.getConfig().roiX = 0; + camera.getConfig().roiY = 0; + camera.getConfig().roiWidth = -1; + camera.getConfig().roiHeight = -1; + + camera.initialize(); + camera.assertInitialized(); + System.out.println("Camera initialization OK"); + loadCameraState(); + if (server != null) { + //server.start(cameraName, false); + if (isUrl){ + System.out.println("Setting url: " + cameraName ); + instanceName = cameraName; + server.setStreamSocket(instanceName); + server.startReceiver(); + cameraName = null; + } else if (isPipeline){ + System.out.println("Setting pipeline: " + cameraName ); + instanceName = cameraName; + server.start(instanceName, true); + try{ + cameraName = server.getCameraName(); + //setComboCameraSelection(cameraName); + } catch (Exception ex){ + cameraName = null; + } + System.out.println("Camera Name: " + cameraName ); + } else { + System.out.println("Setting camera: " + cameraName ); + String pipelineName = cameraName + pipelineSuffix; + instanceName = cameraName + pipelineSuffix + "1"; + if (!server.getPipelines().contains(pipelineName)) { + System.out.println("Creating pipeline: " + pipelineName); + HashMap config = new HashMap<>(); + config.put("camera_name", cameraName); + //server.createFromConfig(config, pipelineName); + server.savePipelineConfig(pipelineName, config); + } + server.start(pipelineName, instanceName); + } + this.cameraName = cameraName; + updatePipelineControls(); + checkThreshold.setEnabled(true); + checkRotation.setEnabled(true); + checkAveraging.setEnabled(true); + checkGoodRegion.setEnabled(true); + } else { + checkThreshold.setSelected(false); + checkRotation.setSelected(false); + checkAveraging.setSelected(false); + checkGoodRegion.setSelected(false); + if (polling <= 0) { + camera.setMonitored(true); + } else { + camera.setPolling(polling); + } + camera.setBackgroundEnabled(checkBackground.isSelected()); + } + updateButtons(); + camera.getConfig().save(); + + renderer.setDevice(camera); + + renderer.setAutoScroll(true); + //renderer.setMarker(marker); + clearMarker(); + imageSize = null; + + camera.addListener(new ImageListener() { + @Override + public void onImage(Object o, BufferedImage bi, Data data) { + if (bi != null) { + if ((imageSize == null) || imageSize.width != bi.getWidth() || imageSize.height != bi.getHeight()) { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + if ((renderer.getMode() == RendererMode.Zoom) || (renderer.getMode() == RendererMode.Fixed)) { + centralizeRenderer(); + } + checkReticle(); + } + }); + imageSize = new Dimension(bi.getWidth(), bi.getHeight()); + } + renderer.setProfileSize(Math.min(bi.getWidth(), bi.getHeight())); + } + //renderer.setCalibration(camera.getCalibration()); + if (!renderer.isPaused()) { + if (data != null) { + synchronized (imageBuffer) { + currentFrame = new Frame(data); + if (imageBufferLenght >= 1) { + imageBuffer.add(currentFrame); + if (imageBuffer.size() > imageBufferLenght) { + imageBuffer.remove(0); + setBufferFull(true); + } else { + setBufferFull(false); + } + } else { + setBufferFull(true); + } + //Update data + if (!renderer.isPaused()) { + updateStreamData(); + } + updateMarker(); + } + } + manageFit(bi, data); + manageUserOverlays(bi, data); + } + //updateImageData(); + } + + @Override + public void onError(Object o, Exception ex) { + //System.err.println(ex); + } + }); + + } catch (Exception ex) { + showException(ex); + renderer.clearOverlays(); + updatePipelineControls(); + if (renderer.getDevice() == null) { + //renderer.setZoom(1.0); + //renderer.setMode(RendererMode.Zoom); + errorOverlay = new Text(renderer.getPenErrorText(), ex.toString(), new Font("Verdana", Font.PLAIN, 12), new Point(20, 20)); + errorOverlay.setFixed(true); + errorOverlay.setAnchor(Overlay.ANCHOR_VIEWPORT_TOP_LEFT); + renderer.addOverlay(errorOverlay); + } + } finally { + //checkReticle(); + onTimer(); + } + onChangeColormap(null); + checkBackground.setEnabled(true); + if (changed) { + if (cameraName==null){ + + } + boolean electrons = (this.cameraName!=null) && getCameraTypes(this.cameraName).contains(ELECTRONS_TYPE); + boolean twoPulses = (this.cameraName!=null) && getCameraTypes(this.cameraName).contains(TWO_PULSES_TYPE); + comboScreen.setModel(new DefaultComboBoxModel()); + comboScreen.setEnabled(false); + comboFilter.setModel(new DefaultComboBoxModel()); + comboFilter.setEnabled(false); + panelFilter.setVisible(electrons); + panelScreen.setVisible(electrons); + panelPulse.setVisible(twoPulses); + textPulse.setText(""); + if (this.cameraName!=null){ + if (electrons) { + //Parallelizing initialization + devicesInitTask = new Thread(() -> { + try { + if (this.cameraName.contains("DSRM")) { + screen = new DiscretePositioner("CurrentScreen", this.cameraName + ":POSITION_SP", this.cameraName + ":POSITION"); + } else { + screen = new DiscretePositioner("CurrentScreen", this.cameraName + ":SET_SCREEN1_POS", this.cameraName + ":GET_SCREEN1_POS"); + } + screen.setMonitored(true); + screen.initialize(); + DefaultComboBoxModel model = new DefaultComboBoxModel(); + for (String pos : screen.getPositions()) { + model.addElement(pos); + } + comboScreen.setModel(model); + comboScreen.setSelectedItem(screen.read()); + + } catch (Exception ex) { + comboScreen.setModel(new DefaultComboBoxModel()); + System.err.println(ex.getMessage()); + screen = null; + } + comboScreen.setEnabled(screen != null); + valueScreen.setDevice(screen); + + try { + filter = new DiscretePositioner("CurrentFilter", this.cameraName + ":SET_FILTER", this.cameraName + ":GET_FILTER"); + filter.setMonitored(true); + filter.initialize(); + DefaultComboBoxModel model = new DefaultComboBoxModel(); + for (String pos : filter.getPositions()) { + model.addElement(pos); + } + comboFilter.setModel(model); + comboFilter.setSelectedItem(filter.read()); + } catch (Exception ex) { + System.err.println(ex.getMessage()); + filter = null; + } + comboFilter.setEnabled(filter != null); + valueFilter.setDevice(filter); + }); + devicesInitTask.start(); + } + } + } + } + + boolean bufferFull = true; + + void setBufferFull(boolean value) { + if (value != bufferFull) { + SwingUtilities.invokeLater(() -> { + buttonPause.setBackground(value ? buttonSave.getBackground() : buttonSave.getBackground().brighter()); + }); + bufferFull = value; + } + } + + volatile Dimension imageSize; + + void checkReticle() { + if ((renderer.getDevice() != null) && (camera != null) && (camera.getConfig().isCalibrated()) && buttonReticle.isSelected()) { + //renderer.setCalibration(camera.getCalibration()); + renderer.configureReticle(new Dimension(800, 800), 200); + renderer.setShowReticle(true); + } else { + //renderer.setCalibration(null); + renderer.setShowReticle(false); + } + renderer.refresh(); + } + + void checkMarker(Point p) throws IOException { + if (camera != null) { + if (buttonMarker.isSelected()) { + Dimension d = renderer.getImageSize(); + if (p == null) { + p = (d == null) ? new Point(renderer.getWidth() / 2, renderer.getHeight() / 2) : new Point(d.width / 2, d.height / 2); + } + Overlay ov = null; + marker = new Overlays.Crosshairs(renderer.getPenMarker(), p, new Dimension(100, 100)); + marker.setMovable(true); + marker.setPassive(false); + } else { + marker = null; + } + renderer.setMarker(marker); + onMarkerChanged(); + } + } + + Point lastMarkerPos; + + void onMarkerChanged() throws IOException { + lastMarkerPos = getStreamMarkerPos(); + if (marker == null) { + setInstanceConfigValue("Marker", null); + } else { + setInstanceConfigValue("Marker", new int[]{marker.getPosition().x, marker.getPosition().y}); + } + } + + void updateMarker() { + try { + if ((server != null) && (!isUrl)) { + Point p = getStreamMarkerPos(); + if (p != null) { + //To prevent a local change being overriden by a message having the old settings. + //TODO: This is not bullet-proof, as one can have 2 changes between 2 frames... + if (!p.equals(lastMarkerPos)) { + if (p.x == Integer.MIN_VALUE) { + if (buttonMarker.isSelected()) { + buttonMarker.setSelected(false); + checkMarker(null); + } + } else { + if (!buttonMarker.isSelected()) { + buttonMarker.setSelected(true); + checkMarker(p); + } else { + if (!p.equals(marker.getPosition())) { + marker.setPosition(p); + } + } + } + } + } + } + } catch (Exception ex) { + ex.printStackTrace(); + } + } + + Point getStreamMarkerPos() throws IOException { + //System.out.println(server.getInstanceConfig().get("Marker")); + Map pars = server.getProcessingParameters(); + if (pars != null) { + List markerPosition = (List) pars.get("Marker"); + if (markerPosition != null) { + return new Point((Integer) markerPosition.get(0), (Integer) markerPosition.get(1)); + } + return new Point(Integer.MIN_VALUE, Integer.MIN_VALUE); + } + return null; + } + + void clearMarker() { + marker = null; + renderer.setMarker(marker); + } + + void setInstanceConfigValue(String name, Object value) throws IOException { + if (server != null) { + Map map = server.getInstanceConfig(); + map.put(name, value); + server.setInstanceConfig(map); + } + } + + void updateZoom() { + try { + buttonZoomStretch.setSelected(renderer.getMode() == RendererMode.Stretch); + buttonZoomFit.setSelected(renderer.getMode() == RendererMode.Fit); + if (renderer.getMode() == RendererMode.Fixed) { + buttonZoomNormal.setSelected(true); + } else if (renderer.getMode() == RendererMode.Zoom) { + if (renderer.getZoom() == 1) { + buttonZoomNormal.setSelected(true); + } else if (renderer.getZoom() == 0.5) { + buttonZoom05.setSelected(true); + } else if (renderer.getZoom() == 0.25) { + buttonZoom025.setSelected(true); + } else if (renderer.getZoom() == 2.0) { + buttonZoom2.setSelected(true); + } else { + buttonGroup1.clearSelection(); + } + } + } catch (Exception ex) { + ex.printStackTrace(); + } + } + + boolean updatingColormap; + + void updateColormap() { + updatingColormap = true; + try { + if ((camera != null) && (camera instanceof ColormapSource)) { + ColormapSourceConfig config = ((ColormapSource) camera).getConfig(); + comboColormap.setSelectedItem(config.colormap); + if (config.isDefaultColormap()) { + buttonFullRange.setSelected(true); + } else if (config.colormapAutomatic) { + buttonAutomatic.setSelected(true); + } else { + buttonManual.setSelected(true); + } + btFixColormapRange.setVisible(buttonAutomatic.isSelected()); + spinnerMin.setEnabled(buttonManual.isSelected()); + spinnerMax.setEnabled(buttonManual.isSelected()); + + boolean signed = spinnerBackground.isVisible() && "signed".equals(spinnerBackground.getValue()); + Integer min = signed ? -65535: 0; + if (!min.equals(((SpinnerNumberModel)spinnerMin.getModel()).getMinimum())){ + spinnerMin.setModel(new SpinnerNumberModel(0, min.intValue(), 65535, 1)); + spinnerMax.setModel(new SpinnerNumberModel(255, min.intValue(), 65535, 1)); + if ((Integer)((SpinnerNumberModel)spinnerMin.getModel()).getValue() < min){ + spinnerMin.setValue(min); + } + if ((Integer)((SpinnerNumberModel)spinnerMax.getModel()).getValue() < min){ + spinnerMax.setValue(min); + } + } + + if (!Double.isNaN(config.colormapMin)) { + Integer value = Math.min(Math.max((int) config.colormapMin, min), 65535); + if (spinnerMin.getModel().getValue()!= value){ + spinnerMin.setValue(value); + } + } + if (!Double.isNaN(config.colormapMax)) { + Integer value = Math.min(Math.max((int) config.colormapMax, min), 65535); + if (spinnerMax.getModel().getValue()!= value){ + spinnerMax.setValue(value); + } + } + } + } catch (Exception ex) { + ex.printStackTrace(); + } + updatingColormap = false; + } + + void updatePipelineProperties() { + goodRegion = checkGoodRegion.isSelected(); + spinnerBackground.setVisible(checkBackground.isSelected()); + spinnerThreshold.setVisible(checkThreshold.isSelected()); + setGoodRegionOptionsVisible(goodRegion); + slicing = goodRegion && checkSlicing.isSelected(); + setSlicingOptionsVisible(slicing); + updatingServerControls = false; + boolean rotation = checkRotation.isSelected(); + setRotationOptionsVisible(rotation); + boolean averaging = checkAveraging.isSelected(); + setAveragingOptionsVisible(averaging); + } + + boolean updatingServerControls; + + void updatePipelineControls() { + if (server != null) { + updatingServerControls = true; + if (server.isStarted()) { + try { + checkBackground.setSelected(server.isBackgroundSubtractionEnabled()); + setBackgoundControl(server.getBackgroundSubtraction()); + Object bg = server.getBackgroundSubtraction(); + if (bg.equals("signed") || bg.equals("passive")){ + spinnerBackground.setValue(bg); + } else { + spinnerBackground.setValue("normal"); + } + Double threshold = (server.getThreshold()); + checkThreshold.setSelected(threshold != null); + spinnerThreshold.setValue((threshold == null) ? 0 : threshold); + Map gr = (server.getGoodRegion()); + checkGoodRegion.setSelected(gr != null); + if (gr != null) { + spinnerGrThreshold.setValue(((Number) gr.get("threshold")).doubleValue()); + spinnerGrScale.setValue(((Number) gr.get("gfscale")).doubleValue()); + } + Map rotation = server.getRotation(); + checkRotation.setSelected(rotation != null); + if (rotation!=null){ + spinnerRotationAngle.setValue(((Number) rotation.get("angle")).doubleValue()); + spinnerRotationOrder.setValue(((Number) rotation.get("order")).intValue()); + String mode = (String) rotation.get("mode"); + try{ + spinnerRotationConstant.setValue(Double.valueOf(mode)); + spinnerRotationMode.setValue("constant"); + } catch (Exception ex){ + spinnerRotationConstant.setValue(0); + spinnerRotationMode.setValue(mode); + } + } + + Number averaging = (Number) server.getInstanceConfig().get("averaging"); + checkAveraging.setSelected(averaging != null); + if (averaging!=null){ + spinnerAvFrames.setValue(Math.abs(averaging.intValue())); + spinnerAvMode.setValue(averaging.intValue()<0 ? "window" : "single"); + } + + + Map slicing = (server.getSlicing()); + checkSlicing.setSelected(slicing != null); + if (slicing != null) { + spinnerSlNumber.setValue(((Number) slicing.get("number_of_slices")).intValue()); + spinnerSlScale.setValue(((Number) slicing.get("scale")).doubleValue()); + spinnerSlOrientation.setValue((String) slicing.get("orientation")); + } + } catch (Exception ex) { + ex.printStackTrace(); + } + } + updatePipelineProperties(); + } + } + + boolean changedPipelinePars(Map pars1, Map pars2) { + String[] keys = new String[]{"image_background_enable", "image_threshold", "image_good_region", + "threshold", "gfscale", "image_slices", "number_of_slices", "scale", "orientation", "image_background_ok"}; + for (String key : keys) { + Object o1 = pars1.get(key); + Object o2 = pars2.get(key); + if (o1 == null) { + if (o2 != null) { + return true; + } + } else if (!o1.equals(o2)) { + return true; + } + } + return false; + } + + void setBackgoundControl(Object background){ + spinnerBackground.setValue((background.equals("signed") || background.equals("passive")) ? background : "normal"); + } + + void updatePipelineControls(Map pars) { + if (pars != null) { + updatingServerControls = true; + try { + Object background = pars.get("image_background_enable"); + checkBackground.setSelected(!background.equals("") && !background.equals(false) && !background.equals("false")); + setBackgoundControl(background); + + manageOverlayErrorOverlay(Boolean.FALSE.equals(pars.get("image_background_ok"))); + + Double threshold = (Double) (pars.get("image_threshold")); + checkThreshold.setSelected(threshold != null); + spinnerThreshold.setValue((threshold == null) ? 0 : threshold); + Map gr = (Map) pars.get("image_good_region"); + checkGoodRegion.setSelected(gr != null); + if (gr != null) { + Double value = ((Number) gr.get("threshold")).doubleValue(); + spinnerGrThreshold.setValue(value); + Double scale = ((Number) gr.get("gfscale")).doubleValue(); + spinnerGrScale.setValue(scale); + } + Map slicing = (Map) (pars.get("image_slices")); + checkSlicing.setSelected(slicing != null); + if (slicing != null) { + int slices = ((Number) slicing.get("number_of_slices")).intValue(); + spinnerSlNumber.setValue(slices); + double scale = ((Number) slicing.get("scale")).doubleValue(); + spinnerSlScale.setValue(scale); + String orientation = (String) slicing.get("orientation"); + spinnerSlOrientation.setValue(orientation); + } + } catch (Exception ex) { + ex.printStackTrace(); + } + updatePipelineProperties(); + } + } + + void setGoodRegionOptionsVisible(boolean visible) { + spinnerGrThreshold.setVisible(visible); + labelGrThreshold.setVisible(visible); + spinnerGrScale.setVisible(visible); + labelGrScale.setVisible(visible); + panelSlicing.setVisible(visible); + } + + void setSlicingOptionsVisible(boolean visible) { + spinnerSlNumber.setVisible(visible); + labelSlNumber.setVisible(visible); + spinnerSlScale.setVisible(visible); + labelSlScale.setVisible(visible); + spinnerSlOrientation.setVisible(visible); + labelSlOrientation.setVisible(visible); + } + + void setAveragingOptionsVisible(boolean visible) { + labelAvMode.setVisible(visible); + labelAvFrames.setVisible(visible); + spinnerAvMode.setVisible(visible); + spinnerAvFrames.setVisible(visible); + } + + void setRotationOptionsVisible(boolean visible) { + labelAngle.setVisible(visible); + labelOrder.setVisible(visible); + labelMode.setVisible(visible); + labelConstant.setVisible(visible); + spinnerRotationAngle.setVisible(visible); + spinnerRotationOrder.setVisible(visible); + spinnerRotationMode.setVisible(visible); + spinnerRotationConstant.setVisible(visible); + } + + boolean isCameraStopped() { + if (server != null) { + if (!isUrl) { + if (!server.isStarted()) + return true; + } + } + return ((camera == null) || camera.isClosed()); + } + + boolean updatingButtons; + + void updateButtons() { + updatingButtons = true; + try { + boolean active = !isCameraStopped();//(camera != null); + buttonSave.setEnabled(active); + buttonGrabBackground.setEnabled(active); + buttonMarker.setEnabled(active); + buttonProfile.setEnabled(active); + buttonFit.setEnabled(active); + buttonReticle.setEnabled(active && camera.getConfig().isCalibrated()); + buttonStreamData.setEnabled(active && (server != null)); + buttonPause.setEnabled(active); + + if (renderer.isPaused() != buttonPause.isSelected()) { + buttonPause.setSelected(renderer.isPaused()); + buttonPauseActionPerformed(null); + } + if (renderer.getShowReticle() != buttonReticle.isSelected()) { + //buttonReticle.setSelected(renderer.getShowReticle()); + } + if ((renderer.getMarker() == null) && buttonMarker.isSelected()) { + buttonMarker.setSelected(false); + } + buttonSave.setSelected(renderer.isSnapshotDialogVisible()); + + } finally { + updatingButtons = false; + } + } + + Frame lastFrame = null; + Map lastPipelinePars = null; + + State state; + void checkAppState(){ + if (App.isDetached()){ + State state = App.getInstance().getState(); + if (state.isInitialized()){ + state = (camera == null) ? state : camera.getState(); + } + if (state!=this.state){ + App.getInstance().getPropertyChangeSupport().firePropertyChange("appstate", this.state, state); + this.state = state; + } + } + } + + + @Override + protected void onTimer() { + for (Device dev : new Device[]{screen, filter}) { + if (dev != null) { + dev.request(); + } + } + + //textState.setText((camera == null) ? "" : camera.getState().toString());\ + checkAppState(); + + if (App.hasArgument("s")) { + try { + ((Source) getDevice("image")).initialize(); + } catch (IOException ex) { + logger.log(Level.SEVERE, null, ex); + } catch (InterruptedException ex) { + logger.log(Level.SEVERE, null, ex); + } + } + updateZoom(); + updateColormap(); + updateButtons(); + checkHistogram.setSelected((histogramDialog != null) && (histogramDialog.isShowing())); + buttonScale.setSelected(renderer.getShowColormapScale()); + try { + Frame frame = getCurrentFrame(); + if (frame != lastFrame) { + lastFrame = frame; + if (frame != null) { + Map pars = getProcessingParameters(frame.cache); + if ((lastPipelinePars == null) || changedPipelinePars(pars, lastPipelinePars)) { + //System.out.println("Update pipeline: " + pars); + lastPipelinePars = pars; + updatePipelineControls(pars); + } + if (panelPulse.isVisible()){ + Object pulse = null; + try{ + pulse = frame.cache.getValue("pulse"); + } catch (Exception ex) { + } + textPulse.setText((pulse==null) ? "" : Str.toString(pulse)); + } + } + } + } catch (Exception ex) { + ex.printStackTrace(); + } + } + + Pen penFit = new Pen(new Color(192, 105, 0), 0); + Pen penCross = new Pen(new Color(192, 105, 0), 0); + Pen penSlices = new Pen(Color.CYAN.darker(), 1); + + Frame getCurrentFrame() { + if ((imageBufferLenght > 1) && (renderer.isPaused())) { + int index = ((int) pauseSelection.getValue()) - 1; + synchronized (imageBuffer) { + return ((index>=0) && (index < imageBuffer.size())) ? imageBuffer.get(index) : null; + } + } + return currentFrame; + } + + Frame getFrame(Data data) { + synchronized (imageBuffer) { + for (Frame f : imageBuffer) { + if (f.data == data) { + return f; + } + } + } + return null; + } + + void setImageBufferSize(int size) { + if (renderer.isPaused()) { + throw new RuntimeException("Cannot change buffer size whn paused"); + } + synchronized (imageBuffer) { + imageBufferLenght = size; + imageBuffer.clear(); + } + + } + + Overlay[][] getFitOverlays(Data data) { + Overlays.Polyline hgaussian = null; + Overlays.Polyline vgaussian = null; + Overlays.Polyline hprofile = null; + Overlays.Polyline vprofile = null; + Double xMean = null, xSigma = null, xNorm = null, xCom = null, xRms = null; + Double yMean = null, ySigma = null, yNorm = null, yCom = null, yRms = null; + double[] pX = null, pY = null, gX = null, gY = null; + PointDouble[] sliceCenters = null; + if (data != null) { + int height = data.getHeight(); + int width = data.getWidth(); + int profileSize = renderer.getProfileSize(); + ImageData id = null; + if ((useServerStats) && (server != null)) { + try { + id = getFrame(data); + if (id == null) { + return null; + } + xMean = id.x_fit_mean; + xSigma = id.x_fit_standard_deviation; + yMean = id.y_fit_mean; + ySigma = id.y_fit_standard_deviation; + gX = id.x_fit_gauss_function; + gY = id.y_fit_gauss_function; + pX = id.x_profile; + pY = id.y_profile; + xCom = id.x_center_of_mass; + xRms = id.x_rms; + yCom = id.y_center_of_mass; + yRms = id.y_rms; + sliceCenters = id.sliceCenters; + + profileSize /= 4; + if (pX != null) { + int[] xp = Arr.indexesInt(pX.length); + int[] xg = xp; + int[] yp = new int[pX.length]; + int[] yg = new int[pX.length]; + + List l = Arrays.asList((Double[]) Convert.toWrapperArray(pX)); + double minProfile = Collections.min(l); + double maxProfile = Collections.max(l); + double rangeProfile = maxProfile - minProfile; + double minGauss = minProfile; + double rangeGauss = rangeProfile; + //If not good region, range of profile and fit are similar so save this calcultion + if (goodRegion && id.gr_size_x > 0) { + l = Arrays.asList((Double[]) Convert.toWrapperArray(Arrays.copyOfRange(gX, id.gr_pos_x, id.gr_pos_x + id.gr_size_x))); + minGauss = Collections.min(l); + rangeGauss = Collections.max(l) - minGauss; + } + + for (int i = 0; i < xp.length; i++) { + if (gX != null) { + yg[i] = (int) (height - 1 - (((gX[i] - minGauss) / rangeGauss) * profileSize)); + } + yp[i] = (int) (height - 1 - (((pX[i] - minProfile) / rangeProfile) * profileSize)); + } + + if (goodRegion && id.gr_size_x > 0) { + xg = Arrays.copyOfRange(xg, id.gr_pos_x, id.gr_pos_x + id.gr_size_x); + yg = Arrays.copyOfRange(yg, id.gr_pos_x, id.gr_pos_x + id.gr_size_x); + } + + vgaussian = new Overlays.Polyline(penFit, xg, yg); + vprofile = new Overlays.Polyline(renderer.getPenProfile(), xp, yp); + } + + if (pY != null) { + int[] xp = new int[pY.length]; + int[] xg = new int[pY.length]; + int[] yp = Arr.indexesInt(pY.length); + int[] yg = yp; + + List l = Arrays.asList((Double[]) Convert.toWrapperArray(pY)); + double minProfile = Collections.min(l); + double maxProfile = Collections.max(l); + double rangeProfile = maxProfile - minProfile; + double minGauss = minProfile; + double rangeGauss = rangeProfile; + //If not good region, range of profile and fit are similar so save this calcultion + if (goodRegion && id.gr_size_y > 0) { + l = Arrays.asList((Double[]) Convert.toWrapperArray(Arrays.copyOfRange(gY, id.gr_pos_y, id.gr_pos_y + id.gr_size_y))); + minGauss = Collections.min(l); + rangeGauss = Collections.max(l) - minGauss; + } + + for (int i = 0; i < xp.length; i++) { + if (gY != null) { + xg[i] = (int) (((gY[i] - minGauss) / rangeGauss) * profileSize); + } + xp[i] = (int) (((pY[i] - minProfile) / rangeProfile) * profileSize); + } + + if (goodRegion && id.gr_size_y > 0) { + xg = Arrays.copyOfRange(xg, id.gr_pos_y, id.gr_pos_y + id.gr_size_y); + yg = Arrays.copyOfRange(yg, id.gr_pos_y, id.gr_pos_y + id.gr_size_y); + } + hgaussian = new Overlays.Polyline(penFit, xg, yg); + hprofile = new Overlays.Polyline(renderer.getPenProfile(), xp, yp); + } + } catch (Exception ex) { + System.err.println(ex.getMessage()); + return null; + } + } else { + ArrayProperties properties = data.getProperties(); + double maxPlot = properties.max; + double minPlot = properties.min; + double rangePlot = maxPlot - minPlot; + + if (rangePlot <= 0) { + return null; + } + if (renderer.getCalibration() != null) { + try { + double[] sum = data.integrateVertically(true); + double[] saux = new double[sum.length]; + int[] p = new int[sum.length]; + double[] x_egu = renderer.getCalibration().getAxisX(sum.length); + double[] comRms = getComRms(sum, x_egu); + xCom = comRms[0]; + xRms = comRms[1]; + int[] x = Arr.indexesInt(sum.length); + DescriptiveStatistics stats = new DescriptiveStatistics(sum); + double min = stats.getMin(); + for (int i = 0; i < sum.length; i++) { + saux[i] = sum[i] - min; + } + if (showFit) { + double[] gaussian = fitGaussian(saux, x); + if (gaussian != null) { + if ((gaussian[2] < sum.length * 0.45) + && (gaussian[2] > 2) + && (gaussian[0] > min * 0.03)) { + xNorm = gaussian[0]; + xMean = gaussian[1]; + xSigma = gaussian[2]; + double[] fit = getFitFunction(gaussian, x); + int[] y = new int[x.length]; + for (int i = 0; i < x.length; i++) { + y[i] = (int) (height - 1 - ((((fit[i] + min) / height - minPlot) / rangePlot) * profileSize)); + } + vgaussian = new Overlays.Polyline(penFit, x, y); + } + } + } + if (showProfile) { + for (int i = 0; i < x.length; i++) { + p[i] = (int) (height - 1 - (((sum[i] / height - minPlot) / rangePlot) * profileSize)); + } + vprofile = new Overlays.Polyline(renderer.getPenProfile(), x, p); + } + } catch (Exception ex) { + ex.printStackTrace(); + } + + try { + double[] sum = data.integrateHorizontally(true); + double[] saux = new double[sum.length]; + int[] p = new int[sum.length]; + double[] y_egu = renderer.getCalibration().getAxisY(sum.length); + double[] comRms = getComRms(sum, y_egu); + yCom = comRms[0]; + yRms = comRms[1]; + int[] x = Arr.indexesInt(sum.length); + DescriptiveStatistics stats = new DescriptiveStatistics(sum); + double min = stats.getMin(); + for (int i = 0; i < sum.length; i++) { + saux[i] = sum[i] - min; + } + + if (showFit) { + double[] gaussian = fitGaussian(saux, x); + if (gaussian != null) { + //Only aknowledge beam fully inside the image and peak over 3% of min + if ((gaussian[2] < sum.length * 0.45) + && (gaussian[2] > 2) + && (gaussian[0] > min * 0.03)) { + yNorm = gaussian[0]; + yMean = gaussian[1]; + ySigma = gaussian[2]; + double[] fit = getFitFunction(gaussian, x); + + int[] y = new int[x.length]; + for (int i = 0; i < x.length; i++) { + y[i] = (int) ((((fit[i] + min) / width - minPlot) / rangePlot) * profileSize); + } + hgaussian = new Overlays.Polyline(penFit, y, x); + } + } + } + if (showProfile) { + for (int i = 0; i < x.length; i++) { + p[i] = (int) (((sum[i] / width - minPlot) / rangePlot) * profileSize); + } + hprofile = new Overlays.Polyline(renderer.getPenProfile(), p, x); + } + + } catch (Exception ex) { + ex.printStackTrace(); + } + if (xSigma != null) { + xSigma *= renderer.getCalibration().getScaleX(); + } + if (ySigma != null) { + ySigma *= renderer.getCalibration().getScaleY(); + } + if (xMean != null) { + xMean = data.getX((int) Math.round(xMean)); + } + if (yMean != null) { + yMean = data.getY((int) Math.round(yMean)); + } + } + } + final String units = (renderer.getCalibration() != null) ? "\u00B5m" : "px"; + final String fmt = "%7.1f" + units; + Overlays.Text textCom = null; + Overlay[] pOv = null, fOv = null; + Font fontInfoText = new Font(Font.MONOSPACED, 0, 14); + Point textPosition = new Point(12, 20); + if (showProfile) { + if ((xCom != null) && (yCom != null)) { + String text = String.format("com x: m=" + fmt + " \u03C3=" + fmt + "\ncom y: m=" + fmt + " \u03C3=" + fmt, xCom, xRms, yCom, yRms); + textCom = new Overlays.Text(renderer.getPenProfile(), text, fontInfoText, textPosition); + textCom.setFixed(true); + textCom.setAnchor(Overlay.ANCHOR_VIEWPORT_TOP_LEFT); + } + pOv = new Overlay[]{hprofile, vprofile, textCom}; + textPosition = new Point(textPosition.x, textPosition.y + 34); + } + if (showFit) { + Overlays.Crosshairs cross = null; + Overlays.Text textFit = null; + if ((xMean != null) && (yMean != null)) { + String text = String.format("fit x: m=" + fmt + " \u03C3=" + fmt + "\nfit y: m=" + fmt + " \u03C3=" + fmt, xMean, xSigma, yMean, ySigma); + textFit = new Overlays.Text(penFit, text, fontInfoText, textPosition); + textFit.setFixed(true); + textFit.setAnchor(Overlay.ANCHOR_VIEWPORT_TOP_LEFT); + Point center = new Point(xMean.intValue(), yMean.intValue()); + if (renderer.getCalibration() != null) { + center = renderer.getCalibration().convertToImagePosition(new PointDouble(xMean, yMean)); + xSigma /= renderer.getCalibration().getScaleX(); + ySigma /= renderer.getCalibration().getScaleY(); + } + cross = new Overlays.Crosshairs(penCross, center, new Dimension(Math.abs(2 * xSigma.intValue()), 2 * Math.abs(ySigma.intValue()))); + } + textPosition = new Point(textPosition.x, textPosition.y + 34); + fOv = new Overlay[]{hgaussian, vgaussian, cross, textFit}; + + if (goodRegion && (id != null)) { + try { + double[] x = id.gr_x_axis; + double[] y = id.gr_y_axis; + Overlays.Rect goodRegionOv = new Overlays.Rect(new Pen(penFit.getColor(), 0, Pen.LineStyle.dotted)); + goodRegionOv.setCalibration(renderer.getCalibration()); + goodRegionOv.setPosition(new Point(id.gr_pos_x, id.gr_pos_y)); + goodRegionOv.setSize(new Dimension(id.gr_x_axis.length, id.gr_y_axis.length)); + fOv = Arr.append(fOv, goodRegionOv); + + if (slicing) { + if (sliceCenters != null) { + for (PointDouble sliceCenter : sliceCenters) { + Overlays.Crosshairs center = new Overlays.Crosshairs(penSlices); + center.setCalibration(renderer.getCalibration()); + center.setAbsolutePosition(sliceCenter); + center.setSize(new Dimension(10, 10)); + fOv = Arr.append(fOv, center); + } + if (sliceCenters.length > 1) { + double[] fit = fitPolynomial(sliceCenters, 1); + double angle = Math.toDegrees(Math.atan(fit[1])); + Overlays.Text text = new Overlays.Text(penSlices, String.format("slice: \u03B8= %5.1fdeg", angle), fontInfoText, textPosition); + text.setFixed(true); + text.setAnchor(Overlay.ANCHOR_VIEWPORT_TOP_LEFT); + fOv = Arr.append(fOv, text); + } + } + } + } catch (Exception ex) { + } + } + + } + return new Overlay[][]{pOv, fOv}; + } + return null; + } + + class UserOverlay { + + String name; + Overlay obj; + String[] channels; + } + ArrayList userOverlayConfig; + + void parseUserOverlays() { + Properties userOverlays = new Properties(); + userOverlayConfig = new ArrayList<>(); + if (userOverlaysConfigFile != null) { + try { + try (FileInputStream in = new FileInputStream(getContext().getSetup().expandPath(userOverlaysConfigFile))) { + userOverlays.load(in); + + for (String name : userOverlays.stringPropertyNames()) { + String val = userOverlays.getProperty(name); + try { + UserOverlay uo = new UserOverlay(); + uo.name = name; + String type = val.substring(0, val.indexOf("(")).trim(); + String pars = val.substring(val.indexOf("(") + 1, val.lastIndexOf(")")).trim(); + String[] tokens = pars.split(","); + for (int i = 0; i < tokens.length; i++) { + tokens[i] = tokens[i].trim(); + } + Color color = Color.GRAY; + try { + color = (Color) Color.class.getField(tokens[tokens.length - 1].toUpperCase()).get(null); + } catch (Exception ex) { + } + Pen pen = new Pen(color); + try { + String[] penTokens = tokens[tokens.length - 1].split(":"); + color = (Color) Color.class.getField(penTokens[0].toUpperCase()).get(null); + int width = Integer.valueOf(penTokens[1]); + Pen.LineStyle style = Pen.LineStyle.valueOf(penTokens[2]); + pen = new Pen(color, width, style); + } catch (Exception ex) { + } + switch (type) { + case "Point": + uo.obj = new Overlays.Crosshairs(); + uo.obj.setSize(new Dimension(Integer.valueOf(tokens[2]), Integer.valueOf(tokens[3]))); + break; + case "Line": + uo.obj = new Overlays.Line(); + break; + case "Arrow": + uo.obj = new Overlays.Arrow(); + break; + case "Rect": + uo.obj = new Overlays.Rect(); + break; + case "Ellipse": + uo.obj = new Overlays.Ellipse(); + break; + case "Polyline": + uo.obj = new Overlays.Polyline(); + break; + } + if (type.equals("Polyline") || type.equals("Point")) { + uo.channels = new String[]{tokens[0], tokens[1]}; + } else { + uo.channels = new String[]{tokens[0], tokens[1], tokens[2], tokens[3]}; + } + uo.obj.setPen(pen); + userOverlayConfig.add(uo); + } catch (Exception ex) { + ex.printStackTrace(); + } + } + } + } catch (Exception ex) { + ex.printStackTrace(); + } + } + } + + Overlay[] getUserOverlays(Data data) { + ArrayList ret = new ArrayList<>(); + if (server != null) { + ImageData id = getFrame(data); + for (UserOverlay uo : userOverlayConfig) { + try { + Overlay ov = uo.obj; + //Overlay ov = (Overlay)uo.cls.newInstance(); + ov.setCalibration(renderer.getCalibration()); + boolean valid = false; + if (ov instanceof Overlays.Polyline) { + double[] x = (uo.channels[0].equals("null")) ? null : id.getDoubleArray(uo.channels[0]); + double[] y = (uo.channels[1].equals("null")) ? null : id.getDoubleArray(uo.channels[1]); + if ((x != null) || (y != null)) { + if (x == null) { + x = (renderer.getCalibration() == null) ? Arr.indexesDouble(y.length) : renderer.getCalibration().getAxisX(y.length); + } + if (y == null) { + y = (renderer.getCalibration() == null) ? Arr.indexesDouble(x.length) : renderer.getCalibration().getAxisY(x.length); + } + ((Overlays.Polyline) ov).updateAbsolute(x, y); + valid = true; + } + } else { + Double x = id.getDouble(uo.channels[0]); + Double y = id.getDouble(uo.channels[1]); + if ((x != null) && (y != null)) { + PointDouble position = new PointDouble(x, y); + ov.setAbsolutePosition(position); + if (!(ov instanceof Overlays.Crosshairs)) { + Double x2 = id.getDouble(uo.channels[2]); + Double y2 = id.getDouble(uo.channels[3]); + if ((x != null) && (y != null)) { + DimensionDouble size = new DimensionDouble(x2 - position.x, y2 - position.y); + ov.setAbsoluteSize(size); + valid = true; + } + } else { + valid = true; + } + } + } + if (valid) { + ret.add(ov); + } + } catch (Exception ex) { + //ex.printStackTrace(); + } + } + } + return ret.toArray(new Overlay[0]); + } + + double[] getComRms(double[] arr, double[] x) { + if (arr != null) { + double xmd = 0; + double xmd2 = 0; + double total = 0; + for (int i = 0; i < arr.length; i++) { + double v = (arr[i] * x[i]); + xmd += v; + xmd2 += (v * x[i]); + total += arr[i]; + } + if (total > 0) { + double com = xmd / total; + double com2 = xmd2 / total; + double rms = Math.sqrt(Math.abs(com2 - com * com)); + return new double[]{com, rms}; + } + } + return new double[]{Double.NaN, Double.NaN}; + } + + double[] fitGaussianScript(int[] y, int[] x) { + ScriptManager sm = Context.getInstance().getScriptManager(); + ArrayProperties pY = ArrayProperties.get(y); + sm.setVar("y", y); + sm.setVar("x", x); + InterpreterResult r = sm.eval("r = fit_gaussians(y, x, [" + pY.maxIndex + ",])"); + if (r.exception != null) { + r.exception.printStackTrace(); + } else { + List ret = (List) sm.getVar("r"); + if ((ret != null) && (ret.size() == 1) && (ret.get(0) instanceof List) && (((List) (ret.get(0))).size() == 3)) { + double norm = (Double) ((List) ret.get(0)).get(0); + double mean = (Double) ((List) ret.get(0)).get(1); + double sigma = (Double) ((List) ret.get(0)).get(2); + return new double[]{norm, mean, sigma}; + } + } + return null; + } + + double[] fitGaussian(double[] y, int[] x) { + try { + ArrayProperties pY = ArrayProperties.get(y); + GaussianCurveFitter fitter = GaussianCurveFitter.create().withStartPoint(new double[]{(pY.max - pY.min) / 2, x[pY.maxIndex], 1.0}).withMaxIterations(1000); + ArrayList values = new ArrayList<>(); + for (int i = 0; i < y.length; i++) { + values.add(new WeightedObservedPoint(1.0, x[i], y[i])); + } + return fitter.fit(values); + } catch (Exception ex) { + return null; + } + + } + + double[] fitPolynomial(PointDouble[] points, int order) { + double[] y = new double[points.length]; + double[] x = new double[points.length]; + for (int i = 0; i < points.length; i++) { + x[i] = points[i].x; + y[i] = points[i].y; + } + return fitPolynomial(y, x, order); + } + + double[] fitPolynomial(double[] y, double[] x, int order) { + try { + ArrayProperties pY = ArrayProperties.get(y); + PolynomialCurveFitter fitter = PolynomialCurveFitter.create(order).withMaxIterations(1000); + ArrayList values = new ArrayList<>(); + for (int i = 0; i < y.length; i++) { + values.add(new WeightedObservedPoint(1.0, x[i], y[i])); + } + return fitter.fit(values); + } catch (Exception ex) { + return null; + } + + } + + double[] getFitFunction(double[] pars, int[] x) { + double[] fit = new double[x.length]; + Gaussian g = new Gaussian(pars[0], pars[1], pars[2]); + for (int i = 0; i < x.length; i++) { + fit[i] = g.value(x[i]); + } + return fit; + } + + void setHistogramVisible(boolean value) { + if (value) { + if ((histogramDialog == null) || (!histogramDialog.isShowing())) { + Histogram histogram = new Histogram(true); + histogram.setRenderer(renderer); + histogramDialog = SwingUtils.showDialog(SwingUtils.getWindow(renderer), "Histogram", null, histogram); + renderer.refresh(); + } + } else { + if (histogramDialog != null) { + histogramDialog.setVisible(false); + histogramDialog = null; + } + } + } + + void setLaserState(int bunch, boolean value) throws Exception { + System.out.println("Setting laser state: " + value + " - bunch" + bunch); + //Epics.putq("SIN-TIMAST-TMA:Beam-Las-Delay-Sel", value ? 0 : 1); + if ((bunch<=0) || (bunch==1)){ + Epics.putq("SIN-TIMAST-TMA:Bunch-1-OnDelay-Sel", value ? 0 : 1); + } + if ((bunch<=0) || (bunch==2)){ + Epics.putq("SIN-TIMAST-TMA:Bunch-2-OnDelay-Sel", value ? 0 : 1); + } + + Epics.putq("SIN-TIMAST-TMA:Beam-Apply-Cmd.PROC", 1); + Thread.sleep(3000); + } + + boolean getLaserState(int bunch) throws Exception { + //return (Epics.get("SIN-TIMAST-TMA:Beam-Las-Delay-Sel", Integer.class) == 0); + try{ + if (bunch<=0){ + return getLaserState(1) && getLaserState(2); + } + if (bunch==2){ + return (Epics.get("SWISSFEL-STATUS:Bunch-2-OnDelay-Sel", Integer.class) == 0); + } + return (Epics.get("SWISSFEL-STATUS:Bunch-1-OnDelay-Sel", Integer.class) == 0); + } catch (Exception ex){ + return false; + } + } + + void elog(String logbook, String title, String message, String[] attachments) throws Exception { + String domain = ""; + String category = "Info"; + String entry = ""; + StringBuffer cmd = new StringBuffer(); + + cmd.append("G_CS_ELOG_add -l \"").append(logbook).append("\" "); + cmd.append("-a \"Author=ScreenPanel\" "); + cmd.append("-a \"Type=pshell\" "); + cmd.append("-a \"Entry=").append(entry).append("\" "); + cmd.append("-a \"Title=").append(title).append("\" "); + cmd.append("-a \"Category=").append(category).append("\" "); + cmd.append("-a \"Domain=").append(domain).append("\" "); + for (String attachment : attachments) { + cmd.append("-f \"").append(attachment).append("\" "); + } + cmd.append("-n 1 "); + cmd.append("\"").append(message).append("\" "); + System.out.println(cmd.toString()); + + final Process process = Runtime.getRuntime().exec(new String[]{"bash", "-c", cmd.toString()}); + new Thread(() -> { + try { + process.waitFor(); + int bytes = process.getInputStream().available(); + byte[] arr = new byte[bytes]; + process.getInputStream().read(arr, 0, bytes); + System.out.println(new String(arr)); + bytes = process.getErrorStream().available(); + arr = new byte[bytes]; + process.getErrorStream().read(arr, 0, bytes); + System.err.println(new String(arr)); + } catch (Exception ex) { + System.err.println(ex); + } + }).start(); + } + + void centralizeRenderer() { + Point center = null; + Dimension size = renderer.getImageSize(); + double zoom = (renderer.getMode() == RendererMode.Fixed) ? 1.0 : renderer.getZoom(); + if (renderer.getCalibration() != null) { + center = renderer.getCalibration().getCenter(); + } else if (size != null) { + center = new Point(size.width / 2, size.height / 2); + } + if (center != null) { + Point topleft = new Point(Math.max((int) (center.x - renderer.getWidth() / 2 / zoom), 0), + Math.max((int) (center.y - renderer.getHeight() / 2 / zoom), 0)); + renderer.setViewPosition(topleft); + } + } + + void updatePause() { + int index = ((int) pauseSelection.getValue()) - 1; + synchronized (imageBuffer) { + if (index < imageBuffer.size()) { + Data data = imageBuffer.get(index).data; + long pid = imageBuffer.get(index).cache.getPulseId(); + BufferedImage image = camera.generateImage(data); + renderer.setImage(renderer.getOrigin(), image, data); + + String text = "PID: " + pid; + if (imagePauseOverlay == null) { + Font font = new Font("Verdana", Font.PLAIN, 12); + Dimension d = SwingUtils.getTextSize(text, renderer.getFontMetrics(font)); + imagePauseOverlay = new Text(renderer.getPenErrorText(), "", font, new Point(-20 - d.width, 42)); + imagePauseOverlay.setFixed(true); + imagePauseOverlay.setAnchor(Overlay.ANCHOR_VIEWPORT_OR_IMAGE_TOP_RIGHT); + renderer.addOverlay(imagePauseOverlay); + } + imagePauseOverlay.update(text); + manageFit(image, data); + manageUserOverlays(image, data); + } + } + updateStreamData(); + } + + void removePauseOverlay() { + renderer.removeOverlay(imagePauseOverlay); + imagePauseOverlay = null; + } + + void saveSnapshot() throws Exception { + boolean paused = isPaused(); + try{ + if (!paused){ + setPaused(true); + } + String snapshotFile = null; + synchronized (imageBuffer) { + Frame frame = getCurrentFrame(); + if (frame == null) { + throw new Exception("No current image"); + } + ArrayList frames = new ArrayList<>(); + frames.add(frame); + this.saveFrames(cameraAlias + "_camera_snapshot", frames); + + //Enforce the same timestamp to data & image files. + snapshotFile = getContext().getExecutionPars().getPath() + ".png"; + //renderer.saveSnapshot(snapshotFile, "png", true); + ImageBuffer.saveImage(SwingUtils.createImage(renderer), snapshotFile, "png"); + } + + JPanel panel = new JPanel(); + GridBagLayout layout = new GridBagLayout(); + layout.columnWidths = new int[]{0, 180}; //Minimum width + layout.rowHeights = new int[]{30, 30, 30}; //Minimum height + panel.setLayout(layout); + JComboBox comboLogbook = new JComboBox(new String[]{"SwissFEL commissioning data", "SwissFEL commissioning"}); + JTextField textComment = new JTextField(); + GridBagConstraints c = new GridBagConstraints(); + c.gridx = 0; + c.gridy = 0; + panel.add(new JLabel("Data file:"), c); + c.gridy = 1; + panel.add(new JLabel("Logbook:"), c); + c.gridy = 2; + panel.add(new JLabel("Comment:"), c); + c.fill = GridBagConstraints.HORIZONTAL; + c.gridx = 1; + panel.add(textComment, c); + c.gridy = 1; + panel.add(comboLogbook, c); + c.gridy = 0; + panel.add(new JLabel(getContext().getExecutionPars().getPath()), c); + + if (SwingUtils.showOption(getTopLevel(), "Success", panel, OptionType.OkCancel) == OptionResult.Yes) { + StringBuilder message = new StringBuilder(); + message.append("Camera: ").append(cameraAlias).append(" ("). + append((server != null) ? "server" : "direct").append(")").append("\n"); + message.append("Screen: ").append(String.valueOf(valueScreen.getLabel().getText())).append("\n"); + message.append("Filter: ").append(String.valueOf(valueFilter.getLabel().getText())).append("\n"); + message.append("Data file: ").append(getContext().getExecutionPars().getPath()).append("\n"); + message.append("Comment: ").append(textComment.getText()).append("\n"); + //Add slicing message + if ((fitOv != null) && (fitOv.length > 5) && (fitOv[fitOv.length - 1] instanceof Overlays.Text)) { + Overlays.Text text = (Overlays.Text) fitOv[fitOv.length - 1]; + message.append(text.getText()).append("\n"); + } + elog((String) comboLogbook.getSelectedItem(), "ScreenPanel Snapshot", message.toString(), new String[]{snapshotFile}); + } + } finally{ + if (!paused){ + setPaused(false); + } + } + } + + void saveStack() throws Exception { + synchronized (imageBuffer) { + saveFrames(cameraAlias + "_camera_stack", imageBuffer); + } + SwingUtils.showMessage(getTopLevel(), "Success", "Generated data file:\n" + getContext().getExecutionPars().getPath()); + } + + public List getCameraTypes(String name) { + if (name == null) { + return null; + } + if (App.hasArgument(ARG_ALIAS) && (aliases!=null)){ + name = aliases.getOrDefault(name, name); + } + + List ret = new ArrayList(); + if (groups!=null){ + for (String group: Arr.sort(groups.keySet().toArray(new String[0]))){ + if (groups.get(group).contains(name)){ + ret.add(group); + } + } + } else { + for (String s : new String[]{"LCAM"}) { + if (name.contains(s)) { + ret.add(LASER_TYPE); + } + } + for (String s : new String[]{"DSCR", "DSRM", "DLAC"}) { + if (name.contains(s)) { + ret.add(ELECTRONS_TYPE); + } + } + for (String s : new String[]{"PROF", "PPRM", "PSSS", "PSCR", "PSRD"}) { + if (name.contains(s)) { + ret.add(PHOTONICS_TYPE); + } + } + } + ret.add("Unknown"); + return ret; + } + + public Map getProcessingParameters(StreamValue value) throws IOException { + return (Map) JsonSerializer.decode(value.getValue("processing_parameters").toString(), Map.class); + } + + void saveFrames(String name, ArrayList frames) throws IOException { + ArrayList values = new ArrayList<>(); + for (Frame frame : frames) { + values.add(frame.cache); + } + saveImages(name, values); + } + + class DifferentFormatException extends IOException{ + DifferentFormatException(){ + super("Images in stack have different formats"); + } + } + + boolean hasSameFormat(ArrayList frames){ + if (frames.size()>0){ + StreamValue first = frames.get(0).cache; + int width = ((Number) first.getValue("width")).intValue(); + int height = ((Number) first.getValue("height")).intValue(); + Class dataType = first.getValue("image").getClass().getComponentType(); + + for (Frame frame : frames){ + StreamValue image = frame.cache; + if ( (width != ((Number) image.getValue("width")).intValue()) || + (height != ((Number) image.getValue("height")).intValue()) || + (dataType != (image.getValue("image").getClass().getComponentType()))){ + return false; + } + } + } + return true; + } + + void saveImages(String name, ArrayList images) throws IOException { + int depth = images.size(); + if (depth == 0) { + return; + } + + StreamValue first = images.get(0); + String pathRoot = "/camera1/"; + String pathImage = pathRoot + "image"; + String pathPid = pathRoot + "pulse_id"; + String pathTimestampStr = pathRoot + "timestamp_str"; + Map processingPars = getProcessingParameters(first); + String camera = (String) processingPars.get("camera_name"); + List types = getCameraTypes(camera); + + int width = ((Number) first.getValue("width")).intValue(); + int height = ((Number) first.getValue("height")).intValue(); + Class dataType = first.getValue("image").getClass().getComponentType(); + + for (StreamValue image : images){ + if ( (width != ((Number) image.getValue("width")).intValue()) || + (height != ((Number) image.getValue("height")).intValue()) || + (dataType != (image.getValue("image").getClass().getComponentType()))){ + throw new DifferentFormatException(); + } + } + + + getContext().setExecutionPars(name); + DataManager dm = getContext().getDataManager(); + + //Create tables + dm.createDataset(pathImage, dataType, new int[]{depth, height, width}); + dm.createDataset(pathPid, Long.class, new int[]{depth}); + dm.createDataset(pathTimestampStr, String.class, new int[]{depth}); + for (String id : first.getIdentifiers()) { + Object val = first.getValue(id); + if (id.equals("image")) { + } else if (id.equals("processing_parameters")) { + Map pars = getProcessingParameters(first); + for (String key : pars.keySet()) { + if ((pars.get(key) != null) && (pars.get(key) instanceof Map)) { + for (String k : ((Map) pars.get(key)).keySet()) { + Object v = ((Map) pars.get(key)).get(k); + k = key + " " + k; + v = (v == null) ? "" : v; + try{ + dm.setAttribute(pathImage, k, v); + } catch (Exception ex){ + logger.info("Cannot set attribute " + pathImage + ": "+ k + " = " + v + " - " + ex.getMessage()); + } + + } + } else { + Object value = pars.get(key); + try{ + if (value == null) { + value = ""; + } else if (value instanceof List) { + if (((List) value).size() > 0){ + Class cls = ((List) value).get(0).getClass() ; + if (cls == String.class){ + value = ((List) value).toArray(new String[0]); + } else { + value = Convert.toPrimitiveArray(value, cls); + } + } else { + value = ""; + } + } + dm.setAttribute(pathImage, key, value); + } catch (Exception ex){ + logger.info("Cannot set attribute " + pathImage + ": "+ key + " = " + value + " - " + ex.getMessage()); + } + } + } + } else if (val.getClass().isArray()) { + dm.createDataset(pathRoot + id, Double.class, new int[]{depth, Array.getLength(val)}); + } else { + dm.createDataset(pathRoot + id, val.getClass(), new int[]{depth}); + } + } + + //Add metadata + dm.setAttribute(pathRoot, "Camera", camera); + dm.setAttribute(pathRoot, "Images", depth); + dm.setAttribute(pathRoot, "Interval", -1); + dm.setAttribute(pathRoot, "Type", types.toArray(new String[0])); + if (types.contains(ELECTRONS_TYPE)) { + dm.setAttribute(pathRoot, "Screen", String.valueOf(valueScreen.getLabel().getText())); + dm.setAttribute(pathRoot, "Filter", String.valueOf(valueFilter.getLabel().getText())); + } + + //Save data + for (int index = 0; index < depth; index++) { + StreamValue streamValue = images.get(index); + dm.setItem(pathImage, streamValue.getValue("image"), new long[]{index, 0, 0}, new int[]{1, height, width}); + dm.setItem(pathPid, streamValue.getPulseId(), index); + dm.setItem(pathTimestampStr, Chrono.getTimeStr(streamValue.getTimestamp(), "YYYY-MM-dd HH:mm:ss.SSS"), index); + + for (String id : streamValue.getIdentifiers()) { + try{ + Object val = streamValue.getValue(id); + if (id.equals("image")) { + } else if (id.equals("processing_parameters")) { + } else if (val.getClass().isArray()) { + dm.setItem(pathRoot + id, val, index); + } else { + dm.setItem(pathRoot + id, val, index); + } + } catch (Exception ex){ + logger.log(Level.WARNING, null, ex); + System.out.println("Error saving " + id + " index " + index + ": " + ex.getMessage()); + } + } + } + getContext().getDataManager().closeOutput(); + } + + StandardDialog calibrationDialolg; + + void calibrate() throws Exception { + if (server != null) { + server.resetRoi(); + calibrationDialolg = (StandardDialog) getContext().getClassByName("CameraCalibrationDialog").getConstructors()[0].newInstance(new Object[]{getTopLevel(), server.getCurrentCamera(), renderer}); + SwingUtils.centerComponent(getTopLevel(), calibrationDialolg); + calibrationDialolg.setVisible(true); + calibrationDialolg.setListener(new StandardDialogListener() { + @Override + public void onWindowOpened(StandardDialog dlg) { + } + + @Override + public void onWindowClosed(StandardDialog dlg, boolean accepted) { + if (accepted) { + //comboCamerasActionPerformed(null); + } + } + }); + } + } + + StandardDialog dataTableDialog; + DefaultTableModel dataTableModel; + JTable dataTable; + + void showStreamData() { + dataTableModel = null; + if (server != null) { + + if ((dataTableDialog != null) && (dataTableDialog.isShowing())) { + SwingUtils.centerComponent(getTopLevel(), dataTableDialog); + dataTableDialog.requestFocus(); + return; + } + dataTableModel = new DefaultTableModel(new Object[0][2], new String[]{"Name", "Value"}) { + public Class getColumnClass(int columnIndex) { + return String.class; + } + + public boolean isCellEditable(int rowIndex, int columnIndex) { + return false; + } + }; + updateStreamData(); + StreamValue val = server.getStream().take(); + dataTable = new JTable(dataTableModel); + dataTable.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION); + dataTable.setCellSelectionEnabled(true); + dataTable.getTableHeader().setReorderingAllowed(false); + dataTable.getTableHeader().setResizingAllowed(true); + dataTableDialog = new StandardDialog(getTopLevel(), "Image Data", false); + dataTableDialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); + JScrollPane scrollPane = new JScrollPane(); + scrollPane.setViewportView(dataTable); + scrollPane.setPreferredSize(new Dimension(300, 400)); + dataTableDialog.setContentPane(scrollPane); + dataTableDialog.pack(); + dataTableDialog.setVisible(true); + dataTableDialog.addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + dataTableModel = null; + } + }); + dataTable.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + try { + int row = dataTable.getSelectedRow(); + int col = dataTable.getSelectedColumn(); + dataTable.setToolTipText(null); + if (row > 1) { + String id = String.valueOf(dataTable.getModel().getValueAt(row, 0)); + String locator = String.valueOf(dataTable.getModel().getValueAt(0, 1)); + String channelId = locator + " " + id; + dataTable.setToolTipText(channelId); + if ((e.getClickCount() == 2) && (!e.isPopupTrigger())) { + if (col == 0) { + SwingUtils.showMessage(dataTableDialog, "Channel Identifier", "Copied to clipboard: " + channelId); + Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); + clipboard.setContents(new StringSelection(channelId), (Clipboard clipboard1, Transferable contents) -> { + }); + } else { + Object obj = getCurrentFrame().cache.getValue(id); + if (id.equals("image")) { + } else if (id.equals("processing_parameters")) { + Map pars = getProcessingParameters(getCurrentFrame().cache); + StringBuilder sb = new StringBuilder(); + for (String key : pars.keySet()) { + sb.append(key).append(" = ").append(Str.toString(pars.get(key), 10)).append("\n"); + } + SwingUtils.showMessage(dataTableDialog, "Processing Parameters", sb.toString()); + } else if ((obj != null) && (obj.getClass().isArray() || (obj instanceof Number))) { + DeviceValueChart chart = new DeviceValueChart(); + Device dev = null; + if (obj.getClass().isArray()) { + dev = new ReadableRegisterArray(new ReadableArray() { + @Override + public Object read() throws IOException, InterruptedException { + return Convert.toDouble(getCurrentFrame().cache.getValue(id)); + } + + @Override + public int getSize() { + return Array.getLength(getCurrentFrame().cache.getValue(id)); + } + }); + } else { + dev = new ReadableRegisterNumber(new ReadableNumber() { + @Override + public Object read() throws IOException, InterruptedException { + return Convert.toDouble(getCurrentFrame().cache.getValue(id)); + } + }); + } + dev.setPolling(1000); + chart.setDevice(dev); + JDialog dlg = SwingUtils.showDialog(dataTableDialog, cameraAlias + " " + id, null, chart); + //TODO: + //PlotBase plot = chart.getPlot(); + //if (plot!=null){ + // plot.setPlotBackgroundColor(Color.BLACK); + //} + } + } + } + } + } catch (Exception ex) { + showException(ex); + } + } + }); + SwingUtils.centerComponent(getTopLevel(), dataTableDialog); + updateStreamData(); + } + } + + volatile boolean updatingStreamData = false; + + void updateStreamData() { + if ((dataTableDialog == null) || !dataTableDialog.isShowing() || updatingStreamData) { + return; + } + updatingStreamData = true; + SwingUtilities.invokeLater(() -> { + updatingStreamData = false; + if ((dataTableModel != null) && (server != null)) { + StreamValue value = server.getValue(); + Frame frame = getCurrentFrame(); + int[] sel_rows = (dataTable == null) ? null : dataTable.getSelectedRows(); + int[] sel_cols = (dataTable == null) ? null : dataTable.getSelectedColumns(); + List ids = (value == null) ? new ArrayList<>() : new ArrayList(value.getIdentifiers()); + if (ids.size() + 4 != dataTableModel.getRowCount()) { + dataTableModel.setNumRows(0); + try { + if (isUrl){ + dataTableModel.addRow(new Object[]{"Locator", ""}); + } else { + dataTableModel.addRow(new Object[]{"Locator", server.getUrl() + "/" + ((value == null) ? instanceName : server.getCurrentInstance())}); + } + } catch (Exception ex) { + dataTableModel.addRow(new Object[]{"Locator", ex.getMessage()}); + } + try { + if (isUrl){ + dataTableModel.addRow(new Object[]{"Stream", cameraName}); + } else { + dataTableModel.addRow(new Object[]{"Stream", server.getStreamAddress()}); + } + } catch (Exception ex) { + dataTableModel.addRow(new Object[]{"Stream", ex.getMessage()}); + } + dataTableModel.addRow(new Object[]{"PID", ""}); + dataTableModel.addRow(new Object[]{"Timestamp", ""}); + Collections.sort(ids); + for (String id : ids) { + dataTableModel.addRow(new Object[]{id, ""}); + } + } + + if ((frame != null) && (frame.cache != null)) { + dataTableModel.setValueAt(frame.cache.getPulseId(), 2, 1); //PID + dataTableModel.setValueAt(frame.cache.getTimestamp(), 3, 1); //Timestamp + for (int i = 4; i < dataTableModel.getRowCount(); i++) { + String id = String.valueOf(dataTableModel.getValueAt(i, 0)); + //Object obj = server.getValue(id); + Object obj = frame.cache.getValue(id); + if (obj != null) { + if (obj.getClass().isArray()) { + obj = obj.getClass().getComponentType().getSimpleName() + "[" + Array.getLength(obj) + "]"; + } else if (obj instanceof Double) { + obj = Convert.roundDouble((Double) obj, 1); + } else if (obj instanceof Float) { + obj = Convert.roundDouble((Float) obj, 1); + } + } + dataTableModel.setValueAt(String.valueOf(obj), i, 1); + } + } + if ((sel_rows != null) && (sel_rows.length > 0)) { + //dataTable.setRowSelectionInterval((Integer)Arr.getMin(sel_rows), (Integer)Arr.getMax(sel_rows)); + dataTable.setRowSelectionInterval(sel_rows[0], sel_rows[sel_rows.length - 1]); + } + if ((sel_cols != null) && (sel_cols.length > 0)) { + //dataTable.setColumnSelectionInterval((Integer)Arr.getMin(sel_cols), (Integer)Arr.getMax(sel_cols)); + dataTable.setColumnSelectionInterval(sel_cols[0], sel_cols[sel_cols.length - 1]); + } + } + }); + } + + ImageIcon getIcon(String name) { + ImageIcon ret = null; + try { + //Path path = Paths.get(getClass().getProtectionDomain().getCodeSource().getLocation().getPath(),"resources", name + ".png"); + String dir = getClass().getProtectionDomain().getCodeSource().getLocation().getPath() + "resources/"; + if (new File(dir + name + ".png").exists()) { + ret = new javax.swing.ImageIcon(dir + name + ".png"); + } else { + ret = new ImageIcon(ch.psi.pshell.ui.App.class.getResource("/ch/psi/pshell/ui/" + name + ".png")); + if (MainFrame.isDark()) { + try { + ret = new ImageIcon(ch.psi.pshell.ui.App.class.getResource("/ch/psi/pshell/ui/dark/" + name + ".png")); + } catch (Exception e) { + } + } + } + } catch (Exception ex) { + ex.printStackTrace(); + } + return ret; + } + + String getIconName(JButton button) { + String ret = button.getIcon().toString(); + if (ret.indexOf(".") > 0) { + ret = ret.substring(0, ret.indexOf(".")); + } + return ret; + } + + void setPaused(boolean paused){ + removePauseOverlay(); + if (camera != null) { + synchronized (imageBuffer) { + if (paused) { + renderer.pause(); + panelCameraSelection.setVisible(false); + pauseSelection.setVisible(true); + if (imageBuffer.size() > 0) { + pauseSelection.setEnabled(true); + pauseSelection.setMaxValue(imageBuffer.size()); + pauseSelection.setValue(imageBuffer.size()); + updatePause(); + } else { + pauseSelection.setEnabled(false); + pauseSelection.setMaxValue(1); + pauseSelection.setValue(1); + } + } else { + imageBuffer.clear(); + renderer.resume(); + //renderer.clear(); + pauseSelection.setVisible(false); + panelCameraSelection.setVisible(true); + } + } + updateStreamData(); + } + } + + boolean isPaused(){ + return renderer.isPaused(); + } + + //////// + @SuppressWarnings("unchecked") + // //GEN-BEGIN:initComponents + private void initComponents() { + + buttonGroup1 = new javax.swing.ButtonGroup(); + buttonGroup2 = new javax.swing.ButtonGroup(); + buttonGroup3 = new javax.swing.ButtonGroup(); + buttonGroup4 = new javax.swing.ButtonGroup(); + jProgressBar1 = new javax.swing.JProgressBar(); + sidePanel = new javax.swing.JPanel(); + panelZoom = new javax.swing.JPanel(); + buttonZoomFit = new javax.swing.JRadioButton(); + buttonZoomStretch = new javax.swing.JRadioButton(); + buttonZoomNormal = new javax.swing.JRadioButton(); + buttonZoom025 = new javax.swing.JRadioButton(); + buttonZoom05 = new javax.swing.JRadioButton(); + buttonZoom2 = new javax.swing.JRadioButton(); + panelColormap = new javax.swing.JPanel(); + checkHistogram = new javax.swing.JCheckBox(); + comboColormap = new javax.swing.JComboBox(); + jLabel3 = new javax.swing.JLabel(); + jLabel4 = new javax.swing.JLabel(); + buttonFullRange = new javax.swing.JRadioButton(); + buttonManual = new javax.swing.JRadioButton(); + buttonAutomatic = new javax.swing.JRadioButton(); + labelMin = new javax.swing.JLabel(); + spinnerMin = new javax.swing.JSpinner(); + spinnerMax = new javax.swing.JSpinner(); + labelMax = new javax.swing.JLabel(); + btFixColormapRange = new javax.swing.JButton(); + panelScreen = new javax.swing.JPanel(); + valueScreen = new ch.psi.pshell.swing.DeviceValuePanel(); + comboScreen = new javax.swing.JComboBox(); + panelFilter = new javax.swing.JPanel(); + valueFilter = new ch.psi.pshell.swing.DeviceValuePanel(); + comboFilter = new javax.swing.JComboBox(); + panelPipeline = new javax.swing.JPanel(); + checkThreshold = new javax.swing.JCheckBox(); + spinnerThreshold = new javax.swing.JSpinner(); + checkBackground = new javax.swing.JCheckBox(); + checkGoodRegion = new javax.swing.JCheckBox(); + spinnerGrScale = new javax.swing.JSpinner(); + spinnerGrThreshold = new javax.swing.JSpinner(); + labelGrThreshold = new javax.swing.JLabel(); + labelGrScale = new javax.swing.JLabel(); + panelSlicing = new javax.swing.JPanel(); + checkSlicing = new javax.swing.JCheckBox(); + labelSlScale = new javax.swing.JLabel(); + spinnerSlScale = new javax.swing.JSpinner(); + labelSlNumber = new javax.swing.JLabel(); + spinnerSlNumber = new javax.swing.JSpinner(); + labelSlOrientation = new javax.swing.JLabel(); + spinnerSlOrientation = new javax.swing.JSpinner(); + checkRotation = new javax.swing.JCheckBox(); + spinnerRotationAngle = new javax.swing.JSpinner(); + spinnerRotationOrder = new javax.swing.JSpinner(); + labelOrder = new javax.swing.JLabel(); + labelMode = new javax.swing.JLabel(); + spinnerRotationMode = new javax.swing.JSpinner(); + labelAngle = new javax.swing.JLabel(); + labelConstant = new javax.swing.JLabel(); + spinnerRotationConstant = new javax.swing.JSpinner(); + checkAveraging = new javax.swing.JCheckBox(); + spinnerAvFrames = new javax.swing.JSpinner(); + labelAvFrames = new javax.swing.JLabel(); + labelAvMode = new javax.swing.JLabel(); + spinnerAvMode = new javax.swing.JSpinner(); + spinnerBackground = new javax.swing.JSpinner(); + panelPulse = new javax.swing.JPanel(); + buttonPulse1 = new javax.swing.JButton(); + buttonPulse2 = new javax.swing.JButton(); + textPulse = new javax.swing.JTextField(); + topPanel = new javax.swing.JPanel(); + toolBar = new javax.swing.JToolBar(); + buttonSidePanel = new javax.swing.JToggleButton(); + buttonStreamData = new javax.swing.JButton(); + buttonSave = new javax.swing.JToggleButton(); + buttonGrabBackground = new javax.swing.JButton(); + buttonPause = new javax.swing.JToggleButton(); + jSeparator6 = new javax.swing.JToolBar.Separator(); + buttonMarker = new javax.swing.JToggleButton(); + buttonProfile = new javax.swing.JToggleButton(); + buttonFit = new javax.swing.JToggleButton(); + buttonReticle = new javax.swing.JToggleButton(); + buttonScale = new javax.swing.JToggleButton(); + buttonTitle = new javax.swing.JToggleButton(); + pauseSelection = new ch.psi.pshell.swing.ValueSelection(); + panelCameraSelection = new javax.swing.JPanel(); + jLabel1 = new javax.swing.JLabel(); + comboCameras = new javax.swing.JComboBox(); + labelType = new javax.swing.JLabel(); + comboType = new javax.swing.JComboBox(); + renderer = new ch.psi.pshell.imaging.Renderer(); + + setPreferredSize(new java.awt.Dimension(873, 600)); + + panelZoom.setBorder(javax.swing.BorderFactory.createTitledBorder("Zoom")); + + buttonGroup1.add(buttonZoomFit); + buttonZoomFit.setText("Fit"); + buttonZoomFit.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + buttonZoomFitActionPerformed(evt); + } + }); + + buttonGroup1.add(buttonZoomStretch); + buttonZoomStretch.setText("Stretch"); + buttonZoomStretch.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + buttonZoomStretchActionPerformed(evt); + } + }); + + buttonGroup1.add(buttonZoomNormal); + buttonZoomNormal.setText("Normal"); + buttonZoomNormal.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + buttonZoomNormalActionPerformed(evt); + } + }); + + buttonGroup1.add(buttonZoom025); + buttonZoom025.setText("1/4"); + buttonZoom025.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + buttonZoom025ActionPerformed(evt); + } + }); + + buttonGroup1.add(buttonZoom05); + buttonZoom05.setText("1/2"); + buttonZoom05.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + buttonZoom05ActionPerformed(evt); + } + }); + + buttonGroup1.add(buttonZoom2); + buttonZoom2.setText("2"); + buttonZoom2.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + buttonZoom2ActionPerformed(evt); + } + }); + + javax.swing.GroupLayout panelZoomLayout = new javax.swing.GroupLayout(panelZoom); + panelZoom.setLayout(panelZoomLayout); + panelZoomLayout.setHorizontalGroup( + panelZoomLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(panelZoomLayout.createSequentialGroup() + .addContainerGap() + .addGroup(panelZoomLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(buttonZoomFit) + .addComponent(buttonZoomNormal) + .addComponent(buttonZoomStretch)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(panelZoomLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(buttonZoom025) + .addComponent(buttonZoom05) + .addComponent(buttonZoom2)) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + panelZoomLayout.setVerticalGroup( + panelZoomLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(panelZoomLayout.createSequentialGroup() + .addGap(4, 4, 4) + .addGroup(panelZoomLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER) + .addComponent(buttonZoomNormal) + .addComponent(buttonZoom025)) + .addGap(0, 0, 0) + .addGroup(panelZoomLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER) + .addComponent(buttonZoomFit) + .addComponent(buttonZoom05)) + .addGap(0, 0, 0) + .addGroup(panelZoomLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER) + .addComponent(buttonZoomStretch) + .addComponent(buttonZoom2)) + .addContainerGap()) + ); + + panelColormap.setBorder(javax.swing.BorderFactory.createTitledBorder("Colormap")); + + checkHistogram.setText("Histogram"); + checkHistogram.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + checkHistogramActionPerformed(evt); + } + }); + + comboColormap.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + onChangeColormap(evt); + } + }); + + jLabel3.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING); + jLabel3.setText("Type:"); + + jLabel4.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING); + jLabel4.setText("Range:"); + + buttonGroup3.add(buttonFullRange); + buttonFullRange.setText("Full"); + buttonFullRange.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + onChangeColormap(evt); + } + }); + + buttonGroup3.add(buttonManual); + buttonManual.setText("Manual"); + buttonManual.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + onChangeColormap(evt); + } + }); + + buttonGroup3.add(buttonAutomatic); + buttonAutomatic.setText("Automatic"); + buttonAutomatic.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + onChangeColormap(evt); + } + }); + + labelMin.setText("Min:"); + + spinnerMin.setModel(new javax.swing.SpinnerNumberModel(0, 0, 65535, 1)); + spinnerMin.setEnabled(false); + spinnerMin.setPreferredSize(new java.awt.Dimension(77, 20)); + spinnerMin.addChangeListener(new javax.swing.event.ChangeListener() { + public void stateChanged(javax.swing.event.ChangeEvent evt) { + onChangeColormapRange(evt); + } + }); + + spinnerMax.setModel(new javax.swing.SpinnerNumberModel(255, 0, 65535, 1)); + spinnerMax.setEnabled(false); + spinnerMax.setPreferredSize(new java.awt.Dimension(77, 20)); + spinnerMax.addChangeListener(new javax.swing.event.ChangeListener() { + public void stateChanged(javax.swing.event.ChangeEvent evt) { + onChangeColormapRange(evt); + } + }); + + labelMax.setText("Max:"); + + btFixColormapRange.setText("Fix"); + btFixColormapRange.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + btFixColormapRangeActionPerformed(evt); + } + }); + + javax.swing.GroupLayout panelColormapLayout = new javax.swing.GroupLayout(panelColormap); + panelColormap.setLayout(panelColormapLayout); + panelColormapLayout.setHorizontalGroup( + panelColormapLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(panelColormapLayout.createSequentialGroup() + .addGap(4, 4, 4) + .addGroup(panelColormapLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel3) + .addComponent(jLabel4)) + .addGap(4, 4, 4) + .addGroup(panelColormapLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(buttonAutomatic) + .addComponent(buttonFullRange) + .addComponent(buttonManual) + .addComponent(comboColormap, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(panelColormapLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, panelColormapLayout.createSequentialGroup() + .addComponent(labelMax) + .addGap(2, 2, 2) + .addComponent(spinnerMax, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(checkHistogram, javax.swing.GroupLayout.Alignment.TRAILING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, panelColormapLayout.createSequentialGroup() + .addComponent(labelMin) + .addGap(2, 2, 2) + .addGroup(panelColormapLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(btFixColormapRange, javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(spinnerMin, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))) + .addContainerGap()) + ); + + panelColormapLayout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {btFixColormapRange, spinnerMax, spinnerMin}); + + panelColormapLayout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {jLabel3, jLabel4}); + + panelColormapLayout.setVerticalGroup( + panelColormapLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, panelColormapLayout.createSequentialGroup() + .addGap(4, 4, 4) + .addGroup(panelColormapLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(comboColormap, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel3) + .addComponent(checkHistogram)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(panelColormapLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(buttonAutomatic) + .addComponent(jLabel4) + .addComponent(btFixColormapRange, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(0, 0, 0) + .addGroup(panelColormapLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER) + .addComponent(labelMin) + .addComponent(spinnerMin, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(buttonFullRange)) + .addGroup(panelColormapLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER) + .addComponent(buttonManual) + .addComponent(labelMax) + .addComponent(spinnerMax, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addContainerGap()) + ); + + panelScreen.setBorder(javax.swing.BorderFactory.createTitledBorder("Screen")); + + comboScreen.setEnabled(false); + comboScreen.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + comboScreenActionPerformed(evt); + } + }); + + javax.swing.GroupLayout panelScreenLayout = new javax.swing.GroupLayout(panelScreen); + panelScreen.setLayout(panelScreenLayout); + panelScreenLayout.setHorizontalGroup( + panelScreenLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(panelScreenLayout.createSequentialGroup() + .addContainerGap() + .addGroup(panelScreenLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(valueScreen, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(comboScreen, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap()) + ); + panelScreenLayout.setVerticalGroup( + panelScreenLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, panelScreenLayout.createSequentialGroup() + .addGap(4, 4, 4) + .addComponent(comboScreen, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(valueScreen, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap()) + ); + + panelFilter.setBorder(javax.swing.BorderFactory.createTitledBorder("Filter")); + + comboFilter.setEnabled(false); + comboFilter.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + comboFilterActionPerformed(evt); + } + }); + + javax.swing.GroupLayout panelFilterLayout = new javax.swing.GroupLayout(panelFilter); + panelFilter.setLayout(panelFilterLayout); + panelFilterLayout.setHorizontalGroup( + panelFilterLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(panelFilterLayout.createSequentialGroup() + .addContainerGap() + .addGroup(panelFilterLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(valueFilter, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(comboFilter, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap()) + ); + panelFilterLayout.setVerticalGroup( + panelFilterLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, panelFilterLayout.createSequentialGroup() + .addGap(4, 4, 4) + .addComponent(comboFilter, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(valueFilter, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + + panelPipeline.setBorder(javax.swing.BorderFactory.createTitledBorder("Pipeline")); + + checkThreshold.setText("Threshold"); + checkThreshold.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + checkThresholdActionPerformed(evt); + } + }); + + spinnerThreshold.setModel(new javax.swing.SpinnerNumberModel(0.0d, 0.0d, 99999.0d, 1.0d)); + spinnerThreshold.addChangeListener(new javax.swing.event.ChangeListener() { + public void stateChanged(javax.swing.event.ChangeEvent evt) { + spinnerThresholdonChange(evt); + } + }); + + checkBackground.setText("Subtract Background"); + checkBackground.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + checkBackgroundActionPerformed(evt); + } + }); + + checkGoodRegion.setText("Good Region"); + checkGoodRegion.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + checkGoodRegionActionPerformed(evt); + } + }); + + spinnerGrScale.setModel(new javax.swing.SpinnerNumberModel(3.0d, 0.01d, 99999.0d, 1.0d)); + spinnerGrScale.addChangeListener(new javax.swing.event.ChangeListener() { + public void stateChanged(javax.swing.event.ChangeEvent evt) { + spinnerGrThresholdonChange(evt); + } + }); + + spinnerGrThreshold.setModel(new javax.swing.SpinnerNumberModel(0.5d, 0.04d, 1.0d, 0.1d)); + spinnerGrThreshold.setPreferredSize(new java.awt.Dimension(92, 20)); + spinnerGrThreshold.addChangeListener(new javax.swing.event.ChangeListener() { + public void stateChanged(javax.swing.event.ChangeEvent evt) { + spinnerGrThresholdonChange(evt); + } + }); + + labelGrThreshold.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING); + labelGrThreshold.setText("Threshold:"); + + labelGrScale.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING); + labelGrScale.setText("Scale:"); + + checkSlicing.setText("Slicing"); + checkSlicing.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + checkSlicingActionPerformed(evt); + } + }); + + labelSlScale.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING); + labelSlScale.setText("Scale:"); + + spinnerSlScale.setModel(new javax.swing.SpinnerNumberModel(3.0d, 0.01d, 99999.0d, 1.0d)); + spinnerSlScale.addChangeListener(new javax.swing.event.ChangeListener() { + public void stateChanged(javax.swing.event.ChangeEvent evt) { + spinnerSlicingChange(evt); + } + }); + + labelSlNumber.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING); + labelSlNumber.setText("Slices:"); + + spinnerSlNumber.setModel(new javax.swing.SpinnerNumberModel(2, 0, 1000, 1)); + spinnerSlNumber.setPreferredSize(new java.awt.Dimension(92, 20)); + spinnerSlNumber.addChangeListener(new javax.swing.event.ChangeListener() { + public void stateChanged(javax.swing.event.ChangeEvent evt) { + spinnerSlicingChange(evt); + } + }); + + labelSlOrientation.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING); + labelSlOrientation.setText("Orientation:"); + + spinnerSlOrientation.setModel(new javax.swing.SpinnerListModel(new String[] {"vertical", "horizontal"})); + spinnerSlOrientation.setPreferredSize(new java.awt.Dimension(92, 20)); + spinnerSlOrientation.addChangeListener(new javax.swing.event.ChangeListener() { + public void stateChanged(javax.swing.event.ChangeEvent evt) { + spinnerSlicingChange(evt); + } + }); + + javax.swing.GroupLayout panelSlicingLayout = new javax.swing.GroupLayout(panelSlicing); + panelSlicing.setLayout(panelSlicingLayout); + panelSlicingLayout.setHorizontalGroup( + panelSlicingLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(panelSlicingLayout.createSequentialGroup() + .addContainerGap() + .addGroup(panelSlicingLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(panelSlicingLayout.createSequentialGroup() + .addComponent(checkSlicing) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(panelSlicingLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, panelSlicingLayout.createSequentialGroup() + .addComponent(labelSlNumber) + .addGap(2, 2, 2) + .addComponent(spinnerSlNumber, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, panelSlicingLayout.createSequentialGroup() + .addComponent(labelSlScale) + .addGap(2, 2, 2) + .addComponent(spinnerSlScale, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, panelSlicingLayout.createSequentialGroup() + .addGap(0, 0, Short.MAX_VALUE) + .addComponent(labelSlOrientation) + .addGap(2, 2, 2) + .addComponent(spinnerSlOrientation, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addContainerGap()) + ); + + panelSlicingLayout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {spinnerSlNumber, spinnerSlOrientation, spinnerSlScale}); + + panelSlicingLayout.setVerticalGroup( + panelSlicingLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(panelSlicingLayout.createSequentialGroup() + .addGroup(panelSlicingLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(checkSlicing) + .addGroup(panelSlicingLayout.createSequentialGroup() + .addGroup(panelSlicingLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(spinnerSlNumber, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(labelSlNumber)) + .addGap(0, 0, 0) + .addGroup(panelSlicingLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(spinnerSlScale, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(labelSlScale)))) + .addGap(0, 0, 0) + .addGroup(panelSlicingLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(spinnerSlOrientation, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(labelSlOrientation))) + ); + + panelSlicingLayout.linkSize(javax.swing.SwingConstants.VERTICAL, new java.awt.Component[] {spinnerSlNumber, spinnerSlOrientation, spinnerSlScale}); + + checkRotation.setText("Rotation"); + checkRotation.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + checkRotationActionPerformed(evt); + } + }); + + spinnerRotationAngle.setModel(new javax.swing.SpinnerNumberModel(0.0d, -360.0d, 360.0d, 1.0d)); + spinnerRotationAngle.addChangeListener(new javax.swing.event.ChangeListener() { + public void stateChanged(javax.swing.event.ChangeEvent evt) { + spinnerRotationAngleStateChanged(evt); + } + }); + + spinnerRotationOrder.setModel(new javax.swing.SpinnerNumberModel(1, 1, 5, 1)); + spinnerRotationOrder.addChangeListener(new javax.swing.event.ChangeListener() { + public void stateChanged(javax.swing.event.ChangeEvent evt) { + spinnerRotationAngleStateChanged(evt); + } + }); + + labelOrder.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING); + labelOrder.setText("Order:"); + + labelMode.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING); + labelMode.setText("Mode:"); + + spinnerRotationMode.setModel(new javax.swing.SpinnerListModel(new String[] {"constant", "reflect", "nearest", "mirror", "wrap", "ortho"})); + spinnerRotationMode.addChangeListener(new javax.swing.event.ChangeListener() { + public void stateChanged(javax.swing.event.ChangeEvent evt) { + spinnerRotationAngleStateChanged(evt); + } + }); + + labelAngle.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING); + labelAngle.setText("Angle:"); + + labelConstant.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING); + labelConstant.setText("Constant:"); + + spinnerRotationConstant.setModel(new javax.swing.SpinnerNumberModel(0, 0, 99999, 1)); + spinnerRotationConstant.addChangeListener(new javax.swing.event.ChangeListener() { + public void stateChanged(javax.swing.event.ChangeEvent evt) { + spinnerRotationAngleStateChanged(evt); + } + }); + + checkAveraging.setText("Averaging"); + checkAveraging.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + checkAveragingActionPerformed(evt); + } + }); + + spinnerAvFrames.setModel(new javax.swing.SpinnerNumberModel(1, 1, 1000, 1)); + spinnerAvFrames.addChangeListener(new javax.swing.event.ChangeListener() { + public void stateChanged(javax.swing.event.ChangeEvent evt) { + spinnerAvFramesStateChanged(evt); + } + }); + + labelAvFrames.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING); + labelAvFrames.setText("Frames:"); + + labelAvMode.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING); + labelAvMode.setText("Mode:"); + + spinnerAvMode.setModel(new javax.swing.SpinnerListModel(new String[] {"single", "window"})); + spinnerAvMode.addChangeListener(new javax.swing.event.ChangeListener() { + public void stateChanged(javax.swing.event.ChangeEvent evt) { + spinnerAvModeonChange(evt); + } + }); + + spinnerBackground.setModel(new javax.swing.SpinnerListModel(new String[] {"normal", "signed", "passive"})); + spinnerBackground.addChangeListener(new javax.swing.event.ChangeListener() { + public void stateChanged(javax.swing.event.ChangeEvent evt) { + spinnerBackgroundStateChanged(evt); + } + }); + + javax.swing.GroupLayout panelPipelineLayout = new javax.swing.GroupLayout(panelPipeline); + panelPipeline.setLayout(panelPipelineLayout); + panelPipelineLayout.setHorizontalGroup( + panelPipelineLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(panelSlicing, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(panelPipelineLayout.createSequentialGroup() + .addContainerGap() + .addGroup(panelPipelineLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(panelPipelineLayout.createSequentialGroup() + .addGroup(panelPipelineLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(panelPipelineLayout.createSequentialGroup() + .addComponent(checkAveraging) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(panelPipelineLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(labelAvFrames, javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(labelAvMode, javax.swing.GroupLayout.Alignment.TRAILING))) + .addGroup(panelPipelineLayout.createSequentialGroup() + .addGroup(panelPipelineLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(checkGoodRegion) + .addComponent(checkRotation) + .addComponent(checkThreshold)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(panelPipelineLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(panelPipelineLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(labelOrder, javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(labelAngle, javax.swing.GroupLayout.Alignment.TRAILING)) + .addComponent(labelGrScale, javax.swing.GroupLayout.Alignment.TRAILING))) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, panelPipelineLayout.createSequentialGroup() + .addGap(0, 0, Short.MAX_VALUE) + .addGroup(panelPipelineLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(labelConstant, javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(labelMode, javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(labelGrThreshold, javax.swing.GroupLayout.Alignment.TRAILING)))) + .addGap(2, 2, 2)) + .addGroup(panelPipelineLayout.createSequentialGroup() + .addComponent(checkBackground) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) + .addGroup(panelPipelineLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(spinnerGrThreshold, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(spinnerGrScale, javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(spinnerThreshold, javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(spinnerRotationOrder, javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(spinnerRotationMode, javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(spinnerRotationAngle, javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(spinnerRotationConstant, javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(spinnerAvFrames, javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(spinnerAvMode, javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(spinnerBackground, javax.swing.GroupLayout.Alignment.TRAILING)) + .addContainerGap()) + ); + + panelPipelineLayout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {spinnerAvFrames, spinnerAvMode, spinnerBackground, spinnerGrScale, spinnerGrThreshold, spinnerRotationAngle, spinnerRotationConstant, spinnerRotationMode, spinnerRotationOrder, spinnerThreshold}); + + panelPipelineLayout.setVerticalGroup( + panelPipelineLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(panelPipelineLayout.createSequentialGroup() + .addContainerGap() + .addGroup(panelPipelineLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(checkBackground) + .addComponent(spinnerBackground, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(2, 2, 2) + .addGroup(panelPipelineLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(checkThreshold) + .addComponent(spinnerThreshold, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(2, 2, 2) + .addGroup(panelPipelineLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(checkAveraging) + .addComponent(spinnerAvFrames, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(labelAvFrames)) + .addGap(2, 2, 2) + .addGroup(panelPipelineLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(spinnerAvMode, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(labelAvMode)) + .addGap(2, 2, 2) + .addGroup(panelPipelineLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(checkRotation) + .addComponent(spinnerRotationAngle, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(labelAngle)) + .addGap(0, 0, 0) + .addGroup(panelPipelineLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(spinnerRotationOrder, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(labelOrder)) + .addGap(0, 0, 0) + .addGroup(panelPipelineLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(spinnerRotationMode, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(labelMode)) + .addGap(0, 0, 0) + .addGroup(panelPipelineLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(spinnerRotationConstant, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(labelConstant)) + .addGap(2, 2, 2) + .addGroup(panelPipelineLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(checkGoodRegion) + .addComponent(spinnerGrScale, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(labelGrScale)) + .addGap(0, 0, 0) + .addGroup(panelPipelineLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(spinnerGrThreshold, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(labelGrThreshold)) + .addGap(2, 2, 2) + .addComponent(panelSlicing, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap()) + ); + + panelPipelineLayout.linkSize(javax.swing.SwingConstants.VERTICAL, new java.awt.Component[] {spinnerAvFrames, spinnerAvMode, spinnerBackground, spinnerGrScale, spinnerGrThreshold, spinnerRotationAngle, spinnerRotationConstant, spinnerRotationMode, spinnerRotationOrder, spinnerThreshold}); + + panelPulse.setBorder(javax.swing.BorderFactory.createTitledBorder("Pulse")); + + buttonPulse1.setText("Pulse 1"); + buttonPulse1.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + buttonPulse1ActionPerformed(evt); + } + }); + + buttonPulse2.setText("Pulse 2"); + buttonPulse2.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + buttonPulse2ActionPerformed(evt); + } + }); + + textPulse.setEditable(false); + textPulse.setHorizontalAlignment(javax.swing.JTextField.CENTER); + + javax.swing.GroupLayout panelPulseLayout = new javax.swing.GroupLayout(panelPulse); + panelPulse.setLayout(panelPulseLayout); + panelPulseLayout.setHorizontalGroup( + panelPulseLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(panelPulseLayout.createSequentialGroup() + .addContainerGap() + .addComponent(buttonPulse1) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(buttonPulse2) + .addGap(18, 18, Short.MAX_VALUE) + .addComponent(textPulse, javax.swing.GroupLayout.PREFERRED_SIZE, 63, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap()) + ); + + panelPulseLayout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {buttonPulse1, buttonPulse2}); + + panelPulseLayout.setVerticalGroup( + panelPulseLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(panelPulseLayout.createSequentialGroup() + .addGroup(panelPulseLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(buttonPulse1, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(buttonPulse2, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(textPulse, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addContainerGap()) + ); + + javax.swing.GroupLayout sidePanelLayout = new javax.swing.GroupLayout(sidePanel); + sidePanel.setLayout(sidePanelLayout); + sidePanelLayout.setHorizontalGroup( + sidePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(sidePanelLayout.createSequentialGroup() + .addContainerGap() + .addGroup(sidePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) + .addComponent(panelZoom, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(panelColormap, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(panelPipeline, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(panelScreen, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(panelFilter, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(panelPulse, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + sidePanelLayout.setVerticalGroup( + sidePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(sidePanelLayout.createSequentialGroup() + .addGap(0, 0, 0) + .addComponent(panelPipeline, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(panelZoom, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(panelColormap, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(panelScreen, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(panelFilter, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(panelPulse, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + + toolBar.setFloatable(false); + toolBar.setRollover(true); + + buttonSidePanel.setIcon(getIcon("List")); + buttonSidePanel.setSelected(true); + buttonSidePanel.setText(" "); + buttonSidePanel.setToolTipText("Show Side Panel"); + buttonSidePanel.setFocusable(false); + buttonSidePanel.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + buttonSidePanel.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + buttonSidePanelActionPerformed(evt); + } + }); + toolBar.add(buttonSidePanel); + + buttonStreamData.setIcon(getIcon("Details")); + buttonStreamData.setText(" "); + buttonStreamData.setToolTipText("Show Data Window"); + buttonStreamData.setFocusable(false); + buttonStreamData.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + buttonStreamData.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + buttonStreamDataActionPerformed(evt); + } + }); + toolBar.add(buttonStreamData); + + buttonSave.setIcon(getIcon("Save")); + buttonSave.setText(" "); + buttonSave.setToolTipText("Save Snapshot"); + buttonSave.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + buttonSave.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + buttonSaveActionPerformed(evt); + } + }); + toolBar.add(buttonSave); + + buttonGrabBackground.setIcon(getIcon("Background")); + buttonGrabBackground.setText(" "); + buttonGrabBackground.setToolTipText("Grab Background"); + buttonGrabBackground.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + buttonGrabBackground.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + buttonGrabBackgroundActionPerformed(evt); + } + }); + toolBar.add(buttonGrabBackground); + + buttonPause.setIcon(getIcon("Pause")); + buttonPause.setText(" "); + buttonPause.setToolTipText("Pause"); + buttonPause.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + buttonPause.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + buttonPauseActionPerformed(evt); + } + }); + toolBar.add(buttonPause); + + jSeparator6.setMaximumSize(new java.awt.Dimension(20, 32767)); + jSeparator6.setPreferredSize(new java.awt.Dimension(20, 0)); + jSeparator6.setRequestFocusEnabled(false); + toolBar.add(jSeparator6); + + buttonMarker.setIcon(getIcon("Marker")); + buttonMarker.setText(" "); + buttonMarker.setToolTipText("Show Marker"); + buttonMarker.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + buttonMarker.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + buttonMarkerActionPerformed(evt); + } + }); + toolBar.add(buttonMarker); + + buttonProfile.setIcon(getIcon("Profile" + + "")); + buttonProfile.setSelected(true); + buttonProfile.setText(" "); + buttonProfile.setToolTipText("Show Image Profile"); + buttonProfile.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + buttonProfile.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + buttonProfileActionPerformed(evt); + } + }); + toolBar.add(buttonProfile); + + buttonFit.setIcon(getIcon("Fit")); + buttonFit.setSelected(true); + buttonFit.setText(" "); + buttonFit.setToolTipText("Show Fit"); + buttonFit.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + buttonFit.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + buttonFitActionPerformed(evt); + } + }); + toolBar.add(buttonFit); + + buttonReticle.setIcon(getIcon("Reticule")); + buttonReticle.setSelected(true); + buttonReticle.setText(" "); + buttonReticle.setToolTipText("Show Reticle"); + buttonReticle.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + buttonReticle.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + buttonReticleActionPerformed(evt); + } + }); + toolBar.add(buttonReticle); + + buttonScale.setIcon(getIcon("Scale")); + buttonScale.setSelected(true); + buttonScale.setText(" "); + buttonScale.setToolTipText("Show Colormap Scale"); + buttonScale.setFocusable(false); + buttonScale.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + buttonScale.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + buttonScaleActionPerformed(evt); + } + }); + toolBar.add(buttonScale); + + buttonTitle.setIcon(getIcon("Title")); + buttonTitle.setSelected(true); + buttonTitle.setText(" "); + buttonTitle.setToolTipText("Show Camera Name"); + buttonTitle.setFocusable(false); + buttonTitle.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + buttonTitle.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + buttonTitleActionPerformed(evt); + } + }); + toolBar.add(buttonTitle); + + pauseSelection.setDecimals(0); + + jLabel1.setText("Camera:"); + + comboCameras.setFont(new java.awt.Font("Dialog", 1, 14)); // NOI18N + comboCameras.setMaximumRowCount(30); + comboCameras.setMinimumSize(new java.awt.Dimension(127, 27)); + comboCameras.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + comboCamerasActionPerformed(evt); + } + }); + + labelType.setText("Type:"); + + comboType.setFont(new java.awt.Font("Dialog", 1, 14)); // NOI18N + comboType.setMaximumRowCount(30); + comboType.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "All", "Laser", "Electrons", "Photonics" })); + comboType.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + comboTypeActionPerformed(evt); + } + }); + + javax.swing.GroupLayout panelCameraSelectionLayout = new javax.swing.GroupLayout(panelCameraSelection); + panelCameraSelection.setLayout(panelCameraSelectionLayout); + panelCameraSelectionLayout.setHorizontalGroup( + panelCameraSelectionLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(panelCameraSelectionLayout.createSequentialGroup() + .addContainerGap() + .addComponent(jLabel1) + .addGap(0, 0, 0) + .addComponent(comboCameras, javax.swing.GroupLayout.PREFERRED_SIZE, 222, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(labelType) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(comboType, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(0, 0, 0)) + ); + panelCameraSelectionLayout.setVerticalGroup( + panelCameraSelectionLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(panelCameraSelectionLayout.createSequentialGroup() + .addGap(0, 0, 0) + .addGroup(panelCameraSelectionLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER) + .addComponent(comboType, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(labelType) + .addComponent(jLabel1) + .addComponent(comboCameras, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(0, 0, 0)) + ); + + javax.swing.GroupLayout topPanelLayout = new javax.swing.GroupLayout(topPanel); + topPanel.setLayout(topPanelLayout); + topPanelLayout.setHorizontalGroup( + topPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, topPanelLayout.createSequentialGroup() + .addComponent(toolBar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(18, 18, 18) + .addComponent(panelCameraSelection, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGap(18, 18, 18) + .addComponent(pauseSelection, javax.swing.GroupLayout.PREFERRED_SIZE, 334, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap()) + ); + topPanelLayout.setVerticalGroup( + topPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addGroup(topPanelLayout.createSequentialGroup() + .addGap(1, 1, 1) + .addGroup(topPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER) + .addComponent(pauseSelection, javax.swing.GroupLayout.PREFERRED_SIZE, 29, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(toolBar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(panelCameraSelection, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + ); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup() + .addComponent(sidePanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(renderer, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup() + .addContainerGap() + .addComponent(topPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(topPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(sidePanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(renderer, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) + ); + }// //GEN-END:initComponents + + private void buttonZoomFitActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonZoomFitActionPerformed + try { + renderer.setMode(RendererMode.Fit); + } catch (Exception ex) { + showException(ex); + } + }//GEN-LAST:event_buttonZoomFitActionPerformed + + private void buttonZoomStretchActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonZoomStretchActionPerformed + try { + renderer.setMode(RendererMode.Stretch); + } catch (Exception ex) { + showException(ex); + } + }//GEN-LAST:event_buttonZoomStretchActionPerformed + + private void buttonZoomNormalActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonZoomNormalActionPerformed + try { + renderer.setMode(RendererMode.Fixed); + centralizeRenderer(); + } catch (Exception ex) { + showException(ex); + } + }//GEN-LAST:event_buttonZoomNormalActionPerformed + + private void onChangeColormap(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_onChangeColormap + try { + if ((camera != null) && (camera instanceof ColormapSource) && !updatingColormap) { + ColormapSource source = (ColormapSource) camera; + Color colorReticule = new Color(16, 16, 16); + Color colorMarker = new Color(128, 128, 128); + Colormap colormap = (Colormap) comboColormap.getSelectedItem(); + source.getConfig().colormap = (colormap == null) ? Colormap.Flame : colormap; + switch (source.getConfig().colormap) { + case Grayscale: + case Inverted: + case Red: + case Green: + case Blue: + colorReticule = new Color(0, 192, 0); + colorMarker = new Color(64, 255, 64); + break; + case Flame: + colorReticule = new Color(0, 192, 0); + colorMarker = new Color(64, 255, 64); + break; + } + + renderer.setPenReticle(new Pen(colorReticule)); + renderer.setPenProfile(new Pen(colorReticule, 0)); + renderer.setPenMarker(new Pen(colorMarker, 2)); + renderer.setShowReticle(false); + checkReticle(); + source.getConfig().colormapAutomatic = buttonAutomatic.isSelected(); + source.getConfig().colormapMin = buttonFullRange.isSelected() ? Double.NaN : (Integer) spinnerMin.getValue(); + source.getConfig().colormapMax = buttonFullRange.isSelected() ? Double.NaN : (Integer) spinnerMax.getValue(); + try { + source.getConfig().save(); + } catch (Exception ex) { + logger.log(Level.WARNING, null, ex); + } + source.refresh(); + if (buttonPause.isSelected()) { + updatePause(); + } + updateColormap(); + } + } catch (Exception ex) { + showException(ex); + } + }//GEN-LAST:event_onChangeColormap + + private void onChangeColormapRange(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_onChangeColormapRange + onChangeColormap(null); + }//GEN-LAST:event_onChangeColormapRange + + private void buttonZoom025ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonZoom025ActionPerformed + renderer.setZoom(0.25); + renderer.setMode(RendererMode.Zoom); + centralizeRenderer(); + }//GEN-LAST:event_buttonZoom025ActionPerformed + + private void buttonZoom05ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonZoom05ActionPerformed + renderer.setZoom(0.5); + renderer.setMode(RendererMode.Zoom); + centralizeRenderer(); + }//GEN-LAST:event_buttonZoom05ActionPerformed + + private void comboScreenActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_comboScreenActionPerformed + + comboScreen.setEnabled(false); + new Thread(new Runnable() { + @Override + public void run() { + ChannelInteger setpoint = null; + try { + int index = comboScreen.getSelectedIndex(); + if (index >= 0) { + if (cameraName.contains("DSRM")) { + setpoint = new ChannelInteger(null, cameraName + ":POSITION_SP"); + } else { + setpoint = new ChannelInteger(null, cameraName + ":SET_SCREEN1_POS"); + } + setpoint.initialize(); + Integer readback = setpoint.read(); + if ((readback == null) || (setpoint.read() != index)) { + setpoint.write(index); + } + screen.read(); + } + } catch (Exception ex) { + showException(ex); + } finally { + comboScreen.setEnabled(true); + if (setpoint != null) { + setpoint.close(); + } + } + } + }).start(); + }//GEN-LAST:event_comboScreenActionPerformed + + private void comboFilterActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_comboFilterActionPerformed + try { + String setpoint = (String) comboFilter.getSelectedItem(); + if (setpoint != null) { + if (!setpoint.equals(filter.read())) { + filter.write(setpoint); + } + } + } catch (Exception ex) { + showException(ex); + } + }//GEN-LAST:event_comboFilterActionPerformed + + private void checkHistogramActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_checkHistogramActionPerformed + try { + setHistogramVisible(checkHistogram.isSelected()); + } catch (Exception ex) { + showException(ex); + } + }//GEN-LAST:event_checkHistogramActionPerformed + + private void buttonZoom2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonZoom2ActionPerformed + renderer.setZoom(2.0); + renderer.setMode(RendererMode.Zoom); + centralizeRenderer(); + }//GEN-LAST:event_buttonZoom2ActionPerformed + + private void spinnerThresholdonChange(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_spinnerThresholdonChange + if (!updatingServerControls) { + try { + if ((server != null) && (server.isStarted())) { + server.setThreshold((Double) spinnerThreshold.getValue()); + } + } catch (Exception ex) { + showException(ex); + updatePipelineControls(); + } + } + }//GEN-LAST:event_spinnerThresholdonChange + + private void checkBackgroundActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_checkBackgroundActionPerformed + if (server != null) { + if (!updatingServerControls) { + try { + if (server.isStarted()) { + spinnerBackground.setVisible(checkBackground.isSelected()); + Object bg_mode = checkBackground.isSelected() ? String.valueOf(spinnerBackground.getValue()) : false; + server.setBackgroundSubtraction(bg_mode.equals("normal") ? true : bg_mode); + } + } catch (Exception ex) { + showException(ex); + updatePipelineControls(); + updatingServerControls = true; + checkBackground.setSelected(false); + updatingServerControls = false; + + } + } + } else { + camera.setBackgroundEnabled(checkBackground.isSelected()); + } + }//GEN-LAST:event_checkBackgroundActionPerformed + + private void checkThresholdActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_checkThresholdActionPerformed + if (!updatingServerControls) { + try { + if ((server != null) && (server.isStarted())) { + spinnerThreshold.setVisible(checkThreshold.isSelected()); + server.setThreshold(checkThreshold.isSelected() ? (Double) spinnerThreshold.getValue() : null); + } + } catch (Exception ex) { + showException(ex); + updatePipelineControls(); + } + } + }//GEN-LAST:event_checkThresholdActionPerformed + + private void checkGoodRegionActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_checkGoodRegionActionPerformed + if (!updatingServerControls) { + try { + if ((server != null) && (server.isStarted())) { + goodRegion = checkGoodRegion.isSelected(); + setGoodRegionOptionsVisible(goodRegion); + if (goodRegion) { + server.setGoodRegion(((Number) spinnerGrThreshold.getValue()).doubleValue(), ((Number) spinnerGrScale.getValue()).doubleValue()); + } else { + server.setGoodRegion(null); + } + } + } catch (Exception ex) { + showException(ex); + updatePipelineControls(); + } + } + }//GEN-LAST:event_checkGoodRegionActionPerformed + + private void spinnerGrThresholdonChange(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_spinnerGrThresholdonChange + if (!updatingServerControls) { + try { + if ((server != null) && (server.isStarted())) { + server.setGoodRegion((Double) spinnerGrThreshold.getValue(), (Double) spinnerGrScale.getValue()); + } + } catch (Exception ex) { + showException(ex); + updatePipelineControls(); + } + } + }//GEN-LAST:event_spinnerGrThresholdonChange + + private void btFixColormapRangeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btFixColormapRangeActionPerformed + try { + updatingColormap = true; + ArrayProperties properties = currentFrame.data.getProperties(); + spinnerMax.setValue(properties.max.intValue()); + spinnerMin.setValue(properties.min.intValue()); + buttonManual.setSelected(true); + } catch (Exception ex) { + showException(ex); + } finally { + updatingColormap = false; + onChangeColormap(null); + } + }//GEN-LAST:event_btFixColormapRangeActionPerformed + + private void checkSlicingActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_checkSlicingActionPerformed + if (!updatingServerControls) { + try { + if ((server != null) && (server.isStarted())) { + slicing = checkSlicing.isSelected(); + setSlicingOptionsVisible(slicing); + if (slicing) { + server.setSlicing((Integer) spinnerSlNumber.getValue(), (Double) spinnerSlScale.getValue(), spinnerSlOrientation.getValue().toString()); + } else { + server.setSlicing(null); + } + } + } catch (Exception ex) { + showException(ex); + updatePipelineControls(); + } + } + }//GEN-LAST:event_checkSlicingActionPerformed + + private void spinnerSlicingChange(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_spinnerSlicingChange + if (!updatingServerControls) { + try { + if ((server != null) && (server.isStarted())) { + server.setSlicing((Integer) spinnerSlNumber.getValue(), (Double) spinnerSlScale.getValue(), spinnerSlOrientation.getValue().toString()); + } + } catch (Exception ex) { + showException(ex); + updatePipelineControls(); + } + } + }//GEN-LAST:event_spinnerSlicingChange + + private void buttonReticleActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonReticleActionPerformed + try { + checkReticle(); + } catch (Exception ex) { + showException(ex); + } + }//GEN-LAST:event_buttonReticleActionPerformed + + private void buttonFitActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonFitActionPerformed + try { + showFit = buttonFit.isSelected(); + if (showFit) { + renderer.setProfile(Renderer.Profile.None); + } else { + renderer.removeOverlays(fitOv); + fitOv = null; + } + } catch (Exception ex) { + showException(ex); + } + }//GEN-LAST:event_buttonFitActionPerformed + + private void buttonProfileActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonProfileActionPerformed + try { + showProfile = buttonProfile.isSelected(); + if (showProfile) { + renderer.setProfile(Renderer.Profile.None); + } else { + renderer.removeOverlays(profileOv); + profileOv = null; + } + } catch (Exception ex) { + showException(ex); + } + }//GEN-LAST:event_buttonProfileActionPerformed + + private void buttonMarkerActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonMarkerActionPerformed + try { + checkMarker(null); + } catch (Exception ex) { + showException(ex); + } + }//GEN-LAST:event_buttonMarkerActionPerformed + + private void buttonPauseActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonPauseActionPerformed + try { + if (!updatingButtons) { + setPaused(buttonPause.isSelected()); + } + } catch (Exception ex) { + showException(ex); + } + }//GEN-LAST:event_buttonPauseActionPerformed + + private void buttonGrabBackgroundActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonGrabBackgroundActionPerformed + try { + if (camera != null) { + boolean laserOn1 = getLaserState(1); + boolean laserOn2 = getLaserState(2); + OptionResult ret = null; + if (laserOn1 || laserOn2) { + if (laserOn1){ + ret = SwingUtils.showOption(getTopLevel(), "Capture Background", "Do you want to put Bunch 1 laser on delay for capturing background?", OptionType.YesNoCancel); + if (ret == OptionResult.No) { + laserOn1 = false; + } + if (ret == OptionResult.Cancel) { + return; + } + } + if (laserOn2){ + ret = SwingUtils.showOption(getTopLevel(), "Capture Background", "Do you want to put Bunch 2 laser on delay for capturing background?", OptionType.YesNoCancel); + if (ret == OptionResult.No) { + laserOn2= false; + } + } + } else { + ret = SwingUtils.showOption(getTopLevel(), "Capture Background", "Do you want to capture background now?", OptionType.OkCancel); + } + + if (ret == OptionResult.Cancel) { + return; + } + + if (laserOn1) { + setLaserState(1,false); + } + if (laserOn2) { + setLaserState(2,false); + } + try { + System.out.println("Grabbing background for: " + cameraAlias); + if (server != null) { + server.captureBackground(5); + } else { + camera.captureBackground(5, 0); + } + } finally { + if (laserOn1) { + setLaserState(1,true); + } + if (laserOn2) { + setLaserState(2,true); + } + } + SwingUtils.showMessage(getTopLevel(), "Success", "Success capturing background", 5000); + } + } catch (Exception ex) { + showException(ex); + } + }//GEN-LAST:event_buttonGrabBackgroundActionPerformed + + private void buttonSaveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonSaveActionPerformed + try { + saveSnapshot(); + } catch (Exception ex) { + logger.log(Level.WARNING, null, ex); + showException(ex); + } + }//GEN-LAST:event_buttonSaveActionPerformed + + private void buttonStreamDataActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonStreamDataActionPerformed + try { + showStreamData(); + } catch (Exception ex) { + showException(ex); + } + }//GEN-LAST:event_buttonStreamDataActionPerformed + + private void buttonSidePanelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonSidePanelActionPerformed + sidePanel.setVisible(buttonSidePanel.isSelected()); + }//GEN-LAST:event_buttonSidePanelActionPerformed + + private void comboTypeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_comboTypeActionPerformed + try { + if (!updatingCameraSelection) { + updateCameraList(); + if ((cameraAlias != null) && (!cameraAlias.equals(comboCameras.getSelectedItem()))) { + setCamera(null); + } + } + + } catch (Exception ex) { + ex.printStackTrace(); + } finally { + updateButtons(); + } + }//GEN-LAST:event_comboTypeActionPerformed + + private void comboCamerasActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_comboCamerasActionPerformed + try { + if (!updatingCameraSelection) { + if (!comboCameras.isEnabled()) { + throw new Exception("Invalid state"); + } + comboCameras.setEnabled(false); + comboType.setEnabled(false); + final String cameraName = (String) comboCameras.getSelectedItem(); + new Thread(new Runnable() { + @Override + public void run() { + if (requestCameraListUpdate) { + requestCameraListUpdate = false; + try { + updateCameraList(); + } catch (Exception ex) { + ex.printStackTrace(); + } + } + try { + setCamera(cameraName.trim().isEmpty() ? null : cameraName); + } catch (Exception ex) { + ex.printStackTrace(); + } finally { + updateButtons(); + comboCameras.setEnabled(true); + comboType.setEnabled(true); + } + } + }).start(); + } + } catch (Exception ex) { + showException(ex); + } + }//GEN-LAST:event_comboCamerasActionPerformed + + private void buttonTitleActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonTitleActionPerformed + try { + manageTitleOverlay(); + } catch (Exception ex) { + showException(ex); + } finally { + } + }//GEN-LAST:event_buttonTitleActionPerformed + + private void buttonScaleActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonScaleActionPerformed + try { + renderer.setShowColormapScale(buttonScale.isSelected()); + } catch (Exception ex) { + showException(ex); + } + }//GEN-LAST:event_buttonScaleActionPerformed + + private void checkRotationActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_checkRotationActionPerformed + if (!updatingServerControls) { + try { + if ((server != null) && (server.isStarted())) { + boolean rotation = checkRotation.isSelected(); + setRotationOptionsVisible(rotation); + if (rotation) { + spinnerRotationAngleStateChanged(null); + } else { + server.setRotation(null); + } + } + } catch (Exception ex) { + showException(ex); + updatePipelineControls(); + } + } + }//GEN-LAST:event_checkRotationActionPerformed + + private void spinnerRotationAngleStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_spinnerRotationAngleStateChanged + try { + String mode = String.valueOf(spinnerRotationMode.getValue()); + server.setRotation(((Number) spinnerRotationAngle.getValue()).doubleValue(), + ((Number) spinnerRotationOrder.getValue()).intValue(), + mode.equals("constant") ? String.valueOf(spinnerRotationConstant.getValue()): mode); + } catch (Exception ex) { + showException(ex); + updatePipelineControls(); + } + }//GEN-LAST:event_spinnerRotationAngleStateChanged + + private void checkAveragingActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_checkAveragingActionPerformed + if (!updatingServerControls) { + try { + if ((server != null) && (server.isStarted())) { + setAveragingOptionsVisible(checkAveraging.isSelected()); + Integer av = spinnerAvMode.getValue().equals("window") ? - (Integer)spinnerAvFrames.getValue() : (Integer)spinnerAvFrames.getValue(); + setInstanceConfigValue("averaging", checkAveraging.isSelected() ? av : null); + } + } catch (Exception ex) { + showException(ex); + updatePipelineControls(); + } + } + }//GEN-LAST:event_checkAveragingActionPerformed + + private void spinnerAvModeonChange(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_spinnerAvModeonChange + checkAveragingActionPerformed(null); + }//GEN-LAST:event_spinnerAvModeonChange + + private void spinnerAvFramesStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_spinnerAvFramesStateChanged + checkAveragingActionPerformed(null); + }//GEN-LAST:event_spinnerAvFramesStateChanged + + private void spinnerBackgroundStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_spinnerBackgroundStateChanged + if (!updatingServerControls) { + try { + Object bg_mode = String.valueOf(spinnerBackground.getValue()); + server.setBackgroundSubtraction((bg_mode=="normal") ? true : bg_mode); + } catch (Exception ex) { + showException(ex); + updatePipelineControls(); + } + } + }//GEN-LAST:event_spinnerBackgroundStateChanged + + private void buttonPulse1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonPulse1ActionPerformed + try { + if ((server != null) && (server.isStarted())) { + server.setInstanceConfigValue("pulse",1); + } + } catch (Exception ex) { + showException(ex); + } + }//GEN-LAST:event_buttonPulse1ActionPerformed + + private void buttonPulse2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonPulse2ActionPerformed + try { + if ((server != null) && (server.isStarted())) { + server.setInstanceConfigValue("pulse",2); + } + } catch (Exception ex) { + showException(ex); + } + }//GEN-LAST:event_buttonPulse2ActionPerformed + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton btFixColormapRange; + private javax.swing.JRadioButton buttonAutomatic; + private javax.swing.JToggleButton buttonFit; + private javax.swing.JRadioButton buttonFullRange; + private javax.swing.JButton buttonGrabBackground; + private javax.swing.ButtonGroup buttonGroup1; + private javax.swing.ButtonGroup buttonGroup2; + private javax.swing.ButtonGroup buttonGroup3; + private javax.swing.ButtonGroup buttonGroup4; + private javax.swing.JRadioButton buttonManual; + private javax.swing.JToggleButton buttonMarker; + private javax.swing.JToggleButton buttonPause; + private javax.swing.JToggleButton buttonProfile; + private javax.swing.JButton buttonPulse1; + private javax.swing.JButton buttonPulse2; + private javax.swing.JToggleButton buttonReticle; + private javax.swing.JToggleButton buttonSave; + private javax.swing.JToggleButton buttonScale; + private javax.swing.JToggleButton buttonSidePanel; + private javax.swing.JButton buttonStreamData; + private javax.swing.JToggleButton buttonTitle; + private javax.swing.JRadioButton buttonZoom025; + private javax.swing.JRadioButton buttonZoom05; + private javax.swing.JRadioButton buttonZoom2; + private javax.swing.JRadioButton buttonZoomFit; + private javax.swing.JRadioButton buttonZoomNormal; + private javax.swing.JRadioButton buttonZoomStretch; + private javax.swing.JCheckBox checkAveraging; + private javax.swing.JCheckBox checkBackground; + private javax.swing.JCheckBox checkGoodRegion; + private javax.swing.JCheckBox checkHistogram; + private javax.swing.JCheckBox checkRotation; + private javax.swing.JCheckBox checkSlicing; + private javax.swing.JCheckBox checkThreshold; + private javax.swing.JComboBox comboCameras; + private javax.swing.JComboBox comboColormap; + private javax.swing.JComboBox comboFilter; + private javax.swing.JComboBox comboScreen; + private javax.swing.JComboBox comboType; + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel3; + private javax.swing.JLabel jLabel4; + private javax.swing.JProgressBar jProgressBar1; + private javax.swing.JToolBar.Separator jSeparator6; + private javax.swing.JLabel labelAngle; + private javax.swing.JLabel labelAvFrames; + private javax.swing.JLabel labelAvMode; + private javax.swing.JLabel labelConstant; + private javax.swing.JLabel labelGrScale; + private javax.swing.JLabel labelGrThreshold; + private javax.swing.JLabel labelMax; + private javax.swing.JLabel labelMin; + private javax.swing.JLabel labelMode; + private javax.swing.JLabel labelOrder; + private javax.swing.JLabel labelSlNumber; + private javax.swing.JLabel labelSlOrientation; + private javax.swing.JLabel labelSlScale; + private javax.swing.JLabel labelType; + private javax.swing.JPanel panelCameraSelection; + private javax.swing.JPanel panelColormap; + private javax.swing.JPanel panelFilter; + private javax.swing.JPanel panelPipeline; + private javax.swing.JPanel panelPulse; + private javax.swing.JPanel panelScreen; + private javax.swing.JPanel panelSlicing; + private javax.swing.JPanel panelZoom; + private ch.psi.pshell.swing.ValueSelection pauseSelection; + private ch.psi.pshell.imaging.Renderer renderer; + private javax.swing.JPanel sidePanel; + private javax.swing.JSpinner spinnerAvFrames; + private javax.swing.JSpinner spinnerAvMode; + private javax.swing.JSpinner spinnerBackground; + private javax.swing.JSpinner spinnerGrScale; + private javax.swing.JSpinner spinnerGrThreshold; + private javax.swing.JSpinner spinnerMax; + private javax.swing.JSpinner spinnerMin; + private javax.swing.JSpinner spinnerRotationAngle; + private javax.swing.JSpinner spinnerRotationConstant; + private javax.swing.JSpinner spinnerRotationMode; + private javax.swing.JSpinner spinnerRotationOrder; + private javax.swing.JSpinner spinnerSlNumber; + private javax.swing.JSpinner spinnerSlOrientation; + private javax.swing.JSpinner spinnerSlScale; + private javax.swing.JSpinner spinnerThreshold; + private javax.swing.JTextField textPulse; + private javax.swing.JToolBar toolBar; + private javax.swing.JPanel topPanel; + private ch.psi.pshell.swing.DeviceValuePanel valueFilter; + private ch.psi.pshell.swing.DeviceValuePanel valueScreen; + // End of variables declaration//GEN-END:variables +} diff --git a/script/.DS_Store b/script/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..b6a6a4c46b344ceb266cddea940806da79914bae GIT binary patch literal 6148 zcmeHKJ5Iwu5S;}VmY_&UxmU;ymdG3+N<)c45EQW-DWP}Ak#Ygu!nq`gZ?z`96QWKIXRF>f8M0>BrAD{?yD+0V+TRr~noCy9%IZ ztJN2dT&VyRpaKU4^!t$EiY2gjv`+^X8v%g&8*hednO!Le HzoEbfyznX7 literal 0 HcmV?d00001 diff --git a/script/local.groovy b/script/local.groovy new file mode 100644 index 0000000..eef7106 --- /dev/null +++ b/script/local.groovy @@ -0,0 +1,3 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////// +// Deployment specific global definitions - executed after startup.groovy +/////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/script/local.js b/script/local.js new file mode 100644 index 0000000..e2eeaad --- /dev/null +++ b/script/local.js @@ -0,0 +1,4 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////// +// Deployment specific global definitions - executed after startup.js +/////////////////////////////////////////////////////////////////////////////////////////////////// + diff --git a/script/local.py b/script/local.py new file mode 100644 index 0000000..11602ec --- /dev/null +++ b/script/local.py @@ -0,0 +1,100 @@ +################################################################################################### +# Deployment specific global definitions - executed after startup.py +################################################################################################### +import numpy +from threading import Thread +import threading +import traceback +import queue +#import multiprocessing + +#Workaround for zmq being a java package and having priority for import over python zmq package +from importlib._bootstrap import _load +from importlib import util +PYHOME = os.environ["PYTHONHOME"] +PYVER = str(sys.version_info[0]) + "." + str(sys.version_info[1]) +_load(util.spec_from_file_location("zmq", PYHOME + "/lib/python" + PYVER + "/site-packages/zmq/__init__.py")) + + +from bsread import source, Source, PUB, SUB, PUSH, PULL, DEFAULT_DISPATCHER_URL + +from cam_server import CamClient, PipelineClient, ProxyClient, config + +from cam_server.utils import get_host_port_from_stream_address +from cam_server.pipeline.configuration import PipelineConfig +#from cam_server.pipeline.types.processing import run as processing_pipeline +from processing import run as processing_pipeline +from cam_server.pipeline.types.store import run as store_pipeline +from cam_server.start_camera_server import start_camera_server + + + +camera_client = CamClient("http://" + App.getArgumentValue("cam_srv_url")) + +class Namespace(object): + def __init__(self, **kwds): + self.__dict__.update(kwds) + def __repr__(self): + items = self.__dict__.items() + temp = [] + for name, value in items: + if not name.startswith('_'): + temp.append('%s=%r' % (name, value)) + temp.sort() + return 'Namespace(%s)' % str.join(', ', temp) + +class Viewer(): + def __init__(self): + app=App.getInstance() + c=get_context() + self.plugin=c.getPlugin("ScreenPanel10") + + def show_stream(self, url): + self.plugin.initStream(url) + + def show_pipeline(self, name): + self.plugin.initPipeline(name) + + def show_camera(self, name): + self.plugin.initCamera(name) + + def stop(self): + self.plugin.initCamera("") + +viewer = Viewer() + + + +class MockBackgroundManager: + def __init__(self): + self.backgrounds = {} + + def get_background(self, background_name): + if not background_name: + return None + + if background_name not in self.backgrounds: + raise ValueError("Requested background '%s' does not exist." % background_name) + + return self.backgrounds[background_name] + + def save_background(self, background_name, image, append_timestamp=True): + if append_timestamp: + background_name += datetime.now().strftime("_%Y%m%d_%H%M%S_%f") + + self.backgrounds[background_name] = image + + return background_name + + def get_latest_background_id(self, background_prefix): + raise NotImplementedError("This cannot work in the mock.") + + def get_background_ids(self, background_prefix): + raise NotImplementedError("This cannot work in the mock.") + + +def dont_exit(status): + print ("Exit status: ", status) + +sys.exit = dont_exit + diff --git a/script/processing.py b/script/processing.py new file mode 100644 index 0000000..9236451 --- /dev/null +++ b/script/processing.py @@ -0,0 +1,306 @@ +from cam_server.pipeline.utils import * +from logging import getLogger +import time +import sys +import os +from collections import deque, OrderedDict +import threading +from threading import Thread + +import numpy + +from cam_server import config +from cam_server.pipeline.data_processing.pre_processor import process_image as pre_process_image +from cam_server.utils import init_statistics +from cam_server.writer import LAYOUT_DEFAULT, LOCALTIME_DEFAULT, CHANGE_DEFAULT +from cam_server.pipeline.data_processing.functions import is_number, binning, copy_image + +_logger = getLogger(__name__) + + +def run(stop_event, statistics, parameter_queue, cam_client, pipeline_config, output_stream_port, + background_manager, user_scripts_manager=None): + + camera_name = pipeline_config.get_camera_name() + set_log_tag(" [" + str(camera_name) + " | " + str(pipeline_config.get_name()) + ":" + str(output_stream_port) + "]") + exit_code = 0 + + def process_bsbuffer(bs_buffer, bs_img_buffer): + i = 0 + while i < len(bs_buffer): + bs_pid, bsdata = bs_buffer[i] + for j in range(len(bs_img_buffer)): + img_pid = bs_img_buffer[0][0] + if img_pid < bs_pid: + bs_img_buffer.popleft() + elif img_pid == bs_pid: + [pulse_id, [global_timestamp, image, x_axis, y_axis, additional_data]] = bs_img_buffer.popleft() + stream_data = OrderedDict() + stream_data.update(bsdata) + for key, value in bsdata.items(): + stream_data[key] = value.value + if additional_data is not None: + try: + stream_data.update(additional_data) + except: + pass + process_data(process_image, pulse_id, global_timestamp, image,x_axis, y_axis, stream_data) + for k in range(i): + bs_buffer.popleft() + i = -1 + break + else: + break + i = i + 1 + + def bs_send_task(bs_buffer, bs_img_buffer, stop_event): + global sender + if number_processing_threads <= 0: + _logger.info("Start bs send thread") + sender = create_sender(output_stream_port, stop_event) + try: + with connect_to_stream() as stream: + while not stop_event.is_set(): + message = stream.receive() + if not message or stop_event.is_set(): + if abort_on_timeout(): + stop_event.set() + continue + bs_buffer.append([message.data.pulse_id, message.data.data]) + try: + process_bsbuffer(bs_buffer, bs_img_buffer) + except Exception as e: + _logger.error("Error processing bs buffer: " + str(e)) + + except Exception as e: + _logger.error("Error on bs_send_task: " + str(e)) + finally: + stop_event.set() + if sender: + try: + sender.close() + except: + pass + _logger.info("Exit bs send thread") + + + def process_pipeline_parameters(): + parameters = get_parameters() + _logger.debug("Processing pipeline parameters %s. %s" % (parameters, log_tag)) + + background_array = None + if parameters.get("image_background_enable"): + background_id = pipeline_config.get_background_id() + _logger.debug("Image background enabled. Using background_id %s. %s" %(background_id, log_tag)) + + try: + background_array = background_manager.get_background(background_id) + parameters["image_background_ok"] = True + except: + _logger.warning("Invalid background_id: %s. %s" % (background_id, log_tag)) + #if abort_on_error(): + # raise + parameters["image_background_ok"] = False + if background_array is not None: + background_array = background_array.astype("uint16",copy=False) + + size_x, size_y = cam_client.get_camera_geometry(pipeline_config.get_camera_name()) + + by, bx = int(parameters.get("binning_y", 1)), int(parameters.get("binning_x", 1)) + bm = parameters.get("binning_mean", False) + if (by > 1) or (bx > 1): + size_x, size_y = int(size_x / bx), int(size_y / by) + if background_array is not None: + background_array, _, _ = binning(background_array, None, None, bx, by, bm) + if background_array.shape != (size_y, size_x): + _logger.warning("Bad background shape: %s instead of %s. %s" % (image_background_array.shape, (size_y, size_x), log_tag)) + + image_region_of_interest = parameters.get("image_region_of_interest") + if image_region_of_interest: + _, size_x, _, size_y = image_region_of_interest + + if size_x and size_y: + _logger.debug("Image width %d and height %d. %s" % (size_x, size_y, log_tag)) + + + if parameters.get("rotation"): + if not isinstance(parameters.get("rotation"), dict): + parameters["rotation"] = {"angle":float(parameters.get("rotation")), "order":1, "mode":"0.0"} + if not parameters["rotation"].get("angle"): + parameters["rotation"] = None + elif not is_number(parameters["rotation"]["angle"]) or (float(parameters["rotation"]["angle"]) == 0): + parameters["rotation"] = None + else: + if not parameters["rotation"].get("order"): + parameters["rotation"]["order"] = 1 + if not parameters["rotation"].get("mode"): + parameters["rotation"]["mode"] = "0.0" + + if parameters.get("averaging"): + try: + parameters["averaging"] = int(parameters.get("averaging")) + except: + parameters["averaging"] = None + + if parameters["mode"] == "FILE": + if parameters.get("layout") is None: + parameters["layout"] = LAYOUT_DEFAULT + if parameters.get("localtime") is None: + parameters["localtime"] = LOCALTIME_DEFAULT + if parameters.get("change") is None: + parameters["change"] = CHANGE_DEFAULT + + if parameters.get("bsread_address"): + if parameters.get("bsread_image_buf"): + parameters["bsread_image_buf"] = min(parameters.get("bsread_image_buf"), config.BSREAD_IMAGE_BUFFER_SIZE_MAX) + else: + parameters["bsread_image_buf"] =config.BSREAD_IMAGE_BUFFER_SIZE_DEFAULT + + if parameters.get("bsread_data_buf"): + parameters["bsread_data_buf"] = min(parameters.get("bsread_data_buf"), config.BSREAD_DATA_BUFFER_SIZE_MAX) + else: + parameters["bsread_data_buf"] =config.BSREAD_DATA_BUFFER_SIZE_DEFAULT + + return parameters, background_array + + + + def process_image(pulse_id, global_timestamp, function, image, x_axis, y_axis, bsdata): + pars = get_parameters() + try: + image, x_axis, y_axis = pre_process_image(image, pulse_id, global_timestamp, x_axis, y_axis, pars, image_background_array) + processed_data = function(image, pulse_id, global_timestamp, x_axis, y_axis, pars, bsdata) + #print("Processing PID %d at proc %d thread %d" % (pulse_id, os.getpid(), threading.get_ident())) + return processed_data + except Exception as e: + _logger.warning("Error processing PID %d at proc %d thread %d: %s" % (pulse_id, os.getpid(), threading.get_ident(), str(e))) + if abort_on_error(): + raise + + + bs_buffer, bs_img_buffer, bs_send_thread = None, None, None + + try: + init_statistics(statistics) + + init_pipeline_parameters(pipeline_config, parameter_queue, user_scripts_manager, process_pipeline_parameters) + pipeline_parameters, image_background_array = process_pipeline_parameters() + connect_to_camera(cam_client) + + _logger.debug("Opening output stream on port %d. %s" % (output_stream_port, log_tag)) + + # Indicate that the startup was successful. + stop_event.clear() + + image_with_stream = has_stream() + + if image_with_stream: + bs_buffer = deque(maxlen=pipeline_parameters["bsread_data_buf"]) + bs_img_buffer = deque(maxlen=pipeline_parameters["bsread_image_buf"]) + bs_send_thread = Thread(target=bs_send_task, args=(bs_buffer, bs_img_buffer,stop_event)) + bs_send_thread.start() + if number_processing_threads > 0: + setup_sender(output_stream_port, stop_event, process_image, user_scripts_manager) + else: + setup_sender(output_stream_port, stop_event, process_image, user_scripts_manager) + + _logger.debug("Transceiver started. %s" % (log_tag)) + last_sent_timestamp = 0 + + image_buffer = [] + while not stop_event.is_set(): + try: + ret = check_parameters_changes() + if ret is not None: + pipeline_parameters, image_background_array = ret + + assert_function_defined() + + pulse_id, global_timestamp, data = receive_stream(True) + + if not data: + continue + + image = data["image"].value + if image is None: + continue + + x_axis = data["x_axis"].value + y_axis = data["y_axis"].value + + if pipeline_parameters.get("rotation"): + if pipeline_parameters["rotation"]["mode"] == "ortho": + rotation_angle = int(pipeline_parameters["rotation"]["angle"] / 90) % 4 + if rotation_angle==1: + x_axis,y_axis = y_axis, numpy.flip(x_axis) + if rotation_angle == 2: + x_axis, y_axis = numpy.flip(x_axis), numpy.flip(y_axis) + if rotation_angle == 3: + x_axis, y_axis = numpy.flip(y_axis), x_axis + + averaging = pipeline_parameters.get("averaging") + if averaging: + continuous = averaging < 0 + averaging = abs(averaging) + if continuous and (len(image_buffer) >= averaging): + image_buffer.pop(0) + image_buffer.append(image) + if (len(image_buffer) >= averaging) or (continuous): + try: + frames = numpy.array(image_buffer) + image = numpy.average(frames, 0) + except: + #Different shapes + image_buffer = [] + continue + else: + continue + else: + if pipeline_parameters.get("copy"): + image = copy_image(image) + + if (not averaging) or (not continuous): + image_buffer = [] + + #Check maximum frame rate parameter + max_frame_rate = pipeline_parameters.get("max_frame_rate") + if max_frame_rate: + min_interval = 1.0 / max_frame_rate + if (time.time() - last_sent_timestamp) < min_interval: + continue + + additional_data = {} + if len(data) != len(config.CAMERA_STREAM_REQUIRED_FIELDS): + for key, value in data.items(): + if not key in config.CAMERA_STREAM_REQUIRED_FIELDS: + additional_data[key] = value.value + + pars = [global_timestamp, image, x_axis, y_axis, additional_data] + if image_with_stream: + bs_img_buffer.append([pulse_id, pars]) + else: + process_data(process_image, pulse_id, *pars) + last_sent_timestamp = time.time() + except ProcessingCompleted: + break + except Exception as e: + exit_code = 2 + _logger.exception("Could not process message %s: %s" % (log_tag, str(e))) + break + + except Exception as e: + exit_code = 1 + _logger.exception("Exception while trying to start the receive and process thread %s: %s" % (log_tag, str(e))) + raise + + finally: + _logger.info("Stopping transceiver. %s" % log_tag) + stop_event.set() + if bs_send_thread: + try: + bs_send_thread.join(0.1) + except: + pass + cleanup() + _logger.debug("Exiting process. %s" % log_tag) + sys.exit(exit_code) diff --git a/script/test/import_zmqw.py b/script/test/import_zmqw.py new file mode 100644 index 0000000..405b2e9 --- /dev/null +++ b/script/test/import_zmqw.py @@ -0,0 +1,24 @@ +from imp import load_package + +try: + load_package("zmq","/Users/gobbo_a/opt/anaconda3/envs/pide/lib/python3.8/site-packages/zmq") +except: + pass + + + +import zmq.backend +import zmq.utils +import zmq.sugar +#import zmq.PUB +#import zmq.Poller +#import zmq._future + + + +load_package("zmq","/Users/gobbo_a/opt/anaconda3/envs/pide/lib/python3.8/site-packages/zmq") + + +#from cam_server import CameraClient + + diff --git a/script/test/test_pipeline1.py b/script/test/test_pipeline1.py new file mode 100644 index 0000000..90a7d2d --- /dev/null +++ b/script/test/test_pipeline1.py @@ -0,0 +1,15 @@ +import base64 +import numpy + +#"localhost:5554” +pipeline_client = PipelineClient("http://0.0.0.0:8889") +instance_id, pipeline_stream_address = pipeline_client.create_instance_from_name("simulation_sp", "simulation_sp3") +pipeline_host, pipeline_port = get_host_port_from_stream_address(pipeline_stream_address) + +# Subscribe to the stream. +with source(host=pipeline_host, port=pipeline_port, mode=SUB) as stream: + # Receive next message. + data = stream.receive() + + + \ No newline at end of file diff --git a/script/test/test_proc.py b/script/test/test_proc.py new file mode 100644 index 0000000..8d9768b --- /dev/null +++ b/script/test/test_proc.py @@ -0,0 +1,9 @@ +from multiprocessing import Process + +def f(name): + print('hello', name) + + +p = Process(target=f, args=('bob',)) +p.start() +p.join() \ No newline at end of file diff --git a/script/test/test_stream_out.py b/script/test/test_stream_out.py new file mode 100644 index 0000000..7e39898 --- /dev/null +++ b/script/test/test_stream_out.py @@ -0,0 +1,35 @@ +#stop_event = multiprocessing.Event() +#parameter_queue = multiprocessing.Queue() +#manager = multiprocessing.Manager() +#statistics = manager.Namespace() + +stop_event = threading.Event() +parameter_queue = queue.Queue() +statistics=Namespace() + + +OUTPUT_PORT = 12005 + +viewer.show_stream("tcp://localhost:" + str(OUTPUT_PORT)) + +pipeline_config = PipelineConfig("test_pipeline", parameters={"camera_name": "simulation", "function":"transparent"}) + +def send(): + print ("Startint pipeline on port: ", OUTPUT_PORT) + try: + processing_pipeline(stop_event, statistics, parameter_queue, camera_client, pipeline_config, OUTPUT_PORT, MockBackgroundManager()) + except: + traceback.print_exc() + + +thread = Thread(target=send) +thread.start() + +with source(host="127.0.0.1", port=OUTPUT_PORT, mode=SUB, receive_timeout = 3000) as stream: + data = stream.receive() + if not data: + raise Exception("Received None message.") + print (data.data.data.keys()) + +stop_event.set() +thread.join(5.0) diff --git a/script/tools/dump_camera_stream.py b/script/tools/dump_camera_stream.py new file mode 100644 index 0000000..9952639 --- /dev/null +++ b/script/tools/dump_camera_stream.py @@ -0,0 +1,19 @@ + +url="tcp://localhost:10100" + + +st1 = Stream("st1", Provider("provider", url, False)) +st1.initialize() +st1.start() +st1.waitCacheChange(20000) + + +try: + bscan (st1, 5, 5, save=False) +finally: + st1.close() + +try: + print (st1.getValues()) +finally: + st1.close()