Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion book/src/intro_validate.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,17 @@ These fields are as follows:
| 2 | start position | 0-based start position | int |
| 3 | end position | 0-based exclusive end position | int |
| 4 | mod code | modified base code | str |
| 6 | strand | strand (e.g. +,-,.) | str |
| 6 | strand | strand (`+` or `-`) | str |

The 5th column is ignored in the validate command.

The start position must be non-negative and the end position must be greater
than the start position. Zero-length BED features do not annotate a reference
base and are rejected by `validate`.
Repeated or overlapping annotations may assign the same status more than once,
but conflicting statuses at the same reference position and strand are
rejected.

The 4th column represents the modified base code annotating the status at this reference position (or range of reference positions).
This value can be `-` representing a canonical base (note that this differs from the `remora validate` annotation), a single letter code as defined in the modBAM tag specification, or any ChEBI code.
The validate command will assume that any base from the associated modBAM file overlapping these positions should match this annotation.
Expand Down
31 changes: 31 additions & 0 deletions modkit-core/src/mod_bam.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1506,6 +1506,7 @@ fn parse_raw_mod_tags(record: &bam::Record) -> MkResult<RawModTags> {
pub struct ModBaseInfo {
pub pos_seq_base_mod_probs: HashMap<DnaBase, SeqPosBaseModProbs>,
pub neg_seq_base_mod_probs: HashMap<DnaBase, SeqPosBaseModProbs>,
modified_primary_base_strands: HashMap<DnaBase, HashSet<Strand>>,
converters: HashMap<DnaBase, DeltaListConverter>,
pub mm_style: &'static str,
pub ml_style: &'static str,
Expand All @@ -1531,6 +1532,24 @@ impl ModBaseInfo {
HashMap::<DnaBase, SeqPosBaseModProbs>::new();
let mut neg_seq_base_mod_probs =
HashMap::<DnaBase, SeqPosBaseModProbs>::new();
let modified_primary_base_strands = tag_infos.iter().fold(
HashMap::<DnaBase, HashSet<Strand>>::new(),
|mut strands_by_base, tag_info| {
for &raw_base in tag_info.fundamental_base.expand_bases() {
let modified_primary_base =
if tag_info.strand == Strand::Negative {
raw_base.complement()
} else {
raw_base
};
strands_by_base
.entry(modified_primary_base)
.or_default()
.insert(tag_info.strand);
}
strands_by_base
},
);

let mut converters = HashMap::new();
let mut pointer = 0usize;
Expand Down Expand Up @@ -1604,12 +1623,24 @@ impl ModBaseInfo {
Ok(Self {
pos_seq_base_mod_probs,
neg_seq_base_mod_probs,
modified_primary_base_strands,
converters,
mm_style: raw_mod_tags.mm_style,
ml_style: raw_mod_tags.ml_style,
})
}

pub(crate) fn mod_strands_for_modified_primary_base(
&self,
canonical_base: DnaBase,
) -> impl Iterator<Item = Strand> + '_ {
self.modified_primary_base_strands
.get(&canonical_base)
.into_iter()
.flatten()
.copied()
}

pub fn into_iter_base_mod_probs(
self,
) -> (
Expand Down
Loading