/// \brief Simple insertion operator for multi_align_builder /// /// \relates multi_align_builder ostream & cath::align::detail::operator<<(ostream &arg_os, ///< The ostream to which the multi_align_builder should be output const multi_align_builder &arg_multi_align_builder ///< The multi_align_builder to output ) { const size_set active_groups = arg_multi_align_builder.get_active_groups(); arg_os << "multi_align_builder["; arg_os << active_groups.size(); arg_os << " active groups : "; for ( const size_t &group_index : active_groups ) { arg_os << "\n\t"; arg_os << arg_multi_align_builder.get_group_of_index( group_index ); } arg_os << ( ( ! active_groups.empty() ) ? "\n" : "" ); arg_os << "]"; return arg_os; }
/// \brief Ctor for alignment_split_mapping /// /// \todo Consider splitting part of this out into a function that creates a copy of the alignment with any missing residues reinserted alignment_split_mapping::alignment_split_mapping(const alignment &arg_alignment, ///< TODOCUMENT const size_set &arg_entries, ///< TODOCUMENT const size_vec &arg_correct_lengths ///< TODOCUMENT ) : orig_length ( arg_alignment.length() ), orig_num_entries ( arg_alignment.num_entries() ), did_insert_entries ( false ), local_aln ( arg_entries.size() ), idx_of_orig_aln_idx ( orig_length ), orig_aln_entries ( common::cbegin( arg_entries ), common::cend( arg_entries ) ), index_of_pdb_res_index( arg_alignment.num_entries() ) { // Sanity check the input list of entries if ( orig_aln_entries.empty() ) { BOOST_THROW_EXCEPTION(invalid_argument_exception("List of entries is empty")); } if ( orig_aln_entries.back() >= orig_num_entries ) { BOOST_THROW_EXCEPTION(invalid_argument_exception("Entries out of range of the entries in the alignment")); } // Loop along the length of the original alignment for (size_t orig_aln_index = 0; orig_aln_index < orig_length; ++orig_aln_index) { const alignment_row local_row = get_row_of_entries_of_alignment( arg_alignment, orig_aln_entries, orig_aln_index ); // Only do anything if at least one of the specified entries is present at this index if ( any_entries_present( local_row ) ) { // For each entry that's present at this index, // insert any missing residues into the local_aln, recording where each has gone for (size_t entry = 0; entry < orig_aln_entries.size(); ++entry) { // Grab some details for this entry: // * a reference to the relevant entry of index_of_pdb_res_index // * the equivalent entry in the original alignment // * the position for this index/entry in the original alignment size_vec &pdb_res_indices = index_of_pdb_res_index[ entry ]; const size_t &orig_aln_entry = orig_aln_entries [ entry ]; const aln_posn_opt position = arg_alignment.position_of_entry_of_index( orig_aln_entry, orig_aln_index ); // If there is something present here in the original alignment then add any missing residues if ( position ) { // Add any missing residues... while ( pdb_res_indices.size() < *position ) { did_insert_entries = true; pdb_res_indices.push_back( local_aln.length() ); append_row_with_single_value( local_aln, entry, pdb_res_indices.size() - 1 ); } } } // For each entry that's present at this index, // record where the residue for this index's row will go for (size_t entry = 0; entry < orig_aln_entries.size(); ++entry) { // Grab some details for this entry: // * a reference to the relevant entry of index_of_pdb_res_index // * the equivalent entry in the original alignment // * the position for this index/entry in the original alignment size_vec &pdb_res_indices = index_of_pdb_res_index[ entry ]; const size_t &orig_aln_entry = orig_aln_entries [ entry ]; const aln_posn_opt position = arg_alignment.position_of_entry_of_index( orig_aln_entry, orig_aln_index ); // If there is something present here in the original alignment then store the residue for this index will go if ( position ) { // ...and store the residue for this index will go pdb_res_indices.push_back( local_aln.length() ); } } // Store where this alignment row is placed in the local_aln and then put it there idx_of_orig_aln_idx[ orig_aln_index ] = local_aln.length(); append_row( local_aln, local_row ); } } // Append any extra residues that are missing at the end of the original alignment for (size_t entry = 0; entry < orig_aln_entries.size(); ++entry) { // Grab some details for this entry: // * a reference to the relevant entry of index_of_pdb_res_index // * the equivalent entry in the original alignment // * the correct length for this entry size_vec &pdb_res_indices = index_of_pdb_res_index[ entry ]; const size_t &orig_aln_entry = orig_aln_entries [ entry ]; const size_t &correct_length = arg_correct_lengths [ orig_aln_entry ]; // Add any missing residues... while ( pdb_res_indices.size() < correct_length ) { did_insert_entries = true; pdb_res_indices.push_back( local_aln.length() ); append_row_with_single_value( local_aln, entry, pdb_res_indices.size() - 1 ); } } // Very basic sanity checks assert( orig_aln_entries.size() == local_aln.num_entries() ); assert( idx_of_orig_aln_idx.size() == orig_length ); }