Beispiel #1
0
def _get_projects_json(user):
    projects = get_projects_user_can_view(user)
    if not projects:
        return {}

    projects_with_counts = projects.annotate(
        models.Count('family', distinct=True), models.Count('family__individual', distinct=True),
        models.Count('family__savedvariant', distinct=True))

    projects_by_guid = {p['projectGuid']: p for p in get_json_for_projects(projects, user=user)}
    for project in projects_with_counts:
        projects_by_guid[project.guid]['numFamilies'] = project.family__count
        projects_by_guid[project.guid]['numIndividuals'] = project.family__individual__count
        projects_by_guid[project.guid]['numVariantTags'] = project.family__savedvariant__count

    analysis_status_counts = Family.objects.filter(project__in=projects).values(
        'project__guid', 'analysis_status').annotate(count=models.Count('*'))
    for agg in analysis_status_counts:
        project_guid = agg['project__guid']
        if 'analysisStatusCounts' not in projects_by_guid[project_guid]:
            projects_by_guid[project_guid]['analysisStatusCounts'] = {}
        projects_by_guid[project_guid]['analysisStatusCounts'][agg['analysis_status']] = agg['count']

    sample_type_status_counts = Sample.objects.filter(individual__family__project__in=projects, dataset_type=Sample.DATASET_TYPE_VARIANT_CALLS
    ).values(
        'individual__family__project__guid', 'sample_type',
    ).annotate(count=models.Count('individual_id', distinct=True))
    for agg in sample_type_status_counts:
        project_guid = agg['individual__family__project__guid']
        if 'sampleTypeCounts' not in projects_by_guid[project_guid]:
            projects_by_guid[project_guid]['sampleTypeCounts'] = {}
        projects_by_guid[project_guid]['sampleTypeCounts'][agg['sample_type']] = agg['count']

    return projects_by_guid
Beispiel #2
0
def awesomebar_autocomplete_handler(request):
    """Accepts HTTP GET request with q=.. url arg, and returns suggestions"""

    query = request.GET.get('q')
    if query is None:
        raise ValueError("missing ?q=<prefix> url arg")
    if not query:
        return create_json_response({'matches': {}})

    categories = request.GET.get('categories').split(',') if request.GET.get(
        'categories') else DEFAULT_CATEGORIES

    projects = get_projects_user_can_view(request.user) if any(
        category for category in categories if category != 'genes') else None

    results = {
        category: {
            'name': _to_title_case(category),
            'results': CATEGORY_MAP[category](query, projects)
        }
        for category in categories
    }

    return create_json_response(
        {'matches': {k: v
                     for k, v in results.items() if v['results']}})
Beispiel #3
0
def mme_details(request):
    submissions = MatchmakerSubmission.objects.filter(deleted_date__isnull=True).filter(
        individual__family__project__in=get_projects_user_can_view(request.user))

    hpo_terms_by_id, genes_by_id, gene_symbols_to_ids = get_mme_genes_phenotypes_for_submissions(submissions)

    submission_json = get_json_for_matchmaker_submissions(
        submissions, additional_model_fields=['label'], all_parent_guids=True)
    submissions_by_guid = {s['submissionGuid']: s for s in submission_json}

    for submission in submissions:
        gene_variants = parse_mme_gene_variants(submission.genomic_features, gene_symbols_to_ids)
        submissions_by_guid[submission.guid].update({
            'phenotypes': parse_mme_features(submission.features, hpo_terms_by_id),
            'geneVariants': gene_variants,
            'geneSymbols': ','.join({genes_by_id.get(gv['geneId'], {}).get('geneSymbol') for gv in gene_variants})
        })

    response = {
        'submissions': list(submissions_by_guid.values()),
        'genesById': genes_by_id,
    }
    if user_is_analyst(request.user):
        response['metrics'] = get_mme_metrics()

    return create_json_response(response)
Beispiel #4
0
def get_all_collaborators(request):
    if request.user.is_staff:
        collaborators = {user.username: _get_json_for_user(user) for user in User.objects.exclude(email='')}
    else:
        collaborators = {}
        for project in get_projects_user_can_view(request.user):
            collaborators.update(get_project_collaborators_by_username(project, include_permissions=False))

    return create_json_response(collaborators)
Beispiel #5
0
def get_all_collaborator_options(request):
    collaborators = set()
    for project in get_projects_user_can_view(request.user):
        collaborators.update(project.get_collaborators())

    return create_json_response({
        user.username: _get_json_for_user(user, fields=USER_OPTION_FIELDS)
        for user in collaborators
    })
