Skip to content

Add native CRAM output support (unsorted and coordinate-sorted) via HTSlib#2670

Open
BenjaminDEMAILLE wants to merge 4 commits into
alexdobin:masterfrom
BenjaminDEMAILLE:master
Open

Add native CRAM output support (unsorted and coordinate-sorted) via HTSlib#2670
BenjaminDEMAILLE wants to merge 4 commits into
alexdobin:masterfrom
BenjaminDEMAILLE:master

Conversation

@BenjaminDEMAILLE

Copy link
Copy Markdown

Add native CRAM output support to STAR

Overview

This contribution adds full support for CRAM output in STAR, both for unsorted and coordinate-sorted alignments, using HTSlib’s native APIs. The implementation is fully backward compatible and preserves all existing BAM/SAM functionality.


Motivation

  • CRAM is a modern, highly compressed format for storing sequencing alignments, supported by the GA4GH and major genomics tools.
  • STAR previously only supported SAM and BAM output. Adding CRAM output allows users to save disk space and integrate more easily with modern pipelines.

Features

  • New output format:
    Users can now specify --outSAMtype CRAM Unsorted or --outSAMtype CRAM SortedByCoordinate to produce CRAM files directly from STAR.

  • HTSlib integration:
    Output is handled via HTSlib’s htsFile and sam_write1 APIs, ensuring compatibility with the CRAM standard and future-proofing for other formats.

  • Automatic format detection:
    The output format is detected from the --outSAMtype parameter and the correct file mode is used for htslib.

  • Unsorted and sorted output:

    • Unsorted CRAM output is written directly during alignment.
    • For coordinate-sorted output, STAR merges the sorted BAM bins and writes the result as CRAM using sam_write1.
  • Backward compatibility:
    Existing BAM/SAM output logic is preserved. If CRAM is not requested, STAR behaves as before.


Implementation Details

  • The BAMoutput class now supports both legacy BGZF output and htslib-based output (htsFile), with logic to route records to the appropriate backend.
  • Output file opening in ReadAlignChunk.cpp and bamSortByCoordinate.cpp is updated to use hts_open with the correct mode for CRAM/SAM/BAM.
  • The merging logic for coordinate-sorted output is updated:
    • If CRAM (or SAM/BAM via htslib) is requested, each sorted bin is read and records are written to the final output using sam_write1.
    • If BAM is requested and htslib is not used, the legacy bam_cat logic is preserved.
  • All changes are guarded to ensure no impact on users who do not request CRAM output.

Usage

  • Unsorted CRAM output:
    --outSAMtype CRAM Unsorted

birdingman0626 added a commit to birdingman0626/STAR-Cross that referenced this pull request Jun 29, 2026
…ndian support (#7)

* fix(macos): spawn readFilesCommand via posix_spawnp

The POSIX path used vfork()+execlp()+exit(0) to run the generated
readsCommand script. On macOS this fails ("Failed spawning
readFilesCommand", upstream issue alexdobin#2663) because the script has no
shebang and posix_spawn-style exec has no ENOEXEC->/bin/sh fallback;
calling exit() in a vfork child is also undefined behavior.

Replace with posix_spawnp invoking "<shell> <script>" explicitly, with
proper error checking. POSIX-only branch; the Windows system()-based
path is unchanged. Ported from upstream PR alexdobin#2693.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* feat: big-endian support with guarded little-endian fast path

STAR read the genome, suffix array and packed arrays through native
uint*/uint128* casts, assuming little-endian byte order, which caused
"next index is smaller than previous" failures on big-endian hosts
(s390x, ppc64).

Add byteOrder.h with loadUintLE/storeUintLE helpers and route the four
endian-sensitive sites (PackedArray::operator[]/writePacked,
funCompareSuffixes, funCalcSAiFromSA) through them. The helpers are
guarded by STAR_BIG_ENDIAN: little-endian builds keep the original
single-instruction native load (zero performance/behavior change), and
only known big-endian compiles take the portable byte-wise path. The
existing MSVC byte-access path in funCalcSAiFromSA is reused for BE.

The byte-wise implementation is exposed by name and unit-tested
(test_byteOrder.cpp) so the BE algorithm is validated on the LE CI
runner. Ported from the patch in upstream issue alexdobin#2690.

Note: compile-validated only; CI has no big-endian runner.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* feat: referenceless CRAM output (--outSAMtype CRAM)

Add CRAM as an output container. STAR produces its BAM via the proven
output path, then transcodes it to referenceless CRAM at finalization
(cramOutput.cpp, using bundled HTSlib with CRAM_OPT_NO_REF, so no
external reference FASTA is required). On conversion failure the
original BAM is kept and the run continues.

- Parameters_runtimeSetup: accept "CRAM" as outSAMtype[0], reusing the
  BAM Unsorted/SortedByCoordinate logic; set outCRAMbool and CRAM names.
- STAR.cpp: transcode Aligned.out.bam / Aligned.sortedByCoord.out.bam
  to .cram after wiggle output, removing the intermediate BAM.
- Hot per-record output code is untouched; the transcriptome BAM stays
  BAM for RSEM/Salmon. CRAM is incompatible with --outStd.
- WebUI: CRAM options in the outSAMtype dropdown, .cram artifacts and
  MIME type.
- Registered cramOutput in CMake build.

Implemented properly rather than porting the incomplete upstream draft
PR alexdobin#2670 (which wrote a NULL header and rerouted the working BAM path).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* build: Makefile ARM64/macOS/libomp parity and cramOutput

Port the platform-detection from upstream PR alexdobin#2694 to the Makefile (CI
uses CMake, which already handles ARM64; this is for `make` users):
- detect UNAME_S/UNAME_M; select -mavx2 on x86_64, -march=armv8-a+simd
  on ARM64/AArch64
- macOS + Apple clang OpenMP: -Xpreprocessor -fopenmp + libomp include,
  -lomp at link; add native STARforMac target (dynamic libomp)
- portable BSD/macOS date fallback for the build timestamp
- add cramOutput.o to OBJECTS

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* docs: document CRAM output, ARM64/macOS, and big-endian support

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant