def update_status(self, institute, case, user, status, link):

if status not in CASE_STATUSES:<EOL><INDENT>LOG.warning("<STR_LIT>".format(status))<EOL>return None<EOL><DEDENT>LOG.info("<STR_LIT>".format(<EOL>case['<STR_LIT>'], status))<EOL>self.create_event(<EOL>institute=institute,<EOL>case=case,<EOL>user=user,<EOL>link=link,<EOL>category='<STR_LIT>',<EOL>verb='<STR_LIT:status>',<EOL>subject=case['<STR_LIT>']<EOL>)<EOL>LOG.info("<STR_LIT>".format(case['<STR_LIT>'], status))<EOL>updated_case = self.case_collection.find_one_and_update(<EOL>{'<STR_LIT>': case['<STR_LIT>']},<EOL>{'<STR_LIT>': {'<STR_LIT:status>': status}},<EOL>return_document=pymongo.ReturnDocument.AFTER<EOL>)<EOL>LOG.debug("<STR_LIT>")<EOL>return updated_case<EOL>

Update the status of a case.

        This function will create an Event to log that a user have updated the
        status of a case. Also the status of the case will be updated.
        Status could be anyone of:
            ("prioritized", "inactive", "active", "solved", "archived")

        Arguments:
            institute (dict): A Institute object
            case (dict): A Case object
            user (dict): A User object
            status (str): The new status of the case
            link (str): The url to be used in the event

        Returns:
            updated_case


def update_synopsis(self, institute, case, user, link, content="<STR_LIT>"):

Create an Event for updating the synopsis for a case.

            This function will create an Event and update the synopsis for
             a case.

        Arguments:
            institute (dict): A Institute object
            case (dict): A Case object
            user (dict): A User object
            link (str): The url to be used in the event
            content (str): The content for what should be added to the synopsis

        Returns:
            updated_case


def archive_case(self, institute, case, user, link):

Create an event for archiving a case.

        Arguments:
            institute (dict): A Institute object
            case (dict): Case object
            user (dict): A User object
            link (str): The url to be used in the event

        Returns:
            updated_case (dict)


def open_research(self, institute, case, user, link):

Create an event for opening the research list a case.

        Arguments:
            institute (dict): A Institute object
            case (dict): Case object
            user (dict): A User object
            link (str): The url to be used in the event

        Returns:
            updated_case(dict)


def request_rerun(self, institute, case, user, link):

Request a case to be re-analyzed.

        Arguments:
            institute (dict): A Institute object
            case (dict): Case object
            user (dict): A User object
            link (str): The url to be used in the event

        Return:
            updated_case


def share(self, institute, case, collaborator_id, user, link):

if collaborator_id in case.get('<STR_LIT>', []):<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT>self.create_event(<EOL>institute=institute,<EOL>case=case,<EOL>user=user,<EOL>link=link,<EOL>category='<STR_LIT>',<EOL>verb='<STR_LIT>',<EOL>subject=collaborator_id<EOL>)<EOL>updated_case = self.case_collection.find_one_and_update(<EOL>{'<STR_LIT>': case['<STR_LIT>']},<EOL>{<EOL>'<STR_LIT>': {'<STR_LIT>': collaborator_id}<EOL>},<EOL>return_document=pymongo.ReturnDocument.AFTER<EOL>)<EOL>LOG.debug("<STR_LIT>")<EOL>return updated_case<EOL>

Share a case with a new institute.

        Arguments:
            institute (dict): A Institute object
            case (dict): Case object
            collaborator_id (str): A instute id
            user (dict): A User object
            link (str): The url to be used in the event

        Return:
            updated_case


def unshare(self, institute, case, collaborator_id, user, link):

if collaborator_id not in case['<STR_LIT>']:<EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT>self.create_event(<EOL>institute=institute,<EOL>case=case,<EOL>user=user,<EOL>link=link,<EOL>category='<STR_LIT>',<EOL>verb='<STR_LIT>',<EOL>subject=collaborator_id<EOL>)<EOL>updated_case = self.case_collection.find_one_and_update(<EOL>{'<STR_LIT>': case['<STR_LIT>']},<EOL>{<EOL>'<STR_LIT>': {'<STR_LIT>': collaborator_id}<EOL>},<EOL>return_document=pymongo.ReturnDocument.AFTER<EOL>)<EOL>LOG.debug("<STR_LIT>")<EOL>return updated_case<EOL>

Revoke access for a collaborator for a case.

        Arguments:
            institute (dict): A Institute object
            case (dict): Case object
            collaborator_id (str): A instute id
            user (dict): A User object
            link (str): The url to be used in the event

        Return:
            updated_case


def diagnose(self, institute, case, user, link, level, omim_id, remove=False):

if level == '<STR_LIT>':<EOL><INDENT>case_key = '<STR_LIT>'<EOL><DEDENT>elif level == '<STR_LIT>':<EOL><INDENT>case_key = '<STR_LIT>'<EOL><DEDENT>else:<EOL><INDENT>raise TypeError('<STR_LIT>')<EOL><DEDENT>diagnosis_list = case.get(case_key, [])<EOL>omim_number = int(omim_id.split('<STR_LIT::>')[-<NUM_LIT:1>])<EOL>updated_case = None<EOL>if remove and omim_number in diagnosis_list:<EOL><INDENT>updated_case = self.case_collection.find_one_and_update(<EOL>{'<STR_LIT>': case['<STR_LIT>']},<EOL>{'<STR_LIT>': {case_key: omim_number}},<EOL>return_document=pymongo.ReturnDocument.AFTER<EOL>)<EOL><DEDENT>elif omim_number not in diagnosis_list:<EOL><INDENT>updated_case = self.case_collection.find_one_and_update(<EOL>{'<STR_LIT>': case['<STR_LIT>']},<EOL>{'<STR_LIT>': {case_key: omim_number}},<EOL>return_document=pymongo.ReturnDocument.AFTER<EOL>)<EOL><DEDENT>if updated_case:<EOL><INDENT>self.create_event(<EOL>institute=institute,<EOL>case=case,<EOL>user=user,<EOL>link=link,<EOL>category='<STR_LIT>',<EOL>verb='<STR_LIT>',<EOL>subject=case['<STR_LIT>'],<EOL>content=omim_id<EOL>)<EOL><DEDENT>return updated_case<EOL>

Diagnose a case using OMIM ids.

        Arguments:
            institute (dict): A Institute object
            case (dict): Case object
            user (dict): A User object
            link (str): The url to be used in the event
            level (str): choices=('phenotype','gene')

        Return:
            updated_case


def add_cohort(self, institute, case, user, link, tag):

Add a cohort tag to case

        Arguments:
            institute (dict): A Institute object
            case (dict): Case object
            user (dict): A User object
            link (str): The url to be used in the event
            tag (str): The cohort tag to be added

        Return:
            updated_case(dict)


def remove_cohort(self, institute, case, user, link, tag):

Remove a cohort tag from case

        Arguments:
            institute (dict): A Institute object
            case (dict): Case object
            user (dict): A User object
            link (str): The url to be used in the event
            tag (str): The cohort tag to be removed

        Return:
            updated_case(dict)


def mark_checked(self, institute, case, user, link,<EOL>unmark=False):

LOG.info("<STR_LIT>"<EOL>.format(case['<STR_LIT>']))<EOL>status = '<STR_LIT>' if unmark else '<STR_LIT>'<EOL>self.create_event(<EOL>institute=institute,<EOL>case=case,<EOL>user=user,<EOL>link=link,<EOL>category='<STR_LIT>',<EOL>verb='<STR_LIT>',<EOL>subject=status<EOL>)<EOL>LOG.info("<STR_LIT>"<EOL>.format(case['<STR_LIT>'], status))<EOL>analysis_checked = False if unmark else True<EOL>updated_case = self.case_collection.find_one_and_update(<EOL>{'<STR_LIT>': case['<STR_LIT>']},<EOL>{<EOL>'<STR_LIT>': {'<STR_LIT>': analysis_checked}<EOL>},<EOL>return_document=pymongo.ReturnDocument.AFTER<EOL>)<EOL>LOG.debug("<STR_LIT>")<EOL>return updated_case<EOL>

Mark a case as checked from an analysis point of view.

        Arguments:
            institute (dict): A Institute object
            case (dict): Case object
            user (dict): A User object
            link (str): The url to be used in the event
            unmark (bool): If case should ve unmarked

        Return:
            updated_case


def update_default_panels(self, institute_obj, case_obj, user_obj, link, panel_objs):

self.create_event(<EOL>institute=institute_obj,<EOL>case=case_obj,<EOL>user=user_obj,<EOL>link=link,<EOL>category='<STR_LIT>',<EOL>verb='<STR_LIT>',<EOL>subject=case_obj['<STR_LIT>'],<EOL>)<EOL>LOG.info("<STR_LIT>".format(case_obj['<STR_LIT>']))<EOL>panel_ids = [panel['<STR_LIT>'] for panel in panel_objs]<EOL>for existing_panel in case_obj['<STR_LIT>']:<EOL><INDENT>if existing_panel['<STR_LIT>'] in panel_ids:<EOL><INDENT>existing_panel['<STR_LIT>'] = True<EOL><DEDENT>else:<EOL><INDENT>existing_panel['<STR_LIT>'] = False<EOL><DEDENT><DEDENT>updated_case = self.case_collection.find_one_and_update(<EOL>{'<STR_LIT>': case_obj['<STR_LIT>']},<EOL>{<EOL>'<STR_LIT>': {'<STR_LIT>': case_obj['<STR_LIT>']}<EOL>},<EOL>return_document=pymongo.ReturnDocument.AFTER<EOL>)<EOL>LOG.debug("<STR_LIT>")<EOL>return updated_case<EOL>

Update default panels for a case.

        Arguments:
            institute_obj (dict): A Institute object
            case_obj (dict): Case object
            user_obj (dict): A User object
            link (str): The url to be used in the event
            panel_objs (list(dict)): List of panel objs

        Return:
            updated_case(dict)


def add_gene_info(self, variant_obj, gene_panels=None):

gene_panels = gene_panels or []<EOL>variant_obj['<STR_LIT>'] = False<EOL>extra_info = {}<EOL>for panel_obj in gene_panels:<EOL><INDENT>for gene_info in panel_obj['<STR_LIT>']:<EOL><INDENT>hgnc_id = gene_info['<STR_LIT>']<EOL>if hgnc_id not in extra_info:<EOL><INDENT>extra_info[hgnc_id] = []<EOL><DEDENT>extra_info[hgnc_id].append(gene_info)<EOL><DEDENT><DEDENT>for variant_gene in variant_obj.get('<STR_LIT>', []):<EOL><INDENT>hgnc_id = variant_gene['<STR_LIT>']<EOL>hgnc_gene = self.hgnc_gene(hgnc_id)<EOL>if not hgnc_gene:<EOL><INDENT>continue<EOL><DEDENT>transcripts_dict = {}<EOL>for transcript in hgnc_gene.get('<STR_LIT>', []):<EOL><INDENT>tx_id = transcript['<STR_LIT>']<EOL>transcripts_dict[tx_id] = transcript<EOL><DEDENT>hgnc_gene['<STR_LIT>'] = transcripts_dict<EOL>if hgnc_gene.get('<STR_LIT>'):<EOL><INDENT>variant_gene['<STR_LIT>'] = True<EOL><DEDENT>panel_info = extra_info.get(hgnc_id, [])<EOL>disease_associated = set()<EOL>disease_associated_no_version = set()<EOL>manual_penetrance = False<EOL>mosaicism = False<EOL>manual_inheritance = set()<EOL>for gene_info in panel_info:<EOL><INDENT>for tx in gene_info.get('<STR_LIT>', []):<EOL><INDENT>stripped = re.sub(r'<STR_LIT>', '<STR_LIT>', tx)<EOL>disease_associated_no_version.add(stripped)<EOL>disease_associated.add(tx)<EOL><DEDENT>if gene_info.get('<STR_LIT>'):<EOL><INDENT>manual_penetrance = True<EOL><DEDENT>if gene_info.get('<STR_LIT>'):<EOL><INDENT>mosaicism = True<EOL><DEDENT>manual_inheritance.update(gene_info.get('<STR_LIT>', []))<EOL><DEDENT>variant_gene['<STR_LIT>'] = list(disease_associated)<EOL>variant_gene['<STR_LIT>'] = manual_penetrance<EOL>variant_gene['<STR_LIT>'] = mosaicism<EOL>variant_gene['<STR_LIT>'] = list(manual_inheritance)<EOL>for transcript in variant_gene.get('<STR_LIT>', []):<EOL><INDENT>tx_id = transcript['<STR_LIT>']<EOL>if not tx_id in transcripts_dict:<EOL><INDENT>continue<EOL><DEDENT>hgnc_transcript = transcripts_dict[tx_id]<EOL>if hgnc_transcript.get('<STR_LIT>'):<EOL><INDENT>transcript['<STR_LIT>'] = True<EOL><DEDENT>if not hgnc_transcript.get('<STR_LIT>'):<EOL><INDENT>continue<EOL><DEDENT>refseq_id = hgnc_transcript['<STR_LIT>']<EOL>transcript['<STR_LIT>'] = refseq_id<EOL>variant_obj['<STR_LIT>'] = True<EOL>if refseq_id in disease_associated_no_version:<EOL><INDENT>transcript['<STR_LIT>'] = True<EOL><DEDENT>transcript['<STR_LIT>'] = hgnc_transcript.get('<STR_LIT>',[])<EOL><DEDENT>variant_gene['<STR_LIT>'] = hgnc_gene<EOL>variant_gene['<STR_LIT>'] = self.disease_terms(hgnc_id)<EOL><DEDENT>return variant_obj<EOL>

Add extra information about genes from gene panels

        Args:
            variant_obj(dict): A variant from the database
            gene_panels(list(dict)): List of panels from database


def variants(self, case_id, query=None, variant_ids=None, category='<STR_LIT>',<EOL>nr_of_variants=<NUM_LIT:10>, skip=<NUM_LIT:0>, sort_key='<STR_LIT>'):

LOG.debug("<STR_LIT>".format(case_id))<EOL>if variant_ids:<EOL><INDENT>nr_of_variants = len(variant_ids)<EOL><DEDENT>elif nr_of_variants == -<NUM_LIT:1>:<EOL><INDENT>nr_of_variants = <NUM_LIT:0> <EOL><DEDENT>else:<EOL><INDENT>nr_of_variants = skip + nr_of_variants<EOL><DEDENT>mongo_query = self.build_query(case_id, query=query,<EOL>variant_ids=variant_ids,<EOL>category=category)<EOL>sorting = []<EOL>if sort_key == '<STR_LIT>':<EOL><INDENT>sorting = [('<STR_LIT>', pymongo.ASCENDING)]<EOL><DEDENT>if sort_key == '<STR_LIT>':<EOL><INDENT>sorting = [('<STR_LIT>', pymongo.DESCENDING)]<EOL><DEDENT>if sort_key == '<STR_LIT>':<EOL><INDENT>sorting = [('<STR_LIT>', pymongo.ASCENDING)]<EOL><DEDENT>result = self.variant_collection.find(<EOL>mongo_query,<EOL>skip=skip,<EOL>limit=nr_of_variants<EOL>).sort(sorting)<EOL>return result<EOL>

