digichem-core 6.0.0rc1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. digichem/__init__.py +75 -0
  2. digichem/basis.py +116 -0
  3. digichem/config/README +3 -0
  4. digichem/config/__init__.py +5 -0
  5. digichem/config/base.py +321 -0
  6. digichem/config/locations.py +14 -0
  7. digichem/config/parse.py +90 -0
  8. digichem/config/util.py +117 -0
  9. digichem/data/README +4 -0
  10. digichem/data/batoms/COPYING +18 -0
  11. digichem/data/batoms/LICENSE +674 -0
  12. digichem/data/batoms/README +2 -0
  13. digichem/data/batoms/__init__.py +0 -0
  14. digichem/data/batoms/batoms-renderer.py +351 -0
  15. digichem/data/config/digichem.yaml +714 -0
  16. digichem/data/functionals.csv +15 -0
  17. digichem/data/solvents.csv +185 -0
  18. digichem/data/tachyon/COPYING.md +5 -0
  19. digichem/data/tachyon/LICENSE +30 -0
  20. digichem/data/tachyon/tachyon_LINUXAMD64 +0 -0
  21. digichem/data/vmd/common.tcl +468 -0
  22. digichem/data/vmd/generate_combined_orbital_images.tcl +70 -0
  23. digichem/data/vmd/generate_density_images.tcl +45 -0
  24. digichem/data/vmd/generate_dipole_images.tcl +68 -0
  25. digichem/data/vmd/generate_orbital_images.tcl +57 -0
  26. digichem/data/vmd/generate_spin_images.tcl +66 -0
  27. digichem/data/vmd/generate_structure_images.tcl +40 -0
  28. digichem/datas.py +14 -0
  29. digichem/exception/__init__.py +7 -0
  30. digichem/exception/base.py +133 -0
  31. digichem/exception/uncatchable.py +63 -0
  32. digichem/file/__init__.py +1 -0
  33. digichem/file/base.py +364 -0
  34. digichem/file/cube.py +284 -0
  35. digichem/file/fchk.py +94 -0
  36. digichem/file/prattle.py +277 -0
  37. digichem/file/types.py +97 -0
  38. digichem/image/__init__.py +6 -0
  39. digichem/image/base.py +113 -0
  40. digichem/image/excited_states.py +335 -0
  41. digichem/image/graph.py +293 -0
  42. digichem/image/orbitals.py +239 -0
  43. digichem/image/render.py +617 -0
  44. digichem/image/spectroscopy.py +797 -0
  45. digichem/image/structure.py +115 -0
  46. digichem/image/vmd.py +826 -0
  47. digichem/input/__init__.py +3 -0
  48. digichem/input/base.py +78 -0
  49. digichem/input/digichem_input.py +500 -0
  50. digichem/input/gaussian.py +140 -0
  51. digichem/log.py +179 -0
  52. digichem/memory.py +166 -0
  53. digichem/misc/__init__.py +4 -0
  54. digichem/misc/argparse.py +44 -0
  55. digichem/misc/base.py +61 -0
  56. digichem/misc/io.py +239 -0
  57. digichem/misc/layered_dict.py +285 -0
  58. digichem/misc/text.py +139 -0
  59. digichem/misc/time.py +73 -0
  60. digichem/parse/__init__.py +13 -0
  61. digichem/parse/base.py +220 -0
  62. digichem/parse/cclib.py +138 -0
  63. digichem/parse/dump.py +253 -0
  64. digichem/parse/gaussian.py +130 -0
  65. digichem/parse/orca.py +96 -0
  66. digichem/parse/turbomole.py +201 -0
  67. digichem/parse/util.py +523 -0
  68. digichem/result/__init__.py +6 -0
  69. digichem/result/alignment/AA.py +114 -0
  70. digichem/result/alignment/AAA.py +61 -0
  71. digichem/result/alignment/FAP.py +148 -0
  72. digichem/result/alignment/__init__.py +3 -0
  73. digichem/result/alignment/base.py +310 -0
  74. digichem/result/angle.py +153 -0
  75. digichem/result/atom.py +742 -0
  76. digichem/result/base.py +258 -0
  77. digichem/result/dipole_moment.py +332 -0
  78. digichem/result/emission.py +402 -0
  79. digichem/result/energy.py +323 -0
  80. digichem/result/excited_state.py +821 -0
  81. digichem/result/ground_state.py +94 -0
  82. digichem/result/metadata.py +644 -0
  83. digichem/result/multi.py +98 -0
  84. digichem/result/nmr.py +1086 -0
  85. digichem/result/orbital.py +647 -0
  86. digichem/result/result.py +244 -0
  87. digichem/result/soc.py +272 -0
  88. digichem/result/spectroscopy.py +514 -0
  89. digichem/result/tdm.py +267 -0
  90. digichem/result/vibration.py +167 -0
  91. digichem/test/__init__.py +6 -0
  92. digichem/test/conftest.py +4 -0
  93. digichem/test/test_basis.py +71 -0
  94. digichem/test/test_calculate.py +30 -0
  95. digichem/test/test_config.py +78 -0
  96. digichem/test/test_cube.py +369 -0
  97. digichem/test/test_exception.py +16 -0
  98. digichem/test/test_file.py +104 -0
  99. digichem/test/test_image.py +337 -0
  100. digichem/test/test_input.py +64 -0
  101. digichem/test/test_parsing.py +79 -0
  102. digichem/test/test_prattle.py +36 -0
  103. digichem/test/test_result.py +489 -0
  104. digichem/test/test_translate.py +112 -0
  105. digichem/test/util.py +207 -0
  106. digichem/translate.py +591 -0
  107. digichem_core-6.0.0rc1.dist-info/METADATA +96 -0
  108. digichem_core-6.0.0rc1.dist-info/RECORD +111 -0
  109. digichem_core-6.0.0rc1.dist-info/WHEEL +4 -0
  110. digichem_core-6.0.0rc1.dist-info/licenses/COPYING.md +10 -0
  111. digichem_core-6.0.0rc1.dist-info/licenses/LICENSE +11 -0
