From 3a1bdc0dbfdc76b534188b0f67f2a91c599e594c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karel=20B=C5=99inda?= Date: Wed, 12 Aug 2015 18:04:36 +0200 Subject: [PATCH 01/16] List of position mapping from a chain file, lifting a FASTQ file --- requirements.txt | 3 +- rnftools/rnfformat/ChainDict.py | 109 ++++++++++++++++++++++++++++++++ rnftools/rnfformat/RnfLifter.py | 30 +++++++++ rnftools/rnfformat/__init__.py | 3 + 4 files changed, 144 insertions(+), 1 deletion(-) create mode 100644 rnftools/rnfformat/ChainDict.py create mode 100644 rnftools/rnfformat/RnfLifter.py diff --git a/requirements.txt b/requirements.txt index 702ed01..66e2412 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,8 +1,9 @@ pysam>=0.8.3 -pbr>=1.0.1 +pbr>=1.4.0 termcolor>=1.1.0 sphinx>=1.3.0 sphinxcontrib-napoleon>=0.3.3 sphinx_rtd_theme>=0.1.8 snakemake>=3.3 smbl>=0.1.1.dev47 +numpy diff --git a/rnftools/rnfformat/ChainDict.py b/rnftools/rnfformat/ChainDict.py new file mode 100644 index 0000000..bdcdcbb --- /dev/null +++ b/rnftools/rnfformat/ChainDict.py @@ -0,0 +1,109 @@ +import numpy + +class ChainDict: + + def __init__(self, + chain_fn, + ): + + self._dict_array={} + self._dict_properties={} + + self._chain_fn=chain_fn + chrom=None + with open(chain_fn) as f: + while 1==1: + line=f.readline() + if line=="": + break + + head=line.strip() + if head=="": + continue + + print(head) + parts=head.split() + + [ + _, + score, + tName, + tSize, + tStrand, + tStart, + tEnd, + qName, + qSize, + qStrand, + qStart, + qEnd, + iid, + ]=parts + + score =int (score) + tSize = int(tSize) + tStart = int(tStart) + tEnd = int(tEnd) + qSize = int(qSize) + qStart = int(qStart) + qEnd = int(qEnd) + iid = int(iid) + + self._dict_array[tName]=numpy.empty(tSize, dtype=numpy.int32) + self._dict_properties[tName]={ + "score":score, + "tName":tName, + "tSize":tSize, + "tStrand":tStrand, + "tStart":tStart, + "tEnd":tEnd, + "qName":qName, + "qSize":qSize, + "qStrand":qStrand, + "qStart":qStart, + "qEnd":qEnd, + "id":iid, + } + + leftp = 0 + rightp= 0 + + #line=f.readline() + #if line is None: + # break + #parts=line.strip().split() + parts=[0, tStart, qStart] + while len(parts)>0: + if len(parts)==1: + parts=[int(parts[0]), tSize-tEnd, qSize-qEnd] + + if len(parts)==3: + [size, dt, dq] = map(int, parts) + for i in range(size): + self._dict_array[tName][leftp]=rightp + leftp+=1 + rightp+=1 + if dt==0 and dq>0: + + rightp+=dq + + elif dt>0: + slope=1.0*dq/dt + for i in range(dt): + self._dict_array[tName][leftp]=rightp+int(round(rightp + (i*slope))) + leftp+=1 + rightp+=dq + + #print(leftp) + parts=f.readline().strip().split() + assert leftp==tSize, "{} {} vs. {} {} (diff: {} {})".format(leftp,rightp,tSize,qSize,tSize-leftp,qSize-rightp) + assert rightp==qSize, "{} {} vs. {} {} (diff: {} {})".format(leftp,rightp,tSize,qSize,tSize-leftp,qSize-rightp) + + + def one_based_transl(chromosome, coordinate): + assert 0<=coordinate + assert coordinate<=self._dict_properties[chromosome][tSize] + if coordinate==0: + return 0 + else: + return sel._dict_array[chromosome][coordinate-1]+1 diff --git a/rnftools/rnfformat/RnfLifter.py b/rnftools/rnfformat/RnfLifter.py new file mode 100644 index 0000000..2336b85 --- /dev/null +++ b/rnftools/rnfformat/RnfLifter.py @@ -0,0 +1,30 @@ +from .chain_dict import ChainDict +import rnftools + +import re + +class RnfLifter: + + def __init__(self, + chain_fn, + fai_fn=, + ): if + self._fai_fn=fai_fn + self._chain_fn=chain_fn + + self._chain_dict=ChainDict(chain_fn) + self._fai_index=rnftools.mishmash.FaiIndex(fai_fn) + + self._reg_block=re.compile(r"(\(([0-9]+),[0-9]+,[FRN],([0-9]+),([0-9]+)\))") + + def lift_rnf_name(self,rnf_name): + for occur in self._reg_block.finditer(rnf_name): + print(occur) + return rnf_name + + def lift_fastq(self, fastq_in_fo, fastq_out_fo): + for i, line in enumerate(fastq_in_fo,start=0): + if i%4==0: + fastq_out_fo.write(self.lift_rnf_name(line)) + else + fastq_out_fo.write(line) \ No newline at end of file diff --git a/rnftools/rnfformat/__init__.py b/rnftools/rnfformat/__init__.py index 2a162ce..c4121b7 100644 --- a/rnftools/rnfformat/__init__.py +++ b/rnftools/rnfformat/__init__.py @@ -6,3 +6,6 @@ from .RnfProfile import * from .Segment import * from .Validator import * + +from .RnfLifter import * +from .ChainDict import * From 79276b2bbaebef762ace236031e4a11c7cf3cc30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karel=20B=C5=99inda?= Date: Wed, 12 Aug 2015 19:38:16 +0200 Subject: [PATCH 02/16] BAM chain-lifting --- rnftools/mishmash/FaiIndex.py | 4 +--- rnftools/rnfformat/RnfLifter.py | 21 +++++++++++++++------ 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/rnftools/mishmash/FaiIndex.py b/rnftools/mishmash/FaiIndex.py index 3c8cb8d..8a88ed8 100644 --- a/rnftools/mishmash/FaiIndex.py +++ b/rnftools/mishmash/FaiIndex.py @@ -29,15 +29,13 @@ def __init__(self, fai_fo): 5) the number of bytes in each fasta line """ - i=1 - for line in fai_fo: + for (i,line) in enumerate(fai_fo,start=1): if line.strip()!="": parts=line.split("\t") chr=parts[0] chr_len=int(parts[1]) self.dict_chr_ids[chr]=i self.dict_chr_lengths[chr]=chr_len - i+=1 self.number_of_chromosomes=len(self.dict_chr_ids) self.chr_id_width=len(str(self.number_of_chromosomes)) diff --git a/rnftools/rnfformat/RnfLifter.py b/rnftools/rnfformat/RnfLifter.py index 2336b85..8e1a1bc 100644 --- a/rnftools/rnfformat/RnfLifter.py +++ b/rnftools/rnfformat/RnfLifter.py @@ -1,5 +1,6 @@ -from .chain_dict import ChainDict +from .ChainDict import ChainDict import rnftools +import pysam import re @@ -7,8 +8,8 @@ class RnfLifter: def __init__(self, chain_fn, - fai_fn=, - ): if + fai_fn, + ): self._fai_fn=fai_fn self._chain_fn=chain_fn @@ -19,12 +20,20 @@ def __init__(self, def lift_rnf_name(self,rnf_name): for occur in self._reg_block.finditer(rnf_name): - print(occur) + pass + #print(occur) return rnf_name def lift_fastq(self, fastq_in_fo, fastq_out_fo): for i, line in enumerate(fastq_in_fo,start=0): if i%4==0: fastq_out_fo.write(self.lift_rnf_name(line)) - else - fastq_out_fo.write(line) \ No newline at end of file + else: + fastq_out_fo.write(line) + + def lift_bam(self, sam_in_fn, sam_out_fn): + infile = pysam.AlignmentFile(sam_in_fn, "r" if sam_in_fn[-4:]==".sam" else "rb") + outfile = pysam.AlignmentFile(sam_out_fn, "w" if sam_out_fn[-4:]==".sam" else "wb", template=infile) + for s in infile: + s.qname=self.lift_rnf_name(s.qname) + outfile.write(s) \ No newline at end of file From 7b377150484f50780fd4683136ca42f657e70088 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karel=20B=C5=99inda?= Date: Wed, 12 Aug 2015 21:40:20 +0200 Subject: [PATCH 03/16] rnftools liftover --- rnftools/rnfformat/RnfLifter.py | 16 ++++-- rnftools/scripts.py | 92 ++++++++++++++++++++++++++++++--- 2 files changed, 98 insertions(+), 10 deletions(-) diff --git a/rnftools/rnfformat/RnfLifter.py b/rnftools/rnfformat/RnfLifter.py index 8e1a1bc..f0bda6f 100644 --- a/rnftools/rnfformat/RnfLifter.py +++ b/rnftools/rnfformat/RnfLifter.py @@ -13,25 +13,33 @@ def __init__(self, self._fai_fn=fai_fn self._chain_fn=chain_fn - self._chain_dict=ChainDict(chain_fn) - self._fai_index=rnftools.mishmash.FaiIndex(fai_fn) + self._chain_dict=ChainDict(chain_fn=chain_fn) + with open(fai_fn) as fai_fo: + self._fai_index_fn=rnftools.mishmash.FaiIndex(fai_fo=fai_fo) self._reg_block=re.compile(r"(\(([0-9]+),[0-9]+,[FRN],([0-9]+),([0-9]+)\))") def lift_rnf_name(self,rnf_name): for occur in self._reg_block.finditer(rnf_name): + # pass #print(occur) return rnf_name - def lift_fastq(self, fastq_in_fo, fastq_out_fo): + def lift_fastq(self, + fastq_in_fo, + fastq_out_fo + ): for i, line in enumerate(fastq_in_fo,start=0): if i%4==0: fastq_out_fo.write(self.lift_rnf_name(line)) else: fastq_out_fo.write(line) - def lift_bam(self, sam_in_fn, sam_out_fn): + def lift_sam(self, + sam_in_fn, + sam_out_fn + ): infile = pysam.AlignmentFile(sam_in_fn, "r" if sam_in_fn[-4:]==".sam" else "rb") outfile = pysam.AlignmentFile(sam_out_fn, "w" if sam_out_fn[-4:]==".sam" else "wb", template=infile) for s in infile: diff --git a/rnftools/scripts.py b/rnftools/scripts.py index 8195660..7288a46 100644 --- a/rnftools/scripts.py +++ b/rnftools/scripts.py @@ -12,13 +12,15 @@ # todo: examples of usages for every subcommand (using epilog) -################################ -################################ + + +################################################################ +################################################################ ## ## RNFTOOLS SUBCOMMANDS ## -################################ -################################ +################################################################ +################################################################ def _add_shared_params(parser, unmapped_switcher=False): @@ -553,12 +555,80 @@ def add_validate_parser(subparsers,subcommand,help,description): ################################ +# LIFTOVER ################################ + + +def liftover(args): + rnf_lifter=rnftools.rnfformat.RnfLifter( + chain_fn=args.chain_fn, + fai_fn=args.fai_fn, + ) + + if args.convert_fastq: + with open(args.input_fn) as fastq_in_fn: + with open(args.output_fn,"w+") as fastq_out_fn: + rnf_lifter.lift_fastq( + fastq_in_fo=fastq_in_fo, + fastq_out_fo=fastq_out_fo, + ) + else: + rnf_lifter.lift_sam( + sam_in_fn=args.input_fn, + sam_out_fn=args.output_fn, + ) + +def add_liftover_parser(subparsers,subcommand,help,description): + parser_liftover = subparsers.add_parser(subcommand,help=help,description=description) + parser_liftover.add_argument( + '-i','--input', + type=str, + metavar='file', + dest='input_fn', + required=True, + help='Input file to be transformed (SAM/BAM unless other specified).', + ) + parser_liftover.add_argument( + '-o','--output', + type=str, + metavar='file', + dest='output_fn', + required=True, + help='Output file (SAM/BAM unless other specified).', + ) + parser_liftover.add_argument( + '-c','--chain', + type=str, + metavar='file', + dest='chain_fn', + required=True, + help='Chain format.', + ) + parser_liftover.add_argument( + '-f','--fasta-index', + type=str, + metavar='file', + dest='fai_fn', + required=True, + help='Fasta index of the reference sequence.', + ) + parser_liftover.add_argument( + '-q','--convert-fastq', + action='store_true', + dest='convert_fastq', + help='Input and output files are FASTQ files (not SAM/BAM).', + ) + parser_liftover.set_defaults(func=liftover) + + + +################################################################ +################################################################ ## ## RNFTOOLS SCRIPT ## -################################ -################################ +################################################################ +################################################################ def default_func(args): pass @@ -621,6 +691,16 @@ def rnftools_script(): description="Validate RNF names in a FASTQ file.", ) + # + # rnftools liftover + # + add_liftover_parser( + subparsers=subparsers, + subcommand="liftover", + help="Liftover genomic coordinates in RNF names.", + description="Liftover genomic coordinates in RNF names in a SAM/BAM files or in a FASTQ file.", + ) + subparsers.add_parser("",help="",description="") subparsers.add_parser("",help="---------------------[MIShmash]---------------------",description="") From d7497a3d8e3c1725540756afa38cf9dab094a2ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karel=20B=C5=99inda?= Date: Wed, 12 Aug 2015 23:18:22 +0200 Subject: [PATCH 04/16] rnftools liftover - make lifting coordinates working --- rnftools/mishmash/FaiIndex.py | 2 ++ rnftools/rnfformat/ChainDict.py | 8 ++++---- rnftools/rnfformat/RnfLifter.py | 30 ++++++++++++++++++++++++++---- 3 files changed, 32 insertions(+), 8 deletions(-) diff --git a/rnftools/mishmash/FaiIndex.py b/rnftools/mishmash/FaiIndex.py index 8a88ed8..505f616 100644 --- a/rnftools/mishmash/FaiIndex.py +++ b/rnftools/mishmash/FaiIndex.py @@ -16,6 +16,7 @@ class FaiIndex: def __init__(self, fai_fo): self.dict_chr_ids = {} + self.dict_ids_chr = {} self.dict_chr_lengths = {} # parsing FAI file @@ -35,6 +36,7 @@ def __init__(self, fai_fo): chr=parts[0] chr_len=int(parts[1]) self.dict_chr_ids[chr]=i + self.dict_ids_chr[i]=chr self.dict_chr_lengths[chr]=chr_len self.number_of_chromosomes=len(self.dict_chr_ids) diff --git a/rnftools/rnfformat/ChainDict.py b/rnftools/rnfformat/ChainDict.py index bdcdcbb..a0a2620 100644 --- a/rnftools/rnfformat/ChainDict.py +++ b/rnftools/rnfformat/ChainDict.py @@ -21,7 +21,7 @@ def __init__(self, if head=="": continue - print(head) + #print(head) parts=head.split() [ @@ -100,10 +100,10 @@ def __init__(self, assert rightp==qSize, "{} {} vs. {} {} (diff: {} {})".format(leftp,rightp,tSize,qSize,tSize-leftp,qSize-rightp) - def one_based_transl(chromosome, coordinate): + def one_based_transl(self, chromosome, coordinate): assert 0<=coordinate - assert coordinate<=self._dict_properties[chromosome][tSize] + #assert coordinate<=self._dict_properties[chromosome][tSize] if coordinate==0: return 0 else: - return sel._dict_array[chromosome][coordinate-1]+1 + return self._dict_array[chromosome][coordinate-1]+1 diff --git a/rnftools/rnfformat/RnfLifter.py b/rnftools/rnfformat/RnfLifter.py index f0bda6f..4322899 100644 --- a/rnftools/rnfformat/RnfLifter.py +++ b/rnftools/rnfformat/RnfLifter.py @@ -15,15 +15,37 @@ def __init__(self, self._chain_dict=ChainDict(chain_fn=chain_fn) with open(fai_fn) as fai_fo: - self._fai_index_fn=rnftools.mishmash.FaiIndex(fai_fo=fai_fo) + self._fai_index=rnftools.mishmash.FaiIndex(fai_fo=fai_fo) self._reg_block=re.compile(r"(\(([0-9]+),[0-9]+,[FRN],([0-9]+),([0-9]+)\))") def lift_rnf_name(self,rnf_name): + #print("=======") + #print(rnf_name) for occur in self._reg_block.finditer(rnf_name): # - pass + #pass + #print(rnf_name) #print(occur) + #print(occur.groups()) + groups=occur.groups() + chrom_id=int(groups[1]) + chrom=self._fai_index.dict_ids_chr[chrom_id] + o_left=groups[2] + o_right=groups[3] + left=int(o_left) + right=int(o_right) + if left!=0: + n_left=self._chain_dict.one_based_transl(chrom,left) + f_new_left=str(n_left).zfill(len(o_left)) + rnf_name=rnf_name.replace(",{},".format(o_left),",{},".format(f_new_left)) + #print("l",o_left,f_new_left) + if right!=0: + new_right=self._chain_dict.one_based_transl(chrom,right) + f_new_right=str(n_right).zfill(len(o_right)) + rnf_name=rnf_name.replace(",{})".format(o_right),",{})".format(f_new_right)) + #print("r",o_right,f_new_right) + #print(rnf_name) return rnf_name def lift_fastq(self, @@ -40,8 +62,8 @@ def lift_sam(self, sam_in_fn, sam_out_fn ): - infile = pysam.AlignmentFile(sam_in_fn, "r" if sam_in_fn[-4:]==".sam" else "rb") - outfile = pysam.AlignmentFile(sam_out_fn, "w" if sam_out_fn[-4:]==".sam" else "wb", template=infile) + infile = pysam.AlignmentFile(sam_in_fn, "rb" if sam_in_fn[-4:]==".bam" else "r") + outfile = pysam.AlignmentFile(sam_out_fn, "wb" if sam_out_fn[-4:]==".bam" else "wh", template=infile) for s in infile: s.qname=self.lift_rnf_name(s.qname) outfile.write(s) \ No newline at end of file From f72c5696914006e4b9b18c4c2166a1a25bd375ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karel=20B=C5=99inda?= Date: Thu, 13 Aug 2015 21:36:03 +0200 Subject: [PATCH 05/16] rnftools.utils --- rnftools/__init__.py | 2 + rnftools/mishmash/CuReSim.py | 8 ++-- rnftools/mishmash/DwgSim.py | 3 +- rnftools/mishmash/FaiIndex.py | 46 ---------------------- rnftools/{rnfformat => utils}/ChainDict.py | 0 rnftools/utils/FaIdx.py | 45 +++++++++++++++++++++ rnftools/utils/__init__.py | 2 + 7 files changed, 54 insertions(+), 52 deletions(-) delete mode 100644 rnftools/mishmash/FaiIndex.py rename rnftools/{rnfformat => utils}/ChainDict.py (100%) create mode 100644 rnftools/utils/FaIdx.py create mode 100644 rnftools/utils/__init__.py diff --git a/rnftools/__init__.py b/rnftools/__init__.py index 6d0fe0d..4822496 100644 --- a/rnftools/__init__.py +++ b/rnftools/__init__.py @@ -11,6 +11,8 @@ import rnftools.mishmash import rnftools.lavender import rnftools.rnfformat +import rnftools.utils + import os # version detection diff --git a/rnftools/mishmash/CuReSim.py b/rnftools/mishmash/CuReSim.py index bb368ec..cdead6d 100644 --- a/rnftools/mishmash/CuReSim.py +++ b/rnftools/mishmash/CuReSim.py @@ -121,9 +121,9 @@ def recode_curesim_reads( """Recode CuReSim output FASTQ file to the RNF-compatible output FASTQ file. Args: - curesim_fastq_fo (file): File object of CuReSim FASTQ file. - fastq_rnf_fo (file): File object of RNF FASTQ. - fai_fo (file): File object for FAI file of the reference genome. + curesim_fastq_fo (file object): File object of CuReSim FASTQ file. + fastq_rnf_fo (file object): File object of RNF FASTQ. + fai_fo (file object): File object for FAI file of the reference genome. genome_id (int): RNF genome ID to be used. number_of_read_tuples (int): Expected number of read tuples (to estimate number of digits in RNF). @@ -149,7 +149,7 @@ def recode_curesim_reads( max_seq_len=0 - fai_index = FaiIndex(fai_fo=fai_fo) + fai_index = rnftools.utils.FaIdx(fai_fo=fai_fo) read_tuple_id_width=len(format(number_of_read_tuples,'x')) fq_creator=rnftools.rnfformat.FqCreator( diff --git a/rnftools/mishmash/DwgSim.py b/rnftools/mishmash/DwgSim.py index 301d647..163a6b4 100644 --- a/rnftools/mishmash/DwgSim.py +++ b/rnftools/mishmash/DwgSim.py @@ -1,6 +1,5 @@ import rnftools from .Source import * -from .FaiIndex import * import os import smbl @@ -223,7 +222,7 @@ def recode_dwgsim_reads( 14) read number (unique within a given contig/chromosome) """ - fai_index = FaiIndex(fai_fo=fai_fo) + fai_index = rnftools.utils.FaIdx(fai_fo=fai_fo) read_tuple_id_width=len(format(number_of_read_tuples,'x')) # parsing FQ file diff --git a/rnftools/mishmash/FaiIndex.py b/rnftools/mishmash/FaiIndex.py deleted file mode 100644 index 505f616..0000000 --- a/rnftools/mishmash/FaiIndex.py +++ /dev/null @@ -1,46 +0,0 @@ - - -class FaiIndex: - """Class for loading FASTA indexes. - - Args: - fai_file (file): FASTA index (FAI) file to be loaded. - - Attributes: - self.dict_chr_ids (dict): FASTA IDs of chromosomes (chr -> id). - self.dict_chr_lengths (dict): Lengths of chromosomes (chr -> length). - number_of_chromosomes (int): Number of chromosomes in the corresponding FASTA file. - chr_id_width (int): Length of strings representing chromosome number. - coor_width (int): Length of string representing coordinates. - """ - - def __init__(self, fai_fo): - self.dict_chr_ids = {} - self.dict_ids_chr = {} - self.dict_chr_lengths = {} - - # parsing FAI file - """ - FAI format - - 1) the name of the sequence - 2) the length of the sequence - 3) the offset of the first base in the file - 4) the number of bases in each fasta line - 5) the number of bytes in each fasta line - """ - - for (i,line) in enumerate(fai_fo,start=1): - if line.strip()!="": - parts=line.split("\t") - chr=parts[0] - chr_len=int(parts[1]) - self.dict_chr_ids[chr]=i - self.dict_ids_chr[i]=chr - self.dict_chr_lengths[chr]=chr_len - - self.number_of_chromosomes=len(self.dict_chr_ids) - self.chr_id_width=len(str(self.number_of_chromosomes)) - self.coor_width=len(str(max(self.dict_chr_lengths.values()))) - - diff --git a/rnftools/rnfformat/ChainDict.py b/rnftools/utils/ChainDict.py similarity index 100% rename from rnftools/rnfformat/ChainDict.py rename to rnftools/utils/ChainDict.py diff --git a/rnftools/utils/FaIdx.py b/rnftools/utils/FaIdx.py new file mode 100644 index 0000000..e4cf2fa --- /dev/null +++ b/rnftools/utils/FaIdx.py @@ -0,0 +1,45 @@ + + +class FaiIndex: + """Class for loading FASTA indexes. + + Args: + fai_fo (file object): FASTA index (FAI) file to be loaded. + + Attributes: + self.dict_chr_ids (dict): FASTA IDs of chromosomes (chr -> id). + self.dict_chr_lengths (dict): Lengths of chromosomes (chr -> length). + number_of_chromosomes (int): Number of chromosomes in the corresponding FASTA file. + chr_id_width (int): Length of strings representing chromosome number. + coor_width (int): Length of string representing coordinates. + """ + + def __init__(self, fai_fo): + self.dict_chr_ids = {} + self.dict_ids_chr = {} + self.dict_chr_lengths = {} + + if fai_fo is not None: + # parsing FAI file + """ + FAI format + + 1) the name of the sequence + 2) the length of the sequence + 3) the offset of the first base in the file + 4) the number of bases in each fasta line + 5) the number of bytes in each fasta line + """ + + for (i,line) in enumerate(fai_fo,start=1): + if line.strip()!="": + parts=line.split("\t") + chr=parts[0] + chr_len=int(parts[1]) + self.dict_chr_ids[chr]=i + self.dict_ids_chr[i]=chr + self.dict_chr_lengths[chr]=chr_len + + self.number_of_chromosomes=len(self.dict_chr_ids) + self.chr_id_width=len(str(self.number_of_chromosomes)) + self.coor_width=len(str(max(self.dict_chr_lengths.values()))) diff --git a/rnftools/utils/__init__.py b/rnftools/utils/__init__.py new file mode 100644 index 0000000..7adea24 --- /dev/null +++ b/rnftools/utils/__init__.py @@ -0,0 +1,2 @@ +from .ChainDict import * +from .FaIdx import * From baeb8b38be4e62d34f97672894208ed4d1f85bac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karel=20B=C5=99inda?= Date: Thu, 13 Aug 2015 22:03:56 +0200 Subject: [PATCH 06/16] Minifix --- rnftools/mishmash/Source.py | 3 +-- rnftools/mishmash/WgSim.py | 3 +-- rnftools/utils/FaIdx.py | 4 +--- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/rnftools/mishmash/Source.py b/rnftools/mishmash/Source.py index 2aa30ac..0413f5c 100644 --- a/rnftools/mishmash/Source.py +++ b/rnftools/mishmash/Source.py @@ -7,7 +7,6 @@ import pysam import rnftools -from .FaiIndex import * class Source(object): """ Abstract class for a genome from which read tuples are simulated. @@ -166,7 +165,7 @@ def recode_sam_reads( NotImplementedError """ - fai_index = FaiIndex(fai_fo) + fai_index = rnftools.utils.FaIdx(fai_fo) #last_read_tuple_name=[] read_tuple_id_width=len(format(number_of_read_tuples,'x')) fq_creator=rnftools.rnfformat.FqCreator( diff --git a/rnftools/mishmash/WgSim.py b/rnftools/mishmash/WgSim.py index 512d6c5..aa1ecc2 100644 --- a/rnftools/mishmash/WgSim.py +++ b/rnftools/mishmash/WgSim.py @@ -1,6 +1,5 @@ import rnftools from .Source import * -from .FaiIndex import * import os import smbl @@ -208,7 +207,7 @@ def recode_wgsim_reads( 11) pair """ - fai_index = FaiIndex(fai_fo) + fai_index = rnftools.utils.FaIdx(fai_fo) read_tuple_id_width=len(format(number_of_read_tuples,'x')) last_read_tuple_name=None diff --git a/rnftools/utils/FaIdx.py b/rnftools/utils/FaIdx.py index e4cf2fa..ed3d0ef 100644 --- a/rnftools/utils/FaIdx.py +++ b/rnftools/utils/FaIdx.py @@ -1,6 +1,4 @@ - - -class FaiIndex: +class FaIdx: """Class for loading FASTA indexes. Args: From 1af8e46f47af360dd82032843d8ea80e6ee99238 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karel=20B=C5=99inda?= Date: Thu, 13 Aug 2015 22:33:51 +0200 Subject: [PATCH 07/16] View TODOs --- view_todos.sh | 4 ++++ 1 file changed, 4 insertions(+) create mode 100755 view_todos.sh diff --git a/view_todos.sh b/view_todos.sh new file mode 100755 index 0000000..a863d9d --- /dev/null +++ b/view_todos.sh @@ -0,0 +1,4 @@ +#! /usr/bin/env bash + +find rnftools -name "*.py" -type f | xargs grep TODO +find rnftools -name "*.py" -type f | xargs grep FIXME From e2bfc1f6460a0ab6c25454ca524a169ee5319c33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karel=20B=C5=99inda?= Date: Thu, 13 Aug 2015 23:06:58 +0200 Subject: [PATCH 08/16] Coordinates liftover partially reimplemented - better memory efficiency (sampled list of intervals instead of full translated array) - support for more chromosomes --- requirements.txt | 1 - rnftools/rnfformat/RnfLifter.py | 20 ++---- rnftools/utils/Chain.py | 112 ++++++++++++++++++++++++++++++++ rnftools/utils/ChainDict.py | 109 ------------------------------- rnftools/utils/ChainSequence.py | 81 +++++++++++++++++++++++ rnftools/utils/__init__.py | 2 +- 6 files changed, 199 insertions(+), 126 deletions(-) create mode 100644 rnftools/utils/Chain.py delete mode 100644 rnftools/utils/ChainDict.py create mode 100644 rnftools/utils/ChainSequence.py diff --git a/requirements.txt b/requirements.txt index 66e2412..8e2a551 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,4 +6,3 @@ sphinxcontrib-napoleon>=0.3.3 sphinx_rtd_theme>=0.1.8 snakemake>=3.3 smbl>=0.1.1.dev47 -numpy diff --git a/rnftools/rnfformat/RnfLifter.py b/rnftools/rnfformat/RnfLifter.py index 4322899..b033644 100644 --- a/rnftools/rnfformat/RnfLifter.py +++ b/rnftools/rnfformat/RnfLifter.py @@ -1,4 +1,3 @@ -from .ChainDict import ChainDict import rnftools import pysam @@ -13,21 +12,15 @@ def __init__(self, self._fai_fn=fai_fn self._chain_fn=chain_fn - self._chain_dict=ChainDict(chain_fn=chain_fn) + with open(chain_fn) as chain_fo: + self._chain=rnftools.utils.Chain(chain_fo=chain_fo) with open(fai_fn) as fai_fo: - self._fai_index=rnftools.mishmash.FaiIndex(fai_fo=fai_fo) + self._fai_index=rnftools.utils.FaiIndex(fai_fo=fai_fo) self._reg_block=re.compile(r"(\(([0-9]+),[0-9]+,[FRN],([0-9]+),([0-9]+)\))") def lift_rnf_name(self,rnf_name): - #print("=======") - #print(rnf_name) for occur in self._reg_block.finditer(rnf_name): - # - #pass - #print(rnf_name) - #print(occur) - #print(occur.groups()) groups=occur.groups() chrom_id=int(groups[1]) chrom=self._fai_index.dict_ids_chr[chrom_id] @@ -36,16 +29,13 @@ def lift_rnf_name(self,rnf_name): left=int(o_left) right=int(o_right) if left!=0: - n_left=self._chain_dict.one_based_transl(chrom,left) + n_left=self._chain.one_based_transl(chrom,left) f_new_left=str(n_left).zfill(len(o_left)) rnf_name=rnf_name.replace(",{},".format(o_left),",{},".format(f_new_left)) - #print("l",o_left,f_new_left) if right!=0: - new_right=self._chain_dict.one_based_transl(chrom,right) + new_right=self._chain.one_based_transl(chrom,right) f_new_right=str(n_right).zfill(len(o_right)) rnf_name=rnf_name.replace(",{})".format(o_right),",{})".format(f_new_right)) - #print("r",o_right,f_new_right) - #print(rnf_name) return rnf_name def lift_fastq(self, diff --git a/rnftools/utils/Chain.py b/rnftools/utils/Chain.py new file mode 100644 index 0000000..2d4a8a6 --- /dev/null +++ b/rnftools/utils/Chain.py @@ -0,0 +1,112 @@ +import collections +from .ChainSequence import ChainSequence + +class Chain: + + def __init__(self, + chain_fo, + sampling_step=10000, + inverted=False + ): + + self._chain_fo=chain_fo + self._inverted=inverted + self._sampling_step=sampling_step + + tmp_chain_sequences=[] + + for line in chain_fo: + line=line.strip() + + if line=="": + continue + + parts=line.split() + + assert len(parts) in [1,3,13] + + if len(parts)==13: + [ + _, + score, + tName, + tSize, + tStrand, + tStart, + tEnd, + qName, + qSize, + qStrand, + qStart, + qEnd, + iid, + ]=parts + + score =int (score) + tSize = int(tSize) + tStart = int(tStart) + tEnd = int(tEnd) + qSize = int(qSize) + qStart = int(qStart) + qEnd = int(qEnd) + iid = int(iid) + + intervals_pairs = [((0,tStart),(0,qStart))] + + elif len(parts)==3: + [size, dt, dq] = map(int, parts) + interval_pairs.append( + ( + (interval_pairs[-1][0][1],interval_pairs[-1][0][1]+size), + (interval_pairs[-1][1][1],interval_pairs[-1][1][1]+size), + ) + ) + interval_pairs.append( + ( + (interval_pairs[-1][0][1],interval_pairs[-1][0][1]+dt), + (interval_pairs[-1][1][1],interval_pairs[-1][1][1]+dq), + ) + ) + elif len(parts)==1: + [size] = map(int, parts) + interval_pairs.append( + ( + (interval_pairs[-1][0][1],interval_pairs[-1][0][1]+size), + (interval_pairs[-1][1][1],interval_pairs[-1][1][1]+size), + ) + ) + interval_pairs.append( + ( + (interval_pairs[-1][0][1],interval_pairs[-1][0][1]+tSize-tEnd), + (interval_pairs[-1][1][1],interval_pairs[-1][1][1]+qSize-qEnd), + ) + ) + assert interval_pairs[-1][0][1]==tSize + assert interval_pairs[-1][1][1]==qSize + + self.tmp_chain_sequences.append( + ChainSequence( + interval_pairs=interval_pairs, + sampling_step=self._sampling_step, + invert=self._invert, + name1=tName, + name2=qName, + ) + ) + + self._chain_sequences=collections.OrderedDict( + [ + (chain_sequence.name1,chain_sequence) for chain_sequence in tmp_chain_sequences + ] + ) + + + def zero_based_transl(self, chromosome, coordinate): + self._chain_sequences[chromosome].zero_based_transl(coordinate) + + def one_based_transl(self, chromosome, coordinate): + self._chain_sequences[chromosome].one_based_transl(coordinate) + + def get_fasta_index(self): + #TODO: method for creating FAI object from a Chain object + pass diff --git a/rnftools/utils/ChainDict.py b/rnftools/utils/ChainDict.py deleted file mode 100644 index a0a2620..0000000 --- a/rnftools/utils/ChainDict.py +++ /dev/null @@ -1,109 +0,0 @@ -import numpy - -class ChainDict: - - def __init__(self, - chain_fn, - ): - - self._dict_array={} - self._dict_properties={} - - self._chain_fn=chain_fn - chrom=None - with open(chain_fn) as f: - while 1==1: - line=f.readline() - if line=="": - break - - head=line.strip() - if head=="": - continue - - #print(head) - parts=head.split() - - [ - _, - score, - tName, - tSize, - tStrand, - tStart, - tEnd, - qName, - qSize, - qStrand, - qStart, - qEnd, - iid, - ]=parts - - score =int (score) - tSize = int(tSize) - tStart = int(tStart) - tEnd = int(tEnd) - qSize = int(qSize) - qStart = int(qStart) - qEnd = int(qEnd) - iid = int(iid) - - self._dict_array[tName]=numpy.empty(tSize, dtype=numpy.int32) - self._dict_properties[tName]={ - "score":score, - "tName":tName, - "tSize":tSize, - "tStrand":tStrand, - "tStart":tStart, - "tEnd":tEnd, - "qName":qName, - "qSize":qSize, - "qStrand":qStrand, - "qStart":qStart, - "qEnd":qEnd, - "id":iid, - } - - leftp = 0 - rightp= 0 - - #line=f.readline() - #if line is None: - # break - #parts=line.strip().split() - parts=[0, tStart, qStart] - while len(parts)>0: - if len(parts)==1: - parts=[int(parts[0]), tSize-tEnd, qSize-qEnd] - - if len(parts)==3: - [size, dt, dq] = map(int, parts) - for i in range(size): - self._dict_array[tName][leftp]=rightp - leftp+=1 - rightp+=1 - if dt==0 and dq>0: - - rightp+=dq - - elif dt>0: - slope=1.0*dq/dt - for i in range(dt): - self._dict_array[tName][leftp]=rightp+int(round(rightp + (i*slope))) - leftp+=1 - rightp+=dq - - #print(leftp) - parts=f.readline().strip().split() - assert leftp==tSize, "{} {} vs. {} {} (diff: {} {})".format(leftp,rightp,tSize,qSize,tSize-leftp,qSize-rightp) - assert rightp==qSize, "{} {} vs. {} {} (diff: {} {})".format(leftp,rightp,tSize,qSize,tSize-leftp,qSize-rightp) - - - def one_based_transl(self, chromosome, coordinate): - assert 0<=coordinate - #assert coordinate<=self._dict_properties[chromosome][tSize] - if coordinate==0: - return 0 - else: - return self._dict_array[chromosome][coordinate-1]+1 diff --git a/rnftools/utils/ChainSequence.py b/rnftools/utils/ChainSequence.py new file mode 100644 index 0000000..84ed105 --- /dev/null +++ b/rnftools/utils/ChainSequence.py @@ -0,0 +1,81 @@ +class ChainSequence: + + def __init__(self, + interval_pairs, + sampling_step, + invert=False, + name1=None, + name2=None, + ): + + self._sampling_step=sampling_step + self._invert=invert + self._name1=name1 + self._name2=name2 + + self._interval_pairs=[] + + last_left1,last_left2,last_right1,last_right2=None,None,None,None + + for ((left1,right1),(left2,right2)) in interval_pairs: + + assert (last_right1 is None) or (last_right1==left1) + assert (last_right2 is None) or (last_right2==left2) + assert left1 <= right1 + assert left2 <= right2 + + self._interval_pairs.append( ((left1,right1),(left2,right2)) ) + last_left1,last_right1,last_left2,last_right2=left1,right1,left2,right2 + + assert self._interval_pairs[0][0][0]==0 + assert self._interval_pairs[0][1][0]==0 + + if self._invert: + self._name1,self._name2=self._name2,self._name1 + + for (i,(interval1,interval2)) in enumerate(self._interval_pairs,start=0): + self._interval_pairs[i]=(interval2,interval1) + + self._length1=self._interval_pairs[-1][0][1] + self._length2=self._interval_pairs[-1][1][1] + + self._sampling=[] + p=0 + for i in range(self._length1//self._sampling_step): + coordinate=i*self._sampling_step + while self._interval_pairs[p][0][0]0 + slope=1.0*(right2-left2)/(right1-left1) + translated_coordinate=int(round(left2+slope*(right1-left1))) + return translated_coordinate + + def one_based_transl(self, coordinate): + assert 0<=coordinate + if coordinate==0: + return 0 + else: + return self.zero_based_transl(coordinate-1)+1 diff --git a/rnftools/utils/__init__.py b/rnftools/utils/__init__.py index 7adea24..7f6ab49 100644 --- a/rnftools/utils/__init__.py +++ b/rnftools/utils/__init__.py @@ -1,2 +1,2 @@ -from .ChainDict import * +from .Chain import * from .FaIdx import * From 88b7d194da5c3e0041a1c89f98f6ca8efbedfec8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karel=20B=C5=99inda?= Date: Thu, 13 Aug 2015 23:26:30 +0200 Subject: [PATCH 09/16] Fasta index from a chain --- rnftools/scripts.py | 46 +++++++++++++++-------------- rnftools/utils/Chain.py | 8 ++++-- rnftools/utils/FaIdx.py | 64 ++++++++++++++++++++++++++++++++--------- 3 files changed, 80 insertions(+), 38 deletions(-) diff --git a/rnftools/scripts.py b/rnftools/scripts.py index 7288a46..e54d691 100644 --- a/rnftools/scripts.py +++ b/rnftools/scripts.py @@ -34,7 +34,7 @@ def _add_shared_params(parser, unmapped_switcher=False): ) parser.add_argument( - '-i','--fasta-index', + '-x','--faidx', type=argparse.FileType('r'), metavar='file', dest='fai_fo', @@ -581,42 +581,46 @@ def liftover(args): def add_liftover_parser(subparsers,subcommand,help,description): parser_liftover = subparsers.add_parser(subcommand,help=help,description=description) parser_liftover.add_argument( - '-i','--input', + '-c','--chain', type=str, metavar='file', - dest='input_fn', + dest='chain_fn', required=True, - help='Input file to be transformed (SAM/BAM unless other specified).', + help='Chain liftover file for coordinates transformation. [no transformation]', ) parser_liftover.add_argument( - '-o','--output', + '-x','--faidx', type=str, metavar='file', - dest='output_fn', + dest='fai_fn', required=True, - help='Output file (SAM/BAM unless other specified).', + help='Fasta index of the reference sequence. [extract from chain file]', ) parser_liftover.add_argument( - '-c','--chain', + '--input-format', type=str, - metavar='file', - dest='chain_fn', - required=True, - help='Chain format.', + metavar='str', + dest='format', + help='Input format (SAM/BAM/FASTQ). [autodetect]', ) parser_liftover.add_argument( - '-f','--fasta-index', + '--output-format', type=str, - metavar='file', - dest='fai_fn', - required=True, - help='Fasta index of the reference sequence.', + metavar='str', + dest='format', + help='Output format (SAM/BAM/FASTQ). [autodetect]', ) parser_liftover.add_argument( - '-q','--convert-fastq', - action='store_true', - dest='convert_fastq', - help='Input and output files are FASTQ files (not SAM/BAM).', + 'input_fn', + type=str, + metavar='input', + help='Input file to be transformed (- for standard input).', + ) + parser_liftover.add_argument( + 'output_fn', + type=str, + metavar='output', + help='Output file to be transformed (- for standard output).', ) parser_liftover.set_defaults(func=liftover) diff --git a/rnftools/utils/Chain.py b/rnftools/utils/Chain.py index 2d4a8a6..4ee3f07 100644 --- a/rnftools/utils/Chain.py +++ b/rnftools/utils/Chain.py @@ -1,5 +1,6 @@ import collections from .ChainSequence import ChainSequence +from .FaIdx import FaIdx class Chain: @@ -100,7 +101,6 @@ def __init__(self, ] ) - def zero_based_transl(self, chromosome, coordinate): self._chain_sequences[chromosome].zero_based_transl(coordinate) @@ -108,5 +108,7 @@ def one_based_transl(self, chromosome, coordinate): self._chain_sequences[chromosome].one_based_transl(coordinate) def get_fasta_index(self): - #TODO: method for creating FAI object from a Chain object - pass + faidx=FaIdx(fai_fo=None) + pairs=[(seq.name1,seq.length1) for seq in self._chain_sequences] + faidx.load_from_list(pairs) + return faidx diff --git a/rnftools/utils/FaIdx.py b/rnftools/utils/FaIdx.py index ed3d0ef..82e403e 100644 --- a/rnftools/utils/FaIdx.py +++ b/rnftools/utils/FaIdx.py @@ -5,17 +5,18 @@ class FaIdx: fai_fo (file object): FASTA index (FAI) file to be loaded. Attributes: - self.dict_chr_ids (dict): FASTA IDs of chromosomes (chr -> id). - self.dict_chr_lengths (dict): Lengths of chromosomes (chr -> length). + dict_chr_ids (dict): FASTA IDs of chromosomes (chr -> id). + dict_ids_chr (dict): FASTA IDs of chromosomes (id -> chr). + dict_chr_lengths (dict): Lengths of chromosomes (chr -> length). number_of_chromosomes (int): Number of chromosomes in the corresponding FASTA file. chr_id_width (int): Length of strings representing chromosome number. coor_width (int): Length of string representing coordinates. """ def __init__(self, fai_fo): - self.dict_chr_ids = {} - self.dict_ids_chr = {} - self.dict_chr_lengths = {} + self._dict_chr_ids = {} + self._dict_ids_chr = {} + self._dict_chr_lengths = {} if fai_fo is not None: # parsing FAI file @@ -29,15 +30,50 @@ def __init__(self, fai_fo): 5) the number of bytes in each fasta line """ + pairs = [] + for (i,line) in enumerate(fai_fo,start=1): if line.strip()!="": parts=line.split("\t") - chr=parts[0] - chr_len=int(parts[1]) - self.dict_chr_ids[chr]=i - self.dict_ids_chr[i]=chr - self.dict_chr_lengths[chr]=chr_len - - self.number_of_chromosomes=len(self.dict_chr_ids) - self.chr_id_width=len(str(self.number_of_chromosomes)) - self.coor_width=len(str(max(self.dict_chr_lengths.values()))) + chromosome=parts[0] + length=int(parts[1]) + pairs.append( (chromosome,legth) ) + self.load_from_list(pairs) + + # pairs:list of (chromosome, length) + def load_from_list(self, pairs): + assert self._dict_chr_ids=={} + + for i,(chromosome, length) in enumerate(pairs,start=1): + self._dict_chr_ids[chromosome]=i + self._dict_ids_chr[i]=chromosome + self._dict_chr_lengths[chromosome]=length + + self._number_of_chromosomes=len(self._dict_chr_ids) + self._chr_id_width=len(str(self._number_of_chromosomes)) + self._coor_width=len(str(max(self._dict_chr_lengths.values()))) + + @property + def dict_chr_ids(self): + return self._dict_chr_ids + + @property + def dict_ids_chr(self): + return self._dict_ids_chr + + @property + def dict_chr_lengths(self): + return self._dict_chr_lengths + + @property + def number_of_chromosomes(self): + return self._number_of_chromosomes + + @property + def chr_id_width(self): + return self._chr_id_width + + @property + def coor_width(self): + return self._coor_width + \ No newline at end of file From 3b4a5da65c5484f00e12a73216d611d3454c7bf7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karel=20B=C5=99inda?= Date: Fri, 14 Aug 2015 00:04:15 +0200 Subject: [PATCH 10/16] rnftools liftover adapted to new api --- rnftools/rnfformat/RnfLifter.py | 51 +++++++++++++++++++++++----- rnftools/scripts.py | 59 ++++++++++++++++++++++++++++++--- rnftools/utils/ChainSequence.py | 4 +-- 3 files changed, 97 insertions(+), 17 deletions(-) diff --git a/rnftools/rnfformat/RnfLifter.py b/rnftools/rnfformat/RnfLifter.py index b033644..db1555b 100644 --- a/rnftools/rnfformat/RnfLifter.py +++ b/rnftools/rnfformat/RnfLifter.py @@ -12,14 +12,26 @@ def __init__(self, self._fai_fn=fai_fn self._chain_fn=chain_fn - with open(chain_fn) as chain_fo: - self._chain=rnftools.utils.Chain(chain_fo=chain_fo) - with open(fai_fn) as fai_fo: - self._fai_index=rnftools.utils.FaiIndex(fai_fo=fai_fo) + if chain_fn is not None: + with open(chain_fn) as chain_fo: + self._chain=rnftools.utils.Chain(chain_fo=chain_fo) + else: + self._chain=None + + if fai_fn is not None: + with open(fai_fn) as fai_fo: + self._fai_index=rnftools.utils.FaIdx(fai_fo=fai_fo) + else: + if self._chain is not None: + self._fai_index=self._chain.get_fasta_index() + else: + self._fai_index=None self._reg_block=re.compile(r"(\(([0-9]+),[0-9]+,[FRN],([0-9]+),([0-9]+)\))") def lift_rnf_name(self,rnf_name): + if self._chain is None: + return rnf_name for occur in self._reg_block.finditer(rnf_name): groups=occur.groups() chrom_id=int(groups[1]) @@ -49,11 +61,32 @@ def lift_fastq(self, fastq_out_fo.write(line) def lift_sam(self, - sam_in_fn, - sam_out_fn + sam_in_fn=None, + bam_in_fn=None, + sam_out_fn=None, + bam_out_fn=None, ): - infile = pysam.AlignmentFile(sam_in_fn, "rb" if sam_in_fn[-4:]==".bam" else "r") - outfile = pysam.AlignmentFile(sam_out_fn, "wb" if sam_out_fn[-4:]==".bam" else "wh", template=infile) + assert sam_in_fn is not None or bam_in_fn is not None + assert sam_in_fn is None or bam_in_fn is None + assert sam_out_fn is not None or bam_out_fn is not None + assert sam_out_fn is None or bam_out_fn is None + + if sam_in_fn is None: + in_mode="rb" + in_fn=bam_in_fn + else: + in_mode="r" + in_fn=sam_in_fn + + if sam_out_fn is None: + out_mode="wb" + out_fn=bam_out_fn + else: + out_mode="wh" + out_fn=sam_out_fn + + infile = pysam.AlignmentFile(in_fn, in_mode) + outfile = pysam.AlignmentFile(out_fn, out_mode, template=infile) for s in infile: s.qname=self.lift_rnf_name(s.qname) - outfile.write(s) \ No newline at end of file + outfile.write(s) diff --git a/rnftools/scripts.py b/rnftools/scripts.py index e54d691..05cd7c1 100644 --- a/rnftools/scripts.py +++ b/rnftools/scripts.py @@ -560,12 +560,63 @@ def add_validate_parser(subparsers,subcommand,help,description): def liftover(args): + input_format=None + output_format=None + + if args.input_fn.lower()[-4:]==".sam": + input_format="sam" + if args.input_fn.lower()[-4:]=="-": + input_format="sam" + elif args.input_fn.lower()[-4:]==".bam": + input_format="bam" + elif args.input_fn.lower()[-4:]==".fq": + input_format="fq" + elif args.input_fn.lower()[-4:]==".fastq": + input_format="fastq" + + if args.output_fn.lower()[-4:]==".sam": + output_format="sam" + if args.output_fn.lower()[-4:]=="-": + output_format="sam" + elif args.output_fn.lower()[-4:]==".bam": + output_format="bam" + elif args.output_fn.lower()[-4:]==".fq": + output_format="fq" + elif args.output_fn.lower()[-4:]==".fastq": + output_format="fastq" + + if args.input_format is not None: + assert args.input_format.lower() in ["sam","bam","fastq","fq"] + if args.input_format.lower()=="sam": + input_format="sam" + elif args.input_format.lower()=="bam": + input_format="sam" + elif args.input_format.lower() in ["fastq","fq"]: + input_format="fq" + + if args.output_format is not None: + assert args.output_format.lower() in ["sam","bam","fastq","fq"] + if args.output_format.lower()=="sam": + output_format="sam" + elif args.output_format.lower()=="bam": + output_format="sam" + elif args.output_format.lower() in ["fastq","fq"]: + output_format="fq" + + if input_format=="fq": + assert output_format=="fq" + if input_format in ["sam","bam"]: + assert output_format in ["sam","bam"] + + assert input_format is not None + assert output_format is not None + rnf_lifter=rnftools.rnfformat.RnfLifter( chain_fn=args.chain_fn, fai_fn=args.fai_fn, ) - if args.convert_fastq: + if input_format=="fq" and output_format=="fq": with open(args.input_fn) as fastq_in_fn: with open(args.output_fn,"w+") as fastq_out_fn: rnf_lifter.lift_fastq( @@ -585,7 +636,6 @@ def add_liftover_parser(subparsers,subcommand,help,description): type=str, metavar='file', dest='chain_fn', - required=True, help='Chain liftover file for coordinates transformation. [no transformation]', ) parser_liftover.add_argument( @@ -593,21 +643,20 @@ def add_liftover_parser(subparsers,subcommand,help,description): type=str, metavar='file', dest='fai_fn', - required=True, help='Fasta index of the reference sequence. [extract from chain file]', ) parser_liftover.add_argument( '--input-format', type=str, metavar='str', - dest='format', + dest='input_format', help='Input format (SAM/BAM/FASTQ). [autodetect]', ) parser_liftover.add_argument( '--output-format', type=str, metavar='str', - dest='format', + dest='output_format', help='Output format (SAM/BAM/FASTQ). [autodetect]', ) parser_liftover.add_argument( diff --git a/rnftools/utils/ChainSequence.py b/rnftools/utils/ChainSequence.py index 84ed105..54543ca 100644 --- a/rnftools/utils/ChainSequence.py +++ b/rnftools/utils/ChainSequence.py @@ -32,9 +32,7 @@ def __init__(self, if self._invert: self._name1,self._name2=self._name2,self._name1 - - for (i,(interval1,interval2)) in enumerate(self._interval_pairs,start=0): - self._interval_pairs[i]=(interval2,interval1) + self._interval_pairs=[x[::-1] for x in self._interval_pairs] self._length1=self._interval_pairs[-1][0][1] self._length2=self._interval_pairs[-1][1][1] From 86646bd09127fc118bef5de5dcfe82698ba87f69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karel=20B=C5=99inda?= Date: Fri, 14 Aug 2015 00:06:19 +0200 Subject: [PATCH 11/16] Minifix --- rnftools/rnfformat/__init__.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/rnftools/rnfformat/__init__.py b/rnftools/rnfformat/__init__.py index c4121b7..21f7e8e 100644 --- a/rnftools/rnfformat/__init__.py +++ b/rnftools/rnfformat/__init__.py @@ -3,9 +3,8 @@ from .FqCreator import * from .FqMerger import * from .ReadTuple import * +from .RnfLifter import * from .RnfProfile import * from .Segment import * from .Validator import * -from .RnfLifter import * -from .ChainDict import * From bb1322aa36734e490d9bb75dbc3f4112f2b3d6cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karel=20B=C5=99inda?= Date: Fri, 14 Aug 2015 11:29:07 +0200 Subject: [PATCH 12/16] Minifix --- tests/command_line/rnftools_art2rnf.sh | 2 +- tests/command_line/rnftools_dwgsim2rnf.sh | 4 ++-- tests/command_line/rnftools_mason2rnf.sh | 4 ++-- tests/command_line/rnftools_wgsim2rnf.sh | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/command_line/rnftools_art2rnf.sh b/tests/command_line/rnftools_art2rnf.sh index 75471ad..3dee18e 100755 --- a/tests/command_line/rnftools_art2rnf.sh +++ b/tests/command_line/rnftools_art2rnf.sh @@ -17,7 +17,7 @@ $ART_ILLUMINA -sam \ --out art_se \ rnftools art2rnf \ - --fasta-index ${FA}.fai \ + --faidx ${FA}.fai \ --sam art_se.sam \ --rnf-fastq _art_rnf_se.fq \ diff --git a/tests/command_line/rnftools_dwgsim2rnf.sh b/tests/command_line/rnftools_dwgsim2rnf.sh index eba50b2..ac7b400 100755 --- a/tests/command_line/rnftools_dwgsim2rnf.sh +++ b/tests/command_line/rnftools_dwgsim2rnf.sh @@ -19,7 +19,7 @@ $DWGSIM \ $FA sim_se rnftools dwgsim2rnf \ - --fasta-index ${FA}.fai \ + --faidx ${FA}.fai \ --dwgsim-prefix sim_se \ --rnf-fastq _dwgsim_rnf_se.fq \ @@ -34,6 +34,6 @@ $DWGSIM \ $FA sim_pe \ rnftools dwgsim2rnf \ - --fasta-index ${FA}.fai \ + --faidx ${FA}.fai \ --dwgsim-prefix sim_pe \ --rnf-fastq _dwgsim_rnf_pe.fq \ diff --git a/tests/command_line/rnftools_mason2rnf.sh b/tests/command_line/rnftools_mason2rnf.sh index 6201460..b77065a 100755 --- a/tests/command_line/rnftools_mason2rnf.sh +++ b/tests/command_line/rnftools_mason2rnf.sh @@ -17,7 +17,7 @@ $MASON \ --out tmp.mason.1.fq \ rnftools mason2rnf \ - --fasta-index ${FA}.fai \ + --faidx ${FA}.fai \ --sam mason_se.sam \ --rnf-fastq _mason_rnf_se.fq \ @@ -31,6 +31,6 @@ $MASON \ --out-right tmp.mason.2.fq \ rnftools mason2rnf \ - --fasta-index ${FA}.fai \ + --faidx ${FA}.fai \ --sam mason_pe.sam \ --rnf-fastq _mason_rnf_pe.fq \ diff --git a/tests/command_line/rnftools_wgsim2rnf.sh b/tests/command_line/rnftools_wgsim2rnf.sh index cae4885..89f1c8d 100755 --- a/tests/command_line/rnftools_wgsim2rnf.sh +++ b/tests/command_line/rnftools_wgsim2rnf.sh @@ -18,14 +18,14 @@ $WGSIM \ # 1) SE test, no contamination rnftools wgsim2rnf \ - --fasta-index ${FA}.fai \ + --faidx ${FA}.fai \ --wgsim-fastq-1 wgsim_1.fq \ --rnf-fastq _wgsim_rnf_se.fq \ # 2) PE test, no contamination rnftools wgsim2rnf \ - --fasta-index ${FA}.fai \ + --faidx ${FA}.fai \ --wgsim-fastq-1 wgsim_1.fq \ --wgsim-fastq-2 wgsim_2.fq \ --rnf-fastq _wgsim_rnf_pe.fq \ From 88ac00d3924c5aa52b00248014c38a0c850ef599 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karel=20B=C5=99inda?= Date: Fri, 14 Aug 2015 12:21:23 +0200 Subject: [PATCH 13/16] rnftools liftover works --- rnftools/utils/Chain.py | 36 +++++++++++++++++++-------------- rnftools/utils/ChainSequence.py | 21 +++++++++++++++---- 2 files changed, 38 insertions(+), 19 deletions(-) diff --git a/rnftools/utils/Chain.py b/rnftools/utils/Chain.py index 4ee3f07..ebd3cad 100644 --- a/rnftools/utils/Chain.py +++ b/rnftools/utils/Chain.py @@ -7,15 +7,17 @@ class Chain: def __init__(self, chain_fo, sampling_step=10000, - inverted=False + invert=False ): self._chain_fo=chain_fo - self._inverted=inverted + self._invert=invert self._sampling_step=sampling_step tmp_chain_sequences=[] + interval_pairs=[] + for line in chain_fo: line=line.strip() @@ -52,7 +54,7 @@ def __init__(self, qEnd = int(qEnd) iid = int(iid) - intervals_pairs = [((0,tStart),(0,qStart))] + interval_pairs.append( ((0,tStart),(0,qStart)) ) elif len(parts)==3: [size, dt, dq] = map(int, parts) @@ -85,15 +87,15 @@ def __init__(self, assert interval_pairs[-1][0][1]==tSize assert interval_pairs[-1][1][1]==qSize - self.tmp_chain_sequences.append( - ChainSequence( - interval_pairs=interval_pairs, - sampling_step=self._sampling_step, - invert=self._invert, - name1=tName, - name2=qName, - ) - ) + tmp_chain_sequences.append( + ChainSequence( + interval_pairs=interval_pairs, + sampling_step=self._sampling_step, + invert=self._invert, + name1=tName, + name2=qName, + ) + ) self._chain_sequences=collections.OrderedDict( [ @@ -102,13 +104,17 @@ def __init__(self, ) def zero_based_transl(self, chromosome, coordinate): - self._chain_sequences[chromosome].zero_based_transl(coordinate) + assert chromosome in self._chain_sequences.keys() + assert isinstance(coordinate,int) + return self._chain_sequences[chromosome].zero_based_transl(coordinate) def one_based_transl(self, chromosome, coordinate): - self._chain_sequences[chromosome].one_based_transl(coordinate) + assert chromosome in self._chain_sequences.keys() + assert isinstance(coordinate,int) + return self._chain_sequences[chromosome].one_based_transl(coordinate) def get_fasta_index(self): faidx=FaIdx(fai_fo=None) - pairs=[(seq.name1,seq.length1) for seq in self._chain_sequences] + pairs=[(seqname,self._chain_sequences[seqname].length1) for seqname in self._chain_sequences.keys()] faidx.load_from_list(pairs) return faidx diff --git a/rnftools/utils/ChainSequence.py b/rnftools/utils/ChainSequence.py index 54543ca..2cf59c2 100644 --- a/rnftools/utils/ChainSequence.py +++ b/rnftools/utils/ChainSequence.py @@ -1,3 +1,6 @@ +import sys +import traceback + class ChainSequence: def __init__(self, @@ -39,9 +42,12 @@ def __init__(self, self._sampling=[] p=0 - for i in range(self._length1//self._sampling_step): + for i in range(self._length1//self._sampling_step+1): coordinate=i*self._sampling_step - while self._interval_pairs[p][0][0]0 From e2125180d28e080058ab7585c5d8c610220cc28f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karel=20B=C5=99inda?= Date: Fri, 14 Aug 2015 15:08:23 +0200 Subject: [PATCH 14/16] tests for rnftools liftover --- rnftools/rnfformat/RnfLifter.py | 4 +- rnftools/scripts.py | 7 + tests/command_line/liftover.bam | Bin 0 -> 126273 bytes tests/command_line/liftover.chain | 1821 +++++++++++++++++++++++ tests/command_line/rnftools_liftover.sh | 19 + tests/tests_run.sh | 3 + 6 files changed, 1853 insertions(+), 1 deletion(-) create mode 100644 tests/command_line/liftover.bam create mode 100644 tests/command_line/liftover.chain create mode 100755 tests/command_line/rnftools_liftover.sh diff --git a/rnftools/rnfformat/RnfLifter.py b/rnftools/rnfformat/RnfLifter.py index db1555b..4ba8c9f 100644 --- a/rnftools/rnfformat/RnfLifter.py +++ b/rnftools/rnfformat/RnfLifter.py @@ -8,13 +8,15 @@ class RnfLifter: def __init__(self, chain_fn, fai_fn, + invert=False, ): self._fai_fn=fai_fn self._chain_fn=chain_fn + self._invert=invert if chain_fn is not None: with open(chain_fn) as chain_fo: - self._chain=rnftools.utils.Chain(chain_fo=chain_fo) + self._chain=rnftools.utils.Chain(chain_fo=chain_fo,invert=invert) else: self._chain=None diff --git a/rnftools/scripts.py b/rnftools/scripts.py index 05cd7c1..1eddebc 100644 --- a/rnftools/scripts.py +++ b/rnftools/scripts.py @@ -614,6 +614,7 @@ def liftover(args): rnf_lifter=rnftools.rnfformat.RnfLifter( chain_fn=args.chain_fn, fai_fn=args.fai_fn, + invert=args.invert, ) if input_format=="fq" and output_format=="fq": @@ -645,6 +646,12 @@ def add_liftover_parser(subparsers,subcommand,help,description): dest='fai_fn', help='Fasta index of the reference sequence. [extract from chain file]', ) + parser_liftover.add_argument( + '--invert', + action='store_true', + dest='invert', + help='Invert chain file (transformation in the other direction).', + ) parser_liftover.add_argument( '--input-format', type=str, diff --git a/tests/command_line/liftover.bam b/tests/command_line/liftover.bam new file mode 100644 index 0000000000000000000000000000000000000000..f6198acf90fab889166bbc3a385c03bc476cb057 GIT binary patch literal 126273 zcmV)3K+C@$iwFb&00000{{{d;LjnNI0DX=@3c@fHMAKz@2{Ks zyvMncLI6zIG)%WEyk5%kq48FI;;1Ae69Rl_feC@LT+)Lx*3p}`rl!O-WlhVfrJjx& z(?r8AiX&d=y1KTFX*)-u@SDb(_GBn~i(K?C!9AhR?%UqOz@Hy@|9y^Ty9~VmbSUl@ z>i_@%ABzYC000000RIL6LPG)o8f}!lf3z&wRUUR{Mk683>#91ZPW3Bc0aHcEl%$d9 zs_LH_f#+10=>jv-2(^GHaHSb(goyzYFkt~oJY6nK1({zC!C78-84Ej(4PJ}bm<0O| zYb7?$a)OcVfb+u(4~gY0oWzF2v7H3R+27u$`rg}Kucz-w^M1c4^?v*8{q1k>{q46r zcE$hvx$k)W)%HCvX?*u%^zXlN|KR67{NWk?DL(w+d{#U||NXLO=)3c>s^;Z0v+c`@Z8_zv<<77hiw%-0QEdvaZgCwCT*y z=}ZkxJ~VY_v$oCJI@f7$Gp(DhX}YZG(^NG{s*KiJ1))|dhyvee6)B&-qm)*m3Vo$K z`dS72V>-YWI`C9LUk3D30exHHPcZb86Z|&%m6Je+N{93X{UP+L-uwLa$>*C7&23R_ z%hk3lc4cYTSM~$j-}SX0*j^>hKJ#avAp3k!KXDa2%0A`MK3@f^ltr;xE-tjsZ_pp3 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 K000000000t5k+SJ literal 0 HcmV?d00001 diff --git a/tests/command_line/liftover.chain b/tests/command_line/liftover.chain new file mode 100644 index 0000000..dfd4cce --- /dev/null +++ b/tests/command_line/liftover.chain @@ -0,0 +1,1821 @@ +chain 4410826 gi|561108321|ref|NC_018143.2| 4411709 + 0 4411709 gi|561108321|ref|NC_018143.2| 4412000 + 0 4412000 1 +1902 0 1 +215 1 0 +3134 0 1 +3877 1 0 +1326 0 1 +2902 0 1 +717 0 1 +1784 0 1 +2874 0 1 +1267 0 1 +5977 0 1 +4130 1 0 +5574 0 1 +10 3 0 +3982 0 1 +2476 0 1 +1686 1 0 +4608 0 1 +11717 0 1 +1066 2 0 +2857 2 0 +2621 0 1 +541 0 1 +5275 0 1 +1642 0 1 +2121 0 1 +1623 2 0 +4397 0 1 +1336 0 1 +1888 1 0 +1230 0 1 +776 0 1 +781 0 1 +646 1 0 +4530 0 1 +2593 0 1 +3225 1 0 +6261 2 0 +1618 1 0 +34 0 1 +497 1 0 +1327 0 1 +3723 1 0 +1692 0 1 +860 0 1 +2613 0 1 +1291 1 0 +2365 0 1 +881 1 0 +2634 0 1 +9 0 1 +3459 0 1 +1830 0 1 +2326 0 1 +1200 1 0 +136 2 0 +9535 0 1 +733 0 1 +767 0 1 +4359 2 0 +3644 0 1 +1352 1 0 +564 1 0 +2801 0 1 +1899 2 0 +2223 1 0 +5969 1 0 +230 0 1 +55 1 0 +957 1 0 +927 0 1 +5956 0 1 +524 1 0 +1641 0 1 +7570 0 1 +4792 0 1 +497 1 0 +5092 0 1 +446 0 1 +365 0 1 +640 2 0 +2253 1 0 +547 1 0 +1780 0 1 +940 0 1 +1358 0 1 +2499 2 0 +8120 0 1 +1849 1 0 +8 0 1 +889 2 0 +2130 1 0 +635 0 1 +7409 1 0 +4123 0 1 +2202 1 0 +2103 0 1 +180 0 1 +2744 0 1 +329 1 0 +1152 1 0 +1821 0 1 +3159 2 0 +265 0 1 +1689 1 0 +4222 1 0 +463 0 1 +1060 0 1 +2749 3 0 +11953 0 1 +350 0 1 +264 1 0 +960 1 0 +200 0 1 +584 1 0 +5255 0 1 +14 1 0 +606 0 1 +290 0 1 +35 0 1 +10989 0 1 +3015 0 1 +176 0 1 +3315 0 1 +251 1 0 +4806 1 0 +44 1 0 +2410 0 1 +570 1 0 +6183 0 1 +830 0 1 +3303 0 1 +6368 1 0 +2814 1 0 +3246 0 1 +596 0 1 +5441 0 1 +357 0 1 +439 0 1 +3433 0 1 +197 0 1 +1333 0 1 +383 0 1 +229 0 1 +4460 0 1 +2330 0 1 +5250 1 0 +1253 0 1 +1593 3 0 +5178 2 0 +77 2 0 +5100 0 1 +767 0 1 +92 0 1 +6505 0 1 +688 0 1 +2858 0 1 +1989 2 0 +1673 0 1 +11429 1 0 +10784 1 0 +4337 1 0 +7049 0 1 +4366 0 1 +59 0 1 +3298 2 0 +445 0 1 +7744 1 0 +47 0 1 +1223 2 0 +2547 0 1 +231 0 1 +2519 1 0 +1179 0 1 +3637 0 1 +964 2 0 +215 0 1 +4568 1 0 +496 0 1 +179 1 0 +6095 0 1 +2753 1 0 +1356 0 1 +4749 0 1 +897 0 1 +4847 0 1 +2096 0 1 +38 0 1 +1023 0 1 +1720 0 1 +2422 0 1 +3057 0 1 +835 0 1 +8919 0 1 +1023 0 1 +507 1 0 +578 1 0 +358 0 1 +852 0 1 +3966 0 1 +119 0 1 +3568 2 0 +1425 1 0 +4798 0 1 +6562 1 0 +319 0 1 +555 0 1 +1535 0 1 +3210 1 0 +1955 0 1 +1294 0 1 +1245 0 1 +561 0 1 +2485 1 0 +10340 0 1 +11665 0 1 +2478 0 1 +8972 0 1 +674 1 0 +22 0 1 +6528 0 1 +7002 1 0 +698 0 1 +2323 0 1 +3374 2 0 +5631 0 1 +1033 0 1 +2490 3 0 +30 1 0 +1892 0 1 +9311 0 1 +490 1 0 +2688 0 1 +3260 1 0 +7037 0 1 +2029 0 1 +1004 2 0 +850 2 0 +3231 0 1 +949 1 0 +3175 0 1 +448 0 1 +2124 2 0 +4868 3 0 +12 2 0 +969 0 1 +3044 1 0 +781 0 1 +918 0 1 +1300 1 0 +68 1 0 +2606 0 1 +7337 0 1 +3284 0 1 +28 1 0 +614 1 0 +1150 0 1 +11788 0 1 +3093 0 1 +456 0 1 +59 0 1 +1269 1 0 +348 2 0 +1466 0 1 +3083 2 0 +10 3 0 +21 0 1 +3281 0 1 +68 2 0 +36 0 1 +771 0 1 +1501 1 0 +613 0 1 +12040 1 0 +168 0 1 +2999 0 1 +2819 0 1 +2167 0 1 +598 0 1 +1099 2 0 +5824 1 0 +6965 1 0 +1959 0 1 +2917 0 1 +41 0 1 +1094 1 0 +1955 0 1 +863 1 0 +1059 0 1 +2321 0 1 +168 0 1 +6685 0 1 +7633 0 1 +6271 0 1 +1032 0 1 +9218 0 1 +1406 0 1 +161 0 1 +8886 0 1 +2673 1 0 +11782 0 1 +1160 0 1 +3071 1 0 +789 0 1 +3311 3 0 +18 1 0 +1193 0 1 +3120 0 1 +4450 1 0 +1384 0 1 +1418 0 1 +3635 0 1 +1645 1 0 +2871 0 1 +343 0 1 +1324 0 1 +2167 0 1 +1495 0 1 +1342 2 0 +1003 1 0 +105 0 1 +2123 0 1 +12 4 0 +29 1 0 +8635 1 0 +614 0 1 +877 1 0 +672 1 0 +2946 0 1 +11886 0 1 +242 0 1 +2901 0 1 +640 0 1 +1751 0 1 +3275 0 1 +191 0 1 +317 1 0 +2757 0 1 +271 0 1 +15675 0 1 +336 0 1 +4556 1 0 +48 0 1 +19 1 0 +289 0 1 +1243 0 1 +2151 0 1 +3758 1 0 +1354 0 1 +4122 3 0 +1999 0 1 +124 2 0 +4787 1 0 +5467 0 1 +2095 0 1 +10356 1 0 +2130 0 1 +456 0 1 +413 0 1 +922 1 0 +5052 0 1 +1023 1 0 +10031 1 0 +798 2 0 +71 0 1 +1047 1 0 +488 1 0 +743 1 0 +22 0 1 +7657 2 0 +1138 0 1 +3834 1 0 +3119 1 0 +2137 1 0 +874 0 1 +42 0 1 +2829 0 1 +1305 0 1 +723 0 1 +4167 0 1 +5 2 0 +2900 1 0 +5686 0 1 +343 1 0 +6853 2 0 +2108 0 1 +2292 0 1 +303 2 0 +73 1 0 +611 0 1 +545 0 1 +1042 0 1 +1589 0 1 +2209 2 0 +959 0 1 +5184 0 1 +28 2 0 +966 0 1 +7113 1 0 +16 0 1 +4 0 1 +1638 0 1 +1803 1 0 +2450 1 0 +8270 0 1 +3414 0 1 +21 0 1 +268 0 1 +5139 0 1 +3060 0 1 +2235 0 1 +39 2 0 +2654 1 0 +852 0 1 +29 0 1 +34 0 1 +2881 1 0 +2425 1 0 +31 0 1 +11031 0 1 +592 1 0 +297 1 0 +5949 0 1 +1485 0 1 +24 0 1 +1068 0 1 +8497 0 1 +3583 1 0 +11 2 0 +1863 0 1 +240 1 0 +561 0 1 +911 2 0 +4757 2 0 +3910 0 1 +15 0 1 +422 0 1 +15 2 0 +969 1 0 +226 0 1 +879 0 1 +149 0 1 +2382 2 0 +2655 0 1 +3331 0 1 +1294 3 0 +996 0 1 +144 1 0 +4295 1 0 +3845 0 1 +841 0 1 +1824 0 1 +1719 0 1 +215 0 1 +16 0 1 +290 0 1 +3691 0 1 +2062 0 1 +3448 0 1 +6444 0 1 +5170 0 1 +56 0 1 +56 0 1 +34 1 0 +276 0 1 +3343 0 1 +1961 1 0 +1926 0 1 +466 1 0 +6988 0 1 +31 0 1 +7434 0 1 +1249 0 1 +2304 1 0 +3858 0 1 +868 0 1 +2369 0 1 +16 1 0 +1875 0 1 +830 0 1 +295 2 0 +1924 1 0 +31 0 1 +2219 0 1 +3075 0 1 +3386 0 1 +1737 0 1 +3104 0 1 +3138 0 1 +71 0 1 +2178 0 1 +579 0 1 +312 0 1 +961 1 0 +1128 2 0 +4623 2 0 +589 2 0 +38 0 1 +3095 0 1 +6338 0 1 +1835 0 1 +1621 0 1 +1689 0 1 +654 0 1 +2554 0 1 +516 2 0 +55 0 1 +4066 0 1 +3752 0 1 +505 0 1 +415 0 1 +88 0 1 +8133 0 1 +486 1 0 +10254 2 0 +6269 0 1 +5739 2 0 +1344 0 1 +2753 1 0 +4 0 1 +1002 2 0 +315 0 1 +7 0 1 +7057 0 1 +42 0 1 +1565 2 0 +1733 0 1 +1993 0 1 +2317 0 1 +53 0 1 +1979 0 1 +3195 0 1 +503 0 1 +3803 1 0 +5802 1 0 +4586 0 1 +3298 0 1 +343 1 0 +1785 1 0 +1019 1 0 +9434 0 1 +3504 2 0 +7 0 1 +2765 3 0 +1453 2 0 +679 0 1 +1028 1 0 +1178 0 1 +116 0 1 +3255 0 1 +2179 0 1 +48 0 1 +1058 1 0 +1777 0 1 +37 0 1 +2326 1 0 +5473 1 0 +8411 0 1 +112 2 0 +2586 0 1 +2040 0 1 +365 0 1 +3652 0 1 +3454 2 0 +72 0 1 +8063 0 1 +308 1 0 +7570 0 1 +67 1 0 +1253 0 1 +1108 1 0 +1834 0 1 +1120 0 1 +551 1 0 +1173 0 1 +5111 0 1 +3156 0 1 +2553 0 1 +4474 0 1 +644 0 1 +1326 1 0 +356 0 1 +5267 2 0 +613 0 1 +26 0 1 +685 0 1 +4010 0 1 +254 0 1 +3942 1 0 +38 1 0 +1610 0 1 +8825 0 1 +1457 0 1 +1475 0 1 +656 1 0 +894 1 0 +2370 0 1 +98 0 1 +4373 2 0 +960 0 1 +2881 0 1 +961 0 1 +4321 0 1 +5275 0 1 +3971 1 0 +1671 1 0 +8692 1 0 +583 0 1 +271 0 1 +5743 1 0 +1293 0 1 +216 0 1 +2078 0 1 +181 2 0 +6520 1 0 +2452 0 1 +1202 0 1 +3974 2 0 +7298 1 0 +1947 1 0 +6393 1 0 +1834 0 1 +360 2 0 +4018 2 0 +199 0 1 +1900 0 1 +9151 1 0 +2003 2 0 +342 0 1 +3413 0 1 +71 0 1 +138 1 0 +2989 1 0 +11294 0 1 +5830 0 1 +7881 2 0 +227 0 1 +2431 0 1 +979 2 0 +523 0 1 +12241 0 1 +370 0 1 +2834 0 1 +4301 0 1 +4297 0 1 +1242 0 1 +464 3 0 +8634 0 1 +2380 1 0 +1194 0 1 +3019 0 1 +3213 0 1 +1827 0 1 +4539 0 1 +126 0 1 +160 0 1 +4200 0 1 +7192 0 1 +885 1 0 +145 2 0 +1363 0 1 +252 1 0 +1291 2 0 +50 0 1 +235 0 1 +653 0 1 +2924 0 1 +4242 0 1 +3526 1 0 +2231 1 0 +1772 1 0 +682 0 1 +39 1 0 +19 2 0 +1565 0 1 +361 0 1 +128 3 0 +10816 2 0 +2611 0 1 +4222 1 0 +1152 3 0 +8416 1 0 +858 0 1 +91 0 1 +1379 1 0 +3864 0 1 +2795 0 1 +2046 0 1 +19 1 0 +433 0 1 +1949 0 1 +1459 0 1 +4540 0 1 +1800 0 1 +893 3 0 +7534 0 1 +2004 0 1 +5429 2 0 +5012 0 1 +7643 2 0 +484 0 1 +6589 0 1 +1073 0 1 +5961 0 1 +4667 0 1 +414 1 0 +2031 0 1 +975 1 0 +4655 0 1 +1343 1 0 +5471 0 1 +6414 1 0 +2706 1 0 +110 0 1 +420 1 0 +2068 0 1 +7309 0 1 +2242 0 1 +439 0 1 +53 0 1 +2256 0 1 +902 1 0 +247 0 1 +8420 0 1 +1973 0 1 +13587 0 1 +1382 0 1 +2696 0 1 +304 0 1 +4718 0 1 +3710 1 0 +9032 0 1 +1990 0 1 +2960 1 0 +1448 0 1 +477 1 0 +8839 1 0 +9 0 1 +50 0 1 +273 0 1 +4369 0 1 +2566 1 0 +2191 0 1 +3070 1 0 +587 0 1 +4090 0 1 +1265 1 0 +5022 4 0 +11232 1 0 +5804 0 1 +25 0 1 +9475 0 1 +5803 1 0 +6007 1 0 +1300 1 0 +45 0 1 +200 2 0 +3807 0 1 +828 2 0 +1185 3 0 +37 0 1 +609 0 1 +6744 0 1 +5 2 0 +1193 0 1 +26 1 0 +512 0 1 +2747 1 0 +3098 1 0 +138 1 0 +934 0 1 +1734 0 1 +451 0 1 +556 1 0 +3198 0 1 +26 0 1 +17 1 0 +6827 0 1 +4 0 1 +1127 1 0 +565 1 0 +560 1 0 +2422 0 1 +2208 0 1 +5895 0 1 +1282 2 0 +295 0 1 +1143 0 1 +3964 0 1 +856 0 1 +441 0 1 +6484 0 1 +8391 2 0 +39 0 1 +278 0 1 +2420 0 1 +8738 0 1 +2343 0 1 +5529 0 1 +357 0 1 +2016 1 0 +5819 0 1 +291 0 1 +48 0 1 +2379 0 1 +2555 1 0 +31 1 0 +2246 1 0 +2250 0 1 +2470 1 0 +2385 0 1 +3010 0 1 +2911 1 0 +724 0 1 +3429 0 1 +19 0 1 +9 0 1 +8318 0 1 +1743 0 1 +5406 0 1 +341 0 1 +3038 0 1 +67 0 1 +2512 1 0 +11 1 0 +1255 0 1 +9 1 0 +3107 0 1 +2652 0 1 +7933 0 1 +1720 0 1 +1480 0 1 +11409 0 1 +6277 1 0 +2849 0 1 +3546 0 1 +26 2 0 +7598 0 1 +467 1 0 +1514 0 1 +24 0 1 +324 0 1 +1282 0 1 +1164 0 1 +36 1 0 +3038 0 1 +940 0 1 +655 0 1 +1627 1 0 +1483 2 0 +5721 0 1 +3455 1 0 +2596 0 1 +7 0 1 +10954 0 1 +924 0 1 +254 0 1 +3325 1 0 +766 0 1 +2209 1 0 +3662 1 0 +12 3 0 +10609 0 1 +5152 3 0 +282 0 1 +3722 0 1 +2527 2 0 +6709 2 0 +4306 0 1 +4430 0 1 +241 0 1 +4509 0 1 +15674 1 0 +40 1 0 +1515 0 1 +616 2 0 +24 0 1 +1241 0 1 +3492 0 1 +30 0 1 +3190 0 1 +2462 2 0 +991 1 0 +1026 0 1 +75 0 1 +8356 0 1 +4980 0 1 +209 1 0 +165 0 1 +1999 0 1 +3596 1 0 +8231 0 1 +273 0 1 +1225 0 1 +4039 0 1 +2382 0 1 +21 0 1 +738 0 1 +2180 1 0 +38 0 1 +979 0 1 +2795 2 0 +1396 1 0 +8 0 1 +3174 0 1 +3761 0 1 +62 0 1 +2365 0 1 +378 0 1 +3 1 0 +630 0 1 +6304 0 1 +6861 0 1 +983 0 1 +1404 0 1 +273 0 1 +6 1 0 +2045 0 1 +20 1 0 +308 0 1 +15 0 1 +1702 0 1 +10256 1 0 +284 1 0 +33 0 1 +698 0 1 +134 2 0 +48 2 0 +1983 1 0 +226 0 1 +25 1 0 +4306 1 0 +3806 3 0 +200 0 1 +125 0 1 +4 1 0 +2292 0 1 +3306 0 1 +240 0 1 +702 4 0 +2093 0 1 +940 0 1 +1748 0 1 +1599 0 1 +162 0 1 +1359 0 1 +1648 0 1 +1742 0 1 +3898 0 1 +1263 0 1 +40 0 1 +1195 1 0 +1381 1 0 +3868 1 0 +28 0 1 +17834 0 1 +4958 2 0 +987 0 1 +2723 1 0 +3563 2 0 +7326 0 1 +16 0 1 +940 2 0 +1575 0 1 +2527 1 0 +130 0 1 +1028 0 1 +3772 1 0 +6339 1 0 +5873 0 1 +43 0 1 +44 1 0 +25 0 1 +901 0 1 +5383 0 1 +6 0 1 +982 0 1 +1328 0 1 +379 0 1 +1319 2 0 +5207 0 1 +6991 0 1 +3018 2 0 +432 0 1 +2960 0 1 +37 0 1 +4142 2 0 +51 0 1 +115 0 1 +996 0 1 +6226 0 1 +124 2 0 +5998 2 0 +10060 0 1 +574 0 1 +5717 0 1 +425 0 1 +2907 0 1 +1863 1 0 +4803 1 0 +978 0 1 +438 1 0 +1235 1 0 +4119 0 1 +1903 0 1 +522 2 0 +939 0 1 +23 1 0 +5199 0 1 +24 1 0 +6446 0 1 +1752 1 0 +2069 0 1 +763 0 1 +489 0 1 +1293 1 0 +8132 1 0 +1938 0 1 +4359 0 1 +576 0 1 +5187 0 1 +7637 1 0 +140 0 1 +5414 0 1 +1254 1 0 +1926 0 1 +5722 3 0 +2927 0 1 +581 0 1 +625 1 0 +7122 0 1 +82 0 1 +3361 0 1 +4389 1 0 +1040 0 1 +5515 0 1 +1739 0 1 +216 0 1 +53 2 0 +16 1 0 +229 0 1 +1968 2 0 +1423 2 0 +3805 1 0 +6846 2 0 +1049 0 1 +55 1 0 +2775 0 1 +1256 0 1 +1162 1 0 +2637 2 0 +2218 1 0 +1449 1 0 +4694 0 1 +257 0 1 +3335 0 1 +6357 0 1 +571 0 1 +1627 0 1 +2865 1 0 +1018 2 0 +1002 0 1 +2087 0 1 +331 0 1 +842 0 1 +4882 0 1 +2065 3 0 +4374 1 0 +5809 0 1 +2746 0 1 +68 0 1 +67 1 0 +1424 0 1 +1253 0 1 +5297 0 1 +669 2 0 +3222 0 1 +2154 0 1 +113 1 0 +10 0 1 +4607 0 1 +722 2 0 +8644 1 0 +6485 0 1 +774 0 1 +2935 1 0 +2060 1 0 +5309 0 1 +3946 1 0 +12301 1 0 +1520 0 1 +5253 1 0 +3 0 1 +18 0 1 +182 1 0 +4751 1 0 +10 0 1 +45 1 0 +3330 0 1 +4456 0 1 +2361 0 1 +152 1 0 +2898 0 1 +1063 2 0 +28 0 1 +2633 0 1 +4 1 0 +2097 1 0 +8445 1 0 +1003 0 1 +1196 0 1 +1599 1 0 +1081 0 1 +5226 0 1 +2048 1 0 +5340 1 0 +5020 0 1 +4612 1 0 +7298 0 1 +44 0 1 +4694 0 1 +2023 0 1 +442 0 1 +221 1 0 +210 1 0 +2690 0 1 +1121 0 1 +68 0 1 +674 0 1 +1339 0 1 +1964 0 1 +6579 2 0 +2225 0 1 +1072 0 1 +2432 1 0 +621 3 0 +784 0 1 +1250 0 1 +5311 1 0 +72 1 0 +405 0 1 +23 1 0 +6773 0 1 +5828 1 0 +2842 0 1 +3456 1 0 +1332 2 0 +7517 1 0 +1992 0 1 +2498 0 1 +1515 0 1 +3614 0 1 +17 1 0 +106 0 1 +132 0 1 +619 0 1 +954 0 1 +1879 1 0 +371 0 1 +1023 0 1 +2646 0 1 +31 1 0 +8903 0 1 +1440 0 1 +699 0 1 +3497 0 1 +46 0 1 +349 1 0 +449 0 1 +14 1 0 +4526 0 1 +14 0 1 +1703 0 1 +727 1 0 +43 0 1 +157 0 1 +649 0 1 +2162 0 1 +5053 0 1 +2584 1 0 +4003 0 1 +894 1 0 +2095 0 1 +4290 0 1 +260 0 1 +1318 0 1 +56 0 1 +840 0 1 +47 0 1 +13 0 1 +2052 0 1 +470 0 1 +2491 0 1 +620 0 1 +4211 0 1 +22 0 1 +1081 0 1 +2670 0 1 +1671 0 1 +2247 1 0 +66 1 0 +1576 1 0 +14 1 0 +2293 0 1 +35 0 1 +15 2 0 +4536 0 1 +293 0 1 +5528 0 1 +4147 0 1 +1723 2 0 +47 0 1 +4884 1 0 +608 0 1 +3084 0 1 +4023 0 1 +410 0 1 +2591 1 0 +3033 0 1 +1599 0 1 +790 0 1 +1624 1 0 +625 0 1 +6191 1 0 +1780 0 1 +2604 0 1 +586 0 1 +549 1 0 +504 0 1 +260 2 0 +462 0 1 +3037 0 1 +2459 0 1 +170 0 1 +5263 1 0 +695 0 1 +95 0 1 +598 0 1 +91 2 0 +4587 0 1 +2914 0 1 +45 0 1 +7232 2 0 +1145 0 1 +61 0 1 +8879 0 1 +1081 0 1 +4319 0 1 +282 1 0 +4504 0 1 +5480 0 1 +2603 2 0 +379 0 1 +4370 1 0 +3741 1 0 +6722 0 1 +27 0 1 +4190 1 0 +5061 1 0 +1925 1 0 +2457 0 1 +10008 2 0 +7152 0 1 +565 2 0 +7433 1 0 +135 1 0 +538 0 1 +4432 0 1 +301 1 0 +2297 0 1 +557 1 0 +1900 0 1 +4063 0 1 +1031 0 1 +506 0 1 +2883 1 0 +1216 1 0 +2053 0 1 +4822 2 0 +40 0 1 +1256 1 0 +2218 0 1 +10 3 0 +748 0 1 +243 0 1 +4886 1 0 +2395 0 1 +147 0 1 +1913 4 0 +9391 0 1 +1090 0 1 +6868 0 1 +5 0 1 +15 0 1 +6809 0 1 +21 0 1 +3366 0 1 +4109 1 0 +944 0 1 +2052 3 0 +3268 0 1 +2630 1 0 +10568 1 0 +4078 0 1 +1330 1 0 +5259 1 0 +14058 0 1 +3459 0 1 +2755 1 0 +1884 2 0 +1650 2 0 +3585 0 1 +195 3 0 +4962 0 1 +873 0 1 +7363 1 0 +962 1 0 +10 0 1 +1771 1 0 +2320 0 1 +2831 0 1 +641 0 1 +4120 0 1 +264 0 1 +3414 1 0 +2127 0 1 +2944 0 1 +3809 1 0 +5273 0 1 +615 2 0 +5536 3 0 +6390 0 1 +3631 0 1 +424 0 1 +16 0 1 +1074 1 0 +19 1 0 +1853 0 1 +15713 0 1 +5042 0 1 +992 0 1 +189 0 1 +8 1 0 +1685 0 1 +43 3 0 +1080 2 0 +480 0 1 +7348 0 1 +3760 0 1 +51 0 1 +644 0 1 +85 0 1 +4090 0 1 +4832 0 1 +626 0 1 +26 0 1 +1183 2 0 +1934 0 1 +3831 0 1 +286 0 1 +5942 1 0 +891 0 1 +36 0 1 +438 0 1 +3087 0 1 +436 1 0 +70 0 1 +4181 0 1 +1498 3 0 +38 0 1 +1008 1 0 +1842 0 1 +1926 0 1 +11 0 1 +627 0 1 +1468 0 1 +870 0 1 +2367 0 1 +2037 0 1 +14 0 1 +2666 0 1 +1459 0 1 +68 1 0 +442 1 0 +1411 0 1 +4281 0 1 +2030 0 1 +5456 1 0 +1519 0 1 +2738 0 1 +2663 1 0 +4201 1 0 +9 0 1 +2416 1 0 +569 0 1 +1041 1 0 +7941 0 1 +4802 0 1 +1832 0 1 +6346 0 1 +248 0 1 +7682 0 1 +2602 2 0 +1964 0 1 +368 1 0 +235 0 1 +762 0 1 +2096 0 1 +3341 0 1 +724 0 1 +4936 0 1 +593 0 1 +4626 1 0 +712 0 1 +54 1 0 +2 1 0 +3877 2 0 +525 0 1 +1127 2 0 +619 0 1 +3698 1 0 +924 2 0 +832 0 1 +782 1 0 +3730 0 1 +458 1 0 +2801 1 0 +7243 0 1 +7731 1 0 +22 2 0 +2380 1 0 +1166 2 0 +859 0 1 +5794 0 1 +69 1 0 +1197 0 1 +1368 0 1 +4659 0 1 +2715 2 0 +1281 0 1 +171 0 1 +1826 1 0 +3268 1 0 +1303 0 1 +5048 1 0 +405 0 1 +1509 1 0 +867 0 1 +27 0 1 +11031 4 0 +782 0 1 +490 0 1 +428 1 0 +1490 0 1 +1478 2 0 +8938 0 1 +6762 1 0 +702 0 1 +4000 0 1 +6031 0 1 +721 0 1 +6616 0 1 +2287 0 1 +2942 0 1 +1970 0 1 +40 0 1 +1017 0 1 +5542 0 1 +2687 0 1 +603 0 1 +1812 1 0 +3350 1 0 +795 1 0 +1146 0 1 +615 0 1 +993 0 1 +2698 1 0 +726 1 0 +616 0 1 +3472 1 0 +1703 0 1 +575 0 1 +545 2 0 +888 1 0 +1183 1 0 +1760 1 0 +6220 0 1 +1866 1 0 +11900 1 0 +1026 0 1 +1716 0 1 +705 1 0 +5351 0 1 +630 0 1 +1170 0 1 +2141 0 1 +2357 0 1 +35 1 0 +2665 2 0 +3633 0 1 +503 1 0 +1171 0 1 +2594 1 0 +133 0 1 +3053 0 1 +14180 1 0 +241 2 0 +277 0 1 +4199 1 0 +278 1 0 +2890 0 1 +3755 1 0 +4431 1 0 +9336 0 1 +3402 1 0 +4118 0 1 +4489 0 1 +56 1 0 +2730 0 1 +795 0 1 +611 1 0 +3255 0 1 +10320 0 1 +1276 0 1 +44 0 1 +448 2 0 +1847 0 1 +3889 2 0 +2478 0 1 +597 0 1 +3415 0 1 +7190 0 1 +341 0 1 +4476 0 1 +2984 1 0 +4952 1 0 +73 0 1 +2229 0 1 +162 1 0 +480 1 0 +159 0 1 +969 0 1 +1815 0 1 +1754 0 1 +1244 0 1 +4432 1 0 +1688 1 0 +62 0 1 +888 1 0 +179 1 0 +1338 1 0 +1871 0 1 +6788 0 1 +1971 1 0 +3445 0 1 +187 0 1 +20 2 0 +2437 2 0 +431 1 0 +369 1 0 +2371 0 1 +567 1 0 +5887 0 1 +613 0 1 +235 4 0 +20 2 0 +26 1 0 +468 0 1 +5409 0 1 +190 2 0 +302 3 0 +1162 0 1 +7164 5 0 +8459 0 1 +553 1 0 +487 0 1 +274 0 1 +638 1 0 +418 0 1 +19 0 1 +4556 0 1 +1404 0 1 +2126 1 0 +4386 0 1 +3608 0 1 +958 0 1 +7 1 0 +1988 0 1 +2419 1 0 +1363 0 1 +3734 2 0 +4520 0 1 +4979 0 1 +1948 1 0 +4858 0 1 +1254 0 1 +4566 0 1 +3749 1 0 +82 2 0 +3481 0 1 +1705 0 1 +1658 0 1 +64 1 0 +6901 0 1 +4818 0 1 +2074 1 0 +4146 0 1 +1077 0 1 +2487 0 1 +4622 0 1 +1398 0 1 +6297 0 1 +1037 0 1 +547 2 0 +1556 1 0 +5633 1 0 +3738 0 1 +2481 1 0 +6600 0 1 +1467 0 1 +11519 1 0 +43 1 0 +3056 1 0 +1027 0 1 +51 0 1 +1442 0 1 +10687 0 1 +2183 0 1 +111 0 1 +193 0 1 +3049 0 1 +872 0 1 +2149 1 0 +178 0 1 +2368 0 1 +17 0 1 +1007 0 1 +1292 0 1 +2525 0 1 +4480 2 0 +430 1 0 +889 0 1 +15 0 1 +3496 1 0 +4295 0 1 +11227 0 1 +2601 0 1 +3221 0 1 +3479 1 0 +51 0 1 +3699 0 1 +4904 1 0 +1131 1 0 +286 0 1 +352 1 0 +719 1 0 +1927 0 1 +378 0 1 +1481 0 1 +2447 1 0 +1141 0 1 +2060 0 1 +26 1 0 +2219 1 0 +402 2 0 +973 1 0 +2038 0 1 +2909 1 0 +11572 3 0 +11870 1 0 +565 0 1 +2821 2 0 +2061 0 1 +315 0 1 +2038 0 1 +1363 1 0 +4828 0 1 +128 0 1 +7769 0 1 +143 1 0 +2189 1 0 +4072 0 1 +52 1 0 +653 0 1 +605 0 1 +1278 1 0 +544 1 0 +4740 1 0 +10 0 1 +67 1 0 +2336 2 0 +201 2 0 +1810 0 1 +2406 0 1 +2282 0 1 +1610 0 1 +576 0 1 +10165 0 1 +73 2 0 +1625 0 1 +47 1 0 +4424 0 1 +1050 0 1 +1823 0 1 +2306 0 1 +21 0 1 +3230 0 1 +1805 1 0 +22 0 1 +1276 1 0 +1142 0 1 +958 0 1 +7340 1 0 +3755 0 1 +1526 0 1 +87 0 1 +226 0 1 +2780 0 1 +372 1 0 +471 0 1 +1943 0 1 +2373 0 1 +4844 0 1 +9445 1 0 +267 2 0 +6077 0 1 +730 0 1 +693 1 0 +4219 0 1 +4347 2 0 +2738 1 0 +288 0 1 +6445 0 1 +5965 0 1 +59 0 1 +2230 2 0 +6787 1 0 +3652 0 1 +4155 0 1 +977 0 1 +78 0 1 +1710 2 0 +318 0 1 +1675 0 1 +2051 0 1 +1376 0 1 +917 2 0 +1173 0 1 +4599 0 1 +2618 1 0 +189 1 0 +4244 2 0 +1434 0 1 +3980 0 1 +202 1 0 +4232 0 1 +4307 0 1 +43 1 0 +1408 1 0 +3144 0 1 +2439 0 1 +2597 0 1 +1480 0 1 +78 0 1 +8421 0 1 +1343 0 1 +1173 0 1 +2406 0 1 +4090 0 1 +787 0 1 +6137 0 1 +1943 0 1 +426 1 0 +2151 1 0 +548 1 0 +1856 0 1 +1646 4 0 +642 0 1 +1328 0 1 +735 2 0 +4356 1 0 +1746 0 1 +3056 3 0 +893 0 1 +1758 1 0 +694 0 1 +3249 0 1 +1550 0 1 +3659 0 1 +35 0 1 +615 0 1 +935 0 1 +1626 0 1 +271 0 1 +6 0 1 +1805 0 1 +3155 2 0 +2301 0 1 +789 0 1 +3037 2 0 +1808 0 1 +1065 1 0 +703 0 1 +2612 0 1 +17 2 0 +19 0 1 +2342 0 1 +19 1 0 +732 0 1 +8187 1 0 +61 0 1 +6 1 0 +5 0 1 +704 0 1 +830 1 0 +9232 0 1 +49 0 1 +1108 0 1 +11873 + diff --git a/tests/command_line/rnftools_liftover.sh b/tests/command_line/rnftools_liftover.sh new file mode 100755 index 0000000..5599faa --- /dev/null +++ b/tests/command_line/rnftools_liftover.sh @@ -0,0 +1,19 @@ +#! /usr/bin/env bash + +set -eux +set -o pipefail + +cd "$(dirname "$0")" + +rnftools liftover -c liftover.chain liftover.bam - > _liftover_new1.sam +rnftools liftover -c liftover.chain --output-format bam liftover.bam - > _liftover_new1.bam + +~/.smbl/bin/samtools view -h liftover.bam > _liftover_orig.sam + +rnftools liftover -c liftover.chain liftover.bam _liftover_new2.sam +rnftools liftover -c liftover.chain liftover.bam _liftover_new2.bam +rnftools liftover -c liftover.chain _liftover_orig.sam _liftover_new3.sam +rnftools liftover -c liftover.chain _liftover_orig.sam _liftover_new3.bam + +rnftools liftover --invert -c liftover.chain _liftover_new1.bam _liftover_pseudoorig.sam + diff --git a/tests/tests_run.sh b/tests/tests_run.sh index 7d02fd6..6c629b0 100755 --- a/tests/tests_run.sh +++ b/tests/tests_run.sh @@ -51,6 +51,9 @@ @test "TESTS: rnftools dwgsim2rnf" { ./command_line/rnftools_dwgsim2rnf.sh } +@test "TESTS: rnftools liftover" { + ./command_line/rnftools_liftover.sh +} ################################################# From a5e97cb4c56a80bf21c9a5dd1f462998815980c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karel=20B=C5=99inda?= Date: Fri, 14 Aug 2015 15:16:05 +0200 Subject: [PATCH 15/16] Tests fixed --- rnftools/utils/FaIdx.py | 2 +- .../{liftover.bam => liftover_orig.bam} | Bin tests/command_line/rnftools_art2rnf.sh | 2 +- tests/command_line/rnftools_curesim2rnf.sh | 2 +- tests/command_line/rnftools_liftover.sh | 10 +++++----- 5 files changed, 8 insertions(+), 8 deletions(-) rename tests/command_line/{liftover.bam => liftover_orig.bam} (100%) diff --git a/rnftools/utils/FaIdx.py b/rnftools/utils/FaIdx.py index 82e403e..31898b8 100644 --- a/rnftools/utils/FaIdx.py +++ b/rnftools/utils/FaIdx.py @@ -37,7 +37,7 @@ def __init__(self, fai_fo): parts=line.split("\t") chromosome=parts[0] length=int(parts[1]) - pairs.append( (chromosome,legth) ) + pairs.append( (chromosome,length) ) self.load_from_list(pairs) # pairs:list of (chromosome, length) diff --git a/tests/command_line/liftover.bam b/tests/command_line/liftover_orig.bam similarity index 100% rename from tests/command_line/liftover.bam rename to tests/command_line/liftover_orig.bam diff --git a/tests/command_line/rnftools_art2rnf.sh b/tests/command_line/rnftools_art2rnf.sh index 3dee18e..fe3e91e 100755 --- a/tests/command_line/rnftools_art2rnf.sh +++ b/tests/command_line/rnftools_art2rnf.sh @@ -32,6 +32,6 @@ $ART_ILLUMINA -sam \ --out art_pe \ rnftools art2rnf \ - --fasta-index ${FA}.fai \ + --faidx ${FA}.fai \ --sam art_pe.sam \ --rnf-fastq _art_rnf_pe.fq \ diff --git a/tests/command_line/rnftools_curesim2rnf.sh b/tests/command_line/rnftools_curesim2rnf.sh index ff04c7c..2a3d1d9 100755 --- a/tests/command_line/rnftools_curesim2rnf.sh +++ b/tests/command_line/rnftools_curesim2rnf.sh @@ -16,6 +16,6 @@ $CURESIM \ 2> /dev/null rnftools curesim2rnf \ - --fasta-index ${FA}.fai \ + --faidx ${FA}.fai \ --curesim-fastq curesim.fq \ --rnf-fastq _curesim_rnf_se.fq \ diff --git a/tests/command_line/rnftools_liftover.sh b/tests/command_line/rnftools_liftover.sh index 5599faa..7cfced3 100755 --- a/tests/command_line/rnftools_liftover.sh +++ b/tests/command_line/rnftools_liftover.sh @@ -5,13 +5,13 @@ set -o pipefail cd "$(dirname "$0")" -rnftools liftover -c liftover.chain liftover.bam - > _liftover_new1.sam -rnftools liftover -c liftover.chain --output-format bam liftover.bam - > _liftover_new1.bam +rnftools liftover -c liftover.chain liftover_orig.bam - > _liftover_new1.sam +rnftools liftover -c liftover.chain --output-format bam liftover_orig.bam - > _liftover_new1.bam -~/.smbl/bin/samtools view -h liftover.bam > _liftover_orig.sam +rnftools liftover liftover_orig.bam _liftover_orig.sam -rnftools liftover -c liftover.chain liftover.bam _liftover_new2.sam -rnftools liftover -c liftover.chain liftover.bam _liftover_new2.bam +rnftools liftover -c liftover.chain liftover_orig.bam _liftover_new2.sam +rnftools liftover -c liftover.chain liftover_orig.bam _liftover_new2.bam rnftools liftover -c liftover.chain _liftover_orig.sam _liftover_new3.sam rnftools liftover -c liftover.chain _liftover_orig.sam _liftover_new3.bam From f05c38b9d009582dfbc99bc91bed64a8ab262fda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karel=20B=C5=99inda?= Date: Fri, 14 Aug 2015 17:58:49 +0200 Subject: [PATCH 16/16] Error in coordiates recomputation fixed --- rnftools/utils/ChainSequence.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rnftools/utils/ChainSequence.py b/rnftools/utils/ChainSequence.py index 2cf59c2..0a0e5f3 100644 --- a/rnftools/utils/ChainSequence.py +++ b/rnftools/utils/ChainSequence.py @@ -81,7 +81,7 @@ def zero_based_transl(self,coordinate): (left1,right1),(left2,right2)=self._interval_pairs[p] assert right1-left1>0 slope=1.0*(right2-left2)/(right1-left1) - translated_coordinate=int(round(left2+slope*(right1-left1))) + translated_coordinate=int(round(left2+slope*(coordinate-left1))) return translated_coordinate def one_based_transl(self, coordinate):