From 52d30cb9b0d891d8f4a6a5533498815aa8685f4b Mon Sep 17 00:00:00 2001 From: labkey-jeckels Date: Tue, 17 Feb 2026 21:02:50 -0800 Subject: [PATCH 1/4] Cache PTM grouping data for better perf --- .../queries/targetedms/PTMPercentsGrouped.sql | 2 +- resources/schemas/targetedms.xml | 23 ++++++ .../labkey/targetedms/SkylineDocImporter.java | 1 + .../labkey/targetedms/TargetedMSManager.java | 79 +++++++++++++++++++ .../labkey/targetedms/TargetedMSModule.java | 2 +- .../labkey/targetedms/TargetedMSSchema.java | 10 ++- .../targetedms/TargetedMSUpgradeCode.java | 39 +++++++++ 7 files changed, 153 insertions(+), 3 deletions(-) diff --git a/resources/queries/targetedms/PTMPercentsGrouped.sql b/resources/queries/targetedms/PTMPercentsGrouped.sql index a196a9cdd..42402a76e 100644 --- a/resources/queries/targetedms/PTMPercentsGrouped.sql +++ b/resources/queries/targetedms/PTMPercentsGrouped.sql @@ -18,7 +18,7 @@ SELECT MAX(ModificationCount) AS ModificationCount @hidden FROM - PTMPercentsGroupedPrepivot + PTMPercentsGroupedPrepivotCache GROUP BY ReplicateName, Sequence, diff --git a/resources/schemas/targetedms.xml b/resources/schemas/targetedms.xml index 2bd32a2d8..ac874f05c 100644 --- a/resources/schemas/targetedms.xml +++ b/resources/schemas/targetedms.xml @@ -1950,4 +1950,27 @@ + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/src/org/labkey/targetedms/SkylineDocImporter.java b/src/org/labkey/targetedms/SkylineDocImporter.java index 5e6f30648..53813313b 100644 --- a/src/org/labkey/targetedms/SkylineDocImporter.java +++ b/src/org/labkey/targetedms/SkylineDocImporter.java @@ -514,6 +514,7 @@ else if (folderType == TargetedMSService.FolderType.Library) parser.logMissingChromatogramCounts(); TargetedMSManager.updateModifiedAreaProportions(_log, run); + TargetedMSManager.populatePTMPercentsGroupedPrepivotCache(_log, run, _user, _container); if (_pipeRoot.isCloudRoot()) copyExtractedFilesToCloud(run); diff --git a/src/org/labkey/targetedms/TargetedMSManager.java b/src/org/labkey/targetedms/TargetedMSManager.java index 2d55db0fd..364ece409 100644 --- a/src/org/labkey/targetedms/TargetedMSManager.java +++ b/src/org/labkey/targetedms/TargetedMSManager.java @@ -23,6 +23,7 @@ import org.fhcrc.cpas.exp.xml.ExperimentArchiveDocument; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.labkey.api.action.SpringActionController; import org.labkey.api.cache.Cache; import org.labkey.api.cache.CacheManager; import org.labkey.api.collections.CaseInsensitiveHashMap; @@ -602,6 +603,11 @@ public static TableInfo getTableInfoQCMetricCache() return getSchema().getTable(TargetedMSSchema.TABLE_QC_METRIC_CACHE); } + public static TableInfo getTableInfoPTMPercentsGroupedPrepivotCache() + { + return getSchema().getTable(TargetedMSSchema.TABLE_PTM_PERCENTS_GROUPED_PREPIVOT_CACHE); + } + public static TableInfo getTableInfoSkylineAuditLogEntry() { return getSchema().getTable(TargetedMSSchema.TABLE_SKYLINE_AUDITLOG_ENTRY); @@ -1029,6 +1035,12 @@ public static TargetedMSRun[] getRunsInContainer(Container container) container.getId(), SkylineDocImporter.STATUS_SUCCESS, Boolean.FALSE); } + public static TargetedMSRun[] getAllNonDeletedRuns() + { + return getRuns("StatusId=? AND deleted=?", + SkylineDocImporter.STATUS_SUCCESS, Boolean.FALSE); + } + @Nullable public static TargetedMSRun getRunByFileName(String fileName, Container container) { @@ -1762,6 +1774,7 @@ private static SQLFragment getTempChromInfoIdsDependentDeleteSql(TableInfo fromT /** Actually delete runs that have been marked as deleted from the database */ private static void purgeDeletedRuns() { + deleteRunDependent(getTableInfoPTMPercentsGroupedPrepivotCache()); // Delete from FoldChange deleteRunDependent(getTableInfoFoldChange()); // Delete from CalibrationCurve @@ -2732,6 +2745,72 @@ public static void updateModifiedAreaProportions(@Nullable Logger log, @NotNull executor.execute("DROP TABLE " + areasTableName); } + /** + * Pre-compute PTMPercentsGroupedPrepivot results during import and store in PTMPercentsCache. + * Only populates cache for ExperimentMAM folders. + */ + public static void populatePTMPercentsGroupedPrepivotCache(@Nullable Logger log, @NotNull TargetedMSRun run, @NotNull User user, @NotNull Container container) + { + // Delete any existing cache rows for this run + new SqlExecutor(getSchema()).execute( + new SQLFragment("DELETE FROM ").append(getTableInfoPTMPercentsGroupedPrepivotCache()).append(" WHERE RunId = ?").add(run.getId())); + + // Only populate cache for ExperimentMAM folders + if (getFolderType(container) != TargetedMSService.FolderType.ExperimentMAM) + { + return; + } + + if (log != null) + { + log.info("Populating PTMPercentsGroupedPrepivotCache for run " + run.getId()); + } + + String labkeySql = "SELECT\n" + + " Modification,\n" + + " TotalPercentModified,\n" + + " PercentModified,\n" + + " MaxPercentModified,\n" + + " ModificationCount,\n" + + " Id,\n" + + " PeptideModifiedSequence,\n" + + " Sequence,\n" + + " PreviousAA,\n" + + " NextAA,\n" + + " SampleFileId,\n" + + " ReplicateName,\n" + + " AminoAcid,\n" + + " SiteLocation,\n" + + " Location,\n" + + " PeptideGroupId\n" + + "FROM PTMPercentsGroupedPrepivot\n" + + "WHERE PeptideGroupId.RunId = " + run.getId(); + + UserSchema schema = QueryService.get().getUserSchema(user, container, TargetedMSSchema.SCHEMA_KEY); + TableInfo tableInfo = QueryService.get().createTable(schema, labkeySql, null, true); + + try (var ignored = SpringActionController.ignoreSqlUpdates()) + { + SQLFragment insertSql = new SQLFragment(); + insertSql.append("INSERT INTO ").append(getTableInfoPTMPercentsGroupedPrepivotCache()); + insertSql.append(" (Container, RunId, Modification, TotalPercentModified, PercentModified, MaxPercentModified,"); + insertSql.append(" ModificationCount, GeneralMoleculeChromInfoId, PeptideModifiedSequence, Sequence,"); + insertSql.append(" PreviousAA, NextAA, SampleFileId, ReplicateName, AminoAcid, SiteLocation, Location, PeptideGroupId)"); + insertSql.append(" SELECT ?, ?, lk.Modification, lk.TotalPercentModified, lk.PercentModified, lk.MaxPercentModified,"); + insertSql.append(" lk.ModificationCount, lk.Id, lk.PeptideModifiedSequence, lk.Sequence,"); + insertSql.append(" lk.PreviousAA, lk.NextAA, lk.SampleFileId, lk.ReplicateName, lk.AminoAcid, lk.SiteLocation, lk.Location, lk.PeptideGroupId"); + insertSql.append(" FROM ").append(tableInfo, "lk"); + insertSql.add(container.getEntityId()); + insertSql.add(run.getId()); + new SqlExecutor(getSchema()).execute(insertSql); + } + + if (log != null) + { + log.info("Finished populating PTMPercentsGroupedPrepivotCache for run " + run.getId()); + } + } + /** * Returns the Transition Full Scan settings for the given run. This may be null if the settings were not included * in the Skyline document. diff --git a/src/org/labkey/targetedms/TargetedMSModule.java b/src/org/labkey/targetedms/TargetedMSModule.java index c68243f38..6d6538561 100644 --- a/src/org/labkey/targetedms/TargetedMSModule.java +++ b/src/org/labkey/targetedms/TargetedMSModule.java @@ -231,7 +231,7 @@ public String getName() @Override public Double getSchemaVersion() { - return 26.001; + return 26.002; } @Override diff --git a/src/org/labkey/targetedms/TargetedMSSchema.java b/src/org/labkey/targetedms/TargetedMSSchema.java index db2ef2cb7..1f5473e47 100644 --- a/src/org/labkey/targetedms/TargetedMSSchema.java +++ b/src/org/labkey/targetedms/TargetedMSSchema.java @@ -71,6 +71,7 @@ import org.labkey.api.security.permissions.AdminPermission; import org.labkey.api.targetedms.RepresentativeDataState; import org.labkey.api.targetedms.RunRepresentativeDataState; +import org.labkey.api.targetedms.TargetedMSService; import org.labkey.api.util.ContainerContext; import org.labkey.api.util.HtmlString; import org.labkey.api.util.Pair; @@ -232,6 +233,7 @@ public class TargetedMSSchema extends UserSchema public static final String TABLE_QC_ENABLED_METRICS = "QCEnabledMetrics"; public static final String TABLE_QC_TRACE_METRIC_VALUES = "QCTraceMetricValues"; public static final String TABLE_QC_METRIC_CACHE = "QCMetricCache"; + public static final String TABLE_PTM_PERCENTS_GROUPED_PREPIVOT_CACHE = "PTMPercentsGroupedPrepivotCache"; public static final String TABLE_GUIDE_SET = "GuideSet"; @@ -1718,7 +1720,7 @@ public QueryView createView(ViewContext context, @NotNull QuerySettings settings String queryName = settings.getQueryName(); if (queryName != null && ("PTMPercentsGrouped".equalsIgnoreCase(queryName) || queryName.toLowerCase().startsWith(QUERY_PTM_PERCENTS_GROUPED_PREFIX.toLowerCase()))) { - return new TargetedMSCrosstabView(TargetedMSSchema.this, settings, errors) + return new TargetedMSCrosstabView(TargetedMSSchema.this, settings, errors) { @Override protected DataRegion createDataRegion() @@ -1882,6 +1884,7 @@ private Set getAllTableNames(boolean caseInsensitive) hs.add(TABLE_RATE_TYPE); hs.add(TABLE_INSTRUMENT_RATE); hs.add(TABLE_INSTRUMENT_USAGE_PAYMENT); + hs.add(TABLE_PTM_PERCENTS_GROUPED_PREPIVOT_CACHE); return hs; } @@ -1921,6 +1924,11 @@ private QueryDefinition createRunScopedPTMQuery(String prefix, String baseQueryN try { long runId = Long.parseLong(runIdString); + if (TargetedMSManager.getFolderType(getContainer()) != TargetedMSService.FolderType.ExperimentMAM) + { + throw new IllegalStateException("PTM queries are only supported in ExperimentMAM folders"); + } + QueryDefinition queryDef = Objects.requireNonNull(getQueryDef(baseQueryName)); QueryDefinition result = QueryService.get().createQueryDef(getUser(), getContainer(), getSchemaPath(), queryName); result.setSql(queryDef.getSql() + " IN (SELECT r.Name FROM targetedms.Replicate r WHERE r.RunId = " + runId + ")"); diff --git a/src/org/labkey/targetedms/TargetedMSUpgradeCode.java b/src/org/labkey/targetedms/TargetedMSUpgradeCode.java index 1654517a3..8d010485d 100644 --- a/src/org/labkey/targetedms/TargetedMSUpgradeCode.java +++ b/src/org/labkey/targetedms/TargetedMSUpgradeCode.java @@ -15,7 +15,10 @@ */ package org.labkey.targetedms; +import org.apache.logging.log4j.Logger; +import org.labkey.api.data.Container; import org.labkey.api.data.ContainerManager; +import org.labkey.api.data.DeferredUpgrade; import org.labkey.api.data.SQLFragment; import org.labkey.api.data.SqlExecutor; import org.labkey.api.data.UpgradeCode; @@ -23,6 +26,8 @@ import org.labkey.api.module.ModuleContext; import org.labkey.api.module.ModuleLoader; import org.labkey.api.security.User; +import org.labkey.api.targetedms.TargetedMSService; +import org.labkey.api.util.logging.LogHelper; import org.labkey.targetedms.query.QCAnnotationTypeTable; import java.util.Date; @@ -36,6 +41,8 @@ */ public class TargetedMSUpgradeCode implements UpgradeCode { + private static final Logger LOG = LogHelper.getLogger(TargetedMSUpgradeCode.class, "TargetedMS schema upgrade operations"); + // called at every bootstrap to initialize annotation types @SuppressWarnings({"UnusedDeclaration"}) public void populateDefaultAnnotationTypes(final ModuleContext moduleContext) @@ -69,4 +76,36 @@ private void insertAnnotationType(String name, String color, User user) sql.add(color); new SqlExecutor(TargetedMSManager.getSchema()).execute(sql); } + + /** Populate PTMPercentsGroupedPrepivotCache for all runs in existing ExperimentMAM folders */ + @SuppressWarnings("UnusedDeclaration") + @DeferredUpgrade + public void populatePTMPercentsGroupedPrepivotCache(final ModuleContext moduleContext) + { + if (moduleContext.isNewInstall()) + { + return; + } + + User user = moduleContext.getUpgradeUser(); + LOG.info("Populating PTMPercentsGroupedPrepivotCache for existing ExperimentMAM folders"); + + for (TargetedMSRun run : TargetedMSManager.getAllNonDeletedRuns()) + { + Container container = run.getContainer(); + if (container != null && TargetedMSManager.getFolderType(container) == TargetedMSService.FolderType.ExperimentMAM) + { + try + { + TargetedMSManager.populatePTMPercentsGroupedPrepivotCache(LOG, run, user, container); + } + catch (Exception e) + { + LOG.error("Error populating PTMPercentsGroupedPrepivotCache for run " + run.getId() + " in " + container.getPath(), e); + } + } + } + + LOG.info("Finished populating PTMPercentsGroupedPrepivotCache for existing ExperimentMAM folders"); + } } From 03cf866343d9fc69a7924f521cc26d005b34af14 Mon Sep 17 00:00:00 2001 From: labkey-jeckels Date: Tue, 17 Feb 2026 21:03:50 -0800 Subject: [PATCH 2/4] Cache PTM grouping data for better perf --- .../postgresql/targetedms-26.001-26.002.sql | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 resources/schemas/dbscripts/postgresql/targetedms-26.001-26.002.sql diff --git a/resources/schemas/dbscripts/postgresql/targetedms-26.001-26.002.sql b/resources/schemas/dbscripts/postgresql/targetedms-26.001-26.002.sql new file mode 100644 index 000000000..da89b89d2 --- /dev/null +++ b/resources/schemas/dbscripts/postgresql/targetedms-26.001-26.002.sql @@ -0,0 +1,35 @@ +CREATE TABLE targetedms.PTMPercentsGroupedPrepivotCache +( + Id BIGSERIAL NOT NULL, + Container ENTITYID NOT NULL, + RunId BIGINT NOT NULL, + Modification VARCHAR(300) NOT NULL, + TotalPercentModified REAL, + PercentModified REAL, + MaxPercentModified REAL, + ModificationCount INT, + GeneralMoleculeChromInfoId BIGINT, + PeptideModifiedSequence VARCHAR(300), + Sequence VARCHAR(300), + PreviousAA VARCHAR(2), + NextAA VARCHAR(2), + SampleFileId BIGINT NOT NULL, + ReplicateName VARCHAR(200), + AminoAcid VARCHAR(5), + SiteLocation VARCHAR(50), + Location INT, + PeptideGroupId BIGINT NOT NULL, + + CONSTRAINT PK_PTMPercentsGroupedPrepivotCache PRIMARY KEY (Id), + CONSTRAINT FK_PTMPercentsGroupedPrepivotCache_Container FOREIGN KEY (Container) REFERENCES core.Containers(EntityId), + CONSTRAINT FK_PTMPercentsGroupedPrepivotCache_RunId FOREIGN KEY (RunId) REFERENCES targetedms.Runs(Id), + CONSTRAINT FK_PTMPercentsGroupedPrepivotCache_SampleFileId FOREIGN KEY (SampleFileId) REFERENCES targetedms.SampleFile(Id), + CONSTRAINT FK_PTMPercentsGroupedPrepivotCache_PeptideGroupId FOREIGN KEY (PeptideGroupId) REFERENCES targetedms.PeptideGroup(Id) +); + +CREATE INDEX IDX_PTMPercentsGroupedPrepivotCache_RunId ON targetedms.PTMPercentsGroupedPrepivotCache(RunId); +CREATE INDEX IDX_PTMPercentsGroupedPrepivotCache_Container ON targetedms.PTMPercentsGroupedPrepivotCache(Container); +CREATE INDEX IDX_PTMPercentsGroupedPrepivotCache_SampleFileId ON targetedms.PTMPercentsGroupedPrepivotCache(SampleFileId); +CREATE INDEX IDX_PTMPercentsGroupedPrepivotCache_PeptideGroupId ON targetedms.PTMPercentsGroupedPrepivotCache(PeptideGroupId); + +SELECT core.executeJavaUpgradeCode('populatePTMPercentsGroupedPrepivotCache'); From 35e0b27ea3814762e0c06ad162a88b0274c5da4f Mon Sep 17 00:00:00 2001 From: labkey-jeckels Date: Wed, 18 Feb 2026 11:32:38 -0800 Subject: [PATCH 3/4] Test coverage and fixes --- .../PTMPercentsGroupedPrepivot/.qview.xml | 7 +++ .../PTMPercentsGroupedPrepivotCache.query.xml | 43 +++++++++++++++++++ .../.qview.xml | 7 +++ .../postgresql/targetedms-26.001-26.002.sql | 6 +-- resources/schemas/targetedms.xml | 3 +- .../labkey/targetedms/TargetedMSManager.java | 2 +- .../labkey/targetedms/TargetedMSSchema.java | 8 ++++ .../targetedms/TargetedMSUpgradeCode.java | 2 + .../TargetedMSEarlyStagePTMReportTest.java | 12 +++++- 9 files changed, 83 insertions(+), 7 deletions(-) create mode 100644 resources/queries/targetedms/PTMPercentsGroupedPrepivot/.qview.xml create mode 100644 resources/queries/targetedms/PTMPercentsGroupedPrepivotCache.query.xml create mode 100644 resources/queries/targetedms/PTMPercentsGroupedPrepivotCache/.qview.xml diff --git a/resources/queries/targetedms/PTMPercentsGroupedPrepivot/.qview.xml b/resources/queries/targetedms/PTMPercentsGroupedPrepivot/.qview.xml new file mode 100644 index 000000000..0b110ac4f --- /dev/null +++ b/resources/queries/targetedms/PTMPercentsGroupedPrepivot/.qview.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/resources/queries/targetedms/PTMPercentsGroupedPrepivotCache.query.xml b/resources/queries/targetedms/PTMPercentsGroupedPrepivotCache.query.xml new file mode 100644 index 000000000..191fa354a --- /dev/null +++ b/resources/queries/targetedms/PTMPercentsGroupedPrepivotCache.query.xml @@ -0,0 +1,43 @@ + + + + + + + + org.labkey.targetedms.query.ModifiedSequenceDisplayColumn$PeptideDisplayColumnFactory + + true + true + SiteLocation + + + Sequence + + + 0.00% + + + 0.00% + + + 0.00% + + + UnmodifiedSequence + + + + org.labkey.targetedms.query.CDRDisplayColumnFactory + + + + + org.labkey.targetedms.query.PTMRiskDisplayColumnFactory + + + +
+
+
+
diff --git a/resources/queries/targetedms/PTMPercentsGroupedPrepivotCache/.qview.xml b/resources/queries/targetedms/PTMPercentsGroupedPrepivotCache/.qview.xml new file mode 100644 index 000000000..0b110ac4f --- /dev/null +++ b/resources/queries/targetedms/PTMPercentsGroupedPrepivotCache/.qview.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/resources/schemas/dbscripts/postgresql/targetedms-26.001-26.002.sql b/resources/schemas/dbscripts/postgresql/targetedms-26.001-26.002.sql index da89b89d2..59d26d370 100644 --- a/resources/schemas/dbscripts/postgresql/targetedms-26.001-26.002.sql +++ b/resources/schemas/dbscripts/postgresql/targetedms-26.001-26.002.sql @@ -1,6 +1,6 @@ CREATE TABLE targetedms.PTMPercentsGroupedPrepivotCache ( - Id BIGSERIAL NOT NULL, + Id BIGINT NOT NULL, -- PeptideId lookup, not a primary key Container ENTITYID NOT NULL, RunId BIGINT NOT NULL, Modification VARCHAR(300) NOT NULL, @@ -8,7 +8,6 @@ CREATE TABLE targetedms.PTMPercentsGroupedPrepivotCache PercentModified REAL, MaxPercentModified REAL, ModificationCount INT, - GeneralMoleculeChromInfoId BIGINT, PeptideModifiedSequence VARCHAR(300), Sequence VARCHAR(300), PreviousAA VARCHAR(2), @@ -20,13 +19,14 @@ CREATE TABLE targetedms.PTMPercentsGroupedPrepivotCache Location INT, PeptideGroupId BIGINT NOT NULL, - CONSTRAINT PK_PTMPercentsGroupedPrepivotCache PRIMARY KEY (Id), CONSTRAINT FK_PTMPercentsGroupedPrepivotCache_Container FOREIGN KEY (Container) REFERENCES core.Containers(EntityId), + CONSTRAINT FK_PTMPercentsGroupedPrepivotCache_Id FOREIGN KEY (Id) REFERENCES targetedms.Peptide(Id), CONSTRAINT FK_PTMPercentsGroupedPrepivotCache_RunId FOREIGN KEY (RunId) REFERENCES targetedms.Runs(Id), CONSTRAINT FK_PTMPercentsGroupedPrepivotCache_SampleFileId FOREIGN KEY (SampleFileId) REFERENCES targetedms.SampleFile(Id), CONSTRAINT FK_PTMPercentsGroupedPrepivotCache_PeptideGroupId FOREIGN KEY (PeptideGroupId) REFERENCES targetedms.PeptideGroup(Id) ); +CREATE INDEX IDX_PTMPercentsGroupedPrepivotCache_Id ON targetedms.PTMPercentsGroupedPrepivotCache(Id); CREATE INDEX IDX_PTMPercentsGroupedPrepivotCache_RunId ON targetedms.PTMPercentsGroupedPrepivotCache(RunId); CREATE INDEX IDX_PTMPercentsGroupedPrepivotCache_Container ON targetedms.PTMPercentsGroupedPrepivotCache(Container); CREATE INDEX IDX_PTMPercentsGroupedPrepivotCache_SampleFileId ON targetedms.PTMPercentsGroupedPrepivotCache(SampleFileId); diff --git a/resources/schemas/targetedms.xml b/resources/schemas/targetedms.xml index ac874f05c..569b890e1 100644 --- a/resources/schemas/targetedms.xml +++ b/resources/schemas/targetedms.xml @@ -1952,7 +1952,7 @@ - + @@ -1960,7 +1960,6 @@ - diff --git a/src/org/labkey/targetedms/TargetedMSManager.java b/src/org/labkey/targetedms/TargetedMSManager.java index 364ece409..5ba491a89 100644 --- a/src/org/labkey/targetedms/TargetedMSManager.java +++ b/src/org/labkey/targetedms/TargetedMSManager.java @@ -2794,7 +2794,7 @@ public static void populatePTMPercentsGroupedPrepivotCache(@Nullable Logger log, SQLFragment insertSql = new SQLFragment(); insertSql.append("INSERT INTO ").append(getTableInfoPTMPercentsGroupedPrepivotCache()); insertSql.append(" (Container, RunId, Modification, TotalPercentModified, PercentModified, MaxPercentModified,"); - insertSql.append(" ModificationCount, GeneralMoleculeChromInfoId, PeptideModifiedSequence, Sequence,"); + insertSql.append(" ModificationCount, Id, PeptideModifiedSequence, Sequence,"); insertSql.append(" PreviousAA, NextAA, SampleFileId, ReplicateName, AminoAcid, SiteLocation, Location, PeptideGroupId)"); insertSql.append(" SELECT ?, ?, lk.Modification, lk.TotalPercentModified, lk.PercentModified, lk.MaxPercentModified,"); insertSql.append(" lk.ModificationCount, lk.Id, lk.PeptideModifiedSequence, lk.Sequence,"); diff --git a/src/org/labkey/targetedms/TargetedMSSchema.java b/src/org/labkey/targetedms/TargetedMSSchema.java index 1f5473e47..b3030e0fb 100644 --- a/src/org/labkey/targetedms/TargetedMSSchema.java +++ b/src/org/labkey/targetedms/TargetedMSSchema.java @@ -1691,6 +1691,14 @@ else if (TABLE_INSTRUMENT_USAGE_PAYMENT.equalsIgnoreCase(name)) result.getMutableColumnOrThrow("ExperimentRunLSID").setFk(QueryForeignKey.from(_expSchema, cf).to("Runs", "LSID", null)); } TargetedMSTable.fixupLookups(result); + + if (name.equalsIgnoreCase(TABLE_PTM_PERCENTS_GROUPED_PREPIVOT_CACHE)) + { + // Inject two null columns to match how the uncached version wires up DisplayColumns + result.addColumn(new ExprColumn(result, "Risk", new SQLFragment("CAST(NULL AS VARCHAR)"), JdbcType.VARCHAR)); + result.addColumn(new ExprColumn(result, "IsCdr", new SQLFragment("CAST(NULL AS VARCHAR)"), JdbcType.VARCHAR)); + } + return result; } diff --git a/src/org/labkey/targetedms/TargetedMSUpgradeCode.java b/src/org/labkey/targetedms/TargetedMSUpgradeCode.java index 8d010485d..d754657d9 100644 --- a/src/org/labkey/targetedms/TargetedMSUpgradeCode.java +++ b/src/org/labkey/targetedms/TargetedMSUpgradeCode.java @@ -87,6 +87,8 @@ public void populatePTMPercentsGroupedPrepivotCache(final ModuleContext moduleCo return; } + new SqlExecutor(TargetedMSManager.getSchema()).execute("TRUNCATE " + TargetedMSManager.getTableInfoPTMPercentsGroupedPrepivotCache()); + User user = moduleContext.getUpgradeUser(); LOG.info("Populating PTMPercentsGroupedPrepivotCache for existing ExperimentMAM folders"); diff --git a/test/src/org/labkey/test/tests/targetedms/TargetedMSEarlyStagePTMReportTest.java b/test/src/org/labkey/test/tests/targetedms/TargetedMSEarlyStagePTMReportTest.java index dedbdb2e4..c0b5907b1 100644 --- a/test/src/org/labkey/test/tests/targetedms/TargetedMSEarlyStagePTMReportTest.java +++ b/test/src/org/labkey/test/tests/targetedms/TargetedMSEarlyStagePTMReportTest.java @@ -39,10 +39,20 @@ private void doInit() @Test public void testEarlyStagePrepivot() { + // Test against the live-query version goToProjectHome(); goToSchemaBrowser(); DataRegionTable table = viewQueryData("targetedms", "PTMPercentsGroupedPrepivot"); + verifyPrepivotData(table); + // Test against the cached version too + goToSchemaBrowser(); + table = viewQueryData("targetedms", "PTMPercentsGroupedPrepivotCache"); + verifyPrepivotData(table); + } + + private void verifyPrepivotData(DataRegionTable table) + { // Test special-cased peptide table.setFilter("PeptideModifiedSequence", "Starts With", "EEQ"); table = new DataRegionTable("query", this); @@ -59,7 +69,7 @@ public void testEarlyStagePrepivot() table.setFilter("PeptideModifiedSequence", "Starts With", "VTN"); table = new DataRegionTable("query", this); assertEquals(List.of("true", "true"), table.getColumnDataAsText("IsCdr")); - assertEquals(List.of("High", "Medium"), table.getColumnDataAsText("Risk")); + assertEquals(List.of("Medium", "High"), table.getColumnDataAsText("Risk")); // Test special-cased N-Term Modification, present on QVTL peptide (Q is modified, so don't use it in the filter) table.setFilter("PeptideModifiedSequence", "Contains", "VTL"); From 3cfa8c37fd1ad20e2b4db0c921bd7ac2d43959dc Mon Sep 17 00:00:00 2001 From: labkey-jeckels Date: Wed, 18 Feb 2026 13:14:50 -0800 Subject: [PATCH 4/4] Cleanup --- .../labkey/targetedms/SkylineDocImporter.java | 2 +- .../labkey/targetedms/TargetedMSManager.java | 40 +++++++------------ .../labkey/targetedms/TargetedMSSchema.java | 2 +- .../targetedms/TargetedMSUpgradeCode.java | 4 +- 4 files changed, 18 insertions(+), 30 deletions(-) diff --git a/src/org/labkey/targetedms/SkylineDocImporter.java b/src/org/labkey/targetedms/SkylineDocImporter.java index 53813313b..3ceca58f6 100644 --- a/src/org/labkey/targetedms/SkylineDocImporter.java +++ b/src/org/labkey/targetedms/SkylineDocImporter.java @@ -514,7 +514,7 @@ else if (folderType == TargetedMSService.FolderType.Library) parser.logMissingChromatogramCounts(); TargetedMSManager.updateModifiedAreaProportions(_log, run); - TargetedMSManager.populatePTMPercentsGroupedPrepivotCache(_log, run, _user, _container); + TargetedMSManager.populatePTMPercentsGroupedPrepivotCache(run, _user, _container); if (_pipeRoot.isCloudRoot()) copyExtractedFilesToCloud(run); diff --git a/src/org/labkey/targetedms/TargetedMSManager.java b/src/org/labkey/targetedms/TargetedMSManager.java index 5ba491a89..64ed12e47 100644 --- a/src/org/labkey/targetedms/TargetedMSManager.java +++ b/src/org/labkey/targetedms/TargetedMSManager.java @@ -23,7 +23,6 @@ import org.fhcrc.cpas.exp.xml.ExperimentArchiveDocument; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.labkey.api.action.SpringActionController; import org.labkey.api.cache.Cache; import org.labkey.api.cache.CacheManager; import org.labkey.api.collections.CaseInsensitiveHashMap; @@ -2749,7 +2748,7 @@ public static void updateModifiedAreaProportions(@Nullable Logger log, @NotNull * Pre-compute PTMPercentsGroupedPrepivot results during import and store in PTMPercentsCache. * Only populates cache for ExperimentMAM folders. */ - public static void populatePTMPercentsGroupedPrepivotCache(@Nullable Logger log, @NotNull TargetedMSRun run, @NotNull User user, @NotNull Container container) + public static void populatePTMPercentsGroupedPrepivotCache(@NotNull TargetedMSRun run, @NotNull User user, @NotNull Container container) { // Delete any existing cache rows for this run new SqlExecutor(getSchema()).execute( @@ -2761,10 +2760,7 @@ public static void populatePTMPercentsGroupedPrepivotCache(@Nullable Logger log, return; } - if (log != null) - { - log.info("Populating PTMPercentsGroupedPrepivotCache for run " + run.getId()); - } + _log.info("Populating PTMPercentsGroupedPrepivotCache for run " + run.getId()); String labkeySql = "SELECT\n" + " Modification,\n" + @@ -2789,26 +2785,20 @@ public static void populatePTMPercentsGroupedPrepivotCache(@Nullable Logger log, UserSchema schema = QueryService.get().getUserSchema(user, container, TargetedMSSchema.SCHEMA_KEY); TableInfo tableInfo = QueryService.get().createTable(schema, labkeySql, null, true); - try (var ignored = SpringActionController.ignoreSqlUpdates()) - { - SQLFragment insertSql = new SQLFragment(); - insertSql.append("INSERT INTO ").append(getTableInfoPTMPercentsGroupedPrepivotCache()); - insertSql.append(" (Container, RunId, Modification, TotalPercentModified, PercentModified, MaxPercentModified,"); - insertSql.append(" ModificationCount, Id, PeptideModifiedSequence, Sequence,"); - insertSql.append(" PreviousAA, NextAA, SampleFileId, ReplicateName, AminoAcid, SiteLocation, Location, PeptideGroupId)"); - insertSql.append(" SELECT ?, ?, lk.Modification, lk.TotalPercentModified, lk.PercentModified, lk.MaxPercentModified,"); - insertSql.append(" lk.ModificationCount, lk.Id, lk.PeptideModifiedSequence, lk.Sequence,"); - insertSql.append(" lk.PreviousAA, lk.NextAA, lk.SampleFileId, lk.ReplicateName, lk.AminoAcid, lk.SiteLocation, lk.Location, lk.PeptideGroupId"); - insertSql.append(" FROM ").append(tableInfo, "lk"); - insertSql.add(container.getEntityId()); - insertSql.add(run.getId()); - new SqlExecutor(getSchema()).execute(insertSql); - } + SQLFragment insertSql = new SQLFragment(); + insertSql.append("INSERT INTO ").append(getTableInfoPTMPercentsGroupedPrepivotCache()); + insertSql.append(" (Container, RunId, Modification, TotalPercentModified, PercentModified, MaxPercentModified,"); + insertSql.append(" ModificationCount, Id, PeptideModifiedSequence, Sequence,"); + insertSql.append(" PreviousAA, NextAA, SampleFileId, ReplicateName, AminoAcid, SiteLocation, Location, PeptideGroupId)"); + insertSql.append(" SELECT ?, ?, lk.Modification, lk.TotalPercentModified, lk.PercentModified, lk.MaxPercentModified,"); + insertSql.append(" lk.ModificationCount, lk.Id, lk.PeptideModifiedSequence, lk.Sequence,"); + insertSql.append(" lk.PreviousAA, lk.NextAA, lk.SampleFileId, lk.ReplicateName, lk.AminoAcid, lk.SiteLocation, lk.Location, lk.PeptideGroupId"); + insertSql.append(" FROM ").append(tableInfo, "lk"); + insertSql.add(container.getEntityId()); + insertSql.add(run.getId()); + new SqlExecutor(getSchema()).execute(insertSql); - if (log != null) - { - log.info("Finished populating PTMPercentsGroupedPrepivotCache for run " + run.getId()); - } + _log.info("Finished populating PTMPercentsGroupedPrepivotCache for run " + run.getId()); } /** diff --git a/src/org/labkey/targetedms/TargetedMSSchema.java b/src/org/labkey/targetedms/TargetedMSSchema.java index b3030e0fb..a863332d8 100644 --- a/src/org/labkey/targetedms/TargetedMSSchema.java +++ b/src/org/labkey/targetedms/TargetedMSSchema.java @@ -1728,7 +1728,7 @@ public QueryView createView(ViewContext context, @NotNull QuerySettings settings String queryName = settings.getQueryName(); if (queryName != null && ("PTMPercentsGrouped".equalsIgnoreCase(queryName) || queryName.toLowerCase().startsWith(QUERY_PTM_PERCENTS_GROUPED_PREFIX.toLowerCase()))) { - return new TargetedMSCrosstabView(TargetedMSSchema.this, settings, errors) + return new TargetedMSCrosstabView(TargetedMSSchema.this, settings, errors) { @Override protected DataRegion createDataRegion() diff --git a/src/org/labkey/targetedms/TargetedMSUpgradeCode.java b/src/org/labkey/targetedms/TargetedMSUpgradeCode.java index d754657d9..3035b5fec 100644 --- a/src/org/labkey/targetedms/TargetedMSUpgradeCode.java +++ b/src/org/labkey/targetedms/TargetedMSUpgradeCode.java @@ -87,8 +87,6 @@ public void populatePTMPercentsGroupedPrepivotCache(final ModuleContext moduleCo return; } - new SqlExecutor(TargetedMSManager.getSchema()).execute("TRUNCATE " + TargetedMSManager.getTableInfoPTMPercentsGroupedPrepivotCache()); - User user = moduleContext.getUpgradeUser(); LOG.info("Populating PTMPercentsGroupedPrepivotCache for existing ExperimentMAM folders"); @@ -99,7 +97,7 @@ public void populatePTMPercentsGroupedPrepivotCache(final ModuleContext moduleCo { try { - TargetedMSManager.populatePTMPercentsGroupedPrepivotCache(LOG, run, user, container); + TargetedMSManager.populatePTMPercentsGroupedPrepivotCache(run, user, container); } catch (Exception e) {