package cz.cuni.lf1.lge.ThunderSTORM.results; import cz.cuni.lf1.lge.ThunderSTORM.ImportExportPlugIn; import cz.cuni.lf1.lge.ThunderSTORM.ModuleLoader; import cz.cuni.lf1.lge.ThunderSTORM.UI.MacroParser; import cz.cuni.lf1.lge.ThunderSTORM.estimators.PSF.Molecule; import cz.cuni.lf1.lge.ThunderSTORM.estimators.PSF.MoleculeDescriptor; import static cz.cuni.lf1.lge.ThunderSTORM.estimators.PSF.MoleculeDescriptor.LABEL_DETECTIONS; import static cz.cuni.lf1.lge.ThunderSTORM.estimators.PSF.PSFModel.Params.LABEL_X; import static cz.cuni.lf1.lge.ThunderSTORM.estimators.PSF.PSFModel.Params.LABEL_Y; import cz.cuni.lf1.lge.ThunderSTORM.rendering.IncrementalRenderingMethod; import cz.cuni.lf1.lge.ThunderSTORM.rendering.RenderingQueue; import cz.cuni.lf1.lge.ThunderSTORM.rendering.ui.ASHRenderingUI; import cz.cuni.lf1.lge.ThunderSTORM.rendering.ui.IRendererUI; import cz.cuni.lf1.lge.ThunderSTORM.util.PluginCommands; import cz.cuni.lf1.lge.ThunderSTORM.util.VectorMath; import ij.IJ; import ij.ImagePlus; import java.awt.BorderLayout; import java.awt.Component; import java.awt.Container; import java.awt.Cursor; import java.awt.Dimension; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.awt.event.MouseEvent; import java.io.File; import java.util.Collections; import java.util.List; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JSeparator; import javax.swing.JTabbedPane; import javax.swing.SwingConstants; import javax.swing.SwingUtilities; public class ResultsTableWindow extends GenericTableWindow { private JButton io_import; private JButton io_export; private JButton showHist; private JButton render; private JButton defaultsButton; private JCheckBox preview; private JLabel status; private RenderingQueue previewRenderer; private boolean livePreview; private JButton resetButton; private JTabbedPane tabbedPane; private OperationsHistoryPanel operationsStackPanel; List<? extends PostProcessingModule> postProcessingModules; public ResultsTableWindow(String frameTitle) { super(frameTitle); } @Override protected void packFrame() { frame.setPreferredSize(new Dimension(600, 750)); // status = new JLabel(" "); status.setAlignmentX(Component.CENTER_ALIGNMENT); status.setMaximumSize(new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE)); //buttons JPanel buttons = new JPanel(); buttons.setLayout(new BoxLayout(buttons, BoxLayout.X_AXIS)); defaultsButton = new JButton("Defaults"); showHist = new JButton("Plot histogram"); io_import = new JButton("Import"); io_export = new JButton("Export"); render = new JButton("Visualization"); defaultsButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { for(PostProcessingModule module : postProcessingModules){ module.resetParamsToDefaults(); } } }); showHist.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { new IJDistribution().run(IJResultsTable.IDENTIFIER); } }); io_import.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { MacroParser.runNestedWithRecording(PluginCommands.IMPORT_RESULTS.getValue(), null); } }); io_export.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { MacroParser.runNestedWithRecording(PluginCommands.EXPORT_RESULTS.getValue(), null); } }); render.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { MacroParser.runNestedWithRecording(PluginCommands.RENDERING.getValue(), null); } }); livePreview = false; preview = new JCheckBox("Preview", livePreview); preview.addItemListener(new ItemListener() { @Override public void itemStateChanged(ItemEvent e) { livePreview = (e.getStateChange() == ItemEvent.SELECTED); showPreview(); } }); buttons.add(preview); buttons.add(Box.createHorizontalGlue()); buttons.add(defaultsButton); buttons.add(Box.createHorizontalStrut(5)); buttons.add(showHist); buttons.add(Box.createHorizontalStrut(5)); buttons.add(render); buttons.add(Box.createHorizontalStrut(5)); buttons.add(io_import); buttons.add(Box.createHorizontalStrut(3)); buttons.add(io_export); // postProcessingModules = ModuleLoader.getPostProcessingModules(); //fill tabbed pane tabbedPane = new JTabbedPane(); for(PostProcessingModule module : postProcessingModules) { module.setModel(model); module.setTable(this); tabbedPane.addTab(module.getTabName(), module.getUIPanel()); } //history pane JPanel historyPane = new JPanel(new GridBagLayout()); operationsStackPanel = new OperationsHistoryPanel(); resetButton = new JButton("Reset"); resetButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { model.copyOriginalToActual(); model.convertAllColumnsToAnalogUnits(); operationsStackPanel.removeAllOperations(); setStatus("Results reset."); showPreview(); TableHandlerPlugin.recordReset(); } }); historyPane.add(operationsStackPanel, new GridBagConstraints(0, 0, 1, 1, 1, 0, GridBagConstraints.BASELINE, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0)); historyPane.add(resetButton); Container contentPane = frame.getContentPane(); JPanel controlsPane = new JPanel(); controlsPane.setLayout(new BoxLayout(controlsPane, BoxLayout.PAGE_AXIS)); contentPane.add(tableScrollPane, BorderLayout.CENTER); contentPane.add(controlsPane, BorderLayout.SOUTH); controlsPane.add(tabbedPane); controlsPane.add(historyPane); controlsPane.add(new JSeparator(SwingConstants.HORIZONTAL)); controlsPane.add(buttons); controlsPane.add(new JSeparator(SwingConstants.HORIZONTAL)); controlsPane.add(status); // frame.setContentPane(contentPane); frame.pack(); } public void setLivePreview(boolean enabled) { livePreview = enabled; preview.setSelected(enabled); } public void showPreview() { IJResultsTable rt = IJResultsTable.getResultsTable(); if(livePreview && !rt.isEmpty()) { if(!rt.columnExists(LABEL_X) || !rt.columnExists(LABEL_Y)) { IJ.error(String.format("X and Y columns not found in Results table. Looking for: %s and %s. Found: %s.", LABEL_X, LABEL_Y, rt.getColumnNames())); return; } if(previewRenderer == null) { IRendererUI renderer = new ASHRenderingUI(); ImagePlus analyzedImage = rt.getAnalyzedImage(); if(analyzedImage != null) { renderer.setSize(analyzedImage.getWidth(), analyzedImage.getHeight()); } else { double[] xpos = rt.getColumnAsDoubles(LABEL_X, MoleculeDescriptor.Units.PIXEL); double[] ypos = rt.getColumnAsDoubles(LABEL_Y, MoleculeDescriptor.Units.PIXEL); int left = Math.max((int) Math.floor(VectorMath.min(xpos)) - 1, 0); int top = Math.max((int) Math.floor(VectorMath.min(ypos)) - 1, 0); int right = (int) Math.ceil(VectorMath.max(xpos)) + 1; int bottom = (int) Math.ceil(VectorMath.max(ypos)) + 1; renderer.setSize(left, top, right - left + 1, bottom - top + 1); } IncrementalRenderingMethod rendererImplementation = renderer.getImplementation(); previewRenderer = new RenderingQueue(rendererImplementation, new RenderingQueue.DefaultRepaintTask(rendererImplementation.getRenderedImage()), renderer.getRepaintFrequency()); } // previewRenderer.resetLater(); previewRenderer.renderLater(rt.getData()); previewRenderer.repaintLater(); } rt.repaintAnalyzedImageOverlay(); } public void setPreviewRenderer(RenderingQueue renderer) { previewRenderer = renderer; livePreview = (renderer != null); preview.setSelected(livePreview); } public ImagePlus getPreviewImage() { if(!livePreview || previewRenderer == null) { return null; } return previewRenderer.method.getRenderedImage(); } public void setStatus(String text) { if(text == null) { text = " "; } this.status.setText(text); } public ResultsFilter getFilter() { if(postProcessingModules != null) { for(PostProcessingModule module : postProcessingModules) { if(module instanceof ResultsFilter) { return (ResultsFilter) module; } } } return null; } public OperationsHistoryPanel getOperationHistoryPanel() { return operationsStackPanel; } public List<? extends PostProcessingModule> getPostProcessingModules() { return postProcessingModules; } @Override protected void tableMouseClicked(MouseEvent e) { if(SwingUtilities.isLeftMouseButton(e)) { if(e.getClickCount() == 2) { IJResultsTable rt = IJResultsTable.getResultsTable(); int row = table.getSelectedRow(); int rowIndex = rt.convertViewRowIndexToModel(row); Molecule mol = rt.getRow(rowIndex); if(mol.hasParam(LABEL_DETECTIONS)) { if(mol.getParam(LABEL_DETECTIONS) > 1) { List<Molecule> detections = mol.getDetections(); Collections.sort(detections); new MergedMoleculesPopUp(table, row, 0, detections); } } } } else if(SwingUtilities.isRightMouseButton(e)) { if(table.getSelectedRowCount() > 0) { new TableRowsPopUpMenu(e, this); } } } @Override protected void tableMouseMoved(MouseEvent e) { IJResultsTable rt = IJResultsTable.getResultsTable(); int rowIndex = rt.convertViewRowIndexToModel(table.rowAtPoint(e.getPoint())); Molecule mol = rt.getRow(rowIndex); if(mol.hasParam(LABEL_DETECTIONS)) { if(mol.getParam(LABEL_DETECTIONS) > 1) { table.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); return; } } table.setCursor(Cursor.getDefaultCursor()); // reset } @Override protected void dropFile(File f) { new ImportExportPlugIn(f.getAbsolutePath()).run(ImportExportPlugIn.IMPORT + ";" + IJResultsTable.IDENTIFIER); } }