29 #include <range/v3/view/zip.hpp>
31 namespace seqan3::detail
34 struct view_equality_fn
37 template <std::ranges::forward_range rng1_type, std::ranges::forward_range rng2_type>
38 constexpr
bool operator()(rng1_type && rng1, rng2_type && rng2)
const
40 return std::ranges::equal(rng1, rng2);
83 template <
typename reference_
char_type,
typename query_
char_type>
84 [[nodiscard]] constexpr cigar_op map_aligned_values_to_cigar_op(reference_char_type
const reference_char,
85 query_char_type
const query_char,
86 bool const extended_cigar)
88 requires seqan3::detail::weakly_equality_comparable_with<reference_char_type, gap> &&
89 seqan3::detail::weakly_equality_comparable_with<query_char_type, gap>
93 uint8_t key = (static_cast<uint8_t>(reference_char == gap{}) << 1) | static_cast<uint8_t>(query_char == gap{});
94 if (extended_cigar && (key == 0))
95 key |= ((1 << 2) | static_cast<uint8_t>(query_char == reference_char));
137 template <tuple_like alignment_type>
139 uint32_t
const query_start_pos = 0,
140 uint32_t
const query_end_pos = 0,
141 bool const extended_cigar =
false)
151 if (
ref_seq.size() != query_seq.size())
161 result.emplace_back(query_start_pos,
'S'_cigar_op);
166 cigar_op operation{map_aligned_values_to_cigar_op(
ref_seq[0], query_seq[0], extended_cigar)};
170 for (
auto column : views::zip(
ref_seq, query_seq))
172 cigar_op next_op = map_aligned_values_to_cigar_op(std::get<0>(column), std::get<1>(column), extended_cigar);
174 if (operation == next_op)
180 result.emplace_back(
count, operation);
187 result.emplace_back(
count, operation);
191 result.emplace_back(query_end_pos,
'S'_cigar_op);
208 std::ranges::for_each(cigar_vector, [&result] (
auto & cig) { result.append(cig.to_string()); });
246 template <tuple_like alignment_type>
248 uint32_t
const query_start_pos = 0,
249 uint32_t
const query_end_pos = 0,
250 bool const extended_cigar =
false)
255 return get_cigar_string(get_cigar_vector(
alignment, query_start_pos, query_end_pos, extended_cigar));
294 template <std::ranges::forward_range ref_seq_type, std::ranges::forward_range query_seq_type>
296 query_seq_type && query_seq,
297 uint32_t
const query_start_pos = 0,
298 uint32_t
const query_end_pos = 0,
299 bool const extended_cigar =
false)
301 requires
std::detail::weakly_equality_comparable_with<gap,
reference_t<ref_seq_type>> &&
302 std::detail::weakly_equality_comparable_with<gap,
reference_t<query_seq_type>>
305 return get_cigar_string(
std::tie(
ref_seq, query_seq), query_start_pos, query_end_pos, extended_cigar);
331 template <tuple_like alignment_type>
333 requires std::tuple_size_v<remove_cvref_t<alignment_type>> == 2 &&
334 detail::all_satisfy_aligned_seq<detail::tuple_type_list_t<alignment_type>>
342 for (
auto [cigar_count, cigar_operation] : cigar_vector)
345 if ((
'S'_cigar_op == cigar_operation) || (
'H'_cigar_op == cigar_operation))
348 assert((
'M'_cigar_op == cigar_operation) || (
'='_cigar_op == cigar_operation) ||
349 (
'X'_cigar_op == cigar_operation) || (
'D'_cigar_op == cigar_operation) ||
350 (
'N'_cigar_op == cigar_operation) || (
'I'_cigar_op == cigar_operation) ||
351 (
'P'_cigar_op == cigar_operation));
353 if ((
'M'_cigar_op == cigar_operation) || (
'='_cigar_op == cigar_operation) || (
'X'_cigar_op == cigar_operation))
355 std::ranges::advance(current_ref_pos , cigar_count);
356 std::ranges::advance(current_read_pos, cigar_count);
358 else if ((
'D'_cigar_op == cigar_operation) || (
'N'_cigar_op == cigar_operation))
363 std::ranges::advance(current_ref_pos , cigar_count);
365 else if ((
'I'_cigar_op == cigar_operation))
367 assert(std::ranges::distance(current_ref_pos, std::ranges::end(get<0>(
alignment))) >= 0);
370 std::ranges::advance(current_read_pos, cigar_count);
372 else if ((
'P'_cigar_op == cigar_operation))
384 struct access_restrictor_fn
387 template <
typename chr_t>
388 [[noreturn]] chr_t operator()(chr_t)
const
390 throw std::logic_error{
"Access is not allowed because there is no sequence information."};