graphinvent/GraphGenerator.py
def graph_to_graph(self, idx : int) -> GenerationGraph:
        """
        Converts a molecular graph representation from the individual node and
        edge feature tensors into `GenerationGraph` objects.

        Args:
        ----
            idx (int) : Index for the molecular graph to convert.

        Returns:
        -------
            graph (GenerationGraph) : Generated graph.
        """
        def _features_to_atom(node_idx : int, node_features : torch.Tensor) -> \
            rdkit.Chem.Atom:
            """
            Converts the node feature vector corresponding to the specified node
            into an atom object.

            Args:
            ----
                node_idx (int)               : Index denoting the specific node
                                               on the graph to convert.
                node_features (torch.Tensor) : Node features tensor for one graph.

            Returns:
            -------
                new_atom (rdkit.Atom) : Atom object corresponding to specified
                                        node features.
            """
            # get all the nonzero indices in the specified node feature vector
            nonzero_idc = torch.nonzero(node_features[node_idx])

            # determine atom symbol
            atom_idx = nonzero_idc[0]
            atom_type = constants.atom_types[atom_idx]

            # initialize atom
            new_atom = rdkit.Chem.Atom(atom_type)

            # determine formal charge
            fc_idx = nonzero_idc[1] - constants.n_atom_types
            formal_charge = constants.formal_charge[fc_idx]

            new_atom.SetFormalCharge(formal_charge)  # set property

            # determine number of implicit Hs (if used)
            if not constants.use_explicit_H and not constants.ignore_H:
                total_num_h_idx = (nonzero_idc[2] -
                                   constants.n_atom_types -
                                   constants.n_formal_charge)
                total_num_h = constants.imp_H[total_num_h_idx]

                new_atom.SetUnsignedProp("_TotalNumHs", total_num_h)  # set property
            elif constants.ignore_H:
                # Hs will be set with structure is "sanitized" (corrected) later
                # in `mol_to_graph()`
                pass

            # determine chirality (if used)
            if constants.use_chirality:
                cip_code_idx = (
                    nonzero_idc[-1]
                    - constants.n_atom_types
                    - constants.n_formal_charge
                    - (not constants.use_explicit_H and not
                       constants.ignore_H) * constants.n_imp_H
                )
                cip_code = constants.chirality[cip_code_idx]
                new_atom.SetProp("_CIPCode", cip_code)  # set property

            return new_atom

        def _graph_to_mol(node_features : torch.Tensor,
                         edge_features : torch.Tensor,
                         n_nodes : int) -> rdkit.Chem.Mol:
            """
            Converts input graph represenetation (node and edge features) into
            an `rdkit.Mol` object.

            Args:
            ----
                node_features (torch.Tensor) : Node features tensor.
                edge_features (torch.Tensor) : Edge features tensor.
                n_nodes (int)                : Number of nodes in the graph representation.

            Returns:
            -------
                molecule (rdkit.Chem.Mol) : Molecule object.
            """

            # create empty editable `rdkit.Chem.Mol` object
            molecule = rdkit.Chem.RWMol()
            node_to_idx = {}

            # add atoms to editable mol object
            for node_idx in range(n_nodes):
                atom_to_add = _features_to_atom(node_idx, node_features)
                molecule_idx = molecule.AddAtom(atom_to_add)
                node_to_idx[node_idx] = molecule_idx

            # add bonds to atoms in editable mol object; to not add the same bond twice
            # (which leads to an error), mask half of the edge features beyond diagonal
            n_max_nodes = constants.dim_nodes[0]
            edge_mask = torch.triu(
                torch.ones((n_max_nodes, n_max_nodes), device=constants.device),
                diagonal=1
            )
            edge_mask = edge_mask.view(n_max_nodes, n_max_nodes, 1)
            edges_idc = torch.nonzero(edge_features * edge_mask)

            for node_idx1, node_idx2, bond_idx in edges_idc:
                molecule.AddBond(
                    node_to_idx[node_idx1.item()],
                    node_to_idx[node_idx2.item()],
                    constants.int_to_bondtype[bond_idx.item()],
                )

            try:  # convert editable mol object to non-editable mol object
                molecule.GetMol()
            except AttributeError:  # will throw an error if molecule is `None`
                pass

            if constants.ignore_H and molecule:
                try:  # correct for ignored Hs
                    rdkit.Chem.SanitizeMol(molecule)
                except ValueError:  # throws exception if molecule is too ugly to correct
                    pass

            return molecule

        try:
            # first get the `rdkit.Mol` object corresponding to the selected graph
            mol = _graph_to_mol(self.generated_nodes[idx],
                                self.generated_edges[idx],
                                self.generated_n_nodes[idx])
        except (IndexError, AttributeError):  # raised when graph is empty
            mol = None

        # use the `rdkit.Mol` object, and node and edge features tensors, to get
        # the `GenerationGraph` object
        graph = GenerationGraph(constants=constants,
                                molecule=mol,
                                node_features=self.generated_nodes[idx],
                                edge_features=self.generated_edges[idx])
        return graph

        Converts a molecular graph representation from the individual node and
        edge feature tensors into `GenerationGraph` objects.

        Args:
        ----
            idx (int) : Index for the molecular graph to convert.

        Returns:
        -------
            graph (GenerationGraph) : Generated graph.
        
