code: def parse_tddft(self):
          
          start_tag = "Convergence criterion met"
          end_tag = "Excited state energy"
          singlet_tag = "singlet excited"
          triplet_tag = "triplet excited"
          state = "singlet"
          inside = False  # true when we are inside output block
  
          lines = self.raw.split("\n")
  
          roots = {"singlet": [], "triplet": []}
  
          while lines:
              line = lines.pop(0).strip()
  
              if start_tag in line:
                  inside = True
  
              elif end_tag in line:
                  inside = False
  
              elif singlet_tag in line:
                  state = "singlet"
  
              elif triplet_tag in line:
                  state = "triplet"
  
              elif inside and "Root" in line and "eV" in line:
                  toks = line.split()
                  roots[state].append({"energy": float(toks[-2])})
  
              elif inside and "Dipole Oscillator Strength" in line:
                  osc = float(line.split()[-1])
                  roots[state][-1]["osc_strength"] = osc
  
          return roots
docs: Parses TDDFT roots. Adapted from nw_spectrum.py script.
  
          Returns:
              {
                  "singlet": [
                      {
                          "energy": float,
                          "osc_strength: float
                      }
                  ],
                  "triplet": [
                      {
                          "energy": float
                      }
                  ]
              }