def get_top_candidates(target_cands, max_coverage=None, min_nucleotides=None, min_domains=None):
    """
    Filter BGC candidate DataFrame by different fields - coverage, nucleotide length or number of domains
    :param target_cands: DataFrame of BGC candidates
    :param max_coverage: maximum allowed coverage
    :param min_nucleotides: minimum allowed number of nucleotides
    :param min_domains: minimum number of domains
    :return: BGC candidate DataFrame filtered by given fields
    """
    top_cands = target_cands.sort_values(by='nucl_length', ascending=False)
    if max_coverage is not None:
        prev_size = len(top_cands)
        top_cands = top_cands[top_cands['coverage'] <= max_coverage]
        print('Filtered candidates by maximum coverage of {:2f}, {}/{} remained.'.format(max_coverage, len(top_cands), prev_size))
    if min_nucleotides is not None:
        prev_size = len(top_cands)
        top_cands = top_cands[top_cands['nucl_length'] >= min_nucleotides]
        print('Filtered candidates by minimum of {} nucleotides, {}/{} remained.'.format(min_nucleotides, len(top_cands), prev_size))
    if min_domains is not None:
        prev_size = len(top_cands)
        top_cands = top_cands[top_cands['num_all_domains'] >= min_domains]
        print('Filtered candidates by minimum of {} domains, {}/{} remained.'.format(min_domains, len(top_cands), prev_size))
    return top_cands