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

org.biopax.paxtools.query.algorithm.PathsFromToQuery Maven / Gradle / Ivy

Go to download

BioPAX graph-theoretic querying - for finding paths between molecules, or identifying molecules that are reachable through specific paths, using the BioPAX pathway data model.

There is a newer version: 6.0.0
Show newest version
package org.biopax.paxtools.query.algorithm;


import org.biopax.paxtools.query.model.GraphObject;
import org.biopax.paxtools.query.model.Node;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * Finds the paths from a specified source set of states or entities to a
 * specified target set of states or entities within the boundaries of a
 * specified length limit. Takes source set, target set, type of distance
 * limit, distance limit and strict value. Based on these parameters, the
 * interactions within source set and within target set may be omitted and/or
 * "shortest+k" may be used as length limit.
 *
 * @author Ozgun Babur
 * @author Merve Cakir
 */
public class PathsFromToQuery
{
	/**
	 * The set of nodes from which the paths of interests should start.
	 */
	private Set sourceSet;

	/**
	 * The set of nodes to which the paths of interests should arrive.
	 */
	private Set targetSet;

	/**
	 * True if length limit is used, false if shortes+k is used.
	 */
	private LimitType limitType;

	/**
	 * Based on the limitType, given integer may be used directly as stop
	 * distance or may be added up with the shortest path's length and used as
	 * stop distance.
	 */
	private int stopDistance;

	/**
	 * When true, the interactions within source set and within target set are
	 * not involved in result set.
	 */
	private boolean strict;

	/**
	 * This is a hard-coded limit to use with the shortest_plus_k limit. If there is no shortest
	 * path between the given nodes, the algorithm should not try to traverse all the graph. So this
	 * shortest path search limit will make sure that the algorithm will not search for indefinitely
	 * for the shortest path.
	 */
	private static final int LIMIT_FOR_SP_SEARCH = 25;

	/**
	 * Constructor with parameters.
	 * @param sourceSet source set
	 * @param targetSet target set
	 * @param limitType normal limit or shortest + k type limit
	 * @param stopDistance search limit
	 * @param strict whether we want to extend and result path towards other source and targets
	 */
	public PathsFromToQuery(Set sourceSet,
							Set targetSet,
							LimitType limitType,
							int stopDistance,
							boolean strict)
	{
		assert limitType != null : "limitType should be specified";

		this.sourceSet = sourceSet;
		this.targetSet = targetSet;
		this.limitType = limitType;
		this.stopDistance = stopDistance;
		this.strict = strict;
	}

	/**
	 * Executes the algorithm.
	 * @return paths from sources to targets
	 */
	public Set run()
	{
		/**
		 * Candidate contains all the graph objects that are the results of BFS.
		 * Eliminating nodes from candidate according to their labels will
		 * yield result.
		 */
		Map candidate = new HashMap();
		Set result = new HashSet();

		BFS bfsFwd = null;
		BFS bfsRev = null;

		if (limitType == LimitType.NORMAL && !strict)
		{
			bfsFwd = new BFS(sourceSet, null, Direction.DOWNSTREAM, stopDistance);
			bfsRev = new BFS(targetSet, null, Direction.UPSTREAM, stopDistance);
		}
		else if (limitType == LimitType.NORMAL && strict)
		{
			bfsFwd = new BFS(sourceSet, targetSet, Direction.DOWNSTREAM, stopDistance);
			bfsRev = new BFS(targetSet, sourceSet, Direction.UPSTREAM, stopDistance);
		}
		else if (limitType == LimitType.SHORTEST_PLUS_K && !strict)
		{
			bfsFwd = new BFS(sourceSet, null, Direction.DOWNSTREAM, LIMIT_FOR_SP_SEARCH);
			bfsRev = new BFS(targetSet, null, Direction.UPSTREAM, LIMIT_FOR_SP_SEARCH);
		}
		else if (limitType == LimitType.SHORTEST_PLUS_K && strict)
		{
			bfsFwd = new BFS(sourceSet, targetSet, Direction.DOWNSTREAM, LIMIT_FOR_SP_SEARCH);
			bfsRev = new BFS(targetSet, sourceSet, Direction.UPSTREAM, LIMIT_FOR_SP_SEARCH);
		}

		candidate.putAll(bfsFwd.run());
		candidate.putAll(bfsRev.run());

		int limit = stopDistance;

		if(limitType == LimitType.NORMAL)
		{
			/**
			 * Only the graph objects whose sum of two search labels being
			 * smaller than or equal to the distance limit will be in the result.
			 */
			for (GraphObject go : candidate.keySet())
			{
				if ((bfsFwd.getLabel(go) + bfsRev.getLabel(go)) <= limit)
				{
					result.add(go);
				}
			}
		}
		else
		{
			int shortestPath = Integer.MAX_VALUE;

			/**
			 * Summing up the labels of two search will give the length of the
			 * path that passes through that particular graph object and the
			 * minimum of those lengths will be the length of the shortest path.
			 */
			for (GraphObject go : candidate.keySet())
			{
				if ((bfsFwd.getLabel(go) + bfsRev.getLabel(go)) <= shortestPath)
				{
					shortestPath = (bfsFwd.getLabel(go) + bfsRev.getLabel(go));
				}
			}

			limit = shortestPath + stopDistance;

			// Proceed only if there is a shortest path found

			if (shortestPath < Integer.MAX_VALUE / 2)
			{
				/**
				 * Only the graph objects whose sum of two search labels being
				 * smaller than or equal to the "shortest + limit" will be in the
				 * result.
				 */
				for (GraphObject go : candidate.keySet())
				{
					if ((bfsFwd.getLabel(go) + bfsRev.getLabel(go)) <= limit)
					{
						result.add(go);
					}
				}
			}
		}

		Set ST = new HashSet(sourceSet);
		ST.addAll(targetSet);

		CycleBreaker breaker = new CycleBreaker(result, ST, limit);
		breaker.breakCycles();

		Prune prune = new Prune(result, ST);
		prune.run();

		return result;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy