Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions .github/workflows/build_wheels.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
name: Build and upload to PyPI

on:
release:
types:
- published

jobs:
build_wheels:
name: Build wheels on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
# macos-13 is an intel runner, macos-14 is apple silicon
os: [ubuntu-latest, macos-13, macos-14]

steps:
- uses: actions/checkout@v4
with:
submodules: 'recursive'

- name: Build wheels
uses: pypa/cibuildwheel@v2.22.0
env:
CIBW_BEFORE_ALL_MACOS: brew install autoconf automake
CIBW_BEFORE_ALL_LINUX: yum install -y bzip2-devel || apk add --upgrade bzip2-dev || apt-get install -y libbz2-dev
# Skip these architectures, 32-bit, PyPy, and musl
CIBW_SKIP: '*-musllinux_i686 *-manylinux_i686 pp* *musllinux*'

- uses: actions/upload-artifact@v4
with:
name: cibw-wheels-${{ matrix.os }}-${{ strategy.job-index }}
path: ./wheelhouse/*.whl

pypi-publish:
needs: [build_wheels]
name: Upload release to PyPI
runs-on: ubuntu-latest
environment:
name: pypi
url: https://pypi.org/p/<your-pypi-project-name>
permissions:
id-token: write
steps:
- uses: actions/download-artifact@v4
with:
pattern: cibw-*
path: dist
merge-multiple: true

- name: Publish package distributions to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
# Testing only
# with:
# repository-url: https://test.pypi.org/legacy/
12 changes: 11 additions & 1 deletion EASTR/extract_junctions.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
import collections
import multiprocessing
import os
import pathlib
import shlex
import subprocess

import pandas as pd

this_directory = pathlib.Path(__file__).resolve().parent
# This should exist with source after compilation.
JUNCTION_CMD = os.path.join(this_directory, 'junction_extractor')


def get_junctions_from_bed(bed_path: str) -> dict:
junctions = {}
Expand Down Expand Up @@ -48,8 +53,9 @@ def get_junctions_multi_bed(bed_list:list, p) -> dict:
return dd

def junction_extractor(bam_path:str, out_path:str) -> dict:
check_for_dependency()
name = os.path.splitext(os.path.basename(bam_path))[0]
cmd = f"junction_extractor -o {out_path} {bam_path}"
cmd = f"{JUNCTION_CMD} -o {out_path} {bam_path}"
a = subprocess.Popen(shlex.split(cmd), stdout=subprocess.DEVNULL)
b = a.communicate()

Expand Down Expand Up @@ -155,3 +161,7 @@ def extract_splice_sites_gtf(gtf_path:str) -> dict:
# x=extract_splice_sites_bam_regtools(bam_path)
# end = time.time()
# print(f"took {(end-start)/60} mins to get junctions")

def check_for_dependency():
if not os.path.exists(JUNCTION_CMD):
raise RuntimeError(f"{JUNCTION_CMD} not found.")
13 changes: 12 additions & 1 deletion EASTR/output_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import csv
import multiprocessing
import os
import pathlib
import shlex
import subprocess
import sys
Expand All @@ -11,6 +12,10 @@
from EASTR import alignment_utils
from EASTR import utils

this_directory = pathlib.Path(__file__).resolve().parent
# This should exist with source after compilation.
VACUUM_CMD = os.path.join(this_directory, 'vacuum')

def out_junctions_filelist(bam_list:list, gtf_path, bed_list, out_junctions, suffix="") -> Union[List[str], None, str]:
if out_junctions is None:
return None
Expand Down Expand Up @@ -217,7 +222,8 @@ def spurious_dict_bam_by_sample_to_bed(spurious_dict, bam_list, out_removed_junc


def filter_bam_with_vacuum(bam_path, spurious_junctions_bed, out_bam_path, verbose, removed_alignments_bam):
vacuum_cmd = "vacuum --remove_mate "
check_for_dependency()
vacuum_cmd = f"{VACUUM_CMD} --remove_mate "
if verbose:
vacuum_cmd = f"{vacuum_cmd} -V"
if removed_alignments_bam:
Expand Down Expand Up @@ -289,3 +295,8 @@ def filter_multi_bam_with_vacuum(bam_list, sample_to_bed, out_bam_list, p, verbo
# # spurious_alignments, NH = get_spurious_alignments(bam_path, spurious_introns)
# # end = time.time()
# # print(f"took {(end-start)/60} mins"))

def check_for_dependency():
"""Check if runtime dependency exists."""
if not os.path.exists(VACUUM_CMD):
raise RuntimeError(f"{VACUUM_CMD} not found.")
61 changes: 9 additions & 52 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,64 +27,21 @@ regardless of the alignment software used.
The installation steps for running EASTR are outlined below. Installation takes
a few minutes.

1. Clone source repository
1. Clone repository

```bash
git clone --recurse-submodules https://github.com/ishinder/EASTR.git
cd EASTR
```

2. Compile junction_extractor and vacuum
2. Install source code

```bash
cd utils
cmake -DCMAKE_BUILD_TYPE=Release .
make
```

3. To add the junction_extractor and vacuum executables in the `utils` folder to
your PATH, you can follow these steps:

Get the absolute path of the build directory:

```bash
pwd
```

This command will print the absolute path of the current directory, which is
the `utils` directory.

Add the absolute path to the PATH environment variable: For temporary use
(not persistent across sessions), you can run:

```bash
export PATH=$PATH:<absolute_path_to_utils_directory>
```

Replace `<absolute_path_to_utils_directory>` with the path you obtained in
the previous step.

For persistent use (across sessions), you can add the `export` command to
your shell's configuration file. For bash, this is typically the `.bashrc` or
`.bash_profile` file in your home directory. For zsh, this is the `.zshrc`
file. To add the path to your shell configuration file, run:

```bash
echo 'export PATH=$PATH:<absolute_path_to_utils_directory>' >> ~/.bashrc
```

4. Install EASTR

Ensure you are in the EASTR main directory before proceeding:

```bash
# Navigate back to the main EASTR directory if you are not already there
cd path/to/EASTR
# (OPTIONAL) Install in a Python virtual environment
# python3 -m virtualenv .venv # (OPTIONAL)
# source .venv/bin/activate # (OPTIONAL)
make install # Install EASTR package
```
```bash
cd EASTR
# python3 -m venv .venv # (OPTIONAL)
# source .venv/bin/activate # (OPTIONAL)
pip install -U pip setuptools
pip install .
```

### Required Arguments

Expand Down
7 changes: 4 additions & 3 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def build_extension(self, ext):
subprocess.check_call(['cmake', '--build', '.', *build_args],
cwd=self.build_temp)

description = 'Tool for emending alignments of spuriously spliced transcript reads'
desc = 'Tool for emending alignments of spuriously spliced transcript reads'

with open('./README.md', 'r', encoding='utf-8') as fh:
long_description = fh.read()
Expand All @@ -67,7 +67,7 @@ def build_extension(self, ext):
version='1.0.0',
author='Ida Shinder',
author_email='ishinde1@jhmi.edu',
description=description,
description=desc,
long_description=long_description,
long_description_content_type='text/markdown',
url='https://github.com/ishinder/EASTR',
Expand All @@ -90,5 +90,6 @@ def build_extension(self, ext):
]
},
python_requires='>=3.10',
license = license_str,
license='MIT',
license_files=('LICENSE',),
)