Returns variants specified in question for a specific case.

        If skip not equal to 0 skip the first n variants.

        Arguments:
            case_id(str): A string that represents the case
            query(dict): A dictionary with querys for the database
            variant_ids(List[str])
            category(str): 'sv', 'str', 'snv' or 'cancer'
            nr_of_variants(int): if -1 return all variants
            skip(int): How many variants to skip
            sort_key: ['variant_rank', 'rank_score', 'position']

        Yields:
            result(Iterable[Variant])


def sanger_variants(self, institute_id=None, case_id=None):

query = {'<STR_LIT>': {'<STR_LIT>': True}}<EOL>if institute_id:<EOL><INDENT>query['<STR_LIT>'] = institute_id<EOL><DEDENT>if case_id:<EOL><INDENT>query['<STR_LIT>'] = case_id<EOL><DEDENT>return self.variant_collection.find(query)<EOL>

Return all variants with sanger information

        Args:
            institute_id(str)
            case_id(str)

        Returns:
            res(pymongo.Cursor): A Cursor with all variants with sanger activity


def variant(self, document_id, gene_panels=None, case_id=None):

query = {}<EOL>if case_id:<EOL><INDENT>query['<STR_LIT>'] = case_id<EOL>query['<STR_LIT>'] = document_id<EOL><DEDENT>else:<EOL><INDENT>query['<STR_LIT>'] = document_id<EOL><DEDENT>variant_obj = self.variant_collection.find_one(query)<EOL>if variant_obj:<EOL><INDENT>variant_obj = self.add_gene_info(variant_obj, gene_panels)<EOL>if variant_obj['<STR_LIT>'] in ['<STR_LIT:X>', '<STR_LIT:Y>']:<EOL><INDENT>variant_obj['<STR_LIT>'] = is_par(variant_obj['<STR_LIT>'],<EOL>variant_obj['<STR_LIT>'])<EOL><DEDENT><DEDENT>return variant_obj<EOL>

Returns the specified variant.

           Arguments:
               document_id : A md5 key that represents the variant or "variant_id"
               gene_panels(List[GenePanel])
               case_id (str): case id (will search with "variant_id")

           Returns:
               variant_object(Variant): A odm variant object


def gene_variants(self, query=None,<EOL>category='<STR_LIT>', variant_type=['<STR_LIT>'],<EOL>nr_of_variants=<NUM_LIT:50>, skip=<NUM_LIT:0>):

mongo_variant_query = self.build_variant_query(query=query,<EOL>category=category, variant_type=variant_type)<EOL>sorting = [('<STR_LIT>', pymongo.DESCENDING)]<EOL>if nr_of_variants == -<NUM_LIT:1>:<EOL><INDENT>nr_of_variants = <NUM_LIT:0> <EOL><DEDENT>else:<EOL><INDENT>nr_of_variants = skip + nr_of_variants<EOL><DEDENT>result = self.variant_collection.find(<EOL>mongo_variant_query<EOL>).sort(sorting).skip(skip).limit(nr_of_variants)<EOL>return result<EOL>

Return all variants seen in a given gene.

        If skip not equal to 0 skip the first n variants.

        Arguments:
            query(dict): A dictionary with querys for the database, including
            variant_type: 'clinical', 'research'
            category(str): 'sv', 'str', 'snv' or 'cancer'
            nr_of_variants(int): if -1 return all variants
            skip(int): How many variants to skip


query = {<EOL>'<STR_LIT>' : '<STR_LIT>',<EOL>'<STR_LIT>' : institute_id,<EOL>}<EOL>res = []<EOL>validate_events = self.event_collection.find(query)<EOL>for validated in list(validate_events):<EOL><INDENT>case_id = validated['<STR_LIT>']<EOL>var_obj = self.variant(case_id=case_id, document_id=validated['<STR_LIT>'])<EOL>case_obj = self.case(case_id=case_id)<EOL>if not case_obj or not var_obj:<EOL><INDENT>continue <EOL><DEDENT>var_obj['<STR_LIT>'] = {<EOL>'<STR_LIT>' : case_obj['<STR_LIT>'],<EOL>'<STR_LIT>' : case_obj['<STR_LIT>']<EOL>}<EOL>res.append(var_obj)<EOL><DEDENT>return res<EOL>

Return all verified variants for a given institute

        Args:
            institute_id(str): institute id

        Returns:
            res(list): a list with validated variants


def get_causatives(self, institute_id, case_id=None):

causatives = []<EOL>if case_id:<EOL><INDENT>case_obj = self.case_collection.find_one(<EOL>{"<STR_LIT>": case_id}<EOL>)<EOL>causatives = [causative for causative in case_obj['<STR_LIT>']]<EOL><DEDENT>elif institute_id:<EOL><INDENT>query = self.case_collection.aggregate([<EOL>{'<STR_LIT>': {'<STR_LIT>': institute_id, '<STR_LIT>': {'<STR_LIT>': True}}},<EOL>{'<STR_LIT>': '<STR_LIT>'},<EOL>{'<STR_LIT>': {'<STR_LIT>': '<STR_LIT>'}}<EOL>])<EOL>causatives = [item['<STR_LIT>'] for item in query]<EOL><DEDENT>return causatives<EOL>

Return all causative variants for an institute

            Args:
                institute_id(str)
                case_id(str)

            Yields:
                str: variant document id


def check_causatives(self, case_obj=None, institute_obj=None):

institute_id = case_obj['<STR_LIT>'] if case_obj else institute_obj['<STR_LIT>']<EOL>institute_causative_variant_ids = self.get_causatives(institute_id)<EOL>if len(institute_causative_variant_ids) == <NUM_LIT:0>:<EOL><INDENT>return []<EOL><DEDENT>if case_obj:<EOL><INDENT>case_causative_ids = set(case_obj.get('<STR_LIT>', []))<EOL>institute_causative_variant_ids = list(<EOL>set(institute_causative_variant_ids).difference(case_causative_ids)<EOL>)<EOL><DEDENT>query = self.variant_collection.find(<EOL>{'<STR_LIT>': {'<STR_LIT>': institute_causative_variant_ids}},<EOL>{'<STR_LIT>': <NUM_LIT:1>}<EOL>)<EOL>positional_variant_ids = [item['<STR_LIT>'] for item in query]<EOL>filters = {'<STR_LIT>': {'<STR_LIT>': positional_variant_ids}}<EOL>if case_obj:<EOL><INDENT>filters['<STR_LIT>'] = case_obj['<STR_LIT>']<EOL><DEDENT>else:<EOL><INDENT>filters['<STR_LIT>'] = institute_obj['<STR_LIT>']<EOL><DEDENT>return self.variant_collection.find(filters)<EOL>

Check if there are any variants that are previously marked causative

            Loop through all variants that are marked 'causative' for an
            institute and check if any of the variants are present in the
            current case.

            Args:
                case_obj (dict): A Case object
                institute_obj (dict): check across the whole institute

            Returns:
                causatives(iterable(Variant))


def other_causatives(self, case_obj, variant_obj):

<EOL>variant_id = variant_obj['<STR_LIT>'].rsplit('<STR_LIT:_>', <NUM_LIT:1>)[<NUM_LIT:0>]<EOL>institute_causatives = self.get_causatives(variant_obj['<STR_LIT>'])<EOL>for causative_id in institute_causatives:<EOL><INDENT>other_variant = self.variant(causative_id)<EOL>if not other_variant:<EOL><INDENT>continue<EOL><DEDENT>not_same_case = other_variant['<STR_LIT>'] != case_obj['<STR_LIT>']<EOL>same_variant = other_variant['<STR_LIT>'].startswith(variant_id)<EOL>if not_same_case and same_variant:<EOL><INDENT>yield other_variant<EOL><DEDENT><DEDENT>

Find the same variant in other cases marked causative.

        Args:
            case_obj(dict)
            variant_obj(dict)

        Yields:
            other_variant(dict)


def delete_variants(self, case_id, variant_type, category=None):

category = category or '<STR_LIT>'<EOL>LOG.info("<STR_LIT>".format(<EOL>variant_type, category, case_id))<EOL>query = {'<STR_LIT>': case_id, '<STR_LIT>': variant_type}<EOL>if category:<EOL><INDENT>query['<STR_LIT>'] = category<EOL><DEDENT>result = self.variant_collection.delete_many(query)<EOL>LOG.info("<STR_LIT>".format(result.deleted_count))<EOL>

Delete variants of one type for a case

            This is used when a case is reanalyzed

            Args:
                case_id(str): The case id
                variant_type(str): 'research' or 'clinical'
                category(str): 'snv', 'sv' or 'cancer'


<EOL>category = '<STR_LIT>' if variant_obj['<STR_LIT>'] == '<STR_LIT>' else '<STR_LIT>'<EOL>query = {<EOL>'<STR_LIT>': [<EOL>{'<STR_LIT>': variant_obj['<STR_LIT>']},<EOL>{'<STR_LIT>': category},<EOL>{'<STR_LIT>' : { '<STR_LIT>' : variant_obj['<STR_LIT>']}}<EOL>]<EOL>}<EOL>sort_key = [('<STR_LIT>', pymongo.DESCENDING)]<EOL>variants = self.variant_collection.find(query).sort(sort_key).limit(<NUM_LIT:30>)<EOL>return variants<EOL>

Return overlapping variants.

        Look at the genes that a variant overlaps to.
        Then return all variants that overlap these genes.

        If variant_obj is sv it will return the overlapping snvs and oposite
        There is a problem when SVs are huge since there are to many overlapping variants.

        Args:
            variant_obj(dict)

        Returns:
            variants(iterable(dict))


<EOL>query = {<EOL>'<STR_LIT>': [<EOL>{'<STR_LIT>': case_id},<EOL>{<EOL>'<STR_LIT>': [<EOL>{'<STR_LIT>': {'<STR_LIT>': True}},<EOL>{'<STR_LIT>': {'<STR_LIT>': True}},<EOL>{'<STR_LIT>': {'<STR_LIT>': True}},<EOL>]<EOL>}<EOL>],<EOL>}<EOL>variants = {}<EOL>for var in self.variant_collection.find(query):<EOL><INDENT>variants[var['<STR_LIT>']] = self.add_gene_info(var)<EOL><DEDENT>event_query = {<EOL>'<STR_LIT>': [<EOL>{'<STR_LIT>': case_id},<EOL>{'<STR_LIT>': '<STR_LIT>'},<EOL>{'<STR_LIT>': '<STR_LIT>'},<EOL>]<EOL>}<EOL>comment_variants = {event['<STR_LIT>'] for event in self.event_collection.find(event_query)}<EOL>for var_id in comment_variants:<EOL><INDENT>if var_id in variants:<EOL><INDENT>continue<EOL><DEDENT>variant_obj = self.variant(var_id, case_id=case_id)<EOL>if not variant_obj:<EOL><INDENT>continue<EOL><DEDENT>variant_obj['<STR_LIT>'] = True<EOL>variants[var_id] = variant_obj<EOL><DEDENT>return variants.values()<EOL>

Returns variants that has been evaluated

        Return all variants, snvs/indels and svs from case case_id
        which have a entry for 'acmg_classification', 'manual_rank', 'dismiss_variant'
        or if they are commented.

        Args:
            case_id(str)

        Returns:
            variants(iterable(Variant))


def get_region_vcf(self, case_obj, chrom=None, start=None, end=None,<EOL>gene_obj=None, variant_type='<STR_LIT>', category='<STR_LIT>',<EOL>rank_threshold=None):

rank_threshold = rank_threshold or -<NUM_LIT:100><EOL>variant_file = None<EOL>if variant_type == '<STR_LIT>':<EOL><INDENT>if category == '<STR_LIT>':<EOL><INDENT>variant_file = case_obj['<STR_LIT>'].get('<STR_LIT>')<EOL><DEDENT>elif category == '<STR_LIT>':<EOL><INDENT>variant_file = case_obj['<STR_LIT>'].get('<STR_LIT>')<EOL><DEDENT>elif category == '<STR_LIT:str>':<EOL><INDENT>variant_file = case_obj['<STR_LIT>'].get('<STR_LIT>')<EOL><DEDENT><DEDENT>elif variant_type == '<STR_LIT>':<EOL><INDENT>if category == '<STR_LIT>':<EOL><INDENT>variant_file = case_obj['<STR_LIT>'].get('<STR_LIT>')<EOL><DEDENT>elif category == '<STR_LIT>':<EOL><INDENT>variant_file = case_obj['<STR_LIT>'].get('<STR_LIT>')<EOL><DEDENT><DEDENT>if not variant_file:<EOL><INDENT>raise SyntaxError("<STR_LIT>")<EOL><DEDENT>vcf_obj = VCF(variant_file)<EOL>region = "<STR_LIT>"<EOL>if gene_obj:<EOL><INDENT>chrom = gene_obj['<STR_LIT>']<EOL>start = gene_obj['<STR_LIT:start>']<EOL>end = gene_obj['<STR_LIT:end>']<EOL><DEDENT>if chrom:<EOL><INDENT>if (start and end):<EOL><INDENT>region = "<STR_LIT>".format(chrom, start, end)<EOL><DEDENT>else:<EOL><INDENT>region = "<STR_LIT>".format(chrom)<EOL><DEDENT><DEDENT>else:<EOL><INDENT>rank_threshold = rank_threshold or <NUM_LIT:5><EOL><DEDENT>with tempfile.NamedTemporaryFile(mode='<STR_LIT:w>', delete=False) as temp:<EOL><INDENT>file_name = str(pathlib.Path(temp.name))<EOL>for header_line in vcf_obj.raw_header.split('<STR_LIT:\n>'):<EOL><INDENT>if len(header_line) > <NUM_LIT:3>:<EOL><INDENT>temp.write(header_line + '<STR_LIT:\n>')<EOL><DEDENT><DEDENT>for variant in vcf_obj(region):<EOL><INDENT>temp.write(str(variant))<EOL><DEDENT><DEDENT>return file_name<EOL>

Produce a reduced vcf with variants from the specified coordinates
           This is used for the alignment viewer.

        Args:
            case_obj(dict): A case from the scout database
            variant_type(str): 'clinical' or 'research'. Default: 'clinical'
            category(str): 'snv' or 'sv'. Default: 'snv'
            rank_threshold(float): Only load variants above this score. Default: 5
            chrom(str): Load variants from a certain chromosome
            start(int): Specify the start position
            end(int): Specify the end position
            gene_obj(dict): A gene object from the database

        Returns:
            file_name(str): Path to the temporary file


def sample_variants(self, variants, sample_name, category = '<STR_LIT>'):

LOG.info('<STR_LIT>'.format(sample_name))<EOL>has_allele = re.compile('<STR_LIT>') <EOL>query = {<EOL>'<STR_LIT>': [<EOL>{'<STR_LIT>' : { '<STR_LIT>' : variants}},<EOL>{'<STR_LIT>' : category},<EOL>{'<STR_LIT>': {<EOL>'<STR_LIT>': { '<STR_LIT>' : sample_name, '<STR_LIT>': { '<STR_LIT>' : has_allele } }<EOL>}}<EOL>]<EOL>}<EOL>result = self.variant_collection.find(query)<EOL>return result<EOL>

Given a list of variants get variant objects found in a specific patient

        Args:
            variants(list): a list of variant ids
            sample_name(str): a sample display name
            category(str): 'snv', 'sv' ..

        Returns:
            result(iterable(Variant))


indexes = []<EOL>for collection_name in self.collections():<EOL><INDENT>if collection and collection != collection_name:<EOL><INDENT>continue<EOL><DEDENT>for index_name in self.db[collection_name].index_information():<EOL><INDENT>if index_name != '<STR_LIT>':<EOL><INDENT>indexes.append(index_name)<EOL><DEDENT><DEDENT><DEDENT>return indexes<EOL>

Return a list with the current indexes

        Skip the mandatory _id_ indexes

        Args:
            collection(str)

        Returns:
            indexes(list)


for collection_name in INDEXES:<EOL><INDENT>existing_indexes = self.indexes(collection_name)<EOL>indexes = INDEXES[collection_name]<EOL>for index in indexes:<EOL><INDENT>index_name = index.document.get('<STR_LIT:name>')<EOL>if index_name in existing_indexes:<EOL><INDENT>LOG.info("<STR_LIT>" % index_name)<EOL>self.db[collection_name].drop_index(index_name)<EOL><DEDENT><DEDENT>LOG.info("<STR_LIT>".format(<EOL>collection_name,<EOL>'<STR_LIT:U+002CU+0020>'.join([index.document.get('<STR_LIT:name>') for index in indexes])<EOL>))<EOL>self.db[collection_name].create_indexes(indexes)<EOL><DEDENT>

Add the proper indexes to the scout instance.

        All indexes are specified in scout/constants/indexes.py

        If this method is utilised when new indexes are defined those should be added


LOG.info("<STR_LIT>")<EOL>nr_updated = <NUM_LIT:0><EOL>for collection_name in INDEXES:<EOL><INDENT>existing_indexes = self.indexes(collection_name)<EOL>indexes = INDEXES[collection_name]<EOL>for index in indexes:<EOL><INDENT>index_name = index.document.get('<STR_LIT:name>')<EOL>if index_name not in existing_indexes:<EOL><INDENT>nr_updated += <NUM_LIT:1><EOL>LOG.info("<STR_LIT>" % index_name)<EOL>self.db[collection_name].create_indexes(indexes)<EOL><DEDENT><DEDENT><DEDENT>if nr_updated == <NUM_LIT:0>:<EOL><INDENT>LOG.info("<STR_LIT>")<EOL><DEDENT>

Update the indexes

        If there are any indexes that are not added to the database, add those.


LOG.warning("<STR_LIT>")<EOL>for collection_name in INDEXES:<EOL><INDENT>LOG.warning("<STR_LIT>", collection_name)<EOL>self.db[collection_name].drop_indexes()<EOL><DEDENT>


panel_obj = build_panel(parsed_panel, self)<EOL>self.add_gene_panel(panel_obj)<EOL>

Load a gene panel based on the info sent
        A panel object is built and integrity checks are made.
        The panel object is then loaded into the database.

        Args:
            path(str): Path to panel file
            institute(str): Name of institute that owns the panel
            panel_id(str): Panel id
            date(datetime.datetime): Date of creation
            version(float)
            full_name(str): Option to have a long name

            panel_info(dict): {
                'file': <path to panel file>(str),
                'institute': <institute>(str),
                'type': <panel type>(str),
                'date': date,
                'version': version,
                'panel_name': panel_id,
                'full_name': name,
            }


def load_omim_panel(self, api_key, institute=None):

existing_panel = self.gene_panel(panel_id='<STR_LIT>')<EOL>if not existing_panel:<EOL><INDENT>LOG.warning("<STR_LIT>")<EOL>LOG.info('<STR_LIT>')<EOL>version = <NUM_LIT:1.0><EOL><DEDENT>if existing_panel:<EOL><INDENT>version = float(math.floor(existing_panel['<STR_LIT:version>']) + <NUM_LIT:1>)<EOL><DEDENT>LOG.info("<STR_LIT>", version)<EOL>try:<EOL><INDENT>mim_files = fetch_mim_files(api_key=api_key, genemap2=True, mim2genes=True)<EOL><DEDENT>except Exception as err:<EOL><INDENT>raise err<EOL><DEDENT>date_string = None<EOL>for line in mim_files['<STR_LIT>']:<EOL><INDENT>if '<STR_LIT>' in line:<EOL><INDENT>date_string = line.split('<STR_LIT::>')[-<NUM_LIT:1>].lstrip().rstrip()<EOL><DEDENT><DEDENT>date_obj = get_date(date_string)<EOL>if existing_panel:<EOL><INDENT>if existing_panel['<STR_LIT:date>'] == date_obj:<EOL><INDENT>LOG.warning("<STR_LIT>")<EOL>return<EOL><DEDENT><DEDENT>panel_data = {}<EOL>panel_data['<STR_LIT:path>'] = None<EOL>panel_data['<STR_LIT:type>'] = '<STR_LIT>'<EOL>panel_data['<STR_LIT:date>'] = date_obj<EOL>panel_data['<STR_LIT>'] = '<STR_LIT>'<EOL>panel_data['<STR_LIT>'] = institute or '<STR_LIT>'<EOL>panel_data['<STR_LIT:version>'] = version<EOL>panel_data['<STR_LIT>'] = '<STR_LIT>'<EOL>panel_data['<STR_LIT>'] = []<EOL>alias_genes = self.genes_by_alias()<EOL>genes = get_omim_panel_genes(<EOL>genemap2_lines = mim_files['<STR_LIT>'],<EOL>mim2gene_lines = mim_files['<STR_LIT>'],<EOL>alias_genes = alias_genes,<EOL>)<EOL>for gene in genes:<EOL><INDENT>panel_data['<STR_LIT>'].append(gene)<EOL><DEDENT>panel_obj = build_panel(panel_data, self)<EOL>if existing_panel:<EOL><INDENT>new_genes = self.compare_mim_panels(existing_panel, panel_obj)<EOL>if new_genes:<EOL><INDENT>self.update_mim_version(new_genes, panel_obj, old_version=existing_panel['<STR_LIT:version>'])<EOL><DEDENT>else:<EOL><INDENT>LOG.info("<STR_LIT>")<EOL>LOG.info("<STR_LIT>")<EOL>return<EOL><DEDENT><DEDENT>self.add_gene_panel(panel_obj)<EOL>


def compare_mim_panels(self, existing_panel, new_panel):

existing_genes = set([gene['<STR_LIT>'] for gene in existing_panel['<STR_LIT>']])<EOL>new_genes = set([gene['<STR_LIT>'] for gene in new_panel['<STR_LIT>']])<EOL>return new_genes.difference(existing_genes)<EOL>

Check if the latest version of OMIM differs from the most recent in database
           Return all genes that where not in the previous version.

        Args:
            existing_panel(dict)
            new_panel(dict)

        Returns:
            new_genes(set(str))


def update_mim_version(self, new_genes, new_panel, old_version):

LOG.info('<STR_LIT>')<EOL>version = new_panel['<STR_LIT:version>']<EOL>for gene in new_panel['<STR_LIT>']:<EOL><INDENT>gene_symbol = gene['<STR_LIT>']<EOL>if gene_symbol in new_genes:<EOL><INDENT>gene['<STR_LIT>'] = version<EOL>continue<EOL><DEDENT>gene['<STR_LIT>'] = old_version<EOL><DEDENT>return<EOL>

Set the correct version for each gene
        Loop over the genes in the new panel

        Args:
            new_genes(set(str)): Set with the new gene symbols
            new_panel(dict)


panel_name = panel_obj['<STR_LIT>']<EOL>panel_version = panel_obj['<STR_LIT:version>']<EOL>display_name = panel_obj.get('<STR_LIT>', panel_name)<EOL>if self.gene_panel(panel_name, panel_version):<EOL><INDENT>raise IntegrityError("<STR_LIT>"<EOL>"<STR_LIT>".format(panel_name, panel_version))<EOL><DEDENT>LOG.info("<STR_LIT>".format(<EOL>display_name, panel_version<EOL>))<EOL>result = self.panel_collection.insert_one(panel_obj)<EOL>LOG.debug("<STR_LIT>")<EOL>return result.inserted_id<EOL>

Add a gene panel to the database

            Args:
                panel_obj(dict)


if not isinstance(panel_id, ObjectId):<EOL><INDENT>panel_id = ObjectId(panel_id)<EOL><DEDENT>panel_obj = self.panel_collection.find_one({'<STR_LIT>': panel_id})<EOL>return panel_obj<EOL>

Fetch a gene panel by '_id'.

        Args:
            panel_id (str, ObjectId): str or ObjectId of document ObjectId

        Returns:
            dict: panel object or `None` if panel not found


res = self.panel_collection.delete_one({'<STR_LIT>': panel_obj['<STR_LIT>']})<EOL>LOG.warning("<STR_LIT>" % (panel_obj['<STR_LIT>'], panel_obj['<STR_LIT:version>']))<EOL>return res<EOL>

Delete a panel by '_id'.

        Args:
            panel_obj(dict)

        Returns:
            res(pymongo.DeleteResult)


def gene_panel(self, panel_id, version=None):

query = {'<STR_LIT>': panel_id}<EOL>if version:<EOL><INDENT>LOG.info("<STR_LIT>".format(<EOL>panel_id, version<EOL>))<EOL>query['<STR_LIT:version>'] = version<EOL>return self.panel_collection.find_one(query)<EOL><DEDENT>else:<EOL><INDENT>LOG.info("<STR_LIT>", panel_id)<EOL>res = self.panel_collection.find(query).sort('<STR_LIT:version>', -<NUM_LIT:1>)<EOL>if res.count() > <NUM_LIT:0>:<EOL><INDENT>return res[<NUM_LIT:0>]<EOL><DEDENT>else:<EOL><INDENT>LOG.info("<STR_LIT>")<EOL>return None<EOL><DEDENT><DEDENT>

Fetch a gene panel.

        If no panel is sent return all panels

        Args:
            panel_id (str): unique id for the panel
            version (str): version of the panel. If 'None' latest version will be returned

        Returns:
            gene_panel: gene panel object


def gene_panels(self, panel_id=None, institute_id=None, version=None):

query = {}<EOL>if panel_id:<EOL><INDENT>query['<STR_LIT>'] = panel_id<EOL>if version:<EOL><INDENT>query['<STR_LIT:version>'] = version<EOL><DEDENT><DEDENT>if institute_id:<EOL><INDENT>query['<STR_LIT>'] = institute_id<EOL><DEDENT>return self.panel_collection.find(query)<EOL>

Return all gene panels

        If panel_id return all versions of panels by that panel name

        Args:
            panel_id(str)

        Returns:
            cursor(pymongo.cursor)


return self.panel_collection.find({'<STR_LIT>' : hgnc_id })<EOL>

Get a list of gene panel objects for a hgnc_id

            Args:
                hgnc_id(int)

            Returns:
                hgnc_panels(dict): A dictionary with hgnc as keys and lists of
                                   gene panel objects as values


LOG.info("<STR_LIT>")<EOL>gene_dict = {}<EOL>for panel_info in case_obj.get('<STR_LIT>', []):<EOL><INDENT>panel_name = panel_info['<STR_LIT>']<EOL>panel_version = panel_info['<STR_LIT:version>']<EOL>panel_obj = self.gene_panel(panel_name, version=panel_version)<EOL>if not panel_obj:<EOL><INDENT>LOG.warning("<STR_LIT>".format(panel_name, panel_version))<EOL><DEDENT>for gene in panel_obj['<STR_LIT>']:<EOL><INDENT>hgnc_id = gene['<STR_LIT>']<EOL>if hgnc_id not in gene_dict:<EOL><INDENT>gene_dict[hgnc_id] = set([panel_name])<EOL>continue<EOL><DEDENT>gene_dict[hgnc_id].add(panel_name)<EOL><DEDENT><DEDENT>LOG.info("<STR_LIT>")<EOL>return gene_dict<EOL>

Fetch all gene panels and group them by gene

            Args:
                case_obj(scout.models.Case)
            Returns:
                gene_dict(dict): A dictionary with gene as keys and a set of
                                 panel names as value


def update_panel(self, panel_obj, version=None, date_obj=None):

LOG.info("<STR_LIT>", panel_obj['<STR_LIT>'])<EOL>date = panel_obj['<STR_LIT:date>']<EOL>if version:<EOL><INDENT>LOG.info("<STR_LIT>".format(<EOL>panel_obj['<STR_LIT:version>'], version))<EOL>panel_obj['<STR_LIT:version>'] = version<EOL>if date_obj:<EOL><INDENT>date = date_obj<EOL><DEDENT><DEDENT>else:<EOL><INDENT>date = date_obj or dt.datetime.now()<EOL><DEDENT>panel_obj['<STR_LIT:date>'] = date<EOL>updated_panel = self.panel_collection.find_one_and_replace(<EOL>{'<STR_LIT>': panel_obj['<STR_LIT>']},<EOL>panel_obj,<EOL>return_document=pymongo.ReturnDocument.AFTER<EOL>)<EOL>return updated_panel<EOL>

Replace a existing gene panel with a new one

        Keeps the object id

        Args:
            panel_obj(dict)
            version(float)
            date_obj(datetime.datetime)

        Returns:
            updated_panel(dict)


def add_pending(self, panel_obj, hgnc_gene, action, info=None):

valid_actions = ['<STR_LIT>', '<STR_LIT>', '<STR_LIT>']<EOL>if action not in valid_actions:<EOL><INDENT>raise ValueError("<STR_LIT>".format(action))<EOL><DEDENT>info = info or {}<EOL>pending_action = {<EOL>'<STR_LIT>': hgnc_gene['<STR_LIT>'],<EOL>'<STR_LIT:action>': action,<EOL>'<STR_LIT:info>': info,<EOL>'<STR_LIT>': hgnc_gene['<STR_LIT>'],<EOL>}<EOL>updated_panel = self.panel_collection.find_one_and_update(<EOL>{'<STR_LIT>': panel_obj['<STR_LIT>']},<EOL>{<EOL>'<STR_LIT>': {<EOL>'<STR_LIT>': pending_action<EOL>}<EOL>},<EOL>return_document=pymongo.ReturnDocument.AFTER<EOL>)<EOL>return updated_panel<EOL>

Add a pending action to a gene panel

        Store the pending actions in panel.pending

        Args:
            panel_obj(dict): The panel that is about to be updated
            hgnc_gene(dict)
            action(str): choices=['add','delete','edit']
            info(dict): additional gene info (disease_associated_transcripts,
                        reduced_penetrance, mosaicism, database_entry_version ,
                        inheritance_models, comment)

        Returns:
            updated_panel(dict):


def apply_pending(self, panel_obj, version):

