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

org.nmdp.ngs.range.Ranges Maven / Gradle / Ivy

There is a newer version: 1.8.3
Show newest version
/*

    ngs-range  Guava ranges for genomics.
    Copyright (c) 2014 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();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy