forked from smarco/WFA2-lib
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request smarco#29 from RagnarGrootKoerkamp/development
Add rust bindings
- Loading branch information
Showing
3 changed files
with
116 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
//! WFA bindings for rust using Bindgen. | ||
//! | ||
//! First, add `bindgen` to your dependencies: | ||
//! ```toml | ||
//! [build-dependencies] | ||
//! bindgen = "0.60.1" | ||
//! ``` | ||
//! | ||
//! Then save this file as `build.rs` in the root of your crate. | ||
//! Update the paths below to match your WFA installation/repository. | ||
//! | ||
//! The example has the WFA2-lib repository cloned in `../wfa2`. | ||
//! Make sure to run `make lib_wfa` in the WFA repository. | ||
//! The code below will tell cargo to link against `../wfa2/lib/libwfa.a`. | ||
//! | ||
//! The bindings will be writted to a special `OUT_DIR` set by cargo. See | ||
//! `example.rs` for an example of how to include and use the generated | ||
//! bindings. | ||
extern crate bindgen; | ||
|
||
use std::env; | ||
use std::path::PathBuf; | ||
|
||
fn wfa() { | ||
// 1. Link instructions for Cargo. | ||
|
||
// The directory of the WFA libraries, added to the search path. | ||
println!("cargo:rustc-link-search=../wfa2/lib"); | ||
// Link the `wfa-lib` library. | ||
println!("cargo:rustc-link-lib=wfa"); | ||
// Also link `omp`. | ||
println!("cargo:rustc-link-lib=omp"); | ||
// Invalidate the built crate whenever the linked library changes. | ||
println!("cargo:rerun-if-changed=../wfa2/lib/libwfa.a"); | ||
|
||
// 2. Generate bindings. | ||
|
||
let bindings = bindgen::Builder::default() | ||
// Generate bindings for this header file. | ||
.header("../wfa2/wavefront/wavefront_align.h") | ||
// Add this directory to the include path to find included header files. | ||
.clang_arg("-I../wfa2") | ||
// Generate bindings for all functions starting with `wavefront_`. | ||
.allowlist_function("wavefront_.*") | ||
// Generate bindings for all variables starting with `wavefront_`. | ||
.allowlist_var("wavefront_.*") | ||
// Invalidate the built crate whenever any of the included header files | ||
// changed. | ||
.parse_callbacks(Box::new(bindgen::CargoCallbacks)) | ||
// Finish the builder and generate the bindings. | ||
.generate() | ||
// Unwrap the Result and panic on failure. | ||
.expect("Unable to generate bindings"); | ||
|
||
// Write the bindings to the $OUT_DIR/bindings_wfa.rs file. | ||
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); | ||
bindings | ||
.write_to_file(out_path.join("bindings_wfa.rs")) | ||
.expect("Couldn't write bindings!"); | ||
} | ||
|
||
fn main() { | ||
wfa(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
/// Include the generated bindings into a separate module. | ||
#[allow(non_upper_case_globals)] | ||
#[allow(non_snake_case)] | ||
#[allow(non_camel_case_types)] | ||
#[allow(unused)] | ||
mod wfa { | ||
include!(concat!(env!("OUT_DIR"), "/bindings_wfa.rs")); | ||
} | ||
|
||
/// Compute the affine alignment score between `a` and `b` with the given substitution, | ||
/// gap-open, and gap-extend penalties. | ||
fn linear_score(a: &[i8], b: &[i8], sub: i32, indel: i32) -> i32 { | ||
unsafe { | ||
let mut attributes = wfa::wavefront_aligner_attr_default; | ||
// Do not use a heuristic (enabled by default). | ||
attributes.heuristic.strategy = wfa::wf_heuristic_strategy_wf_heuristic_none; | ||
// Only compute the score (not a path). | ||
attributes.alignment_scope = wfa::alignment_scope_t_compute_score; | ||
|
||
// Set the cost model and parameters. | ||
attributes.distance_metric = wfa::distance_metric_t_gap_affine; | ||
attributes.affine_penalties.mismatch = mismatch as i32; | ||
attributes.affine_penalties.gap_opening = gap_open as i32; | ||
attributes.affine_penalties.gap_extension = gap_extend as i32; | ||
|
||
// Initialize the aligner object. | ||
// This should be reused for multiple queries. | ||
let wf_aligner = wfa::wavefront_aligner_new(&mut attributes); | ||
|
||
// Do the alignment. | ||
let status = wfa::wavefront_align( | ||
wf_aligner, | ||
a.as_ptr(), | ||
a.len() as i32, | ||
b.as_ptr(), | ||
b.len() as i32, | ||
); | ||
assert_eq!(status, 0); | ||
|
||
let score = (*wf_aligner).cigar.score; | ||
|
||
// Clean up memory. | ||
wfa::wavefront_aligner_delete(wf_aligner); | ||
score | ||
} | ||
} |