pub fn read_pos(
        &self,
        ref_pos: u32,
        include_softclips: bool,
        include_dels: bool,
    ) -> Result<Option<u32>, CigarError> {
        let mut rpos = self.pos as u32; // reference position
        let mut qpos = 0u32; // position within read
        let mut j = 0; // index into cigar operation vector

        // find first cigar operation referring to qpos = 0 (and thus bases in record.seq()),
        // because all augmentations of qpos and rpos before that are invalid
        for (i, c) in self.iter().enumerate() {
            match c {
                &Cigar::Match(_) |
                &Cigar::Diff(_)  |
                &Cigar::Equal(_) |
                // this is unexpected, but bwa + GATK indel realignment can produce insertions
                // before matching positions
                &Cigar::Ins(_) => {
                    j = i;
                    break;
                },
                &Cigar::SoftClip(l) => {
                    j = i;
                    if include_softclips {
                        // Alignment starts with softclip and we want to include it in the
                        // projection of the reference position. However, the POS field does not
                        // include the softclip. Hence we have to subtract its length.
                        rpos = rpos.saturating_sub(l);
                    }
                    break;
                },
                &Cigar::Del(_) => {
                    return Err(CigarError::UnexpectedOperation(
                        "'deletion' (D) found before any operation describing read sequence".to_owned()
                    ));
                },
                &Cigar::RefSkip(_) => {
                    return Err(CigarError::UnexpectedOperation(
                        "'reference skip' (N) found before any operation describing read sequence".to_owned()
                    ));
                },
                &Cigar::HardClip(_) if i > 0 && i < self.len()-1 => {
                    return Err(CigarError::UnexpectedOperation(
                        "'hard clip' (H) found in between operations, contradicting SAMv1 spec that hard clips can only be at the ends of reads".to_owned()
                    ));
                },
                // if we have reached the end of the CigarString with only pads and hard clips, we have no read position matching the variant
                &Cigar::Pad(_) | &Cigar::HardClip(_) if i == self.len()-1 => return Ok(None),
                // skip leading HardClips and Pads, as they consume neither read sequence nor reference sequence
                &Cigar::Pad(_) | &Cigar::HardClip(_) => ()
            }
        }

        let contains_ref_pos = |cigar_op_start: u32, cigar_op_length: u32| {
            cigar_op_start <= ref_pos && cigar_op_start + cigar_op_length > ref_pos
        };

        while rpos <= ref_pos && j < self.len() {
            match &self[j] {
                // potential SNV evidence
                &Cigar::Match(l) | &Cigar::Diff(l) | &Cigar::Equal(l)
                    if contains_ref_pos(rpos, l) =>
                {
                    // difference between desired position and first position of current cigar
                    // operation
                    qpos += ref_pos - rpos;
                    return Ok(Some(qpos));
                }
                &Cigar::SoftClip(l) if include_softclips && contains_ref_pos(rpos, l) => {
                    qpos += ref_pos - rpos;
                    return Ok(Some(qpos));
                }
                &Cigar::Del(l) if include_dels && contains_ref_pos(rpos, l) => {
                    // qpos shall resemble the start of the deletion
                    return Ok(Some(qpos));
                }
                // for others, just increase pos and qpos as needed
                &Cigar::Match(l) | &Cigar::Diff(l) | &Cigar::Equal(l) => {
                    rpos += l;
                    qpos += l;
                    j += 1;
                }
                &Cigar::SoftClip(l) => {
                    qpos += l;
                    j += 1;
                    if include_softclips {
                        rpos += l;
                    }
                }
                &Cigar::Ins(l) => {
                    qpos += l;
                    j += 1;
                }
                &Cigar::RefSkip(l) | &Cigar::Del(l) => {
                    rpos += l;
                    j += 1;
                }
                &Cigar::Pad(_) => {
                    j += 1;
                }
                &Cigar::HardClip(_) if j < self.len() - 1 => {
                    return Err(CigarError::UnexpectedOperation(
                        "'hard clip' (H) found in between operations, contradicting SAMv1 spec that hard clips can only be at the ends of reads".to_owned()
                    ));
                }
                &Cigar::HardClip(_) => return Ok(None),
            }
        }

        Ok(None)
    }
/// For a given position in the reference, get corresponding position within read.
/// If reference position is outside of the read alignment, return None.
///
/// # Arguments
///
/// * `ref_pos` - the reference position
/// * `include_softclips` - if true, softclips will be considered as matches or mismatches
/// * `include_dels` - if true, positions within deletions will be considered (first reference matching read position after deletion will be returned)
///
For a given position in the reference, get corresponding position within read.
If reference position is outside of the read alignment, return None.
For a given position in the reference get corresponding position within read . If reference position is outside of the read alignment return None .
pub fn read_pos(
        &self,
        ref_pos: u32,
        include_softclips: bool,
        include_dels: bool,
    ) -> Result<Option<u32>, CigarError> {
        let mut rpos = self.pos as u32; // reference position
        let mut qpos = 0u32; // position within read
        let mut j = 0; // index into cigar operation vector
        // find first cigar operation referring to qpos = 0 (and thus bases in record.seq()),
        // because all augmentations of qpos and rpos before that are invalid
        for (i, c) in self.iter().enumerate() {
            match c {
                &Cigar::Match(_) |
                &Cigar::Diff(_)  |
                &Cigar::Equal(_) |
                // this is unexpected, but bwa + GATK indel realignment can produce insertions
                // before matching positions
                &Cigar::Ins(_) => {
                    j = i;
                    break;
                },
                &Cigar::SoftClip(l) => {
                    j = i;
                    if include_softclips {
                        // Alignment starts with softclip and we want to include it in the
                        // projection of the reference position. However, the POS field does not
                        // include the softclip. Hence we have to subtract its length.
                        rpos = rpos.saturating_sub(l);
                    }
                    break;
                },
                &Cigar::Del(_) => {
                    return Err(CigarError::UnexpectedOperation(
                        "'deletion' (D) found before any operation describing read sequence".to_owned()
                    ));
                },
                &Cigar::RefSkip(_) => {
                    return Err(CigarError::UnexpectedOperation(
                        "'reference skip' (N) found before any operation describing read sequence".to_owned()
                    ));
                },
                &Cigar::HardClip(_) if i > 0 && i < self.len()-1 => {
                    return Err(CigarError::UnexpectedOperation(
                        "'hard clip' (H) found in between operations, contradicting SAMv1 spec that hard clips can only be at the ends of reads".to_owned()
                    ));
                },
                // if we have reached the end of the CigarString with only pads and hard clips, we have no read position matching the variant
                &Cigar::Pad(_) | &Cigar::HardClip(_) if i == self.len()-1 => return Ok(None),
                // skip leading HardClips and Pads, as they consume neither read sequence nor reference sequence
                &Cigar::Pad(_) | &Cigar::HardClip(_) => ()
            }
        }
        let contains_ref_pos = |cigar_op_start: u32, cigar_op_length: u32| {
            cigar_op_start <= ref_pos && cigar_op_start + cigar_op_length > ref_pos
        };
        while rpos <= ref_pos && j < self.len() {
            match &self[j] {
                // potential SNV evidence
                &Cigar::Match(l) | &Cigar::Diff(l) | &Cigar::Equal(l)
                    if contains_ref_pos(rpos, l) =>
                {
                    // difference between desired position and first position of current cigar
                    // operation
                    qpos += ref_pos - rpos;
                    return Ok(Some(qpos));
                }
                &Cigar::SoftClip(l) if include_softclips && contains_ref_pos(rpos, l) => {
                    qpos += ref_pos - rpos;
                    return Ok(Some(qpos));
                }
                &Cigar::Del(l) if include_dels && contains_ref_pos(rpos, l) => {
                    // qpos shall resemble the start of the deletion
                    return Ok(Some(qpos));
                }
                // for others, just increase pos and qpos as needed
                &Cigar::Match(l) | &Cigar::Diff(l) | &Cigar::Equal(l) => {
                    rpos += l;
                    qpos += l;
                    j += 1;
                }
                &Cigar::SoftClip(l) => {
                    qpos += l;
                    j += 1;
                    if include_softclips {
                        rpos += l;
                    }
                }
                &Cigar::Ins(l) => {
                    qpos += l;
                    j += 1;
                }
                &Cigar::RefSkip(l) | &Cigar::Del(l) => {
                    rpos += l;
                    j += 1;
                }
                &Cigar::Pad(_) => {
                    j += 1;
                }
                &Cigar::HardClip(_) if j < self.len() - 1 => {
                    return Err(CigarError::UnexpectedOperation(
                        "'hard clip' (H) found in between operations, contradicting SAMv1 spec that hard clips can only be at the ends of reads".to_owned()
                    ));
                }
                &Cigar::HardClip(_) => return Ok(None),
            }
        }
        Ok(None)
    }