Beispiel #6
0
def saved_variants_page(request, tag):
    gene = request.GET.get('gene')
    if tag == 'ALL':
        saved_variant_models = SavedVariant.objects.exclude(varianttag=None)
    else:
        tag_type = VariantTagType.objects.get(name=tag, project__isnull=True)
        saved_variant_models = SavedVariant.objects.filter(varianttag__variant_tag_type=tag_type)

    saved_variant_models = saved_variant_models.filter(family__project__in=get_projects_user_can_view(request.user))

    if gene:
        saved_variant_models = saved_variant_models.filter(saved_variant_json__transcripts__has_key=gene)
    elif saved_variant_models.count() > MAX_SAVED_VARIANTS:
        return create_json_response({'error': 'Select a gene to filter variants'}, status=400)

    prefetch_related_objects(saved_variant_models, 'family__project')
    response_json = get_json_for_saved_variants_with_tags(saved_variant_models, add_details=True, include_missing_variants=True)

    project_models_by_guid = {variant.family.project.guid: variant.family.project for variant in saved_variant_models}
    families = {variant.family for variant in saved_variant_models}
    individuals = Individual.objects.filter(family__in=families)

    saved_variants = list(response_json['savedVariantsByGuid'].values())
    genes = saved_variant_genes(saved_variants)
    locus_lists_by_guid = _add_locus_lists(list(project_models_by_guid.values()), genes, include_all_lists=True)

    projects_json = get_json_for_projects(list(project_models_by_guid.values()), user=request.user, add_project_category_guids_field=False)
    functional_tag_types = get_json_for_variant_functional_data_tag_types()

    variant_tag_types = VariantTagType.objects.filter(Q(project__in=project_models_by_guid.values()) | Q(project__isnull=True))
    prefetch_related_objects(variant_tag_types, 'project')
    variant_tags_json = _get_json_for_models(variant_tag_types)
    tag_projects = {vt.guid: vt.project.guid for vt in variant_tag_types if vt.project}

    for project_json in projects_json:
        project_guid = project_json['projectGuid']
        project_variant_tags = [
            vt for vt in variant_tags_json if tag_projects.get(vt['variantTagTypeGuid'], project_guid) == project_guid]
        project_json.update({
            'locusListGuids': list(locus_lists_by_guid.keys()),
            'variantTagTypes': sorted(project_variant_tags, key=lambda variant_tag_type: variant_tag_type['order'] or 0),
            'variantFunctionalTagTypes': functional_tag_types,
        })

    families_json = _get_json_for_families(list(families), user=request.user, add_individual_guids_field=True)
    individuals_json = _get_json_for_individuals(individuals, add_hpo_details=True, user=request.user)
    for locus_list in get_json_for_locus_lists(LocusList.objects.filter(guid__in=locus_lists_by_guid.keys()), request.user):
        locus_lists_by_guid[locus_list['locusListGuid']].update(locus_list)

    response_json.update({
        'genesById': genes,
        'projectsByGuid': {project['projectGuid']: project for project in projects_json},
        'familiesByGuid': {family['familyGuid']: family for family in families_json},
        'individualsByGuid': {indiv['individualGuid']: indiv for indiv in individuals_json},
        'locusListsByGuid': locus_lists_by_guid,
    })
    return create_json_response(response_json)
Beispiel #7
0
def export_projects_table_handler(request):
    file_format = request.GET.get('file_format', 'tsv')

    cursor = connection.cursor()

    projects_user_can_view = get_projects_user_can_view(request.user)

    projects_by_guid = _retrieve_projects_by_guid(cursor, projects_user_can_view, [])
    _add_analysis_status_counts(cursor, projects_by_guid)
    _add_sample_type_counts(cursor, projects_by_guid)
    project_categories_by_guid = _retrieve_project_categories_by_guid(projects_by_guid)

    cursor.close()

    header = [
        'Project',
        'Description',
        'Categories',
        'Created Date',
        'Families',
        'Individuals',
        'Tagged Variants',
        'WES Samples',
        'WGS Samples',
        'RNA Samples',
    ]

    header.extend([label for key, label in Family.ANALYSIS_STATUS_CHOICES if key != 'S'])

    rows = []
    for project in sorted(projects_by_guid.values(), key=lambda project: project.get('name') or project.get('deprecatedProjectId')):
        project_categories = ', '.join(
            [project_categories_by_guid[category_guid]['name'] for category_guid in project.get('projectCategoryGuids')]
        )

        row = [
            project.get('name') or project.get('deprecatedProjectId'),
            project.get('description'),
            project_categories,
            project.get('createdDate'),
            project.get('numFamilies'),
            project.get('numIndividuals'),
            project.get('numVariantTags'),
            project.get('sampleTypeCounts', {}).get(Sample.SAMPLE_TYPE_WES, 0),
            project.get('sampleTypeCounts', {}).get(Sample.SAMPLE_TYPE_WGS, 0),
            project.get('sampleTypeCounts', {}).get(Sample.SAMPLE_TYPE_RNA, 0),
        ]

        row.extend([project.get('analysisStatusCounts', {}).get(key, 0) for key, _ in Family.ANALYSIS_STATUS_CHOICES if key != 'S'])

        rows.append(row)

    return export_table('projects', header, rows, file_format)
