Ejemplo n.º 1
0
def update_individual_handler(request, individual_guid):
    """Updates a single field in an Individual record.

    Args:
        request (object): Django HTTP Request object.
        individual_guid (string): GUID of the Individual.

    Request:
        body should be a json dictionary like: { 'value': xxx }

    Response:
        json dictionary representing the updated individual like:
            {
                <individualGuid> : {
                    individualId: xxx,
                    sex: xxx,
                    affected: xxx,
                    ...
                }
            }
    """

    individual = Individual.objects.get(guid=individual_guid)

    project = individual.family.project

    check_permissions(project, request.user, CAN_EDIT)

    request_json = json.loads(request.body)

    update_individual_from_json(individual, request_json, user=request.user, allow_unknown_keys=True)

    return create_json_response({
        individual.guid: _get_json_for_individual(individual, request.user)
    })
Ejemplo n.º 2
0
def update_individual_field_handler(request, individual_guid, field_name):
    """Updates an Individual record.

    Args:
        individual_guid (string): GUID of the individual.
        field_name (string): Name of Individual record field to update (eg. "affected").
    """

    individual = Individual.objects.get(guid=individual_guid)

    # check permission
    project = individual.family.project
    if not request.user.is_staff and not request.user.has_perm(
            CAN_EDIT, project):
        raise PermissionDenied("%s does not have EDIT permissions for %s" %
                               (request.user, project))

    request_json = json.loads(request.body)
    if "value" not in request_json:
        raise ValueError("Request is missing 'value' key")

    individual_json = {field_name: request_json['value']}
    update_individual_from_json(individual, individual_json)

    return create_json_response(
        {individual.guid: _get_json_for_individual(individual, request.user)})
Ejemplo n.º 3
0
def add_or_update_individuals_and_families(project, individual_records):
    """Add or update individual and family records in the given project.

    Args:
        project (object): Django ORM model for the project to add families to
        individual_records (list): A list of JSON records representing individuals. See
            pedigree_info_utils#convert_fam_file_rows_to_json(..)
    """
    families = {}
    for record in individual_records:
        family, created = Family.objects.get_or_create(
            project=project, family_id=record['familyId'])
        if created:
            if not family.display_name:
                family.display_name = family.family_id
                family.save()

            logger.info("Created family: %s" % (family, ))

        individual, created = Individual.objects.get_or_create(
            family=family, individual_id=record['individualId'])
        update_individual_from_json(individual,
                                    record,
                                    allow_unknown_keys=True)

        # apply additional json fields which don't directly map to Individual model fields
        individual.phenotips_eid = individual.guid  # use this instead of individual_id to avoid chance of collisions

        if created:
            # create new PhenoTips patient record
            patient_record = create_patient(project, individual.phenotips_eid)
            individual.phenotips_patient_id = patient_record['id']

            logger.info(
                "Created PhenoTips record with patient id %s and external id %s"
                % (str(individual.phenotips_patient_id),
                   str(individual.phenotips_eid)))

        if record.get('hpoTerms'):
            # update phenotips hpo ids
            logger.info("Setting PhenoTips HPO Terms to: %s" %
                        (record.get('hpoTerms'), ))
            set_patient_hpo_terms(project,
                                  individual.phenotips_eid,
                                  record.get('hpoTerms'),
                                  is_external_id=True)

        if not individual.display_name:
            individual.display_name = individual.individual_id

        individual.save()

        _deprecated_update_original_individual_data(project, individual)

        families[family.family_id] = family

    # update pedigree images
    for family in families.values():
        update_pedigree_image(family)
Ejemplo n.º 4
0
def save_individuals_table(request, project_guid, token):
    """Handler for 'save' requests to apply Individual tables previously uploaded through receive_individuals_table(..)

    Args:
        request (object): Django request object
        project_guid (string): project GUID
        token (string): a token sent to the client by receive_individuals_table(..)
    """
    project = _get_project_and_check_permissions(project_guid, request.user)

    serialized_file_path = _compute_serialized_file_path(token)
    with gzip.open(serialized_file_path) as f:
        records = json.load(f)

    families = {}
    for record in records:
        family, created = Family.objects.get_or_create(project=project, family_id=record['familyId'])
        if created:
            if not family.display_name:
                family.display_name = family.family_id
                family.save()

            logger.info("Created family: %s" % str(family))

        individual, created = Individual.objects.get_or_create(family=family, individual_id=record['individualId'])
        update_individual_from_json(individual, record, allow_unknown_keys=True)

        individual.phenotips_eid = individual.guid  # use this instead of individual_id to avoid chance of collisions
        if created:
            patient_record = create_patient(project, individual.phenotips_eid)
            individual.phenotips_patient_id = patient_record['id']
            logger.info("Created phenotips record with patient id %s and external id %s" % (
                str(individual.phenotips_patient_id), str(individual.phenotips_eid)))

        if not individual.case_review_status:
            individual.case_review_status = Individual.CASE_REVIEW_STATUS_IN_REVIEW
        if not individual.display_name:
            individual.display_name = individual.individual_id
        individual.save()

        _deprecated_update_original_individual_data(project, individual)

        families[family.family_id] = family

    # update pedigree images
    for family in families.values():
        update_pedigree_image(family)

    # sync events

    os.remove(serialized_file_path)

    return create_json_response({})
Ejemplo n.º 5
0
def update_individual_field_handler(request, individual_guid, field_name):
    """Updates a single field in an Individual record.

    Args:
        request (object): Django HTTP Request object.
        individual_guid (string): GUID of the Individual.
        field_name (string): Name of the field to update (eg. "maternalId").

    Request:
        body should be a json dictionary like: { 'value': xxx }

    Response:
        json dictionary representing the updated individual like:
            {
                <individualGuid> : {
                    individualId: xxx,
                    maternalId: xxx,
                    affected: xxx,
                    ...
                }
            }
    """

    individual = Individual.objects.get(guid=individual_guid)

    project = individual.family.project

    check_permissions(project, request.user, CAN_EDIT)

    request_json = json.loads(request.body)
    if "value" not in request_json:
        raise ValueError("Request is missing 'value' key: %s" %
                         (request.body, ))

    individual_json = {field_name: request_json['value']}
    update_individual_from_json(individual, individual_json)

    return create_json_response(
        {individual.guid: _get_json_for_individual(individual, request.user)})
Ejemplo n.º 6
0
def update_individual_field_handler(request, individual_guid, field_name):
    """Updates an Individual record.

    Args:
        individual_guid (string): GUID of the individual.
        field_name (string): Name of Individual record field to update (eg. "affected").
    """

    individual = Individual.objects.get(guid=individual_guid)

    project = individual.family.project

    check_permissions(project, request.user, CAN_EDIT)

    request_json = json.loads(request.body)
    if "value" not in request_json:
        raise ValueError("Request is missing 'value' key: %s" %
                         (request.body, ))

    individual_json = {field_name: request_json['value']}
    update_individual_from_json(individual, individual_json)

    return create_json_response(
        {individual.guid: _get_json_for_individual(individual, request.user)})
