Java tutorial
/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package intensityclustering; import TMARKERPluginInterface.PluginManager; import com.boxysystems.jgoogleanalytics.FocusPoint; import com.boxysystems.jgoogleanalytics.JGoogleAnalyticsTracker; import java.awt.Color; import java.awt.Component; import java.awt.Container; import java.awt.Cursor; import java.awt.Graphics; import java.awt.SystemColor; import java.awt.event.KeyEvent; import java.awt.event.MouseEvent; import java.awt.image.BufferedImage; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Properties; import java.util.logging.Level; import java.util.logging.Logger; import javax.imageio.ImageIO; import javax.swing.Icon; import javax.swing.ImageIcon; import javax.swing.JFrame; import javax.swing.JOptionPane; import javax.swing.JRadioButton; import org.jdesktop.swingx.JXColorSelectionButton; import org.math.plot.Plot2DPanel; import org.math.plot.Plot3DPanel; import org.math.plot.PlotPanel; import org.math.plot.plotObjects.Line; import org.math.plot.plots.Plot; import plugins.TMARKERPluginManager; import tmarker.FileChooser; import tmarker.TMAspot.TMALabel; import tmarker.TMAspot.TMApoint; import tmarker.TMAspot.TMAspot; import tmarker.misc.Misc; import tmarker.tmarker; import weka.clusterers.Clusterer; import weka.clusterers.EM; import weka.clusterers.FarthestFirst; import weka.clusterers.HierarchicalClusterer; import weka.clusterers.SimpleKMeans; import weka.core.Attribute; import weka.core.FastVector; import weka.core.Instance; import weka.core.Instances; import weka.gui.hierarchyvisualizer.HierarchyVisualizer; /** * Plugin for the clustering of nuclei according to their colors/intensities. * Unstained and stained nuclei can be automatically clustered in up to 4 * clusters (0, 1+, 2+ and 3+). This might influence the staining estimation * value. * * @author Peter J. Schffler */ public class IntensityClustering extends javax.swing.JFrame implements TMARKERPluginInterface.Pluggable { public static String PLUGINNAME = "Intensity Clustering"; private static final String PLUGINVERSION = "1." + java.util.ResourceBundle.getBundle("intensityclustering/Bundle").getString("build"); PluginManager manager; List<TMAspot> current_TMAspots_Intensity = null; JFrame clusterVisualizer = null; // for visualization of the hierarchical clusterer. private String dispayed3DColorSpace = ""; /** * Creates new form IntensityClusteringFrame */ public IntensityClustering() { initComponents(); try { this.setIconImage(ImageIO.read((getClass().getResource("/intensityclustering/icon.png")))); } catch (IOException ex) { Logger.getLogger(IntensityClustering.class.getName()).log(Level.SEVERE, null, ex); } } /** * This method is called from within the constructor to initialize the form. * WARNING: Do NOT modify this code. The content of this method is always * regenerated by the Form Editor. */ @SuppressWarnings("unchecked") // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents private void initComponents() { java.awt.GridBagConstraints gridBagConstraints; buttonGroup1 = new javax.swing.ButtonGroup(); buttonGroup2 = new javax.swing.ButtonGroup(); buttonGroup3 = new javax.swing.ButtonGroup(); buttonGroup4 = new javax.swing.ButtonGroup(); jPanel20 = new javax.swing.JPanel(); jPanel11 = new javax.swing.JPanel(); jPanel2 = new javax.swing.JPanel(); jPanel28 = new javax.swing.JPanel(); jLabel39 = new javax.swing.JLabel(); jLabel41 = new javax.swing.JLabel(); jPanel9 = new javax.swing.JPanel(); jPanel15 = new javax.swing.JPanel(); jPanel29 = new javax.swing.JPanel(); jLabel5 = new javax.swing.JLabel(); jTextField1 = new javax.swing.JTextField(); jLabel30 = new javax.swing.JLabel(); jTextField16 = new javax.swing.JTextField(); jLabel36 = new javax.swing.JLabel(); jTextField17 = new javax.swing.JTextField(); jSlider7 = new javax.swing.JSlider(); jPanel21 = new javax.swing.JPanel(); jLabel38 = new javax.swing.JLabel(); jLabel42 = new javax.swing.JLabel(); jPanel5 = new javax.swing.JPanel(); jPanel25 = new javax.swing.JPanel(); jPanel4 = new javax.swing.JPanel(); jLabel34 = new javax.swing.JLabel(); jPanel8 = new javax.swing.JPanel(); jXColorSelectionButton3 = new org.jdesktop.swingx.JXColorSelectionButton(); jXColorSelectionButton4 = new org.jdesktop.swingx.JXColorSelectionButton(); jXColorSelectionButton5 = new org.jdesktop.swingx.JXColorSelectionButton(); jXColorSelectionButton6 = new org.jdesktop.swingx.JXColorSelectionButton(); jLabel35 = new javax.swing.JLabel(); jPanel18 = new javax.swing.JPanel(); jButton13 = new javax.swing.JButton(); jRadioButton7 = new javax.swing.JRadioButton(); jRadioButton8 = new javax.swing.JRadioButton(); jRadioButton13 = new javax.swing.JRadioButton(); jButton1 = new javax.swing.JButton(); jLabel37 = new javax.swing.JLabel(); jPanel17 = new javax.swing.JPanel(); jRadioButton9 = new javax.swing.JRadioButton(); jRadioButton10 = new javax.swing.JRadioButton(); jRadioButton11 = new javax.swing.JRadioButton(); jRadioButton12 = new javax.swing.JRadioButton(); jButton16 = new javax.swing.JButton(); jButton17 = new javax.swing.JButton(); jButton2 = new javax.swing.JButton(); jButton3 = new javax.swing.JButton(); jPanel22 = new javax.swing.JPanel(); jPanel26 = new javax.swing.JPanel(); jPanel23 = new javax.swing.JPanel(); jRadioButton3 = new javax.swing.JRadioButton(); jButton14 = new javax.swing.JButton(); jPanel27 = new javax.swing.JPanel(); jPanel24 = new javax.swing.JPanel(); jButton15 = new javax.swing.JButton(); jPanel12 = new javax.swing.JPanel(); jRadioButton1 = new javax.swing.JRadioButton(); jPanel16 = new javax.swing.JPanel(); jRadioButton2 = new javax.swing.JRadioButton(); jComboBox2 = new javax.swing.JComboBox(); jLabel43 = new javax.swing.JLabel(); jRadioButton5 = new javax.swing.JRadioButton(); jRadioButton6 = new javax.swing.JRadioButton(); jRadioButton4 = new javax.swing.JRadioButton(); jButton18 = new javax.swing.JButton(); jPanel30 = new javax.swing.JPanel(); jLabel40 = new javax.swing.JLabel(); jScrollPane1 = new javax.swing.JScrollPane(); jTextArea1 = new javax.swing.JTextArea(); setTitle(PLUGINNAME + " v1." + java.util.ResourceBundle.getBundle("intensityclustering/Bundle").getString("build")); // NOI18N jPanel20.setLayout(new java.awt.BorderLayout()); jPanel11.setLayout(new java.awt.GridLayout(2, 1, 10, 10)); jPanel2.setBorder(javax.swing.BorderFactory.createEtchedBorder()); jPanel2.setPreferredSize(new java.awt.Dimension(500, 330)); jPanel2.setLayout(new java.awt.BorderLayout()); jPanel28.setLayout(new javax.swing.BoxLayout(jPanel28, javax.swing.BoxLayout.PAGE_AXIS)); jLabel39.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N jLabel39.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("intensityclustering/Bundle"); // NOI18N jLabel39.setText(bundle.getString("IntensityClustering.jLabel39.text")); // NOI18N jLabel39.setAlignmentX(0.5F); jPanel28.add(jLabel39); jLabel41.setForeground(new java.awt.Color(255, 0, 0)); jLabel41.setText(bundle.getString("IntensityClustering.jLabel41.text")); // NOI18N jLabel41.setAlignmentX(0.5F); jPanel28.add(jLabel41); jPanel2.add(jPanel28, java.awt.BorderLayout.PAGE_START); jPanel11.add(jPanel2); jPanel9.setBorder(javax.swing.BorderFactory.createEtchedBorder()); jPanel9.setPreferredSize(new java.awt.Dimension(500, 330)); jPanel9.setLayout(new java.awt.BorderLayout()); jPanel15.setLayout(new java.awt.BorderLayout()); jPanel29.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.RIGHT, 1, 0)); jLabel5.setText(bundle.getString("IntensityClustering.jLabel5.text")); // NOI18N jPanel29.add(jLabel5); jTextField1.setColumns(3); jTextField1.setHorizontalAlignment(javax.swing.JTextField.TRAILING); jTextField1.setText(bundle.getString("IntensityClustering.jTextField1.text")); // NOI18N jTextField1.setMargin(new java.awt.Insets(0, 0, 0, 0)); jTextField1.addKeyListener(new java.awt.event.KeyAdapter() { public void keyPressed(java.awt.event.KeyEvent evt) { jTextField1KeyPressed(evt); } }); jPanel29.add(jTextField1); jLabel30.setText(bundle.getString("IntensityClustering.jLabel30.text")); // NOI18N jPanel29.add(jLabel30); jTextField16.setColumns(3); jTextField16.setHorizontalAlignment(javax.swing.JTextField.TRAILING); jTextField16.setText(bundle.getString("IntensityClustering.jTextField16.text")); // NOI18N jTextField16.setMargin(new java.awt.Insets(0, 0, 0, 0)); jTextField16.addKeyListener(new java.awt.event.KeyAdapter() { public void keyReleased(java.awt.event.KeyEvent evt) { jTextField16KeyReleased(evt); } }); jPanel29.add(jTextField16); jLabel36.setText(bundle.getString("IntensityClustering.jLabel36.text")); // NOI18N jPanel29.add(jLabel36); jTextField17.setColumns(3); jTextField17.setHorizontalAlignment(javax.swing.JTextField.TRAILING); jTextField17.setToolTipText(bundle.getString("IntensityClustering.jTextField17.toolTipText")); // NOI18N jTextField17.setBorder(null); jTextField17.setOpaque(false); jPanel29.add(jTextField17); jSlider7.setMaximum(255); jSlider7.setMinimum(2); jSlider7.setValue(51); jSlider7.setOpaque(false); jSlider7.setPreferredSize(new java.awt.Dimension(100, 26)); jSlider7.addChangeListener(new javax.swing.event.ChangeListener() { public void stateChanged(javax.swing.event.ChangeEvent evt) { jSlider7StateChanged(evt); } }); jPanel29.add(jSlider7); jPanel15.add(jPanel29, java.awt.BorderLayout.PAGE_START); jPanel9.add(jPanel15, java.awt.BorderLayout.PAGE_END); jPanel21.setLayout(new javax.swing.BoxLayout(jPanel21, javax.swing.BoxLayout.PAGE_AXIS)); jLabel38.setBackground(jPanel9.getBackground().darker()); jLabel38.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N jLabel38.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); jLabel38.setText(bundle.getString("IntensityClustering.jLabel38.text")); // NOI18N jLabel38.setAlignmentX(0.5F); jPanel21.add(jLabel38); jLabel42.setForeground(new java.awt.Color(255, 0, 0)); jLabel42.setText(bundle.getString("IntensityClustering.jLabel42.text")); // NOI18N jLabel42.setAlignmentX(0.5F); jPanel21.add(jLabel42); jPanel9.add(jPanel21, java.awt.BorderLayout.NORTH); jPanel11.add(jPanel9); jPanel20.add(jPanel11, java.awt.BorderLayout.LINE_END); jPanel5.setLayout(new java.awt.BorderLayout()); jPanel25.setLayout(new java.awt.BorderLayout()); jPanel4.setLayout(new java.awt.GridBagLayout()); jLabel34.setText(bundle.getString("IntensityClustering.jLabel34.text")); // NOI18N jLabel34.setToolTipText(bundle.getString("IntensityClustering.jLabel34.toolTipText")); // NOI18N gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 2; gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START; gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 0); jPanel4.add(jLabel34, gridBagConstraints); jPanel8.setLayout(new java.awt.GridLayout(1, 1, 15, 0)); jXColorSelectionButton3.setBackground(new java.awt.Color(0, 0, 255)); jXColorSelectionButton3.setText(bundle.getString("IntensityClustering.jXColorSelectionButton3.text")); // NOI18N jPanel8.add(jXColorSelectionButton3); jXColorSelectionButton4.setBackground(new java.awt.Color(0, 0, 255)); jPanel8.add(jXColorSelectionButton4); jXColorSelectionButton5.setBackground(new java.awt.Color(0, 0, 255)); jPanel8.add(jXColorSelectionButton5); jXColorSelectionButton6.setBackground(new java.awt.Color(0, 0, 255)); jPanel8.add(jXColorSelectionButton6); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 1; gridBagConstraints.gridy = 3; gridBagConstraints.gridwidth = 4; gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START; gridBagConstraints.insets = new java.awt.Insets(0, 20, 10, 0); jPanel4.add(jPanel8, gridBagConstraints); jLabel35.setText(bundle.getString("IntensityClustering.jLabel35.text")); // NOI18N gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 3; gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START; gridBagConstraints.insets = new java.awt.Insets(0, 5, 10, 0); jPanel4.add(jLabel35, gridBagConstraints); jPanel18.setLayout(new java.awt.GridBagLayout()); jButton13.setText(bundle.getString("IntensityClustering.jButton13.text")); // NOI18N jButton13.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jButton13ActionPerformed(evt); } }); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 1; gridBagConstraints.gridwidth = 3; gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; gridBagConstraints.insets = new java.awt.Insets(2, 5, 2, 2); jPanel18.add(jButton13, gridBagConstraints); buttonGroup1.add(jRadioButton7); jRadioButton7.setText(bundle.getString("IntensityClustering.jRadioButton7.text")); // NOI18N jRadioButton7.setToolTipText(bundle.getString("IntensityClustering.jRadioButton7.toolTipText")); // NOI18N jRadioButton7.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jRadioButton7ActionPerformed(evt); } }); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 1; gridBagConstraints.gridy = 0; gridBagConstraints.insets = new java.awt.Insets(5, 0, 5, 0); jPanel18.add(jRadioButton7, gridBagConstraints); buttonGroup1.add(jRadioButton8); jRadioButton8.setSelected(true); jRadioButton8.setText(bundle.getString("IntensityClustering.jRadioButton8.text")); // NOI18N jRadioButton8.setToolTipText(bundle.getString("IntensityClustering.jRadioButton8.toolTipText")); // NOI18N jRadioButton8.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jRadioButton8ActionPerformed(evt); } }); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 0; gridBagConstraints.insets = new java.awt.Insets(5, 0, 5, 0); jPanel18.add(jRadioButton8, gridBagConstraints); buttonGroup1.add(jRadioButton13); jRadioButton13.setText(bundle.getString("IntensityClustering.jRadioButton13.text")); // NOI18N jRadioButton13.setToolTipText(bundle.getString("IntensityClustering.jRadioButton13.toolTipText")); // NOI18N jRadioButton13.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jRadioButton13ActionPerformed(evt); } }); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 2; gridBagConstraints.gridy = 0; gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER; gridBagConstraints.insets = new java.awt.Insets(5, 0, 5, 0); jPanel18.add(jRadioButton13, gridBagConstraints); jButton1.setText("Show Nucleus Singlets (very slow)"); jButton1.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jButton1ActionPerformed(evt); } }); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 3; gridBagConstraints.gridy = 1; gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; gridBagConstraints.insets = new java.awt.Insets(2, 5, 2, 2); jPanel18.add(jButton1, gridBagConstraints); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 1; gridBagConstraints.gridwidth = 5; gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START; gridBagConstraints.insets = new java.awt.Insets(0, 10, 5, 0); jPanel4.add(jPanel18, gridBagConstraints); jLabel37.setText(bundle.getString("IntensityClustering.jLabel37.text")); // NOI18N gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 0; gridBagConstraints.gridwidth = 5; gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START; gridBagConstraints.insets = new java.awt.Insets(10, 10, 0, 0); jPanel4.add(jLabel37, gridBagConstraints); jPanel17.setLayout(new java.awt.GridLayout(1, 0)); buttonGroup2.add(jRadioButton9); jRadioButton9.setText(bundle.getString("IntensityClustering.jRadioButton9.text")); // NOI18N jRadioButton9.setVerticalTextPosition(javax.swing.SwingConstants.TOP); jPanel17.add(jRadioButton9); buttonGroup2.add(jRadioButton10); jRadioButton10.setText(bundle.getString("IntensityClustering.jRadioButton10.text")); // NOI18N jRadioButton10.setToolTipText(bundle.getString("IntensityClustering.jRadioButton10.toolTipText")); // NOI18N jRadioButton10.setVerticalTextPosition(javax.swing.SwingConstants.TOP); jPanel17.add(jRadioButton10); buttonGroup2.add(jRadioButton11); jRadioButton11.setText(bundle.getString("IntensityClustering.jRadioButton11.text")); // NOI18N jRadioButton11.setVerticalTextPosition(javax.swing.SwingConstants.TOP); jPanel17.add(jRadioButton11); buttonGroup2.add(jRadioButton12); jRadioButton12.setSelected(true); jRadioButton12.setText(bundle.getString("IntensityClustering.jRadioButton12.text")); // NOI18N jRadioButton12.setVerticalTextPosition(javax.swing.SwingConstants.TOP); jPanel17.add(jRadioButton12); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 1; gridBagConstraints.gridy = 2; gridBagConstraints.gridwidth = 4; gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START; gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 0); jPanel4.add(jPanel17, gridBagConstraints); jButton16.setText(bundle.getString("IntensityClustering.jButton16.text")); // NOI18N jButton16.setToolTipText(bundle.getString("IntensityClustering.jButton16.toolTipText")); // NOI18N jButton16.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jButton16ActionPerformed(evt); } }); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 1; gridBagConstraints.gridy = 4; gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START; gridBagConstraints.insets = new java.awt.Insets(0, 20, 5, 0); jPanel4.add(jButton16, gridBagConstraints); jButton17.setText(bundle.getString("IntensityClustering.jButton17.text")); // NOI18N jButton17.setToolTipText(bundle.getString("IntensityClustering.jButton17.toolTipText")); // NOI18N jButton17.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jButton17ActionPerformed(evt); } }); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 2; gridBagConstraints.gridy = 4; gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START; gridBagConstraints.insets = new java.awt.Insets(0, 5, 5, 0); jPanel4.add(jButton17, gridBagConstraints); jButton2.setText("Save Cluster Centers..."); jButton2.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jButton2ActionPerformed(evt); } }); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 1; gridBagConstraints.gridy = 5; gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; gridBagConstraints.insets = new java.awt.Insets(0, 20, 5, 0); jPanel4.add(jButton2, gridBagConstraints); jButton3.setText("Load Cluster Centers..."); jButton3.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jButton3ActionPerformed(evt); } }); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 2; gridBagConstraints.gridy = 5; gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; gridBagConstraints.insets = new java.awt.Insets(0, 5, 5, 0); jPanel4.add(jButton3, gridBagConstraints); jPanel25.add(jPanel4, java.awt.BorderLayout.LINE_START); jPanel5.add(jPanel25, java.awt.BorderLayout.PAGE_START); jPanel22.setLayout(new java.awt.BorderLayout()); jPanel26.setBorder(javax.swing.BorderFactory .createTitledBorder(bundle.getString("IntensityClustering.jPanel26.border.title"))); // NOI18N jPanel26.setLayout(new java.awt.BorderLayout()); jPanel23.setLayout(new java.awt.GridBagLayout()); buttonGroup3.add(jRadioButton3); jRadioButton3.setText(bundle.getString("IntensityClustering.jRadioButton3.text")); // NOI18N jRadioButton3.setVerticalTextPosition(javax.swing.SwingConstants.TOP); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 0; gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START; gridBagConstraints.insets = new java.awt.Insets(10, 5, 0, 0); jPanel23.add(jRadioButton3, gridBagConstraints); jButton14.setText(bundle.getString("IntensityClustering.jButton14.text")); // NOI18N jButton14.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jButton14ActionPerformed(evt); } }); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 2; gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START; gridBagConstraints.insets = new java.awt.Insets(2, 25, 2, 2); jPanel23.add(jButton14, gridBagConstraints); jPanel26.add(jPanel23, java.awt.BorderLayout.PAGE_START); jPanel22.add(jPanel26, java.awt.BorderLayout.LINE_START); jPanel27.setBorder(javax.swing.BorderFactory .createTitledBorder(bundle.getString("IntensityClustering.jPanel27.border.title"))); // NOI18N jPanel27.setLayout(new java.awt.BorderLayout()); jPanel24.setLayout(new java.awt.GridBagLayout()); jButton15.setText(bundle.getString("IntensityClustering.jButton15.text")); // NOI18N jButton15.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jButton15ActionPerformed(evt); } }); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 2; gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START; gridBagConstraints.insets = new java.awt.Insets(4, 25, 7, 0); jPanel24.add(jButton15, gridBagConstraints); jPanel12.setLayout(new java.awt.GridLayout(4, 0)); buttonGroup4.add(jRadioButton1); jRadioButton1.setSelected(true); jRadioButton1.setText(bundle.getString("IntensityClustering.jRadioButton1.text")); // NOI18N jPanel12.add(jRadioButton1); jPanel16.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEFT, 0, 0)); buttonGroup4.add(jRadioButton2); jRadioButton2.setText(bundle.getString("IntensityClustering.jRadioButton2.text")); // NOI18N jPanel16.add(jRadioButton2); jComboBox2.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "SINGLE", "COMPLETE", "AVERAGE", "MEAN", "CENTROID", "WARD", "ADJCOMLPETE", "NEIGHBOR_JOINING" })); jComboBox2.setSelectedIndex(4); jPanel16.add(jComboBox2); jLabel43.setText(bundle.getString("IntensityClustering.jLabel43.text")); // NOI18N jLabel43.setToolTipText(bundle.getString("IntensityClustering.jLabel43.toolTipText")); // NOI18N jLabel43.setHorizontalTextPosition(javax.swing.SwingConstants.LEFT); jLabel43.addMouseListener(new java.awt.event.MouseAdapter() { public void mouseClicked(java.awt.event.MouseEvent evt) { jLabel43MouseClicked(evt); } }); jPanel16.add(jLabel43); jPanel12.add(jPanel16); buttonGroup4.add(jRadioButton5); jRadioButton5.setText(bundle.getString("IntensityClustering.jRadioButton5.text")); // NOI18N jPanel12.add(jRadioButton5); buttonGroup4.add(jRadioButton6); jRadioButton6.setText(bundle.getString("IntensityClustering.jRadioButton6.text")); // NOI18N jPanel12.add(jRadioButton6); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 1; gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START; gridBagConstraints.insets = new java.awt.Insets(0, 25, 0, 0); jPanel24.add(jPanel12, gridBagConstraints); buttonGroup3.add(jRadioButton4); jRadioButton4.setSelected(true); jRadioButton4.setText(bundle.getString("IntensityClustering.jRadioButton4.text")); // NOI18N jRadioButton4.setVerticalTextPosition(javax.swing.SwingConstants.TOP); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 0; gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START; gridBagConstraints.insets = new java.awt.Insets(10, 10, 0, 0); jPanel24.add(jRadioButton4, gridBagConstraints); jButton18.setText(bundle.getString("IntensityClustering.jButton18.text")); // NOI18N jButton18.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jButton18ActionPerformed(evt); } }); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 3; gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START; gridBagConstraints.insets = new java.awt.Insets(4, 25, 7, 0); jPanel24.add(jButton18, gridBagConstraints); jPanel27.add(jPanel24, java.awt.BorderLayout.PAGE_START); jPanel30.setLayout(new java.awt.BorderLayout()); jLabel40.setText(bundle.getString("IntensityClustering.jLabel40.text")); // NOI18N jPanel30.add(jLabel40, java.awt.BorderLayout.PAGE_START); jTextArea1.setBackground(SystemColor.info); jTextArea1.setColumns(40); jTextArea1.setFont(jTextArea1.getFont()); jTextArea1.setRows(5); jTextArea1.setText(bundle.getString("IntensityClustering.jTextArea1.text")); // NOI18N jTextArea1.setWrapStyleWord(true); jScrollPane1.setViewportView(jTextArea1); jPanel30.add(jScrollPane1, java.awt.BorderLayout.CENTER); jPanel27.add(jPanel30, java.awt.BorderLayout.CENTER); jPanel22.add(jPanel27, java.awt.BorderLayout.CENTER); jPanel5.add(jPanel22, java.awt.BorderLayout.CENTER); jPanel20.add(jPanel5, java.awt.BorderLayout.CENTER); getContentPane().add(jPanel20, java.awt.BorderLayout.CENTER); pack(); }// </editor-fold>//GEN-END:initComponents private void jTextField1KeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_jTextField1KeyPressed if (evt.getKeyCode() == KeyEvent.VK_ENTER) { drawNucleiIntensities2D(manager.getSelectedTMAspots(), false); } }//GEN-LAST:event_jTextField1KeyPressed private void jTextField16KeyReleased(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_jTextField16KeyReleased if (evt.getKeyCode() == KeyEvent.VK_ENTER) { drawNucleiIntensities2D(manager.getSelectedTMAspots(), false); } }//GEN-LAST:event_jTextField16KeyReleased private void jSlider7StateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_jSlider7StateChanged drawNucleiIntensities2D(manager.getSelectedTMAspots(), false); }//GEN-LAST:event_jSlider7StateChanged private void jButton13ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton13ActionPerformed List<TMAspot> tss = manager.getSelectedTMAspots(); drawNucleiIntensities3D(tss); drawNucleiIntensities2D(tss, false); jLabel41.setText(" "); jLabel42.setText(" "); }//GEN-LAST:event_jButton13ActionPerformed private void jRadioButton7ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jRadioButton7ActionPerformed //drawNucleiIntensities3D(manager.getSelectedTMAspots()); change3DPlotAxis(); }//GEN-LAST:event_jRadioButton7ActionPerformed private void jRadioButton8ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jRadioButton8ActionPerformed //drawNucleiIntensities3D(manager.getSelectedTMAspots()); change3DPlotAxis(); }//GEN-LAST:event_jRadioButton8ActionPerformed private void jRadioButton13ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jRadioButton13ActionPerformed //drawNucleiIntensities3D(manager.getSelectedTMAspots()); change3DPlotAxis(); }//GEN-LAST:event_jRadioButton13ActionPerformed private void jButton16ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton16ActionPerformed adoptMeanIntensities(); drawNucleiIntensities3D(manager.getSelectedTMAspots()); drawNucleiIntensities2D(manager.getSelectedTMAspots(), false); }//GEN-LAST:event_jButton16ActionPerformed private void jButton17ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton17ActionPerformed adoptUnkownPointsIntensities(); drawNucleiIntensities3D(manager.getSelectedTMAspots()); drawNucleiIntensities2D(manager.getSelectedTMAspots(), false); }//GEN-LAST:event_jButton17ActionPerformed private void jButton14ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton14ActionPerformed clusterPointsManually(manager.getSelectedTMAspots()); JGoogleAnalyticsTracker tracker = new JGoogleAnalyticsTracker("TMARKER", "UA-61194283-1"); FocusPoint focusPoint = new FocusPoint("IntensityClusteringManualUsage"); tracker.trackAsynchronously(focusPoint); }//GEN-LAST:event_jButton14ActionPerformed private void jButton15ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton15ActionPerformed clusterPointsAutomaticallyColorSpace(manager.getSelectedTMAspots()); drawNucleiIntensities2D(manager.getSelectedTMAspots(), false); JGoogleAnalyticsTracker tracker = new JGoogleAnalyticsTracker("TMARKER", "UA-61194283-1"); FocusPoint focusPoint = new FocusPoint("IntensityClusteringAutomatic3D"); tracker.trackAsynchronously(focusPoint); }//GEN-LAST:event_jButton15ActionPerformed private void jLabel43MouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jLabel43MouseClicked displayDendrogram(); }//GEN-LAST:event_jLabel43MouseClicked private void jButton18ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton18ActionPerformed drawNucleiIntensities2D(manager.getSelectedTMAspots(), true); drawNucleiIntensities3D(manager.getSelectedTMAspots()); JGoogleAnalyticsTracker tracker = new JGoogleAnalyticsTracker("TMARKER", "UA-61194283-1"); FocusPoint focusPoint = new FocusPoint("IntensityClusteringAutomatic2D"); tracker.trackAsynchronously(focusPoint); }//GEN-LAST:event_jButton18ActionPerformed private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed List<TMAspot> tss = manager.getSelectedTMAspots(); drawNucleiIntensities3DSinglets(tss); jLabel41.setText(" "); }//GEN-LAST:event_jButton1ActionPerformed private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton3ActionPerformed loadClusterCenters(); }//GEN-LAST:event_jButton3ActionPerformed private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton2ActionPerformed saveClusterCenters(); }//GEN-LAST:event_jButton2ActionPerformed /** * @param args the command line arguments */ public static void main(String args[]) { /* Set the Nimbus look and feel */ //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) "> /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel. * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html */ try { for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) { if ("Nimbus".equals(info.getName())) { javax.swing.UIManager.setLookAndFeel(info.getClassName()); break; } } } catch (ClassNotFoundException ex) { java.util.logging.Logger.getLogger(IntensityClustering.class.getName()) .log(java.util.logging.Level.SEVERE, null, ex); } catch (InstantiationException ex) { java.util.logging.Logger.getLogger(IntensityClustering.class.getName()) .log(java.util.logging.Level.SEVERE, null, ex); } catch (IllegalAccessException ex) { java.util.logging.Logger.getLogger(IntensityClustering.class.getName()) .log(java.util.logging.Level.SEVERE, null, ex); } catch (javax.swing.UnsupportedLookAndFeelException ex) { java.util.logging.Logger.getLogger(IntensityClustering.class.getName()) .log(java.util.logging.Level.SEVERE, null, ex); } //</editor-fold> /* Create and display the form */ java.awt.EventQueue.invokeLater(new Runnable() { @Override public void run() { new IntensityClustering().setVisible(true); } }); } // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.ButtonGroup buttonGroup1; private javax.swing.ButtonGroup buttonGroup2; private javax.swing.ButtonGroup buttonGroup3; private javax.swing.ButtonGroup buttonGroup4; private javax.swing.JButton jButton1; private javax.swing.JButton jButton13; private javax.swing.JButton jButton14; private javax.swing.JButton jButton15; private javax.swing.JButton jButton16; private javax.swing.JButton jButton17; private javax.swing.JButton jButton18; private javax.swing.JButton jButton2; private javax.swing.JButton jButton3; private javax.swing.JComboBox jComboBox2; private javax.swing.JLabel jLabel30; private javax.swing.JLabel jLabel34; private javax.swing.JLabel jLabel35; private javax.swing.JLabel jLabel36; private javax.swing.JLabel jLabel37; private javax.swing.JLabel jLabel38; private javax.swing.JLabel jLabel39; private javax.swing.JLabel jLabel40; private javax.swing.JLabel jLabel41; private javax.swing.JLabel jLabel42; private javax.swing.JLabel jLabel43; private javax.swing.JLabel jLabel5; private javax.swing.JPanel jPanel11; private javax.swing.JPanel jPanel12; private javax.swing.JPanel jPanel15; private javax.swing.JPanel jPanel16; private javax.swing.JPanel jPanel17; private javax.swing.JPanel jPanel18; private javax.swing.JPanel jPanel2; private javax.swing.JPanel jPanel20; private javax.swing.JPanel jPanel21; private javax.swing.JPanel jPanel22; private javax.swing.JPanel jPanel23; private javax.swing.JPanel jPanel24; private javax.swing.JPanel jPanel25; private javax.swing.JPanel jPanel26; private javax.swing.JPanel jPanel27; private javax.swing.JPanel jPanel28; private javax.swing.JPanel jPanel29; private javax.swing.JPanel jPanel30; private javax.swing.JPanel jPanel4; private javax.swing.JPanel jPanel5; private javax.swing.JPanel jPanel8; private javax.swing.JPanel jPanel9; private javax.swing.JRadioButton jRadioButton1; private javax.swing.JRadioButton jRadioButton10; private javax.swing.JRadioButton jRadioButton11; private javax.swing.JRadioButton jRadioButton12; private javax.swing.JRadioButton jRadioButton13; private javax.swing.JRadioButton jRadioButton2; private javax.swing.JRadioButton jRadioButton3; private javax.swing.JRadioButton jRadioButton4; private javax.swing.JRadioButton jRadioButton5; private javax.swing.JRadioButton jRadioButton6; private javax.swing.JRadioButton jRadioButton7; private javax.swing.JRadioButton jRadioButton8; private javax.swing.JRadioButton jRadioButton9; private javax.swing.JScrollPane jScrollPane1; private javax.swing.JSlider jSlider7; private javax.swing.JTextArea jTextArea1; private javax.swing.JTextField jTextField1; private javax.swing.JTextField jTextField16; private javax.swing.JTextField jTextField17; private org.jdesktop.swingx.JXColorSelectionButton jXColorSelectionButton3; private org.jdesktop.swingx.JXColorSelectionButton jXColorSelectionButton4; private org.jdesktop.swingx.JXColorSelectionButton jXColorSelectionButton5; private org.jdesktop.swingx.JXColorSelectionButton jXColorSelectionButton6; // End of variables declaration//GEN-END:variables @Override public String getAuthor() { return "Peter J. Schffler"; } @Override public String getVersion() { return PLUGINVERSION; } @Override public boolean start() { return true; } @Override public boolean stop() { setVisible(false); return true; } @Override public void setPluginManager(PluginManager manager) { this.manager = manager; } @Override public Icon getIcon() { return new ImageIcon(this.getIconImage()); } @Override public String getPluginName() { return PLUGINNAME; } @Override public void actionPerformed(java.awt.event.ActionEvent evt) { jLabel41.setText(" "); jLabel42.setText(" "); this.setVisible(true); adoptUnkownPointsIntensities(); List<TMAspot> tss = manager.getSelectedTMAspots(); if (!tss.isEmpty()) { drawNucleiIntensities3D(tss); drawNucleiIntensities2D(tss, false); } } @Override public void setParameterDefaults() { setParam_nClusters(4); setParam_ColorSpace("HSB"); setParam_ColorOfClassK(0, Color.BLUE); setParam_ColorOfClassK(1, Color.YELLOW); setParam_ColorOfClassK(2, Color.ORANGE); setParam_ColorOfClassK(3, Color.RED); setParam_ManualAutomaticClustering(1); setParam_AutomaticClustererString("K-Means"); setParam_HierarchicalClusteringMethod("CENTROID"); } @Override public void setParameters(Properties parameters) { String value; value = parameters.getProperty("nClusters"); if (value != null) { setParam_nClusters(Integer.parseInt(value)); } value = parameters.getProperty("colorSpace"); if (value != null) { setParam_ColorSpace(value); } value = parameters.getProperty("colorClass0"); if (value != null) { setParam_ColorOfClassK(0, new Color(Integer.parseInt(value))); } value = parameters.getProperty("colorClass1"); if (value != null) { setParam_ColorOfClassK(1, new Color(Integer.parseInt(value))); } value = parameters.getProperty("colorClass2"); if (value != null) { setParam_ColorOfClassK(2, new Color(Integer.parseInt(value))); } value = parameters.getProperty("colorClass3"); if (value != null) { setParam_ColorOfClassK(3, new Color(Integer.parseInt(value))); } value = parameters.getProperty("manualAutomaticClustering"); if (value != null) { setParam_ManualAutomaticClustering(Integer.parseInt(value)); } value = parameters.getProperty("automaticClusteringString"); if (value != null) { setParam_AutomaticClustererString(value); } value = parameters.getProperty("hierarchicalClusteringMethod"); if (value != null) { setParam_HierarchicalClusteringMethod(value); } } @Override public Properties getParameters() { Properties parameters = new Properties(); parameters.setProperty("nClusters", Integer.toString(getParam_nClusters())); parameters.setProperty("colorSpace", getParam_ColorSpace()); parameters.setProperty("colorClass0", Integer.toString(getParam_ColorOfClassK(0).getRGB())); parameters.setProperty("colorClass1", Integer.toString(getParam_ColorOfClassK(1).getRGB())); parameters.setProperty("colorClass2", Integer.toString(getParam_ColorOfClassK(2).getRGB())); parameters.setProperty("colorClass3", Integer.toString(getParam_ColorOfClassK(3).getRGB())); parameters.setProperty("manualAutomaticClustering", Integer.toString(getParam_ManualAutomaticClustering())); parameters.setProperty("automaticClusteringString", getParam_AutomaticClustererString()); parameters.setProperty("hierarchicalClusteringMethod", getParam_HierarchicalClusteringMethod()); return parameters; } @Override public String getHTMLReport(String HTMLFolderPath) { String output = "<html>"; char linebreak = '\n'; String HTMLFolderName = new File(HTMLFolderPath).getName() + File.separator; // Save the intensity plot images if (!getClusteringDescription().equals("-")) { try { File file_tmp = new File(HTMLFolderPath + "3DPlot.png"); BufferedImage bi = get3DPlot(); ImageIO.write(bi, "png", file_tmp); file_tmp = new File(HTMLFolderPath + "2DPlot.png"); bi = get2DPlot(); ImageIO.write(bi, "png", file_tmp); } catch (IOException ex) { Logger.getLogger(IntensityClustering.class.getName()).log(Level.SEVERE, null, ex); } } output += "<table><tr>" + linebreak + " <td colspan=2><i><u>Intensity Clustering Parameters</u></i></td>" + linebreak + " </tr>" + linebreak + " <tr>" + linebreak + " <td><b>Color Space</b></td>" + linebreak + " <td>" + getParam_ColorSpace() + "</td>" + linebreak + " </tr>" + linebreak + " <tr>" + linebreak + " <td><b>Number of Classes</b></td>" + linebreak + " <td>" + getParam_nClusters() + "</td>" + linebreak + " </tr>" + linebreak + " <tr>" + linebreak + " <td><b>Clustering:</b></td>" + linebreak + " <td>" + getClusteringDescription() + "</td>" + linebreak + " </tr>" + linebreak; if (!getClusteringDescription().equals("-")) { // save the two clustering images output += " <tr>" + linebreak + " <td></td>" + linebreak + " <td>" + " <br><a href=\"" + HTMLFolderName + "3DPlot.png\"><img alt=\"Nucleus Distribution in Color Space\" src=\"" + HTMLFolderName + "3DPlot.png\" width=400></a> " + linebreak + " <a href=\"" + HTMLFolderName + "2DPlot.png\"><img alt=\"Nucleus Distribution in Color Space\" src=\"" + HTMLFolderName + "2DPlot.png\" width=400></a><br><br>" + linebreak + " </td>" + " </tr>" + linebreak + " <tr>" + linebreak + " <td></td>" + linebreak + " <td><textarea rows=\"10\" cols=\"115\">" + getClustererInfo() + "</textarea></td>" + linebreak + " </tr>" + linebreak; } output += "</table><br>" + linebreak; output += "</html>"; return output; } @Override public void updateOptionsToTMAspot(TMAspot visible_TMAspot, List<TMAspot> selected_TMAspots) { if (isShowing()) { drawNucleiIntensities2D(selected_TMAspots, false); drawNucleiIntensities3D(selected_TMAspots); } } @Override public void drawInformationPreNuclei(TMAspot ts, Graphics g, double z, int x_min, int y_min, int x_max, int y_max) { } @Override public void drawInformationPostNuclei(TMAspot ts, Graphics g, double z, int x_min, int y_min, int x_max, int y_max) { } @Override public BufferedImage showAlternativeImage(TMAspot ts) { return null; } @Override public void TMAspotMouseClicked(TMAspot ts, TMApoint tp, MouseEvent evt) { } /** * Draws the 2D Histogram Plot in the IntensityClustering. X-Axsis is * intensity value of chanel 2 image (where the stained nuclei are). Y-axis * are relative frequencies of present nuclei. * * @param tss The TMAspots whose nuclei are considered (both gold-standard * and estimated nuclei). * @param doAlsoClustering If true, the TMApoints are also clustered * according to the histogram. */ void drawNucleiIntensities2D(List<TMAspot> tss, boolean doAlsoClustering) { // draw the plot Plot2DPanel plot; if (((java.awt.BorderLayout) (jPanel9.getLayout())) .getLayoutComponent(java.awt.BorderLayout.CENTER) != null) { plot = (Plot2DPanel) ((java.awt.BorderLayout) (jPanel9.getLayout())) .getLayoutComponent(java.awt.BorderLayout.CENTER); plot.removeAllPlots(); plot.removeAllPlotables(); } else { plot = new Plot2DPanel(PlotPanel.SOUTH); plot.setAxisLabels("Intensity", "Frequency"); plot.plotCanvas.setBackground(jPanel9.getBackground()); plot.plotLegend.setBackground(jPanel9.getBackground()); plot.plotToolBar.setBackground(plot.plotCanvas.getBackground()); } if (((java.awt.BorderLayout) (jPanel9.getLayout())) .getLayoutComponent(java.awt.BorderLayout.CENTER) == null) { jPanel9.add(plot, java.awt.BorderLayout.CENTER); jPanel15.setBackground(plot.plotCanvas.getBackground()); jPanel15.setVisible(true); validate(); pack(); } if (tss.size() > 0) { try { this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); List<Integer> intensities = new ArrayList<>(); int intensity; int min = Integer.parseInt(jTextField1.getText()); int max = Integer.parseInt(jTextField16.getText()); for (TMAspot ts : tss) { //TODO: GET THE CHANNEL 2 Image //BufferedImage img = ts.getBufferedImage(TMAspot.SHOW_CHANNEL2_IMAGE, false); BufferedImage img = ts.getBufferedImage(false); // img can be null if color deconvolution has not been performed, yet. if (img != null) { List<TMApoint> tps = ts.getPoints(); for (TMALabel tp : tps) { intensity = TMAspot.getAverageColorAtPoint(img, tp.x, tp.y, ts.getParam_r(), false) .getRed(); if (intensity >= min && intensity <= max) { intensities.add(intensity); } } } } double[] intensities_array = new double[intensities.size()]; for (int i = 0; i < intensities.size(); i++) { intensities_array[i] = intensities.get(i); } int nbins = jSlider7.getValue(); if (intensities_array.length > 0) { plot.addHistogramPlot("TMA points", intensities_array, 0, 256, nbins); } //else { // JOptionPane.showMessageDialog(this, "No TMA points have been found.", "No TMA points found.", JOptionPane.WARNING_MESSAGE); //} //// Cluster Points according to histograms if (doAlsoClustering) { // Find Clusters int n = getParam_nClusters(); // Create ARFF Data FastVector atts; Instances data; int i; // 1. create arff data format atts = new FastVector(1); for (i = 0; i < 1; i++) { atts.addElement(new Attribute(Integer.toString(i))); } // 2. create Instances object data = new Instances("TMA points", atts, tmarker.getNumberNuclei(tss)); // 3. fill with data for (i = 0; i < intensities_array.length; i++) { // add the instance Instance inst = new Instance(1.0, new double[] { intensities_array[i] }); inst.setDataset(data); data.add(inst); } // 4. set data class index (last attribute is the class) //data.setClassIndex(data.numAttributes() - 1); // not for weka 3.5.X if (tmarker.DEBUG > 4) { java.util.logging.Logger.getLogger(getClass().getName()).log(java.util.logging.Level.INFO, data.toString()); } Clusterer clusterer = getClusterer(); String[] options = getClustererOptions(); if (tmarker.DEBUG > 3) { if (options.length > 0) { String info = "Clusterer should have options:\n"; for (String o : options) { info += o + " "; } info += "\n"; java.util.logging.Logger.getLogger(getClass().getName()) .log(java.util.logging.Level.INFO, info); } } clusterer.setOptions(options); // set the clusterer options clusterer.buildClusterer(data); // build the clusterer // order the clusters according to the brightness // The most bright cluster should be 0, then 1, then 2,... ArrayList<ArrayList<Double>> values = new ArrayList<>(); for (i = 0; i < n; i++) { values.add(new ArrayList<Double>()); } int z; double value; for (i = 0; i < data.numInstances(); i++) { z = clusterer.clusterInstance(data.instance(i)); value = data.instance(i).value(0); values.get(z).add(value); } double[] means = new double[n]; double[] stds = new double[n]; for (i = 0; i < n; i++) { means[i] = Misc.mean(values.get(i).toArray(new Double[values.get(i).size()])); stds[i] = Misc.std(values.get(i).toArray(new Double[values.get(i).size()])); } int[] ordering = Misc.orderArray(means, true); for (i = 0; i < n; i++) { int ind = Misc.IndexOf(ordering, i); plot.addPlotable(new Line(getParam_ColorOfClassK(i), new double[] { means[ind], plot.plotCanvas.base.roundXmin[1] }, new double[] { means[ind], plot.plotCanvas.base.roundXmax[1] }, 2 * stds[ind])); plot.addPlot(Plot2DPanel.LINE, "Staining " + i, getParam_ColorOfClassK(i), new double[][] { new double[] { means[ind], plot.plotCanvas.base.roundXmin[1] }, new double[] { means[ind], plot.plotCanvas.base.roundXmax[1] } }); } String clusterInfo = ""; for (String o : clusterer.getOptions()) { clusterInfo += o + " "; } clusterInfo += "\n\n"; clusterInfo += clusterer.toString().trim(); if (getParam_AutomaticClustererString().equalsIgnoreCase("Hierarchical")) { try { clusterInfo += ((HierarchicalClusterer) clusterer).graph(); HierarchyVisualizer a = new HierarchyVisualizer( ((HierarchicalClusterer) clusterer).graph()); a.setSize(800, 600); if (clusterVisualizer == null) { clusterVisualizer = new JFrame("Hierarchical Clusterer Dendrogram"); clusterVisualizer.setIconImage(getIconImage()); clusterVisualizer.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); clusterVisualizer.setSize(800, 600); } Container contentPane = clusterVisualizer.getContentPane(); contentPane.removeAll(); contentPane.add(a); } catch (Exception e) { clusterVisualizer = null; } } jTextArea1.setText(clusterInfo); if (tmarker.DEBUG > 3) { String info = "Clusterer has options\n"; for (String o : clusterer.getOptions()) { info += o + " "; } info += "\n"; info += clusterer.toString() + "\n"; // info += (clusterer).globalInfo() + "\n"; info += "\n"; info += clusterInfo + "\n"; java.util.logging.Logger.getLogger(getClass().getName()).log(java.util.logging.Level.INFO, info); } // cluster all TMAspots and assign the corresponding class to them // Cluster the points List<List<Integer>> clustered_points = new ArrayList<>(); for (i = 0; i < n; i++) { clustered_points.add(new ArrayList<Integer>()); } int k; for (TMAspot ts : tss) { //TODO: GET THE CHANNEL 2 IMAGE //BufferedImage img = ts.getBufferedImage(TMAspot.SHOW_CHANNEL2_IMAGE, false); BufferedImage img = ts.getBufferedImage(false); List<TMApoint> tps = ts.getPoints(); for (TMApoint tp : tps) { intensity = TMAspot.getAverageColorAtPoint(img, tp.x, tp.y, ts.getParam_r(), false) .getRed(); // add the instance Instance inst = new Instance(1.0, new double[] { intensity }); inst.setDataset(data); k = ordering[clusterer.clusterInstance(inst)]; // store the color for later visualization clustered_points.get(k).add(intensity); // set the staining of the TMApoint switch (k) { case 0: tp.setStaining(TMALabel.STAINING_0); break; case 1: tp.setStaining(TMALabel.STAINING_1); break; case 2: tp.setStaining(TMALabel.STAINING_2); break; default: tp.setStaining(TMALabel.STAINING_3); break; } } ts.dispStainingInfo(); if (manager.getVisibleTMAspot() == ts) { manager.repaintVisibleTMAspot(); } } // Write the description String description = "Nuclei clustered with " + getParam_AutomaticClustererString(); if (getParam_AutomaticClustererString().equalsIgnoreCase("Hierarchical")) { description += " (" + getParam_HierarchicalClusteringMethod() + ")"; } description += ", n=" + getParam_nClusters() + ", channel 2 intensity."; jLabel42.setText(description); jLabel41.setText(" "); } } catch (Exception e) { e.printStackTrace(); } finally { this.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); } } } /** * Changes the plot axes and transfers the datapoints into another color space (which the user clicked on). */ void change3DPlotAxis() { Plot3DPanel plot; if (((java.awt.BorderLayout) (jPanel2.getLayout())) .getLayoutComponent(java.awt.BorderLayout.CENTER) != null) { plot = (Plot3DPanel) ((java.awt.BorderLayout) (jPanel2.getLayout())) .getLayoutComponent(java.awt.BorderLayout.CENTER); } else { plot = new Plot3DPanel(); plot.plotCanvas.setBackground(jPanel2.getBackground()); plot.plotToolBar.setBackground(plot.plotCanvas.getBackground()); plot.addLegend(PlotPanel.SOUTH); plot.plotLegend.setBackground(jPanel2.getBackground()); } String newcolorSpace = getParam_ColorSpace(); if (newcolorSpace.equalsIgnoreCase("hsb")) { plot.setAxisLabels("Hue", "Saturation", "Brightness"); } else if (newcolorSpace.equalsIgnoreCase("rtp")) { plot.setAxisLabels("R", "Theta", "Phi"); } else { plot.setAxisLabels("Red", "Green", "Blue"); } List<Plot> plots = plot.getPlots(); float[] container = new float[3]; for (Plot scatter : plots) { double[][] data = scatter.getData(); for (int i = 0; i < data.length; i++) { double[] point = data[i]; Color c; if (dispayed3DColorSpace.equalsIgnoreCase("rgb")) { c = new Color((int) (point[0]), (int) (point[1]), (int) (point[2])); } else if (dispayed3DColorSpace.equalsIgnoreCase("hsb")) { c = new Color(Color.HSBtoRGB((float) (point[0]), (float) (point[1]), (float) (point[2]))); } else { RTPtoRGB((float) (point[0]), (float) (point[1]), (float) (point[2]), container); try { c = new Color(container[0] / 255.0f, container[1] / 255.0f, container[2] / 255.0f); } catch (Exception e) { c = Color.BLACK; } } Color2Feature(c, newcolorSpace, container); point[0] = container[0]; point[1] = container[1]; point[2] = container[2]; } } // reset axes plot.revalidate(); plot.plotCanvas.resetBase(); plot.plotCanvas.resetMapData(); dispayed3DColorSpace = newcolorSpace; } /** * Draws the 3D Plot in the IntensityClustering. Axis are color values * (either RGB or HSB), points are nuclei. * * @param tss The TMAspots whose nuclei are to be drawn (both gold-standard * and estimated nuclei). */ void drawNucleiIntensities3D(List<TMAspot> tss) { // draw the plot Plot3DPanel plot; if (((java.awt.BorderLayout) (jPanel2.getLayout())) .getLayoutComponent(java.awt.BorderLayout.CENTER) != null) { plot = (Plot3DPanel) ((java.awt.BorderLayout) (jPanel2.getLayout())) .getLayoutComponent(java.awt.BorderLayout.CENTER); plot.removeAllPlots(); } else { plot = new Plot3DPanel(); plot.plotCanvas.setBackground(jPanel2.getBackground()); plot.plotToolBar.setBackground(plot.plotCanvas.getBackground()); plot.addLegend(PlotPanel.SOUTH); plot.plotLegend.setBackground(jPanel2.getBackground()); } plot.plotLegend.setVisible(true); String colorSpace = getParam_ColorSpace(); if (colorSpace.equalsIgnoreCase("hsb")) { plot.setAxisLabels("Hue", "Saturation", "Brightness"); } else if (colorSpace.equalsIgnoreCase("rtp")) { plot.setAxisLabels("R", "Theta", "Phi"); } else { plot.setAxisLabels("Red", "Green", "Blue"); } if (((java.awt.BorderLayout) (jPanel2.getLayout())) .getLayoutComponent(java.awt.BorderLayout.CENTER) == null) { jPanel2.add(plot, java.awt.BorderLayout.CENTER); validate(); pack(); } if (tss.size() > 0) { try { this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); List<Float> rs_0 = new ArrayList<>(); List<Float> gs_0 = new ArrayList<>(); List<Float> bs_0 = new ArrayList<>(); List<Float> rs_1 = new ArrayList<>(); List<Float> gs_1 = new ArrayList<>(); List<Float> bs_1 = new ArrayList<>(); List<Float> rs_2 = new ArrayList<>(); List<Float> gs_2 = new ArrayList<>(); List<Float> bs_2 = new ArrayList<>(); List<Float> rs_3 = new ArrayList<>(); List<Float> gs_3 = new ArrayList<>(); List<Float> bs_3 = new ArrayList<>(); Color c; BufferedImage img; float[] features = new float[3]; for (TMAspot ts : tss) { img = ts.getBufferedImage(); List<TMApoint> tps = ts.getPoints(TMALabel.STAINING_0, false); for (TMApoint tp : tps) { Color2Feature(TMAspot.getAverageColorAtPoint(img, tp.x, tp.y, ts.getParam_r(), false), colorSpace, features); rs_0.add(features[0]); gs_0.add(features[1]); bs_0.add(features[2]); } tps = ts.getPoints(TMALabel.STAINING_1, false); for (TMApoint tp : tps) { Color2Feature(TMAspot.getAverageColorAtPoint(img, tp.x, tp.y, ts.getParam_r(), false), colorSpace, features); rs_1.add(features[0]); gs_1.add(features[1]); bs_1.add(features[2]); } tps = ts.getPoints(TMALabel.STAINING_2, false); for (TMApoint tp : tps) { Color2Feature(TMAspot.getAverageColorAtPoint(img, tp.x, tp.y, ts.getParam_r(), false), colorSpace, features); rs_2.add(features[0]); gs_2.add(features[1]); bs_2.add(features[2]); } tps = ts.getPoints(TMALabel.STAINING_3, false); for (TMApoint tp : tps) { Color2Feature(TMAspot.getAverageColorAtPoint(img, tp.x, tp.y, ts.getParam_r(), false), colorSpace, features); rs_3.add(features[0]); gs_3.add(features[1]); bs_3.add(features[2]); } } double[] xs_0 = new double[rs_0.size()]; double[] ys_0 = new double[gs_0.size()]; double[] zs_0 = new double[bs_0.size()]; double[] xs_1 = new double[rs_1.size()]; double[] ys_1 = new double[gs_1.size()]; double[] zs_1 = new double[bs_1.size()]; double[] xs_2 = new double[rs_2.size()]; double[] ys_2 = new double[gs_2.size()]; double[] zs_2 = new double[bs_2.size()]; double[] xs_3 = new double[rs_3.size()]; double[] ys_3 = new double[gs_3.size()]; double[] zs_3 = new double[bs_3.size()]; for (int i = 0; i < rs_0.size(); i++) { xs_0[i] = rs_0.get(i); ys_0[i] = gs_0.get(i); zs_0[i] = bs_0.get(i); } for (int i = 0; i < rs_1.size(); i++) { xs_1[i] = rs_1.get(i); ys_1[i] = gs_1.get(i); zs_1[i] = bs_1.get(i); } for (int i = 0; i < rs_2.size(); i++) { xs_2[i] = rs_2.get(i); ys_2[i] = gs_2.get(i); zs_2[i] = bs_2.get(i); } for (int i = 0; i < rs_3.size(); i++) { xs_3[i] = rs_3.get(i); ys_3[i] = gs_3.get(i); zs_3[i] = bs_3.get(i); } if (xs_0.length > 0) { c = getParam_ColorOfClassK(0); plot.addScatterPlot("Staining 0", c, xs_0, ys_0, zs_0); } if (xs_1.length > 0) { c = getParam_ColorOfClassK(1); plot.addScatterPlot("Staining 1", c, xs_1, ys_1, zs_1); } if (xs_2.length > 0) { c = getParam_ColorOfClassK(2); plot.addScatterPlot("Staining 2", c, xs_2, ys_2, zs_2); } if (xs_3.length > 0) { c = getParam_ColorOfClassK(3); plot.addScatterPlot("Staining 3", c, xs_3, ys_3, zs_3); } //if (xs_0.length==0 && xs_1.length==0 && xs_2.length==0 && xs_3.length==0) { // JOptionPane.showMessageDialog(this, "No TMA points have been found.", "No TMA points found.", JOptionPane.WARNING_MESSAGE); //} // add cluster Centers defined by the user if (isManualClustering()) { int n = getParam_nClusters(); for (int i = 0; i < n; i++) { c = getParam_ColorOfClassK(i); Color2Feature(c, colorSpace, features); plot.addScatterPlot("Center " + (i + 1), c.darker(), new double[] { features[0] }, new double[] { features[1] }, new double[] { features[2] }); } } } finally { this.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); } } } /** * Draws the 3D Plot in the IntensityClustering. Axis are color values * (either RGB or HSB), points are nuclei. Each nucleus is displayed with its color (rather than with its class color). * * @param tss The TMAspots whose nuclei are to be drawn (both gold-standard * and estimated nuclei). */ void drawNucleiIntensities3DSinglets2(List<TMAspot> tss) { // draw the plot Plot3DPanel plot; if (((java.awt.BorderLayout) (jPanel2.getLayout())) .getLayoutComponent(java.awt.BorderLayout.CENTER) != null) { plot = (Plot3DPanel) ((java.awt.BorderLayout) (jPanel2.getLayout())) .getLayoutComponent(java.awt.BorderLayout.CENTER); plot.removeAllPlots(); } else { plot = new Plot3DPanel(); plot.plotCanvas.setBackground(jPanel2.getBackground()); plot.plotToolBar.setBackground(plot.plotCanvas.getBackground()); plot.addLegend(PlotPanel.SOUTH); plot.plotLegend.setBackground(jPanel2.getBackground()); } plot.plotLegend.setVisible(false); String colorSpace = getParam_ColorSpace(); if (colorSpace.equalsIgnoreCase("hsb")) { plot.setAxisLabels("Hue", "Saturation", "Brightness"); } else if (colorSpace.equalsIgnoreCase("rtp")) { plot.setAxisLabels("R", "Theta", "Phi"); } else { plot.setAxisLabels("Red", "Green", "Blue"); } if (((java.awt.BorderLayout) (jPanel2.getLayout())) .getLayoutComponent(java.awt.BorderLayout.CENTER) == null) { jPanel2.add(plot, java.awt.BorderLayout.CENTER); validate(); pack(); } if (tss.size() > 0) { try { this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); Color c; BufferedImage img; float[] features = new float[3]; double[] xs_0 = new double[1]; double[] ys_0 = new double[1]; double[] zs_0 = new double[1]; for (TMAspot ts : tss) { img = ts.getBufferedImage(); List<TMApoint> tps = ts.getPoints(); for (TMApoint tp : tps) { c = TMAspot.getAverageColorAtPoint(img, tp.x, tp.y, ts.getParam_r(), false); Color2Feature(c, colorSpace, features); xs_0[0] = features[0]; ys_0[0] = features[1]; zs_0[0] = features[2]; plot.addScatterPlot(null, c, xs_0, ys_0, zs_0); } } } finally { this.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); } } } /** * Draws the 3D Plot in the IntensityClustering. Axis are color values * (either RGB or HSB), points are nuclei. Each nucleus is displayed with its color (rather than with its class color). * * @param tss The TMAspots whose nuclei are to be drawn (both gold-standard * and estimated nuclei). */ void drawNucleiIntensities3DSinglets(List<TMAspot> tss) { // draw the plot Plot3DPanel plot; if (((java.awt.BorderLayout) (jPanel2.getLayout())) .getLayoutComponent(java.awt.BorderLayout.CENTER) != null) { plot = (Plot3DPanel) ((java.awt.BorderLayout) (jPanel2.getLayout())) .getLayoutComponent(java.awt.BorderLayout.CENTER); plot.removeAllPlots(); } else { plot = new Plot3DPanel(); plot.plotCanvas.setBackground(jPanel2.getBackground()); plot.plotToolBar.setBackground(plot.plotCanvas.getBackground()); plot.addLegend(PlotPanel.SOUTH); plot.plotLegend.setBackground(jPanel2.getBackground()); } plot.plotLegend.setVisible(false); String colorSpace = getParam_ColorSpace(); if (colorSpace.equalsIgnoreCase("hsb")) { plot.setAxisLabels("Hue", "Saturation", "Brightness"); } else if (colorSpace.equalsIgnoreCase("rtp")) { plot.setAxisLabels("R", "Theta", "Phi"); } else { plot.setAxisLabels("Red", "Green", "Blue"); } if (((java.awt.BorderLayout) (jPanel2.getLayout())) .getLayoutComponent(java.awt.BorderLayout.CENTER) == null) { jPanel2.add(plot, java.awt.BorderLayout.CENTER); validate(); pack(); } if (tss.size() > 0) { try { this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); BufferedImage img; for (TMAspot ts : tss) { img = ts.getBufferedImage(); List<TMApoint> tps = ts.getPoints(); DrawNucleiIntensitySingletsFork.DrawNucleiIntensitySinglets_Fork((TMARKERPluginManager) manager, this, ts, img, tps, colorSpace, plot); } } finally { this.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); } } } static NucleusIntensity3DSinglet drawNucleiIntensity3DSingletsCore(TMAspot ts, BufferedImage img, TMApoint tp, String colorSpace, Plot3DPanel plot) { float[] features = new float[3]; Color c = TMAspot.getAverageColorAtPoint(img, tp.x, tp.y, ts.getParam_r(), false); Color2Feature(c, colorSpace, features); return (new NucleusIntensity3DSinglet(c, features)); //plot.addScatterPlot(null, c, new double[]{features[0]}, new double[]{features[1]}, new double[]{features[2]}); } /** * Adopt the mean colors of already labeled nuclei as cluster centers for * the stainings. */ public void adoptMeanIntensities() { int n = 4; //getParam_nClusters(); if (manager.getVisibleTMAspot() != null) { byte staining; for (int i = 0; i < n; i++) { staining = i == 0 ? TMALabel.STAINING_0 : i == 1 ? TMALabel.STAINING_1 : i == 2 ? TMALabel.STAINING_2 : TMALabel.STAINING_3; setParam_ColorOfClassK(i, manager.getVisibleTMAspot().getAverageColor(staining, false, false)); } } } /** * Adopt the intensities of the "Unknown" points from TMARKER settings as * cluster centers for the stainings. */ public void adoptUnkownPointsIntensities() { int n = 4; //getParam_nClusters(); byte staining; for (int i = 0; i < n; i++) { staining = i == 0 ? TMALabel.STAINING_0 : i == 1 ? TMALabel.STAINING_1 : i == 2 ? TMALabel.STAINING_2 : TMALabel.STAINING_3; setParam_ColorOfClassK(i, manager.getLabelsColor(TMALabel.LABEL_UNK, staining)); } } /** * Clusters the TMApoints on given TMAspots according to their staining * intensity (color) and according to the center points given by the user * (as colors). All parameters (e.g. clusterer and parameters) are selected * by the user. Features are simple color features. * * @param tss The TMAspots of which all nuclei (gold-standard and estimated) * are clustered according to color. */ private void clusterPointsManually(List<TMAspot> tss) { if (tss.size() > 0) { try { tmarker t = tss.get(0).getCenter(); this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); int n = getParam_nClusters(); double[][] centers = new double[n][3]; Color c; float[] features = new float[3]; String colorSpace = getParam_ColorSpace(); for (int i = 0; i < n; i++) { Color2Feature(getParam_ColorOfClassK(i), colorSpace, features); centers[i][0] = features[0]; centers[i][1] = features[1]; centers[i][2] = features[2]; } // Cluster the points List<List<Color>> clustered_points = new ArrayList<>(); for (int i = 0; i < n; i++) { clustered_points.add(new ArrayList<Color>()); } BufferedImage img; double[] dists = new double[n]; int k; for (TMAspot ts : tss) { img = ts.getBufferedImage(); List<TMApoint> tps = ts.getPoints(); for (TMApoint tp : tps) { c = TMAspot.getAverageColorAtPoint(img, tp.x, tp.y, ts.getParam_r(), false); Color2Feature(c, colorSpace, features); // calculate distance to center for (int i = 0; i < n; i++) { dists[i] = Misc.Euclidean_distance( new double[] { features[0], features[1], features[2] }, centers[i]); } // find the min dist k = Misc.min_arg(dists); // assign the point to the class ind byte staining = k == 0 ? TMALabel.STAINING_0 : k == 1 ? TMALabel.STAINING_1 : k == 2 ? TMALabel.STAINING_2 : TMALabel.STAINING_3; tp.setStaining(staining); // store the color for later visualization clustered_points.get(k).add(c); } ts.dispStainingInfo(); if (t.getVisibleTMAspot() == ts) { t.getTMAView().repaint(); } } // draw the points Plot3DPanel plot; if (((java.awt.BorderLayout) (jPanel2.getLayout())) .getLayoutComponent(java.awt.BorderLayout.CENTER) != null) { plot = (Plot3DPanel) ((java.awt.BorderLayout) (jPanel2.getLayout())) .getLayoutComponent(java.awt.BorderLayout.CENTER); plot.removeAllPlots(); } else { plot = new Plot3DPanel(); plot.plotCanvas.setBackground(jPanel2.getBackground()); plot.addLegend(PlotPanel.SOUTH); plot.plotLegend.setBackground(jPanel2.getBackground()); } if (colorSpace.equalsIgnoreCase("hsb")) { plot.setAxisLabels("Hue", "Saturation", "Brightness"); } else if (colorSpace.equalsIgnoreCase("rtp")) { plot.setAxisLabels("R", "Theta", "Phi"); } else { plot.setAxisLabels("Red", "Green", "Blue"); } for (int i = 0; i < n; i++) { double[] xs = new double[clustered_points.get(i).size()]; double[] ys = new double[clustered_points.get(i).size()]; double[] zs = new double[clustered_points.get(i).size()]; for (int j = 0; j < clustered_points.get(i).size(); j++) { Color2Feature(clustered_points.get(i).get(j), colorSpace, features); xs[j] = features[0]; ys[j] = features[1]; zs[j] = features[2]; } if (xs.length > 0) { c = getParam_ColorOfClassK(i); plot.addScatterPlot("Cluster " + (i + 1), c, xs, ys, zs); } } // add cluster Centers defined by the user for (int i = 0; i < n; i++) { c = getParam_ColorOfClassK(i); Color2Feature(c, colorSpace, features); plot.addScatterPlot("Center " + (i + 1), c.darker(), new double[] { features[0] }, new double[] { features[1] }, new double[] { features[2] }); } // Write the description String description = "Nuclei clustered to manual center points with K-Nearest Neighbor"; description += ", n=" + getParam_nClusters() + ", color space " + getParam_ColorSpace() + "."; jLabel41.setText(description); jLabel42.setText(" "); if (((java.awt.BorderLayout) (jPanel2.getLayout())) .getLayoutComponent(java.awt.BorderLayout.CENTER) == null) { jPanel2.add(plot, java.awt.BorderLayout.CENTER); validate(); pack(); } } finally { this.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); } } } /** * Clusters the TMApoints on given TMAspots according to their staining * intensity (color). All parameters (e.g. clusterer and parameters) are * selected by the user. Features are simple color features. * * @param tss The TMAspots of which all nuclei (gold-standard and estimated) * are clustered according to color. */ private void clusterPointsAutomaticallyColorSpace(List<TMAspot> tss) { if (tss.size() > 0) { try { this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); int n = getParam_nClusters(); // Create ARFF Data FastVector atts; Instances data; int i; // 1. create arff data format atts = new FastVector(3); for (i = 0; i < 3; i++) { atts.addElement(new Attribute(Integer.toString(i))); } // 2. create Instances object data = new Instances("TMA points", atts, tmarker.getNumberNuclei(tss)); // 3. fill with data BufferedImage img; Color c; float[] features = new float[3]; String colorSpace = getParam_ColorSpace(); for (TMAspot ts : tss) { img = ts.getBufferedImage(); List<TMApoint> tps = ts.getPoints(); for (TMApoint tp : tps) { Color2Feature(TMAspot.getAverageColorAtPoint(img, tp.x, tp.y, ts.getParam_r(), false), colorSpace, features); // add the instance Instance inst = new Instance(1.0, new double[] { features[0], features[1], features[2] }); inst.setDataset(data); data.add(inst); } } // 4. set data class index (last attribute is the class) //data.setClassIndex(data.numAttributes() - 1); // not for weka 3.5.X if (tmarker.DEBUG > 4) { java.util.logging.Logger.getLogger(getClass().getName()).log(java.util.logging.Level.INFO, data.toString()); } Clusterer clusterer = getClusterer(); String[] options = getClustererOptions(); if (false && colorSpace.equalsIgnoreCase("hsb")) { String[] newoptions = new String[options.length + 2]; System.arraycopy(options, 0, newoptions, 0, options.length); newoptions[options.length] = "-A"; newoptions[options.length + 1] = "weka.core.MyHSBDistance"; options = newoptions; } if (tmarker.DEBUG > 3) { if (options.length > 0) { String info = "Clusterer should have options\n"; for (String o : options) { info += o + " "; } info += "\n"; java.util.logging.Logger.getLogger(getClass().getName()).log(java.util.logging.Level.INFO, info); } } clusterer.setOptions(options); // set the clusterer options clusterer.buildClusterer(data); // build the clusterer // order the clusters according to the brightness // The most bright cluster should be 0, then 1, then 2,... ArrayList<ArrayList<Double>> values = new ArrayList<>(); for (i = 0; i < clusterer.numberOfClusters(); i++) { values.add(new ArrayList<Double>()); } int z; double value; for (i = 0; i < data.numInstances(); i++) { z = clusterer.clusterInstance(data.instance(i)); value = getParam_ColorSpace().equalsIgnoreCase("hsb") ? data.instance(i).value(2) : Misc.RGBToGray(data.instance(i).value(0), data.instance(i).value(1), data.instance(i).value(2)); values.get(z).add(value); } double[] means = new double[clusterer.numberOfClusters()]; for (i = 0; i < clusterer.numberOfClusters(); i++) { means[i] = Misc.mean(values.get(i).toArray(new Double[values.get(i).size()])); } int[] ordering = Misc.orderArray(means, !getParam_ColorSpace().equalsIgnoreCase("rtp")); String clusterInfo = ""; for (String o : clusterer.getOptions()) { clusterInfo += o + " "; } clusterInfo += "\n\n"; clusterInfo += clusterer.toString().trim(); if (getParam_AutomaticClustererString().equalsIgnoreCase("Hierarchical")) { try { clusterInfo += ((HierarchicalClusterer) clusterer).graph(); HierarchyVisualizer a = new HierarchyVisualizer( ((HierarchicalClusterer) clusterer).graph()); a.setSize(800, 600); if (clusterVisualizer == null) { clusterVisualizer = new JFrame("Hierarchical Clusterer Dendrogram"); clusterVisualizer.setIconImage(getIconImage()); clusterVisualizer.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); clusterVisualizer.setSize(800, 600); } Container contentPane = clusterVisualizer.getContentPane(); contentPane.removeAll(); contentPane.add(a); } catch (Exception e) { clusterVisualizer = null; } } jTextArea1.setText(clusterInfo); if (tmarker.DEBUG > 3) { String info = "Clusterer has options\n"; for (String o : clusterer.getOptions()) { info += o + " "; } info += "\n"; info += clusterer.toString() + "\n"; // info += (clusterer).globalInfo() + "\n"; info += "\n"; info += clusterInfo + "\n"; java.util.logging.Logger.getLogger(getClass().getName()).log(java.util.logging.Level.INFO, info); } // cluster all TMAspots and assign the corresponding class to them // Cluster the points List<List<Color>> clustered_points = new ArrayList<>(); for (i = 0; i < clusterer.numberOfClusters(); i++) { clustered_points.add(new ArrayList<Color>()); } int k; for (TMAspot ts : tss) { img = ts.getBufferedImage(); List<TMApoint> tps = ts.getPoints(); for (TMApoint tp : tps) { c = TMAspot.getAverageColorAtPoint(img, tp.x, tp.y, ts.getParam_r(), false); Color2Feature(c, colorSpace, features); // add the instance Instance inst = new Instance(1.0, new double[] { features[0], features[1], features[2] }); inst.setDataset(data); k = ordering[clusterer.clusterInstance(inst)]; // store the color for later visualization clustered_points.get(k).add(c); // set the staining of the TMApoint switch (k) { case 0: tp.setStaining(TMALabel.STAINING_0); break; case 1: tp.setStaining(TMALabel.STAINING_1); break; case 2: tp.setStaining(TMALabel.STAINING_2); break; default: tp.setStaining(TMALabel.STAINING_3); break; } } ts.dispStainingInfo(); if (manager.getVisibleTMAspot() == ts) { manager.repaintVisibleTMAspot(); } } // draw the points Plot3DPanel plot; if (((java.awt.BorderLayout) (jPanel2.getLayout())) .getLayoutComponent(java.awt.BorderLayout.CENTER) != null) { plot = (Plot3DPanel) ((java.awt.BorderLayout) (jPanel2.getLayout())) .getLayoutComponent(java.awt.BorderLayout.CENTER); plot.removeAllPlots(); } else { plot = new Plot3DPanel(); plot.plotCanvas.setBackground(jPanel2.getBackground()); plot.addLegend(PlotPanel.SOUTH); plot.plotLegend.setBackground(jPanel2.getBackground()); } if (colorSpace.equalsIgnoreCase("hsb")) { plot.setAxisLabels("Hue", "Saturation", "Brightness"); } else if (colorSpace.equalsIgnoreCase("rtp")) { plot.setAxisLabels("R", "Theta", "Phi"); } else { plot.setAxisLabels("Red", "Green", "Blue"); } for (i = 0; i < clusterer.numberOfClusters(); i++) { double[] xs = new double[clustered_points.get(i).size()]; double[] ys = new double[clustered_points.get(i).size()]; double[] zs = new double[clustered_points.get(i).size()]; for (int j = 0; j < clustered_points.get(i).size(); j++) { Color2Feature(clustered_points.get(i).get(j), colorSpace, features); xs[j] = features[0]; ys[j] = features[1]; zs[j] = features[2]; } if (xs.length > 0) { c = getParam_ColorOfClassK(i); plot.addScatterPlot("Staining " + i, c, xs, ys, zs); } } // Write the description String description = "Nuclei clustered with " + getParam_AutomaticClustererString(); if (getParam_AutomaticClustererString().equalsIgnoreCase("Hierarchical")) { description += " (" + getParam_HierarchicalClusteringMethod() + ")"; } description += ", n=" + getParam_nClusters() + ", color space " + getParam_ColorSpace() + "."; jLabel41.setText(description); jLabel42.setText(" "); if (((java.awt.BorderLayout) (jPanel2.getLayout())) .getLayoutComponent(java.awt.BorderLayout.CENTER) == null) { jPanel2.add(plot, java.awt.BorderLayout.CENTER); validate(); pack(); } } catch (Exception | OutOfMemoryError e) { java.util.logging.Logger.getLogger(getClass().getName()).log(java.util.logging.Level.SEVERE, null, e); JOptionPane.showMessageDialog(this, "The clustering could not be performed.\n\n" + "A possible reasons is:\n" + "- Not enough memory (too many points), \n\n" + "You might want to try a different clustering method or less TMAspots.\n\n" + "The error message is: \n" + e.getMessage(), "Error at Nucleus clustering", JOptionPane.WARNING_MESSAGE); } finally { this.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); } } } /** * Displays the dendrogram of the hierarchical clusterer, if any. */ private void displayDendrogram() { if (clusterVisualizer != null) { clusterVisualizer.setVisible(true); } else { JOptionPane.showMessageDialog(this, "A dendrogram has not been created, yet,\n" + "or could not be computed."); } } /** * Saves the current cluster centers into a file which the users chooses. */ private void saveClusterCenters() { int n = getParam_nClusters(); ArrayList exts = new ArrayList(); ArrayList descs = new ArrayList(); exts.add("txt"); descs.add("Text file"); File file = FileChooser.chooseSavingFile(null, "", "clusters.txt", exts, descs); String sep = ";"; if (file != null) { BufferedWriter writer = null; try { writer = new BufferedWriter(new FileWriter(file)); for (int i = 0; i < n; i++) { Color c = getParam_ColorOfClassK(i); writer.write(Integer.toString(c.getRed()) + sep); writer.write(Integer.toString(c.getGreen()) + sep); writer.write(Integer.toString(c.getBlue())); writer.newLine(); } } catch (IOException ex) { Logger.getLogger(IntensityClustering.class.getName()).log(Level.SEVERE, null, ex); } finally { try { writer.close(); } catch (IOException ex) { Logger.getLogger(IntensityClustering.class.getName()).log(Level.SEVERE, null, ex); } } } } /** * Loads cluster centers and sets into the plugin. They can be used for manual clustering. */ private void loadClusterCenters() { ArrayList exts = new ArrayList(); ArrayList descs = new ArrayList(); exts.add("txt"); descs.add("Text file"); File file = FileChooser.chooseLoadingFile(null, "", exts, descs); String sep = ";"; if (file != null) { BufferedReader reader = null; try { reader = new BufferedReader(new FileReader(file)); int n = 0; String line; Color c; while (reader.ready() && !(line = reader.readLine()).isEmpty()) { String[] split = line.split(sep); c = new Color(Integer.parseInt(split[0]), Integer.parseInt(split[1]), Integer.parseInt(split[2])); setParam_ColorOfClassK(n, c); n++; } setParam_nClusters(n); } catch (IOException ex) { Logger.getLogger(IntensityClustering.class.getName()).log(Level.SEVERE, null, ex); } finally { try { reader.close(); } catch (IOException ex) { Logger.getLogger(IntensityClustering.class.getName()).log(Level.SEVERE, null, ex); } } } int n = getParam_nClusters(); double[][] centers = new double[n][3]; float[] features = new float[3]; String colorSpace = getParam_ColorSpace(); for (int i = 0; i < n; i++) { Color2Feature(getParam_ColorOfClassK(i), colorSpace, features); centers[i][0] = features[0]; centers[i][1] = features[1]; centers[i][2] = features[2]; } } /** * Returns a new weka clusterer used for nucleus staining intensity * clustering. The kind of clusterer is determined by the user. * * @return A new weka clusterer. */ private Clusterer getClusterer() { String clustername = getParam_AutomaticClustererString(); Clusterer clusterer = null; if (clustername.equalsIgnoreCase("K-Means")) { clusterer = new SimpleKMeans(); } else if (clustername.equalsIgnoreCase("Hierarchical")) { clusterer = new HierarchicalClusterer(); } else if (clustername.equalsIgnoreCase("EM")) { clusterer = new EM(); } else { clusterer = new FarthestFirst(); } return clusterer; } /** * Returns the name of the selected clusterer. * * @return A name of the clusterer (One of "K-Means", "Hierarchical", "EM" * or "Farthest First"). */ public String getParam_AutomaticClustererString() { String clustername = "Farthest First"; if (jRadioButton1.isSelected()) { clustername = "K-Means"; } else if (jRadioButton2.isSelected()) { clustername = "Hierarchical"; } else if (jRadioButton5.isSelected()) { clustername = "EM"; } return clustername; } /** * Sets the name of the selected clusterer. * * @param name A name of the clusterer (One of "K-Means", "Hierarchical", * "EM" or "Farthest First"). */ public void setParam_AutomaticClustererString(String name) { jRadioButton1.setSelected(name.equalsIgnoreCase("K-Means")); jRadioButton2.setSelected(name.equalsIgnoreCase("Hierarchical")); jRadioButton5.setSelected(name.equalsIgnoreCase("EM")); jRadioButton6.setSelected(name.equalsIgnoreCase("Farthest First")); } /** * Returns clusterer options for the weka clustering algorithm. * * @return Options for the clustering algorithm. These might be changed by * the user in the program. */ private String[] getClustererOptions() { String[] options = null; // SimpleKMeans if (jRadioButton1.isSelected()) { options = new String[3]; options[0] = "-N"; // Number clusters options[1] = Integer.toString(getParam_nClusters()); options[2] = "-V"; // Hierarchical Clustering } else if (jRadioButton2.isSelected()) { options = new String[4]; options[0] = "-N"; // Number clusters options[1] = Integer.toString(getParam_nClusters()); options[2] = "-L"; // Number clusters options[3] = (String) jComboBox2.getSelectedItem(); } else { options = new String[2]; options[0] = "-N"; // Number clusters options[1] = Integer.toString(getParam_nClusters()); } return options;// build clusterer } /** * Returns the text written in the WEKA clusterer output information of the * automatic intensity clustering. * * @return The text in jTextArea1. */ public String getClustererInfo() { return jTextArea1.getText(); } /** * Whether or not manual clustering should be done (indicated by the user). * * @return If true, manual clustering should be done, automatic clustering * otherwise. */ private boolean isManualClustering() { return jRadioButton3.isSelected(); } /** * Returns the description of the recent clustering method (the red headline * text of the two plots). * * @return The description of the current clustering method. "-", if no * clustering is done. */ public String getClusteringDescription() { String description = "-"; if (!jLabel41.getText().trim().isEmpty()) { description = jLabel41.getText().trim(); } if (!jLabel42.getText().trim().isEmpty()) { description = jLabel42.getText().trim(); } return description; } /** * Returns the 3D Plot of the nucleus intensity distribution. * * @return The 3D Plot of the nucleus intensity distribution. */ public BufferedImage get3DPlot() { return Misc.getScreenShot(jPanel2); } /** * Returns the 2D Plot of the nucleus intensity histogram. * * @return The 2D Plot of the nucleus intensity histogram. */ public BufferedImage get2DPlot() { return Misc.getScreenShot(jPanel9); } /** * Returns a feature vector for a given color. * * @param c The color to be processed. * @param colorSpace If "rgb", the color is directly used. If "hsb", the c * is first converted to HSB. If "rtp" the color is first converted to r * theta phi. * @param feature The container in which the feature is written. If null or * length is smaller than 3, a new container is created. * @return The container of the feature (length 3). */ static float[] Color2Feature(Color c, String colorSpace, float[] feature) { if (feature == null || feature.length < 3) { feature = new float[3]; } if (colorSpace.equalsIgnoreCase("hsb")) { Color.RGBtoHSB(c.getRed(), c.getGreen(), c.getBlue(), feature); } else if (colorSpace.equalsIgnoreCase("rtp")) { RGBtoRTP(c.getRed(), c.getGreen(), c.getBlue(), feature); } else { feature[0] = c.getRed(); feature[1] = c.getGreen(); feature[2] = c.getBlue(); } return (feature); } /** * Converts a RGB color to r theta phi. * * @param r The red value (0-255). * @param g The red value (0-255). * @param b The red value (0-255). * @param container the rtp value is stored here. If Null or length less * then 3, a new float array is created. * @return A float array with the r theta phi values calculated from r g b. */ static float[] RGBtoRTP(int r, int g, int b, float[] container) { if (container == null || container.length < 3) { container = new float[3]; } double r_double = 1.0 * r; double g_double = 1.0 * g; double b_double = 1.0 * b; double rad = Math.sqrt(Math.pow(r_double, 2) + Math.pow(g_double, 2) + Math.pow(b_double, 2)); double theta_deg; if (r_double == 0) { theta_deg = 0; } else { double p = g_double / r_double; double theta = Math.atan(p); theta_deg = Math.toDegrees(theta); } double phi_deg; if (rad == 0) { phi_deg = 0; } else { double q = Math.sqrt(Math.pow(r_double, 2) + Math.pow(g_double, 2)) / rad; double phi = Math.asin(q); phi_deg = Math.toDegrees(phi); } container[0] = (float) (rad); container[1] = (float) (theta_deg); container[2] = (float) (phi_deg); return (container); } /** * Converts a r theta phi color to RGB. * * @param rad The radius value (double). * @param theta The theta angle (double). * @param phi The phi angle (double). * @param container the RGB value is stored here. If Null or length less * then 3, a new float array is created. * @return A float array with the RGB (0-255) values calculated from r theta phi values. */ static float[] RTPtoRGB(double rad, double theta, double phi, float[] container) { if (container == null || container.length < 3) { container = new float[3]; } double theta_rad = Math.toRadians(1.0 * theta); double phi_rad = Math.toRadians(1.0 * phi); container[0] = (float) Math.round(rad * Math.cos(theta_rad) * Math.sin(phi_rad)); container[1] = (float) Math.round(rad * Math.sin(theta_rad) * Math.sin(phi_rad)); container[2] = (float) Math.round(rad * Math.cos(phi_rad)); return (container); } /** * Returns which color space should be used for clustering (RGB, HSB or R * THETA PHI), as indicated by the user. * * @return "HSB", if the HSB Color space should be used. "RGB" for RGB * space. "RTP" for r theta phi space. */ public String getParam_ColorSpace() { if (jRadioButton7.isSelected()) { return "RGB"; } if (jRadioButton8.isSelected()) { return "HSB"; } return "RTP"; } /** * Sets the color space to be used for clustering (RGB, HSB or R THETA PHI). * * @param colorSpace "HSB", if the HSB Color space should be used. "RGB" for * RGB space. "RTP" for r theta phi space. */ public void setParam_ColorSpace(String colorSpace) { if (colorSpace.equalsIgnoreCase("RGB")) { jRadioButton7.setSelected(true); } else if (colorSpace.equalsIgnoreCase("HSB")) { jRadioButton8.setSelected(true); } else { jRadioButton13.setSelected(true); } dispayed3DColorSpace = colorSpace.toLowerCase(); } /** * Returns the color of the class labels in the visualization plots. * * @param k The class of which the color is wanted (starts with 0). * @return The color of the nuclei in class k. */ public Color getParam_ColorOfClassK(int k) { return ((JXColorSelectionButton) jPanel8.getComponent(k)).getBackground(); } /** * Sets the color of the class labels in the visualization plots. * * @param k The class of which the color is set (starts with 0). * @param c The color of the nuclei in class k. */ public void setParam_ColorOfClassK(int k, Color c) { ((JXColorSelectionButton) jPanel8.getComponent(k)).setBackground(c); } /** * Returns the index of the selected nucleus intensity clustering method. * * @return 0 for manual clustering, 1 for automatic clustering. */ public int getParam_ManualAutomaticClustering() { int i = 0; if (jRadioButton4.isSelected()) { i = 1; } return i; } /** * Sets the index of the selected nucleus intensity clustering method. * * @param i 0 for manual clustering, 1 for automatic clustering. */ public void setParam_ManualAutomaticClustering(int i) { jRadioButton3.setSelected(i == 0); jRadioButton4.setSelected(i == 1); } /** * Returns the selected method for the hierarchical intensity clusterer. * * @return The selected method for the hierarchical intensity clusterer. */ public String getParam_HierarchicalClusteringMethod() { return (String) (jComboBox2.getSelectedItem()); } /** * Sets the method for the hierarchical intensity clusterer. * * @param method The method for the hierarchical intensity clusterer. */ public void setParam_HierarchicalClusteringMethod(String method) { jComboBox2.setSelectedItem(method); } /** * Returns the number of clusters used for nucleus intensity clustering. * * @return The number of clusters. */ public int getParam_nClusters() { int n = 1; for (Component c : jPanel17.getComponents()) { if (((JRadioButton) c).isSelected()) { return n; } else { n++; } } return n; } /** * Sets the number of clusters used for nucleus intensity clustering. * * @param n The number of clusters. */ public void setParam_nClusters(int n) { ((JRadioButton) jPanel17.getComponent(Math.max(0, Math.min(n - 1, jPanel17.getComponentCount())))) .setSelected(true); } /** * Refreshes the intensity panel with the given list of TMAspots, i.e. * redraws the 3D plot and the 2D plot. * * @param tss The list of TMAspots whose TMApoints are considered (should be * the currently selected TMAspots). */ void updateIntensityPanelToTMAspots(List<TMAspot> tss) { if (tss != null && (current_TMAspots_Intensity == null || !current_TMAspots_Intensity.containsAll(tss) || !tss.containsAll(current_TMAspots_Intensity))) { //adoptMeanIntensities(); drawNucleiIntensities2D(tss, false); drawNucleiIntensities3D(tss); current_TMAspots_Intensity = tss; } } /** * Sets all necessary parameters to the values of the selected TMAspots. * * @param t The tmarker program from which the TMAspots are taken. Null * allowed. */ public void updateOptionsToTMAspot(tmarker t) { if (t != null) { updateIntensityPanelToTMAspots(t.getSelectedTMAspots(false)); pack(); } } }