예제 #1
0
    def to_ao(self, mo_operator):
        """ Transform an operator from this orbital basis into the AO basis

        Given the matrix elements :math:`\hat O_{ij}` of an operator over orbital basis indices
        :math:`i,j`, returns the operator's matrix elements :math:`\hat O_{\mu \nu}` over
        orbital indices :math:`\mu, \nu`:

        ..math::
           \hat O_{\mu \nu} =
           \left \langle \mu \right| \hat O \left| \nu \right \rangle =
           \sum_{i,j,\lambda,\kappa}S_{\mu \lambda} C_{i \lambda} O_{ij} C_{j \kappa} S_{\kappa \nu}

        where :math:`S_{\mu \nu} = \left \langle \mu | \nu \right \rangle` is the AO overlap matrix
        and :math:`C_{i \mu}` is the expansion coefficient for AO basis function :math:`\mu` in
        molecular orbital _i_.

        Args:
            mo_operator (u.Array): matrix elements of the operator in this orbital basis

        Returns:
            u.Array: matrix elements of the operator in the AO basis
        """
        units = u.get_units(mo_operator)
        s = self.wfn.aobasis.overlaps
        o_ao = s.dot(self.coeffs.T).dot(mo_operator).dot(self.coeffs).dot(s)
        return o_ao * units
예제 #2
0
    def _validate(self, change):
        import pint

        self._validated_value = None
        self._error_msg = False

        # Check that we can parse this
        try:
            val = u.ureg(change['new'])

        except (pint.UndefinedUnitError, pint.DimensionalityError,
                pint.compat.tokenize.TokenError):
            self._error_msg = "Failed to parse '%s'" % self.textbox.value

        except Exception as e:  # unfortunately, pint's parser sometimes raises bare exception class
            if e.__class__ != Exception:
                raise  # this isn't what we want
            self._error_msg = "Failed to parse '%s'" % self.textbox.value

        else:  # Check dimensionality
            valdim = u.get_units(val).dimensionality
            if self.dimensionality is not None and valdim != self.dimensionality:
                self._error_msg = "Requires dimensionality %s" % self.dimensionality

        if not self._error_msg:
            self.validated.value = '<span title="Valid quantity">%s</span>' % self.VALID
            self._validated_value = val
        else:
            self.validated.value = '<span title="%s">%s</span>' % (
                self._error_msg, self.INVALID)
예제 #3
0
    def to_ao(self, mo_operator):
        """ Transform an operator from this orbital basis into the AO basis

        Given the matrix elements :math:`\hat O_{ij}` of an operator over orbital basis indices
        :math:`i,j`, returns the operator's matrix elements :math:`\hat O_{\mu \nu}` over
        orbital indices :math:`\mu, \nu`:

        ..math::
           \hat O_{\mu \nu} =
           \left \langle \mu \right| \hat O \left| \nu \right \rangle =
           \sum_{i,j,\lambda,\kappa}S_{\mu \lambda} C_{i \lambda} O_{ij} C_{j \kappa} S_{\kappa \nu}

        where :math:`S_{\mu \nu} = \left \langle \mu | \nu \right \rangle` is the AO overlap matrix
        and :math:`C_{i \mu}` is the expansion coefficient for AO basis function :math:`\mu` in
        molecular orbital _i_.

        Args:
            mo_operator (u.Array): matrix elements of the operator in this orbital basis

        Returns:
            u.Array: matrix elements of the operator in the AO basis
        """
        units = u.get_units(mo_operator)
        s = self.wfn.aobasis.overlaps
        o_ao = s.dot(self.coeffs.T).dot(mo_operator).dot(self.coeffs).dot(s)
        return o_ao * units
예제 #4
0
    def from_ao(self, ao_operator):
        """ Transform an operator into this orbital basis from the ao basis

        Given the matrix elements :math:`\hat O_{\mu \nu}` of an operator over AO basis indices
        :math:`\mu,\nu`, returns the operator's matrix elements :math:`\hat O_{ij}` over
        orbital indices :math:`i,j`:

        ..math::
            \hat O_{ij} =
             \left \langle i \right| \hat O \left| j \right \rangle =
              \sum_{\mu \nu}C_{i \mu} O_{\mu \nu} C_{j \nu}


        where :math:`C_{i \mu}` is the expansion coefficient for AO basis function :math:`\mu` in
        molecular orbital _i_.

        Args:
            ao_operator (u.Array): matrix elements of the operator in the ao basis

        Returns:
            u.Array: matrix elements of the operator in this orbital basis

        Note:
            Assumes that this set of orbitals is orthogonal
        """
        # Dot doesn't place nice with units, so we need to pass them explicitly
        ao_units = u.get_units(ao_operator)
        return self.coeffs.dot(ao_operator.dot(self.coeffs.T)) * ao_units
예제 #5
0
    def from_ao(self, ao_operator):
        """ Transform an operator into this orbital basis from the ao basis

        Given the matrix elements :math:`\hat O_{\mu \nu}` of an operator over AO basis indices
        :math:`\mu,\nu`, returns the operator's matrix elements :math:`\hat O_{ij}` over
        orbital indices :math:`i,j`:

        ..math::
            \hat O_{ij} =
             \left \langle i \right| \hat O \left| j \right \rangle =
              \sum_{\mu \nu}C_{i \mu} O_{\mu \nu} C_{j \nu}


        where :math:`C_{i \mu}` is the expansion coefficient for AO basis function :math:`\mu` in
        molecular orbital _i_.

        Args:
            ao_operator (u.Array): matrix elements of the operator in the ao basis

        Returns:
            u.Array: matrix elements of the operator in this orbital basis

        Note:
            Assumes that this set of orbitals is orthogonal
        """
        # Dot doesn't place nice with units, so we need to pass them explicitly
        ao_units = u.get_units(ao_operator)
        return self.coeffs.dot(ao_operator.dot(self.coeffs.T)) * ao_units
    def _validate(self, change):
        import pint

        self._validated_value = None
        self._error_msg = False

        # Check that we can parse this
        try:
            val = u.ureg(change['new'])

        except (pint.UndefinedUnitError,
                pint.DimensionalityError,
                pint.compat.tokenize.TokenError):
            self._error_msg = "Failed to parse '%s'" % self.textbox.value

        except Exception as e:  # unfortunately, pint's parser sometimes raises bare exception class
            if e.__class__ != Exception:
                raise  # this isn't what we want
            self._error_msg = "Failed to parse '%s'" % self.textbox.value

        else:  # Check dimensionality
            valdim = u.get_units(val).dimensionality
            if self.dimensionality is not None and valdim != self.dimensionality:
                self._error_msg = "Requires dimensionality %s" % self.dimensionality

        if not self._error_msg:
            self.validated.value = '<span title="Valid quantity">%s</span>' % self.VALID
            self._validated_value = val
        else:
            self.validated.value = '<span title="%s">%s</span>' % (self._error_msg, self.INVALID)
    def draw_atom_vectors(self,
                          vecs,
                          rescale_to=1.75,
                          scale_factor=None,
                          opacity=0.85,
                          radius=0.11,
                          **kwargs):
        """ Draw a 3D vector on each atom

        Args:
            vecs (Matrix[shape=(*,3)]): list of vectors for each atom
            rescale_to (Scalar[length]): vectors so the largest is this long
            scale_factor (Scalar[length/units]): factor for conversion between input units and
               length
            kwargs (dict): keyword arguments for self.draw_arrow
        """
        kwargs['radius'] = radius
        kwargs['opacity'] = opacity
        if vecs.shape == (self.mol.ndims, ):
            vecs = vecs.reshape(self.mol.num_atoms, 3)
        assert vecs.shape == (self.mol.num_atoms, 3), '`vecs` must be a num_atoms X 3 matrix or' \
                                                      ' 3*num_atoms vector'
        assert not np.allclose(vecs, 0.0), "Input vectors are 0."

        # strip units and scale the vectors appropriately
        if scale_factor is not None:  # scale all arrows by this quantity
            if (u.get_units(vecs) /
                    scale_factor).dimensionless:  # allow implicit scale factor
                scale_factor = scale_factor / self.DISTANCE_UNITS

            vecarray = vecs / scale_factor
            try:
                arrowvecs = vecarray.value_in(self.DISTANCE_UNITS)
            except AttributeError:
                arrowvecs = vecarray

        else:  # rescale the maximum length arrow length to rescale_to
            try:
                vecarray = vecs.magnitude
                unit = vecs.getunits()
            except AttributeError:
                vecarray = vecs
                unit = ''
            lengths = np.sqrt((vecarray * vecarray).sum(axis=1))
            scale = (lengths.max() / rescale_to
                     )  # units of [vec units] / angstrom
            if hasattr(scale, 'defunits'):
                scale = scale.defunits()
            arrowvecs = vecarray / scale
            print('Arrow scale: {q:.3f} {unit} per {native}'.format(
                q=scale, unit=unit, native=self.DISTANCE_UNITS))
        shapes = []
        for atom, vecarray in zip(self.mol.atoms, arrowvecs):
            if mathutils.norm(vecarray) < 0.2:
                continue
            shapes.append(
                self.draw_arrow(atom.position, vector=vecarray, **kwargs))
        return shapes
    def draw_atom_vectors(self,
                          vecs,
                          rescale_to=1.75,
                          scale_factor=None,
                          opacity=0.85,
                          radius=0.11,
                          **kwargs):
        """
        For displaying atom-centered vector data (e.g., momenta, forces)
        :param rescale_to: rescale to this length (in angstroms) (not used if scale_factor is passed)
        :param scale_factor: Scaling factor for arrows: dimensions of [vecs dimensions] / [length]
        :param kwargs: keyword arguments for self.draw_arrow
        """
        kwargs['radius'] = radius
        kwargs['opacity'] = opacity
        if vecs.shape == (self.mol.ndims, ):
            vecs = vecs.reshape(self.mol.num_atoms, 3)
        assert vecs.shape == (self.mol.num_atoms, 3), '`vecs` must be a num_atoms X 3 matrix or' \
                                                      ' 3*num_atoms vector'
        assert not np.allclose(vecs, 0.0), "Input vectors are 0."

        # strip units and scale the vectors appropriately
        if scale_factor is not None:  # scale all arrows by this quantity
            if (u.get_units(vecs) /
                    scale_factor).dimensionless:  # allow implicit scale factor
                scale_factor = scale_factor / self.DISTANCE_UNITS

            vecarray = vecs / scale_factor
            try:
                arrowvecs = vecarray.value_in(self.DISTANCE_UNITS)
            except AttributeError:
                arrowvecs = vecarray

        else:  # rescale the maximum length arrow length to rescale_to
            try:
                vecarray = vecs.magnitude
                unit = vecs.getunits()
            except AttributeError:
                vecarray = vecs
                unit = ''
            lengths = np.sqrt((vecarray * vecarray).sum(axis=1))
            scale = (lengths.max() / rescale_to
                     )  # units of [vec units] / angstrom
            if hasattr(scale, 'defunits'): scale = scale.defunits()
            arrowvecs = vecarray / scale
            print 'Arrow scale: {q:.3f} {unit} per {native}'.format(
                q=scale, unit=unit, native=self.DISTANCE_UNITS)
        shapes = []
        for atom, vecarray in zip(self.mol.atoms, arrowvecs):
            if vecarray.norm() < 0.2: continue
            shapes.append(
                self.draw_arrow(atom.position, vector=vecarray, **kwargs))
        return shapes
    def draw_atom_vectors(self, vecs, rescale_to=1.75,
                          scale_factor=None, opacity=0.85,
                          radius=0.11, **kwargs):
        """ Draw a 3D vector on each atom

        Args:
            vecs (Matrix[shape=(*,3)]): list of vectors for each atom
            rescale_to (Scalar[length]): vectors so the largest is this long
            scale_factor (Scalar[length/units]): factor for conversion between input units and
               length
            kwargs (dict): keyword arguments for self.draw_arrow
        """
        kwargs['radius'] = radius
        kwargs['opacity'] = opacity
        if vecs.shape == (self.mol.ndims,):
            vecs = vecs.reshape(self.mol.num_atoms, 3)
        assert vecs.shape == (self.mol.num_atoms, 3), '`vecs` must be a num_atoms X 3 matrix or' \
                                                      ' 3*num_atoms vector'
        assert not np.allclose(vecs, 0.0), "Input vectors are 0."

        # strip units and scale the vectors appropriately
        if scale_factor is not None:  # scale all arrows by this quantity
            if (u.get_units(vecs)/scale_factor).dimensionless:  # allow implicit scale factor
                scale_factor = scale_factor/self.DISTANCE_UNITS

            vecarray = vecs/scale_factor
            try:
                arrowvecs = vecarray.value_in(self.DISTANCE_UNITS)
            except AttributeError:
                arrowvecs = vecarray

        else:  # rescale the maximum length arrow length to rescale_to
            try:
                vecarray = vecs.magnitude
                unit = vecs.getunits()
            except AttributeError:
                vecarray = vecs
                unit = ''
            lengths = np.sqrt((vecarray*vecarray).sum(axis=1))
            scale = (lengths.max()/rescale_to)  # units of [vec units] / angstrom
            if hasattr(scale, 'defunits'):
                scale = scale.defunits()
            arrowvecs = vecarray/scale
            print('Arrow scale: {q:.3f} {unit} per {native}'.format(q=scale, unit=unit,
                                                                    native=self.DISTANCE_UNITS))
        shapes = []
        for atom, vecarray in zip(self.mol.atoms, arrowvecs):
            if mathutils.norm(vecarray) < 0.2:
                continue
            shapes.append(self.draw_arrow(atom.position, vector=vecarray, **kwargs))
        return shapes
