docstr: Load structure data and return neighbor information
  
  Parameters
  ----------
  struct: : PymatgenStructure
      Pymatgen Structure object of the surface configuration. It also requires
      site_properties attribute with "Sitetypes"(Active or spectator site) and
      "oss"(Species of Active site from the list of self.aos and "-1" for
      spectator sites).
  cutoff_factor : float
      this is extra buffer factor multiplied to cutoff to
      ensure pooling all relevant sites.
  
  Return
  ------
  XSites : List[float]
      One hot encoding features of the site.
  XNSs : List[List[int]]
      Neighbors calculated in different permutations
docstr_tok: ["Load","structure","data","and","return","neighbor","information","Parameters","--","--","--","--","--","struct",":",":","PymatgenStructure","Pymatgen","Structure","object","of","the","surface","configuration",".","It","also","requires","site_properties","attribute","with","``","Sitetypes","''","(","Active","or","spectator","site",")","and","``","oss","''","(","Species","of","Active","site","from","the","list","of","self.aos","and","``","-1","''","for","spectator","sites",")",".","cutoff_factor",":","float","this","is","extra","buffer","factor","multiplied","to","cutoff","to","ensure","pooling","all","relevant","sites",".","Return","--","--","--","XSites",":","List","[","float","]","One","hot","encoding","features","of","the","site",".","XNSs",":","List","[","List","[","int","]","]","Neighbors","calculated","in","different","permutations"]
code: def read_datum(
      self, struct, cutoff_factor: float = 1.1
  ) -> Tuple[np.ndarray, np.ndarray]:
      """
      Load structure data and return neighbor information
  
      Parameters
      ----------
      struct: : PymatgenStructure
          Pymatgen Structure object of the surface configuration. It also requires
          site_properties attribute with "Sitetypes"(Active or spectator site) and
          "oss"(Species of Active site from the list of self.aos and "-1" for
          spectator sites).
      cutoff_factor : float
          this is extra buffer factor multiplied to cutoff to
          ensure pooling all relevant sites.
  
      Return
      ------
      XSites : List[float]
          One hot encoding features of the site.
      XNSs : List[List[int]]
          Neighbors calculated in different permutations
      """
      oss = [
          species
          for species in struct.site_properties["oss"]
          if species != "-1"
      ]
      # Construct one hot encoding
      XSites = np.zeros((len(oss), len(self.aos)))
      for i, o in enumerate(oss):
          XSites[i, self.aos.index(o)] = 1
      # get mapping between all site index to active site index
      alltoactive = {}
      n = 0
      for i, s in enumerate(struct.site_properties["SiteTypes"]):
          if "A" in s:
              alltoactive[i] = n
              n += 1
      # Get Neighbors
      # Read Data
      site_envs = _get_SiteEnvironments(
          struct,
          self.cutoff * cutoff_factor,
          self.pbc,
          get_permutations=False,
          eigen_tol=self.eigen_tol,
      )
      XNSs: List[list] = [[] for _ in range(len(self.site_envs))]
      for env in site_envs:
          i = self.unique_site_types.index(env["sitetypes"][0])
          new_env = self._truncate(self.site_envs[i], env)
  
          # get map between two environment
          mapping = self.site_envs[i].get_mapping(new_env)
          # align input to the primitive cell (reference)
          aligned_idx = [
              new_env["env2config"][mapping[i]]
              for i in range(len(new_env["env2config"]))
          ]
          # apply permutations
          nni_perm = np.take(
              aligned_idx, self.site_envs[i].permutations
          )
          # remove spectators
          nni_perm = nni_perm[:, self.site_envs[i].activesiteidx]
          # map it to active sites
          nni_perm = np.vectorize(alltoactive.__getitem__)(nni_perm)
          XNSs[i].append(nni_perm.tolist())
      return np.array(XSites), np.array(XNSs)
  
imports: import numpy
  import logging
  from deepchem.feat import MaterialStructureFeaturizer
  from collections import defaultdict
  from typing import List, Dict, Tuple, DefaultDict, Any
  from deepchem.utils.typing import PymatgenStructure
  from deepchem.feat.graph_data import GraphData
  from scipy.spatial.distance import pdist, squareform, cdist
  from scipy.spatial.transform import Rotation
label_desc: Use image node_id 2 for calling the _SiteEnvironments obj's underlying member method code with example usage: obj.read_datum(struct, cutoff_factor) and returns: np,  np