From fe45439c5a3ae7f5910085fc73cc7e6c2237af3a Mon Sep 17 00:00:00 2001 From: Charles Plessy Date: Thu, 13 Jan 2011 18:09:25 +0900 Subject: [PATCH] Imported Upstream version 0.1.1 --- MANIFEST.in | 9 + PKG-INFO | 2 +- pysam/csamtools.pyx | 98 ++++--- pysam/pysam_util.c | 5 + setup.py | 6 +- tests/00README.txt | 32 +++ tests/Makefile | 30 +++ tests/ex1.fa | 56 ++++ tests/ex1.sam.gz | Bin 0 -> 113194 bytes tests/ex3.sam | 9 + tests/ex4.sam | 9 + tests/example.py | 119 +++++++++ tests/pysam_test.py | 551 ++++++++++++++++++++++++++++++++++++++++ tests/segfault_tests.py | 37 +++ 14 files changed, 920 insertions(+), 43 deletions(-) create mode 100644 tests/00README.txt create mode 100644 tests/Makefile create mode 100644 tests/ex1.fa create mode 100644 tests/ex1.sam.gz create mode 100644 tests/ex3.sam create mode 100644 tests/ex4.sam create mode 100644 tests/example.py create mode 100755 tests/pysam_test.py create mode 100755 tests/segfault_tests.py diff --git a/MANIFEST.in b/MANIFEST.in index cd0beee..c0ca312 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -11,4 +11,13 @@ include THANKS include pysam/csamtools.pxd include pysam/pysam_util.h include samtools/*.h +include tests/00README.txt +include tests/Makefile +include tests/ex1.fa +include tests/ex1.sam.gz +include tests/ex3.sam +include tests/ex4.sam +include tests/example.py +include tests/pysam_test.py +include tests/segfault_tests.py diff --git a/PKG-INFO b/PKG-INFO index 7126e3b..174c1a9 100644 --- a/PKG-INFO +++ b/PKG-INFO @@ -1,6 +1,6 @@ Metadata-Version: 1.0 Name: pysam -Version: 0.1 +Version: 0.1.1 Summary: pysam Home-page: http://code.google.com/p/pysam/ Author: Andreas Heger diff --git a/pysam/csamtools.pyx b/pysam/csamtools.pyx index b469e78..a0bda89 100644 --- a/pysam/csamtools.pyx +++ b/pysam/csamtools.pyx @@ -46,6 +46,9 @@ cdef makeAlignedRead( bam1_t * src): '''enter src into AlignedRead.''' cdef AlignedRead dest dest = AlignedRead() + # destroy dummy delegate created in constructor + # to prevent memory leak. + bam_destroy1(dest._delegate) dest._delegate = bam_dup1(src) return dest @@ -160,8 +163,7 @@ cdef class Samfile: so to open a :term:`BAM` file for reading:: f=Samfile('ex1.bam','rb') - - + For writing, the header of a :term:`TAM` file/:term:`BAM` file can be constituted from several sources: @@ -285,17 +287,13 @@ cdef class Samfile: if self.index == NULL: raise IOError("could not open index `%s` " % filename ) - def _getTarget( self, tid ): + def getrname( self, tid ): '''(tid ) - convert numerical :term:`tid` into target name.''' + convert numerical :term:`tid` into :ref:`reference` name.''' if not 0 <= tid < self.samfile.header.n_targets: raise ValueError( "tid out of range 0<=tid<%i" % self.samfile.header.n_targets ) return self.samfile.header.target_name[tid] - def getNumReferences( self ): - """return the number of :term:`reference` sequences.""" - return self.samfile.header.n_targets - def _parseRegion( self, reference = None, start = None, end = None, region = None ): '''parse region information. @@ -305,6 +303,8 @@ cdef class Samfile: returns a tuple of region, tid, start and end. Region is a valid samtools :term:`region` or None if the region extends over the whole file. + + Note that regions are 1-based, while start,end are python coordinates. ''' cdef int rtid @@ -316,7 +316,7 @@ cdef class Samfile: # translate to a region if reference: if start != None and end != None: - region = "%s:%i-%i" % (reference, start, end) + region = "%s:%i-%i" % (reference, start+1, end) else: region = reference @@ -331,7 +331,9 @@ cdef class Samfile: return region, rtid, rstart, rend def fetch( self, - reference = None, start = None, end = None, + reference = None, + start = None, + end = None, region = None, callback = None, until_eof = False ): @@ -369,14 +371,17 @@ cdef class Samfile: return bam_fetch(self.samfile.x.bam, self.index, rtid, rstart, rend, callback, fetch_callback ) else: if region: - return IteratorRow( self, region ) + return IteratorRow( self, rtid, rstart, rend ) else: if until_eof: return IteratorRowAll( self ) else: # return all targets by chaining the individual targets together. i = [] - for x in self.references: i.append( IteratorRow( self, x)) + rstart = 0 + rend = 1<<29 + for rtid from 0 <= rtid < self.nreferences: + i.append( IteratorRow( self, rtid, rstart, rend)) return itertools.chain( *i ) else: if region != None: @@ -427,11 +432,14 @@ cdef class Samfile: bam_plbuf_destroy(buf) else: if region: - return IteratorColumn( self, region ) + return IteratorColumn( self, rtid, rstart, rend ) else: # return all targets by chaining the individual targets together. i = [] - for x in self.references: i.append( IteratorColumn( self, x)) + rstart = 0 + rend = 1<<29 + for rtid from 0 <= rtid < self.nreferences: + i.append( IteratorColumn( self, rtid, rstart, rend)) return itertools.chain( *i ) else: @@ -439,7 +447,6 @@ cdef class Samfile: def close( self ): '''closes file.''' - if self.samfile != NULL: samclose( self.samfile ) bam_index_destroy(self.index); @@ -458,6 +465,11 @@ cdef class Samfile: ''' return samwrite( self.samfile, read._delegate ) + property nreferences: + '''number of :term:`reference` sequences in the file.''' + def __get__(self): + return self.samfile.header.n_targets + property references: """tuple with the names of :term:`reference` sequences.""" def __get__(self): @@ -608,23 +620,20 @@ cdef class IteratorRow: cdef bam1_t * b cdef error_msg cdef int error_state - def __cinit__(self, Samfile samfile, region ): + cdef Samfile samfile + def __cinit__(self, Samfile samfile, int tid, int beg, int end ): self.bam_iter = NULL assert samfile._isOpen() assert samfile._hasIndex() + + # makes sure that samfile stays alive as long as the + # iterator is alive. + self.samfile = samfile # parse the region - cdef int tid - cdef int beg - cdef int end self.error_state = 0 self.error_msg = None - bam_parse_region( samfile.samfile.header, region, &tid, &beg, &end) - if tid < 0: - self.error_state = 1 - self.error_msg = "invalid region `%s`" % region - return cdef bamFile fp fp = samfile.samfile.x.bam @@ -714,13 +723,14 @@ cdef class IteratorColumn: # check if first iteration cdef int notfirst + # result of the last plbuf_push cdef int n_pu cdef int eof cdef IteratorRow iter - def __cinit__(self, Samfile samfile, region ): + def __cinit__(self, Samfile samfile, int tid, int start, int end ): - self.iter = IteratorRow( samfile, region ) + self.iter = IteratorRow( samfile, tid, start, end ) self.buf = bam_plbuf_init(NULL, NULL ) self.n_pu = 0 self.eof = 0 @@ -729,9 +739,18 @@ cdef class IteratorColumn: return self cdef int cnext(self): + '''perform next iteration. + + return 1 if there is a buffer to emit. Return 0 for end of iteration. + ''' cdef int retval1, retval2 + # pysam bam_plbuf_push returns: + # 1: if buf is full and can be emitted + # 0: if b has been added + # -1: if there was an error + # check if previous plbuf was incomplete. If so, continue within # the loop and yield if necessary if self.n_pu > 0: @@ -744,12 +763,11 @@ cdef class IteratorColumn: # an new column has finished while self.n_pu == 0: retval1 = self.iter.cnext() - # wrap up if no more input if retval1 == 0: self.n_pu = pysam_bam_plbuf_push( NULL, self.buf, 0) self.eof = 1 - return 1 + return self.n_pu # submit to plbuf self.n_pu = pysam_bam_plbuf_push( self.iter.getCurrent(), self.buf, 0) @@ -878,13 +896,17 @@ cdef class AlignedRead: def __get__(self): return self._delegate.core.flag property rname: - """chromosome/target ID""" + """:term:`reference` ID""" def __get__(self): return self._delegate.core.tid property pos: """0-based leftmost coordinate""" def __get__(self): return self._delegate.core.pos + property rlen: + '''length of the read. Returns 0 if not given.''' + def __get__(self): + return self._delegate.core.l_qseq property mapq: """mapping quality""" def __get__(self): @@ -1034,8 +1056,7 @@ cdef class PileupRead: def __str__(self): return "\t".join( map(str, (self.alignment, self.qpos, self.indel, self.level, self.is_del, self.is_head, self.is_tail ) ) ) - - + property alignment: """a :class:`pysam.AlignedRead` object of the aligned read""" def __get__(self): @@ -1052,18 +1073,17 @@ cdef class PileupRead: """1 iff the base on the padded read is a deletion""" def __get__(self): return self._is_del - property head: + property is_head: def __get__(self): return self._is_head - property tail: + property is_tail: def __get__(self): return self._is_tail - - - - - - + property level: + def __get__(self): + return self._level + + class Outs: '''http://mail.python.org/pipermail/python-list/2000-June/038406.html''' def __init__(self, id = 1): diff --git a/pysam/pysam_util.c b/pysam/pysam_util.c index 7f3174b..8d28096 100644 --- a/pysam/pysam_util.c +++ b/pysam/pysam_util.c @@ -138,6 +138,11 @@ static inline int resolve_cigar(bam_pileup1_t *p, uint32_t pos) return ret; } +// the following code has been taken from bam_plbuf_push +// and modified such that instead of a function call +// the function returns and will continue (if cont is true). +// from where it left off. + // returns // 1: if buf is full and can be emitted // 0: if b has been added diff --git a/setup.py b/setup.py index 7a7ab7e..544e48f 100644 --- a/setup.py +++ b/setup.py @@ -8,6 +8,9 @@ pysam import os, sys, glob, shutil +name = "pysam" +version = "0.1.1" + samtools_exclude = ( "bamtk.c", "razip.c", "bgzip.c" ) samtools_dest = os.path.abspath( "samtools" ) @@ -32,9 +35,6 @@ if len(sys.argv) >= 2 and sys.argv[1] == "import": from distutils.core import setup, Extension from Pyrex.Distutils import build_ext -name = "pysam" -version = "0.1" - classifiers = """ Development Status :: 2 - Alpha Operating System :: MacOS :: MacOS X diff --git a/tests/00README.txt b/tests/00README.txt new file mode 100644 index 0000000..67b8689 --- /dev/null +++ b/tests/00README.txt @@ -0,0 +1,32 @@ +File ex1.fa contains two sequences cut from the human genome +build36. They were exatracted with command: + + samtools faidx human_b36.fa 2:2043966-2045540 20:67967-69550 + +Sequence names were changed manually for simplicity. File ex1.sam.gz +contains MAQ alignments exatracted with: + + (samtools view NA18507_maq.bam 2:2044001-2045500; + samtools view NA18507_maq.bam 20:68001-69500) + +and processed with `samtools fixmate' to make it self-consistent as a +standalone alignment. + +To try samtools, you may run the following commands: + + samtools faidx ex1.fa # index the reference FASTA + samtools import ex1.fa.fai ex1.sam.gz ex1.bam # SAM->BAM + samtools index ex1.bam # index BAM + samtools tview ex1.bam ex1.fa # view alignment + samtools pileup -cf ex1.fa ex1.bam # pileup and consensus + samtools pileup -cf ex1.fa -t ex1.fa.fai ex1.sam.gz + +In order for the script pysam_test.py to work, you will need pysam +in your PYTHONPATH. + +In order for the script example.py to work, you will need pysam +in your PYTHONPATH and run + + make all + +beforehand. diff --git a/tests/Makefile b/tests/Makefile new file mode 100644 index 0000000..7de46f5 --- /dev/null +++ b/tests/Makefile @@ -0,0 +1,30 @@ +all: ex1.glf ex1.pileup.gz ex1.bam.bai ex1.glfview.gz ex2.sam.gz ex2.sam ex1.sam ex3.bam ex3.bam.bai ex4.bam ex4.bam.bai + @echo; echo \# You can now launch the viewer with: \'samtools tview ex1.bam ex1.fa\'; echo; + +ex2.sam.gz: ex1.bam ex1.bam.bai + samtools view -h ex1.bam | gzip > ex2.sam.gz + +ex3.bam: ex3.sam ex1.fa.fai + samtools import ex1.fa.fai ex3.sam ex3.bam + +ex4.bam: ex4.sam ex1.fa.fai + samtools import ex1.fa.fai ex4.sam ex4.bam + +%.sam: %.sam.gz + gunzip < $< > $@ + +ex1.fa.fai:ex1.fa + samtools faidx ex1.fa +ex1.bam:ex1.sam.gz ex1.fa.fai + samtools import ex1.fa.fai ex1.sam.gz ex1.bam +%.bam.bai:%.bam + samtools index $< +ex1.pileup.gz:ex1.bam ex1.fa + samtools pileup -cf ex1.fa ex1.bam | gzip > ex1.pileup.gz +ex1.glf:ex1.bam ex1.fa + samtools pileup -gf ex1.fa ex1.bam > ex1.glf +ex1.glfview.gz:ex1.glf + samtools glfview ex1.glf | gzip > ex1.glfview.gz + +clean: + rm -fr *.bam *.bai *.glf* *.fai *.pileup* *~ calDepth *.dSYM pysam_*.sam ex2.sam ex2.sam.gz ex1.sam diff --git a/tests/ex1.fa b/tests/ex1.fa new file mode 100644 index 0000000..b4ed0cf --- /dev/null +++ b/tests/ex1.fa @@ -0,0 +1,56 @@ +>chr1 +CACTAGTGGCTCATTGTAAATGTGTGGTTTAACTCGTCCATGGCCCAGCATTAGGGAGCT +GTGGACCCTGCAGCCTGGCTGTGGGGGCCGCAGTGGCTGAGGGGTGCAGAGCCGAGTCAC +GGGGTTGCCAGCACAGGGGCTTAACCTCTGGTGACTGCCAGAGCTGCTGGCAAGCTAGAG +TCCCATTTGGAGCCCCTCTAAGCCGTTCTATTTGTAATGAAAACTATATTTATGCTATTC +AGTTCTAAATATAGAAATTGAAACAGCTGTGTTTAGTGCCTTTGTTCAACCCCCTTGCAA +CAACCTTGAGAACCCCAGGGAATTTGTCAATGTCAGGGAAGGAGCATTTTGTCAGTTACC +AAATGTGTTTATTACCAGAGGGATGGAGGGAAGAGGGACGCTGAAGAACTTTGATGCCCT +CTTCTTCCAAAGATGAAACGCGTAACTGCGCTCTCATTCACTCCAGCTCCCTGTCACCCA +ATGGACCTGTGATATCTGGATTCTGGGAAATTCTTCATCCTGGACCCTGAGAGATTCTGC +AGCCCAGCTCCAGATTGCTTGTGGTCTGACAGGCTGCAACTGTGAGCCATCACAATGAAC +AACAGGAAGAAAAGGTCTTTCAAAAGGTGATGTGTGTTCTCATCAACCTCATACACACAC +ATGGTTTAGGGGTATAATACCTCTACATGGCTGATTATGAAAACAATGTTCCCCAGATAC +CATCCCTGTCTTACTTCCAGCTCCCCAGAGGGAAAGCTTTCAACGCTTCTAGCCATTTCT +TTTGGCATTTGCCTTCAGACCCTACACGAATGCGTCTCTACCACAGGGGGCTGCGCGGTT +TCCCATCATGAAGCACTGAACTTCCACGTCTCATCTAGGGGAACAGGGAGGTGCACTAAT +GCGCTCCACGCCCAAGCCCTTCTCACAGTTTCTGCCCCCAGCATGGTTGTACTGGGCAAT +ACATGAGATTATTAGGAAATGCTTTACTGTCATAACTATGAAGAGACTATTGCCAGATGA +ACCACACATTAATACTATGTTTCTTATCTGCACATTACTACCCTGCAATTAATATAATTG +TGTCCATGTACACACGCTGTCCTATGTACTTATCATGACTCTATCCCAAATTCCCAATTA +CGTCCTATCTTCTTCTTAGGGAAGAACAGCTTAGGTATCAATTTGGTGTTCTGTGTAAAG +TCTCAGGGAGCCGTCCGTGTCCTCCCATCTGGCCTCGTCCACACTGGTTCTCTTGAAAGC +TTGGGCTGTAATGATGCCCCTTGGCCATCACCCAGTCCCTGCCCCATCTCTTGTAATCTC +TCTCCTTTTTGCTGCATCCCTGTCTTCCTCTGTCTTGATTTACTTGTTGTTGGTTTTCTG +TTTCTTTGTTTGATTTGGTGGAAGACATAATCCCACGCTTCCTATGGAAAGGTTGTTGGG +AGATTTTTAATGATTCCTCAATGTTAAAATGTCTATTTTTGTCTTGACACCCAACTAATA +TTTGTCTGAGCAAAACAGTCTAGATGAGAGAGAACTTCCCTGGAGGTCTGATGGCGTTTC +TCCCTCGTCTTCTTA +>chr2 +TTCAAATGAACTTCTGTAATTGAAAAATTCATTTAAGAAATTACAAAATATAGTTGAAAG +CTCTAACAATAGACTAAACCAAGCAGAAGAAAGAGGTTCAGAACTTGAAGACAAGTCTCT +TATGAATTAACCCAGTCAGACAAAAATAAAGAAAAAAATTTTAAAAATGAACAGAGCTTT +CAAGAAGTATGAGATTATGTAAAGTAACTGAACCTATGAGTCACAGGTATTCCTGAGGAA +AAAGAAAAAGTGAGAAGTTTGGAAAAACTATTTGAGGAAGTAATTGGGGAAAACCTCTTT +AGTCTTGCTAGAGATTTAGACATCTAAATGAAAGAGGCTCAAAGAATGCCAGGAAGATAC +ATTGCAAGACAGACTTCATCAAGATATGTAGTCATCAGACTATCTAAAGTCAACATGAAG +GAAAAAAATTCTAAAATCAGCAAGAGAAAAGCATACAGTCATCTATAAAGGAAATCCCAT +CAGAATAACAATGGGCTTCTCAGCAGAAACCTTACAAGCCAGAAGAGATTGGATCTAATT +TTTGGACTTCTTAAAGAAAAAAAAACCTGTCAAACACGAATGTTATGCCCTGCTAAACTA +AGCATCATAAATGAAGGGGAAATAAAGTCAAGTCTTTCCTGACAAGCAAATGCTAAGATA +ATTCATCATCACTAAACCAGTCCTATAAGAAATGCTCAAAAGAATTGTAAAAGTCAAAAT +TAAAGTTCAATACTCACCATCATAAATACACACAAAAGTACAAAACTCACAGGTTTTATA +AAACAATTGAGACTACAGAGCAACTAGGTAAAAAATTAACATTACAACAGGAACAAAACC +TCATATATCAATATTAACTTTGAATAAAAAGGGATTAAATTCCCCCACTTAAGAGATATA +GATTGGCAGAACAGATTTAAAAACATGAACTAACTATATGCTGTTTACAAGAAACTCATT +AATAAAGACATGAGTTCAGGTAAAGGGGTGGAAAAAGATGTTCTACGCAAACAGAAACCA +AATGAGAGAAGGAGTAGCTATACTTATATCAGATAAAGCACACTTTAAATCAACAACAGT +AAAATAAAACAAAGGAGGTCATCATACAATGATAAAAAGATCAATTCAGCAAGAAGATAT +AACCATCCTACTAAATACATATGCACCTAACACAAGACTACCCAGATTCATAAAACAAAT +ACTACTAGACCTAAGAGGGATGAGAAATTACCTAATTGGTACAATGTACAATATTCTGAT +GATGGTTACACTAAAAGCCCATACTTTACTGCTACTCAATATATCCATGTAACAAATCTG +CGCTTGTACTTCTAAATCTATAAAAAAATTAAAATTTAACAAAAGTAAATAAAACACATA +GCTAAAACTAAAAAAGCAAAAACAAAAACTATGCTAAGTATTGGTAAAGATGTGGGGAAA +AAAGTAAACTCTCAAATATTGCTAGTGGGAGTATAAATTGTTTTCCACTTTGGAAAACAA +TTTGGTAATTTCGTTTTTTTTTTTTTCTTTTCTCTTTTTTTTTTTTTTTTTTTTGCATGC +CAGAAAAAAATATTTACAGTAACT diff --git a/tests/ex1.sam.gz b/tests/ex1.sam.gz new file mode 100644 index 0000000000000000000000000000000000000000..8dd2bc447cb504be23c29aa54d1a7b8ccfb8fa73 GIT binary patch literal 113194 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

ZoyT4hP62x zqz@)CbaXUS6ggefhO?q6aXp=!N(lm9snc=wH7g{QI4zAy)rl_8s2!O5fuLIXJc4D(90<1sVBJ4H4pZjS1f0uxvNio1d62YDoDS;;Yx}pC;efU`v{1YL{MoC4Y$_v`iw5Zr-hxO z2K0RC{T67O=g68Jb8*@@ma0TY)?Rh#c7!Q6Khi?0tUVi2?E20zB*k+jQh2^3L z9}KqQC`c)3fl4o z^o&83=2^9iOEhS2vVwVi0}!`(@NvbT#-q&1gH;FU2gXOVi+}Q0)bdvp3Q|;aXxOI* zr~f{cP5OHb+(G{RAXNg^g_YtrlTLlJB6*mWc0N1KCOHO@MsJLO4Z)M!jRCmzMLXwl) zls%`OIGd@EQ^9#+(;<7%8%DpTN~0kLvKZhI-4FMkIT^A6-AXEu)PR28enH_h%rb`K zj^y3tv>ut%kv_OHGHz8_BApBOI+#=;X+gR}ud@DJP3$2Mm6%Y4_-24WJiqhZdhJaU z&e~xbuM1kw2`Hp=Rp>);ns~sR=#Y^nufQaiPltI#$?w>9)7aGDKBdu53@2%^^7ueC ztLK&PQaQYa5=Fdcx;{_lDL0h3_0vSXVwOgJz3QbYVVe0UiKGqR0&@^kmqy;Gi)e7z zhgnaRWS9!<=U{~LT>*5y@O6+mMcx3^Q>`8W$go41_sB__)PsbE;Hv4tCcE6Cj`xb$ z?v`V`3d}v9WP0-PhC*%k^7Ld*k;dZ=8YsvI6}`dW?)Cf)r8bxf&hzZ}!O}NX#%O*? zxVTH>Ev5OxWHuIe+KD;syvvmlH`#F%gUmh7S(h#1dUTWpgRU}WPTz5JYHHT0gZxQ}2v3O!F$K!;pmzxOM)B0$*YyV5G&if^ z;X81;;8bz#lM-q4_`rhQf^-<{%zcILgU+AtF+s5=}b z(Rj}z70FD?D>+(_s%;C-%V)nKN1kpeOAW#?bi(#ryyt=elC;Crl-E7o0Ssxsq#nWlw?AZICw0u_=WKa459c1Cvtdl;-BI06la~ zFVBOLSfmFVdT{aX?-4YiIv9z4G^U=f-e^vq_#sP=zEZgqM5NZXPJt z1ayY;>&Twhl~*ZpLKlRfSTqD~(IRN}lMr9~W$Jbsc6Qm48phQ#M=h#&7HvMvo*br- z`N403nZP{tFB_Qq3*Vp{N8Qe7+tDaFF=KjGWA-X(!cQQ-4?)Irg!=N(jrY4C^SQWD zhxDy*`#2jWY~o3BB*2JNghTSIZCa;y+Ogz#f67d z{c@5Dq!^{fNoqs-I{wnzeF-o9+AIFoCP6F;%vUHPVlN9n0Q*O4TXR{Uz> z9c4BNAT$82H)=gH^F2AE7^R1HT*v2d3Y&H|w?j186qV%33q9z~zB)dT)*gk>_|SXZ z>mmUaiUgFQ=BKJb8?xiuoL&>r7?s7M#|-yA7?vajPFLJd@u_bCst%M+hS`f=0hNvK zr;k2KN4;;V7*Gz}%}Y$Z@>U1>bJG*1*8=6p9)d>*Nsw(0eMHi0o-GN?&-2mD`TeYb zECg3~M+S$jMOzxmU{Oa(@KU?z7;1LxJ@-g#F4|X-Zno(2f-&D)E1b6FEYUay6bM}O z^Mm6qiC?>T=!AIy=+0+l(0Xg`lz_q@HF}9<=hqg^87Pp^WX<~8+M^n^@l5s#PM42= zCc_n^ylN0OGi7kcIgpK*oxLjDWLdL3OFOV1YA~_HF6@Yv1jWw8qrM(_AO_s@25$J zgSM^fQ-hOyT<9gL5PG>%UB~mJXg~n=lKuoc?86%({t)8hckxP{r*hCz zY++o>EoxYIArWCCqgw@mM{=28)`IUfsG4m+Z6+ zNI?lx23wQno$Im+UfU*UDfD5RY-S2uQUMlaDb+c87c|QSIL?x6G;wN%TLa*P_Kl<4 zjF&z#6``|=gBC7Hb318X<$`n%HWZezwT_E70h=-W%38Q2_POX!oHRXR$5W zANxg=w%Ta`QNG8_J4pSRLHXrMl;gzvTEmII=yDxG5_y|wPToe*&&q^Hk#=jj7hAPg z&}SD;@$JfEL!+mIRmB{wE1yA$Em_`jRi=E9qXVvXAHY;8i*3LP6(PD`6l&FNd*;66 z@2@AUsddUzGRQ&jJ}@_nGwTH+tTVTUEl|H#*XpvBwa<~O>rn$xpf2O<&e`gW$!Yb5 zjhdtEdCpAkl&CHTFO#T)piwh}#wi|WC9LUS1&AX^(*hO$2ghbzV1s$@?eYlx+}9nQ zSf@PZH@SKFD`2w{a?3RUqPpRpxsLY9S{`Wb^#}@di1#blCD0NC=iqYaBP&2B*VekLFMN>OwU-kS zWW(B{Uv|i)^tbWFE~S=(q)=Uago*(mfJ9LhU%0M#0o4be2h5w0?p{#GHf>4^(11DA z&pj?x$D+c_%w?xoi)1S6r$65Q7=Q~HiK zsyG2e>|Up7IC9g|-<-IVRI;#Lbg$B6#1<%G72$Og&{;%~z8OCB$1vpI*bm{{+vb95 z=$fT+x{Nozj$u_-9D3eHL0m#f#-#!?5ghtxH#_pQ%E|TA;Pz9K7ZIt027%3T0Om~j zZ)`Wy{(b`BXPQ3QhuPozzwb}u{qOjNQ^Dwn=T@lXcL8Dq_En^dLs&MywDgvFr{P{V%Li0tM zCOq~Z(212^9@6q?jKvw(^?}Lv6hMug7@v2LeisHMm&EpVeCk={|E&bPU-qA_CbjLJ znnpK0I^{cbcP}d+x5_M?51kN68UYs0YO%SEX>N2Oz&n#1|PYTG^nVpEc>e?Daj?;HPPRPeC__HP4|M!2CQa zR8g>hjx%1PPvg_e=-+a-&qIEGjdyiD**byPBqtle#($LOKzUZe`5Z)7?1?bXx$t2W zY5EKwJ@ZGG?=DSAuc-YV;QZt!{Wbp9 zS*)ushPID@$_9z=G7%=Z_f?#AvhU3pblY^XN75AZ`GG{eW`k<}GI=>`yH{ZT+`3;M z>KDmJe~j6T9$cIXMzwnewR<=I)^~#TNJsSPK`^IT7jJzUIjWnpE+zbkJyR7Gt?|7! zBnGb-P|1PHOv+S&i3!sI6`r1AjRBj#8 ziRfPtF?i@PSi0;|UPCuBJ)w1*{@kWa&d@x@(WpJ=lbSHvJw(SAU-QLRnKrBj^MNu{ zB@)RANZAKs3S}dPPV-kO5Z$u4)d2pGk7swMi`)^$iVQ)H<`vbUl?9;$??owa`Y_#0 zb)5b98gWhxvAd7{BSaDsNI}kocgflVgIY6<#MFVhQOCb7F!Hof+2T#o5JiLb43Cq| z`mQJbs0zwYByvn)#`-f~CtF4u4~0A-dkZ1)j-?%pD4$MT^>vhw4C^+L1WvLZ7=T9R zsVg;_3%HbbA~&xAZ_e9<<{7hAN=r?GQ%)n9$J#p`Cyv8FFJ_IZFl%M!p?}@P%XOO2 ziF;ETWW{~&8PWQLQ_qDlsZw|6IndiAiFQ1AusZlHvS?lqF^i$(C=SyClTW~UktwdK z=1lhN)9Mqm*<57q4}dlf>JuNEKv!3Moq{ZoE~zJ?5$U>Sr1|Lg!*)ty$E5YKavz9b z-}k|wM~0y^H!o(CdKx#WflSH!A*GlPV!V5aGMq&rYI>O<_|kiHb=!_#qvq!3Xvvaz zylaN3h?XPd;X=o|(Bei|!4#?iC+Q7=*(zA*3-aU668AxbB&kt_+0LtWhiPhSpgxG@>rjE!4RfZxd_?E$^U87FPmr#`5*-)xa056ay;UV#KQrFY=qA`ie(ILB zPcP4Eu!FTj_-&lDK}P@Hg+c!bL$HGhYs=={sWzXc4oC(q8<0VF@HrHY9>R|u#@eigo)5PX7v^nG4 z^-s1qEeT<3jPE*@%#F9!OtT+UNb-GEoH>oJPILKdpu3J~0d%4-r(RC1ebHwGsB_*~ z+RP+VhsxG?hfZK*jTaC*OuQ8*;4;F;HE%ABKCp2v>M_{nYINlhFaRL>#QSF1m|R zI6BiU;L_ejJ9W}mtHO=Dp>(MBDv;~VyPKWZu`l`#du>U&j$H@=G~5hs&^a;Lg0}pu zgTVWC@9tN1H)zRgrE-2WwJ*?uR+OOy`BadPpq)Q%0&dr6P4!|Rxh>?+b#G(XB8nWk zBi)S%G@>Qnz!EP?yvOQj>228Q;yJx?t6O1WoghIt%+H7tZnQ6hYkX!Mslok;a2+Jf zrl3{v3{VQey3Mt_ZkaHLn?a)LV_n?CmTg^_S8=>(oIq-|#kvQ3VY+jX-dJ0Aw`F>p zuY~$a{C86+`Cn`XY!0AxX)}l^=;Clccj4L(=N7WgrACs}nuOP?=lwA!HkywRGwH`w#-ZQTsAZ``u- zw(1GtQ6waL;%)#n010?31~%vm5nY5V1sT{l8V{>k7abQU5(Q45H|Y3tNc_%0dH>|r zuf_RxnDZVoKw2)IIo?<6h=dppy3~tLHj&evA!YSfcg9J3{VAUKKB0vO8X&`pTh7C_ zj^S1LsI|b&35Bv>aj$o=(YA~nf@Z=X@4$PmB3c(1+TbKT6c=o}g-J>YVcfaKb_)sX zcUa?I=v42c*8r^q_7Hn8<}YXskx~nN9qz~2bF)70+EzCO>}h-^Kam$=)X6 zYXMzhwq?V@^KD3p1T9Uc)=Wr2n+z)^qI{EAUU6QNNBmq%Nl>sbAWtv5eWX_Se6U)O z?)0kv+iPG6eiahS@gDH3aR5-wy!x7|GfhZ0Cu$lEP7*r9gZVGaiOU#9s<;gd2O1r* zS_L+NgaN#Lz_X^tKy0<$tp)9|57SQ;UiY@iRmOgu2VaE8 zD6@oji)TJKQu4hiW4A#4JcK%J&JhYP=O=5`M=&Lp%gaj4?QKb58jXX+5VPl1Pn;`E zTQ%79elNCXkK8@JHz~z*-{5R4EkHLT{{MJtYIU4UouE#or2uv?DO#b@5)XNN5&pJF z!veOq(cK#KejnZ$)c>Y!szd}SsQa1&<$W&J-;yS7^-$gJd#hb?mGAQ|95oEilXk+O z{kC_U&w!Ja1``s`UiIJ?@yo#zaGlI(Au%)5dF>20C$H4$T&b%AZE1P1kJ0EOlC=R2 ztHMOk25X)O!~nYzO;~?^HUps(aY(+U^4I9VUy)5J;w^=Yax|~BEZ*YVz(S8mcBX9~ z^c~K+&Ub&k@1<_siGK&pIR+!Fhd4uGh-kv8i9r2*x~axRANv4ji&h%74aVh%IA+l} z$T@3mH)(e_>{c&MJMngKw#)_5uub#;(R^=soQ>Z0#rJb*-RI}&^BCvzYxJVWyGSA* z{mfu-h;!ns&DW{ywlCB&A|U&KVLQb-p14JW6X`nrA2|N*0a9fm1Tlm&MylTPJWGMo znlv7A0Vlgnld2!F7?AkSr8dlE5HLE@60eiz*FK-GL!JUE=qr$)+xzLZzU`j|qF0!I zYmOX~QXaE-n*tG3$2U}Wgp{G=4dO-;w@Sk$x~ap!iF#sJ)6l!ky2~ zI;YgNaw7kzU-f9rFm3VEm0@a(SrDa$3+NMPS(E~(@OcQZ1t{H?6Q$z7FZqN&JV2&E zBFOQuOX|cEjI`2m2H1Sdr>?Q%3yHclZvN>{DzDtR`p}6*ZRt15y)o4(s~R0=7k8=9 zynGzg(l%y^rX*UN8}xG*>1W*B5uqDjF%k9@&rNQ2;uq8Y1$uIl$jgI>TQsOCO7hX$ z_wz}LR}^Y7HBThDdAVWGFZl-={u3w(d>{q5@|x>@2u@Pkp~_(No2|R%CrPFa+5&S( zje^5k3i0?PHPPsxxS~Wyl!cnkj{kSJ};R?#{TWVsokn{+2pltjuiQ?vu*gxzw3T+Vk_dbx?+`R6-D_$g#(z!K| zbdG#$Mz47mWL80jJKq_w(u+0HoPMIXLnfp<&Id<|Uw_@yYu~@Rak%#(r5&Od`qD?A z>~-jKzMQhBrx&T%n^Z;{101}#2?X*bj9bxnf?GFC3XWCCi0qG*J$9{IBHft>%Qav} z10tTTewHmSpyF7;fjZp=UkRy9+d!td#nI6=jX%+!zg}_u?~m1<=80{iSd4 zNT+(FNAo2Tdur(nDv&0Fc5Oi6-(^ABF@K%J#)rW|)$8hr-Hxt2vnYR};+CKWg_g4) z4>zmlHHPV=-{HgG0d|<+Mg|j8ZLjhV_ z5GKWk-yXrFi&Xv_nEl7cfaWFVAE0?j`Eew2;*Bp7i~a(X2lnW458bVfv+kL0^SO1; zG>f-N6>q5yawO^qC?b-Xp7vh=9dLQAGNWx1Z0Ng&ECDik5RvzLIIYg(^esR`;J9`_ zmt51O+T=SlEFz!7?$N-CO(0T0Yfl~JB9Eqvdx>?54_ly3UsVN)SkgM0sY@NOdwJK2eG9& zU}=_U)N}S((RFAxakrMG&v;gu+pH%)TC3OIQyZtNBi9)Uj`4Z&VIOGlepaMt!+C1b z%hixcx6>tAamj@7yx<-_=_cUytl~_fW75vd`NhW-ZK=)k-{2xgJ0AutA&|y=5~0@S z>~2+zyOZ?)tbcKt?_uI1_XcDif_e|<%P9fPQJ$LS!RknfK@Ys%-qPjd^YK|L{0uvo z8!oBbo=g&X0#i(G-?s5gndwYDVBB%-rmoIZ^ZR75{;pS=KlsHaApUXnD9-ug(*1um zbCSd+4M}##qc5#wM@nxleRpfv0k<52jJ@Y|hLg?O;y|YYW57^7sL~z3^f}VtyEJFj z1a$8+14hTeW0w@=%KCr{HE<6~@Q?(pr_gh&AE}1d=}{JE0iV=quu%nm{OxA#!>!@$ z-!P<3d7PPQ)Xraa*S&8Qs?2d$9I$W6JX7M3ZJJj+{aK+3e5t zsNYU;M4qJ{B+unLY)xpMduB|9zUO=^S&Eo^6V3tT8J2)0eF3)_tX**w?4Bc)D|fy) zNS!1ZFJU`wQd1^L(zIsU$a>u!sq zB(jHJH|K)0-}|=TShJ2Zr<*OjCS&2~7dw|Lgny?AV)S5-!a;U=pqvA@Shuoo$-frTwjn zGfxmu_JL&FT5NjuehN;C3zlI6(yX{CSY1SkTl_JfeNcY|(iyA(jZb}%BpHZ6DINQe zI^IKA3pVXz%{w(L0aN1ebWrh9+`m^c2FtTI>T@7cM>^y=p>ZTa+*H8n#*rEzN9{K6 zs5tYQX9}HEW7HZ7p4^~JT$q%xg1gm0Rwc$#3hJuY44j%q$PBVOPB5H_-zi`EfhhVL zU>><8ZanaQ@s(>LBXZ=-B5f`yemg3hLFv5P?8EO*NR)!58VR z5A>%FVGPy^8}GR=<3t*}cJSxcVbhb?Vf=%!A$v~WYJHcwU1@Ci6eFrP_wjEB=N_KE zyX%@UZAtBB53|myHxVe6ngqW{H5^4b*q+o4ZGyslWMObq00#npH|R$-M>^N^0AXA(}rx+I2x0Lq8*yXfGrV=l>AM|0IzA`OnUwy7hli z8RsvY8`J;wSO4Z*-z(+4w~CUnYnlU7&WfH92Vm*JGq2fs;(We&>^Ib!Cs`2` za1CM;t}X$nh)c5Pr)(m*AXKMNe{Rpu&rdHeFZbWiFVEBG{`}|pclq3PRGDc>RSWgsoBV{E6?_$cjOTEtF0iL#IM$B=*+t8wt_bLE0O#)Aa&k{kXTMO zA5VX;8xQJ4{**zDP8Gsv^zfO*r;3iWHO!}KSp1uR_M`cGbR>2(5E-p|9p}bK(0rCY zm2FveXa}NSFFH5Ts)1#DY;jYmM3LPB^d9DPR2CPi?azA0-ZF_Bz3Bjp@`pb|O+iXf zi6p)0K^Bhs8@4kNk3_f)Pn_cVgudi>y{e^GKD#Wkokzi`Ux$(Dq z>DBN4N%p_H3^B-q|M}?7E&uy7u||f_vYK>61d?I7ha~k5lT@Ik6P_Sg-4Y;8Q%n}j zV73EG1&fd@kC4K|d0xYaFfMy*vw-2Bas9d4ESg%HHT8|5gCM@6AOoR@A&O#S5YU)D_4Pj-l&2=H~8RE5Bq&c^VKd88PG;DrtNmL zcxvMF?K=l2WloD($4!bxah+Pn&T(!hnL;jtLHb~zSa}_3Ha*@cDFQBWkNnLF>EdRn z)Oy{BbiNViNEio955Lk=^mcjiCq4xj6@4zYz!}$QisGX+r*voqXZ-c9R@CMVg0lIA z#Aq=jX3(6YHEBb#2hwrBXkrCy+yup(GPI6Lz*n2HCi-g(i^1n8wt(lGRhg_}S+(q@ zt$oTlE<(%e^IvZq%`y^*;^U2~JnzW@P&WgOk0s_;TYxThOLuFpNmatc6+`xB(06@x zug+Jh>7aJvwJHqimNKa6Zj)YhD^5fkykv*Qr!<5mFYeIE*_4Pe0=n>v9m;#KgG{tf z=Q!!>4P(E<=twl`H+EPfDzQ<0ZW^yx6{!ySkteK3Ga~(!WF+XD z%QII~l8I#4qBF%)cL`{6Q0PRZ9Ag#e7hR}uO?&@jj2U0fQuvR=@L(p47eDmC4UG;g zo7NZisu7v;t%~@BMvtT!$M@lV{{g6`8zjj``Dka56)zjXi{*T|#IGW5O}4dncaL%L zJav7Kf5D#)6Twp0WO3^gL(`-K%t}ffj>Ucn>$DeK$~U%Pr4m`ZVD5jON6kX1RqkPT zFSNSX7;}pE0a$B0KAw??fpU_RE(K`YwqcGDmbG^qZMx|+I?wA=vt?=O!S#?B>0(f5 zH0wU_l5bzoK*qPBWlJ2wo8}DM`fX^^VUG7LoS1l#X%@A5#S>*dMXfD%#sBMqZ}tz= z0(yABEuhX~PgF~2=P2l_J*O*-7IoCN+XD6QLRdENL!1#JHJM6ic4@=9^jAm)^&0+r zq&u6mtwVxricV-Wn<~kG#>ZBcKp`erzX$dX5;lPxrNyH=4A&y;+_3FvkOW;^;QMCh zzewY|tj@Uy@`oM#iD!KcwNz}`$2k?9TQ%+H6BStM8T$59ne6n6!uPAx^T3lA2Vk3Y zZi$0MBA#?IK6QLfBfe5BXw_NDpaJTRQRh!8o2)~Z7GAI<(&#`|2=Pm|Lb|$5yEddR zV6-WC;9VGBOb9Pye5E7Wl>nM;k!OvI?y2i2o-ElN;&dXXf-YG!(7-EIN-TBus2-%S z_Q8$=4L?9g1<4T4)ME;)$t%QvcQe*y&DX<@+kIO1w5L89Yl%`_d)62kn9CB4DsL&Z zS_S$;j6nxGl}~R(Uuiv)UwQrKj#CNgTN*FoyFl}JE5aw~(+0FR4lNB8j3 zR-M;$vZD9u1Wo3bnLy5K<>bs)dcm$CH*!~ZLEWS&%@RChgFtS>ZCYdkJ!q9lT;Uw$ z&&H$$5vYj2F#dAQB6S^t84ig7d|`^R1yV;GaWn(fh_s(%R(9KY9?7jHxhqLsr-lj2 z`cS;8sFEslpVe@F-cp6i4HKFAxb;;ZqlH95prcV|7uY5ZoGuJ4o~e9I!tWLP-kIT{Lr=G-2E(%*4)S2UjEyKDHOw*%B1PL|I|OXzv`c| zOgaUkXdscKxyEkEz?s#O^NI0+y0H$2nQgLE{(zr3y1b8&*Jz}tJXDq9jR~b6wi8)c zhh{@!F=>Dt9WCXYoqI_7zU(Pc4>XiaXNKloJbdPkBUK!!&W>o^wzv2Mzw~oknOGTF zZqH1Gb7M|UD&H%G>B0F53Z3TOvdfJcE$i<=N_s}8xq(?97EYaym}u^z`E?(J;0D#) zpi^IQ9qUcHK>{iXfDOfcx!+CRFxEU3PQC0y^hO1n8x5QZEZ(IlsBf{U@g_f!jV5i* zOQQV+&3YvJB^gxK{pN@VQX2G2RFHmu{d~u8xqpI}{5)=Cp7bf`vai@2SQi&pKtCBW zXk2G6bVUW-CkE}Rb!SPnvmEL=wbK&dk#na>+#$NpiW!$XB5E4dsGIio;Xj7w5A*Rc z3=^65K-cYy(w1yGkLAgjl|NRfJuZ%Ex!eskm- zfKFFGO49I_FwD$WzMu@4n2f4Ow~4YDsUM`L8AyNi*(ahcB=lqq06dA7&PSdzuDHZw zMEncqD8Gp59df1oemZyQFEB0{)oZ*_LP>5?!`#1kn&Rr~7O4Nh#jw9uhjH=${P>s9 zNA90EW!}+fd`4W4gT)GdrFD(SJo+ux?HR&-QNl-vO_K8$sOsx^1|r0Z&CU~=A|5mx ztr|{NJe#~KSko@Q>bs}0J589DujwS~geyRy$p@DKo6QaJzeO;dmNF&#Fu%Tje!j?@ zpET@D<(z^32%||4Kzy<9_c1*G(!;YUaf*ynC!G2~yI2zC8uELXE8W%^r3?N zl?e5Cfc?_l7i8i3#s5Sq--NVsp2C)S>n!pUlSd_~%?AopCT>%9MM=3Z2slh;VlJl& zlUnutT8VlcuC};-azh0hLHg+L`z~%%{*sntQ9%-~b{%Mq#BPVQwjn=3LNAg`DpAc7 z?Bq*|{P>eE{|(S#TKHCzZi$sOnN%tW|liV`Sm>J2WnN;LpI+?~sry4cj4QzsC7 z&;flhp7rqnsF?$O8!{n715h*^IYZSEKzrSRygE$vJAYz?q!uYOAF*y(GUpY@(LO}RJq8=&M2!7Qg?TmFuQ zg&fcsB46unEjU$#XA;W&+~n0)bZ(1?4=6N00?+fRqS%DGxN^5DO3)gGaZp%&cbMaQ zXg~&6emwHlf!9ozNN1)n=Q5>w3sSHfs9YLLP&amcsGAc6;Fur>T~xd*mrkRgL~-ZK zEJ#&D8W(>Xh&WPvNxxT*QSl_bG)d{`o*$-&nH{F7zEg$yd7IzLq2S`-8{zU{A`c3a zCSX&KE;Q?i2{BHd#|%@J4|V%0&iT$~Ju$2=(nsTlU%PkyiNsHqQ9$pOwxr|97GAHD ze4W2lVSewpq(foOVYrx$%>4y|`p#`UQ=AhtZ~~_2JelM@)j-ynb%(7gX4|2cxJ9+a zs#Ao=pz`vA5FxW0)R6wL2D1SSH|nm^0SZs!d;jj;_`c3XwnBwwZ&JuqMTuAWbv!~^ z=ryEO)wFHev_+pFjhTUaO+yvi@e+h$(P(<_(H30=`gzkq2Y$#cKmN~q=f0&E!Vy)N zNkUXk@$Zv_*K1>D&$-ntcrNq`lQHq=3;NzVKPYhpr-EDR$bkl0~ z{JtgAZC$7#I{`z#o;Ya}q=5s4K4>Bh@g>qF2iZaUCn!StH6#80`rboID~y78Kk9g* z(D|CC_sGz4So1A*1yhVVNI}w!u|e?U(G155CR(g7sraAPO-dsic~~bkXU0cA4E>OQ z4guXZvufcXG(`7>&TqS8fY+dhTr^UaCV)GuvW%;6sK--@{eWUALx*Xo^K?dv6a))#)h*=*CM zf-Vj1n&|MwH;Sjo3uZ7O@NKkFM9_E<^9+2zHW`GYB@4~ z7(+b=ZjpDIfTsG0pX(#F!$e5YS#lrGnm8^8PV+Mwk)pE8L|%d^U(v({+=f&Y&T{?+ z(C>Js)cZAFxP0T2!bh~fNTet8+MA-3Ppoh>r+R0=4;%WzbN6Xi zu6?=jIZg;ay-q}{Rh&I^+fHxO%WqSz;7Uy`?@F@1D1+4f9EOHzVw1s)ul^S1_s#V8 zz8jvOpYCJVJrR+m86{2Rj9%^FoFodSj+j0Ex{0ma#s>flFkNEc=pj+2iVLblswc&yt4Oz>j|T?G{yQt>LAy6vl=Va!-e>4l=7OxE zj4(CYVeVxz=S&$>ww0TxFs6L(p_u1+H*ADDC!W(bO&Pr^)L|HRMzi{3sBN5pME|cf zIr);y_Xblqr9zRDUk5tV|9c|n@r(q{qnX#)4gG%`5uBm9=eR>5_fp!_GN+V?gy57` zfkvDD0)fzlE2?#HRALkp0ZHMMn!+iSXx~QnRt@G}W@q(L578eGbD5$Gzf_)_kYz^7OjZoP4y<-6T4c(Y57}UI;1dYXo6X@=XT*+Srwt60s%tA%p$NW z%CUw`2tObN)dKY?9+%XiMYR7QxS`;gYUD`^;L>TzNj)(CBkvfubg}S!z{T6db5`G= z>ru=Wi?+-*r)K@G47-uc`m*n{<-=&`9c88{JZWXw#Xb^j{%8Sp3#!v`|Ez z50hnXiBEht-K_!=-`}Rn4gS>oTlRXAbgeMGz|vZo7QC>x@4(iK4U za*YyaU|>Lh&P__6o!Q$xlTNB`6UUX>j$ z`Rf@dYSz}##qXjI8@DT0eF&U0(gmIU=PJ-t8JlMA4_<()=P40gA#{>RnRw4ijRj8c zCMAtFoR!bjaAaZ&MDsh&{SnOIriEX_{MvyTPv-cpM(>^OAvO4iQch%A>Ly-q(y}|- z@6BeQQ46vJDtb}HxSO>+se`FoNgetXW5UBf;IKKir>qXVZNxDbb22XvLYc2<&}@Nu zKI*oE@`5-fQ*S*0YEsu@3(&*vr{!~bdT1)(fW8LpkCMOi1*0j&^)x=jk$xYTlz)n= zG`&|FakjCtlst+kz2M3$>m9&dC85ril18W;G=v*z)X zd6J^Zq$zuE%yM!nD}UOO&8LSfBwU4|vRK$I|1>_Nk_vVM*7#C=@AbTf<#Z)BqaG*Y z@Os`q-w%`d(w-oh4)bJj6y`~y|7{j$}$^S{h@|xJzqI06bWW*eO4%Bxc za|1sN^kf$_`A=xqApa?Vflu*ytb!>tc~F?hE`k1Rcff7!U;`F8cr1M)Oa7wqr!`_ z%i)_}r(33_2f-3`KB|s&6S^{!Z&RtUe()RYxvDwT%Q)%CQyE7K(+93U5?m3Anv{BM zx}b)cQ*E{EY%2l)>@rq5&aDW6v>-i zXwDBTYU13mlr2fGehuc9xV-K?Hx(M!(%t(&Wp?vhfCloKJ{TuJ@fkNjTZgbURPy?` zL5<=$(g@VrB}eLLti1*3vhLWGJ`aja?*9Ae^okF*p|K>(&S3~gfo{2Q^j#5;m?@Fp zj&$FRcH^c2s*wZ^FQ^UZd{khsT`zv7-=GA!5-ms*jq#tMPvTSk8Zb2%tLdi;+dxdU z97WPz5Jx7G%K7;F&Bae->ovS&T6gr|n{lv5Oc7@=k=P582y1hJF{5M+CJ|+zX7?7O zwhWD3(Jh(AFfAxTYyv+}(v(Y_JJ?fx~MP+GJIBI_ zzI^1VgFKoNG>T|4VsU7ueAdjM?$!X4*>YWUcpAr-VfcOZC?%0WNt~ZCBq1`0W!=px zy+d8u6_B4_`{|u?2dasjkmThBbaZSVirzP0xTGKqia*wYKH};%HNm8Q9TM*jebyJ9 zkup{g55gTwHswgaf%Nlh`o+%|-S*U4()GO`Uu{2jR_fR1@#!_F*B5{P{WLe{PO7N3 zq}#Bim(L3KRJ^mj;nU#}nJ+6i5(*$SgMt;r&7%X5ei8BSXO=b>n>~O^XwNk9 zC>f&)pk?Wnh8!Az4&I1~x@ZoU%1-j@gdhr0eTbf(fl9yA ztdK&@4Yx9;dr zeouctl5n1w7OX+7(H#MG>Xx+HF9TiU-txOQD14-je3bAE#dXqfW`GDa{ygnd>e+C6 zP`_7DX_nb#VVZ7?VVu2_n#yvSZX{Ghnatgx_@9(L;v*_Fm}?|Um4!0-7}7XK)u^Ah zy*;`dt6}h)@VsoA6znBP-Q&rmwgu5YJDkN(7~tMKN>r%D%d zL!lTGCdzc#0yg#MGG5*Iy@`L3pr%EC?)$nwx3$`AG2JF;yiHpkl7zxFMYmpVFln&s z{OOBtQ0E$)UI)$1B>z+*m4XE7`4+JJm9h(O_BqfQ=@Y0nUdJgKb-V-N5h_TUal-g@ zj7x2?{6)$P{EE>}spCwF;%?7#&cCz|_|TaTNYN!l{QewinSqM`kpl-{4QS;~?I|eT zPn6f*IyZ8qW^Gcj#QF9Gv%HQdHhsq&n@LQM|^_8PK#_0*sMH8*=zPZ%jr!Dkn0xRy1KJY_3(I&(kQz%Yz~hD^|Ss! z6VM*JGtJ&M=?~OJGRWam6q9%Y8xDY~96+@IwL_RxlBZ8{s@(z5=6BSfF6vRt@v3#IMtKVk~cq4jxQd*T6R1u~mr(mG5`4(XwIKDT9^2e>q8*g@KOnF+AMEK47e%G)X? z1vNw!=;zJJesEN~?Z;QQ_$GZc=)K=T+E5i2{~ebdaY-PVB*jC$5~{$6cq`PyE6M>i zX-_?pGmDXlA`&=>*$lUbHCJ9Z+S@iD_R?ps3opcAcSpRdd{EHZYwSVPrk}nrNJaJQ^9UK2joeM}S(BtE81!sh|gztro0@mpuKzkxYS@06<0gwQf6nU=4Iwl*zYR_01tW=CksYWa*h5+hFMkbY zeej{*zWlBI5$H0Cr(dD<#PH>34H914TqdnUB?--2f5)J30{3zP{ILiX1W{lBH$CHr z65vT$c$KNhBQWh+MSNi0#TVG@*gD@D^+$oC8vhi>D%{L86-Z2xIqQpG*{nNAn+m4HZGi@v_@);6xNE3Bk#PJpK)r8} z6{+bhoBFyPb}geaM}CO+W26%8+wo%+&)7`=?3KxRsS3<|102wU9T>GeFO5-%PV|O9 z{aNtAE@!FpEjSBx#2M{WPqFFmbzkK96zM$uBp^{>&}b@d!Yn4W#9|hqKHo@nE`j_k zK@vPvcLDPAX3Xnr{O>ZhQ^x$4$)7jloN@o<@cs0jA{$GuR9V+G<&ai4CC~q#FBOd^ zlK6+vU9Y7mwrWu`CoKhiyJXka4bVubj+qEhF(9&1+^vd7EZF%~1;vFjw=K+{0%opD zjBZopDSmPJP^DtDBIjR0`$ZLQl`QWnKND*o+VgW}U|K#+6uXV=HlhccokAZ%vHsD8 zv@?4tP)eB^;?IEssrSPek0F9694ISo7=j+3bSGY|l~3})j7nVi=u#Qm+cNws2;k`f z=-Qxi&vcbo8A32yUsbpBgcuLp6(Wp_IRj;0^dMY)S&lS`Z;y>t>;8xY^ z1VD!|$QshKtZ$m&*?1|Z4uD*!_s|{fY59w!ieyg!<^Cv-Ud8z}X^&?C-#G{zPHuqH zy{f19&k_kdDicN(u1W;P+I!%}c+~>6!p$&jxf%9>ssvOmQxTd{RTwQbLbFR%^1c~s za%mDcKhI1Wk;0C@E^JhF#$LS0xm&c(xcFKj^{dOB%D7JQPL;RPrr*0*KlBIw{_r0k zA$&Z2_cjRi%u$J_oieIWyX=1ihrf>jd3{{pEd9Vt3BDOo-r(cKi zv(pwB!t3jbg-x8&>(BZh7UwGZD$0Q#R`DIc^VB*_9$+2nKqPT}d6XVLRD#8Th6rK< z(tyQVrMUdK$m$AJph*?%AZ8720*$u1=%cJz?oL%pYp1_w{m%dET^=ifRp* zuXldzCxbFlp_g#g(9EgqNQ0U~1y{@L3J^0qy#zJu?m}Je+#NL#xtk5hx0bNX7f?Ns zF=B|*`!(3bZ|MvL1TA29vQ?Q)%oCXy8nsHWyU*4H)^kQ{NEs+l+y?$|DV`3pJ_)-w zY}rH>yw5fu_fJ?84X>oxGo|np^v>|-AU><8tfn{CWICya!}XPFEUeXUkI3OdnoSgx zEt2wqMwPb#k6hpirsv?ni=g~mZ~RNN`vDboQUhW(W%O*&2Basp!K9z@I$lmv+cfv7 zH^}GC!Q5cuU1g9FDmJTICeP6sLgRAa;QstfEZj#M;QcvXgumW?578@7C0Ak_U13HZt(|-agklFI;j+42_r2^{)L?KBkhrh|B%{64aI!!t$2I`w zkLSSEiuA%(LB{oWjD>Z+1cp4&nSQ&1*+kd_avAIUfLpcGENY2BUAM%7n(ovVpta*P zYzh~x>hCrNEn0nX57n5zN&K@5E2pQ=B<@(}z)oOLQlKM&=^X(}yWtiUh zZW#OS^`CM0C%)bPgz+DT^46Lo;ndd_(|7`!z(~3So2~%awcyNBA(j4Ko3xf71Aki^X;UW2==4s^}a=@T}3s?uAvjaKTbPYv}p zrGo?wsqm9uy!|rCz_uXekJ9$j99MCqDH&|28WbS7W$X&+V$%*K_U;pZ4!yPjp zv{QGVr%3_2%&)VCT7*&pRINprwli0eW@a={VEV2jbzQzw`G^9P&L(EjbD*a)srLt`XVWkZQdBWeL>7pRD6Nr_ z!i8)?%5Kl~s!vhN<-Q8KQ5^=7J>05Lo_^l80-buQuGMfJ$0>oKzwG-{D-enn9p!#Z zSqL<|r(R-0O+kFChV&7>sk%@UxqUWq4r$3FKid@+O%s1rkae1jM^1jqr=p({;c5J0 z-62vf(j;9g(lU|?B&HrxaX1XG58P3n^p_&s4(gDW-TRPUbj52LpOUYn3weU``({Sj z{}&3X%Fny9$)x#-QU{e4;!Dt&Pzq(IDh9sI)LS8Sd`yM8)h)W3QfPJMt4Xm79MFRLbm(_dolSAjdtnQ|K?yyNWq=CD-{(Fo(#$Hmzc5)D--8}0 zG`4&B$YKzA+@fLQUe;`=tD8<^z)<1sob8P+S_2BGL^++^!5UPHj^N}@nUCJ?_*!!R zc%2&6(eXkp5PB_wH!)>~WW{bT8U#NFO2TYz+%P^IUIL92gdQvv0WG1{6!v8Fvq6MJ zja}cUU$;@+*EQgC_J=zCY-+U>a9YvB+!gLs1ZsVG2dLX7>e~VOhR+jyeR{qKM zvP7}dXh{hRM@=?F=~=w8oOv|9vMISYWHS{~l^?IXiLW*8XOax&h!0+PB$KEvI ze4-~*v>*FMa_o3NfxtI6;(n;XJol_EEV|)-sD~?4?>Y#S;uD~~;KwOJ z%@qJLsT3_xzlc<$k1t>^W@`Mxz{g|Yjnh`tZWGPxp&DHj0t>=aDqCoIYk+*~(QIS- z51wCL{qW#yeSD=9*m46}ZcK5w^yYAxCa{M);V8S_-W&|M%fwQ|HZ5;sM&z2h?d#j1 z&PTYJU^7jlwuacWqWc=LYFqSMxiWQO$fylq53w@V$4B^T3{`<38xOCQcZbLK&MloQ znTz&cSTzIfx69weoT?$-qKW<~>s&54nMFaLi0A6xul|;=rbYBJpn=V~p6I`Hk+mw= zJ*CZZ@zuMkA#Jf445~Aa=aO~2-%0pV`tBGih-!m+7%JPLejLPAH#Of=1`X^Y1WK~< z?d4j-gk0wh@-1022m+MU`h^^)n;^*G6AHqyX>r%9R z*_ocGzaVxB`k%mEm56j6uu5)fB6{2+{oWwm`q59tPy24_L6LgtSCG96@y^Gby)JEP zmpV1LN`h&!sc?wx?x`>p6s9eye?d_9rE@O6br&zFxg9)74280?60PfOi4-qX4d{VQ zi*5SI(3*#qpd?;zZqDMlCthb1RBIT|uczE=^T^Nw27%(U6kTeNQ5W4`p1t_s)g;lT zI@0f4Qk^pu!)_zsBO|s72`kL2YvRo9wqVnN>aq}41K1mROAEZd%KFz3p(d!VSLpr& zTT$`kN2qL{8lQWW>QGBme!`po^joOygj$xm6hhfa<`_RR|2Kpy{ z%rw0c@C)ON?JmcC)Cq1V;bSls4o(fW{Ol&epDbD2%4;HfI8CCJ`Be% z>Ld3)F{=ou-V$84_<{4PNY~M1bpz6`Tgc65xt(GX69@0#)VRDFu5I9_Oo0hFV3fv7 zrFmL{(-Q`n)i3KvX`}ug{nHrMtsjRcs>PL}_!-iIy6b&81Xd6!N|$;R8j)^3=Z|TV ziZnf@AXdO6nBZa#Ypm82w|fg#y!rFHU-~D5Pu!K4tU7DX#2YGDa8_{tg!4Uy#H-ZZ z>L~H(`@SD1vY*{j+STI8%%H2ls}!GoBUVU@3_4mAT96K7H}p><(Uh$Gz5Q!SHVuHL zxk`s-&t9)ilv|P~`9zUM#yQZq_HX{3KyH+8kJ$9u^alb>e<3j;RMDCm4LTS6g6@)b z*9zz77Uw4kb|za2{P`4cw~83w6DzSh44;o%k}>`1(Mn+)G#z;HL~uH_yh%xB@YI-a z_~T=V_j2~0HkbdUsRXs;PSBbFin8ePvjQK0x@m+eD3#`tDAY?Si9?|G@#!Az_mZgH zGdS^*uK;U7?!OMTT9c76(kwO0nW`>s(dhSiTiA4+kHY*^9cZmLX(zdRAt*&hBDhIqS9DJlU<25* zahd*n{#3yZ_rJ`lWdamx1A7DZ&6>LsM2Xfe45-sRG*Ih{<WJ>bLoKJG^hFSk01=lypgX zgUKPm*WcXyk~DXM@+WnmxTrMQZqRt8^w>Ygw<(@__vS+A<0}=KM!oq(mFv8Y^u(bv zTyUv~#QT=Jd=zGqb=Ly*2krDN`?c@;uxd!DD>qLH3b+P3%qSN=fZgm_eQQ8`1Dom| zqt0WA6w4?zG_I-+1K)*hi!_=~J--c>J?l=MetX%gqLvh!ay}iZ{-JmS9QRjbV*YJ` zYKjh@Vc_ZC>rmNfiX~xrZ6V()4xuU%AM;I6PjV9vEI*r}GF0O;P@&?rGZAsI*#x3g zL*rESU>&?x#hm)8)90+h@5{E&=wA`}kCOaMF+psQ7`~$CyX6YNkWF-2`y~XJw!(?M^8Xv)35K{K z$Kh=zQlRGP(O)OkM+-%^Dg4(?6{nwPR8=QPf3)TPuUx0w_o`8gkf?PHIRTLCWfy9Z z`wgbhrg|Ld&PHv~^$d;@0T};@-*FkGh%~-XdOlKqsr~@x*M#$Dg%ds?>ZaNZF`j;U z8;$j9@ES>$;Z8|vzs{_QRm;EHw*0541(lTEBgbaS%fIOK3LPcXt0t{rp10pNBZ(`u{y@ueU0_)`zMb_z`<#rIW0$ zjLx5hJef5|Sd~lp)v8T@Ao6*S7@uBLh*&3>)J8RQf`lshRzsh6Xw8cq|h_h5?A zwB8ISFl|%Dk}AKrQw``pH4m#~kp-NHYO6?bq^8((;N-ePz7Gbu^H4RZ6~v7y!Tg9( z53s552Y}P628mOpd<$A4eS15i&e=0;16lbr_78P34ErcP`&U9$K9wq4paM%cpQE_+ z{^t%Ak>uW@$HKKLgya>~M5?N9_0^9S?S{2)n!8kvU^W%0sf7|J-+PQw6nT{bs}_06 zs{yO`%AucPPpKk*E*+~(_vJvLL8^qs^pudijY?B##S>5I8A#;R2K7Yczdnf-`JG2~ zzsvhXP$iKQV8p{f|Ai~)l}H5!)u=tGVoo64=Os9C{Of7Tnfnvn{b*1U#guZ!I*m|b zz=ry~t5`8?zvBRG!m0qGtyMFvt7<5lkP?AN0-~9|cn0{pYGj&JZUB7ipEgj}`L>59 zXaaR8f=UBT)am8`_L#4vf;w9_`YrK20MmZ4 zbqiiq;)kH#?<(Gt4!~hlV?Tt!UvRLwZUwUJ(HS(h$XIZo*=q@nK$jxW`%Xjc1G^y2 zrm7ULdQZ)YM^IJBx;0Hu`$bxG~qYstOOw<=3^oS#KXti3%F? zXv4>c9alqY+u^jT@-NC3Xb9+uRJY?Oxet(tU(v2qzpcV_=+UJ}G1jK_`=L=vL!LG1 zD2JjLtkf!3iPGgm_v(C{@GtO+*!t?qC+43d1LMfMW@Dd16{B7uje6Cus7mYquw&E4 znY6g{G5Q0Ws^$^^Lb>8?)rnH2igRnyVf(`)Z3{%EOr3uir?%x~>NxQy8PzpmJ)zP> zHQ3wWA2O=SDWK@E@MuL9{)!YtP*sO{viM8faw!2kIK#(PHMc2Z7}aQqRuzE?XQmA< z>y*}U#>Iahhr1cQF+=K7%mCRdx;jrSIW=b6^$^q21O$D?{ z?sq&=eWp`fovW)vY7=t?m_A~lqJ`wUl=sq8EiF$cRe|PD3RAQ9zXSpCmRfZzv@}z1 zCA60ZO7mwF;|V08ond|-z@*kH=f>g1j4zxztK_NMH|Ys|LZYMqeL`ZWLehjSe}UDR z)UEhcF)6U#6&ea{8U4Rzz~dkMaE?_ThE?%}^6`=?B5JKR+cexDr*sbU^Va*6J9BK+ zed$f@Kl;bf-=y>oS^`wmg+Bu7b1kKAPh`_aZ4P+pPl48xY0-^~PAORQZL#)6*(apP zzXfVfgA~*C8S13;4NxiXZ%OViUYPL;;MHlZ*AX?bC)I#{?X{_Jm|=^wal9YXa}@vU zBAKFjG9~f+qC8o{`Ewh3WGVNZ{PbCS(2YPr_Z7{lZ1niJBc%%(f{?{@8jzkq++X~* zVNYsMS6#d&KucPjC~i~hX71!VQc!%&H~qw<)*mBnNT(#E2Ceie1}Cb>P!~weq)^&| z6j`*%Gg-zaPYzU5Dov3dg^Q0A=2G}J<^5?ckIyDhXE;A^zs#!~o@{ZDPKRh#{j}kj zhycMTC}~9zLg}L7hZ#_ZHszW{3*U62`yUptJK4#$v3dA>UP44G{;SDjo2pcvXhHf* zYhS8;KCNGYt1J|gc#ej58a*mLmsXloiKOsx(WE<{ozCxiWjYPfpph2r-W|#OFr-DW z2R>S9Z*`yzg~@)s_;r$BGO13DUh(C(wz#AG`YDzARtNf(n-jSeH|gmW(gvm+F-d)k z9_<`_lLl7ob75+vufdG5o=kJHb9w4sO`J7l_>hSVaP{LGC3!}oU?Rsgi}Gm$(u1{M z+CRe>uHO0+PagVbDa|AOj#0C}uTqD43)F!AbabALAJbPf{P6y?N780Gwa|umOL01< z%=J7Ue3Q7n&SBzSxQ%b65%GC`#*HeGOM7~jPx}Xde~N-R(Wvq1c=g*p6iI##HF%rb zCmOctZe!Q!d8*%0nKK)jq|xc~UGYG1BJ#LTH6>5#K&u?T!{&}^=t(D}N!h_@lF>Vc z3NJdo`fX6xK?x7~z@^|XCr*V#o!3$0oPxSjk>ll1Asv&#y#}b7$IPz{G`}t75^A16 z_YA71ohxjrS*4$HXYiydC~3(1XxY=()SrC$Ii*8|@HxIuUCHb^L1nM02rW>nWy#R5 zW0OWYPfI-X4(*;r6va8ygC|$YC326NO@EIvdQX4G)d20=(dth#{<}H^ydgn@+b2F$ zGVn}K2~^}NRLkP`(c6dk2#V)p?)Es_rVUMg2`EBn-z$xIzhX8iVx4K7;^`MujA+3+ zZAofFNcB7#QKoq19bJBpr1395nJ0yTQ9 zO}e{PTdHPR=G8}!1}d+`HB~r%5T8m3>2sJBlZb))H={k6{ zr4(f|VD-y8l~fa2unvC)t=>#GDB^U}#OW4Z-P`aS|Frhmt!VQr6^XeaDY{Y$TvJx7RN-`x1#_sbx{{N-@%+jwX+9jLfdC75$K_izDKbe+aNHBDHbwG|GQ z6vN=c@a~>oG_hs5ne^i_R#Nsrb5D#>!I#EG9ntc|p~_t1t0Kkd-1~HO4!e_Gk2?My zBc8#<4QqKPA}2>r5x>qf52rYPZuh&!Jx@2iM@w>AeR&Af>auHIAEqTOViZBWbK1%y zu)(CTzi!l@n|~YUlq7KvJ;c*psoK2Am5@V{hn@t zH;(v>IYsWc{SzmFMz?ezO2;CRRxCeV|57#?6{3^bN$ES*?R~ubb0!AnlPL zil^W68PxdiidpnJ&@_pXTz-a8dZKge(|Fg4=cRi2Pl+_Bc?a1`sJQZ-S~Q}dsWyaj zsQ*b&=Lya^Z#E^-+{f_O=(frJvdDYZFBQN&szI8@p}NAM(l&MY*KA6Mio2-u;U7rf zl@!y%BMFME=Irc>FAcLEEI|RKG!phXM;ZSv5>$Q$y3pt0tG#rkW~iwm>2$nW%YLa9 zR5NKgG(lZX5RoIl@e6CO+S8OtwZ!g)4iBTan-Y=EQ>dZ?&kw4n4Nz}HND|-vV2gu) z+%>bGMVCc~M*#D%FvOeGn{v9(sp3VQ29X<}{z7Sge)M+-kxviR&O?>xM-zFHHKA9| z9bru|YP`w52-rDPF%Y?v9ju*P>UnI!@39fM@=e_&sB6YLz}GY&L2e6A9f^GTu@aGL*+i!JQQ&s{a9`F!5uYDbe-o;tSw=9f}Nv3pYK_ zp;B#1k)Zn-O6rq$sT*Z~i|%byv3vM!rXaAhN8OPCCC1PpmQq+XEOK5Hqo#@JI@X#| zH!4};%&KC(sT`V69Z8Ne0$SWkZi%I# zaew}_JpUP~Hj`8R|9q)V7?H?x1PPJyWR)+{D#9k#U!x{q75ouYJ z(|nQoC!GWoDQYl}?o~p5k0D`vbPghbTKJE#9z|`5I0 zDIPe909(ZpG>AT37x#c!Azj?+j+m3snN&ymee3!=GX7ykm-zIC-0ZC`FaPqgTIxzg zrrMis1$SY1A*D=Zo9r6yW*iV+%NST=%=5YH2W5+Z6Hlnr0LNcY}c|#naT1k zyIA9yYq09)Ep*Fr-;+JrmaycrJ~GtjsdHXqSsdxiyw-sUrx%tpVeLZG~SU&K~Hjw|HIT-b3BW#-FZ;86sf_Q z5&^po{K>`rA2u#Pq9v_?-CX^w*)#v*f!V%kU`{~Wr(n$pVry1?tKy7E$$px{{GY1- z*tqbH=b-SgRe-3f18Pa3J~91#u?F8j=!) zY=Y|IDGU?qRHjeu(L*)%KHGS|s#0&FHSzj~>a6D#6)r;&-2{}jH0p?c6`T*Ont{19_mReK35<01>D653BRw<`x=^E0X z+jNYkA+%xJ3V8WurD}zu0+2xyP%$=HK!r+uJJR({HOvNzZGiFbH3+BZDV*z0;zHF4W#n)3afPsRyXnI6V~rjtVX-%@aO5t-68GfrhTA} zu&xSgJAwqDc=4n~;UZAq72LU@$gDxlk%lO0HvL)G)s|QQeKynwa;*fw`G}zJB2la^ zp8#9t8=q6U_@mJ_2?D5C0R= zO!CrA{P_(~@yj0?N5?B_h%#YA@L4%s^|~cmL6q}7_9O%Ci%UypErmK}dI|i(NLq)g z8whDowv3SgL=%0{RxPtKiDmDAytP=i-U7Zs+Hkfg8o&%)^vC0_EtK75SClPn8Ubj) zdYj`Y%K!DFOmWumfp(w|64HBcQ~^FKn6z|h)S_42BM=a`t2VWzDbsn|R013OKroXI zDw5vt7GOM1!7PrTOmAz;v69eB1E`nAvW09)S^23Jj2=*-R#2JGnw4E!pt?SFR_Qfu z;^T)u`K-FPn50G8QgEb&!%75dT|QH%K!0xYp!aSE*keegAo|Q0t)hUA{%U`SRjbrp z*M!wkgN4(in>0ExroKAX4F1@aYA6>FAf#gW+$WO0VR5cB?SM1_bPn}9I#;+;&HG8M zWyQ1B8VVH(xquy@-yG=56CC=?pO8N>61cl{jnxz`tK6d{McM*$v>5)=Wj#<9 zdJih7bgkAb`g6dZzI>c>>lu(%{$yl>1hoD#x6g#M$OL(vyuf{&pEJ&5Qkvh{sL{b% zm#s>h?wB-rfv#7IOzOBk4Pb4~RBo<3G3XbytkTAOb!!^BWlKDArjjD1i+eT30=m%q zAh3(C;u48U1J?7ge+s#`!xc?8E80Oo`r;u>R~{=-IxCinK`n+o!@AG))Wl1Sf-smg z6>1jzxr%C3rKHv#fkKsD~KZ12**7_(&YF$Jcu-6v8V9~l%LhTZV{w2Hi zYk>4|doe&0i59FG!1UWoYYL;P;t4P`SY5~2Lj17`TQ4N8HL3yV3D(8cs%}m%SF4x? z0qa;p^wC_PWLi%iK%a5|NmGlyyKt^7=c$N6V1T#M>0uHLohp!fLzB z0>r@Dft9#-g+w9xf3#YTzoKCE80yyybxK#EBV4E_Vts~v|GYoF|M@fiZC}@2HtIAJ zI7e3TR+S<`MR?6Os_bsYFQ;E*RqC2eLHUcSrK2yiGc|lHwakyTw<6C9?1Cj&(PGoZ z#|lgUg;@dCF5ar5Myn>Qthzb@G}HI*^v9LnH72F%67>s6ii$ovWKx)C9WPlFgsVvN zbajOa;KBtk3F=uA{fcgt7nohCa)-9{|0nTeM_?(FhptwCJ+Hrh&<40V$8G&=P1aAkDGfFo%8AxHyht zaPMns@>X93dQ`|;3(O>QqZXqJK@fpz6=+`k6UsNeZL&WPR&&(?+=TJpO7}s_VwZ+R zl!#_p65V?h=g-ZXU-yBE6yfM-T}@Y|%!GuZdn&e-P zul;zp$4C#T35!ZlNMt1zdSt!lyHqg&jfm5eB3ad*oA7`B%)@qZ>Fp!kAjJ76Y@oRn zTjo^@f^XE`r4}t<>$&QShks^yk7zYI!8q9`s{WSUQJUP8W|Pte=zBp0pkSf!6Mxnt zGI-*0b6q<4;8p0+_}#0ZN~Eh7N|<(}N1ufEGV@a^R|?;I68z;bRRPo8(y_0hWH9?_ zM70c1#CqLL)4URHP{gJNbv1rLDLw?$Ig_+g8<2k9Ua5RO&U!SKk?HLpd~^1YmLfl3 zfB|W~E{(cerYg8;UaiHb2=OT-NwGe@4KFAF4o}a6dU;#jQ1uMuG*{iZ7)8Z@eDUb7 z)*sun$*SdO)&A##O<9uKfj`y9YZWpBejjK@%>F_&A&pCI=%GJuv40?!V$fCzaX(F+ z^=$DCbE8y{lt`)X(jq%0hq>}gO?Gk|q#XUz?iF<+N0O?)=&1qYBWA%w5uGY7q1;(D zO)J;HBB+Xp`<^HZ%6(8D2WuDy_5Y2N<*3mfEPz6+U@z*lUDEpSEwFFnA3FMHY#>)l zD^vV05mlkK<~zP^i@|m0vxZ{bz&DT;dCo^&gW4eXV5D}FGk8X4V3sKS)QkN-fT96Vy1)u-i+V*;}f(k&M+Ch=4^u?H630BKg zSZT8=`%IXV^cM!~CDi$@-dfaQr;=ICN|ZttZ2!8`LhI(DJUnC5 zicvhjJd;_`ZvVu00OVu2Su-bqDsw<(lTC^$QdC&Gk z->;eK>(drgw?H%qsj~P_FolH!)BWfsNreW`x4-|kzbtiF%+Kwg)7zkRiUk}th_wPI zhLJj6wsYRHvm{eSRracJZ^7K@#xm3J`tbK`SeLJ|t4C}mTyd8CLSZdy4F%dVbVW(9 z<)z(S{&_~6W|}YO*i-ysK)52HSwSqy%NB@O-BQ1FxqkT=*v;obVmKZ8fcmvBnwNAL zyXrI_*sue(hsnn+-WM)_S*n^U!ZAK{4r=A@5NgtZ zF-=hG=l|NnI+N`}`U`~%&S5CErE*}-v&Lr&{layWb4w790;b^*5?Z48`{MCW?EsJ_ z1dF9Gy6~~%m9@O7S|!S@cBK2C)C=G)KdICVpah0(yXdd*#+8C(ow^o~b+5t%<4U5c zU-ej@3^8Beg@iPr!>!5{)d}ky32fmGAXM#_t#%8j{>wGC%K2y7dC}dk&g})@31sQs?AT- zKf~8 zf4)ep?&pV0d-L)ahU{Nas(5~;-c>*Td6(~F|Gv9h%K%%;od6r88xdvz>7MAzZa`CJ zSh`eUJ+~f`PJ-Gjyn zKRi|qBa9iUiZ_6jkOknY&ykA6x7=n_I!gVTwftXR0F+}#FCfN(@aFR)Rd@i9uK?%L z@ngCm&F6jkGIdu!kuF5M82VqQ?I3&Ifa&;)L=F+)=#M_ ze2{4k*J+GXP%Xe=98hV~MLS?YxlJ7*UEBfJu+qn1OOy(Rmm3%$t4FblKw(G*zEwGm zks!XEG`n~X6OD^u45u4)2kLq0Vxb2`w!+0bH9~O)B?c_H69qKeKl{`yH+@pC*%y|_OOgN2tb z{P1TO{`4;*yoLVH+n@NvzCEem*^WULTu-3UjPK4$lSCGTzgmVgLfv31*vZdf{6zOK z=-i_mJ=4p>D6{(^L7+jB-i2sl3AQ70k}fo%HP3JTo8d$sJv%48+-|>?us%=#5*=v} zRPcthf}2=J*l4P#qMX_$=V}9eUC0UUz1a-T)n(@wM+q$YxPgk|gX4Zu7cz}b#`<-F zH9B>k+Pv<=fCy<}QTI!jcd!Re_=z}|9yGLikh}IFO(N}@SEqizX7e5mrV5%^zk0W) z)IM6LUGJg#{2h^`Ks9(2tDwO__gSEpuqU0Ft$IBzWoeJ5L5Z3R| zKAFZgWA1xTGYS1FW#)?Fj#l&x)s4D1%uAgVUtTF4;YMhITxWhtSrfP-LTPXnnPaH* zymw7dhn)|6Q=h(b@v|S^x5#P44U2A%qB+r(RR~Gk?^T?YJY+Wa)k<^{cSm%md+ku- zDYq);DUEwIOa2km&l9LPR&RgIb9|T3hA_UEQK|kl5C7*2_v%)is(a9U(-3<0hL_9= zPGvM`P_s|fsuVU`cRHMYeKIlm_lB}25`wQ~7qu&LQKloexsG&`i^^60Ak#}5>>w_) z)TA3AhD#lhs#>o5v<8}+{jUREu7SgDpL%td8q*Z`)P!~Dnvnj)sESDSFJNV?Z?G#- z6di=3jYbtjRckzP!1Jx@iU3cfcFHDBsrxBG@!sM%8gq1 zf-3ofb)2` zxhXCFm|v$Szps$2AT8}W(CAy=V?Y4`sDmxK zLD~?zBE|+!VNd1W@?Zt-t`e7$H{=4=fd2Vo%%4AZ`4oNC7*fA<*0|{k*mqY|QIHh& zsLRtLb%8qo&NOqaOA270l{E-x1*^P2OZP!}{^(`LwVw#Uj#B(nEh4+tVZU?+*IHBQ z#0!16`huJl)wKHcA(iVVDi6}3*B=evp=_JP2GGmt_gSo_0jqe`q929H?Q%rWBlz3!Hmp=Y8ha6u28ss? zjJ16ILszW7O&PWppg!IvgPTS^cE=O0ws_#`2T7%&QMw`%STHK5R5a>4RhU1w5M%vi z*rTDvqt#bUqFM?Q^rD!jE4Y7!&QeuXq%l?zgZ_O-MqiKXiP{Hjs-}rg4ACJ3Fh!hF zP}GXVr;O&_8p`D~yf-`Q^bC7<^`r6PlpIp^=`A4TugRH!mpeaa7k;cMI zRRh$o&r{#er+?tVYRp9Lj;Ku;;hpztPGBqWf56DPcn1QPfe^&~lxa#Uut8IDkGtV* zsbdtNlld3D^8%oS7xRcX2oWNP?3h54C!(>8OJ zXEtpk)zf$mB2=%Dxq`@=6b$TQRs7U7A@wf)MU?tOZu#t!2tX!PoUenn+TTa*Az)WK^ABQIRTs z6{BKyp6B`foJ02n-i%Mb@2im16_K7)hxr~<`=VWC+%JM(MSRXX)%$dJYuT=p^pkQ3 zVOUC(3vX(1N3Bq=WMB3;NmK2|l01>OXzyi@k}Bv^DV8Qy%BC}>d$2q_fh}VOeRhF1 za8jny4`#YdeE3}mYpiy0{XFdIzayw1 zCKsl~tmoNDa;?@EY`wE9k&}R$CVHqyR&y;C75&gfqD~}EN^z^+1D}&f^;7bdTuM=z zA=iTT%-Rz7BSRfc8sZ-4dRH_msDeII7&j49S8gnj=uQgd{pj^Lu02$<-2oK}<$SJ? zlqQKf!{R9=I6I9dO2VX2d}`0*0EJ~L`pu!LbCPC-B2;}NWLxysD52I_-*m0kO!|3C zbCTnnklaxzyJk~Hper!j1$x3lqDYA{{&$(7q{*x2H$#}9#XHf9F%78zQg#XSB`t!(JrJBgT zJh_32+(E%lRrFchf>ThHvSQEGu=Ejyp1XYgXa8Cl8kT_W6JP!!LoIz4{%e4WRsUyl zt^Q$O50}5et;%IIq$Vt;=ETaX%fK8ZR8lhaf>k%4^dk6k{=5SZ&?43+vuYAnJ~V6M zPgTcQKNqYqDqXMru=@6qh6>84IYVW2$h-5Ks=%r#``0yLg@)dJ!nL1Bx#R)NV_lJgP@Vo!-itu8+T7av1Y3`V)>VC@{Q2Va1cNFzbD;Ox{Vq{9m@&yQ!jMDMqPtK|yhUepf=?9Ph#6u!U`djxd@O)6oOpCfO7*i@6 z;FA9{ibFyUf`tQvmr)eONQ3SlKl5@K# zFz7AWio`>uZs!)ok0}LkX#Zb|+4ZpA~O3RXffQT=^Z z7aua^)z5y5+WDl4>JzV%jyo2Me~49Q_4oQl{k(OH-`_79Km7^Th6n(SUm;MBl9oIG z(8WdNEzkcQV$40Yq(l}Lc$vx1e2QY3QX&YT7lh4J413S;(exe|)CE_OAGB zztV-X>N+k-acZe)!%)wE;*}t{j)Nqvt>)Y$~;7T{c)dGP@>`LHaXM-hk0HD zYRaoin?>qF8mhA#>_YHiluA_U3)asAthezWJ^m9v!$1E#{qy=y_$LfH{uw_nI{x%B zihovKwcER?iYGOd10{ND1dS^e73>Jrxv3s#gdn-MbF+SZX103gq?aZ1; z6H7>2*fr+T4~zj;!&cb9UB_4cx*wSJDO6(l)A9Cn>peTatB*ijed3ezC~Ha*rXdfY zV=U#$bVUj{{>p=itbVQzmi**cHKc$|9tHQ{Bj8Lls$k6$L_(LYstQg9^td%?-&3vA zkRn-$9DvdMvNC0@3Uw8gZ`D(z1oaNqLHKO~U;HwpQnNyN1JKj8 z-*C`0GP}m3B#49r4U@}JTFAY!i&_I%xt!uj4|enHH+6iY^p8A+2d`5x_6wA5R(Uj_ z_$FSre+AX`Zig@Z4D|EX{|4#9J2F(%=l`0}afyo4;pDyNla7)^2axeykA9>QDN9aJY~q@b ze*8&7zEk&?|4{ft9n(3Lag^V=@RJ@5ST$t4^gA{^r3&6D@Z(W+q5?AU&K4eiOAmd$ zu=Q1y$iL)@yI&`lKtIjHth$+wCVCIw|%ms;tZ8>3B!HMiU4(1f(;(e@|fY4W`* zLsRsBg!1r<97vr)O=Ql$(&;CY+7-3u#;US`O=Cyjm)Vs^Co)a^lhR8SE5o!!xw``z zl?dWXDx*&t|2B;ALs?Geih^*e`PXpnyrXRA-f5C${)yy(=(ho4(@)eR8Eq@ey034LS5Z z)og~ZjC4wcP}Jc3mASeOONe)k9{^6R0XhB3-Rd|$Z!X%y|q?Z52wr)D~|)k2Io-2q2f zeWvwn!HOr}yiTfqX$PEdfkyQKun&{73IziG3aqfwM1pU^dQXQ7pY`$I$J)&4UW$A# zb}feK>B@q1?sv|m9^m|;U^-=fUnXEXRe=4%-)fL{OP5**5;LfZjZxxV%?xzxvj;TZ zS^tHle-#Pj^Ap^bmt0>_Dt%db*5%BvTsv1w;4i5I7zGtoIM-emUQ3uS*u%w7SoahN zicf!N*YieY2SF;(W&5J_#}}6?c~?@-kLw}I)KNS2_#PAL?B^(^UwjMK_QQjwh26PR2>bHZuHzeoE%&McHW#CnYpE0_FZs~@;l3Wn&D ze^mvVyq4VjvFcBof4n}EMjZ;!$uWAJ1t`XTC6QB*%JXLu&pHJ9NrOPo6r0#e$jt*eTQqQ|}g;Y|T zl50b%S*~KxtFh0Wl$CBRQ)wc1mvFDRV21A0%`BId>~crtjPz$8X~e1%BsHq1_(jC) zG;Z37Hd*37df9KNI2o|pY7#P}g|9-rpPjhXO!^J=bOU~Z|B8nR*S>J>$u0b)dhZTs zhy#d)+Cqa!$9upPNXuN1O@#S%pouTr;RX=&g>Hl72dK%im%OTEQ)GZhg~AAn+In%S ziu{VSNir`{)SN;6jCa7FKW_A36s4wAH2%49lBFD<)h5K&)l}eGKb-^RBlK_$UMEJ? zQ?$1e(a`IJmK2zlrz%nc@F+PF%gEv&^Vx|gCbp&f}HIpW1#qXw751)Vr zrPn17J9YrV>C?AmL|9A?wvt}-?$`&EIal$FP;pGGJn zP*<{PY=}xKoVrWdLc|M@xPJn5;oq$NG8G zuh9d5MRmWZQ^QG7(+uln7hq44c!M?f|0Kr>lNEKWKa^pMPfNe%f#2H~m+#j-Spc>j ziYi8Gu(r2J;`t2lICTB5u@7V3!D-HF=n`DS1}pK*RknRE*}g-t%`99rgM)9IW-Mx! zO>OJpkXP$byKd!k7poS%;1H;#q;M4{!hskMpRE2CXWvS|5zi;VOO>8SeKg_%<<58}qDJWcX*B@Cnsl9ehmem+e z8S~J}&>QMmAMy-K`g-Y|-DiR2b}e4oB=#GjHkj2eeamgdp(epMB7+n*P@k>kxz-g_ z3Si>-YT5zIPHlu*ZwTCx`#FMYO-f+2KwZJg8FzC6wc#Du2tF~SzCb$3tyFYiI zCoxy%h_tpL)v{qOXF!YR%K0gKRl}J>mvt;Kmon@l8+AvQwm`bng{9`rK`lt9L)EfR z8x&MmLci?j>y9b?N@A{1sdjY)^M_#Oae(w#y~#Ahu!1cg8wp(rmn=3dgue5Q>TVT# zQjkU6K_6~z2Lj9P+!{3QUH+|aRVhozuXO!99qP}|ExS_({Z@NBpk5h17Te)_ zp|}Rp3d3rke z-nSdN;q}^)2w8ST(IPJ0#JXF@eAD6YgwhX3q3!h@yrte}Pz!I{(_yo>2IJm_uu``A z_g38%31L{(#;hXK@0{-gx@=EF+DAn~3gs2HZH?VRHMi=1#Tn~I*H1J-dqsHnKcZ-{ zSk;#CR>(z-Ey&LqE{Ehu4`~|`!eisF*2z9=2DYj;ejO+ zNYs&{RfT6y*S=*hpR0{t99w_8y2%HPdlT&n+opckru8noJt9uFQ;Tk~bf)5&s{w^K zpgeKc7HxQ|jj&I~dEV8;Y2r9e&J(AotAT7kj?mvR8|)rnFb_Qq^!qq*m~sZ0Rh~{wVum;=9zE8XUlKDj(2nskr#n`LX%zFwxM?%IeZ0Nh@7Mq??tv$^ z2}0Q043mpBb>yzeEp|C>8B#tro^Atp169M~=?YXF=u=uqx0tozJy=s5F54EsQJYc! zpZLF}WP3OM*B_d7LQ7QAln!#L+LSr<51bS79M2AO%*C|;vP+sCt{E48AqB9*&@9SP z&ui{+UCvv<6wNM*I^JaFx;lnQn|8dzvQKBFm=>-}xfv$104f zl>mQ;*nYH2p71H|18RNj7d=6-%gHvikC${DLKb~aG5(`g7irZpleO;!a$Rsw zzn=6g$kq27i|*?%%VOoB7Kr(APj{3n)J!tWiQho4k?z_uK2AZt4<>qnf9|9CW8L^3 zMxwSNZ;;gZ63$aG6IsRSOPtRO%5QWCe&zHU0`2dw_?x73@r@1p70=QAx9Xq%m@#z9 zjOtJSIvO?JpPpXte<02NH1{%OF_ZtMRxl~CsBrLi7Sx<9=-0+fiJmZ}c!^@s`N1*4 z%JZvImH9H|I0tMZRztotR1tosh5XzuTzWu?V>@no)J- zHSH+=L5r7zq*q}^bGX#>=Iz|lbSj3?5B~i91K7~ap$jLpfzV?5;3afsEyzx^`m zt^XtLVNfc#LAYQ{=k7|G;qA$YKW6v2UF|rz_FYX}$QbFxE1C#9_zie=ET-k0KlnG8 z9y|KrI{EWDVCLmdh|gW%L$3#M!5-o99*ZFNu=&Z*CiRiFoD4l?9$}5jD@h36={NH% zMAOL-h5xd{$yQ=rn51$HBX$kD2AeMG>73w;dmwU=8`m|id!RAxF7PvKkNno}v_-cO z7InGyDC*dDfmEb)WJSrz`!F@)X%-Z*OD2TMyVh>g5Bt4O7=ReTnm# zq5P)w)c2ALAd4=Z1dR+l)9p9(V>iKy2Pn{37HoR&*Pb;201q%27lP%Bxyh4Mj1>R( zyD_|t=FOxRPLTWR4LPwPnQwP7PlI{#TcfLBd(x^l#mf;EBZZVGS29E0KguOz;{!a?eukOCrh7a`y}EYcdPC6d6Lt2XS*pJ?Iu*0 zX$p~;DE`e#4nuVC;)?x_izY<8-|_}x(k?A4DT~Vu_gXx$MCWa}oP&|;d{+(N?4zva zxuy$l7}S$$K!`WE%*JTsH{(0u(Z=mu;9ltg%-zsqHss+azHon>orv-GJ?Aysc;W1E zI={s)jZP}q{8UbG>65G+`+Vp3j7o=3yKMy5^KiM|C8F;f&_xn`0p`raC{_AZCN`hk zjWH>skcfuw!|*~+#%9)RZ(mAZ21`4s*kn$)_(&B8BE@zbWk(8`9OTY=r%Ut;8Ul%B7*73Gn9RAX=Ha+g`F*>%r%&yG3MATk*JQOWwwOSD1H!N|cD*p`P#r zlUl~^fB*eA<%C^7+@rg&BQn2B-?qvxt)=Bx)Y6MlqnoxcOD8W|gd?O3=;uwnyu9SX eI|}e)>LY$VF2l=xso6QK|NjFqE)HdPaR>l(AaSh# literal 0 HcmV?d00001 diff --git a/tests/ex3.sam b/tests/ex3.sam new file mode 100644 index 0000000..801d13a --- /dev/null +++ b/tests/ex3.sam @@ -0,0 +1,9 @@ +@HD VN:1.0 +@SQ SN:chr1 LN:1575 +@SQ SN:chr2 LN:1584 +@RG ID:L1 PU:SC_1_10 LB:SC_1 SM:NA12891 +@RG ID:L2 PU:SC_2_12 LB:SC_2 SM:NA12891 +@CO this is a comment +@CO this is another comment +read_28833_29006_6945 99 chr1 33 20 10M1D25M = 200 167 AGCTTAGCTAGCTACCTATATCTTGGTCTTGGCCG <<<<<<<<<<<<<<<<<<<<<:<9/,&,22;;<<< NM:i:1 RG:Z:L1 +read_28701_28881_323b 147 chr2 88 30 35M = 500 412 ACCTATATCTTGGCCTTGGCCGATGCGGCCTTGCA <<<<<;<<<<7;:<<<6;<<<<<<<<<<<<7<<<< MF:i:18 RG:Z:L2 diff --git a/tests/ex4.sam b/tests/ex4.sam new file mode 100644 index 0000000..b2282b8 --- /dev/null +++ b/tests/ex4.sam @@ -0,0 +1,9 @@ +@HD VN:1.0 +@SQ SN:chr1 LN:100 +@SQ SN:chr2 LN:100 +@RG ID:L1 PU:SC_1_10 LB:SC_1 SM:NA12891 +@RG ID:L2 PU:SC_2_12 LB:SC_2 SM:NA12891 +@CO this is a comment +@CO this is another comment +read_28833_29006_6945 99 chr1 21 20 10M1D25M = 200 167 AGCTTAGCTAGCTACCTATATCTTGGTCTTGGCCG <<<<<<<<<<<<<<<<<<<<<:<9/,&,22;;<<< NM:i:1 RG:Z:L1 +read_28701_28881_323b 147 chr2 21 30 35M = 500 412 ACCTATATCTTGGCCTTGGCCGATGCGGCCTTGCA <<<<<;<<<<7;:<<<6;<<<<<<<<<<<<7<<<< MF:i:18 RG:Z:L2 diff --git a/tests/example.py b/tests/example.py new file mode 100644 index 0000000..42e7347 --- /dev/null +++ b/tests/example.py @@ -0,0 +1,119 @@ +import pysam + +samfile = pysam.Samfile( "ex1.bam", "rb" ) + +print "###################" +# check different ways to iterate +print len(list(samfile.fetch())) +print len(list(samfile.fetch( "seq1", 10, 200 ))) +print len(list(samfile.fetch( region="seq1:10-200" ))) +print len(list(samfile.fetch( "seq1" ))) +print len(list(samfile.fetch( region="seq1"))) +print len(list(samfile.fetch( "seq2" ))) +print len(list(samfile.fetch( region="seq2"))) +print len(list(samfile.fetch())) +print len(list(samfile.fetch( "seq1" ))) +print len(list(samfile.fetch( region="seq1"))) +print len(list(samfile.fetch())) + +print len(list(samfile.pileup( "seq1", 10, 200 ))) +print len(list(samfile.pileup( region="seq1:10-200" ))) +print len(list(samfile.pileup( "seq1" ))) +print len(list(samfile.pileup( region="seq1"))) +print len(list(samfile.pileup( "seq2" ))) +print len(list(samfile.pileup( region="seq2"))) +print len(list(samfile.pileup())) +print len(list(samfile.pileup())) + +print "########### fetch with callback ################" +def my_fetch_callback( alignment ): print str(alignment) +samfile.fetch( region="seq1:10-200", callback=my_fetch_callback ) + +print "########## pileup with callback ################" +def my_pileup_callback( pileups ): print str(pileups) +samfile.pileup( region="seq1:10-200", callback=my_pileup_callback ) + +print "##########iterator row #################" +iter = pysam.IteratorRow( samfile, "seq1:10-200") +for x in iter: print str(x) + +print "##########iterator col #################" +iter = pysam.IteratorColumn( samfile, "seq1:10-200") +for x in iter: print str(x) + +print "#########row all##################" +iter = pysam.IteratorRowAll( samfile ) +for x in iter: print str(x) + + +print "###################" + +class Counter: + mCounts = 0 + def __call__(self, alignment): + self.mCounts += 1 + +c = Counter() +samfile.fetch( "seq1:10-200", c ) +print "counts=", c.mCounts + +print samfile.getTarget( 0 ) +print samfile.getTarget( 1 ) + +for p in pysam.pileup( "-c", "ex1.bam" ): + print str(p) + +print pysam.pileup.getMessages() + +for p in pysam.pileup( "-c", "ex1.bam", raw=True ): + print str(p), + + + +print "###########################" + +samfile = pysam.Samfile( "ex2.sam.gz", "r" ) + +print "num targets=", samfile.getNumTargets() + +iter = pysam.IteratorRowAll( samfile ) +for x in iter: print str(x) + +samfile.close() + +print "###########################" +samfile = pysam.Samfile( "ex2.sam.gz", "r" ) +def my_fetch_callback( alignment ): + print str(alignment) + +try: + samfile.fetch( "seq1:10-20", my_fetch_callback ) +except AssertionError: + print "caught fetch exception" + +samfile.close() + +print "###########################" +samfile = pysam.Samfile( "ex2.sam.gz", "r" ) +def my_pileup_callback( pileups ): + print str(pileups) +try: + samfile.pileup( "seq1:10-20", my_pileup_callback ) +except NotImplementedError: + print "caught pileup exception" + +# playing arount with headers +samfile = pysam.Samfile( "ex3.sam", "r" ) +print samfile.targets +print samfile.lengths +print samfile.text +print samdile.header +header = samfile.header +samfile.close() + +header["HD"]["SO"] = "unsorted" +outfile = pysam.Samfile( "out.sam", "wh", + header = header ) + +outfile.close() + diff --git a/tests/pysam_test.py b/tests/pysam_test.py new file mode 100755 index 0000000..2bbe8a3 --- /dev/null +++ b/tests/pysam_test.py @@ -0,0 +1,551 @@ +#!/usr/bin/env python +'''unit testing code for pysam.''' + +import pysam +import unittest +import os +import itertools +import subprocess +import shutil + +def checkBinaryEqual( filename1, filename2 ): + '''return true if the two files are binary equal.''' + if os.path.getsize( filename1 ) != os.path.getsize( filename2 ): + return False + + infile1 = open(filename1, "rb") + infile2 = open(filename2, "rb") + + def chariter( infile ): + while 1: + c = infile.read(1) + if c == "": break + yield c + + found = False + for c1,c2 in itertools.izip( chariter( infile1), chariter( infile2) ): + if c1 != c2: break + else: + found = True + + infile1.close() + infile2.close() + return found + +def runSamtools( cmd ): + '''run a samtools command''' + + try: + retcode = subprocess.call(cmd, shell=True) + if retcode < 0: + print >>sys.stderr, "Child was terminated by signal", -retcode + except OSError, e: + print >>sys.stderr, "Execution failed:", e + +class BinaryTest(unittest.TestCase): + '''test samtools command line commands and compare + against pysam commands. + + Tests fail, if the output is not binary identical. + ''' + + first_time = True + + # a list of commands to test + mCommands = \ + { "faidx" : \ + ( + ("ex1.fa.fai", "samtools faidx ex1.fa"), + ("pysam_ex1.fa.fai", (pysam.faidx, "ex1.fa") ), + ), + "import" : + ( + ("ex1.bam", "samtools import ex1.fa.fai ex1.sam.gz ex1.bam" ), + ("pysam_ex1.bam", (pysam.samimport, "ex1.fa.fai ex1.sam.gz pysam_ex1.bam") ), + ), + "index": + ( + ("ex1.bam.bai", "samtools index ex1.bam" ), + ("pysam_ex1.bam.bai", (pysam.index, "pysam_ex1.bam" ) ), + ), + "pileup1" : + ( + ("ex1.pileup", "samtools pileup -cf ex1.fa ex1.bam > ex1.pileup" ), + ("pysam_ex1.pileup", (pysam.pileup, "-c -f ex1.fa ex1.bam" ) ) + ), + "pileup2" : + ( + ("ex1.glf", "samtools pileup -gf ex1.fa ex1.bam > ex1.glf" ), + ("pysam_ex1.glf", (pysam.pileup, "-g -f ex1.fa ex1.bam" ) ) + ), + "glfview" : + ( + ("ex1.glfview", "samtools glfview ex1.glf > ex1.glfview"), + ("pysam_ex1.glfview", (pysam.glfview, "ex1.glf" ) ), + ), + "view" : + ( + ("ex1.view", "samtools view ex1.bam > ex1.view"), + ("pysam_ex1.view", (pysam.view, "ex1.bam" ) ), + ), + } + + # some tests depend on others. The order specifies in which order + # the samtools commands are executed. + mOrder = ('faidx', 'import', 'index', 'pileup1', 'pileup2', 'glfview', 'view' ) + + def setUp( self ): + '''setup tests. + + For setup, all commands will be run before the first test is + executed. Individual tests will then just compare the output + files. + ''' + + if BinaryTest.first_time: + # copy the source + shutil.copy( "ex1.fa", "pysam_ex1.fa" ) + + for label in self.mOrder: + command = self.mCommands[label] + samtools_target, samtools_command = command[0] + pysam_target, pysam_command = command[1] + runSamtools( samtools_command ) + pysam_method, pysam_options = pysam_command + output = pysam_method( *pysam_options.split(" "), raw=True) + if ">" in samtools_command: + outfile = open( pysam_target, "w" ) + for line in output: outfile.write( line ) + outfile.close() + + BinaryTest.first_time = False + + def checkCommand( self, command ): + if command: + samtools_target, pysam_target = self.mCommands[command][0][0], self.mCommands[command][1][0] + self.assertTrue( checkBinaryEqual( samtools_target, pysam_target ), + "%s failed: files %s and %s are not the same" % (command, samtools_target, pysam_target) ) + + def testImport( self ): + self.checkCommand( "import" ) + + def testIndex( self ): + self.checkCommand( "index" ) + + def testPileup1( self ): + self.checkCommand( "pileup1" ) + + def testPileup2( self ): + self.checkCommand( "pileup2" ) + + def testGLFView( self ): + self.checkCommand( "glfview" ) + + def testView( self ): + self.checkCommand( "view" ) + + def __del__(self): + + for label, command in self.mCommands.iteritems(): + samtools_target, samtools_command = command[0] + pysam_target, pysam_command = command[1] + if os.path.exists( samtools_target): os.remove( samtools_target ) + if os.path.exists( pysam_target): os.remove( pysam_target ) + if os.path.exists( "pysam_ex1.fa" ): os.remove( "pysam_ex1.fa" ) + +class IOTest(unittest.TestCase): + '''check if reading samfile and writing a samfile are consistent.''' + + def checkEcho( self, input_filename, reference_filename, + output_filename, + input_mode, output_mode, use_template = True): + '''iterate through *input_filename* writing to *output_filename* and + comparing the output to *reference_filename*. + + The files are opened according to the *input_mode* and *output_mode*. + + If *use_template* is set, the header is copied from infile using the + template mechanism, otherwise target names and lengths are passed explicitely. + ''' + + infile = pysam.Samfile( input_filename, input_mode ) + if use_template: + outfile = pysam.Samfile( output_filename, output_mode, template = infile ) + else: + outfile = pysam.Samfile( output_filename, output_mode, + referencenames = infile.references, + referencelengths = infile.lengths ) + + iter = infile.fetch() + for x in iter: outfile.write( x ) + infile.close() + outfile.close() + + self.assertTrue( checkBinaryEqual( reference_filename, output_filename), + "files %s and %s are not the same" % (reference_filename, output_filename) ) + + def testReadWriteBam( self ): + + input_filename = "ex1.bam" + output_filename = "pysam_ex1.bam" + reference_filename = "ex1.bam" + + self.checkEcho( input_filename, reference_filename, output_filename, + "rb", "wb" ) + + def testReadWriteBamWithTargetNames( self ): + + input_filename = "ex1.bam" + output_filename = "pysam_ex1.bam" + reference_filename = "ex1.bam" + + self.checkEcho( input_filename, reference_filename, output_filename, + "rb", "wb", use_template = False ) + + def testReadWriteSamWithHeader( self ): + + input_filename = "ex2.sam" + output_filename = "pysam_ex2.sam" + reference_filename = "ex2.sam" + + self.checkEcho( input_filename, reference_filename, output_filename, + "r", "wh" ) + + def testReadWriteSamWithoutHeader( self ): + + input_filename = "ex2.sam" + output_filename = "pysam_ex2.sam" + reference_filename = "ex1.sam" + + self.checkEcho( input_filename, reference_filename, output_filename, + "r", "w" ) + +class TestIteratorRow(unittest.TestCase): + + def setUp(self): + self.samfile=pysam.Samfile( "ex1.bam","rb" ) + + def checkRange( self, rnge ): + '''compare results from iterator with those from samtools.''' + ps = list(self.samfile.fetch(region=rnge)) + sa = list(pysam.view( "ex1.bam", rnge , raw = True) ) + self.assertEqual( len(ps), len(sa), "unequal number of results for range %s: %i != %i" % (rnge, len(ps), len(sa) )) + # check if the same reads are returned and in the same order + for line, pair in enumerate( zip( ps, sa ) ): + data = pair[1].split("\t") + self.assertEqual( pair[0].qname, data[0], "read id mismatch in line %i: %s != %s" % (line, pair[0].rname, data[0]) ) + + def testIteratePerContig(self): + '''check random access per contig''' + for contig in self.samfile.references: + self.checkRange( contig ) + + def testIterateRanges(self): + '''check random access per range''' + for contig, length in zip(self.samfile.references, self.samfile.lengths): + for start in range( 1, length, 90): + self.checkRange( "%s:%i-%i" % (contig, start, start + 90) ) # this includes empty ranges + + def tearDown(self): + self.samfile.close() + +class TestIteratorRowAll(unittest.TestCase): + + def setUp(self): + self.samfile=pysam.Samfile( "ex1.bam","rb" ) + + def testIterate(self): + '''compare results from iterator with those from samtools.''' + ps = list(self.samfile.fetch()) + sa = list(pysam.view( "ex1.bam", raw = True) ) + self.assertEqual( len(ps), len(sa), "unequal number of results: %i != %i" % (len(ps), len(sa) )) + # check if the same reads are returned + for line, pair in enumerate( zip( ps, sa ) ): + data = pair[1].split("\t") + self.assertEqual( pair[0].qname, data[0], "read id mismatch in line %i: %s != %s" % (line, pair[0].rname, data[0]) ) + + def tearDown(self): + self.samfile.close() + +class TestIteratorColumn(unittest.TestCase): + '''test iterator column against contents of ex3.bam.''' + + # note that samfile contains 1-based coordinates + # 1D means deletion with respect to reference sequence + # + mCoverages = { 'chr1' : [ 0 ] * 20 + [1] * 36 + [0] * (100 - 20 -35 ), + 'chr2' : [ 0 ] * 20 + [1] * 35 + [0] * (100 - 20 -35 ), + } + + def setUp(self): + self.samfile=pysam.Samfile( "ex4.bam","rb" ) + + def checkRange( self, rnge ): + '''compare results from iterator with those from samtools.''' + # check if the same reads are returned and in the same order + for column in self.samfile.pileup(region=rnge): + thiscov = len(column.pileups) + refcov = self.mCoverages[self.samfile.getrname(column.tid)][column.pos] + self.assertEqual( thiscov, refcov, "wrong coverage at pos %s:%i %i should be %i" % (self.samfile.getrname(column.tid), column.pos, thiscov, refcov)) + + def testIterateAll(self): + '''check random access per contig''' + self.checkRange( None ) + + def testIteratePerContig(self): + '''check random access per contig''' + for contig in self.samfile.references: + self.checkRange( contig ) + + def testIterateRanges(self): + '''check random access per range''' + for contig, length in zip(self.samfile.references, self.samfile.lengths): + for start in range( 1, length, 90): + self.checkRange( "%s:%i-%i" % (contig, start, start + 90) ) # this includes empty ranges + + def testInverse( self ): + '''test the inverse, is point-wise pileup accurate.''' + for contig, refseq in self.mCoverages.items(): + refcolumns = sum(refseq) + for pos, refcov in enumerate( refseq ): + columns = list(self.samfile.pileup( contig, pos, pos+1) ) + if refcov == 0: + # if no read, no coverage + self.assertEqual( len(columns), refcov, "wrong number of pileup columns returned for position %s:%i, %i should be %i" %(contig,pos,len(columns), refcov) ) + elif refcov == 1: + # one read, all columns of the read are returned + self.assertEqual( len(columns), refcolumns, "pileup incomplete - %i should be %i " % (len(columns), refcolumns)) + + def tearDown(self): + self.samfile.close() + + +class TestAlignedReadBam(unittest.TestCase): + + def setUp(self): + self.samfile=pysam.Samfile( "ex3.bam","rb" ) + self.reads=list(self.samfile.fetch()) + + def testARqname(self): + self.assertEqual( self.reads[0].qname, "read_28833_29006_6945", "read name mismatch in read 1: %s != %s" % (self.reads[0].qname, "read_28833_29006_6945") ) + self.assertEqual( self.reads[1].qname, "read_28701_28881_323b", "read name mismatch in read 2: %s != %s" % (self.reads[1].qname, "read_28701_28881_323b") ) + + def testARflag(self): + self.assertEqual( self.reads[0].flag, 99, "flag mismatch in read 1: %s != %s" % (self.reads[0].flag, 99) ) + self.assertEqual( self.reads[1].flag, 147, "flag mismatch in read 2: %s != %s" % (self.reads[1].flag, 147) ) + + def testARrname(self): + self.assertEqual( self.reads[0].rname, 0, "chromosome/target id mismatch in read 1: %s != %s" % (self.reads[0].rname, 0) ) + self.assertEqual( self.reads[1].rname, 1, "chromosome/target id mismatch in read 2: %s != %s" % (self.reads[1].rname, 1) ) + + def testARpos(self): + self.assertEqual( self.reads[0].pos, 33-1, "mapping position mismatch in read 1: %s != %s" % (self.reads[0].pos, 33-1) ) + self.assertEqual( self.reads[1].pos, 88-1, "mapping position mismatch in read 2: %s != %s" % (self.reads[1].pos, 88-1) ) + + def testARmapq(self): + self.assertEqual( self.reads[0].mapq, 20, "mapping quality mismatch in read 1: %s != %s" % (self.reads[0].mapq, 20) ) + self.assertEqual( self.reads[1].mapq, 30, "mapping quality mismatch in read 2: %s != %s" % (self.reads[1].mapq, 30) ) + + def testARcigar(self): + self.assertEqual( self.reads[0].cigar, [(0, 10), (2, 1), (0, 25)], "read name length mismatch in read 1: %s != %s" % (self.reads[0].cigar, [(0, 10), (2, 1), (0, 25)]) ) + self.assertEqual( self.reads[1].cigar, [(0, 35)], "read name length mismatch in read 2: %s != %s" % (self.reads[1].cigar, [(0, 35)]) ) + + def testARmrnm(self): + self.assertEqual( self.reads[0].mrnm, 0, "mate reference sequence name mismatch in read 1: %s != %s" % (self.reads[0].mrnm, 0) ) + self.assertEqual( self.reads[1].mrnm, 1, "mate reference sequence name mismatch in read 2: %s != %s" % (self.reads[1].mrnm, 1) ) + + def testARmpos(self): + self.assertEqual( self.reads[0].mpos, 200-1, "mate mapping position mismatch in read 1: %s != %s" % (self.reads[0].mpos, 200-1) ) + self.assertEqual( self.reads[1].mpos, 500-1, "mate mapping position mismatch in read 2: %s != %s" % (self.reads[1].mpos, 500-1) ) + + def testARisize(self): + self.assertEqual( self.reads[0].isize, 167, "insert size mismatch in read 1: %s != %s" % (self.reads[0].isize, 167) ) + self.assertEqual( self.reads[1].isize, 412, "insert size mismatch in read 2: %s != %s" % (self.reads[1].isize, 412) ) + + def testARseq(self): + self.assertEqual( self.reads[0].seq, "AGCTTAGCTAGCTACCTATATCTTGGTCTTGGCCG", "sequence mismatch in read 1: %s != %s" % (self.reads[0].seq, "AGCTTAGCTAGCTACCTATATCTTGGTCTTGGCCG") ) + self.assertEqual( self.reads[1].seq, "ACCTATATCTTGGCCTTGGCCGATGCGGCCTTGCA", "sequence size mismatch in read 2: %s != %s" % (self.reads[1].seq, "ACCTATATCTTGGCCTTGGCCGATGCGGCCTTGCA") ) + + def testARqual(self): + self.assertEqual( self.reads[0].qual, "<<<<<<<<<<<<<<<<<<<<<:<9/,&,22;;<<<", "quality string mismatch in read 1: %s != %s" % (self.reads[0].qual, "<<<<<<<<<<<<<<<<<<<<<:<9/,&,22;;<<<") ) + self.assertEqual( self.reads[1].qual, "<<<<<;<<<<7;:<<<6;<<<<<<<<<<<<7<<<<", "quality string mismatch in read 2: %s != %s" % (self.reads[1].qual, "<<<<<;<<<<7;:<<<6;<<<<<<<<<<<<7<<<<") ) + + def testPresentOptionalFields(self): + self.assertEqual( self.reads[0].opt('NM'), 1, "optional field mismatch in read 1, NM: %s != %s" % (self.reads[0].opt('NM'), 1) ) + self.assertEqual( self.reads[0].opt('RG'), 'L1', "optional field mismatch in read 1, RG: %s != %s" % (self.reads[0].opt('RG'), 'L1') ) + self.assertEqual( self.reads[1].opt('RG'), 'L2', "optional field mismatch in read 2, RG: %s != %s" % (self.reads[1].opt('RG'), 'L2') ) + self.assertEqual( self.reads[1].opt('MF'), 18, "optional field mismatch in read 2, MF: %s != %s" % (self.reads[1].opt('MF'), 18) ) + + def testPairedBools(self): + self.assertEqual( self.reads[0].is_paired, True, "is paired mismatch in read 1: %s != %s" % (self.reads[0].is_paired, True) ) + self.assertEqual( self.reads[1].is_paired, True, "is paired mismatch in read 2: %s != %s" % (self.reads[1].is_paired, True) ) + self.assertEqual( self.reads[0].is_proper_pair, True, "is proper pair mismatch in read 1: %s != %s" % (self.reads[0].is_proper_pair, True) ) + self.assertEqual( self.reads[1].is_proper_pair, True, "is proper pair mismatch in read 2: %s != %s" % (self.reads[1].is_proper_pair, True) ) + + def tearDown(self): + self.samfile.close() + +class TestAlignedReadSam(unittest.TestCase): + + def setUp(self): + self.samfile=pysam.Samfile( "ex3.sam","r" ) + self.reads=list(self.samfile.fetch()) + + def testARqname(self): + self.assertEqual( self.reads[0].qname, "read_28833_29006_6945", "read name mismatch in read 1: %s != %s" % (self.reads[0].qname, "read_28833_29006_6945") ) + self.assertEqual( self.reads[1].qname, "read_28701_28881_323b", "read name mismatch in read 2: %s != %s" % (self.reads[1].qname, "read_28701_28881_323b") ) + + def testARflag(self): + self.assertEqual( self.reads[0].flag, 99, "flag mismatch in read 1: %s != %s" % (self.reads[0].flag, 99) ) + self.assertEqual( self.reads[1].flag, 147, "flag mismatch in read 2: %s != %s" % (self.reads[1].flag, 147) ) + + def testARrname(self): + self.assertEqual( self.reads[0].rname, 0, "chromosome/target id mismatch in read 1: %s != %s" % (self.reads[0].rname, 0) ) + self.assertEqual( self.reads[1].rname, 1, "chromosome/target id mismatch in read 2: %s != %s" % (self.reads[1].rname, 1) ) + + def testARpos(self): + self.assertEqual( self.reads[0].pos, 33-1, "mapping position mismatch in read 1: %s != %s" % (self.reads[0].pos, 33-1) ) + self.assertEqual( self.reads[1].pos, 88-1, "mapping position mismatch in read 2: %s != %s" % (self.reads[1].pos, 88-1) ) + + def testARmapq(self): + self.assertEqual( self.reads[0].mapq, 20, "mapping quality mismatch in read 1: %s != %s" % (self.reads[0].mapq, 20) ) + self.assertEqual( self.reads[1].mapq, 30, "mapping quality mismatch in read 2: %s != %s" % (self.reads[1].mapq, 30) ) + + def testARcigar(self): + self.assertEqual( self.reads[0].cigar, [(0, 10), (2, 1), (0, 25)], "read name length mismatch in read 1: %s != %s" % (self.reads[0].cigar, [(0, 10), (2, 1), (0, 25)]) ) + self.assertEqual( self.reads[1].cigar, [(0, 35)], "read name length mismatch in read 2: %s != %s" % (self.reads[1].cigar, [(0, 35)]) ) + + def testARmrnm(self): + self.assertEqual( self.reads[0].mrnm, 0, "mate reference sequence name mismatch in read 1: %s != %s" % (self.reads[0].mrnm, 0) ) + self.assertEqual( self.reads[1].mrnm, 1, "mate reference sequence name mismatch in read 2: %s != %s" % (self.reads[1].mrnm, 1) ) + + def testARmpos(self): + self.assertEqual( self.reads[0].mpos, 200-1, "mate mapping position mismatch in read 1: %s != %s" % (self.reads[0].mpos, 200-1) ) + self.assertEqual( self.reads[1].mpos, 500-1, "mate mapping position mismatch in read 2: %s != %s" % (self.reads[1].mpos, 500-1) ) + + def testARisize(self): + self.assertEqual( self.reads[0].isize, 167, "insert size mismatch in read 1: %s != %s" % (self.reads[0].isize, 167) ) + self.assertEqual( self.reads[1].isize, 412, "insert size mismatch in read 2: %s != %s" % (self.reads[1].isize, 412) ) + + def testARseq(self): + self.assertEqual( self.reads[0].seq, "AGCTTAGCTAGCTACCTATATCTTGGTCTTGGCCG", "sequence mismatch in read 1: %s != %s" % (self.reads[0].seq, "AGCTTAGCTAGCTACCTATATCTTGGTCTTGGCCG") ) + self.assertEqual( self.reads[1].seq, "ACCTATATCTTGGCCTTGGCCGATGCGGCCTTGCA", "sequence size mismatch in read 2: %s != %s" % (self.reads[1].seq, "ACCTATATCTTGGCCTTGGCCGATGCGGCCTTGCA") ) + + def testARqual(self): + self.assertEqual( self.reads[0].qual, "<<<<<<<<<<<<<<<<<<<<<:<9/,&,22;;<<<", "quality string mismatch in read 1: %s != %s" % (self.reads[0].qual, "<<<<<<<<<<<<<<<<<<<<<:<9/,&,22;;<<<") ) + self.assertEqual( self.reads[1].qual, "<<<<<;<<<<7;:<<<6;<<<<<<<<<<<<7<<<<", "quality string mismatch in read 2: %s != %s" % (self.reads[1].qual, "<<<<<;<<<<7;:<<<6;<<<<<<<<<<<<7<<<<") ) + + def testPresentOptionalFields(self): + self.assertEqual( self.reads[0].opt('NM'), 1, "optional field mismatch in read 1, NM: %s != %s" % (self.reads[0].opt('NM'), 1) ) + self.assertEqual( self.reads[0].opt('RG'), 'L1', "optional field mismatch in read 1, RG: %s != %s" % (self.reads[0].opt('RG'), 'L1') ) + self.assertEqual( self.reads[1].opt('RG'), 'L2', "optional field mismatch in read 2, RG: %s != %s" % (self.reads[1].opt('RG'), 'L2') ) + self.assertEqual( self.reads[1].opt('MF'), 18, "optional field mismatch in read 2, MF: %s != %s" % (self.reads[1].opt('MF'), 18) ) + + def testPairedBools(self): + self.assertEqual( self.reads[0].is_paired, True, "is paired mismatch in read 1: %s != %s" % (self.reads[0].is_paired, True) ) + self.assertEqual( self.reads[1].is_paired, True, "is paired mismatch in read 2: %s != %s" % (self.reads[1].is_paired, True) ) + self.assertEqual( self.reads[0].is_proper_pair, True, "is proper pair mismatch in read 1: %s != %s" % (self.reads[0].is_proper_pair, True) ) + self.assertEqual( self.reads[1].is_proper_pair, True, "is proper pair mismatch in read 2: %s != %s" % (self.reads[1].is_proper_pair, True) ) + + def tearDown(self): + self.samfile.close() + +class TestHeaderSam(unittest.TestCase): + + def setUp(self): + self.samfile=pysam.Samfile( "ex3.sam","r" ) + + def testHeaders(self): + self.assertEqual( self.samfile.header, {'SQ': [{'LN': 1575, 'SN': 'chr1'}, {'LN': 1584, 'SN': 'chr2'}], 'RG': [{'LB': 'SC_1', 'ID': 'L1', 'SM': 'NA12891', 'PU': 'SC_1_10'}, {'LB': 'SC_2', 'ID': 'L2', 'SM': 'NA12891', 'PU': 'SC_2_12'}], 'CO': ['this is a comment', 'this is another comment'], 'HD': {'VN': '1.0'}}, "mismatch in headers: %s != %s" % (self.samfile.header, {'SQ': [{'LN': 1575, 'SN': 'chr1'}, {'LN': 1584, 'SN': 'chr2'}], 'RG': [{'LB': 'SC_1', 'ID': 'L1', 'SM': 'NA12891', 'PU': 'SC_1_10'}, {'LB': 'SC_2', 'ID': 'L2', 'SM': 'NA12891', 'PU': 'SC_2_12'}], 'CO': ['this is a comment', 'this is another comment'], 'HD': {'VN': '1.0'}}) ) + + def tearDown(self): + self.samfile.close() + +class TestHeaderBam(unittest.TestCase): + + def setUp(self): + self.samfile=pysam.Samfile( "ex3.sam","r" ) + + def testHeaders(self): + self.assertEqual( self.samfile.header, {'SQ': [{'LN': 1575, 'SN': 'chr1'}, {'LN': 1584, 'SN': 'chr2'}], 'RG': [{'LB': 'SC_1', 'ID': 'L1', 'SM': 'NA12891', 'PU': 'SC_1_10'}, {'LB': 'SC_2', 'ID': 'L2', 'SM': 'NA12891', 'PU': 'SC_2_12'}], 'CO': ['this is a comment', 'this is another comment'], 'HD': {'VN': '1.0'}}, "mismatch in headers: %s != %s" % (self.samfile.header, {'SQ': [{'LN': 1575, 'SN': 'chr1'}, {'LN': 1584, 'SN': 'chr2'}], 'RG': [{'LB': 'SC_1', 'ID': 'L1', 'SM': 'NA12891', 'PU': 'SC_1_10'}, {'LB': 'SC_2', 'ID': 'L2', 'SM': 'NA12891', 'PU': 'SC_2_12'}], 'CO': ['this is a comment', 'this is another comment'], 'HD': {'VN': '1.0'}}) ) + + def tearDown(self): + self.samfile.close() + +class TestPileupObjects(unittest.TestCase): + + def setUp(self): + self.samfile=pysam.Samfile( "ex1.bam","rb" ) + + def testPileupColumn(self): + for pcolumn1 in self.samfile.pileup( region="chr1:105" ): + if pcolumn1.pos == 104: + self.assertEqual( pcolumn1.tid, 0, "chromosome/target id mismatch in position 1: %s != %s" % (pcolumn1.tid, 0) ) + self.assertEqual( pcolumn1.pos, 105-1, "position mismatch in position 1: %s != %s" % (pcolumn1.pos, 105-1) ) + self.assertEqual( pcolumn1.n, 2, "# reads mismatch in position 1: %s != %s" % (pcolumn1.n, 2) ) + for pcolumn2 in self.samfile.pileup( region="chr2:1480" ): + if pcolumn2.pos == 1479: + self.assertEqual( pcolumn2.tid, 1, "chromosome/target id mismatch in position 1: %s != %s" % (pcolumn2.tid, 1) ) + self.assertEqual( pcolumn2.pos, 1480-1, "position mismatch in position 1: %s != %s" % (pcolumn2.pos, 1480-1) ) + self.assertEqual( pcolumn2.n, 12, "# reads mismatch in position 1: %s != %s" % (pcolumn2.n, 12) ) + + def testPileupRead(self): + for pcolumn1 in self.samfile.pileup( region="chr1:105" ): + if pcolumn1.pos == 104: + self.assertEqual( len(pcolumn1.pileups), 2, "# reads aligned to column mismatch in position 1: %s != %s" % (len(pcolumn1.pileups), 2) ) +# self.assertEqual( pcolumn1.pileups[0] # need to test additional properties here + + def tearDown(self): + self.samfile.close() + +class TestExceptions(unittest.TestCase): + + def setUp(self): + self.samfile=pysam.Samfile( "ex1.bam","rb" ) + + def testBadFile(self): + self.assertRaises( IOError, pysam.Samfile, "exdoesntexist.bam", "rb" ) + self.assertRaises( IOError, pysam.Samfile, "exdoesntexist.sam","r" ) + self.assertRaises( IOError, pysam.Samfile, "exdoesntexist.bam", "r" ) + self.assertRaises( IOError, pysam.Samfile, "exdoesntexist.sam","rb" ) + + def testBadContig(self): + self.assertRaises( ValueError, self.samfile.fetch, "chr88" ) + + def testMeaninglessCrap(self): + self.assertRaises( ValueError, self.samfile.fetch, "skljf" ) + + def testBackwardsOrderNewFormat(self): + self.assertRaises( ValueError, self.samfile.fetch, 'chr1', 100, 10 ) + + def testBackwardsOrderOldFormat(self): + self.assertRaises( ValueError, self.samfile.fetch, region="chr1:100-10") + + def testOutOfRangeNegativeNewFormat(self): + self.assertRaises( ValueError, self.samfile.fetch, "chr1", 5, -10 ) + self.assertRaises( ValueError, self.samfile.fetch, "chr1", 5, 0 ) + self.assertRaises( ValueError, self.samfile.fetch, "chr1", -5, -10 ) + + def testOutOfRangeNegativeOldFormat(self): + self.assertRaises( ValueError, self.samfile.fetch, region="chr1:-5-10" ) + self.assertRaises( ValueError, self.samfile.fetch, region="chr1:-5-0" ) + self.assertRaises( ValueError, self.samfile.fetch, region="chr1:-5--10" ) + + def testOutOfRangNewFormat(self): + self.assertRaises( ValueError, self.samfile.fetch, "chr1", 9999999999, 99999999999 ) + + def testOutOfRangeLargeNewFormat(self): + self.assertRaises( ValueError, self.samfile.fetch, "chr1", 9999999999999999999999999999999, 9999999999999999999999999999999999999999 ) + + def testOutOfRangeLargeOldFormat(self): + self.assertRaises( ValueError, self.samfile.fetch, "chr1:99999999999999999-999999999999999999" ) + + def tearDown(self): + self.samfile.close() + +# TODOS +# 1. finish testing all properties within pileup objects +# 2. check exceptions and bad input problems (missing files, optional fields that aren't present, etc...) + +if __name__ == "__main__": + unittest.main() diff --git a/tests/segfault_tests.py b/tests/segfault_tests.py new file mode 100755 index 0000000..ff32fec --- /dev/null +++ b/tests/segfault_tests.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python +'''unit testing code for pysam.''' + +import pysam +import unittest +import os +import itertools +import subprocess +import shutil + +class TestExceptions(unittest.TestCase): + + def setUp(self): + self.samfile=pysam.Samfile( "ex1.bam","rb" ) + + def testOutOfRangeNegativeNewFormat(self): + self.assertRaises( ValueError, self.samfile.fetch, "chr1", 5, -10 ) + self.assertRaises( ValueError, self.samfile.fetch, "chr1", 5, 0 ) + self.assertRaises( ValueError, self.samfile.fetch, "chr1", -5, -10 ) + + def testOutOfRangeNegativeOldFormat(self): + self.assertRaises( ValueError, self.samfile.fetch, "chr1:-5-10" ) + self.assertRaises( ValueError, self.samfile.fetch, "chr1:-5-0" ) + self.assertRaises( ValueError, self.samfile.fetch, "chr1:-5--10" ) + + def testOutOfRangeLargeNewFormat(self): + self.assertRaises( ValueError, self.samfile.fetch, "chr1", 99999999999999999, 999999999999999999 ) + + def testOutOfRangeLargeOldFormat(self): + self.assertRaises( ValueError, self.samfile.fetch, "chr1:99999999999999999-999999999999999999" ) + + def tearDown(self): + self.samfile.close() + +if __name__ == "__main__": + unittest.main() + -- 2.30.2