Converts a molecular graph representation from the individual node and
edge feature tensors into `GenerationGraph` objects.
Converts a molecular graph representation from the individual node and edge feature tensors into ` GenerationGraph ` objects .
def graph_to_graph(self, idx : int) -> GenerationGraph:
        def _features_to_atom(node_idx : int, node_features : torch.Tensor) -> \
            rdkit.Chem.Atom:
            nonzero_idc = torch.nonzero(node_features[node_idx])
            atom_idx = nonzero_idc[0]
            atom_type = constants.atom_types[atom_idx]
            new_atom = rdkit.Chem.Atom(atom_type)
            fc_idx = nonzero_idc[1] - constants.n_atom_types
            formal_charge = constants.formal_charge[fc_idx]
            new_atom.SetFormalCharge(formal_charge)  
            if not constants.use_explicit_H and not constants.ignore_H:
                total_num_h_idx = (nonzero_idc[2] -
                                   constants.n_atom_types -
                                   constants.n_formal_charge)
                total_num_h = constants.imp_H[total_num_h_idx]
                new_atom.SetUnsignedProp("_TotalNumHs", total_num_h)  
            elif constants.ignore_H:
                pass
            if constants.use_chirality:
                cip_code_idx = (
                    nonzero_idc[-1]
                    - constants.n_atom_types
                    - constants.n_formal_charge
                    - (not constants.use_explicit_H and not
                       constants.ignore_H) * constants.n_imp_H
                )
                cip_code = constants.chirality[cip_code_idx]
                new_atom.SetProp("_CIPCode", cip_code)  
            return new_atom
        def _graph_to_mol(node_features : torch.Tensor,
                         edge_features : torch.Tensor,
                         n_nodes : int) -> rdkit.Chem.Mol:
            molecule = rdkit.Chem.RWMol()
            node_to_idx = {}
            for node_idx in range(n_nodes):
                atom_to_add = _features_to_atom(node_idx, node_features)
                molecule_idx = molecule.AddAtom(atom_to_add)
                node_to_idx[node_idx] = molecule_idx
            n_max_nodes = constants.dim_nodes[0]
            edge_mask = torch.triu(
                torch.ones((n_max_nodes, n_max_nodes), device=constants.device),
                diagonal=1
            )
            edge_mask = edge_mask.view(n_max_nodes, n_max_nodes, 1)
            edges_idc = torch.nonzero(edge_features * edge_mask)
            for node_idx1, node_idx2, bond_idx in edges_idc:
                molecule.AddBond(
                    node_to_idx[node_idx1.item()],
                    node_to_idx[node_idx2.item()],
                    constants.int_to_bondtype[bond_idx.item()],
                )
            try:  
                molecule.GetMol()
            except AttributeError:  
                pass
            if constants.ignore_H and molecule:
                try:  
                    rdkit.Chem.SanitizeMol(molecule)
                except ValueError:  
                    pass
            return molecule
        try:
            mol = _graph_to_mol(self.generated_nodes[idx],
                                self.generated_edges[idx],
                                self.generated_n_nodes[idx])
        except (IndexError, AttributeError):  
            mol = None
        graph = GenerationGraph(constants=constants,
                                molecule=mol,
                                node_features=self.generated_nodes[idx],
                                edge_features=self.generated_edges[idx])
        return graph
