Esempio n. 1
0
    def from_xml(cls, xmls_or_etrees):
        """Create a gmso.Forcefield object from XML File(s)

        This class method creates a ForceFiled object from the reference
        XML file. This method takes in a single or collection of XML files
        with information about gmso.AtomTypes, gmso.BondTypes, gmso.AngleTypes
        and gmso.DihedralTypes to create the ForceField object.

        Parameters
        ----------
        xmls_or_etrees : Union[str, Iterable[str], etree._ElementTree, Iterable[etree._ElementTree]]
          The forcefield XML locations or XML Element Trees

        Returns
        --------
        forcefield : gmso.ForceField
            A gmso.Forcefield object with a collection of Potential objects
            created using the information in the XML file
        """
        if not isinstance(xmls_or_etrees, typing.Iterable) or isinstance(xmls_or_etrees, str):
            xmls_or_etrees = [xmls_or_etrees]

        should_parse_xml = False
        if not (all(map(lambda x: isinstance(x, str), xmls_or_etrees))
                or all(map(lambda x: isinstance(x, etree._ElementTree), xmls_or_etrees))):
            raise TypeError('Please provide an iterable of strings '
                            'as locations of the XML files '
                            'or equivalent element Trees')

        if all(map(lambda x: isinstance(x, str), xmls_or_etrees)):
            should_parse_xml = True

        versions = []
        names = []
        ff_atomtypes_list = []
        ff_bondtypes_list = []
        ff_angletypes_list = []
        ff_dihedraltypes_list = []

        atom_types_dict = ChainMap()
        bond_types_dict = {}
        angle_types_dict = {}
        dihedral_types_dict = {}
        improper_types_dict = {}
        potential_groups = {}

        for loc_or_etree in set(xmls_or_etrees):
            validate(loc_or_etree)
            ff_tree = loc_or_etree

            if should_parse_xml:
                ff_tree = etree.parse(loc_or_etree)

            ff_el = ff_tree.getroot()
            versions.append(ff_el.attrib['version'])
            names.append(ff_el.attrib['name'])
            ff_meta_tree = ff_tree.find('FFMetaData')

            if ff_meta_tree is not None:
                ff_meta_map = parse_ff_metadata(ff_meta_tree)

            ff_atomtypes_list.extend(ff_tree.findall('AtomTypes'))
            ff_bondtypes_list.extend(ff_tree.findall('BondTypes'))
            ff_angletypes_list.extend(ff_tree.findall('AngleTypes'))
            ff_dihedraltypes_list.extend(ff_tree.findall('DihedralTypes'))

        # Consolidate AtomTypes
        for atom_types in ff_atomtypes_list:
            this_atom_types_group = parse_ff_atomtypes(atom_types, ff_meta_map)
            this_atom_group_name = atom_types.attrib.get('name', None)
            if this_atom_group_name:
                potential_groups[this_atom_group_name] = this_atom_types_group
            atom_types_dict.update(this_atom_types_group)

        # Consolidate BondTypes
        for bond_types in ff_bondtypes_list:
            this_bond_types_group = parse_ff_connection_types(
                bond_types,
                atom_types_dict,
                child_tag='BondType'
            )
            this_bond_types_group_name = bond_types.attrib.get('name', None)

            if this_bond_types_group_name:
                potential_groups[this_bond_types_group_name] = this_bond_types_group

            bond_types_dict.update(this_bond_types_group)

        # Consolidate AngleTypes
        for angle_types in ff_angletypes_list:
            this_angle_types_group = parse_ff_connection_types(
                angle_types,
                atom_types_dict,
                child_tag='AngleType'
            )
            this_angle_types_group_name = angle_types.attrib.get('name', None)

            if this_angle_types_group_name:
                potential_groups[this_angle_types_group_name] = this_angle_types_group

            angle_types_dict.update(this_angle_types_group)

        # Consolidate DihedralTypes
        for dihedral_types in ff_dihedraltypes_list:
            this_dihedral_types_group = parse_ff_connection_types(
                dihedral_types,
                atom_types_dict,
                child_tag='DihedralType'
            )
            this_improper_types_group = parse_ff_connection_types(
                dihedral_types,
                atom_types_dict,
                child_tag='ImproperType'
            )
            this_group_name = dihedral_types.attrib.get('name', None)

            dihedral_types_dict.update(this_dihedral_types_group)
            improper_types_dict.update(this_improper_types_group)

            if this_group_name:
                this_dihedral_types_group.update(this_improper_types_group)
                potential_groups[this_group_name] = this_dihedral_types_group

        ff = cls()
        ff.name = names[0]
        ff.version = versions[0]
        ff.scaling_factors = ff_meta_map['scaling_factors']
        ff.units = ff_meta_map['Units']
        ff.atom_types = atom_types_dict.maps[0]
        ff.bond_types = bond_types_dict
        ff.angle_types = angle_types_dict
        ff.dihedral_types = dihedral_types_dict
        ff.improper_types = improper_types_dict
        ff.potential_groups = potential_groups
        return ff
