Skip to content

Implement OTF (On-The-Fly) expression call propagation and remove Affymetrix/EST datatypes#252

Draft
jwollbrett wants to merge 74 commits into
developfrom
updated_implement_otf
Draft

Implement OTF (On-The-Fly) expression call propagation and remove Affymetrix/EST datatypes#252
jwollbrett wants to merge 74 commits into
developfrom
updated_implement_otf

Conversation

@jwollbrett

Copy link
Copy Markdown
Contributor

Summary

This branch implements a new On-The-Fly (OTF) propagation approach for expression calls,
replacing the previous pre-computed pipeline-based propagation for the gene page and data
expression API. It also completes the removal of Affymetrix and EST legacy datatypes
from all layers of the codebase.

147 files changed — 10 541 insertions / 12 648 deletions.


What has been done

1. OTF propagation — new core logic (bgee-core)

  • New OTFExpressionCall: model class for a call after OTF propagation (aggregates raw
    observed calls across the condition graph). Carries the aggregated p-value, score, supporting
    data types, propagation state, and best-direct-descendant values for redundancy pruning.
  • New OTFExpressionCallFilterEngine: post-propagation filtering that removes conditions
    with excluded terms or non-requested child terms.
  • New ConditionGraphCacheService: on-demand caching of the condition graph (topological
    order, direct ancestor/descendant maps). Avoids reloading and recomputing the ontology
    structure on every request; the cache is keyed by species and condition parameters so it
    can be safely shared across calls within the same request.
  • ExpressionCallLoader: new loadDataOnTheFly() method replacing loadData() for the
    gene page and expression data API. Core sub-methods:
    • propagateCalls() — topological child→parent sweep over the condition graph.
    • generateOTFExpressionCall() — aggregates self observations and descendant calls into a
      single OTFExpressionCall for a given gene × condition; combines p-values and scores
      (see "reviewer focus" below).
  • ConditionGraph: propagation now returns a Set; removed obsolete maxRanksPerSpecies
    lookups (scores are now stored in the DB by the pipeline).

2. New DAOs and pipeline step

  • New ObservedExpressionDAO / MySQLObservedExpressionDAO: retrieves expression rows
    with actual observations for selected data types.
  • New RawExpressionCallDAO / MySQLRawExpressionCallDAO + DAORawCallFilter /
    DAORawCallValues.
  • New pipeline class InsertPropagatedConditions: pre-computes and inserts the propagated
    condition mapping into the DB.
  • DAOConditionFilter2: updated to support species-only filtering for OTF queries.

3. Webapp controllers (bgee-webapp)

  • CommandData and CommandGene refactored to use the new OTF path.
  • New CommandExpressionSupport: shared expression-call logic extracted from the two
    controllers.
  • Excluded terms and child-term requests now correctly flow through the condition filter.
  • Expression calls sorted by decreasing score.

4. Removal of Affymetrix and EST datatypes

Complete removal across all layers (bgee-core, bgee-dao-api, bgee-dao-sql, bgee-webapp):

  • Deleted all EST and Affymetrix model classes, DAOs, SQL DAOs, type adapters, and
    download-file generators.
  • Updated all remaining code that referenced these types.

5. Schema / model updates for Bgee 16

  • Removed hiddenSpecies from the Species model.
  • Removed OMAParentNodeId; added seqRegionName to gene objects.
  • Renamed expression table columns

What is missing / known limitations compared to the old loadData() approach

# Area Description Location
1 JSON output expressionState and expressionQuality hardcoded (p-value ≤ 0.05 → "expressed", quality always "gold"). Proper SummaryCallType / SummaryQuality propagation not yet implemented. ExpressionCallResponseTypeAdapter.java
2 Multi-species OTF propagation currently assumes a single species per request. Multi-species support not yet implemented. ExpressionCallLoader.java
3 Ordering Advanced ordering via OrderingAttribute not yet implemented; only score-based descending sort is available. OTFExpressionCall.java
4 includeChildTerms filter Still included in the DAOConditionFilter sent for OTF — should be removed (child term expansion is handled post-propagation). CommandExpressionSupport.java
5 DAOConditionFilter2 ontology dependency Construction of DAOConditionFilter2 for OTF still unnecessarily uses ontologies. It is not mandatory to solve that point for Bgee 16 to be released but a new approach not using the ontologies could drasticaly fasten the creation of the condition part of the ExpressionCallLoader ExpressionCallLoader.java
6 maxRanksPerSpecies Should be removed from ExpressionCallProcessedFilter; no longer needed since scores are pre-computed. ExpressionCallLoader.java
7 keepOnlyParentsMoreExpressed Purpose of this post-propagation filter needs clarification vs. SummaryQuality.SILVER filtering. ExpressionCallLoader.java
8 Best-descendant p-value After propagation, a parent condition should inherit the best (lowest) p-value among its descendants when it has no self-observation. Currently the mean of descendant p-values is used. ExpressionCallLoader.generateOTFExpressionCall()
9 P-value doubling for multiple observations When a condition has more than one observation (from different experiments), the p-value should be multiplied by 2 (conservative correction) before aggregation. This logic is not yet implemented. ExpressionCallLoader.generateOTFExpressionCall()

Notes for the reviewer

  • The old loadData() code path is not yet removed — it is retained for non-OTF use cases
    (download files, TopAnat). The OTF path is only activated for the gene page and data
    expression API calls.

…Id to throw an error on empty DAOConditionFilter2
…d terms or excluded terms after OTF propagation
…ditionIds are retrieved before OTF propagation
…ed terms or child terms not requested. Also implement 1st version of post propagation sorting
// return null;
// }

private OTFExpressionCall generateOTFExpressionCall(Gene gene, Condition2 cond,

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please review this method carefully. This is the core aggregation: it combines self-observed p-values (repeated nObs times) and scores with the FDR-corrected p-value from descendant calls. Two behaviours are not yet implemented and must be discussed: (1) a parent with no self-observation should inherit the best (lowest) descendant p-value rather than the mean; (2) when nObs > 1 for a single data type, the p-value should be multiplied by 2 before being added to the pool (conservative correction for multiple observations).

return log.traceExit(match);
}

private Map<Gene, Set<OTFExpressionCall>> propagateCalls(

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Entry point for OTF propagation — equivalent of the old loadData(). Walks the condition graph in topological order (child → parent), accumulating calls. Redundant ancestor conditions (same score as their best descendant) are pruned at the end. Please review the traversal logic and the redundancy-detection condition carefully.

}

//right now
public Map<Gene, List<OTFExpressionCall>> loadDataOnTheFly() {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Top-level OTF entry point. Note the single-species assumption (FIXME). Also note that post-propagation filtering (OTFExpressionCallFilterEngine) and summary-call-type filtering (matchesRequestedSummaryCallType) happen after propagation

dataTypes.contains(DataType.RNA_SEQ) ||
dataTypes.contains(DataType.SC_RNA_SEQ) ||
call.getMeanRank().compareTo(BigDecimal.valueOf(20000)) < 0)) {
//FXIME: Need to consider the SummaryQuality once it is implemented. TO be done before Bgee 16.0 release

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FIXME: temporary hardcoding — must use proper SummaryCallType/SummaryQuality before Bgee 16.0 release

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New pipeline step that pre-inserts propagated condition mappings into the DB, enabling OTF lookups without recomputing the full graph at query time.

CommandData commandData = this.getPartialCommandData();
commandData.initializeCaches(sleepBetweenComputeMs);

// --- Add condition graph cache initialization here ---

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cache loading condition graphs at server startup

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant