/* * 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.feature; import org.apache.log4j.Logger; import org.fhcrc.cpl.toolbox.CPUTimer; import org.fhcrc.cpl.toolbox.datastructure.Pair; import org.fhcrc.cpl.toolbox.proteomics.feature.Spectrum; import org.fhcrc.cpl.toolbox.proteomics.feature.Feature; import org.fhcrc.cpl.viewer.feature.ExtractEdgeFeatures; import org.fhcrc.cpl.viewer.feature.extraction.SpectrumResampler; import org.fhcrc.cpl.toolbox.proteomics.MSRun; import org.fhcrc.cpl.toolbox.datastructure.FloatRange; import org.fhcrc.cpl.toolbox.proteomics.Scan; import java.awt.*; import java.awt.datatransfer.Clipboard; import java.awt.datatransfer.StringSelection; import java.io.InputStream; import java.io.Writer; import java.util.ArrayList; import java.util.Collection; import java.util.Properties; /** * User: mbellew * Date: Nov 2, 2004 * * This is meant to represent the peaks used in FeatureStrategyCombined */ public class FeatureStrategyPeaks extends FeatureStrategyUsingWindow // extends FeatureExtractor { static Logger _log = Logger.getLogger(FeatureStrategyPeaks.class); static int _WindowMargin = 64; static int _FeatureScanWindowStart; static int _FeatureScanWindowWidth; static float _FeatureMzWindowStart; static float _FeatureMzWindowHeight; static float _AverageWindowWidth; static CPUTimer timerAnalyze = new CPUTimer("FeatureStrategyCombined.analyze"); static CPUTimer timerResample = new CPUTimer("FeatureStrategyCombined.get and resample"); static CPUTimer timerBackground = new CPUTimer("FeatureStrategyCombined.background"); static CPUTimer timerEdgeFeatures = new CPUTimer("FeatureStrategyCombined.edges"); static CPUTimer timerExtractPeaks = new CPUTimer("FeatureStrategyCombined.peaks"); static CPUTimer timerExtractPeptides = new CPUTimer("FeatureStrategyCombined.peptides"); static { initProps(); } private static boolean bPropsInitialized = false; int _startNum = 0; int _endNum = 0; Scan[] _scans = null; private static void initProps() { assert false == (bPropsInitialized = false); if (bPropsInitialized) return; try { InputStream is = ExtractEdgeFeatures.class.getResourceAsStream("features.properties"); Properties props = new Properties(); props.load(is); _FeatureScanWindowStart = Integer.parseInt(((String)props.get("feature.ScanWindowStart")).trim()); _FeatureScanWindowWidth = Integer.parseInt(((String)props.get("feature.ScanWindowWidth")).trim()); _FeatureMzWindowStart = Float.parseFloat(((String)props.get("feature.MzWindowStart")).trim()); _FeatureMzWindowHeight = Float.parseFloat(((String)props.get("feature.MzWindowHeight")).trim()); _AverageWindowWidth = Integer.parseInt(((String)props.get("feature.AverageWindowWidth")).trim()); } catch (java.io.IOException x) { x.printStackTrace(); } } public FeatureStrategyPeaks(MSRun run, int scanIndex, int count, int maxCharge, FloatRange range, double sn) { super(run, scanIndex, count, maxCharge, range, sn); int scanMax = Math.min(scanIndex + count, run.getScanCount()); count = scanMax - scanIndex; _scans = getScans(run, scanIndex, count); _startNum = run.getScan(scanIndex).getNum(); _endNum = run.getScan(scanMax-1).getNum(); } public int getType() { return TYPE_2D; // lie for detail pane } public Feature[] _analyze() throws InterruptedException { //return analyzeScanAtATime(_scans); return analyzeWindow(_scans, 256, 32); } /** * THIS IS THE MAIN FEATURE FINDING ROUTINE */ protected Collection analyze1D(Scan scan) { float[][] spectrum = Spectrum.ResampleSpectrum(scan.getSpectrum(), _mzRange, SpectrumResampler.getResampleFrequency(), false); // HACK try averaging int scanIndex=0; for (; scanIndex < _scans.length; scanIndex++) if (scan == _scans[scanIndex]) break; int c=1; if (scanIndex-1 >=0) { c++; float[] t = Spectrum.Resample(_scans[scanIndex-1].getSpectrum(), _mzRange, SpectrumResampler.getResampleFrequency()); for (int i = 0; i < t.length; i++) spectrum[1][i] += t[i]; } if (scanIndex+1 < _scans.length) { c++; float[] t = Spectrum.Resample(_scans[scanIndex+1].getSpectrum(), _mzRange, SpectrumResampler.getResampleFrequency()); for (int i = 0; i < t.length; i++) spectrum[1][i] += t[i]; } for (int i = 0; i < spectrum[1].length; i++) spectrum[1][i] /= c; // END HACK float[] signal = spectrum[1]; int height = signal.length; // separate background and signal components // we're pretty conservative about what we call background, // we can use background and/or median later to filter peaks // further. float[] background = Spectrum.RemoveBackground(new float[][] {signal})[0]; float[] median = Spectrum.MedianWindow(signal, height, 72, false); assert timerExtractPeaks.start(); // .analyze() is destructive, need to copy float[] spectraT = (float[])signal.clone(); float[] d3 = Spectrum.WaveletD3(spectraT, null); int[] indexes = Spectrum.PickPeakIndexes(d3, 0F); ArrayList peaks = new ArrayList(); for (int i = 0; i < indexes.length; i++) { int index = indexes[i]; float mz = spectrum[0][index]; float in = spectrum[1][index]; if (in < median[index] * 2) continue; Spectrum.Peak p = new Spectrum.Peak(scan.getNum(), mz, in); p.setMedian(median[index]); p.setBackground(background[index]); peaks.add(p); } Spectrum.Peak[] arr = (Spectrum.Peak[])peaks.toArray(new Spectrum.Peak[0]); return PeaksAsFeatures(arr); } protected Collection analyze2D(Scan[] scans) { _log.debug("analyze2D " + scans[0].getNum() + "-" + scans[scans.length - 1].getNum()); assert timerAnalyze.start(); // // Convert data into 2D matrix // we will do all processing on this data until the end and // then process back to "scan" space // assert timerResample.start(); float[][] spectra = new float[scans.length][]; for (int i = 0; i < scans.length; i++) spectra[i] = Spectrum.Resample(scans[i].getSpectrum(), _mzRange, SpectrumResampler.getResampleFrequency()); int width = spectra.length; int height = spectra[0].length; // a little smoothing across elution, median eliminate lock spray! float[] row = null, t = null; for (int i=0 ; i<height ; i++) { row = Spectrum.getRow(spectra, i, row); t = Spectrum.MedianSmooth(row, row.length, t); Spectrum.SmoothALittle(t); Spectrum.setRow(spectra, i, t); } assert timerResample.stop(); _log.debug("analyze2D datasize = " + (width * height * 4)); // separate background and signal components // we're pretty conservative about what we call background, // we can use background and/or median later to filter peaks // further. timerBackground.start(); float[][] original = new float[width][]; for (int i=0 ; i<width ; i++) original[i] = (float[])spectra[i].clone(); float[][] background = Spectrum.RemoveBackground(spectra); float[][] median = new float[spectra.length][]; for (int i=0 ; i<width ; i++) median[i] = Spectrum.MedianWindow(spectra[i], height, 72, false); timerBackground.stop(); ArrayList peaks = new ArrayList(); float[][] wavelets = new float[width][]; Pair tmp = new Pair(null, null); for (int s = 0; s < spectra.length; s++) { float[] spectraT = (float[])spectra[s].clone(); float[] d3 = Spectrum.WaveletD3(spectraT, tmp); wavelets[s] = d3; int[] indexes = Spectrum.PickPeakIndexes(d3, 0F); for (int p = 0; p < indexes.length; p++) { int index = indexes[p]; float mz = this._mzRange.min + index/ SpectrumResampler.getResampleFrequency(); float in = spectra[s][index]; if (in < median[s][index] * 2) continue; Spectrum.Peak peak = new Spectrum.Peak(_scans[s].getNum(), mz, in); peak.setMedian(median[s][index]); peak.setBackground(background[s][index]); if (peak.intensity < (0.5*peak.background + 2*peak.getMedian() + 3)) continue; peaks.add(peak); } } float debugMapMZ = 0; if (debugMapMZ != 0) { try{ Writer out = new java.io.StringWriter(); int middle = Math.round((debugMapMZ - _mzRange.min) * SpectrumResampler.getResampleFrequency()); int start = Math.max(0,middle-100); int end = Math.min(height,middle+100); out.write("# scans [" + _scans[0].getNum() + "," + _scans[_scans.length-1].getNum() + "] mz [" + (_mzRange.min + start/ SpectrumResampler.getResampleFrequency()) + "," + (_mzRange.min + (end-1)/ SpectrumResampler.getResampleFrequency()) + "]" + "\n"); float[][] source = wavelets;// original; //spectra; // wavelets : original; for (int z = end-1 ; z>=start ; z--) { for (int s = 0; s < source.length; s++) { out.write(Math.max(0,source[s][z]) + "\t"); } out.write("\n"); } out.write("\n"); StringSelection sel = new StringSelection(out.toString()); Clipboard clip = Toolkit.getDefaultToolkit().getSystemClipboard(); clip.setContents(sel,sel); } catch (Exception x){ } } Spectrum.Peak[] arr = (Spectrum.Peak[])peaks.toArray(new Spectrum.Peak[0]); return PeaksAsFeatures(arr); } Collection PeaksAsFeatures(Spectrum.Peak[] peaks) { ArrayList l = new ArrayList(); for (int p = 0; p < peaks.length; p++) l.add(new Feature(peaks[p])); return l; } }