updates = {}<EOL>new_panel = deepcopy(panel_obj)<EOL>new_panel['<STR_LIT>'] = []<EOL>new_panel['<STR_LIT:date>'] = dt.datetime.now()<EOL>info_fields = ['<STR_LIT>', '<STR_LIT>', '<STR_LIT>',<EOL>'<STR_LIT>', '<STR_LIT>', '<STR_LIT>']<EOL>new_genes = []<EOL>for update in panel_obj.get('<STR_LIT>', []):<EOL><INDENT>hgnc_id = update['<STR_LIT>']<EOL>if update['<STR_LIT:action>'] != '<STR_LIT>':<EOL><INDENT>updates[hgnc_id] = update<EOL>continue<EOL><DEDENT>info = update.get('<STR_LIT:info>', {})<EOL>gene_obj = {<EOL>'<STR_LIT>': hgnc_id,<EOL>'<STR_LIT>': update['<STR_LIT>']<EOL>}<EOL>for field in info_fields:<EOL><INDENT>if field in info:<EOL><INDENT>gene_obj[field] = info[field]<EOL><DEDENT><DEDENT>new_genes.append(gene_obj)<EOL><DEDENT>for gene in panel_obj['<STR_LIT>']:<EOL><INDENT>hgnc_id = gene['<STR_LIT>']<EOL>if hgnc_id not in updates:<EOL><INDENT>new_genes.append(gene)<EOL>continue<EOL><DEDENT>current_update = updates[hgnc_id]<EOL>action = current_update['<STR_LIT:action>']<EOL>info = current_update['<STR_LIT:info>']<EOL>if action == '<STR_LIT>':<EOL><INDENT>continue<EOL><DEDENT>elif action == '<STR_LIT>':<EOL><INDENT>for field in info_fields:<EOL><INDENT>if field in info:<EOL><INDENT>gene[field] = info[field]<EOL><DEDENT><DEDENT>new_genes.append(gene)<EOL><DEDENT><DEDENT>new_panel['<STR_LIT>'] = new_genes<EOL>new_panel['<STR_LIT:version>'] = float(version)<EOL>inserted_id = None<EOL>if new_panel['<STR_LIT:version>'] == panel_obj['<STR_LIT:version>']:<EOL><INDENT>result = self.panel_collection.find_one_and_replace(<EOL>{'<STR_LIT>':panel_obj['<STR_LIT>']},<EOL>new_panel,<EOL>return_document=pymongo.ReturnDocument.AFTER<EOL>)<EOL>inserted_id = result['<STR_LIT>']<EOL><DEDENT>else: <EOL><INDENT>new_panel.pop('<STR_LIT>')<EOL>panel_obj['<STR_LIT>'] = True<EOL>self.update_panel(panel_obj=panel_obj, date_obj=panel_obj['<STR_LIT:date>'])<EOL>inserted_id = self.panel_collection.insert_one(new_panel).inserted_id<EOL><DEDENT>return inserted_id<EOL>

Apply the pending changes to an existing gene panel or create a new version of the same panel.

        Args:
            panel_obj(dict): panel in database to update
            version(double): panel version to update

        Returns:
            inserted_id(str): id of updated panel or the new one


panel_ids = [panel['<STR_LIT>'] for panel in case_obj['<STR_LIT>']]<EOL>query = self.panel_collection.aggregate([<EOL>{'<STR_LIT>': {'<STR_LIT>': {'<STR_LIT>': panel_ids}}},<EOL>{'<STR_LIT>': '<STR_LIT>'},<EOL>{'<STR_LIT>': {'<STR_LIT>': '<STR_LIT>'}}<EOL>])<EOL>return set(item['<STR_LIT>'] for item in query)<EOL>

Return all the clinical gene symbols for a case.


host = app.config.get('<STR_LIT>', '<STR_LIT:localhost>')<EOL>port = app.config.get('<STR_LIT>', <NUM_LIT>)<EOL>dbname = app.config['<STR_LIT>']<EOL>log.info("<STR_LIT>", host, port, dbname)<EOL>self.setup(app.config['<STR_LIT>'])<EOL>


self.db = database<EOL>self.hgnc_collection = database.hgnc_gene<EOL>self.user_collection = database.user<EOL>self.whitelist_collection = database.whitelist<EOL>self.institute_collection = database.institute<EOL>self.event_collection = database.event<EOL>self.case_collection = database.case<EOL>self.panel_collection = database.gene_panel<EOL>self.hpo_term_collection = database.hpo_term<EOL>self.disease_term_collection = database.disease_term<EOL>self.variant_collection = database.variant<EOL>self.acmg_collection = database.acmg<EOL>self.clinvar_collection = database.clinvar<EOL>self.clinvar_submission_collection = database.clinvar_submission<EOL>self.exon_collection = database.exon<EOL>self.transcript_collection = database.transcript<EOL>


return self.db.collection_names(include_system_collections=False)<EOL>

Return all collection names

        Returns:
            collection_names(list(str))


def create_submission(self, user_id, institute_id):

submission_obj = {<EOL>'<STR_LIT:status>' : '<STR_LIT>',<EOL>'<STR_LIT>' : datetime.now(),<EOL>'<STR_LIT>' : user_id,<EOL>'<STR_LIT>' : institute_id<EOL>}<EOL>LOG.info("<STR_LIT>", user_id, institute_id)<EOL>result = self.clinvar_submission_collection.insert_one(submission_obj)<EOL>return result.inserted_id<EOL>

Create an open clinvar submission for a user and an institute
           Args:
                user_id(str): a user ID
                institute_id(str): an institute ID

           returns:
                submission(obj): an open clinvar submission object


LOG.info("<STR_LIT>", submission_id)<EOL>submission_obj = self.clinvar_submission_collection.find_one({ '<STR_LIT>' : ObjectId(submission_id)})<EOL>submission_variants = submission_obj.get('<STR_LIT>')<EOL>submission_casedata = submission_obj.get('<STR_LIT>')<EOL>submission_objects = []<EOL>if submission_variants and submission_casedata:<EOL><INDENT>submission_objects = submission_variants + submission_casedata<EOL><DEDENT>elif submission_variants:<EOL><INDENT>submission_objects = submission_variants<EOL><DEDENT>elif submission_casedata:<EOL><INDENT>submission_objects = submission_casedata<EOL><DEDENT>result = self.clinvar_collection.delete_many({'<STR_LIT>': { "<STR_LIT>": submission_objects} })<EOL>deleted_objects = result.deleted_count<EOL>result = self.clinvar_submission_collection.delete_one({'<STR_LIT>': ObjectId(submission_id)})<EOL>deleted_submissions = result.deleted_count<EOL>return deleted_objects,deleted_submissions<EOL>

Deletes a Clinvar submission object, along with all associated clinvar objects (variants and casedata)

            Args:
                submission_id(str): the ID of the submission to be deleted

            Returns:
                deleted_objects(int): the number of associated objects removed (variants and/or casedata)
                deleted_submissions(int): 1 if it's deleted, 0 if something went wrong


def get_open_clinvar_submission(self, user_id, institute_id):

LOG.info("<STR_LIT>", user_id, institute_id)<EOL>query = dict(user_id=user_id, institute_id=institute_id, status='<STR_LIT>')<EOL>submission = self.clinvar_submission_collection.find_one(query)<EOL>if submission is None:<EOL><INDENT>submission_id = self.create_submission(user_id, institute_id)<EOL>submission = self.clinvar_submission_collection.find_one({'<STR_LIT>':submission_id})<EOL><DEDENT>return submission<EOL>

Retrieve the database id of an open clinvar submission for a user and institute,
           if none is available then create a new submission and return it

           Args:
                user_id(str): a user ID
                institute_id(str): an institute ID

           Returns:
                submission(obj) : an open clinvar submission object


def update_clinvar_id(self, clinvar_id, submission_id ):

updated_submission = self.clinvar_submission_collection.find_one_and_update( {'<STR_LIT>': ObjectId(submission_id)}, { '<STR_LIT>' : {'<STR_LIT>' : clinvar_id, '<STR_LIT>': datetime.now()} }, upsert=True, return_document=pymongo.ReturnDocument.AFTER )<EOL>return updated_submission<EOL>

saves an official clinvar submission ID in a clinvar submission object

            Args:
                clinvar_id(str): a string with a format: SUB[0-9]. It is obtained from clinvar portal when starting a new submission
                submission_id(str): submission_id(str) : id of the submission to be updated

            Returns:
                updated_submission(obj): a clinvar submission object, updated


submission_obj = self.clinvar_submission_collection.find_one({'<STR_LIT>': ObjectId(submission_id)})<EOL>clinvar_subm_id = submission_obj.get('<STR_LIT>') <EOL>return clinvar_subm_id<EOL>

Returns the official Clinvar submission ID for a submission object

            Args:
                submission_id(str): submission_id(str) : id of the submission

            Returns:
                clinvar_subm_id(str): a string with a format: SUB[0-9]. It is obtained from clinvar portal when starting a new submission


def add_to_submission(self, submission_id, submission_objects):

LOG.info("<STR_LIT>", submission_id)<EOL>for var_obj in submission_objects[<NUM_LIT:0>]:<EOL><INDENT>try:<EOL><INDENT>result = self.clinvar_collection.insert_one(var_obj)<EOL>self.clinvar_submission_collection.update_one({'<STR_LIT>':submission_id}, {'<STR_LIT>': { '<STR_LIT>' : str(result.inserted_id) }}, upsert=True)<EOL><DEDENT>except pymongo.errors.DuplicateKeyError:<EOL><INDENT>LOG.error("<STR_LIT>")<EOL><DEDENT><DEDENT>if submission_objects[<NUM_LIT:1>]:<EOL><INDENT>for case_obj in submission_objects[<NUM_LIT:1>]:<EOL><INDENT>try:<EOL><INDENT>result = self.clinvar_collection.insert_one(case_obj)<EOL>self.clinvar_submission_collection.update_one({'<STR_LIT>':submission_id}, {'<STR_LIT>': { '<STR_LIT>': str(result.inserted_id)}}, upsert=True)<EOL><DEDENT>except pymongo.errors.DuplicateKeyError:<EOL><INDENT>LOG.error("<STR_LIT>")<EOL><DEDENT><DEDENT><DEDENT>updated_submission = self.clinvar_submission_collection.find_one_and_update( {'<STR_LIT>':submission_id}, { '<STR_LIT>' : {'<STR_LIT>': datetime.now()} }, return_document=pymongo.ReturnDocument.AFTER )<EOL>return updated_submission<EOL>

Adds submission_objects to clinvar collection and update the coresponding submission object with their id

            Args:
                submission_id(str) : id of the submission to be updated
                submission_objects(tuple): a tuple of 2 elements coresponding to a list of variants and a list of case data objects to add to submission

            Returns:
                updated_submission(obj): an open clinvar submission object, updated


def update_clinvar_submission_status(self, user_id, submission_id, status):

LOG.info('<STR_LIT>', submission_id)<EOL>if status == '<STR_LIT>': <EOL><INDENT>self.clinvar_submission_collection.update_many(<EOL>{'<STR_LIT>' : user_id},<EOL>{'<STR_LIT>' :<EOL>{'<STR_LIT:status>' : '<STR_LIT>', '<STR_LIT>' : datetime.now()}<EOL>}<EOL>)<EOL><DEDENT>updated_submission = self.clinvar_submission_collection.find_one_and_update(<EOL>{'<STR_LIT>'  : ObjectId(submission_id)},<EOL>{'<STR_LIT>' :<EOL>{'<STR_LIT:status>' : status, '<STR_LIT>' : datetime.now()}<EOL>},<EOL>return_document=pymongo.ReturnDocument.AFTER<EOL>)<EOL>return updated_submission<EOL>

Set a clinvar submission ID to 'closed'

            Args:
                submission_id(str): the ID of the clinvar submission to close

            Return
                updated_submission(obj): the submission object with a 'closed' status


def clinvar_submissions(self, user_id, institute_id):

LOG.info("<STR_LIT>", user_id, institute_id)<EOL>query = dict(user_id=user_id, institute_id=institute_id)<EOL>results = list(self.clinvar_submission_collection.find(query))<EOL>submissions = []<EOL>for result in results:<EOL><INDENT>submission = {}<EOL>submission['<STR_LIT>'] =  result.get('<STR_LIT>')<EOL>submission['<STR_LIT:status>'] = result.get('<STR_LIT:status>')<EOL>submission['<STR_LIT>'] = result.get('<STR_LIT>')<EOL>submission['<STR_LIT>'] = result.get('<STR_LIT>')<EOL>submission['<STR_LIT>'] = result.get('<STR_LIT>')<EOL>submission['<STR_LIT>'] = result.get('<STR_LIT>')<EOL>if '<STR_LIT>' in result:<EOL><INDENT>submission['<STR_LIT>'] = result['<STR_LIT>']<EOL><DEDENT>if result.get('<STR_LIT>'):<EOL><INDENT>submission['<STR_LIT>'] = self.clinvar_collection.find({'<STR_LIT>': { "<STR_LIT>": result['<STR_LIT>'] } })<EOL><DEDENT>if result.get('<STR_LIT>'):<EOL><INDENT>submission['<STR_LIT>'] = self.clinvar_collection.find({'<STR_LIT>' : { "<STR_LIT>": result['<STR_LIT>'] } })<EOL><DEDENT>submissions.append(submission)<EOL><DEDENT>return submissions<EOL>

Collect all open and closed clinvar submission created by a user for an institute

            Args:
                user_id(str): a user ID
                institute_id(str): an institute ID

            Returns:
                submissions(list): a list of clinvar submission objects


def clinvar_objs(self, submission_id, key_id):

<EOL>submission = self.clinvar_submission_collection.find_one({'<STR_LIT>': ObjectId(submission_id)})<EOL>if submission.get(key_id):<EOL><INDENT>clinvar_obj_ids = list(submission.get(key_id))<EOL>clinvar_objects = self.clinvar_collection.find({'<STR_LIT>' : { "<STR_LIT>": clinvar_obj_ids }})<EOL>return list(clinvar_objects)<EOL><DEDENT>else:<EOL><INDENT>return None<EOL><DEDENT>

Collects a list of objects from the clinvar collection (variants of case data) as specified by the key_id in the clinvar submission

            Args:
                submission_id(str): the _id key of a clinvar submission
                key_id(str) : either 'variant_data' or 'case_data'. It's a key in a clinvar_submission object.
                              Its value is a list of ids of clinvar objects (either variants of casedata objects)

            Returns:
                clinvar_objects(list) : a list of clinvar objects (either variants of casedata)


def delete_clinvar_object(self, object_id, object_type, submission_id):

LOG.info("<STR_LIT>", object_id, object_type)<EOL>result = '<STR_LIT>'<EOL>if object_type == '<STR_LIT>':<EOL><INDENT>self.clinvar_submission_collection.find_one_and_update( {'<STR_LIT>': ObjectId(submission_id)}, {'<STR_LIT>': {'<STR_LIT>': object_id} })<EOL>variant_object = self.clinvar_collection.find_one( {'<STR_LIT>': object_id} )<EOL>linking_id = variant_object.get("<STR_LIT>") <EOL>result = self.clinvar_collection.delete_many( {'<STR_LIT>': linking_id } )<EOL><DEDENT>else: <EOL><INDENT>result = self.clinvar_collection.delete_one( {'<STR_LIT>': object_id } )<EOL><DEDENT>self.clinvar_submission_collection.find_one_and_update( {'<STR_LIT>': ObjectId(submission_id)}, {'<STR_LIT>': {'<STR_LIT>': object_id} })<EOL>updated_submission = self.clinvar_submission_collection.find_one_and_update( {'<STR_LIT>':submission_id}, { '<STR_LIT>' : {'<STR_LIT>': datetime.now()} }, return_document=pymongo.ReturnDocument.AFTER )<EOL>return updated_submission<EOL>

