code: def mol2dgl_single(cand_batch):
      cand_graphs = []
      tree_mess_source_edges = []  # map these edges from trees to...
      tree_mess_target_edges = []  # these edges on candidate graphs
      tree_mess_target_nodes = []
      n_nodes = 0
      n_edges = 0
      atom_x = []
      bond_x = []
  
      for mol, mol_tree, ctr_node_id in cand_batch:
          n_atoms = mol.GetNumAtoms()
          n_bonds = mol.GetNumBonds()
  
          ctr_node = mol_tree.nodes_dict[ctr_node_id]
          ctr_bid = ctr_node["idx"]
          mol_tree_graph = getattr(mol_tree, "graph", mol_tree)
  
          for i, atom in enumerate(mol.GetAtoms()):
              assert i == atom.GetIdx()
              atom_x.append(atom_features(atom))
  
          bond_src = []
          bond_dst = []
          for i, bond in enumerate(mol.GetBonds()):
              a1 = bond.GetBeginAtom()
              a2 = bond.GetEndAtom()
              begin_idx = a1.GetIdx()
              end_idx = a2.GetIdx()
              features = bond_features(bond)
  
              bond_src.append(begin_idx)
              bond_dst.append(end_idx)
              bond_x.append(features)
              bond_src.append(end_idx)
              bond_dst.append(begin_idx)
              bond_x.append(features)
  
              x_nid, y_nid = a1.GetAtomMapNum(), a2.GetAtomMapNum()
              # Tree node ID in the batch
              x_bid = (
                  mol_tree.nodes_dict[x_nid - 1]["idx"]
                  if x_nid > 0
                  else -1
              )
              y_bid = (
                  mol_tree.nodes_dict[y_nid - 1]["idx"]
                  if y_nid > 0
                  else -1
              )
              if x_bid >= 0 and y_bid >= 0 and x_bid != y_bid:
                  if mol_tree_graph.has_edges_between(x_bid, y_bid):
                      tree_mess_target_edges.append(
                          (begin_idx + n_nodes, end_idx + n_nodes)
                      )
                      tree_mess_source_edges.append((x_bid, y_bid))
                      tree_mess_target_nodes.append(end_idx + n_nodes)
                  if mol_tree_graph.has_edges_between(y_bid, x_bid):
                      tree_mess_target_edges.append(
                          (end_idx + n_nodes, begin_idx + n_nodes)
                      )
                      tree_mess_source_edges.append((y_bid, x_bid))
                      tree_mess_target_nodes.append(begin_idx + n_nodes)
  
          n_nodes += n_atoms
          g = dgl.graph((bond_src, bond_dst), num_nodes=n_atoms)
          cand_graphs.append(g)
  
      return (
          cand_graphs,
          torch.stack(atom_x),
          torch.stack(bond_x) if len(bond_x) > 0 else torch.zeros(0),
          torch.LongTensor(tree_mess_source_edges),
          torch.LongTensor(tree_mess_target_edges),
          torch.LongTensor(tree_mess_target_nodes),
      )
  
imports: import os
  import dgl
  import dgl.function
  import rdkit.Chem
  import torch
  import torch.nn
  from dgl import line_graph, mean_nodes
  from .nnutils import cuda
label_desc: Use image node_id 4 for calling a global function with example usage: mol2dgl_single(cand_batch) and returns: cand_graphs,  torch,  unknown,  torch,  torch,  torch