Ejemplo n.º 7
0
def add_or_update_individuals_and_families(project, individual_records, user=None):
    """Add or update individual and family records in the given project.

    Args:
        project (object): Django ORM model for the project to add families to
        individual_records (list): A list of JSON records representing individuals. See
            the return value of pedigree_info_utils#convert_fam_file_rows_to_json(..)

    Return:
        2-tuple: updated_families, updated_individuals containing Django ORM models
    """
    families = {}
    updated_individuals = set()
    parent_updates = []
    for i, record in enumerate(individual_records):
        # family id will be in different places in the json depending on whether it comes from a flat uploaded file or from the nested individual object
        family_id = record.get(JsonConstants.FAMILY_ID_COLUMN) or record.get('family', {}).get('familyId')
        if not family_id:
            raise ValueError("record #%s doesn't contain a 'familyId' key: %s" % (i, record))

        if JsonConstants.INDIVIDUAL_ID_COLUMN not in record and 'individualGuid' not in record:
            raise ValueError("record #%s doesn't contain an 'individualId' key: %s" % (i, record))

        family = families.get(family_id)
        if family:
            created = False
        else:
            family, created = get_or_create_seqr_model(Family, project=project, family_id=family_id)

        if created:
            logger.info("Created family: %s", family)

        # uploaded files do not have unique guid's so fall back to a combination of family and individualId
        if record.get('individualGuid'):
            individual_filters = {'guid': record['individualGuid']}
        else:
            individual_id = record.get(JsonConstants.PREVIOUS_INDIVIDUAL_ID_COLUMN) or record[JsonConstants.INDIVIDUAL_ID_COLUMN]
            individual_filters = {'family': family, 'individual_id': individual_id}

        individual, created = get_or_create_seqr_model(Individual, **individual_filters)

        if created:
            record.update({
                'caseReviewStatus': 'I',
            })

        record['family'] = family
        record.pop('familyId', None)
        if individual.family != family:
            families[individual.family.family_id] = individual.family

        if record.get(JsonConstants.PREVIOUS_INDIVIDUAL_ID_COLUMN):
            updated_individuals.update(individual.maternal_children.all())
            updated_individuals.update(individual.paternal_children.all())
            record['displayName'] = ''

        # Update the parent ids last, so if they are referencing updated individuals they will check for the correct ID
        if record.get('maternalId') or record.get('paternalId'):
            parent_updates.append({
                'individual': individual,
                'maternalId': record.pop('maternalId', None),
                'paternalId': record.pop('paternalId', None),
            })

        update_individual_from_json(individual, record, allow_unknown_keys=True, user=user)

        updated_individuals.add(individual)
        families[family.family_id] = family

    for update in parent_updates:
        individual = update.pop('individual')
        update_individual_from_json(individual, update, user=user)

    updated_families = list(families.values())

    # update pedigree images
    update_pedigree_images(updated_families, project_guid=project.guid)

    return updated_families, list(updated_individuals)
Ejemplo n.º 8
0
def add_or_update_individuals_and_families(project, individual_records, user):
    """
    Add or update individual and family records in the given project.

    Args:
        project (object): Django ORM model for the project to add families to
        individual_records (list): A list of JSON records representing individuals. See
            the return value of pedigree_info_utils#convert_fam_file_rows_to_json(..)

    Return:
        2-tuple: updated_families, updated_individuals containing Django ORM models

    """
    updated_families = set()
    updated_individuals = set()
    parent_updates = []

    family_ids = {_get_record_family_id(record) for record in individual_records}
    families_by_id = {f.family_id: f for f in Family.objects.filter(project=project, family_id__in=family_ids)}

    missing_family_ids = family_ids - set(families_by_id.keys())
    for family_id in missing_family_ids:
        family = create_model_from_json(Family, {'project': project, 'family_id': family_id}, user)
        families_by_id[family_id] = family
        updated_families.add(family)

    individual_models = Individual.objects.filter(family__project=project).prefetch_related(
        'family', 'mother', 'father')
    has_individual_guid = any(record.get('individualGuid') for record in individual_records)
    if has_individual_guid:
        individual_lookup = {
            i.guid: i for i in individual_models.filter(
            guid__in=[record['individualGuid'] for record in individual_records])
        }
    else:
        individual_lookup = defaultdict(dict)
        for i in individual_models.filter(
                individual_id__in=[_get_record_individual_id(record) for record in individual_records]):
            individual_lookup[i.individual_id][i.family] = i

    for record in individual_records:
        family_id = _get_record_family_id(record)
        family = families_by_id.get(family_id)

        if has_individual_guid:
            individual = individual_lookup[record.pop('individualGuid')]
        else:
            # uploaded files do not have unique guid's so fall back to a combination of family and individualId
            individual_id = _get_record_individual_id(record)
            individual = individual_lookup[individual_id].get(family)
            if not individual:
                individual = create_model_from_json(
                    Individual, {'family': family, 'individual_id': individual_id, 'case_review_status': 'I'}, user)

        record['family'] = family
        record.pop('familyId', None)
        if individual.family != family:
            family = individual.family
            updated_families.add(family)

        previous_id = record.pop(JsonConstants.PREVIOUS_INDIVIDUAL_ID_COLUMN, None)
        if previous_id:
            updated_individuals.update(individual.maternal_children.all())
            updated_individuals.update(individual.paternal_children.all())
            record['displayName'] = ''

        # Update the parent ids last, so if they are referencing updated individuals they will check for the correct ID
        if record.get('maternalId') or record.get('paternalId'):
            parent_updates.append({
                'individual': individual,
                'maternalId': record.pop('maternalId', None),
                'paternalId': record.pop('paternalId', None),
            })

        family_notes = record.pop(JsonConstants.FAMILY_NOTES_COLUMN, None)
        if family_notes:
            update_family_from_json(family, {'analysis_notes': family_notes}, user)
            updated_families.add(family)

        is_updated = update_individual_from_json(individual, record, user=user, allow_unknown_keys=True)
        if is_updated:
            updated_individuals.add(individual)
            updated_families.add(family)

    for update in parent_updates:
        individual = update.pop('individual')
        is_updated = update_individual_from_json(individual, update, user=user)
        if is_updated:
            updated_individuals.add(individual)
            updated_families.add(individual.family)

    # update pedigree images
    update_pedigree_images(updated_families, user, project_guid=project.guid)

    return list(updated_families), list(updated_individuals)
Ejemplo n.º 9
0
def add_or_update_individuals_and_families(project,
                                           individual_records,
                                           user=None):
    """Add or update individual and family records in the given project.

    Args:
        project (object): Django ORM model for the project to add families to
        individual_records (list): A list of JSON records representing individuals. See
            the return value of pedigree_info_utils#convert_fam_file_rows_to_json(..)

    Return:
        2-tuple: updated_families, updated_individuals containing Django ORM models
    """
    families = {}
    updated_individuals = []
    for i, record in enumerate(individual_records):
        # family id will be in different places in the json depending on whether it comes from a flat uploaded file or from the nested individual object
        family_id = record.get('familyId') or record.get('family',
                                                         {}).get('familyId')
        if not family_id:
            raise ValueError(
                "record #%s doesn't contain a 'familyId' key: %s" %
                (i, record))

        if 'individualId' not in record and 'individualGuid' not in record:
            raise ValueError(
                "record #%s doesn't contain an 'individualId' key: %s" %
                (i, record))

        family, created = get_or_create_seqr_model(Family,
                                                   project=project,
                                                   family_id=family_id)

        if created:
            logger.info("Created family: %s", family)
            if not family.display_name:
                update_seqr_model(family, display_name=family.family_id)

        # uploaded files do not have unique guid's so fall back to a combination of family and individualId
        if record.get('individualGuid'):
            individual_filters = {'guid': record['individualGuid']}
        else:
            individual_filters = {
                'family': family,
                'individual_id': record['individualId']
            }

        individual, created = get_or_create_seqr_model(Individual,
                                                       **individual_filters)
        record['family'] = family
        record.pop('familyId', None)
        update_individual_from_json(individual,
                                    record,
                                    allow_unknown_keys=True,
                                    user=user)

        updated_individuals.append(individual)

        # apply additional json fields which don't directly map to Individual model fields
        individual.phenotips_eid = individual.guid  # use guid instead of indiv_id to avoid collisions

        if created:
            # create new PhenoTips patient record
            patient_record = create_patient(project, individual)
            update_seqr_model(individual,
                              phenotips_patient_id=patient_record['id'],
                              case_review_status='I')

            logger.info(
                "Created PhenoTips record with patient id %s and external id %s"
                % (str(individual.phenotips_patient_id),
                   str(individual.phenotips_eid)))

        if record.get(JsonConstants.HPO_TERMS_PRESENT_COLUMN) or record.get(
                JsonConstants.FINAL_DIAGNOSIS_OMIM_COLUMN):
            # update phenotips hpo ids
            logger.info("Setting PhenoTips HPO Terms to: %s" %
                        (record.get(JsonConstants.HPO_TERMS_PRESENT_COLUMN), ))
            set_patient_hpo_terms(
                project,
                individual,
                hpo_terms_present=record.get(
                    JsonConstants.HPO_TERMS_PRESENT_COLUMN, []),
                hpo_terms_absent=record.get(
                    JsonConstants.HPO_TERMS_ABSENT_COLUMN, []),
                final_diagnosis_mim_ids=record.get(
                    JsonConstants.FINAL_DIAGNOSIS_OMIM_COLUMN, []))

        if not individual.display_name:
            update_seqr_model(individual,
                              display_name=individual.individual_id)

        families[family.family_id] = family

    updated_families = list(families.values())

    # update pedigree images
    update_pedigree_images(updated_families)

    return updated_families, updated_individuals
