class_docstr: Holds information about a molecules.
  
  Resorts order of atoms internally to be in order of increasing degree. Note
  that only heavy atoms (hydrogens excluded) are considered here.
class_docstr_tok: ["Holds","information","about","a","molecules",".","Resorts","order","of","atoms","internally","to","be","in","order","of","increasing","degree",".","Note","that","only","heavy","atoms","(","hydrogens","excluded",")","are","considered","here","."]
docstr: Sorts atoms by degree and reorders internal data structures.
  
  Sort the order of the atom_features by degree, maintaining original order
  whenever two atom_features have the same degree.
docstr_tok: ["Sorts","atoms","by","degree","and","reorders","internal","data","structures",".","Sort","the","order","of","the","atom_features","by","degree",",","maintaining","original","order","whenever","two","atom_features","have","the","same","degree","."]
code: def _deg_sort(self):
      """Sorts atoms by degree and reorders internal data structures.
  
      Sort the order of the atom_features by degree, maintaining original order
      whenever two atom_features have the same degree.
      """
      old_ind = range(self.get_num_atoms())
      deg_list = self.deg_list
      new_ind = list(np.lexsort((old_ind, deg_list)))
  
      num_atoms = self.get_num_atoms()
  
      # Reorder old atom_features
      self.atom_features = self.atom_features[new_ind, :]
  
      # Reorder old deg lists
      self.deg_list = [self.deg_list[i] for i in new_ind]
  
      # Sort membership
      self.membership = [self.membership[i] for i in new_ind]
  
      # Create old to new dictionary. not exactly intuitive
      old_to_new = dict(zip(new_ind, old_ind))
  
      # Reorder adjacency lists
      self.canon_adj_list = [self.canon_adj_list[i] for i in new_ind]
      self.canon_adj_list = [
          [old_to_new[k] for k in self.canon_adj_list[i]]
          for i in range(len(new_ind))
      ]
  
      # Get numpy version of degree list for indexing
      deg_array = np.array(self.deg_list)
  
      # Initialize adj_lists, which supports min_deg = 1 only
      self.deg_adj_lists = (self.max_deg + 1 - self.min_deg) * [0]
  
      # Parse as deg separated
      for deg in range(self.min_deg, self.max_deg + 1):
          # Get indices corresponding to the current degree
          rng = np.array(range(num_atoms))
          indices = rng[deg_array == deg]
  
          # Extract and save adjacency list for the current degree
          to_cat = [self.canon_adj_list[i] for i in indices]
          if len(to_cat) > 0:
              adj_list = np.vstack(
                  [self.canon_adj_list[i] for i in indices]
              )
              self.deg_adj_lists[deg - self.min_deg] = adj_list.astype(
                  np.int32
              )
  
          else:
              self.deg_adj_lists[deg - self.min_deg] = np.zeros(
                  [0, deg], dtype=np.int32
              )
  
      # Construct the slice information
      deg_slice = np.zeros(
          [self.max_deg + 1 - self.min_deg, 2], dtype=np.int32
      )
  
      for deg in range(self.min_deg, self.max_deg + 1):
          if deg == 0:
              deg_size = np.sum(deg_array == deg)
          else:
              deg_size = self.deg_adj_lists[deg - self.min_deg].shape[0]
  
          deg_slice[deg - self.min_deg, 1] = deg_size
          # Get the cumulative indices after the first index
          if deg > self.min_deg:
              deg_slice[deg - self.min_deg, 0] = (
                  deg_slice[deg - self.min_deg - 1, 0]
                  + deg_slice[deg - self.min_deg - 1, 1]
              )
  
      # Set indices with zero sized slices to zero to avoid indexing errors
      deg_slice[:, 0] *= deg_slice[:, 1] != 0
      self.deg_slice = deg_slice
  
imports: import csv
  import random
  import numpy
label_desc: Use image node_id 5 for calling the ConvMol obj's underlying member method code with example usage: obj._deg_sort() without return types