From adcd90dc58b0e6e2193b0e364b25c990aaeb775e Mon Sep 17 00:00:00 2001 From: Cory Nathe Date: Thu, 14 Mar 2019 15:10:18 +0000 Subject: [PATCH 1/5] Secure Issue 36967: SQL Injection in LabKey SQL via LeveyJennings report (Luminex) --- .../org/labkey/luminex/view/leveyJenningsReport.jsp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/luminex/src/org/labkey/luminex/view/leveyJenningsReport.jsp b/luminex/src/org/labkey/luminex/view/leveyJenningsReport.jsp index 3e0062b1b7..fda77543f6 100644 --- a/luminex/src/org/labkey/luminex/view/leveyJenningsReport.jsp +++ b/luminex/src/org/labkey/luminex/view/leveyJenningsReport.jsp @@ -133,18 +133,19 @@ // verify that the given titration/singlepointcontrol exists and has run's associated with it as a Standard or QC Control var sql; - if ('Titration' == _controlType) { - sql = "SELECT COUNT(*) AS RunCount FROM Titration WHERE Name='" + _controlName + "' AND IncludeInQcReport=true"; + if ('Titration' === _controlType) { + sql = "SELECT COUNT(*) AS RunCount FROM Titration WHERE Name=CONTROL_NAME AND IncludeInQcReport=true"; } else { - sql = "SELECT COUNT(*) AS RunCount FROM SinglePointControl WHERE Name='" + _controlName + "'"; + sql = "SELECT COUNT(*) AS RunCount FROM SinglePointControl WHERE Name=CONTROL_NAME"; } LABKEY.Query.executeSql({ containerFilter: LABKEY.Query.containerFilter.allFolders, schemaName: 'assay.Luminex.' + LABKEY.QueryKey.encodePart(_protocolName), - sql: sql, + sql: 'PARAMETERS(CONTROL_NAME VARCHAR) ' + sql, + parameters: {CONTROL_NAME: _controlName}, success: function(data) { - if (data.rows.length == 0 || data.rows[0]['RunCount'] == 0) + if (data.rows.length === 0 || data.rows[0]['RunCount'] === 0) { Ext.get('graphParamsPanel').update("Error: there were no records found in '" + $h(_protocolName) + "' for '" + $h(_controlName) + "'."); From f67ab6a108868cd6c68229ccc8d8467fa76b57fa Mon Sep 17 00:00:00 2001 From: Matthew Bellew Date: Thu, 14 Mar 2019 23:26:01 +0000 Subject: [PATCH 2/5] Sampleset delete perf -- ExpressionMatrixExperimentListener.beforeMaterialDelete() -- ExperimentServiceImpl.deleteRunsUsingInputs() --- .../ExpressionMatrixExperimentListener.java | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/microarray/src/org/labkey/microarray/matrix/ExpressionMatrixExperimentListener.java b/microarray/src/org/labkey/microarray/matrix/ExpressionMatrixExperimentListener.java index 1563287297..53925e2bcf 100644 --- a/microarray/src/org/labkey/microarray/matrix/ExpressionMatrixExperimentListener.java +++ b/microarray/src/org/labkey/microarray/matrix/ExpressionMatrixExperimentListener.java @@ -18,12 +18,16 @@ import org.labkey.api.data.Container; import org.labkey.api.data.SQLFragment; import org.labkey.api.data.SqlExecutor; +import org.labkey.api.data.dialect.SqlDialect; import org.labkey.api.exp.api.ExpMaterial; +import org.labkey.api.exp.api.ExpObject; import org.labkey.api.exp.api.ExperimentListener; import org.labkey.api.security.User; import org.labkey.microarray.query.MicroarrayUserSchema; +import java.util.ArrayList; import java.util.List; +import java.util.stream.Collectors; /** * User: jeckels @@ -34,14 +38,12 @@ public class ExpressionMatrixExperimentListener implements ExperimentListener @Override public void beforeMaterialDelete(List materials, Container container, User user) { + SqlDialect d = MicroarrayUserSchema.getSchema().getSqlDialect(); SqlExecutor sqlExecutor = new SqlExecutor(MicroarrayUserSchema.getSchema()); - for (ExpMaterial material : materials) - { - SQLFragment sql = new SQLFragment("DELETE FROM "); - sql.append(MicroarrayUserSchema.getSchema().getTable("FeatureData")); - sql.append(" WHERE SampleId = ?"); - sql.add(material.getRowId()); - sqlExecutor.execute(sql); - } + SQLFragment sql = new SQLFragment("DELETE FROM "); + sql.append(MicroarrayUserSchema.getSchema().getTable("FeatureData")); + sql.append(" WHERE SampleId "); + d.appendInClauseSql(sql, materials.stream().map(ExpObject::getRowId).collect(Collectors.toList())); + sqlExecutor.execute(sql); } } From 6b7b5d568300093a78d9d1a69c6cb035444dc9ea Mon Sep 17 00:00:00 2001 From: Susan Hert Date: Wed, 20 Mar 2019 19:01:11 +0000 Subject: [PATCH 3/5] Use new parameterized method for getting paths to platform modules and commonAssay modules in anticipation of migration to Git. --- flow/build.gradle | 8 ++++---- ms1/build.gradle | 4 ++-- ms2/build.gradle | 7 +++---- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/flow/build.gradle b/flow/build.gradle index 76efb635ab..7c6f214a35 100644 --- a/flow/build.gradle +++ b/flow/build.gradle @@ -9,9 +9,9 @@ sourceSets { } dependencies { - BuildUtils.addLabKeyDependency(project: project, config: "engineCompile", depProjectPath: ":server:modules:flow", depProjectConfig: 'xmlSchema') - BuildUtils.addLabKeyDependency(project: project, config: "engineCompile", depProjectPath: ":server:api") - BuildUtils.addLabKeyDependency(project: project, config: "engineCompile", depProjectPath: ":server:internal") + BuildUtils.addLabKeyDependency(project: project, config: "engineCompile", depProjectPath: project.path, depProjectConfig: 'xmlSchema') + BuildUtils.addLabKeyDependency(project: project, config: "engineCompile", depProjectPath: BuildUtils.getApiProjectPath(project.gradle)) + BuildUtils.addLabKeyDependency(project: project, config: "engineCompile", depProjectPath: BuildUtils.getInternalProjectPath(project.gradle)) engineCompile "org.labkey:labkey-client-api:${project.version}" engineCompile 'org.apache.tomcat:jsp-api' engineCompile 'org.apache.tomcat:jasper' @@ -19,7 +19,7 @@ dependencies { compile sourceSets.engine.output jspCompile sourceSets.engine.output - BuildUtils.addLabKeyDependency(project: project, config: "jspCompile", depProjectPath: ":server:modules:flow", depProjectConfig: 'xmlSchema') + BuildUtils.addLabKeyDependency(project: project, config: "jspCompile", depProjectPath: project.path, depProjectConfig: 'xmlSchema') } project.task("engineJar", diff --git a/ms1/build.gradle b/ms1/build.gradle index cf161e106c..e35dafffa3 100644 --- a/ms1/build.gradle +++ b/ms1/build.gradle @@ -1,8 +1,8 @@ import org.labkey.gradle.util.BuildUtils dependencies { - BuildUtils.addLabKeyDependency(project: project, config: "compile", depProjectPath: ":server:modules:ms2", depProjectConfig: 'apiCompile', specialParams: { - if(!BuildUtils.shouldBuildFromSource(project.project(":server:modules:ms2"))) { + BuildUtils.addLabKeyDependency(project: project, config: "compile", depProjectPath: BuildUtils.getCommonAssayModuleProjectPath(project.gradle, "ms2"), depProjectConfig: 'apiCompile', specialParams: { + if(!BuildUtils.shouldBuildFromSource(project.project( BuildUtils.getCommonAssayModuleProjectPath(project.gradle, "ms2")))) { exclude group: 'org.labkey', module: 'ms1' } }) diff --git a/ms2/build.gradle b/ms2/build.gradle index d7f7367ffb..4826d4ed4e 100644 --- a/ms2/build.gradle +++ b/ms2/build.gradle @@ -1,10 +1,9 @@ import org.labkey.gradle.util.BuildUtils -dependencies -{ +dependencies { external 'commons-httpclient:commons-httpclient:3.1' - BuildUtils.addLabKeyDependency(project: project, config: "compile", depProjectPath: ":server:modules:ms1", depProjectConfig: 'apiCompile', specialParams: { - if(!BuildUtils.shouldBuildFromSource(project.project(":server:modules:ms1"))) { + BuildUtils.addLabKeyDependency(project: project, config: "compile", depProjectPath: BuildUtils.getCommonAssayModuleProjectPath(project.gradle, "ms1"), depProjectConfig: 'apiCompile', specialParams: { + if(!BuildUtils.shouldBuildFromSource(project.project(BuildUtils.getCommonAssayModuleProjectPath(project.gradle, "ms1")))) { exclude group: 'org.labkey', module: 'ms2' } }) From 72c9bca1a7b6f3d8780954585b2b8cb560f03291 Mon Sep 17 00:00:00 2001 From: Susan Hert Date: Wed, 20 Mar 2019 20:02:48 +0000 Subject: [PATCH 4/5] Don't apply java plugin and labkey Module plugin to internal and api (when the become a subproject here) --- build.gradle | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index a3b4c308c6..9953403d8b 100644 --- a/build.gradle +++ b/build.gradle @@ -1,8 +1,13 @@ +import org.labkey.gradle.util.BuildUtils import org.labkey.gradle.util.ModuleFinder subprojects { Project p -> - if (p.projectDir.exists() && ModuleFinder.isPotentialModule(p)) + if (p.projectDir.exists() && + ModuleFinder.isPotentialModule(p) && + !p.path.equals(BuildUtils.getApiProjectPath(p.gradle)) && + !p.path.equals(BuildUtils.getInternalProjectPath(p.gradle)) + ) { apply plugin: 'java' apply plugin: 'org.labkey.module' From 551d0d7c17f73bf6cf291408ec647cf3427b1e7b Mon Sep 17 00:00:00 2001 From: labkey-jeckels Date: Mon, 1 Apr 2019 11:56:53 -0700 Subject: [PATCH 5/5] Issue 37145 - Sequest Peptide Search not appearing due to server confusion about variant to use for configuration Remove unused UW variant of Sequest --- ms2/src/org/labkey/ms2/MS2Module.java | 5 - .../sequest/SequestPipelineProvider.java | 4 +- .../sequest/UWSequestParamsBuilder.java | 365 ------- .../pipeline/sequest/UWSequestSearchTask.java | 928 ------------------ ms2/webapp/WEB-INF/ms2/ms2Context.xml | 8 - 5 files changed, 2 insertions(+), 1308 deletions(-) delete mode 100644 ms2/src/org/labkey/ms2/pipeline/sequest/UWSequestParamsBuilder.java delete mode 100644 ms2/src/org/labkey/ms2/pipeline/sequest/UWSequestSearchTask.java diff --git a/ms2/src/org/labkey/ms2/MS2Module.java b/ms2/src/org/labkey/ms2/MS2Module.java index 6c07f008af..8981a5316e 100644 --- a/ms2/src/org/labkey/ms2/MS2Module.java +++ b/ms2/src/org/labkey/ms2/MS2Module.java @@ -77,8 +77,6 @@ import org.labkey.ms2.pipeline.sequest.SequestPipelineProvider; import org.labkey.ms2.pipeline.sequest.SequestSearchTask; import org.labkey.ms2.pipeline.sequest.ThermoSequestParamsBuilder; -import org.labkey.ms2.pipeline.sequest.UWSequestParamsBuilder; -import org.labkey.ms2.pipeline.sequest.UWSequestSearchTask; import org.labkey.ms2.pipeline.tandem.XTandemPipelineProvider; import org.labkey.ms2.protein.CustomAnnotationSet; import org.labkey.ms2.protein.CustomProteinListView; @@ -423,10 +421,7 @@ public Set getUnitTests() NaturalNumberParamsValidator.TestCase.class, MultipleIntegerParamsValidator.TestCase.class, MultipleDoubleParamsValidator.TestCase.class, - UWSequestParamsBuilder.TestCase.class, - UWSequestSearchTask.TestCase.class, ProteinCoverageMapBuilder.TestCase.class, - UWSequestSearchTask.TestCase.class, Comet2014ParamsBuilder.LimitedParseTestCase.class, Comet2015ParamsBuilder.LimitedParseTestCase.class, TPPTask.TestCase.class, diff --git a/ms2/src/org/labkey/ms2/pipeline/sequest/SequestPipelineProvider.java b/ms2/src/org/labkey/ms2/pipeline/sequest/SequestPipelineProvider.java index 1f2577a528..fc94a81813 100644 --- a/ms2/src/org/labkey/ms2/pipeline/sequest/SequestPipelineProvider.java +++ b/ms2/src/org/labkey/ms2/pipeline/sequest/SequestPipelineProvider.java @@ -46,7 +46,7 @@ * Date: Aug 24, 2006 * Time: 12:45:45 PM */ -public class SequestPipelineProvider extends AbstractMS2SearchPipelineProvider +public class SequestPipelineProvider extends AbstractMS2SearchPipelineProvider { private static final String ACTION_LABEL = "Sequest Peptide Search"; @@ -54,7 +54,7 @@ public class SequestPipelineProvider extends AbstractMS2SearchPipelineProvider UW_SEQUEST_ENZYME_MAP; - - static - { - Map m = new CaseInsensitiveHashMap<>(); - - m.put("[X]|[X]", 0); // None - m.put("[KR]|{P}", 1); // Trypsin - m.put("[FMWY]|{P}", 2); // Chymotrypsin - m.put("[R]|[X]", 3); // Clostripain - m.put("[M]|{P}", 4); // Cyanogen_Bromide - m.put("[W]|[X]", 5); // IodosoBenzoate - m.put("[P]|[X]", 6); // Proline_Endopept - m.put("[E]|[X]", 7); // Staph_Protease - m.put("[K]|{P}", 8); // Trypsin_K - m.put("[R]|{P}", 8); // Trypsin_R - m.put("[X]|[D]", 10); // AspN -// "11. Cymotryp/Modified 1 FWYL P\n" + - m.put("[AGILV]|{P}", 12); -// "13. Elastase/Tryp/Chymo 1 ALIVKRWFY P\n"; - - UW_SEQUEST_ENZYME_MAP = Collections.unmodifiableMap(m); - } - - public UWSequestParamsBuilder(Map sequestInputParams, File sequenceRoot) - { - super(sequestInputParams, sequenceRoot, SequestParams.Variant.uwsequest, null); - } - - public UWSequestParamsBuilder(Map sequestInputParams, File sequenceRoot, SequestParams.Variant variant, List databaseFiles) - { - super(sequestInputParams, sequenceRoot, variant, databaseFiles); - } - - protected void initSubclass() - { - _params.initUWSequestAndCometProperties(); - - _params.addProperty(new SequestParam( - 71, //sortOrder - "0.11", //The value of the property - "fragment_bin_startoffset", // the sequest.params property name - "offset position to start the binning",// the sequest.params comment - ConverterFactory.getSequestBasicConverter(), //converts the instance to a sequest.params line - ParamsValidatorFactory.getRealNumberParamsValidator(), - true - )).setInputXmlLabels("spectrum, fragment_bin_startoffset"); - - _params.addProperty(new SequestParam( - 208, //sortOrder - "5", //The value of the property - "minimum_peaks", // the sequest.params property name - "minimum num. of peaks in spectrum to search (default 5)", // the input.xml label - ConverterFactory.getSequestBasicConverter(), //converts the instance to a sequest.params line - new NaturalNumberParamsValidator(), - true - )).setInputXmlLabels("sequest, minimum_peaks"); - - _params.addProperty(new SequestParam( - 131, //sortOrder - "1", //The value of the property - "enzyme_number", // the sequest.params property name - "", // the input.xml label - ConverterFactory.getSequestBasicConverter(), //converts the instance to a sequest.params line - null, - false - )).setInputXmlLabels(ParameterNames.ENZYME); - - _params.addProperty(new SequestParam( - 151, //sortOrder - "0 0 0 0 0 0", //The value of the property - "diff_search_type", // the sequest.params property name - "0=variable mod, 1=binary mod", // the sequest.params comment - ConverterFactory.getSequestBasicConverter(), //converts the instance to a sequest.params line - new MultipleIntegerParamsValidator(0, 1, 6), - true - )).setInputXmlLabels("sequest, diff_search_type"); - - _params.addProperty(new SequestParam( - 152, //sortOrder - "4 4 4 4 4 4", //The value of the property - "diff_search_count", // the sequest.params property name - "max num of modified AA per each variable mod in a peptide", // the sequest.params comment - ConverterFactory.getSequestBasicConverter(), //converts the instance to a sequest.params line - new MultipleIntegerParamsValidator(0, 50, 6), - true - )).setInputXmlLabels("sequest, diff_search_count"); - - _params.addProperty(new SequestParam( - 252, //sortOrder - "2", //The value of the property - "num_enzyme_termini", // the sequest.params property name - "Generate peptides with enzyme digestion sites at one or both termini. Default 2.", // the sequest.params comment - ConverterFactory.getSequestBasicConverter(), //converts the instance to a sequest.params line - new NonNegativeIntegerParamsValidator(), - true - )).setInputXmlLabels("sequest, num_enzyme_termini" ); - - _params.addProperty(new SequestParam( - 253, //sortOrder - "0", //The value of the property - "isotope_error", // the sequest.params property name - "0=off, 1= on -1/0/1/2/3 (standard C13 error), 2= -8/-4/0/4/8 (for +4/+8 labeling)", // the sequest.params comment - ConverterFactory.getSequestBasicConverter(), //converts the instance to a sequest.params line - new ListParamsValidator("0", "1", "2"), - true - )).setInputXmlLabels("sequest, isotope_error" ); - - _params.addProperty(new SequestParam( - 571, //sortOrder - "0.0", //The value of the property - "add_U_user_amino_acid", // the sequest.params property name - "added to U - avg. 0.0000, mono. 0.00000", // the sequest.params comment - ConverterFactory.getSequestBasicConverter(), //converts the instance to a sequest.params line - new RealNumberParamsValidator(), - true - )).setInputXmlLabels().setInputXmlLabels("sequest, add_U_user_amino_acid"); - - _params.addProperty(new SequestParam( - 572, //sortOrder - "0.0", //The value of the property - "add_J_user_amino_acid", // the sequest.params property name - "added to J - avg. 0.0000, mono. 0.00000", // the sequest.params comment - ConverterFactory.getSequestBasicConverter(), //converts the instance to a sequest.params line - new RealNumberParamsValidator(), - true - )).setInputXmlLabels().setInputXmlLabels("sequest, add_J_user_amino_acid"); - - - _params.addProperty(new SequestParam( - 258, //sortOrder - "0", //The value of the property - "output_format", // the sequest.params property name - "0=sqt stdout (default), 1=out files", // the sequest.params comment - ConverterFactory.getSequestBasicConverter(), //converts the instance to a sequest.params line - new BooleanParamsValidator(), - false - )); - - _params.addProperty(new SequestParam( - 259, //sortOrder - "0", //The value of the property - "max_fragment_charge", // the sequest.params property name - "Set the maximum charge state of fragment ions automatically (based on the precursor charge) or set the maximum to the given charge. Default 0 (automatic).", // the sequest.params comment - ConverterFactory.getSequestBasicConverter(), //converts the instance to a sequest.params line - new NonNegativeIntegerParamsValidator(), - true - )).setInputXmlLabels("sequest, max_fragment_charge" ); - - _params.addProperty(new SequestParam( - 261, //sortOrder - "5", //The value of the property - "max_precursor_charge", // the sequest.params property name - "Analyze spectra with charge no higher than that given. Default 5.", // the sequest.params comment - ConverterFactory.getSequestBasicConverter(), //converts the instance to a sequest.params line - new NaturalNumberParamsValidator(), - true - )).setInputXmlLabels("sequest, max_precursor_charge" ); - } - - @Override - protected List initDynamicTermMods(char term, String massString) - { - if (term != '[' && term != ']') - { - return Collections.singletonList("Invalid terminal modification: " + term); - } - - try - { - double mass = Double.parseDouble(massString); - Param termProp = _params.getParam(term == '[' ? "variable_N_terminus" : "variable_C_terminus"); - termProp.setValue(massString); - } - catch (NumberFormatException e) - { - return Collections.singletonList("Could not parse variable terminal modification: " + massString); - } - return Collections.emptyList(); - } - - @Override - protected String getSupportedEnzyme(String enzyme) throws SequestParamsException - { - enzyme = removeWhiteSpace(enzyme); - if (enzyme == null || enzyme.isEmpty()) - { - throw new SequestParamsException("No enzyme specified"); - } - - enzyme = removeWhiteSpace(enzyme); - enzyme = combineEnzymes(enzyme.split(",")); - for(Map.Entry entry : UW_SEQUEST_ENZYME_MAP.entrySet()) - { - if(sameEnzyme(enzyme, entry.getKey())) - { - _params.getParam("enzyme_number").setValue(entry.getValue().toString()); - return entry.getValue().toString(); - } - } - throw new SequestParamsException("Unsupported enzyme: " + enzyme); - } - - - - @Override - public String getSequestParamsText() throws SequestParamsException - { - String result = super.getSequestParamsText(); - - return result + - "\n" + - "[SEQUEST_ENZYME_INFO]\n" + - "0. No_Enzyme 0 - -\n" + - "1. Trypsin 1 KR P\n" + - "2. Chymotrypsin 1 FWY P\n" + - "3. Clostripain 1 R -\n" + - "4. Cyanogen_Bromide 1 M -\n" + - "5. IodosoBenzoate 1 W -\n" + - "6. Proline_Endopept 1 P -\n" + - "7. Staph_Protease 1 E -\n" + - "8. Trypsin_K 1 K P\n" + - "9. Trypsin_R 1 R P\n" + - "10. AspN 0 D -\n" + - "11. Cymotryp/Modified 1 FWYL P\n" + - "12. Elastase 1 ALIV P\n" + - "13. Elastase/Tryp/Chymo 1 ALIVKRWFY P\n"; - } - - public static class TestCase extends Assert - { - private final File _root = new File("fakeroot"); - - public void fail(List messages) - { - fail(StringUtils.join(messages, '\n')); - } - - @Test - public void testEnzyme() - { - UWSequestParamsBuilder spb = new UWSequestParamsBuilder(Collections.singletonMap("protein, cleavage site", "[X]|[X]"), _root); - List parserError = spb.initEnzymeInfo(); - if (!parserError.isEmpty()) fail(parserError); - assertEquals("enzyme_number", "0", spb.getProperties().getParam("enzyme_number").getValue()); - - // Bad enzyme - spb = new UWSequestParamsBuilder(Collections.singletonMap("protein, cleavage site", "[AA]|[B]"), _root); - parserError = spb.initEnzymeInfo(); - assertEquals("Should have one error", 1, parserError.size()); - - // Typsin - spb = new UWSequestParamsBuilder(Collections.singletonMap("protein, cleavage site", "[KR]|{P}"), _root); - parserError = spb.initEnzymeInfo(); - if (!parserError.isEmpty()) fail(parserError); - assertEquals("enzyme_number", "1", spb.getProperties().getParam("enzyme_number").getValue()); - - // AspN - spb = new UWSequestParamsBuilder(Collections.singletonMap("protein, cleavage site", "[X]|[D]"), _root); - parserError = spb.initEnzymeInfo(); - if (!parserError.isEmpty()) fail(parserError); - assertEquals("enzyme_number", "10", spb.getProperties().getParam("enzyme_number").getValue()); - } - - @Test - public void testUWSpecificParams() - { - Map params = new HashMap<>(); - params.put("pipeline, database", "Bovine_mini.fasta"); - params.put("sequest, max_precursor_charge", "4"); - UWSequestParamsBuilder spb = new UWSequestParamsBuilder(params, _root); - spb.initPassThroughs(); - assertEquals("max_precursor_charge", "4", spb.getPropertyValue("max_precursor_charge")); - } - - @Test - public void testVariableTermModification() - { - UWSequestParamsBuilder spb = new UWSequestParamsBuilder(Collections.singletonMap("residue, potential modification mass", "50.43@[,90.12@]"), _root); - spb.initDynamicMods(); - assertEquals("variable_N_terminus", "50.43", spb.getPropertyValue("variable_N_terminus")); - assertEquals("variable_C_terminus", "90.12", spb.getPropertyValue("variable_C_terminus")); - } - - @Test - public void testStaticTermModification() - { - UWSequestParamsBuilder spb = new UWSequestParamsBuilder(Collections.singletonMap(ParameterNames.STATIC_MOD, "50.43@[,90.12@]"), _root); - spb.initStaticMods(); - assertEquals("add_Nterm_peptide", "50.43", spb.getPropertyValue("add_Nterm_peptide")); - assertEquals("add_Cterm_peptide", "90.12", spb.getPropertyValue("add_Cterm_peptide")); - } - - @Test - public void testGenerateFile() throws SequestParamsException - { - Map paramMap = new HashMap<>(); - - paramMap.put(ParameterNames.STATIC_MOD, "50.43@[,90.12@]"); - paramMap.put(ParameterNames.SEQUENCE_DB, DUMMY_FASTA_NAME); - paramMap.put("sequest, digest_mass_range", "400.0 5900.0"); - paramMap.put("spectrum, parent monoisotopic mass error units", "mmu"); - UWSequestParamsBuilder spb = new UWSequestParamsBuilder(paramMap, _root); - spb.initXmlValues(); - String text = spb.getSequestParamsText(); - assertTrue(text.contains("database_name =")); - assertTrue(text.contains("num_threads = 0")); - assertTrue(text.contains("digest_mass_range = 400.0 5900.0")); - assertTrue(text.contains("peptide_mass_units = 1")); - } - - @Test - public void testAlternateXmlInputs() - { - Map paramMap = new HashMap<>(); - paramMap.put(ParameterNames.SEQUENCE_DB, DUMMY_FASTA_NAME); - paramMap.put("spectrum, fragment mass error", "500.0"); - UWSequestParamsBuilder spb = new UWSequestParamsBuilder(paramMap, _root); - spb.initPassThroughs(); - assertEquals("fragment_ion_tolerance", "500.0", spb.getPropertyValue("fragment_ion_tolerance")); - - paramMap = new HashMap<>(); - paramMap.put(ParameterNames.SEQUENCE_DB, DUMMY_FASTA_NAME); - paramMap.put("sequest, fragment_ion_tolerance", "500.0"); - spb = new UWSequestParamsBuilder(paramMap, _root); - spb.initPassThroughs(); - assertEquals("fragment_ion_tolerance", "500.0", spb.getPropertyValue("fragment_ion_tolerance")); - } - } -} diff --git a/ms2/src/org/labkey/ms2/pipeline/sequest/UWSequestSearchTask.java b/ms2/src/org/labkey/ms2/pipeline/sequest/UWSequestSearchTask.java deleted file mode 100644 index b42ddb570a..0000000000 --- a/ms2/src/org/labkey/ms2/pipeline/sequest/UWSequestSearchTask.java +++ /dev/null @@ -1,928 +0,0 @@ -/* - * Copyright (c) 2007-2016 LabKey Corporation - * - * 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.labkey.ms2.pipeline.sequest; - -import org.apache.commons.lang3.StringUtils; -import org.apache.log4j.Logger; -import org.jetbrains.annotations.NotNull; -import org.jmock.Mockery; -import org.jmock.lib.legacy.ClassImposteriser; -import org.junit.Assert; -import org.junit.Test; -import org.labkey.api.pipeline.PipelineJob; -import org.labkey.api.pipeline.PipelineJobException; -import org.labkey.api.pipeline.PipelineJobService; -import org.labkey.api.pipeline.RecordedAction; -import org.labkey.api.pipeline.RecordedActionSet; -import org.labkey.api.pipeline.ToolExecutionException; -import org.labkey.api.pipeline.WorkDirectory; -import org.labkey.api.pipeline.cmd.TaskPath; -import org.labkey.api.reader.Readers; -import org.labkey.api.util.DateUtil; -import org.labkey.api.util.FileType; -import org.labkey.api.util.FileUtil; -import org.labkey.api.util.Pair; -import org.labkey.api.util.StringUtilsLabKey; -import org.labkey.api.writer.PrintWriters; -import org.labkey.ms2.pipeline.AbstractMS2SearchTask; -import org.labkey.ms2.pipeline.FastaCheckTask; -import org.labkey.ms2.pipeline.client.ParameterNames; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.Reader; -import java.io.StringReader; -import java.io.Writer; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import java.util.zip.CRC32; - -/** - * SequestSearchTask - */ -public class UWSequestSearchTask extends AbstractMS2SearchTask -{ - private static final String SEQUEST_PARAMS = "sequest.params"; - private static final String MAKE_DB_PARAMS = "makedb.params"; - - private static final String SEQUEST_ACTION_NAME = "Sequest Search"; - private static final String SEQUEST_DECOY_ACTION_NAME = "Sequest Decoy Search"; - private static final String MAKEDB_ACTION_NAME = "MakeDB"; - public static final String FASTA_DECOY_INPUT_ROLE = "DecoyFASTA"; - - public static final String MASS_TYPE_PARENT = "sequest, mass_type_parent"; - - public static final String USE_INDEX_PARAMETER_NAME = "pipeline, use index"; - public static final String INDEX_FILE_NAME_PARAMETER_NAME = "pipeline, index file name"; - - public static final FileType INDEX_FILE_TYPE = new FileType(".hdr"); - public static final FileType SEQUEST_OUTPUT_FILE_TYPE = new FileType(".sqt"); - public static final FileType SEQUEST_DECOY_OUTPUT_FILE_TYPE = new FileType(".decoy.sqt"); - - private static final Object INDEX_LOCK = new Object(); - - public static class Factory extends AbstractSequestSearchTaskFactory - { - public Factory() - { - super(UWSequestSearchTask.class); - } - - public PipelineJob.Task createTask(PipelineJob job) - { - return new UWSequestSearchTask(this, job); - } - - public List getProtocolActionNames() - { - return Arrays.asList(MAKEDB_ACTION_NAME, SEQUEST_ACTION_NAME, SEQUEST_DECOY_ACTION_NAME); - } - } - - protected UWSequestSearchTask(Factory factory, PipelineJob job) - { - super(factory, job); - } - - public SequestPipelineJob getJob() - { - return (SequestPipelineJob)super.getJob(); - } - - private File getIndexFileWithoutExtension() throws PipelineJobException - { - File fastaFile = getJob().getSequenceFiles()[0]; - File fastaRoot = getJob().getSequenceRootDirectory(); - - Map params = getJob().getParameters(); - String indexFileName = params.get(INDEX_FILE_NAME_PARAMETER_NAME); - if (indexFileName == null) - { - // Build one based on a CRC of the parameters that define an index file - StringBuilder sb = new StringBuilder(); - sb.append("Enzyme-"); - sb.append(params.get(ParameterNames.ENZYME)); - sb.append(".MinParentMH-"); - sb.append(params.get(AbstractMS2SearchTask.MINIMUM_PARENT_M_H)); - sb.append(".MaxParentMH-"); - sb.append(params.get(AbstractMS2SearchTask.MAXIMUM_PARENT_M_H)); - sb.append(".MaxMissedCleavages-"); - sb.append(params.get(AbstractMS2SearchTask.MAXIMUM_MISSED_CLEAVAGE_SITES)); - sb.append(".MassTypeParent-"); - sb.append(params.get(UWSequestSearchTask.MASS_TYPE_PARENT)); - sb.append(".StaticMod-"); - sb.append(params.get(ParameterNames.STATIC_MOD)); - - CRC32 crc = new CRC32(); - crc.update(toBytes(sb.toString())); - - indexFileName = fastaFile.getName() + "_" + crc.getValue(); - } - - String relativeDirPath = FileUtil.relativePath(fastaFile.getParentFile().getPath(), fastaRoot.getPath()); - File indexDir; - if (_factory.getIndexRootDir() == null) - { - indexDir = new File(new File(fastaRoot, relativeDirPath), "index"); - } - else - { - indexDir = new File(new File(_factory.getIndexRootDir()), relativeDirPath); - } - indexDir.mkdirs(); - if (!indexDir.isDirectory()) - { - throw new PipelineJobException("Failed to create index directory " + indexDir); - } - - return new File(indexDir, indexFileName); - } - - private static byte[] toBytes(String s) - { - return s == null ? new byte[] { 0 } : s.getBytes(StringUtilsLabKey.DEFAULT_CHARSET); - } - - private boolean usesIndex() - { - Map params = getJob().getParameters(); - String indexUsage = params.get(USE_INDEX_PARAMETER_NAME); - return "true".equalsIgnoreCase(indexUsage) || "1".equalsIgnoreCase(indexUsage) || "yes".equalsIgnoreCase(indexUsage); - } - - private List getFASTAOrIndexFiles(List actions) throws PipelineJobException - { - if (!usesIndex()) - { - return Arrays.asList(getJob().getSequenceFiles()); - } - - File indexFileBase = getIndexFileWithoutExtension(); - File indexFile = new File(indexFileBase.getParentFile(), indexFileBase.getName() + INDEX_FILE_TYPE.getDefaultSuffix()); - - synchronized (INDEX_LOCK) - { - if (!indexFile.exists()) - { - assert getJob().getSequenceFiles().length == 1 : "Only one FASTA is supported when using indices"; - - getJob().setStatus("CREATING FASTA INDEX"); - getJob().info("Creating a FASTA index for " + getJob().getSequenceFiles()[0] + " as " + indexFileBase); - - // Create a makedb.params to control the index creation - File fileWorkParams = _wd.newFile(MAKE_DB_PARAMS); - UWSequestParamsBuilder builder = new UWSequestParamsBuilder(getJob().getParameters(), getJob().getSequenceRootDirectory(), SequestParams.Variant.makedb, null); - builder.initXmlValues(); - builder.writeFile(fileWorkParams); - - // Invoke makedb - List args = new ArrayList<>(); - File makeDBExecutable = new File(_factory.getSequestInstallDir(), "makedb"); - args.add(makeDBExecutable.getAbsolutePath()); - args.add("-O" + indexFileBase); - args.add("-P" + fileWorkParams.getAbsolutePath()); - ProcessBuilder pb = new ProcessBuilder(args); - - // In order to find sort.exe, use the Sequest directory as the working directory - File dir = makeDBExecutable.getParentFile(); - getJob().runSubProcess(pb, dir); - - RecordedAction action = new RecordedAction(MAKEDB_ACTION_NAME); - action.addInput(getJob().getSequenceFiles()[0], "FASTA"); - action.addInput(fileWorkParams, "MakeDB Params"); - action.addOutput(indexFile, "FASTA Index", false); - action.addParameter(RecordedAction.COMMAND_LINE_PARAM, StringUtils.join(args, " ")); - - actions.add(action); - - try - { - _wd.outputFile(fileWorkParams); - } - catch (IOException e) - { - throw new PipelineJobException(e); - } - - // Set the status back to the search - getJob().setStatus("SEARCH RUNNING"); - } - } - - return Collections.singletonList(indexFile); - } - - @NotNull - public RecordedActionSet run() throws PipelineJobException - { - try - { - List actions = new ArrayList<>(); - // Copy so that we can add our own values - Map params = new HashMap<>(getJob().getParameters()); - params.put("list path, sequest parameters", SEQUEST_PARAMS); - params.put("search, useremail", params.get(PipelineJob.PIPELINE_EMAIL_ADDRESS_PARAM)); - params.put("search, username", "CPAS User"); - - List sequenceFiles = getFASTAOrIndexFiles(actions); - - File fileMzXML = _factory.findInputFile(getJob()); - File fileMzXMLWork = _wd.inputFile(fileMzXML, true); - - // Write out sequest.params file - File fileWorkParams = _wd.newFile(SEQUEST_PARAMS); - - List decoySequenceFiles = FastaCheckTask.getDecoySequenceFiles(getJob()); - - File sequestLogFileWork = SEQUEST_OUTPUT_FILE_TYPE.getFile(_wd.getDir(), getJob().getBaseName()); - - _wd.newFile(sequestLogFileWork.getName()); - - List sequestArgs = performSearch(_wd.getDir(), params, sequenceFiles, fileMzXMLWork, fileWorkParams, sequestLogFileWork); - File decoyResults = null; - if (!decoySequenceFiles.isEmpty()) - { - File decoyDir = new File(_wd.getDir(), "decoy"); - decoyDir.mkdir(); - getJob().getLogger().info("Performing a decoy search with " + decoySequenceFiles); - File fileWorkDecoyParams = new File(decoyDir, "sequest.params"); - File decoySubResults = SEQUEST_OUTPUT_FILE_TYPE.getFile(decoyDir, getJob().getBaseName()); - performSearch(decoyDir, params, decoySequenceFiles, fileMzXMLWork, fileWorkDecoyParams, decoySubResults); - - decoyResults = SEQUEST_DECOY_OUTPUT_FILE_TYPE.getFile(_wd.getDir(), getJob().getBaseName()); - getJob().getLogger().info("Copying decoy results from " + decoySubResults + " to " + decoyResults + ", file is " + decoySubResults.length()); - FileUtil.copyFile(decoySubResults, decoyResults); - FileUtil.deleteDir(decoyDir); - } - - try (WorkDirectory.CopyingResource ignored = _wd.ensureCopyingLock()) - { - RecordedAction sequestAction = new RecordedAction(SEQUEST_ACTION_NAME); - sequestAction.addParameter(RecordedAction.COMMAND_LINE_PARAM, StringUtils.join(sequestArgs, " ")); - sequestAction.addOutput(_wd.outputFile(fileWorkParams), "SequestParams", true); - sequestAction.addOutput(_wd.outputFile(sequestLogFileWork), "SequestResults", false); - for (File file : sequenceFiles) - { - sequestAction.addInput(file, FASTA_INPUT_ROLE); - } - for (File file : decoySequenceFiles) - { - sequestAction.addInput(file, FASTA_DECOY_INPUT_ROLE); - } - if (decoyResults != null) - { - sequestAction.addOutput(_wd.outputFile(decoyResults), "SequestDecoyResults", false); - } - sequestAction.addInput(fileMzXML, SPECTRA_INPUT_ROLE); - _wd.discardFile(fileMzXMLWork); - _wd.acceptFilesAsOutputs(Collections.emptyMap(), sequestAction); - - actions.add(sequestAction); - } - - return new RecordedActionSet(actions); - } - catch(IOException e) - { - throw new PipelineJobException(e); - } - } - - private static final Pattern SEQUEST_VERSION = Pattern.compile(".*(\\d\\d\\d\\d\\.\\d+\\.\\d+).*"); - - private List performSearch(File workingDir, Map params, List sequenceFiles, File fileMzXMLWork, File paramsFile, File resultsFile) - throws IOException, PipelineJobException - { - UWSequestParamsBuilder builder = new UWSequestParamsBuilder(params, getJob().getSequenceRootDirectory(), SequestParams.Variant.uwsequest, sequenceFiles); - builder.initXmlValues(); - builder.writeFile(paramsFile); - - String version = getJob().getParameters().get("sequest, version"); - String sequestPath = PipelineJobService.get().getExecutablePath("sequest." + PipelineJobService.VERSION_SUBSTITUTION, _factory.getSequestInstallDir(), null, version, getJob().getLogger()); - if (sequestPath.endsWith("/sequest")) - { - // Sequest versions have the binaries themselves being renamed, not the parent directories, - // so hack off the trailing "/sequest" on the path - sequestPath = sequestPath.substring(0, sequestPath.length() - "/sequest".length()); - } - String sequestVersion = determineSequestVersion(sequestPath, workingDir); - if (sequestVersion != null) - { - getJob().info("Running Sequest " + sequestVersion); - } - - // Perform Sequest search - List sequestArgs = new ArrayList<>(); - sequestArgs.add(sequestPath); - sequestArgs.addAll(_factory.getSequestOptions()); - sequestArgs.add(FileUtil.relativize(workingDir, fileMzXMLWork, false)); - ProcessBuilder sequestPB = new ProcessBuilder(sequestArgs); - try (Writer writer = PrintWriters.getPrintWriter(resultsFile)) - { - writeParams(writer, paramsFile, getJob().getLogger(), getJob().getSequenceFiles()[0], sequestVersion); - } - getJob().runSubProcess(sequestPB, workingDir, resultsFile, 10, true); - return sequestArgs; - } - - private String determineSequestVersion(String sequestPath, File workingDir) throws PipelineJobException, IOException - { - File versionFile = new File(workingDir, "sequest.version"); - ProcessBuilder versionPB = new ProcessBuilder(sequestPath); - try - { - getJob().runSubProcess(versionPB, workingDir, versionFile, 0, false); - } - catch (ToolExecutionException ignored) - { - // Sequest returns a non-zero exit code when invoked without arguments - } - - if (versionFile.exists()) - { - try (FileInputStream headerIn = new FileInputStream(versionFile)) - { - return parseSequestVersion(Readers.getReader(headerIn)); - } - finally - { - versionFile.delete(); - } - } - return null; - } - - private String parseSequestVersion(Reader innerReader) throws IOException - { - BufferedReader reader = new BufferedReader(innerReader); - String line; - while ((line = reader.readLine()) != null) - { - Matcher matcher = SEQUEST_VERSION.matcher(line); - if (matcher.matches()) - { - return matcher.group(1).replace(".", ""); - } - } - - return null; - } - - private static final String version = "H\tSQTGenerator SEQUEST\nH\tSQTGeneratorVersion\t2.7\n"; - private static final String version2 = "H\tComment\tSEQUEST was written by J Eng and JR Yates, III\n"; - private static final String version3 = "H\tComment\tSEQUEST ref. J. Am. Soc. Mass Spectrom., 1994, v. 4, p. 976\n"; - private static final String version4 = "H\tComment\tSEQUEST is licensed to Finnigan Corp.\n"; - private static final String version5 = "H\tComment\tInvoked through LabKey Server Pipeline\n"; - private static final String version6 = "H\tComment\tHeader output code adapted from run_ms2, written by Rovshan Sadygov\n"; - private static final String credit = " Molecular Biotechnology, Univ. of Washington, J.Eng/J.Yates"; - private static final String license = " Licensed to Finnigan Corp., A Division of ThermoQuest Corp."; - - - private static void writeParams(Writer writer, File paramsFile, Logger logger, File fastaFile, String sequestVersion) throws IOException - { - int ixcorr = 0; - float[] aa_mass = new float[256]; - String line, szDbase = "", szDate; -// String szTemp1, szTemp2, szIonSeries; - String szIonSeries = ""; -// String szTemp3, szDisplay; - String szDisplay = ""; -// String szTemp4, szTemp6; - List> diffMods = new ArrayList<>(); - String diffModCharacters = "*#@^~$"; - float mdif1, mdif2, mdif3, mstat, ion_cutoff; - String szDiff1, szDiff2, szDiff3, sDif1; - String sDif2, sDif3; - String szStatMode = "", szMass_Accuracy = ""; - String szMass_AccPrecursor = "", szMass_AccFr = ""; - String szEnzymeSpec = ""; - String PIsotope = "", FIsotope = "", szIons = "", szMaxDiffMod = ""; - String szOutPutLines = ""; - long N_AA, N_dup, N_rm_pr, N_rd_fr; - long N_prot, flag_stat, flag_diff, N_a, N_b, N_y; - long N_enz, N_diff_mod; - N_prot = N_AA = flag_stat = flag_diff = N_dup = N_rm_pr = 0; - mdif1 = mdif2 = mdif3 = mstat = ion_cutoff = 0.0f; - N_rd_fr = N_a = N_b = N_y = N_enz = N_diff_mod = 0; - - try (BufferedReader reader = Readers.getReader(paramsFile)) - { - while ((line = reader.readLine()) != null) - { - line = line.trim(); - if (line.startsWith("database_name")) - szDbase = getSingleValue(line); - else if (line.startsWith("peptide_mass_tolerance")) - { - String szTemp3 = getSingleValue(line); - szMass_Accuracy = String.format(" ~ %s, ", szTemp3); - szMass_AccPrecursor = szTemp3; - } - else if (line.startsWith("xcorr_mode")) - { - String szTemp3 = getSingleValue(line); - ixcorr = Integer.parseInt(szTemp3); - } - else if (line.startsWith("ion_series")) - { - String[] values = line.split("\\s"); - if (values.length < 6) - { - logger.error("Error: ion_series"); - } - else - { - try - { - N_a = Integer.parseInt(values[2]); - N_b = Integer.parseInt(values[3]); - N_y = Integer.parseInt(values[4]); - - if (N_a == 0) - szIonSeries = "IonSeries nA"; - else if (N_a == 1) - szIonSeries = "IonSeries A"; - - if (N_b == 0) - szIonSeries += "nB"; - if (N_b == 1) - szIonSeries += "B"; - if (N_y == 0) - szIonSeries += "nY"; - if (N_y == 1) - szIonSeries += "Y"; - szIonSeries += line.charAt(13); - szIons = line.substring(13); - } - catch (NumberFormatException e) - { - logger.error("Error: ion_series"); - } - } - - } - /*else if(strstr(line, "fragment_ion_tolerance") != null && - line[0] == 'f') { */ - else if (line.startsWith("fragment_ion_tolerance")) - { - String szTemp3 = getSingleValue(line); - szMass_Accuracy += String.format("fragment tol = %s, ", szTemp3); - szMass_AccFr = szTemp3; - } - else if (line.startsWith("num_output_lines")) - { - String szTemp3 = getSingleValue(line); - szDisplay = String.format(" display top %s", szTemp3); - szOutPutLines = szTemp3; - } - else if (line.startsWith("num_description_lines")) - { - String szTemp3 = getSingleValue(line); - szDisplay += String.format("/%s,", szTemp3); - } - else if (line.startsWith("print_duplicate_references")) - { - try - { - N_dup = Integer.parseInt(getSingleValue(line)); - } - catch (NumberFormatException e) - { - logger.error("Error: print_duplicate_references"); - } - } - else if (line.startsWith("enzyme_number")) - { - try - { - N_enz = Integer.parseInt(getSingleValue(line)); - } - catch (NumberFormatException e) - { - logger.error("Error: enzyme_number"); - } - } - /* - else if(strstr(line, "diff_search_options") != null) { - if(8 != sscanf(line, "%s%s%s%s%s%s%s%s", szTemp1,szTemp2,szTemp3, - szTemp4,szTemp5,szTemp6,szTemp7,szTemp8)) - printf("Did not read the diffmod line correctly\n"); - if(1 == COPY_DIFFMODE(szTemp3, &mdif1,szSign1)) { - flag_diff = 1; - sprintf(szDiff1, szTemp4); - } - if(1 == COPY_DIFFMODE(szTemp5, &mdif2,szSign2)) { - flag_diff = 1; - sprintf(szDiff2, szTemp6); - } - if(1 == COPY_DIFFMODE(szTemp7, &mdif3,szSign3)) { - flag_diff = 1; - sprintf(szDiff3, szTemp8); - } - } - */ - /*JDE 9/16/2011 changing this to read an arbitrary number of diff mods*/ - else if (line.startsWith("diff_search_options")) - { - processDiffLine(line, diffModCharacters, diffMods, logger); - } - else if (line.startsWith("max_num_differential_AA_per_mod")) - { - try - { - N_diff_mod = Integer.parseInt(getSingleValue(line)); - } - catch (NumberFormatException e) - { - logger.error("Problem: max_num_differential_AA_per_mod"); - } - szMaxDiffMod = String.format("%d", N_diff_mod); - } - else if (line.startsWith("diff_search_count")) - { - - String[] ss = getValues(line); - List diffSearchCounts = new ArrayList<>(); - szMaxDiffMod = ""; - for (String s : ss) - { - if (s.isEmpty() || !Character.isDigit(s.charAt(0))) - { - break; - } - diffSearchCounts.add(s); - } - for (int index = 0; index < diffSearchCounts.size() - 1; ++index) - { - szMaxDiffMod += diffSearchCounts.get(index); - szMaxDiffMod += ","; - } - szMaxDiffMod += diffSearchCounts.get(diffSearchCounts.size() - 1); - } - else if (line.startsWith("nucleotide_reading_frame")) - { - try - { - N_rd_fr = Integer.parseInt(getSingleValue(line)); - } - catch (NumberFormatException e) - { - logger.error("Problem: nucleotide_reading_frame\n"); - } - } - else if (line.startsWith("mass_type_parent")) - { - String szTemp3 = getSingleValue(line); - if ("0".equals(szTemp3)) - { - szMass_Accuracy += "AVG/"; - PIsotope = "AVG"; - } - else if ("1".equals(szTemp3)) - { - szMass_Accuracy += "MONO/"; - PIsotope = "MONO"; - } - else - { - logger.warn("Did not recognize parent mass type\n"); - } - } - else if (line.startsWith("remove_precursor_peak")) - { - try - { - N_rm_pr = Integer.parseInt(getSingleValue(line)); - } - catch (NumberFormatException e) - { - logger.error("Error: remove_precursor_peak\n"); - } - } - else if (line.startsWith("mass_type_fragment")) - { - String szTemp3 = getSingleValue(line); - if ("0".equals(szTemp3)) - { - szMass_Accuracy += "AVG\n"; - FIsotope = "AVG"; - } - else if ("1".equals(szTemp3)) - { - szMass_Accuracy += "MONO\n"; - FIsotope = "MONO"; - } - else - { - logger.error("Did not recognize fragment mass type\n"); - } - } - else if (line.startsWith("ion_cutoff_percentage")) - { - try - { - ion_cutoff = Float.parseFloat(getSingleValue(line)); - } - catch (NumberFormatException e) - { - logger.error("Error: ion_cutoff_percentage"); - } - ion_cutoff = 100.0f * ion_cutoff; - szDisplay += String.format(" ion %% = %.1f, CODE = %d%d%d0", ion_cutoff, N_dup, N_rm_pr, N_rd_fr); - } - else if (line.startsWith("add_")) - { - /* looks like on each ornithine, we get the line cut off at 116.\0 followed immediately by - the Alg-Display line*/ - try - { - mstat = Float.parseFloat(getSingleValue(line)); - } - catch (NumberFormatException e) - { - logger.warn("Did not read all of the StatMode line\n"); - } - if (0.0 != mstat) - { - flag_stat = 1; - szStatMode += String.format("H\tStaticMod\t%c=%.3f\n", line.charAt(4), mstat + aa_mass[line.charAt(4)]); - } - } - else if (line.startsWith("[SEQUEST_ENZYME_INFO]")) - { - //sprintf(szTemp1,"%d", N_enz); - while ((line = reader.readLine()) != null) - { - String[] values = line.split("\\s+"); - if (values.length < 4) - logger.error("Enzyme Reader only got " + values.length + " values instead of the expected 4"); - else - { - if (values[0].length() > 1) - { - values[0] = values[0].substring(0, 1); - } - if (N_enz == Integer.parseInt(values[0])) - { - szEnzymeSpec = values[1]; - break; - } - } - /* if(line.startsWith(szTemp1, strlen(szTemp1))) { */ - /* - if(strncmp(line, szTemp1, strlen(szTemp1)) == 0) { - if(3 != sscanf(line, "%s%s%s", szTemp2,szTemp3,szTemp4)) - logger.error("Error: Enzyme\n"); - sprintf(szEnzymeSpec, "Enzyme:%s (%d)", szTemp3, N_enz); - break; - } */ - } - } - } - //exit(0); - - try (BufferedReader fastaReader = Readers.getReader(fastaFile)) - { - while ((line = fastaReader.readLine()) != null) - { - if (line.startsWith(">")) - N_prot++; - else - N_AA += line.length() - 1; - } - } - - if (0 == ixcorr) - { - writer.write(String.format("%s%s", version, version2)); - if (sequestVersion != null) - { - writer.write("H\tSEQUESTVersion\t" + sequestVersion + "\n"); - } - writer.write(version3); - writer.write("H\tComment\tSEQUEST ref. Eng,J.K.; McCormack A.L.; Yates J.R.\n"); - writer.write(version4); - writer.write(String.format("%s%s", version5, version6)); - } - else if (1 == ixcorr) - { - writer.write("H\tSQTGenerator\tEE-normalized SEQUEST\n"); - writer.write(String.format("%s%s", version2, version3)); - writer.write("H\tComment\tSEQUEST ref. Eng,J.K.; McCormack A.L.; Yates J.R.\n"); - writer.write(version4); - writer.write("H\tComment\tNormalized SEQUEST ref. MacCoss,M.J.; Wu C.C; Yates J.R.\n"); - writer.write("H\tComment\tNormalized SEQUEST ref. Anal. Chem. 2002, v. 74, p. 5593\n"); - writer.write(String.format("%s%s", version5, version6)); - } - else if (2 == ixcorr) - { - writer.write("H\tSQTGenerator\tET-normalized SEQUEST\n"); - writer.write(version3); - writer.write("H\tComment\tSEQUEST ref. Eng,J.K.; McCormack A.L.; Yates J.R.\n"); - writer.write(version4); - writer.write("H\tComment\tNormalized SEQUEST ref. Sadygov R.G.; Yates J.R.\n"); - writer.write("H\tComment\tNormalized SEQUEST ref. to be published\n"); - writer.write(String.format("%s%s", version5, version6)); - } - - // TODO - use real times? - szDate = DateUtil.formatDateTime(new Date(), "M/d/y, H:mm a"); - writer.write(String.format("H\tStartTime %s\n", szDate)); - // strftime(szDate, 22, "%m/%d/%Y, %I:%M %p", localtime(&tEndTime)); - writer.write(String.format("H\tEndTime %s\n", szDate)); - writer.write(String.format("H\tDatabase\t%s\n", szDbase)); - writer.write(String.format("H\tDBSeqLength\t%d\n", N_AA)); - writer.write(String.format("H\tDBLocusCount\t%d\n", N_prot)); - writer.write(String.format("H\tPrecursorMasses\t%s\n", PIsotope)); - writer.write(String.format("H\tFragmentMasses\t%s\n", FIsotope)); - writer.write(String.format("H\tAlg-PreMassTol\t%s\n", szMass_AccPrecursor)); - writer.write(String.format("H\tAlg-FragMassTol\t%s\n", szMass_AccFr)); - writer.write(String.format("H\tAlg-XCorrMode\t%d\n", ixcorr)); - //writer.write(" # amino acids = %ld, # proteins = %d, %s\n%s%s%s\n", - // N_AA, N_prot, szDbase,szMass_Accuracy,szIonSeries, - // szDisplay); - line = " "; - if (diffMods.size() > 0) - { - line += String.format("max_diff_mod = %d\n ", N_diff_mod); - /* - if(0.0 != mdif1) { - sprintf(line+strlen(line),"(%s* %s%.3f) ",szDiff1, szSign1,mdif1); - sprintf(sDif1,"%s*=%s%.3f ",szDiff1, szSign1,mdif1); - } - if(0.0 != mdif2) { - sprintf(line+strlen(line),"(%s# %s%.3f) ",szDiff2, szSign2,mdif2); - sprintf(sDif2,"%s#=%s%.3f ",szDiff2, szSign2,mdif2); - } - if(0.0 != mdif3) { - sprintf(line+strlen(line),"(%s@ %s%.3f) ",szDiff3, szSign3,mdif3); - sprintf(sDif3,"%s@=%s%.3f ",szDiff3, szSign3,mdif3); - } - //writer.write("%s", line); - */ - } - if (szStatMode != null && szStatMode.length() > 0) - writer.write(szStatMode); - //writer.write("H\tStaticMod\t%s\n",szStatMode); - for (Pair p : diffMods) - { - writer.write(String.format("H\tDiffMod\t%s=%s\n", p.first, p.second)); - } - /* - if(0 != mdif1) - writer.write("H\tDiffMod\t%s\n",sDif1); - if(0 != mdif2) - writer.write("H\tDiffMod\t%s\n",sDif2); - if(0 != mdif3) - writer.write("H\tDiffMod\t%s\n",sDif3); - */ - if (diffMods.size() > 0) - { - writer.write(String.format("H\tAlg-MaxDiffMod\t%s\n", szMaxDiffMod)); - } - /* - if(0 != mdif1 || 0 != mdif2 || 0 != mdif3) - writer.write("H\tAlg-MaxDiffMod\t%s",szMaxDiffMod); - */ - - writer.write(String.format("H\tAlg-DisplayTop\t%s\n", szOutPutLines)); - writer.write(String.format("H\tAlg-IonSeries\t%s\n", szIons)); - writer.write(String.format("H\tEnzymeSpec\t%s\n", szEnzymeSpec)); - /* - if(flag_stat) - writer.write("%s %s\n", szStatMode,szEnzyme); - else if(!flag_stat && flag_diff) - writer.write(" %s\n", szEnzyme); - else if (!flag_stat && !flag_diff) - writer.write(" %s\n", szEnzyme); - */ - } - } - - private static String getSingleValue(String line) - { - return getValues(line)[0]; - } - - private static String[] getValues(String line) - { - if (!line.contains("=")) - { - throw new IllegalArgumentException("No '=' in line: " + line); - } - return line.substring(line.indexOf("=") + 1).trim().split("\\s"); - } - - private static void processDiffLine(String line, String diffModCharacters, List> diffMods, Logger logger) - { - //input is line, which is the diff_search_options line from a sequest parameters file - //the output is diffMods which is a vector with a pair of strings for each differential modification - //the first string is the aminio acid being modified, along with its symbolic representation the second is the mass of the differential mod - //which is guaranteed to either have a + or - sign in front of it - //read in the line using a string stream - diffMods.clear(); - String[] values = line.split("\\s"); - String aminoAcid; - String diffModMass; - int diffModCharIndex = -1; - char diffModChar; - // Start at 2 so we skip the parameter name and the = - for (int i = 2; i < values.length; i++) - { - diffModMass = values[i]; - diffModCharIndex += 1; - //read in and process the amino acid - if (i + 1 < values.length) - { - aminoAcid = values[++i]; - if (diffModCharIndex < diffModCharacters.length()) - { - diffModChar = diffModCharacters.charAt(diffModCharIndex); - aminoAcid += diffModChar; - } - else - { - logger.warn("More differential modifications were specified in the sequest.params file than this build"); - logger.warn("of run_ms_ssh was designed to handle (" + diffModCharacters.length() + ") please treat these results"); - logger.warn("with caution"); - } - } - else - { - //there is an amino acid but no corresponding differential modification mass - logger.error("Trouble reading the differential modification line in sequest.params!"); - logger.error("Could not find the amino acid for differential mod " + diffModMass); - break; - } - - //make sure the diff mod mass can be read as a float and is not equal to zero - try - { - float diffMass = Float.parseFloat(diffModMass); - if (diffMass != 0.0f) - { - //now we know that the diff mod mass is a valid float and is not zero - // prefix positive values with + - diffMods.add(new Pair<>(aminoAcid, (diffMass > 0 ? "+" : "") + Float.toString(diffMass))); - } - } - catch (NumberFormatException e) - { - logger.error("Trouble reading a differential mod mass for amino acid " + aminoAcid); - } - } - } - - public static class TestCase extends Assert - { - @Test - public void testParse() throws IOException - { - Mockery context = new Mockery(); - context.setImposteriser(ClassImposteriser.INSTANCE); - PipelineJob job = context.mock(PipelineJob.class); - Factory factory = context.mock(Factory.class); - UWSequestSearchTask task = new UWSequestSearchTask(factory, job); - assertEquals("2011011", task.parseSequestVersion(new StringReader("SEQUEST ver. UW 2011.01.1 MacCoss Lab, Genome Sciences"))); - - assertEquals("20120112", task.parseSequestVersion(new StringReader("SEQUEST ver. UW 2012.01.12 MacCoss Lab, Genome Sciences"))); - - assertEquals("2012012", task.parseSequestVersion(new StringReader(" SEQUEST version UW2012.01.2 MacCoss Lab, Genome Sciences"))); - - assertEquals(null, task.parseSequestVersion(new StringReader("SEQUEST ver. UW 202.01.12 MacCoss Lab, Genome Sciences"))); - assertEquals(null, task.parseSequestVersion(new StringReader("SEQUEST ver. "))); - assertEquals(null, task.parseSequestVersion(new StringReader(""))); - } - } - - public static void main(String... args) throws Exception - { - try (Writer writer = PrintWriters.getPrintWriter(new FileOutputStream("c:/temp/headers.txt"))) - { - writeParams(writer, new File("c:/temp/sequestProduction.params"), Logger.getLogger(UWSequestSearchTask.class), new File("c:/temp/databases/149Proteins.fsa"), "2050059"); - } - } -} diff --git a/ms2/webapp/WEB-INF/ms2/ms2Context.xml b/ms2/webapp/WEB-INF/ms2/ms2Context.xml index 762039a01c..e5a8d819bd 100644 --- a/ms2/webapp/WEB-INF/ms2/ms2Context.xml +++ b/ms2/webapp/WEB-INF/ms2/ms2Context.xml @@ -37,14 +37,6 @@ - - - - - - - -