obisort.py 1.78 KB
Newer Older
Eric Coissac committed
1 2
#!/usr/local/bin/python
'''
Aurélie Bonin committed
3 4 5 6 7 8
:py:mod:`obisort`: Sorts sequence records according to the value of a given attribute 
=====================================================================================

.. codeauthor:: Eric Coissac <eric.coissac@metabarcoding.org>

:py:mod:`obisort` sorts sequence records according to the value of a given attribute, which can be either numeric or alphanumeric.
Eric Coissac committed
9 10

'''
Eric Coissac committed
11
from obitools.format.options import addInOutputOption, sequenceWriterGenerator
Eric Coissac committed
12 13 14
from obitools.options import getOptionManager

def addSortOptions(optionManager):
Aurélie Bonin committed
15 16
    group=optionManager.add_option_group('Obisort specific options')
    group.add_option('-k','--key',
Eric Coissac committed
17 18 19 20
                             action="append", dest="key",
                             metavar="<TAG NAME>",
                             type="string",
                             default=[],
Aurélie Bonin committed
21
                             help="Attribute used to sort the sequence records.")
Eric Coissac committed
22
    
Aurélie Bonin committed
23
    group.add_option('-r','--reverse',
Eric Coissac committed
24 25
                             action="store_true", dest="reverse",
                             default=False,
Aurélie Bonin committed
26
                             help="Sorts in reverse order.")
Eric Coissac committed
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
    
def cmpGenerator(options):

    keys=options.key
    lk=len(keys)-1

    def cmpkeys(x,y,i=0):
        k=keys[i]
        c=cmp(x[k],y[k])
        if c==0 and i < lk:
            i+=1
            c=cmpkeys(x, y,i+1)
        if i==lk:
            i=0
        return c
    
    return cmpkeys

            

if __name__ == '__main__':

    optionParser = getOptionManager([addSortOptions,addInOutputOption])
    
    (options, entries) = optionParser()

    cmpk=cmpGenerator(options)
    
    seqs = [seq for seq in entries]
    seqs.sort(cmpk, reverse=options.reverse)
Eric Coissac committed
57 58 59

    writer = sequenceWriterGenerator(options)
    
Eric Coissac committed
60
    for seq in seqs:
Eric Coissac committed
61
        writer(seq)