def graph_to_graph ( self , idx : int ) -> GenerationGraph : def _features_to_atom ( node_idx : int , node_features : torch . Tensor ) -> rdkit . Chem . Atom : """
            Converts the node feature vector corresponding to the specified node
            into an atom object.

            Args:
            ----
                node_idx (int)               : Index denoting the specific node
                                               on the graph to convert.
                node_features (torch.Tensor) : Node features tensor for one graph.

            Returns:
            -------
                new_atom (rdkit.Atom) : Atom object corresponding to specified
                                        node features.
            """ nonzero_idc = torch . nonzero ( node_features [ node_idx ] ) atom_idx = nonzero_idc [ 0 ] atom_type = constants . atom_types [ atom_idx ] new_atom = rdkit . Chem . Atom ( atom_type ) fc_idx = nonzero_idc [ 1 ] - constants . n_atom_types formal_charge = constants . formal_charge [ fc_idx ] new_atom . SetFormalCharge ( formal_charge ) if not constants . use_explicit_H and not constants . ignore_H : total_num_h_idx = ( nonzero_idc [ 2 ] - constants . n_atom_types - constants . n_formal_charge ) total_num_h = constants . imp_H [ total_num_h_idx ] new_atom . SetUnsignedProp ( "_TotalNumHs" , total_num_h ) elif constants . ignore_H : pass if constants . use_chirality : cip_code_idx = ( nonzero_idc [ - 1 ] - constants . n_atom_types - constants . n_formal_charge - ( not constants . use_explicit_H and not constants . ignore_H ) * constants . n_imp_H ) cip_code = constants . chirality [ cip_code_idx ] new_atom . SetProp ( "_CIPCode" , cip_code ) return new_atom def _graph_to_mol ( node_features : torch . Tensor , edge_features : torch . Tensor , n_nodes : int ) -> rdkit . Chem . Mol : """
            Converts input graph represenetation (node and edge features) into
            an `rdkit.Mol` object.

            Args:
            ----
                node_features (torch.Tensor) : Node features tensor.
                edge_features (torch.Tensor) : Edge features tensor.
                n_nodes (int)                : Number of nodes in the graph representation.

            Returns:
            -------
                molecule (rdkit.Chem.Mol) : Molecule object.
            """ molecule = rdkit . Chem . RWMol ( ) node_to_idx = { } for node_idx in range ( n_nodes ) : atom_to_add = _features_to_atom ( node_idx , node_features ) molecule_idx = molecule . AddAtom ( atom_to_add ) node_to_idx [ node_idx ] = molecule_idx n_max_nodes = constants . dim_nodes [ 0 ] edge_mask = torch . triu ( torch . ones ( ( n_max_nodes , n_max_nodes ) , device = constants . device ) , diagonal = 1 ) edge_mask = edge_mask . view ( n_max_nodes , n_max_nodes , 1 ) edges_idc = torch . nonzero ( edge_features * edge_mask ) for node_idx1 , node_idx2 , bond_idx in edges_idc : molecule . AddBond ( node_to_idx [ node_idx1 . item ( ) ] , node_to_idx [ node_idx2 . item ( ) ] , constants . int_to_bondtype [ bond_idx . item ( ) ] , ) try : molecule . GetMol ( ) except AttributeError : pass if constants . ignore_H and molecule : try : rdkit . Chem . SanitizeMol ( molecule ) except ValueError : pass return molecule try : mol = _graph_to_mol ( self . generated_nodes [ idx ] , self . generated_edges [ idx ] , self . generated_n_nodes [ idx ] ) except ( IndexError , AttributeError ) : mol = None graph = GenerationGraph ( constants = constants , molecule = mol , node_features = self . generated_nodes [ idx ] , edge_features = self . generated_edges [ idx ] ) return graph
Converts a molecular graph representation from the individual node and
edge feature tensors into `GenerationGraph` objects.
Converts a molecular graph representation from the individual node and edge feature tensors into ` GenerationGraph ` objects .
"""
        Converts a molecular graph representation from the individual node and
        edge feature tensors into `GenerationGraph` objects.

        Args:
        ----
            idx (int) : Index for the molecular graph to convert.

        Returns:
        -------
            graph (GenerationGraph) : Generated graph.
        """ """
            Converts the node feature vector corresponding to the specified node
            into an atom object.

            Args:
            ----
                node_idx (int)               : Index denoting the specific node
                                               on the graph to convert.
                node_features (torch.Tensor) : Node features tensor for one graph.

            Returns:
            -------
                new_atom (rdkit.Atom) : Atom object corresponding to specified
                                        node features.
            """ # get all the nonzero indices in the specified node feature vector # determine atom symbol # initialize atom # determine formal charge # set property # determine number of implicit Hs (if used) # set property # Hs will be set with structure is "sanitized" (corrected) later # in `mol_to_graph()` # determine chirality (if used) # set property """
            Converts input graph represenetation (node and edge features) into
            an `rdkit.Mol` object.

            Args:
            ----
                node_features (torch.Tensor) : Node features tensor.
                edge_features (torch.Tensor) : Edge features tensor.
                n_nodes (int)                : Number of nodes in the graph representation.

            Returns:
            -------
                molecule (rdkit.Chem.Mol) : Molecule object.
            """ # create empty editable `rdkit.Chem.Mol` object # add atoms to editable mol object # add bonds to atoms in editable mol object; to not add the same bond twice # (which leads to an error), mask half of the edge features beyond diagonal # convert editable mol object to non-editable mol object # will throw an error if molecule is `None` # correct for ignored Hs # throws exception if molecule is too ugly to correct # first get the `rdkit.Mol` object corresponding to the selected graph # raised when graph is empty # use the `rdkit.Mol` object, and node and edge features tensors, to get # the `GenerationGraph` object
graph (GenerationGraph) : Generated graph.
graph ( GenerationGraph ) : Generated graph .
self
idx
int
Index for the molecular graph to convert.
Index for the molecular graph to convert .