diff --git a/requirements.txt b/requirements.txt index 702ed01..8e2a551 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ 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 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 3c8cb8d..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_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 - """ - - i=1 - for line in fai_fo: - 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)) - self.coor_width=len(str(max(self.dict_chr_lengths.values()))) - - 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/rnfformat/RnfLifter.py b/rnftools/rnfformat/RnfLifter.py new file mode 100644 index 0000000..4ba8c9f --- /dev/null +++ b/rnftools/rnfformat/RnfLifter.py @@ -0,0 +1,94 @@ +import rnftools +import pysam + +import re + +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,invert=invert) + 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]) + 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.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)) + if right!=0: + 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)) + 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) + + def lift_sam(self, + sam_in_fn=None, + bam_in_fn=None, + sam_out_fn=None, + bam_out_fn=None, + ): + 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) diff --git a/rnftools/rnfformat/__init__.py b/rnftools/rnfformat/__init__.py index 2a162ce..21f7e8e 100644 --- a/rnftools/rnfformat/__init__.py +++ b/rnftools/rnfformat/__init__.py @@ -3,6 +3,8 @@ from .FqCreator import * from .FqMerger import * from .ReadTuple import * +from .RnfLifter import * from .RnfProfile import * from .Segment import * from .Validator import * + diff --git a/rnftools/scripts.py b/rnftools/scripts.py index 8195660..1eddebc 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): @@ -32,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', @@ -553,12 +555,140 @@ def add_validate_parser(subparsers,subcommand,help,description): ################################ -################################ +# LIFTOVER +################################ + + +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, + invert=args.invert, + ) + + 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( + 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( + '-c','--chain', + type=str, + metavar='file', + dest='chain_fn', + help='Chain liftover file for coordinates transformation. [no transformation]', + ) + parser_liftover.add_argument( + '-x','--faidx', + type=str, + metavar='file', + 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, + metavar='str', + dest='input_format', + help='Input format (SAM/BAM/FASTQ). [autodetect]', + ) + parser_liftover.add_argument( + '--output-format', + type=str, + metavar='str', + dest='output_format', + help='Output format (SAM/BAM/FASTQ). [autodetect]', + ) + parser_liftover.add_argument( + '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) + + + +################################################################ +################################################################ ## ## RNFTOOLS SCRIPT ## -################################ -################################ +################################################################ +################################################################ def default_func(args): pass @@ -621,6 +751,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="") diff --git a/rnftools/utils/Chain.py b/rnftools/utils/Chain.py new file mode 100644 index 0000000..ebd3cad --- /dev/null +++ b/rnftools/utils/Chain.py @@ -0,0 +1,120 @@ +import collections +from .ChainSequence import ChainSequence +from .FaIdx import FaIdx + +class Chain: + + def __init__(self, + chain_fo, + sampling_step=10000, + invert=False + ): + + self._chain_fo=chain_fo + self._invert=invert + self._sampling_step=sampling_step + + tmp_chain_sequences=[] + + interval_pairs=[] + + 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) + + interval_pairs.append( ((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 + + 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): + 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): + 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=[(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 new file mode 100644 index 0000000..0a0e5f3 --- /dev/null +++ b/rnftools/utils/ChainSequence.py @@ -0,0 +1,92 @@ +import sys +import traceback + +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 + 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] + + self._sampling=[] + p=0 + for i in range(self._length1//self._sampling_step+1): + coordinate=i*self._sampling_step + while not ( \ + self._interval_pairs[p][0][0]<=coordinate and \ + coordinate0 + slope=1.0*(right2-left2)/(right1-left1) + translated_coordinate=int(round(left2+slope*(coordinate-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/FaIdx.py b/rnftools/utils/FaIdx.py new file mode 100644 index 0000000..31898b8 --- /dev/null +++ b/rnftools/utils/FaIdx.py @@ -0,0 +1,79 @@ +class FaIdx: + """Class for loading FASTA indexes. + + Args: + fai_fo (file object): FASTA index (FAI) file to be loaded. + + Attributes: + 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 = {} + + 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 + """ + + pairs = [] + + for (i,line) in enumerate(fai_fo,start=1): + if line.strip()!="": + parts=line.split("\t") + chromosome=parts[0] + length=int(parts[1]) + pairs.append( (chromosome,length) ) + 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 diff --git a/rnftools/utils/__init__.py b/rnftools/utils/__init__.py new file mode 100644 index 0000000..7f6ab49 --- /dev/null +++ b/rnftools/utils/__init__.py @@ -0,0 +1,2 @@ +from .Chain import * +from .FaIdx import * 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/liftover_orig.bam b/tests/command_line/liftover_orig.bam new file mode 100644 index 0000000..f6198ac Binary files /dev/null and b/tests/command_line/liftover_orig.bam differ diff --git a/tests/command_line/rnftools_art2rnf.sh b/tests/command_line/rnftools_art2rnf.sh index 75471ad..fe3e91e 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 \ @@ -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_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_liftover.sh b/tests/command_line/rnftools_liftover.sh new file mode 100755 index 0000000..7cfced3 --- /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_orig.bam - > _liftover_new1.sam +rnftools liftover -c liftover.chain --output-format bam liftover_orig.bam - > _liftover_new1.bam + +rnftools liftover liftover_orig.bam _liftover_orig.sam + +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 + +rnftools liftover --invert -c liftover.chain _liftover_new1.bam _liftover_pseudoorig.sam + 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 \ 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 +} ################################################# 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