Skip to content

Commit

Permalink
Ensure that inference works across ontologies
Browse files Browse the repository at this point in the history
Add a test case where a term from TGEMO has a parent defined in EFO.
  • Loading branch information
arteymix committed Dec 13, 2023
1 parent e68130d commit 4300e77
Show file tree
Hide file tree
Showing 2 changed files with 173 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -388,32 +388,31 @@ public Collection<CharacteristicValueObject> findTermsInexact( String givenQuery

@Override
public Set<OntologyTerm> getParents( Collection<OntologyTerm> terms, boolean direct, boolean includeAdditionalProperties ) {
return combineInThreads( os -> ontologyCache.getParents( os, terms, direct, includeAdditionalProperties ) );
Set<OntologyTerm> toQuery = new HashSet<>( terms );
Set<OntologyTerm> results = new HashSet<>();
while ( !toQuery.isEmpty() ) {
Set<OntologyTerm> newResults = combineInThreads( os -> ontologyCache.getParents( os, toQuery, direct, includeAdditionalProperties ) );
results.addAll( newResults );
// toQuery = newResults - toQuery
newResults.removeAll( toQuery );
toQuery.clear();
toQuery.addAll( newResults );
}
return results;
}

@Override
public Set<OntologyTerm> getChildren( Collection<OntologyTerm> terms, boolean direct, boolean includeAdditionalProperties ) {
StopWatch timer = StopWatch.createStarted();
try {
return combineInThreads( os -> {
StopWatch timer2 = StopWatch.createStarted();
try {
return ontologyCache.getChildren( os, terms, direct, includeAdditionalProperties );
} finally {
if ( timer2.getTime() > 1000 ) {
log.warn( String.format( "Gathering children of %d terms from %s took %d ms", terms.size(), os, timer2.getTime() ) );
} else {
log.trace( String.format( "Gathering children of %d terms from %s took %d ms", terms.size(), os, timer2.getTime() ) );
}
}
} );
} finally {
if ( timer.getTime() > 1000 ) {
log.warn( String.format( "Gathering children of %d terms took %d ms", terms.size(), timer.getTime() ) );
} else {
log.debug( String.format( "Gathering children of %d terms took %d ms", terms.size(), timer.getTime() ) );
}
Set<OntologyTerm> toQuery = new HashSet<>( terms );
Set<OntologyTerm> results = new HashSet<>();
while ( !toQuery.isEmpty() ) {
Set<OntologyTerm> newResults = combineInThreads( os -> ontologyCache.getChildren( os, toQuery, direct, includeAdditionalProperties ) );
results.addAll( newResults );
newResults.removeAll( toQuery );
toQuery.clear();
toQuery.addAll( newResults );
}
return results;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
package ubic.gemma.core.ontology;

import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.cache.CacheManager;
import org.springframework.cache.concurrent.ConcurrentMapCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.task.AsyncTaskExecutor;
import org.springframework.core.task.SimpleAsyncTaskExecutor;
import org.springframework.core.task.TaskExecutor;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;
import ubic.basecode.ontology.model.OntologyTerm;
import ubic.basecode.ontology.providers.ExperimentalFactorOntologyService;
import ubic.basecode.ontology.providers.ObiService;
import ubic.gemma.core.genome.gene.service.GeneService;
import ubic.gemma.core.ontology.providers.GemmaOntologyService;
import ubic.gemma.core.ontology.providers.GeneOntologyService;
import ubic.gemma.core.search.SearchService;
import ubic.gemma.core.util.test.TestPropertyPlaceholderConfigurer;
import ubic.gemma.core.util.test.category.SlowTest;
import ubic.gemma.persistence.service.common.description.CharacteristicService;
import ubic.gemma.persistence.util.TestComponent;

import java.util.Collections;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertNotNull;
import static org.mockito.Mockito.mock;

/**
* This test covers cases where inference is done across two distinct {@link ubic.basecode.ontology.providers.OntologyService}.
* @author poirigui
*/
@Category(SlowTest.class)
@ContextConfiguration
public class GemmaAndExperimentalFactorOntologyTest extends AbstractJUnit4SpringContextTests {

@Configuration
@TestComponent
static class GemmaOntologyAndEfoTestContextConfiguration {

@Bean
public static TestPropertyPlaceholderConfigurer testPropertyPlaceholderConfigurer() {
return new TestPropertyPlaceholderConfigurer( "load.ontologies=false" );
}

@Bean
public ExperimentalFactorOntologyService experimentalFactorOntologyService() {
ExperimentalFactorOntologyService ontology = new ExperimentalFactorOntologyService();
ontology.setSearchEnabled( false );
ontology.initialize( true, false );
return ontology;
}

@Bean
public GemmaOntologyService gemmaOntologyService() {
GemmaOntologyService ontology = new GemmaOntologyService();
ontology.setProcessImports( false ); // FIXME: remove this once https://github.com/PavlidisLab/TGEMO/pull/20 is merged in TGEMO
ontology.initialize( true, false );
return ontology;
}

@Bean
public OntologyService ontologyService() {
return new OntologyServiceImpl();
}

@Bean
public CharacteristicService characteristicService() {
return mock();
}

@Bean
public SearchService searchService() {
return mock();
}

@Bean
public GeneOntologyService geneOntologyService() {
return mock();
}

@Bean
public GeneService geneService() {
return mock();
}

@Bean
public AsyncTaskExecutor taskExecutor() {
return new SimpleAsyncTaskExecutor();
}

@Bean
public ObiService obiService() {
return mock();
}

@Bean
@Qualifier("ontologyTaskExecutor")
public TaskExecutor ontologyTaskExecutor() {
return mock();
}

@Bean
public CacheManager cacheManager() {
return new ConcurrentMapCacheManager();
}
}

@Autowired
private ExperimentalFactorOntologyService experimentalFactorOntologyService;

@Autowired
private GemmaOntologyService gemmaOntologyService;

@Autowired
private OntologyService ontologyService;

@Test
@Category(SlowTest.class)
public void testInferenceInGemma() {
OntologyTerm overexpression = ontologyService.getTerm( "http://gemma.msl.ubc.ca/ont/TGEMO_00004" );
assertNotNull( overexpression );

assertThat( gemmaOntologyService.getParents( Collections.singleton( overexpression ), false, false ) )
.extracting( OntologyTerm::getUri )
.containsExactly( "http://www.ebi.ac.uk/efo/EFO_0000510" );

OntologyTerm geneticModification = experimentalFactorOntologyService.getTerm( "http://www.ebi.ac.uk/efo/EFO_0000510" );
assertNotNull( geneticModification );

assertThat( experimentalFactorOntologyService.getParents( Collections.singleton( geneticModification ), false, false ) )
.extracting( OntologyTerm::getUri )
.containsExactly( "http://www.ebi.ac.uk/efo/EFO_0000001",
"http://purl.obolibrary.org/obo/BFO_0000015",
"http://www.ebi.ac.uk/efo/EFO_0004542",
"http://www.ebi.ac.uk/efo/EFO_0002694" );

// ensure that parents are combined when using the OS
assertThat( ontologyService.getParents( Collections.singleton( overexpression ), false, false ) )
.extracting( OntologyTerm::getUri )
.containsExactlyInAnyOrder(
"http://www.ebi.ac.uk/efo/EFO_0000001",
"http://purl.obolibrary.org/obo/BFO_0000015",
"http://www.ebi.ac.uk/efo/EFO_0004542",
"http://www.ebi.ac.uk/efo/EFO_0002694",
"http://www.ebi.ac.uk/efo/EFO_0000510" );
}
}

0 comments on commit 4300e77

Please sign in to comment.