diff --git a/devices/CurrentCamera.properties b/devices/CurrentCamera.properties index eb603d1..f10afe0 100644 --- a/devices/CurrentCamera.properties +++ b/devices/CurrentCamera.properties @@ -1,10 +1,10 @@ -#Fri Jul 07 14:47:24 CEST 2017 +#Mon Jul 10 15:31:47 CEST 2017 colormap=Flame -colormapAutomatic=false -colormapMax=NaN -colormapMin=NaN +colormapAutomatic=true +colormapMax=29058.0 +colormapMin=0.0 flipHorizontally=false -flipVertically=true +flipVertically=false grayscale=false imageHeight=1680 imageWidth=1744 @@ -21,9 +21,9 @@ rotation=0.0 rotationCrop=false scale=1.0 serverURL=localhost\:10000 -spatialCalOffsetX=-861.0 -spatialCalOffsetY=-820.0 -spatialCalScaleX=-18.90359168241966 -spatialCalScaleY=-19.37984496124031 +spatialCalOffsetX=-861.4939970777481 +spatialCalOffsetY=-820.4883730911062 +spatialCalScaleX=-18.90359092620482 +spatialCalScaleY=-19.37984500632817 spatialCalUnits=mm transpose=false diff --git a/plugins/ScreenPanel.form b/plugins/ScreenPanel.form index f185ced..21f7673 100644 --- a/plugins/ScreenPanel.form +++ b/plugins/ScreenPanel.form @@ -490,7 +490,7 @@ - + @@ -512,7 +512,7 @@ - + @@ -636,6 +636,9 @@ + + + diff --git a/plugins/ScreenPanel.java b/plugins/ScreenPanel.java index 44489e2..1f1e2af 100644 --- a/plugins/ScreenPanel.java +++ b/plugins/ScreenPanel.java @@ -916,16 +916,23 @@ public class ScreenPanel extends Panel { buttonFullRange.setSelected(true); } else if (config.colormapAutomatic) { buttonAutomatic.setSelected(true); - } else { + } else { buttonManual.setSelected(true); } + btFixColormapRange.setVisible(buttonAutomatic.isSelected()); //spinnerMin.setVisible(buttonManual.isSelected()); labelMin.setVisible(spinnerMin.isVisible()); //spinnerMax.setVisible(buttonManual.isSelected()); labelMax.setVisible(spinnerMax.isVisible()); spinnerMin.setEnabled(buttonManual.isSelected()); spinnerMax.setEnabled(buttonManual.isSelected()); - spinnerMin.setValue(Double.isNaN(config.colormapMin) ? 0 : Math.min(Math.max((int) config.colormapMin, 0), 65535)); - spinnerMax.setValue(Double.isNaN(config.colormapMax) ? 0 : Math.min(Math.max((int) config.colormapMax, 0), 65535)); + //spinnerMin.setValue(Double.isNaN(config.colormapMin) ? 0 : Math.min(Math.max((int) config.colormapMin, 0), 65535)); + //spinnerMax.setValue(Double.isNaN(config.colormapMax) ? 0 : Math.min(Math.max((int) config.colormapMax, 0), 65535)); + if (!Double.isNaN(config.colormapMin) ){ + spinnerMin.setValue(Math.min(Math.max((int) config.colormapMin, 0), 65535)); + } + if (!Double.isNaN(config.colormapMax) ){ + spinnerMax.setValue(Math.min(Math.max((int) config.colormapMax, 0), 65535)); + } } } catch (Exception ex) { ex.printStackTrace(); @@ -2283,6 +2290,11 @@ public class ScreenPanel extends Panel { 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 jPanel2Layout = new javax.swing.GroupLayout(jPanel2); jPanel2.setLayout(jPanel2Layout); @@ -2310,7 +2322,7 @@ public class ScreenPanel extends Panel { .addComponent(labelMin) .addGap(2, 2, 2) .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) - .addComponent(btFixColormapRange, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .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()) ); @@ -2331,7 +2343,7 @@ public class ScreenPanel extends Panel { .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(buttonAutomatic) .addComponent(jLabel4) - .addComponent(btFixColormapRange)) + .addComponent(btFixColormapRange, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE)) .addGap(0, 0, 0) .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER) .addComponent(labelMin) @@ -2827,7 +2839,7 @@ public class ScreenPanel extends Panel { renderer.setPenReticle(new Pen(colorReticule)); renderer.setPenProfile(new Pen(colorReticule, 0)); renderer.setPenMarker(new Pen(colorMarker, 2)); - renderer.setShowReticle(false); + renderer.setShowReticle(false); checkReticle(); source.getConfig().colormapAutomatic = buttonAutomatic.isSelected(); source.getConfig().colormapMin = buttonFullRange.isSelected() ? Double.NaN : (Integer) spinnerMin.getValue(); @@ -3060,6 +3072,21 @@ public class ScreenPanel extends Panel { } }//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 + // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton btFixColormapRange; private javax.swing.JButton buttonArgs; diff --git a/plugins/back/ScreenPanel.form b/plugins/back/ScreenPanel.form new file mode 100644 index 0000000..f185ced --- /dev/null +++ b/plugins/back/ScreenPanel.form @@ -0,0 +1,954 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/plugins/back/ScreenPanel.java b/plugins/back/ScreenPanel.java new file mode 100644 index 0000000..44489e2 --- /dev/null +++ b/plugins/back/ScreenPanel.java @@ -0,0 +1,3128 @@ +/* + * Copyright (c) 2014 Paul Scherrer Institute. All rights reserved. + */ + +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.Camtool; +import ch.psi.pshell.bs.StreamValue; +import ch.psi.pshell.device.DescStatsDouble; +import ch.psi.pshell.device.Device; +import ch.psi.pshell.epics.ChannelInteger; +import ch.psi.pshell.epics.DiscretePositioner; +import ch.psi.pshell.epics.Epics; +import ch.psi.pshell.imaging.Calibration; +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.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.ValueSelection; +import ch.psi.pshell.swing.ValueSelection.ValueSelectionListener; +import ch.psi.utils.Arr; +import ch.psi.utils.ArrayProperties; +import ch.psi.utils.Convert; +import ch.psi.utils.TcpClient; +import ch.psi.utils.swing.Editor.EditorDialog; +import ch.psi.utils.swing.MainFrame; +import ch.psi.utils.swing.StandardDialog; +import ch.psi.utils.swing.SwingUtils.OptionResult; +import ch.psi.utils.swing.SwingUtils.OptionType; +import java.awt.BorderLayout; +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.event.ActionEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.awt.image.BufferedImage; +import java.io.FileInputStream; +import java.lang.reflect.Array; +import java.lang.reflect.Field; +import java.net.ServerSocket; +import java.nio.file.Files; +import java.nio.file.Path; +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.JComboBox; +import javax.swing.JDialog; +import javax.swing.JLabel; +import javax.swing.JMenuItem; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTable; +import javax.swing.JTextField; +import javax.swing.ListSelectionModel; +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.WeightedObservedPoint; +import org.apache.commons.math3.stat.descriptive.DescriptiveStatistics; + +/** + * + */ +public class ScreenPanel extends Panel { + + final String CAMERA_DEVICE_NAME = "CurrentCamera"; + boolean useCamtoolStats = true; + + String userOverlaysConfigFile; + ColormapSource camera; + String cameraName; + String cameraConfigJson; + 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; + Integer localServerPort; + Process privateServer; + String serverUrl; + boolean goodRegion; + + Double getCamtoolDouble(String name) { + return (Double) Convert.toDouble(((Camtool) camera).getValue(name)); + } + + double[] getCamtoolDoubleArray(String name) { + return (double[]) Convert.toDouble(((Camtool) camera).getValue(name)); + } + + Double getCamtoolDouble(String name, StreamValue cache) { + return (Double) Convert.toDouble(cache.__getitem__(name)); + } + + double[] getCamtoolDoubleArray(String name, StreamValue cache) { + return (double[]) Convert.toDouble(cache.__getitem__(name)); + } + + + class ImageData { + ImageData(){ + if (camera instanceof Camtool) { + StreamValue cache = ((Camtool) camera).getStream().take(); + + String prefix = goodRegion ? "gr_" : ""; + x_fit_mean = getCamtoolDouble(prefix + "x_fit_mean", cache); + y_fit_mean = getCamtoolDouble(prefix + "y_fit_mean", cache); + x_fit_standard_deviation = getCamtoolDouble(prefix + "x_fit_standard_deviation", cache); + y_fit_standard_deviation = getCamtoolDouble(prefix + "y_fit_standard_deviation", cache); + x_fit_gauss_function = getCamtoolDoubleArray(prefix +"x_fit_gauss_function", cache); + y_fit_gauss_function = getCamtoolDoubleArray(prefix +"y_fit_gauss_function", cache); + x_profile = getCamtoolDoubleArray("x_profile", cache); + y_profile = getCamtoolDoubleArray("y_profile", cache); + x_center_of_mass = getCamtoolDouble("x_center_of_mass", cache); + y_center_of_mass = getCamtoolDouble("y_center_of_mass", cache); + x_rms = getCamtoolDouble("x_rms", cache); + y_rms = getCamtoolDouble("y_rms", cache); + if (goodRegion){ + double[] gX2 = new double[x_profile.length]; + Arrays.fill(gX2, Double.NaN); + try{ + double x = getCamtoolDoubleArray("gr_x_axis", cache)[0]; + System.arraycopy(x_fit_gauss_function, 0, gX2, (int) ((renderer.getCalibration() != null) ? renderer.getCalibration().convertToImageX(x): x), x_fit_gauss_function.length); + } catch (Exception ex){ + } + x_fit_gauss_function = gX2; + double[] gY2 = new double[y_profile.length]; + Arrays.fill(gY2, Double.NaN); + try{ + double y = getCamtoolDoubleArray("gr_y_axis", cache)[0]; + System.arraycopy(y_fit_gauss_function, 0, gY2, (int) ((renderer.getCalibration() != null) ? renderer.getCalibration().convertToImageY(y): y), y_fit_gauss_function.length); + } catch (Exception ex){ + } + y_fit_gauss_function = gY2; + } + } + } + public Double x_fit_mean; + public Double y_fit_mean; + public Double x_center_of_mass; + public Double x_rms; + public Double x_fit_standard_deviation; + public Double y_fit_standard_deviation; + public Double y_center_of_mass; + public Double y_rms; + public double[] x_profile; + public double[] x_fit_gauss_function; + public double[] y_profile; + public double[] y_fit_gauss_function; + + } + + class Frame extends ImageData{ + + Frame(Data data) { + this.data = data; + } + Data data; + } + + final ArrayList imageBuffer = new ArrayList(); + Frame currentFrame; + int imageBufferLenght = 0; + Text imageBufferOverlay; + + public ScreenPanel() { + initComponents(); + spinnerThreshold.setVisible(false); + btFixColormapRange.setVisible(false); + spinnerGrThreshold.setVisible(false); labelGrThreshold.setVisible(false); + spinnerGrScale.setVisible(false); labelGrScale.setVisible(false); + //spinnerMin.setVisible(false); labelMin.setVisible(false); + //spinnerMax.setVisible(false); labelMax.setVisible(false); + renderer.setPersistenceFile(Paths.get(getContext().getSetup().getContextPath(), "Renderer_Cameras.bin")); + setPersistedComponents(new Component[]{buttonCamtool, buttonDirect}); + comboCameras.setEnabled(false); + 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("priv_srv")) { + try { + try(ServerSocket s = new ServerSocket(0)){ + localServerPort = s.getLocalPort(); + } + } catch (Exception ex) { + ex.printStackTrace(); + } + } + + if (App.hasArgument("srv_port")) { + localServerPort = Integer.valueOf(App.getArgumentValue("srv_port")); + } + + if (App.hasArgument("srv_url")) { + serverUrl = App.getArgumentValue("srv_url"); + } + + if (App.hasArgument("calc")) { + useCamtoolStats = false; + } + + renderer.setProfileNormalized(true); + renderer.setShowProfileLimits(false); + + JMenuItem menuCalibrate = new JMenuItem("Calibrate..."); + menuCalibrate.addActionListener((ActionEvent e) -> { + try { + calibrate(); + } catch (Exception ex) { + showException(ex); + } + }); + + JMenuItem menuShowImageData = new JMenuItem("Show Image Data"); + menuShowImageData.addActionListener((ActionEvent e) -> { + try { + showImageData(); + } catch (Exception ex) { + showException(ex); + } + }); + + JMenuItem menuSaveStack = new JMenuItem("Save Stack"); + menuSaveStack.addActionListener((ActionEvent e) -> { + try { + saveStack(); + } catch (Exception ex) { + showException(ex); + } + }); + menuSaveStack.setEnabled(imageBufferLenght > 0); + + JMenuItem menuSetROI = new JMenuItem("Set ROI..."); + menuSetROI.addActionListener((ActionEvent e) -> { + renderer.abortSelection(); + if (camera instanceof Camtool) { + 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 (((Camtool) camera).isRoiEnabled()) { + int[] cur = ((Camtool) camera).getRoi(); + ((Camtool) camera).setRoi(new int[]{roi.x + cur[0], roi.y + cur[1], roi.width, roi.height}); + } else { + ((Camtool) camera).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 (camera instanceof Camtool) { + try { + renderer.setShowReticle(false); + ((Camtool) camera).resetRoi(); + } catch (IOException ex) { + showException(ex); + } + } + }); + + renderer.getPopupMenu().add(menuShowImageData); + renderer.getPopupMenu().add(menuCalibrate); + renderer.getPopupMenu().add(menuSaveStack); + renderer.getPopupMenu().addSeparator(); + renderer.getPopupMenu().add(menuSetROI); + renderer.getPopupMenu().add(menuResetROI); + renderer.getPopupMenu().addPopupMenuListener(new PopupMenuListener() { + @Override + public void popupMenuWillBecomeVisible(PopupMenuEvent e) { + menuResetROI.setEnabled(camera instanceof Camtool); + menuSetROI.setEnabled(camera instanceof Camtool); + menuShowImageData.setVisible(camera instanceof Camtool); + menuCalibrate.setVisible(camera instanceof Camtool); + menuCalibrate.setEnabled(calibrationOverlays==null); + } + + @Override + public void popupMenuWillBecomeInvisible(PopupMenuEvent e) { + } + + @Override + public void popupMenuCanceled(PopupMenuEvent e) { + } + }); + renderer.getPopupMenu().setVisible(false); + + 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(); + } + } + }); + imageBufferOverlay = new Text(renderer.getPenErrorText(), "", new Font("Verdana", Font.PLAIN, 12), new Point(-100, 20)); + imageBufferOverlay.setFixed(true); + imageBufferOverlay.setAnchor(Overlay.ANCHOR_VIEWPORT_TOP_RIGHT); + if (MainFrame.isDark()) { + textState.setEnabled(true); + } + } + + @Override + public void onStart() { + super.onStart(); + if (App.hasArgument("ct")) { + boolean direct = App.getArgumentValue("ct").equals("0") || App.getArgumentValue("ct").equalsIgnoreCase("false"); + buttonCamtool.setSelected(!direct); + buttonDirect.setSelected(direct); + } + if (App.hasArgument("priv_srv")) { + try { + System.out.println("Starting camtool server on port: " + localServerPort); + //Was creating sub-processes which cannot be destroyed. + //String cmd = "cam_server"; + //cmd = "source /opt/gfa/python\n" + cmd; + //privateServer = Runtime.getRuntime().exec(new String[]{"bash", "-c", cmd}); + String cmd = "/opt/gfa/python-3.5/2.4.1/bin/python /opt/gfa/python-3.5/latest/bin/cam_server"; + String configFolder = (String) getContext().getClassByName("SfCamera").getMethod("getConfigFolder", new Class[]{}).invoke(null); + cmd = cmd + " -p " + localServerPort + " -b " + configFolder; + privateServer = Runtime.getRuntime().exec(cmd); + //System.out.println("pid = " + Sys.getPid(privateServer)); + long start = System.currentTimeMillis(); + while (true){ + try (TcpClient c = new TcpClient("localhost", localServerPort)){ + try{ + c.connect(); + System.out.println("Connected to camtool server on port: " + localServerPort); + break; + } catch (Exception ex){ + } + } + Thread.sleep(10); + if ((System.currentTimeMillis() - start) > 5000){ + errorOverlay = new Text(renderer.getPenErrorText(), "Error connecting to server at port " + localServerPort , new Font("Verdana", Font.PLAIN, 12), new Point(20, 20)); + renderer.addOverlay(errorOverlay); + break; + } + } + } catch (Exception ex) { + ex.printStackTrace(); + } + } + + } + + + + @Override + public void onStop() { + try{ + if (camera != null) { + camera.close(); + camera = null; + } + if (privateServer!=null){ + System.out.println("Closing camtool server"); + //int pid = Sys.getPid(privateServer); + privateServer.destroyForcibly(); + //if (pid>0){ + // System.out.println("Killing pid = " + pid); + // Runtime.getRuntime().exec("kill " + pid); + // + //} + privateServer = null; + } + } catch (Exception ex) { + ex.printStackTrace(); + } + super.onStop(); + } + + //Overridable callbacks + @Override + public void onInitialize(int runCount) { + comboCameras.setEnabled(false); + if (App.hasArgument("s")) { + 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 excptn) { + } + } + ); + + } else { + usingCamtool = buttonCamtool.isSelected(); + updateCameraList(); + comboCameras.setEnabled(true); + setComboCameraSelection(-1); + + if (comboCameras.getModel().getSize() > 0) { + try { + if (App.hasArgument("cam")) { + setComboCameraSelection(App.getArgumentValue("cam")); + comboCamerasActionPerformed(null); + } + } catch (Exception ex) { + ex.printStackTrace(); + } + } + } + startTimer(1000); + } + + DefaultComboBoxModel getCameraListFromFolder() throws Exception { + ArrayList cameras = (ArrayList) getContext().getClassByName("SfCamera").getMethod("getCameras", new Class[]{}).invoke(null); + DefaultComboBoxModel model = new DefaultComboBoxModel(); + for (String cam:cameras) { + model.addElement(cam); + } + return model; + } + + DefaultComboBoxModel getCameraListFromCamtool() throws IOException, InterruptedException { + DefaultComboBoxModel model = new DefaultComboBoxModel(); + Camtool camtool = newCamtool(); + try { + camtool.initialize(); + List cameras = camtool.getCameras(); + Collections.sort(cameras); + for (String camera : cameras) { + model.addElement(camera); + } + //model.addElement(Camtool.SIMULATION); + } finally { + camtool.close(); + } + return model; + } + + Camtool newCamtool(){ + if (serverUrl!=null){ + return new Camtool(CAMERA_DEVICE_NAME, serverUrl); + } + return (localServerPort != null) ? new Camtool(CAMERA_DEVICE_NAME, "localhost:"+localServerPort) : new Camtool(CAMERA_DEVICE_NAME); + } + + boolean updatingCameraSelection; + + void setComboCameraSelection(Object selection) { + updatingCameraSelection = true; + try { + comboCameras.setSelectedItem(selection); + } finally { + updatingCameraSelection = false; + } + } + + boolean usingCamtool; + + void updateCameraList() { + try { + String selected = (String) comboCameras.getSelectedItem(); + DefaultComboBoxModel model = usingCamtool ? getCameraListFromCamtool() : getCameraListFromFolder(); + if (App.hasArgument("cam")) { + String cam = App.getArgumentValue("cam"); + if (model.getIndexOf(cam) < 0) { + model.addElement(cam); + } + } + comboCameras.setModel(model); + if (selected != null) { + setComboCameraSelection(selected); + } + } catch (Exception ex) { + ex.printStackTrace(); + } finally { + updateStop(); + } + } + + final Object lockOverlays = new Object(); + + void manageFit(BufferedImage bi, Data data) { + Overlay[][] fo = ((bi == null) || ((!showFit && !showProfile))) ? null : getFitOverlays(data); + 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; + } + } + + + @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("Setting camera: " + cameraName + " [" + (buttonCamtool.isSelected() ? "camtool" : "direct") + "]"); + parseUserOverlays(); + errorOverlay = null; + + if (dataTableDialog!=null){ + dataTableDialog.dispose(); + dataTableDialog = null; + } + dataTableModel = null; + + if (calibrationDialolg!=null){ + calibrationDialolg.dispose(); + calibrationDialolg = null; + } + + boolean was_camtool = false; + if (camera != null) { + //camera.removeAllListeners(); + was_camtool = camera instanceof Camtool; + camera.close(); + camera = null; + } + renderer.setDevice(null); + + renderer.setShowReticle(false); + renderer.removeOverlays(fitOv); + renderer.removeOverlays(profileOv); + renderer.removeOverlays(userOv); + renderer.clear(); + renderer.resetZoom(); + + boolean changed = !String.valueOf(cameraName).equals(this.cameraName); + this.cameraName = cameraName; + + if (changed || buttonDirect.isSelected()) { + spinnerThreshold.setVisible(false); + spinnerGrThreshold.setVisible(false); labelGrThreshold.setVisible(false); + spinnerGrScale.setVisible(false); labelGrScale.setVisible(false); + checkThreshold.setEnabled(false); + checkGoodRegion.setEnabled(false); + } + 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 (cameraName == null) { + return; + } + + synchronized (imageBuffer) { + currentFrame = null; + imageBuffer.clear(); + } + + + try { + String configFolder = (String) getContext().getClassByName("SfCamera").getMethod("getConfigFolder", new Class[]{}).invoke(null); + Path configFile = Paths.get(configFolder, cameraName + ".json"); + cameraConfigJson = configFile.toFile().exists() ? new String(Files.readAllBytes(configFile)) : null; + + if (buttonCamtool.isSelected()) { + camera = newCamtool(); + 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; + } else { + //camera = new SfCamera(CAMERA_DEVICE_NAME, cameraName); + camera = (ColormapSource) getContext().getClassByName("SfCamera").getConstructor(new Class[]{String.class, String.class}).newInstance(new Object[]{CAMERA_DEVICE_NAME, cameraName}); + } + camera.initialize(); + camera.assertInitialized(); + System.out.println("Camera initialization OK"); + if (camera instanceof Camtool) { + //Managing no background exception. Can be done in a better way? +// if (changed) { + ((Camtool) camera).startPipeline(cameraName, null); + updateCamtoolControls(); +// } else { +// ((Camtool) camera).startPipeline(cameraName, null, checkBackground.isSelected(), null, null, null); +// } + // HashMap gr = null; + // if (goodRegion){ + // gr = new HashMap<>(); + // gr.put("threshold", spinnerGrThreshold.getValue()); + // gr.put("gfscale", spinnerGrScale.getValue()); + // } + // ((Camtool) camera).startPipeline(cameraName, null, checkBackground.isSelected(), null, checkThreshold.isSelected() ? (Double) spinnerThreshold.getValue() : null, gr); + //} + + checkThreshold.setEnabled(true); + checkGoodRegion.setEnabled(true); + + ((Camtool) camera).startReceiver(); + } else { + checkThreshold.setSelected(false); + checkGoodRegion.setSelected(false); + if (polling <= 0) { + camera.setMonitored(true); + } else { + camera.setPolling(polling); + } + camera.setBackgroundEnabled(checkBackground.isSelected()); + } + + buttonReticle.setEnabled(camera.getConfig().isCalibrated()); + camera.getConfig().save(); + renderer.setDevice(camera); + renderer.setAutoScroll(true); + renderer.setMarker(marker); + 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); + } + } + } + } + manageFit(bi, data); + manageUserOverlays(bi, data); + } + //updateImageData(); + } + + @Override + public void onError(Object o, Exception excptn) { + } + }); + + } catch (Exception ex) { + ex.printStackTrace(); + showException(ex); + renderer.clearOverlays(); + updateCamtoolControls(); + 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) { + comboScreen.setModel(new DefaultComboBoxModel()); + comboFilter.setModel(new DefaultComboBoxModel()); + + //Parallelizing initialization + devicesInitTask = new Thread(() -> { + try { + if (cameraName.contains("DSRM")){ + screen = new DiscretePositioner("CurrentScreen", cameraName + ":POSITION_SP", cameraName + ":POSITION"); + } else { + screen = new DiscretePositioner("CurrentScreen", cameraName + ":SET_SCREEN1_POS", 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", cameraName + ":SET_FILTER", 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(); + } + + } + + 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() { + if (camera != null) { + if (buttonMarker.isSelected()) { + Dimension d = renderer.getImageSize(); + Point 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); + } + } + + 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); + } + + //spinnerMin.setVisible(buttonManual.isSelected()); labelMin.setVisible(spinnerMin.isVisible()); + //spinnerMax.setVisible(buttonManual.isSelected()); labelMax.setVisible(spinnerMax.isVisible()); + spinnerMin.setEnabled(buttonManual.isSelected()); + spinnerMax.setEnabled(buttonManual.isSelected()); + spinnerMin.setValue(Double.isNaN(config.colormapMin) ? 0 : Math.min(Math.max((int) config.colormapMin, 0), 65535)); + spinnerMax.setValue(Double.isNaN(config.colormapMax) ? 0 : Math.min(Math.max((int) config.colormapMax, 0), 65535)); + } + } catch (Exception ex) { + ex.printStackTrace(); + } + updatingColormap = false; + } + + boolean updatingCamtoolControls; + + void updateCamtoolControls() { + if ((camera != null) && (camera instanceof Camtool)) { + updatingCamtoolControls = true; + try { + checkBackground.setSelected(((Camtool) camera).getBackgroundSubtraction()); + Double threshold = ((Camtool) camera).getThreshold(); + checkThreshold.setSelected(threshold != null); + spinnerThreshold.setValue((threshold == null) ? 0 : threshold); + Map gr = ((Camtool) camera).getGoodRegion(); + checkGoodRegion.setSelected(gr != null); + if (gr != null){ + spinnerGrThreshold.setValue(gr.get("threshold")); + spinnerGrScale.setValue(gr.get("gfscale")); + } + } catch (Exception ex) { + } + goodRegion = checkGoodRegion.isSelected(); + spinnerThreshold.setVisible(checkThreshold.isSelected()); + spinnerGrThreshold.setVisible(goodRegion); labelGrThreshold.setVisible(spinnerGrThreshold.isVisible()); + spinnerGrScale.setVisible(goodRegion); labelGrScale.setVisible(spinnerGrScale.isVisible()); + updatingCamtoolControls = false; + } + } + + boolean isCameraStopped() { + if ((camera != null) && (camera instanceof Camtool)) { + if (!((Camtool) camera).isPipelineStarted()) { + return true; + } + } + return ((camera == null) || (camera.isClosed()) || !buttonStop.isEnabled()); + } + + void updateStop() { + buttonStop.setEnabled(comboCameras.getSelectedItem() != null); + buttonStop.setText(isCameraStopped() ? "Start" : "Stop"); + + } + + @Override + protected void onTimer() { + for (Device dev : new Device[]{screen, filter}) { + if (dev != null) { + dev.request(); + } + } + + textState.setText((camera == null) ? "" : camera.getState().toString()); + buttonArgs.setEnabled(camera != null); + if (App.hasArgument("s")) { + try { + ((Source) getDevice("image")).initialize(); + } catch (IOException ex) { + Logger.getLogger(ScreenPanel.class.getName()).log(Level.SEVERE, null, ex); + } catch (InterruptedException ex) { + Logger.getLogger(ScreenPanel.class.getName()).log(Level.SEVERE, null, ex); + } + } + 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); + } + if (!renderer.isPaused() && (dataTableDialog!=null) && (dataTableDialog.isShowing())){ + updateImageData(); + } + updateZoom(); + updateColormap(); + updateStop(); + buttonSave.setSelected(renderer.isSnapshotDialogVisible()); + checkHistogram.setSelected((histogramDialog != null) && (histogramDialog.isShowing())); + } + + Pen penFit = new Pen(new Color(192, 105, 0), 1); + Pen penCross = new Pen(new Color(192, 105, 0), 1); + + + Frame getCurrentFrame(){ + if ((imageBufferLenght > 1) && (renderer.isPaused())) { + int index = ((int) pauseSelection.getValue()) - 1; + synchronized (imageBuffer) { + return (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; + } + + 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; + int height = data.getHeight(); + int width = data.getWidth(); + //Double xCom=null, yCom=null; + if (data != null) { + int profileSize = renderer.getProfileSize(); + if ((useCamtoolStats) && (camera instanceof Camtool)) { + try { + + ImageData 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; + + profileSize /= 4; + if (pX != null) { + int[] x = Arr.indexesInt(pX.length); + int[] y = new int[pX.length]; + int[] p = new int[pX.length]; + List l = Arrays.asList((Double[]) Convert.toWrapperArray(pX)); + Double min = Collections.min(l); + Double max = Collections.max(l); + double minPlot = min; + double rangePlot = max - min; + + for (int i = 0; i < x.length; i++) { + if (gX != null) { + y[i] = (int) (height - 1 - (((gX[i] - minPlot) / rangePlot) * profileSize)); + } + p[i] = (int) (height - 1 - (((pX[i] - minPlot) / rangePlot) * profileSize)); + } + + if (goodRegion){ + for (int i = 0; i < x.length; i++) { + y[i] = (Double.isNaN(gX[i])) ? 100000 : y[i]; + } + } + + vgaussian = new Overlays.Polyline(penFit, x, y); + vprofile = new Overlays.Polyline(renderer.getPenProfile(), x, p); + } + + if (pY != null) { + int[] y = Arr.indexesInt(pY.length); + int[] x = new int[pY.length]; + int[] p = new int[pY.length]; + + List l = Arrays.asList((Double[]) Convert.toWrapperArray(pY)); + Double min = Collections.min(l); + Double max = Collections.max(l); + double minPlot = min; + double rangePlot = max - min; + + for (int i = 0; i < x.length; i++) { + if (gY != null) { + x[i] = (int) (((gY[i] - minPlot) / rangePlot) * profileSize); + } + p[i] = (int) (((pY[i] - minPlot) / rangePlot) * profileSize); + } + + if (goodRegion){ + for (int i = 0; i < x.length; i++) { + x[i] = (Double.isNaN(gY[i])) ? -1 :x[i]; + } + } + hgaussian = new Overlays.Polyline(penFit, x, y); + hprofile = new Overlays.Polyline(renderer.getPenProfile(), p, y); + } + } 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; + } + 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 (renderer.getCalibration() != null) { + 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; + 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, new Font(Font.MONOSPACED, 0, 14), textPosition); + textCom.setFixed(true); + textCom.setAnchor(Overlay.ANCHOR_VIEWPORT_TOP_LEFT); + } + pOv = new Overlay[]{hprofile, vprofile, textCom}; + } + 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, new Font(Font.MONOSPACED, 0, 14), showProfile ? new Point(12, 54) : 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()))); + } + fOv = new Overlay[]{hgaussian, vgaussian, cross, textFit}; + + if (goodRegion){ + try{ + double[] x = getCamtoolDoubleArray("gr_x_axis"); double[] y = getCamtoolDoubleArray("gr_y_axis"); + double x1 = x[0]; double x2 = x[x.length-1]; double y1 = y[0]; double y2 = y[y.length-1]; + Overlays.Rect goodRegionOv = new Overlays.Rect(new Pen(penFit.getColor(), 0, Pen.LineStyle.dotted)); + goodRegionOv.setCalibration(renderer.getCalibration()); + goodRegionOv.setAbsolutePosition(new PointDouble(x1, y1)); + goodRegionOv.setAbsoluteSize(new DimensionDouble(x2-x1, y2-y1)); + fOv = Arr.append(fOv, goodRegionOv); + } 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 (camera instanceof Camtool) { + 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 : getCamtoolDoubleArray(uo.channels[0]); + double[] y = (uo.channels[1].equals("null")) ? null : getCamtoolDoubleArray(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 = getCamtoolDouble(uo.channels[0]); Double y = getCamtoolDouble(uo.channels[1]); + if ((x != null) && (y !=null)) { + PointDouble position = new PointDouble(x,y); + ov.setAbsolutePosition(position); + if (!(ov instanceof Overlays.Crosshairs)) { + Double x2 = getCamtoolDouble(uo.channels[2]); Double y2 = getCamtoolDouble(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[] 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(boolean value) throws Exception { + System.out.println( "Setting laser state: " + value); + Epics.putq("SIN-TIMAST-TMA:Beam-Las-Delay-Sel", value ? 0 : 1); + Epics.putq("SIN-TIMAST-TMA:Beam-Apply-Cmd.PROC", 1); + Thread.sleep(3000); + } + + boolean getLaserState() throws Exception { + return (Epics.get("SIN-TIMAST-TMA:Beam-Las-Delay-Sel", Integer.class) == 0); + } + + 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; + BufferedImage image = camera.generateImage(data); + renderer.setImage(renderer.getOrigin(), image, data); + imageBufferOverlay.update(Chrono.getTimeStr(data.getTimestamp(), "HH:mm:ss.SSS")); + manageFit(image, data); + manageUserOverlays(image, data); + } + } + } + + void writeFrameMetadata(String path, Frame frame) throws Exception{ + getContext().getDataManager().setAttribute("/", "Camera", String.valueOf(cameraName)); + getContext().getDataManager().setAttribute("/", "Screen", String.valueOf(valueScreen.getLabel().getText())); + getContext().getDataManager().setAttribute("/", "Filter", String.valueOf(valueFilter.getLabel().getText())); + Calibration cal = renderer.getCalibration(); + getContext().getDataManager().setAttribute("/", "Calibration", cal == null ? new double[]{1,1,0,0} : + new double[]{cal.getScaleX(), cal.getScaleY(), cal.getOffsetX(), cal.getOffsetY()}); + getContext().getDataManager().setAttribute(path, "Timestamp", Chrono.getTimeStr(frame.data.getTimestamp(), "HH:mm:ss.SSS")); + if (camera instanceof Camtool){ + try{ + getContext().getDataManager().setAttribute("/", "ROI", ((Camtool) camera).getRoi()); + } catch (Exception ex){ + getContext().getDataManager().setAttribute("/", "ROI", new int[]{0,0,-1,-1}); + } + if (frame!=null){ + for (Field f:ImageData.class.getFields()){ + Object value = f.get(frame); + getContext().getDataManager().setAttribute(path, f.getName(), (value == null) ? Double.NaN : value); + } + } + for (String name : new String[]{"x_axis", "y_axis", "gr_x_axis", "gr_y_axis"}){ + double[] val = getCamtoolDoubleArray(name); + getContext().getDataManager().setAttribute("/", "GoodRegion", goodRegion); + if (val!=null){ + getContext().getDataManager().setAttribute("/", name, val); + } + } + } + } + + void saveSnapshot() throws Exception { + getContext().setExecutionPars("snapshot"); + String path = "/data"; + String snapshotFile = null; + synchronized (imageBuffer) { + Frame id = getCurrentFrame(); + if (id==null){ + throw new Exception("No current image"); + } + Object data = id.data.getMatrix(); + getContext().getDataManager().setDataset(path, data, id.data.isUnsigned()); + writeFrameMetadata(path, id); + getContext().getDataManager().closeOutput(); + //Enforce the same timestamp to data & image files. + //snapshotFile = getContext().getSetup().expandPath("{images}/{date}_{time}_snapshot.png", getContext().getExecutionPars().getStart()); + snapshotFile = getContext().getExecutionPars().getPath() + ".png"; + renderer.saveSnapshot(snapshotFile, "png", true); + } + + 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(cameraName).append(" ("). + append((camera instanceof Camtool) ? "camtool" : "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"); + if ((fitOv != null) && (fitOv.length > 5)) { + Overlays.Text text = (Overlays.Text) fitOv[5]; + message.append(text.getText()).append("\n"); + } + elog((String) comboLogbook.getSelectedItem(), "ScreenPanel Snapshot", message.toString(), new String[]{snapshotFile}); + } + //SwingUtils.showMessage(getTopLevel(), "Success", "Generated data file:\n" + getContext().getExecutionPars().getPath(), 5000); + //elog("SwissFEL commissioning data", "ScreenPanel Snapshot", message.toString(), new String[]{snapshotFile}); + } + + void saveStack() throws Exception { + getContext().setExecutionPars("snapshot"); + ArrayList x = new ArrayList<>(); + ArrayList y = new ArrayList<>(); + synchronized (imageBuffer) { + for (int i = 0; i < imageBuffer.size(); i++) { + Frame frame = imageBuffer.get(i); + String path = "/data_" + i; + getContext().getDataManager().setDataset(path, frame.data.getMatrix(), frame.data.isUnsigned()); + writeFrameMetadata(path, frame); + x.add(frame.x_fit_mean); + y.add(frame.y_fit_mean); + } + } + DescStatsDouble xs = new DescStatsDouble(x.toArray(new Double[0]), -1); + DescStatsDouble ys = new DescStatsDouble(y.toArray(new Double[0]), -1); + + getContext().getDataManager().closeOutput(); + SwingUtils.showMessage(getTopLevel(), "Success", "Generated data file:\n" + getContext().getExecutionPars().getPath(), 5000); + } + + JDialog calibrationDialolg; + Overlay[] calibrationOverlays; + void calibrate() throws IOException{ + if ( (camera instanceof Camtool) && (calibrationOverlays==null)) { + Map calibration = ((Camtool) camera).getCalibration(cameraName); + //Map calibration = (Map) ((Camtool) camera).getConfig(cameraName).get("calibration"); + ((Camtool) camera).resetRoi(); + renderer.setMode(RendererMode.Fit); + Pen pen = new Pen(new Color(128, 0, 128), 1, Pen.LineStyle.solid); + Overlays.Crosshairs top = new Overlays.Crosshairs(pen, new Dimension(-1, 1)); + Overlays.Crosshairs bottom = new Overlays.Crosshairs(pen, new Dimension(-1, 1)); + Overlays.Crosshairs left = new Overlays.Crosshairs(pen, new Dimension(1, -1)); + Overlays.Crosshairs right = new Overlays.Crosshairs(pen, new Dimension(1, -1)); + calibrationOverlays = new Overlay[]{top, bottom, left, right}; + for (Overlay ov : calibrationOverlays){ + ov.setMovable(true); + } + renderer.addOverlays(calibrationOverlays); + + try{ + List refMarker = ((List)calibration.get("reference_marker")); + Rectangle r = new Rectangle(); + left.update(new Point(Math.max((Integer)refMarker.get(0), 0), 0)); + top.update(new Point(0, Math.max((Integer)refMarker.get(1), 0))); + right.update(new Point(Math.max((Integer)refMarker.get(2), 0), 0)); + bottom.update(new Point(0, Math.max((Integer)refMarker.get(3),0))); + } catch (Exception ex){ + SwingUtils.invokeDelayed(() -> { + Dimension size = renderer.getImageSize(); + top.update(new Point(0, size.height/8)); + bottom.update(new Point(0, 7*size.height/8)); + left.update(new Point(size.width/8, 0)); + right.update(new Point(7*size.width/8, 0)); + }, 500); + } + + JPanel panel = new JPanel(new BorderLayout()); + JTextField textWidth = new JTextField(); + JTextField textHeight= new JTextField(); + if (calibration!=null){ + textWidth.setText(String.valueOf(calibration.get("reference_marker_width"))); + textHeight.setText(String.valueOf(calibration.get("reference_marker_height"))); + } + ((BorderLayout) panel.getLayout()).setVgap(10); + JPanel p1 = new JPanel(new BorderLayout()); + ((BorderLayout) p1.getLayout()).setHgap(5); + p1.add(new JLabel("Move the lines to the reference marks"), BorderLayout.NORTH); + p1.add(new JLabel("and press 'OK' to update the calibration."), BorderLayout.SOUTH); + panel.add(p1, BorderLayout.NORTH); + JPanel p2 = new JPanel(new BorderLayout()); + ((BorderLayout) p2.getLayout()).setHgap(5); + p2.add(new JLabel("Reference marker width (um): "), BorderLayout.WEST); + p2.add(textWidth, BorderLayout.EAST); + panel.add(p2, BorderLayout.CENTER); + JPanel p3 = new JPanel(new BorderLayout()); + ((BorderLayout) p3.getLayout()).setHgap(5); + p3.add(new JLabel("Reference marker height(um): "), BorderLayout.WEST); + p3.add(textHeight, BorderLayout.EAST); + panel.add(p3, BorderLayout.SOUTH); + textWidth.setPreferredSize(new Dimension(70, textWidth.getPreferredSize().height)); + textHeight.setPreferredSize(new Dimension(70, textHeight.getPreferredSize().height)); + + JOptionPane calibrationMessage = new JOptionPane(panel,JOptionPane.QUESTION_MESSAGE, JOptionPane.OK_CANCEL_OPTION, null,null, null); + calibrationDialolg = calibrationMessage.createDialog(getTopLevel(), "Calibration"); + calibrationDialolg.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); + calibrationDialolg.setModal(false); + calibrationDialolg.addWindowListener(new java.awt.event.WindowAdapter() { + @Override + public void windowClosed(WindowEvent e) { + if (calibrationOverlays!=null){ + try { + renderer.removeOverlays(calibrationOverlays); + calibrationOverlays = null; + calibrationDialolg = null; + if (calibrationMessage.getValue().equals(0)){ //If pressed OK + int x1 = Math.min(left.getPosition().x, right.getPosition().x); + int x2 = Math.max(left.getPosition().x, right.getPosition().x); + int y1 = Math.min(top.getPosition().y, bottom.getPosition().y); + int y2 = Math.max(top.getPosition().y, bottom.getPosition().y); + if ((x1!=-1) && (x2!=-1) && (y1!=-1) && (y2!=-1)){ + System.out.println("Updating " + cameraName + " calibration: " + x1 + ", "+ x2 + ", " + y1 + ", " + y2); + HashMap c = new HashMap(); + c.put("reference_marker", Arrays.asList(new Integer[]{x1, y1, x2, y2})); + if (textWidth.getText().trim().length() > 0){ + c.put("reference_marker_width", Double.valueOf(textWidth.getText())); + } + if (textHeight.getText().trim().length() > 0){ + c.put("reference_marker_height", Double.valueOf(textHeight.getText())); + } + ((Camtool) camera).setCalibration(cameraName, c); + Logger.getLogger(ScreenPanel.class.getName()).warning("Updated " + cameraName + " calibration: " + x1 + ", "+ x2 + ", " + y1 + ", " + y2); + } + } + } catch (IOException ex) { + Logger.getLogger(ScreenPanel.class.getName()).log(Level.SEVERE, null, ex); + } + } + } + @Override + public void windowDeactivated(java.awt.event.WindowEvent e) { + if (!calibrationDialolg.isShowing()){ //windowClosed is not called if window closed with ok/cancel + windowClosed(e); + } + } + }); + calibrationDialolg.setVisible(true); + } + } + + StandardDialog dataTableDialog; + DefaultTableModel dataTableModel; + void showImageData(){ + dataTableModel = null; + if (camera instanceof Camtool){ + + if ((dataTableDialog!=null) && (dataTableDialog.isShowing())){ + SwingUtils.centerComponent(getTopLevel(), dataTableDialog); + dataTableDialog.requestFocus(); + return; + } + //String msg = String.join("\n", ids); + //SwingUtils.showMessage(getTopLevel(), "Image Data", msg); + 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; + } + }; + updateImageData(); + StreamValue val = ((Camtool)camera).getStream().take(); + JTable dataTable = new JTable(dataTableModel); + dataTable.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION); + 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(); + SwingUtils.centerComponent(getTopLevel(), dataTableDialog); + dataTableDialog.setVisible(true); + dataTableDialog.addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + dataTableModel = null; + } + }); + } + } + + void updateImageData(){ + if ((dataTableModel!=null)&&(camera instanceof Camtool)){ + List ids = new ArrayList(((Camtool)camera).getValue().getIdentifiers()); + if (ids.size() != dataTableModel.getRowCount()){ + dataTableModel.setNumRows(0); + Collections.sort(ids); + for (String id : ids){ + dataTableModel.addRow(new Object[]{id, ""}); + } + } + for (int i = 0 ; i< dataTableModel.getRowCount(); i++){ + String id = String.valueOf(dataTableModel.getValueAt(i, 0)); + Object obj = ((Camtool)camera).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); + } + } + } + + //////// + @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(); + jPanel1 = new javax.swing.JPanel(); + jPanel7 = new javax.swing.JPanel(); + buttonMarker = new javax.swing.JToggleButton(); + buttonGrabBackground = new javax.swing.JButton(); + buttonSave = new javax.swing.JToggleButton(); + buttonFit = new javax.swing.JToggleButton(); + buttonReticle = new javax.swing.JToggleButton(); + buttonPause = new javax.swing.JToggleButton(); + buttonProfile = new javax.swing.JToggleButton(); + jPanel6 = new javax.swing.JPanel(); + textState = new javax.swing.JTextField(); + jLabel2 = new javax.swing.JLabel(); + comboCameras = new javax.swing.JComboBox(); + buttonConfig = new javax.swing.JButton(); + jLabel1 = new javax.swing.JLabel(); + buttonArgs = new javax.swing.JButton(); + buttonStop = new javax.swing.JButton(); + renderer = new ch.psi.pshell.imaging.Renderer(); + jPanel4 = new javax.swing.JPanel(); + jPanel3 = 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(); + jPanel2 = 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(); + jPanel5 = new javax.swing.JPanel(); + buttonCamtool = new javax.swing.JRadioButton(); + buttonDirect = new javax.swing.JRadioButton(); + panelScreen = new javax.swing.JPanel(); + valueScreen = new ch.psi.pshell.swing.DeviceValuePanel(); + comboScreen = new javax.swing.JComboBox(); + panelScreen1 = new javax.swing.JPanel(); + valueFilter = new ch.psi.pshell.swing.DeviceValuePanel(); + comboFilter = new javax.swing.JComboBox(); + pauseSelection = new ch.psi.pshell.swing.ValueSelection(); + panelScreen2 = 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(); + + setPreferredSize(new java.awt.Dimension(873, 600)); + + buttonMarker.setText("Marker"); + buttonMarker.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + buttonMarkerActionPerformed(evt); + } + }); + + buttonGrabBackground.setText("Grab Background"); + buttonGrabBackground.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + buttonGrabBackgroundActionPerformed(evt); + } + }); + + buttonSave.setText("Save Snapshot"); + buttonSave.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + buttonSaveActionPerformed(evt); + } + }); + + buttonFit.setSelected(true); + buttonFit.setText("Fit"); + buttonFit.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + buttonFitActionPerformed(evt); + } + }); + + buttonReticle.setSelected(true); + buttonReticle.setText("Reticle"); + buttonReticle.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + buttonReticleActionPerformed(evt); + } + }); + + buttonPause.setText("Pause"); + buttonPause.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + buttonPauseActionPerformed(evt); + } + }); + + buttonProfile.setSelected(true); + buttonProfile.setText("Profile"); + buttonProfile.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + buttonProfileActionPerformed(evt); + } + }); + + javax.swing.GroupLayout jPanel7Layout = new javax.swing.GroupLayout(jPanel7); + jPanel7.setLayout(jPanel7Layout); + jPanel7Layout.setHorizontalGroup( + jPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel7Layout.createSequentialGroup() + .addGap(0, 0, 0) + .addComponent(buttonPause) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(buttonMarker) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(buttonProfile) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(buttonFit) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(buttonReticle) + .addGap(18, 18, Short.MAX_VALUE) + .addComponent(buttonGrabBackground) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(buttonSave) + .addGap(0, 0, 0)) + ); + + jPanel7Layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {buttonFit, buttonMarker, buttonPause, buttonProfile, buttonReticle}); + + jPanel7Layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {buttonGrabBackground, buttonSave}); + + jPanel7Layout.setVerticalGroup( + jPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel7Layout.createSequentialGroup() + .addGap(0, 0, 0) + .addGroup(jPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(buttonPause) + .addComponent(buttonFit) + .addComponent(buttonMarker) + .addComponent(buttonSave) + .addComponent(buttonReticle) + .addComponent(buttonGrabBackground) + .addComponent(buttonProfile)) + .addGap(0, 0, 0)) + ); + + textState.setEditable(false); + textState.setHorizontalAlignment(javax.swing.JTextField.CENTER); + textState.setDisabledTextColor(new java.awt.Color(0, 0, 0)); + textState.setEnabled(false); + + jLabel2.setText("State:"); + + comboCameras.setMaximumRowCount(30); + comboCameras.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + comboCamerasActionPerformed(evt); + } + }); + + buttonConfig.setText("Config"); + buttonConfig.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + buttonConfigActionPerformed(evt); + } + }); + + jLabel1.setText("Camera:"); + + buttonArgs.setText("Setup"); + buttonArgs.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + buttonArgsActionPerformed(evt); + } + }); + + buttonStop.setText("Stop"); + buttonStop.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + buttonStopActionPerformed(evt); + } + }); + + javax.swing.GroupLayout jPanel6Layout = new javax.swing.GroupLayout(jPanel6); + jPanel6.setLayout(jPanel6Layout); + jPanel6Layout.setHorizontalGroup( + jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel6Layout.createSequentialGroup() + .addGap(0, 0, 0) + .addComponent(jLabel1) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(comboCameras, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(buttonArgs) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(buttonConfig) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(buttonStop) + .addGap(18, 18, 18) + .addComponent(jLabel2) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(textState, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(0, 0, 0)) + ); + + jPanel6Layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {buttonArgs, buttonConfig, buttonStop}); + + jPanel6Layout.setVerticalGroup( + jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel6Layout.createSequentialGroup() + .addGap(0, 0, 0) + .addGroup(jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel1) + .addComponent(comboCameras, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel2) + .addComponent(textState, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(buttonArgs) + .addComponent(buttonConfig) + .addComponent(buttonStop)) + .addGap(0, 0, 0)) + ); + + jPanel6Layout.linkSize(javax.swing.SwingConstants.VERTICAL, new java.awt.Component[] {comboCameras, textState}); + + javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); + jPanel1.setLayout(jPanel1Layout); + jPanel1Layout.setHorizontalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup() + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(renderer, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jPanel7, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jPanel6, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap()) + ); + jPanel1Layout.setVerticalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addContainerGap() + .addComponent(jPanel6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(renderer, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jPanel7, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap()) + ); + + jPanel3.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 jPanel3Layout = new javax.swing.GroupLayout(jPanel3); + jPanel3.setLayout(jPanel3Layout); + jPanel3Layout.setHorizontalGroup( + jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel3Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel3Layout.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(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(buttonZoom025) + .addComponent(buttonZoom05) + .addComponent(buttonZoom2)) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + jPanel3Layout.setVerticalGroup( + jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel3Layout.createSequentialGroup() + .addGap(4, 4, 4) + .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER) + .addComponent(buttonZoomNormal) + .addComponent(buttonZoom025)) + .addGap(0, 0, 0) + .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER) + .addComponent(buttonZoomFit) + .addComponent(buttonZoom05)) + .addGap(0, 0, 0) + .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER) + .addComponent(buttonZoomStretch) + .addComponent(buttonZoom2)) + .addContainerGap()) + ); + + jPanel2.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"); + + javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2); + jPanel2.setLayout(jPanel2Layout); + jPanel2Layout.setHorizontalGroup( + jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel2Layout.createSequentialGroup() + .addGap(4, 4, 4) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel3) + .addComponent(jLabel4)) + .addGap(4, 4, 4) + .addGroup(jPanel2Layout.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, 12, Short.MAX_VALUE) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.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, jPanel2Layout.createSequentialGroup() + .addComponent(labelMin) + .addGap(2, 2, 2) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(btFixColormapRange, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(spinnerMin, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))) + .addContainerGap()) + ); + + jPanel2Layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {btFixColormapRange, spinnerMax, spinnerMin}); + + jPanel2Layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {jLabel3, jLabel4}); + + jPanel2Layout.setVerticalGroup( + jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup() + .addGap(4, 4, 4) + .addGroup(jPanel2Layout.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(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(buttonAutomatic) + .addComponent(jLabel4) + .addComponent(btFixColormapRange)) + .addGap(0, 0, 0) + .addGroup(jPanel2Layout.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(jPanel2Layout.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()) + ); + + jPanel5.setBorder(javax.swing.BorderFactory.createTitledBorder("Source")); + + buttonGroup4.add(buttonCamtool); + buttonCamtool.setSelected(true); + buttonCamtool.setText("Camtool"); + buttonCamtool.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + buttonCamtoolActionPerformed(evt); + } + }); + + buttonGroup4.add(buttonDirect); + buttonDirect.setText("Direct"); + buttonDirect.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + buttonDirectActionPerformed(evt); + } + }); + + javax.swing.GroupLayout jPanel5Layout = new javax.swing.GroupLayout(jPanel5); + jPanel5.setLayout(jPanel5Layout); + jPanel5Layout.setHorizontalGroup( + jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel5Layout.createSequentialGroup() + .addContainerGap() + .addComponent(buttonCamtool) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(buttonDirect) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + jPanel5Layout.setVerticalGroup( + jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel5Layout.createSequentialGroup() + .addGap(4, 4, 4) + .addGroup(jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(buttonCamtool) + .addComponent(buttonDirect)) + .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()) + ); + + panelScreen1.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 panelScreen1Layout = new javax.swing.GroupLayout(panelScreen1); + panelScreen1.setLayout(panelScreen1Layout); + panelScreen1Layout.setHorizontalGroup( + panelScreen1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(panelScreen1Layout.createSequentialGroup() + .addContainerGap() + .addGroup(panelScreen1Layout.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()) + ); + panelScreen1Layout.setVerticalGroup( + panelScreen1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, panelScreen1Layout.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)) + ); + + pauseSelection.setDecimals(0); + + panelScreen2.setBorder(javax.swing.BorderFactory.createTitledBorder("Image")); + + 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.setPreferredSize(new java.awt.Dimension(77, 20)); + 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, 100.0d, 1.0d)); + spinnerGrScale.setPreferredSize(new java.awt.Dimension(77, 20)); + 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(77, 20)); + spinnerGrThreshold.addChangeListener(new javax.swing.event.ChangeListener() { + public void stateChanged(javax.swing.event.ChangeEvent evt) { + spinnerGrThresholdonChange(evt); + } + }); + + labelGrThreshold.setText("Threshold:"); + + labelGrScale.setText("Scale:"); + + javax.swing.GroupLayout panelScreen2Layout = new javax.swing.GroupLayout(panelScreen2); + panelScreen2.setLayout(panelScreen2Layout); + panelScreen2Layout.setHorizontalGroup( + panelScreen2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(panelScreen2Layout.createSequentialGroup() + .addContainerGap() + .addGroup(panelScreen2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, panelScreen2Layout.createSequentialGroup() + .addComponent(checkGoodRegion) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(labelGrScale) + .addGap(2, 2, 2) + .addComponent(spinnerGrScale, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, panelScreen2Layout.createSequentialGroup() + .addGap(0, 0, Short.MAX_VALUE) + .addComponent(labelGrThreshold) + .addGap(2, 2, 2) + .addComponent(spinnerGrThreshold, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(panelScreen2Layout.createSequentialGroup() + .addComponent(checkBackground) + .addGap(0, 0, Short.MAX_VALUE)) + .addGroup(panelScreen2Layout.createSequentialGroup() + .addComponent(checkThreshold) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(spinnerThreshold, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addContainerGap()) + ); + + panelScreen2Layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {spinnerGrScale, spinnerGrThreshold, spinnerThreshold}); + + panelScreen2Layout.setVerticalGroup( + panelScreen2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, panelScreen2Layout.createSequentialGroup() + .addGap(4, 4, 4) + .addComponent(checkBackground) + .addGap(2, 2, 2) + .addGroup(panelScreen2Layout.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(panelScreen2Layout.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(2, 2, 2) + .addGroup(panelScreen2Layout.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)) + .addContainerGap()) + ); + + javax.swing.GroupLayout jPanel4Layout = new javax.swing.GroupLayout(jPanel4); + jPanel4.setLayout(jPanel4Layout); + jPanel4Layout.setHorizontalGroup( + jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel4Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) + .addComponent(jPanel5, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(panelScreen, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(panelScreen1, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jPanel3, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jPanel2, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(pauseSelection, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE) + .addComponent(panelScreen2, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + jPanel4Layout.setVerticalGroup( + jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel4Layout.createSequentialGroup() + .addContainerGap() + .addComponent(jPanel5, 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(panelScreen1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(panelScreen2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jPanel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(pauseSelection, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap()) + ); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addGap(0, 0, 0) + .addComponent(jPanel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGap(0, 0, 0) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jPanel4, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) + ); + }// //GEN-END:initComponents + + 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); + buttonCamtool.setEnabled(false); + buttonDirect.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); + } catch (Exception ex) { + ex.printStackTrace(); + } finally { + updateStop(); + comboCameras.setEnabled(true); + buttonCamtool.setEnabled(true); + buttonDirect.setEnabled(true); + } + } + }).start(); + } + } catch (Exception ex) { + showException(ex); + } + }//GEN-LAST:event_comboCamerasActionPerformed + + private void buttonArgsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonArgsActionPerformed + try { + if (camera != null) { + TextEditor editor = new TextEditor(); + editor.setText(cameraConfigJson); + editor.setReadOnly(true); + editor.setTitle(cameraName); + EditorDialog dlg = editor.getDialog(getTopLevel(), false); + dlg.setSize(480, 640); + dlg.setVisible(true); + SwingUtils.centerComponent(this, dlg); + } + } catch (Exception ex) { + showException(ex); + } + }//GEN-LAST:event_buttonArgsActionPerformed + + private void buttonConfigActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonConfigActionPerformed + try { + if (camera != null) { + this.showDeviceConfigDialog(camera, false); + } + } catch (Exception ex) { + showException(ex); + } + }//GEN-LAST:event_buttonConfigActionPerformed + + private void buttonPauseActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonPauseActionPerformed + try { + renderer.removeOverlay(imageBufferOverlay); + if (camera != null) { + synchronized (imageBuffer) { + if (buttonPause.isSelected()) { + renderer.pause(); + } else { + imageBuffer.clear(); + renderer.resume(); + } + pauseSelection.setVisible(buttonPause.isSelected() && (imageBuffer.size() > 0)); + if (pauseSelection.isVisible()) { + renderer.addOverlay(imageBufferOverlay); + pauseSelection.setMaxValue(imageBuffer.size()); + pauseSelection.setValue(imageBuffer.size());; + } + } + updateImageData(); + } + } catch (Exception ex) { + ex.printStackTrace(); + showException(ex); + } + }//GEN-LAST:event_buttonPauseActionPerformed + + private void buttonMarkerActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonMarkerActionPerformed + try { + checkMarker(); + } catch (Exception ex) { + showException(ex); + } + }//GEN-LAST:event_buttonMarkerActionPerformed + + 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 buttonReticleActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonReticleActionPerformed + try { + checkReticle(); + } catch (Exception ex) { + showException(ex); + } + }//GEN-LAST:event_buttonReticleActionPerformed + + private void buttonSaveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonSaveActionPerformed + try { + saveSnapshot(); + } catch (Exception ex) { + ex.printStackTrace(); + showException(ex); + } + }//GEN-LAST:event_buttonSaveActionPerformed + + private void buttonGrabBackgroundActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonGrabBackgroundActionPerformed + try { + if (camera != null) { + if (SwingUtils.showOption(getTopLevel(), "Background", "Do you want to capture background now?", OptionType.YesNo) == OptionResult.Yes) { + boolean laserOn = getLaserState(); + if (camera instanceof Camtool){ + boolean rendering = (!camera.isClosed()); + if (rendering) { + camera.close(); + } + if (laserOn) { + setLaserState(false); + } + try { + System.out.println("Grabbing background for: " + cameraName); + ((Camtool) camera).grabBackground(cameraName, 5); + } finally { + if (laserOn) { + setLaserState(true); + } + if (rendering) { + comboCamerasActionPerformed(null); + } + updateStop(); + } + } else { + if (laserOn) { + setLaserState(false); + } + try { + camera.captureBackground(5, 0); + } finally { + if (laserOn) { + setLaserState(true); + } + } + } + SwingUtils.showMessage(getTopLevel(), "Success", "Success capturing background", 5000); + } + } + } catch (Exception ex) { + showException(ex); + } + }//GEN-LAST:event_buttonGrabBackgroundActionPerformed + + 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); + source.getConfig().colormap = (Colormap)comboColormap.getSelectedItem(); + switch (source.getConfig().colormap){ + case Grayscale: + case Inverted: + 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(); + source.getConfig().save(); + 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 buttonCamtoolActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonCamtoolActionPerformed + if (!usingCamtool) { + usingCamtool = true; + requestCameraListUpdate = true; + } + comboCamerasActionPerformed(null); + }//GEN-LAST:event_buttonCamtoolActionPerformed + + private void buttonDirectActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonDirectActionPerformed + if (usingCamtool) { + usingCamtool = false; + requestCameraListUpdate = true; + } + comboCamerasActionPerformed(null); + }//GEN-LAST:event_buttonDirectActionPerformed + + 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 (cameraName.contains("DSRM")){ + setpoint = new ChannelInteger(null, cameraName + ":POSITION_SP"); + } else { + setpoint = new ChannelInteger(null, cameraName + ":SET_SCREEN1_POS"); + } + setpoint.initialize(); + if (setpoint.read() != index) { + setpoint.write(index); + //Must be threaded to control the laser because of sleep in setLaserState + /* + boolean laserOn = getLaserState(); + if (laserOn) { + setLaserState(false); + } + try { + setpoint.write(index); + } finally { + if (laserOn) { + setLaserState(true); + } + } + */ + } + 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.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 (!updatingCamtoolControls) { + try { + if ((camera instanceof Camtool) && (((Camtool) camera).isPipelineStarted())) { + ((Camtool) camera).setThreshold((Double) spinnerThreshold.getValue()); + } + } catch (Exception ex) { + showException(ex); + updateCamtoolControls(); + } + } + }//GEN-LAST:event_spinnerThresholdonChange + + private void checkBackgroundActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_checkBackgroundActionPerformed + if (camera instanceof Camtool){ + if (!updatingCamtoolControls) { + try { + if (((Camtool) camera).isPipelineStarted()) { + ((Camtool) camera).setBackgroundSubtraction(checkBackground.isSelected()); + } + } catch (Exception ex) { + showException(ex); + updateCamtoolControls(); + //There is a bug in camtool: it will flag bg extraction as on: + updatingCamtoolControls = true; + checkBackground.setSelected(false); + updatingCamtoolControls = false; + + } + } + } else { + camera.setBackgroundEnabled(checkBackground.isSelected()); + } + }//GEN-LAST:event_checkBackgroundActionPerformed + + private void checkThresholdActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_checkThresholdActionPerformed + if (!updatingCamtoolControls) { + try { + if ((camera instanceof Camtool) && (((Camtool) camera).isPipelineStarted())) { + spinnerThreshold.setVisible(checkThreshold.isSelected()); + ((Camtool) camera).setThreshold(checkThreshold.isSelected() ? (Double) spinnerThreshold.getValue() : null); + } + } catch (Exception ex) { + showException(ex); + updateCamtoolControls(); + } + } + }//GEN-LAST:event_checkThresholdActionPerformed + + private void buttonStopActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonStopActionPerformed + try { + if (buttonStop.getText().equals("Stop")) { + if ((camera != null) && !camera.isClosed()) { + camera.close(); + } + } else { + if (isCameraStopped()) { + comboCamerasActionPerformed(null); + } + } + } catch (Exception ex) { + showException(ex); + } finally { + updateStop(); + } + }//GEN-LAST:event_buttonStopActionPerformed + + 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 checkGoodRegionActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_checkGoodRegionActionPerformed + if (!updatingCamtoolControls) { + try { + if ((camera instanceof Camtool) && (((Camtool) camera).isPipelineStarted())) { + spinnerGrScale.setVisible(checkGoodRegion.isSelected()); labelGrScale.setVisible(spinnerGrScale.isVisible()); + spinnerGrThreshold.setVisible(checkGoodRegion.isSelected()); labelGrThreshold.setVisible(spinnerGrThreshold.isVisible()); + if (checkGoodRegion.isSelected()){ + ((Camtool) camera).setGoodRegion( (Double)spinnerGrThreshold.getValue(), (Double)spinnerGrScale.getValue() ); + } else { + ((Camtool) camera).setGoodRegion(null); + } + goodRegion = checkGoodRegion.isSelected(); + } + } catch (Exception ex) { + showException(ex); + updateCamtoolControls(); + } + } + }//GEN-LAST:event_checkGoodRegionActionPerformed + + private void spinnerGrThresholdonChange(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_spinnerGrThresholdonChange + if (!updatingCamtoolControls) { + try { + if ((camera instanceof Camtool) && (((Camtool) camera).isPipelineStarted())) { + ((Camtool) camera).setGoodRegion( (Double)spinnerGrThreshold.getValue(), (Double)spinnerGrScale.getValue() ); + } + } catch (Exception ex) { + showException(ex); + updateCamtoolControls(); + } + } + }//GEN-LAST:event_spinnerGrThresholdonChange + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton btFixColormapRange; + private javax.swing.JButton buttonArgs; + private javax.swing.JRadioButton buttonAutomatic; + private javax.swing.JRadioButton buttonCamtool; + private javax.swing.JButton buttonConfig; + private javax.swing.JRadioButton buttonDirect; + 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.JToggleButton buttonReticle; + private javax.swing.JToggleButton buttonSave; + private javax.swing.JButton buttonStop; + 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 checkBackground; + private javax.swing.JCheckBox checkGoodRegion; + private javax.swing.JCheckBox checkHistogram; + 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.JLabel jLabel1; + private javax.swing.JLabel jLabel2; + private javax.swing.JLabel jLabel3; + private javax.swing.JLabel jLabel4; + private javax.swing.JPanel jPanel1; + private javax.swing.JPanel jPanel2; + private javax.swing.JPanel jPanel3; + private javax.swing.JPanel jPanel4; + private javax.swing.JPanel jPanel5; + private javax.swing.JPanel jPanel6; + private javax.swing.JPanel jPanel7; + private javax.swing.JProgressBar jProgressBar1; + private javax.swing.JLabel labelGrScale; + private javax.swing.JLabel labelGrThreshold; + private javax.swing.JLabel labelMax; + private javax.swing.JLabel labelMin; + private javax.swing.JPanel panelScreen; + private javax.swing.JPanel panelScreen1; + private javax.swing.JPanel panelScreen2; + private ch.psi.pshell.swing.ValueSelection pauseSelection; + private ch.psi.pshell.imaging.Renderer renderer; + private javax.swing.JSpinner spinnerGrScale; + private javax.swing.JSpinner spinnerGrThreshold; + private javax.swing.JSpinner spinnerMax; + private javax.swing.JSpinner spinnerMin; + private javax.swing.JSpinner spinnerThreshold; + private javax.swing.JTextField textState; + 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/Diagnostics/AnalysisWireScan.py b/script/Diagnostics/AnalysisWireScan.py new file mode 100644 index 0000000..3a1c518 --- /dev/null +++ b/script/Diagnostics/AnalysisWireScan.py @@ -0,0 +1,31 @@ +from mathutils import fit_gaussian,calculate_peaks + +prefix="2017/05/10/20170510_132908_WireScan.h5|/" + +xdata, ydata = "w_pos", "blm1" +number_scans = 6 +c1, c2 = Color.RED, Color.BLUE + +p= plot(None, title = xdata)[0] +for i in range(1,number_scans+1): + c = c1 if ((i%2) == 1) else c2 + s = LinePlotSeries("Measure" + str(i), color = c) + p.addSeries(s) + xval = load_data(prefix+ "x_000" + str(i)+"/" + xdata) + yval = load_data(prefix+ "x_000" + str(i)+"/" + ydata) + yval = yval[:len(xval)] + s.setData(xval, yval) + #This is to cope with the repeated values: fit needs increasing x + for i in range (len(xval)-1): + if xval[i+1] == xval[i]: + xval[i+1] = xval[i] + 0.00001 + max_y= max(ydata) + index_max = ydata.index(max_y) + (norm, mean, sigma) = fit_gaussian(yval, xval) + + print mean + if mean is not None: + p.addMarker(mean, p.AxisId.X, "", c) + + +#plot( load_data(prefix+ "x_0003/blm1"), "1", xdata = load_data(prefix+ "x_0003/w_pos")) \ No newline at end of file