/*
* Copyright (c) 2003-2012 Fred Hutchinson Cancer Research Center
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.fhcrc.cpl.viewer.gui;
import org.fhcrc.cpl.viewer.align.Aligner;
import org.fhcrc.cpl.viewer.align.BucketedPeptideArray;
import org.fhcrc.cpl.viewer.align.SplineAligner;
import org.fhcrc.cpl.toolbox.proteomics.MSRun;
import org.fhcrc.cpl.viewer.Localizer;
import org.fhcrc.cpl.viewer.util.SharedProperties;
import org.fhcrc.cpl.toolbox.gui.ListenerHelper;
import org.fhcrc.cpl.toolbox.ApplicationContext;
import org.fhcrc.cpl.toolbox.TextProvider;
import org.fhcrc.cpl.toolbox.proteomics.feature.*;
import org.jfree.data.xy.XYSeriesCollection;
import org.jfree.data.xy.XYSeries;
import org.jfree.chart.ChartPanel;
import org.apache.log4j.Logger;
import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.table.*;
import javax.swing.event.ListSelectionEvent;
import java.awt.*;
import java.awt.event.*;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.io.FileOutputStream;
import java.io.PrintWriter;
import java.util.*;
import java.util.List;
import java.text.SimpleDateFormat;
import java.text.NumberFormat;
import java.text.DecimalFormat;
public class FeatureSelectionFrame extends AbstractAction implements PropertyChangeListener
{
protected static Logger _log = Logger.getLogger(FeatureSelectionFrame.class);
public FeatureSelectionDialog dialog = null;
public void propertyChange(PropertyChangeEvent event)
{
// setEnabled(null != ApplicationContext.getProperty(SharedProperties.MS_RUN));
}
public void actionPerformed(ActionEvent event)
{
dialog = new FeatureSelectionDialog();
dialog.setVisible(true);
}
public static class FeatureSelectionDialog extends JDialog
{
public static final int ACTION_CANCEL = 0;
public static final int ACTION_OK = 1;
public int action = ACTION_CANCEL;
public JTable tblFeatureSets;
public JButton buttonAddFiles;
public JButton buttonRemoveFiles;
public JTabbedPane tabbedPane;
public JTextField textMinMz;
public JTextField textMaxMz;
public JTextField textMinCharge;
public JTextField textMaxCharge;
public JTextField textMinScans;
public JTextField textMaxKL;
public JTextField textMinIntensity;
public JTextField textMinPeaks;
public JTextField textOutputFile;
public JButton buttonBrowseOutputDir;
public JTextField textPepArrayMzBucket;
public JTextField textPepArrayScanBucket;
public JCheckBox checkBoxNormalize;
public JButton buttonOptimize;
public JLabel lblNumBuckets;
public JLabel lblExactMatches;
public JButton buttonCreatePeptideArray;
public JButton buttonCancel;
public JButton buttonApply;
public JButton buttonOK;
public FileListTableModel model;
//supporting components
public static JFileChooser chooser = new WorkbenchFileChooser();
public static JFileChooser saveChooser = new WorkbenchFileChooser();
private static FeatureSelectionDialog _instance;
private static Color[] featureSetColors = new Color[]{
Color.BLUE,
Color.GREEN,
Color.CYAN,
Color.MAGENTA,
Color.ORANGE,
Color.PINK,
Color.RED,
Color.YELLOW
};
synchronized public static FeatureSelectionDialog getInstance()
{
if (null == _instance)
_instance = new FeatureSelectionDialog();
return _instance;
}
static
{
chooser.setMultiSelectionEnabled(true);
}
public FeatureSelectionDialog()
{
super(ApplicationContext.getFrame(), TextProvider.getText("DISPLAY_FEATURES"));
//graphical stuff
Container contentPanel = null;
try
{
contentPanel = Localizer.renderSwixml("org/fhcrc/cpl/viewer/gui/FeatureSelectionFrame.xml", this);
setContentPane(contentPanel);
pack();
}
catch (Exception x)
{
ApplicationContext.errorMessage(TextProvider.getText("ERROR_CREATING_DIALOG"), x);
throw new RuntimeException(x);
}
Dimension d = contentPanel.getPreferredSize();
setBounds(600, 100, 6 + (int) d.getWidth(), 50 + (int) d.getHeight());
ListenerHelper helper = new ListenerHelper(this);
buttonApply.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
FeatureSet.FeatureSelector selector = createFeatureSelector();
updateFeatureSelector(selector);
}
});
buttonCancel.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
FeatureSelectionDialog.this.dispose();
}
});
buttonOK.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
FeatureSet.FeatureSelector selector = createFeatureSelector();
updateFeatureSelector(selector);
FeatureSelectionDialog.this.dispose();
}
});
helper.addListener(buttonAddFiles, "buttonAddFile_actionPerformed");
helper.addListener(buttonRemoveFiles, "buttonRemoveFiles_actionPerformed");
//end graphical stuff
FeatureSet.FeatureSelector selector = (FeatureSet.FeatureSelector) ApplicationContext.getProperty("featureSelector");
if (null == selector)
{
selector = new FeatureSet.FeatureSelector();
updateFeatureSelector(selector);
}
textMaxKL.setText(String.valueOf(selector.getMaxKL()));
textMinCharge.setText(String.valueOf(selector.getMinCharge()));
textMaxCharge.setText(String.valueOf(selector.getMaxCharge()));
textMaxMz.setText(String.valueOf(selector.getMaxMz()));
textMinMz.setText(String.valueOf(selector.getMinMz()));
textMinIntensity.setText(String.valueOf(selector.getMinIntensity()));
textMinScans.setText(String.valueOf(selector.getMinScans()));
File dir = null;
MSRun run = (MSRun) ApplicationContext.getProperty(SharedProperties.MS_RUN);
if (null != run && null != run.getFile())
dir = run.getFile().getParentFile();
if (null == dir)
dir = saveChooser.getCurrentDirectory();
if (null != dir)
textOutputFile.setText(dir.getAbsolutePath() + File.separatorChar + "pepArray.tsv");
else
textOutputFile.setText("pepArray.tsv");
model = new FileListTableModel();
tblFeatureSets.setModel(model);
TableColumn displayColumn = tblFeatureSets.getColumnModel().getColumn(0);
displayColumn.setPreferredWidth(50);
displayColumn.setMaxWidth(50);
TableColumn colorColumn = tblFeatureSets.getColumnModel().getColumn(2);
colorColumn.setPreferredWidth(50);
colorColumn.setMaxWidth(50);
colorColumn.setCellRenderer(new ColorRenderer(false));
colorColumn.setCellEditor(new ColorEditor());
TableColumn browseColumn = tblFeatureSets.getColumnModel().getColumn(3);
browseColumn.setPreferredWidth(30);
browseColumn.setMaxWidth(30);
final JButton button = new JButton("...");
final TableCellRenderer browseButtonRenderer = new TableCellRenderer()
{
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
{
return button;
}
};
browseColumn.setCellRenderer(browseButtonRenderer);
browseColumn.setCellEditor(new BrowseEditor());
List<FeatureSet> featureSets = (List<FeatureSet>) ApplicationContext.getProperty(SharedProperties.FEATURE_SETS);
if (null != featureSets)
{
for (FeatureSet fs : featureSets)
{
model.addFeatureSet(fs);
}
}
buttonAddFiles.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
int chooserStatus = chooser.showOpenDialog(FeatureSelectionDialog.this);
//if user didn't hit OK, ignore
if (chooserStatus != JFileChooser.APPROVE_OPTION)
return;
File[] files = chooser.getSelectedFiles();
for (File file : files)
{
//String path = files[i].getAbsolutePath().toLowerCase();
FeatureSet featureSet = new FeatureSet(file, nextColor());
//int numWithoutComp = 0;
//for (Feature feature : featureSet.getFeatures()) if (feature.comprised == null) numWithoutComp++;
//System.err.println(numWithoutComp + " of " + featureSet.getFeatures().length + " features no comp");
_log.debug("Loaded " + featureSet.getFeatures().length + " features from file " +
file.getAbsolutePath() + ". Status: " + featureSet.getLoadStatus());
//check to see if features loaded correctly
if (featureSet.getLoadStatus() == FeatureSet.FEATURESET_LOAD_SUCCESS)
{
featureSet.setDisplayed(tabbedPane.getSelectedIndex() != 3);
addFeatureSet(featureSet);
}
else
{
ApplicationContext.infoMessage(featureSet.getLoadStatusMessage());
}
}
}
});
buttonRemoveFiles.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
int[] rows = tblFeatureSets.getSelectedRows();
Arrays.sort(rows);
FileListTableModel model = (FileListTableModel) tblFeatureSets.getModel();
for (int i = rows.length - 1; i >= 0; i--)
model.removeFeatureSet(rows[i]);
}
});
buttonBrowseOutputDir.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
File file = new File(textOutputFile.getText());
File dir = file.getParentFile();
if (dir.exists())
{
saveChooser.setCurrentDirectory(dir.getParentFile());
saveChooser.setSelectedFile(file);
}
int chooserStatus = saveChooser.showOpenDialog(FeatureSelectionDialog.this);
//if user didn't hit OK, ignore
if (chooserStatus != JFileChooser.APPROVE_OPTION)
return;
file = saveChooser.getSelectedFile();
if (null != file)
textOutputFile.setText(file.getAbsolutePath());
}
});
buttonOptimize.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
double[] mzVal = new double[1];
mzVal[0] = Double.parseDouble(textPepArrayMzBucket.getText());
final Optimizer optimizer = new Optimizer(mzVal, new int[]{10, 25, 50, 75, 100, 150, 200, 300, 400}, getFeatureRanges());
optimizer.runLater = new OptimizeGrapher(optimizer);
Thread t = new Thread(optimizer);
t.start();
}
});
buttonCreatePeptideArray.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
List featureSets = getFeatureSets();
if (null == featureSets || featureSets.size() < 2)
{
ApplicationContext.errorMessage(TextProvider.getText("TWO_FILES_TO_CREATE_PEPTIDE_ARRAY"), null);
return;
}
BucketedPeptideArray arr = new BucketedPeptideArray(featureSets, createFeatureSelector());
float mzBucketSize = Float.parseFloat(textPepArrayMzBucket.getText());
int scanBucketSize = Integer.parseInt(textPepArrayScanBucket.getText());
boolean normalize = checkBoxNormalize.isSelected();
arr.setElutionMode(FeatureClusterer.ELUTION_MODE_SCAN);
arr.setElutionBucket(scanBucketSize);
arr.setMassBucket(mzBucketSize);
arr.setNormalize(normalize);
File file = new File(textOutputFile.getText());
if (!file.getParentFile().exists())
{
ApplicationContext.errorMessage(TextProvider.getText("DIR_NOT_LEGAL_DIR_NAME",
file.getParentFile().getAbsolutePath()), null);
return;
}
arr.setOutFileName(file.getAbsolutePath());
Thread t = new Thread(arr);
t.setPriority(Thread.MIN_PRIORITY);
t.start();
// //Create because user may have failed to hit apply button
// FeatureSet.FeatureSelector sel = createFeatureSelector();
// List ranges = generateMergedSets(featureSets, sel, false);
// PeptideArray array = new PeptideArray(ranges);
// array.setOutputDir(dir);
// //TODO: Error checking
}
});
}
private static int nextColor;
public static synchronized Color nextColor()
{
Color color = featureSetColors[nextColor];
nextColor = ++nextColor % featureSetColors.length;
return color;
}
public List getFeatureSets()
{
return (List) ApplicationContext.getProperty(SharedProperties.FEATURE_SETS);
}
public List getFeatureRanges()
{
return (List) ApplicationContext.getProperty(SharedProperties.FEATURE_RANGES);
}
public FeatureSet.FeatureSelector getFeatureSelector()
{
FeatureSet.FeatureSelector sel = (FeatureSet.FeatureSelector) ApplicationContext.getProperty("featureSelector");
if (null == sel) //Should never happen...
{
sel = createFeatureSelector();
ApplicationContext.setProperty("featureSelector", sel);
}
return sel;
}
private FeatureSet.FeatureSelector createFeatureSelector()
{
FeatureSet.FeatureSelector selector = new FeatureSet.FeatureSelector();
//TODO: Error handling...
selector.setMaxKL(Float.parseFloat(textMaxKL.getText()));
selector.setMinCharge(Integer.parseInt(textMinCharge.getText()));
selector.setMaxCharge(Integer.parseInt(textMaxCharge.getText()));
selector.setMaxMz(Float.parseFloat(textMaxMz.getText()));
selector.setMinMz(Float.parseFloat(textMinMz.getText()));
selector.setMinIntensity(Float.parseFloat(textMinIntensity.getText()));
selector.setMinPeaks(Integer.parseInt(textMinPeaks.getText()));
selector.setMinScans(Integer.parseInt(textMinScans.getText()));
return selector;
}
public void addFeatureSet(File file)
{
FeatureSet featureSet;
try
{
featureSet = new FeatureSet(file);
}
catch (Exception x)
{
//JOptionPane.showMessageDialog(null, x.getMessage());
ApplicationContext.errorMessage(null, x);
return;
}
addFeatureSet(featureSet);
}
public void addFeatureSet(Feature[] features)
{
addFeatureSet(new FeatureSet(features));
}
public void addFeatureSet(FeatureSet featureSet)
{
featureSet.setColor(nextColor());
_log.debug("Adding new featureset with " + featureSet.getFeatures().length +
" features to list of displayed featuresets");
((FileListTableModel) tblFeatureSets.getModel()).addFeatureSet(featureSet);
ApplicationContext.setProperty(SharedProperties.SELECTED, featureSet);
}
/**
* Updates the featureselector based on the currently loaded features
*
* @param sel
*/
public void updateFeatureSelector(FeatureSet.FeatureSelector sel)
{
List featureSets = (List) ApplicationContext.getProperty(SharedProperties.FEATURE_SETS);
if (null != featureSets)
{
List mergedFeatureSets = generateMergedSets(featureSets, sel);
ApplicationContext.setProperty(SharedProperties.FEATURE_RANGES, mergedFeatureSets);
}
ApplicationContext.setProperty("featureSelector", sel);
}
/**
* Generates a new merged feature list
*
* @param featureSets
* @param sel
* @return
*/
protected List<FeatureSet> generateMergedSets(List<? extends FeatureSet> featureSets, FeatureSet.FeatureSelector sel)
{
List<FeatureSet> mergedFeatureSets = new ArrayList<FeatureSet>(featureSets.size());
for (FeatureSet fs : featureSets)
{
FeatureSet fsMerged = fs.filter(sel);
fsMerged.setDisplayed(fs.isDisplayed());
fsMerged.setSourceFile(fs.getSourceFile());
mergedFeatureSets.add(fsMerged);
}
return mergedFeatureSets;
}
public void updateFeatureSets(List<? extends FeatureSet> featureSets, boolean displayOnly)
{
FeatureSet.FeatureSelector sel = (FeatureSet.FeatureSelector) ApplicationContext.getProperty("featureSelector");
if (null != sel)
{
List<FeatureSet> mergedFeatureSets = null;
if (displayOnly)
{
mergedFeatureSets = new ArrayList<FeatureSet>();
List<? extends FeatureSet> oldFeatureSets = (List<? extends FeatureSet>) ApplicationContext.getProperty(SharedProperties.FEATURE_RANGES);
for (int i = 0; i < oldFeatureSets.size(); i++)
{
//Need to clone them or else property change support says nothing changed.
FeatureSet merged = (FeatureSet) oldFeatureSets.get(i).clone();
FeatureSet unmerged = featureSets.get(i);
merged.setColor(unmerged.getColor());
merged.setDisplayed(unmerged.isDisplayed());
mergedFeatureSets.add(merged);
}
}
else
{
mergedFeatureSets = generateMergedSets(featureSets, sel);
}
ApplicationContext.setProperty(SharedProperties.FEATURE_RANGES, mergedFeatureSets);
}
ApplicationContext.setProperty(SharedProperties.FEATURE_SETS, featureSets);
}
/*
* UI event handlers
*/
public void buttonAddFile_actionPerformed(ActionEvent event)
{
}
public void buttonRemoveFiles_actionPerformed(ActionEvent event)
{
}
/*
* Inner classes
*/
public static class Optimizer implements Runnable
{
//private static final int OPTIMIZE_STEPS = 15;
//private static final int OPTIMIZE_INCREMENT = 20;
double[] mzValues;
int[] scanValues;
int bestScanWindow = 50;
double bestMzWindow = .3;
int bestMatchMzIndex = 0;
int bestMatchScanIndex = 0;
//2D Arrays one subarray for each mzValue
int[][] numBuckets = null;
int[][] perfectMatches = null;
private int topN = 0;
XYSeries[] series;
List<FeatureSet> featureSets = null;
public boolean align = true;
Runnable runLater = null;
File outFile = null;
PrintWriter out = new PrintWriter(System.out);
public Optimizer(double[] mzValues, int[] scanValues, List<FeatureSet> featureSets)
{
this.mzValues = mzValues;
this.scanValues = scanValues;
this.featureSets = featureSets;
series = new XYSeries[mzValues.length];
for (int i = 0; i < series.length; i++)
series[i] = new XYSeries("-Points (" + mzValues[i] + ")");
numBuckets = new int[mzValues.length][scanValues.length];
perfectMatches = new int[mzValues.length][scanValues.length];
}
public Optimizer(double[] mzValues, int[] scanValues, List<FeatureSet> featureSets, File outFile)
{
this(mzValues, scanValues, featureSets);
if (null == outFile)
return;
this.outFile = outFile;
try
{
this.out = new PrintWriter(new FileOutputStream(outFile));
}
catch (Exception x)
{
ApplicationContext.errorMessage(TextProvider.getText("COULD_NOT_OPEN_FILE_FILENAME", outFile.getPath()), x);
}
}
public void run()
{
//use getFeatureRanges so that we have a filtered set.
//Alignment was much too slow.
if (null == featureSets || featureSets.size() < 2)
{
//JOptionPane.showMessageDialog(FeatureSelectionFrame.this, "At least 2 files must be selected to create a peptide array");
ApplicationContext.errorMessage(TextProvider.getText("TWO_FILES_TO_CREATE_PEPTIDE_ARRAY"), null);
return;
}
FeatureSet[] alignedSets = null;
if (align)
{
List<FeatureSet> alignedList;
try
{
ApplicationContext.setMessage(TextProvider.getText("ALIGNING_DOTDOTDOT"));
Aligner aligner = new SplineAligner();
aligner.setBuildCharts(true);
Aligner.MzFeaturePairSelector pairSelector =
new Aligner.MzFeaturePairSelector();
pairSelector.setTopN(topN);
aligner.setFeaturePairSelector(Aligner.DEFAULT_FEATURE_PAIR_SELECTOR);
alignedList = aligner.alignFeatureSets(featureSets, true);
}
catch (Exception x)
{
ApplicationContext.errorMessage(TextProvider.getText("COULD_NOT_ALIGN_FEATURE_SETS"), x);
return;
}
alignedSets = alignedList.toArray(new FeatureSet[featureSets.size()]);
}
else
alignedSets = featureSets.toArray(new FeatureSet[featureSets.size()]);
FeatureGrouper grouper = new FeatureGrouper();
for (int i = 0; i < alignedSets.length; i++)
grouper.addSet(alignedSets[i]);
out.println("mzBucketSize\tscanCount\tnumBuckets\tperfectMatches");
for (int iMz = 0; iMz < mzValues.length; iMz++)
{
for (int iScan = 0; iScan < scanValues.length; iScan++)
{
int scanCount = scanValues[iScan];
double mzBucketSize = mzValues[iMz];
ApplicationContext.setMessage(TextProvider.getText("CALCULATING_ARRAY_SCAN_MZ", "SCAN_COUNT", Integer.toString(scanCount), "MZ_WINDOW", Double.toString(mzBucketSize)));
grouper.split2D(mzBucketSize, scanCount);
numBuckets[iMz][iScan] = grouper.numBuckets();
perfectMatches[iMz][iScan] = grouper.rowsWithOneFromEach();
if (perfectMatches[iMz][iScan] > perfectMatches[bestMatchMzIndex][bestMatchScanIndex])
{
bestMatchMzIndex = iMz;
bestMatchScanIndex = iScan;
bestScanWindow = scanCount;
bestMzWindow = mzBucketSize;
}
series[iMz].add(scanCount, (double) perfectMatches[iMz][iScan]);
out.println(mzBucketSize + "\t" + scanCount + "\t" + numBuckets[iMz][iScan] + "\t" + perfectMatches[iMz][iScan]);
}
}
out.flush();
if (null != this.outFile)
out.close();
if (null != runLater)
EventQueue.invokeLater(runLater);
}
public int getTopN()
{
return topN;
}
public void setTopN(int topN)
{
this.topN = topN;
}
}
private class FileListTableModel extends AbstractTableModel
{
ArrayList _featureSets = new ArrayList();
synchronized public void addFeatureSet(FeatureSet fs)
{
_featureSets.add(fs);
ArrayList changedFeatureSets = new ArrayList();
changedFeatureSets.addAll(_featureSets);
updateFeatureSets(changedFeatureSets, false);
super.fireTableRowsInserted(_featureSets.size() - 1, _featureSets.size() - 1);
}
synchronized public void removeFeatureSet(int i)
{
_featureSets.remove(i);
ArrayList changedFeatureSets = new ArrayList();
changedFeatureSets.addAll(_featureSets);
updateFeatureSets(changedFeatureSets, false);
super.fireTableRowsDeleted(i, i);
}
public int getRowCount()
{
return _featureSets.size();
}
public int getColumnCount()
{
return 4;
}
public Class getColumnClass(int c)
{
switch (c)
{
case 0:
return Boolean.class;
case 2:
return Color.class;
default:
return Object.class;
}
}
public boolean isCellEditable(int row, int col)
{
return col == 0 || col == 2 || col == 3;
}
public Object getValueAt(int row, int col)
{
if (row >= _featureSets.size())
return null;
FeatureSet fs = (FeatureSet) _featureSets.get(row);
switch (col)
{
case 0:
return new Boolean(fs.isDisplayed());
case 1:
return fs.getSourceFile() != null ? fs.getSourceFile().getAbsolutePath() : "(no file)";
case 2:
return fs.getColor();
default:
return fs;
}
}
private String[] columnNames = new String[]{TextProvider.getText("DISPLAY"),
TextProvider.getText("FILE"),
TextProvider.getText("COLOR")};
public String getColumnName(int i)
{
return i >= 0 && i < columnNames.length ? columnNames[i] : "";
}
public void setValueAt(Object o, int row, int col)
{
if (row >= _featureSets.size())
return;
FeatureSet fs = (FeatureSet) _featureSets.get(row);
switch (col)
{
case 0:
fs.setDisplayed(((Boolean) o).booleanValue());
break;
case 1:
throw new IllegalArgumentException(TextProvider.getText("CANT_EDIT_FILE_NAME"));
case 2:
fs.setColor((Color) o);
break;
default:
return;
}
ArrayList changedFeatureSets = new ArrayList();
changedFeatureSets.addAll(_featureSets);
updateFeatureSets(changedFeatureSets, true);
super.fireTableCellUpdated(row, col);
}
}
private class OptimizeGrapher implements Runnable
{
FeatureSelectionFrame.FeatureSelectionDialog.Optimizer optimizer;
private OptimizeGrapher(Optimizer optimizer)
{
this.optimizer = optimizer;
}
public void run()
{
textPepArrayScanBucket.setText(String.valueOf(optimizer.bestScanWindow));
textPepArrayMzBucket.setText(String.valueOf(optimizer.bestMzWindow));
lblNumBuckets.setText(String.valueOf(optimizer.numBuckets[optimizer.bestMatchMzIndex][optimizer.bestMatchScanIndex]));
lblExactMatches.setText(String.valueOf(optimizer.perfectMatches[optimizer.bestMatchMzIndex][optimizer.bestMatchScanIndex]));
XYSeriesCollection seriesColl = new XYSeriesCollection();
for (int i = 0; i < optimizer.mzValues.length; i++)
seriesColl.addSeries(optimizer.series[i]);
StringBuffer mzBucketSizeStr = new StringBuffer();
String sep = "";
for (int i = 0; i < optimizer.mzValues.length; i++)
{
mzBucketSizeStr.append(sep);
mzBucketSizeStr.append(optimizer.mzValues[i]);
sep = ", ";
}
JFrame newFrame = new JFrame(TextProvider.getText("BUCKETS_FOR_MZ_OF_SIZE", new String(mzBucketSizeStr)));
ChartPanel chart = SpectrumChartFactory.CreateChartPanel(seriesColl);
chart.getChart().getXYPlot().getDomainAxis().setLabel(TextProvider.getText("SCAN_WINDOW"));
chart.getChart().getXYPlot().getRangeAxis().setLabel(TextProvider.getText("QUOTE_PERFECT_BUCKETS"));
newFrame.setContentPane(chart);
newFrame.setSize(400, 500);
newFrame.setVisible(true);
}
}
public static class ColorRenderer extends JLabel
implements TableCellRenderer
{
Border unselectedBorder = null;
Border selectedBorder = null;
boolean isBordered = true;
public ColorRenderer(boolean isBordered)
{
this.isBordered = isBordered;
setOpaque(true); //MUST do this for background to show up.
}
public Component getTableCellRendererComponent(JTable table, Object color,
boolean isSelected, boolean hasFocus,
int row, int column)
{
Color newColor = (Color) color;
setBackground(newColor);
if (isBordered)
{
if (isSelected)
{
if (selectedBorder == null)
{
selectedBorder = BorderFactory.createMatteBorder(2, 5, 2, 5,
table.getSelectionBackground());
}
setBorder(selectedBorder);
}
else
{
if (unselectedBorder == null)
{
unselectedBorder = BorderFactory.createMatteBorder(2, 5, 2, 5,
table.getBackground());
}
setBorder(unselectedBorder);
}
}
setToolTipText(TextProvider.getText("RGB_VALUE_RED_GREEN_BLUE",
"RED", Integer.toString(newColor.getRed()),
"GREEN", Integer.toString(newColor.getGreen()),
"BLUE", Integer.toString(newColor.getBlue())));
return this;
}
}
public static class ColorEditor extends AbstractCellEditor
implements TableCellEditor,
ActionListener
{
Color currentColor;
JButton button;
JColorChooser colorChooser;
JDialog dialog;
protected static final String EDIT = "edit";
public ColorEditor()
{
//Set up the editor (from the table's point of view),
//which is a button.
//This button brings up the color chooser dialog,
//which is the editor from the user's point of view.
button = new JButton();
button.setActionCommand(EDIT);
button.addActionListener(this);
button.setBorderPainted(false);
//Set up the dialog that the button brings up.
colorChooser = new JColorChooser();
dialog = JColorChooser.createDialog(button,
"Pick a Color",
true, //modal
colorChooser,
this, //OK button handler
null); //no CANCEL button handler
}
/**
* Handles events from the editor button and from
* the dialog's OK button.
*/
public void actionPerformed(ActionEvent e)
{
if (EDIT.equals(e.getActionCommand()))
{
//The user has clicked the cell, so
//bring up the dialog.
button.setBackground(currentColor);
colorChooser.setColor(currentColor);
dialog.setVisible(true);
//Make the renderer reappear.
fireEditingStopped();
}
else
{ //User pressed dialog's "OK" button.
currentColor = colorChooser.getColor();
}
}
//Implement the one CellEditor method that AbstractCellEditor doesn't.
public Object getCellEditorValue()
{
return currentColor;
}
//Implement the one method defined by TableCellEditor.
public Component getTableCellEditorComponent(JTable table,
Object value,
boolean isSelected,
int row,
int column)
{
currentColor = (Color) value;
return button;
}
}
public static class BrowseEditor extends AbstractCellEditor
implements TableCellEditor,
ActionListener
{
FeatureSet fs;
JButton button;
public BrowseEditor()
{
button = new JButton("...");
button.addActionListener(this);
}
public void actionPerformed(ActionEvent e)
{
if (null == fs)
return;
FeatureFrame frame = new FeatureFrame(fs);
frame.setVisible(true);
}
//Implement the one CellEditor method that AbstractCellEditor doesn't.
public Object getCellEditorValue()
{
return fs;
}
//Implement the one method defined by TableCellEditor.
public Component getTableCellEditorComponent(JTable table,
Object value,
boolean isSelected,
int row,
int column)
{
fs = (FeatureSet) value;
return button;
}
}
public static class FeatureFrame extends JFrame
{
FeatureSet _fs;
FeatureTable _table;
JDialog _popup = null;
public FeatureFrame(FeatureSet fs)
{
super((fs.getSourceFile() != null ? fs.getSourceFile().getName() : "(no file)") + " -- " + fs.getFeatures().length);
setSize(640, 400);
setIconImage(ApplicationContext.getFrame().getIconImage());
JPanel editPanel = new JPanel();
JButton propertiesButton = new JButton(TextProvider.getText("PROPERTIES"));
JButton deleteButton = new JButton(TextProvider.getText("DELETE"));
JButton saveButton = new JButton(TextProvider.getText("SAVE"));
JButton addButton = new JButton(TextProvider.getText("ADD"));
JButton closeButton = new JButton(TextProvider.getText("CLOSE"));
ListenerHelper helper = new ListenerHelper(this);
helper.addListener(propertiesButton, "properties_actionPerformed");
helper.addListener(deleteButton, "delete_actionPerformed");
helper.addListener(addButton, "add_actionPerformed");
helper.addListener(saveButton, "save_actionPerformed");
helper.addListener(closeButton, "close_actionPerformed");
editPanel.add(propertiesButton);
editPanel.add(addButton);
editPanel.add(deleteButton);
editPanel.add(saveButton);
editPanel.add(closeButton);
_table = new FeatureTable(fs);
JScrollPane pane = new JScrollPane(_table);
getContentPane().add(pane);
getContentPane().add(editPanel, BorderLayout.PAGE_END);
}
public void properties_actionPerformed(ActionEvent e)
{
if (true)
{
if (ApplicationContext.getFrame() instanceof WorkbenchFrame)
((WorkbenchFrame) ApplicationContext.getFrame()).showPropertiesPane();
ApplicationContext.setProperty(SharedProperties.SELECTED, _fs);
}
else
{
PropertiesPane.popup(_fs.getProperties());
}
/* Map map = _fs.getProperties();
if (null == map)
map = new HashMap();
TableModel m = new DefaultTableModel(map.size(), 2);
int row = 0;
for (Iterator it = map.entrySet().iterator(); it.hasNext();)
{
Map.Entry entry = (Map.Entry)it.next();
m.setValueAt(entry.getKey(), row, 0);
m.setValueAt(entry.getValue(), row, 1);
row++;
}
JTable table = new JTable(m);
table.getColumnModel().getColumn(0).setHeaderValue("property");
table.getColumnModel().getColumn(1).setHeaderValue("value");
String title = "" + _fs.getSourceFile() + " properties";
JDialog dialog = new JDialog(ApplicationContext.getFrame(), title, true);
ListenerHelper h = new ListenerHelper(this);
h.addListener(dialog.getContentPane(), "popup_keyPressed");
h.addListener(table, "popup_keyPressed");
dialog.getContentPane().add(new JScrollPane(table));
dialog.setSize(400, 300);
_popup = dialog;
dialog.setVisible(true);
}
*/ }
/* public void popup_keyPressed(KeyEvent e)
{
if (e.getKeyCode() == KeyEvent.VK_ESCAPE && null != _popup)
{
_popup.dispose();
_popup = null;
e.consume();
return;
}
} */
public void delete_actionPerformed(ActionEvent e)
{
int row;
int sortRow = _table.getSelectedRow();
if (sortRow < 0 || sortRow >= _fs.getFeatures().length)
return;
row = _table.convertRowIndexToModel(sortRow);
Feature[] features = _fs.getFeatures();
Feature[] newFeatures = new Feature[features.length - 1];
for (int i = 0; i < row; i++)
newFeatures[i] = features[i];
for (int i = row + 1; i < features.length; i++)
newFeatures[i - 1] = features[i];
//TODO: Move fs into tablemodel so don't have to hack around like this...
_fs.setFeatures(newFeatures);
_table._model._features = newFeatures;
_table._model.fireTableRowsDeleted(row, row);
_table.getSelectionModel().setSelectionInterval(sortRow, sortRow);
_table.requestFocus();
FeatureSelectionDialog.getInstance().updateFeatureSets(FeatureSelectionDialog.getInstance().getFeatureSets(), false);
}
public void add_actionPerformed(ActionEvent e)
{
Spectrum.Peak p = (Spectrum.Peak) ApplicationContext.getProperty(SharedProperties.SELECTED_POINT);
Feature f;
if (null == p)
f = new Feature();
else
f = new Feature(p);
int row;
int sortRow = _table.getSelectedRow();
sortRow = Math.min(sortRow, _fs.getFeatures().length - 1);
row = _table.convertRowIndexToModel(sortRow);
Feature[] features = _fs.getFeatures();
Feature[] newFeatures = new Feature[features.length + 1];
for (int i = 0; i <= row; i++)
newFeatures[i] = features[i];
newFeatures[row + 1] = f;
for (int i = row + 1; i < features.length; i++)
newFeatures[i + 1] = features[i];
String userName = System.getProperty("user.name");
//not translating, since this will be stored at the feature level
f.setDescription("Added=" + userName + ", " + new SimpleDateFormat().format(new Date()));
//TODO: Move fs into tablemodel so don't have to hack around like this...
_fs.setFeatures(newFeatures);
_table._model._features = newFeatures;
_table._model.fireTableRowsInserted(row + 1, row + 1);
_table.getSelectionModel().setSelectionInterval(sortRow + 1, sortRow + 1);
_table.requestFocus();
FeatureSelectionDialog.getInstance().updateFeatureSets(FeatureSelectionDialog.getInstance().getFeatureSets(), false);
}
public void close_actionPerformed(ActionEvent e)
{
this.dispose();
}
public void save_actionPerformed(ActionEvent e)
{
try
{
if (_fs.getSourceFile() == null)
{
WorkbenchFileChooser wfc = new WorkbenchFileChooser();
wfc.showSaveDialog(this);
File file = wfc.getSelectedFile();
_fs.setSourceFile(file);
}
_fs.save();
}
catch (Exception x)
{
//JOptionPane.showMessageDialog(null, "Exception saving: " + x.getMessage());
ApplicationContext.errorMessage(null, x);
}
}
private void selectRow()
{
if (null == _fs)
return;
if (null == _table)
return;
int row = _table.getSelectedRow();
if (row < 0 || row >= _fs.getFeatures().length)
return;
row = _table.convertRowIndexToModel(row);
Feature f = _fs.getFeatures()[row];
//System.err.println(f);
float mz = f.getMz();
if (mz <= 0)
return;
// UNDONE: float time = f.getCPUTime();
int scanNum = f.getScan();
if (scanNum <= 0)
return;
MSRun run = (MSRun) ApplicationContext.getProperty(SharedProperties.MS_RUN);
MSRun.MSScan selectedScan = null;
if (run != null)
{
if (scanNum >= run.getScanCount())
scanNum = run.getScanCount() - 1;
selectedScan = run.getScan(scanNum);
}
ApplicationContext.setProperty(SharedProperties.MS_SCAN, selectedScan);
Feature c = (Feature) f.clone();
ApplicationContext.setProperty(SharedProperties.SELECTED_POINT, c);
ApplicationContext.setProperty(SharedProperties.SELECTED, c);
}
public void table_keyPressed(KeyEvent e)
{
ApplicationContext.setMessage("" + e.getKeyCode());
if (e.getKeyCode() != 10)
return;
e.consume();
selectRow();
}
public void table_mouseClicked(MouseEvent e)
{
if (e.getClickCount() != 2)
return;
e.consume();
selectRow();
}
public class FeatureTable extends JTable
{
FeatureTableModel _model;
JTextField _textEditor;
public FeatureTable(FeatureSet fs)
{
_fs = fs;
_model = new FeatureTableModel(_fs.getFeatures());
setModel(_model);
//dhmay replacing the old usage of our custom TableSorter class with the standard 1.6 syntax
TableRowSorter<TableModel> sorter
= new TableRowSorter<TableModel>(_model);
setRowSorter(sorter);
int count = _model.getColumnCount();
for (int i = 0; i < count - 1; i++)
getColumnModel().getColumn(i).setCellRenderer(new FeatureSelectionDialog.NumberRenderer());
getColumnModel().getColumn(count - 1).setPreferredWidth(200);
ListenerHelper helper = new ListenerHelper(FeatureFrame.this);
helper.addListener(this, "table_mouseClicked");
helper.addListener(this, "table_keyPressed");
}
public Component prepareEditor(TableCellEditor editor, int row, int column)
{
Component c = super.prepareEditor(editor, row, column);
if (c instanceof JTextField)
((JTextField) c).selectAll();
return c;
}
public void valueChanged(ListSelectionEvent e)
{
super.valueChanged(e);
selectRow();
}
}
}
public static class NumberRenderer extends DefaultTableCellRenderer
{
NumberFormat format;
int decimal = 2;
public NumberRenderer()
{
super();
setHorizontalAlignment(RIGHT);
format = new DecimalFormat();
format.setMaximumFractionDigits(decimal);
format.setMinimumFractionDigits(decimal);
}
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
{
Object formatted = value;
if (value instanceof Float || value instanceof Double)
formatted = format.format(value);
return super.getTableCellRendererComponent(table, formatted, isSelected, hasFocus, row, column);
}
}
}
}