Imported Upstream version 0.6
[pysam.git] / setup.py
1 #!/usr/bin/python
2 '''
3
4 pysam
5 *****
6
7 '''
8
9 import os, sys, glob, shutil, hashlib, re, fnmatch
10 import platform
11
12 name = "pysam"
13
14 # collect pysam version
15 sys.path.insert( 0, "pysam")
16 import version
17
18 version = version.__version__
19
20 samtools_exclude = ( "bamtk.c", "razip.c", "bgzip.c", 
21                      "main.c", "calDepth.c", "bam2bed.c",
22                      "wgsim.c", "md5fa.c", "maq2sam.c",)
23 samtools_dest = os.path.abspath( "samtools" )
24 tabix_exclude = ( "main.c", )
25 tabix_dest = os.path.abspath( "tabix" )
26
27 def locate(pattern, root=os.curdir):
28     '''Locate all files matching supplied filename pattern in and below
29     supplied root directory.'''
30     for path, dirs, files in os.walk(os.path.abspath(root)):
31        for filename in fnmatch.filter(files, pattern):
32           yield os.path.join(path, filename)
33
34 def _update_pysam_files(cf, destdir):
35   for filename in cf:
36      if not filename: continue
37      dest = filename + ".pysam.c"
38      with open( filename ) as infile:
39         with open( dest, "w" ) as outfile:
40            outfile.write( '#include "pysam.h"\n\n' )
41            outfile.write( re.sub( "stderr", "pysamerr", "".join(infile.readlines()) ) )
42   with open( os.path.join( destdir, "pysam.h" ), "w" )as outfile:
43      outfile.write ("""#ifndef PYSAM_H
44 #define PYSAM_H
45 #include "stdio.h"
46 extern FILE * pysamerr;
47 #endif
48 """)
49
50 # copy samtools source
51 if len(sys.argv) >= 2 and sys.argv[1] == "import":
52    if len(sys.argv) < 3: raise ValueError("missing PATH to samtools source directory")
53    if len(sys.argv) < 4: raise ValueError("missing PATH to tabix source directory")
54
55    for destdir, srcdir, exclude in zip( 
56       (samtools_dest, tabix_dest), 
57       sys.argv[2:4],
58       (samtools_exclude, tabix_exclude)):
59
60       srcdir = os.path.abspath( srcdir )
61       if not os.path.exists( srcdir ): raise IOError( "samtools src dir `%s` does not exist." % srcdir )
62
63       cfiles = locate( "*.c", srcdir )
64       hfiles = locate( "*.h", srcdir )
65       ncopied = 0
66       
67       def _compareAndCopy( src, srcdir, destdir, exclude ):
68
69          d, f = os.path.split(src)
70          if f in exclude: return None
71          common_prefix = os.path.commonprefix( (d, srcdir ) )
72          subdir = re.sub( common_prefix, "", d )[1:]
73          targetdir = os.path.join( destdir, subdir )
74          if not os.path.exists( targetdir ):
75             os.makedirs( targetdir )
76          old_file = os.path.join( targetdir, f )
77          if os.path.exists( old_file ):
78             md5_old = hashlib.md5("".join(open(old_file,"r").readlines())).digest()
79             md5_new = hashlib.md5("".join(open(src,"r").readlines())).digest()
80             if md5_old != md5_new:
81                raise ValueError( "incompatible files for %s and %s" % (old_file, src ))
82
83          shutil.copy( src, targetdir )
84          return old_file
85
86       for src_file in hfiles:
87          _compareAndCopy( src_file, srcdir,destdir, exclude )
88          ncopied += 1
89
90       cf = []
91       for src_file in cfiles:
92          cf.append( _compareAndCopy( src_file, srcdir, destdir, exclude ) )
93          ncopied += 1
94          
95       print "installed latest source code from %s: %i files copied" % (srcdir, ncopied)
96       # redirect stderr to pysamerr and replace bam.h with a stub.
97       print "applying stderr redirection"
98      
99       _update_pysam_files(cf, destdir)
100       
101
102    sys.exit(0)
103
104 if len(sys.argv) >= 2 and sys.argv[1] == "refresh":
105     print "refreshing latest source code from .c to .pysam.c"
106 # redirect stderr to pysamerr and replace bam.h with a stub.
107     print "applying stderr redirection"
108     for destdir in ('samtools', 'tabix'):
109         pysamcfiles = locate( "*.pysam.c", destdir )
110         for f in pysamcfiles: os.remove(f)
111         cfiles = locate( "*.c", destdir )
112         _update_pysam_files(cfiles, destdir)
113
114     sys.exit(0)
115
116
117
118 from ez_setup import use_setuptools
119 use_setuptools()
120
121 from setuptools import Extension, setup
122
123 ## note that for automatic cythoning, 
124 ## both pyrex and cython need to be installed.
125 ## see http://mail.python.org/pipermail/distutils-sig/2007-September/008204.html
126
127 try:
128     from Cython.Distutils import build_ext
129 except:
130     from setuptools.command.build_ext import build_ext
131
132 classifiers = """
133 Development Status :: 2 - Alpha
134 Operating System :: MacOS :: MacOS X
135 Operating System :: Microsoft :: Windows :: Windows NT/2000
136 Operating System :: OS Independent
137 Operating System :: POSIX
138 Operating System :: POSIX :: Linux
139 Operating System :: Unix
140 Programming Language :: Python
141 Topic :: Scientific/Engineering
142 Topic :: Scientific/Engineering :: Bioinformatics
143 """
144
145 if platform.system()=='Windows':
146     include_os = ['win32']
147     os_c_files = ['win32/getopt.c']
148 else:
149     include_os = []
150     os_c_files = []
151
152 samtools = Extension(
153     "csamtools",                   # name of extension
154     [ "pysam/csamtools.pyx" ]  +\
155         [ "pysam/%s" % x for x in (
156                 "pysam_util.c", )] +\
157         glob.glob( os.path.join( "samtools", "*.pysam.c" )) +\
158         os_c_files + \
159         glob.glob( os.path.join( "samtools", "*", "*.pysam.c" ) ),
160     library_dirs=[],
161     include_dirs=[ "samtools", "pysam" ] + include_os,
162     libraries=[ "z", ],
163     language="c",
164     define_macros = [('_FILE_OFFSET_BITS','64'),
165                      ('_USE_KNETFILE','')], 
166     )
167
168 tabix = Extension(
169     "ctabix",                   # name of extension
170     [ "pysam/ctabix.pyx", ]  +\
171        [ "pysam/%s" % x for x in ( "tabix_util.c", )] +\
172         os_c_files + \
173        glob.glob( os.path.join( "tabix", "*.pysam.c" ) ),
174     library_dirs=[],
175     include_dirs=[ "tabix", "pysam" ] + include_os,
176     libraries=[ "z", ],
177     language="c",
178     )
179
180 tabproxies = Extension(
181     "TabProxies",                   # name of extension
182     [ "pysam/TabProxies.pyx", ] + os_c_files,
183     library_dirs=[],
184     include_dirs= include_os,
185     libraries=[ "z", ],
186     language="c",
187     )
188
189 cvcf = Extension(
190     "cvcf",                   # name of extension
191     [ "pysam/cvcf.pyx", ] + os_c_files,
192     library_dirs=[],
193     include_dirs= ["tabix",] + include_os,
194     libraries=[ "z", ],
195     language="c",
196     )
197
198 metadata = {
199     'name': name,
200     'version': version,
201     'description': "pysam", 
202     'long_description': __doc__,
203     'author': "Andreas Heger",
204     'author_email': "andreas.heger@gmail.com",
205     'license': "MIT",
206     'platforms': "ALL",
207     'url': "http://code.google.com/p/pysam/",
208     'py_modules': [
209       "pysam/__init__", 
210       "pysam/Pileup", 
211       "pysam/namedtuple",
212       "pysam/version" ],
213     'requires' : ['cython (>=0.12)'],
214     'ext_modules': [samtools, tabix, tabproxies, cvcf ],
215     'cmdclass' : {'build_ext': build_ext},
216     'install_requires' : ['cython>=0.12.1',], 
217     # do not pack in order to permit linking to csamtools.so
218     'zip_safe' :False,
219     }
220
221 if __name__=='__main__':
222    dist = setup(**metadata)