diff --git a/ms2/src/org/labkey/ms2/MS2Controller.java b/ms2/src/org/labkey/ms2/MS2Controller.java index 7ee2eb6bbf..09dccb9f0e 100644 --- a/ms2/src/org/labkey/ms2/MS2Controller.java +++ b/ms2/src/org/labkey/ms2/MS2Controller.java @@ -120,7 +120,6 @@ import org.labkey.ms2.compare.RunColumn; import org.labkey.ms2.compare.SpectraCountQueryView; import org.labkey.ms2.peptideview.AbstractMS2RunView; -import org.labkey.ms2.peptideview.AbstractQueryMS2RunView; import org.labkey.ms2.peptideview.MS2RunViewType; import org.labkey.ms2.peptideview.QueryPeptideMS2RunView; import org.labkey.ms2.pipeline.AbstractMS2SearchTask; @@ -257,7 +256,7 @@ private NavTree appendProteinAdminNavTrail(NavTree root, String title, PageConfi } - private AbstractMS2RunView getPeptideView(String grouping, MS2Run... runs) + private AbstractMS2RunView getPeptideView(String grouping, MS2Run... runs) { return MS2RunViewType.getViewType(grouping).createView(getViewContext(), runs); } @@ -1081,9 +1080,9 @@ public ModelAndView getView(ChartForm form, BindException errors) throws Excepti throw new NotFoundException("Unsupported GO chart type: " + form.getChartType()); } - AbstractMS2RunView peptideView = getPeptideView(queryURL.getParameter("grouping"), _run); + AbstractMS2RunView peptideView = getPeptideView(queryURL.getParameter("grouping"), _run); - Map filters = peptideView.getFilter(queryURL, _run); + Map filters = peptideView.getFilter(queryURL); String chartTitle = "GO " + _goChartType + " Classifications"; SQLFragment fragment = peptideView.getProteins(queryURL, _run, form); @@ -3828,7 +3827,7 @@ public ModelAndView getView(DetailsForm form, BindException errors) throws Excep run = form.validateRun(); QueryPeptideMS2RunView peptideQueryView = new QueryPeptideMS2RunView(getViewContext(), run); SimpleFilter filter = getAllPeptidesFilter(getViewContext(), getViewContext().getActionURL().clone(), run); - AbstractQueryMS2RunView.AbstractMS2QueryView gridView = peptideQueryView.createGridView(filter); + AbstractMS2RunView.AbstractMS2QueryView gridView = peptideQueryView.createGridView(filter); protein.setPeptides(new TableSelector(gridView.getTable(), PageFlowUtil.set("Peptide"), filter, new Sort("Peptide")).getArray(String.class)); } diff --git a/ms2/src/org/labkey/ms2/peptideview/AbstractMS2RunView.java b/ms2/src/org/labkey/ms2/peptideview/AbstractMS2RunView.java index 701a374f38..057d723deb 100644 --- a/ms2/src/org/labkey/ms2/peptideview/AbstractMS2RunView.java +++ b/ms2/src/org/labkey/ms2/peptideview/AbstractMS2RunView.java @@ -17,25 +17,40 @@ package org.labkey.ms2.peptideview; import org.apache.log4j.Logger; +import org.jetbrains.annotations.Nullable; import org.labkey.api.data.ButtonBar; +import org.labkey.api.data.ColumnHeaderType; import org.labkey.api.data.ColumnInfo; import org.labkey.api.data.Container; import org.labkey.api.data.DataRegion; import org.labkey.api.data.DisplayColumn; +import org.labkey.api.data.ExcelWriter; import org.labkey.api.data.MenuButton; +import org.labkey.api.data.NestableQueryView; +import org.labkey.api.data.NestedRenderContext; +import org.labkey.api.data.RenderContext; import org.labkey.api.data.SQLFragment; import org.labkey.api.data.SimpleFilter; import org.labkey.api.data.Sort; +import org.labkey.api.data.TSVGridWriter; +import org.labkey.api.data.Table; import org.labkey.api.data.TableInfo; import org.labkey.api.data.TableSelector; import org.labkey.api.query.DetailsURL; +import org.labkey.api.query.FieldKey; +import org.labkey.api.query.QueryNestingOption; +import org.labkey.api.query.QueryService; +import org.labkey.api.query.QuerySettings; +import org.labkey.api.query.UserSchema; import org.labkey.api.security.User; import org.labkey.api.util.Pair; import org.labkey.api.view.ActionURL; +import org.labkey.api.view.DataView; +import org.labkey.api.view.DisplayElement; import org.labkey.api.view.GridView; import org.labkey.api.view.NavTree; +import org.labkey.api.view.NotFoundException; import org.labkey.api.view.ViewContext; -import org.labkey.api.view.WebPartView; import org.labkey.ms2.HydrophobicityColumn; import org.labkey.ms2.MS2Controller; import org.labkey.ms2.MS2ExportType; @@ -44,12 +59,11 @@ import org.labkey.ms2.MS2Run; import org.labkey.ms2.MassType; import org.labkey.ms2.RunListException; +import org.labkey.ms2.SpectrumIterator; import org.labkey.ms2.SpectrumRenderer; import org.labkey.ms2.protein.ProteinManager; import org.labkey.ms2.protein.tools.GoLoader; import org.labkey.ms2.protein.tools.ProteinDictionaryHelpers; -import org.springframework.web.servlet.ModelAndView; -import org.springframework.web.servlet.mvc.Controller; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @@ -57,6 +71,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; @@ -64,7 +79,7 @@ * User: jeckels * Date: Feb 22, 2006 */ -public abstract class AbstractMS2RunView +public abstract class AbstractMS2RunView { private static Logger _log = Logger.getLogger(AbstractMS2RunView.class); @@ -83,12 +98,12 @@ public AbstractMS2RunView(ViewContext viewContext, MS2Run... runs) _runs = runs; } - public WebPartType createGridView(MS2Controller.RunForm form) + public AbstractMS2QueryView createGridView(MS2Controller.RunForm form) { return createGridView(form.getExpanded(), false); } - public abstract WebPartType createGridView(boolean expanded, boolean forExport); + public abstract AbstractMS2QueryView createGridView(boolean expanded, boolean forExport); public abstract GridView getPeptideViewForProteinGrouping(String proteinGroupingId, String columns) throws SQLException; @@ -96,8 +111,6 @@ public WebPartType createGridView(MS2Controller.RunForm form) public abstract SQLFragment getProteins(ActionURL queryUrl, MS2Run run, MS2Controller.ChartForm form); - public abstract Map getFilter(ActionURL queryUrl, MS2Run run); - public Container getContainer() { return _container; @@ -112,14 +125,14 @@ protected String getAJAXNestedGridURL() return groupURL.toString() + "&proteinGroupingId="; } - protected ButtonBar createButtonBar(Class exportAllAction, Class exportSelectedAction, String whatWeAreSelecting, DataRegion dataRegion) + protected ButtonBar createButtonBar(String whatWeAreSelecting, DataRegion dataRegion) { ButtonBar result = new ButtonBar(); List exportFormats = getExportTypes(); ActionURL exportUrl = _url.clone(); - exportUrl.setAction(exportAllAction); + exportUrl.setAction(MS2Controller.ExportAllPeptidesAction.class); MenuButton exportAll = new MenuButton("Export All"); for (MS2ExportType exportFormat : exportFormats) { @@ -133,7 +146,7 @@ protected ButtonBar createButtonBar(Class exportAllAction, result.add(exportAll); MenuButton exportSelected = new MenuButton("Export Selected"); - exportUrl.setAction(exportSelectedAction); + exportUrl.setAction(MS2Controller.ExportSelectedPeptidesAction.class); exportSelected.setRequiresSelection(true); for (MS2ExportType exportFormat : exportFormats) { @@ -332,13 +345,139 @@ protected MS2Run getSingleRun() return _runs[0]; } - public abstract ModelAndView exportToTSV(MS2Controller.ExportForm form, HttpServletResponse response, List selectedRows, List headers) throws IOException; + public Map getFilter(ActionURL queryUrl) + { + NestableQueryView queryView = createGridView(false, false); + RenderContext context = queryView.createDataView().getRenderContext(); + TableInfo tinfo = queryView.createTable(); + + Sort sort = new Sort(); + return Collections.singletonMap("Filter", context.buildFilter(tinfo, Collections.emptyList(), queryUrl, queryView.getDataRegionName(), Table.ALL_ROWS, Table.NO_OFFSET, sort)); + } + + public void exportToExcel(MS2Controller.ExportForm form, HttpServletResponse response, List selectedRows) throws IOException + { + createGridView(form.getExpanded(), true).exportToExcel(response, selectedRows); + } + + + public void exportToTSV(MS2Controller.ExportForm form, HttpServletResponse response, List selectedRows, List headers) throws IOException + { + AbstractMS2QueryView gridView = createGridView(form.getExpanded(), true); + gridView.createRowIdFragment(selectedRows); + gridView.exportToTSV(response, headers); + } + + public void exportToAMT(MS2Controller.ExportForm form, HttpServletResponse response, List selectedRows) throws IOException + { + AbstractMS2QueryView ms2QueryView = createGridView(form.getExpanded(), true); + ms2QueryView.createRowIdFragment(selectedRows); + + List keys = new ArrayList<>(); + keys.add(FieldKey.fromParts("Fraction", "Run", "Run")); + keys.add(FieldKey.fromParts("Fraction", "Fraction")); + keys.add(FieldKey.fromParts("Mass")); + keys.add(FieldKey.fromParts("Scan")); + keys.add(FieldKey.fromParts("RetentionTime")); + keys.add(FieldKey.fromParts("H")); + keys.add(FieldKey.fromParts("PeptideProphet")); + keys.add(FieldKey.fromParts("Peptide")); + ms2QueryView.setOverrideColumns(keys); + + ms2QueryView.exportToTSV(response, getAMTFileHeader()); + } + + public void exportSpectra(MS2Controller.ExportForm form, ActionURL currentURL, SpectrumRenderer spectrumRenderer, List exportRows) throws IOException, RunListException + { + List runs = form.validateRuns(); + + // Choose a different iterator based on whether this is a nested view that may include protein group criteria + NestableQueryView queryView = createGridView(form); + SQLFragment sql = generateSubSelect(queryView, currentURL, exportRows, FieldKey.fromParts("RowId")).second; + try (SpectrumIterator iter = new QueryResultSetSpectrumIterator(runs, sql)) + { + spectrumRenderer.render(iter); + spectrumRenderer.close(); + } + } + + /** Generate the SELECT SQL to get a particular FieldKey, respecting the filters and other config on the URL */ + protected Pair generateSubSelect(NestableQueryView queryView, ActionURL currentURL, @Nullable List selectedIds, FieldKey desiredFK) + { + RenderContext context = queryView.createDataView().getRenderContext(); + TableInfo tinfo = queryView.createTable(); + + Sort sort = new Sort(); + SimpleFilter filter; + if (context instanceof NestedRenderContext) + { + filter = ((NestedRenderContext)context).buildFilter(tinfo, Collections.emptyList(), currentURL, queryView.getDataRegionName(), Table.ALL_ROWS, Table.NO_OFFSET, sort, true); + } + else + { + filter = context.buildFilter(tinfo, Collections.emptyList(), currentURL, queryView.getDataRegionName(), Table.ALL_ROWS, Table.NO_OFFSET, sort); + } + addSelectionFilter(selectedIds, queryView, filter); - public abstract ModelAndView exportToAMT(MS2Controller.ExportForm form, HttpServletResponse response, List selectedRows) throws IOException; + ColumnInfo desiredCol = QueryService.get().getColumns(tinfo, Collections.singletonList(desiredFK)).get(desiredFK); + if (desiredCol == null) + { + throw new IllegalArgumentException("Couldn't find column " + desiredFK + " in table " + tinfo); + } + + List columns = new ArrayList<>(); + columns.add(desiredCol); + + QueryService.get().ensureRequiredColumns(tinfo, columns, filter, sort, new HashSet<>()); + + SQLFragment sql = QueryService.get().getSelectSQL(tinfo, columns, filter, sort, Table.ALL_ROWS, Table.NO_OFFSET, false); + return new Pair<>(desiredCol, sql); + } + + /** Add a filter for any selection the user might have made. The type of selection depends on the type of view (peptides/protein groups/search engine protein) */ + private void addSelectionFilter(@Nullable List exportRows, NestableQueryView queryView, SimpleFilter filter) + { + if (exportRows != null) + { + List rowIds = parseIds(exportRows); + FieldKey selectionFK; + QueryNestingOption nestingOption = queryView.getSelectedNestingOption(); + if (nestingOption != null) + { + // We're nested, so the selection key is going to be at the protein or protein group level + selectionFK = nestingOption.getAggregateRowIdFieldKey(); + } + else + { + // No nesting, so the selection key will just be the peptide's RowId + selectionFK = FieldKey.fromParts("RowId"); + } + filter.addClause(new SimpleFilter.InClause(selectionFK, rowIds)); + } + } + + /** + * Convert from Strings to Integers + * @throws NotFoundException if there's an unparseable value + */ + private List parseIds(List exportRows) + { + List rowIds = new ArrayList<>(exportRows.size()); + for (String exportRow : exportRows) + { + try + { + rowIds.add(Integer.parseInt(exportRow)); + } + catch (NumberFormatException e) + { + throw new NotFoundException("Invalid selection: " + exportRow); + } + } + return rowIds; + } - public abstract ModelAndView exportToExcel(MS2Controller.ExportForm form, HttpServletResponse response, List selectedRows) throws IOException; - public abstract void exportSpectra(MS2Controller.ExportForm form, ActionURL currentURL, SpectrumRenderer spectrumRenderer, List exportRows) throws IOException, RunListException; protected List getAMTFileHeader() { @@ -371,4 +510,80 @@ protected List getAMTFileHeader() return fileHeader; } + + public abstract class AbstractMS2QueryView extends NestableQueryView + { + protected SimpleFilter.FilterClause _selectedRowsClause; + + public AbstractMS2QueryView(UserSchema schema, QuerySettings settings, boolean expanded, boolean forExport, QueryNestingOption... queryNestingOptions) + { + super(schema, settings, expanded, forExport, queryNestingOptions); + + setViewItemFilter((type, label) -> SingleMS2RunRReport.TYPE.equals(type)); + } + + @Override + protected void populateButtonBar(DataView view, ButtonBar bar) + { + super.populateButtonBar(view, bar); + ButtonBar bb = createButtonBar("peptides", view.getDataRegion()); + for (DisplayElement element : bb.getList()) + { + bar.add(element); + } + } + + public void exportToTSV(HttpServletResponse response, List headers) throws IOException + { + getSettings().setMaxRows(Table.ALL_ROWS); + + try (TSVGridWriter tsvWriter = getTsvWriter()) + { + tsvWriter.setColumnHeaderType(ColumnHeaderType.Caption); + tsvWriter.setFileHeader(headers); + tsvWriter.write(response); + } + } + + public void exportToExcel(HttpServletResponse response, List selectedRows) throws IOException + { + createRowIdFragment(selectedRows); + getSettings().setMaxRows(ExcelWriter.MAX_ROWS_EXCEL_97); + exportToExcel(response); + } + + protected void createRowIdFragment(List selectedRows) + { + if (selectedRows != null) + { + List parsedSelection = new ArrayList<>(); + for (String selectedRow : selectedRows) + { + Integer row = Integer.valueOf(selectedRow); + parsedSelection.add(row); + } + + // Don't used _selectedNestingOption one because we want to export as if we're a simple flat view + QueryNestingOption nesting = determineNestingOption(); + FieldKey column = nesting == null ? FieldKey.fromParts("RowId") : nesting.getRowIdFieldKey(); + _selectedRowsClause = new SimpleFilter.InClause(column, parsedSelection); + } + } + + @Override + public DataView createDataView() + { + DataView result = super.createDataView(); + SimpleFilter filter = new SimpleFilter(result.getRenderContext().getBaseFilter()); + + if (_selectedRowsClause != null) + { + filter.addClause(_selectedRowsClause); + } + + filter.addAllClauses(ProteinManager.getPeptideFilter(_url, ProteinManager.EXTRA_FILTER | ProteinManager.PROTEIN_FILTER, getUser(), _runs)); + result.getRenderContext().setBaseFilter(filter); + return result; + } + } } diff --git a/ms2/src/org/labkey/ms2/peptideview/AbstractQueryMS2RunView.java b/ms2/src/org/labkey/ms2/peptideview/AbstractQueryMS2RunView.java deleted file mode 100644 index 2b1f59525a..0000000000 --- a/ms2/src/org/labkey/ms2/peptideview/AbstractQueryMS2RunView.java +++ /dev/null @@ -1,277 +0,0 @@ -/* - * Copyright (c) 2007-2018 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.peptideview; - -import org.jetbrains.annotations.Nullable; -import org.labkey.api.data.ButtonBar; -import org.labkey.api.data.ColumnHeaderType; -import org.labkey.api.data.ColumnInfo; -import org.labkey.api.data.ExcelWriter; -import org.labkey.api.data.NestableQueryView; -import org.labkey.api.data.NestedRenderContext; -import org.labkey.api.data.RenderContext; -import org.labkey.api.data.SQLFragment; -import org.labkey.api.data.SimpleFilter; -import org.labkey.api.data.Sort; -import org.labkey.api.data.TSVGridWriter; -import org.labkey.api.data.Table; -import org.labkey.api.data.TableInfo; -import org.labkey.api.query.FieldKey; -import org.labkey.api.query.QueryNestingOption; -import org.labkey.api.query.QueryService; -import org.labkey.api.query.QuerySettings; -import org.labkey.api.query.UserSchema; -import org.labkey.api.util.Pair; -import org.labkey.api.view.ActionURL; -import org.labkey.api.view.DataView; -import org.labkey.api.view.DisplayElement; -import org.labkey.api.view.NotFoundException; -import org.labkey.api.view.ViewContext; -import org.labkey.ms2.MS2Controller; -import org.labkey.ms2.MS2Run; -import org.labkey.ms2.RunListException; -import org.labkey.ms2.SpectrumIterator; -import org.labkey.ms2.SpectrumRenderer; -import org.labkey.ms2.protein.ProteinManager; -import org.springframework.web.servlet.ModelAndView; - -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Map; - -/** - * User: jeckels - * Date: Apr 27, 2007 - */ -public abstract class AbstractQueryMS2RunView extends AbstractMS2RunView -{ - public AbstractQueryMS2RunView(ViewContext viewContext, MS2Run... runs) - { - super(viewContext, runs); - } - - public ModelAndView exportToTSV(MS2Controller.ExportForm form, HttpServletResponse response, List selectedRows, List headers) throws IOException - { - return createGridView(form.getExpanded(), true).exportToTSV(response, selectedRows, headers); - } - - public ModelAndView exportToAMT(MS2Controller.ExportForm form, HttpServletResponse response, List selectedRows) throws IOException - { - AbstractMS2QueryView ms2QueryView = createGridView(form.getExpanded(), true); - - List keys = new ArrayList<>(); - keys.add(FieldKey.fromParts("Fraction", "Run", "Run")); - keys.add(FieldKey.fromParts("Fraction", "Fraction")); - keys.add(FieldKey.fromParts("Mass")); - keys.add(FieldKey.fromParts("Scan")); - keys.add(FieldKey.fromParts("RetentionTime")); - keys.add(FieldKey.fromParts("H")); - keys.add(FieldKey.fromParts("PeptideProphet")); - keys.add(FieldKey.fromParts("Peptide")); - ms2QueryView.setOverrideColumns(keys); - - return ms2QueryView.exportToTSV(response, selectedRows, getAMTFileHeader()); - } - - public Map getFilter(ActionURL queryUrl, MS2Run run) - { - NestableQueryView queryView = createGridView(false, false); - RenderContext context = queryView.createDataView().getRenderContext(); - TableInfo tinfo = queryView.createTable(); - - Sort sort = new Sort(); - return Collections.singletonMap("Filter", context.buildFilter(tinfo, Collections.emptyList(), queryUrl, queryView.getDataRegionName(), Table.ALL_ROWS, Table.NO_OFFSET, sort)); - } - - public ModelAndView exportToExcel(MS2Controller.ExportForm form, HttpServletResponse response, List selectedRows) throws IOException - { - createGridView(form.getExpanded(), true).exportToExcel(response, selectedRows); - return null; - } - - @Override - public void exportSpectra(MS2Controller.ExportForm form, ActionURL currentURL, SpectrumRenderer spectrumRenderer, List exportRows) throws IOException, RunListException - { - List runs = form.validateRuns(); - - // Choose a different iterator based on whether this is a nested view that may include protein group criteria - NestableQueryView queryView = createGridView(form); - SQLFragment sql = generateSubSelect(queryView, currentURL, exportRows, FieldKey.fromParts("RowId")).second; - try (SpectrumIterator iter = new QueryResultSetSpectrumIterator(runs, sql)) - { - spectrumRenderer.render(iter); - spectrumRenderer.close(); - } - } - - /** Generate the SELECT SQL to get a particular FieldKey, respecting the filters and other config on the URL */ - protected Pair generateSubSelect(NestableQueryView queryView, ActionURL currentURL, @Nullable List selectedIds, FieldKey desiredFK) - { - RenderContext context = queryView.createDataView().getRenderContext(); - TableInfo tinfo = queryView.createTable(); - - Sort sort = new Sort(); - SimpleFilter filter; - if (context instanceof NestedRenderContext) - { - filter = ((NestedRenderContext)context).buildFilter(tinfo, Collections.emptyList(), currentURL, queryView.getDataRegionName(), Table.ALL_ROWS, Table.NO_OFFSET, sort, true); - } - else - { - filter = context.buildFilter(tinfo, Collections.emptyList(), currentURL, queryView.getDataRegionName(), Table.ALL_ROWS, Table.NO_OFFSET, sort); - } - addSelectionFilter(selectedIds, queryView, filter); - - ColumnInfo desiredCol = QueryService.get().getColumns(tinfo, Collections.singletonList(desiredFK)).get(desiredFK); - if (desiredCol == null) - { - throw new IllegalArgumentException("Couldn't find column " + desiredFK + " in table " + tinfo); - } - - List columns = new ArrayList<>(); - columns.add(desiredCol); - - QueryService.get().ensureRequiredColumns(tinfo, columns, filter, sort, new HashSet<>()); - - SQLFragment sql = QueryService.get().getSelectSQL(tinfo, columns, filter, sort, Table.ALL_ROWS, Table.NO_OFFSET, false); - return new Pair<>(desiredCol, sql); - } - - /** Add a filter for any selection the user might have made. The type of selection depends on the type of view (peptides/protein groups/search engine protein) */ - private void addSelectionFilter(@Nullable List exportRows, NestableQueryView queryView, SimpleFilter filter) - { - if (exportRows != null) - { - List rowIds = parseIds(exportRows); - FieldKey selectionFK; - QueryNestingOption nestingOption = queryView.getSelectedNestingOption(); - if (nestingOption != null) - { - // We're nested, so the selection key is going to be at the protein or protein group level - selectionFK = nestingOption.getAggregateRowIdFieldKey(); - } - else - { - // No nesting, so the selection key will just be the peptide's RowId - selectionFK = FieldKey.fromParts("RowId"); - } - filter.addClause(new SimpleFilter.InClause(selectionFK, rowIds)); - } - } - - /** - * Convert from Strings to Integers - * @throws NotFoundException if there's an unparseable value - */ - private List parseIds(List exportRows) - { - List rowIds = new ArrayList<>(exportRows.size()); - for (String exportRow : exportRows) - { - try - { - rowIds.add(Integer.parseInt(exportRow)); - } - catch (NumberFormatException e) - { - throw new NotFoundException("Invalid selection: " + exportRow); - } - } - return rowIds; - } - - public abstract AbstractMS2QueryView createGridView(boolean expanded, boolean forExport); - - public abstract class AbstractMS2QueryView extends NestableQueryView - { - protected List _selectedRows; - - public AbstractMS2QueryView(UserSchema schema, QuerySettings settings, boolean expanded, boolean forExport, QueryNestingOption... queryNestingOptions) - { - super(schema, settings, expanded, forExport, queryNestingOptions); - - setViewItemFilter((type, label) -> SingleMS2RunRReport.TYPE.equals(type)); - } - - protected void populateButtonBar(DataView view, ButtonBar bar) - { - super.populateButtonBar(view, bar); - ButtonBar bb = createButtonBar(MS2Controller.ExportAllPeptidesAction.class, MS2Controller.ExportSelectedPeptidesAction.class, "peptides", view.getDataRegion()); - for (DisplayElement element : bb.getList()) - { - bar.add(element); - } - } - - public ModelAndView exportToTSV(HttpServletResponse response, List selectedRows, List headers) throws IOException - { - createRowIdFragment(selectedRows); - getSettings().setMaxRows(Table.ALL_ROWS); - - try (TSVGridWriter tsvWriter = getTsvWriter()) - { - tsvWriter.setColumnHeaderType(ColumnHeaderType.Caption); - tsvWriter.setFileHeader(headers); - tsvWriter.write(response); - } - - return null; - } - - public void exportToExcel(HttpServletResponse response, List selectedRows) throws IOException - { - createRowIdFragment(selectedRows); - getSettings().setMaxRows(ExcelWriter.MAX_ROWS_EXCEL_97); - exportToExcel(response); - } - - protected void createRowIdFragment(List selectedRows) - { - if (selectedRows != null) - { - _selectedRows = new ArrayList<>(); - for (String selectedRow : selectedRows) - { - Integer row = Integer.valueOf(selectedRow); - _selectedRows.add(row); - } - } - } - - public DataView createDataView() - { - DataView result = super.createDataView(); - SimpleFilter filter = new SimpleFilter(result.getRenderContext().getBaseFilter()); - - if (_selectedRows != null) - { - // Don't used _selectedNestingOption one because we want to export as if we're a simple flat view - QueryNestingOption nesting = determineNestingOption(); - FieldKey column = nesting == null ? FieldKey.fromParts("RowId") : nesting.getRowIdFieldKey(); - filter.addClause(new SimpleFilter.InClause(column, _selectedRows)); - } - - filter.addAllClauses(ProteinManager.getPeptideFilter(_url, ProteinManager.EXTRA_FILTER | ProteinManager.PROTEIN_FILTER, getUser(), _runs)); - result.getRenderContext().setBaseFilter(filter); - return result; - } - } -} diff --git a/ms2/src/org/labkey/ms2/peptideview/MS2RunViewType.java b/ms2/src/org/labkey/ms2/peptideview/MS2RunViewType.java index 719431f580..81f91a156f 100644 --- a/ms2/src/org/labkey/ms2/peptideview/MS2RunViewType.java +++ b/ms2/src/org/labkey/ms2/peptideview/MS2RunViewType.java @@ -16,6 +16,7 @@ package org.labkey.ms2.peptideview; +import org.jetbrains.annotations.NotNull; import org.labkey.api.view.ViewContext; import org.labkey.api.view.WebPartView; import org.labkey.ms2.MS2Run; @@ -31,23 +32,27 @@ public enum MS2RunViewType { QUERY_PEPTIDES("Standard", "query") { - public AbstractMS2RunView createView(ViewContext viewContext, MS2Run... runs) + @Override @NotNull + public AbstractMS2RunView createView(ViewContext viewContext, MS2Run... runs) { return new QueryPeptideMS2RunView(viewContext, runs); } }, QUERY_PROTEIN_GROUPS("Protein Groups", "queryproteingroups") { - public AbstractMS2RunView createView(ViewContext viewContext, MS2Run... runs) + @Override @NotNull + public AbstractMS2RunView createView(ViewContext viewContext, MS2Run... runs) { return new QueryProteinGroupMS2RunView(viewContext, runs); } + @Override public boolean supportsRun(MS2Run run) { return run.hasProteinProphet(); } + @Override public boolean supportsExtraFilters() { return false; @@ -89,7 +94,8 @@ public boolean supportsExtraFilters() return true; } - public abstract AbstractMS2RunView createView(ViewContext viewContext, MS2Run... runs); + @NotNull + public abstract AbstractMS2RunView createView(ViewContext viewContext, MS2Run... runs); public static MS2RunViewType getViewType(String urlName) { diff --git a/ms2/src/org/labkey/ms2/peptideview/QueryPeptideMS2RunView.java b/ms2/src/org/labkey/ms2/peptideview/QueryPeptideMS2RunView.java index 4b939e4731..6564305b1e 100644 --- a/ms2/src/org/labkey/ms2/peptideview/QueryPeptideMS2RunView.java +++ b/ms2/src/org/labkey/ms2/peptideview/QueryPeptideMS2RunView.java @@ -59,7 +59,7 @@ * User: jeckels * Date: Mar 6, 2006 */ -public class QueryPeptideMS2RunView extends AbstractQueryMS2RunView +public class QueryPeptideMS2RunView extends AbstractMS2RunView { private PeptidesTableInfo _peptidesTable; @@ -134,6 +134,7 @@ public SQLFragment getProteins(ActionURL queryUrl, MS2Run run, MS2Controller.Cha } } + @Override public PeptideQueryView createGridView(boolean expanded, boolean forExport) { MS2Schema schema = new MS2Schema(getUser(), getContainer()); @@ -174,6 +175,7 @@ public PeptideQueryView(MS2Schema schema, QuerySettings settings, boolean expand setShowDetailsColumn(false); } + @Override public List getDisplayColumns() { List result = new ArrayList<>(); @@ -192,6 +194,7 @@ public List getDisplayColumns() return result; } + @Override protected DataRegion createDataRegion() { DataRegion rgn = super.createDataRegion(); @@ -211,6 +214,7 @@ protected Sort getBaseSort() return ProteinManager.getPeptideBaseSort(); } + @Override public PeptidesTableInfo createTable() { return createPeptideTable((MS2Schema)getSchema()); @@ -243,10 +247,12 @@ private PeptidesTableInfo createPeptideTable(MS2Schema schema) return _peptidesTable; } + @Override public void addSQLSummaries(SimpleFilter peptideFilter, List> sqlSummaries) { } + @Override public GridView getPeptideViewForProteinGrouping(String proteinGroupingId, String columns) { MS2Schema schema = new MS2Schema(getUser(), getContainer()); @@ -292,6 +298,7 @@ public GridView getPeptideViewForProteinGrouping(String proteinGroupingId, Strin return result; } + @Override protected List getExportTypes() { return Arrays.asList(MS2ExportType.Excel, MS2ExportType.TSV, MS2ExportType.AMT, MS2ExportType.MS2Ions, MS2ExportType.Bibliospec); diff --git a/ms2/src/org/labkey/ms2/peptideview/QueryProteinGroupMS2RunView.java b/ms2/src/org/labkey/ms2/peptideview/QueryProteinGroupMS2RunView.java index 6416ef00cd..d0471ce173 100644 --- a/ms2/src/org/labkey/ms2/peptideview/QueryProteinGroupMS2RunView.java +++ b/ms2/src/org/labkey/ms2/peptideview/QueryProteinGroupMS2RunView.java @@ -50,7 +50,7 @@ * User: jeckels * Date: Apr 11, 2007 */ -public class QueryProteinGroupMS2RunView extends AbstractQueryMS2RunView +public class QueryProteinGroupMS2RunView extends AbstractMS2RunView { private static final String DATA_REGION_NAME = "ProteinGroups"; @@ -68,6 +68,7 @@ protected QuerySettings createQuerySettings(UserSchema schema) throws RedirectEx return settings; } + @Override public ProteinGroupQueryView createGridView(boolean expanded, boolean forExport) { UserSchema schema = QueryService.get().getUserSchema(getUser(), getContainer(), MS2Schema.SCHEMA_NAME); @@ -102,6 +103,7 @@ public ProteinGroupQueryView(UserSchema schema, QuerySettings settings, boolean { super(schema, settings, expanded, forExport, new QueryNestingOption(FieldKey.fromParts("RowId"), FieldKey.fromParts("RowId"), getAJAXNestedGridURL()) { + @Override public boolean isOuter(FieldKey fieldKey) { return fieldKey.size() == 1; @@ -109,6 +111,7 @@ public boolean isOuter(FieldKey fieldKey) }); } + @Override protected DataRegion createDataRegion() { DataRegion rgn = super.createDataRegion(); @@ -125,6 +128,7 @@ protected Sort getBaseSort() return new Sort("RowId"); } + @Override public ProteinGroupTableInfo createTable() { ProteinGroupTableInfo result = ((MS2Schema)getSchema()).createProteinGroupsForRunTable(getContainerFilter(), false); @@ -133,11 +137,13 @@ public ProteinGroupTableInfo createTable() } } + @Override public void addSQLSummaries(SimpleFilter peptideFilter, List> sqlSummaries) { } + @Override public GridView getPeptideViewForProteinGrouping(String proteinGroupingId, String columns) { MS2Schema schema = new MS2Schema(getUser(), getContainer()); @@ -176,6 +182,7 @@ public GridView getPeptideViewForProteinGrouping(String proteinGroupingId, Strin return result; } + @Override protected List getExportTypes() { return Arrays.asList(MS2ExportType.Excel, MS2ExportType.TSV); diff --git a/ms2/src/org/labkey/ms2/peptideview/SingleMS2RunRReport.java b/ms2/src/org/labkey/ms2/peptideview/SingleMS2RunRReport.java index 1303b16e86..39dc8a2ef5 100644 --- a/ms2/src/org/labkey/ms2/peptideview/SingleMS2RunRReport.java +++ b/ms2/src/org/labkey/ms2/peptideview/SingleMS2RunRReport.java @@ -44,6 +44,7 @@ public SingleMS2RunRReport() super(PARAMS, TYPE); } + @Override protected QueryView getQueryView(ViewContext context) { ActionURL url = context.getActionURL(); @@ -65,17 +66,13 @@ protected QueryView getQueryView(ViewContext context) String groupingString = url.getParameter(MS2Controller.RunForm.PARAMS.grouping); MS2RunViewType type = MS2RunViewType.getViewType(groupingString); AbstractMS2RunView view = type.createView(context, run); - if (view instanceof AbstractQueryMS2RunView) - { - String expandedString = url.getParameter(MS2Controller.RunForm.PARAMS.expanded); - boolean expanded = "1".equals(expandedString); - return ((AbstractQueryMS2RunView)view).createGridView(expanded, true); - } - - throw new NotFoundException("Unsupported grouping type: " + groupingString); + String expandedString = url.getParameter(MS2Controller.RunForm.PARAMS.expanded); + boolean expanded = "1".equals(expandedString); + return view.createGridView(expanded, true); } + @Override protected boolean hasRequiredParams(ViewContext context) { try diff --git a/ms2/src/org/labkey/ms2/query/MS2Schema.java b/ms2/src/org/labkey/ms2/query/MS2Schema.java index 742e7252de..b1e440ca7e 100644 --- a/ms2/src/org/labkey/ms2/query/MS2Schema.java +++ b/ms2/src/org/labkey/ms2/query/MS2Schema.java @@ -302,6 +302,7 @@ public TableInfo createTable(MS2Schema ms2Schema, ContainerFilter cf) public TableInfo createTable(MS2Schema ms2Schema, ContainerFilter cf) { ProteinGroupTableInfo result = new ProteinGroupTableInfo(ms2Schema, cf); + result.setRunFilter(null); return result; } }, diff --git a/ms2/src/org/labkey/ms2/query/ProteinGroupTableInfo.java b/ms2/src/org/labkey/ms2/query/ProteinGroupTableInfo.java index 7e0d33e0f7..66ec5cc0ee 100644 --- a/ms2/src/org/labkey/ms2/query/ProteinGroupTableInfo.java +++ b/ms2/src/org/labkey/ms2/query/ProteinGroupTableInfo.java @@ -23,7 +23,6 @@ import org.labkey.api.data.ContainerFilter; import org.labkey.api.data.ContainerManager; import org.labkey.api.data.DataColumn; -import org.labkey.api.data.DisplayColumn; import org.labkey.api.data.DisplayColumnFactory; import org.labkey.api.data.JdbcType; import org.labkey.api.data.SQLFragment; @@ -56,8 +55,8 @@ */ public class ProteinGroupTableInfo extends FilteredTable { - private static final Set HIDDEN_PROTEIN_GROUP_COLUMN_NAMES = new CaseInsensitiveHashSet(Arrays.asList("RowId", "GroupNumber", "IndistinguishableCollectionId", "Deleted", "HasPeptideProphet")); - private static final Set HIDDEN_PROTEIN_GROUP_MEMBERSHIPS_COLUMN_NAMES = new CaseInsensitiveHashSet("ProteinGroupId", "SeqId"); + private static final Set HIDDEN_PROTEIN_GROUP_COLUMN_NAMES = Collections.unmodifiableSet(new CaseInsensitiveHashSet(Arrays.asList("RowId", "GroupNumber", "IndistinguishableCollectionId", "Deleted", "HasPeptideProphet"))); + private static final Set HIDDEN_PROTEIN_GROUP_MEMBERSHIPS_COLUMN_NAMES = Collections.unmodifiableSet(new CaseInsensitiveHashSet("ProteinGroupId", "SeqId")); private List _runs; public ProteinGroupTableInfo(MS2Schema schema, ContainerFilter cf) @@ -70,13 +69,7 @@ public ProteinGroupTableInfo(MS2Schema schema, ContainerFilter cf, boolean inclu super(MS2Manager.getTableInfoProteinGroups(), schema, cf); var groupNumberColumn = wrapColumn("Group", getRealTable().getColumn("GroupNumber")); - groupNumberColumn.setDisplayColumnFactory(new DisplayColumnFactory() - { - public DisplayColumn createRenderer(ColumnInfo colInfo) - { - return new GroupNumberDisplayColumn(colInfo, _userSchema.getContainer()); - } - }); + groupNumberColumn.setDisplayColumnFactory(colInfo -> new GroupNumberDisplayColumn(colInfo, _userSchema.getContainer())); addColumn(groupNumberColumn); @@ -90,6 +83,7 @@ public DisplayColumn createRenderer(ColumnInfo colInfo) quantitation.setIsUnselectable(true); quantitation.setFk(new LookupForeignKey("ProteinGroupId") { + @Override public TableInfo getLookupTableInfo() { // TODO ContainerFilter @@ -104,6 +98,7 @@ public TableInfo getLookupTableInfo() iTraqQuantitation.setIsUnselectable(true); iTraqQuantitation.setFk(new LookupForeignKey("ProteinGroupId") { + @Override public TableInfo getLookupTableInfo() { // TODO ContainerFilter @@ -123,6 +118,7 @@ public TableInfo getLookupTableInfo() LookupForeignKey foreignKey = new LookupForeignKey("RowId") { + @Override public TableInfo getLookupTableInfo() { // TODO ContainerFilter @@ -150,9 +146,10 @@ public TableInfo getLookupTableInfo() ExprColumn firstProteinColumn = new ExprColumn(this, "FirstProtein", firstProteinSQL, JdbcType.INTEGER); firstProteinColumn.setFk(new LookupForeignKey(cf, "SeqId", null) { + @Override public TableInfo getLookupTableInfo() { - return new SequencesTableInfo(null, _userSchema, getLookupContainerFilter()); + return new SequencesTableInfo<>(null, _userSchema, getLookupContainerFilter()); } }); addColumn(firstProteinColumn); @@ -201,7 +198,7 @@ public void addPeptideFilter(MS2Controller.ProbabilityProteinSearchForm form, Vi peptidesSQL = _userSchema.getPeptideSelectSQL(filter, peptideFieldKeys); } SQLFragment condition = new SQLFragment(); - condition.append("RowId IN (SELECT ProteinGroupId FROM " + MS2Manager.getTableInfoPeptideMemberships() + " WHERE PeptideId IN ("); + condition.append("RowId IN (SELECT ProteinGroupId FROM ").append(String.valueOf(MS2Manager.getTableInfoPeptideMemberships())).append(" WHERE PeptideId IN ("); condition.append(peptidesSQL); condition.append("))"); addCondition(condition, FieldKey.fromParts("RowId")); @@ -212,6 +209,7 @@ public void addProteinsColumn() var proteinGroup = wrapColumn("Proteins", getRealTable().getColumn("RowId")); LookupForeignKey fk = new LookupForeignKey(getContainerFilter(), "ProteinGroupId", null) { + @Override public TableInfo getLookupTableInfo() { // TODO ContainerFilter @@ -227,29 +225,26 @@ public TableInfo getLookupTableInfo() } var proteinColumn = result.wrapColumn("Protein", info.getColumn("SeqId")); - proteinColumn.setDisplayColumnFactory(new DisplayColumnFactory() - { - public DisplayColumn createRenderer(ColumnInfo colInfo) - { - DataColumn result = new DataColumn(colInfo); - result.setLinkTarget("prot"); + proteinColumn.setDisplayColumnFactory(colInfo -> { + DataColumn result1 = new DataColumn(colInfo); + result1.setLinkTarget("prot"); - ActionURL url = new ActionURL(MS2Controller.ShowProteinAction.class, _userSchema.getContainer()); - if (_runs != null && _runs.size() == 1) - { - url.addParameter("run", Integer.toString(_runs.get(0).getRun())); - } - result.setURL(url.getLocalURIString() + "&proteinGroupId=${RowId}&seqId=${" + colInfo.getName() + "}"); - return result; + ActionURL url = new ActionURL(MS2Controller.ShowProteinAction.class, _userSchema.getContainer()); + if (_runs != null && _runs.size() == 1) + { + url.addParameter("run", Integer.toString(_runs.get(0).getRun())); } + result1.setURL(url.getLocalURIString() + "&proteinGroupId=${RowId}&seqId=${" + colInfo.getName() + "}"); + return result1; }); result.addColumn(proteinColumn); proteinColumn.setFk(new LookupForeignKey(getContainerFilter(), "SeqId", "DatabaseSequenceName") { + @Override public TableInfo getLookupTableInfo() { - SequencesTableInfo result = new SequencesTableInfo(_userSchema, getLookupContainerFilter()); + SequencesTableInfo result = new SequencesTableInfo<>(_userSchema, getLookupContainerFilter()); ExprColumn col = new ExprColumn(result, "DatabaseSequenceName", new SQLFragment("#PLACEHOLDER#"), JdbcType.VARCHAR) { @Override @@ -298,15 +293,11 @@ public void addProteinDetailColumns() { ColumnInfo rowIdColumn = _rootTable.getColumn("RowId"); - DisplayColumnFactory factory = new DisplayColumnFactory() - { - public DisplayColumn createRenderer(ColumnInfo colInfo) - { - _userSchema.getProteinGroupProteins().setRuns(_userSchema.getRuns()); - ProteinListDisplayColumn result = new ProteinListDisplayColumn(colInfo.getColumnName(), _userSchema.getProteinGroupProteins()); - result.setColumnInfo(colInfo); - return result; - } + DisplayColumnFactory factory = colInfo -> { + _userSchema.getProteinGroupProteins().setRuns(_userSchema.getRuns()); + ProteinListDisplayColumn result = new ProteinListDisplayColumn(colInfo.getColumnName(), _userSchema.getProteinGroupProteins()); + result.setColumnInfo(colInfo); + return result; }; var proteinNameColumn = wrapColumn("Protein", rowIdColumn); @@ -331,24 +322,16 @@ public DisplayColumn createRenderer(ColumnInfo colInfo) var totalCount = wrapColumn("TotalFilteredPeptides", rowIdColumn); - totalCount.setDisplayColumnFactory(new DisplayColumnFactory() - { - public DisplayColumn createRenderer(ColumnInfo colInfo) - { - ColumnInfo peptideColumn = colInfo.getParentTable().getColumn("Peptide"); - return new PeptideCountCoverageColumn(colInfo, peptideColumn, "TotalFilteredPeptides"); - } + totalCount.setDisplayColumnFactory(colInfo -> { + ColumnInfo peptideColumn = colInfo.getParentTable().getColumn("Peptide"); + return new PeptideCountCoverageColumn(colInfo, peptideColumn, "TotalFilteredPeptides"); }); addColumn(totalCount); var uniqueCount = wrapColumn("UniqueFilteredPeptides", rowIdColumn); - uniqueCount.setDisplayColumnFactory(new DisplayColumnFactory() - { - public DisplayColumn createRenderer(ColumnInfo colInfo) - { - ColumnInfo peptideColumn = colInfo.getParentTable().getColumn("Peptide"); - return new UniquePeptideCountCoverageColumn(colInfo, peptideColumn, "UniqueFilteredPeptides"); - } + uniqueCount.setDisplayColumnFactory(colInfo -> { + ColumnInfo peptideColumn = colInfo.getParentTable().getColumn("Peptide"); + return new UniquePeptideCountCoverageColumn(colInfo, peptideColumn, "UniqueFilteredPeptides"); }); addColumn(uniqueCount); } @@ -432,32 +415,17 @@ public void addProteinNameFilter(String identifier, MS2Controller.MatchCriteria addCondition(sql); } - public void addMinimumProbability(float minProb) - { - SQLFragment sql = new SQLFragment(); - sql.append("GroupProbability >= ?"); - sql.add(minProb); - addCondition(sql); - } - - public void addMaximumErrorRate(float maxError) - { - SQLFragment sql = new SQLFragment(); - sql.append("ErrorRate <= ?"); - sql.add(maxError); - addCondition(sql); - } - public void setRunFilter(List runs) { _runs = runs; SQLFragment sql = new SQLFragment(); sql.append("ProteinProphetFileId IN (SELECT RowId FROM "); - sql.append(MS2Manager.getTableInfoProteinProphetFiles()); + sql.append(MS2Manager.getTableInfoProteinProphetFiles(), "ppf"); sql.append(" WHERE Run IN (SELECT Run FROM "); - sql.append(MS2Manager.getTableInfoRuns()); - sql.append(" WHERE Container = ? AND Deleted = ?"); - sql.add(_userSchema.getContainer().getId()); + sql.append(MS2Manager.getTableInfoRuns(), "r"); + sql.append(" WHERE "); + sql.append(getContainerFilter().getSQLFragment(getSchema(), new SQLFragment("Container"), getContainer())); + sql.append(" AND Deleted = ?"); sql.add(Boolean.FALSE); if (runs != null) { diff --git a/ms2/test/src/org/labkey/test/tests/ms2/MS2Test.java b/ms2/test/src/org/labkey/test/tests/ms2/MS2Test.java index ffff4d0093..12c983e909 100644 --- a/ms2/test/src/org/labkey/test/tests/ms2/MS2Test.java +++ b/ms2/test/src/org/labkey/test/tests/ms2/MS2Test.java @@ -493,7 +493,7 @@ private void verifyFirstRun() TextSearcher selectedAmtSrch = new TextSearcher(selectedAmtFile); selectedAmtSrch.setSourceTransformer(String::trim); // File has an extra blank line on Windows assertTextPresent(selectedAmtSrch, "Peptide"); - assertTextPresent(selectedAmtSrch, "\n", 3); + assertTextPresent(selectedAmtSrch, "\n", 4); assertTextNotPresent(selectedAmtSrch, "Next AA"); selectOptionByText(Locator.name("viewParams"), "");