docs: def _read_mulliken(self):
          """
          Parses Mulliken charges. Also parses spins given an unrestricted SCF.
          """
          if self.data.get('unrestricted', []):
              header_pattern = r"\-+\s+Ground-State Mulliken Net Atomic Charges\s+Atom\s+Charge \(a\.u\.\)\s+Spin\s\(a\.u\.\)\s+\-+"
              table_pattern = r"\s+\d+\s\w+\s+([\d\-\.]+)\s+([\d\-\.]+)"
              footer_pattern = r"\s\s\-+\s+Sum of atomic charges"
          else:
              header_pattern = r"\-+\s+Ground-State Mulliken Net Atomic Charges\s+Atom\s+Charge \(a\.u\.\)\s+\-+"
              table_pattern = r"\s+\d+\s\w+\s+([\d\-\.]+)"
              footer_pattern = r"\s\s\-+\s+Sum of atomic charges"
  
          temp_mulliken = read_table_pattern(self.text, header_pattern,
                                             table_pattern, footer_pattern)
          real_mulliken = []
          for one_mulliken in temp_mulliken:
              if self.data.get('unrestricted', []):
                  temp = np.zeros(shape=(len(one_mulliken), 2))
                  for ii, entry in enumerate(one_mulliken):
                      temp[ii, 0] = float(entry[0])
                      temp[ii, 1] = float(entry[1])
              else:
                  temp = np.zeros(len(one_mulliken))
                  for ii, entry in enumerate(one_mulliken):
                      temp[ii] = float(entry[0])
              real_mulliken += [temp]
  
          self.data["Mulliken"] = real_mulliken