From ec1918f6fc03cd377f2afa1f250fbfc374cc32a4 Mon Sep 17 00:00:00 2001
From: felmer <felmer>
Date: Tue, 24 Nov 2009 10:03:00 +0000
Subject: [PATCH] SE-163 Protein/Peptide Counts table implemented. Tests
 missing.

SVN: 13480
---
 .../web/client/IPhosphoNetXClientService.java |   8 ++
 .../IPhosphoNetXClientServiceAsync.java       |  11 ++
 .../client/web/client/application/Dict.java   |   7 +
 .../PhosphoNetXDisplayTypeIDGenerator.java    |   2 +
 .../ProteinByExperimentBrowerToolBar.java     |  17 ++-
 .../ProteinByExperimentBrowserGrid.java       |  60 ++++++++-
 .../application/ProteinSummaryGrid.java       | 111 ++++++++++++++++
 .../columns/ProteinSummaryColDefKind.java     |  91 +++++++++++++
 ...istProteinSummaryByExperimentCriteria.java |  45 +++++++
 .../web/public/phosphonetx-dictionary.js      |   5 +-
 .../server/ListProteinSummaryProvider.java    |  51 +++++++
 .../web/server/PhosphoNetXClientService.java  |  15 +++
 .../phosphonetx/server/PhosphoNetXServer.java |  11 ++
 .../server/PhosphoNetXServerLogger.java       |   9 ++
 .../business/BusinessObjectFactory.java       |   5 +
 .../server/business/ErrorModel.java           |  14 +-
 .../business/IBusinessObjectFactory.java      |   2 +
 .../server/business/IProteinSummaryTable.java |  36 +++++
 .../server/business/ProteinSummaryTable.java  | 124 ++++++++++++++++++
 .../server/dataaccess/IProteinQueryDAO.java   |  11 ++
 .../shared/IPhosphoNetXServer.java            |   8 ++
 .../shared/basic/dto/ProteinInfo.java         |  16 ---
 .../shared/basic/dto/ProteinSummary.java      |  69 ++++++++++
 .../ProteinReferenceWithPeptideSequence.java  |  14 ++
 ...einReferenceWithProbabilityAndPeptide.java |  41 ++++++
 25 files changed, 756 insertions(+), 27 deletions(-)
 create mode 100644 rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/client/application/ProteinSummaryGrid.java
 create mode 100644 rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/client/application/columns/ProteinSummaryColDefKind.java
 create mode 100644 rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/client/dto/ListProteinSummaryByExperimentCriteria.java
 create mode 100644 rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/server/ListProteinSummaryProvider.java
 create mode 100644 rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/business/IProteinSummaryTable.java
 create mode 100644 rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/business/ProteinSummaryTable.java
 create mode 100644 rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/shared/basic/dto/ProteinSummary.java
 create mode 100644 rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/shared/dto/ProteinReferenceWithProbabilityAndPeptide.java

diff --git a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/client/IPhosphoNetXClientService.java b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/client/IPhosphoNetXClientService.java
index a5c9d0585ac..ca845babddb 100644
--- a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/client/IPhosphoNetXClientService.java
+++ b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/client/IPhosphoNetXClientService.java
@@ -27,12 +27,14 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Vocabulary;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.client.web.client.dto.ListProteinByExperimentAndReferenceCriteria;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.client.web.client.dto.ListProteinByExperimentCriteria;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.client.web.client.dto.ListProteinSequenceCriteria;
+import ch.systemsx.cisd.openbis.plugin.phosphonetx.client.web.client.dto.ListProteinSummaryByExperimentCriteria;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.client.web.client.dto.ListSampleAbundanceByProteinCriteria;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.AbundanceColumnDefinition;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.DataSetProtein;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.ProteinByExperiment;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.ProteinInfo;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.ProteinSequence;
+import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.ProteinSummary;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.SampleWithPropertiesAndAbundance;
 
 /**
@@ -53,6 +55,12 @@ public interface IPhosphoNetXClientService extends IClientService
     public String prepareExportProteins(TableExportCriteria<ProteinInfo> exportCriteria)
             throws UserFailureException;
     
+    public ResultSet<ProteinSummary> listProteinSummariesByExperiment(
+            ListProteinSummaryByExperimentCriteria criteria) throws UserFailureException;
+    
+    public String prepareExportProteinSummary(TableExportCriteria<ProteinSummary> exportCriteria)
+            throws UserFailureException;
+    
     public ProteinByExperiment getProteinByExperiment(TechId experimentID, TechId proteinReferenceID)
             throws UserFailureException;
     
diff --git a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/client/IPhosphoNetXClientServiceAsync.java b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/client/IPhosphoNetXClientServiceAsync.java
index 4c50cb062db..5d6370d3470 100644
--- a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/client/IPhosphoNetXClientServiceAsync.java
+++ b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/client/IPhosphoNetXClientServiceAsync.java
@@ -23,17 +23,20 @@ import com.google.gwt.user.client.rpc.AsyncCallback;
 import ch.systemsx.cisd.openbis.generic.client.web.client.IClientServiceAsync;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ResultSet;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.TableExportCriteria;
+import ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException;
 import ch.systemsx.cisd.openbis.generic.shared.basic.TechId;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Vocabulary;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.client.web.client.dto.ListProteinByExperimentAndReferenceCriteria;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.client.web.client.dto.ListProteinByExperimentCriteria;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.client.web.client.dto.ListProteinSequenceCriteria;
+import ch.systemsx.cisd.openbis.plugin.phosphonetx.client.web.client.dto.ListProteinSummaryByExperimentCriteria;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.client.web.client.dto.ListSampleAbundanceByProteinCriteria;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.AbundanceColumnDefinition;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.DataSetProtein;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.ProteinByExperiment;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.ProteinInfo;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.ProteinSequence;
+import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.ProteinSummary;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.SampleWithPropertiesAndAbundance;
 
 /**
@@ -60,6 +63,14 @@ public interface IPhosphoNetXClientServiceAsync extends IClientServiceAsync
     public void prepareExportProteins(TableExportCriteria<ProteinInfo> exportCriteria,
             AsyncCallback<String> callback);
 
+    /** @see IPhosphoNetXClientService#listProteinSummariesByExperiment(ListProteinSummaryByExperimentCriteria) */
+    public void listProteinSummariesByExperiment(ListProteinSummaryByExperimentCriteria criteria,
+            AsyncCallback<ResultSet<ProteinSummary>> callback);
+    
+    /** @see IPhosphoNetXClientService#prepareExportProteinSummary(TableExportCriteria) */
+    public void prepareExportProteinSummary(TableExportCriteria<ProteinSummary> exportCriteria,
+            AsyncCallback<String> callback);
+    
     /** @see IPhosphoNetXClientService#getProteinByExperiment(TechId, TechId) */
     public void getProteinByExperiment(TechId experimentID, TechId proteinReferenceID,
             AsyncCallback<ProteinByExperiment> callback);
