Beispiel #1
0
def _update_locus_list_items(locus_list, genes_by_id, intervals, request_json,
                             user):
    # Update genes
    for locus_list_gene in locus_list.locuslistgene_set.exclude(
            gene_id__in=genes_by_id.keys()):
        delete_seqr_model(locus_list_gene)

    for gene_id in genes_by_id.keys():
        get_or_create_seqr_model(
            LocusListGene,
            locus_list=locus_list,
            gene_id=gene_id,
            created_by=user,
        )

    # Update intervals
    genome_version = request_json.get(
        'intervalGenomeVersion') or GENOME_VERSION_GRCh37
    interval_guids = set()
    for interval in intervals:
        interval_model, _ = LocusListInterval.objects.get_or_create(
            locus_list=locus_list,
            chrom=interval['chrom'],
            start=interval['start'],
            end=interval['end'],
            genome_version=genome_version,
        )
        interval_guids.add(interval_model.guid)
    locus_list.locuslistinterval_set.exclude(guid__in=interval_guids).delete()
Beispiel #2
0
def _update_locus_list_items(locus_list, genes_by_id, intervals, request_json, user):
    # Update genes
    for locus_list_gene in locus_list.locuslistgene_set.exclude(gene_id__in=genes_by_id.keys()):
        delete_seqr_model(locus_list_gene)

    for gene_id in genes_by_id.keys():
        get_or_create_seqr_model(
            LocusListGene,
            locus_list=locus_list,
            gene_id=gene_id,
            created_by=user,
        )

    # Update intervals
    genome_version = request_json.get('intervalGenomeVersion') or GENOME_VERSION_GRCh37
    interval_guids = set()
    for interval in intervals:
        interval_model, _ = LocusListInterval.objects.get_or_create(
            locus_list=locus_list,
            chrom=interval['chrom'],
            start=interval['start'],
            end=interval['end'],
            genome_version=genome_version,
        )
        interval_guids.add(interval_model.guid)
    locus_list.locuslistinterval_set.exclude(guid__in=interval_guids).delete()
Beispiel #3
0
def _create_project(name, description=None, genome_version=None, user=None):
    """Creates a new project.

    Args:
        name (string): Project name
        description (string): optional description
        user (object): Django user that is creating this project
    """
    if not name:
        raise ValueError("Name not specified: %s" % (name,))

    project_args = {
        'name': name,
        'description': description,
        'created_by': user,
        'deprecated_project_id': _slugify(name),
    }
    if genome_version:
        project_args['genome_version'] = genome_version

    project, _ = get_or_create_seqr_model(Project, **project_args)

    if PHENOTIPS_SERVER:
        try:
            _enable_phenotips_for_project(project)
        except Exception as e:
            logger.error("Unable to create patient in PhenoTips. Make sure PhenoTips is running: %s", e)
            raise

    return project
Beispiel #4
0
def edit_families_handler(request, project_guid):
    """Edit or one or more Family records.

    Args:
        project_guid (string): GUID of project that contains these individuals.
    """

    request_json = json.loads(request.body)

    if request_json.get('uploadedFileId'):
        modified_families = load_uploaded_file(
            request_json.get('uploadedFileId'))
    else:
        modified_families = request_json.get('families')
    if modified_families is None:
        return create_json_response({},
                                    status=400,
                                    reason="'families' not specified")

    project = get_project_and_check_permissions(project_guid, request.user,
                                                CAN_EDIT)

    updated_families = []
    for fields in modified_families:
        if fields.get('familyGuid'):
            family = Family.objects.get(project=project,
                                        guid=fields['familyGuid'])
        elif fields.get(PREVIOUS_FAMILY_ID_FIELD):
            family = Family.objects.get(
                project=project, family_id=fields[PREVIOUS_FAMILY_ID_FIELD])
        else:
            family, _ = get_or_create_seqr_model(
                Family, project=project, family_id=fields[FAMILY_ID_FIELD])

        update_family_from_json(family,
                                fields,
                                user=request.user,
                                allow_unknown_keys=True)
        updated_families.append(family)

    updated_families_by_guid = {
        'familiesByGuid': {
            family.guid: _get_json_for_family(family,
                                              request.user,
                                              add_individual_guids_field=True)
            for family in updated_families
        }
    }

    return create_json_response(updated_families_by_guid)
