Beispiel #1
0
def update_variant_main_transcript(request, variant_guid, transcript_id):
    saved_variant = SavedVariant.objects.get(guid=variant_guid)
    check_project_permissions(saved_variant.family.project, request.user, can_edit=True)

    update_model_from_json(saved_variant, {'selected_main_transcript_id': transcript_id}, request.user)

    return create_json_response({'savedVariantsByGuid': {variant_guid: {'selectedMainTranscriptId': transcript_id}}})
Beispiel #2
0
def update_variant_tags_handler(request, variant_guids):
    request_json = json.loads(request.body)

    family_guid = request_json.pop('familyGuid')
    family = Family.objects.get(guid=family_guid)
    check_project_permissions(family.project, request.user)

    all_variant_guids = set(variant_guids.split(','))
    saved_variants = SavedVariant.objects.filter(guid__in=all_variant_guids)
    if len(saved_variants) != len(all_variant_guids):
        error = 'Unable to find the following variant(s): {}'.format(
            ', '.join([guid for guid in all_variant_guids if guid not in {sv.guid for sv in saved_variants}]))
        return create_json_response({'error': error}, status=400, reason=error)

    deleted_tag_guids = _delete_removed_tags(saved_variants, all_variant_guids, request_json.get('tags', []), request.user)
    created_tags = _create_new_tags(saved_variants, request_json, request.user)
    tag_updates = {tag['tagGuid']: tag for tag in get_json_for_variant_tags(created_tags)}
    tag_updates.update({guid: None for guid in deleted_tag_guids})

    saved_variants_by_guid = {}
    for saved_variant in saved_variants:
        tags = saved_variant.varianttag_set.all()
        saved_variants_by_guid[saved_variant.guid] = {'tagGuids': [t.guid for t in tags]}
        if not tags:
            if not saved_variant.variantnote_set.count() > 0:
                saved_variant.delete_model(request.user, user_can_delete=True)
                saved_variants_by_guid[saved_variant.guid] = None

    return create_json_response({
        'savedVariantsByGuid': saved_variants_by_guid,
        'variantTagsByGuid': tag_updates,
    })
Beispiel #3
0
def delete_variant_note_handler(request, variant_guids, note_guid):
    variant_guids = variant_guids.split(',')
    note = VariantNote.objects.get(guid=note_guid)
    projects = {
        saved_variant.family.project
        for saved_variant in note.saved_variants.all()
    }
    for project in projects:
        check_project_permissions(project, request.user)
    note.delete()

    saved_variants_by_guid = {}
    for saved_variant in SavedVariant.objects.filter(guid__in=variant_guids):
        notes = saved_variant.variantnote_set.all()
        saved_variants_by_guid[saved_variant.guid] = {
            'noteGuids': [n.guid for n in notes]
        }
        if not notes:
            if not saved_variant.varianttag_set.count() > 0:
                saved_variant.delete()
                saved_variants_by_guid[saved_variant.guid] = None

    return create_json_response({
        'savedVariantsByGuid': saved_variants_by_guid,
        'variantNotesByGuid': {
            note_guid: None
        },
    })
Beispiel #4
0
def create_saved_variant_handler(request):
    variant_json = json.loads(request.body)
    family_guid = variant_json['familyGuid']

    family = Family.objects.get(guid=family_guid)
    check_project_permissions(family.project, request.user)

    variants_json = variant_json['variant']
    if not isinstance(variant_json['variant'], list):
        variants_json = [variants_json]

    saved_variants = []
    for single_variant_json in variants_json:
        try:
            parsed_variant_json = _get_parsed_variant_args(single_variant_json, family)
        except ValueError as e:
            return create_json_response({'error': str(e)}, status=400)
        saved_variant, _ = get_or_create_model_from_json(
            SavedVariant, create_json=parsed_variant_json,
            update_json={'saved_variant_json': single_variant_json}, user=request.user)
        saved_variants.append(saved_variant)

    if variant_json.get('note'):
        _create_variant_note(saved_variants, variant_json, request.user)
    elif variant_json.get('tags'):
        _create_new_tags(saved_variants, variant_json, request.user)

    return create_json_response(get_json_for_saved_variants_with_tags(saved_variants, add_details=True))
Beispiel #5
0
def update_individual_hpo_terms(request, individual_guid):
    """Updates features fields for the given Individual
    """

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

    project = individual.family.project

    check_project_permissions(project, request.user, can_edit=True)

    request_json = json.loads(request.body)

    for feature_key in [
            'features', 'absentFeatures', 'nonstandardFeatures',
            'absentNonstandardFeatures'
    ]:
        orm_key = _to_snake_case(feature_key)
        value = [get_parsed_feature(feature) for feature in request_json[feature_key]] \
            if request_json.get(feature_key) else None
        setattr(individual, orm_key, value)
    individual.save()

    return create_json_response({
        individual.guid:
        _get_json_for_individual(individual,
                                 request.user,
                                 add_hpo_details=True)
    })
Beispiel #6
0
def update_individual_hpo_terms(request, individual_guid):
    """Updates features fields for the given Individual
    """

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

    project = individual.family.project

    check_project_permissions(project, request.user, can_edit=True)

    request_json = json.loads(request.body)

    update_json = {
        key:
        [get_parsed_feature(feature)
         for feature in request_json[key]] if request_json.get(key) else None
        for key in [
            'features', 'absentFeatures', 'nonstandardFeatures',
            'absentNonstandardFeatures'
        ]
    }
    update_model_from_json(individual, update_json, user=request.user)

    return create_json_response({
        individual.guid:
        _get_json_for_individual(individual,
                                 request.user,
                                 add_hpo_details=True)
    })
Beispiel #7
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_project_permissions(project, request.user, can_edit=True)

    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)
    })
Beispiel #8
0
def create_saved_variant_handler(request):
    variant_json = json.loads(request.body)
    family_guid = variant_json['familyGuid']

    family = Family.objects.get(guid=family_guid)
    check_project_permissions(family.project, request.user)

    if isinstance(variant_json['variant'], list):
        # are compound hets
        saved_variants = []
        for single_variant_json in variant_json['variant']:
            saved_variant, created = SavedVariant.objects.get_or_create(
                **_get_parsed_variant_args(single_variant_json, family))
            if created:
                saved_variant.saved_variant_json = single_variant_json
                saved_variant.save()
            saved_variants.append(saved_variant)
    else:
        saved_variant = SavedVariant.objects.create(
            saved_variant_json=variant_json['variant'],
            **_get_parsed_variant_args(variant_json['variant'], family))
        saved_variants = [saved_variant]

    if variant_json.get('note'):
        _create_variant_note(saved_variants, variant_json, request.user)
    elif variant_json.get('tags'):
        _create_new_tags(saved_variants, variant_json, request.user)

    return create_json_response(
        get_json_for_saved_variants_with_tags(saved_variants,
                                              add_details=True))
Beispiel #9
0
def update_family_pedigree_image(request, family_guid):
    """Updates the specified field in the Family model.

    Args:
        family_guid (string): GUID of the family.
    """

    family = Family.objects.get(guid=family_guid)

    # check permission
    check_project_permissions(family.project, request.user, can_edit=True)

    if len(request.FILES) == 0:
        pedigree_image = None
    elif len(request.FILES) > 1:
        return create_json_response({},
                                    status=400,
                                    reason='Received {} files'.format(
                                        len(request.FILES)))
    else:
        pedigree_image = next(iter((request.FILES.values())))

    family.pedigree_image = pedigree_image
    family.save()

    return create_json_response(
        {family.guid: _get_json_for_family(family, request.user)})
Beispiel #10
0
def update_family_assigned_analyst(request, family_guid):
    """Updates the specified field in the Family model.

    Args:
        family_guid (string): GUID of the family.
    """
    family = Family.objects.get(guid=family_guid)
    # assigned_analyst can be edited by anyone with access to the project
    check_project_permissions(family.project, request.user, can_edit=False)

    request_json = json.loads(request.body)
    assigned_analyst_username = request_json.get('assigned_analyst_username')

    if assigned_analyst_username:
        try:
            assigned_analyst = User.objects.get(
                username=assigned_analyst_username)
        except Exception:
            return create_json_response({},
                                        status=400,
                                        reason="specified user does not exist")
    else:
        assigned_analyst = None
    family.assigned_analyst = assigned_analyst
    family.save()

    return create_json_response(
        {family.guid: _get_json_for_family(family, request.user)})
Beispiel #11
0
def create_variant_note_handler(request, variant_guids):
    request_json = json.loads(request.body)
    save_as_gene_note = request_json.get('saveAsGeneNote')

    family_guid = request_json.pop('familyGuid')
    family = Family.objects.get(guid=family_guid)
    check_project_permissions(family.project, request.user)

    all_variant_guids = variant_guids.split(',')
    saved_variants = SavedVariant.objects.filter(guid__in=all_variant_guids)
    if len(saved_variants) != len(all_variant_guids):
        error = 'Unable to find the following variant(s): {}'.format(', '.join(
            [
                guid for guid in all_variant_guids
                if guid not in {sv.guid
                                for sv in saved_variants}
            ]))
        return create_json_response({'error': error}, status=400, reason=error)

    # update saved_variants
    note = _create_variant_note(saved_variants, request_json, request.user)
    note_json = get_json_for_variant_note(note, add_variant_guids=False)
    note_json['variantGuids'] = all_variant_guids
    response = {
        'savedVariantsByGuid': {
            saved_variant.guid: {
                'noteGuids':
                [n.guid for n in saved_variant.variantnote_set.all()]
            }
            for saved_variant in saved_variants
        },
        'variantNotesByGuid': {
            note.guid: note_json
        },
    }

    if save_as_gene_note:
        main_transcript_id = saved_variants[
            0].selected_main_transcript_id or saved_variants[
                0].saved_variant_json['mainTranscriptId']
        gene_id = next(
            (gene_id for gene_id, transcripts in saved_variants[0].
             saved_variant_json['transcripts'].items() if any(
                 t['transcriptId'] == main_transcript_id
                 for t in transcripts)), None) if main_transcript_id else None
        GeneNote.objects.create(
            note=request_json.get('note'),
            gene_id=gene_id,
            created_by=request.user,
        )
        response['genesById'] = {
            gene_id: {
                'notes':
                get_json_for_gene_notes_by_gene_id([gene_id],
                                                   request.user)[gene_id],
            }
        }

    return create_json_response(response)
Beispiel #12
0
def update_mme_submission(request, submission_guid=None):
    """
    Create or update the submission for the given individual.
    """
    submission_json = json.loads(request.body)
    phenotypes = submission_json.pop('phenotypes', [])
    gene_variants = submission_json.pop('geneVariants', [])
    if not phenotypes and not gene_variants:
        return create_json_response({}, status=400, reason='Genotypes or phentoypes are required')

    genomic_features = []
    for gene_variant in gene_variants:
        if not gene_variant.get('geneId'):
            return create_json_response({}, status=400, reason='Gene id is required for genomic features')
        feature = {'gene': {'id': gene_variant['geneId']}}
        if 'numAlt' in gene_variant and gene_variant['numAlt'] > 0:
            feature['zygosity'] = gene_variant['numAlt']
        if gene_variant.get('pos'):
            genome_version = gene_variant['genomeVersion']
            feature['variant'] = {
                'referenceName': gene_variant['chrom'],
                'start': gene_variant['pos'],
                'assembly': GENOME_VERSION_LOOKUP.get(genome_version, genome_version),
            }
            if gene_variant.get('alt'):
                feature['variant'].update({
                    'alternateBases': gene_variant['alt'],
                    'referenceBases': gene_variant['ref'],
                })
            elif gene_variant.get('end'):
                feature['variant']['end'] = gene_variant['end']
        genomic_features.append(feature)

    submission_json.update({
        'features': phenotypes,
        'genomicFeatures': genomic_features,
        'deletedDate': None,
        'deletedBy': None,
    })

    if submission_guid:
        submission = MatchmakerSubmission.objects.get(guid=submission_guid)
        check_mme_permissions(submission, request.user)
    else:
        individual_guid = submission_json.get('individualGuid')
        if not individual_guid:
            return create_json_response({}, status=400, reason='Individual is required for a new submission')
        individual = Individual.objects.get(guid=individual_guid)
        check_project_permissions(individual.family.project, request.user)
        submission = MatchmakerSubmission.objects.create(
            individual=individual,
            submission_id=individual.guid,
            label=individual.individual_id,
        )

    update_model_from_json(submission, submission_json, allow_unknown_keys=True)

    # search for new matches
    return _search_matches(submission, request.user)
Beispiel #13
0
def _update_variant_tag_models(request,
                               variant_guids,
                               tag_key,
                               model_cls,
                               get_tag_create_data,
                               get_tags_json,
                               response_guid_key=None,
                               delete_variants_if_empty=False):
    request_json = json.loads(request.body)

    family_guid = request_json.pop('familyGuid')
    family = Family.objects.get(guid=family_guid)
    check_project_permissions(family.project, request.user)

    all_variant_guids = set(variant_guids.split(','))
    saved_variants = SavedVariant.objects.filter(guid__in=all_variant_guids)
    if len(saved_variants) != len(all_variant_guids):
        error = 'Unable to find the following variant(s): {}'.format(', '.join(
            [
                guid for guid in all_variant_guids
                if guid not in {sv.guid
                                for sv in saved_variants}
            ]))
        return create_json_response({'error': error}, status=400, reason=error)

    tag_type = tag_key.lower().rstrip('s')
    updated_data = request_json.get(tag_key, [])
    deleted_guids = _delete_removed_tags(saved_variants, all_variant_guids,
                                         updated_data, request.user, tag_type)

    updated_models = _update_tags(saved_variants, request_json, request.user,
                                  tag_key, model_cls, get_tag_create_data)
    updates = {tag['tagGuid']: tag for tag in get_tags_json(updated_models)}
    updates.update({guid: None for guid in deleted_guids})

    if not response_guid_key:
        response_guid_key = '{}Guids'.format(tag_key)
    saved_variants_by_guid = {}
    for saved_variant in saved_variants:
        tags = _get_tag_set(saved_variant, tag_type).all()
        saved_variants_by_guid[saved_variant.guid] = {
            response_guid_key: [t.guid for t in tags]
        }
        if delete_variants_if_empty and not tags:
            if not saved_variant.variantnote_set.count() > 0:
                saved_variant.delete_model(request.user, user_can_delete=True)
                saved_variants_by_guid[saved_variant.guid] = None

    return create_json_response({
        'savedVariantsByGuid':
        saved_variants_by_guid,
        'variant{}{}ByGuid'.format(tag_key[0].upper(), tag_key[1:]):
        updates,
    })
Beispiel #14
0
def discovery_sheet(request, project_guid):
    project = Project.objects.filter(guid=project_guid).prefetch_related(
        Prefetch('family_set', to_attr='families', queryset=Family.objects.prefetch_related('individual_set'))
    ).distinct().first()
    if not project:
        message = 'Invalid project {}'.format(project_guid)
        return create_json_response({'error': message}, status = 400, reason = message)
    check_project_permissions(project, request.user)

    rows = []
    errors = []

    loaded_samples_by_family = _get_loaded_samples_by_family(project)
    saved_variants_by_family = _get_project_saved_discovery_variants_by_family(project)
    mme_submission_families = _get_has_mme_submission_families(project)

    if not loaded_samples_by_family:
        errors.append("No data loaded for project: {}".format(project))
        return create_json_response({
            'rows': [],
            'errors': errors,
        })

    if "external" in project.name.lower() or "reprocessed" in project.name.lower():
        sequencing_approach = "REAN"
    else:
        sequencing_approach = next(iter(loaded_samples_by_family.values()))[-1].sample_type
    initial_row = {
        "project_guid": project.guid,
        "collaborator": project.name,
        "sequencing_approach": sequencing_approach,
    }
    initial_row.update(DEFAULT_ROW)

    now = timezone.now()
    for family in project.families:
        samples = loaded_samples_by_family.get(family.guid)
        if not samples:
            errors.append("No data loaded for family: %s. Skipping..." % family)
            continue
        saved_variants = saved_variants_by_family.get(family.guid)
        submitted_to_mme = family in mme_submission_families

        rows += _generate_rows(initial_row, family, samples, saved_variants, submitted_to_mme, errors, now=now)

    _update_gene_symbols(rows)
    _update_hpo_categories(rows, errors)
    _update_initial_omim_numbers(rows)

    return create_json_response({
        'rows': rows,
        'errors': errors,
    })
Beispiel #15
0
def update_individual_igv_sample(request, individual_guid):
    individual = Individual.objects.get(guid=individual_guid)
    project = individual.family.project
    check_project_permissions(project, request.user, can_edit=True)

    request_json = json.loads(request.body)

    try:
        file_path = request_json.get('filePath')
        if not file_path:
            raise ValueError('request must contain fields: filePath')

        suffix = '.'.join(file_path.split('.')[1:])
        sample_type = SAMPLE_TYPE_MAP.get(suffix)
        if not sample_type:
            raise Exception(
                'Invalid file extension for "{}" - valid extensions are {}'.
                format(file_path, ', '.join(SAMPLE_TYPE_MAP.keys())))
        if not does_file_exist(file_path):
            raise Exception('Error accessing "{}"'.format(file_path))

        sample, created = get_or_create_model_from_json(
            IgvSample,
            create_json={
                'individual': individual,
                'sample_type': sample_type
            },
            update_json={
                'file_path': file_path,
                'sample_id': request_json.get('sampleId')
            },
            user=request.user)

        response = {
            'igvSamplesByGuid': {
                sample.guid:
                get_json_for_sample(sample,
                                    individual_guid=individual_guid,
                                    project_guid=project.guid)
            }
        }
        if created:
            response['individualsByGuid'] = {
                individual.guid: {
                    'igvSampleGuids':
                    [s.guid for s in individual.igvsample_set.all()]
                }
            }
        return create_json_response(response)
    except Exception as e:
        error = str(e)
        return create_json_response({'error': error}, status=400, reason=error)
Beispiel #16
0
def update_variant_note_handler(request, variant_guids, note_guid):
    note = VariantNote.objects.get(guid=note_guid)
    projects = {saved_variant.family.project for saved_variant in note.saved_variants.all()}
    for project in projects:
        check_project_permissions(project, request.user)
    request_json = json.loads(request.body)
    update_model_from_json(note, request_json, user=request.user, allow_unknown_keys=True)

    note_json = get_json_for_variant_note(note, add_variant_guids=False)
    note_json['variantGuids'] = variant_guids.split(',')

    return create_json_response({
        'variantNotesByGuid': {note.guid: note_json},
    })
Beispiel #17
0
def update_project_categories_handler(request, project_guid):
    """Update ProjectCategories for the given project.

    Args:
        project_guid (string): GUID of the project that should be updated

    HTTP POST
        Request body - should contain the following json structure:
        {
            'form' : {
                'categories': a list of category GUIDs for the categories assigned to the given project
            }
        }

        Response body - will contain the following structure, representing the updated project,
            as well all categories in seqr:
            {
                'projectsByGuid':  {
                    <projectGuid1> : { ... <project key-value pairs> ... }
                }
                'projectCategoriesByGuid':  {
                    <projectCategoryGuid1> : { ... <category key-value pairs> ... }
                    <projectCategoryGuid2> : { ... <category key-value pairs> ... }
                }
            }
    """
    project = Project.objects.get(guid=project_guid)

    # check permissions
    check_project_permissions(project, request.user, can_edit=True)

    request_json = json.loads(request.body)

    # project categories according to the UI
    current_category_guids = set(request_json['categories'])

    project_categories_by_guid = _update_project_categories(
        project, request.user, current_category_guids)

    projects_by_guid = {
        project.guid: _get_json_for_project(project, request.user)
    }

    return create_json_response({
        'projectsByGuid':
        projects_by_guid,
        'projectCategoriesByGuid':
        project_categories_by_guid,
    })
Beispiel #18
0
def update_family_analysed_by(request, family_guid):
    """Updates the specified field in the Family model.

    Args:
        family_guid (string): GUID of the family.
        field_name (string): Family model field name to update
    """

    family = Family.objects.get(guid=family_guid)
    # analysed_by can be edited by anyone with access to the project
    check_project_permissions(family.project, request.user, can_edit=False)

    FamilyAnalysedBy.objects.create(family=family, created_by=request.user)

    return create_json_response(
        {family.guid: _get_json_for_family(family, request.user)})
Beispiel #19
0
def update_individual_igv_sample(request, individual_guid):
    individual = Individual.objects.get(guid=individual_guid)
    project = individual.family.project
    check_project_permissions(project, request.user, can_edit=True)

    request_json = json.loads(request.body)

    try:
        required_fields = ['filePath']
        if any(field not in request_json for field in required_fields):
            raise ValueError("request must contain fields: {}".format(
                ', '.join(required_fields)))

        file_path = request_json['filePath']
        if not (file_path.endswith(".bam") or file_path.endswith(".cram")):
            raise Exception(
                'BAM / CRAM file "{}" must have a .bam or .cram extension'.
                format(file_path))
        validate_alignment_dataset_path(file_path)

        sample, created = IgvSample.objects.get_or_create(
            individual=individual)
        sample.file_path = file_path
        sample.save()

        response = {
            'igvSamplesByGuid': {
                sample.guid:
                get_json_for_sample(sample,
                                    individual_guid=individual_guid,
                                    project_guid=project.guid)
            }
        }
        if created:
            response['individualsByGuid'] = {
                individual.guid: {
                    'igvSampleGuids':
                    [s.guid for s in individual.igvsample_set.all()]
                }
            }
        return create_json_response(response)
    except Exception as e:
        error = str(e)
        return create_json_response({'error': error}, status=400, reason=error)
Beispiel #20
0
def update_family_fields_handler(request, family_guid):
    """Updates the specified field in the Family model.

    Args:
        family_guid (string): GUID of the family.
    """

    family = Family.objects.get(guid=family_guid)

    # check permission - can be edited by anyone with access to the project
    check_project_permissions(family.project, request.user)

    request_json = json.loads(request.body)
    update_family_from_json(family, request_json, user=request.user, allow_unknown_keys=True, immutable_keys=[
        'family_id', 'display_name',
    ])

    return create_json_response({
        family.guid: _get_json_for_family(family, request.user)
    })
Beispiel #21
0
def update_family_fields_handler(request, family_guid):
    """Updates the specified field in the Family model.

    Args:
        family_guid (string): GUID of the family.
    """

    family = Family.objects.get(guid=family_guid)

    # check permission
    project = family.project

    check_project_permissions(project, request.user, can_edit=True)

    request_json = json.loads(request.body)
    update_family_from_json(family, request_json, user=request.user, allow_unknown_keys=True)

    return create_json_response({
        family.guid: _get_json_for_family(family, request.user)
    })
