Пример #1
0
  /**
   * Extract a sub-sequence from the sequence given a Range object
   *
   * @param range
   * @param sequence
   * @return the sub-sequence, null if the range or sequence is null
   */
  public static String extractRangeSequence(Range range, String sequence) {
    if (range == null || sequence == null || (sequence != null && sequence.length() == 0)) {
      return null;
    }
    // when the range is valid
    if (validateRange(range, sequence).isEmpty()) {
      Position pos1 = range.getStart();
      Position pos2 = range.getEnd();

      // both the start position and the end position have a status
      // if both positions are undetermined, or of type 'n-?','n-n', 'c-c' or '?-c', no feature
      // sequence can be extracted
      // if the start position is negative, it means we cannot extract a sequence for this range
      if ((pos1.isPositionUndetermined() && pos2.isPositionUndetermined()) || pos1.getStart() < 0) {
        return null;
      }
      // a feature sequence can be extracted
      else {
        // the start position is the start position of the start interval
        long startSequence = pos1.getStart();
        // the end position is the end position of the end interval
        long endSequence = pos2.getEnd();

        // in case of undetermined, the start position is starting from 1
        if (pos1.isPositionUndetermined() || PositionUtils.isLessThan(pos1)) {
          startSequence = 1;
        }
        // in case of greater than, the start position is starting from fromIntervalStart + 1
        else if (PositionUtils.isGreaterThan(pos1)) {
          startSequence++;
        }

        // in case of undetermined, the end position is at the end of the sequence
        if (pos2.isPositionUndetermined() || PositionUtils.isGreaterThan(pos2)) {
          endSequence = sequence.length();
        }
        // in case of less than, the end position is at 'toIntervalEnd' - 1
        else if (PositionUtils.isLessThan(pos2)) {
          endSequence--;
        }

        return sequence.substring(
            (int) Math.max(0, startSequence - 1),
            (int) endSequence); // we make sure that we don't request index < 0.
      }
    }

    return null;
  }
Пример #2
0
  /**
   * Checks if the interval positions of the range are overlapping
   *
   * @param range
   * @return true if the range intervals are overlapping
   */
  public static boolean areRangePositionsOverlapping(Range range) {
    // get the range status
    Position start = range.getStart();
    Position end = range.getEnd();
    long fromStart = start.getStart();
    long fromEnd = start.getEnd();
    long toStart = end.getStart();
    long toEnd = end.getEnd();

    // both the end and the start have a specific status
    // in the specific case where the start is superior to a position and the end is inferior to
    // another position, we need to check that the
    // range is not invalid because 'greater than' and 'less than' are both exclusive
    if (PositionUtils.isGreaterThan(start)
        && PositionUtils.isLessThan(end)
        && toStart - fromEnd < 2) {
      return true;
    }
    // we have a greater than start position and the end position is equal to the start position
    else if (PositionUtils.isGreaterThan(start)
        && !PositionUtils.isGreaterThan(end)
        && fromStart == toEnd) {
      return true;
    }
    // we have a less than end position and the start position is equal to the start position
    else if (!PositionUtils.isLessThan(start)
        && PositionUtils.isLessThan(end)
        && fromStart == toEnd) {
      return true;
    }
    // As the range positions are 0 when the status is undetermined, we can only check if the ranges
    // are not overlapping when both start and end are not undetermined
    else if (!start.isPositionUndetermined() && !end.isPositionUndetermined()) {
      return PositionUtils.arePositionsOverlapping(fromStart, fromEnd, toStart, toEnd);
    }

    return false;
  }
Пример #3
0
  /**
   * Method to check if the range is valid or not. If the range is valid, the method returns null
   * otherwise it returns a message.
   *
   * @param range : the range to check
   * @param sequence : the sequence of the polymer
   * @return empty list if the range is within the sequence, coherent with its fuzzy type and not
   *     overlapping. If the range is not valid, it will return a list of error messages describing
   *     why the range is invalid
   */
  public static List<String> validateRange(Range range, String sequence) {

    if (range != null) {

      Position start = range.getStart();
      Position end = range.getEnd();

      List<String> messages = PositionUtils.validateRangePosition(start, sequence);

      messages.addAll(PositionUtils.validateRangePosition(end, sequence));

      if (areRangeStatusInconsistent(range)) {
        messages.add(
            "The start status "
                + start.getStatus().getShortName()
                + " and end status "
                + end.getStatus().getShortName()
                + " are inconsistent");
      }

      if (areRangePositionsOverlapping(range)) {
        messages.add(
            "The range positions overlap : ("
                + start.getStart()
                + "-"
                + start.getEnd()
                + ") - ("
                + end.getStart()
                + "-"
                + end.getEnd()
                + ")");
      }

      return messages;
    }

    return Collections.EMPTY_LIST;
  }