def _add_locus_lists(projects, genes, include_all_lists=False): locus_lists = LocusList.objects.filter(projects__in=projects) if include_all_lists: locus_lists_by_guid = { locus_list.guid: { 'intervals': [] } for locus_list in locus_lists } else: locus_lists_by_guid = defaultdict(lambda: {'intervals': []}) intervals = LocusListInterval.objects.filter(locus_list__in=locus_lists) for interval in _get_json_for_models(intervals, nested_fields=[{ 'fields': ('locus_list', 'guid') }]): locus_lists_by_guid[interval['locusListGuid']]['intervals'].append( interval) for locus_list_gene in LocusListGene.objects.filter( locus_list__in=locus_lists, gene_id__in=genes.keys()).prefetch_related('locus_list'): genes[locus_list_gene.gene_id]['locusListGuids'].append( locus_list_gene.locus_list.guid) return locus_lists_by_guid
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 _add_omim(gene): omim_phenotypes = _get_json_for_models(gene.omim_set.all()) return { 'omimPhenotypes': [ phenotype for phenotype in omim_phenotypes if phenotype['phenotypeMimNumber'] ], 'mimNumber': omim_phenotypes[0]['mimNumber'] if omim_phenotypes else None, }
def _get_json_for_variant_tag_types(project): note_counts_by_family = VariantNote.objects.filter(saved_variants__family__project=project)\ .values('saved_variants__family__guid').annotate(count=Count('*')) num_tags = sum(count['count'] for count in note_counts_by_family) note_tag_type = { 'variantTagTypeGuid': 'notes', 'name': 'Has Notes', 'category': 'Notes', 'description': '', 'color': 'grey', 'order': 100, 'numTags': num_tags, 'numTagsPerFamily': {count['saved_variants__family__guid']: count['count'] for count in note_counts_by_family}, } tag_counts_by_type_and_family = VariantTag.objects.filter(saved_variants__family__project=project)\ .values('saved_variants__family__guid', 'variant_tag_type__name').annotate(count=Count('*')) project_variant_tags = _get_json_for_models(VariantTagType.objects.filter(Q(project=project) | Q(project__isnull=True))) for tag_type in project_variant_tags: current_tag_type_counts = [counts for counts in tag_counts_by_type_and_family if counts['variant_tag_type__name'] == tag_type['name']] num_tags = sum(count['count'] for count in current_tag_type_counts) tag_type.update({ 'numTags': num_tags, 'numTagsPerFamily': {count['saved_variants__family__guid']: count['count'] for count in current_tag_type_counts}, }) project_variant_tags.append(note_tag_type) project_variant_tags = sorted(project_variant_tags, key=lambda variant_tag_type: variant_tag_type['order']) discovery_tag_type_guids = [tag_type['variantTagTypeGuid'] for tag_type in project_variant_tags if tag_type['category'] == 'CMG Discovery Tags' and tag_type['numTags'] > 0] discovery_tags = get_json_for_saved_variants(SavedVariant.objects.filter( family__project=project, varianttag__variant_tag_type__guid__in=discovery_tag_type_guids, ), add_details=True) project_functional_tags = [] for category, tags in VariantFunctionalData.FUNCTIONAL_DATA_CHOICES: project_functional_tags += [{ 'category': category, 'name': name, 'metadataTitle': json.loads(tag_json).get('metadata_title'), 'color': json.loads(tag_json)['color'], 'description': json.loads(tag_json).get('description'), } for name, tag_json in tags] return { 'variantTagTypes': sorted(project_variant_tags, key=lambda variant_tag_type: variant_tag_type['order']), 'variantFunctionalTagTypes': get_json_for_variant_functional_data_tag_types(), 'discoveryTags': discovery_tags, }
def get_project_variant_tag_types(project, tag_counts_by_type_and_family=None, note_counts_by_family=None): note_tag_type = { 'variantTagTypeGuid': 'notes', 'name': 'Has Notes', 'category': 'Notes', 'description': '', 'color': 'grey', 'order': 100, 'is_built_in': True, } if note_counts_by_family is not None: num_tags = sum(count['count'] for count in note_counts_by_family) note_tag_type.update({ 'numTags': num_tags, 'numTagsPerFamily': { count['saved_variant__family__guid']: count['count'] for count in note_counts_by_family }, }) project_variant_tags = _get_json_for_models( VariantTagType.objects.filter( Q(project=project) | Q(project__isnull=True))) if tag_counts_by_type_and_family is not None: for tag_type in project_variant_tags: current_tag_type_counts = [ counts for counts in tag_counts_by_type_and_family if counts['variant_tag_type__name'] == tag_type['name'] ] num_tags = sum(count['count'] for count in current_tag_type_counts) tag_type.update({ 'numTags': num_tags, 'numTagsPerFamily': { count['saved_variant__family__guid']: count['count'] for count in current_tag_type_counts }, }) project_variant_tags.append(note_tag_type) return sorted(project_variant_tags, key=lambda variant_tag_type: variant_tag_type['order'])
def _get_json_for_genes(genes, user=None, gene_fields=None): if not gene_fields: gene_fields = {} total_gene_constraints = None if CONSTRAINT in gene_fields: total_gene_constraints = GeneConstraint.objects.count() if NOTES in gene_fields: gene_notes_json = get_json_for_gene_notes_by_gene_id( [gene.gene_id for gene in genes], user) def _add_total_constraint_count(result, *args): result['totalGenes'] = total_gene_constraints def _process_result(result, gene): for field, (_, result_func) in gene_fields.items(): if field == NOTES: updates = {'notes': gene_notes_json.get(result['geneId'], [])} elif field == CONSTRAINT: constraint = _get_gene_model(gene, 'geneconstraint') updates = { 'constraints': _get_json_for_model( constraint, process_result=_add_total_constraint_count) if constraint else {} } else: updates = result_func(gene) result.update(updates) for model, _ in gene_fields.values(): if model: prefetch_related_objects( genes, Prefetch('{}_set'.format(model.__name__.lower()), queryset=model.objects.only( 'gene__gene_id', *model._meta.json_fields))) return _get_json_for_models(genes, process_result=_process_result)
def _get_projects_details(projects, user, project_category_guid=None): for project in projects: check_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 = set() 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( variant_tag_types_by_guid.values()) for project_json in projects_json: project = project_models_by_guid[project_json['projectGuid']] project_locus_lists = get_project_locus_list_models(project) locus_lists.update(project_locus_lists) project_json.update({ 'locusListGuids': [locus_list.guid for locus_list in project_locus_lists], '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, }) families = _get_json_for_families( Family.objects.filter(project__in=projects), user) individuals = _get_json_for_individuals( Individual.objects.filter(family__project__in=projects), user=user) samples = get_json_for_samples( Sample.objects.filter(individual__family__project__in=projects)) analysis_groups = get_json_for_analysis_groups( AnalysisGroup.objects.filter(project__in=projects)) 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']) for individual in individuals: individual['sampleGuids'] = 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}, 'locusListsByGuid': { ll['locusListGuid']: ll for ll in get_json_for_locus_lists(list(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
def saved_variants_page(request, tag): gene = request.GET.get('gene') tag_type = VariantTagType.objects.get(name=tag, project__isnull=True) saved_variant_models = SavedVariant.objects.filter( varianttag__variant_tag_type=tag_type) if gene: saved_variant_models = saved_variant_models.filter( saved_variant_json__transcripts__has_key=gene) if saved_variant_models.count() > 10000 and not gene: return create_json_response( {'message': 'Select a gene to filter variants'}, status=400) prefetch_related_objects(saved_variant_models, 'family__project') saved_variants = get_json_for_saved_variants(saved_variant_models, add_tags=True, add_details=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) genes = _saved_variant_genes(saved_variants) locus_list_guids = _add_locus_lists(project_models_by_guid.values(), saved_variants, genes) projects_json = get_json_for_projects( 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': locus_list_guids, 'variantTagTypes': sorted(project_variant_tags, key=lambda variant_tag_type: variant_tag_type['order']), '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, user=request.user) locus_lists_by_guid = { locus_list['locusListGuid']: locus_list for locus_list in get_json_for_locus_lists( LocusList.objects.filter(guid__in=locus_list_guids), request.user) } return create_json_response({ 'savedVariantsByGuid': {variant['variantGuid']: variant for variant in saved_variants}, '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, })
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