/* * 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.commandline.modules; import org.fhcrc.cpl.toolbox.proteomics.MSRun; import org.fhcrc.cpl.toolbox.gui.chart.PanelWithHistogram; import org.fhcrc.cpl.toolbox.gui.chart.ChartDialog; import org.fhcrc.cpl.toolbox.proteomics.feature.FeatureSet; import org.fhcrc.cpl.toolbox.proteomics.feature.AnalyzeICAT; import org.fhcrc.cpl.toolbox.proteomics.feature.Feature; import org.fhcrc.cpl.toolbox.proteomics.feature.Spectrum; import org.fhcrc.cpl.toolbox.proteomics.feature.extraInfo.IsotopicLabelExtraInfoDef; import org.apache.log4j.Logger; import org.fhcrc.cpl.toolbox.ApplicationContext; import org.fhcrc.cpl.toolbox.commandline.CommandLineModuleExecutionException; import org.fhcrc.cpl.toolbox.commandline.CommandLineModule; import org.fhcrc.cpl.toolbox.commandline.arguments.*; import java.io.File; import java.io.PrintWriter; import java.io.FileOutputStream; import java.util.List; import java.util.ArrayList; /** * Command linemodule for deconvolution. The "quant" and "icat" commands subclass * this module... all the work is done here. */ public class DeconvoluteCommandLineModule extends BaseViewerCommandLineModuleImpl implements CommandLineModule { protected static Logger _log = Logger.getLogger(DeconvoluteCommandLineModule.class); protected File[] files; protected File outFile; protected File outDir; protected boolean deconvolute = true; protected boolean quant = false; protected int scanWindow = 6; protected double massWindow = .4; protected float lightTagWeight = -1.f; protected float heavyTagWeight = -1.f; protected char labeledResidue = ' '; protected int maxLabelCount = 3; protected MSRun run = null; protected int intensityType = FeatureSet.DEFAULT_INTENSITY_TYPE; protected float massTolerance = AnalyzeICAT.DEFAULT_DELTA_MASS; protected int massToleranceType = AnalyzeICAT.DEFAULT_DELTA_MASS_TYPE; protected float timeTolerance = AnalyzeICAT.DEFAULT_DELTA_TIME; protected boolean sumIntensities = true; protected boolean showCharts = false; AnalyzeICAT.IsotopicLabel label = AnalyzeICAT.icatLabel; // Default to ICAT parameters for quantitation protected static final String[] intensityTypeStrings = { "total", "max", "recalculated" }; public DeconvoluteCommandLineModule() { init(); } protected CommandLineArgumentDefinition[] createCommonArgDefs() { CommandLineArgumentDefinition[] argDefs = { createUnnamedSeriesFileArgumentDefinition(true, "Input File(s)"), new FileToWriteArgumentDefinition("out",false, "Output File"), new DirectoryToWriteArgumentDefinition("outdir",false, "Output Directory (for multiple files)"), new DecimalArgumentDefinition("masswindow",false,"Mass Window", massWindow), new IntegerArgumentDefinition("scanwindow",false,"Scan Window", scanWindow), new DecimalArgumentDefinition("lighttagweight",false,"Light tag weight", lightTagWeight), new DecimalArgumentDefinition("heavytagweight",false,"Heavy tag weight", heavyTagWeight), new IntegerArgumentDefinition("maxlabelcount",false,"Maximum Label Count", maxLabelCount), new StringArgumentDefinition("labeledresidue",false,"Labeled Residue"), new FileToReadArgumentDefinition("msfile",false,"mzXml File"), new EnumeratedValuesArgumentDefinition("intensitytype", false, "Intensity type",intensityTypeStrings), new DecimalArgumentDefinition("deltatime",false,"Time Tolerance", timeTolerance), new DeltaMassArgumentDefinition("deltamass",false,"Mass Tolerance", new DeltaMassArgumentDefinition.DeltaMassWithType(massTolerance, massToleranceType)), new BooleanArgumentDefinition("showcharts", false,"Show Charts", showCharts), new BooleanArgumentDefinition("sumintensities", false, "If true, deconvoluted feature intensities reflect the sum of all component feature intensities. If false, intensity of most-intense feature is kept.", sumIntensities), }; return argDefs; } protected void init() { mCommandName = "deconvolute"; mShortDescription = "Deconvolute"; mHelpMessage = "Deconvolute"; addArgumentDefinitions(createCommonArgDefs()); addArgumentDefinition(new BooleanArgumentDefinition("quant",false, "Quantitate", false)); } public void assignArgumentValues() throws ArgumentValidationException { files = this.getUnnamedSeriesFileArgumentValues(); outFile = getFileArgumentValue("out"); if (outFile == null) { assertArgumentPresent("outdir"); outDir = getFileArgumentValue("outdir"); } else assertArgumentAbsent("outdir"); if (files.length > 1) assertArgumentPresent("outdir"); if (hasArgumentValue("quant")) quant = getBooleanArgumentValue("quant"); massWindow = getDoubleArgumentValue("masswindow"); scanWindow = getIntegerArgumentValue("scanwindow"); lightTagWeight = getFloatArgumentValue("lighttagweight"); heavyTagWeight = getFloatArgumentValue("heavytagweight"); maxLabelCount = getIntegerArgumentValue("maxlabelcount"); String labeledResidueString = getStringArgumentValue("labeledresidue"); if (hasArgumentValue("labeledresidue")) { if (labeledResidueString.length() > 1 || !Character.isLetter(labeledResidueString.charAt(0))) throw new ArgumentValidationException("Bad residue value " + labeledResidueString); labeledResidue = labeledResidueString.charAt(0); } File runFile = getFileArgumentValue("msfile"); if (runFile != null) { try { run = MSRun.load(runFile.getAbsolutePath()); } catch (Exception e) { throw new ArgumentValidationException("Failed to load file " + runFile.getAbsolutePath(),e); } } if (hasArgumentValue("intensitytype")) { int rawIntensityType = ((EnumeratedValuesArgumentDefinition) getArgumentDefinition("intensitytype")).getIndexForArgumentValue(getStringArgumentValue("intensitytype")); switch(rawIntensityType) { case 0: intensityType = FeatureSet.TOTAL_INTENSITY; break; case 1: intensityType = FeatureSet.MAX_INTENSITY; break; case 2: intensityType = FeatureSet.RECALCULATED_INTENSITY; if (run == null) throw new ArgumentValidationException("When specifying intensityType=recalc, you must specify an msFile as well"); break; } } timeTolerance = getFloatArgumentValue("deltatime"); DeltaMassArgumentDefinition.DeltaMassWithType deltaMassResult = getDeltaMassArgumentValue("deltamass"); massTolerance = deltaMassResult.getDeltaMass(); massToleranceType = deltaMassResult.getDeltaMassType(); // ???? TODO: Expand these checks; deltaMass and deltaTime and maxLabelCount have no meaning if ! --quant if (!quant) { if ( lightTagWeight != -1.f || heavyTagWeight != -1.f ) throw new ArgumentValidationException("Tag weights can only be specified along with --quant"); } else if ((lightTagWeight > -1.f && heavyTagWeight == -1.f ) || (heavyTagWeight > -1.f && lightTagWeight == -1.f )) throw new ArgumentValidationException("Must specify both light and heavy tag weights explicitly, or leave both to default"); else if (lightTagWeight > -1.f && heavyTagWeight > -1.f) { // Build an Isotopic label from the given params. NB: we pass in the mass *delta*, not the heavy weight label = new AnalyzeICAT.IsotopicLabel(lightTagWeight, heavyTagWeight - lightTagWeight, labeledResidue, maxLabelCount); } showCharts = getBooleanArgumentValue("showcharts"); sumIntensities = getBooleanArgumentValue("sumintensities"); } public void execute() throws CommandLineModuleExecutionException { for (File file : files) { ApplicationContext.setMessage("Processing file " + file.getName()); File outputFile = outFile; if (outFile == null) { outputFile = new File(outDir, file.getName().substring(0, file.getName().indexOf(".")) + ".quant.tsv"); } processFile(file, outputFile); } } /** * do the actual work */ public void processFile(File inputFile, File outputFile) throws CommandLineModuleExecutionException { try { PrintWriter pw = null; if (null != outputFile) { try { pw = new PrintWriter(new FileOutputStream(outputFile)); } catch (java.io.FileNotFoundException e) { throw new CommandLineModuleExecutionException("Error creating PrintWriter from file " + outputFile.getAbsolutePath() + ", file not found"); } } else pw = new PrintWriter(System.out); try { FeatureSet fs = new FeatureSet(inputFile); if (deconvolute) fs = fs.deconvolute(scanWindow, massWindow, sumIntensities); if (quant) fs = fs.quant(label, intensityType, run, massTolerance, massToleranceType, timeTolerance); fs.save(pw); //PrintWriter deconPW = new PrintWriter(new File("/home/dhmay/temp/decon.tsv")); //FeatureSet fsDecon = (FeatureSet)fs.clone(); //List<Feature> deconOnlyFeatures = new ArrayList<Feature>(); //for (Feature feature : fs.getFeatures()) // if (feature.comprised != null && feature.comprised.length > 1) {for (Spectrum.Peak comprisedFeature : feature.comprised) deconOnlyFeatures.add((Feature) comprisedFeature);} //System.err.println("Decon only: " + deconOnlyFeatures.size()); //fsDecon.setFeatures(deconOnlyFeatures.toArray(new Feature[deconOnlyFeatures.size()])); //fsDecon.save(deconPW); if (quant && showCharts) { List<Float> ratioList = new ArrayList<Float>(); for (Feature feature : fs.getFeatures()) { double ratio = IsotopicLabelExtraInfoDef.getRatio(feature); if (ratio != IsotopicLabelExtraInfoDef.NO_RATIO_FOR_FEATURE) ratioList.add((float) ratio); } PanelWithHistogram pwh = new PanelWithHistogram(ratioList, "Quantitation Ratios"); ChartDialog histDialog = new ChartDialog(pwh); histDialog.setVisible(true); } } finally { if (null != outputFile && null != pw) pw.close(); } } catch (Exception x) { throw new CommandLineModuleExecutionException(x); } } }