TSnePlotService { public Map<String, Set<TSnePoint>> fetchTSnePlotWithMetadata(String experimentAccession, int perplexity, String metadataCategory) { List<TSnePoint.Dto> pointDtos = tSnePlotDao.fetchTSnePlotForPerplexity(experimentAccession, perplexity); List<String> cellIds = pointDtos .stream() .map(TSnePoint.Dto::name) .collect(Collectors.toList()); Map<String, String> metadataValuesForCells = cellMetadataDao.getMetadataValueForCellIds( experimentAccession, SingleCellAnalyticsCollectionProxy.metadataAsSchemaField(metadataCategory), cellIds); return pointDtos.stream() .map( pointDto -> TSnePoint.create( pointDto.x(), pointDto.y(), pointDto.name(), StringUtils.capitalize(metadataValuesForCells.get(pointDto.name())))) .collect(groupingBy(TSnePoint::metadata, mapping(Function.identity(), Collectors.toSet()))); } TSnePlotService(TSnePlotDao tSnePlotDao, CellMetadataDao cellMetadataDao); Set<TSnePoint> fetchTSnePlotWithExpression(String experimentAccession, int perplexity, String geneId); Map<Integer, Set<TSnePoint>> fetchTSnePlotWithClusters(String experimentAccession, int perplexity, int k); Map<String, Set<TSnePoint>> fetchTSnePlotWithMetadata(String experimentAccession,
                                                                 int perplexity,
                                                                 String metadataCategory);  }
@Test @DisplayName("Points retrieved by the DAO class are correctly grouped according to metadata values") void testFetchPlotWithMetadata() { String experimentAccession = RandomDataTestUtils.generateRandomExperimentAccession(); int[] perplexities = new int[] {1, 5, 10, 15, 20}; int perplexity = perplexities[ThreadLocalRandom.current().nextInt(0, perplexities.length)]; String metadataCategory = "characteristic_inferred_cell_type"; List<String> metadataValues = Arrays.asList("neuron", "stem cell", "B cell"); Set<TSnePoint.Dto> randomPointDtos = RandomDataTestUtils.generateRandomTSnePointDtos(NUMBER_OF_CELLS); when(tSnePlotDaoMock.fetchTSnePlotForPerplexity(experimentAccession, perplexity)) .thenReturn(ImmutableList.copyOf(randomPointDtos)); List<String> cellIds = randomPointDtos .stream() .map(TSnePoint.Dto::name) .collect(Collectors.toList()); assertThat(cellIds).doesNotHaveDuplicates(); Map<String, String> cellMetadata = cellIds .stream() .collect(Collectors.toMap( Function.identity(), value -> metadataValues.get(ThreadLocalRandom.current().nextInt(0, metadataValues.size())))); when( cellMetadataDaoMock.getMetadataValueForCellIds( eq(experimentAccession), any(SingleCellAnalyticsSchemaField.class), eq(cellIds))) .thenReturn(cellMetadata); Map<String, Set<TSnePoint>> results = subject.fetchTSnePlotWithMetadata(experimentAccession, perplexity, metadataCategory); assertThat(results) .containsOnlyKeys(metadataValues.stream().map(StringUtils::capitalize).toArray(String[]::new)); }