diff.py 4.61 KB
Newer Older
1 2 3
#!/usr/bin/env python
# -*- coding: utf-8 -*-

Mathieu Giraud's avatar
Mathieu Giraud committed
4
from __future__ import print_function
5 6
import fuse
import sys
7
import ansi
Mathieu Giraud's avatar
Mathieu Giraud committed
8 9
import argparse

10
parser = argparse.ArgumentParser(description = 'Show differences or similarities between clones in two .vidjil files')
11
parser.add_argument('--nb', '-n', type=int, default=5, help='number of clones to display from the first file (%(default)d), 0 for all')
Mathieu Giraud's avatar
Mathieu Giraud committed
12
parser.add_argument('--nb_others', '-o', type=int, default=3, help='number of clones to display from the other files (%(default)d)')
13
parser.add_argument('--common', '-c', action='store_true', help='display common clones instead of different clones')
Mathieu Giraud's avatar
Mathieu Giraud committed
14 15 16
parser.add_argument('--verbose', '-v', action='store_true', help='verbose output')
parser.add_argument('file', nargs=2, help='''.vidjil files to be compared''')

17

18 19 20 21 22 23 24 25 26
DIFF_COLORS = {
    '+': ansi.Fore.GREEN,
    '-': ansi.Fore.RED,
    '=': ansi.Fore.BLUE,
    '?': ansi.Fore.CYAN,
}



27 28 29 30 31 32 33 34
def format_rank(rank, colorize):
    s = ''
    if rank < 1000:
        s += '#%03d' % rank
    else:
        s += '#%02dk' % (rank / 1000)

    if rank <= 5 and colorize:
35
        s = ansi.Fore.BLUE + s + ansi.Style.RESET_ALL
36 37 38 39

    return s

def format_rank_nb_reads(rank, list_nb_reads, list_total_nb_reads):
40
    s = format_rank(rank, True) + ' '
41 42 43 44
    for (nb_reads, total_nb_reads) in zip(list_nb_reads, list_total_nb_reads):
        s += ' %6d %6.2f%%' % (nb_reads, 100*float(nb_reads)/float(total_nb_reads))
    return s

45

46 47 48 49 50
def common_two_clones(self, other, seg=None):

    if seg is None:
        seg = [1000000]
    
51 52
    if not other or not self:
        return
Mathieu Giraud's avatar
Mathieu Giraud committed
53 54 55 56
    
    print("%s\t%s%s" % (self.d['id'],
                        format_rank_nb_reads(self.d['top'], self.d['reads'], seg),
                        format_rank_nb_reads(other.d['top'], other.d['reads'], seg)))
57 58


59
def diff_two_clones(self, other):
60

61
    if not other or not self:
62
        who = "+-"[not other]
Mathieu Giraud's avatar
Mathieu Giraud committed
63 64 65
        print(DIFF_COLORS[who]+who, end=' ')
        print("!!! Clone not present:", self, "/", other, end=' ')
        print(ansi.Style.RESET_ALL)
66 67 68
        return

    if not self.d['reads'] == other.d['reads']:
69 70 71 72 73 74 75 76 77 78

        ### Computes 'who' character identification
        who_minus = False
        who_plus = False
        for reads_s, reads_o in zip(self.d['reads'], other.d['reads']):
            if reads_o > reads_s:
                who_plus = True
            if reads_o < reads_s:
                who_minus = True
        who = ["=+", "-?"][who_minus][who_plus]
Mathieu Giraud's avatar
Mathieu Giraud committed
79 80 81
        print(DIFF_COLORS[who]+who, end=' ')
        print("!!! Not the same number or reads:", self.d['id'], "-", self.d['reads'], "/", other.d['reads'], end=' ')
        print(ansi.Style.RESET_ALL)
82 83


Mathieu Giraud's avatar
Mathieu Giraud committed
84
def compare(data1, data2, args):
85 86 87 88 89 90 91

    displayed_clones = []

    def print_clone_in_self_and_others(clone):
        if clone in displayed_clones:
            return

Mathieu Giraud's avatar
Mathieu Giraud committed
92
        if args.verbose:
Mathieu Giraud's avatar
Mathieu Giraud committed
93
            print(clone, end=' ')
94 95
        other_clones = []
        for o in [data1] + [data2]:
Mathieu Giraud's avatar
Mathieu Giraud committed
96
            if args.verbose:
Mathieu Giraud's avatar
Mathieu Giraud committed
97
                print("\t", end='')
98 99 100 101 102 103 104 105
            try:
                w = o[clone]
                other_clones += [w]
            except:
                continue
            if not w:
                continue

Mathieu Giraud's avatar
Mathieu Giraud committed
106
            if args.verbose:
Mathieu Giraud's avatar
Mathieu Giraud committed
107
                print(format_rank_nb_reads(w.d['top'], w.d['reads'], o.d['reads'].d['segmented']), end=' ')
108 109

        displayed_clones.append(clone)        
Mathieu Giraud's avatar
Mathieu Giraud committed
110
        if args.verbose:
Mathieu Giraud's avatar
Mathieu Giraud committed
111
            print()
112 113 114 115 116 117 118

        if args.common:
            common_two_clones(other_clones[0], other_clones[1] if len(other_clones) > 1 else None)
        else:
            diff_two_clones(other_clones[0], other_clones[1] if len(other_clones) > 1 else None)


119 120 121 122 123 124 125

    ### 

    ids_1 = [clone.d['id'] for clone in data1]
    ids_2 = [clone.d['id'] for clone in data2]
 
    ### Display clones of this ListWindows
Mathieu Giraud's avatar
Mathieu Giraud committed
126
    if args.verbose:
Mathieu Giraud's avatar
Mathieu Giraud committed
127
        print("==== Diff from %s, %d first clones" % (data1, args.nb))
128

129 130 131
    ids_1_cut = ids_1[:args.nb] if args.nb else ids_1

    for id in ids_1_cut:
132 133 134
        print_clone_in_self_and_others(id)

    ### Display clones of other ListWindows not present in this ListWindows
Mathieu Giraud's avatar
Mathieu Giraud committed
135
    if args.verbose:
Mathieu Giraud's avatar
Mathieu Giraud committed
136 137
        print()
        print("==== Other clones in the top %d of other files" % args.nb_others)
138 139 140 141 142 143 144 145 146

    for o in [ids_2]:
        for id in o[:args.nb_others]:
            if id in ids_1[:args.nb]:
                continue
            print_clone_in_self_and_others(id)



Mathieu Giraud's avatar
Mathieu Giraud committed
147 148 149 150 151 152 153 154 155
def main():

    args = parser.parse_args()
    datas = []

    for i in args.file:
        data = fuse.ListWindows()
        data.load(i, False, verbose = args.verbose)
        datas.append(data)
156
    
Mathieu Giraud's avatar
Mathieu Giraud committed
157 158 159 160 161
    data1 = datas[0]
    data2 = datas[1]

    compare(data1, data2, args)

162 163


Mathieu Giraud's avatar
Mathieu Giraud committed
164 165
if  __name__ =='__main__':
    main()
166 167 168 169