Beispiel #5
0
def edit_families_handler(request, project_guid):
    """Edit or one or more Family records.

    Args:
        project_guid (string): GUID of project that contains these individuals.
    """

    request_json = json.loads(request.body)

    if request_json.get('uploadedFileId'):
        modified_families = load_uploaded_file(request_json.get('uploadedFileId'))
    else:
        modified_families = request_json.get('families')
    if modified_families is None:
        return create_json_response(
            {}, status=400, reason="'families' not specified")

    project = get_project_and_check_permissions(project_guid, request.user, CAN_EDIT)

    updated_families = []
    for fields in modified_families:
        if fields.get('familyGuid'):
            family = Family.objects.get(project=project, guid=fields['familyGuid'])
        elif fields.get(PREVIOUS_FAMILY_ID_FIELD):
            family = Family.objects.get(project=project, family_id=fields[PREVIOUS_FAMILY_ID_FIELD])
        else:
            family, _ = get_or_create_seqr_model(Family, project=project, family_id=fields[FAMILY_ID_FIELD])

        update_family_from_json(family, fields, user=request.user, allow_unknown_keys=True)
        updated_families.append(family)

    updated_families_by_guid = {
        'familiesByGuid': {
            family.guid: _get_json_for_family(family, request.user, add_individual_guids_field=True) for family in updated_families
        }
    }

    return create_json_response(updated_families_by_guid)
Beispiel #6
0
    def handle(self, *args, **options):
        from_project = Project.objects.get(guid=options['from_project'])
        to_project = Project.objects.get(guid=options['to_project'])
        family_ids = options['family_ids']
        families = Family.objects.filter(project=from_project,
                                         family_id__in=family_ids)
        print('Found {} out of {} families. No match for: {}.'.format(
            len(families), len(set(family_ids)),
            set(family_ids) - set([f.family_id for f in families])))

        for f in families:
            print("==> Moving phenotips for {}".format(f))
            for seqr_individual in f.individual_set.all():

                if phenotips_patient_exists(seqr_individual):
                    # make sure phenotips_patient_id is up to date
                    data_json = _get_patient_data(
                        from_project,
                        seqr_individual,
                    )

                    seqr_individual.phenotips_patient_id = data_json["id"]
                    seqr_individual.save()

                    # update permissions
                    phenotips_readonly_username, _ = get_phenotips_uname_and_pwd_for_project(
                        to_project.phenotips_user_id, read_only=True)
                    _add_user_to_patient(phenotips_readonly_username,
                                         seqr_individual.phenotips_patient_id,
                                         allow_edit=False)

                    phenotips_readwrite_username, _ = get_phenotips_uname_and_pwd_for_project(
                        to_project.phenotips_user_id, read_only=False)
                    _add_user_to_patient(phenotips_readwrite_username,
                                         seqr_individual.phenotips_patient_id,
                                         allow_edit=True)

        for variant_tag_type in VariantTagType.objects.filter(
                project=from_project):
            variant_tags = VariantTag.objects.filter(
                saved_variant__family__in=families,
                variant_tag_type=variant_tag_type)
            if variant_tags:
                print('Updating "{}" tags'.format(variant_tag_type.name))
                to_tag_type, created = get_or_create_seqr_model(
                    VariantTagType,
                    project=to_project,
                    name=variant_tag_type.name)
                if created:
                    update_seqr_model(
                        to_tag_type,
                        category=variant_tag_type.category,
                        description=variant_tag_type.description,
                        color=variant_tag_type.color,
                        order=variant_tag_type.order,
                    )
                variant_tags.update(variant_tag_type=to_tag_type)

        print("Updating families")
        families.update(project=to_project)

        print("Done.")
Beispiel #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)
Beispiel #8
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
    def handle(self, *args, **options):
        from_project = Project.objects.get(guid=options['from_project'])
        to_project = Project.objects.get(guid=options['to_project'])
        to_base_project = find_matching_xbrowse_model(to_project)
        family_ids = options['family_ids']
        families = Family.objects.filter(project=from_project,
                                         family_id__in=family_ids)
        print('Found {} out of {} families. No match for: {}.'.format(
            len(families), len(set(family_ids)),
            set(family_ids) - set([f.family_id for f in families])))

        for f in families:
            print("==> Moving {}".format(f))
            for seqr_individual in f.individual_set.all():
                base_individual = find_matching_xbrowse_model(seqr_individual)
                base_individual.project = to_base_project
                base_individual.save()
                # Update individuals in phenotips
                if _phenotips_patient_exists(seqr_individual):
                    # make sure phenotips_patient_id is up to date
                    data_json = _get_patient_data(
                        from_project,
                        seqr_individual,
                    )

                    seqr_individual.phenotips_patient_id = data_json["id"]
                    seqr_individual.save()

                    # update permissions
                    phenotips_readonly_username, _ = _get_phenotips_uname_and_pwd_for_project(
                        to_project.phenotips_user_id, read_only=True)
                    _add_user_to_patient(phenotips_readonly_username,
                                         seqr_individual.phenotips_patient_id,
                                         allow_edit=False)

                    phenotips_readwrite_username, _ = _get_phenotips_uname_and_pwd_for_project(
                        to_project.phenotips_user_id, read_only=False)
                    _add_user_to_patient(phenotips_readwrite_username,
                                         seqr_individual.phenotips_patient_id,
                                         allow_edit=True)

                # Update individuals samples/ VCFs
                for from_vcf_file in base_individual.vcf_files.all():
                    to_vcf_file, _ = VCFFile.objects.get_or_create(
                        project=to_base_project,
                        elasticsearch_index=from_vcf_file.elasticsearch_index,
                        file_path=from_vcf_file.file_path,
                        dataset_type=from_vcf_file.dataset_type,
                        sample_type=from_vcf_file.sample_type,
                        loaded_date=from_vcf_file.loaded_date,
                    )
                    base_individual.vcf_files.add(to_vcf_file)
                    base_individual.vcf_files.remove(from_vcf_file)

            # Update variant tags/ notes
            saved_variants = SavedVariant.objects.filter(family=f)
            for variant_tag in VariantTag.objects.filter(
                    saved_variant__in=saved_variants).select_related(
                        'variant_tag_type'):
                if variant_tag.variant_tag_type.project:
                    to_tag_type, created = get_or_create_seqr_model(
                        VariantTagType,
                        project=to_project,
                        name=variant_tag.variant_tag_type.name)
                    if created:
                        update_seqr_model(
                            to_tag_type,
                            category=variant_tag.variant_tag_type.category,
                            description=variant_tag.variant_tag_type.
                            description,
                            color=variant_tag.variant_tag_type.color,
                            order=variant_tag.variant_tag_type.order,
                        )
                    update_seqr_model(variant_tag,
                                      variant_tag_type=to_tag_type)
                else:
                    to_project_tag, created = ProjectTag.objects.get_or_create(
                        project=to_base_project,
                        tag=variant_tag.variant_tag_type.name)
                    if created:
                        to_project_tag.category = variant_tag.variant_tag_type.category
                        to_project_tag.title = variant_tag.variant_tag_type.description
                        to_project_tag.color = variant_tag.variant_tag_type.color
                        to_project_tag.order = variant_tag.variant_tag_type.order
                        to_project_tag.save()
                    variant_tag.project_tag = to_project_tag
                    variant_tag.save()

            base_family = find_matching_xbrowse_model(f)
            for note in BaseVariantNote.objects.filter(family=base_family):
                note.project = to_base_project
                note.save()

            # Update families
            update_seqr_model(f, project=to_project)

        print("Done.")