Remove a variant object from clinvar database and update the relative submission object

            Args:
                object_id(str) : the id of an object to remove from clinvar_collection database collection (a variant of a case)
                object_type(str) : either 'variant_data' or 'case_data'. It's a key in the clinvar_submission object.
                submission_id(str): the _id key of a clinvar submission

            Returns:
                updated_submission(obj): an updated clinvar submission


query = dict(case_id=case_id, csv_type='<STR_LIT>')<EOL>clinvar_objs = list(self.clinvar_collection.find(query))<EOL>submitted_vars = {}<EOL>for clinvar in clinvar_objs:<EOL><INDENT>submitted_vars[clinvar.get('<STR_LIT>')] = clinvar<EOL><DEDENT>return submitted_vars<EOL>

Get all variants included in clinvar submissions for a case

        Args:
            case_id(str): a case _id

        Returns:
            submission_variants(dict): keys are variant ids and values are variant submission objects


def build_variant_query(self, query=None, category='<STR_LIT>', variant_type=['<STR_LIT>']):

query = query or {}<EOL>mongo_variant_query = {}<EOL>LOG.debug("<STR_LIT>" % query)<EOL>if query.get('<STR_LIT>'):<EOL><INDENT>mongo_variant_query['<STR_LIT>'] = {'<STR_LIT>': query['<STR_LIT>']}<EOL><DEDENT>mongo_variant_query['<STR_LIT>'] = {'<STR_LIT>': variant_type}<EOL>mongo_variant_query['<STR_LIT>'] = category<EOL>rank_score = query.get('<STR_LIT>') or <NUM_LIT:15><EOL>mongo_variant_query['<STR_LIT>'] = {'<STR_LIT>': rank_score}<EOL>LOG.debug("<STR_LIT>" % mongo_variant_query)<EOL>return mongo_variant_query<EOL>

Build a mongo query across multiple cases.
        Translate query options from a form into a complete mongo query dictionary.

        Beware that unindexed queries against a large variant collection will
        be extremely slow.

        Currently indexed query options:
            hgnc_symbols
            rank_score
            variant_type
            category

        Args:
            query(dict): A query dictionary for the database, from a query form.
            category(str): 'snv', 'sv', 'str' or 'cancer'
            variant_type(str): 'clinical' or 'research'

        Returns:
            mongo_query : A dictionary in the mongo query format.


def build_query(self, case_id, query=None, variant_ids=None, category='<STR_LIT>'):

query = query or {}<EOL>mongo_query = {}<EOL>gene_query = None<EOL>for criterion in FUNDAMENTAL_CRITERIA:<EOL><INDENT>if criterion == '<STR_LIT>':<EOL><INDENT>LOG.debug("<STR_LIT>" % case_id)<EOL>mongo_query['<STR_LIT>'] = case_id<EOL><DEDENT>elif criterion == '<STR_LIT>' and variant_ids:<EOL><INDENT>LOG.debug("<STR_LIT>" % '<STR_LIT:U+002CU+0020>'.join(variant_ids))<EOL>mongo_query['<STR_LIT>'] = {'<STR_LIT>': variant_ids}<EOL><DEDENT>elif criterion == '<STR_LIT>':<EOL><INDENT>LOG.debug("<STR_LIT>" % category)<EOL>mongo_query['<STR_LIT>'] = category<EOL><DEDENT>elif criterion == '<STR_LIT>':<EOL><INDENT>mongo_query['<STR_LIT>'] = query.get('<STR_LIT>', '<STR_LIT>')<EOL>LOG.debug("<STR_LIT>", mongo_query['<STR_LIT>'])<EOL><DEDENT>elif criterion in ['<STR_LIT>', '<STR_LIT>'] and gene_query is None:<EOL><INDENT>gene_query = self.gene_filter(query, mongo_query)<EOL><DEDENT>elif criterion == '<STR_LIT>' and query.get('<STR_LIT>'): <EOL><INDENT>self.coordinate_filter(query, mongo_query)<EOL><DEDENT>elif criterion == '<STR_LIT>' and variant_ids:<EOL><INDENT>LOG.debug("<STR_LIT>" % '<STR_LIT:U+002CU+0020>'.join(variant_ids))<EOL>mongo_query['<STR_LIT>'] = {'<STR_LIT>': variant_ids}<EOL><DEDENT><DEDENT>primary_terms = False<EOL>secondary_terms = False<EOL>for term in PRIMARY_CRITERIA:<EOL><INDENT>if query.get(term):<EOL><INDENT>primary_terms = True<EOL><DEDENT><DEDENT>for term in SECONDARY_CRITERIA:<EOL><INDENT>if query.get(term):<EOL><INDENT>secondary_terms = True<EOL><DEDENT><DEDENT>if primary_terms is True:<EOL><INDENT>clinsign_filter = self.clinsig_query(query, mongo_query)<EOL><DEDENT>if secondary_terms is True:<EOL><INDENT>secondary_filter = self.secondary_query(query, mongo_query)<EOL>if primary_terms is False:<EOL><INDENT>if gene_query:<EOL><INDENT>mongo_query['<STR_LIT>'] = [ {'<STR_LIT>': gene_query}, {'<STR_LIT>': secondary_filter}]<EOL><DEDENT>else:<EOL><INDENT>mongo_query['<STR_LIT>'] = secondary_filter<EOL><DEDENT><DEDENT>if primary_terms is True: <EOL><INDENT>if query.get('<STR_LIT>') == True:<EOL><INDENT>if gene_query:<EOL><INDENT>mongo_query['<STR_LIT>'] = [<EOL>{'<STR_LIT>': gene_query},<EOL>{<EOL>'<STR_LIT>': [<EOL>{'<STR_LIT>': secondary_filter}, clinsign_filter<EOL>]<EOL>}<EOL>]<EOL><DEDENT>else:<EOL><INDENT>mongo_query['<STR_LIT>'] = [ {'<STR_LIT>': secondary_filter}, clinsign_filter ]<EOL><DEDENT><DEDENT>else: <EOL><INDENT>secondary_filter.append(clinsign_filter)<EOL>if gene_query:<EOL><INDENT>mongo_query['<STR_LIT>'] = [ {'<STR_LIT>': gene_query}, {'<STR_LIT>': secondary_filter}]<EOL><DEDENT>else:<EOL><INDENT>mongo_query['<STR_LIT>'] = secondary_filter<EOL><DEDENT><DEDENT><DEDENT><DEDENT>elif primary_terms is True: <EOL><INDENT>mongo_query['<STR_LIT>'] = clinsign_filter['<STR_LIT>']<EOL>if gene_query:<EOL><INDENT>mongo_query['<STR_LIT>'] = [{ '<STR_LIT>': gene_query }]<EOL><DEDENT><DEDENT>elif gene_query: <EOL><INDENT>mongo_query['<STR_LIT>'] = [{ '<STR_LIT>': gene_query }]<EOL><DEDENT>LOG.info("<STR_LIT>", mongo_query)<EOL>return mongo_query<EOL>

Build a mongo query

        These are the different query options:
            {
                'genetic_models': list,
                'chrom': str,
                'thousand_genomes_frequency': float,
                'exac_frequency': float,
                'clingen_ngi': int,
                'cadd_score': float,
                'cadd_inclusive": boolean,
                'genetic_models': list(str),
                'hgnc_symbols': list,
                'region_annotations': list,
                'functional_annotations': list,
                'clinsig': list,
                'clinsig_confident_always_returned': boolean,
                'variant_type': str(('research', 'clinical')),
                'chrom': str,
                'start': int,
                'end': int,
                'svtype': list,
                'size': int,
                'size_shorter': boolean,
                'gene_panels': list(str),
                'mvl_tag": boolean,
                'decipher": boolean,
            }

        Arguments:
            case_id(str)
            query(dict): a dictionary of query filters specified by the users
            variant_ids(list(str)): A list of md5 variant ids

        Returns:
            mongo_query : A dictionary in the mongo query format


def clinsig_query(self, query, mongo_query):

LOG.debug('<STR_LIT>')<EOL>trusted_revision_level = ['<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>']<EOL>rank = []<EOL>str_rank = []<EOL>clnsig_query = {}<EOL>for item in query['<STR_LIT>']:<EOL><INDENT>rank.append(int(item))<EOL>rank.append(CLINSIG_MAP[int(item)])<EOL>str_rank.append(CLINSIG_MAP[int(item)])<EOL><DEDENT>if query.get('<STR_LIT>') == True:<EOL><INDENT>LOG.debug("<STR_LIT>")<EOL>clnsig_query = { "<STR_LIT>":<EOL>{<EOL>'<STR_LIT>': {<EOL>'<STR_LIT>' : [<EOL>{<EOL>'<STR_LIT>' : [<EOL>{'<STR_LIT:value>' : { '<STR_LIT>': rank }},<EOL>{'<STR_LIT>': { '<STR_LIT>': trusted_revision_level }}<EOL>]<EOL>},<EOL>{<EOL>'<STR_LIT>': [<EOL>{'<STR_LIT:value>' : re.compile('<STR_LIT:|>'.join(str_rank))},<EOL>{'<STR_LIT>' : re.compile('<STR_LIT:|>'.join(trusted_revision_level))}<EOL>]<EOL>}<EOL>]<EOL>}<EOL>}<EOL>}<EOL><DEDENT>else:<EOL><INDENT>LOG.debug("<STR_LIT>" %<EOL>'<STR_LIT:U+002CU+0020>'.join(str(query['<STR_LIT>'])))<EOL>clnsig_query = {<EOL>"<STR_LIT>":<EOL>{<EOL>'<STR_LIT>': {<EOL>'<STR_LIT>' : [<EOL>{ '<STR_LIT:value>' : { '<STR_LIT>': rank }},<EOL>{ '<STR_LIT:value>' : re.compile('<STR_LIT:|>'.join(str_rank)) }<EOL>]<EOL>}<EOL>}<EOL>}<EOL><DEDENT>return clnsig_query<EOL>

Add clinsig filter values to the mongo query object

            Args:
                query(dict): a dictionary of query filters specified by the users
                mongo_query(dict): the query that is going to be submitted to the database

            Returns:
                clinsig_query(dict): a dictionary with clinsig key-values


def coordinate_filter(self, query, mongo_query):

LOG.debug('<STR_LIT>')<EOL>chromosome = query['<STR_LIT>']<EOL>mongo_query['<STR_LIT>'] = chromosome<EOL>if (query.get('<STR_LIT:start>') and query.get('<STR_LIT:end>')):<EOL><INDENT>mongo_query['<STR_LIT>'] = {'<STR_LIT>': int(query['<STR_LIT:end>'])}<EOL>mongo_query['<STR_LIT:end>'] = {'<STR_LIT>': int(query['<STR_LIT:start>'])}<EOL><DEDENT>return mongo_query<EOL>

Adds genomic coordinated-related filters to the query object

        Args:
            query(dict): a dictionary of query filters specified by the users
            mongo_query(dict): the query that is going to be submitted to the database

        Returns:
            mongo_query(dict): returned object contains coordinate filters


def gene_filter(self, query, mongo_query):

LOG.debug('<STR_LIT>')<EOL>gene_query = []<EOL>if query.get('<STR_LIT>') and query.get('<STR_LIT>'):<EOL><INDENT>gene_query.append({'<STR_LIT>': {'<STR_LIT>': query['<STR_LIT>']}})<EOL>gene_query.append({'<STR_LIT>': {'<STR_LIT>': query['<STR_LIT>']}})<EOL>mongo_query['<STR_LIT>']=gene_query<EOL><DEDENT>else:<EOL><INDENT>if query.get('<STR_LIT>'):<EOL><INDENT>hgnc_symbols = query['<STR_LIT>']<EOL>mongo_query['<STR_LIT>'] = {'<STR_LIT>': hgnc_symbols}<EOL>LOG.debug("<STR_LIT>" %<EOL>'<STR_LIT:U+002CU+0020>'.join(hgnc_symbols))<EOL><DEDENT>if query.get('<STR_LIT>'):<EOL><INDENT>gene_panels = query['<STR_LIT>']<EOL>mongo_query['<STR_LIT>'] = {'<STR_LIT>': gene_panels}<EOL><DEDENT><DEDENT>return gene_query<EOL>

Adds gene-related filters to the query object

        Args:
            query(dict): a dictionary of query filters specified by the users
            mongo_query(dict): the query that is going to be submitted to the database

        Returns:
            mongo_query(dict): returned object contains gene and panel-related filters


def secondary_query(self, query, mongo_query, secondary_filter=None):