Beispiel #8
0
def export_projects_table_handler(request):
    file_format = request.GET.get('file_format', 'tsv')

    cursor = connection.cursor()

    projects_user_can_view = get_projects_user_can_view(request.user)

    projects_by_guid = _retrieve_projects_by_guid(cursor, projects_user_can_view, [])
    _add_analysis_status_counts(cursor, projects_by_guid)
    _add_sample_type_counts(cursor, projects_by_guid)
    project_categories_by_guid = _retrieve_project_categories_by_guid(projects_by_guid)

    cursor.close()

    header = [
        'Project',
        'Description',
        'Categories',
        'Created Date',
        'Families',
        'Individuals',
        'Tagged Variants',
        'WES Samples',
        'WGS Samples',
        'RNA Samples',
    ]

    header.extend([label for key, label in Family.ANALYSIS_STATUS_CHOICES if key != 'S'])

    rows = []
    for project in sorted(projects_by_guid.values(), key=lambda project: project.get('name') or project.get('deprecatedProjectId')):
        project_categories = ', '.join(
            [project_categories_by_guid[category_guid]['name'] for category_guid in project.get('projectCategoryGuids')]
        )

        row = [
            project.get('name') or project.get('deprecatedProjectId'),
            project.get('description'),
            project_categories,
            project.get('createdDate'),
            project.get('numFamilies'),
            project.get('numIndividuals'),
            project.get('numVariantTags'),
            project.get('sampleTypeCounts', {}).get(Sample.SAMPLE_TYPE_WES, 0),
            project.get('sampleTypeCounts', {}).get(Sample.SAMPLE_TYPE_WGS, 0),
            project.get('sampleTypeCounts', {}).get(Sample.SAMPLE_TYPE_RNA, 0),
        ]

        row.extend([project.get('analysisStatusCounts', {}).get(key, 0) for key, _ in Family.ANALYSIS_STATUS_CHOICES if key != 'S'])

        rows.append(row)

    return export_table('projects', header, rows, file_format)
def _get_or_create_results_model(search_hash, search_context, user):
    results_model = VariantSearchResults.objects.filter(
        search_hash=search_hash).first()
    if not results_model:
        if not search_context:
            raise Exception('Invalid search hash: {}'.format(search_hash))

        project_families = search_context.get('projectFamilies')
        if project_families:
            all_families = set()
            for project_family in project_families:
                all_families.update(project_family['familyGuids'])
            families = Family.objects.filter(guid__in=all_families)
        elif search_context.get('allProjectFamilies'):
            omit_projects = ProjectCategory.objects.get(
                name='Demo').projects.all()
            projects = [
                project for project in get_projects_user_can_view(user)
                if project not in omit_projects
            ]
            families = Family.objects.filter(project__in=projects)
        elif search_context.get('projectGuids'):
            families = Family.objects.filter(
                project__guid__in=search_context['projectGuids'])
        else:
            raise Exception('Invalid search: no projects/ families specified')

        search_dict = search_context.get('search', {})
        search_model = VariantSearch.objects.filter(search=search_dict).filter(
            Q(created_by=user) | Q(name__isnull=False)).first()
        if not search_model:
            search_model = VariantSearch.objects.create(created_by=user,
                                                        search=search_dict)

        try:
            results_model = VariantSearchResults.objects.create(
                search_hash=search_hash, variant_search=search_model)
        except IntegrityError:
            # This can happen if a search_context request and results request are dispatched at the same time,
            results_model = VariantSearchResults.objects.get(
                search_hash=search_hash)
            try:
                results_model.families.set(families)
            except IntegrityError:
                pass
            return results_model

        results_model.families.set(families)
    return results_model
Beispiel #10
0
def _get_projects_json(user, cursor):
    projects = get_projects_user_can_view(user)
    projects_with_counts = projects.annotate(
        models.Count('family', distinct=True), models.Count('family__individual', distinct=True),
        models.Count('family__savedvariant', distinct=True))

    projects_by_guid = {p['projectGuid']: p for p in get_json_for_projects(projects, user=user)}
    for project in projects_with_counts:
        projects_by_guid[project.guid]['numFamilies'] = project.family__count
        projects_by_guid[project.guid]['numIndividuals'] = project.family__individual__count
        projects_by_guid[project.guid]['numVariantTags'] = project.family__savedvariant__count

    #  TODO get rid of cursor
    _add_analysis_status_counts(cursor, projects_by_guid)
    _add_sample_type_counts(cursor, projects_by_guid)

    return projects_by_guid
