Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue 550 - Show modified peptide forms in sequence view #572

Closed
wants to merge 13 commits into from
Closed
41 changes: 37 additions & 4 deletions src/org/labkey/targetedms/TargetedMSController.java
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.function.Function;
import java.util.function.Predicate;
Expand Down Expand Up @@ -2384,6 +2385,8 @@ public static class ChromatogramForm extends AbstractChartForm
private boolean _update;
private Long _chromInfoId;
private Long _highlightChromInfoId;
private long _replicateId;
private String _peptideForm;

public ChromatogramForm()
{
Expand All @@ -2400,6 +2403,15 @@ public void setId(long id)
_id = id;
}

public long getReplicateId()
{
return _replicateId;
}

public void setReplicateId(long replicateId)
{
_replicateId = replicateId;
}

public String getReplicatesFilter()
{
Expand Down Expand Up @@ -2586,6 +2598,16 @@ public void setChromInfoId(Long chromInfoId)
{
_chromInfoId = chromInfoId;
}

public String getPeptideForm()
{
return _peptideForm;
}

public void setPeptideForm(String peptideForm)
{
_peptideForm = Objects.requireNonNullElse(peptideForm, PeptideCharacteristic.COMBINED_PEPTIDE);
}
}


Expand Down Expand Up @@ -4746,7 +4768,8 @@ public ModelAndView getView(final ChromatogramForm form, BindException errors)
// Peptide group details
VBox result = new VBox();

Integer peptideCount = addProteinSummaryViews(result, group, _run, getUser(), getContainer());
var showStackedPeptides = form._peptideForm != null && form._peptideForm.equalsIgnoreCase("stacked");
Integer peptideCount = addProteinSummaryViews(result, group, _run, form.getReplicateId(), showStackedPeptides);

GroupChromatogramsTableInfo tableInfo = new GroupChromatogramsTableInfo(new TargetedMSSchema(getUser(), getContainer()), form);
ChromatogramsDataRegion chromatogramRegion = new ChromatogramsDataRegion(getViewContext(), tableInfo,
Expand Down Expand Up @@ -4879,7 +4902,7 @@ private QueryView createViewWithNoContainerFilterOptions(QuerySettings settings,
return result;
}

public static Integer addProteinSummaryViews(VBox box, PeptideGroup group, TargetedMSRun run, User user, Container container)
public static Integer addProteinSummaryViews(VBox box, PeptideGroup group, TargetedMSRun run, @Nullable Long replicateId, boolean showStackedPeptides)
{
Integer peptideCount = TargetedMSManager.getPeptideGroupPeptideCount(run, group.getId());
boolean proteomics = peptideCount != null && peptideCount.intValue() > 0;
Expand All @@ -4893,10 +4916,20 @@ public static Integer addProteinSummaryViews(VBox box, PeptideGroup group, Targe
if (group.getSequenceId() != null)
{
int seqId = group.getSequenceId().intValue();
List<PeptideCharacteristic> peptideCharacteristics = new ArrayList<>(PeptideManager.getPeptideCharacteristic(group.getId()));
List<PeptideCharacteristic> combinedPeptideCharacteristics = new ArrayList<>(PeptideManager.getCombinedPeptideCharacteristics(group.getId(), replicateId));
List<PeptideCharacteristic> modifiedPeptideCharacteristics = new ArrayList<>(PeptideManager.getModifiedPeptideCharacteristics(group.getId(), replicateId));;

List<Replicate> replicates = ReplicateManager.getReplicatesForRun(run.getRunId());
List<org.labkey.api.ms.Replicate> msReplicates = new ArrayList<>();
replicates.forEach(replicate -> {
var rep = new org.labkey.api.ms.Replicate();
rep.setName(replicate.getName());
rep.setId(replicate.getId());
msReplicates.add(rep);
});

ProteinService proteinService = ProteinService.get();
WebPartView<?> sequenceView = proteinService.getProteinCoverageView(seqId, peptideCharacteristics, 100, true, group.getAccession());
WebPartView<?> sequenceView = proteinService.getProteinCoverageViewWithSettings(seqId, combinedPeptideCharacteristics, 100, true, group.getAccession(), msReplicates, modifiedPeptideCharacteristics, showStackedPeptides);

sequenceView.setTitle("Sequence Coverage");
sequenceView.enableExpandCollapse("SequenceCoverage", false);
Expand Down
12 changes: 12 additions & 0 deletions src/org/labkey/targetedms/parser/Replicate.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
*/
public class Replicate extends AnnotatedEntity<ReplicateAnnotation>
{
private long _id;
private long _runId;
private String _name;

Expand All @@ -36,6 +37,17 @@ public class Replicate extends AnnotatedEntity<ReplicateAnnotation>

private List<SampleFile> _sampleFileList;

@Override
public long getId()
{
return _id;
}

@Override
public void setId(long id)
{
_id = id;
}

public long getRunId()
{
Expand Down
2 changes: 1 addition & 1 deletion src/org/labkey/targetedms/passport/PassportController.java
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ public ModelAndView getView(ProteinForm form, BindException errors) throws IOExc
VBox result = new VBox();
PeptideGroup group = PeptideGroupManager.getPeptideGroup(getContainer(), _protein.getPepGroupId());
_run = TargetedMSManager.getRun(group.getRunId());
TargetedMSController.addProteinSummaryViews(result, group, _run, getUser(), getContainer());
TargetedMSController.addProteinSummaryViews(result, group, _run, null, false);

if (beforeAfter)
{
Expand Down
88 changes: 76 additions & 12 deletions src/org/labkey/targetedms/query/PeptideManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,22 @@

package org.labkey.targetedms.query;

import org.jetbrains.annotations.Nullable;
import org.labkey.api.cache.CacheLoader;
import org.labkey.api.cache.CacheManager;
import org.labkey.api.data.Container;
import org.labkey.api.data.DatabaseCache;
import org.labkey.api.data.SQLFragment;
import org.labkey.api.data.SqlSelector;
import org.labkey.api.data.dialect.SqlDialect;
import org.labkey.api.protein.PeptideCharacteristic;
import org.labkey.targetedms.TargetedMSManager;
import org.labkey.targetedms.parser.GeneralMoleculeChromInfo;
import org.labkey.targetedms.parser.Peptide;

import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.Set;

/**
Expand Down Expand Up @@ -94,18 +97,31 @@ public static Collection<Peptide> getPeptidesForGroup(long peptideGroupId)
return new SqlSelector(TargetedMSManager.getSchema(), sql).getArrayList(Peptide.class);
}

public static List<PeptideCharacteristic> getPeptideCharacteristic(long peptideGroupId)
private static String appendLog10IntensitySql(SqlDialect sqlDialect)
{
var sqlDialect = TargetedMSManager.getSqlDialect();
var pgLog10Intensity = "LOG(" + sqlDialect.getNumericCast(new SQLFragment("MAX(X.Intensity)")).getSQL() + ")";
var sqlServerLog10Intensity = "LOG10(MAX(X.Intensity))";
var pgConfidenceValueToRound = "-LOG(" + sqlDialect.getNumericCast(new SQLFragment("MAX(X.Confidence)")).getSQL() + ")";
var pgLog10Intensity = " CASE WHEN MAX(X.Intensity) IS NOT NULL AND MAX(X.Intensity) != 0 THEN LOG(" + sqlDialect.getNumericCast(new SQLFragment("MAX(X.Intensity)")).getSQL() + ") ELSE 0 END ";
var sqlServerLog10Intensity = " CASE WHEN MAX(X.Intensity) IS NOT NULL AND MAX(X.Intensity) != 0 THEN LOG10(MAX(X.Intensity)) ELSE 0 END ";
return sqlDialect.isPostgreSQL() ? pgLog10Intensity : sqlServerLog10Intensity;
}

private static String appendLog10ConfidenceSql(SqlDialect sqlDialect)
{
var pgConfidenceValueToRound = " CASE WHEN MAX(X.Confidence) IS NOT NULL AND MAX(X.Confidence) != 0 THEN -LOG(" + sqlDialect.getNumericCast(new SQLFragment("MAX(X.Confidence)")).getSQL() + ") ELSE 0 END ";
var pgLog10Confidence = "ROUND(" + sqlDialect.getNumericCast(new SQLFragment(pgConfidenceValueToRound)).getSQL() + ",4)";
var sqlServerLog10Confidence = "ROUND(-LOG10(MAX(X.Confidence)),4)";
var log10IntensitySql = sqlDialect.isPostgreSQL() ? pgLog10Intensity : sqlServerLog10Intensity;
var log10ConfidenceSql = sqlDialect.isPostgreSQL() ? pgLog10Confidence : sqlServerLog10Confidence;
SQLFragment sql = new SQLFragment("SELECT X.Sequence, " + log10IntensitySql + " AS Intensity, " + log10ConfidenceSql + " AS Confidence FROM ");
sql.append("(SELECT pep.Sequence, SUM(TotalArea) AS Intensity, MAX(qvalue) AS Confidence FROM ");
var sqlServerLog10Confidence = " CASE WHEN MAX(X.Confidence) IS NOT NULL AND MAX(X.Confidence) != 0 THEN ROUND(-LOG10(MAX(X.Confidence)),4) ELSE 0 END ";
return sqlDialect.isPostgreSQL() ? pgLog10Confidence : sqlServerLog10Confidence;
}

public static List<PeptideCharacteristic> getCombinedPeptideCharacteristics(long peptideGroupId, @Nullable Long replicateId)
{
var shouldFilterAndGroupByReplicate = null != replicateId && !Objects.equals(replicateId, Long.valueOf(0));
var sqlDialect = TargetedMSManager.getSqlDialect();

SQLFragment sql = new SQLFragment("SELECT X.Sequence, " + appendLog10IntensitySql(sqlDialect) + " AS Intensity, " + appendLog10ConfidenceSql(sqlDialect) + " AS Confidence, ");
sql.append(" MAX(X.Intensity) AS RawIntensity, MAX(X.Confidence) AS RawConfidence, X.StartIndex, X.EndIndex FROM ");
sql.append("(SELECT pep.Sequence, pep.StartIndex, pep.EndIndex, ");
sql.append(" CASE WHEN SUM(TotalArea) IS NULL OR SUM(TotalArea) < 1 THEN 1 ELSE SUM(TotalArea) END AS Intensity, ");
sql.append(" MAX(qvalue) AS Confidence FROM ");
sql.append(TargetedMSManager.getTableInfoPrecursorChromInfo(), "pci");
sql.append(" INNER JOIN ").append(TargetedMSManager.getTableInfoGeneralPrecursor(), "p");
sql.append(" ON p.Id = pci.PrecursorId");
Expand All @@ -115,10 +131,58 @@ public static List<PeptideCharacteristic> getPeptideCharacteristic(long peptideG
sql.append(" ON gm.id = pep.Id");
sql.append(" INNER JOIN ").append(TargetedMSManager.getTableInfoSampleFile(), "sf");
sql.append(" ON sf.Id = pci.SampleFileId");
if (shouldFilterAndGroupByReplicate)
{
sql.append(" INNER JOIN ").append(TargetedMSManager.getTableInfoReplicate(), "rep");
sql.append(" ON rep.Id = sf.ReplicateId");
}
sql.append(" WHERE gm.PeptideGroupId=? ");
sql.append(" GROUP BY pep.Sequence,pci.SampleFileId ) X ");
sql.append(" GROUP BY X.Sequence");
sql.add(peptideGroupId);
if (shouldFilterAndGroupByReplicate)
{
sql.append(" AND rep.Id=? ");
sql.add(replicateId);
}
sql.append(" GROUP BY pep.Sequence,pci.SampleFileId, pep.StartIndex, pep.EndIndex ) X ");
sql.append(" GROUP BY X.Sequence, X.StartIndex, X.EndIndex ");
return new SqlSelector(TargetedMSManager.getSchema(), sql).getArrayList(PeptideCharacteristic.class);
}

public static List<PeptideCharacteristic> getModifiedPeptideCharacteristics(long peptideGroupId, @Nullable Long replicateId)
{
var shouldFilterAndGroupByReplicate = null != replicateId && !Objects.equals(replicateId, Long.valueOf(0));
var sqlDialect = TargetedMSManager.getSqlDialect();

SQLFragment sql = new SQLFragment("SELECT X.Sequence, X.PeptideModifiedSequence AS ModifiedSequence, X.StartIndex, X.EndIndex ,");
sql.append(appendLog10IntensitySql(sqlDialect) + " AS Intensity, " + appendLog10ConfidenceSql(sqlDialect) + " AS Confidence, ");
sql.append(" MAX(X.Intensity) AS RawIntensity, MAX(X.Confidence) AS RawConfidence FROM ");
sql.append("(SELECT pep.Sequence, pep.PeptideModifiedSequence, pep.StartIndex, pep.EndIndex, ");
sql.append(" CASE WHEN SUM(TotalArea) IS NULL OR SUM(TotalArea) < 1 THEN 1 ELSE SUM(TotalArea) END AS Intensity, ");
sql.append(" MAX(qvalue) AS Confidence FROM ");
sql.append(TargetedMSManager.getTableInfoPrecursorChromInfo(), "pci");
sql.append(" INNER JOIN ").append(TargetedMSManager.getTableInfoGeneralPrecursor(), "p");
sql.append(" ON p.Id = pci.PrecursorId");
sql.append(" INNER JOIN ").append(TargetedMSManager.getTableInfoPeptide(),"pep");
sql.append(" ON p.GeneralMoleculeId = pep.Id");
sql.append(" INNER JOIN ").append(TargetedMSManager.getTableInfoGeneralMolecule(),"gm");
sql.append(" ON gm.id = pep.Id");
sql.append(" INNER JOIN ").append(TargetedMSManager.getTableInfoSampleFile(), "sf");
sql.append(" ON sf.Id = pci.SampleFileId");
if (shouldFilterAndGroupByReplicate)
{
sql.append(" INNER JOIN ").append(TargetedMSManager.getTableInfoReplicate(), "rep");
sql.append(" ON rep.Id = sf.ReplicateId");
}
sql.append(" WHERE gm.PeptideGroupId=? ");
sql.add(peptideGroupId);
if (shouldFilterAndGroupByReplicate)
{
sql.append(" AND rep.Id=? ");
sql.add(replicateId);
}
sql.append(" GROUP BY pep.Sequence,pci.SampleFileId, pep.PeptideModifiedSequence, pep.StartIndex, pep.EndIndex ) X ");
sql.append(" GROUP BY X.Sequence, X.PeptideModifiedSequence, X.StartIndex, X.EndIndex ");

return new SqlSelector(TargetedMSManager.getSchema(), sql).getArrayList(PeptideCharacteristic.class);
}

Expand Down