<commit_before>"""Estimate resources required for processing a set of tasks.

Uses annotations provided in multitasks.py for each function to identify utilized
programs, then extracts resource requirements from the input bcbio_system file.
"""
import copy
import math
import operator

from bcbio.pipeline import config_utils
from bcbio.log import logger

def _get_resource_programs(progs, algs):
    """Retrieve programs used in analysis based on algorithm configurations.
    Handles special cases like aligners and variant callers.
    """
    checks = {"gatk-vqsr": config_utils.use_vqsr,
              "snpeff": config_utils.use_snpeff,
              "bcbio-variation-recall": config_utils.use_bcbio_variation_recall}
    parent_child = {"vardict": _parent_prefix("vardict")}
    out = set([])
    for p in progs:
        if p == "aligner":
            for alg in algs:
                aligner = alg.get("aligner")
                if aligner:
                    out.add(aligner)
        elif p in ["variantcaller", "svcaller", "peakcaller"]:
            if p == "variantcaller":
                for key, fn in parent_child.items():
                    if fn(algs):
                        out.add(key)
            for alg in algs:
                callers = alg.get(p)
                if callers:
                    if isinstance(callers, dict):
                        callers = reduce(operator.add, callers.values())
                    if isinstance(callers, (list, tuple)):
                        for x in callers:
                            out.add(x)
                    else:
                        out.add(callers)
        elif p in checks:
            if checks[p](algs):
                out.add(p)
        else:
            out.add(p)
    return sorted(list(out))

def _parent_prefix(prefix):
    """Identify a parent prefix we should add to resources if present in a caller name.
    """<commit_msg>Avoid confusing error message if aligner: true<commit_after>"""Estimate resources required for processing a set of tasks.

Uses annotations provided in multitasks.py for each function to identify utilized
programs, then extracts resource requirements from the input bcbio_system file.
"""
import copy
import math
import operator

from bcbio.pipeline import config_utils
from bcbio.log import logger

def _get_resource_programs(progs, algs):
    """Retrieve programs used in analysis based on algorithm configurations.
    Handles special cases like aligners and variant callers.
    """
    checks = {"gatk-vqsr": config_utils.use_vqsr,
              "snpeff": config_utils.use_snpeff,
              "bcbio-variation-recall": config_utils.use_bcbio_variation_recall}
    parent_child = {"vardict": _parent_prefix("vardict")}
    out = set([])
    for p in progs:
        if p == "aligner":
            for alg in algs:
                aligner = alg.get("aligner")
                if aligner and not isinstance(aligner, bool):
                    out.add(aligner)
        elif p in ["variantcaller", "svcaller", "peakcaller"]:
            if p == "variantcaller":
                for key, fn in parent_child.items():
                    if fn(algs):
                        out.add(key)
            for alg in algs:
                callers = alg.get(p)
                if callers and not isinstance(callers, bool):
                    if isinstance(callers, dict):
                        callers = reduce(operator.add, callers.values())
                    if isinstance(callers, (list, tuple)):
                        for x in callers:
                            out.add(x)
                    else:
                        out.add(callers)
        elif p in checks:
            if checks[p](algs):
                out.add(p)
        else:
            out.add(p)
    return sorted(list(out))

def _parent_prefix(prefix):
    """Identify a parent prefix we should add to resources if present in a caller name.
    """
{'fraction_non_alphanumeric': 0.08610617221234443, 'fraction_numerical': 0.0, 'mean_word_length': 1.859840232389252, 'pattern_counts': {'":': 12, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7532550', 'n_tokens_mistral': 1096, 'n_tokens_neox': 1059, 'n_words': 338}