Beispiel #1
0
    def _get_angle_type(self, atom_types, warn=False):
        """Get a particular angle_type between `atom_types` from this ForceField"""
        if len(atom_types) != 3:
            raise ValueError(
                f"AngleType potential can only "
                f"be extracted for three atoms. Provided {len(atom_types)}")

        forward = FF_TOKENS_SEPARATOR.join(atom_types)
        reverse = FF_TOKENS_SEPARATOR.join(reversed(atom_types))
        match = None
        if forward in self.angle_types:
            match = self.angle_types[forward]
        if reverse in self.angle_types:
            match = self.angle_types[reverse]

        msg = f"AngleType between atoms {atom_types[0]}, {atom_types[1]} " \
              f"and {atom_types[2]} is missing from the ForceField"

        if match:
            return match
        elif warn:
            warnings.warn(msg)
            return None
        else:
            raise MissingPotentialError(msg)
Beispiel #2
0
    def _get_improper_type(self, atom_types, warn=False):
        """Get a particular improper_type between `atom_types` from this ForceField."""
        if len(atom_types) != 4:
            raise ValueError(
                f"ImproperType potential can only "
                f"be extracted for four atoms. Provided {len(atom_types)}"
            )

        forward = FF_TOKENS_SEPARATOR.join(atom_types)
        reverse = FF_TOKENS_SEPARATOR.join(
            [atom_types[0], atom_types[2], atom_types[1], atom_types[3]]
        )

        if forward is self.improper_types:
            return self.improper_types[forward]
        if reverse in self.improper_types:
            return self.improper_types[reverse]

        match = None
        for i in range(1, 5):
            forward_patterns = mask_with(atom_types, i)
            reverse_patterns = mask_with(
                [atom_types[0], atom_types[2], atom_types[1], atom_types[3]], i
            )

            for forward_pattern, reverse_pattern in zip(
                forward_patterns, reverse_patterns
            ):
                forward_match_key = FF_TOKENS_SEPARATOR.join(forward_pattern)
                reverse_match_key = FF_TOKENS_SEPARATOR.join(reverse_pattern)

                if forward_match_key in self.dihedral_types:
                    match = self.dihedral_types[forward_match_key]
                    break

                if reverse_match_key in self.dihedral_types:
                    match = self.dihedral_types[reverse_match_key]
                    break

            if match:
                break

        msg = (
            f"ImproperType between atoms {atom_types[0]}, {atom_types[1]}, "
            f"{atom_types[2]} and {atom_types[3]} is missing from the ForceField."
        )
        if match:
            return match
        elif warn:
            warnings.warn(msg)
            return None
        else:
            raise MissingPotentialError(msg)
Beispiel #3
0
def parse_ff_connection_types(connectiontypes_el, child_tag='BondType'):
    """Given an XML etree Element rooted at BondTypes, parse the XML to create topology.core.AtomTypes,"""
    connectiontypes_dict = {}
    connectiontype_expression = connectiontypes_el.attrib.get('expression', None)
    param_unit_dict = _parse_param_units(connectiontypes_el)

    # Parse all the bondTypes and create a new BondType
    for connection_type in connectiontypes_el.getiterator(child_tag):
        ctor_kwargs = {
            'name': child_tag,
            'expression': '0.5 * k * (r-r_eq)**2',
            'parameters': None,
            'independent_variables': None,
            'member_types': None
        }
        if connectiontype_expression:
            ctor_kwargs['expression'] = connectiontype_expression

        for kwarg in ctor_kwargs.keys():
            ctor_kwargs[kwarg] = connection_type.attrib.get(kwarg, ctor_kwargs[kwarg])

        ctor_kwargs['member_types'] = _get_member_types(connection_type)
        if not ctor_kwargs['parameters']:
            ctor_kwargs['parameters'] = _parse_params_values(connection_type,
                                                             param_unit_dict,
                                                             child_tag,
                                                             ctor_kwargs['expression'])

        valued_param_vars = set(sympify(param) for param in ctor_kwargs['parameters'].keys())
        ctor_kwargs['independent_variables'] = sympify(connectiontype_expression).free_symbols - valued_param_vars
        this_conn_type_key = FF_TOKENS_SEPARATOR.join(ctor_kwargs['member_types'])
        this_conn_type = TAG_TO_CLASS_MAP[child_tag](**ctor_kwargs)
        connectiontypes_dict[this_conn_type_key] = this_conn_type

    return connectiontypes_dict
Beispiel #4
0
    def _get_bond_type(self, atom_types, warn=False):
        """Get a particular bond_type between `atom_types` from this ForceField"""
        if len(atom_types) != 2:
            raise ValueError(
                f"BondType potential can only "
                f"be extracted for two atoms. Provided {len(atom_types)}")

        forward = FF_TOKENS_SEPARATOR.join(atom_types)
        reverse = FF_TOKENS_SEPARATOR.join(reversed(atom_types))
        if forward in self.bond_types:
            return self.bond_types[forward]
        if reverse in self.bond_types:
            return self.bond_types[reverse]

        msg = f"BondType between atoms {atom_types[0]} and {atom_types[1]} " \
              f"is missing from the ForceField"
        if warn:
            warnings.warn(msg)
            return None
        else:
            raise MissingPotentialError(msg)
Beispiel #5
0
def parse_ff_connection_types(connectiontypes_el, child_tag="BondType"):
    """Parse an XML etree Element rooted at BondTypes to create topology.core.AtomTypes."""
    connectiontypes_dict = {}
    connectiontype_expression = connectiontypes_el.attrib.get(
        "expression", None)
    param_unit_dict = _parse_param_units(connectiontypes_el)

    # Parse all the bondTypes and create a new BondType
    for connection_type in connectiontypes_el.getiterator(child_tag):
        ctor_kwargs = {
            "name": child_tag,
            "expression": "0.5 * k * (r-r_eq)**2",
            "parameters": None,
            "independent_variables": None,
            "member_types": None,
        }
        if connectiontype_expression:
            ctor_kwargs["expression"] = connectiontype_expression

        for kwarg in ctor_kwargs.keys():
            ctor_kwargs[kwarg] = connection_type.attrib.get(
                kwarg, ctor_kwargs[kwarg])

        ctor_kwargs["member_types"] = _get_member_types(connection_type)
        if not ctor_kwargs["parameters"]:
            ctor_kwargs["parameters"] = _parse_params_values(
                connection_type,
                param_unit_dict,
                child_tag,
                ctor_kwargs["expression"],
            )

        valued_param_vars = set(
            sympify(param) for param in ctor_kwargs["parameters"].keys())
        ctor_kwargs["independent_variables"] = (
            sympify(connectiontype_expression).free_symbols -
            valued_param_vars)
        this_conn_type_key = FF_TOKENS_SEPARATOR.join(
            ctor_kwargs["member_types"])
        this_conn_type = TAG_TO_CLASS_MAP[child_tag](**ctor_kwargs)
        connectiontypes_dict[this_conn_type_key] = this_conn_type

    return connectiontypes_dict