Commands: ngsfilter and alignpairedend can now be used in whichever

order
This commit is contained in:
Celine Mercier
2018-08-08 19:53:26 +02:00
parent 3fcf29a76f
commit e8dc5eb123
2 changed files with 292 additions and 122 deletions

View File

@ -8,13 +8,17 @@ from obitools3.dms.view.typed_view.view_NUC_SEQS cimport View_NUC_SEQS
from obitools3.dms.column.column cimport Column, Column_line
from obitools3.dms.capi.obiview cimport QUALITY_COLUMN, COUNT_COLUMN, NUC_SEQUENCE_COLUMN, ID_COLUMN
from obitools3.dms.capi.obitypes cimport OBI_INT, OBI_STR, index_t, OBI_QUAL
from obitools3.apps.optiongroups import addMinimalOutputOption
from obitools3.apps.optiongroups import addSequenceInputOption, addMinimalOutputOption
from obitools3.uri.decode import open_uri
from obitools3.apps.config import logger
from obitools3.align._qsassemble import QSolexaReverseAssemble
from obitools3.align._qsrassemble import QSolexaRightReverseAssemble
from obitools3.align._solexapairend import buildConsensus, buildJoinedSequence
from obitools3.dms.obiseq cimport Nuc_Seq_Stored
from obitools3.dms.obiseq cimport Nuc_Seq_Stored, Nuc_Seq
REVERSE_SEQ_COLUMN_NAME = b"REVERSE_SEQUENCE"
REVERSE_QUALITY_COLUMN_NAME = b"REVERSE_QUALITY"
__title__="Aligns paired-ended reads"
@ -22,23 +26,17 @@ __title__="Aligns paired-ended reads"
def addOptions(parser):
addSequenceInputOption(parser)
addMinimalOutputOption(parser)
group = parser.add_argument_group('obi alignpairedend specific options')
group.add_argument('-f', '--forward-reads',
action="store", dest="alignpairedend:forward",
metavar="<URI>",
default=None,
type=str,
help="URI to the forward reads")
group.add_argument('-r', '--reverse-reads',
group.add_argument('-R', '--reverse-reads',
action="store", dest="alignpairedend:reverse",
metavar="<URI>",
default=None,
type=str,
help="URI to the reverse reads")
help="URI to the reverse reads if they are in a different view than the forward reads")
# TODO
# group.add_argument('--index-file',
@ -60,7 +58,7 @@ def addOptions(parser):
la = QSolexaReverseAssemble()
ra = QSolexaRightReverseAssemble()
def buildAlignment(Nuc_Seq_Stored direct, Nuc_Seq_Stored reverse):
def buildAlignment(object direct, object reverse):
if len(direct)==0 or len(reverse)==0:
return None
@ -83,9 +81,27 @@ def buildAlignment(Nuc_Seq_Stored direct, Nuc_Seq_Stored reverse):
return ali
def alignmentIterator(View_NUC_SEQS forward, View_NUC_SEQS reverse):
for i in range(len(forward)):
ali = buildAlignment(forward[i], reverse[i])
def alignmentIterator(entries):
if type(entries) == list:
two_views = True
forward = entries[0]
reverse = entries[1]
entries_len = len(forward)
else:
two_views = False
entries_len = len(entries)
for i in range(entries_len):
if two_views:
seqF = forward[i]
seqR = reverse[i]
else:
seqF = Nuc_Seq.new_from_stored(entries[i])
seqR = Nuc_Seq(seqF.id, seqF[REVERSE_SEQ_COLUMN_NAME], quality=seqF[REVERSE_QUALITY_COLUMN_NAME])
seqF.pop(REVERSE_SEQ_COLUMN_NAME)
seqF.pop(REVERSE_QUALITY_COLUMN_NAME)
ali = buildAlignment(seqF, seqR)
if ali is None:
continue
yield ali
@ -98,22 +114,49 @@ def run(config):
logger("info", "obi alignpairedend")
# Open the input
finput = open_uri(config["alignpairedend"]["forward"])
if finput is None:
raise Exception("Could not open forward reads")
forward = finput[1]
rinput = open_uri(config["alignpairedend"]["reverse"])
if rinput is None:
raise Exception("Could not open reverse reads")
reverse = rinput[1]
if len(forward) != len(reverse):
raise Exception("Error: the number of forward and reverse reads are different")
if "index" in config["alignpairedend"]: # TODO
index = open_uri(config["alignpairedend"]["index"])
two_views = False
forward = None
reverse = None
input = None
input = open_uri(config['obi']['inputURI'])
if input is None:
raise Exception("Could not open input reads")
if input[2] != View_NUC_SEQS:
raise NotImplementedError('obi alignpairedend only works on NUC_SEQS views')
if "reverse" in config["alignpairedend"]:
two_views = True
forward = input[1]
rinput = open_uri(config["alignpairedend"]["reverse"])
if rinput is None:
raise Exception("Could not open reverse reads")
if rinput[2] != View_NUC_SEQS:
raise NotImplementedError('obi alignpairedend only works on NUC_SEQS views')
reverse = rinput[1]
if len(forward) != len(reverse):
raise Exception("Error: the number of forward and reverse reads are different")
entries = [forward, reverse]
else:
index = None
entries = input[1]
if two_views:
entries_len = len(forward)
else:
entries_len = len(entries)
# if "index" in config["alignpairedend"]: # TODO
# index = open_uri(config["alignpairedend"]["index"])
# else:
# index = None
# Open the output
output = open_uri(config['obi']['outputURI'],
@ -135,9 +178,9 @@ def run(config):
sminR = 0
# Initialize the progress bar
pb = ProgressBar(len(forward), config, seconde=5)
pb = ProgressBar(entries_len, config, seconde=5)
ba = alignmentIterator(forward, reverse)
ba = alignmentIterator(entries)
i = 0
for ali in ba:
@ -151,7 +194,13 @@ def run(config):
or (ali.score > sminR)):
buildConsensus(ali, consensus)
else:
buildJoinedSequence(ali, reverse[i], consensus)
seqF = ali[0].wrapped
if not two_views:
seq = entries[i]
seqR = Nuc_Seq(seq.id, seq[REVERSE_SEQ_COLUMN_NAME], quality = seq[REVERSE_QUALITY_COLUMN_NAME])
else:
seqR = reverse[i]
buildJoinedSequence(ali, seqR, consensus)
consensus[b"sminL"] = sminL
consensus[b"sminR"] = sminR
@ -165,7 +214,11 @@ def run(config):
i+=1
finput[0].close()
rinput[0].close()
print("\n")
print(repr(view))
input[0].close()
if two_views:
rinput[0].close()
output[0].close()