@@ -0,0 +1,244 @@
1
+ # Code for processing results from calculations and generating reports.
2
+
3
+ # General imports.
4
+ import itertools
5
+ import warnings
6
+
7
+ from digichem.exception import Result_unavailable_error
8
+
9
+ from digichem.result import Result_object
10
+ import digichem.result.excited_state
11
+ from digichem.result.emission import Emissions
12
+
13
+
14
+ class Result_set(Result_object):
15
+ """
16
+ Class that represents a collection of results from a calculation.
17
+
18
+ This class is a bit heavy and might not be around for long...
19
+ """
20
+
21
+ def __init__(self, **attributes):
22
+ """Constructor for Result_set objects."""
23
+ super().__init__()
24
+
25
+ # The ID uniquely identifies this calculation result.
26
+ # In most cases, it is generated from the combined chekcsum of the log files from which the results was parsed.
27
+ # If this result was not read from log files (but was read from a database or from a .si calc result or similar),
28
+ # then the id will simply be the same as was written previously.
29
+ #
30
+ # Note that the underscore here does not imply that this attribute is 'hidden'. Instead, this is used for
31
+ # consistency with mongo-like DBs, where the ID field is also typically named _id.
32
+ #self._id = attributes.pop('database_id', None)
33
+ self._id = attributes.pop('_id', None)
34
+
35
+ self.results = (self,)
36
+ self.emission = attributes.pop('emission', Emissions())
37
+
38
+ for attr_name, attribute in attributes.items():
39
+ setattr(self, attr_name, attribute)
40
+
41
+ @property
42
+ def alignment(self):
43
+ warnings.warn("alignment is deprecated, use atoms instead", DeprecationWarning)
44
+ return self.atoms
45
+
46
+ @property
47
+ def CC_energies(self):
48
+ warnings.warn("CC_energies is deprecated, use energies.cc instead", DeprecationWarning)
49
+ return self.energies.cc
50
+
51
+ @CC_energies.setter
52
+ def CC_energies(self, value):
53
+ warnings.warn("CC_energies is deprecated, use energies.cc instead", DeprecationWarning)
54
+ self.energies.cc = value
55
+
56
+ @property
57
+ def MP_energies(self):
58
+ warnings.warn("MP_energies is deprecated, use energies.mp instead", DeprecationWarning)
59
+ return self.energies.mp
60
+
61
+ @MP_energies.setter
62
+ def MP_energies(self, value):
63
+ warnings.warn("MP_energies is deprecated, use energies.mp instead", DeprecationWarning)
64
+ self.energies.mp = value
65
+
66
+ @property
67
+ def SCF_energies(self):
68
+ warnings.warn("SCF_energies is deprecated, use energies.scf instead", DeprecationWarning)
69
+ return self.energies.scf
70
+
71
+ @SCF_energies.setter
72
+ def SCF_energies(self, value):
73
+ warnings.warn("SCF_energies is deprecated, use energies.scf instead", DeprecationWarning)
74
+ self.energies.scf = value
75
+
76
+ @property
77
+ def molecular_orbitals(self):
78
+ warnings.warn("molecular_orbitals is deprecated, use orbitals instead", DeprecationWarning)
79
+ return self.orbitals
80
+
81
+ @molecular_orbitals.setter
82
+ def molecular_orbitals(self, value):
83
+ warnings.warn("molecular_orbitals is deprecated, use orbitals instead", DeprecationWarning)
84
+ self.orbitals = value
85
+
86
+ @property
87
+ def spin_orbit_coupling(self):
88
+ warnings.warn("spin_orbit_coupling is deprecated, use soc instead", DeprecationWarning)
89
+ return self.soc
90
+
91
+ @spin_orbit_coupling.setter
92
+ def spin_orbit_coupling(self, value):
93
+ warnings.warn("spin_orbit_coupling is deprecated, use soc instead", DeprecationWarning)
94
+ self.soc = value
95
+
96
+ @property
97
+ def dipole_moment(self):
98
+ warnings.warn("dipole_moment is deprecated, use pdm instead", DeprecationWarning)
99
+ return self.pdm
100
+
101
+ @dipole_moment.setter
102
+ def dipole_moment(self, value):
103
+ warnings.warn("dipole_moment is deprecated, use pdm instead", DeprecationWarning)
104
+ self.pdm = value
105
+
106
+ @property
107
+ def vertical_emission(self):
108
+ warnings.warn("vertical_emission is deprecated, use emission.vertical instead", DeprecationWarning)
109
+ return self.emission.vertical
110
+
111
+ @vertical_emission.setter
112
+ def vertical_emission(self, value):
113
+ warnings.warn("vertical_emission is deprecated, use emission.vertical instead", DeprecationWarning)
114
+ self.emission.vertical = value
115
+
116
+ @property
117
+ def adiabatic_emission(self):
118
+ warnings.warn("adiabatic_emission is deprecated, use emission.adiabatic instead", DeprecationWarning)
119
+ return self.emission.adiabatic
120
+
121
+ @adiabatic_emission.setter
122
+ def adiabatic_emission(self, value):
123
+ warnings.warn("adiabatic_emission is deprecated, use emission.adiabatic instead", DeprecationWarning)
124
+ self.emission.adiabatic = value
125
+
126
+ @property
127
+ def metadatas(self):
128
+ """
129
+ Property providing access to the list of metadatas of the calculations that were merged together.
130
+ """
131
+ return [result.metadata for result in self.results]
132
+
133
+ @property
134
+ def level_of_theory(self):
135
+ """
136
+ A short-hand summary of the methods and basis sets used.
137
+ """
138
+ methods = []
139
+ basis_sets = []
140
+ for metadata in self.metadatas:
141
+ if len(metadata.converted_methods) > 0:
142
+ method = metadata.converted_methods[-1]
143
+ # for method in metadata.converted_methods:
144
+ if method not in methods:
145
+ methods.append(method)
146
+
147
+ if metadata.basis_set is not None and metadata.basis_set not in basis_sets:
148
+ basis_sets.append(metadata.basis_set)
149
+
150
+ return "/".join(itertools.chain(methods, basis_sets))
151
+
152
+ @property
153
+ def title(self):
154
+ """
155
+ A string Title describing this result.
156
+ """
157
+ title = ", ".join(self.metadata.calculations)
158
+ if "Excited States" in self.metadata.calculations:
159
+ # Add multiplicity based on ES.
160
+ mult = self.excited_states.group()
161
+ mult_strings = [digichem.result.excited_state.Energy_state.multiplicity_number_to_string(multiplicity).capitalize() for multiplicity in mult]
162
+ if len(mult_strings) <= 2:
163
+ # Add the strings.
164
+ title += " ({})".format(", ".join(mult_strings))
165
+ else:
166
+ # Add something non-specific.
167
+ title += " (Various Multiplicities)"
168
+ else:
169
+ title += " ({})".format(digichem.result.excited_state.Energy_state.multiplicity_number_to_string(self.metadata.multiplicity).capitalize())
170
+ return title
171
+
172
+ @property
173
+ def energy(self):
174
+ """
175
+ The total energy of this calculation.
176
+
177
+ This convenience property is the energy at the highest level of theory available (CC > MP > SCF).
178
+
179
+ :raises Result_unavailable_error: If no total energy is available.
180
+ """
181
+ warnings.warn("energy is deprecated, use energies.final instead", DeprecationWarning)
182
+ return self.energies.final
183
+
184
+
185
+ @property
186
+ def electric_transition_dipole_moment(self):
187
+ """
188
+ The S1 electric dipole moment, commonly referred to as THE electric transition dipole moment (although this name is ambiguous).
189
+
190
+ None is returned if the S1 dipole moment is not available.
191
+ """
192
+ tdm = self.transition_dipole_moment
193
+ if tdm is not None:
194
+ return tdm.electric
195
+
196
+ @property
197
+ def magnetic_transition_dipole_moment(self):
198
+ """
199
+ The S1 magnetic dipole moment, commonly referred to as THE magnetic transition dipole moment (although this name is ambiguous).
200
+
201
+ None is returned if the S1 dipole moment is not available.
202
+ """
203
+ tdm = self.transition_dipole_moment
204
+ if tdm is not None:
205
+ return tdm.magnetic
206
+
207
+ @property
208
+ def transition_dipole_moment(self):
209
+ """
210
+ The S1 dipole moment (both electric and magnetic), commonly referred to as THE transition dipole moment (although this name is ambiguous).
211
+
212
+ None is returned if the S1 dipole moment is not available.
213
+ """
214
+ try:
215
+ S1 = self.excited_states.get_state("S(1)")
216
+ return S1.transition_dipole_moment
217
+ except Result_unavailable_error:
218
+ # No S1 available.
219
+ return None
220
+
221
+ def dump(self, digichem_options):
222
+ "Dump the data contained in this result set, serialising it to a hierarchy of dicts that can be saved in various formats."
223
+ # Start with our DB ID if we have one.
224
+ dump_dic = {}
225
+ if self._id is not None:
226
+ dump_dic['_id'] = self._id
227
+
228
+ dump_dic.update({
229
+ "metadata": self.metadata.dump(digichem_options),
230
+ "ground_state": self.ground_state.dump(digichem_options) if self.ground_state is not None else None,
231
+ "energies": self.energies.dump(digichem_options),
232
+ "atoms": self.atoms.dump(digichem_options),
233
+ "raw_atoms": self.raw_atoms.dump(digichem_options),
234
+ "orbitals": self.orbitals.dump(digichem_options),
235
+ "beta_orbitals": self.beta_orbitals.dump(digichem_options),
236
+ "pdm": self.pdm.dump(digichem_options) if self.pdm is not None else None,
237
+ "excited_states": self.excited_states.dump(digichem_options),
238
+ "soc": self.soc.dump(digichem_options),
239
+ "vibrations": self.vibrations.dump(digichem_options),
240
+ "nmr": self.nmr.dump(digichem_options),
241
+ "emission": self.emission.dump(digichem_options)
242
+ })
243
+
244
+ return dump_dic
digichem/result/soc.py ADDED
@@ -0,0 +1,272 @@
1
+ # General imports.
2
+ import math
3
+
4
+ from digichem.exception import Result_unavailable_error
5
+ from digichem.result import Result_container
6
+ from digichem.result import Result_object
7
+ from digichem.result.base import Floatable_mixin
8
+
9
+
10
+ class SOC_list(Result_container):
11
+ """
12
+ An augmented list containing spin orbit coupling.
13
+ """
14
+
15
+ def find(self, criteria):
16
+ """
17
+ """
18
+ states = criteria.split(",")
19
+
20
+ # Check we have two states.
21
+ if len(states) != 2:
22
+ raise ValueError("SOC can only be found between exactly 2 states, not {} states.".format(len(states)))
23
+
24
+ return self.between(*states)
25
+
26
+ def between(self, state1, state2, **kwargs):
27
+ """
28
+ Return the spin-orbit coupling object between the two states with given symbols.
29
+
30
+ :param states: Symbols identifying the two states to get SOC between (eg, "S(1)" "T(1)").
31
+ :param default: A default argument that will be returned if the given states cannot be found.
32
+ """
33
+ states = set((state1, state2))
34
+
35
+ # Iterate through all our SOC.
36
+ for soc in self:
37
+ # Check if the two states match the two we've been asked to find.
38
+ if len(states.intersection((soc.singlet_state.state_symbol, soc.triplet_state.state_symbol))) == 2:
39
+ # A match!
40
+ return soc
41
+
42
+ # No match.
43
+ # Return the default if given, otherwise panic.
44
+ if "default" in kwargs:
45
+ return kwargs['default']
46
+ else:
47
+ raise Result_unavailable_error("Spin-orbit coupling", "could not find SOC between states with symbols '{}' and '{}'".format(state1, state2))
48
+
49
+ @classmethod
50
+ def from_parser(self, parser):
51
+ """
52
+ Get a SOC_list object from an output file parser.
53
+
54
+ :param parser: An output file parser.
55
+ :return: A SOC_list object. The list will be empty if no SOC is available.
56
+ """
57
+ # Decide which SOC class to use.
58
+ if hasattr(parser.data, "socelements"):
59
+ soc_cls = Spin_orbit_coupling
60
+ else:
61
+ soc_cls = Total_spin_orbit_coupling
62
+
63
+ return self(soc_cls.list_from_parser(parser))
64
+
65
+ @classmethod
66
+ def from_dump(self, data, result_set, options):
67
+ """
68
+ Get an instance of this class from its dumped representation.
69
+
70
+ :param data: The data to parse.
71
+ :param result_set: The partially constructed result set which is being populated.
72
+ """
73
+ return self([(Spin_orbit_coupling if 'soc' in soc_dict else Total_spin_orbit_coupling).from_dump(soc_dict, result_set, options) for soc_dict in data])
74
+
75
+ def sort(self, *, key = None, **kwargs):
76
+ """
77
+ Sort this list in place.
78
+ """
79
+ # If no key is given, we use a custom default key.
80
+ if key is None:
81
+ key = lambda SOC: (SOC.singlet_state.level, SOC.triplet_state.level)
82
+
83
+ return super().sort(key = key, **kwargs)
84
+
85
+
86
+ class Spin_orbit_coupling(Result_object, Floatable_mixin):
87
+ """
88
+ Class that represents spin-orbit coupling between two states.
89
+ """
90
+
91
+ def __init__(self, singlet_state, triplet_state, positive_one, zero, negative_one):
92
+ """
93
+ Constructor for SOC objects.
94
+
95
+ :param singlet_state: The singlet excited state this coupling is between.
96
+ :param triplet_state: The triplet excited state this coupling is between.
97
+ :param positive_one: SOC between the singlet state and triplet sub-state with quantum number +1 in cm-1.
98
+ :param zero: SOC between the singlet state and triplet sub-state with quantum number 0 in cm-1.
99
+ :param negative_one: SOC between the singlet state and triplet sub-state with quantum number -1 in cm-1.
100
+ """
101
+ self.singlet_state = singlet_state
102
+ self.triplet_state = triplet_state
103
+ self.positive_one = positive_one
104
+ self.zero = zero
105
+ self.negative_one = negative_one
106
+
107
+ def dump(self, digichem_options):
108
+ """
109
+ Get a representation of this result object in primitive format.
110
+ """
111
+ return {
112
+ "singlet": self.singlet_state.state_symbol,
113
+ "triplet": self.triplet_state.state_symbol,
114
+ "soc": {
115
+ "+1": {
116
+ "value": self.positive_one,
117
+ "units": "c m^-1",
118
+ },
119
+ "0": {
120
+ "value": self.zero,
121
+ "units": "c m^-1",
122
+ },
123
+ "-1": {
124
+ "value": self.negative_one,
125
+ "units": "c m^-1",
126
+ },
127
+ },
128
+ "rss": {
129
+ "units": "c m^-1",
130
+ "value": self.root_sum_square,
131
+ },
132
+ "mixing_coefficient": self.mixing_coefficient
133
+ }
134
+
135
+ @classmethod
136
+ def from_dump(self, data, result_set, options):
137
+ """
138
+ Get an instance of this class from its dumped representation.
139
+
140
+ :param data: The data to parse.
141
+ :param result_set: The partially constructed result set which is being populated.
142
+ """
143
+ return self(result_set.energy_states.find(data['singlet']), result_set.energy_states.find(data['triplet']), data['soc']['+1']['value'], data['soc']['0']['value'], data['soc']['-1']['value'])
144
+
145
+ @classmethod
146
+ def list_from_parser(self, parser):
147
+ """
148
+ Create a SOC object from an output file parser.
149
+ """
150
+ # Go through our data.
151
+ try:
152
+ return [self(
153
+ singlet_state = parser.results.energy_states.get_state(state_symbol = singlet_symbol),
154
+ triplet_state = parser.results.energy_states.get_state(state_symbol = triplet_symbol),
155
+ positive_one = positive_soc,
156
+ zero = zero_soc,
157
+ negative_one = negative_soc
158
+ ) for (singlet_symbol, triplet_symbol), (positive_soc, zero_soc, negative_soc) in zip(parser.data.socstates, parser.data.socelements)]
159
+ except AttributeError:
160
+ # No data.
161
+ return []
162
+
163
+ @property
164
+ def splitting_energy(self):
165
+ """
166
+ The difference in energy between these two states.
167
+ """
168
+ return max(float(self.singlet_state), float(self.triplet_state)) - min(float(self.singlet_state), float(self.triplet_state))
169
+
170
+ @property
171
+ def mixing_coefficient(self):
172
+ """
173
+ The first order mixing coefficient (λ), given by Hso / dEst.
174
+ Be aware that λ will == math.inf if dEst == 0.
175
+ """
176
+ try:
177
+ return self.energy / self.splitting_energy
178
+ except (FloatingPointError, ZeroDivisionError):
179
+ return math.inf
180
+
181
+ @property
182
+ def root_sum_square(self):
183
+ """
184
+ The root sum square of this SOC.
185
+ """
186
+ return math.sqrt(self.positive_one **2 + self.zero **2 + self.negative_one **2)
187
+
188
+ def __float__(self):
189
+ """
190
+ Floatify this SOC class.
191
+ """
192
+ return float(self.root_sum_square)
193
+
194
+ @property
195
+ def wavenumbers(self):
196
+ """
197
+ SOC in wavenumbers.
198
+ """
199
+ return self.root_sum_square
200
+
201
+ @property
202
+ def energy(self):
203
+ """
204
+ SOC in eV.
205
+ """
206
+ try:
207
+ return self.wavenumbers_to_energy(self.root_sum_square)
208
+ except (FloatingPointError, ZeroDivisionError):
209
+ return 0.0
210
+
211
+ def __str__(self):
212
+ """
213
+ Stringify this SOC class.
214
+ """
215
+ return "<{}|Hso|{}> (RSS, +1, 0, -1) (cm-1): {:10.5f} {:10.5f} {:10.5f} {:10.5f}".format(self.singlet_state.state_symbol, self.triplet_state.state_symbol, self.root_sum_square, self.positive_one, self.zero, self.negative_one)
216
+
217
+
218
+ class Total_spin_orbit_coupling(Spin_orbit_coupling):
219
+ """
220
+ A class for representing SOC when only the total is known (and not the individual elements).
221
+ """
222
+
223
+ def __init__(self, singlet_state, triplet_state, total):
224
+ super().__init__(singlet_state, triplet_state, None, None, None)
225
+
226
+ self._root_sum_square = total
227
+
228
+ @property
229
+ def root_sum_square(self):
230
+ return self._root_sum_square
231
+
232
+ def __str__(self):
233
+ """
234
+ Stringify this SOC class.
235
+ """
236
+ return "<{}|Hso|{}> (cm-1): {:10.5f}".format(self.singlet_state.state_symbol, self.triplet_state.state_symbol, self.root_sum_square)
237
+
238
+ def dump(self, digichem_options):
239
+ """
240
+ Get a representation of this result object in primitive format.
241
+ """
242
+ dump_dic = super().dump(digichem_options)
243
+ # Remove elements.
244
+ del(dump_dic['soc'])
245
+ return dump_dic
246
+
247
+ @classmethod
248
+ def from_dump(self, data, result_set, options):
249
+ """
250
+ Get an instance of this class from its dumped representation.
251
+
252
+ :param data: The data to parse.
253
+ :param result_set: The partially constructed result set which is being populated.
254
+ """
255
+ return self(result_set.energy_states.find(data['singlet']), result_set.energy_states.find(data['triplet']), data['rss']['value'])
256
+
257
+ @classmethod
258
+ def list_from_parser(self, parser):
259
+ """
260
+ Create a SOC object from an output file parser.
261
+ """
262
+ # Go through our data.
263
+ try:
264
+ return [self(
265
+ singlet_state = parser.results.energy_states.get_state(state_symbol = singlet_symbol),
266
+ triplet_state = parser.results.energy_states.get_state(state_symbol = triplet_symbol),
267
+ total = total
268
+ ) for (singlet_symbol, triplet_symbol), total in zip(parser.data.socstates, parser.data.socenergies)]
269
+ except (AttributeError, Result_unavailable_error):
270
+ # No data.
271
+ return []
272
+