Skip to content

Feat multispec#251

Open
fbastian wants to merge 16 commits into
developfrom
feat_multispec
Open

Feat multispec#251
fbastian wants to merge 16 commits into
developfrom
feat_multispec

Conversation

@fbastian

Copy link
Copy Markdown
Member

PR solely for being able to comment in diff

@fbastian fbastian self-assigned this Jun 19, 2026
* @return The {@code Stream} of {@code SimilarityExpressionCall}s that are
* the similar expression calls for the requested parameters.
*/
public Stream<SimilarityExpressionCall> loadSimilarityExpressionCalls(int taxonId,

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I think we discussed this method should work as for org.bgee.model.expressiondata.call.ExpressionCallLoader and org.bgee.model.expressiondata.call.ExpressionCallService?

Meaning, this method should accept a org.bgee.model.expressiondata.call.CallFilter.ExpressionCallFilter2, or a new class extending org.bgee.model.expressiondata.call.CallFilter to accept multiple GeneFilters?

Then under the hood, the code could use the ExpressionCallLoader or ExpressionCallService directly

Set<AnatEntitySimilarity> anatEntitySimilaritiesFromCellTypeFilter =
new HashSet<>(anatEntitySimilaritiesFromAnatFilter);

// Extract anat entity and cell type IDs from conditionFilters for filtering similarities

@fbastian fbastian Jun 19, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This logic should go in a separate function probably, returning the Map<ConditionParameter<?, ?>, ComposedFilterIds<String>> condParamToFilter

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Also, don't separate anatEntities and CellTypes work, do everything at once, and separate at the end using methd isCellType() for line 1107

}
filterAnatEntityIds.addAll(expandedAnatIds);
}
if (cellIds != null) {

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Refactor to avoid code duplication (same as for anatIds)
Probably it's more optimal to instantiate the ontology once for both anat and cell type at the same time


if (!filterAnatEntityIds.isEmpty()) {
anatEntitySimilaritiesFromAnatFilter = anatEntitySimilaritiesFromAnatFilter.stream()
.filter(s -> s.getSourceAnatEntities().stream()

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Shouldn't it use getAllAnatEntities?

// Build maps for grouping (same logic as loadSimilarityExpressionCalls)
Map<AnatEntity, Set<AnatEntitySimilarity>> similaritiesByAnatEntityFromAnatFilter =
anatEntitySimilaritiesFromAnatFilter.stream()
.flatMap(sim -> sim.getSourceAnatEntities().stream()

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

getAllAnatEntities

.collect(Collectors.toList());

if (this.requestParameters.isGetResultCount()) {
count = (long) allCalls.size();

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Yeah, so here it shows that the code hasn't be written as the ExpressionCallLoader, and all results are always all in memory. Is that OK?

if (offset < 0) {
throw log.throwing(new InvalidRequestException("Offset cannot be less than 0."));
}
calls = allCalls.stream()

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

same

.collect(Collectors.toList());
}
if (this.requestParameters.isGetFilters()) {
// Multi-species endpoint does not support post-filters; ignore.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

throw InvalidRequestException then

log.traceExit();
}

private MultispecExprCallItem toMultispecExprCallItem(SimilarityExpressionCall2 sc) {

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Feel lazy to read, explain to me why it's needed when we meet :p

Comment thread pom.xml
<groupId>org.bgee.log4jdbc-log4j2</groupId>
<artifactId>log4jdbc-log4j2-jdbc4.1</artifactId>
<version>1.17-SNAPSHOT</version>
<version>1.16</version>

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Check whether this should be merge back

@fbastian fbastian requested a review from hdetering June 19, 2026 14:28
* @return The {@code Stream} of {@code SimilarityExpressionCall2}s that are
* the similar expression calls for the requested parameters.
*/
public Stream<SimilarityExpressionCall2> loadSimilarityExpressionCalls2(int taxonId,

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

You can extend CallFilter to create a MultiSpeciesExpressionCallFilter accepting multiple GeneFilters, taxonId, and the boolean onlyTrusted

throw log.throwing(new IllegalArgumentException("No gene filter should be null"));
}

Set<GeneFilter> clnGeneFilters = Collections.unmodifiableSet(

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Set clnGeneFilters = geneFilters == null || geneFilters.isEmpty() ?Collections.unmodifiableSet(this.getServiceFactory().getSpeciesService()
.loadSpeciesByTaxonIds(Collections.singleton(taxonId), false)
.stream().map(s -> new GeneFilter(s.getId()))
.collect(Collectors.toSet())) :
geneFilters;

Set<AnatEntitySimilarity> anatEntitySimilaritiesFromCellTypeFilter =
new HashSet<>(anatEntitySimilaritiesFromAnatFilter);

// Extract anat entity and cell type IDs from conditionFilters for filtering similarities

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Also, don't separate anatEntities and CellTypes work, do everything at once, and separate at the end using methd isCellType() for line 1107


// Load ExpressionCall2 for each species and merge (ExpressionCallFilter2 has single GeneFilter)
List<ExpressionCall2> allCalls = new ArrayList<>();
for (GeneFilter gf : clnGeneFilters) {

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Maybe a solution not to put everything in memory at once for a given GeneFilter, and still retrieving all data at once for `AnatEntitySimilarity, would be to have 2 interleaved loops:

for (AnatEntitySimilarity sim: sims) {
    for (GeneFilter gf : clnGeneFilters) {
      call ExpressionCallLoader
      for (Gene gene in returned ExpressionCalls) {
          => produce ONE SimilarityExpressionCall
      }
   }
}

Should we put all orthologous genes in a SimilarityExpressionCall?
Should we provide "pagination" on number of AnatEntitySimilaritys iterated? Or on number of SimilarityExpressionCalls returned? But then, complicated to know which AnatEntitySimilarity and GeneFilter to restart the procedure from

* Extracts the anatomical entity from a {@code Condition2} for ANAT_ENTITY_CELL_TYPE.
* ComposedEntity order: cellType at index 0, anatEntity at index 1 when both present.
*/
private static AnatEntity getAnatEntityFromCondition2(

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

See contructor of Condition2

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