Пример #1
0
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)
Пример #2
0
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)
Пример #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)
Пример #4
0
 def _process_result(result, search):
     # Do not apply HGMD filters in shared searches for non-analyst users
     if not search.created_by and not user_is_analyst(
             user) and result['search'].get('pathogenicity',
                                            {}).get('hgmd'):
         result['search']['pathogenicity'] = {
             k: v
             for k, v in result['search']['pathogenicity'].items()
             if k != 'hgmd'
         }
Пример #5
0
def query_variants_handler(request, search_hash):
    """Search variants.
    """
    page = int(request.GET.get('page') or 1)
    per_page = int(request.GET.get('per_page') or 100)
    sort = request.GET.get('sort') or XPOS_SORT_KEY
    if sort == PATHOGENICTY_SORT_KEY and user_is_analyst(request.user):
        sort = PATHOGENICTY_HGMD_SORT_KEY

    search_context = json.loads(request.body or '{}')
    try:
        results_model = _get_or_create_results_model(search_hash,
                                                     search_context,
                                                     request.user)
    except Exception as e:
        return create_json_response({'error': str(e)},
                                    status=400,
                                    reason=str(e))

    _check_results_permission(results_model, request.user)
    is_all_project_search = _is_all_project_family_search(search_context)

    variants, total_results = get_es_variants(
        results_model,
        sort=sort,
        page=page,
        num_results=per_page,
        skip_genotype_filter=is_all_project_search,
        user=request.user)

    response_context = {}
    if is_all_project_search and len(variants) == total_results:
        # For all project search only save the relevant families
        family_guids = set()
        for variant in variants:
            family_guids.update(variant['familyGuids'])
        families = results_model.families.filter(guid__in=family_guids)
        results_model.families.set(families)

        projects = Project.objects.filter(family__in=families).distinct()
        response_context = _get_projects_details(projects, request.user)

    response = _process_variants(variants or [], results_model.families.all(),
                                 request.user)
    response['search'] = _get_search_context(results_model)
    response['search']['totalResults'] = total_results
    response.update(response_context)

    return create_json_response(response)
Пример #6
0
def get_json_for_saved_searches(searches, user):
    is_analyst = user_is_analyst(user)

    def _process_result(result, search):
        # Do not apply HGMD filters in shared searches for non-analyst users
        if not search.created_by and not is_analyst and result['search'].get(
                'pathogenicity', {}).get('hgmd'):
            result['search']['pathogenicity'] = {
                k: v
                for k, v in result['search']['pathogenicity'].items()
                if k != 'hgmd'
            }

    prefetch_related_objects(searches, 'created_by')
    return _get_json_for_models(searches,
                                guid_key='savedSearchGuid',
                                process_result=_process_result)
Пример #7
0
def _process_variants(variants, families, user):
    if not variants:
        return {'searchedVariants': variants}

    prefetch_related_objects(families, 'project')
    genes = saved_variant_genes(variants)
    projects = {family.project for family in families}
    locus_lists_by_guid = _add_locus_lists(projects, genes)
    response_json, _ = _get_saved_variants(
        variants, families, include_discovery_tags=user_is_analyst(user))

    response_json.update({
        'searchedVariants': variants,
        'genesById': genes,
        'locusListsByGuid': locus_lists_by_guid,
    })
    return response_json
Пример #8
0
def project_page_data(request, project_guid):
    """Returns a JSON object containing information used by the project page:
    ::

      json_response = {
         'project': {..},
         'familiesByGuid': {..},
         'individualsByGuid': {..},
         'samplesByGuid': {..},
       }

    Args:
        project_guid (string): GUID of the Project to retrieve data for.
    """
    project = get_project_and_check_permissions(project_guid, request.user)
    update_project_from_json(project, {'last_accessed_date': timezone.now()},
                             request.user)

    is_analyst = user_is_analyst(request.user)
    response = _get_project_child_entities(project, request.user, is_analyst)

    project_json = _get_json_for_project(project,
                                         request.user,
                                         is_analyst=is_analyst)
    project_json['collaborators'] = get_json_for_project_collaborator_list(
        request.user, project)
    project_json['locusListGuids'] = list(response['locusListsByGuid'].keys())
    project_json['detailsLoaded'] = True
    project_json.update(_get_json_for_variant_tag_types(project))

    gene_ids = set()
    for tag in project_json['discoveryTags']:
        gene_ids.update(list(tag.get('transcripts', {}).keys()))
    for submission in response['mmeSubmissionsByGuid'].values():
        gene_ids.update(submission['geneIds'])

    response.update({
        'projectsByGuid': {
            project_guid: project_json
        },
        'genesById': get_genes(gene_ids),
    })

    return create_json_response(response)
Пример #9
0
def update_model_from_json(model_obj,
                           json,
                           user,
                           allow_unknown_keys=False,
                           immutable_keys=None,
                           updated_fields=None,
                           verbose=True):
    immutable_keys = (immutable_keys or []) + [
        'created_by', 'created_date', 'last_modified_date', 'id'
    ]
    internal_fields = model_obj._meta.internal_json_fields if hasattr(
        model_obj._meta, 'internal_json_fields') else []

    if not updated_fields:
        updated_fields = set()
    for json_key, value in json.items():
        orm_key = _to_snake_case(json_key)
        if orm_key in immutable_keys:
            if allow_unknown_keys:
                continue
            raise ValueError('Cannot edit field {}'.format(orm_key))
        if allow_unknown_keys and not hasattr(model_obj, orm_key):
            continue
        if getattr(model_obj, orm_key) != value:
            if orm_key in internal_fields and not user_is_analyst(user):
                raise PermissionDenied(
                    'User {0} is not authorized to edit the internal field {1}'
                    .format(user, orm_key))
            updated_fields.add(orm_key)
            setattr(model_obj, orm_key, value)

    if updated_fields:
        model_obj.save()
        if verbose:
            log_model_update(logger, model_obj, user, 'update', updated_fields)
    return bool(updated_fields)
