Skip to content

Commit

Permalink
[ALS-5050] Ignore invalid concept paths in anyRecordOf queries (#87)
Browse files Browse the repository at this point in the history
  • Loading branch information
ramari16 authored and Luke Sikina committed Oct 30, 2023
1 parent b785670 commit 47b827b
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,12 @@ private void addIdSetsForAnyRecordOf(List<String> anyRecordOfFilters, ArrayList<
addIdSetsForVariantSpecCategoryFilters(new String[]{"0/1", "1/1"}, path, patientsInScope, bucketCache);
return patientsInScope.stream();
} else {
return (Stream<Integer>) getCube(path).keyBasedIndex().stream();
try {
return (Stream<Integer>) getCube(path).keyBasedIndex().stream();
} catch (InvalidCacheLoadException e) {
// return an empty stream if this concept doesn't exist
return Stream.empty();
}
}
}).collect(Collectors.toSet());
filteredIdSets.add(anyRecordOfPatientSet);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package edu.harvard.hms.dbmi.avillach.hpds.processing;


import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import edu.harvard.hms.dbmi.avillach.hpds.data.genotype.FileBackedByteIndexedInfoStore;
import edu.harvard.hms.dbmi.avillach.hpds.data.phenotype.PhenoCube;
import edu.harvard.hms.dbmi.avillach.hpds.data.query.Query;
import edu.harvard.hms.dbmi.avillach.hpds.storage.FileBackedByteIndexedStorage;
import org.junit.Before;
Expand All @@ -12,6 +15,7 @@
import org.mockito.junit.MockitoJUnitRunner;

import java.util.*;
import java.util.concurrent.ExecutionException;