Esempio n. 2
0
    def from_xml(cls, xml_locs):
        """Create a gmso.Forcefield object from XML File(s)

        This class method creates a ForceFiled object from the reference
        XML file. This method takes in a single or collection of XML files
        with information about gmso.AtomTypes, gmso.BondTypes, gmso.AngleTypes
        and gmso.DihedralTypes to create the ForceField object.

        Parameters
        ----------
        xml_locs : str or iterable of str
            string or iterable of strings containing the forcefield XML locations

        Returns
        --------
        forcefield : gmso.ForceField
            A gmso.Forcefield object with a collection of Potential objects
            created using the information in the XML file
        """

        if not hasattr(xml_locs, '__iter__'):
            xml_locs = [].append(xml_locs)
        if isinstance(xml_locs, str):
            xml_locs = [xml_locs]

        versions = []
        names = []
        ff_atomtypes_list = []
        ff_bondtypes_list = []
        ff_angletypes_list = []
        ff_dihedraltypes_list = []

        atom_types_dict = ChainMap()
        bond_types_dict = {}
        angle_types_dict = {}
        dihedral_types_dict = {}
        improper_types_dict = {}
        potential_groups = {}

        for loc in xml_locs:
            validate(loc)
            ff_tree = etree.parse(loc)
            ff_el = ff_tree.getroot()
            versions.append(ff_el.attrib['version'])
            names.append(ff_el.attrib['name'])
            ff_meta_tree = ff_tree.find('FFMetaData')

            if ff_meta_tree is not None:
                ff_meta_map = parse_ff_metadata(ff_meta_tree)

            ff_atomtypes_list.extend(ff_tree.findall('AtomTypes'))
            ff_bondtypes_list.extend(ff_tree.findall('BondTypes'))
            ff_angletypes_list.extend(ff_tree.findall('AngleTypes'))
            ff_dihedraltypes_list.extend(ff_tree.findall('DihedralTypes'))

        # Consolidate AtomTypes
        for atom_types in ff_atomtypes_list:
            this_atom_types_group = parse_ff_atomtypes(atom_types, ff_meta_map)
            this_atom_group_name = atom_types.attrib.get('name', None)
            if this_atom_group_name:
                potential_groups[this_atom_group_name] = this_atom_types_group
            atom_types_dict.update(this_atom_types_group)

        # Consolidate BondTypes
        for bond_types in ff_bondtypes_list:
            this_bond_types_group = parse_ff_connection_types(
                bond_types, atom_types_dict, child_tag='BondType')
            this_bond_types_group_name = bond_types.attrib.get('name', None)

            if this_bond_types_group_name:
                potential_groups[
                    this_bond_types_group_name] = this_bond_types_group

            bond_types_dict.update(this_bond_types_group)

        # Consolidate AngleTypes
        for angle_types in ff_angletypes_list:
            this_angle_types_group = parse_ff_connection_types(
                angle_types, atom_types_dict, child_tag='AngleType')
            this_angle_types_group_name = angle_types.attrib.get('name', None)

            if this_angle_types_group_name:
                potential_groups[
                    this_angle_types_group_name] = this_angle_types_group

            angle_types_dict.update(this_angle_types_group)

        # Consolidate DihedralTypes
        for dihedral_types in ff_dihedraltypes_list:
            this_dihedral_types_group = parse_ff_connection_types(
                dihedral_types, atom_types_dict, child_tag='DihedralType')
            this_improper_types_group = parse_ff_connection_types(
                dihedral_types, atom_types_dict, child_tag='ImproperType')
            this_group_name = dihedral_types.attrib.get('name', None)

            dihedral_types_dict.update(this_dihedral_types_group)
            improper_types_dict.update(this_improper_types_group)

            if this_group_name:
                this_dihedral_types_group.update(this_improper_types_group)
                potential_groups[this_group_name] = this_dihedral_types_group

        ff = cls()
        ff.name = names[0]
        ff.version = versions[0]
        ff.scaling_factors = ff_meta_map['scaling_factors']
        ff.units = ff_meta_map['Units']
        ff.atom_types = atom_types_dict.maps[0]
        ff.bond_types = bond_types_dict
        ff.angle_types = angle_types_dict
        ff.dihedral_types = dihedral_types_dict
        ff.improper_types = improper_types_dict
        ff.potential_groups = potential_groups
        return ff
Esempio n. 3
0
    def from_xml(cls, xmls_or_etrees, strict=True, greedy=True):
        """Create a gmso.Forcefield object from XML File(s).

        This class method creates a ForceField object from the reference
        XML file. This method takes in a single or collection of XML files
        with information about gmso.AtomTypes, gmso.BondTypes, gmso.AngleTypes
        and gmso.DihedralTypes to create the ForceField object.

        Parameters
        ----------
        xmls_or_etrees : Union[str, Iterable[str], etree._ElementTree, Iterable[etree._ElementTree]]
            The forcefield XML locations or XML Element Trees
        strict: bool, default=True
            If true, perform a strict validation of the forcefield XML file
        greedy: bool, default=True
            If True, when using strict mode, fail on the first error/mismatch

        Returns
        -------
        forcefield : gmso.ForceField
            A gmso.Forcefield object with a collection of Potential objects
            created using the information in the XML file
        """
        if not isinstance(xmls_or_etrees, Iterable) or isinstance(
            xmls_or_etrees, str
        ):
            xmls_or_etrees = [xmls_or_etrees]

        should_parse_xml = False
        if not (
            all(map(lambda x: isinstance(x, str), xmls_or_etrees))
            or all(
                map(lambda x: isinstance(x, etree._ElementTree), xmls_or_etrees)
            )
        ):
            raise TypeError(
                "Please provide an iterable of strings "
                "as locations of the XML files "
                "or equivalent element Trees"
            )

        if all(map(lambda x: isinstance(x, str), xmls_or_etrees)):
            should_parse_xml = True

        versions = []
        names = []
        ff_atomtypes_list = []
        ff_bondtypes_list = []
        ff_angletypes_list = []
        ff_dihedraltypes_list = []

        atom_types_dict = ChainMap()
        bond_types_dict = {}
        angle_types_dict = {}
        dihedral_types_dict = {}
        improper_types_dict = {}
        potential_groups = {}

        for loc_or_etree in set(xmls_or_etrees):
            validate(loc_or_etree, strict=strict, greedy=greedy)
            ff_tree = loc_or_etree

            if should_parse_xml:
                ff_tree = etree.parse(loc_or_etree)

            ff_el = ff_tree.getroot()
            versions.append(ff_el.attrib["version"])
            names.append(ff_el.attrib["name"])
            ff_meta_tree = ff_tree.find("FFMetaData")

            if ff_meta_tree is not None:
                ff_meta_map = parse_ff_metadata(ff_meta_tree)

            ff_atomtypes_list.extend(ff_tree.findall("AtomTypes"))
            ff_bondtypes_list.extend(ff_tree.findall("BondTypes"))
            ff_angletypes_list.extend(ff_tree.findall("AngleTypes"))
            ff_dihedraltypes_list.extend(ff_tree.findall("DihedralTypes"))

        # Consolidate AtomTypes
        for atom_types in ff_atomtypes_list:
            this_atom_types_group = parse_ff_atomtypes(atom_types, ff_meta_map)
            this_atom_group_name = atom_types.attrib.get("name", None)
            if this_atom_group_name:
                potential_groups[this_atom_group_name] = this_atom_types_group
            atom_types_dict.update(this_atom_types_group)

        # Consolidate BondTypes
        for bond_types in ff_bondtypes_list:
            this_bond_types_group = parse_ff_connection_types(
                bond_types, child_tag="BondType"
            )
            this_bond_types_group_name = bond_types.attrib.get("name", None)

            if this_bond_types_group_name:
                potential_groups[
                    this_bond_types_group_name
                ] = this_bond_types_group

            bond_types_dict.update(this_bond_types_group)

        # Consolidate AngleTypes
        for angle_types in ff_angletypes_list:
            this_angle_types_group = parse_ff_connection_types(
                angle_types, child_tag="AngleType"
            )
            this_angle_types_group_name = angle_types.attrib.get("name", None)

            if this_angle_types_group_name:
                potential_groups[
                    this_angle_types_group_name
                ] = this_angle_types_group

            angle_types_dict.update(this_angle_types_group)

        # Consolidate DihedralTypes
        for dihedral_types in ff_dihedraltypes_list:
            this_dihedral_types_group = parse_ff_connection_types(
                dihedral_types, child_tag="DihedralType"
            )
            this_improper_types_group = parse_ff_connection_types(
                dihedral_types, child_tag="ImproperType"
            )
            this_group_name = dihedral_types.attrib.get("name", None)

            dihedral_types_dict.update(this_dihedral_types_group)
            improper_types_dict.update(this_improper_types_group)

            if this_group_name:
                this_dihedral_types_group.update(this_improper_types_group)
                potential_groups[this_group_name] = this_dihedral_types_group

        ff = cls()
        ff.name = names[0]
        ff.version = versions[0]
        ff.scaling_factors = ff_meta_map["scaling_factors"]
        ff.units = ff_meta_map["Units"]
        ff.atom_types = atom_types_dict.maps[0]
        ff.bond_types = bond_types_dict
        ff.angle_types = angle_types_dict
        ff.dihedral_types = dihedral_types_dict
        ff.improper_types = improper_types_dict
        ff.potential_groups = potential_groups
        return ff