def enrich(args):
    """
    %prog enrich omgfile groups ntaxa > enriched.omg

    Enrich OMG output by pulling genes misses by OMG.
    """
    p = OptionParser(enrich.__doc__)
    p.add_option("--ghost", default=False, action="store_true",
                 help="Add ghost homologs already used [default: %default]")
    opts, args = p.parse_args(args)

    if len(args) != 3:
        sys.exit(not p.print_help())

    omgfile, groupsfile, ntaxa = args
    ntaxa = int(ntaxa)
    ghost = opts.ghost

    # Get gene pair => weight mapping
    weights = get_edges()
    info = get_info()
    # Get gene => taxon mapping
    info = dict((k, v.split()[5]) for k, v in info.items())

    groups = Grouper()

    fp = open(groupsfile)
    for row in fp:
        members = row.strip().split(",")
        groups.join(*members)

    logging.debug("Imported {0} families with {1} members.".\
                    format(len(groups), groups.num_members))

    seen = set()
    omggroups = Grouper()
    fp = open(omgfile)
    for row in fp:
        genes, idxs = row.split()
        genes = genes.split(",")
        seen.update(genes)
        omggroups.join(*genes)

    nmembers = omggroups.num_members
    logging.debug("Imported {0} OMG families with {1} members.".\
                    format(len(omggroups), nmembers))
    assert nmembers == len(seen)

    alltaxa = set(str(x) for x in range(ntaxa))
    recruited = []
    fp = open(omgfile)
    for row in fp:
        genes, idxs = row.split()
        genes = genes.split(",")
        a = genes[0]

        idxs = set(idxs.split(","))
        missing_taxa = alltaxa - idxs
        if not missing_taxa:
            print(row.rstrip())
            continue

        leftover = groups[a]
        if not ghost:
            leftover = set(leftover) - seen

        if not leftover:
            print(row.rstrip())
            continue

        leftover_sorted_by_taxa = dict((k, \
                             [x for x in leftover if info[x] == k]) \
                                for k in missing_taxa)

        #print genes, leftover
        #print leftover_sorted_by_taxa
        solutions = []
        for solution in product(*leftover_sorted_by_taxa.values()):
            score = sum(weights.get((a, b), 0) for a in solution for b in genes)
            if score == 0:
                continue
            score += sum(weights.get((a, b), 0) for a, b in combinations(solution, 2))
            solutions.append((score, solution))
            #print solution, score

        best_solution = max(solutions) if solutions else None
        if best_solution is None:
            print(row.rstrip())
            continue

        #print "best ==>", best_solution
        best_score, best_addition = best_solution
        genes.extend(best_addition)
        recruited.extend(best_addition)

        genes = sorted([(info[x], x) for x in genes])
        idxs, genes = zip(*genes)

        if ghost:  # decorate additions so it's clear that they were added
            pgenes = []
            for g in genes:
                if g in recruited and g in seen:
                    pgenes.append("|{0}|".format(g))
                else:
                    pgenes.append(g)
            genes = pgenes

        print("\t".join((",".join(genes), ",".join(idxs))))
        if not ghost:
            seen.update(best_addition)

    logging.debug("Recruited {0} new genes.".format(len(recruited)))
def enrich ( args ) : p = OptionParser ( enrich . __doc__ ) p . add_option ( "--ghost" , default = False , action = "store_true" , help = "Add ghost homologs already used [default: %default]" ) opts , args = p . parse_args ( args ) if len ( args ) != 3 : sys . exit ( not p . print_help ( ) ) omgfile , groupsfile , ntaxa = args ntaxa = int ( ntaxa ) ghost = opts . ghost weights = get_edges ( ) info = get_info ( ) info = dict ( ( k , v . split ( ) [ 5 ] ) for k , v in info . items ( ) ) groups = Grouper ( ) fp = open ( groupsfile ) for row in fp : members = row . strip ( ) . split ( "," ) groups . join ( * members ) logging . debug ( "Imported {0} families with {1} members." . format ( len ( groups ) , groups . num_members ) ) seen = set ( ) omggroups = Grouper ( ) fp = open ( omgfile ) for row in fp : genes , idxs = row . split ( ) genes = genes . split ( "," ) seen . update ( genes ) omggroups . join ( * genes ) nmembers = omggroups . num_members logging . debug ( "Imported {0} OMG families with {1} members." . format ( len ( omggroups ) , nmembers ) ) assert nmembers == len ( seen ) alltaxa = set ( str ( x ) for x in range ( ntaxa ) ) recruited = [ ] fp = open ( omgfile ) for row in fp : genes , idxs = row . split ( ) genes = genes . split ( "," ) a = genes [ 0 ] idxs = set ( idxs . split ( "," ) ) missing_taxa = alltaxa - idxs if not missing_taxa : print ( row . rstrip ( ) ) continue leftover = groups [ a ] if not ghost : leftover = set ( leftover ) - seen if not leftover : print ( row . rstrip ( ) ) continue leftover_sorted_by_taxa = dict ( ( k , [ x for x in leftover if info [ x ] == k ] ) for k in missing_taxa ) solutions = [ ] for solution in product ( * leftover_sorted_by_taxa . values ( ) ) : score = sum ( weights . get ( ( a , b ) , 0 ) for a in solution for b in genes ) if score == 0 : continue score += sum ( weights . get ( ( a , b ) , 0 ) for a , b in combinations ( solution , 2 ) ) solutions . append ( ( score , solution ) ) best_solution = max ( solutions ) if solutions else None if best_solution is None : print ( row . rstrip ( ) ) continue best_score , best_addition = best_solution genes . extend ( best_addition ) recruited . extend ( best_addition ) genes = sorted ( [ ( info [ x ] , x ) for x in genes ] ) idxs , genes = zip ( * genes ) if ghost : pgenes = [ ] for g in genes : if g in recruited and g in seen : pgenes . append ( "|{0}|" . format ( g ) ) else : pgenes . append ( g ) genes = pgenes print ( "\t" . join ( ( "," . join ( genes ) , "," . join ( idxs ) ) ) ) if not ghost : seen . update ( best_addition ) logging . debug ( "Recruited {0} new genes." . format ( len ( recruited ) ) )
%prog enrich omgfile groups ntaxa > enriched.omg

    Enrich OMG output by pulling genes misses by OMG.