Return count variants for a case.

        This function needs to have different behaviours based on what is asked
        for. It should allways try to give minimal information back to improve
        on speed. For example, if consequences are not asked for we will not
        build all transcripts. If not sv variants we will not build sv
        coordinates.
        So the minimal case is to just show what is asked for in the variants
        interface.

            Args:
                case_id (str): A gemini db
                skip (int): Skip first variants
                count (int): The number of variants to return
                filters (dict): A dictionary with filters. Currently this will
                look like: {
                    gene_list: [] (list of hgnc ids),
                    frequency: None (float),
                    cadd: None (float),
                    consequence: [] (list of consequences),
                    impact_severities: [] (list of consequences),
                    genetic_models [] (list of genetic models)
                }
            Returns:
                puzzle.constants.Results : Named tuple with variants and
                                           nr_of_variants

def variants(self, case_id, skip=0, count=1000, filters=None):
        """Return count variants for a case.

        This function needs to have different behaviours based on what is asked
        for. It should allways try to give minimal information back to improve
        on speed. For example, if consequences are not asked for we will not
        build all transcripts. If not sv variants we will not build sv
        coordinates.
        So the minimal case is to just show what is asked for in the variants
        interface.

            Args:
                case_id (str): A gemini db
                skip (int): Skip first variants
                count (int): The number of variants to return
                filters (dict): A dictionary with filters. Currently this will
                look like: {
                    gene_list: [] (list of hgnc ids),
                    frequency: None (float),
                    cadd: None (float),
                    consequence: [] (list of consequences),
                    impact_severities: [] (list of consequences),
                    genetic_models [] (list of genetic models)
                }
            Returns:
                puzzle.constants.Results : Named tuple with variants and
                                           nr_of_variants

        """
        filters = filters or {}
        logger.debug("Looking for variants in {0}".format(case_id))

        limit = count + skip

        gemini_query = filters.get('gemini_query') or "SELECT * from variants v"

        any_filter = False

        if filters.get('frequency'):
            frequency = filters['frequency']

            extra_info = "(v.max_aaf_all < {0} or v.max_aaf_all is"\
                         " Null)".format(frequency)
            gemini_query = self.build_gemini_query(gemini_query, extra_info)

        if filters.get('cadd'):
            cadd_score = filters['cadd']

            extra_info = "(v.cadd_scaled > {0})".format(cadd_score)
            gemini_query = self.build_gemini_query(gemini_query, extra_info)

        if filters.get('gene_ids'):
            gene_list = [gene_id.strip() for gene_id in filters['gene_ids']]

            gene_string = "v.gene in ("
            for index, gene_id in enumerate(gene_list):
                if index == 0:
                    gene_string += "'{0}'".format(gene_id)
                else:
                    gene_string += ", '{0}'".format(gene_id)
            gene_string += ")"

            gemini_query = self.build_gemini_query(gemini_query, gene_string)

        if filters.get('range'):
            chrom = filters['range']['chromosome']
            if not chrom.startswith('chr'):
                chrom = "chr{0}".format(chrom)

            range_string = "v.chrom = '{0}' AND "\
                           "((v.start BETWEEN {1} AND {2}) OR "\
                           "(v.end BETWEEN {1} AND {2}))".format(
                               chrom,
                               filters['range']['start'],
                               filters['range']['end']
                           )
            gemini_query = self.build_gemini_query(gemini_query, range_string)

        filtered_variants = self._variants(
            case_id=case_id,
            gemini_query=gemini_query,
        )

        if filters.get('consequence'):
            consequences = set(filters['consequence'])

            filtered_variants = (variant for variant in filtered_variants if
                set(variant.consequences).intersection(consequences))

        if filters.get('impact_severities'):
            severities = set([severity.strip()
                    for severity in filters['impact_severities']])
            new_filtered_variants = []
            filtered_variants = (variant for variant in filtered_variants if
                set([variant.impact_severity]).intersection(severities))

        if filters.get('sv_len'):
            sv_len = int(filters['sv_len'])
            filtered_variants = (variant for variant in filtered_variants if
                variant.sv_len >= sv_len)

        variants = []
        for index, variant_obj in enumerate(filtered_variants):
            if index >= skip:
                if index < limit:
                    variants.append(variant_obj)
                else:
                    break

        return Results(variants, len(variants))