From c9a61d49a79267d01c4f8d2ecdf7bfe6013897c4 Mon Sep 17 00:00:00 2001 From: gobbo_a Date: Tue, 6 Jun 2017 12:42:15 +0200 Subject: [PATCH] Startup --- devices/CurrentCamera.properties | 18 +- devices/camtool.properties | 10 +- plugins/ScreenPanel.form | 14 +- plugins/ScreenPanel.java | 208 +- plugins/ScreenPanel_back.form | 946 ++++++++ plugins/ScreenPanel_back.java | 2808 ++++++++++++++++++++++++ script/RFscan/phase_scan_caqtdm_sim.py | 27 +- 7 files changed, 3921 insertions(+), 110 deletions(-) create mode 100644 plugins/ScreenPanel_back.form create mode 100644 plugins/ScreenPanel_back.java diff --git a/devices/CurrentCamera.properties b/devices/CurrentCamera.properties index 3f3fa4b..4c45338 100644 --- a/devices/CurrentCamera.properties +++ b/devices/CurrentCamera.properties @@ -1,15 +1,15 @@ -#Fri Jun 02 17:12:43 CEST 2017 +#Tue Jun 06 12:40:51 CEST 2017 colormap=Flame colormapAutomatic=true -colormapMax=42400.0 +colormapMax=10600.0 colormapMin=10.0 flipHorizontally=false flipVertically=false grayscale=false -imageHeight=2160 -imageWidth=1936 +imageHeight=1024 +imageWidth=1280 invert=false -regionStartX=321 +regionStartX=1 regionStartY=1 rescaleFactor=1.0 rescaleOffset=0.0 @@ -21,9 +21,9 @@ rotation=0.0 rotationCrop=false scale=1.0 serverURL=localhost\:10000 -spatialCalOffsetX=-50.03909304143862 -spatialCalOffsetY=-50.048875855327466 -spatialCalScaleX=-1.0 -spatialCalScaleY=-1.0 +spatialCalOffsetX=-216.34895100768858 +spatialCalOffsetY=-231.41621563133825 +spatialCalScaleX=-26.85765457769588 +spatialCalScaleY=-27.12477389498874 spatialCalUnits=mm transpose=false diff --git a/devices/camtool.properties b/devices/camtool.properties index fa93089..14be110 100644 --- a/devices/camtool.properties +++ b/devices/camtool.properties @@ -1,4 +1,4 @@ -#Wed May 31 17:49:39 CEST 2017 +#Tue Jun 06 10:04:55 CEST 2017 colormap=Flame colormapAutomatic=true colormapMax=578.797 @@ -18,9 +18,9 @@ roiY=0 rotation=0.0 rotationCrop=false scale=1.0 -spatialCalOffsetX=-50.03909304143862 -spatialCalOffsetY=-50.048875855327466 -spatialCalScaleX=-1.0 -spatialCalScaleY=-1.0 +spatialCalOffsetX=0.0 +spatialCalOffsetY=0.0 +spatialCalScaleX=1.0 +spatialCalScaleY=1.0 spatialCalUnits=mm transpose=false diff --git a/plugins/ScreenPanel.form b/plugins/ScreenPanel.form index 96f341e..b2adcad 100644 --- a/plugins/ScreenPanel.form +++ b/plugins/ScreenPanel.form @@ -95,10 +95,12 @@ + + - + @@ -117,6 +119,7 @@ + @@ -175,6 +178,15 @@ + + + + + + + + + diff --git a/plugins/ScreenPanel.java b/plugins/ScreenPanel.java index 89e04bc..77c8f58 100644 --- a/plugins/ScreenPanel.java +++ b/plugins/ScreenPanel.java @@ -104,8 +104,10 @@ public class ScreenPanel extends Panel { DiscretePositioner screen; DiscretePositioner filter; boolean showFit; + boolean showProfile; Overlay[] userOv; Overlay[] fitOv; + Overlay[] profileOv; Overlay errorOverlay; boolean requestCameraListUpdate; Integer localServerPort; @@ -320,6 +322,7 @@ public class ScreenPanel extends Panel { renderer.getPopupMenu().setVisible(false); showFit = buttonFit.isSelected(); + showProfile = buttonProfile.isSelected(); pauseSelection.setVisible(false); pauseSelection.setMinValue(1); @@ -519,10 +522,13 @@ public class ScreenPanel extends Panel { final Object lockOverlays = new Object(); void manageFit(BufferedImage bi, Data data) { - Overlay[] fo = ((bi == null) || (!showFit)) ? null : getFitOverlays(data); + Overlay[][] fo = ((bi == null) || ((!showFit && !showProfile))) ? null : getFitOverlays(data); synchronized(lockOverlays){ - renderer.updateOverlays(fo, fitOv); - fitOv = fo; + fo = (fo==null) ? new Overlay[][]{null, null} : fo; + renderer.updateOverlays(fo[0], profileOv); + profileOv = fo[0]; + renderer.updateOverlays(fo[1], fitOv); + fitOv = fo[1]; } } @@ -574,6 +580,7 @@ public class ScreenPanel extends Panel { renderer.setShowReticle(false); renderer.removeOverlays(fitOv); + renderer.removeOverlays(profileOv); renderer.removeOverlays(userOv); renderer.clear(); renderer.resetZoom(); @@ -931,7 +938,7 @@ public class ScreenPanel extends Panel { Pen penFit = new Pen(new Color(192, 105, 0), 1); Pen penCross = new Pen(new Color(192, 105, 0), 1); - Overlay[] getFitOverlays(Data data) { + Overlay[][] getFitOverlays(Data data) { Overlays.Polyline hgaussian = null; Overlays.Polyline vgaussian = null; Overlays.Polyline hprofile = null; @@ -1033,36 +1040,40 @@ public class ScreenPanel extends Panel { if (rangePlot <= 0) { return null; } - try { + try { double[] sum = data.integrateVertically(true); - double[] saux = new double[sum.length]; + double[] saux = new double[sum.length]; int[] p = new int[sum.length]; - //xCom = getCom(sum); + double[] x_egu = renderer.getCalibration().getAxisX(sum.length); + xCom = getCom(sum, x_egu); 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; } - - 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)); - p[i] = (int) (height - 1 - (((sum[i] / height- minPlot) / rangePlot) * profileSize)); - } - vgaussian = new Overlays.Polyline(penFit, x, y); - vprofile = new Overlays.Polyline(renderer.getPenProfile(), x, p); + 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)); + p[i] = (int) (height - 1 - (((sum[i] / height- minPlot) / rangePlot) * profileSize)); + } + vgaussian = new Overlays.Polyline(penFit, x, y); + } } } + if (showProfile){ + vprofile = new Overlays.Polyline(renderer.getPenProfile(), x, p); + } } catch (Exception ex) { ex.printStackTrace(); } @@ -1071,7 +1082,8 @@ public class ScreenPanel extends Panel { double[] sum = data.integrateHorizontally(true); double[] saux = new double[sum.length]; int[] p = new int[sum.length]; - //yCom = getCom(sum); + double[] y_egu = renderer.getCalibration().getAxisY(sum.length); + yCom = getCom(sum, y_egu); int[] x = Arr.indexesInt(sum.length); DescriptiveStatistics stats = new DescriptiveStatistics(sum); double min = stats.getMin(); @@ -1079,25 +1091,29 @@ public class ScreenPanel extends Panel { saux[i] = sum[i] - min; } - 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); + 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); - p[i] = (int) (((sum[i] / width - minPlot) / rangePlot) * profileSize); - } - hgaussian = new Overlays.Polyline(penFit, y, x); - hprofile = new Overlays.Polyline(renderer.getPenProfile(), p, 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); + p[i] = (int) (((sum[i] / width - minPlot) / rangePlot) * profileSize); + } + hgaussian = new Overlays.Polyline(penFit, y, x); + } } + } + if (showProfile){ + hprofile = new Overlays.Polyline(renderer.getPenProfile(), p, x); } } catch (Exception ex) { @@ -1117,35 +1133,42 @@ public class ScreenPanel extends Panel { yMean = data.getY((int) Math.round(yMean)); } } - } - - Overlays.Crosshairs cross = null; - Overlays.Text textFit = null; - if ((xMean != null) && (yMean != null)) { - textFit = new Overlays.Text(penFit, - String.format("x: m=%1.1f \u03C3=%1.1f\ny: m=%1.1f \u03C3=%1.1f",xMean, xSigma, yMean, ySigma), - new Font(Font.MONOSPACED, 0, 14), new Point(20, 20)); - 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()))); - } - + } + final String units = (renderer.getCalibration() != null) ? "\u00B5m" : "px"; + final String fmt = "%7.1f" + units; Overlays.Text textCom = null; - if ((xCom != null) && (yCom != null)) { - textCom = new Overlays.Text(renderer.getPenProfile(), - String.format("x: m=%1.1f \u03C3=%1.1f\ny: m=%1.1f \u03C3=%1.1f",xCom, xRms,yCom, yRms), - new Font(Font.MONOSPACED, 0, 14), new Point(20, 60)); - textCom.setFixed(true); - textCom.setAnchor(Overlay.ANCHOR_VIEWPORT_TOP_LEFT); - } - return new Overlay[]{hprofile, vprofile, hgaussian, vgaussian, cross, textFit, textCom}; + Overlay[] pOv=null, fOv=null; + Point textPosition = new Point(12, 20); + if (showProfile){ + if ((xCom != null) && (yCom != null)) { + String text = ((xRms != null) && (yRms != null)) ? + String.format("com x: m=" + fmt + " \u03C3=" + fmt + "\ncom y: m=" + fmt + " \u03C3=" + fmt,xCom, xRms,yCom, yRms) : + String.format("com x: m=" + fmt + "\ncom y: m=" + fmt ,xCom, yCom); + 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}; + } + return new Overlay[][]{pOv, fOv}; } return null; } @@ -1265,7 +1288,7 @@ public class ScreenPanel extends Panel { return ret.toArray(new Overlay[0]); } - double getCom(double[] arr) { + double getCom(double[] arr, double[] x) { if (arr == null) { return Double.NaN; } @@ -1273,7 +1296,7 @@ public class ScreenPanel extends Panel { double ret = 0; double total = 0; for (double v : arr) { - ret += (v * index++); + ret += (v * x[index++]); total += v; } if (total == 0) { @@ -1637,6 +1660,7 @@ public class ScreenPanel extends Panel { 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(); @@ -1731,6 +1755,14 @@ public class ScreenPanel extends Panel { } }); + 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( @@ -1741,17 +1773,19 @@ public class ScreenPanel extends Panel { .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) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .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, buttonReticle}); + 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}); @@ -1765,7 +1799,8 @@ public class ScreenPanel extends Panel { .addComponent(buttonMarker) .addComponent(buttonSave) .addComponent(buttonReticle) - .addComponent(buttonGrabBackground)) + .addComponent(buttonGrabBackground) + .addComponent(buttonProfile)) .addGap(0, 0, 0)) ); @@ -2450,11 +2485,11 @@ public class ScreenPanel extends Panel { private void buttonFitActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonFitActionPerformed try { showFit = buttonFit.isSelected(); - if (!buttonFit.isSelected()) { - renderer.removeOverlays(fitOv); - fitOv = null; - } else { + if (showFit) { renderer.setProfile(Renderer.Profile.None); + } else { + renderer.removeOverlays(fitOv); + fitOv = null; } } catch (Exception ex) { showException(ex); @@ -2741,6 +2776,20 @@ public class ScreenPanel extends Panel { } }//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 + // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton buttonArgs; private javax.swing.JRadioButton buttonAutomatic; @@ -2760,6 +2809,7 @@ public class ScreenPanel extends Panel { private javax.swing.JRadioButton buttonManual; private javax.swing.JToggleButton buttonMarker; private javax.swing.JToggleButton buttonPause; + private javax.swing.JToggleButton buttonProfile; private javax.swing.JRadioButton buttonRainbow; private javax.swing.JToggleButton buttonReticle; private javax.swing.JToggleButton buttonSave; diff --git a/plugins/ScreenPanel_back.form b/plugins/ScreenPanel_back.form new file mode 100644 index 0000000..96f341e --- /dev/null +++ b/plugins/ScreenPanel_back.form @@ -0,0 +1,946 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/plugins/ScreenPanel_back.java b/plugins/ScreenPanel_back.java new file mode 100644 index 0000000..4da57d6 --- /dev/null +++ b/plugins/ScreenPanel_back.java @@ -0,0 +1,2808 @@ +/* + * 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.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.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.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.WindowEvent; +import java.awt.image.BufferedImage; +import java.io.FileInputStream; +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.JTextField; +import javax.swing.SwingUtilities; +import javax.swing.event.PopupMenuEvent; +import javax.swing.event.PopupMenuListener; +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_back 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; + Overlay[] userOv; + Overlay[] fitOv; + Overlay errorOverlay; + boolean requestCameraListUpdate; + Integer localServerPort; + Process privateServer; + String serverUrl; + + Double getCamtoolDouble(String name) { + return (Double) Convert.toDouble(((Camtool) camera).getValue(name)); + } + + double[] getCamtoolDoubleArray(String name) { + return (double[]) Convert.toDouble(((Camtool) camera).getValue(name)); + } + + class Frame { + + Frame(Data data) { + this.data = data; + if (camera instanceof Camtool) { + xMean = getCamtoolDouble("x_fit_mean"); + yMean = getCamtoolDouble("y_fit_mean"); + xSigma = getCamtoolDouble("x_fit_standard_deviation"); + ySigma = getCamtoolDouble("y_fit_standard_deviation"); + xCom = getCamtoolDouble("x_center_of_mass"); + yCom = getCamtoolDouble("y_center_of_mass"); + xRms = getCamtoolDouble("x_rms"); + yRms = getCamtoolDouble("y_rms"); + x_profile = getCamtoolDoubleArray("x_profile"); + x_fit_gauss_function = getCamtoolDoubleArray("x_fit_gauss_function"); + y_profile = getCamtoolDoubleArray("y_profile"); + y_fit_gauss_function = getCamtoolDoubleArray("y_fit_gauss_function"); + } + } + Data data; + Double xMean; + Double yMean; + Double xCom; + Double xRms; + Double xSigma; + Double ySigma; + Double yCom; + Double yRms; + double[] x_profile; + double[] x_fit_gauss_function; + double[] y_profile; + double[] y_fit_gauss_function; + } + + final ArrayList imageBuffer = new ArrayList(); + int imageBufferLenght = 0; + Text imageBufferOverlay; + + public ScreenPanel_back() { + initComponents(); + renderer.setPersistenceFile(Paths.get(getContext().getSetup().getContextPath(), "Renderer_Cameras.bin")); + setPersistedComponents(new Component[]{buttonCamtool, buttonDirect}); + comboCameras.setEnabled(false); + 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 menuShowIdentifiers = new JMenuItem("Show Identifiers..."); + menuShowIdentifiers.addActionListener((ActionEvent e) -> { + try { + showIdentifiers(); + } 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(menuShowIdentifiers); + 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); + menuShowIdentifiers.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(); + + 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)) ? null : getFitOverlays(data); + synchronized(lockOverlays){ + renderer.updateOverlays(fo, fitOv); + fitOv = fo; + } + } + + 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; + buttonGrabBackground.setEnabled(false); + checkBackground.setEnabled(false); + spinnerThreshold.setEnabled(false); + + checkThreshold.setEnabled(false); + + if (calibrationDialolg!=null){ + calibrationDialolg.dispose(); + calibrationDialolg = null; + } + + if (camera != null) { + //camera.removeAllListeners(); + camera.close(); + camera = null; + } + renderer.setDevice(null); + + renderer.setShowReticle(false); + renderer.removeOverlays(fitOv); + renderer.removeOverlays(userOv); + renderer.clear(); + renderer.resetZoom(); + + boolean changed = !String.valueOf(cameraName).equals(this.cameraName); + this.cameraName = cameraName; + + if (changed) { + 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; + } + + 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? + checkBackground.setEnabled(true); + if (changed) { + ((Camtool) camera).startPipeline(cameraName, null); + updateCamtoolControls(); + } else { + ((Camtool) camera).startPipeline(cameraName, null, checkBackground.isSelected(), null, checkThreshold.isSelected() ? (Double) spinnerThreshold.getValue() : null, null); + } + spinnerThreshold.setEnabled(true); + checkThreshold.setEnabled(true); + buttonGrabBackground.setEnabled(true); + + ((Camtool) camera).startReceiver(); + } else { + if (polling <= 0) { + camera.setMonitored(true); + } else { + camera.setPolling(polling); + } + } + + 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 (imageBufferLenght > 1) { + if (data != null) { + synchronized (imageBuffer) { + imageBuffer.add(new Frame(data)); + if (imageBuffer.size() > imageBufferLenght) { + imageBuffer.remove(0); + } + } + } + } + manageFit(bi, data); + manageUserOverlays(bi, data); + } + + } + + @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); + + 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(); + switch (config.colormap) { + case Grayscale: + buttonGrayscale.setSelected(true); + break; + case Rainbow: + buttonRainbow.setSelected(true); + break; + case Temperature: + buttonTemperature.setSelected(true); + break; + case Flame: + buttonFlame.setSelected(true); + break; + case Inverted: + buttonInverted.setSelected(true); + break; + default: + buttonGroup2.clearSelection(); + + } + if (config.isDefaultColormap()) { + buttonFullRange.setSelected(true); + } else if (config.colormapAutomatic) { + buttonAutomatic.setSelected(true); + } else { + buttonManual.setSelected(true); + } + + 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); + + } catch (Exception ex) { + } + 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); + } + 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); + + 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 { + if (renderer.isPaused()) { + synchronized (imageBuffer) { + for (Frame f : imageBuffer) { + if (f.data == data) { + xMean = f.xMean; + xSigma = f.xSigma; + yMean = f.yMean; + ySigma = f.ySigma; + pX = f.x_profile; + gX = f.x_fit_gauss_function; + pY = f.y_profile; + gY = f.y_fit_gauss_function; + xCom = f.xCom; + xRms = f.xRms; + yCom = f.yCom; + yRms = f.yRms; + } + } + } + } else { + xMean = getCamtoolDouble("x_fit_mean"); + yMean = getCamtoolDouble("y_fit_mean"); + xSigma = getCamtoolDouble("x_fit_standard_deviation"); + ySigma = getCamtoolDouble("y_fit_standard_deviation"); + xCom = getCamtoolDouble("x_center_of_mass"); + yCom = getCamtoolDouble("y_center_of_mass"); + xRms = getCamtoolDouble("x_rms"); + yRms = getCamtoolDouble("y_rms"); + pX = getCamtoolDoubleArray("x_profile"); + gX = getCamtoolDoubleArray("x_fit_gauss_function"); + pY = getCamtoolDoubleArray("y_profile"); + gY = getCamtoolDoubleArray("y_fit_gauss_function"); + } + 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)); + } + vgaussian = new Overlays.Polyline(penFit, x, y); + vprofile = new Overlays.Polyline(renderer.getPenProfile(), x, p); + } + + if (pX != 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); + } + 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]; + //xCom = getCom(sum); + 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; + } + + 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)); + p[i] = (int) (height - 1 - (((sum[i] / height- minPlot) / rangePlot) * profileSize)); + } + vgaussian = new Overlays.Polyline(penFit, x, y); + 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]; + //yCom = getCom(sum); + 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; + } + + 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); + p[i] = (int) (((sum[i] / width - minPlot) / rangePlot) * profileSize); + } + hgaussian = new Overlays.Polyline(penFit, y, x); + 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; + if ((xCom != null) && (yCom != null)) { + textCom = new Overlays.Text(renderer.getPenProfile(), + String.format("x: m=" + fmt + " \u03C3=" + fmt + "\ny: m=" + fmt + " \u03C3=" + fmt,xCom, xRms,yCom, yRms), + new Font(Font.MONOSPACED, 0, 14), new Point(12, 20)); + textCom.setFixed(true); + textCom.setAnchor(Overlay.ANCHOR_VIEWPORT_TOP_LEFT); + } + + Overlays.Crosshairs cross = null; + Overlays.Text textFit = null; + if ((xMean != null) && (yMean != null)) { + textFit = new Overlays.Text(penFit, + String.format("x: m=" + fmt + " \u03C3=" + fmt + "\ny: m=" + fmt + " \u03C3=" + fmt,xMean, xSigma, yMean, ySigma), + new Font(Font.MONOSPACED, 0, 14), new Point(12, 54)); + 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()))); + } + + return new Overlay[]{hprofile, vprofile, hgaussian, vgaussian, cross, textFit, textCom}; + } + 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()); + 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) { + 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); + } else { + PointDouble position = new PointDouble(getCamtoolDouble(uo.channels[0]), getCamtoolDouble(uo.channels[1])); + ov.setAbsolutePosition(position); + if (!(ov instanceof Overlays.Crosshairs)) { + DimensionDouble size = new DimensionDouble(getCamtoolDouble(uo.channels[2]) - position.x, getCamtoolDouble(uo.channels[3]) - position.y); + ov.setAbsoluteSize(size); + } + } + ret.add(ov); + } catch (Exception ex) { + ex.printStackTrace(); + } + } + } + return ret.toArray(new Overlay[0]); + } + + double getCom(double[] arr) { + if (arr == null) { + return Double.NaN; + } + int index = 0; + double ret = 0; + double total = 0; + for (double v : arr) { + ret += (v * index++); + total += v; + } + if (total == 0) { + return Double.NaN; + } + return ret / total; + } + + 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 { + + 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 saveSnapshot() throws Exception { + String snapshotFile = getContext().getSetup().expandPath("{images}/{date}_{time}_snapshot.png"); + renderer.saveSnapshot(snapshotFile, "png", true); + getContext().setExecutionPars("snapshot"); + String path = "/data"; + getContext().getDataManager().setDataset(path, renderer.getData().getMatrix(), renderer.getData().isUnsigned()); + getContext().getDataManager().setAttribute(path, "Camera", String.valueOf(cameraName)); + getContext().getDataManager().setAttribute(path, "Screen", String.valueOf(valueScreen.getLabel().getText())); + getContext().getDataManager().setAttribute(path, "Filter", String.valueOf(valueFilter.getLabel().getText())); + getContext().getDataManager().closeOutput(); + + 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()); + getContext().getDataManager().setAttribute(path, "x_mean", (frame.xMean == null) ? Double.NaN : frame.xMean); + getContext().getDataManager().setAttribute(path, "x_sigma", (frame.xSigma == null) ? Double.NaN : frame.xSigma); + getContext().getDataManager().setAttribute(path, "y_mean", (frame.yMean == null) ? Double.NaN : frame.yMean); + getContext().getDataManager().setAttribute(path, "y_sigma", (frame.ySigma == null) ? Double.NaN : frame.ySigma); + x.add(frame.xMean); + y.add(frame.yMean); + } + } + DescStatsDouble xs = new DescStatsDouble(x.toArray(new Double[0]), -1); + DescStatsDouble ys = new DescStatsDouble(y.toArray(new Double[0]), -1); + String path = "/"; + getContext().getDataManager().setAttribute(path, "x_mean", xs.getMean()); + getContext().getDataManager().setAttribute(path, "x_sigma", xs.getStdev()); + getContext().getDataManager().setAttribute(path, "y_mean", ys.getMean()); + getContext().getDataManager().setAttribute(path, "y_sigma", ys.getStdev()); + 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); + } + } + + void showIdentifiers(){ + if (camera instanceof Camtool){ + List ids = ((Camtool)camera).getValue().getIdentifiers(); + Collections.sort(ids); + String msg = String.join("\n", ids); + SwingUtils.showMessage(getTopLevel(), "Camtool Identifiers", msg); + } + } + + //////// + @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(); + 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(); + buttonFullRange = new javax.swing.JRadioButton(); + buttonManual = new javax.swing.JRadioButton(); + jLabel3 = new javax.swing.JLabel(); + jLabel4 = new javax.swing.JLabel(); + spinnerMin = new javax.swing.JSpinner(); + spinnerMax = new javax.swing.JSpinner(); + buttonAutomatic = new javax.swing.JRadioButton(); + checkHistogram = new javax.swing.JCheckBox(); + jPanel8 = new javax.swing.JPanel(); + buttonInverted = new javax.swing.JRadioButton(); + buttonFlame = new javax.swing.JRadioButton(); + buttonTemperature = new javax.swing.JRadioButton(); + buttonRainbow = new javax.swing.JRadioButton(); + buttonGrayscale = new javax.swing.JRadioButton(); + 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(); + + 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.setEnabled(false); + 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); + } + }); + + 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(buttonFit) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(buttonReticle) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, 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, 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)) + .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.RELATED) + .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)) + .addGap(47, 47, 47)) + ); + 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")); + + buttonGroup3.add(buttonFullRange); + buttonFullRange.setText("Full range"); + 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); + } + }); + + jLabel3.setText("Min:"); + + jLabel4.setText("Max:"); + + 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); + } + }); + + buttonGroup3.add(buttonAutomatic); + buttonAutomatic.setText("Automatic"); + buttonAutomatic.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + onChangeColormap(evt); + } + }); + + checkHistogram.setText("Histogram"); + checkHistogram.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + checkHistogramActionPerformed(evt); + } + }); + + buttonGroup2.add(buttonInverted); + buttonInverted.setText("Inverted"); + buttonInverted.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + onChangeColormap(evt); + } + }); + + buttonGroup2.add(buttonFlame); + buttonFlame.setText("Flame"); + buttonFlame.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + onChangeColormap(evt); + } + }); + + buttonGroup2.add(buttonTemperature); + buttonTemperature.setText("Temperature"); + buttonTemperature.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + onChangeColormap(evt); + } + }); + + buttonGroup2.add(buttonRainbow); + buttonRainbow.setText("Rainbow"); + buttonRainbow.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + onChangeColormap(evt); + } + }); + + buttonGroup2.add(buttonGrayscale); + buttonGrayscale.setText("Grayscale"); + buttonGrayscale.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + onChangeColormap(evt); + } + }); + + javax.swing.GroupLayout jPanel8Layout = new javax.swing.GroupLayout(jPanel8); + jPanel8.setLayout(jPanel8Layout); + jPanel8Layout.setHorizontalGroup( + jPanel8Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel8Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel8Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel8Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel8Layout.createSequentialGroup() + .addGroup(jPanel8Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(buttonGrayscale) + .addComponent(buttonInverted)) + .addGap(20, 20, 20)) + .addComponent(buttonFlame)) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel8Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(buttonTemperature) + .addComponent(buttonRainbow))) + .addGap(0, 0, 0)) + ); + jPanel8Layout.setVerticalGroup( + jPanel8Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel8Layout.createSequentialGroup() + .addGap(0, 0, 0) + .addComponent(buttonGrayscale) + .addGap(0, 0, 0) + .addComponent(buttonInverted) + .addGap(0, 0, 0) + .addComponent(buttonFlame) + .addGap(0, 0, 0) + .addComponent(buttonRainbow) + .addGap(0, 0, 0) + .addComponent(buttonTemperature) + .addGap(0, 0, 0)) + ); + + javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2); + jPanel2.setLayout(jPanel2Layout); + jPanel2Layout.setHorizontalGroup( + jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel2Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel2Layout.createSequentialGroup() + .addComponent(checkHistogram) + .addGap(0, 0, Short.MAX_VALUE)) + .addGroup(jPanel2Layout.createSequentialGroup() + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(buttonAutomatic) + .addComponent(buttonFullRange) + .addComponent(buttonManual) + .addGroup(jPanel2Layout.createSequentialGroup() + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel4) + .addComponent(jLabel3)) + .addGap(2, 2, 2) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(spinnerMin, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(spinnerMax, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jPanel8, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addContainerGap()) + ); + + jPanel2Layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {spinnerMax, spinnerMin}); + + jPanel2Layout.setVerticalGroup( + jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel2Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addGroup(jPanel2Layout.createSequentialGroup() + .addComponent(buttonAutomatic) + .addGap(0, 0, 0) + .addComponent(buttonFullRange) + .addGap(0, 0, 0) + .addComponent(buttonManual) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel3) + .addComponent(spinnerMin, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel4) + .addComponent(spinnerMax, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addComponent(jPanel8, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(checkHistogram)) + ); + + 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, 65535.0d, 1.0d)); + spinnerThreshold.setEnabled(false); + 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); + } + }); + + 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) + .addComponent(checkBackground) + .addGroup(panelScreen2Layout.createSequentialGroup() + .addComponent(checkThreshold) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(spinnerThreshold, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + 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)) + .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()) + ); + 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());; + } + } + } + } 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 (!buttonFit.isSelected()) { + renderer.removeOverlays(fitOv); + fitOv = null; + } else { + renderer.setProfile(Renderer.Profile.None); + } + } 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) && (camera instanceof Camtool)) { + if (SwingUtils.showOption(getTopLevel(), "Background", "Do you want to capture background now?", OptionType.YesNo) == OptionResult.Yes) { + boolean laserOn = getLaserState(); + 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(); + } + 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); + if (buttonGrayscale.isSelected() || buttonInverted.isSelected()) { + colorReticule = new Color(0, 192, 0); + colorMarker = new Color(64, 255, 64); + source.getConfig().colormap = buttonGrayscale.isSelected() ? Colormap.Grayscale : Colormap.Inverted; + } else if (buttonFlame.isSelected()) { + colorReticule = new Color(0, 192, 0); + colorMarker = new Color(64, 255, 64); + source.getConfig().colormap = Colormap.Flame; + } else if (buttonTemperature.isSelected()) { + source.getConfig().colormap = Colormap.Temperature; + } else if (buttonRainbow.isSelected()) { + source.getConfig().colormap = Colormap.Rainbow; + } + 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(); + } + } + } 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) { + return; + } + 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 (updatingCamtoolControls) { + return; + } + try { + if ((camera instanceof Camtool) && (((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; + + } + }//GEN-LAST:event_checkBackgroundActionPerformed + + private void checkThresholdActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_checkThresholdActionPerformed + if (updatingCamtoolControls) { + return; + } + try { + if ((camera instanceof Camtool) && (((Camtool) camera).isPipelineStarted())) { + spinnerThreshold.setEnabled(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 + + // Variables declaration - do not modify//GEN-BEGIN:variables + 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 buttonFlame; + private javax.swing.JRadioButton buttonFullRange; + private javax.swing.JButton buttonGrabBackground; + private javax.swing.JRadioButton buttonGrayscale; + private javax.swing.ButtonGroup buttonGroup1; + private javax.swing.ButtonGroup buttonGroup2; + private javax.swing.ButtonGroup buttonGroup3; + private javax.swing.ButtonGroup buttonGroup4; + private javax.swing.JRadioButton buttonInverted; + private javax.swing.JRadioButton buttonManual; + private javax.swing.JToggleButton buttonMarker; + private javax.swing.JToggleButton buttonPause; + private javax.swing.JRadioButton buttonRainbow; + private javax.swing.JToggleButton buttonReticle; + private javax.swing.JToggleButton buttonSave; + private javax.swing.JButton buttonStop; + private javax.swing.JRadioButton buttonTemperature; + 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 checkHistogram; + private javax.swing.JCheckBox checkThreshold; + private javax.swing.JComboBox comboCameras; + 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.JPanel jPanel8; + private javax.swing.JProgressBar jProgressBar1; + 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 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/RFscan/phase_scan_caqtdm_sim.py b/script/RFscan/phase_scan_caqtdm_sim.py index 915ee3d..3e07eaa 100644 --- a/script/RFscan/phase_scan_caqtdm_sim.py +++ b/script/RFscan/phase_scan_caqtdm_sim.py @@ -6,16 +6,14 @@ if get_exec_pars().source == CommandSource.ui: else: station = args[0] bpm_ch = args[1] - + start = caget(station + "-RSYS:SET-SCAN-START") stop = caget(station + "-RSYS:SET-SCAN-STOP") step = caget(station + "-RSYS:SET-SCAN-STEP") lat = caget(station + "-RSYS:SET-SCAN-WAIT-TIME") nb = caget(station + "-RSYS:SET-NUM-AVERAGE") -#disp = caget(bpm_ch + ":DISPERSION") -#energy0 = caget(bpm_ch + ":ENERGY") -disp = 1 -energy0 = 1000 +disp = caget(bpm_ch + ":DISPERSION") +energy0 = caget(bpm_ch + ":ENERGY") phase = ControlledVariable("Phase", station + "-RSYS:SET-VSUM-PHASE", station + "-RSYS:SET-VSUM-PHASE") phase.config.minValue =-180.0 @@ -27,8 +25,6 @@ V = Channel(station + "-RSYS:GET-VSUM-AMPLT", type = 'd', alias='Amplitude Read P = Channel(station + "-RSYS:GET-KLY-POWER", type = 'd', alias='Power Readback') x = Channel(bpm_ch + ":X1-SIMU", type = 'd', alias='BPM-X') -phase0 = phase.read() - caput(station + "-RSYS:GET-FIT-PHASE-ARRAY", to_array([0.0],'d')) caput(station + "-RSYS:GET-FIT-ENERGY-ARRAY", to_array([0.0],'d')) caput(station + "-RSYS:GET-ONCREST-VSUM-PHASE", float('nan')) @@ -36,6 +32,8 @@ caput(station + "-RSYS:GET-ONCREST-VSUM-AMPLT", float('nan')) caput(station + "-RSYS:GET-ONCREST-E-GAIN", float('nan')) caput(station + "-RSYS:GET-ONCREST-KLY-POWER", float('nan')) +phase0 = phase.read() + #update the plot dynamically arr_phase,arr_energy = [],[] def after(rec): @@ -52,14 +50,11 @@ try: energy = [val.mean/1000.0/disp*energy0 for val in r.getReadable(0)] caput(station + "-RSYS:GET-ENERGY-ARRAY", to_array(energy, 'd')) caput(station + "-RSYS:GET-PHASE-ARRAY", to_array(rf_phase,'d')) - run("CPython/wrapper") - (fit_amplitude, fit_phase_deg, fit_offset, ph_crest, fit_x, fit_y) = hfitoff(energy , rf_phase) - #try: - #(energy_max, angular_frequency, phase0, in_range, ph_crest, fit_x, fit_y) = hfit(energy , xdata = rf_phase) - #run("CPython/wrapper") - #(fit_amplitude, fit_phase_deg, fit_offset, ph_crest, fit_x, fit_y) = hfitoff(energy , rf_phase) - #except: - # raise Exception("Fit failure") + try: + run("CPython/wrapper") + (fit_amplitude, fit_phase_deg, fit_offset, ph_crest, fit_x, fit_y) = hfitoff(energy , rf_phase) + except: + raise Exception("Fit failure") plot([energy, fit_y], ["data", "fit"], [rf_phase, fit_x]) energy_max = fit_amplitude - fit_offset caput(station + "-RSYS:GET-ONCREST-VSUM-PHASE", ph_crest) @@ -68,7 +63,7 @@ try: caput(station + "-RSYS:GET-FIT-ENERGY-ARRAY", fit_y) phase_min, phase_max = min(rf_phase), max(rf_phase) if not (phase_min <= ph_crest <= phase_max): - raise Exception("Fit maximum outside scan range") + raise Exception("On-crest phase outside scan range") phase.write(ph_crest) time.sleep(lat) Ampl = V.read()