Skip to content

Modernizing .NET Bio for .NET 8/10, a few concurrency fixes, and an offer to help maintain #46

Description

@ataumutozsoy

Hi @evolvedmicrobe,

I'm a bioinformatics software engineer and I'd like to help bring .NET Bio up to date. I've done a first round of work on a fork and wanted to check with you before opening a PR.

Branch: https://github.com/ataumutozsoy/bio/tree/modernize/net10

What the branch does

  • Targets: the libraries target netstandard2.0, net8.0 and net10.0. netstandard2.0 is kept, so .NET Framework users are not affected. The public API and the NuGet package IDs are unchanged.
  • Tests: the test projects run on net8.0 and net10.0, since netcoreapp2.0 can no longer run. Across the three test projects all 1,984 tests pass or are skipped on both frameworks, on Windows and Linux.
  • CI: Travis is replaced with GitHub Actions, which builds and tests on Linux, Windows and macOS.

Bugs found and fixed along the way

  1. Padena gave nondeterministic results. DeBruijnNode keeps all eight extension "invalid" flags in one byte and updates it without a lock. SimplePathContigBuilder.ExcludeAmbiguousExtensions runs in parallel and sets bits on neighbouring nodes too, so concurrent updates to the same node could be lost. As a result contigs were dropped, wrongly merged, or TraceSimplePath threw. On the small-reads test data, about 5% of assemblies gave a different result. After the fix, 2,000 consecutive runs gave identical output.
  2. PAMSAM guide trees depended on thread timing. HierarchicalClusteringParallel searched for the closest pair in parallel while writing shared fields, and passed each computed distance through a shared field. A wrong value could end up in the distance matrix.
  3. Parsers needed write access to their input. They opened files with FileMode.Open, which requests read/write access, so parsing read-only files failed.
  4. The BAM parser and formatter ignored the return value of Stream.Read.
  5. 21 GenBank P2 negative tests never ran the parser. The result was never enumerated, the data paths were not resolved, and Assert.Fail was swallowed by a catch-all. 18 of them now pass for real. For the other 3 inputs the parser accepts malformed data; I marked those tests [Ignore] for now.

Each fix is a separate, focused commit.

Found but not changed yet

These change results, so I'd like your opinion first:

  • DeBruijnGraph: node.KmerCount <= 255 is always true for a byte, so k-mer counts wrap to 0 at 256 on high-coverage data.
  • HierarchicalClusteringParallel.UpdateNearestColumn never updates min, so the nearest distance ends up as float.MaxValue.
  • DanglingLinksPurger discards the result of Union(...) (it should be UnionWith).

Questions

  1. Would you be willing to review and merge a PR with these changes? I can also split it into smaller PRs if you prefer.
  2. Longer term, would you consider adding me as a co-maintainer, including co-ownership of the NetBio.* packages on NuGet? That would let me publish a proper release (3.1 or 4.0). Next I'd like to work on:
    • nullable annotations
    • faster Span<T>-based FASTA/FASTQ/SAM parsers, with benchmarks
    • porting the command line tools to .NET 10

Thanks for creating .NET Bio and keeping it available all these years.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions