{"id":43413439,"url":"https://github.com/nsbuitrago/vfind","last_synced_at":"2026-02-02T17:14:19.756Z","repository":{"id":232883151,"uuid":"770525213","full_name":"nsbuitrago/vfind","owner":"nsbuitrago","description":"Simple variant finding from NGS data","archived":false,"fork":false,"pushed_at":"2025-06-30T22:49:04.000Z","size":215,"stargazers_count":1,"open_issues_count":0,"forks_count":2,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-11-27T14:16:54.998Z","etag":null,"topics":["bioinformatics","ngs","sequence-analysis"],"latest_commit_sha":null,"homepage":"https://pypi.org/project/vfind/","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nsbuitrago.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-03-11T17:45:23.000Z","updated_at":"2025-06-30T22:47:01.000Z","dependencies_parsed_at":"2025-06-02T17:18:14.522Z","dependency_job_id":null,"html_url":"https://github.com/nsbuitrago/vfind","commit_stats":null,"previous_names":["nsbuitrago/vfind"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/nsbuitrago/vfind","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nsbuitrago%2Fvfind","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nsbuitrago%2Fvfind/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nsbuitrago%2Fvfind/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nsbuitrago%2Fvfind/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nsbuitrago","download_url":"https://codeload.github.com/nsbuitrago/vfind/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nsbuitrago%2Fvfind/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29015939,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-02T16:17:30.374Z","status":"ssl_error","status_checked_at":"2026-02-02T15:58:50.469Z","response_time":58,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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","ngs","sequence-analysis"],"created_at":"2026-02-02T17:14:15.367Z","updated_at":"2026-02-02T17:14:19.736Z","avatar_url":"https://github.com/nsbuitrago.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# vFind\n\n[![PyPI - Version](https://img.shields.io/pypi/v/vfind)](https://pypi.org/project/vfind/)\n\n*A simple variant finder for NGS data.*\n\n1. [Introduction](#introduction)\n2. [Installation](#installation)\n3. [Examples](#examples)\n4. [Contributing](#contributing)\n5. [License](#license)\n\n## Introduction\n\nvFind is unlike a traditional [*variant caller*](https://gencore.bio.nyu.edu/variant-calling-pipeline-gatk4/).\nIt is actually using a simpler algorithm which is *usually* sufficient for\nscreening experiments. The main use case is finding variants from a library that\nhas constant adapter sequences flanking a variable region.\n\nThis simple algorithm is summarized as:\n\n1. Define a pair of adapter sequences that flank the variable region.\n2. For each fastq read, search for exact matches of these adapters.\n3. If both adapters are found exactly, recover the variable region.\n4. For each adapter without an exact match, perform semi-global alignment between the given adapter and read (see the [alignment parameters](#using-custom-alignment-parameters) section\nfor more details).\n5. If the alignment score meets a set threshold, that adapter is considered to match.\n6. If both adapters are exactly or partially matched, recover the variable region.\n7. For exact matches of both adapters, recover the variable region. Otherwise, continue to the next read.\n8. Finally, translate the variable region to its amino acid sequence and filter out any sequences with partial codons (see the [miscellaneous](#miscellaneous) section for more details).\n\n\u003e [!WARNING]\n\u003e Note that vFind doesn't do any kind of preprocessing. For initial quality\n\u003e filtering, merging, and other common preprocessing operations, you might be\n\u003e interested in something like [fastp](https://github.com/OpenGene/fastp) or\n\u003e [ngmerge](https://github.com/jsh58/NGmerge). We generally recommend using\n\u003e fastp for quality filtering and merging fastq files before using vFind.\n\nInstallation details and usage examples are given below. For more usage details,\nplease see the [API reference](docs/api-reference.md)\n\n## Installation\n\nThe package is available on [PyPI](https://pypi.org/project/vfind) and can be installed via pip (or alternatives like [uv](https://github.com/astral-sh/uv)).\n\n### PyPI (Recommended)\n\nBelow is an example using uv to initialize a project and add vfind as a dependency.\n\n```bash\nuv init\nuv add vfind\n```\n\nand with pip after creating and activating a new virtual environment\n\n```bash\npython3 -m venv .venv\nsource .venv/bin/activate\n\npython3 -m pip install vfind\n\n```\n\n### Source\n\nvFind is developed using PyO3 and Rust. You will need to make sure you have\na Rust toolchain installed as well as standard C tooling to build some\ndependencies (i.e., parasail-rs crate).\n\n1. Clone the repository\n\n```bash\ngit clone https://github.com/nsbuitrago/vfind.git\ncd vfind\n```\n\n2. Inside the vfind directory, sync dependencies with uv and build vfind\n\n```bash\nuv sync\n\n# this will build and install vfind in the virtual env\nuv run maturin develop --uv # or `make dev`\n```\n\n## Examples\n\n### Basic Usage\n\n```python\nfrom vfind import find_variants\nimport polars as pl # variants are returned in a polars dataframe\n\nadapters = (\"GGG\", \"CCC\") # define the adapters\nfq_path = \"./path/to/your/fastq/file.fq.gz\" # path to fq file\n\nvariants = find_variants(fq_path, adapters)\n\n# print the number of unique sequences\nprint(variants.n_unique())\n```\n\n`find_variants` returns a polars dataframe with `sequence` and `count` columns.\n`sequence` contains the amino acid sequence of the variable regions and\n`count` contains the frequency of those variant.\n\nWe can then use [dataframe methods](https://docs.pola.rs/py-polars/html/reference/dataframe/index.html)\nto further analyze the recovered variants. Some examples are shown below.\n\n```python\n# Get the top 5 most frequent variants\nvariants.sort(\"count\", descending=True) # sort by the counts in descending order\nprint(variants.head(5)) # print the first 5 (most frequent) variants\n\n# filter out sequences with less than 10 read counts\n# also any sequences that have a pre-mature stop codon (i.e., * before the last residue)\n\nfiltered_variants = variants.filter(\n    variants[\"count\"] \u003e 10,\n    ~variants[\"sequence\"][::-2].str.contains(\"*\")\n)\n\n# write the filtered variants to a csv file\nfiltered_variants.write_csv(\"filtered_variants.csv\")\n```\n\n### Using Custom Alignment Parameters\n\nBy default, vFind uses semi-global alignment with the following parameters:\n\n- match score = 3\n- mismatch score = -2\n- gap open penalty = 5\n- gap extend penalty = 2\n\nNote that the gap penalties are represented as positive integers. This is largely due to how the underlying\nalignment library works.\n\nTo adjust these alignment parameters, use the `match_score`, `mismatch_score`,\n`gap_open_penalty`, and `gap_extend_penalty` keyword arguments:\n\n```python\nfrom vfind import find_variants\n\n# ... define adapters and fq_path\n\n# use identity scoring with no gap penalties for alignments\nvariants = find_variants(\n    fq_path,\n    adapters,\n    match_score = 1,\n    mismatch_score = -1,\n    gap_open_penalty: 0,\n    gap_extend_penalty: 0,\n)\n```\n\nAlignments are accepted if they produce a score above a set threshold. The\nthreshold for considering an acceptable alignment can be adjusted with the\n`accept_prefix_alignment` and `accept_suffix_alignment` arguments. By default,\nboth thresholds are set to 0.75.\n\nThe thresholds are represent a percentage of the maximum alignment score. So, a\nvalue of 0.75 means alignments producing scores that are greater than 75% the\nmaximum theoretical score will be accepted. Thus, valid values are between 0 and\n1.\n\nEither an exact match or partial match (accepted alignment) must be made for\nboth adapter sequences to recover a variant.  In order to skip alignment and\nonly look for exact matches, set the alignment thresolds to 1 (i.e.,\n`accept_suffix_alignment = 1` to only allow perfect matches of the suffix\nadapter).\n\n### Miscellaneous\n\n**Q:** I don't need the amino acid sequence. Can I just get the DNA sequence?\n\n**A:** Yes. Just set `skip_translation` to True.\n\n```python\n# ...\ndna_seqs = find_variants(fq_path, adapters, skip_translation=True)\n```\n\n---\n\n**Q:** I don't want to use polars. Can I use pandas instead?\n\n**A:** Yes. Use the [`to_pandas`](https://docs.pola.rs/py-polars/html/reference/dataframe/api/polars.DataFrame.to_pandas.html#polars.DataFrame.to_pandas) method on the dataframe.\n\n---\n\n**Q:** I have a lot of data and `find_variants` is slow. Is there anything I can do to speed it up?\n\n**A:** Maybe. Try changing the number of threads or queue length the function uses.\n\n```python\n# ...\nvariants = find_variants(fq_path, adapters, n_threads=6, queue_len=4)\n```\n\nFor more usage details, see the [API reference](./docs/api-reference.md).\n\n## Contributing\n\nFeedback is a gift and contributions are more than welcome. Please submit an\nissue or pull request for any bugs, suggestions, or feedback. Please see the\n[developing](./docs/developing.md) guide for more details on how to work on vFind.\n\n## License\n\nvFind is licensed under the [MIT license](./LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnsbuitrago%2Fvfind","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnsbuitrago%2Fvfind","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnsbuitrago%2Fvfind/lists"}