import static org.mockito.ArgumentMatchers.any;
import static org.junit.Assert.*;
Expand All @@ -33,6 +37,9 @@ public class AbstractProcessorTest {
@Mock
private PatientVariantJoinHandler patientVariantJoinHandler;

@Mock
private LoadingCache<String, PhenoCube<?>> mockLoadingCache;

public static final String GENE_WITH_VARIANT_KEY = "Gene_with_variant";
private static final String VARIANT_SEVERITY_KEY = "Variant_severity";
public static final List<String> EXAMPLE_GENES_WITH_VARIANT = List.of("CDH8", "CDH9", "CDH10");
Expand Down Expand Up @@ -61,7 +68,7 @@ public void setup() {
new TreeMap<>(),
new TreeSet<>()
),
null,
mockLoadingCache,
infoStores,
null,
variantService,
Expand Down Expand Up @@ -125,20 +132,87 @@ public void getPatientSubsetForQuery_twoVariantCategoryFilters_intersectFilters(
when(patientVariantJoinHandler.getPatientIdsForIntersectionOfVariantSets(any(), argumentCaptor.capture())).thenReturn(List.of(Set.of(42)));

Map<String, String[]> categoryVariantInfoFilters = Map.of(
GENE_WITH_VARIANT_KEY, new String[] {EXAMPLE_GENES_WITH_VARIANT.get(0)},
VARIANT_SEVERITY_KEY, new String[] {EXAMPLE_VARIANT_SEVERITIES.get(0)}
GENE_WITH_VARIANT_KEY, new String[] {EXAMPLE_GENES_WITH_VARIANT.get(0)},
VARIANT_SEVERITY_KEY, new String[] {EXAMPLE_VARIANT_SEVERITIES.get(0)}
);
Query.VariantInfoFilter variantInfoFilter = new Query.VariantInfoFilter();
variantInfoFilter.categoryVariantInfoFilters = categoryVariantInfoFilters;

List<Query.VariantInfoFilter> variantInfoFilters = List.of(variantInfoFilter);

Query query = new Query();
query.setVariantInfoFilters(variantInfoFilters);

TreeSet<Integer> patientSubsetForQuery = abstractProcessor.getPatientSubsetForQuery(query);
assertFalse(patientSubsetForQuery.isEmpty());
// Expected result is the intersection of the two filters
assertEquals(argumentCaptor.getValue(), new SparseVariantIndex(Set.of(4, 6)));
}

@Test
public void getPatientSubsetForQuery_anyRecordOf_applyOrLogic() throws ExecutionException {
when(variantIndexCache.get(GENE_WITH_VARIANT_KEY, EXAMPLE_GENES_WITH_VARIANT.get(0))).thenReturn(new SparseVariantIndex(Set.of(2, 4, 6)));
when(variantIndexCache.get(VARIANT_SEVERITY_KEY, EXAMPLE_VARIANT_SEVERITIES.get(0))).thenReturn(new SparseVariantIndex(Set.of(4, 5, 6, 7)));

ArgumentCaptor<VariantIndex> argumentCaptor = ArgumentCaptor.forClass(VariantIndex.class);
ArgumentCaptor<List<Set<Integer>>> listArgumentCaptor = ArgumentCaptor.forClass(List.class);
when(patientVariantJoinHandler.getPatientIdsForIntersectionOfVariantSets(listArgumentCaptor.capture(), argumentCaptor.capture())).thenReturn(List.of(Set.of(42)));

Map<String, String[]> categoryVariantInfoFilters = Map.of(
GENE_WITH_VARIANT_KEY, new String[] {EXAMPLE_GENES_WITH_VARIANT.get(0)},
VARIANT_SEVERITY_KEY, new String[] {EXAMPLE_VARIANT_SEVERITIES.get(0)}
);
Query.VariantInfoFilter variantInfoFilter = new Query.VariantInfoFilter();
variantInfoFilter.categoryVariantInfoFilters = categoryVariantInfoFilters;

List<Query.VariantInfoFilter> variantInfoFilters = List.of(variantInfoFilter);

PhenoCube mockPhenoCube = mock(PhenoCube.class);
when(mockPhenoCube.keyBasedIndex()).thenReturn(List.of(42, 101));
when(mockLoadingCache.get("good concept")).thenReturn(mockPhenoCube);
when(mockLoadingCache.get("bad concept")).thenThrow(CacheLoader.InvalidCacheLoadException.class);

Query query = new Query();
query.setVariantInfoFilters(variantInfoFilters);
query.setAnyRecordOf(List.of("good concept", "bad concept"));

TreeSet<Integer> patientSubsetForQuery = abstractProcessor.getPatientSubsetForQuery(query);
assertFalse(patientSubsetForQuery.isEmpty());
// Expected result is the intersection of the two filters
assertEquals(argumentCaptor.getValue(), new SparseVariantIndex(Set.of(4, 6)));
assertEquals(listArgumentCaptor.getValue().get(0), Set.of(42, 101));
}



@Test
public void getPatientSubsetForQuery_anyRecordOfInvalidKey_returnEmpty() throws ExecutionException {
when(variantIndexCache.get(GENE_WITH_VARIANT_KEY, EXAMPLE_GENES_WITH_VARIANT.get(0))).thenReturn(new SparseVariantIndex(Set.of(2, 4, 6)));
when(variantIndexCache.get(VARIANT_SEVERITY_KEY, EXAMPLE_VARIANT_SEVERITIES.get(0))).thenReturn(new SparseVariantIndex(Set.of(4, 5, 6, 7)));

ArgumentCaptor<VariantIndex> argumentCaptor = ArgumentCaptor.forClass(VariantIndex.class);
ArgumentCaptor<List<Set<Integer>>> listArgumentCaptor = ArgumentCaptor.forClass(List.class);
when(patientVariantJoinHandler.getPatientIdsForIntersectionOfVariantSets(listArgumentCaptor.capture(), argumentCaptor.capture())).thenReturn(List.of(Set.of(42)));

Map<String, String[]> categoryVariantInfoFilters = Map.of(
GENE_WITH_VARIANT_KEY, new String[] {EXAMPLE_GENES_WITH_VARIANT.get(0)},
VARIANT_SEVERITY_KEY, new String[] {EXAMPLE_VARIANT_SEVERITIES.get(0)}
);
Query.VariantInfoFilter variantInfoFilter = new Query.VariantInfoFilter();
variantInfoFilter.categoryVariantInfoFilters = categoryVariantInfoFilters;

List<Query.VariantInfoFilter> variantInfoFilters = List.of(variantInfoFilter);

when(mockLoadingCache.get("bad concept")).thenThrow(CacheLoader.InvalidCacheLoadException.class);

Query query = new Query();
query.setVariantInfoFilters(variantInfoFilters);
query.setAnyRecordOf(List.of("bad concept"));

TreeSet<Integer> patientSubsetForQuery = abstractProcessor.getPatientSubsetForQuery(query);
assertFalse(patientSubsetForQuery.isEmpty());
// Expected result is the intersection of the two filters
assertEquals(argumentCaptor.getValue(), new SparseVariantIndex(Set.of(4, 6)));
assertEquals(listArgumentCaptor.getValue().get(0), Set.of());
}
}

0 comments on commit 47b827b

Please sign in to comment.