pub fn read_pos ( & self , ref_pos : u32 , include_softclips : bool , include_dels : bool , ) -> Result < Option < u32 > , CigarError > { let mut rpos = self . pos as u32 ; // reference position let mut qpos = 0u32 ; // position within read let mut j = 0 ; // index into cigar operation vector // find first cigar operation referring to qpos = 0 (and thus bases in record.seq()), // because all augmentations of qpos and rpos before that are invalid for ( i , c ) in self . iter ( ) . enumerate ( ) { match c { & Cigar :: Match ( _ ) | & Cigar :: Diff ( _ ) | & Cigar :: Equal ( _ ) | // this is unexpected, but bwa + GATK indel realignment can produce insertions // before matching positions & Cigar :: Ins ( _ ) => { j = i ; break ; } , & Cigar :: SoftClip ( l ) => { j = i ; if include_softclips { // Alignment starts with softclip and we want to include it in the // projection of the reference position. However, the POS field does not // include the softclip. Hence we have to subtract its length. rpos = rpos . saturating_sub ( l ) ; } break ; } , & Cigar :: Del ( _ ) => { return Err ( CigarError :: UnexpectedOperation ( " " . to_owned ( ) ) ) ; } , & Cigar :: RefSkip ( _ ) => { return Err ( CigarError :: UnexpectedOperation ( " " . to_owned ( ) ) ) ; } , & Cigar :: HardClip ( _ ) if i > 0 && i < self . len ( ) - 1 => { return Err ( CigarError :: UnexpectedOperation ( " " . to_owned ( ) ) ) ; } , // if we have reached the end of the CigarString with only pads and hard clips, we have no read position matching the variant & Cigar :: Pad ( _ ) | & Cigar :: HardClip ( _ ) if i == self . len ( ) - 1 => return Ok ( None ) , // skip leading HardClips and Pads, as they consume neither read sequence nor reference sequence & Cigar :: Pad ( _ ) | & Cigar :: HardClip ( _ ) => ( ) } } let contains_ref_pos = | cigar_op_start : u32 , cigar_op_length : u32 | { cigar_op_start <= ref_pos && cigar_op_start + cigar_op_length > ref_pos } ; while rpos <= ref_pos && j < self . len ( ) { match & self [ j ] { // potential SNV evidence & Cigar :: Match ( l ) | & Cigar :: Diff ( l ) | & Cigar :: Equal ( l ) if contains_ref_pos ( rpos , l ) => { // difference between desired position and first position of current cigar // operation qpos += ref_pos - rpos ; return Ok ( Some ( qpos ) ) ; } & Cigar :: SoftClip ( l ) if include_softclips && contains_ref_pos ( rpos , l ) => { qpos += ref_pos - rpos ; return Ok ( Some ( qpos ) ) ; } & Cigar :: Del ( l ) if include_dels && contains_ref_pos ( rpos , l ) => { // qpos shall resemble the start of the deletion return Ok ( Some ( qpos ) ) ; } // for others, just increase pos and qpos as needed & Cigar :: Match ( l ) | & Cigar :: Diff ( l ) | & Cigar :: Equal ( l ) => { rpos += l ; qpos += l ; j += 1 ; } & Cigar :: SoftClip ( l ) => { qpos += l ; j += 1 ; if include_softclips { rpos += l ; } } & Cigar :: Ins ( l ) => { qpos += l ; j += 1 ; } & Cigar :: RefSkip ( l ) | & Cigar :: Del ( l ) => { rpos += l ; j += 1 ; } & Cigar :: Pad ( _ ) => { j += 1 ; } & Cigar :: HardClip ( _ ) if j < self . len ( ) - 1 => { return Err ( CigarError :: UnexpectedOperation ( " " . to_owned ( ) ) ) ; } & Cigar :: HardClip ( _ ) => return Ok ( None ) , } } Ok ( None ) }
For a given position in the reference, get corresponding position within read.
For a given position in the reference get corresponding position within read .
&self
ref_pos
u32
include_softclips
bool
include_dels
bool
&self
ref_pos
u32
include_softclips
bool
include_dels
bool