LOG.debug('<STR_LIT>')<EOL>mongo_secondary_query = []<EOL>for criterion in SECONDARY_CRITERIA:<EOL><INDENT>if not query.get(criterion):<EOL><INDENT>continue<EOL><DEDENT>if criterion == '<STR_LIT>':<EOL><INDENT>gnomad = query.get('<STR_LIT>')<EOL>if gnomad == '<STR_LIT>':<EOL><INDENT>mongo_query['<STR_LIT>'] = {'<STR_LIT>': False}<EOL><DEDENT>else:<EOL><INDENT>mongo_secondary_query.append(<EOL>{<EOL>'<STR_LIT>': [<EOL>{<EOL>'<STR_LIT>': {'<STR_LIT>': float(gnomad)}<EOL>},<EOL>{<EOL>'<STR_LIT>': {'<STR_LIT>': False}<EOL>}<EOL>]<EOL>}<EOL>)<EOL><DEDENT>LOG.debug("<STR_LIT>")<EOL><DEDENT>if criterion == '<STR_LIT>':<EOL><INDENT>local_obs = query.get('<STR_LIT>')<EOL>mongo_secondary_query.append({<EOL>'<STR_LIT>': [<EOL>{'<STR_LIT>': None},<EOL>{'<STR_LIT>': {'<STR_LIT>': local_obs + <NUM_LIT:1>}},<EOL>]<EOL>})<EOL><DEDENT>if criterion in ['<STR_LIT>', '<STR_LIT>']:<EOL><INDENT>mongo_secondary_query.append({<EOL>'<STR_LIT>': [<EOL>{ criterion : {'<STR_LIT>': False}},<EOL>{ criterion : {'<STR_LIT>': query[criterion] + <NUM_LIT:1>}},<EOL>]<EOL>})<EOL><DEDENT>if criterion == '<STR_LIT>':<EOL><INDENT>spidex_human = query['<STR_LIT>']<EOL>spidex_query_or_part = []<EOL>if ( '<STR_LIT>' in spidex_human):<EOL><INDENT>spidex_query_or_part.append({'<STR_LIT>': {'<STR_LIT>': False}})<EOL><DEDENT>for spidex_level in SPIDEX_HUMAN:<EOL><INDENT>if ( spidex_level in spidex_human ):<EOL><INDENT>spidex_query_or_part.append({'<STR_LIT>': [<EOL>{'<STR_LIT>': [{'<STR_LIT>': {'<STR_LIT>': SPIDEX_HUMAN[spidex_level]['<STR_LIT>'][<NUM_LIT:0>]}},<EOL>{'<STR_LIT>': {'<STR_LIT>': SPIDEX_HUMAN[spidex_level]['<STR_LIT>'][<NUM_LIT:1>]}}]},<EOL>{'<STR_LIT>': [{'<STR_LIT>': {'<STR_LIT>': SPIDEX_HUMAN[spidex_level]['<STR_LIT>'][<NUM_LIT:0>]}},<EOL>{'<STR_LIT>': {'<STR_LIT>': SPIDEX_HUMAN[spidex_level]['<STR_LIT>'][<NUM_LIT:1>]}} ]} ]})<EOL><DEDENT><DEDENT>mongo_secondary_query.append({'<STR_LIT>': spidex_query_or_part })<EOL><DEDENT>if criterion == '<STR_LIT>':<EOL><INDENT>cadd = query['<STR_LIT>']<EOL>cadd_query = {'<STR_LIT>': {'<STR_LIT>': float(cadd)}}<EOL>LOG.debug("<STR_LIT>", cadd)<EOL>if query.get('<STR_LIT>') is True:<EOL><INDENT>cadd_query = {<EOL>'<STR_LIT>': [<EOL>cadd_query,<EOL>{'<STR_LIT>': {'<STR_LIT>': False}}<EOL>]}<EOL>LOG.debug("<STR_LIT>")<EOL><DEDENT>mongo_secondary_query.append(cadd_query)<EOL><DEDENT>if criterion in ['<STR_LIT>', '<STR_LIT>', '<STR_LIT>']:<EOL><INDENT>criterion_values = query[criterion]<EOL>if criterion == '<STR_LIT>':<EOL><INDENT>mongo_secondary_query.append({criterion: {'<STR_LIT>': criterion_values}})<EOL><DEDENT>else:<EOL><INDENT>mongo_secondary_query.append({ '<STR_LIT:.>'.join(['<STR_LIT>', criterion[:-<NUM_LIT:1>]]) : {'<STR_LIT>': criterion_values}})<EOL><DEDENT>LOG.debug("<STR_LIT>".format(criterion, '<STR_LIT:U+002CU+0020>'.join(criterion_values)))<EOL><DEDENT>if criterion == '<STR_LIT:size>':<EOL><INDENT>size = query['<STR_LIT:size>']<EOL>size_query = {'<STR_LIT>': {'<STR_LIT>': int(size)}}<EOL>LOG.debug("<STR_LIT>" % size)<EOL>if query.get('<STR_LIT>'):<EOL><INDENT>size_query = {<EOL>'<STR_LIT>': [<EOL>{'<STR_LIT>': {'<STR_LIT>': int(size)}},<EOL>{'<STR_LIT>': {'<STR_LIT>': False}}<EOL>]}<EOL>LOG.debug("<STR_LIT>")<EOL><DEDENT>mongo_secondary_query.append(size_query)<EOL><DEDENT>if criterion == '<STR_LIT>':<EOL><INDENT>svtype = query['<STR_LIT>']<EOL>mongo_secondary_query.append({'<STR_LIT>': {'<STR_LIT>': svtype}})<EOL>LOG.debug("<STR_LIT>" %<EOL>'<STR_LIT:U+002CU+0020>'.join(svtype))<EOL><DEDENT>if criterion == '<STR_LIT>':<EOL><INDENT>mongo_query['<STR_LIT>'] = {'<STR_LIT>': True}<EOL>LOG.debug("<STR_LIT>")<EOL><DEDENT>if criterion == '<STR_LIT>':<EOL><INDENT>LOG.debug("<STR_LIT>")<EOL>mongo_secondary_query.append({<EOL>'<STR_LIT>': {<EOL>'<STR_LIT>': query.get('<STR_LIT>'),<EOL>}<EOL>})<EOL><DEDENT>if criterion == '<STR_LIT>':<EOL><INDENT>LOG.debug("<STR_LIT>")<EOL>mongo_secondary_query.append({<EOL>'<STR_LIT>': {<EOL>'<STR_LIT>': query.get('<STR_LIT>'),<EOL>}<EOL>})<EOL><DEDENT>if criterion == '<STR_LIT>':<EOL><INDENT>LOG.debug("<STR_LIT>")<EOL>mongo_secondary_query.append({<EOL>'<STR_LIT>': {<EOL>'<STR_LIT>': float(query.get('<STR_LIT>')),<EOL>}<EOL>})<EOL><DEDENT>if criterion == '<STR_LIT>':<EOL><INDENT>LOG.debug("<STR_LIT>")<EOL>mongo_secondary_query.append({<EOL>'<STR_LIT>': {<EOL>'<STR_LIT>': True,<EOL>}<EOL>})<EOL><DEDENT><DEDENT>return mongo_secondary_query<EOL>

Creates a secondary query object based on secondary parameters specified by user

            Args:
                query(dict): a dictionary of query filters specified by the users
                mongo_query(dict): the query that is going to be submitted to the database

            Returns:
                mongo_secondary_query(list): a dictionary with secondary query parameters


internal_id = institute_obj['<STR_LIT>']<EOL>display_name = institute_obj['<STR_LIT>']<EOL>if self.institute(institute_id=internal_id):<EOL><INDENT>raise IntegrityError("<STR_LIT>"<EOL>.format(display_name))<EOL><DEDENT>LOG.info("<STR_LIT>"<EOL>"<STR_LIT>".format(internal_id,<EOL>display_name))<EOL>insert_info = self.institute_collection.insert_one(institute_obj)<EOL>LOG.info("<STR_LIT>")<EOL>

Add a institute to the database

            Args:
                institute_obj(Institute)


def update_institute(self, internal_id, sanger_recipient=None, coverage_cutoff=None, <EOL>frequency_cutoff=None, display_name=None, remove_sanger=None,<EOL>phenotype_groups=None, group_abbreviations=None, add_groups=None):

add_groups = add_groups or False<EOL>institute_obj = self.institute(internal_id)<EOL>if not institute_obj:<EOL><INDENT>raise IntegrityError("<STR_LIT>".format(internal_id))<EOL><DEDENT>updates = {}<EOL>updated_institute = institute_obj<EOL>if sanger_recipient:<EOL><INDENT>user_obj = self.user(sanger_recipient)<EOL>if not user_obj:<EOL><INDENT>raise IntegrityError("<STR_LIT>".format(sanger_recipient))<EOL><DEDENT>LOG.info("<STR_LIT>".format(<EOL>internal_id, sanger_recipient))<EOL>updates['<STR_LIT>'] = {'<STR_LIT>':remove_sanger}<EOL><DEDENT>if remove_sanger:<EOL><INDENT>LOG.info("<STR_LIT>".format(<EOL>remove_sanger, internal_id))<EOL>updates['<STR_LIT>'] = {'<STR_LIT>':remove_sanger}<EOL><DEDENT>if coverage_cutoff:<EOL><INDENT>LOG.info("<STR_LIT>".format(<EOL>internal_id, coverage_cutoff))<EOL>updates['<STR_LIT>'] = {'<STR_LIT>': coverage_cutoff}<EOL><DEDENT>if frequency_cutoff:<EOL><INDENT>LOG.info("<STR_LIT>".format(<EOL>internal_id, frequency_cutoff))<EOL>if not '<STR_LIT>' in updates:<EOL><INDENT>updates['<STR_LIT>'] = {}<EOL><DEDENT>updates['<STR_LIT>'] = {'<STR_LIT>': frequency_cutoff}<EOL><DEDENT>if display_name:<EOL><INDENT>LOG.info("<STR_LIT>".format(<EOL>internal_id, display_name))<EOL>if not '<STR_LIT>' in updates:<EOL><INDENT>updates['<STR_LIT>'] = {}<EOL><DEDENT>updates['<STR_LIT>'] = {'<STR_LIT>': display_name}<EOL><DEDENT>if phenotype_groups:<EOL><INDENT>if group_abbreviations:<EOL><INDENT>group_abbreviations = list(group_abbreviations)<EOL><DEDENT>existing_groups = {}<EOL>if add_groups:<EOL><INDENT>existing_groups = institute_obj.get('<STR_LIT>', PHENOTYPE_GROUPS)<EOL><DEDENT>for i,hpo_term in enumerate(phenotype_groups):<EOL><INDENT>hpo_obj = self.hpo_term(hpo_term)<EOL>if not hpo_obj:<EOL><INDENT>raise IntegrityError("<STR_LIT>".format(hpo_term))<EOL><DEDENT>hpo_id = hpo_obj['<STR_LIT>']<EOL>description = hpo_obj['<STR_LIT:description>']<EOL>abbreviation = None<EOL>if group_abbreviations:<EOL><INDENT>abbreviation = group_abbreviations[i]<EOL><DEDENT>existing_groups[hpo_term] = {'<STR_LIT:name>': description, '<STR_LIT>':abbreviation}<EOL><DEDENT>updates['<STR_LIT>'] = {'<STR_LIT>': existing_groups}<EOL><DEDENT>if updates:<EOL><INDENT>if not '<STR_LIT>' in updates:<EOL><INDENT>updates['<STR_LIT>'] = {}<EOL><DEDENT>updates['<STR_LIT>']['<STR_LIT>'] = datetime.now()<EOL>updated_institute = self.institute_collection.find_one_and_update(<EOL>{'<STR_LIT>':internal_id}, updates, return_document = pymongo.ReturnDocument.AFTER)<EOL>LOG.info("<STR_LIT>")<EOL><DEDENT>return updated_institute<EOL>

Update the information for an institute

        Args:
            internal_id(str): The internal institute id
            sanger_recipient(str): Email adress to add for sanger order
            coverage_cutoff(int): Update coverage cutoff
            frequency_cutoff(float): New frequency cutoff
            display_name(str): New display name
            remove_sanger(str): Email adress for sanger user to be removed
            phenotype_groups(iterable(str)): New phenotype groups
            group_abbreviations(iterable(str))
            add_groups: If groups should be added. If False replace groups

        Returns:
            updated_institute(dict)


LOG.debug("<STR_LIT>".format(institute_id))<EOL>institute_obj = self.institute_collection.find_one({<EOL>'<STR_LIT>': institute_id<EOL>})<EOL>if institute_obj is None:<EOL><INDENT>LOG.debug("<STR_LIT>".format(institute_id))<EOL><DEDENT>return institute_obj<EOL>

Featch a single institute from the backend

            Args:
                institute_id(str)

            Returns:
                Institute object


query = {}<EOL>if institute_ids:<EOL><INDENT>query['<STR_LIT>'] = {'<STR_LIT>': institute_ids}<EOL><DEDENT>LOG.debug("<STR_LIT>")<EOL>return self.institute_collection.find(query)<EOL>

Fetch all institutes.

        Args:
            institute_ids(list(str))

        Returns:
            res(pymongo.Cursor)


LOG.info("<STR_LIT>", user_obj['<STR_LIT>'])<EOL>updated_user = self.user_collection.find_one_and_replace(<EOL>{'<STR_LIT>': user_obj['<STR_LIT>']},<EOL>user_obj,<EOL>return_document=pymongo.ReturnDocument.AFTER<EOL>)<EOL>return updated_user<EOL>

Update an existing user.

            Args:
                user_obj(dict)

            Returns:
                updated_user(dict)


LOG.info("<STR_LIT>", user_obj['<STR_LIT:email>'])<EOL>if not '<STR_LIT>' in user_obj:<EOL><INDENT>user_obj['<STR_LIT>'] = user_obj['<STR_LIT:email>']<EOL><DEDENT>try:<EOL><INDENT>self.user_collection.insert_one(user_obj)<EOL>LOG.debug("<STR_LIT>")<EOL><DEDENT>except DuplicateKeyError as err:<EOL><INDENT>raise IntegrityError("<STR_LIT>".format(user_obj['<STR_LIT:email>']))<EOL><DEDENT>return user_obj<EOL>

Add a user object to the database

            Args:
                user_obj(scout.models.User): A dictionary with user information

            Returns:
                user_info(dict): a copy of what was inserted


query = {}<EOL>if institute:<EOL><INDENT>LOG.info("<STR_LIT>", institute)<EOL>query = {'<STR_LIT>': {'<STR_LIT>': [institute]}}<EOL><DEDENT>else:<EOL><INDENT>LOG.info("<STR_LIT>")<EOL><DEDENT>res = self.user_collection.find(query)<EOL>return res<EOL>

Return all users from the database

            Args:
                institute(str): A institute_id

            Returns:
                res(pymongo.Cursor): A cursor with users


LOG.info("<STR_LIT>", email)<EOL>user_obj = self.user_collection.find_one({'<STR_LIT>': email})<EOL>return user_obj<EOL>

Fetch a user from the database.

            Args:
                email(str)

            Returns:
                user_obj(dict)


LOG.info("<STR_LIT>", email)<EOL>user_obj = self.user_collection.delete_one({'<STR_LIT>': email})<EOL>return user_obj<EOL>

Delete a user from the database

        Args:
            email(str)

        Returns:
            user_obj(dict)


LOG.debug('<STR_LIT>', variant_obj.get('<STR_LIT>'))<EOL>new_variant = self.variant_collection.find_one_and_replace(<EOL>{'<STR_LIT>': variant_obj['<STR_LIT>']},<EOL>variant_obj,<EOL>return_document=pymongo.ReturnDocument.AFTER<EOL>)<EOL>return new_variant<EOL>

Update one variant document in the database.

        This means that the variant in the database will be replaced by variant_obj.

        Args:
            variant_obj(dict)

        Returns:
            new_variant(dict)


def update_variant_rank(self, case_obj, variant_type='<STR_LIT>', category='<STR_LIT>'):

<EOL>variants = self.variant_collection.find({<EOL>'<STR_LIT>': case_obj['<STR_LIT>'],<EOL>'<STR_LIT>': category,<EOL>'<STR_LIT>': variant_type,<EOL>}).sort('<STR_LIT>', pymongo.DESCENDING)<EOL>LOG.info("<STR_LIT>")<EOL>requests = []<EOL>for index, var_obj in enumerate(variants):<EOL><INDENT>if len(requests) > <NUM_LIT>:<EOL><INDENT>try:<EOL><INDENT>self.variant_collection.bulk_write(requests, ordered=False)<EOL>requests = []<EOL><DEDENT>except BulkWriteError as err:<EOL><INDENT>LOG.warning("<STR_LIT>")<EOL>raise err<EOL><DEDENT><DEDENT>operation = pymongo.UpdateOne(<EOL>{'<STR_LIT>': var_obj['<STR_LIT>']},<EOL>{<EOL>'<STR_LIT>': {<EOL>'<STR_LIT>': index + <NUM_LIT:1>,<EOL>}<EOL>})<EOL>requests.append(operation)<EOL><DEDENT>try:<EOL><INDENT>self.variant_collection.bulk_write(requests, ordered=False)<EOL><DEDENT>except BulkWriteError as err:<EOL><INDENT>LOG.warning("<STR_LIT>")<EOL>raise err<EOL><DEDENT>LOG.info("<STR_LIT>")<EOL>

Updates the manual rank for all variants in a case

        Add a variant rank based on the rank score
        Whenever variants are added or removed from a case we need to update the variant rank

        Args:
            case_obj(Case)
            variant_type(str)


def update_variant_compounds(self, variant, variant_objs = None):

compound_objs = []<EOL>for compound in variant.get('<STR_LIT>', []):<EOL><INDENT>not_loaded = True<EOL>gene_objs = []<EOL>if variant_objs:<EOL><INDENT>variant_obj = variant_objs.get(compound['<STR_LIT>'])<EOL><DEDENT>else:<EOL><INDENT>variant_obj = self.variant_collection.find_one({'<STR_LIT>': compound['<STR_LIT>']})<EOL><DEDENT>if variant_obj:<EOL><INDENT>not_loaded = False<EOL>compound['<STR_LIT>'] = variant_obj['<STR_LIT>']<EOL>for gene in variant_obj.get('<STR_LIT>', []):<EOL><INDENT>gene_obj = {<EOL>'<STR_LIT>': gene['<STR_LIT>'],<EOL>'<STR_LIT>': gene.get('<STR_LIT>'),<EOL>'<STR_LIT>': gene.get('<STR_LIT>'),<EOL>'<STR_LIT>': gene.get('<STR_LIT>'),<EOL>}<EOL>gene_objs.append(gene_obj)<EOL>compound['<STR_LIT>'] = gene_objs<EOL><DEDENT><DEDENT>compound['<STR_LIT>'] = not_loaded<EOL>compound_objs.append(compound)<EOL><DEDENT>return compound_objs<EOL>

Update compounds for a variant.

        This will add all the necessary information of a variant on a compound object.

        Args:
            variant(scout.models.Variant)
            variant_objs(dict): A dictionary with _ids as keys and variant objs as values.

        Returns:
            compound_objs(list(dict)): A dictionary with updated compound objects.


LOG.debug("<STR_LIT>")<EOL>for var_id in variants:<EOL><INDENT>variant_obj = variants[var_id]<EOL>if not variant_obj.get('<STR_LIT>'):<EOL><INDENT>continue<EOL><DEDENT>updated_compounds = self.update_variant_compounds(variant_obj, variants)<EOL>variant_obj['<STR_LIT>'] = updated_compounds<EOL><DEDENT>LOG.debug("<STR_LIT>")<EOL>return variants<EOL>

Update the compounds for a set of variants.

        Args:
            variants(dict): A dictionary with _ids as keys and variant objs as values


requests = []<EOL>for var_id in bulk:<EOL><INDENT>var_obj = bulk[var_id]<EOL>if not var_obj.get('<STR_LIT>'):<EOL><INDENT>continue<EOL><DEDENT>operation = pymongo.UpdateOne(<EOL>{'<STR_LIT>': var_obj['<STR_LIT>']},<EOL>{<EOL>'<STR_LIT>': {<EOL>'<STR_LIT>': var_obj['<STR_LIT>']<EOL>}<EOL>})<EOL>requests.append(operation)<EOL><DEDENT>if not requests:<EOL><INDENT>return<EOL><DEDENT>try:<EOL><INDENT>self.variant_collection.bulk_write(requests, ordered=False)<EOL><DEDENT>except BulkWriteError as err:<EOL><INDENT>LOG.warning("<STR_LIT>")<EOL>raise err<EOL><DEDENT>

Update the compound information for a bulk of variants in the database

            Args:
                bulk(dict): {'_id': scout.models.Variant}


def update_case_compounds(self, case_obj, build='<STR_LIT>'):

case_id = case_obj['<STR_LIT>']<EOL>categories = set()<EOL>variant_types = set()<EOL>for file_type in FILE_TYPE_MAP:<EOL><INDENT>if case_obj.get('<STR_LIT>',{}).get(file_type):<EOL><INDENT>categories.add(FILE_TYPE_MAP[file_type]['<STR_LIT>'])<EOL>variant_types.add(FILE_TYPE_MAP[file_type]['<STR_LIT>'])<EOL><DEDENT><DEDENT>coding_intervals = self.get_coding_intervals(build=build)<EOL>for chrom in CHROMOSOMES:<EOL><INDENT>intervals = coding_intervals.get(chrom, IntervalTree())<EOL>for var_type in variant_types:<EOL><INDENT>for category in categories:<EOL><INDENT>LOG.info("<STR_LIT>".format(<EOL>chrom, var_type, category, case_id))<EOL>query  = {<EOL>'<STR_LIT>': var_type,<EOL>'<STR_LIT>': chrom,<EOL>}<EOL>variant_objs = self.variants(<EOL>case_id=case_id,<EOL>query=query,<EOL>category=category,<EOL>nr_of_variants=-<NUM_LIT:1>,<EOL>sort_key='<STR_LIT>'<EOL>)<EOL>bulk = {}<EOL>current_region = None<EOL>special = False<EOL>for var_obj in variant_objs:<EOL><INDENT>var_id = var_obj['<STR_LIT>']<EOL>var_chrom = var_obj['<STR_LIT>']<EOL>var_start = var_obj['<STR_LIT>']<EOL>var_end = var_obj['<STR_LIT:end>'] + <NUM_LIT:1><EOL>update_bulk = True<EOL>new_region = None<EOL>genomic_regions = coding_intervals.get(var_chrom, IntervalTree()).search(var_start, var_end)<EOL>if genomic_regions:<EOL><INDENT>new_region = genomic_regions.pop().data<EOL><DEDENT>if new_region and (new_region == current_region):<EOL><INDENT>update_bulk = False<EOL><DEDENT>current_region = new_region<EOL>if update_bulk and bulk:<EOL><INDENT>self.update_compounds(bulk)<EOL>self.update_mongo_compound_variants(bulk)<EOL>bulk = {}<EOL><DEDENT>if new_region:<EOL><INDENT>bulk[var_id] = var_obj<EOL><DEDENT><DEDENT>if not bulk:<EOL><INDENT>continue<EOL><DEDENT>self.update_compounds(bulk)<EOL>self.update_mongo_compound_variants(bulk)<EOL><DEDENT><DEDENT><DEDENT>LOG.info("<STR_LIT>")<EOL>return<EOL>

Update the compounds for a case

        Loop over all coding intervals to get coordinates for all potential compound positions.
        Update all variants within a gene with a bulk operation.


<EOL>try:<EOL><INDENT>result = self.variant_collection.insert_one(variant_obj)<EOL><DEDENT>except DuplicateKeyError as err:<EOL><INDENT>raise IntegrityError("<STR_LIT>", variant_obj['<STR_LIT>'])<EOL><DEDENT>return result<EOL>

Load a variant object

        Args:
            variant_obj(dict)

        Returns:
            inserted_id


LOG.debug("<STR_LIT>", variant_obj['<STR_LIT>'])<EOL>try:<EOL><INDENT>result = self.variant_collection.insert_one(variant_obj)<EOL><DEDENT>except DuplicateKeyError as err:<EOL><INDENT>LOG.debug("<STR_LIT>", variant_obj['<STR_LIT>'])<EOL>result = self.variant_collection.find_one_and_update(<EOL>{'<STR_LIT>': variant_obj['<STR_LIT>']},<EOL>{<EOL>'<STR_LIT>': {<EOL>'<STR_LIT>': variant_obj.get('<STR_LIT>',[])<EOL>}<EOL>}<EOL>)<EOL>variant = self.variant_collection.find_one({'<STR_LIT>': variant_obj['<STR_LIT>']})<EOL><DEDENT>return result<EOL>

Load a variant object, if the object already exists update compounds.

        Args:
            variant_obj(dict)

        Returns:
            result


if not len(variants) > <NUM_LIT:0>:<EOL><INDENT>return<EOL><DEDENT>LOG.debug("<STR_LIT>")<EOL>try:<EOL><INDENT>result = self.variant_collection.insert_many(variants)<EOL><DEDENT>except (DuplicateKeyError, BulkWriteError) as err:<EOL><INDENT>for var_obj in variants:<EOL><INDENT>try:<EOL><INDENT>self.upsert_variant(var_obj)<EOL><DEDENT>except IntegrityError as err:<EOL><INDENT>pass<EOL><DEDENT><DEDENT><DEDENT>return<EOL>

Load a bulk of variants

        Args:
            variants(iterable(scout.models.Variant))

        Returns:
            object_ids


def _load_variants(self, variants, variant_type, case_obj, individual_positions, rank_threshold,<EOL>institute_id, build=None, rank_results_header=None, vep_header=None,<EOL>category='<STR_LIT>', sample_info = None):

build = build or '<STR_LIT>'<EOL>genes = [gene_obj for gene_obj in self.all_genes(build=build)]<EOL>gene_to_panels = self.gene_to_panels(case_obj)<EOL>hgncid_to_gene = self.hgncid_to_gene(genes=genes)<EOL>genomic_intervals = self.get_coding_intervals(genes=genes)<EOL>LOG.info("<STR_LIT>".format(variant_type, category))<EOL>start_insertion = datetime.now()<EOL>start_five_thousand = datetime.now()<EOL>nr_variants = <NUM_LIT:0><EOL>nr_inserted = <NUM_LIT:0><EOL>inserted = <NUM_LIT:1><EOL>nr_bulks = <NUM_LIT:0><EOL>bulk = {}<EOL>current_region = None<EOL>for nr_variants, variant in enumerate(variants):<EOL><INDENT>mt_variant = '<STR_LIT>' in variant.CHROM<EOL>rank_score = parse_rank_score(variant.INFO.get('<STR_LIT>'), case_obj['<STR_LIT>'])<EOL>if (rank_score is None) or (rank_score > rank_threshold) or mt_variant:<EOL><INDENT>nr_inserted += <NUM_LIT:1><EOL>parsed_variant = parse_variant(<EOL>variant=variant,<EOL>case=case_obj,<EOL>variant_type=variant_type,<EOL>rank_results_header=rank_results_header,<EOL>vep_header=vep_header,<EOL>individual_positions=individual_positions,<EOL>category=category,<EOL>)<EOL>variant_obj = build_variant(<EOL>variant=parsed_variant,<EOL>institute_id=institute_id,<EOL>gene_to_panels=gene_to_panels,<EOL>hgncid_to_gene=hgncid_to_gene,<EOL>sample_info=sample_info<EOL>)<EOL>var_chrom = variant_obj['<STR_LIT>']<EOL>var_start = variant_obj['<STR_LIT>']<EOL>var_end = variant_obj['<STR_LIT:end>'] + <NUM_LIT:1><EOL>var_id = variant_obj['<STR_LIT>']<EOL>load = True<EOL>new_region = None<EOL>genomic_regions = genomic_intervals.get(var_chrom, IntervalTree()).search(var_start, var_end)<EOL>if genomic_regions:<EOL><INDENT>new_region = genomic_regions.pop().data<EOL>if new_region == current_region:<EOL><INDENT>load = False<EOL><DEDENT><DEDENT>else:<EOL><INDENT>if not current_region:<EOL><INDENT>load = False<EOL><DEDENT>if len(bulk) > <NUM_LIT>:<EOL><INDENT>load = True<EOL><DEDENT><DEDENT>if load:<EOL><INDENT>if current_region:<EOL><INDENT>self.update_compounds(bulk)<EOL><DEDENT>try:<EOL><INDENT>self.load_variant_bulk(list(bulk.values()))<EOL>nr_bulks += <NUM_LIT:1><EOL><DEDENT>except IntegrityError as error:<EOL><INDENT>pass<EOL><DEDENT>bulk = {}<EOL><DEDENT>current_region = new_region<EOL>bulk[var_id] = variant_obj<EOL>if (nr_variants != <NUM_LIT:0> and nr_variants % <NUM_LIT> == <NUM_LIT:0>):<EOL><INDENT>LOG.info("<STR_LIT>", str(nr_variants))<EOL>LOG.info("<STR_LIT>",<EOL>(datetime.now() - start_five_thousand))<EOL>start_five_thousand = datetime.now()<EOL><DEDENT>if (nr_inserted != <NUM_LIT:0> and (nr_inserted * inserted) % (<NUM_LIT:1000> * inserted) == <NUM_LIT:0>):<EOL><INDENT>LOG.info("<STR_LIT>", nr_inserted)<EOL>inserted += <NUM_LIT:1><EOL><DEDENT><DEDENT><DEDENT>if current_region:<EOL><INDENT>self.update_compounds(bulk)<EOL><DEDENT>self.load_variant_bulk(list(bulk.values()))<EOL>nr_bulks += <NUM_LIT:1><EOL>LOG.info("<STR_LIT>".format(<EOL>datetime.now() - start_insertion))<EOL>if nr_variants:<EOL><INDENT>nr_variants += <NUM_LIT:1><EOL><DEDENT>LOG.info("<STR_LIT>", nr_variants)<EOL>LOG.info("<STR_LIT>", nr_inserted)<EOL>LOG.debug("<STR_LIT>", nr_bulks)<EOL>return nr_inserted<EOL>

Perform the loading of variants

        This is the function that loops over the variants, parse them and build the variant
        objects so they are ready to be inserted into the database.


def load_variants(self, case_obj, variant_type='<STR_LIT>', category='<STR_LIT>',<EOL>rank_threshold=None, chrom=None, start=None, end=None,<EOL>gene_obj=None, build='<STR_LIT>'):

