Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
nh13 committed Dec 12, 2024
1 parent 9c99244 commit 9a20323
Show file tree
Hide file tree
Showing 5 changed files with 155 additions and 83 deletions.
20 changes: 20 additions & 0 deletions .github/workflows/readthedocs.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
name: readthedocs/actions
on:
pull_request_target:
types:
- opened
# Execute this action only on PRs that touch
# documentation files.
paths:
- "docs/**"

permissions:
pull-requests: write

jobs:
documentation-links:
runs-on: ubuntu-24.04
steps:
- uses: readthedocs/actions/preview@v1
with:
project-slug: "fgpyo"
106 changes: 69 additions & 37 deletions build.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,55 +2,87 @@
import os
import glob
import shutil
from distutils.command.build_ext import build_ext
from distutils.core import Distribution, Extension
from setuptools import Extension, Distribution
from typing import List

from Cython.Build import cythonize
from Cython.Distutils.build_ext import new_build_ext as cython_build_ext
import multiprocessing
from pathlib import Path


SOURCE_DIR = Path("bwapy")
BUILD_DIR = Path("cython_build")
compile_args = []
link_args = []
include_dirs = ['.']
# Relative to project root directory
include_dirs = ["bwa", "bwapy"]
libraries = ['m', 'z', 'pthread']
library_dirs=['.']
extra_objects = glob.glob(os.path.join('bwa', '*.o'))
library_dirs=['bwa']
extra_objects = [] #glob.glob(os.path.join('bwa', '*.o'))

c_files = [str(x) for x in Path("bwa").rglob("*.c") if x.name not in ['example.c', 'main.c']]
extension_module = Extension(
name='bwapy.libbwapy',
sources=['bwapy/libbwapy.pyx'] + c_files,
depends=['bwa/bwtaln.h'],
extra_compile_args=compile_args,
extra_link_args=link_args,
extra_objects=extra_objects,
include_dirs=include_dirs,
language='c',
libraries=libraries,
library_dirs=library_dirs,
)

def build():
extensions = [
Extension(
'bwapy',
sources=['bwapy/bwapy.pyx'],
depends=['bwa/bwtaln.h'],
extra_compile_args=compile_args,
extra_link_args=link_args,
extra_objects=extra_objects,
include_dirs=include_dirs,
language='c',
libraries=libraries,
library_dirs=library_dirs,
)
]
ext_modules = cythonize(
extensions,
include_path=include_dirs,
compiler_directives={"binding": True, "language_level": 3},


def cythonize_helper(extension_modules: List[Extension]) -> List[Extension]:
"""Cythonize all Python extensions"""

return cythonize(
module_list=extension_modules,

# Don't build in source tree (this leaves behind .c files)
build_dir=BUILD_DIR,

# Don't generate an .html output file. Would contain source.
annotate=False,

# Parallelize our build
nthreads=multiprocessing.cpu_count() * 2,

# Tell Cython we're using Python 3. Becomes default in Cython 3
compiler_directives={"language_level": "3"},

# (Optional) Always rebuild, even if files untouched
force=True,
)

distribution = Distribution({"name": "extended", "ext_modules": ext_modules})
distribution.package_dir = "extended"

cmd = build_ext(distribution)
cmd.ensure_finalized()
cmd.run()

# Copy built extensions back to the project
for output in cmd.get_outputs():
relative_extension = os.path.relpath(output, cmd.build_lib)
shutil.copyfile(output, relative_extension)
mode = os.stat(relative_extension).st_mode
mode |= (mode & 0o444) >> 2
os.chmod(relative_extension, mode)
def build():
# Collect and cythonize all files
extension_modules = cythonize_helper([extension_module])

# Use Setuptools to collect files
distribution = Distribution({
"ext_modules": extension_modules,
"cmdclass": {
"build_ext": cython_build_ext,
},
})

# Grab the build_ext command and copy all files back to source dir.
# Done so Poetry grabs the files during the next step in its build.
build_ext_cmd = distribution.get_command_obj("build_ext")
build_ext_cmd.ensure_finalized()
# Set the value to 1 for "inplace", with the goal to build extensions
# in build directory, and then copy all files back to the source dir
# (under the hood, "copy_extensions_to_source" will be called after
# building the extensions). This is done so Poetry grabs the files
# during the next step in its build.
build_ext_cmd.inplace = 1
build_ext_cmd.run()


if __name__ == "__main__":
Expand Down
3 changes: 3 additions & 0 deletions bwapy/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import bwapy.libbwapy as libbwapy

__all__ = (libbwapy.__all__)
98 changes: 54 additions & 44 deletions bwapy/bwapy.pyx → bwapy/libbwapy.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,29 @@ from libc.stdint cimport uint8_t
from pysam import FastqProxy
cimport cython

cdef extern from "bwa/bntseq.h":

__all__ = [
"BwaIndex",
"BwaOptions",
"Bwa",
]


cdef extern from "bntseq.h":
unsigned char nst_nt4_table[256]

cdef extern from "bwa/bwa.h":
cdef extern from "bwa.h":
char * bwa_idx_infer_prefix(const char * hint)

cdef extern from "bwa/bwt.h":
cdef extern from "bwt.h":
ctypedef struct bwt_t:
pass

bwt_t *bwt_restore_bwt(const char *fn);
void bwt_destroy(bwt_t *bwt);


cdef extern from "bwa/bwtaln.h":
cdef extern from "bwtaln.h":
ctypedef struct gap_opt_t:
int trim_qual
int s_mm
Expand Down Expand Up @@ -50,7 +58,7 @@ cdef extern from "bwa/bwtaln.h":



cdef extern from "bwa/bwtaln.h":
cdef extern from "bwtaln.h":
ctypedef struct bwa_seq_t:
int tid
int len
Expand Down Expand Up @@ -124,42 +132,44 @@ cdef class BwaIndex:
self._bwt = NULL


#cdef class Bwa:
#
# def __init__(self, prefix: str):
# self._index = BwaIndex(prefix=prefix)
#
#
# def align(self, query: *FastqProxy) -> None:
# self._calign(query)
#
# cdef _calign(self, query):
# cdef bwa_seq_t* seqs
# cdef bwa_seq_t* s
# cdef char* s_char
# num_seqs = len(query)
# seqs = <bwa_seq_t*>calloc(sizeof(bwa_seq_t), num_seqs)
# for i in range(num_seqs):
# q = query[i]
# s = &seqs[i]
# s.tid = -1
# seq_len = len(q.sequence)
# s.len = seq_len
# s.clip_len = seq_len
# s.seq = <uint8_t*>calloc(sizeof(uint8_t), seq_len)
# for i in range(len
# for base in q.sequence:
# base = nst_nt4_table[ord(base)]
# s.seq[i] = base
# #if q.qual is not None:
# # # TODO
# # pass
# # TODO: reverse the seq
# #s.name = <char*>calloc(sizeof(char), len(q.name))
# #strncpy(s.name, force_bytes(q.name), len(q.name))
#
# #bwa_free_read_seq(seqs)
# #bwa_cal_sa_reg_gap
#
#
##void bwa_aln_core(const char *prefix, const char *fn_fa, const gap_opt_t *opt)
cdef class Bwa:

cdef BwaIndex _index

def __init__(self, prefix: str):
self._index = BwaIndex(prefix=prefix)


def align(self, query: *FastqProxy) -> None:
self._calign(query)

cdef _calign(self, query):
cdef bwa_seq_t* seqs
cdef bwa_seq_t* s
cdef char* s_char
num_seqs = len(query)
seqs = <bwa_seq_t*>calloc(sizeof(bwa_seq_t), num_seqs)
for i in range(num_seqs):
q = query[i]
s = &seqs[i]
s.tid = -1
seq_len = len(q.sequence)
s.len = seq_len
s.clip_len = seq_len
s.seq = <uint8_t*>calloc(sizeof(uint8_t), seq_len)
#for i in range(len
for base in q.sequence:
base = nst_nt4_table[ord(base)]
s.seq[i] = base
#if q.qual is not None:
# # TODO
# pass
# TODO: reverse the seq
#s.name = <char*>calloc(sizeof(char), len(q.name))
#strncpy(s.name, force_bytes(q.name), len(q.name))

#bwa_free_read_seq(seqs)
#bwa_cal_sa_reg_gap


#void bwa_aln_core(const char *prefix, const char *fn_fa, const gap_opt_t *opt)
11 changes: 9 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ readme = "README.md"
homepage = "https://github.com/fulcrumgenomics/bwapy"
repository = "https://github.com/fulcrumgenomics/bwapy"
keywords = ["bioinformatics"]
packages = [{ include = "bwapy" }]
classifiers = [
"Development Status :: 3 - Alpha",
"Environment :: Console",
Expand All @@ -20,7 +21,13 @@ classifiers = [
"Topic :: Software Development :: Documentation",
"Topic :: Software Development :: Libraries :: Python Modules",
]
include = ["LICENSE"]
include = [
"LICENSE",
{ path = "bwapy/**/*.so", format = "wheel" },
{ path = "**/*.so", format = "wheel" },
{ path = "*.so", format = "wheel" },
#{ path = "*.so", format = "wheel" }
]

[tool.poetry.build]
generate-setup-file = false
Expand Down Expand Up @@ -53,7 +60,7 @@ mkdocstrings-python = { version = ">=1.6.2" }
mkdocstrings = { version = ">=0.23.0" }

[build-system]
requires = ["poetry-core>=1.0.0", "cython>=3.0.11"]
requires = ["poetry-core>=1.0.0", "cython>=3.0.11", "setuptools>=75.1.0"]
build-backend = "poetry.core.masonry.api"

[tool.ruff]
Expand Down

0 comments on commit 9a20323

Please sign in to comment.