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))
def saved_variant_data(request, project_guid, variant_guids=None): project = get_project_and_check_permissions(project_guid, request.user) family_guids = request.GET['families'].split(',') if request.GET.get('families') else None variant_guids = variant_guids.split(',') if variant_guids else None if family_guids: variant_query = SavedVariant.objects.filter(family__guid__in=family_guids) else: variant_query = SavedVariant.objects.filter(family__project=project) if variant_guids: variant_query = variant_query.filter(guid__in=variant_guids) if variant_query.count() < 1: return create_json_response({}, status=404, reason='Variant {} not found'.format(', '.join(variant_guids))) discovery_tags_query = None if user_is_analyst(request.user): discovery_tags_query = Q() for variant in variant_query: discovery_tags_query |= Q(Q(variant_id=variant.variant_id) & ~Q(family_id=variant.family_id)) discovery_tags_query &= Q(family__project__projectcategory__name=ANALYST_PROJECT_CATEGORY) response = get_json_for_saved_variants_with_tags(variant_query, add_details=True, discovery_tags_query=discovery_tags_query) variants = list(response['savedVariantsByGuid'].values()) genes = saved_variant_genes(variants) response['locusListsByGuid'] = _add_locus_lists([project], genes) discovery_tags = response.pop('discoveryTags', None) if discovery_tags: _add_discovery_tags(variants, discovery_tags) response['genesById'] = genes return create_json_response(response)
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))
def get_individual_mme_matches(request, submission_guid): """ Looks for matches for the given submission. Expects a single patient (MME spec) in the POST data field under key "patient_data" Args: project_id,indiv_id and POST all data in POST under key "patient_data" Returns: Status code and results """ submission = MatchmakerSubmission.objects.get(guid=submission_guid) check_mme_permissions(submission, request.user) results = MatchmakerResult.objects.filter(submission=submission) response_json = get_json_for_saved_variants_with_tags( SavedVariant.objects.filter(family=submission.individual.family), add_details=True) gene_ids = set() for variant in response_json['savedVariantsByGuid'].values(): gene_ids.update(variant['transcripts'].keys()) return _parse_mme_results(submission, results, request.user, additional_genes=gene_ids, response_json=response_json)
def saved_variant_data(request, project_guid, variant_guids=None): project = get_project_and_check_permissions(project_guid, request.user) family_guids = request.GET['families'].split(',') if request.GET.get('families') else None variant_guids = variant_guids.split(',') if variant_guids else None if family_guids: variant_query = SavedVariant.objects.filter(family__guid__in=family_guids) else: get_note_only = bool(request.GET.get('includeNoteVariants')) variant_query = SavedVariant.objects.filter(family__project=project, varianttag__isnull=get_note_only).distinct() if variant_guids: variant_query = variant_query.filter(guid__in=variant_guids) if variant_query.count() < 1: return create_json_response({}, status=404, reason='Variant {} not found'.format(', '.join(variant_guids))) response = get_json_for_saved_variants_with_tags(variant_query, add_details=True) discovery_tags = None if user_is_analyst(request.user): discovery_tags, discovery_response = get_json_for_discovery_tags(response['savedVariantsByGuid'].values()) response.update(discovery_response) variants = list(response['savedVariantsByGuid'].values()) genes = saved_variant_genes(variants) response['locusListsByGuid'] = _add_locus_lists([project], genes) if discovery_tags: _add_discovery_tags(variants, discovery_tags) response['genesById'] = genes return create_json_response(response)
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 _get_saved_variants(variants, families, include_discovery_tags=False): variants = _flatten_variants(variants) prefetch_related_objects(families, 'project') hg37_family_guids = {family.guid for family in families if family.project.genome_version == GENOME_VERSION_GRCh37} variant_q = Q() variants_by_id = {} for variant in variants: variants_by_id[get_variant_key(**variant)] = variant variant_q |= Q(variant_id=variant['variantId'], family__guid__in=variant['familyGuids']) if variant['liftedOverGenomeVersion'] == GENOME_VERSION_GRCh37 and hg37_family_guids: variant_hg37_families = [family_guid for family_guid in variant['familyGuids'] if family_guid in hg37_family_guids] if variant_hg37_families: lifted_xpos = get_xpos(variant['liftedOverChrom'], variant['liftedOverPos']) variant_q |= Q(xpos=lifted_xpos, ref=variant['ref'], alt=variant['alt'], family__guid__in=variant_hg37_families) variants_by_id[get_variant_key( xpos=lifted_xpos, ref=variant['ref'], alt=variant['alt'], genomeVersion=variant['liftedOverGenomeVersion'] )] = variant saved_variants = SavedVariant.objects.filter(variant_q) json = get_json_for_saved_variants_with_tags(saved_variants, add_details=True) discovery_tags = {} if include_discovery_tags: discovery_tags, discovery_response = get_json_for_discovery_tags(variants) json.update(discovery_response) variants_to_saved_variants = {} for saved_variant in json['savedVariantsByGuid'].values(): family_guids = saved_variant['familyGuids'] searched_variant = variants_by_id.get(get_variant_key(**saved_variant)) if not searched_variant: # This can occur when an hg38 family has a saved variant that did not successfully lift from hg37 continue saved_variant.update(searched_variant) # For saved variants only use family it was saved for, not all families in search saved_variant['familyGuids'] = family_guids json['savedVariantsByGuid'][saved_variant['variantGuid']] = saved_variant if searched_variant['variantId'] not in variants_to_saved_variants: variants_to_saved_variants[searched_variant['variantId']] = {} for family_guid in family_guids: variants_to_saved_variants[searched_variant['variantId']][family_guid] = saved_variant['variantGuid'] for variant_id, tags in discovery_tags.items(): searched_variant = variants_by_id.get(variant_id) if searched_variant: if not searched_variant.get('discoveryTags'): searched_variant['discoveryTags'] = [] searched_variant['discoveryTags'] += [ tag for tag in tags if tag['savedVariant']['familyGuid'] not in searched_variant['familyGuids']] return json, variants_to_saved_variants
def test_json_for_saved_variants_with_tags(self): variant_guid_1 = 'SV0000001_2103343353_r0390_100' variant_guid_2 = 'SV0000002_1248367227_r0390_100' v1_tag_guids = {'VT1708633_2103343353_r0390_100', 'VT1726961_2103343353_r0390_100'} v2_tag_guids = {'VT1726945_2103343353_r0390_100', 'VT1726970_2103343353_r0004_tes'} v2_note_guids = ['VN0714935_2103343353_r0390_100'] v1_functional_guids = { 'VFD0000023_1248367227_r0390_10', 'VFD0000024_1248367227_r0390_10', 'VFD0000025_1248367227_r0390_10', 'VFD0000026_1248367227_r0390_10'} variants = SavedVariant.objects.filter(guid__in=[variant_guid_1, variant_guid_2]) json = get_json_for_saved_variants_with_tags(variants) keys = {'variantTagsByGuid', 'variantNotesByGuid', 'variantFunctionalDataByGuid', 'savedVariantsByGuid'} self.assertSetEqual(set(json.keys()), keys) self.assertSetEqual(set(json['savedVariantsByGuid'].keys()), {variant_guid_1, variant_guid_2}) var_fields = {'tagGuids', 'noteGuids', 'functionalDataGuids'} var_fields.update(SAVED_VARIANT_FIELDS) self.assertSetEqual(set(json['savedVariantsByGuid'][variant_guid_1].keys()), var_fields) var_1 = json['savedVariantsByGuid'][variant_guid_1] self.assertEqual(var_1['variantId'], '21-3343353-GAGA-G') self.assertSetEqual(set(var_1['tagGuids']), v1_tag_guids) self.assertSetEqual(set(var_1['functionalDataGuids']), v1_functional_guids) var_2 = json['savedVariantsByGuid'][variant_guid_2] self.assertEqual(var_2['variantId'], '12-48367227-TC-T') self.assertSetEqual(set(var_2['tagGuids']), v2_tag_guids) self.assertListEqual(var_2['noteGuids'], v2_note_guids) self.assertSetEqual(set(json['variantTagsByGuid'].keys()), v1_tag_guids | v2_tag_guids) self.assertSetEqual(set(next(iter(json['variantTagsByGuid'].values())).keys()), TAG_FIELDS) for tag_guid in v1_tag_guids: self.assertListEqual(json['variantTagsByGuid'][tag_guid]['variantGuids'], [variant_guid_1]) for tag_guid in v2_tag_guids: self.assertListEqual(json['variantTagsByGuid'][tag_guid]['variantGuids'], [variant_guid_2]) self.assertListEqual(list(json['variantNotesByGuid'].keys()), v2_note_guids) self.assertSetEqual(set(json['variantNotesByGuid'][v2_note_guids[0]].keys()), VARIANT_NOTE_FIELDS) self.assertListEqual(json['variantNotesByGuid'][v2_note_guids[0]]['variantGuids'], [variant_guid_2]) self.assertSetEqual(set(json['variantFunctionalDataByGuid'].keys()), v1_functional_guids) self.assertSetEqual(set(next(iter(json['variantFunctionalDataByGuid'].values())).keys()), FUNCTIONAL_FIELDS) for tag_guid in v1_functional_guids: self.assertListEqual(json['variantFunctionalDataByGuid'][tag_guid]['variantGuids'], [variant_guid_1])
def saved_variant_data(request, project_guid, variant_guids=None): project = get_project_and_check_permissions(project_guid, request.user) family_guids = request.GET['families'].split(',') if request.GET.get('families') else None variant_guids = variant_guids.split(',') if variant_guids else None if family_guids: variant_query = SavedVariant.objects.filter(family__guid__in=family_guids) else: variant_query = SavedVariant.objects.filter(family__project=project) if variant_guids: variant_query = variant_query.filter(guid__in=variant_guids) if variant_query.count() < 1: return create_json_response({}, status=404, reason='Variant {} not found'.format(', '.join(variant_guids))) response = get_json_for_saved_variants_with_tags(variant_query, add_details=True) variants = response['savedVariantsByGuid'].values() genes = _saved_variant_genes(variants) _add_locus_lists([project], variants, genes) response['genesById'] = genes return create_json_response(response)
def _get_saved_variants(variants, families, include_discovery_tags=False): if not variants: return {}, {} variants = _flatten_variants(variants) prefetch_related_objects(families, 'project') hg37_family_guids = { family.guid for family in families if family.project.genome_version == GENOME_VERSION_GRCh37 } variant_q = Q() discovery_variant_q = Q() variants_by_id = {} for variant in variants: variants_by_id[_get_variant_key(**variant)] = variant variant_q |= Q(xpos_start=variant['xpos'], ref=variant['ref'], alt=variant['alt'], family__guid__in=variant['familyGuids']) discovery_variant_q |= Q( Q(xpos_start=variant['xpos'], ref=variant['ref'], alt=variant['alt']) & ~Q(family__guid__in=variant['familyGuids'])) if variant[ 'liftedOverGenomeVersion'] == GENOME_VERSION_GRCh37 and hg37_family_guids: variant_hg37_families = [ family_guid for family_guid in variant['familyGuids'] if family_guid in hg37_family_guids ] if variant_hg37_families: lifted_xpos = get_xpos(variant['liftedOverChrom'], variant['liftedOverPos']) variant_q |= Q(xpos_start=lifted_xpos, ref=variant['ref'], alt=variant['alt'], family__guid__in=variant_hg37_families) variants_by_id[_get_variant_key( xpos=lifted_xpos, ref=variant['ref'], alt=variant['alt'], genomeVersion=variant['liftedOverGenomeVersion'] )] = variant saved_variants = SavedVariant.objects.filter(variant_q) json = get_json_for_saved_variants_with_tags(saved_variants, add_details=True) variants_to_saved_variants = {} for saved_variant in json['savedVariantsByGuid'].values(): family_guids = saved_variant['familyGuids'] searched_variant = variants_by_id.get( _get_variant_key(**saved_variant)) if not searched_variant: # This can occur when an hg38 family has a saved variant that did not successfully lift from hg37 continue saved_variant.update(searched_variant) # For saved variants only use family it was saved for, not all families in search saved_variant['familyGuids'] = family_guids json['savedVariantsByGuid'][ saved_variant['variantGuid']] = saved_variant if searched_variant['variantId'] not in variants_to_saved_variants: variants_to_saved_variants[searched_variant['variantId']] = {} for family_guid in family_guids: variants_to_saved_variants[searched_variant['variantId']][ family_guid] = saved_variant['variantGuid'] if include_discovery_tags: discovery_tags = get_json_for_variant_tags( VariantTag.objects.filter( variant_tag_type__category='CMG Discovery Tags', saved_variants__in=SavedVariant.objects.filter( discovery_variant_q)), include_variant_details=True) if discovery_tags: family_guids = set() for tag in discovery_tags: for variant in tag['variants']: family_guids.update(variant['familyGuids']) families_by_guid = { f.guid: f for f in Family.objects.filter( guid__in=family_guids).prefetch_related('project') } for tag in discovery_tags: for variant in tag.pop('variants'): variant_family = families_by_guid[variant['familyGuids'] [0]] searched_variant = variants_by_id.get( _get_variant_key(genomeVersion=variant_family.project. genome_version, **variant)) if searched_variant: if not searched_variant.get('discoveryTags'): searched_variant['discoveryTags'] = [] tag_json = { 'savedVariant': { 'variantGuid': variant['variantGuid'], 'familyGuid': variant_family.guid, 'projectGuid': variant_family.project.guid, } } tag_json.update(tag) searched_variant['discoveryTags'].append(tag_json) json['familiesByGuid'] = { f['familyGuid']: f for f in _get_json_for_families(families_by_guid.values()) } return json, variants_to_saved_variants