Ejemplo n.º 10
0
def add_or_update_individuals_and_families(project, individual_records):
    """Add or update individual and family records in the given project.

    Args:
        project (object): Django ORM model for the project to add families to
        individual_records (list): A list of JSON records representing individuals. See
            the return value of pedigree_info_utils#convert_fam_file_rows_to_json(..)

    Return:
        2-tuple: updated_families, updated_individuals containing Django ORM models
    """
    families = {}
    updated_individuals = []
    for i, record in enumerate(individual_records):
        if 'familyId' not in record:
            raise ValueError(
                "record #%s doesn't contain a 'familyId' key: %s" %
                (i, record))
        if 'individualId' not in record:
            raise ValueError(
                "record #%s doesn't contain an 'individualId' key: %s" %
                (i, record))

        family, created = Family.objects.get_or_create(
            project=project, family_id=record['familyId'])

        if created:
            logger.info("Created family: %s", family)
            if not family.display_name:
                family.display_name = family.family_id
                family.save()

        individual, created = Individual.objects.get_or_create(
            family=family, individual_id=record['individualId'])

        update_individual_from_json(individual,
                                    record,
                                    allow_unknown_keys=True)

        updated_individuals.append(individual)

        # apply additional json fields which don't directly map to Individual model fields
        individual.phenotips_eid = individual.guid  # use guid instead of indiv_id to avoid collisions

        if created:
            # create new PhenoTips patient record
            patient_record = create_patient(project, individual.phenotips_eid)
            individual.phenotips_patient_id = patient_record['id']
            individual.case_review_status = 'I'

            logger.info(
                "Created PhenoTips record with patient id %s and external id %s"
                % (str(individual.phenotips_patient_id),
                   str(individual.phenotips_eid)))

        if record.get('hpoTerms'):
            # update phenotips hpo ids
            logger.info("Setting PhenoTips HPO Terms to: %s" %
                        (record.get('hpoTerms'), ))
            set_patient_hpo_terms(project,
                                  individual.phenotips_eid,
                                  record.get('hpoTerms'),
                                  is_external_id=True)

        if not individual.display_name:
            individual.display_name = individual.individual_id

        individual.save()

        _deprecated_update_original_individual_data(project, individual)

        families[family.family_id] = family

    updated_families = list(families.values())

    # update pedigree images
    update_pedigree_images(updated_families)

    return updated_families, updated_individuals