/* * 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; import java.io.File; import java.io.FileWriter; import java.io.PrintWriter; import java.util.*; import org.fhcrc.cpl.toolbox.ApplicationContext; import org.fhcrc.cpl.viewer.feature.FeatureStrategyCentroided; import org.fhcrc.cpl.toolbox.datastructure.FloatRange; import org.fhcrc.cpl.toolbox.proteomics.feature.Spectrum; import org.fhcrc.cpl.toolbox.proteomics.feature.FeatureSet; import org.fhcrc.cpl.toolbox.proteomics.feature.Feature; import org.fhcrc.cpl.toolbox.proteomics.MSRun; import org.apache.log4j.Logger; public class DumpWindow2D { private static Logger _log = Logger.getLogger(DumpWindow2D.class); private static Comparator compareFeaturesByScanAndMzAsc = new Comparator(){ public int compare(Object o1, Object o2) { Feature f1 = (Feature)o1; Feature f2 = (Feature)o2; if ( f1.scan != f2.scan ) return f1.scan > f2.scan ? 1 : -1; return f1.mz == f2.scan ? 0 : ( f1.mz > f2.mz ? 1 : -1 ); } }; public static void dump(File runFile, File featureFile, int leadingScans, int trailingScans, int leadingPeaks, int trailingPeaks, File outFile) throws Exception { if (!runFile.exists()) { ApplicationContext.errorMessage("Couldn't find mzXML file " + runFile.getPath(), null); return; } if (!featureFile.exists()) { ApplicationContext.errorMessage("Couldn't find feature file" + featureFile.getPath(), null); return; } PrintWriter out = null; try { out = new PrintWriter(new FileWriter(outFile)); MSRun run = MSRun.load(runFile.getPath()); if (null == run) { ApplicationContext.errorMessage("Couldn't load mzXML file" + runFile.getPath(), null); return; } FeatureSet fs = new FeatureSet(featureFile); Feature[] features = fs.getFeatures(); Arrays.sort(features, compareFeaturesByScanAndMzAsc); // Check this for LTQ-FT; may just come from mzXML header... boolean centroided = run.getHeaderInfo().getDataProcessing().getCentroided() == 1; _log.debug("Data is " + (centroided ? "" : "not ") + "centroided."); out.println("FeatureID\tLabel\tPeptide\tProtein\tCharge\tm/z\tMass\tScan\tScan\tTime\tWindow"); for (int i = 0; i < features.length; i++) { // Skip charge zero features if ( features[i].charge == 0 ) continue; int nScans = leadingScans + trailingScans; MSRun.MSScan[] scans = new MSRun.MSScan[nScans]; // search back for some number of MS1 scans // int startIndex = run.getIndexForFeature(features[i]) - 1; int startIndex = run.getIndexForScanNum(features[i].scan) - 1; // The acrylquant.R code currently has trouble if you are // within the last 20 scans; don't output such features if ( startIndex < 10 || run.getScanCount() - startIndex < 20 ) { _log.warn("Skipping feature (" + features[i].scan + ", " + features[i].mass + ", " + features[i].charge + ") " + startIndex + " " + run.getScanCount()); continue; } int s = leadingScans - 1; while ( s >= 0 && startIndex >= 0 ) { scans[s] = run.getScan(startIndex); if ( scans[s].getMsLevel() == 1 ) s--; startIndex--; } // now search forward for some number of MS1 scans int endIndex = run.getIndexForFeature(features[i]); s = leadingScans; while ( s < nScans && endIndex < run.getScanCount() ) { scans[s] = run.getScan(endIndex); if ( scans[s].getMsLevel() == 1 ) s++; endIndex++; } nScans = s; // get the number of scans actually read float startMz = features[i].mz - leadingPeaks; float endMz = features[i].mz + trailingPeaks; // HACK: We expect the description to contain feature ID, label type, etc. String desc = features[i].getDescription(); String[] tokens = desc.split(" "); desc = join("\t", tokens); for (s = 0; s < nScans; s++) { float[][] spectrum = scans[s].getSpectrum(); if ( centroided ) spectrum = FeatureStrategyCentroided.cleanSpectrum(spectrum); float[] signal = Spectrum.Resample(spectrum, new FloatRange(startMz, endMz), 36); StringBuffer sb = new StringBuffer(); sb.append(desc + "\t"); sb.append(features[i].charge + "\t"); // charge sb.append(features[i].mz + "\t"); // mz sb.append(features[i].mass + "\t"); // mass sb.append(features[i].scan + "\t"); // scan sb.append(scans[s].getNum() + "\t"); // scan sb.append(scans[s].getRetentionTime() + "\t"); // retention time for (int m = 0; m < signal.length; m++) sb.append(signal[m] + "\t"); out.println(sb.toString()); } } } finally { if (null != out) out.close(); } } private static String join(String delim, String[] s) { if ( null == s ) return null; if ( s.length == 0 ) return ""; StringBuffer sb = new StringBuffer(s[0]); for (int i = 1; i < s.length; i++) { if ( null != delim ) sb.append(delim); sb.append(s[i]); } return sb.toString(); } }