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
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']}})
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)
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)
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 })
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)
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 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
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
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)
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)
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)
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)