diff --git a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/client/application/Dict.java b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/client/application/Dict.java
index 92d022f3ec1..0e2904ddc8f 100644
--- a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/client/application/Dict.java
+++ b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/client/application/Dict.java
@@ -42,6 +42,11 @@ public class Dict
     public static final String FALSE_DISCOVERY_RATE = "false_discovery_rate";
 
     public static final String DATA_SET = "data_set";
+    
+    public static final String PROTEIN_BROWSER = "protein_browser";
+    
+    public static final String PROTEIN_SUMMARY = "protein_summary";
+    
 
     // Protein Viewer
     public static final String PROTEIN_IN_EXPERIMENT_TAB_LABEL = "protein_in_experiment_tab_label";
@@ -60,6 +65,8 @@ public class Dict
 
     public static final String DATA_SET_PERM_ID = "data_set_perm_id";
 
+    public static final String PROTEIN_COUNT = "protein_count";
+    
     public static final String PEPTIDE_COUNT = "peptide_count";
 
     public static final String PEPTIDES = "peptides";
diff --git a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/client/application/PhosphoNetXDisplayTypeIDGenerator.java b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/client/application/PhosphoNetXDisplayTypeIDGenerator.java
index d5c2e90be58..72097342ead 100644
--- a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/client/application/PhosphoNetXDisplayTypeIDGenerator.java
+++ b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/client/application/PhosphoNetXDisplayTypeIDGenerator.java
@@ -26,6 +26,8 @@ public enum PhosphoNetXDisplayTypeIDGenerator implements IDisplayTypeIDGenerator
     PROTEIN_BY_EXPERIMENT_BROWSER_GRID("protein-by-experiment-browser-grid"),
 
     PROTEIN_SEQUENCE_BROWSER_GRID("protein-sequence-browser-grid"),
+    
+    PROTEIN_SUMMARY_BROWSER_GRID("protein-summary-browser-grid"),
 
     DATA_SET_PROTEIN_BROWSER_GRID("data-set-protein-browser-grid"), ;
 
diff --git a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/client/application/ProteinByExperimentBrowerToolBar.java b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/client/application/ProteinByExperimentBrowerToolBar.java
index 3569f638e96..73dbdb7f616 100644
--- a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/client/application/ProteinByExperimentBrowerToolBar.java
+++ b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/client/application/ProteinByExperimentBrowerToolBar.java
@@ -24,6 +24,7 @@ import com.extjs.gxt.ui.client.event.Listener;
 import com.extjs.gxt.ui.client.event.SelectionChangedEvent;
 import com.extjs.gxt.ui.client.event.SelectionChangedListener;
 import com.extjs.gxt.ui.client.store.ListStore;
+import com.extjs.gxt.ui.client.widget.form.CheckBox;
 import com.extjs.gxt.ui.client.widget.form.ComboBox;
 import com.extjs.gxt.ui.client.widget.toolbar.LabelToolItem;
 import com.extjs.gxt.ui.client.widget.toolbar.ToolBar;
@@ -34,7 +35,6 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.application.GenericCon
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.IViewContext;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.model.NonHierarchicalBaseModelData;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.model.VocabularyTermModel;
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.field.CheckBoxField;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.field.ExperimentChooserField;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.field.IChosenEntityListener;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.field.VocabularyTermSelectionWidget;
@@ -159,12 +159,14 @@ class ProteinByExperimentBrowerToolBar extends ToolBar
 
     private final VocabularyTermSelectionWidget treatmentTypeComboBox;
 
-    private final CheckBoxField aggregateOriginalCheckBox;
+    private final CheckBox aggregateOriginalCheckBox;
 
     private ProteinByExperimentBrowserGrid browserGrid;
 
     private Experiment experiment;
 