<EOL>institute_id = self.institute(institute_id=case_obj['<STR_LIT>'])['<STR_LIT>']<EOL>nr_inserted = <NUM_LIT:0><EOL>variant_file = None<EOL>if variant_type == '<STR_LIT>':<EOL><INDENT>if category == '<STR_LIT>':<EOL><INDENT>variant_file = case_obj['<STR_LIT>'].get('<STR_LIT>')<EOL><DEDENT>elif category == '<STR_LIT>':<EOL><INDENT>variant_file = case_obj['<STR_LIT>'].get('<STR_LIT>')<EOL><DEDENT>elif category == '<STR_LIT:str>':<EOL><INDENT>LOG.debug('<STR_LIT>')<EOL>variant_file = case_obj['<STR_LIT>'].get('<STR_LIT>')<EOL><DEDENT>elif category == '<STR_LIT>':<EOL><INDENT>variant_file = case_obj['<STR_LIT>'].get('<STR_LIT>')<EOL><DEDENT><DEDENT>elif variant_type == '<STR_LIT>':<EOL><INDENT>if category == '<STR_LIT>':<EOL><INDENT>variant_file = case_obj['<STR_LIT>'].get('<STR_LIT>')<EOL><DEDENT>elif category == '<STR_LIT>':<EOL><INDENT>variant_file = case_obj['<STR_LIT>'].get('<STR_LIT>')<EOL><DEDENT>elif category == '<STR_LIT>':<EOL><INDENT>variant_file = case_obj['<STR_LIT>'].get('<STR_LIT>')<EOL><DEDENT><DEDENT>if not variant_file:<EOL><INDENT>raise SyntaxError("<STR_LIT>")<EOL><DEDENT>try:<EOL><INDENT>vcf_obj = VCF(variant_file)<EOL>var = next(vcf_obj)<EOL><DEDENT>except StopIteration as err:<EOL><INDENT>LOG.warning("<STR_LIT>", variant_file)<EOL>return nr_inserted<EOL><DEDENT>vcf_obj = VCF(variant_file)<EOL>rank_results_header = parse_rank_results_header(vcf_obj)<EOL>vep_header = parse_vep_header(vcf_obj)<EOL>individual_positions = {}<EOL>for i, ind in enumerate(vcf_obj.samples):<EOL><INDENT>individual_positions[ind] = i<EOL><DEDENT>sample_info = {}<EOL>if category == '<STR_LIT>':<EOL><INDENT>for ind in case_obj['<STR_LIT>']:<EOL><INDENT>if ind['<STR_LIT>'] == <NUM_LIT:2>:<EOL><INDENT>sample_info[ind['<STR_LIT>']] = '<STR_LIT>'<EOL><DEDENT>else:<EOL><INDENT>sample_info[ind['<STR_LIT>']] = '<STR_LIT>'<EOL><DEDENT><DEDENT><DEDENT>region = "<STR_LIT>"<EOL>if gene_obj:<EOL><INDENT>chrom = gene_obj['<STR_LIT>']<EOL>start = max(gene_obj['<STR_LIT:start>'] - <NUM_LIT>, <NUM_LIT:0>)<EOL>end = gene_obj['<STR_LIT:end>'] + <NUM_LIT><EOL><DEDENT>if chrom:<EOL><INDENT>rank_threshold = rank_threshold or -<NUM_LIT:1000><EOL>if not (start and end):<EOL><INDENT>raise SyntaxError("<STR_LIT>")<EOL><DEDENT>region = "<STR_LIT>".format(chrom, start, end)<EOL><DEDENT>else:<EOL><INDENT>rank_threshold = rank_threshold or <NUM_LIT:0><EOL><DEDENT>variants = vcf_obj(region)<EOL>try:<EOL><INDENT>nr_inserted = self._load_variants(<EOL>variants=variants,<EOL>variant_type=variant_type,<EOL>case_obj=case_obj,<EOL>individual_positions=individual_positions,<EOL>rank_threshold=rank_threshold,<EOL>institute_id=institute_id,<EOL>build=build,<EOL>rank_results_header=rank_results_header,<EOL>vep_header=vep_header,<EOL>category=category,<EOL>sample_info = sample_info<EOL>)<EOL><DEDENT>except Exception as error:<EOL><INDENT>LOG.exception('<STR_LIT>')<EOL>LOG.warning("<STR_LIT>")<EOL>self.delete_variants(case_obj['<STR_LIT>'], variant_type)<EOL>raise error<EOL><DEDENT>self.update_variant_rank(case_obj, variant_type, category=category)<EOL>return nr_inserted<EOL>

Load variants for a case into scout.

        Load the variants for a specific analysis type and category into scout.
        If no region is specified, load all variants above rank score threshold
        If region or gene is specified, load all variants from that region
        disregarding variant rank(if not specified)

        Args:
            case_obj(dict): A case from the scout database
            variant_type(str): 'clinical' or 'research'. Default: 'clinical'
            category(str): 'snv', 'str' or 'sv'. Default: 'snv'
            rank_threshold(float): Only load variants above this score. Default: 0
            chrom(str): Load variants from a certain chromosome
            start(int): Specify the start position
            end(int): Specify the end position
            gene_obj(dict): A gene object from the database

        Returns:
            nr_inserted(int)


LOG.info("<STR_LIT>".format(event_id))<EOL>if not isinstance(event_id, ObjectId):<EOL><INDENT>event_id = ObjectId(event_id)<EOL><DEDENT>self.event_collection.delete_one({'<STR_LIT>': event_id})<EOL>LOG.debug("<STR_LIT>".format(event_id))<EOL>

Delete a event

            Arguments:
                event_id (str): The database key for the event


def create_event(self, institute, case, user, link, category, verb,<EOL>subject, level='<STR_LIT>', variant=None, content=None,<EOL>panel=None):

Create a Event with the parameters given.

        Arguments:
            institute (dict): A institute
            case (dict): A case
            user (dict): A User
            link (str): The url to be used in the event
            category (str): case or variant
            verb (str): What type of event
            subject (str): What is operated on
            level (str): 'specific' or 'global'. Default is 'specific'
            variant (dict): A variant
            content (str): The content of the comment

        Returns:
            event(dict): The inserted event


def events(self, institute, case=None, variant_id=None, level=None,<EOL>comments=False, panel=None):

query = {}<EOL>if variant_id:<EOL><INDENT>if comments:<EOL><INDENT>LOG.debug("<STR_LIT>".format(<EOL>institute['<STR_LIT>'], case['<STR_LIT>'], variant_id))<EOL>query = {<EOL>'<STR_LIT>': [<EOL>{<EOL>'<STR_LIT>' : '<STR_LIT>',<EOL>'<STR_LIT>' : variant_id,<EOL>'<STR_LIT>' : '<STR_LIT>',<EOL>'<STR_LIT>' : '<STR_LIT>'<EOL>},<EOL>{<EOL>'<STR_LIT>' : '<STR_LIT>',<EOL>'<STR_LIT>' : variant_id,<EOL>'<STR_LIT>' : institute['<STR_LIT>'],<EOL>'<STR_LIT>' : case['<STR_LIT>'],<EOL>'<STR_LIT>' : '<STR_LIT>',<EOL>'<STR_LIT>' : '<STR_LIT>'<EOL>}<EOL>]<EOL>}<EOL><DEDENT>else: <EOL><INDENT>query['<STR_LIT>'] = institute['<STR_LIT>']<EOL>query['<STR_LIT>'] = '<STR_LIT>'<EOL>query['<STR_LIT>'] = variant_id<EOL>query['<STR_LIT>'] = case['<STR_LIT>']<EOL><DEDENT><DEDENT>else:<EOL><INDENT>query['<STR_LIT>'] = institute['<STR_LIT>']<EOL>if panel:<EOL><INDENT>query['<STR_LIT>'] = panel<EOL><DEDENT>else:<EOL><INDENT>query['<STR_LIT>'] = '<STR_LIT>'<EOL>if case:<EOL><INDENT>query['<STR_LIT>'] = case['<STR_LIT>']<EOL><DEDENT>if comments:<EOL><INDENT>query['<STR_LIT>'] = '<STR_LIT>'<EOL><DEDENT><DEDENT><DEDENT>return self.event_collection.find(query).sort('<STR_LIT>', pymongo.DESCENDING)<EOL>

Fetch events from the database.

          Args:
            institute (dict): A institute
            case (dict): A case
            variant_id (str, optional): global variant id
            level (str, optional): restrict comments to 'specific' or 'global'
            comments (bool, optional): restrict events to include only comments
            panel (str): A panel name

          Returns:
              pymongo.Cursor: Query result


query = dict(user_id=user_obj['<STR_LIT>']) if user_obj else dict()<EOL>return self.event_collection.find(query)<EOL>


def add_phenotype(self, institute, case, user, link, hpo_term=None,<EOL>omim_term=None, is_group=False):

hpo_results = []<EOL>try:<EOL><INDENT>if hpo_term:<EOL><INDENT>hpo_results = [hpo_term]<EOL><DEDENT>elif omim_term:<EOL><INDENT>LOG.debug("<STR_LIT>".format(omim_term))<EOL>disease_obj = self.disease_term(omim_term)<EOL>if disease_obj:<EOL><INDENT>for hpo_term in disease_obj.get('<STR_LIT>', []):<EOL><INDENT>hpo_results.append(hpo_term)<EOL><DEDENT><DEDENT><DEDENT>else:<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT><DEDENT>except ValueError as e:<EOL><INDENT>raise e<EOL><DEDENT>existing_terms = set(term['<STR_LIT>'] for term in<EOL>case.get('<STR_LIT>', []))<EOL>updated_case = case<EOL>phenotype_terms = []<EOL>for hpo_term in hpo_results:<EOL><INDENT>LOG.debug("<STR_LIT>".format(hpo_term))<EOL>hpo_obj = self.hpo_term(hpo_term)<EOL>if hpo_obj is None:<EOL><INDENT>raise ValueError("<STR_LIT>" % hpo_term)<EOL><DEDENT>phenotype_id = hpo_obj['<STR_LIT>']<EOL>description = hpo_obj['<STR_LIT:description>']<EOL>if phenotype_id not in existing_terms:<EOL><INDENT>phenotype_term = dict(phenotype_id=phenotype_id, feature=description)<EOL>phenotype_terms.append(phenotype_term)<EOL>LOG.info("<STR_LIT>"<EOL>"<STR_LIT>".format(case['<STR_LIT>']))<EOL>self.create_event(<EOL>institute=institute,<EOL>case=case,<EOL>user=user,<EOL>link=link,<EOL>category='<STR_LIT>',<EOL>verb='<STR_LIT>',<EOL>subject=case['<STR_LIT>'],<EOL>content=phenotype_id<EOL>)<EOL><DEDENT>if is_group:<EOL><INDENT>updated_case = self.case_collection.find_one_and_update(<EOL>{'<STR_LIT>': case['<STR_LIT>']},<EOL>{<EOL>'<STR_LIT>': {<EOL>'<STR_LIT>': {'<STR_LIT>': phenotype_terms},<EOL>'<STR_LIT>': {'<STR_LIT>': phenotype_terms},<EOL>},<EOL>},<EOL>return_document=pymongo.ReturnDocument.AFTER<EOL>)<EOL><DEDENT>else:<EOL><INDENT>updated_case = self.case_collection.find_one_and_update(<EOL>{'<STR_LIT>': case['<STR_LIT>']},<EOL>{<EOL>'<STR_LIT>': {<EOL>'<STR_LIT>': {'<STR_LIT>': phenotype_terms},<EOL>},<EOL>},<EOL>return_document=pymongo.ReturnDocument.AFTER<EOL>)<EOL><DEDENT><DEDENT>LOG.debug("<STR_LIT>")<EOL>return updated_case<EOL>

Add a new phenotype term to a case

            Create a phenotype term and event with the given information

            Args:
                institute (Institute): A Institute object
                case (Case): Case object
                user (User): A User object
                link (str): The url to be used in the event
                hpo_term (str): A hpo id
                omim_term (str): A omim id
                is_group (bool): is phenotype term a group?


def remove_phenotype(self, institute, case, user, link, phenotype_id,<EOL>is_group=False):

LOG.info("<STR_LIT>".format(case['<STR_LIT>']))<EOL>if is_group:<EOL><INDENT>updated_case = self.case_collection.find_one_and_update(<EOL>{'<STR_LIT>': case['<STR_LIT>']},<EOL>{<EOL>'<STR_LIT>': {<EOL>'<STR_LIT>': {'<STR_LIT>': phenotype_id},<EOL>'<STR_LIT>': {'<STR_LIT>': phenotype_id},<EOL>},<EOL>},<EOL>return_document=pymongo.ReturnDocument.AFTER<EOL>)<EOL><DEDENT>else:<EOL><INDENT>updated_case = self.case_collection.find_one_and_update(<EOL>{'<STR_LIT>': case['<STR_LIT>']},<EOL>{<EOL>'<STR_LIT>': {<EOL>'<STR_LIT>': {'<STR_LIT>': phenotype_id},<EOL>},<EOL>},<EOL>return_document=pymongo.ReturnDocument.AFTER<EOL>)<EOL><DEDENT>LOG.info("<STR_LIT>""<STR_LIT>".format(phenotype_id, case['<STR_LIT>']))<EOL>self.create_event(<EOL>institute=institute,<EOL>case=case,<EOL>user=user,<EOL>link=link,<EOL>category='<STR_LIT>',<EOL>verb='<STR_LIT>',<EOL>subject=case['<STR_LIT>']<EOL>)<EOL>LOG.debug("<STR_LIT>")<EOL>return updated_case<EOL>

Remove an existing phenotype from a case

        Args:
            institute (dict): A Institute object
            case (dict): Case object
            user (dict): A User object
            link (dict): The url to be used in the event
            phenotype_id (str): A phenotype id

        Returns:
            updated_case(dict)


def comment(self, institute, case, user, link, variant=None,<EOL>content="<STR_LIT>", comment_level="<STR_LIT>"):

Add a comment to a variant or a case.

        This function will create an Event to log that a user have commented on
        a variant. If a variant id is given it will be a variant comment.
        A variant comment can be 'global' or specific. The global comments will
        be shown for this variation in all cases while the specific comments
        will only be shown for a specific case.

        Arguments:
            institute (dict): A Institute object
            case (dict): A Case object
            user (dict): A User object
            link (str): The url to be used in the event
            variant (dict): A variant object
            content (str): The content of the comment
            comment_level (str): Any one of 'specific' or 'global'.
                                 Default is 'specific'

        Return:
            comment(dict): The comment event that was inserted


def pin_variant(self, institute, case, user, link, variant):

LOG.info("<STR_LIT>".format(<EOL>variant['<STR_LIT>']))<EOL>updated_case = self.case_collection.find_one_and_update(<EOL>{'<STR_LIT>': case['<STR_LIT>']},<EOL>{'<STR_LIT>': {'<STR_LIT>': variant['<STR_LIT>']}},<EOL>return_document=pymongo.ReturnDocument.AFTER<EOL>)<EOL>kwargs = dict(<EOL>institute=institute,<EOL>case=case,<EOL>user=user,<EOL>link=link,<EOL>verb='<STR_LIT>',<EOL>variant=variant,<EOL>subject=variant['<STR_LIT>'],<EOL>)<EOL>self.create_event(category='<STR_LIT>', **kwargs)<EOL>self.create_event(category='<STR_LIT>', **kwargs)<EOL>return updated_case<EOL>

Create an event for pinning a variant.

        Arguments:
            institute (dict): A Institute object
            case (dict): Case object
            user (dict): A User object
            link (str): The url to be used in the event
            variant (dict): A variant object

        Returns:
            updated_case


def unpin_variant(self, institute, case, user, link, variant):

Create an event for unpinning a variant.

        Arguments:
            institute (dict): A Institute object
            case (dict): Case object
            user (dict): A User object
            link (str): The url to be used in the event
            variant (dict): A variant object

        Returns:
            updated_case(dict)


def order_verification(self, institute, case, user, link, variant):

Create an event for a variant verification for a variant
        and an event for a variant verification for a case

        Arguments:
            institute (dict): A Institute object
            case (dict): Case object
            user (dict): A User object
            link (str): The url to be used in the event
            variant (dict): A variant object

        Returns:
            updated_variant(dict)


def cancel_verification(self, institute, case, user, link, variant):

Create an event for cancellation of a verification of a variant

        Arguments:
            institute (dict): A Institute object
            case (dict): Case object
            user (dict): A User object
            link (str): The url to be used in the event
            variant (dict): A variant object

        Returns:
            updated_variant(dict)