diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/FamilyMongoDBAdaptor.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/FamilyMongoDBAdaptor.java index cdf850b571f..020e4aecef0 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/FamilyMongoDBAdaptor.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/FamilyMongoDBAdaptor.java @@ -181,7 +181,8 @@ Family insert(ClientSession clientSession, long studyUid, Family family, List> roles = calculateRoles(clientSession, studyUid, family); + family.setRoles(roles); Document familyDocument = familyConverter.convertToStorageType(family, variableSetList); @@ -356,8 +357,6 @@ OpenCGAResult privateUpdate(ClientSession clientSession, Family family, Bson bsonQuery = parseQuery(tmpQuery); return versionedMongoDBAdaptor.update(clientSession, bsonQuery, () -> { DataResult result = updateAnnotationSets(clientSession, family.getUid(), parameters, variableSetList, queryOptions, true); - UpdateDocument updateDocument = parseAndValidateUpdateParams(clientSession, parameters, tmpQuery); - List familyMemberIds = family.getMembers().stream().map(Individual::getId).collect(Collectors.toList()); boolean updateRoles = queryOptions.getBoolean(ParamConstants.FAMILY_UPDATE_ROLES_PARAM); if (CollectionUtils.isNotEmpty(parameters.getAsList(QueryParams.MEMBERS.key()))) { @@ -399,10 +398,11 @@ OpenCGAResult privateUpdate(ClientSession clientSession, Family family, OpenCGAResult memberResult = dbAdaptorFactory.getCatalogIndividualDBAdaptor().get(clientSession, individualQuery, relationshipOptions); family.setMembers(memberResult.getResults()); - calculateRoles(clientSession, family.getStudyUid(), family); - updateDocument.getSet().put(QueryParams.ROLES.key(), family.getRoles()); + Map> roles = calculateRoles(clientSession, family.getStudyUid(), + family); + parameters.put(QueryParams.ROLES.key(), roles); } else { - updateDocument.getSet().put(QueryParams.ROLES.key(), Collections.emptyMap()); + parameters.put(QueryParams.ROLES.key(), Collections.emptyMap()); } } @@ -1009,12 +1009,12 @@ public OpenCGAResult updateProjectRelease(long studyId, int release) }); } - private void calculateRoles(ClientSession clientSession, long studyUid, Family family) + Map> calculateRoles(ClientSession clientSession, long studyUid, Family family) throws CatalogDBException, CatalogParameterException, CatalogAuthorizationException { if (family.getMembers() == null || family.getMembers().size() <= 1) { family.setRoles(Collections.emptyMap()); // Nothing to calculate - return; + return Collections.emptyMap(); } Set individualIds = family.getMembers().stream().map(Individual::getId).collect(Collectors.toSet()); @@ -1032,7 +1032,7 @@ private void calculateRoles(ClientSession clientSession, long studyUid, Family f roles.put(member.getId(), memberRelation); } - family.setRoles(roles); + return roles; } /** diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/IndividualMongoDBAdaptor.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/IndividualMongoDBAdaptor.java index 6a8b41ae409..6cf02c41fed 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/IndividualMongoDBAdaptor.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/IndividualMongoDBAdaptor.java @@ -83,6 +83,8 @@ public class IndividualMongoDBAdaptor extends AnnotationMongoDBAdaptor privateUpdate(ClientSession clientSession, Individual indi individual.getId(), parameters.getString(QueryParams.ID.key())); // Update the family roles - dbAdaptorFactory.getCatalogFamilyDBAdaptor().updateIndividualIdFromFamilies(clientSession, individual.getStudyUid(), + familyDBAdaptor.updateIndividualIdFromFamilies(clientSession, individual.getStudyUid(), individual.getUid(), individual.getId(), parameters.getString(QueryParams.ID.key())); } + if (parameters.containsKey(QueryParams.FATHER_UID.key()) || parameters.containsKey(QueryParams.MOTHER_UID.key())) { + // If the parents have changed, we need to check family roles + recalculateFamilyRolesForMember(clientSession, individual.getStudyUid(), individual.getUid()); + } + logger.debug("Individual {} successfully updated", individual.getId()); } @@ -457,6 +466,24 @@ OpenCGAResult privateUpdate(ClientSession clientSession, Individual indi iterator)); } + private void recalculateFamilyRolesForMember(ClientSession clientSession, long studyUid, long memberUid) + throws CatalogParameterException, CatalogDBException, CatalogAuthorizationException { + Query query = new Query() + .append(FamilyDBAdaptor.QueryParams.STUDY_UID.key(), studyUid) + .append(FamilyDBAdaptor.QueryParams.MEMBER_UID.key(), memberUid); + QueryOptions options = new QueryOptions(QueryOptions.INCLUDE, + Arrays.asList(FamilyDBAdaptor.QueryParams.ID.key(), FamilyDBAdaptor.QueryParams.UID.key(), + FamilyDBAdaptor.QueryParams.VERSION.key(), FamilyDBAdaptor.QueryParams.STUDY_UID.key(), + FamilyDBAdaptor.QueryParams.MEMBERS.key() + "." + IndividualDBAdaptor.QueryParams.ID.key())); + try (DBIterator iterator = familyDBAdaptor.iterator(clientSession, query, options)) { + while (iterator.hasNext()) { + Family family = iterator.next(); + familyDBAdaptor.privateUpdate(clientSession, family, new ObjectMap(), null, + new QueryOptions(ParamConstants.FAMILY_UPDATE_ROLES_PARAM, true)); + } + } + } + private void updateReferencesAfterIndividualVersionIncrement(ClientSession clientSession, long studyUid, MongoDBIterator iterator) throws CatalogDBException, CatalogParameterException, CatalogAuthorizationException { @@ -468,7 +495,7 @@ private void updateReferencesAfterIndividualVersionIncrement(ClientSession clien } if (!individualMap.isEmpty()) { - dbAdaptorFactory.getCatalogFamilyDBAdaptor().updateIndividualReferencesInFamily(clientSession, studyUid, individualMap); + familyDBAdaptor.updateIndividualReferencesInFamily(clientSession, studyUid, individualMap); } } @@ -481,8 +508,6 @@ private void recalculateFamilyDisordersPhenotypes(ClientSession clientSession, I .append(QueryParams.STUDY_UID.key(), individual.getStudyUid()) .append(QueryParams.UID.key(), individual.getUid()), individualOptions).first(); - FamilyMongoDBAdaptor familyDBAdaptor = dbAdaptorFactory.getCatalogFamilyDBAdaptor(); - Query familyQuery = new Query() .append(FamilyDBAdaptor.QueryParams.MEMBER_UID.key(), individual.getUid()) .append(FamilyDBAdaptor.QueryParams.STUDY_UID.key(), individual.getStudyUid()); @@ -919,8 +944,6 @@ public OpenCGAResult delete(Query query) throws CatalogDBException, CatalogParam OpenCGAResult privateDelete(ClientSession clientSession, Document individualDocument) throws CatalogDBException, CatalogParameterException, CatalogAuthorizationException { - FamilyMongoDBAdaptor familyDBAdaptor = dbAdaptorFactory.getCatalogFamilyDBAdaptor(); - String individualId = individualDocument.getString(QueryParams.ID.key()); long individualUid = individualDocument.getLong(PRIVATE_UID); long studyUid = individualDocument.getLong(PRIVATE_STUDY_UID); diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/MongoDBAdaptorFactory.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/MongoDBAdaptorFactory.java index 8873a37d33d..32e12c95271 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/MongoDBAdaptorFactory.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/MongoDBAdaptorFactory.java @@ -411,6 +411,8 @@ private void connect(Configuration catalogConfiguration) throws CatalogDBExcepti collections.put(AUDIT_COLLECTION, auditCollection); fileDBAdaptor = new FileMongoDBAdaptor(fileCollection, deletedFileCollection, catalogConfiguration, this); + familyDBAdaptor = new FamilyMongoDBAdaptor(familyCollection, familyArchivedCollection, deletedFamilyCollection, + catalogConfiguration, this); individualDBAdaptor = new IndividualMongoDBAdaptor(individualCollection, individualArchivedCollection, deletedIndividualCollection, catalogConfiguration, this); jobDBAdaptor = new JobMongoDBAdaptor(jobCollection, deletedJobCollection, catalogConfiguration, this); @@ -422,8 +424,6 @@ private void connect(Configuration catalogConfiguration) throws CatalogDBExcepti cohortDBAdaptor = new CohortMongoDBAdaptor(cohortCollection, deletedCohortCollection, catalogConfiguration, this); panelDBAdaptor = new PanelMongoDBAdaptor(panelCollection, panelArchivedCollection, deletedPanelCollection, catalogConfiguration, this); - familyDBAdaptor = new FamilyMongoDBAdaptor(familyCollection, familyArchivedCollection, deletedFamilyCollection, - catalogConfiguration, this); clinicalDBAdaptor = new ClinicalAnalysisMongoDBAdaptor(clinicalCollection, deletedClinicalCollection, catalogConfiguration, this); interpretationDBAdaptor = new InterpretationMongoDBAdaptor(interpretationCollection, interpretationArchivedCollection, deletedInterpretationCollection, catalogConfiguration, this); diff --git a/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/FamilyManagerTest.java b/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/FamilyManagerTest.java index 377a81694a8..04654a6a3a9 100644 --- a/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/FamilyManagerTest.java +++ b/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/FamilyManagerTest.java @@ -415,7 +415,152 @@ public void createComplexFamily() throws CatalogException { assertEquals(Family.FamiliarRelationship.FULL_SIBLING, sisterMap.get("sibling")); assertEquals(Family.FamiliarRelationship.BROTHER, sisterMap.get("brother")); assertEquals(Family.FamiliarRelationship.FULL_SIBLING, sisterMap.get("proband")); + } + + @Test + public void updateFamilyRoles() throws CatalogException { + Individual paternalGrandfather = new Individual().setId("p_grandfather"); + Individual paternalGrandmother = new Individual().setId("p_grandmother"); + Individual maternalGrandfather = new Individual().setId("m_grandfather"); + Individual maternalGrandmother = new Individual().setId("m_grandmother"); + Individual father = new Individual().setId("father").setSex(SexOntologyTermAnnotation.initMale()); + Individual mother = new Individual().setId("mother").setSex(SexOntologyTermAnnotation.initFemale()); + Individual proband = new Individual().setId("proband"); + Individual brother = new Individual().setId("brother").setSex(SexOntologyTermAnnotation.initMale()); + Individual sister = new Individual().setId("sister").setSex(SexOntologyTermAnnotation.initFemale()); + Individual sibling = new Individual().setId("sibling"); + + catalogManager.getFamilyManager().create(STUDY, new Family().setId("family").setMembers( + Arrays.asList(paternalGrandfather, paternalGrandmother, maternalGrandfather, maternalGrandmother, mother, father, proband, + brother, sister, sibling)), QueryOptions.empty(), sessionIdUser); + OpenCGAResult family = catalogManager.getFamilyManager().get(STUDY, "family", QueryOptions.empty(), sessionIdUser); + Map> roles = family.first().getRoles(); + assertEquals(10, family.first().getMembers().size()); + for (Map.Entry> entry : family.first().getRoles().entrySet()) { + assertEquals(0, entry.getValue().size()); + } + // We perform all individual updates to set which are the individual's parents + IndividualUpdateParams updateParams = new IndividualUpdateParams() + .setFather(new IndividualReferenceParam().setId(paternalGrandfather.getId())) + .setMother(new IndividualReferenceParam().setId(paternalGrandmother.getId())); + catalogManager.getIndividualManager().update(STUDY, father.getId(), updateParams, QueryOptions.empty(), sessionIdUser); + + updateParams = new IndividualUpdateParams() + .setFather(new IndividualReferenceParam().setId(maternalGrandfather.getId())) + .setMother(new IndividualReferenceParam().setId(maternalGrandmother.getId())); + catalogManager.getIndividualManager().update(STUDY, mother.getId(), updateParams, QueryOptions.empty(), sessionIdUser); + + updateParams = new IndividualUpdateParams() + .setFather(new IndividualReferenceParam().setId(father.getId())) + .setMother(new IndividualReferenceParam().setId(mother.getId())); + catalogManager.getIndividualManager().update(STUDY, proband.getId(), updateParams, QueryOptions.empty(), sessionIdUser); + catalogManager.getIndividualManager().update(STUDY, brother.getId(), updateParams, QueryOptions.empty(), sessionIdUser); + catalogManager.getIndividualManager().update(STUDY, sister.getId(), updateParams, QueryOptions.empty(), sessionIdUser); + catalogManager.getIndividualManager().update(STUDY, sibling.getId(), updateParams, QueryOptions.empty(), sessionIdUser); + +// catalogManager.getFamilyManager().update(STUDY, family.first().getId(), null, new QueryOptions(ParamConstants.FAMILY_UPDATE_ROLES_PARAM, true), sessionIdUser); + + // Roles should have been automatically updated containing up to date roles + family = catalogManager.getFamilyManager().get(STUDY, "family", QueryOptions.empty(), sessionIdUser); + roles = family.first().getRoles(); + assertEquals(10, family.first().getMembers().size()); + Map pGrandfather = roles.get("p_grandfather"); + assertEquals(5, pGrandfather.size()); + assertEquals(Family.FamiliarRelationship.SON, pGrandfather.get("father")); + assertEquals(Family.FamiliarRelationship.GRANDCHILD, pGrandfather.get("proband")); + assertEquals(Family.FamiliarRelationship.GRANDCHILD, pGrandfather.get("sibling")); + assertEquals(Family.FamiliarRelationship.GRANDSON, pGrandfather.get("brother")); + assertEquals(Family.FamiliarRelationship.GRANDDAUGHTER, pGrandfather.get("sister")); + + Map pGrandmother = roles.get("p_grandmother"); + assertEquals(5, pGrandmother.size()); + assertEquals(Family.FamiliarRelationship.SON, pGrandmother.get("father")); + assertEquals(Family.FamiliarRelationship.GRANDCHILD, pGrandmother.get("proband")); + assertEquals(Family.FamiliarRelationship.GRANDCHILD, pGrandmother.get("sibling")); + assertEquals(Family.FamiliarRelationship.GRANDSON, pGrandmother.get("brother")); + assertEquals(Family.FamiliarRelationship.GRANDDAUGHTER, pGrandmother.get("sister")); + + Map mGrandfather = roles.get("m_grandfather"); + assertEquals(5, mGrandfather.size()); + assertEquals(Family.FamiliarRelationship.DAUGHTER, mGrandfather.get("mother")); + assertEquals(Family.FamiliarRelationship.GRANDCHILD, mGrandfather.get("proband")); + assertEquals(Family.FamiliarRelationship.GRANDCHILD, mGrandfather.get("sibling")); + assertEquals(Family.FamiliarRelationship.GRANDSON, mGrandfather.get("brother")); + assertEquals(Family.FamiliarRelationship.GRANDDAUGHTER, mGrandfather.get("sister")); + + Map mGrandmother = roles.get("m_grandmother"); + assertEquals(5, mGrandmother.size()); + assertEquals(Family.FamiliarRelationship.DAUGHTER, mGrandmother.get("mother")); + assertEquals(Family.FamiliarRelationship.GRANDCHILD, mGrandmother.get("proband")); + assertEquals(Family.FamiliarRelationship.GRANDCHILD, mGrandmother.get("sibling")); + assertEquals(Family.FamiliarRelationship.GRANDSON, mGrandmother.get("brother")); + assertEquals(Family.FamiliarRelationship.GRANDDAUGHTER, mGrandmother.get("sister")); + + Map motherMap = roles.get("mother"); + assertEquals(6, motherMap.size()); + assertEquals(Family.FamiliarRelationship.MOTHER, motherMap.get("m_grandmother")); + assertEquals(Family.FamiliarRelationship.FATHER, motherMap.get("m_grandfather")); + assertEquals(Family.FamiliarRelationship.CHILD_OF_UNKNOWN_SEX, motherMap.get("proband")); + assertEquals(Family.FamiliarRelationship.CHILD_OF_UNKNOWN_SEX, motherMap.get("sibling")); + assertEquals(Family.FamiliarRelationship.SON, motherMap.get("brother")); + assertEquals(Family.FamiliarRelationship.DAUGHTER, motherMap.get("sister")); + Map fatherMap = roles.get("father"); + assertEquals(6, fatherMap.size()); + assertEquals(Family.FamiliarRelationship.MOTHER, fatherMap.get("p_grandmother")); + assertEquals(Family.FamiliarRelationship.FATHER, fatherMap.get("p_grandfather")); + assertEquals(Family.FamiliarRelationship.CHILD_OF_UNKNOWN_SEX, fatherMap.get("proband")); + assertEquals(Family.FamiliarRelationship.CHILD_OF_UNKNOWN_SEX, fatherMap.get("sibling")); + assertEquals(Family.FamiliarRelationship.SON, fatherMap.get("brother")); + assertEquals(Family.FamiliarRelationship.DAUGHTER, fatherMap.get("sister")); + + Map probandMap = roles.get("proband"); + assertEquals(9, probandMap.size()); + assertEquals(Family.FamiliarRelationship.MATERNAL_GRANDMOTHER, probandMap.get("m_grandmother")); + assertEquals(Family.FamiliarRelationship.MATERNAL_GRANDFATHER, probandMap.get("m_grandfather")); + assertEquals(Family.FamiliarRelationship.PATERNAL_GRANDMOTHER, probandMap.get("p_grandmother")); + assertEquals(Family.FamiliarRelationship.PATERNAL_GRANDFATHER, probandMap.get("p_grandfather")); + assertEquals(Family.FamiliarRelationship.MOTHER, probandMap.get("mother")); + assertEquals(Family.FamiliarRelationship.FATHER, probandMap.get("father")); + assertEquals(Family.FamiliarRelationship.FULL_SIBLING, probandMap.get("sibling")); + assertEquals(Family.FamiliarRelationship.BROTHER, probandMap.get("brother")); + assertEquals(Family.FamiliarRelationship.SISTER, probandMap.get("sister")); + + Map siblingMap = roles.get("sibling"); + assertEquals(9, siblingMap.size()); + assertEquals(Family.FamiliarRelationship.MATERNAL_GRANDMOTHER, siblingMap.get("m_grandmother")); + assertEquals(Family.FamiliarRelationship.MATERNAL_GRANDFATHER, siblingMap.get("m_grandfather")); + assertEquals(Family.FamiliarRelationship.PATERNAL_GRANDMOTHER, siblingMap.get("p_grandmother")); + assertEquals(Family.FamiliarRelationship.PATERNAL_GRANDFATHER, siblingMap.get("p_grandfather")); + assertEquals(Family.FamiliarRelationship.MOTHER, siblingMap.get("mother")); + assertEquals(Family.FamiliarRelationship.FATHER, siblingMap.get("father")); + assertEquals(Family.FamiliarRelationship.FULL_SIBLING, siblingMap.get("proband")); + assertEquals(Family.FamiliarRelationship.BROTHER, siblingMap.get("brother")); + assertEquals(Family.FamiliarRelationship.SISTER, siblingMap.get("sister")); + + Map brotherMap = roles.get("brother"); + assertEquals(9, brotherMap.size()); + assertEquals(Family.FamiliarRelationship.MATERNAL_GRANDMOTHER, brotherMap.get("m_grandmother")); + assertEquals(Family.FamiliarRelationship.MATERNAL_GRANDFATHER, brotherMap.get("m_grandfather")); + assertEquals(Family.FamiliarRelationship.PATERNAL_GRANDMOTHER, brotherMap.get("p_grandmother")); + assertEquals(Family.FamiliarRelationship.PATERNAL_GRANDFATHER, brotherMap.get("p_grandfather")); + assertEquals(Family.FamiliarRelationship.MOTHER, brotherMap.get("mother")); + assertEquals(Family.FamiliarRelationship.FATHER, brotherMap.get("father")); + assertEquals(Family.FamiliarRelationship.FULL_SIBLING, brotherMap.get("sibling")); + assertEquals(Family.FamiliarRelationship.FULL_SIBLING, brotherMap.get("proband")); + assertEquals(Family.FamiliarRelationship.SISTER, brotherMap.get("sister")); + + Map sisterMap = roles.get("sister"); + assertEquals(9, sisterMap.size()); + assertEquals(Family.FamiliarRelationship.MATERNAL_GRANDMOTHER, sisterMap.get("m_grandmother")); + assertEquals(Family.FamiliarRelationship.MATERNAL_GRANDFATHER, sisterMap.get("m_grandfather")); + assertEquals(Family.FamiliarRelationship.PATERNAL_GRANDMOTHER, sisterMap.get("p_grandmother")); + assertEquals(Family.FamiliarRelationship.PATERNAL_GRANDFATHER, sisterMap.get("p_grandfather")); + assertEquals(Family.FamiliarRelationship.MOTHER, sisterMap.get("mother")); + assertEquals(Family.FamiliarRelationship.FATHER, sisterMap.get("father")); + assertEquals(Family.FamiliarRelationship.FULL_SIBLING, sisterMap.get("sibling")); + assertEquals(Family.FamiliarRelationship.BROTHER, sisterMap.get("brother")); + assertEquals(Family.FamiliarRelationship.FULL_SIBLING, sisterMap.get("proband")); } @Test