{"id":13752350,"url":"https://github.com/lh3/ksw2","last_synced_at":"2025-08-22T22:03:07.930Z","repository":{"id":45844637,"uuid":"95136066","full_name":"lh3/ksw2","owner":"lh3","description":"Global alignment and alignment extension","archived":false,"fork":false,"pushed_at":"2023-06-27T17:21:12.000Z","size":194,"stargazers_count":131,"open_issues_count":11,"forks_count":26,"subscribers_count":13,"default_branch":"master","last_synced_at":"2025-05-07T08:12:17.289Z","etag":null,"topics":["bioinformatics","sequence-alignment"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lh3.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2017-06-22T16:37:15.000Z","updated_at":"2025-03-23T08:14:33.000Z","dependencies_parsed_at":"2023-01-20T17:16:33.926Z","dependency_job_id":"3301daf9-89e3-47e1-93ed-9977ce459002","html_url":"https://github.com/lh3/ksw2","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lh3%2Fksw2","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lh3%2Fksw2/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lh3%2Fksw2/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lh3%2Fksw2/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lh3","download_url":"https://codeload.github.com/lh3/ksw2/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252839295,"owners_count":21812090,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bioinformatics","sequence-alignment"],"created_at":"2024-08-03T09:01:04.385Z","updated_at":"2025-05-07T08:12:23.200Z","avatar_url":"https://github.com/lh3.png","language":"C","funding_links":[],"categories":["Ranked by starred repositories"],"sub_categories":[],"readme":"## Introduction\n\nKSW2 is a library to align a pair of biological sequences based on dynamic\nprogramming (DP). So far it comes with global alignment and alignment extension\n(no local alignment yet) under an affine gap cost function: gapCost(*k*) =\n*q*+*k*\\**e*, or a two-piece affine gap cost: gapCost2(*k*) = min{*q*+*k*\\**e*,\n*q2*+*k*\\**e2*}. For the latter cost function, if *q*+*e*\u003c*q2*+*e2* and *e*\u003e*e2*,\n(*q*,*e*) is effectively applied to short gaps only, while (*q2*,*e2*) applied\nto gaps no shorter than ceil((*q2*-*q*)/(*e*-*e2*)-1). It helps to retain long\ngaps. The algorithm behind the two-piece cost is close to [Gotoh\n(1990)][piece-affine].\n\nKSW2 supports fixed banding and optionally produces alignment paths (i.e.\nCIGARs) with gaps either left- or right-aligned. It provides implementations\nusing SSE2 and SSE4.1 intrinsics based on [Hajime Suzuki][hs]'s diagonal\n[formulation][hs-eq] which enables 16-way SSE parallelization for the most part\nof the inner loop, regardless of the maximum score of the alignment.\n\nKSW2 implements the Suzuki-Kasahara algorithm and is a component of\n[minimap2][mm2]. If you use KSW2 in your work, please cite:\n\n\u003e * Suzuki, H. and Kasahara, M. (2018). Introducing difference recurrence relations for faster semi-global alignment of long sequences. *BMC Bioinformatics*, **19**:45.\n\u003e * Li, H (2018) Minimap2: pairwise alignment for nucleotide sequences. *Bioinformatics*, **34**:3094-3100.\n\n## Usage\n\nEach `ksw2_*.c` file implements a single function and is independent of each\nother. Here are brief descriptions about what each file implements:\n\n* [ksw2_gg.c](ksw2_gg.c): global alignment; Green's standard formulation\n* [ksw2_gg2.c](ksw2_gg2.c): global alignment; Suzuki's diagonal formulation\n* [ksw2_gg2_sse.c](ksw2_gg2_sse.c): global alignment with SSE intrinsics; Suzuki's\n* [ksw2_extz.c](ksw2_extz.c): global and extension alignment; Green's formulation\n* [ksw2_extz2_sse.c](ksw2_extz2_sse.c): global and extension with SSE intrinsics; Suzuki's\n* [ksw2_extd.c](ksw2_extd.c): global and extension alignment, dual gap cost; Green's formulation\n* [ksw2_extd2_sse.c](ksw2_extd2_sse.c): global and extension, dual gap cost, with SSE intrinsics; Suzuki's\n\nUsers are encouraged to copy the header file `ksw2.h` and relevant\n`ksw2_*.c` file to their own source code trees. On x86 CPUs with SSE2\nintrinsics, `ksw2_extz2_sse.c` is recommended in general. It supports global\nalignment, alignment extension with Z-drop, score-only alignment, global-only\nalignment and right-aligned CIGARs. `ksw2_gg*.c` are mostly for demonstration\nand comparison purposes. They are annotated with more comments and easier to\nunderstand than `ksw2_ext*.c`. Header file [ksw2.h](ksw2.h) contains brief\ndocumentations. TeX file [ksw2.tex](tex/ksw2.tex) gives brief derivation.\n\nTo compile the test program `ksw-test`, just type `make`. It takes the\nadvantage of SSE4.1 when available. To compile with SSE2 only, use `make\nsse2=1` instead. If you have installed [parasail][para], use `make\nparasail=prefix`, where `prefix` points to the parasail install directory (e.g.\n`/usr/local`).\n\nThe following shows a complete example about how to use the library.\n```c\n#include \u003cstring.h\u003e\n#include \u003cstdio.h\u003e\n#include \"ksw2.h\"\n\nvoid align(const char *tseq, const char *qseq, int sc_mch, int sc_mis, int gapo, int gape)\n{\n\tint i, a = sc_mch, b = sc_mis \u003c 0? sc_mis : -sc_mis; // a\u003e0 and b\u003c0\n\tint8_t mat[25] = { a,b,b,b,0, b,a,b,b,0, b,b,a,b,0, b,b,b,a,0, 0,0,0,0,0 };\n\tint tl = strlen(tseq), ql = strlen(qseq);\n\tuint8_t *ts, *qs, c[256];\n\tksw_extz_t ez;\n\n\tmemset(\u0026ez, 0, sizeof(ksw_extz_t));\n\tmemset(c, 4, 256);\n\tc['A'] = c['a'] = 0; c['C'] = c['c'] = 1;\n\tc['G'] = c['g'] = 2; c['T'] = c['t'] = 3; // build the encoding table\n\tts = (uint8_t*)malloc(tl);\n\tqs = (uint8_t*)malloc(ql);\n\tfor (i = 0; i \u003c tl; ++i) ts[i] = c[(uint8_t)tseq[i]]; // encode to 0/1/2/3\n\tfor (i = 0; i \u003c ql; ++i) qs[i] = c[(uint8_t)qseq[i]];\n\tksw_extz(0, ql, qs, tl, ts, 5, mat, gapo, gape, -1, -1, 0, \u0026ez);\n\tfor (i = 0; i \u003c ez.n_cigar; ++i) // print CIGAR\n\t\tprintf(\"%d%c\", ez.cigar[i]\u003e\u003e4, \"MID\"[ez.cigar[i]\u00260xf]);\n\tputchar('\\n');\n\tfree(ez.cigar); free(ts); free(qs);\n}\n\nint main(int argc, char *argv[])\n{\n\talign(\"ATAGCTAGCTAGCAT\", \"AGCTAcCGCAT\", 1, -2, 2, 1);\n\treturn 0;\n}\n```\n\n## Performance Analysis\n\nThe following table shows timing on two pairs of long sequences (both in the\n\"test\" directory).\n\n|Data set|Command line options             |Time (s)|CIGAR|Ext|SIMD|Source  |\n|:-------|:--------------------------------|:-------|:---:|:-:|:--:|:-------|\n|50k     |-t gg -s                         |7.3     |N    |N  |N   |ksw2    |\n|        |-t gg2 -s                        |19.8    |N    |N  |N   |ksw2    |\n|        |-t extz -s                       |9.2     |N    |Y  |N   |ksw2    |\n|        |-t ps\\_nw                        |9.8     |N    |N  |N   |parasail|\n|        |-t ps\\_nw\\_striped\\_sse2\\_128\\_32|2.9     |N    |N  |SSE2|parasail|\n|        |-t ps\\_nw\\_striped\\_32           |2.2     |N    |N  |SSE4|parasail|\n|        |-t ps\\_nw\\_diag\\_32              |3.0     |N    |N  |SSE4|parasail|\n|        |-t ps\\_nw\\_scan\\_32              |3.0     |N    |N  |SSE4|parasail|\n|        |-t extz2\\_sse -sg                |0.96    |N    |N  |SSE2|ksw2    |\n|        |-t extz2\\_sse -sg                |0.84    |N    |N  |SSE4|ksw2    |\n|        |-t extz2\\_sse -s                 |3.0     |N    |Y  |SSE2|ksw2    |\n|        |-t extz2\\_sse -s                 |2.7     |N    |Y  |SSE4|ksw2    |\n|16.5k   |-t gg -s                         |0.84    |N    |N  |N   |ksw2    |\n|        |-t gg                            |1.6     |Y    |N  |N   |ksw2    |\n|        |-t gg2                           |3.3     |Y    |N  |N   |ksw2    |\n|        |-t extz                          |2.0     |Y    |Y  |N   |ksw2    |\n|        |-t extz2\\_sse                    |0.40    |Y    |Y  |SSE4|ksw2    |\n|        |-t extz2\\_sse -g                 |0.18    |Y    |N  |SSE4|ksw2    |\n\nThe standard DP formulation is about twice as fast as Suzuki's diagonal\nformulation (`-tgg` vs `-tgg2`), but SSE-based diagonal formulation\nis several times faster than the standard DP. If we only want to compute one\nglobal alignment score, we can use 16-way parallelization in the entire inner\nloop.  For extension alignment, though, we need to keep an array of 32-bit\nscores and have to use 4-way parallelization for part of the inner loop. This\nsignificantly reduces performance (`-sg` vs `-s`).  KSW2 is faster than\nparasail partly because the former uses one score for all matches and another\nscore for all mismatches. For diagonal formulations, vectorization is more\ncomplex given a generic scoring matrix.\n\nIt is possible to further accelerate global alignment with dynamic banding as\nis implemented in [edlib][edlib]. However, it is not as effective for extension\nalignment. Another idea is [adaptive banding][adap-band], which might be worth\ntrying at some point.\n\n## Alternative Libraries\n\n|Library         |CIGAR|Intra-seq|Affine-gap|Local    |Global   |Glocal   |Extension|\n|:---------------|:---:|:-------:|:--------:|:-------:|:-------:|:-------:|:-------:|\n|[edlib][edlib]  |Yes  |Yes      |No        |Very fast|Very fast|Very fast|N/A      |\n|[KSW][klib]     |Yes  |Yes      |Yes       |Fast     |Slow     |N/A      |Slow     |\n|KSW2            |Yes  |Yes      |Yes/dual  |N/A      |Fast     |N/A      |Fast     |\n|[libgaba][gaba] |Yes  |Yes      |Yes       |N/A?     |N/A?     |N/A?     |Fast     |\n|[libssa][ssa]   |No   |No?      |Yes       |Fast     |Fast     |N/A      |N/A      |\n|[Opal][opal]    |No   |No       |Yes       |Fast     |Fast     |Fast     |N/A      |\n|[Parasail][para]|No   |Yes      |Yes       |Fast     |Fast     |Fast     |N/A      |\n|[SeqAn][seqan]  |Yes  |Yes      |Yes       |Slow     |Slow     |Slow     |N/A      |\n|[SSW][ssw]      |Yes  |Yes      |Yes       |Fast     |N/A      |N/A      |N/A      |\n|[SWIPE][swipe]  |Yes  |No       |Yes       |Fast     |N/A?     |N/A?     |N/A      |\n|[SWPS3][swps3]  |No   |Yes      |Yes       |Fast     |N/A?     |N/A      |N/A      |\n\n\n\n[hs]: https://github.com/ocxtal\n[hs-eq]: https://github.com/ocxtal/diffbench\n[edlib]: https://github.com/Martinsos/edlib\n[klib]: https://github.com/attractivechaos/klib\n[para]: https://github.com/jeffdaily/parasail\n[opal]: https://github.com/Martinsos/opal\n[ssw]: https://github.com/mengyao/Complete-Striped-Smith-Waterman-Library\n[ssa]: https://github.com/RonnySoak/libssa\n[gaba]: https://github.com/ocxtal/libgaba\n[adap-band]: https://github.com/ocxtal/adaptivebandbench\n[swipe]: https://github.com/torognes/swipe\n[swps3]: http://lab.dessimoz.org/swps3/\n[seqan]: http://seqan.de\n[piece-affine]: https://www.ncbi.nlm.nih.gov/pubmed/2165832\n[mm2]: https://github.com/lh3/minimap2\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flh3%2Fksw2","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flh3%2Fksw2","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flh3%2Fksw2/lists"}