+    private ProteinSummaryGrid summaryGrid;
+
     ProteinByExperimentBrowerToolBar(IViewContext<IPhosphoNetXClientServiceAsync> viewContext)
     {
         this.viewContext = viewContext;
@@ -232,7 +234,7 @@ class ProteinByExperimentBrowerToolBar extends ToolBar
         add(treatmentTypeComboBox);
         add(new LabelToolItem(viewContext.getMessage(Dict.AGGREGATE_ORIGINAL_LABEL)
                 + GenericConstants.LABEL_SEPARATOR));
-        aggregateOriginalCheckBox = new CheckBoxField("aggregateOriginal", false);
+        aggregateOriginalCheckBox = new CheckBox();
         aggregateOriginalCheckBox.addListener(Events.Change, new Listener<BaseEvent>()
             {
 
@@ -297,16 +299,23 @@ class ProteinByExperimentBrowerToolBar extends ToolBar
     {
         this.browserGrid = browserGrid;
     }
+    
+    void setSummaryGrid(ProteinSummaryGrid summaryGrid)
+    {
+        this.summaryGrid = summaryGrid;
+    }
 
     void update()
     {
         if (experiment != null)
         {
+            TechId experimentID = TechId.create(experiment);
+            summaryGrid.setLoadMaskImmediately(true);
+            summaryGrid.update(experimentID);
             browserGrid.setLoadMaskImmediately(true);
             double falseDiscoveryRate = getSelection(fdrComboBox, 0.0);
             AggregateFunction aggregateFunction =
                     getSelection(aggregateFunctionComboBox, DEFAULT_AGGREGATE_FUNCTION);
-            TechId experimentID = TechId.create(experiment);
             VocabularyTermModel value = treatmentTypeComboBox.getValue();
             String treatmentTypeCode = value == null ? null : value.getTerm().getCode();
             AsyncCallback<List<AbundanceColumnDefinition>> callback =
diff --git a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/client/application/ProteinByExperimentBrowserGrid.java b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/client/application/ProteinByExperimentBrowserGrid.java
index aaeb5d72c1d..6c159e592c5 100644
--- a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/client/application/ProteinByExperimentBrowserGrid.java
+++ b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/client/application/ProteinByExperimentBrowserGrid.java
@@ -22,6 +22,14 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
+import com.extjs.gxt.ui.client.widget.Component;
+import com.extjs.gxt.ui.client.widget.LayoutContainer;
+import com.extjs.gxt.ui.client.widget.TabItem;
+import com.extjs.gxt.ui.client.widget.TabPanel;
+import com.extjs.gxt.ui.client.widget.layout.FitLayout;
+import com.extjs.gxt.ui.client.widget.layout.RowData;
+import com.extjs.gxt.ui.client.widget.layout.RowLayout;
+
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.AbstractAsyncCallback;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.GenericConstants;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.IViewContext;
@@ -34,6 +42,7 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.grid.Ab
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.grid.ColumnDefsAndConfigs;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.grid.ICellListener;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.grid.IDisposableComponent;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.util.IMessageProvider;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.DefaultResultSetConfig;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ResultSet;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.TableExportCriteria;
@@ -71,15 +80,60 @@ class ProteinByExperimentBrowserGrid extends AbstractSimpleBrowserGrid<ProteinIn
     private ListProteinByExperimentCriteria criteria;
 
     private List<AbundanceColumnDefinition> abundanceColumnDefinitions;
-
+    
     static IDisposableComponent create(
             final IViewContext<IPhosphoNetXClientServiceAsync> viewContext)
     {
-        final ProteinByExperimentBrowserGrid browserGrid =
+        final IDisposableComponent summaryGrid = ProteinSummaryGrid.create(viewContext);
+        ProteinByExperimentBrowserGrid browserGrid =
                 new ProteinByExperimentBrowserGrid(viewContext);
-        return browserGrid.asDisposableWithToolbar(browserGrid.toolbar);
+        final IDisposableComponent disposableBrowerGrid = browserGrid.asDisposableWithoutToolbar();
+        ProteinByExperimentBrowerToolBar toolBar = browserGrid.toolbar;
+        toolBar.setSummaryGrid((ProteinSummaryGrid) summaryGrid.getComponent());
+        final LayoutContainer container = new LayoutContainer();
+        container.setLayout(new RowLayout());
+        container.add(toolBar);
+        TabPanel tabPanel = new TabPanel();
+        tabPanel.add(createTab(disposableBrowerGrid, viewContext, Dict.PROTEIN_BROWSER));
+        tabPanel.add(createTab(summaryGrid, viewContext, Dict.PROTEIN_SUMMARY));
+        container.add(tabPanel, new RowData(1, 1));
+        return new IDisposableComponent()
+            {
+                public void update(Set<DatabaseModificationKind> observedModifications)
+                {
+                    disposableBrowerGrid.update(observedModifications);
+                    summaryGrid.update(observedModifications);
+                }
+
+                public DatabaseModificationKind[] getRelevantModifications()
+                {
+                    return disposableBrowerGrid.getRelevantModifications();
+                }
+
+                public Component getComponent()
+                {
+                    return container;
+                }
+
+                public void dispose()
+                {
+                    disposableBrowerGrid.dispose();
+                    summaryGrid.dispose();
+                }
+            };
     }
 
+    private static TabItem createTab(IDisposableComponent disposableComponent,
+            IMessageProvider messageProvider, String titleKey)
+    {
+        TabItem tabItem = new TabItem(messageProvider.getMessage(titleKey));
+        tabItem.setLayout(new FitLayout());
+        Component component = disposableComponent.getComponent();
+        component.setHeight("100%");
+        tabItem.add(component);
+        return tabItem;
+    }
+    
     private ProteinByExperimentBrowserGrid(
             final IViewContext<IPhosphoNetXClientServiceAsync> viewContext)
     {
diff --git a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/client/application/ProteinSummaryGrid.java b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/client/application/ProteinSummaryGrid.java
new file mode 100644
index 00000000000..80e6fe30c69
--- /dev/null
+++ b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/client/application/ProteinSummaryGrid.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2009 ETH Zuerich, CISD
+ *
+ * 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 ch.systemsx.cisd.openbis.plugin.phosphonetx.client.web.client.application;
+
+import java.util.List;
+
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.AbstractAsyncCallback;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.GenericConstants;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.IViewContext;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.columns.framework.IColumnDefinitionKind;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.grid.AbstractSimpleBrowserGrid;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.grid.IDisposableComponent;
+import ch.systemsx.cisd.openbis.generic.client.web.client.dto.DefaultResultSetConfig;
+import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ResultSet;
+import ch.systemsx.cisd.openbis.generic.client.web.client.dto.TableExportCriteria;
+import ch.systemsx.cisd.openbis.generic.shared.basic.IColumnDefinition;
+import ch.systemsx.cisd.openbis.generic.shared.basic.TechId;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseModificationKind;
+import ch.systemsx.cisd.openbis.plugin.phosphonetx.client.web.client.IPhosphoNetXClientServiceAsync;
+import ch.systemsx.cisd.openbis.plugin.phosphonetx.client.web.client.application.columns.ProteinSummaryColDefKind;
+import ch.systemsx.cisd.openbis.plugin.phosphonetx.client.web.client.dto.ListProteinSummaryByExperimentCriteria;
+import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.ProteinSummary;
+
+/**
+ * 
+ *
+ * @author Franz-Josef Elmer
+ */
+class ProteinSummaryGrid extends AbstractSimpleBrowserGrid<ProteinSummary>
+{
+    private static final String PREFIX =
+            GenericConstants.ID_PREFIX + "protein-summary";
+
+    // browser consists of the grid and additional toolbars (paging, filtering)
+    public static final String BROWSER_ID = PREFIX + "_main";
+
+    public static final String GRID_ID = PREFIX + "_grid";
+
+    static IDisposableComponent create(IViewContext<IPhosphoNetXClientServiceAsync> viewContext)
+    {
+        return new ProteinSummaryGrid(viewContext).asDisposableWithoutToolbar();
+    }
+
+    private final IViewContext<IPhosphoNetXClientServiceAsync> specificViewContext;
+
+    private ListProteinSummaryByExperimentCriteria criteria;
+
+    ProteinSummaryGrid(IViewContext<IPhosphoNetXClientServiceAsync> viewContext)
+    {
+        super(viewContext.getCommonViewContext(), BROWSER_ID, GRID_ID, false,
+                PhosphoNetXDisplayTypeIDGenerator.PROTEIN_SUMMARY_BROWSER_GRID);
+        specificViewContext = viewContext;
+    }
+    
+    void update(TechId experimentID)
+    {
+        criteria = new ListProteinSummaryByExperimentCriteria();
+        criteria.setExperimentID(experimentID);
+        refresh(true);
+    }
+    
+    @Override
+    protected IColumnDefinitionKind<ProteinSummary>[] getStaticColumnsDefinition()
+    {
+        return ProteinSummaryColDefKind.values();
+    }
+
+    @Override
+    protected List<IColumnDefinition<ProteinSummary>> getInitialFilters()
+    {
+        return asColumnFilters(new ProteinSummaryColDefKind[0]);
+    }
+
+    @Override
+    protected void listEntities(DefaultResultSetConfig<String, ProteinSummary> resultSetConfig,
+            AbstractAsyncCallback<ResultSet<ProteinSummary>> callback)
+    {
+        if (criteria != null)
+        {
+            criteria.copyPagingConfig(resultSetConfig);
+            specificViewContext.getService().listProteinSummariesByExperiment(criteria, callback);
+        }
+    }
+
+    @Override
+    protected void prepareExportEntities(TableExportCriteria<ProteinSummary> exportCriteria,
+            AbstractAsyncCallback<String> callback)
+    {
+        specificViewContext.getService().prepareExportProteinSummary(exportCriteria, callback);
+    }
+
+    public DatabaseModificationKind[] getRelevantModifications()
+    {
+        return new DatabaseModificationKind[0];
+    }
+
+}
diff --git a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/client/application/columns/ProteinSummaryColDefKind.java b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/client/application/columns/ProteinSummaryColDefKind.java
new file mode 100644
index 00000000000..cdbb6283ee7
--- /dev/null
+++ b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/client/application/columns/ProteinSummaryColDefKind.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2009 ETH Zuerich, CISD
+ *
+ * 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 ch.systemsx.cisd.openbis.plugin.phosphonetx.client.web.client.application.columns;
+
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.columns.framework.AbstractColumnDefinitionKind;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.columns.framework.IColumnDefinitionKind;
+import ch.systemsx.cisd.openbis.generic.shared.basic.GridRowModel;
+import ch.systemsx.cisd.openbis.plugin.phosphonetx.client.web.client.application.Dict;
+import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.ProteinSummary;
+
+/**
+ * 
+ *
+ * @author Franz-Josef Elmer
+ */
+public enum ProteinSummaryColDefKind implements IColumnDefinitionKind<ProteinSummary>
+{
+    FDR(new AbstractColumnDefinitionKind<ProteinSummary>(Dict.FDR)
+        {
+            @Override
+            public String tryGetValue(ProteinSummary entity)
+            {
+                return Double.toString(entity.getFDR());
+            }
+
+            @Override
+            public Comparable<?> getComparableValue(GridRowModel<ProteinSummary> entity)
+            {
+                return entity.getOriginalObject().getFDR();
+            }
+        }), PROTEIN_COUNT(new AbstractColumnDefinitionKind<ProteinSummary>(Dict.PROTEIN_COUNT)
+        {
+            @Override
+            public String tryGetValue(ProteinSummary entity)
+            {
+                return Integer.toString(entity.getProteinCount());
+            }
+
+            @Override
+            public Comparable<?> getComparableValue(GridRowModel<ProteinSummary> entity)
+            {
+                return entity.getOriginalObject().getProteinCount();
+            }
+        }), PEPTIDE_COUNT(new AbstractColumnDefinitionKind<ProteinSummary>(Dict.PEPTIDE_COUNT)
+        {
+            @Override
+            public String tryGetValue(ProteinSummary entity)
+            {
+                return Integer.toString(entity.getPeptideCount());
+            }
+
+            @Override
+            public Comparable<?> getComparableValue(GridRowModel<ProteinSummary> entity)
+            {
+                return entity.getOriginalObject().getPeptideCount();
+            }
+        }),            ;
+    
+    private final AbstractColumnDefinitionKind<ProteinSummary> columnDefinitionKind;
+
+    private ProteinSummaryColDefKind(AbstractColumnDefinitionKind<ProteinSummary> columnDefinitionKind)
+    {
+        this.columnDefinitionKind = columnDefinitionKind;
+    }
+
+    public String id()
+    {
+        return name();
+    }
+
+    public AbstractColumnDefinitionKind<ProteinSummary> getDescriptor()
+    {
+        return columnDefinitionKind;
+    }
+
+
+}
diff --git a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/client/dto/ListProteinSummaryByExperimentCriteria.java b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/client/dto/ListProteinSummaryByExperimentCriteria.java
new file mode 100644
index 00000000000..935a217acf3
--- /dev/null
+++ b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/client/dto/ListProteinSummaryByExperimentCriteria.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2009 ETH Zuerich, CISD
+ *
+ * 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 ch.systemsx.cisd.openbis.plugin.phosphonetx.client.web.client.dto;
+
+import com.google.gwt.user.client.rpc.IsSerializable;
+
+import ch.systemsx.cisd.openbis.generic.client.web.client.dto.DefaultResultSetConfig;
+import ch.systemsx.cisd.openbis.generic.shared.basic.TechId;
+import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.ProteinSummary;
+
+/**
+ * 
+ *
+ * @author Franz-Josef Elmer
+ */
+public class ListProteinSummaryByExperimentCriteria extends DefaultResultSetConfig<String, ProteinSummary>
+        implements IsSerializable
+{
+    private TechId experimentID;
+
+    public final TechId getExperimentID()
+    {
+        return experimentID;
+    }
+
+    public final void setExperimentID(TechId experimentID)
+    {
+        this.experimentID = experimentID;
+    }
+
+}
diff --git a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/public/phosphonetx-dictionary.js b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/public/phosphonetx-dictionary.js
index 6e6db44b7f2..6a2876facb3 100644
--- a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/public/phosphonetx-dictionary.js
+++ b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/public/phosphonetx-dictionary.js
@@ -12,18 +12,21 @@ var phosphonetx = {
   // Protein grid
   accession_number: "Accession Number",
   protein_description: "Protein",
-  coverage: "Coverage",
+  coverage: "Protein Coverage (in %)",
   false_discovery_rate: "FDR",
   
   // Protein in experiment viewer
   protein_in_experiment_tab_label: "{0} in {1}",
   experiment_label: "Experiment",
   sequence_short_name: "",
+  protein_browser: "Proteins",
+  protein_summary: "Protein/Peptide Counts",
   database_name_and_version: "Database",
   sequence: "Amino Acid Sequence",
   sequences: "Amino Acid Sequences",
   data_set_proteins: "Data Sets",
   data_set_perm_id: "Data Set",
+  protein_count: "Proteins",
   peptide_count: "Peptides",
   peptides: "Peptides ({0})",
   sequence_name: "Sequence",
diff --git a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/server/ListProteinSummaryProvider.java b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/server/ListProteinSummaryProvider.java
new file mode 100644
index 00000000000..35a3f45637b
--- /dev/null
+++ b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/server/ListProteinSummaryProvider.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2009 ETH Zuerich, CISD
+ *
+ * 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 ch.systemsx.cisd.openbis.plugin.phosphonetx.client.web.server;
+
+import java.util.List;
+
+import ch.systemsx.cisd.common.exceptions.UserFailureException;
+import ch.systemsx.cisd.openbis.generic.client.web.server.resultset.IOriginalDataProvider;
+import ch.systemsx.cisd.openbis.generic.shared.basic.TechId;
+import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.IPhosphoNetXServer;
+import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.ProteinSummary;
+
+/**
+ * 
+ *
+ * @author Franz-Josef Elmer
+ */
+class ListProteinSummaryProvider implements IOriginalDataProvider<ProteinSummary>
+{
+    private final IPhosphoNetXServer server;
+    private final String sessionToken;
+    private final TechId experimentID;
+
+    ListProteinSummaryProvider(IPhosphoNetXServer server, String sessionToken,
+            TechId experimentID)
+    {
+        this.server = server;
+        this.sessionToken = sessionToken;
+        this.experimentID = experimentID;
+    }
+
+    public List<ProteinSummary> getOriginalData() throws UserFailureException
+    {
+        return server.listProteinSummariesByExperiment(sessionToken, experimentID);
+    }
+
+}
diff --git a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/server/PhosphoNetXClientService.java b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/server/PhosphoNetXClientService.java
index 96a748d55f2..c09d7148368 100644
--- a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/server/PhosphoNetXClientService.java
+++ b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/server/PhosphoNetXClientService.java
@@ -35,6 +35,7 @@ import ch.systemsx.cisd.openbis.plugin.phosphonetx.client.web.client.IPhosphoNet
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.client.web.client.dto.ListProteinByExperimentAndReferenceCriteria;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.client.web.client.dto.ListProteinByExperimentCriteria;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.client.web.client.dto.ListProteinSequenceCriteria;
+import ch.systemsx.cisd.openbis.plugin.phosphonetx.client.web.client.dto.ListProteinSummaryByExperimentCriteria;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.client.web.client.dto.ListSampleAbundanceByProteinCriteria;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.IPhosphoNetXServer;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.ResourceNames;
@@ -44,6 +45,7 @@ import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.DataSetProte
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.ProteinByExperiment;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.ProteinInfo;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.ProteinSequence;
+import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.ProteinSummary;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.SampleWithPropertiesAndAbundance;
 
 /**
@@ -105,6 +107,19 @@ public class PhosphoNetXClientService extends AbstractClientService implements
         return prepareExportEntities(exportCriteria);
     }
 
+    public ResultSet<ProteinSummary> listProteinSummariesByExperiment(ListProteinSummaryByExperimentCriteria criteria)
+    throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException
+    {
+        final String sessionToken = getSessionToken();
+        return listEntities(criteria, new ListProteinSummaryProvider(server, sessionToken, criteria.getExperimentID()));
+    }
+    
+    public String prepareExportProteinSummary(TableExportCriteria<ProteinSummary> exportCriteria)
+    throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException
+    {
+        return prepareExportEntities(exportCriteria);
+    }
+    
     public ProteinByExperiment getProteinByExperiment(TechId experimentID, TechId proteinReferenceID)
             throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException
     {
diff --git a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/PhosphoNetXServer.java b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/PhosphoNetXServer.java
index cedf3d99cc6..fca57b6d970 100644
--- a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/PhosphoNetXServer.java
+++ b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/PhosphoNetXServer.java
@@ -45,6 +45,7 @@ import ch.systemsx.cisd.openbis.plugin.phosphonetx.server.business.IDataSetProte
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.server.business.IProteinDetailsBO;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.server.business.IProteinSequenceTable;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.server.business.IProteinInfoTable;
+import ch.systemsx.cisd.openbis.plugin.phosphonetx.server.business.IProteinSummaryTable;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.server.business.ISampleTable;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.server.dataaccess.IPhosphoNetXDAOFactory;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.server.dataaccess.IProteinQueryDAO;
@@ -56,6 +57,7 @@ import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.DataSetProte
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.ProteinByExperiment;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.ProteinInfo;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.ProteinSequence;
+import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.ProteinSummary;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.SampleWithPropertiesAndAbundance;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.dto.ProteinReference;
 
@@ -138,6 +140,15 @@ public class PhosphoNetXServer extends AbstractServer<IPhosphoNetXServer> implem
         return table.getProteinInfos();
     }
 
+    public List<ProteinSummary> listProteinSummariesByExperiment(String sessionToken,
+            TechId experimentId) throws UserFailureException
+    {
+        final Session session = getSession(sessionToken);
+        IProteinSummaryTable summaryTable = specificBOFactory.createProteinSummaryTable(session);
+        summaryTable.load(experimentId);
+        return summaryTable.getProteinSummaries();
+    }
+
     public ProteinByExperiment getProteinByExperiment(String sessionToken, TechId experimentID,
             TechId proteinReferenceID) throws UserFailureException
     {
diff --git a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/PhosphoNetXServerLogger.java b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/PhosphoNetXServerLogger.java
index 4222fd2b29f..2f3197c65ea 100644
--- a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/PhosphoNetXServerLogger.java
+++ b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/PhosphoNetXServerLogger.java
@@ -31,6 +31,7 @@ import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.DataSetProte
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.ProteinByExperiment;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.ProteinInfo;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.ProteinSequence;
+import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.ProteinSummary;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.SampleWithPropertiesAndAbundance;
 
 /**
@@ -70,6 +71,14 @@ public class PhosphoNetXServerLogger extends AbstractServerLogger implements IPh
                         .getLabel(), treatmentTypeCode, aggregateOnOriginal);
         return null;
     }
+    
+    public List<ProteinSummary> listProteinSummariesByExperiment(String sessionToken,
+            TechId experimentId) throws UserFailureException
+            {
+        logAccess(sessionToken, "list_protein_summaries_by_experiment", "EXPERIMENT_ID(%s)",
+                experimentId);
+        return null;
+            }
 
     public ProteinByExperiment getProteinByExperiment(String sessionToken, TechId experimentId,
             TechId proteinReferenceID) throws UserFailureException
diff --git a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/business/BusinessObjectFactory.java b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/business/BusinessObjectFactory.java
index 602794065a4..00460f7cc89 100644
--- a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/business/BusinessObjectFactory.java
+++ b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/business/BusinessObjectFactory.java
@@ -47,6 +47,11 @@ public class BusinessObjectFactory implements IBusinessObjectFactory
         return new ProteinInfoTable(daoFactory, specificDAOFactory, session);
     }
 
+    public IProteinSummaryTable createProteinSummaryTable(Session session)
+    {
+        return new ProteinSummaryTable(daoFactory, specificDAOFactory, session);
+    }
+    
     public IProteinSequenceTable createProteinSequenceTable(Session session)
     {
         return new ProteinSequenceTable(daoFactory, specificDAOFactory, session);
diff --git a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/business/ErrorModel.java b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/business/ErrorModel.java
index 7b8fcb78faa..91a88da70a9 100644
--- a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/business/ErrorModel.java
+++ b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/business/ErrorModel.java
@@ -107,11 +107,19 @@ class ErrorModel
         ProbabilityToFDRCalculator calculator = getCalculator(protein.getDataSetID());
         return calculator.calculateFDR(protein.getProbability()) <= falseDiscoveryRate;
     }
-
+    
     void setFalseDiscoveryRateFor(IdentifiedProtein protein)
     {
-        ProbabilityToFDRCalculator calculator = getCalculator(protein.getDataSetID());
-        protein.setFalseDiscoveryRate(calculator.calculateFDR(protein.getProbability()));
+        long dataSetID = protein.getDataSetID();
+        double probability = protein.getProbability();
+        protein.setFalseDiscoveryRate(calculateFalsDiscoveryRate(dataSetID, probability));
+    }
+
+    double calculateFalsDiscoveryRate(long dataSetID, double probability)
+    {
+        ProbabilityToFDRCalculator calculator = getCalculator(dataSetID);
+        double fdr = calculator.calculateFDR(probability);
+        return fdr;
     }
 
     private ProbabilityToFDRCalculator getCalculator(long dataSetID)
diff --git a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/business/IBusinessObjectFactory.java b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/business/IBusinessObjectFactory.java
index f36a260a889..2ab6190df08 100644
--- a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/business/IBusinessObjectFactory.java
+++ b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/business/IBusinessObjectFactory.java
@@ -29,6 +29,8 @@ public interface IBusinessObjectFactory
     
     public IProteinInfoTable createProteinInfoTable(Session session);
     
+    public IProteinSummaryTable createProteinSummaryTable(Session session);
+    
     public IProteinSequenceTable createProteinSequenceTable(Session session);
     
     public IDataSetProteinTable createDataSetProteinTable(Session session);
diff --git a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/business/IProteinSummaryTable.java b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/business/IProteinSummaryTable.java
new file mode 100644
index 00000000000..a964c7fa627
--- /dev/null
+++ b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/business/IProteinSummaryTable.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2009 ETH Zuerich, CISD
+ *
+ * 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 ch.systemsx.cisd.openbis.plugin.phosphonetx.server.business;
+
+import java.util.List;
+
+import ch.systemsx.cisd.openbis.generic.shared.basic.TechId;
+import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.ProteinSummary;
+
+/**
+ * 
+ *
+ * @author Franz-Josef Elmer
+ */
+public interface IProteinSummaryTable
+{
+
+    public void load(TechId experimentID);
+
+    public List<ProteinSummary> getProteinSummaries();
+
+}
diff --git a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/business/ProteinSummaryTable.java b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/business/ProteinSummaryTable.java
new file mode 100644
index 00000000000..c891781b433
--- /dev/null
+++ b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/business/ProteinSummaryTable.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright 2009 ETH Zuerich, CISD
+ *
+ * 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 ch.systemsx.cisd.openbis.plugin.phosphonetx.server.business;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import net.lemnik.eodsql.DataSet;
+
+import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory;
+import ch.systemsx.cisd.openbis.generic.server.dataaccess.IExperimentDAO;
+import ch.systemsx.cisd.openbis.generic.shared.basic.TechId;
+import ch.systemsx.cisd.openbis.generic.shared.dto.Session;
+import ch.systemsx.cisd.openbis.plugin.phosphonetx.server.dataaccess.IPhosphoNetXDAOFactory;
+import ch.systemsx.cisd.openbis.plugin.phosphonetx.server.dataaccess.IProteinQueryDAO;
+import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.ProteinSummary;
+import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.dto.ProteinReferenceWithProbabilityAndPeptide;
+
+/**
+ * 
+ *
+ * @author Franz-Josef Elmer
+ */
+class ProteinSummaryTable extends AbstractBusinessObject implements IProteinSummaryTable
+{
+    private static final double[] FDR_LEVELS = new double[] {0, 0.01, 0.025, 0.05, 0.1};
+    
+    private static final class Counter
+    {
+        private final double fdrLevel;
+        private final Set<Long> proteins;
+        private final Set<String> peptides;
+
+        Counter(double fdrLevel)
+        {
+            this.fdrLevel = fdrLevel;
+            proteins = new HashSet<Long>();
+            peptides = new HashSet<String>();
+        }
+        
+        public ProteinSummary getProteinSummary()
+        {
+            ProteinSummary proteinSummary = new ProteinSummary();
+            proteinSummary.setFDR(fdrLevel);
+            proteinSummary.setProteinCount(proteins.size());
+            proteinSummary.setPeptideCount(peptides.size());
+            return proteinSummary;
+        }
+
+        public void handle(double fdr, ProteinReferenceWithProbabilityAndPeptide protein)
+        {
+            if (fdr <= fdrLevel)
+            {
+                proteins.add(protein.getId());
+                peptides.add(protein.getPeptideSequence());
+            }
+        }
+    }
+    
+    private List<ProteinSummary> summaries;
+    
+    ProteinSummaryTable(IDAOFactory daoFactory, IPhosphoNetXDAOFactory specificDAOFactory,
+            Session session)
+    {
+        super(daoFactory, specificDAOFactory, session);
+    }
+
+    public List<ProteinSummary> getProteinSummaries()
+    {
+        return summaries;
+    }
+
+    public void load(TechId experimentID)
+    {
+        IExperimentDAO experimentDAO = getDaoFactory().getExperimentDAO();
+        String permID = experimentDAO.getByTechId(experimentID).getPermId();
+        IProteinQueryDAO dao = getSpecificDAOFactory().getProteinQueryDAO();
+        ErrorModel errorModel = new ErrorModel(getSpecificDAOFactory());
+        DataSet<ProteinReferenceWithProbabilityAndPeptide> resultSet = dao.listProteinsWithProbabilityAndPeptidesByExperiment(permID);
+        List<Counter> counters = new ArrayList<Counter>(FDR_LEVELS.length);
+        for (double fdrLevel : FDR_LEVELS)
+        {
+            counters.add(new Counter(fdrLevel));
+        }
+        try
+        {
+            for (ProteinReferenceWithProbabilityAndPeptide protein : resultSet)
+            {
+                long dataSetID = protein.getDataSetID();
+                double probability = protein.getProbability();
+                double fdr = errorModel.calculateFalsDiscoveryRate(dataSetID, probability);
+                for (Counter counter : counters)
+                {
+                    counter.handle(fdr, protein);
+                }
+            }
+            summaries = new ArrayList<ProteinSummary>(counters.size());
+            for (Counter counter : counters)
+            {
+                summaries.add(counter.getProteinSummary());
+            }
+        } finally
+        {
+            resultSet.close();
+        }
+    }
+
+}
diff --git a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/dataaccess/IProteinQueryDAO.java b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/dataaccess/IProteinQueryDAO.java
index 9ea1d906da7..1d9f8daeeeb 100644
--- a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/dataaccess/IProteinQueryDAO.java
+++ b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/dataaccess/IProteinQueryDAO.java
@@ -26,6 +26,7 @@ import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.dto.ProbabilityFDRMapp
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.dto.ProteinReference;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.dto.ProteinReferenceWithPeptideSequence;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.dto.ProteinReferenceWithProbability;
+import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.dto.ProteinReferenceWithProbabilityAndPeptide;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.dto.SampleAbundance;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.dto.Sequence;
 
@@ -50,6 +51,16 @@ public interface IProteinQueryDAO extends BaseQuery
             + "left join samples on a.samp_id = samples.id "
             + "where e.perm_id = ?{1} order by pr.accession_number, samples.perm_id")
     public DataSet<ProteinReferenceWithProbability> listProteinsByExperiment(String experimentPermID);
+
+    @Select(sql = "select p.dase_id as data_set_id, p.probability, s.prre_id as id, pe.sequence "
+            + "from identified_proteins as ip left join sequences as s on ip.sequ_id = s.id "
+            + "left join proteins as p on ip.prot_id = p.id "
+            + "left join peptides as pe on pe.prot_id = p.id "
+            + "left join data_sets as d on p.dase_id = d.id "
+            + "left join experiments as e on d.expe_id = e.id " 
+            + "where e.perm_id = ?{1} ")
+    public DataSet<ProteinReferenceWithProbabilityAndPeptide> listProteinsWithProbabilityAndPeptidesByExperiment(
+            String experimentPermID);
     
     @Select("select distinct s.prre_id, s.amino_acid_sequence, pe.sequence " 
             + "from identified_proteins as ip "
diff --git a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/shared/IPhosphoNetXServer.java b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/shared/IPhosphoNetXServer.java
index ce73f84b4ce..8935dcee6f7 100644
--- a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/shared/IPhosphoNetXServer.java
+++ b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/shared/IPhosphoNetXServer.java
@@ -34,6 +34,7 @@ import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.DataSetProte
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.ProteinByExperiment;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.ProteinInfo;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.ProteinSequence;
+import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.ProteinSummary;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.SampleWithPropertiesAndAbundance;
 
 /**
@@ -61,6 +62,13 @@ public interface IPhosphoNetXServer extends IServer
             TechId experimentId, double falseDiscoveryRate, AggregateFunction function,
             String treatmentTypeCode, boolean aggregateOnOriginal) throws UserFailureException;
     
+    
+    @Transactional
+    @RolesAllowed(RoleSet.OBSERVER)
+    public List<ProteinSummary> listProteinSummariesByExperiment(String sessionToken,
+            @AuthorizationGuard(guardClass = ExperimentTechIdPredicate.class) TechId experimentId)
+            throws UserFailureException;
+    
     @Transactional
     @RolesAllowed(RoleSet.OBSERVER)
     public ProteinByExperiment getProteinByExperiment(String sessionToken,
diff --git a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/shared/basic/dto/ProteinInfo.java b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/shared/basic/dto/ProteinInfo.java
index acfe23f355e..f53b613680e 100644
--- a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/shared/basic/dto/ProteinInfo.java
+++ b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/shared/basic/dto/ProteinInfo.java
@@ -43,22 +43,6 @@ public class ProteinInfo implements Serializable, IsSerializable
     
     private String description;
     
-    /*
-* New column: Protein Coverage. It contains the ratio (in %)
-
-sum of the lengths of all peptide sequences / length of the protein sequence
-
-where overlapping peptide sequences count only once.
-* New table:
-
-|FDR|0|1|2.5|5|10|
-|Number of Proteins|..|..|..|..|..|
-|Number of Peptides|..|..|..|..|..|
-
-These values are the number of proteins/peptides per experiment for FDR value less than or equal the specified one. 
-
-This table could appear in the same tab as 'Protein of an Experiment' table.
-     */
     private double coverage;
     
     private Map<Long, Double> abundances;
diff --git a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/shared/basic/dto/ProteinSummary.java b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/shared/basic/dto/ProteinSummary.java
new file mode 100644
index 00000000000..a6bba8abacc
--- /dev/null
+++ b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/shared/basic/dto/ProteinSummary.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2009 ETH Zuerich, CISD
+ *
+ * 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 ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto;
+
+import java.io.Serializable;
+
+import com.google.gwt.user.client.rpc.IsSerializable;
+
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ServiceVersionHolder;
+
+/**
+ * 
+ *
+ * @author Franz-Josef Elmer
+ */
+public class ProteinSummary implements Serializable, IsSerializable
+{
+    private static final long serialVersionUID = ServiceVersionHolder.VERSION;
+    private double fdr;
+    
+    private int proteinCount;
+    
+    private int peptideCount;
+
+    public double getFDR()
+    {
+        return fdr;
+    }
+
+    public void setFDR(double fdr)
+    {
+        this.fdr = fdr;
+    }
+
+    public int getProteinCount()
+    {
+        return proteinCount;
+    }
+
+    public void setProteinCount(int proteinCount)
+    {
+        this.proteinCount = proteinCount;
+    }
+
+    public int getPeptideCount()
+    {
+        return peptideCount;
+    }
+
+    public void setPeptideCount(int peptideCount)
+    {
+        this.peptideCount = peptideCount;
+    }
+    
+}
diff --git a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/shared/dto/ProteinReferenceWithPeptideSequence.java b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/shared/dto/ProteinReferenceWithPeptideSequence.java
index c1a29f78629..e61ffa75e27 100644
--- a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/shared/dto/ProteinReferenceWithPeptideSequence.java
+++ b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/shared/dto/ProteinReferenceWithPeptideSequence.java
@@ -28,6 +28,9 @@ public class ProteinReferenceWithPeptideSequence
     @ResultColumn("prre_id")
     private long id;
     
+    @ResultColumn("dase_id")
+    private long dataSetID;
+    
     @ResultColumn("amino_acid_sequence")
     private String proteinSequence;
 
@@ -44,6 +47,16 @@ public class ProteinReferenceWithPeptideSequence
         this.id = id;
     }
 
+    public long getDataSetID()
+    {
+        return dataSetID;
+    }
+    
+    public void setDataSetID(long dataSetID)
+    {
+        this.dataSetID = dataSetID;
+    }
+    
     public String getProteinSequence()
     {
         return proteinSequence;
@@ -63,5 +76,6 @@ public class ProteinReferenceWithPeptideSequence
     {
         this.peptideSequence = peptideSequence;
     }
+
     
 }
diff --git a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/shared/dto/ProteinReferenceWithProbabilityAndPeptide.java b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/shared/dto/ProteinReferenceWithProbabilityAndPeptide.java
new file mode 100644
index 00000000000..b0ec609f8d7
--- /dev/null
+++ b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/shared/dto/ProteinReferenceWithProbabilityAndPeptide.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2009 ETH Zuerich, CISD
+ *
+ * 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 ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.dto;
+
+import net.lemnik.eodsql.ResultColumn;
+
+/**
+ * 
+ *
+ * @author Franz-Josef Elmer
+ */
+public class ProteinReferenceWithProbabilityAndPeptide extends ProteinReferenceWithProbability
+{
+    @ResultColumn("sequence")
+    private String peptideSequence;
+
+    public String getPeptideSequence()
+    {
+        return peptideSequence;
+    }
+
+    public void setPeptideSequence(String peptideSequence)
+    {
+        this.peptideSequence = peptideSequence;
+    }
+
+}
-- 
GitLab