Beispiel #11
0
def dashboard_page_data(request):
    """Returns a JSON object containing information used by the dashboard page:
    ::

      json_response = {
         'user': {..},
         'familiesByGuid': {..},
         'individualsByGuid': {..},
       }
    """

    cursor = connection.cursor()

    projects_user_can_view = get_projects_user_can_view(request.user)
    projects_user_can_edit = get_projects_user_can_edit(request.user)

    # defensive programming
    edit_but_not_view_permissions = set(p.guid
                                        for p in projects_user_can_edit) - set(
                                            p.guid
                                            for p in projects_user_can_view)
    if edit_but_not_view_permissions:
        raise Exception(
            'ERROR: %s has EDIT permissions but not VIEW permissions for: %s' %
            (request.user, edit_but_not_view_permissions))

    projects_by_guid = _retrieve_projects_by_guid(cursor,
                                                  projects_user_can_view,
                                                  projects_user_can_edit)

    _add_analysis_status_counts(cursor, projects_by_guid)
    _add_sample_type_counts(cursor, projects_by_guid)

    project_categories_by_guid = _retrieve_project_categories_by_guid(
        projects_by_guid)

    cursor.close()

    json_response = {
        'user': _get_json_for_user(request.user),
        'projectsByGuid': projects_by_guid,
        'projectCategoriesByGuid': project_categories_by_guid,
    }

    return create_json_response(json_response)
Beispiel #12
0
def dashboard_page_data(request):
    """Returns a JSON object containing information used by the dashboard page:
    ::

      json_response = {
         'user': {..},
         'familiesByGuid': {..},
         'individualsByGuid': {..},
       }
    """

    cursor = connection.cursor()

    projects_user_can_view = get_projects_user_can_view(request.user)
    projects_user_can_edit = get_projects_user_can_edit(request.user)

    # defensive programming
    edit_but_not_view_permissions = set(p.guid for p in projects_user_can_edit) - set(p.guid for p in projects_user_can_view)
    if edit_but_not_view_permissions:
        raise Exception('ERROR: %s has EDIT permissions but not VIEW permissions for: %s' % (request.user, edit_but_not_view_permissions))

    projects_by_guid = _retrieve_projects_by_guid(cursor, projects_user_can_view, projects_user_can_edit)

    _add_analysis_status_counts(cursor, projects_by_guid)
    _add_sample_type_counts(cursor, projects_by_guid)

    project_categories_by_guid = _retrieve_project_categories_by_guid(projects_by_guid)

    cursor.close()

    json_response = {
        'projectsByGuid': projects_by_guid,
        'projectCategoriesByGuid': project_categories_by_guid,
    }

    return create_json_response(json_response)
Beispiel #13
0
def get_all_collaborators(request):
    collaborators = {}
    for project in get_projects_user_can_view(request.user):
        collaborators.update(_get_project_collaborators(project, include_permissions=False))

    return create_json_response(collaborators)
Beispiel #14
0
def variant_search_page_data(request, project_guid, family_guid):
    """Returns a JSON object containing information needed to display the variant search page
    ::

      json_response = {
         'user': {..},
         'variants': [..],
       }
    Args:
        project_guid (string): GUID of the Project under case review.
    """
    logger.info("project_guid: %s" % (project_guid,))
    logger.info("family_guid: %s" % (family_guid,))
    if family_guid is not None:
        # single-family search mode
        family = Family.objects.get(guid=family_guid)

        # TODO handle family-not-found

        project = family.project

        check_permissions(project, request.user, CAN_VIEW)

        project_guids = [project.guid]
        family_guids = [family_guid]
    else:
        # all-families-in-a-project search mode
        family = None
        family_guids = None
        if project_guid is not None:
            project = Project.objects.get(guid=project_guid)
            # TODO handle project-not-found

            # check permissions
            check_permissions(project, request.user, CAN_VIEW)

            project_guids = [project.guid]
        else:
            # all projects search mode permissions to access
            project = None
            project_guids = [p.guid for p in get_projects_user_can_view(request.user)]

    # get all datasets
    dataset_info = _retrieve_datasets(
        project_guids=project_guids,
        family_guids=family_guids,
        individual_guids=None,
        sample_types=None,
        analysis_types=None,
        only_loaded_datasets=True
    )

    # retrieve search params from hash or use default values
    search_params_hash = request.GET.get("h")
    if search_params_hash is not None:
        search_params = {}  # TODO retrieve search params for hash
        raise ValueError("Not implemented")

    else:
        search_params = {
            'dataset_guids': [],
            'project_guids': project_guids,
            'family_guids': [],
        }

    # TODO adjust search params that are no-longer valid

    json_response = {
        'user': _get_json_for_user(request.user),
        'project': _get_json_for_project(project, request.user) if project is not None else {},
        'family': _get_json_for_family(family, request.user) if family is not None else {},
        'variants': {},
        'datasets': dataset_info,
    }

    return create_json_response(json_response)