All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.github.evenjn.align.alphabet.TupleAlignmentAlphabetBuilderTools Maven / Gradle / Ivy

There is a newer version: 0.6.0
Show newest version
package org.github.evenjn.align.alphabet;

import java.util.Iterator;
import java.util.LinkedList;
import java.util.Vector;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;

import org.github.evenjn.align.TupleAligner;
import org.github.evenjn.align.graph.NotAlignableException;
import org.github.evenjn.align.graph.TupleAlignmentGraph;
import org.github.evenjn.align.graph.TupleAlignmentGraphFactory;
import org.github.evenjn.align.graph.TupleAlignmentNode;
import org.github.evenjn.knit.BasicAutoHook;
import org.github.evenjn.knit.KnittingCursable;
import org.github.evenjn.knit.KnittingTuple;
import org.github.evenjn.knit.ProgressManager;
import org.github.evenjn.numeric.PercentPrinter;
import org.github.evenjn.yarn.AutoHook;
import org.github.evenjn.yarn.Cursable;
import org.github.evenjn.yarn.Di;
import org.github.evenjn.yarn.Progress;
import org.github.evenjn.yarn.ProgressSpawner;
import org.github.evenjn.yarn.Tuple;

public class TupleAlignmentAlphabetBuilderTools {

	public TupleAlignmentAlphabetBuilderTools() {
		
	}
	
	public static  String tuple_printer(
			Function b_printer, Tuple tuple ) {
		StringBuilder sb = new StringBuilder( );
		sb.append( "[" );
		for ( int i = 0; i < tuple.size( ); i++ ) {
			sb.append( " " ).append( b_printer.apply( tuple.get( i ) ) );
		}
		sb.append( " ]" );
		return sb.toString( );
	}

	public static  int computeMinMaxAligneable(
			ProgressSpawner progress_spawner,
			Consumer logger,
			Function a_printer,
			Function b_printer,
			int min_below,
			int max_below,
			Cursable, Tuple>> data,
			int total ) {
		try ( AutoHook hook = new BasicAutoHook( ) ) {
			Progress spawn = ProgressManager.safeSpawn( hook, progress_spawner,
					"TupleAlignmentAlphabetBuilderTools::computeMinMaxCoverage" )
					.target( total );
			int not_aligneable = 0;
			for ( Di, Tuple> datum : KnittingCursable
					.wrap( data ).pull( hook ).once( ) ) {
				spawn.step( 1 );
				try {
					TupleAlignmentAlphabetBuilderTools.attemptToAlingn(
							min_below, max_below, datum.front( ), datum.back( ), x -> true );
				}
				catch ( NotAlignableException e ) {
					if ( logger != null ) {
						StringBuilder sb = new StringBuilder( );
						sb.append( "Not aligneable using min = " ).append( min_below )
								.append( " max = " )
								.append( max_below ).append( ":" );
						for ( SymbolAbove a : KnittingTuple.wrap( datum.front( ) )
								.asIterable( ) ) {
							sb.append( " " ).append( a_printer.apply( a ) );
						}
						sb.append( " ----" );
						for ( SymbolBelow b : KnittingTuple.wrap( datum.back( ) )
								.asIterable( ) ) {
							sb.append( " " ).append( b_printer.apply( b ) );
						}
						logger.accept( sb.toString( ) );
					}
					not_aligneable++;
				}
			}
			if ( logger != null ) {
				StringBuilder sb = new StringBuilder( );
				sb.append( "The number of not aligneable pairs using" )
						.append( " min = " )
						.append( min_below )
						.append( " max = " ).append( max_below )
						.append( " is " )
						.append( not_aligneable )
						.append( " out of " )
						.append( total )
						.append( " ( " ).append(
								PercentPrinter.printRatioAsPercent( 2, not_aligneable, total ) )
						.append( " )" );
				logger.accept( sb.toString( ) );
			}
			return total - not_aligneable;
		}
	}

	public static  int computeCoverage(
			ProgressSpawner progress_spawner,
			Consumer logger,
			int min_below,
			int max_below,
			Cursable, Tuple>> data,
			Predicate> filter,
			int total,
			int min_max_total ) {
		try ( AutoHook hook = new BasicAutoHook( ) ) {
			Progress spawn = ProgressManager.safeSpawn( hook, progress_spawner,
					"TupleAlignmentAlphabetBuilderTools::computeCoverage" )
					.target( total );
			int not_aligneable = 0;
			for ( Di, Tuple> datum : KnittingCursable
					.wrap( data ).pull( hook ).once( ) ) {
				spawn.step( 1 );
				try {
					TupleAlignmentAlphabetBuilderTools.attemptToAlingn(
							min_below, max_below, datum.front( ), datum.back( ), filter );
				}
				catch ( NotAlignableException e ) {
					not_aligneable++;
				}
			}
			if ( logger != null ) {
				StringBuilder sb = new StringBuilder( );
				sb.append( "The number of not aligneable pairs using the current alphabet is " )
						.append( not_aligneable )
						.append( " out of " )
						.append( min_max_total )
						.append( " pairs aligneable with a full alphabet." )
						.append( " ( " ).append(
								PercentPrinter.printRatioAsPercent( 2, not_aligneable, min_max_total ) )
						.append( " )" );
				logger.accept( sb.toString( ) );
			}
			return not_aligneable;
		}
	}

	public static  void attemptToAlingn(
			int min_below,
			int max_below,
			Tuple above,
			Tuple below,
			Predicate> filter )
			throws NotAlignableException {
		BiFunction, Integer> pair_encoder =
				new BiFunction, Integer>( ) {

					@Override
					public Integer apply( SymbolAbove suba,
							Tuple subb ) {

						TupleAlignmentAlphabetPair pair =
								new TupleAlignmentAlphabetPair<>( );
						pair.above = suba;
						pair.below = KnittingTuple.wrap( subb );
						boolean test = filter.test( pair );
						if ( !test ) {
							return null;
						}
						return 1;
					}
				};
		TupleAlignmentGraphFactory.graph(
				pair_encoder,
				above,
				below,
				min_below,
				max_below );
	}

	public static 
			Iterable>
			localAlphabetWithAligner(
					int min_below,
					int max_below,
					Tuple above,
					Tuple below,
					TupleAligner aligner)
					throws NotAlignableException {
		LinkedList> result =
				new LinkedList<>( );
		Tuple> align = aligner.align( above, below );
		int a_so_far = 0;
		int b_so_far = 0;
		for (int i = 0; i < align.size( ); i++) {
			Di di = align.get( i );
			

			TupleAlignmentAlphabetPair pair =
					new TupleAlignmentAlphabetPair<>( );
			if (di.front( ) != 1) {
				throw NotAlignableException.neo;
			}
			pair.above = above.get( a_so_far );
			Vector subb = KnittingTuple.wrap( below )
					.head( b_so_far, di.back( ) ).asCursor( ).collect( new Vector<>( ) );
			pair.below = KnittingTuple.wrap( subb );
			a_so_far = a_so_far + di.front( );
			b_so_far = b_so_far + di.back( );
			result.add( pair );
		}
		return result;
	}

	public static 
			Iterable>
			localAlphabet(
					int min_below,
					int max_below,
					Tuple above,
					Tuple below )
					throws NotAlignableException {

		/**
		 * We invoke the graph factory passing a special encoder. This encoder
		 * appends the requested pair to a buffer vector and returns the size of the
		 * buffer.
		 */
		final Vector> buffer =
				new Vector<>( );
		LinkedList> result =
				new LinkedList<>( );
		BiFunction, Integer> pair_encoder =
				new BiFunction, Integer>( ) {

					@Override
					public Integer apply( SymbolAbove suba,
							Tuple subb ) {

						TupleAlignmentAlphabetPair pair =
								new TupleAlignmentAlphabetPair<>( );
						pair.above = suba;
						pair.below = KnittingTuple.wrap( subb );
						buffer.add( pair );
						return buffer.size( );
					}
				};
		TupleAlignmentGraph graph =
				TupleAlignmentGraphFactory.graph( pair_encoder, above, below,
						min_below, max_below );

		Iterator forward = graph.forward( );
		while ( forward.hasNext( ) ) {
			TupleAlignmentNode node = forward.next( );
			for ( int ie = 0; ie < node.number_of_incoming_edges; ie++ ) {
				int index = node.incoming_edges[ie][2];
				TupleAlignmentAlphabetPair pair =
						buffer.get( index - 1 );
				result.add( pair );
			}
		}
		return result;
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy