From 50452df05e9deba62f8181b4234b91df91dd51e5 Mon Sep 17 00:00:00 2001 From: ivan-aksamentov Date: Sat, 26 Mar 2022 04:54:11 +0100 Subject: [PATCH] refactor: lint --- docker-dev | 261 ++++++++++++------ packages_rs/nextclade-web/src/lib.rs | 2 +- packages_rs/nextclade/src/align/align.rs | 95 +++---- packages_rs/nextclade/src/align/backtrace.rs | 108 ++++---- packages_rs/nextclade/src/align/gap_open.rs | 8 +- .../nextclade/src/align/score_matrix.rs | 166 +++++------ .../nextclade/src/align/score_matrix_aa.rs | 6 +- .../nextclade/src/align/score_matrix_nuc.rs | 6 +- .../nextclade/src/align/seed_alignment.rs | 78 +++--- packages_rs/nextclade/src/align/seed_match.rs | 13 +- packages_rs/nextclade/src/analyze/analyze.rs | 2 - .../nextclade/src/cli/nextclade_loop.rs | 2 +- packages_rs/nextclade/src/gene/gene.rs | 7 +- packages_rs/nextclade/src/io/aa.rs | 20 +- packages_rs/nextclade/src/io/errors_csv.rs | 2 +- packages_rs/nextclade/src/io/fs.rs | 2 +- packages_rs/nextclade/src/io/nuc.rs | 28 +- .../nextclade/src/translate/complement.rs | 2 +- .../src/translate/frame_shifts_translate.rs | 4 +- .../nextclade/src/translate/translate.rs | 12 +- .../src/translate/translate_genes.rs | 5 +- packages_rs/nextclade/src/tree/tree.rs | 15 +- packages_rs/nextclade/src/utils/error.rs | 1 - .../nextclade/src/utils/global_init.rs | 6 +- packages_rs/nextclade/src/utils/range.rs | 6 +- 25 files changed, 452 insertions(+), 405 deletions(-) diff --git a/docker-dev b/docker-dev index 7b4c7330f..fc4b99c4e 100755 --- a/docker-dev +++ b/docker-dev @@ -49,75 +49,174 @@ export COLORBT_SHOW_HIDDEN="0" export RUST_LOG="warn" export CARGO_BUILD_TARGET_DIR="${BUILD_DIR_REL}" +export LINT_NORMAL="\ +-Wfuture_incompatible \ +-Wnonstandard_style \ +-Wrust_2018_idioms \ +-Wtrivial_numeric_casts \ +\ +-Wclippy::all \ +\ +-Wclippy::await_holding_lock \ +-Wclippy::char_lit_as_u8 \ +-Wclippy::checked_conversions \ +-Wclippy::dbg_macro \ +-Wclippy::debug_assert_with_mut_call \ +-Wclippy::disallowed_script_idents \ +-Wclippy::doc_markdown \ +-Wclippy::empty_enum \ +-Wclippy::enum_glob_use \ +-Wclippy::equatable_if_let \ +-Wclippy::exit \ +-Wclippy::expl_impl_clone_on_copy \ +-Wclippy::explicit_deref_methods \ +-Wclippy::explicit_into_iter_loop \ +-Wclippy::fallible_impl_from \ +-Wclippy::filter_map_next \ +-Wclippy::flat_map_option \ +-Wclippy::float_cmp_const \ +-Wclippy::fn_params_excessive_bools \ +-Wclippy::fn_to_numeric_cast_any \ +-Wclippy::from_iter_instead_of_collect \ +-Wclippy::if_let_mutex \ +-Wclippy::implicit_clone \ +-Wclippy::imprecise_flops \ +-Wclippy::index_refutable_slice \ +-Wclippy::inefficient_to_string \ +-Wclippy::invalid_upcast_comparisons \ +-Wclippy::iter_not_returning_iterator \ +-Wclippy::large_digit_groups \ +-Wclippy::large_stack_arrays \ +-Wclippy::large_types_passed_by_value \ +-Wclippy::let_unit_value \ +-Wclippy::linkedlist \ +-Wclippy::lossy_float_literal \ +-Wclippy::macro_use_imports \ +-Wclippy::manual_ok_or \ +-Wclippy::map_err_ignore \ +-Wclippy::map_flatten \ +-Wclippy::map_unwrap_or \ +-Wclippy::match_on_vec_items \ +-Wclippy::match_same_arms \ +-Wclippy::match_wild_err_arm \ +-Wclippy::match_wildcard_for_single_variants \ +-Wclippy::mem_forget \ +-Wclippy::mismatched_target_os \ +-Wclippy::missing_enforced_import_renames \ +-Wclippy::mut_mut \ +-Wclippy::mutex_integer \ +-Wclippy::needless_continue \ +-Wclippy::needless_for_each \ +-Wclippy::negative_feature_names \ +-Wclippy::nonstandard_macro_braces \ +-Wclippy::option_option \ +-Wclippy::path_buf_push_overwrite \ +-Wclippy::ptr_as_ptr \ +-Wclippy::rc_mutex \ +-Wclippy::ref_option_ref \ +-Wclippy::rest_pat_in_fully_bound_structs \ +-Wclippy::same_functions_in_if_condition \ +-Wclippy::semicolon_if_nothing_returned \ +-Wclippy::single_match_else \ +-Wclippy::string_add \ +-Wclippy::string_add_assign \ +-Wclippy::string_lit_as_bytes \ +-Wclippy::string_to_string \ +-Wclippy::todo \ +-Wclippy::trailing_empty_array \ +-Wclippy::trait_duplication_in_bounds \ +-Wclippy::unimplemented \ +-Wclippy::unnecessary_wraps \ +-Wclippy::unnested_or_patterns \ +-Wclippy::useless_transmute \ +-Wclippy::verbose_file_reads \ +-Wclippy::zero_sized_map_values \ +" + +export LINT_EXTRA="\ + ${LINT_NORMAL} \ + -Wclippy::pedantic \ +" + +export LINT_CRAZY="\ + ${LINT_EXTRA} \ + -Wclippy::restriction \ + -Wclippy::nursery \ +" + export LINT_ALLOW_NOW_BUT_FIX_THESE_LATER=" \ --A clippy::cognitive-complexity \ --A clippy::else-if-without-else \ --A clippy::expect-used \ --A clippy::missing-const-for-fn \ --A clippy::panic \ --A clippy::panic-in-result-fn \ --A clippy::suboptimal_flops \ --A clippy::too_many_arguments \ --A clippy::unsafe-derive-deserialize \ --A clippy::unwrap-in-result \ --A clippy::unwrap-used \ --A clippy::useless-transmute \ +-Aclippy::cognitive-complexity \ +-Aclippy::else-if-without-else \ +-Aclippy::expect-used \ +-Aclippy::missing-const-for-fn \ +-Aclippy::panic \ +-Aclippy::panic-in-result-fn \ +-Aclippy::suboptimal_flops \ +-Aclippy::too_many_arguments \ +-Aclippy::unsafe-derive-deserialize \ +-Aclippy::unwrap-in-result \ +-Aclippy::unwrap-used \ +-Aclippy::useless-transmute \ " export LINT_ALLOW=" \ ${LINT_ALLOW_NOW_BUT_FIX_THESE_LATER} \ --A clippy::as-conversions \ --A clippy::cast-lossless \ --A clippy::cast-possible-truncation \ --A clippy::cast-possible-wrap \ --A clippy::cast-precision-loss \ --A clippy::cast-sign-loss \ --A clippy::default-numeric-fallback \ --A clippy::doc-markdown \ --A clippy::exhaustive-enums \ --A clippy::exhaustive-structs \ --A clippy::float-arithmetic \ --A clippy::if-not-else \ --A clippy::implicit-hasher \ --A clippy::implicit-return \ --A clippy::inconsistent_digit_grouping \ --A clippy::indexing-slicing \ --A clippy::integer-arithmetic \ --A clippy::integer-division \ --A clippy::large_digit_groups \ --A clippy::let-underscore-must-use \ --A clippy::match-same-arms \ --A clippy::missing-docs-in-private-items \ --A clippy::missing-errors-doc \ --A clippy::missing-panics-doc \ --A clippy::missing_inline_in_public_items \ --A clippy::mod-module-files \ --A clippy::module-name-repetitions \ --A clippy::module_inception \ --A clippy::must-use-candidate \ --A clippy::new_without_default \ --A clippy::non-ascii-literal \ --A clippy::option-if-let-else \ --A clippy::pattern-type-mismatch \ --A clippy::print-stderr \ --A clippy::print-stdout \ --A clippy::separated-literal-suffix \ --A clippy::shadow-reuse \ --A clippy::shadow-same \ --A clippy::shadow-unrelated \ --A clippy::should_implement_trait \ --A clippy::similar-names \ --A clippy::too-many-lines \ --A clippy::unnecessary-wraps \ --A clippy::unreachable \ --A clippy::unreadable-literal \ --A clippy::unused-self \ --A clippy::unused-unit \ --A clippy::use-debug \ --A clippy::use-self \ --A clippy::wildcard-enum-match-arm \ +-Aclippy::as-conversions \ +-Aclippy::cast-lossless \ +-Aclippy::cast-possible-truncation \ +-Aclippy::cast-possible-wrap \ +-Aclippy::cast-precision-loss \ +-Aclippy::cast-sign-loss \ +-Aclippy::default-numeric-fallback \ +-Aclippy::doc-markdown \ +-Aclippy::exhaustive-enums \ +-Aclippy::exhaustive-structs \ +-Aclippy::float-arithmetic \ +-Aclippy::if-not-else \ +-Aclippy::implicit-hasher \ +-Aclippy::implicit-return \ +-Aclippy::inconsistent_digit_grouping \ +-Aclippy::indexing-slicing \ +-Aclippy::integer-arithmetic \ +-Aclippy::integer-division \ +-Aclippy::iter_nth_zero \ +-Aclippy::large_digit_groups \ +-Aclippy::let-underscore-must-use \ +-Aclippy::match-same-arms \ +-Aclippy::missing-docs-in-private-items \ +-Aclippy::missing-errors-doc \ +-Aclippy::missing-panics-doc \ +-Aclippy::missing_inline_in_public_items \ +-Aclippy::mod-module-files \ +-Aclippy::module-name-repetitions \ +-Aclippy::module_inception \ +-Aclippy::must-use-candidate \ +-Aclippy::new_without_default \ +-Aclippy::non-ascii-literal \ +-Aclippy::option-if-let-else \ +-Aclippy::pattern-type-mismatch \ +-Aclippy::print-stderr \ +-Aclippy::print-stdout \ +-Aclippy::separated-literal-suffix \ +-Aclippy::shadow-reuse \ +-Aclippy::shadow-same \ +-Aclippy::shadow-unrelated \ +-Aclippy::should_implement_trait \ +-Aclippy::similar-names \ +-Aclippy::too-many-lines \ +-Aclippy::unnecessary-wraps \ +-Aclippy::unreachable \ +-Aclippy::unreadable-literal \ +-Aclippy::unused-self \ +-Aclippy::unused-unit \ +-Aclippy::use-debug \ +-Aclippy::use-self \ +-Aclippy::wildcard-enum-match-arm \ " +export LINT_FIX="--fix --allow-staged" + + export EXTENSIONS_TO_WATCH="rs,toml,lock" export FILES_TO_WATCH="\ @@ -226,75 +325,75 @@ case "$1" in ;; "lint" | "l") shift - LINT=" " + LINT="${LINT_NORMAL}" WATCH=0 FIX= ;; "watch-lint" | "wl") shift - LINT=" " + LINT="${LINT_NORMAL}" WATCH=1 FIX= ;; "lint-extra" | "le") shift - LINT="-W clippy::all -W clippy::pedantic" + LINT="${LINT_EXTRA}" WATCH=0 FIX= ;; "watch-lint-extra" | "wle") shift - LINT="-W clippy::all -W clippy::pedantic" + LINT="${LINT_EXTRA}" WATCH=1 FIX= ;; "lint-crazy" | "lc") shift - LINT="-W clippy::all -W clippy::pedantic -W clippy::restriction -W clippy::nursery" + LINT="${LINT_CRAZY}" WATCH=0 FIX= ;; "watch-lint-crazy" | "wlc") shift - LINT="-W clippy::all -W clippy::pedantic -W clippy::restriction -W clippy::nursery" + LINT="${LINT_CRAZY}" WATCH=1 FIX= ;; "lint-fix" | "lf") shift - LINT=" " + LINT="${LINT_NORMAL}" WATCH=0 - FIX="--fix --allow-staged" + FIX="${LINT_FIX}" ;; "watch-lint-fix" | "wlf") shift - LINT=" " + LINT="${LINT_NORMAL}" WATCH=1 - FIX="--fix --allow-staged" + FIX="${LINT_FIX}" ;; "lint-extra-fix" | "lef") shift - LINT="-W clippy::all -W clippy::pedantic" + LINT="${LINT_EXTRA}" WATCH=0 - FIX="--fix --allow-staged" + FIX="${LINT_FIX}" ;; "watch-lint-extra-fix" | "wlef") shift - LINT="-W clippy::all -W clippy::pedantic" + LINT="${LINT_EXTRA}" WATCH=1 - FIX="--fix --allow-staged" + FIX="${LINT_FIX}" ;; "lint-crazy-fix" | "lcf") shift - LINT="-W clippy::all -W clippy::pedantic -W clippy::restriction -W clippy::nursery" + LINT="${LINT_CRAZY}" WATCH=0 - FIX="--fix --allow-staged" + FIX="${LINT_FIX}" ;; "watch-lint-crazy-fix" | "wlcf") shift - LINT="-W clippy::all -W clippy::pedantic -W clippy::restriction -W clippy::nursery" + LINT="${LINT_CRAZY}" WATCH=1 - FIX="--fix --allow-staged" + FIX="${LINT_FIX}" ;; "exec" | "e") shift @@ -358,7 +457,7 @@ elif [ "${TEST}" == "1" ]; then PRETTY_TEST="( grep --color=always --line-buffered -vP \"running.*tests|\x1b\[32m.\x1b\(B\x1b\[m|^$|test result|TEST START\" || true )" COMMAND="cargo test --color=always -q --target-dir='${BUILD_DIR_REL}' ${RUST_TARGET} ${@:-} -- --nocapture --color=always | ${PRETTY_TEST} ${SUCCESS_OR_FAILURE}" elif [ ! -z "${LINT}" ]; then - COMMAND="cargo clippy --exclude=3rdparty -q --target-dir=\"${BUILD_DIR_REL}\" --all ${FIX:-} -- ${LINT:-} ${LINT_ALLOW}" + COMMAND="cargo clippy --exclude=3rdparty -q --target-dir=\"${BUILD_DIR_REL}\" --all ${FIX:-} -- ${LINT} ${LINT_ALLOW}" else COMMAND="${NICE} ${TIME} ${COMMAND}" fi diff --git a/packages_rs/nextclade-web/src/lib.rs b/packages_rs/nextclade-web/src/lib.rs index abe5f3c60..9fe005be0 100644 --- a/packages_rs/nextclade-web/src/lib.rs +++ b/packages_rs/nextclade-web/src/lib.rs @@ -4,7 +4,7 @@ use nextclade::analyze::analyze::{AnalysisInput, AnalysisResult, Nextclade, Next use nextclade::utils::error::report_to_string; #[global_allocator] -static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT; +static ALLOC: wee_alloc::WeeAlloc<'_> = wee_alloc::WeeAlloc::INIT; #[wasm_bindgen] pub struct NextcladeWasm { diff --git a/packages_rs/nextclade/src/align/align.rs b/packages_rs/nextclade/src/align/align.rs index b31a92162..da8507bd1 100644 --- a/packages_rs/nextclade/src/align/align.rs +++ b/packages_rs/nextclade/src/align/align.rs @@ -1,8 +1,6 @@ -#![allow(non_snake_case)] - use crate::align::backtrace::{backtrace, AlignmentOutput}; use crate::align::score_matrix::{score_matrix, ScoreMatrixResult}; -use crate::align::seed_alignment::{seedAlignment, SeedAlignmentResult}; +use crate::align::seed_alignment::{seed_alignment, SeedAlignmentResult}; use crate::io::aa::Aa; use crate::io::letter::Letter; use crate::io::nuc::Nuc; @@ -12,58 +10,58 @@ use log::trace; #[derive(Debug)] pub struct AlignPairwiseParams { - pub penaltyGapExtend: i32, - pub penaltyGapOpen: i32, - pub penaltyGapOpenInFrame: i32, - pub penaltyGapOpenOutOfFrame: i32, - pub penaltyMismatch: i32, - pub scoreMatch: i32, - pub maxIndel: usize, + pub penalty_gap_extend: i32, + pub penalty_gap_open: i32, + pub penalty_gap_open_in_frame: i32, + pub penalty_gap_open_out_of_frame: i32, + pub penalty_mismatch: i32, + pub score_match: i32, + pub max_indel: usize, pub min_length: usize, - pub seedLength: usize, - pub seedSpacing: i32, - pub minSeeds: i32, - pub mismatchesAllowed: usize, - pub translatePastStop: bool, + pub seed_length: usize, + pub seed_spacing: i32, + pub min_seeds: i32, + pub mismatches_allowed: usize, + pub translate_past_stop: bool, } impl Default for AlignPairwiseParams { fn default() -> Self { Self { min_length: 100, - penaltyGapExtend: 0, - penaltyGapOpen: 6, - penaltyGapOpenInFrame: 7, - penaltyGapOpenOutOfFrame: 8, - penaltyMismatch: 1, - scoreMatch: 3, - maxIndel: 400, - seedLength: 21, - minSeeds: 10, - seedSpacing: 100, - mismatchesAllowed: 3, - translatePastStop: true, + penalty_gap_extend: 0, + penalty_gap_open: 6, + penalty_gap_open_in_frame: 7, + penalty_gap_open_out_of_frame: 8, + penalty_mismatch: 1, + score_match: 3, + max_indel: 400, + seed_length: 21, + min_seeds: 10, + seed_spacing: 100, + mismatches_allowed: 3, + translate_past_stop: true, } } } -fn alignPairwise>( +fn align_pairwise>( qry_seq: &[T], ref_seq: &[T], - gapOpenClose: &[i32], + gap_open_close: &[i32], params: &AlignPairwiseParams, - bandWidth: usize, + band_width: usize, shift: i32, ) -> Result, Report> { trace!("Align pairwise: started. Params: {params:?}"); - let max_indel = params.maxIndel; - if bandWidth > max_indel { - trace!("Align pairwise: failed. band_width={bandWidth}, max_indel={max_indel}"); + let max_indel = params.max_indel; + if band_width > max_indel { + trace!("Align pairwise: failed. band_width={band_width}, max_indel={max_indel}"); return make_error!("Unable to align: too many insertions, deletions, duplications, or ambiguous seed matches"); } - let ScoreMatrixResult { scores, paths } = score_matrix(qry_seq, ref_seq, gapOpenClose, bandWidth, shift, params); + let ScoreMatrixResult { scores, paths } = score_matrix(qry_seq, ref_seq, gap_open_close, band_width, shift, params); Ok(backtrace(qry_seq, ref_seq, &scores, &paths, shift)) } @@ -71,7 +69,7 @@ fn alignPairwise>( pub fn align_nuc( qry_seq: &[Nuc], ref_seq: &[Nuc], - gapOpenClose: &[i32], + gap_open_close: &[i32], params: &AlignPairwiseParams, ) -> Result, Report> { let qry_len: usize = qry_seq.len(); @@ -82,25 +80,25 @@ pub fn align_nuc( ); } - let SeedAlignmentResult { meanShift, bandWidth } = seedAlignment(qry_seq, ref_seq, params)?; + let SeedAlignmentResult { mean_shift, band_width } = seed_alignment(qry_seq, ref_seq, params)?; trace!( - "Align pairwise: after seed alignment: bandWidth={:}, meanShift={:}\n", - bandWidth, - meanShift + "Align pairwise: after seed alignment: band_width={:}, mean_shift={:}\n", + band_width, + mean_shift ); - alignPairwise(qry_seq, ref_seq, gapOpenClose, params, bandWidth, meanShift) + align_pairwise(qry_seq, ref_seq, gap_open_close, params, band_width, mean_shift) } pub fn align_aa( qry_seq: &[Aa], ref_seq: &[Aa], - gapOpenClose: &[i32], + gap_open_close: &[i32], params: &AlignPairwiseParams, - bandWidth: usize, - meanShift: i32, + band_width: usize, + mean_shift: i32, ) -> Result, Report> { - alignPairwise(qry_seq, ref_seq, gapOpenClose, params, bandWidth, meanShift) + align_pairwise(qry_seq, ref_seq, gap_open_close, params, band_width, mean_shift) } #[cfg(test)] @@ -116,7 +114,6 @@ mod tests { struct Context { params: AlignPairwiseParams, - gene_map: GeneMap, gap_open_close: GapScoreMap, } @@ -129,14 +126,10 @@ mod tests { let gene_map = GeneMap::new(); - let dummy_ref_seq = vec![Nuc::GAP; 100]; + let dummy_ref_seq = vec![Nuc::Gap; 100]; let gap_open_close = get_gap_open_close_scores_codon_aware(&dummy_ref_seq, &gene_map, ¶ms); - Context { - params, - gene_map, - gap_open_close, - } + Context { params, gap_open_close } } #[rstest] diff --git a/packages_rs/nextclade/src/align/backtrace.rs b/packages_rs/nextclade/src/align/backtrace.rs index ef3cbf459..00176af54 100644 --- a/packages_rs/nextclade/src/align/backtrace.rs +++ b/packages_rs/nextclade/src/align/backtrace.rs @@ -1,22 +1,16 @@ -#![allow(clippy::separated_literal_suffix)] -#![allow(non_snake_case)] -#![allow(non_upper_case_globals)] -#![allow(unused_assignments)] -#![allow(unused_imports)] - -use crate::align::score_matrix::{qryGAPextend, qryGAPmatrix, refGAPextend, refGAPmatrix, END_OF_SEQUENCE, MATCH}; +use crate::align::score_matrix::{QRY_GAP_EXTEND, QRY_GAP_MATRIX, REF_GAP_EXTEND, REF_GAP_MATRIX, END_OF_SEQUENCE, MATCH}; use crate::io::letter::Letter; use crate::utils::vec2d::Vec2d; use std::cmp; -fn index_to_shift(si: i32, bandWidth: i32, meanShift: i32) -> i32 { - si - bandWidth + meanShift +fn index_to_shift(si: i32, band_width: i32, mean_shift: i32) -> i32 { + si - band_width + mean_shift } struct DetermineBestAlignmentResult { si: i32, - qPos: i32, - rPos: i32, + q_pos: i32, + r_pos: i32, best_score: usize, } @@ -30,34 +24,34 @@ fn determine_best_alignment( let num_cols = scores.num_cols() as i32; let num_rows = scores.num_rows() as i32; - let mut lastScoreByShift: Vec = vec![0; num_rows as usize]; - let mut lastIndexByShift: Vec = vec![0; num_rows as usize]; + let mut last_score_by_shift: Vec = vec![0; num_rows as usize]; + let mut last_index_by_shift: Vec = vec![0; num_rows as usize]; let mut si: i32 = 0; let mut best_score = END_OF_SEQUENCE; for i in 0..num_rows { let is = index_to_shift(i, band_width, mean_shift); // Determine the last index - lastIndexByShift[i as usize] = cmp::min(num_cols as i32 - 1, qry_len as i32 + is); + last_index_by_shift[i as usize] = cmp::min(num_cols - 1, qry_len + is); - if (lastIndexByShift[i as usize] >= 0) && (lastIndexByShift[i as usize] < num_cols as i32) { - lastScoreByShift[i as usize] = scores[(i, lastIndexByShift[i as usize])]; + if (last_index_by_shift[i as usize] >= 0) && (last_index_by_shift[i as usize] < num_cols) { + last_score_by_shift[i as usize] = scores[(i, last_index_by_shift[i as usize])]; - if lastScoreByShift[i as usize] > best_score { - best_score = lastScoreByShift[i as usize]; + if last_score_by_shift[i as usize] > best_score { + best_score = last_score_by_shift[i as usize]; si = i; } } } - // determine position tuple qPos, rPos corresponding to the place it the matrix + // determine position tuple q_pos, r_pos corresponding to the place it the matrix let shift = index_to_shift(si, band_width, mean_shift); - let rPos = lastIndexByShift[si as usize] - 1; - let qPos = rPos - shift; + let r_pos = last_index_by_shift[si as usize] - 1; + let q_pos = r_pos - shift; DetermineBestAlignmentResult { - si: si as i32, - qPos, - rPos, + si, + q_pos, + r_pos, best_score: best_score as usize, } } @@ -73,73 +67,73 @@ pub fn backtrace>( ref_seq: &[T], scores: &Vec2d, paths: &Vec2d, - meanShift: i32, + mean_shift: i32, ) -> AlignmentOutput { let num_cols = scores.num_cols(); let num_rows = scores.num_rows(); let qry_len = qry_seq.len() as i32; let ref_len = ref_seq.len() as i32; - let bandWidth = ((num_rows - 1) / 2) as i32; + let band_width = ((num_rows - 1) / 2) as i32; - let aln_capacity = num_cols + 3 * bandWidth as usize; + let aln_capacity = num_cols + 3 * band_width as usize; let mut aln_ref = Vec::::with_capacity(aln_capacity); let mut aln_qry = Vec::::with_capacity(aln_capacity); let DetermineBestAlignmentResult { mut si, - mut qPos, - mut rPos, + mut q_pos, + mut r_pos, best_score, - } = determine_best_alignment(scores, bandWidth, meanShift, qry_len); + } = determine_best_alignment(scores, band_width, mean_shift, qry_len); // Add right overhang, i.e. unaligned parts of the query or reference - if rPos < ref_len - 1 { - for i in (rPos + 1..ref_len).rev() { + if r_pos < ref_len - 1 { + for i in (r_pos + 1..ref_len).rev() { aln_qry.push(T::GAP); aln_ref.push(ref_seq[i as usize]); } - } else if qPos < qry_len - 1 { - for i in (qPos + 1..qry_len).rev() { + } else if q_pos < qry_len - 1 { + for i in (q_pos + 1..qry_len).rev() { aln_qry.push(qry_seq[i as usize]); aln_ref.push(T::GAP); } } - let mut origin: i32 = 0; - let mut currentMatrix = 0; + let mut origin: i32; + let mut current_matrix = 0; // Do backtrace in the aligned region - while rPos >= 0 && qPos >= 0 { - origin = paths[(si, rPos + 1)]; + while r_pos >= 0 && q_pos >= 0 { + origin = paths[(si, r_pos + 1)]; - if (origin & MATCH) != 0 && (currentMatrix == 0) { + if (origin & MATCH) != 0 && (current_matrix == 0) { // Match -- decrement both strands and add match to alignment - aln_qry.push(qry_seq[qPos as usize]); - aln_ref.push(ref_seq[rPos as usize]); - qPos -= 1; - rPos -= 1; - } else if ((origin & refGAPmatrix) != 0 && currentMatrix == 0) || currentMatrix == refGAPmatrix { + aln_qry.push(qry_seq[q_pos as usize]); + aln_ref.push(ref_seq[r_pos as usize]); + q_pos -= 1; + r_pos -= 1; + } else if ((origin & REF_GAP_MATRIX) != 0 && current_matrix == 0) || current_matrix == REF_GAP_MATRIX { // Insertion in ref -- decrement query, increase shift - aln_qry.push(qry_seq[qPos as usize]); + aln_qry.push(qry_seq[q_pos as usize]); aln_ref.push(T::GAP); - qPos -= 1; + q_pos -= 1; si += 1; - currentMatrix = if (origin & refGAPextend) != 0 { + current_matrix = if (origin & REF_GAP_EXTEND) != 0 { // Remain in gap-extension mode and ignore best-overall score - refGAPmatrix + REF_GAP_MATRIX } else { // Close gap, return to best-overall score 0 } - } else if ((origin & qryGAPmatrix) != 0 && currentMatrix == 0) || currentMatrix == qryGAPmatrix { + } else if ((origin & QRY_GAP_MATRIX) != 0 && current_matrix == 0) || current_matrix == QRY_GAP_MATRIX { // Deletion in query -- decrement reference, reduce shift aln_qry.push(T::GAP); - aln_ref.push(ref_seq[rPos as usize]); - rPos -= 1; + aln_ref.push(ref_seq[r_pos as usize]); + r_pos -= 1; si -= 1; - currentMatrix = if (origin & qryGAPextend) != 0 { + current_matrix = if (origin & QRY_GAP_EXTEND) != 0 { // Remain in gap-extension mode and ignore best-overall score - qryGAPmatrix + QRY_GAP_MATRIX } else { // Close gap, return to best-overall score 0 @@ -150,13 +144,13 @@ pub fn backtrace>( } // Add left overhang, i.e. unaligned parts of the query or reference - if rPos >= 0 { - for i in (0..=rPos).rev() { + if r_pos >= 0 { + for i in (0..=r_pos).rev() { aln_qry.push(T::GAP); aln_ref.push(ref_seq[i as usize]); } - } else if qPos >= 0 { - for i in (0..=qPos).rev() { + } else if q_pos >= 0 { + for i in (0..=q_pos).rev() { aln_qry.push(qry_seq[i as usize]); aln_ref.push(T::GAP); } diff --git a/packages_rs/nextclade/src/align/gap_open.rs b/packages_rs/nextclade/src/align/gap_open.rs index 7812e0142..f5712b859 100644 --- a/packages_rs/nextclade/src/align/gap_open.rs +++ b/packages_rs/nextclade/src/align/gap_open.rs @@ -5,7 +5,7 @@ use crate::io::nuc::Nuc; pub type GapScoreMap = Vec; pub fn get_gap_open_close_scores_flat(ref_seq: &[Nuc], params: &AlignPairwiseParams) -> GapScoreMap { - let value = params.penaltyGapOpen as i32; + let value = params.penalty_gap_open; let len = ref_seq.len() + 2; vec![value; len] } @@ -18,9 +18,9 @@ pub fn get_gap_open_close_scores_codon_aware( let mut gap_open_close = get_gap_open_close_scores_flat(ref_seq, params); for (_, gene) in gene_map.iter() { for i in (gene.start..gene.end).step_by(3) { - gap_open_close[i] = params.penaltyGapOpenInFrame; - gap_open_close[i + 1] = params.penaltyGapOpenOutOfFrame; - gap_open_close[i + 2] = params.penaltyGapOpenOutOfFrame; + gap_open_close[i] = params.penalty_gap_open_in_frame; + gap_open_close[i + 1] = params.penalty_gap_open_out_of_frame; + gap_open_close[i + 2] = params.penalty_gap_open_out_of_frame; } } gap_open_close diff --git a/packages_rs/nextclade/src/align/score_matrix.rs b/packages_rs/nextclade/src/align/score_matrix.rs index 872e232eb..8c47aba2f 100644 --- a/packages_rs/nextclade/src/align/score_matrix.rs +++ b/packages_rs/nextclade/src/align/score_matrix.rs @@ -1,28 +1,16 @@ -#![allow(clippy::separated_literal_suffix)] -#![allow(non_snake_case)] -#![allow(non_upper_case_globals)] -#![allow(unused_assignments)] -#![allow(unused_imports)] - use crate::align::align::AlignPairwiseParams; -use crate::io::aa::Aa; use crate::io::letter::Letter; -use crate::io::nuc::Nuc; use crate::utils::vec2d::Vec2d; use log::trace; -use std::io; -use std::io::Write; -use std::marker::PhantomData; -use std::ops::Index; // store direction info for backtrace as bits in paths matrix // these indicate the currently optimal move pub const MATCH: i32 = 1 << 0; -pub const refGAPmatrix: i32 = 1 << 1; -pub const qryGAPmatrix: i32 = 1 << 2; +pub const REF_GAP_MATRIX: i32 = 1 << 1; +pub const QRY_GAP_MATRIX: i32 = 1 << 2; // these are the override flags for gap extension -pub const refGAPextend: i32 = 1 << 3; -pub const qryGAPextend: i32 = 1 << 4; +pub const REF_GAP_EXTEND: i32 = 1 << 3; +pub const QRY_GAP_EXTEND: i32 = 1 << 4; pub const END_OF_SEQUENCE: i32 = -1; pub struct ScoreMatrixResult { @@ -33,24 +21,24 @@ pub struct ScoreMatrixResult { pub fn score_matrix>( qry_seq: &[T], ref_seq: &[T], - gapOpenClose: &[i32], - bandWidth: usize, - meanShift: i32, + gap_open_close: &[i32], + band_width: usize, + mean_shift: i32, params: &AlignPairwiseParams, ) -> ScoreMatrixResult { - let querySize = qry_seq.len(); - let refSize = ref_seq.len(); - let n_rows = bandWidth * 2 + 1; - let n_cols = refSize + 1; + let query_size = qry_seq.len(); + let ref_size = ref_seq.len(); + let n_rows = band_width * 2 + 1; + let n_cols = ref_size + 1; trace!( - "Score matrix: stared: querySize={querySize}, refSize={refSize}, \ - bandWidth={bandWidth}, meanShift={meanShift}, n_rows={n_rows}, n_cols={n_cols}" + "Score matrix: stared: query_size={query_size}, ref_size={ref_size}, \ + band_width={band_width}, mean_shift={mean_shift}, n_rows={n_rows}, n_cols={n_cols}" ); let mut paths = Vec2d::::new(n_rows, n_cols); let mut scores = Vec2d::::new(n_rows, n_cols); - let mut qryGaps = vec![0_i32; n_rows]; + let mut qry_gaps = vec![0_i32; n_rows]; // fill scores with alignment scores // The inner index scores[][ri] is the index of the reference sequence @@ -64,101 +52,101 @@ pub fn score_matrix>( // -> vertical step in the matrix from si+1 to si // 2) if X is a base and Y is '-', rPos advances the same and the shift increases // -> diagonal step in the matrix from (ri,si-1) to (ri+1,si) - let NO_ALIGN = -(params.scoreMatch + params.penaltyMismatch) * refSize as i32; + let no_align = -(params.score_match + params.penalty_mismatch) * ref_size as i32; - for si in bandWidth + 1..=2 * bandWidth { - paths[(si, 0)] = qryGAPmatrix; + for si in band_width + 1..=2 * band_width { + paths[(si, 0)] = QRY_GAP_MATRIX; } - paths[(bandWidth, 0)] = MATCH; - qryGaps[bandWidth] = -params.penaltyGapOpen; - for si in (0..bandWidth).rev() { - paths[(si, 0)] = refGAPmatrix; - qryGaps[si] = -params.penaltyGapOpen; + paths[(band_width, 0)] = MATCH; + qry_gaps[band_width] = -params.penalty_gap_open; + for si in (0..band_width).rev() { + paths[(si, 0)] = REF_GAP_MATRIX; + qry_gaps[si] = -params.penalty_gap_open; } - for ri in 0..refSize as i32 { - let mut qPos: i32 = ri as i32 - (bandWidth as i32 + meanShift); - let mut refGaps = -gapOpenClose[ri as usize]; - - for si in (0..=(2 * bandWidth as i32)).rev() { - let mut tmpPath = 0; - let mut score = 0; - let mut origin = 0; - let mut qGapExtend = 0; - let mut rGapExtend = 0; - let mut rGapOpen = 0; - let mut qGapOpen = 0; - let mut tmpMatch = 0; - let mut tmpScore = 0; - - if qPos < 0 { + for ri in 0..ref_size as i32 { + let mut q_pos: i32 = ri - (band_width as i32 + mean_shift); + let mut ref_gaps = -gap_open_close[ri as usize]; + + for si in (0..=(2 * band_width as i32)).rev() { + let mut tmp_path = 0; + let mut score: i32; + let mut origin: i32; + let q_gap_extend: i32; + let r_gap_extend: i32; + let r_gap_open: i32; + let q_gap_open: i32; + let tmp_match: i32; + let mut tmp_score: i32; + + if q_pos < 0 { // precedes query sequence -- no score, origin is query gap // we could fill all of this at once score = 0; - tmpPath += qryGAPextend; - refGaps = -gapOpenClose[ri as usize]; - origin = qryGAPmatrix; - } else if qPos < querySize as i32 { + tmp_path += QRY_GAP_EXTEND; + ref_gaps = -gap_open_close[ri as usize]; + origin = QRY_GAP_MATRIX; + } else if q_pos < query_size as i32 { // if the shifted position is within the query sequence // no gap -- match case - let matrix_score = T::lookup_match_score(qry_seq[qPos as usize], ref_seq[ri as usize]); - tmpMatch = if matrix_score > 0 { - params.scoreMatch + let matrix_score = T::lookup_match_score(qry_seq[q_pos as usize], ref_seq[ri as usize]); + tmp_match = if matrix_score > 0 { + params.score_match } else { - -params.penaltyMismatch + -params.penalty_mismatch }; - score = scores[(si, ri)] + tmpMatch; + score = scores[(si, ri)] + tmp_match; origin = MATCH; // check the scores of a reference gap - if si < 2 * bandWidth as i32 { - rGapExtend = refGaps - params.penaltyGapExtend; - rGapOpen = scores[(si + 1, ri + 1)] - gapOpenClose[(ri + 1) as usize]; - if rGapExtend > rGapOpen { - tmpScore = rGapExtend; - tmpPath += refGAPextend; + if si < 2 * band_width as i32 { + r_gap_extend = ref_gaps - params.penalty_gap_extend; + r_gap_open = scores[(si + 1, ri + 1)] - gap_open_close[(ri + 1) as usize]; + if r_gap_extend > r_gap_open { + tmp_score = r_gap_extend; + tmp_path += REF_GAP_EXTEND; } else { - tmpScore = rGapOpen; + tmp_score = r_gap_open; } - refGaps = tmpScore; - if score < tmpScore { - score = tmpScore; - origin = refGAPmatrix; + ref_gaps = tmp_score; + if score < tmp_score { + score = tmp_score; + origin = REF_GAP_MATRIX; } } else { - refGaps = NO_ALIGN; + ref_gaps = no_align; } // check the scores of a reference gap if si > 0 { - qGapExtend = qryGaps[(si - 1) as usize] - params.penaltyGapExtend; - qGapOpen = scores[(si - 1, ri)] - gapOpenClose[ri as usize]; - tmpScore = qGapExtend.max(qGapOpen); - if qGapExtend > qGapOpen { - tmpScore = qGapExtend; - tmpPath += qryGAPextend; + q_gap_extend = qry_gaps[(si - 1) as usize] - params.penalty_gap_extend; + q_gap_open = scores[(si - 1, ri)] - gap_open_close[ri as usize]; + tmp_score = q_gap_extend.max(q_gap_open); + if q_gap_extend > q_gap_open { + tmp_score = q_gap_extend; + tmp_path += QRY_GAP_EXTEND; } else { - tmpScore = qGapOpen; + tmp_score = q_gap_open; } - qryGaps[si as usize] = tmpScore; - if score < tmpScore { - score = tmpScore; - origin = qryGAPmatrix; + qry_gaps[si as usize] = tmp_score; + if score < tmp_score { + score = tmp_score; + origin = QRY_GAP_MATRIX; } } else { - qryGaps[si as usize] = NO_ALIGN; + qry_gaps[si as usize] = no_align; } } else { // past query sequence -- mark as sequence end score = END_OF_SEQUENCE; origin = END_OF_SEQUENCE; } - tmpPath += origin; - paths[(si, ri + 1)] = tmpPath; + tmp_path += origin; + paths[(si, ri + 1)] = tmp_path; scores[(si, ri + 1)] = score; - qPos += 1; + q_pos += 1; } } @@ -171,9 +159,7 @@ mod tests { use super::*; use crate::align::gap_open::{get_gap_open_close_scores_codon_aware, GapScoreMap}; use crate::gene::gene_map::GeneMap; - use crate::io::nuc::{from_nuc_seq, to_nuc_seq}; - use crate::utils::global_init::global_init; - use ctor::ctor; + use crate::io::nuc::{to_nuc_seq, Nuc}; use eyre::Report; use pretty_assertions::assert_eq; use rstest::{fixture, rstest}; @@ -193,7 +179,7 @@ mod tests { let gene_map = GeneMap::new(); - let dummy_ref_seq = vec![Nuc::GAP; 100]; + let dummy_ref_seq = vec![Nuc::Gap; 100]; let gap_open_close = get_gap_open_close_scores_codon_aware(&dummy_ref_seq, &gene_map, ¶ms); Context { diff --git a/packages_rs/nextclade/src/align/score_matrix_aa.rs b/packages_rs/nextclade/src/align/score_matrix_aa.rs index e2dee9b3b..bc1aa141a 100644 --- a/packages_rs/nextclade/src/align/score_matrix_aa.rs +++ b/packages_rs/nextclade/src/align/score_matrix_aa.rs @@ -1,7 +1,7 @@ use crate::io::aa::Aa; -const NUM_COLS: u8 = 28; -const SCORING_MATRIX_AA_SIZE: usize = NUM_COLS as usize * NUM_COLS as usize; +const NUM_COLS: usize = 28; +const SCORING_MATRIX_AA_SIZE: usize = NUM_COLS * NUM_COLS; #[rustfmt::skip] static SCORING_MATRIX_AA: &[i32; SCORING_MATRIX_AA_SIZE] = &[ @@ -38,5 +38,5 @@ static SCORING_MATRIX_AA: &[i32; SCORING_MATRIX_AA_SIZE] = &[ ]; pub fn lookup_aa_scoring_matrix(x: Aa, y: Aa) -> i32 { - SCORING_MATRIX_AA[(x as usize * NUM_COLS as usize + y as usize) as usize] + SCORING_MATRIX_AA[(x as usize * NUM_COLS + y as usize)] } diff --git a/packages_rs/nextclade/src/align/score_matrix_nuc.rs b/packages_rs/nextclade/src/align/score_matrix_nuc.rs index 23e2edfc0..bbe9820f2 100644 --- a/packages_rs/nextclade/src/align/score_matrix_nuc.rs +++ b/packages_rs/nextclade/src/align/score_matrix_nuc.rs @@ -1,7 +1,7 @@ use crate::io::nuc::Nuc; -const NUM_COLS: u8 = 16; -const SCORING_MATRIX_NUC_SIZE: usize = NUM_COLS as usize * NUM_COLS as usize; +const NUM_COLS: usize = 16; +const SCORING_MATRIX_NUC_SIZE: usize = NUM_COLS * NUM_COLS; #[rustfmt::skip] static SCORING_MATRIX_NUC: &[i32; SCORING_MATRIX_NUC_SIZE] = &[ @@ -26,5 +26,5 @@ static SCORING_MATRIX_NUC: &[i32; SCORING_MATRIX_NUC_SIZE] = &[ ]; pub fn lookup_nuc_scoring_matrix(x: Nuc, y: Nuc) -> i32 { - SCORING_MATRIX_NUC[(x as usize * NUM_COLS as usize + y as usize) as usize] + SCORING_MATRIX_NUC[(x as usize * NUM_COLS + y as usize)] } diff --git a/packages_rs/nextclade/src/align/seed_alignment.rs b/packages_rs/nextclade/src/align/seed_alignment.rs index 15506d879..ea489503b 100644 --- a/packages_rs/nextclade/src/align/seed_alignment.rs +++ b/packages_rs/nextclade/src/align/seed_alignment.rs @@ -1,9 +1,5 @@ -#![allow(non_snake_case)] -#![allow(non_upper_case_globals)] -#![allow(clippy::separated_literal_suffix)] - use crate::align::align::AlignPairwiseParams; -use crate::align::seed_match::seedMatch; +use crate::align::seed_match::seed_match; use crate::io::nuc::Nuc; use crate::make_error; use eyre::Report; @@ -31,72 +27,72 @@ fn get_map_to_good_positions(qry_seq: &[Nuc], seed_length: usize) -> Vec } pub struct SeedAlignmentResult { - pub meanShift: i32, - pub bandWidth: usize, + pub mean_shift: i32, + pub band_width: usize, } -pub fn seedAlignment( +pub fn seed_alignment( qry_seq: &[Nuc], ref_seq: &[Nuc], params: &AlignPairwiseParams, ) -> Result { - let querySize = qry_seq.len(); - let refSize = ref_seq.len(); + let query_size = qry_seq.len(); + let ref_size = ref_seq.len(); - let nSeeds = if refSize > (params.minSeeds * params.seedSpacing) as usize { - (refSize as f32 / params.seedSpacing as f32) as i32 + let n_seeds = if ref_size > (params.min_seeds * params.seed_spacing) as usize { + (ref_size as f32 / params.seed_spacing as f32) as i32 } else { - params.minSeeds + params.min_seeds }; - let margin = (refSize as f32 / (nSeeds * 3) as f32).round() as i32; - let bandWidth = (((refSize + querySize) as f32 * 0.5) - 3.0).round() as usize; + let margin = (ref_size as f32 / (n_seeds * 3) as f32).round() as i32; + let band_width = (((ref_size + query_size) as f32 * 0.5) - 3.0).round() as usize; let mut start_pos = 0; - if bandWidth < (2 * params.seedLength) { + if band_width < (2 * params.seed_length) { return Ok(SeedAlignmentResult { - meanShift: ((refSize as f32 - querySize as f32) * 0.5).round() as i32, - bandWidth, + mean_shift: ((ref_size as f32 - query_size as f32) * 0.5).round() as i32, + band_width, }); }; - let map_to_good_positions = get_map_to_good_positions(qry_seq, params.seedLength); + let map_to_good_positions = get_map_to_good_positions(qry_seq, params.seed_length); let n_good_positions = map_to_good_positions.len() as i32; // Generate kmers equally spaced on the query - let seedCover = n_good_positions - 2 * margin; - let kmerSpacing = ((seedCover as f32) - 1.0) / ((nSeeds - 1) as f32); + let seed_cover = n_good_positions - 2 * margin; + let kmer_spacing = ((seed_cover as f32) - 1.0) / ((n_seeds - 1) as f32); - if seedCover < 0 || kmerSpacing < 0.0 { + if seed_cover < 0 || kmer_spacing < 0.0 { return make_error!( - "Unable to align: poor seed matches. Details: seed cover: {seedCover}, k-mer spacing: {kmerSpacing}." + "Unable to align: poor seed matches. Details: seed cover: {seed_cover}, k-mer spacing: {kmer_spacing}." ); } // TODO: Maybe use something other than tuple? A struct with named fields to make // the code in the end of the function less confusing? - let mut seedMatches = Vec::<(usize, usize, i64, usize)>::new(); - for ni in 0..nSeeds { - let goodPositionIndex = (margin as f32 + (kmerSpacing * ni as f32)).round() as usize; - let qPos = map_to_good_positions[goodPositionIndex]; + let mut seed_matches = Vec::<(usize, usize, i64, usize)>::new(); + for ni in 0..n_seeds { + let good_position_index = (margin as f32 + (kmer_spacing * ni as f32)).round() as usize; + let q_pos = map_to_good_positions[good_position_index]; - let seed = &qry_seq[qPos..qPos + params.seedLength]; - let tmpMatch = seedMatch(seed, ref_seq, start_pos, params.mismatchesAllowed); + let seed = &qry_seq[q_pos..q_pos + params.seed_length]; + let tmp_match = seed_match(seed, ref_seq, start_pos, params.mismatches_allowed); // Only use seeds with at most allowed_mismatches - if tmpMatch.score >= params.seedLength - params.mismatchesAllowed { - seedMatches.push(( - qPos, - tmpMatch.shift, - (tmpMatch.shift as i64 - qPos as i64), - tmpMatch.score, + if tmp_match.score >= params.seed_length - params.mismatches_allowed { + seed_matches.push(( + q_pos, + tmp_match.shift, + (tmp_match.shift as i64 - q_pos as i64), + tmp_match.score, )); - start_pos = tmpMatch.shift as usize; + start_pos = tmp_match.shift; } } - let num_seed_matches = seedMatches.len(); + let num_seed_matches = seed_matches.len(); if num_seed_matches < 2 { return make_error!("Unable to align: no seed matches. Details: num seed matches: {num_seed_matches}"); } @@ -108,8 +104,8 @@ pub fn seedAlignment( // ref: ACTCTACTGC-TCAGAC // qry: ----TCACTCATCT-ACACCGAT // => shift = 4, then 3, 4 again - let (minShift, maxShift) = seedMatches.iter().fold( - (refSize as i64, -(refSize as i64)), + let (min_shift, max_shift) = seed_matches.iter().fold( + (ref_size as i64, -(ref_size as i64)), |(min, max): (i64, i64), clamp: &(usize, usize, i64, usize)| { let shift = clamp.2; (min.min(shift), max.max(shift)) @@ -117,7 +113,7 @@ pub fn seedAlignment( ); Ok(SeedAlignmentResult { - meanShift: (0.5 * (minShift + maxShift) as f64).round() as i32, - bandWidth: (maxShift - minShift + 9) as usize, + mean_shift: (0.5 * (min_shift + max_shift) as f64).round() as i32, + band_width: (max_shift - min_shift + 9) as usize, }) } diff --git a/packages_rs/nextclade/src/align/seed_match.rs b/packages_rs/nextclade/src/align/seed_match.rs index 300caa6c6..453e195f2 100644 --- a/packages_rs/nextclade/src/align/seed_match.rs +++ b/packages_rs/nextclade/src/align/seed_match.rs @@ -1,7 +1,3 @@ -#![allow(non_snake_case)] -#![allow(non_upper_case_globals)] -#![allow(clippy::separated_literal_suffix)] - use crate::io::nuc::Nuc; pub struct SeedMatchResult { @@ -9,14 +5,13 @@ pub struct SeedMatchResult { pub score: usize, } -pub fn seedMatch(kmer: &[Nuc], ref_seq: &[Nuc], start_pos: usize, mismatches_allowed: usize) -> SeedMatchResult { +pub fn seed_match(kmer: &[Nuc], ref_seq: &[Nuc], start_pos: usize, mismatches_allowed: usize) -> SeedMatchResult { let ref_len = ref_seq.len(); let kmer_len = kmer.len(); - #[allow(unused_assignments)] - let mut tmp_score: usize = 0; - let mut max_score: usize = 0; - let mut max_shift: usize = 0; + let mut tmp_score: usize; + let mut max_score = 0; + let mut max_shift = 0; let end_pos = ref_len - kmer_len; for shift in start_pos..end_pos { diff --git a/packages_rs/nextclade/src/analyze/analyze.rs b/packages_rs/nextclade/src/analyze/analyze.rs index f69822540..f41da6600 100644 --- a/packages_rs/nextclade/src/analyze/analyze.rs +++ b/packages_rs/nextclade/src/analyze/analyze.rs @@ -1,5 +1,3 @@ -#![allow(clippy::use_self)] - use crate::wasm::js_value::{deserialize_js_value, serialize_js_value}; use eyre::Report; use serde::{Deserialize, Serialize}; diff --git a/packages_rs/nextclade/src/cli/nextclade_loop.rs b/packages_rs/nextclade/src/cli/nextclade_loop.rs index 90ebffc1b..6e773ea6e 100644 --- a/packages_rs/nextclade/src/cli/nextclade_loop.rs +++ b/packages_rs/nextclade/src/cli/nextclade_loop.rs @@ -146,7 +146,7 @@ pub fn nextclade_run(args: NextcladeRunArgs) -> Result<(), Report> { let virus_properties = VirusProperties::from_path(&input_virus_properties)?; - let ref_seq_str = from_nuc_seq(&ref_seq); + let ref_seq_str = from_nuc_seq(ref_seq); let pcr_primers = PcrPrimer::from_path(&input_pcr_primers, &ref_seq_str)?; thread::scope(|s| { diff --git a/packages_rs/nextclade/src/gene/gene.rs b/packages_rs/nextclade/src/gene/gene.rs index 3baca9744..c3ab9dff2 100644 --- a/packages_rs/nextclade/src/gene/gene.rs +++ b/packages_rs/nextclade/src/gene/gene.rs @@ -1,5 +1,3 @@ -#![allow(non_snake_case)] - #[derive(Debug)] pub struct Gene { pub gene_name: String, @@ -10,8 +8,11 @@ pub struct Gene { } impl Gene { - #[allow(clippy::len_without_is_empty)] pub fn len(&self) -> usize { self.end - self.start } + + pub fn is_empty(&self) -> bool { + self.len() == 0 + } } diff --git a/packages_rs/nextclade/src/io/aa.rs b/packages_rs/nextclade/src/io/aa.rs index 44c5d16dd..a98ed0987 100644 --- a/packages_rs/nextclade/src/io/aa.rs +++ b/packages_rs/nextclade/src/io/aa.rs @@ -1,5 +1,3 @@ -#![allow(clippy::use_self, clippy::upper_case_acronyms)] - use crate::align::score_matrix_aa::lookup_aa_scoring_matrix; use crate::io::letter::{Letter, ScoreMatrixLookup}; use crate::make_error; @@ -34,13 +32,13 @@ pub enum Aa { Y, Z, X, - STOP, - GAP, + Stop, + Gap, } impl Default for Aa { fn default() -> Self { - Aa::GAP + Aa::Gap } } @@ -51,11 +49,11 @@ impl ScoreMatrixLookup for Aa { } impl Letter for Aa { - const GAP: Aa = Aa::GAP; + const GAP: Aa = Aa::Gap; #[inline] fn is_gap(&self) -> bool { - self == &Aa::GAP + self == &Aa::Gap } #[inline] @@ -99,8 +97,8 @@ pub fn to_aa(letter: char) -> Result { 'Y' => Ok(Aa::Y), 'Z' => Ok(Aa::Z), 'X' => Ok(Aa::X), - '*' => Ok(Aa::STOP), - '-' => Ok(Aa::GAP), + '*' => Ok(Aa::Stop), + '-' => Ok(Aa::Gap), _ => make_error!("Unknown nucleotide: {letter}"), } } @@ -134,8 +132,8 @@ pub fn from_aa(nuc: Aa) -> char { Aa::Y => 'Y', Aa::Z => 'Z', Aa::X => 'X', - Aa::STOP => '*', - Aa::GAP => '-', + Aa::Stop => '*', + Aa::Gap => '-', } } diff --git a/packages_rs/nextclade/src/io/errors_csv.rs b/packages_rs/nextclade/src/io/errors_csv.rs index ea95288b0..8aa385e3f 100644 --- a/packages_rs/nextclade/src/io/errors_csv.rs +++ b/packages_rs/nextclade/src/io/errors_csv.rs @@ -81,7 +81,7 @@ impl<'a> ErrorsCsvWriter<'a> { maybe_translations: &[Result], ) -> Result<(), Report> { let warnings = &format_aa_warnings(maybe_translations); - let failed_genes = &format_aa_failed_genes(maybe_translations, &self.gene_map); + let failed_genes = &format_aa_failed_genes(maybe_translations, self.gene_map); self.writer.write(&ErrorCsvEntry { seq_name, errors: "", diff --git a/packages_rs/nextclade/src/io/fs.rs b/packages_rs/nextclade/src/io/fs.rs index 09ee2cf99..aa0cacb65 100644 --- a/packages_rs/nextclade/src/io/fs.rs +++ b/packages_rs/nextclade/src/io/fs.rs @@ -44,7 +44,7 @@ pub fn basename(filepath: impl AsRef) -> Result { /// Reads entire file into a string. /// Compared to `std::fs::read_to_string` uses buffered reader pub fn read_file_to_string(filepath: impl AsRef) -> Result { - const BUF_SIZE: usize = 1 * 1024 * 1024; + const BUF_SIZE: usize = 2 * 1024 * 1024; let filepath = filepath.as_ref(); diff --git a/packages_rs/nextclade/src/io/nuc.rs b/packages_rs/nextclade/src/io/nuc.rs index 4147138d9..613a80743 100644 --- a/packages_rs/nextclade/src/io/nuc.rs +++ b/packages_rs/nextclade/src/io/nuc.rs @@ -1,5 +1,3 @@ -#![allow(clippy::use_self, clippy::upper_case_acronyms)] - use crate::align::score_matrix_nuc::lookup_nuc_scoring_matrix; use crate::io::letter::{Letter, ScoreMatrixLookup}; use crate::make_error; @@ -24,30 +22,24 @@ pub enum Nuc { B, V, N, - GAP, + Gap, } impl Nuc { #[inline] - pub fn is_acgt(&self) -> bool { - match self { - Nuc::A | Nuc::C | Nuc::G | Nuc::T => true, - _ => false, - } + pub fn is_acgt(self) -> bool { + matches!(self, Nuc::A | Nuc::C | Nuc::G | Nuc::T) } #[inline] - pub fn is_acgtn(&self) -> bool { - match self { - Nuc::A | Nuc::C | Nuc::G | Nuc::T | Nuc::N => true, - _ => false, - } + pub fn is_acgtn(self) -> bool { + matches!(self, Nuc::A | Nuc::C | Nuc::G | Nuc::T | Nuc::N) } } impl Default for Nuc { fn default() -> Self { - Nuc::GAP + Nuc::Gap } } @@ -58,11 +50,11 @@ impl ScoreMatrixLookup for Nuc { } impl Letter for Nuc { - const GAP: Nuc = Nuc::GAP; + const GAP: Nuc = Nuc::Gap; #[inline] fn is_gap(&self) -> bool { - self == &Nuc::GAP + self == &Nuc::Gap } #[inline] @@ -95,7 +87,7 @@ pub fn to_nuc(letter: char) -> Result { 'B' => Ok(Nuc::B), 'V' => Ok(Nuc::V), 'N' => Ok(Nuc::N), - '-' => Ok(Nuc::GAP), + '-' => Ok(Nuc::Gap), _ => make_error!("Unknown nucleotide: {letter}"), } } @@ -118,7 +110,7 @@ pub fn from_nuc(nuc: Nuc) -> char { Nuc::B => 'B', Nuc::V => 'V', Nuc::N => 'N', - Nuc::GAP => '-', + Nuc::Gap => '-', } } diff --git a/packages_rs/nextclade/src/translate/complement.rs b/packages_rs/nextclade/src/translate/complement.rs index 9aaa3bb77..8fd110de9 100644 --- a/packages_rs/nextclade/src/translate/complement.rs +++ b/packages_rs/nextclade/src/translate/complement.rs @@ -17,7 +17,7 @@ pub fn complement(nuc: Nuc) -> Nuc { Nuc::H => Nuc::D, Nuc::B => Nuc::V, Nuc::N => Nuc::N, - Nuc::GAP => Nuc::GAP, + Nuc::Gap => Nuc::Gap, } } diff --git a/packages_rs/nextclade/src/translate/frame_shifts_translate.rs b/packages_rs/nextclade/src/translate/frame_shifts_translate.rs index 98396703b..8adfa12ef 100644 --- a/packages_rs/nextclade/src/translate/frame_shifts_translate.rs +++ b/packages_rs/nextclade/src/translate/frame_shifts_translate.rs @@ -1,5 +1,3 @@ -#![allow(clippy::integer_division)] - use crate::gene::gene::Gene; use crate::io::letter::Letter; use crate::io::nuc::Nuc; @@ -12,7 +10,7 @@ pub fn find_mask_begin(seq: &[Nuc], frame_shift_nuc_range_rel: &Range) -> usize // From begin, rewind to find the first adjacent nuc deletion let mut begin = frame_shift_nuc_range_rel.begin - 1; if begin > 0 { - while seq[begin as usize].is_gap() { + while seq[begin].is_gap() { begin -= 1; } } diff --git a/packages_rs/nextclade/src/translate/translate.rs b/packages_rs/nextclade/src/translate/translate.rs index 9e250f864..02234aed2 100644 --- a/packages_rs/nextclade/src/translate/translate.rs +++ b/packages_rs/nextclade/src/translate/translate.rs @@ -1,5 +1,3 @@ -#![allow(clippy::integer_division)] - use crate::align::align::AlignPairwiseParams; use crate::gene::gene::Gene; use crate::io::aa::Aa; @@ -10,7 +8,7 @@ use eyre::Report; pub fn decode(triplet: &[Nuc]) -> Aa { match *triplet { - [Nuc::GAP, Nuc::GAP, Nuc::GAP] => Aa::GAP, + [Nuc::Gap, Nuc::Gap, Nuc::Gap] => Aa::Gap, [Nuc::A, Nuc::A, Nuc::A] => Aa::K, [Nuc::A, Nuc::A, Nuc::C] => Aa::N, [Nuc::A, Nuc::A, Nuc::G] => Aa::K, @@ -59,15 +57,15 @@ pub fn decode(triplet: &[Nuc]) -> Aa { [Nuc::G, Nuc::T, Nuc::C] => Aa::V, [Nuc::G, Nuc::T, Nuc::G] => Aa::V, [Nuc::G, Nuc::T, Nuc::T] => Aa::V, - [Nuc::T, Nuc::A, Nuc::A] => Aa::STOP, + [Nuc::T, Nuc::A, Nuc::A] => Aa::Stop, [Nuc::T, Nuc::A, Nuc::C] => Aa::Y, - [Nuc::T, Nuc::A, Nuc::G] => Aa::STOP, + [Nuc::T, Nuc::A, Nuc::G] => Aa::Stop, [Nuc::T, Nuc::A, Nuc::T] => Aa::Y, [Nuc::T, Nuc::C, Nuc::A] => Aa::S, [Nuc::T, Nuc::C, Nuc::C] => Aa::S, [Nuc::T, Nuc::C, Nuc::G] => Aa::S, [Nuc::T, Nuc::C, Nuc::T] => Aa::S, - [Nuc::T, Nuc::G, Nuc::A] => Aa::STOP, + [Nuc::T, Nuc::G, Nuc::A] => Aa::Stop, [Nuc::T, Nuc::G, Nuc::C] => Aa::C, [Nuc::T, Nuc::G, Nuc::G] => Aa::W, [Nuc::T, Nuc::G, Nuc::T] => Aa::C, @@ -91,7 +89,7 @@ pub fn translate(gene_nuc_seq: &[Nuc], gene: &Gene, params: &AlignPairwiseParams let triplet: &[Nuc] = &gene_nuc_seq[i_nuc..(i_nuc + 3)]; let aminoacid = decode(triplet); peptide.push(aminoacid); - if !params.translatePastStop && aminoacid == Aa::STOP { + if !params.translate_past_stop && aminoacid == Aa::Stop { break; } } diff --git a/packages_rs/nextclade/src/translate/translate_genes.rs b/packages_rs/nextclade/src/translate/translate_genes.rs index 9c2192c91..e3c91c1e6 100644 --- a/packages_rs/nextclade/src/translate/translate_genes.rs +++ b/packages_rs/nextclade/src/translate/translate_genes.rs @@ -52,7 +52,6 @@ pub struct PeptideAlignmentParams { /// Deduces aminoacid alignment params from nucleotide alignment. /// Gap counts from nucleotide alignment are used to estimate rough parameters. This is by contrast to nucleotide /// alignment, where these parameters are estimated using seed matching. -#[allow(clippy::integer_division)] pub fn calculate_aa_alignment_params(qry_gaps: &GapCounts, ref_gaps: &GapCounts) -> PeptideAlignmentParams { const BASE_BAND_WIDTH: usize = 5; // An arbitrary magic number to give some additional room for alignment let band_width = (qry_gaps.internal + ref_gaps.internal) / 3 + BASE_BAND_WIDTH; @@ -119,9 +118,9 @@ pub fn fill_range_inplace(seq: &mut [Aa], range: &Range, letter: Aa) { /// and we cover them with `X`. pub fn mask_peptide_frame_shifts_in_place(seq: &mut [Aa], frame_shifts: &[FrameShift]) { for frame_shift in frame_shifts { - fill_range_inplace(seq, &frame_shift.gaps_leading.codon, Aa::GAP); + fill_range_inplace(seq, &frame_shift.gaps_leading.codon, Aa::Gap); fill_range_inplace(seq, &frame_shift.codon, Aa::X); - fill_range_inplace(seq, &frame_shift.gaps_trailing.codon, Aa::GAP); + fill_range_inplace(seq, &frame_shift.gaps_trailing.codon, Aa::Gap); } } diff --git a/packages_rs/nextclade/src/tree/tree.rs b/packages_rs/nextclade/src/tree/tree.rs index 1d59ca487..aee2491e9 100644 --- a/packages_rs/nextclade/src/tree/tree.rs +++ b/packages_rs/nextclade/src/tree/tree.rs @@ -37,22 +37,25 @@ pub struct TreeNodeAttrs { pub node_type: Option, #[serde(skip_serializing_if = "Option::is_none")] - region: Option, + pub region: Option, #[serde(skip_serializing_if = "Option::is_none")] - country: Option, + pub country: Option, #[serde(skip_serializing_if = "Option::is_none")] - division: Option, + pub division: Option, #[serde(skip_serializing_if = "Option::is_none")] - Alignment: Option, + #[serde(rename = "Alignment")] + pub alignment: Option, #[serde(skip_serializing_if = "Option::is_none")] - Missing: Option, + #[serde(rename = "Missing")] + pub missing: Option, #[serde(skip_serializing_if = "Option::is_none")] - Gaps: Option, + #[serde(rename = "Missing")] + gaps: Option, #[serde(skip_serializing_if = "Option::is_none")] #[serde(rename = "Non-ACGTNs")] diff --git a/packages_rs/nextclade/src/utils/error.rs b/packages_rs/nextclade/src/utils/error.rs index 01f21bc0a..044505864 100644 --- a/packages_rs/nextclade/src/utils/error.rs +++ b/packages_rs/nextclade/src/utils/error.rs @@ -14,7 +14,6 @@ pub fn to_eyre_error>(val_or_err: Result) -> Resul val_or_err.map_err(|report| eyre!(report)) } -#[allow(unused_variables)] pub fn report_to_string_debug_only(report: &Report) -> String { #[cfg(not(debug_assertions))] return "An unexpected error occurred. Please try again later.".to_owned(); diff --git a/packages_rs/nextclade/src/utils/global_init.rs b/packages_rs/nextclade/src/utils/global_init.rs index eb04a4a9c..048bd0d9d 100644 --- a/packages_rs/nextclade/src/utils/global_init.rs +++ b/packages_rs/nextclade/src/utils/global_init.rs @@ -10,7 +10,7 @@ fn get_current_exe_filename() -> Option { env::current_exe().ok()?.file_name()?.to_str()?.to_owned().into() } -fn get_file_line(record: &Record) -> String { +fn get_file_line(record: &Record<'_>) -> String { match (record.file(), record.line()) { (Some(file), None) => file.to_owned(), (Some(file), Some(line)) => format!("{:}:{:}", file, line), @@ -18,13 +18,13 @@ fn get_file_line(record: &Record) -> String { } } -fn log_level_str(record: &Record) -> String { +fn log_level_str(record: &Record<'_>) -> String { let mut level_str = record.level().to_string(); level_str.truncate(5); format!("{:<5}", level_str) } -fn color_log_level(record: &Record) -> String { +fn color_log_level(record: &Record<'_>) -> String { match record.level() { Level::Error => log_level_str(record).red().to_string(), Level::Warn => log_level_str(record).yellow().to_string(), diff --git a/packages_rs/nextclade/src/utils/range.rs b/packages_rs/nextclade/src/utils/range.rs index 41cc137ad..d94598383 100644 --- a/packages_rs/nextclade/src/utils/range.rs +++ b/packages_rs/nextclade/src/utils/range.rs @@ -1,5 +1,3 @@ -#![allow(clippy::use_self)] - use auto_ops::impl_op_ex; use serde::{Deserialize, Serialize}; use std::ops::Range as StdRange; @@ -29,8 +27,8 @@ impl_op_ex!(- |range: &Range, scalar: usize| -> Range { Range{ begin: range.begi impl From for StdRange { fn from(other: Range) -> Self { StdRange:: { - start: other.begin as usize, - end: other.end as usize, + start: other.begin, + end: other.end, } } }