Skip to content

Commit

Permalink
add first iteration of A*PA2 figures
Browse files Browse the repository at this point in the history
  • Loading branch information
RagnarGrootKoerkamp committed Mar 5, 2024
1 parent e352baf commit b66e74a
Show file tree
Hide file tree
Showing 5 changed files with 303 additions and 0 deletions.
9 changes: 9 additions & 0 deletions justfile
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,12 @@ codecoverage:

vis:
cargo run -r --example aligners_vis --features sdl

fig name:
cargo run -r --example fig-{{name}}-2 --features sdl
mogrify -format png imgs/astarpa2-paper/{{name}}/*bmp
rm imgs/astarpa2-paper/{{name}}/*bmp

fig-intro: (fig "intro")
fig-limitations: (fig "limitations")
fig-layers: (fig "layers")
12 changes: 12 additions & 0 deletions pa-bin/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ pa-types.workspace = true
pa-generate.workspace = true
pa-heuristic.workspace = true
astarpa.workspace = true
astarpa2.workspace = true
itertools.workspace = true
clap.workspace = true
pa-vis = {workspace = true, optional=true}
Expand Down Expand Up @@ -47,3 +48,14 @@ path = "examples/astarpa-figures/comparison.rs"
[[example]]
name = "fig-limitations"
path = "examples/astarpa-figures/limitations.rs"

# A*PA2 figures
[[example]]
name = "fig-intro-2"
path = "examples/astarpa2-figures/intro.rs"
[[example]]
name = "fig-limitations-2"
path = "examples/astarpa2-figures/limitations.rs"
[[example]]
name = "fig-layers-2"
path = "examples/astarpa2-figures/layers.rs"
110 changes: 110 additions & 0 deletions pa-bin/examples/astarpa2-figures/intro.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
#![feature(trait_upcasting)]
//! This generates the visualizations used in figure 1 in the paper and in the slides.

use astarpa::{astar, AstarPa};
use pa_affine_types::AffineCost;
use pa_base_algos::{
dt::{DiagonalTransition, GapCostHeuristic},
nw::{AffineFront, NW},
};
use pa_generate::uniform_fixed;
use pa_heuristic::{MatchConfig, NoCost, Pruning, GCSH};
use pa_types::Aligner;
use pa_vis::visualizer::{self, Gradient, When};
use pa_vis_types::NoVis;
use std::{path::PathBuf, time::Duration};

fn main() {
let n = 8000;
let e = 0.20;
let (ref a, ref b) = uniform_fixed(n, e);
eprintln!("Length {}", a.len());
let cost = astar(&a, &b, &NoCost, &NoVis).0 .0;
eprintln!("Distance {cost}");
eprintln!("Divergence {}", cost as f32 / a.len() as f32);

let cm = AffineCost::unit();
let mut config = visualizer::Config::default();
config.draw = When::None;
config.save = When::None;
config.save_last = true;
config.delay = Duration::from_secs_f32(0.0001);
config.downscaler = 4;
config.cell_size = 1;
config.style.bg_color = (255, 255, 255, 128);
config.style.expanded = Gradient::TurboGradient(0.25..0.90);
config.style.path = Some((0, 0, 0, 0));
config.style.path_width = Some(4);
config.layer_drawing = false;
config.style.draw_dt = false;
config.style.draw_f = false;
config.style.draw_labels = false;
config.transparent_bmp = true;
config.draw_old_on_top = true;
config.filepath = PathBuf::from("imgs/astarpa2-paper/intro");
config.clear_after_meeting_point = false;

let aligners: &mut [Box<dyn Aligner>] = &mut [
Box::new(NW {
cm,
strategy: pa_base_algos::Strategy::band_doubling(),
domain: pa_base_algos::Domain::gap_gap(),
block_width: 1,
v: config.with_filename("0_ukkonen"),
front: AffineFront,
trace: true,
sparse_h: false,
prune: false,
}),
Box::new(NW {
cm,
strategy: pa_base_algos::Strategy::band_doubling(),
domain: pa_base_algos::Domain::dist_gap(),
block_width: 1,
v: config.with_filename("1_edlib"),
front: AffineFront,
trace: true,
sparse_h: false,
prune: false,
}),
Box::new(AstarPa {
dt: false,
h: NoCost,
v: config.with_filename("2_dijkstra"),
}),
Box::new(DiagonalTransition::new(
cm,
GapCostHeuristic::Disable,
NoCost,
false,
config.with_filename("3_diagonal-transition"),
)),
Box::new(DiagonalTransition::new(
cm,
GapCostHeuristic::Disable,
NoCost,
true,
{
let mut c = config.with_filename("4_dt-divide-and-conquer");
c.draw_old_on_top = false;
c
},
)),
Box::new(AstarPa {
h: GCSH::new(MatchConfig::exact(5), Pruning::both()),
dt: true,
v: config.with_filename("5_astarpa"),
}),
astarpa2::AstarPa2Params::simple()
.make_aligner_with_visualizer(true, config.with_filename("6_astarpa2_simple")),
{
let mut params = astarpa2::AstarPa2Params::full();
params.heuristic.k = 5;
params
}
.make_aligner_with_visualizer(true, config.with_filename("7_astarpa2_full")),
];
for aligner in aligners {
aligner.align(a, b);
}
}
77 changes: 77 additions & 0 deletions pa-bin/examples/astarpa2-figures/layers.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
use astarpa::AstarPa;
use pa_heuristic::{MatchConfig, Prune, Pruning, CSH, GCSH, SH};
use pa_vis::visualizer::{self, Gradient, When};
use pa_vis_types::canvas::*;
use std::path::PathBuf;
use std::time::Duration;

fn main() {
let a = b"ACTCAGCTGTTGCCCGCTGTCGATCCGTAATTTAAAGTAGGTCGAAAC";
let b = b"ACTCAACGTTGCGCCTGTCTATCGTAATTAAAGTGGAGAAAC";

let mut config = visualizer::Config::default();
config.draw = When::None;
config.save = When::None;
config.save_last = true;
config.paused = false;
config.delay = Duration::from_secs_f32(0.0001);
config.cell_size = 12;
config.draw_old_on_top = false;
config.style.bg_color = WHITE;
config.style.expanded = Gradient::Fixed((130, 179, 102, 0));
config.style.explored = Some((0, 102, 204, 0));
config.style.heuristic = Gradient::Gradient((250, 250, 250, 0)..(180, 180, 180, 0));
config.style.max_heuristic = Some(10);
config.style.max_layer = Some(20);
config.style.pruned_match = RED;
config.style.path = None;
config.style.match_width = 3;
config.style.draw_heuristic = false;
config.style.draw_layers = true;
config.style.draw_contours = true;
config.style.draw_matches = true;
config.style.contour = BLACK;
config.layer_drawing = false;
config.style.draw_dt = false;
config.style.draw_f = false;
config.style.draw_labels = false;

config.filepath = PathBuf::from("imgs/astarpa2-paper/layers/");

if !cfg!(feature = "example") {
eprintln!("WARNING: Without the example feature, pruned matches aren't shown red for SH");
}

let mut astarpa2 = astarpa2::AstarPa2Params::full();
astarpa2.heuristic.k = 3;

let k = 2;
let mut match_config = MatchConfig {
length: pa_heuristic::LengthConfig::Fixed(k),
r: 1,
local_pruning: 0,
};
let pruning = Prune::None;
for p in [0, 5] {
match_config.local_pruning = p;
let suf = if p > 0 { "-lp" } else { "" };
AstarPa {
dt: false,
h: SH::new(match_config, Pruning::new(pruning)),
v: config.with_filename(&("sh".to_string() + suf)),
}
.align(a, b);
AstarPa {
dt: false,
h: CSH::new(match_config, Pruning::new(pruning)),
v: config.with_filename(&("csh".to_string() + suf)),
}
.align(a, b);
AstarPa {
dt: false,
h: GCSH::new(match_config, Pruning::new(pruning)),
v: config.with_filename(&("gcsh".to_string() + suf)),
}
.align(a, b);
}
}
95 changes: 95 additions & 0 deletions pa-bin/examples/astarpa2-figures/limitations.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
//! This generates the visualizations used in the limitations section of the paper.

use pa_generate::{uniform_seeded, ErrorModel};
use pa_vis::visualizer::{self, Gradient, When};
use pa_vis_types::canvas::RED;
use rand::SeedableRng;
use std::time::Duration;

fn main() {
let mut config = visualizer::Config::default();
config.draw = When::All;
config.save = When::None;
config.save_last = true;
config.delay = Duration::from_secs_f32(1.0);
config.paused = true;
config.style.bg_color = (255, 255, 255, 128);
config.style.expanded = Gradient::TurboGradient(0.25..0.9);
config.style.path_width = None;
config.draw_old_on_top = false;
config.layer_drawing = false;
config.transparent_bmp = false;
let scale = 16;
//config.downscaler = scale as u32;
config.downscaler = 16;
config.cell_size = 1;
config.style.path = None;
config.style.draw_matches = true;
config.style.match_width = 4;
config.style.match_shrink = 0;
config.style.pruned_match = RED;
config.style.draw_dt = false;
config.style.draw_f = false;
config.style.draw_labels = false;

config.filepath = "imgs/astarpa2-paper/limitations".into();

let mut astarpa2 = astarpa2::AstarPa2Params::full();
astarpa2.heuristic.k = 8;
astarpa2.block_width = 64;

{
let (mut a, mut b) = uniform_seeded(250 * scale, 0.05, 6);
let (mut a2, mut b2) = uniform_seeded(200 * scale, 0.50, 2);
let (mut a3, mut b3) = uniform_seeded(50 * scale, 0.08, 3);
a.append(&mut a2);
b.append(&mut b2);
a.append(&mut a3);
b.append(&mut b3);

let cost = astarpa2
.make_aligner_with_visualizer(true, config.with_filename("high-error-rate"))
.align(&a, &b)
.0;
println!("cost {cost}");
}

{
let (mut a, mut b) = uniform_seeded(350 * scale, 0.08, 5);
let (mut a2, _) = uniform_seeded(50 * scale, 0.08, 8);
let (mut a3, mut b3) = uniform_seeded(100 * scale, 0.08, 9);
a.append(&mut a2);
//b.append(&mut b2);
a.append(&mut a3);
b.append(&mut b3);

let cost = astarpa2
.make_aligner_with_visualizer(true, config.with_filename("deletion"))
.align(&a, &b)
.0;
println!("cost {cost}");
}

{
let (mut a, mut b) = uniform_seeded(100 * scale, 0.08, 1);
let rng = &mut rand_chacha::ChaCha8Rng::seed_from_u64(2 as u64);
let (mut a2, mut b2) = pa_generate::SeqPairGenerator {
length: 300 * scale,
error_rate: 0.08,
error_model: ErrorModel::SymmetricRepeat,
pattern_length: Some(10 * scale),
}
.generate(rng);
let (mut a3, mut b3) = uniform_seeded(100 * scale, 0.08, 3);
a.append(&mut a2);
b.append(&mut b2);
a.append(&mut a3);
b.append(&mut b3);

let cost = astarpa2
.make_aligner_with_visualizer(true, config.with_filename("repeats"))
.align(&a, &b)
.0;
println!("cost {cost}");
}
}

0 comments on commit b66e74a

Please sign in to comment.