Пример #10
0
 def _process_result(result, family):
     result['analysedBy'] = [{
         'createdBy': {
             'fullName': ab.created_by.get_full_name(),
             'email': ab.created_by.email,
             'isAnalyst': user_is_analyst(ab.created_by)
         },
         'lastModifiedDate': ab.last_modified_date,
     } for ab in family.familyanalysedby_set.all()]
     pedigree_image = _get_pedigree_image_url(result.pop('pedigreeImage'))
     result['pedigreeImage'] = pedigree_image
     if add_individual_guids_field:
         result['individualGuids'] = [
             i.guid for i in family.individual_set.all()
         ]
     if not result['displayName']:
         result['displayName'] = result['familyId']
     if result['assignedAnalyst']:
         result['assignedAnalyst'] = {
             'fullName': result['assignedAnalyst'].get_full_name(),
             'email': result['assignedAnalyst'].email,
         }
     else:
         result['assignedAnalyst'] = None
Пример #11
0
def _get_json_for_models(models,
                         nested_fields=None,
                         user=None,
                         is_analyst=None,
                         process_result=None,
                         guid_key=None,
                         additional_model_fields=None):
    """Returns an array JSON representations of the given models.

    Args:
        models (array): Array of django models
        user (object): Django User object for determining whether to include restricted/internal-only fields
        nested_fields (array): Optional array of fields to get from the model that are nested on related objects
        process_result (lambda): Optional function to post-process a given model json
        guid_key (string): Optional key to use for the model's guid
    Returns:
        array: json objects
    """

    if not models:
        return []

    model_class = type(models[0])
    fields = copy(model_class._meta.json_fields)
    if is_analyst is None:
        is_analyst = user and user_is_analyst(user)
    if is_analyst:
        fields += getattr(model_class._meta, 'internal_json_fields', [])
    if additional_model_fields:
        fields += additional_model_fields

    if 'created_by' in fields:
        prefetch_related_objects(models, 'created_by')
    for nested_field in nested_fields or []:
        if not nested_field.get('value'):
            prefetch_related_objects(models,
                                     '__'.join(nested_field['fields'][:-1]))

    results = []
    for model in models:
        result = {
            _to_camel_case(field): getattr(model, field)
            for field in fields
        }
        for nested_field in (nested_fields or []):
            field_value = nested_field.get('value')
            if not field_value:
                field_value = model
                for field in nested_field['fields']:
                    field_value = getattr(field_value,
                                          field) if field_value else None

            result[nested_field.get(
                'key', _to_camel_case('_'.join(
                    nested_field['fields'])))] = field_value

        if result.get('guid'):
            guid_key = guid_key or '{}{}Guid'.format(
                model_class.__name__[0].lower(), model_class.__name__[1:])
            result[guid_key] = result.pop('guid')
        if result.get('createdBy'):
            result['createdBy'] = result['createdBy'].get_full_name(
            ) or result['createdBy'].email
        if process_result:
            process_result(result, model)
        results.append(result)

    return results
Пример #12
0
    'date_joined', 'id'
]
BOOL_USER_FIELDS = {
    'is_superuser': False,
    'is_active': True,
}
MODEL_USER_FIELDS = MAIN_USER_FIELDS + list(BOOL_USER_FIELDS.keys())
COMPUTED_USER_FIELDS = {
    'is_anvil':
    lambda user, is_anvil=None, **kwargs: is_anvil_authenticated(user)
    if is_anvil is None else is_anvil,
    'display_name':
    lambda user, **kwargs: user.get_full_name(),
    'is_analyst':
    lambda user, analyst_users=None, **kwargs: user in analyst_users
    if analyst_users is not None else user_is_analyst(user),
    'is_data_manager':
    lambda user, **kwargs: user_is_data_manager(user),
    'is_pm':
    lambda user, pm_users=None, **kwargs: user in pm_users
    if pm_users is not None else user_is_pm(user),
}

DEFAULT_USER = {_to_camel_case(field): '' for field in MAIN_USER_FIELDS}
DEFAULT_USER.update(
    {_to_camel_case(field): val
     for field, val in BOOL_USER_FIELDS.items()})
DEFAULT_USER.update(
    {_to_camel_case(field): False
     for field in COMPUTED_USER_FIELDS.keys()})
Пример #13
0
    'username', 'email', 'first_name', 'last_name', 'last_login',
    'date_joined', 'id'
]
BOOL_USER_FIELDS = {
    'is_superuser': False,
    'is_active': True,
}
MODEL_USER_FIELDS = MAIN_USER_FIELDS + list(BOOL_USER_FIELDS.keys())
COMPUTED_USER_FIELDS = {
    'is_anvil':
    lambda user, is_anvil=None: is_anvil_authenticated(user)
    if is_anvil is None else is_anvil,
    'display_name':
    lambda user, **kwargs: user.get_full_name(),
    'is_analyst':
    lambda user, **kwargs: user_is_analyst(user),
    'is_data_manager':
    lambda user, **kwargs: user_is_data_manager(user),
    'is_pm':
    lambda user, **kwargs: user_is_pm(user),
}

DEFAULT_USER = {_to_camel_case(field): '' for field in MAIN_USER_FIELDS}
DEFAULT_USER.update(
    {_to_camel_case(field): val
     for field, val in BOOL_USER_FIELDS.items()})
DEFAULT_USER.update(
    {_to_camel_case(field): False
     for field in COMPUTED_USER_FIELDS.keys()})