예제 #10
0
    def __init__(self, value=None, units=None, **kwargs):
        super(UnitText, self).__init__(layout=ipy.Layout(display='flex',
                                                         flex_flow='row wrap'),
                                       **kwargs)
        self.textbox = ipy.Text()
        self.textbox.observe(self._validate, 'value')
        self._error_msg = None

        if units is not None:
            self.dimensionality = u.get_units(units).dimensionality
        else:
            self.dimensionality = None

        self._validated_value = None
        self.validated = ipy.HTML(self.INVALID)
        self.children = [self.textbox, self.validated]
        self._is_valid = False
        if value is not None: self.value = value
예제 #11
0
    def __init__(self, value=None, units=None, **kwargs):
        super(UnitText, self).__init__(layout=ipy.Layout(display='flex', flex_flow='row wrap'),
                                       **kwargs)
        self.textbox = ipy.Text()
        self.textbox.observe(self._validate, 'value')
        self._error_msg = None

        if units is not None:
            self.dimensionality = u.get_units(units).dimensionality
        else:
            self.dimensionality = None

        self._validated_value = None
        self.validated = ipy.HTML(self.INVALID)
        self.children = [self.textbox, self.validated]
        self._is_valid = False
        if value is not None:
            self.value = value
예제 #12
0
    def draw_atom_vectors(self, vecs, rescale_to=1.75,
                          scale_factor=None, opacity=0.85,
                          radius=0.11, **kwargs):
        """
        For displaying atom-centered vector data (e.g., momenta, forces)
        :param rescale_to: rescale to this length (in angstroms) (not used if scale_factor is passed)
        :param scale_factor: Scaling factor for arrows: dimensions of [vecs dimensions] / [length]
        :param kwargs: keyword arguments for self.draw_arrow
        """
        kwargs['radius'] = radius
        kwargs['opacity'] = opacity
        if vecs.shape == (self.mol.ndims,):
            vecs = vecs.reshape(self.mol.num_atoms, 3)
        assert vecs.shape == (self.mol.num_atoms, 3), '`vecs` must be a num_atoms X 3 matrix or' \
                                                      ' 3*num_atoms vector'
        assert not np.allclose(vecs, 0.0), "Input vectors are 0."

        # strip units and scale the vectors appropriately
        if scale_factor is not None:  # scale all arrows by this quantity
            if (u.get_units(vecs)/scale_factor).dimensionless:  # allow implicit scale factor
                scale_factor = scale_factor / self.DISTANCE_UNITS

            vecarray = vecs / scale_factor
            try: arrowvecs = vecarray.value_in(self.DISTANCE_UNITS)
            except AttributeError: arrowvecs = vecarray

        else:  # rescale the maximum length arrow length to rescale_to
            try:
                vecarray = vecs.magnitude
                unit = vecs.getunits()
            except AttributeError:
                vecarray = vecs
                unit = ''
            lengths = np.sqrt((vecarray * vecarray).sum(axis=1))
            scale = (lengths.max() / rescale_to)  # units of [vec units] / angstrom
            if hasattr(scale,'defunits'): scale = scale.defunits()
            arrowvecs = vecarray / scale
            print 'Arrow scale: {q:.3f} {unit} per {native}'.format(q=scale, unit=unit,
                                                                    native=self.DISTANCE_UNITS)
        shapes = []
        for atom, vecarray in zip(self.mol.atoms, arrowvecs):
            if vecarray.norm() < 0.2: continue
            shapes.append(self.draw_arrow(atom.position, vector=vecarray, **kwargs))
        return shapes
예제 #13
0
    def _validate(self, change):
        self._validated_value = None
        self._error_msg = False

        # Check that we can parse this
        try:
            val = u.ureg(change['new'])
        except:  # parsing failed, pint just raises generic "Exception"
            self._error_msg = "Failed to parse '%s'" % self.textbox.value
        else:  # Check dimensionality
            valdim = u.get_units(val).dimensionality
            if self.dimensionality is not None and valdim != self.dimensionality:
                self._error_msg = "Requires dimensionality %s" % self.dimensionality

        if not self._error_msg:
            self.validated.value = '<span title="Valid quantity">%s</span>' % self.VALID
            self._validated_value = val
        else:
            self.validated.value = '<span title="%s">%s</span>' % (
                self._error_msg, self.INVALID)
def test_getunits_doctests():
    assert units.get_units(1.0 * units.angstrom) == units.MdtUnit('angstrom')
    assert units.get_units(np.array([1.0, 2,
                                     3.0])) == units.MdtUnit('dimensionless')
    assert units.get_units([[1.0 * units.dalton, 3.0 * units.eV], ['a'],
                            'gorilla']) == units.MdtUnit('amu')