예제 #1
0
/// \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             );
}