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

de.citec.tcs.alignment.Operation Maven / Gradle / Ivy

/* 
 * TCS Alignment Toolbox Version 3
 * 
 * Copyright (C) 2016
 * Benjamin Paaßen
 * AG Theoretical Computer Science
 * Centre of Excellence Cognitive Interaction Technology (CITEC)
 * University of Bielefeld
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 * 
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see .
 */

package de.citec.tcs.alignment;

import de.citec.tcs.alignment.comparators.OperationType;
import java.util.Objects;
import lombok.Getter;
import lombok.NonNull;

/**
 * This defines an applied Alignment Operation. It is specified by the nodes that have been aligned
 * from the left or the right sequence in the Alignment.
 * If a node was replaced by a gap or skip it is denoted here as a null reference.
 *
 * @author Benjamin Paassen - [email protected]
 * @param  the class of the elements in the left input sequence.
 * @param  the class of the elements in the right input sequence.
 */
public class Operation {

	/**
	 * An element of the left input sequence that has been processed in this operation. This may be
	 * null for insertion and skip-insertion operations.
	 *
	 * @return An element of the left input sequence that has been processed in this operation.
	 */
	@Getter
	private final X left;
	/**
	 * An element of the right input sequence that has been processed in this operation. This may be
	 * null for deletion and skip-deletion operations.
	 *
	 * @return An element of the right input sequence that has been processed in this operation.
	 */
	@Getter
	private final Y right;
	/**
	 * The type of this Operation. Please refer to the OperationType class for more information.
	 *
	 * @return The type of this Operation. Please refer to the OperationType class for more
	 * information.
	 */
	@Getter
	@NonNull
	private final OperationType type;
	/**
	 * The local distance contributed by this operation.
	 *
	 * @return The local distance contributed by this operation.
	 */
	@Getter
	private final double distance;

	/**
	 * This constructs an Operation within an AlignmentPath.
	 *
	 * @param left The Node from the left input sequence that was used here or null if this is a
	 * DELETION/SKIPDELETION operation.
	 * @param right The Node from the right input sequence that was used here or null if this is an
	 * INSERTION/SKIPINSERTION operation.
	 * @param type The type of this Operation. Please refer to the OperationType class for more
	 * information.
	 * @param distance The local distance contributed by this operation.
	 */
	public Operation(X left, Y right, @NonNull OperationType type, double distance) {
		this.left = left;
		this.right = right;
		this.type = type;
		//check validity.
		switch (type) {
			case DELETION:
			case SKIPDELETION:
				if (right != null) {
					throw new IllegalArgumentException("Expected right input to be null for a deletion/skip-deletion but it was not null!");
				}
				break;
			default:
				if (right == null) {
					throw new NullPointerException("Right input was null unexpectedly for a " + type + " operation.");
				}
		}
		switch (type) {
			case INSERTION:
			case SKIPINSERTION:
				if (left != null) {
					throw new IllegalArgumentException("Expected left input to be null for an insertion/skip-insertion but it was not null!");
				}
				break;
			default:
				if (left == null) {
					throw new NullPointerException("Left input was null unexpectedly for a " + type + " operation.");
				}
		}
		this.distance = distance;
	}

	/**
	 * A copy constructor.
	 *
	 * @param copy the operation that shall be copied.
	 */
	public Operation(@NonNull Operation copy) {
		this.left = copy.left;
		this.right = copy.right;
		this.type = copy.type;
		this.distance = copy.distance;
	}

	@Override
	public int hashCode() {
		int hash = 3;
		hash = 13 * hash + Objects.hashCode(this.left);
		hash = 13 * hash + Objects.hashCode(this.right);
		hash = 13 * hash + Objects.hashCode(this.type);
		hash = 13 * hash + (int) (Double.doubleToLongBits(this.distance) ^ (Double.doubleToLongBits(this.distance) >>> 32));
		return hash;
	}

	@Override
	public boolean equals(Object obj) {
		if (obj == null) {
			return false;
		}
		if (getClass() != obj.getClass()) {
			return false;
		}
		final Operation other = (Operation) obj;
		if (!Objects.equals(this.left, other.left)) {
			return false;
		}
		if (!Objects.equals(this.right, other.right)) {
			return false;
		}
		if (this.type != other.type) {
			return false;
		}
		if (Double.doubleToLongBits(this.distance) != Double.doubleToLongBits(other.distance)) {
			return false;
		}
		return true;
	}

	@Override
	public String toString() {
		final StringBuilder builder = new StringBuilder();
		builder.append(type);
		builder.append("\nLocal Cost = ");
		builder.append(Double.toString(distance));
		builder.append("\n");
		switch (type) {
			case INSERTION:
				builder.append("-");
				break;
			case SKIPINSERTION:
				builder.append("_");
				break;
			default:
				builder.append(left.toString());
		}
		builder.append(" vs. ");

		switch (type) {
			case DELETION:
				builder.append("-");
				break;
			case SKIPDELETION:
				builder.append("_");
				break;
			default:
				builder.append(right.toString());
		}
		return builder.toString();
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy