Skip to content

Commit

Permalink
Allow Cohort sample list updates (#1212)
Browse files Browse the repository at this point in the history
Signed-off-by: Angelica Ochoa <[email protected]>
  • Loading branch information
ao508 authored Jul 2, 2024
1 parent de5f044 commit 1efb394
Show file tree
Hide file tree
Showing 8 changed files with 120 additions and 20 deletions.
21 changes: 20 additions & 1 deletion model/src/main/java/org/mskcc/smile/model/tempo/Cohort.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
package org.mskcc.smile.model.tempo;

import java.io.Serializable;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.mskcc.smile.model.SmileSample;
import org.mskcc.smile.model.tempo.json.CohortCompleteJson;
Expand Down Expand Up @@ -103,7 +106,7 @@ public void setCohortSamples(List<SmileSample> cohortSamples) {

/**
* Returns latest cohort complete data.
* @return
* @return CohortComplete
*/
public CohortComplete getLatestCohortComplete() {
if (cohortCompleteList != null && !cohortCompleteList.isEmpty()) {
Expand All @@ -116,6 +119,22 @@ public CohortComplete getLatestCohortComplete() {
return null;
}

/**
* Returns sample ids as set of strings.
* @return Set
* @throws ParseException
*/
public Set<String> getCohortSamplePrimaryIds() throws ParseException {
if (cohortSamples == null) {
return new HashSet<>();
}
Set<String> sampleIds = new HashSet<>();
for (SmileSample sample : cohortSamples) {
sampleIds.add(sample.getPrimarySampleAlias());
}
return sampleIds;
}

@Override
public String toString() {
return ToStringBuilder.reflectionToString(this);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import java.util.List;
import java.util.Set;
import org.mskcc.smile.model.tempo.Cohort;
import org.mskcc.smile.model.tempo.CohortComplete;

/**
*
Expand All @@ -13,6 +12,8 @@ public interface CohortCompleteService {
Cohort saveCohort(Cohort cohort, Set<String> samplePrimaryIds) throws Exception;
Cohort getCohortByCohortId(String cohortId) throws Exception;
List<Cohort> getCohortsBySamplePrimaryId(String primaryId) throws Exception;
Boolean hasUpdates(Cohort cohort, CohortComplete newCohortComplete) throws Exception;
Boolean hasUpdates(Cohort existingCohort, Cohort cohort) throws Exception;
Boolean hasCohortCompleteUpdates(Cohort existingCohort, Cohort cohort)
throws Exception;
Cohort updateCohort(Cohort cohort) throws Exception;
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
import org.mskcc.smile.commons.JsonComparator;
import org.mskcc.smile.model.SmileSample;
import org.mskcc.smile.model.tempo.Cohort;
import org.mskcc.smile.model.tempo.CohortComplete;
import org.mskcc.smile.persistence.neo4j.CohortCompleteRepository;
import org.mskcc.smile.service.CohortCompleteService;
import org.mskcc.smile.service.SmileSampleService;
Expand Down Expand Up @@ -87,10 +86,20 @@ public List<Cohort> getCohortsBySamplePrimaryId(String primaryId) throws Excepti
}

@Override
public Boolean hasUpdates(Cohort cohort, CohortComplete cohortComplete) throws Exception {
String existingCohortComplete = mapper.writeValueAsString(cohort.getLatestCohortComplete());
String currentCohortComplete = mapper.writeValueAsString(cohortComplete);
return !jsonComparator.isConsistentGenericComparison(existingCohortComplete, currentCohortComplete);
public Boolean hasUpdates(Cohort existingCohort, Cohort cohort) throws Exception {
// check cohort complete data for updates first
Boolean hasUpdates = hasCohortCompleteUpdates(existingCohort, cohort);
Set<String> newSamples = cohort.getCohortSamplePrimaryIds();
newSamples.removeAll(existingCohort.getCohortSamplePrimaryIds());
return (hasUpdates || !newSamples.isEmpty());
}

@Override
public Boolean hasCohortCompleteUpdates(Cohort existingCohort, Cohort cohort) throws Exception {
String existingCohortComplete = mapper.writeValueAsString(existingCohort.getLatestCohortComplete());
String currentCohortComplete = mapper.writeValueAsString(cohort.getLatestCohortComplete());
return !jsonComparator.isConsistentGenericComparison(existingCohortComplete,
currentCohortComplete);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,8 @@ public SmileSample getDetailedSmileSample(SmileSample sample) throws Exception {
sample.setTempo(tempo);
} catch (IncorrectResultSizeDataAccessException e) {
if (e.getActualSize() < 0) {
LOG.warn("There is no TEMPO data for sample: " + sample.getPrimarySampleAlias());
LOG.warn("There is no TEMPO data for sample: " + sample.getPrimarySampleAlias()
+ " - TEMPO data will not be set for sample.");
} else {
StringBuilder b = new StringBuilder();
b.append("Error fetching TEMPO data for sample: ")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,7 @@
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.nats.client.Message;
import java.nio.charset.StandardCharsets;
import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
Expand All @@ -26,7 +22,6 @@
import org.mskcc.smile.model.SmileSample;
import org.mskcc.smile.model.tempo.BamComplete;
import org.mskcc.smile.model.tempo.Cohort;
import org.mskcc.smile.model.tempo.CohortComplete;
import org.mskcc.smile.model.tempo.MafComplete;
import org.mskcc.smile.model.tempo.QcComplete;
import org.mskcc.smile.model.tempo.Tempo;
Expand Down Expand Up @@ -273,10 +268,18 @@ public void run() {
// compiles them into a set list of strings
cohortCompleteService.saveCohort(cohort, ccJson.getTumorNormalPairsAsSet());
} else if (cohortCompleteService.hasUpdates(existingCohort,
cohort.getLatestCohortComplete())) {
cohort)) {
LOG.info("Received updates for cohort: " + ccJson.getCohortId());
existingCohort.addCohortComplete(cohort.getLatestCohortComplete());
cohortCompleteService.updateCohort(existingCohort);
if (cohortCompleteService.hasCohortCompleteUpdates(existingCohort, cohort)) {
existingCohort.addCohortComplete(cohort.getLatestCohortComplete());
}

// new samples refer to samples that aren't yet linked to the given cohort
Set<String> newSamples = ccJson.getTumorNormalPairsAsSet();
newSamples.removeAll(existingCohort.getCohortSamplePrimaryIds());

// persist updates to db
cohortCompleteService.saveCohort(existingCohort, newSamples);
} else {
LOG.error("Cohort " + ccJson.getCohortId()
+ " already exists and no new updates were received.");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
import org.mskcc.smile.model.SmileRequest;
Expand Down Expand Up @@ -103,8 +104,16 @@ public void initializeMockDatabase() throws Exception {
// mock request id: MOCKREQUEST1_B
MockJsonTestData request1Data = mockDataUtils.mockedRequestJsonDataMap
.get("mockIncomingRequest1JsonDataWith2T2N");
SmileRequest request1 = RequestDataFactory.buildNewLimsRequestFromJson(request1Data.getJsonString());
SmileRequest request1 =
RequestDataFactory.buildNewLimsRequestFromJson(request1Data.getJsonString());
requestService.saveRequest(request1);

// mock request id: 22022_BZ
MockJsonTestData request2bData = mockDataUtils.mockedRequestJsonDataMap
.get("mockIncomingRequest2bJsonDataMissing1N");
SmileRequest request2b =
RequestDataFactory.buildNewLimsRequestFromJson(request2bData.getJsonString());
requestService.saveRequest(request2b);
}

@Test
Expand Down Expand Up @@ -213,8 +222,7 @@ public void testUpdateCohortCompleteData() throws Exception {
CohortCompleteJson ccJsonUpdate = getCohortEventData("mockCohortCompleteCCSPPPQQQQUpdated");

Cohort updatedCohort = new Cohort(ccJsonUpdate);
CohortComplete updatedCohortComplete = updatedCohort.getLatestCohortComplete();
Boolean hasUpdates = cohortCompleteService.hasUpdates(cohort, updatedCohortComplete);
Boolean hasUpdates = cohortCompleteService.hasUpdates(cohort, updatedCohort);
Assertions.assertThat(hasUpdates).isTrue();
}

Expand Down Expand Up @@ -251,6 +259,32 @@ public void testNormalSampleTumorSampleTempoImportDefaults() throws Exception {
Assertions.assertThat(tempoAfterSave3.getAccessLevel()).isNotBlank();
}

@Test
public void testCohortSampleListUpdate() throws Exception {
CohortCompleteJson ccJson = getCohortEventData("mockCohortCompleteCCSPPPQQQQ");
cohortCompleteService.saveCohort(new Cohort(ccJson), ccJson.getTumorNormalPairsAsSet());
Cohort cohort = cohortCompleteService.getCohortByCohortId("CCS_PPPQQQQ");
Assertions.assertThat(cohort.getCohortSamplePrimaryIds().size()).isEqualTo(4);

CohortCompleteJson ccJsonUpdate =
getCohortEventData("mockCohortCompleteCCSPPPQQQQUpdatedSamplesOnly");
Assertions.assertThat(ccJsonUpdate.getTumorNormalPairsAsSet().size()).isEqualTo(6);

Cohort updatedCohort = new Cohort(ccJsonUpdate);
Boolean hasUpdates = cohortCompleteService.hasUpdates(cohort, updatedCohort);
Assertions.assertThat(hasUpdates).isTrue();

// verify there are 2 new samples getting added to the cohort
Set<String> newSamples = ccJsonUpdate.getTumorNormalPairsAsSet();
newSamples.removeAll(cohort.getCohortSamplePrimaryIds());
Assertions.assertThat(newSamples.size()).isEqualTo(2);

// save cohort and verify that it now has 6 samples instead of 4
cohortCompleteService.saveCohort(cohort, newSamples);
Cohort cohortAfterSave = cohortCompleteService.getCohortByCohortId("CCS_PPPQQQQ");
Assertions.assertThat(cohortAfterSave.getCohortSamplePrimaryIds().size()).isEqualTo(6);
}

private CohortCompleteJson getCohortEventData(String dataIdentifier) throws JsonProcessingException {
MockJsonTestData mockData = mockDataUtils.mockedTempoDataMap.get(dataIdentifier);
CohortCompleteJson cohortCompleteData = mapper.readValue(mockData.getJsonString(),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"cohortId": "CCS_PPPQQQQ",
"date": "2022-11-12 21:59",
"type": "investigator",
"endUsers": [
"enduser1",
"enduser2",
"enduser3"
],
"pmUsers": [
"pmuser1",
"pmuser2",
"pmuser3"
],
"projectTitle": "A title",
"projectSubtitle": "A longer description",
"samples": [
{
"primaryId": "MOCKREQUEST1_B_1",
"normalPrimaryId": "MOCKREQUEST1_B_2"
},
{
"primaryId": "MOCKREQUEST1_B_3",
"normalPrimaryId": "MOCKREQUEST1_B_4"
},
{
"primaryId": "22022_BZ_15",
"normalPrimaryId": "22022_BZ_19"
}
],
"status": "PASS"
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@ mockMafCompleteSampleB3pass tempo/maf_complete_MOCKREQUEST1_B_3_pass.json Mocked
mockCohortCompleteCCSPPPQQQQ tempo/cohort_complete_CCS_PPPQQQQ.json Mocked Cohort complete JSON with cohort ID CCS_PPPQQQQ. Has 4 samples associated with it.
mockCohortCompleteCCSPPPQQQQ2 tempo/cohort_complete_CCS_PPPQQQQ_2.json Mocked Cohort complete JSON with cohort ID CCS_PPPQQQQ_2. Has 2 samples associated with it.
mockCohortCompleteCCSPPPQQQQUpdated tempo/cohort_complete_CCS_PPPQQQQ_updated.json Mocked updated Cohort complete JSON with cohort ID CCS_PPPQQQQ. Has 4 samples associated with it.
mockCohortCompleteCCSPPPQQQQUpdatedSamplesOnly tempo/cohort_complete_CCS_PPPQQQQ_updated_samples_only.json Mocked updated Cohort complete JSON with cohort ID CCS_PPPQQQQ. Has 6 samples associated with it.

0 comments on commit 1efb394

Please sign in to comment.