org.nmdp.ngs.range.Ranges Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of ngs-range Show documentation
Show all versions of ngs-range Show documentation
Guava ranges for genomics.
/*
ngs-range Guava ranges for genomics.
Copyright (c) 2014-2015 National Marrow Donor Program (NMDP)
This library is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation; either version 3 of the License, or (at
your option) any later version.
This library is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; with out even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this library; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
> http://www.gnu.org/licenses/lgpl.html
*/
package org.nmdp.ngs.range;
import static com.google.common.base.Preconditions.checkNotNull;
import java.math.BigInteger;
import com.google.common.collect.BoundType;
import com.google.common.collect.ComparisonChain;
import com.google.common.collect.Ordering;
import com.google.common.collect.Range;
/**
* Utility methods on ranges.
*/
public final class Ranges {
/**
* Private no-arg constructor.
*/
private Ranges() {
// empty
}
/**
* Return the center of the specified range.
*
* @param range endpoint type
* @param range range, must not be null
* @return the center of the specified range
*/
public static C center(final Range range) {
checkNotNull(range);
if (!range.hasLowerBound() && !range.hasUpperBound()) {
throw new IllegalStateException("cannot find the center of a range without bounds");
}
if (!range.hasLowerBound()) {
return range.upperEndpoint();
}
if (!range.hasUpperBound()) {
return range.lowerEndpoint();
}
C lowerEndpoint = range.lowerEndpoint();
C upperEndpoint = range.upperEndpoint();
if (upperEndpoint instanceof Integer) {
Integer upper = (Integer) upperEndpoint;
Integer lower = (Integer) lowerEndpoint;
return (C) Integer.valueOf((upper.intValue() + lower.intValue()) / 2);
}
if (upperEndpoint instanceof Long) {
Long upper = (Long) upperEndpoint;
Long lower = (Long) lowerEndpoint;
return (C) Long.valueOf((upper.longValue() + lower.longValue()) / 2L);
}
if (upperEndpoint instanceof BigInteger) {
BigInteger upper = (BigInteger) upperEndpoint;
BigInteger lower = (BigInteger) lowerEndpoint;
BigInteger two = BigInteger.valueOf(2L);
return (C) upper.subtract(lower).divide(two);
}
// todo: could potentially calculate the center of any range with a discrete domain
throw new IllegalStateException("cannot find the center of a range whose endpoint type is not Integer, Long, or BigInteger");
}
/**
* Return true if the specified ranges intersect.
*
* @param range endpoint type
* @param range0 first range, must not be null
* @param range1 second range, must not be null
* @return true if the specified ranges intersect
*/
public static boolean intersect(final Range range0, final Range range1) {
checkNotNull(range0);
checkNotNull(range1);
return range0.isConnected(range1) && !range0.intersection(range1).isEmpty();
}
/**
* Return true if the specified range is strictly less than the specified value.
*
* @param range endpoint type
* @param range range, must not be null
* @param value value, must not be null
* @return true if the specified range is strictly less than the specified value
*/
public static boolean isLessThan(final Range range, final C value) {
checkNotNull(range);
checkNotNull(value);
if (!range.hasUpperBound()) {
return false;
}
if (range.upperBoundType() == BoundType.OPEN && range.upperEndpoint().equals(value)) {
return true;
}
return range.upperEndpoint().compareTo(value) < 0;
}
/**
* Return true if the specified range is strictly greater than the specified value.
*
* @param range endpoint type
* @param range range, must not be null
* @param value value, must not be null
* @return true if the specified range is strictly greater than the specified value
*/
public static boolean isGreaterThan(final Range range, final C value) {
checkNotNull(range);
checkNotNull(value);
if (!range.hasLowerBound()) {
return false;
}
if (range.lowerBoundType() == BoundType.OPEN && range.lowerEndpoint().equals(value)) {
return true;
}
return range.lowerEndpoint().compareTo(value) > 0;
}
/**
* Return an ordering by lower endpoint over ranges.
*
* @param range endpoint type
* @return an ordering by lower endpoint over ranges
*/
public static Ordering> orderingByLowerEndpoint() {
return new Ordering>() {
@Override
public int compare(final Range left, final Range right) {
return ComparisonChain.start()
.compare(left.hasLowerBound(), right.hasLowerBound())
.compare(left.lowerEndpoint(), right.lowerEndpoint())
.result();
}
};
}
/**
* Return a reverse ordering by lower endpoint over ranges.
*
* @param range endpoint type
* @return a reverse ordering by lower endpoint over ranges
*/
public static Ordering> reverseOrderingByLowerEndpoint() {
Ordering> orderingByLowerEndpoint = orderingByLowerEndpoint();
return orderingByLowerEndpoint.reverse();
}
/**
* Return an ordering by upper endpoint over ranges.
*
* @param range endpoint type
* @return an ordering by upper endpoint over ranges
*/
public static Ordering> orderingByUpperEndpoint() {
return new Ordering>() {
@Override
public int compare(final Range left, final Range right) {
return ComparisonChain.start()
.compare(left.hasUpperBound(), right.hasUpperBound())
.compare(left.upperEndpoint(), right.upperEndpoint())
.result();
}
};
}
/**
* Return a reverse ordering by upper endpoint over ranges.
*
* @param range endpoint type
* @return a reverse ordering by upper endpoint over ranges
*/
public static Ordering> reverseOrderingByUpperEndpoint() {
Ordering> orderingByUpperEndpoint = orderingByUpperEndpoint();
return orderingByUpperEndpoint.reverse();
}
}