Beispiel #22
0
def update_variant_functional_data_handler(request, variant_guids):
    request_json = json.loads(request.body)

    family_guid = request_json.pop('familyGuid')
    family = Family.objects.get(guid=family_guid)
    check_project_permissions(family.project, request.user)

    all_variant_guids = set(variant_guids.split(','))
    saved_variants = SavedVariant.objects.filter(guid__in=all_variant_guids)
    if len(saved_variants) != len(all_variant_guids):
        error = 'Unable to find the following variant(s): {}'.format(
            ', '.join([guid for guid in all_variant_guids if guid not in {sv.guid for sv in saved_variants}]))
        return create_json_response({'error': error}, status=400, reason=error)

    updated_functional_data = request_json.get('functionalData', [])
    deleted_functional_guids = _delete_removed_tags(
        saved_variants, all_variant_guids, updated_functional_data, request.user, tag_type='functionaldata')

    updated_functional_models = []
    for tag in updated_functional_data:
        if tag.get('tagGuid'):
            functional_data = VariantFunctionalData.objects.get(guid=tag.get('tagGuid'))
            update_model_from_json(functional_data, tag, user=request.user, allow_unknown_keys=True)
        else:
            functional_data = create_model_from_json(VariantFunctionalData, {
                'functional_data_tag': tag.get('name'),
                'metadata': tag.get('metadata'),
                'search_hash': request_json.get('searchHash'),
            }, request.user)
            functional_data.saved_variants.set(saved_variants)
        updated_functional_models.append(functional_data)

    functional_updates = {tag['tagGuid']: tag for tag in get_json_for_variant_functional_data_tags(updated_functional_models)}
    functional_updates.update({guid: None for guid in deleted_functional_guids})

    return create_json_response({
        'savedVariantsByGuid': {saved_variant.guid: {
            'functionalDataGuids': [t.guid for t in saved_variant.variantfunctionaldata_set.all()],
        } for saved_variant in saved_variants},
        'variantFunctionalDataByGuid': functional_updates,
    })
Beispiel #23
0
def update_project_handler(request, project_guid):
    """Update project metadata - including one or more of these fields: name, description

    Args:
        project_guid (string): GUID of the project that should be updated

    HTTP POST
        Request body - should contain the following json structure:
        {
            'form' : {
                'name':  <project name>,
                'description': <project description>,
            }
        }

        Response body - will contain the following structure, representing the updated project:
            {
                'projectsByGuid':  {
                    <projectGuid1> : { ... <project key-value pairs> ... }
                }
            }

    """

    project = Project.objects.get(guid=project_guid)

    check_project_permissions(project, request.user, can_edit=True)

    request_json = json.loads(request.body)
    update_project_from_json(project,
                             request_json,
                             request.user,
                             allow_unknown_keys=True)

    return create_json_response({
        'projectsByGuid': {
            project.guid: _get_json_for_project(project, request.user)
        },
    })
Beispiel #24
0
def _get_projects_details(projects, user, project_category_guid=None):
    for project in projects:
        check_project_permissions(project, user)

    prefetch_related_objects(projects, 'can_view_group')
    project_models_by_guid = {project.guid: project for project in projects}
    projects_json = get_json_for_projects(projects, user)

    locus_lists = LocusList.objects.filter(
        projects__in=projects).prefetch_related('projects')

    project_guid = projects[0].guid if len(projects) == 1 else None

    functional_data_tag_types = get_json_for_variant_functional_data_tag_types(
    )
    variant_tag_types_by_guid = {
        vtt.guid: vtt
        for vtt in VariantTagType.objects.filter(
            Q(project__in=projects)
            | Q(project__isnull=True)).prefetch_related('project')
    }
    variant_tag_types = _get_json_for_models(
        list(variant_tag_types_by_guid.values()))
    for project_json in projects_json:
        project = project_models_by_guid[project_json['projectGuid']]

        project_json.update({
            'locusListGuids': [
                locus_list.guid for locus_list in locus_lists
                if project in locus_list.projects.all()
            ],
            'variantTagTypes': [
                vtt for vtt in variant_tag_types
                if variant_tag_types_by_guid[vtt['variantTagTypeGuid']].project
                is None or variant_tag_types_by_guid[vtt['variantTagTypeGuid']]
                .project.guid == project_json['projectGuid']
            ],
            'variantFunctionalTagTypes':
            functional_data_tag_types,
        })

    family_models = Family.objects.filter(project__in=projects)
    families = _get_json_for_families(family_models,
                                      user,
                                      project_guid=project_guid,
                                      skip_nested=True)

    individual_models = Individual.objects.filter(family__in=family_models)
    individuals = _get_json_for_individuals(individual_models,
                                            user=user,
                                            project_guid=project_guid,
                                            add_hpo_details=True,
                                            skip_nested=True)

    sample_models = Sample.objects.filter(individual__in=individual_models)
    samples = get_json_for_samples(sample_models,
                                   project_guid=project_guid,
                                   skip_nested=True)

    igv_sample_models = IgvSample.objects.filter(
        individual__in=individual_models)
    igv_samples = get_json_for_samples(igv_sample_models,
                                       project_guid=project_guid,
                                       skip_nested=True)

    analysis_group_models = AnalysisGroup.objects.filter(project__in=projects)
    analysis_groups = get_json_for_analysis_groups(analysis_group_models,
                                                   project_guid=project_guid,
                                                   skip_nested=True)

    if not project_guid:
        project_id_to_guid = {project.id: project.guid for project in projects}
        family_id_to_guid = {
            family.id: family.guid
            for family in family_models
        }
        individual_id_to_guid = {
            individual.id: individual.guid
            for individual in individual_models
        }
        family_guid_to_project_guid = {}
        individual_guid_to_project_guid = {}
        for family in families:
            project_guid = project_id_to_guid[family.pop('projectId')]
            family['projectGuid'] = project_guid
            family_guid_to_project_guid[family['familyGuid']] = project_guid
        for individual in individuals:
            family_guid = family_id_to_guid[individual.pop('familyId')]
            project_guid = family_guid_to_project_guid[family_guid]
            individual['familyGuid'] = family_guid
            individual['projectGuid'] = project_guid
            individual_guid_to_project_guid[
                individual['individualGuid']] = project_guid
        for sample in samples:
            individual_guid = individual_id_to_guid[sample.pop('individualId')]
            sample['individualGuid'] = individual_guid
            sample['projectGuid'] = individual_guid_to_project_guid[
                individual_guid]
        for sample in igv_samples:
            individual_guid = individual_id_to_guid[sample.pop('individualId')]
            sample['individualGuid'] = individual_guid
            sample['projectGuid'] = individual_guid_to_project_guid[
                individual_guid]
        for group in analysis_groups:
            group['projectGuid'] = project_id_to_guid[group.pop('projectId')]

    individual_guids_by_family = defaultdict(list)
    for individual in individuals:
        individual_guids_by_family[individual['familyGuid']].append(
            individual['individualGuid'])
    for family in families:
        family['individualGuids'] = individual_guids_by_family[
            family['familyGuid']]

    sample_guids_by_individual = defaultdict(list)
    for sample in samples:
        sample_guids_by_individual[sample['individualGuid']].append(
            sample['sampleGuid'])
    igv_sample_guids_by_individual = defaultdict(list)
    for sample in igv_samples:
        igv_sample_guids_by_individual[sample['individualGuid']].append(
            sample['sampleGuid'])
    for individual in individuals:
        individual['sampleGuids'] = sample_guids_by_individual[
            individual['individualGuid']]
        individual['igvSampleGuids'] = igv_sample_guids_by_individual[
            individual['individualGuid']]

    response = {
        'projectsByGuid': {p['projectGuid']: p
                           for p in projects_json},
        'familiesByGuid': {f['familyGuid']: f
                           for f in families},
        'individualsByGuid': {i['individualGuid']: i
                              for i in individuals},
        'samplesByGuid': {s['sampleGuid']: s
                          for s in samples},
        'igvSamplesByGuid': {s['sampleGuid']: s
                             for s in igv_samples},
        'locusListsByGuid': {
            ll['locusListGuid']: ll
            for ll in get_json_for_locus_lists(locus_lists, user)
        },
        'analysisGroupsByGuid':
        {ag['analysisGroupGuid']: ag
         for ag in analysis_groups},
    }
    if project_category_guid:
        response['projectCategoriesByGuid'] = {
            project_category_guid:
            ProjectCategory.objects.get(guid=project_category_guid).json()
        }
    return response
Beispiel #25
0
def _check_results_permission(results_model, user):
    families = results_model.families.prefetch_related('project').all()
    projects = {family.project for family in families}
    for project in projects:
        check_project_permissions(project, user)