Skip to content

Commit

Permalink
cram/record/feature: Use named fields
Browse files Browse the repository at this point in the history
  • Loading branch information
zaeleus committed Oct 5, 2024
1 parent 02c5340 commit ebb6c81
Show file tree
Hide file tree
Showing 10 changed files with 746 additions and 342 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,15 @@ pub struct Builder {
impl Builder {
pub fn update(&mut self, record: &Record) {
for feature in record.features().iter() {
match feature {
Feature::Substitution(_, substitution::Value::Bases(reference_base, read_base)) => {
self.histogram.hit(*reference_base, *read_base);
if let Feature::Substitution { value, .. } = feature {
match value {
substitution::Value::Bases(reference_base, read_base) => {
self.histogram.hit(*reference_base, *read_base);
}
substitution::Value::Code(_) => {
panic!("substitution matrix cannot be built from substitution codes");
}
}
Feature::Substitution(_, substitution::Value::Code(_)) => {
panic!("substitution matrix cannot be built from substitution codes");
}
_ => {}
}
}
}
Expand Down Expand Up @@ -51,30 +52,30 @@ mod tests {
.set_read_length(bases.len())
.set_bases(bases)
.set_features(Features::from(vec![
Feature::Substitution(
Position::try_from(1)?,
substitution::Value::Bases(Base::A, Base::T),
),
Feature::Substitution(
Position::try_from(3)?,
substitution::Value::Bases(Base::A, Base::T),
),
Feature::Substitution(
Position::try_from(6)?,
substitution::Value::Bases(Base::A, Base::C),
),
Feature::Substitution(
Position::try_from(7)?,
substitution::Value::Bases(Base::A, Base::G),
),
Feature::Substitution(
Position::try_from(9)?,
substitution::Value::Bases(Base::A, Base::G),
),
Feature::Substitution(
Position::try_from(10)?,
substitution::Value::Bases(Base::A, Base::T),
),
Feature::Substitution {
position: Position::try_from(1)?,
value: substitution::Value::Bases(Base::A, Base::T),
},
Feature::Substitution {
position: Position::try_from(3)?,
value: substitution::Value::Bases(Base::A, Base::T),
},
Feature::Substitution {
position: Position::try_from(6)?,
value: substitution::Value::Bases(Base::A, Base::C),
},
Feature::Substitution {
position: Position::try_from(7)?,
value: substitution::Value::Bases(Base::A, Base::G),
},
Feature::Substitution {
position: Position::try_from(9)?,
value: substitution::Value::Bases(Base::A, Base::G),
},
Feature::Substitution {
position: Position::try_from(10)?,
value: substitution::Value::Bases(Base::A, Base::T),
},
]))
.build();

Expand Down
16 changes: 8 additions & 8 deletions noodles-cram/src/data_container/slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -649,10 +649,10 @@ mod tests {
.set_reference_sequence_id(0)
.set_read_length(2)
.set_alignment_start(Position::MIN)
.set_features(Features::from(vec![Feature::Bases(
Position::MIN,
vec![b'A', b'C'],
)]))
.set_features(Features::from(vec![Feature::Bases {
position: Position::MIN,
bases: vec![b'A', b'C'],
}]))
.build()];

resolve_bases(
Expand Down Expand Up @@ -681,10 +681,10 @@ mod tests {
.set_id(1)
.set_bam_flags(sam::alignment::record::Flags::empty())
.set_read_length(2)
.set_features(Features::from(vec![Feature::Scores(
Position::try_from(1)?,
vec![8, 13],
)]))
.set_features(Features::from(vec![Feature::Scores {
position: Position::try_from(1)?,
quality_scores: vec![8, 13],
}]))
.build(),
Record::builder().set_id(2).build(),
Record::builder()
Expand Down
41 changes: 27 additions & 14 deletions noodles-cram/src/io/reader/record.rs
Original file line number Diff line number Diff line change
Expand Up @@ -465,52 +465,65 @@ where
match code {
Code::Bases => {
let bases = self.read_stretches_of_bases()?;
Ok(Feature::Bases(position, bases))
Ok(Feature::Bases { position, bases })
}
Code::Scores => {
let quality_scores = self.read_stretches_of_quality_scores()?;
Ok(Feature::Scores(position, quality_scores))

Ok(Feature::Scores {
position,
quality_scores,
})
}
Code::ReadBase => {
let base = self.read_base()?;
let quality_score = self.read_quality_score()?;
Ok(Feature::ReadBase(position, base, quality_score))

Ok(Feature::ReadBase {
position,
base,
quality_score,
})
}
Code::Substitution => {
let code = self.read_base_substitution_code()?;
Ok(Feature::Substitution(position, code))
let value = self.read_base_substitution_code()?;
Ok(Feature::Substitution { position, value })
}
Code::Insertion => {
let bases = self.read_insertion_bases()?;
Ok(Feature::Insertion(position, bases))
Ok(Feature::Insertion { position, bases })
}
Code::Deletion => {
let len = self.read_deletion_length()?;
Ok(Feature::Deletion(position, len))
Ok(Feature::Deletion { position, len })
}
Code::InsertBase => {
let base = self.read_base()?;
Ok(Feature::InsertBase(position, base))
Ok(Feature::InsertBase { position, base })
}
Code::QualityScore => {
let score = self.read_quality_score()?;
Ok(Feature::QualityScore(position, score))
let quality_score = self.read_quality_score()?;

Ok(Feature::QualityScore {
position,
quality_score,
})
}
Code::ReferenceSkip => {
let len = self.read_reference_skip_length()?;
Ok(Feature::ReferenceSkip(position, len))
Ok(Feature::ReferenceSkip { position, len })
}
Code::SoftClip => {
let bases = self.read_soft_clip_bases()?;
Ok(Feature::SoftClip(position, bases))
Ok(Feature::SoftClip { position, bases })
}
Code::Padding => {
let len = self.read_padding_length()?;
Ok(Feature::Padding(position, len))
Ok(Feature::Padding { position, len })
}
Code::HardClip => {
let len = self.read_hard_clip_length()?;
Ok(Feature::HardClip(position, len))
Ok(Feature::HardClip { position, len })
}
}
}
Expand Down
30 changes: 17 additions & 13 deletions noodles-cram/src/io/writer/record.rs
Original file line number Diff line number Diff line change
Expand Up @@ -501,41 +501,45 @@ where
self.write_feature_position(position)?;

match feature {
Feature::Bases(_, bases) => {
Feature::Bases { bases, .. } => {
self.write_stretches_of_bases(bases)?;
}
Feature::Scores(_, quality_scores) => {
Feature::Scores { quality_scores, .. } => {
self.write_stretches_of_quality_scores(quality_scores)?;
}
Feature::ReadBase(_, base, quality_score) => {
Feature::ReadBase {
base,
quality_score,
..
} => {
self.write_base(*base)?;
self.write_quality_score(*quality_score)?;
}
Feature::Substitution(_, value) => {
Feature::Substitution { value, .. } => {
self.write_base_substitution_code(*value)?;
}
Feature::Insertion(_, bases) => {
Feature::Insertion { bases, .. } => {
self.write_insertion(bases)?;
}
Feature::Deletion(_, len) => {
Feature::Deletion { len, .. } => {
self.write_deletion_length(*len)?;
}
Feature::InsertBase(_, base) => {
Feature::InsertBase { base, .. } => {
self.write_base(*base)?;
}
Feature::QualityScore(_, score) => {
self.write_quality_score(*score)?;
Feature::QualityScore { quality_score, .. } => {
self.write_quality_score(*quality_score)?;
}
Feature::ReferenceSkip(_, len) => {
Feature::ReferenceSkip { len, .. } => {
self.write_reference_skip_length(*len)?;
}
Feature::SoftClip(_, bases) => {
Feature::SoftClip { bases, .. } => {
self.write_soft_clip(bases)?;
}
Feature::Padding(_, len) => {
Feature::Padding { len, .. } => {
self.write_padding(*len)?;
}
Feature::HardClip(_, len) => {
Feature::HardClip { len, .. } => {
self.write_hard_clip(*len)?;
}
}
Expand Down
40 changes: 29 additions & 11 deletions noodles-cram/src/record.rs
Original file line number Diff line number Diff line change
Expand Up @@ -338,11 +338,11 @@ pub(crate) fn calculate_alignment_span(read_length: usize, features: &Features)
features
.iter()
.fold(read_length, |alignment_span, feature| match feature {
Feature::Insertion(_, bases) => alignment_span - bases.len(),
Feature::InsertBase(_, _) => alignment_span - 1,
Feature::Deletion(_, len) => alignment_span + len,
Feature::ReferenceSkip(_, len) => alignment_span + len,
Feature::SoftClip(_, bases) => alignment_span - bases.len(),
Feature::Insertion { bases, .. } => alignment_span - bases.len(),
Feature::InsertBase { .. } => alignment_span - 1,
Feature::Deletion { len, .. } => alignment_span + len,
Feature::ReferenceSkip { len, .. } => alignment_span + len,
Feature::SoftClip { bases, .. } => alignment_span - bases.len(),
_ => alignment_span,
})
}
Expand Down Expand Up @@ -370,15 +370,33 @@ mod tests {
let features = Features::default();
assert_eq!(calculate_alignment_span(4, &features), 4);

let features = Features::from(vec![Feature::HardClip(Position::try_from(1)?, 4)]);
let features = Features::from(vec![Feature::HardClip {
position: Position::try_from(1)?,
len: 4,
}]);
assert_eq!(calculate_alignment_span(4, &features), 4);

let features = Features::from(vec![
Feature::Insertion(Position::try_from(1)?, vec![b'A', b'C']),
Feature::InsertBase(Position::try_from(4)?, b'G'),
Feature::Deletion(Position::try_from(6)?, 3),
Feature::ReferenceSkip(Position::try_from(10)?, 5),
Feature::SoftClip(Position::try_from(16)?, vec![b'A', b'C', b'G', b'T']),
Feature::Insertion {
position: Position::try_from(1)?,
bases: vec![b'A', b'C'],
},
Feature::InsertBase {
position: Position::try_from(4)?,
base: b'G',
},
Feature::Deletion {
position: Position::try_from(6)?,
len: 3,
},
Feature::ReferenceSkip {
position: Position::try_from(10)?,
len: 5,
},
Feature::SoftClip {
position: Position::try_from(16)?,
bases: vec![b'A', b'C', b'G', b'T'],
},
]);
assert_eq!(calculate_alignment_span(20, &features), 21);

Expand Down
Loading

0 comments on commit ebb6c81

Please sign in to comment.