<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def align(self, other, indices=None, ignore_hydrogens=False):
 """Align two Cartesians. Minimize the RMSD (root mean squared deviation) between ``self`` and ``other``. Returns a tuple of copies of ``self`` and ``other`` where both are centered around their centroid and ``other`` is rotated unto ``self``. The rotation minimises the distances between the atom pairs of same label. Uses the Kabsch algorithm implemented within :func:`~.xyz_functions.get_kabsch_rotation` .. note:: If ``indices is None``, then ``len(self) == len(other)`` must be true and the elements in each index have to be the same. Args: other (Cartesian):
 indices (sequence):
 It is possible to specify a subset of indices that is used for the determination of the best rotation matrix:: If ``indices`` is given in this form, the rotation matrix minimises the distance between ``i1`` and ``j1``, ``i2`` and ``j2`` and so on. ignore_hydrogens (bool):
 Returns: tuple: """

        m1 = (self - self.get_centroid()).sort_index()
        m2 = (other - other.get_centroid()).sort_index()
        if indices is not None and ignore_hydrogens:
            message = 'Indices != None and ignore_hydrogens == True is invalid'
            raise IllegalArgumentCombination(message)
        elif ignore_hydrogens:
            m1 = m1[m1['atom'] != 'H']
            m2 = m2[m2['atom'] != 'H']
        elif indices is not None:
            pos1 = m1.loc[indices[0], ['x', 'y', 'z']].values
            pos2 = m2.loc[indices[1], ['x', 'y', 'z']].values
        else:
            pos1 = m1.loc[:, ['x', 'y', 'z']].values
            pos2 = m2.loc[m1.index, ['x', 'y', 'z']].values
        m2 = dot(xyz_functions.get_kabsch_rotation(pos1, pos2), m2)
        return m1, m2