convert an interval in the alignmnet into co-ordinates in one of the
    sequences. Alignment intervals are inclusive of start, but not end. They
    are one-based. Hence the full alignment has coords [1, N+1), where N is the
    length of the alignment (number of columns). Sequence coords follow the
    same conventions: one-based, inclusive of start but not end.

    :param seq_name: which sequence are the start and end coords for?
    :param start:    start of the interval in alignment co-ordinates
    :param end:      end of the interval in alignment co-ordinates
    :param trim:     if true, trim coordinates that fall partially outside
                     the alignment
    :return: a tuple with the start and end sequence coords, in that order;
             None if the interval in the alignment defined by (start, end)
             contains only gaps in the specified sequence. start < end always,
             even if the sequence is reverse complement.
    :raises AlignmentError: if the sequence number specifies a sequence not
                            in this alignment, or the coordinates fall
                            entirely outside the alignment (or partially
                            outside and trim == false), or they are not a valid
                            interval (start >= end)

def alignment_to_sequence_coords(self, seq_name, start, end, trim=False):
    """
    convert an interval in the alignmnet into co-ordinates in one of the
    sequences. Alignment intervals are inclusive of start, but not end. They
    are one-based. Hence the full alignment has coords [1, N+1), where N is the
    length of the alignment (number of columns). Sequence coords follow the
    same conventions: one-based, inclusive of start but not end.

    :param seq_name: which sequence are the start and end coords for?
    :param start:    start of the interval in alignment co-ordinates
    :param end:      end of the interval in alignment co-ordinates
    :param trim:     if true, trim coordinates that fall partially outside
                     the alignment
    :return: a tuple with the start and end sequence coords, in that order;
             None if the interval in the alignment defined by (start, end)
             contains only gaps in the specified sequence. start < end always,
             even if the sequence is reverse complement.
    :raises AlignmentError: if the sequence number specifies a sequence not
                            in this alignment, or the coordinates fall
                            entirely outside the alignment (or partially
                            outside and trim == false), or they are not a valid
                            interval (start >= end)
    """
    start = 1 if start < 1 and trim else start
    end = self.size() + 1 if (end > self.size() + 1) and trim else end

    if (start < 1 or end > (self.size() + 1)):
      msg = "Coordinates fall partially outside alignemnt: " + str(start) +\
            ", " + str(end)
      raise InvalidAlignmentCoordinatesError(msg)
    if (end < 1 or start > self.size() + 1):
      msg = "Coordinates fall entirely outside alignment: " + str(start) +\
            ", " + str(end)
      raise InvalidAlignmentCoordinatesError(msg)
    if (end <= start):
      msg = "Invalid alignment coordinates: " + str(start) + ", " + str(end)
      raise InvalidAlignmentCoordinatesError(msg)

    seq = self[seq_name]
    pos_strand = seq.is_positive_strand()
    non_gaps = 0
    r_start = None
    r_end = None
    l_start = 0 if pos_strand else self.size() - 1
    l_end = end - 1 if pos_strand else start - 2
    l_step = 1 if pos_strand else -1
    for i in range(l_start, l_end, l_step):
      if seq[i] != GAP_CHAR:
        non_gaps += 1
        if ((pos_strand and r_start is None and (i + 1) >= start) or
           (not pos_strand and r_start is None and (i + 1) < end)):
          r_start = non_gaps + seq.start - 1
    if r_start is None:
      # we went through the whole region and didn't find a single non-gap char
      return None
    r_end = non_gaps + seq.start
    return (r_start, r_end)