Skip to content

Result Parser (result.py)

The core engine for building and running Multiwfn sequences.

pymultiwfn.analysis.result

Result container for Multiwfn job execution.

Provides the parsed-result dataclasses, the :class:MultiwfnResult container that accumulates parser output, and per-molecule JSON persistence (replacing the former storage.py).

AOMDiagnostics dataclass

Bases: ParsedMultiwfnResult

Atomic overlap matrix quality diagnostics.

Source code in src/pymultiwfn/analysis/result.py
861
862
863
864
865
866
867
868
869
870
@dataclass
class AOMDiagnostics(ParsedMultiwfnResult):
    """Atomic overlap matrix quality diagnostics."""

    error: float | None = None
    max_diagonal_deviation: float | None = None
    max_diagonal_orbital: int | None = None
    max_nondiagonal_deviation: float | None = None
    max_nondiagonal_orbitals: tuple[int, int] | None = None
    exported_file: str | None = None

Aromaticity dataclass

Bases: ParsedMultiwfnResult

Result for aromaticity analysis (Menu 25).

Source code in src/pymultiwfn/analysis/result.py
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
@dataclass
class Aromaticity(ParsedMultiwfnResult):
    """Result for aromaticity analysis (Menu 25)."""

    NICS: float | None = None
    NICS_ZZ: float | None = None
    NICS_1: float | None = None
    HOMA: float | None = None
    HOMAC: float | None = None
    HOMER: float | None = None
    Bird: float | None = None
    EN_GEO: float | None = None
    EN_BLA: float | None = None

AromaticityIndex dataclass

Bases: ParsedMultiwfnResult

Result for aromaticity indices (Menu 15).

Source code in src/pymultiwfn/analysis/result.py
948
949
950
951
952
953
@dataclass
class AromaticityIndex(ParsedMultiwfnResult):
    """Result for aromaticity indices (Menu 15)."""

    index_name: str
    value: float

AtomInfo dataclass

Bases: ParsedMultiwfnResult

Atom entry from the atom list output.

Source code in src/pymultiwfn/analysis/result.py
35
36
37
38
39
40
41
42
43
44
@dataclass
class AtomInfo(ParsedMultiwfnResult):
    """Atom entry from the atom list output."""

    atom_id: int
    element: str
    nuclear_charge: float
    x_bohr: float
    y_bohr: float
    z_bohr: float

AtomicMultipole dataclass

Bases: ParsedMultiwfnResult

Full atomic multipole moments for one atom.

Source code in src/pymultiwfn/analysis/result.py
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
@dataclass
class AtomicMultipole(ParsedMultiwfnResult):
    """Full atomic multipole moments for one atom."""

    atom_id: int
    atom_element: str

    # Charge / monopole
    atomic_charge: float | None = None
    monopole_moment: float | None = None

    # Dipole
    dipole_x: float | None = None
    dipole_y: float | None = None
    dipole_z: float | None = None
    dipole_norm: float | None = None

    # Contribution to molecular dipole
    mol_dipole_contrib_x: float | None = None
    mol_dipole_contrib_y: float | None = None
    mol_dipole_contrib_z: float | None = None
    mol_dipole_contrib_norm: float | None = None

    # Quadrupole (traceless Cartesian)
    quadrupole_xx: float | None = None
    quadrupole_xy: float | None = None
    quadrupole_xz: float | None = None
    quadrupole_yy: float | None = None
    quadrupole_yz: float | None = None
    quadrupole_zz: float | None = None
    quadrupole_magnitude: float | None = None

    # Spatial extent
    spatial_extent_r2: float | None = None
    spatial_extent_x: float | None = None
    spatial_extent_y: float | None = None
    spatial_extent_z: float | None = None

    # Octopole (spherical harmonic magnitudes)
    octopole_magnitude: float | None = None

BLA_BOA dataclass

Bases: ParsedMultiwfnResult

Result for BLA/BOA.

Source code in src/pymultiwfn/analysis/result.py
1462
1463
1464
1465
1466
1467
@dataclass
class BLA_BOA(ParsedMultiwfnResult):  # noqa: N801
    """Result for BLA/BOA."""

    bla: float | None = None
    boa: float | None = None

Basin dataclass

Bases: ParsedMultiwfnResult

Result for basin analysis.

Source code in src/pymultiwfn/analysis/result.py
968
969
970
971
972
973
974
975
976
977
@dataclass
class Basin(ParsedMultiwfnResult):
    """Result for basin analysis."""

    basin_id: int
    population: float
    attractor_atom: int | None = None
    attractor_element: str | None = None
    volume: float | None = None
    charge: float | None = None

BasisFunction dataclass

Bases: ParsedMultiwfnResult

Single basis function mapping to shell and GTF range.

Source code in src/pymultiwfn/analysis/result.py
169
170
171
172
173
174
175
176
177
178
179
@dataclass
class BasisFunction(ParsedMultiwfnResult):
    """Single basis function mapping to shell and GTF range."""

    basis_index: int
    shell_index: int
    center_atom_id: int
    center_element: str
    function_type: str
    gtf_start: int
    gtf_end: int

BondAngle dataclass

Bases: ParsedMultiwfnResult

Result for bond angle analysis.

Source code in src/pymultiwfn/analysis/result.py
1367
1368
1369
1370
1371
1372
1373
1374
@dataclass
class BondAngle(ParsedMultiwfnResult):
    """Result for bond angle analysis."""

    atom1_id: int
    atom2_id: int
    atom3_id: int
    angle: float

BondLength dataclass

Bases: ParsedMultiwfnResult

Result for bond length analysis.

Source code in src/pymultiwfn/analysis/result.py
1358
1359
1360
1361
1362
1363
1364
@dataclass
class BondLength(ParsedMultiwfnResult):
    """Result for bond length analysis."""

    atom1_id: int
    atom2_id: int
    length: float

BondOrder dataclass

Bases: ParsedMultiwfnResult

Single bond order entry between two atoms.

Source code in src/pymultiwfn/analysis/result.py
384
385
386
387
388
389
390
@dataclass
class BondOrder(ParsedMultiwfnResult):
    """Single bond order entry between two atoms."""

    atom1_id: int
    atom2_id: int
    bond_order: float

BondOrderDecomposition dataclass

Bases: ParsedMultiwfnResult

Result for bond order decomposition (per orbital) analysis.

Source code in src/pymultiwfn/analysis/result.py
421
422
423
424
425
426
@dataclass
class BondOrderDecomposition(ParsedMultiwfnResult):
    """Result for bond order decomposition (per orbital) analysis."""

    orbital_id: int
    contribution: float

BondOrderSet dataclass

Bases: ParsedMultiwfnResult

A complete set of bond orders from one method.

Parameters

method Standardized method identifier. One of: "mayer", "wiberg", "mulliken", "fuzzy", "laplacian". threshold The printing threshold used, if reported (e.g. 0.05). bond_orders Per-pair bond orders.

Source code in src/pymultiwfn/analysis/result.py
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
@dataclass
class BondOrderSet(ParsedMultiwfnResult):
    """A complete set of bond orders from one method.

    Parameters
    ----------
    method
        Standardized method identifier.  One of: ``"mayer"``,
        ``"wiberg"``, ``"mulliken"``, ``"fuzzy"``,
        ``"laplacian"``.
    threshold
        The printing threshold used, if reported (e.g. 0.05).
    bond_orders
        Per-pair bond orders.
    """

    method: str
    threshold: float | None = None
    bond_orders: list[BondOrder] = field(default_factory=list)

    def to_dict(self) -> dict[str, Any]:
        return {
            "method": self.method,
            "threshold": self.threshold,
            "bond_orders": [asdict(b) for b in self.bond_orders],
        }

CLRKMatrix dataclass

Bases: ParsedMultiwfnResult

Condensed linear response kernel matrix (atom × atom).

Source code in src/pymultiwfn/analysis/result.py
925
926
927
928
929
930
@dataclass
class CLRKMatrix(ParsedMultiwfnResult):
    """Condensed linear response kernel matrix (atom × atom)."""

    n_atoms: int = 0
    data: dict[tuple[int, int], float] = field(default_factory=dict)

Charge dataclass

Bases: ParsedMultiwfnResult

Single atomic charge entry.

Source code in src/pymultiwfn/analysis/result.py
222
223
224
225
226
227
@dataclass
class Charge(ParsedMultiwfnResult):
    """Single atomic charge entry."""

    atom_id: int
    charge: float

ChargeSet dataclass

Bases: ParsedMultiwfnResult

A complete set of atomic charges from one method.

Parameters

method Standardized method identifier. One of: "mulliken", "lowdin", "hirshfeld", "vdd", "scpa", "stout_politzer", "bickelhaupt", "becke", "adch", "chelpg", "mk", "aim", "hirshfeld_i", "cm5", "eem", "resp", "gasteiger", "mbis", "ddec", "esp" (for raw ESP fit), "population" (for Mulliken/Lowdin gross populations). stage For methods with multiple stages (e.g. RESP stage 1/2), the stage identifier. "final" for the final normalized charges. "corrected" for ADC-corrected intermediate. "raw" for the raw/unnormalized charges. None if there is only one stage. charges Per-atom charges. total_charge Sum of all charges, if reported in the output.

Source code in src/pymultiwfn/analysis/result.py
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
@dataclass
class ChargeSet(ParsedMultiwfnResult):
    """A complete set of atomic charges from one method.

    Parameters
    ----------
    method
        Standardized method identifier.  One of: ``"mulliken"``,
        ``"lowdin"``, ``"hirshfeld"``, ``"vdd"``, ``"scpa"``,
        ``"stout_politzer"``, ``"bickelhaupt"``, ``"becke"``,
        ``"adch"``, ``"chelpg"``, ``"mk"``, ``"aim"``,
        ``"hirshfeld_i"``, ``"cm5"``, ``"eem"``, ``"resp"``,
        ``"gasteiger"``, ``"mbis"``, ``"ddec"``,
        ``"esp"`` (for raw ESP fit), ``"population"`` (for
        Mulliken/Lowdin gross populations).
    stage
        For methods with multiple stages (e.g. RESP stage 1/2),
        the stage identifier.  ``"final"`` for the final normalized
        charges.  ``"corrected"`` for ADC-corrected intermediate.
        ``"raw"`` for the raw/unnormalized charges.  ``None`` if
        there is only one stage.
    charges
        Per-atom charges.
    total_charge
        Sum of all charges, if reported in the output.
    """

    method: str
    stage: str | None = None
    charges: list[Charge] = field(default_factory=list)
    total_charge: float | None = None

    def to_dict(self) -> dict[str, Any]:
        return {
            "method": self.method,
            "stage": self.stage,
            "charges": [asdict(c) for c in self.charges],
            "total_charge": self.total_charge,
        }

ChargeTransfer dataclass

Bases: ParsedMultiwfnResult

Result for charge transfer analysis.

Source code in src/pymultiwfn/analysis/result.py
1007
1008
1009
1010
1011
1012
1013
@dataclass
class ChargeTransfer(ParsedMultiwfnResult):
    """Result for charge transfer analysis."""

    distance: float | None = None
    transfer_amount: float | None = None
    fragments: list[ChargeTransferFragment] | None = None

ChargeTransferFragment dataclass

Bases: ParsedMultiwfnResult

Individual fragment contribution to charge transfer analysis.

Source code in src/pymultiwfn/analysis/result.py
 998
 999
1000
1001
1002
1003
1004
@dataclass
class ChargeTransferFragment(ParsedMultiwfnResult):
    """Individual fragment contribution to charge transfer analysis."""

    fragment_id: int
    hole_contribution: float
    electron_contribution: float

CoefficientMatrix dataclass

Bases: ParsedMultiwfnResult

MO coefficient matrix (basis x orbitals) for one sequence.

Rows are basis functions, columns are orbital indices. Stored as a flat dict mapping (row, col) to the coefficient value, to avoid importing numpy.

Source code in src/pymultiwfn/analysis/result.py
182
183
184
185
186
187
188
189
190
191
192
193
194
@dataclass
class CoefficientMatrix(ParsedMultiwfnResult):
    """MO coefficient matrix (basis x orbitals) for one sequence.

    Rows are basis functions, columns are orbital indices.
    Stored as a flat dict mapping ``(row, col)`` to the coefficient
    value, to avoid importing numpy.
    """

    label: str = ""
    n_basis: int = 0
    n_orbitals: int = 0
    data: dict[tuple[int, int], float] = field(default_factory=dict)

Color dataclass

Bases: ParsedMultiwfnResult

Result for color prediction in CIE XYZ color space and RGB values.

Source code in src/pymultiwfn/analysis/result.py
570
571
572
573
574
575
576
577
578
579
@dataclass
class Color(ParsedMultiwfnResult):
    """Result for color prediction in CIE XYZ color space and RGB values."""

    X: float
    Y: float  # noqa: E741
    Z: float
    R: int
    G: int
    B: int

CondensedFukui dataclass

Bases: ParsedMultiwfnResult

Result for condensed Fukui functions.

Source code in src/pymultiwfn/analysis/result.py
1190
1191
1192
1193
1194
1195
1196
1197
@dataclass
class CondensedFukui(ParsedMultiwfnResult):
    """Result for condensed Fukui functions."""

    atom_id: int
    fukui_plus: float | None = None
    fukui_minus: float | None = None
    fukui_zero: float | None = None

CoordinationNumber dataclass

Bases: ParsedMultiwfnResult

Result for coordination numbers.

Source code in src/pymultiwfn/analysis/result.py
1445
1446
1447
1448
1449
1450
@dataclass
class CoordinationNumber(ParsedMultiwfnResult):
    """Result for coordination numbers."""

    atom_id: int
    coordination_number: float

CorrelationIndex dataclass

Bases: ParsedMultiwfnResult

Result for correlation index analysis.

Source code in src/pymultiwfn/analysis/result.py
1453
1454
1455
1456
1457
1458
1459
@dataclass
class CorrelationIndex(ParsedMultiwfnResult):
    """Result for correlation index analysis."""

    nondynamic_correlation_index: float
    dynamic_correlation_index: float
    total_correlation_index: float

CriticalPoint dataclass

Bases: ParsedMultiwfnResult

Critical point from topology summary output.

Source code in src/pymultiwfn/analysis/result.py
65
66
67
68
69
70
71
72
73
74
75
76
77
@dataclass
class CriticalPoint(ParsedMultiwfnResult):
    """Critical point from topology summary output."""

    index: int
    x: float
    y: float
    z: float
    type: Literal["nuclear", "bond", "ring", "cage", "unknown"] = "unknown"
    nucleus_atom_id: int | None = None
    nucleus_element: str | None = None
    bonded_atom1_id: int | None = None
    bonded_atom2_id: int | None = None

Cube dataclass

Bases: ParsedMultiwfnResult

Result for a single cube/grid calculation sequence.

Source code in src/pymultiwfn/analysis/result.py
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
@dataclass
class Cube(ParsedMultiwfnResult):
    """Result for a single cube/grid calculation sequence."""

    file_name: str = ""
    origin_x: float | None = None
    origin_y: float | None = None
    origin_z: float | None = None
    end_x: float | None = None
    end_y: float | None = None
    end_z: float | None = None
    spacing_x: float | None = None
    spacing_y: float | None = None
    spacing_z: float | None = None
    x_dim: int = 0
    y_dim: int = 0
    z_dim: int = 0
    total_points: int = 0
    minimum: GridExtremum | None = None
    maximum: GridExtremum | None = None
    integral_total: float | None = None
    integral_positive: float | None = None
    integral_negative: float | None = None

DOSMetadata dataclass

Bases: ParsedMultiwfnResult

Metadata from density of states calculation.

Parameters

tdos_center_au Center of TDOS in Hartree, if reported. homo_level_au HOMO energy level used for the vertical dash line, in Hartree.

Source code in src/pymultiwfn/analysis/result.py
472
473
474
475
476
477
478
479
480
481
482
483
484
485
@dataclass
class DOSMetadata(ParsedMultiwfnResult):
    """Metadata from density of states calculation.

    Parameters
    ----------
    tdos_center_au
        Center of TDOS in Hartree, if reported.
    homo_level_au
        HOMO energy level used for the vertical dash line, in Hartree.
    """

    tdos_center_au: float | None = None
    homo_level_au: float | None = None

DelocalizationIndex dataclass

Bases: ParsedMultiwfnResult

Pairwise delocalization index between two atoms.

Source code in src/pymultiwfn/analysis/result.py
956
957
958
959
960
961
962
@dataclass
class DelocalizationIndex(ParsedMultiwfnResult):
    """Pairwise delocalization index between two atoms."""

    atom1_id: int
    atom2_id: int
    index: float

DelocalizationIndexMatrix dataclass

Bases: ParsedMultiwfnResult

Full delocalization index matrix (atom × atom).

Diagonal elements are localization indices (or atomic valence for closed-shell). The label distinguishes "Total" from regular DI matrices.

Source code in src/pymultiwfn/analysis/result.py
885
886
887
888
889
890
891
892
893
894
895
896
897
@dataclass
class DelocalizationIndexMatrix(ParsedMultiwfnResult):
    """Full delocalization index matrix (atom × atom).

    Diagonal elements are localization indices (or atomic valence
    for closed-shell).  The ``label`` distinguishes "Total" from
    regular DI matrices.
    """

    label: str = ""
    n_atoms: int = 0
    data: dict[tuple[int, int], float] = field(default_factory=dict)
    localization_indices: list[LocalizationIndex] = field(default_factory=list)

DeltaR dataclass

Bases: ParsedMultiwfnResult

Result for Delta_r index.

Source code in src/pymultiwfn/analysis/result.py
1016
1017
1018
1019
1020
1021
@dataclass
class DeltaR(ParsedMultiwfnResult):
    """Result for Delta_r index."""

    state_id: int
    delta_r: float

DensityMatrix dataclass

Bases: ParsedMultiwfnResult

Density matrix (symmetric, basis x basis) for one sequence.

Lower-triangle storage: keys (row, col) with row >= col.

Source code in src/pymultiwfn/analysis/result.py
197
198
199
200
201
202
203
204
205
206
207
208
@dataclass
class DensityMatrix(ParsedMultiwfnResult):
    """Density matrix (symmetric, basis x basis) for one sequence.

    Lower-triangle storage: keys ``(row, col)`` with ``row >= col``.
    """

    label: str = ""
    n_basis: int = 0
    data: dict[tuple[int, int], float] = field(default_factory=dict)
    trace: float | None = None
    trace_overlap: float | None = None

DensityOfStates dataclass

Bases: ParsedMultiwfnResult

Discrete DOS/PDOS arrays sampled on an energy grid.

Source code in src/pymultiwfn/analysis/result.py
488
489
490
491
492
493
494
@dataclass
class DensityOfStates(ParsedMultiwfnResult):
    """Discrete DOS/PDOS arrays sampled on an energy grid."""

    energies_eV: list[float] = field(default_factory=list)  # noqa: N815
    dos: list[float] = field(default_factory=list)
    projected_dos: dict[str, list[float]] | None = None

DihedralAngle dataclass

Bases: ParsedMultiwfnResult

Result for dihedral angle analysis.

Source code in src/pymultiwfn/analysis/result.py
1377
1378
1379
1380
1381
1382
1383
1384
1385
@dataclass
class DihedralAngle(ParsedMultiwfnResult):
    """Result for dihedral angle analysis."""

    atom1_id: int
    atom2_id: int
    atom3_id: int
    atom4_id: int
    angle: float

Dipole dataclass

Bases: ParsedMultiwfnResult

Result for dipole moment analysis.

Source code in src/pymultiwfn/analysis/result.py
271
272
273
274
275
276
277
278
@dataclass
class Dipole(ParsedMultiwfnResult):
    """Result for dipole moment analysis."""

    x: float
    y: float
    z: float
    total: float

DipoleMoment dataclass

Bases: Dipole

Utility-menu dipole vector (same data model as :class:Dipole).

Source code in src/pymultiwfn/analysis/result.py
1388
1389
1390
@dataclass
class DipoleMoment(Dipole):
    """Utility-menu dipole vector (same data model as :class:`Dipole`)."""

DispersionContribution dataclass

Bases: ParsedMultiwfnResult

Result for dispersion contributions.

Source code in src/pymultiwfn/analysis/result.py
1156
1157
1158
1159
1160
1161
@dataclass
class DispersionContribution(ParsedMultiwfnResult):
    """Result for dispersion contributions."""

    atom_id: int
    contribution: float

DualDescriptor dataclass

Bases: ParsedMultiwfnResult

Result for dual descriptor.

Source code in src/pymultiwfn/analysis/result.py
1200
1201
1202
1203
1204
1205
@dataclass
class DualDescriptor(ParsedMultiwfnResult):
    """Result for dual descriptor."""

    atom_id: int
    value: float

ElectricMultipoleMomentReport dataclass

Bases: ParsedMultiwfnResult

Comprehensive electric multipole report for Menu 300.

Source code in src/pymultiwfn/analysis/result.py
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
@dataclass
class ElectricMultipoleMomentReport(ParsedMultiwfnResult):
    """Comprehensive electric multipole report for Menu 300."""

    positive_charge_center_angstrom: tuple[float, float, float] | None = None
    negative_charge_center_angstrom: tuple[float, float, float] | None = None
    nuclear_dipole_au: tuple[float, float, float] | None = None
    electronic_dipole_au: tuple[float, float, float] | None = None
    total_dipole_au: tuple[float, float, float] | None = None
    total_dipole_debye: tuple[float, float, float] | None = None
    dipole_magnitude_au: float | None = None
    dipole_magnitude_debye: float | None = None
    quadrupole_standard_cartesian: dict[str, float] = field(
        default_factory=dict
    )
    quadrupole_traceless_cartesian: dict[str, float] = field(
        default_factory=dict
    )
    quadrupole_traceless_magnitude: float | None = None
    quadrupole_spherical_harmonic: dict[str, float] = field(
        default_factory=dict
    )
    quadrupole_spherical_magnitude: float | None = None
    octopole_cartesian: dict[str, float] = field(default_factory=dict)
    octopole_spherical_harmonic: dict[str, float] = field(default_factory=dict)
    octopole_spherical_magnitude: float | None = None
    hexadecapole: dict[str, float] = field(default_factory=dict)
    electronic_spatial_extent_r2: float | None = None
    electronic_spatial_extent_components: tuple[float, float, float] | None = (
        None
    )

EnergyDecompositionAnalysis dataclass

Bases: ParsedMultiwfnResult

Result for energy decomposition analysis.

Source code in src/pymultiwfn/analysis/result.py
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
@dataclass
class EnergyDecompositionAnalysis(ParsedMultiwfnResult):
    """Result for energy decomposition analysis."""

    electrostatic: float | None = None
    exchange: float | None = None
    repulsion: float | None = None
    polarization: float | None = None
    dispersion: float | None = None
    orbital_interaction: float | None = None
    total_interaction: float | None = None

ExportedMatrix dataclass

Bases: ParsedMultiwfnResult

Record that a matrix was exported to a file.

Source code in src/pymultiwfn/analysis/result.py
211
212
213
214
215
216
@dataclass
class ExportedMatrix(ParsedMultiwfnResult):
    """Record that a matrix was exported to a file."""

    file_name: str = ""
    label: str = ""

FLUReferenceParameter dataclass

Bases: ParsedMultiwfnResult

FLU reference bond order for one element pair.

Source code in src/pymultiwfn/analysis/result.py
936
937
938
939
940
941
942
@dataclass
class FLUReferenceParameter(ParsedMultiwfnResult):
    """FLU reference bond order for one element pair."""

    element1: str
    element2: str
    reference_value: float

FuzzyIntegrationEntry dataclass

Single atom entry in a fuzzy integration table.

Source code in src/pymultiwfn/analysis/result.py
743
744
745
746
747
748
749
750
751
@dataclass
class FuzzyIntegrationEntry:
    """Single atom entry in a fuzzy integration table."""

    atom_id: int
    atom_element: str
    value: float
    pct_of_sum: float
    pct_of_sum_abs: float

FuzzyIntegrationResult dataclass

Bases: ParsedMultiwfnResult

Result of fuzzy space integration for one property.

Parameters

integrated_property Standardized identifier: "edensity", "norm_rho", "laplacian", "orb_wfn_homo", "orb_wfn_lumo", "espin_density", "kr", "gr", "esp_charges", "elf", "lol", "local_entropy", "esp", "rdg", "rdg_promolecular", "lambda2rho", "lambda2rho_promolecular", "alie", "edr", "orb_overlap_dr", "deltag_promolecular", "deltag_hirshfeld", "iri".

Source code in src/pymultiwfn/analysis/result.py
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
@dataclass
class FuzzyIntegrationResult(ParsedMultiwfnResult):
    """Result of fuzzy space integration for one property.

    Parameters
    ----------
    integrated_property
        Standardized identifier: ``"edensity"``, ``"norm_rho"``,
        ``"laplacian"``, ``"orb_wfn_homo"``, ``"orb_wfn_lumo"``,
        ``"espin_density"``, ``"kr"``, ``"gr"``, ``"esp_charges"``,
        ``"elf"``, ``"lol"``, ``"local_entropy"``, ``"esp"``,
        ``"rdg"``, ``"rdg_promolecular"``, ``"lambda2rho"``,
        ``"lambda2rho_promolecular"``, ``"alie"``, ``"edr"``,
        ``"orb_overlap_dr"``, ``"deltag_promolecular"``,
        ``"deltag_hirshfeld"``, ``"iri"``.
    """

    integrated_property: str
    entries: list[FuzzyIntegrationEntry] = field(default_factory=list)
    total_sum: float | None = None
    total_sum_abs: float | None = None

GaussianTypeFunction dataclass

Bases: ParsedMultiwfnResult

Single Gaussian-type function (GTF) from basis set info.

Source code in src/pymultiwfn/analysis/result.py
158
159
160
161
162
163
164
165
166
@dataclass
class GaussianTypeFunction(ParsedMultiwfnResult):
    """Single Gaussian-type function (GTF) from basis set info."""

    gtf_index: int
    center_atom_id: int
    center_element: str
    function_type: str
    exponent: float

GridExtremum dataclass

Position and value of a grid minimum or maximum.

Source code in src/pymultiwfn/analysis/result.py
122
123
124
125
126
127
128
129
@dataclass
class GridExtremum:
    """Position and value of a grid minimum or maximum."""

    value: float
    x_bohr: float
    y_bohr: float
    z_bohr: float

HOMOLUMOGap dataclass

Bases: ParsedMultiwfnResult

HOMO-LUMO gap information.

Source code in src/pymultiwfn/analysis/result.py
47
48
49
50
51
52
53
54
55
56
57
58
59
@dataclass
class HOMOLUMOGap(ParsedMultiwfnResult):
    """HOMO-LUMO gap information."""

    homo_index: int
    homo_energy_au: float
    homo_energy_eV: float  # noqa: N815
    lumo_index: int
    lumo_energy_au: float
    lumo_energy_eV: float  # noqa: N815
    gap_au: float
    gap_eV: float  # noqa: N815
    gap_kJ_mol: float  # noqa: N815

HoleElectron dataclass

Bases: ParsedMultiwfnResult

Result for hole-electron analysis.

Source code in src/pymultiwfn/analysis/result.py
983
984
985
986
987
988
989
990
991
992
993
994
995
@dataclass
class HoleElectron(ParsedMultiwfnResult):
    """Result for hole-electron analysis."""

    hole_id: float
    electron_id: float
    transition_index: float
    electron_delocalisation_index: float
    hole_delocalisation_index: float
    Sr: float
    d_index: float
    hole_centroid: tuple[float, float, float] = (0.0, 0.0, 0.0)
    electron_centroid: tuple[float, float, float] = (0.0, 0.0, 0.0)

IBSIAnalysis dataclass

Bases: ParsedMultiwfnResult

Complete IBSI analysis result set.

Source code in src/pymultiwfn/analysis/result.py
457
458
459
460
461
462
463
464
465
466
@dataclass
class IBSIAnalysis(ParsedMultiwfnResult):
    """Complete IBSI analysis result set."""

    entries: list[IBSIEntry] = field(default_factory=list)

    def to_dict(self) -> dict[str, Any]:
        return {
            "entries": [asdict(e) for e in self.entries],
        }

IBSIEntry dataclass

Bases: ParsedMultiwfnResult

Single IBSI analysis entry between two atoms.

Source code in src/pymultiwfn/analysis/result.py
446
447
448
449
450
451
452
453
454
@dataclass
class IBSIEntry(ParsedMultiwfnResult):
    """Single IBSI analysis entry between two atoms."""

    atom1_id: int
    atom2_id: int
    distance: float
    int_dg_pair: float
    ibsi: float

LMOAtomContribution dataclass

Single atom contribution to a localized molecular orbital.

Source code in src/pymultiwfn/analysis/result.py
1035
1036
1037
1038
1039
1040
1041
@dataclass
class LMOAtomContribution:
    """Single atom contribution to a localized molecular orbital."""

    atom_id: int
    atom_element: str
    contribution_pct: float

LambdaIndex dataclass

Bases: ParsedMultiwfnResult

Result for Lambda index.

Source code in src/pymultiwfn/analysis/result.py
1024
1025
1026
1027
1028
1029
@dataclass
class LambdaIndex(ParsedMultiwfnResult):
    """Result for Lambda index."""

    state_id: int
    lambda_index: float

LocalizationConvergence dataclass

Convergence history for one localization run.

Parameters

orbital_set Which orbitals were localized: "occupied" or "unoccupied" or "all". n_cycles Number of cycles to convergence. final_p Final value of the localization functional p. converged Whether the localization converged successfully.

Source code in src/pymultiwfn/analysis/result.py
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
@dataclass
class LocalizationConvergence:
    """Convergence history for one localization run.

    Parameters
    ----------
    orbital_set
        Which orbitals were localized: ``"occupied"`` or
        ``"unoccupied"`` or ``"all"``.
    n_cycles
        Number of cycles to convergence.
    final_p
        Final value of the localization functional p.
    converged
        Whether the localization converged successfully.
    """

    orbital_set: str
    n_cycles: int = 0
    final_p: float | None = None
    converged: bool = False

LocalizationIndex dataclass

Bases: ParsedMultiwfnResult

Localization index for one atom.

Source code in src/pymultiwfn/analysis/result.py
876
877
878
879
880
881
882
@dataclass
class LocalizationIndex(ParsedMultiwfnResult):
    """Localization index for one atom."""

    atom_id: int
    index: float
    atom_element: str | None = None

LocalizedOrbital dataclass

Character of a single localized molecular orbital.

Parameters

orbital_id 1-based LMO index. category One of "single_center", "two_center", "delocalized". contributions Atom contributions listed for this LMO, ordered by decreasing percentage.

Source code in src/pymultiwfn/analysis/result.py
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
@dataclass
class LocalizedOrbital:
    """Character of a single localized molecular orbital.

    Parameters
    ----------
    orbital_id
        1-based LMO index.
    category
        One of ``"single_center"``, ``"two_center"``,
        ``"delocalized"``.
    contributions
        Atom contributions listed for this LMO, ordered by
        decreasing percentage.
    """

    orbital_id: int
    category: Literal["single_center", "two_center", "delocalized"]
    contributions: list[LMOAtomContribution] = field(default_factory=list)

MolecularMultipole dataclass

Bases: ParsedMultiwfnResult

Molecular dipole and multipole moments.

Source code in src/pymultiwfn/analysis/result.py
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
@dataclass
class MolecularMultipole(ParsedMultiwfnResult):
    """Molecular dipole and multipole moments."""

    total_electrons: float | None = None
    net_charge: float | None = None

    # Dipole
    dipole_x_au: float | None = None
    dipole_y_au: float | None = None
    dipole_z_au: float | None = None
    dipole_magnitude_au: float | None = None
    dipole_x_debye: float | None = None
    dipole_y_debye: float | None = None
    dipole_z_debye: float | None = None
    dipole_magnitude_debye: float | None = None

    # Quadrupole (traceless Cartesian)
    quadrupole_xx: float | None = None
    quadrupole_xy: float | None = None
    quadrupole_xz: float | None = None
    quadrupole_yy: float | None = None
    quadrupole_yz: float | None = None
    quadrupole_zz: float | None = None
    quadrupole_magnitude: float | None = None

    # Spatial extent
    spatial_extent_r2: float | None = None
    spatial_extent_x: float | None = None
    spatial_extent_y: float | None = None
    spatial_extent_z: float | None = None

    # Octopole magnitude
    octopole_magnitude: float | None = None

MultiCenterBondOrder dataclass

Bases: ParsedMultiwfnResult

Result for multi-center bond order analysis.

Source code in src/pymultiwfn/analysis/result.py
438
439
440
441
442
443
@dataclass
class MultiCenterBondOrder(ParsedMultiwfnResult):
    """Result for multi-center bond order analysis."""

    atom_ids: list[int] = field(default_factory=list)
    bond_order: float = 0.0

MultipoleMoments dataclass

Bases: ParsedMultiwfnResult

Result for multipole moments.

Source code in src/pymultiwfn/analysis/result.py
1405
1406
1407
1408
1409
@dataclass
class MultipoleMoments(ParsedMultiwfnResult):
    """Result for multipole moments."""

    moments: dict[str, float] = field(default_factory=dict)

MultiwfnResult

Container for parsed Multiwfn analysis results.

Each instance is bound to a single :class:Menu analysis type. After :meth:parse is called with raw stdout, the parsed :class:ParsedMultiwfnResult objects are available in :attr:result.

Parameters

analysis The Menu enum member identifying this analysis.

Source code in src/pymultiwfn/analysis/result.py
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
class MultiwfnResult:
    """Container for parsed Multiwfn analysis results.

    Each instance is bound to a single :class:`Menu` analysis type.
    After :meth:`parse` is called with raw stdout, the parsed
    :class:`ParsedMultiwfnResult` objects are available in
    :attr:`result`.

    Parameters
    ----------
    analysis
        The Menu enum member identifying this analysis.

    """

    def __init__(self, analysis: Menu) -> None:
        self.analysis: Menu = analysis
        self.result: list[ParsedMultiwfnResult] = []

    def parse(self, stdout: str) -> None:
        """Parse *stdout* using the router and store results.

        Imports :class:`ParserRoute` lazily to avoid circular imports
        (parsers.py imports dataclasses from this module).
        """
        from pymultiwfn.analysis.parsers import ParserRoute

        parser_cls = ParserRoute.ROUTE_TABLE.get(self.analysis)
        if parser_cls is None:
            return

        parsed = parser_cls.parse_for_result(self.analysis, stdout)
        if parsed:
            self.result.extend(parsed)

    # ── serialisation ────────────────────────────────────────────────────

    def to_dict(self) -> dict[str, Any]:
        """Serialise the result list to a JSON-safe dict."""
        return {
            "analysis": self.analysis.name,
            "results": [r.to_dict() for r in self.result],
        }

    def __repr__(self) -> str:
        return (
            f"MultiwfnResult(analysis={self.analysis.name!r}, "
            f"n_results={len(self.result)})"
        )

parse(stdout)

Parse stdout using the router and store results.

Imports :class:ParserRoute lazily to avoid circular imports (parsers.py imports dataclasses from this module).

Source code in src/pymultiwfn/analysis/result.py
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
def parse(self, stdout: str) -> None:
    """Parse *stdout* using the router and store results.

    Imports :class:`ParserRoute` lazily to avoid circular imports
    (parsers.py imports dataclasses from this module).
    """
    from pymultiwfn.analysis.parsers import ParserRoute

    parser_cls = ParserRoute.ROUTE_TABLE.get(self.analysis)
    if parser_cls is None:
        return

    parsed = parser_cls.parse_for_result(self.analysis, stdout)
    if parsed:
        self.result.extend(parsed)

to_dict()

Serialise the result list to a JSON-safe dict.

Source code in src/pymultiwfn/analysis/result.py
1512
1513
1514
1515
1516
1517
def to_dict(self) -> dict[str, Any]:
    """Serialise the result list to a JSON-safe dict."""
    return {
        "analysis": self.analysis.name,
        "results": [r.to_dict() for r in self.result],
    }

NICSScan dataclass

Bases: ParsedMultiwfnResult

Result for Nucleus Independent Chemical Shift scan.

Source code in src/pymultiwfn/analysis/result.py
1347
1348
1349
1350
1351
1352
@dataclass
class NICSScan(ParsedMultiwfnResult):
    """Result for Nucleus Independent Chemical Shift scan."""

    distances: list[float] = field(default_factory=list)
    values: list[float] = field(default_factory=list)

Orbital dataclass

Bases: ParsedMultiwfnResult

Orbital descriptor used by wavefunction and DOS parsers.

Source code in src/pymultiwfn/analysis/result.py
551
552
553
554
555
556
557
558
559
@dataclass
class Orbital(ParsedMultiwfnResult):
    """Orbital descriptor used by wavefunction and DOS parsers."""

    orbital_id: int
    energy_au: float
    energy_eV: float  # noqa: N815
    occupation: float | None = None
    spin: Literal["alpha", "beta"] | None = None

OrbitalAtomComposition dataclass

Bases: ParsedMultiwfnResult

Per-atom contribution to an orbital (Hirshfeld/Becke/fragment methods).

Simpler than OrbitalBasisComposition — only atom-level contributions are available, no basis/shell breakdown.

Source code in src/pymultiwfn/analysis/result.py
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
@dataclass
class OrbitalAtomComposition(ParsedMultiwfnResult):
    """Per-atom contribution to an orbital (Hirshfeld/Becke/fragment methods).

    Simpler than ``OrbitalBasisComposition`` — only atom-level
    contributions are available, no basis/shell breakdown.
    """

    method: str
    orbital_id: int
    energy_au: float
    occupation: float
    orbital_type: str = ""

    atom_contributions: list[OrbitalAtomEntry] = field(default_factory=list)
    delocalization_index: float | None = None
    sum_before_normalization: float | None = None

OrbitalAtomEntry dataclass

Single atom contribution to an orbital.

Source code in src/pymultiwfn/analysis/result.py
350
351
352
353
354
355
356
@dataclass
class OrbitalAtomEntry:
    """Single atom contribution to an orbital."""

    atom_id: int
    atom_element: str
    composition_pct: float

OrbitalBasisComposition dataclass

Bases: ParsedMultiwfnResult

Per-basis-function contribution to an orbital.

Each orbital that has detailed composition output produces one of these containers. The method field distinguishes which decomposition scheme was used (Mulliken/SCPA/Stout-Politzer).

Source code in src/pymultiwfn/analysis/result.py
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
@dataclass
class OrbitalBasisComposition(ParsedMultiwfnResult):
    """Per-basis-function contribution to an orbital.

    Each orbital that has detailed composition output produces one
    of these containers.  The ``method`` field distinguishes which
    decomposition scheme was used (Mulliken/SCPA/Stout-Politzer).
    """

    method: str
    orbital_id: int
    energy_au: float
    occupation: float
    orbital_type: str = ""

    # Per-basis contributions
    basis_contributions: list[OrbitalBasisEntry] = field(default_factory=list)

    # Per-shell contributions
    shell_contributions: list[OrbitalShellEntry] = field(default_factory=list)

    # Per-shell-type (angular momentum) contributions
    shell_type_composition: OrbitalShellTypeComposition | None = None

    # Per-atom contributions
    atom_contributions: list[OrbitalAtomEntry] = field(default_factory=list)

    # Summary
    delocalization_index: float | None = None

OrbitalBasisEntry dataclass

Single basis function contribution to an orbital.

Source code in src/pymultiwfn/analysis/result.py
313
314
315
316
317
318
319
320
321
322
323
324
@dataclass
class OrbitalBasisEntry:
    """Single basis function contribution to an orbital."""

    basis_index: int
    function_type: str
    atom_id: int
    atom_element: str
    shell_index: int
    local_pct: float
    cross_pct: float
    total_pct: float

OrbitalEnergy dataclass

Bases: ParsedMultiwfnResult

Orbital energy and occupation entry.

Source code in src/pymultiwfn/analysis/result.py
497
498
499
500
501
502
503
@dataclass
class OrbitalEnergy(ParsedMultiwfnResult):
    """Orbital energy and occupation entry."""

    index: int
    energy_eV: float  # noqa: N815
    occupation: float

OrbitalLocalizationResult dataclass

Bases: ParsedMultiwfnResult

Complete result for one orbital localization run.

Each Menu sequence (e.g. Pipek-Mezey/Hirshfeld/occupied) produces one of these. The method, population_scheme, and orbital_set together uniquely identify the calculation.

Parameters

method Localization method: "pipek_mezey" or "boys". population_scheme Population analysis used for Pipek-Mezey: "hirshfeld", "lowdin", "becke". None for Boys. orbital_set Which orbitals: "occupied", "all". convergence Convergence history for each sub-run (occupied and/or unoccupied). occupied_lmos Character of occupied LMOs. unoccupied_lmos Character of unoccupied LMOs (only present for "all" runs). exported_file Name of the exported file, if any.

Source code in src/pymultiwfn/analysis/result.py
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
@dataclass
class OrbitalLocalizationResult(ParsedMultiwfnResult):
    """Complete result for one orbital localization run.

    Each ``Menu`` sequence (e.g. Pipek-Mezey/Hirshfeld/occupied)
    produces one of these.  The ``method``, ``population_scheme``,
    and ``orbital_set`` together uniquely identify the calculation.

    Parameters
    ----------
    method
        Localization method: ``"pipek_mezey"`` or ``"boys"``.
    population_scheme
        Population analysis used for Pipek-Mezey: ``"hirshfeld"``,
        ``"lowdin"``, ``"becke"``.  ``None`` for Boys.
    orbital_set
        Which orbitals: ``"occupied"``, ``"all"``.
    convergence
        Convergence history for each sub-run (occupied and/or
        unoccupied).
    occupied_lmos
        Character of occupied LMOs.
    unoccupied_lmos
        Character of unoccupied LMOs (only present for "all"
        runs).
    exported_file
        Name of the exported file, if any.
    """

    method: str
    population_scheme: str | None = None
    orbital_set: str = ""

    convergence: list[LocalizationConvergence] = field(default_factory=list)
    occupied_lmos: list[LocalizedOrbital] = field(default_factory=list)
    unoccupied_lmos: list[LocalizedOrbital] = field(default_factory=list)
    exported_file: str | None = None

OrbitalShellEntry dataclass

Single shell contribution to an orbital.

Source code in src/pymultiwfn/analysis/result.py
327
328
329
330
331
332
333
334
335
@dataclass
class OrbitalShellEntry:
    """Single shell contribution to an orbital."""

    shell_index: int
    shell_type: str
    atom_id: int
    atom_element: str
    composition_pct: float

OrbitalShellTypeComposition dataclass

Angular momentum type composition of an orbital.

Source code in src/pymultiwfn/analysis/result.py
338
339
340
341
342
343
344
345
346
347
@dataclass
class OrbitalShellTypeComposition:
    """Angular momentum type composition of an orbital."""

    s: float = 0.0
    p: float = 0.0
    d: float = 0.0
    f: float = 0.0
    g: float = 0.0
    h: float = 0.0

OrbitalWeightDecomposition dataclass

Bases: ParsedMultiwfnResult

Decomposition of orbital-weighted Fukui into orbital contributions.

Parameters

fukui_type Which Fukui function: "f+", "f-".

Source code in src/pymultiwfn/analysis/result.py
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
@dataclass
class OrbitalWeightDecomposition(ParsedMultiwfnResult):
    """Decomposition of orbital-weighted Fukui into orbital contributions.

    Parameters
    ----------
    fukui_type
        Which Fukui function: ``"f+"``, ``"f-"``.
    """

    fukui_type: str
    entries: list[OrbitalWeightEntry] = field(default_factory=list)
    total_weight_pct: float | None = None

OrbitalWeightEntry dataclass

Single orbital's weight in f+ or f- decomposition.

Source code in src/pymultiwfn/analysis/result.py
1278
1279
1280
1281
1282
1283
1284
1285
@dataclass
class OrbitalWeightEntry:
    """Single orbital's weight in f+ or f- decomposition."""

    orbital_id: int
    orbital_label: str
    weight_pct: float
    e_diff_eV: float  # noqa: N815

OrbitalWeightedFukuiEntry dataclass

Per-atom orbital-weighted Fukui values.

Source code in src/pymultiwfn/analysis/result.py
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
@dataclass
class OrbitalWeightedFukuiEntry:
    """Per-atom orbital-weighted Fukui values."""

    atom_id: int
    atom_element: str
    ow_f_plus: float
    ow_f_minus: float
    ow_f_zero: float
    ow_dd: float

OrbitalWeightedFukuiResult dataclass

Bases: ParsedMultiwfnResult

Complete orbital-weighted Fukui analysis.

Contains per-atom values and sums of f+ and f-.

Source code in src/pymultiwfn/analysis/result.py
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
@dataclass
class OrbitalWeightedFukuiResult(ParsedMultiwfnResult):
    """Complete orbital-weighted Fukui analysis.

    Contains per-atom values and sums of f+ and f-.
    """

    entries: list[OrbitalWeightedFukuiEntry] = field(default_factory=list)
    sum_ow_f_plus: float | None = None
    sum_ow_f_minus: float | None = None

OverlapIntegrationMatrix dataclass

Bases: ParsedMultiwfnResult

Overlap region integration matrix for one sign category.

Parameters

category One of "positive", "negative", "all".

Source code in src/pymultiwfn/analysis/result.py
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
@dataclass
class OverlapIntegrationMatrix(ParsedMultiwfnResult):
    """Overlap region integration matrix for one sign category.

    Parameters
    ----------
    category
        One of ``"positive"``, ``"negative"``, ``"all"``.
    """

    category: str
    integrated_property: str = ""
    n_atoms: int = 0
    data: dict[tuple[int, int], float] = field(default_factory=dict)
    sum_diagonal: float | None = None
    sum_nondiagonal: float | None = None
    sum_all: float | None = None

OxidationState dataclass

Bases: ParsedMultiwfnResult

Integer oxidation state inferred for one atom.

Source code in src/pymultiwfn/analysis/result.py
562
563
564
565
566
567
@dataclass
class OxidationState(ParsedMultiwfnResult):
    """Integer oxidation state inferred for one atom."""

    atom_id: int
    oxidation_state: int

ParsedMultiwfnResult dataclass

Base class for all Multiwfn parsed result types.

Source code in src/pymultiwfn/analysis/result.py
23
24
25
26
27
28
29
@dataclass
class ParsedMultiwfnResult:
    """Base class for all Multiwfn parsed result types."""

    def to_dict(self) -> dict[str, Any]:
        """Serialise to a plain dict (JSON-safe)."""
        return asdict(self)

to_dict()

Serialise to a plain dict (JSON-safe).

Source code in src/pymultiwfn/analysis/result.py
27
28
29
def to_dict(self) -> dict[str, Any]:
    """Serialise to a plain dict (JSON-safe)."""
    return asdict(self)

PoincareHopfCounts dataclass

Bases: ParsedMultiwfnResult

Critical point counts and Poincare-Hopf verification.

Source code in src/pymultiwfn/analysis/result.py
108
109
110
111
112
113
114
115
116
@dataclass
class PoincareHopfCounts(ParsedMultiwfnResult):
    """Critical point counts and Poincare-Hopf verification."""

    nuclear: int = 0
    bond: int = 0
    ring: int = 0
    cage: int = 0
    satisfied: bool = False

Polarizability dataclass

Bases: ParsedMultiwfnResult

Result for polarizability.

Source code in src/pymultiwfn/analysis/result.py
1318
1319
1320
1321
1322
1323
1324
1325
1326
@dataclass
class Polarizability(ParsedMultiwfnResult):
    """Result for polarizability."""

    isotropic: float | None = None
    anisotropic: float | None = None
    beta_total: float | None = None
    gamma_total: float | None = None
    tensor: PolarizabilityTensor | None = None

PolarizabilityTensor dataclass

Bases: ParsedMultiwfnResult

Result for polarizability tensor.

Source code in src/pymultiwfn/analysis/result.py
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
@dataclass
class PolarizabilityTensor(ParsedMultiwfnResult):
    """Result for polarizability tensor."""

    alpha_xx: float = 0.0
    alpha_xy: float = 0.0
    alpha_xz: float = 0.0
    alpha_yy: float = 0.0
    alpha_yz: float = 0.0
    alpha_zz: float = 0.0

QuadrupoleMoment dataclass

Bases: ParsedMultiwfnResult

Result for quadrupole moment analysis.

Source code in src/pymultiwfn/analysis/result.py
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
@dataclass
class QuadrupoleMoment(ParsedMultiwfnResult):
    """Result for quadrupole moment analysis."""

    xx: float | None = None
    xy: float | None = None
    xz: float | None = None
    yy: float | None = None
    yz: float | None = None
    zz: float | None = None

Reactivity dataclass

Bases: ParsedMultiwfnResult

Result for global reactivity indices.

Source code in src/pymultiwfn/analysis/result.py
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
@dataclass
class Reactivity(ParsedMultiwfnResult):
    """Result for global reactivity indices."""

    chemical_potential: float | None = None
    chemical_potential_eV: float | None = None  # noqa: N815
    hardness: float | None = None
    softness: float | None = None
    electrophilicity: float | None = None
    nucleophilicity: float | None = None
    ionization_potential: float | None = None
    electron_affinity: float | None = None
    homo_energy_au: float | None = None
    homo_energy_eV: float | None = None  # noqa: N815
    lumo_energy_au: float | None = None
    lumo_energy_eV: float | None = None  # noqa: N815
    delta_parameter_au: float | None = None
    delta_parameter_eV: float | None = None  # noqa: N815

ResultStore

Per-molecule result store with optional JSON persistence.

Parsed results are always cached in memory so that :meth:has_result and :meth:get_result work regardless of whether a JSON file exists on disk.

Parameters

input_file Path to the wavefunction input file. work_dir Directory used for the working data. Created if it does not exist. json_path Controls JSON persistence:

* ``None`` (the default) — results are cached in memory only;
  no file is written to disk.
* A :class:`~pathlib.Path` — results are written to that exact
  file every time :meth:`store` is called.  If the file already
  exists it is loaded on construction so that previous results
  are available immediately.

The value can be changed at any time via the :attr:`json_path`
property.  Setting it from ``None`` to a ``Path`` will
immediately flush the current in-memory data to disk.
Source code in src/pymultiwfn/analysis/result.py
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
class ResultStore:
    """Per-molecule result store with optional JSON persistence.

    Parsed results are always cached in memory so that
    :meth:`has_result` and :meth:`get_result` work regardless of
    whether a JSON file exists on disk.

    Parameters
    ----------
    input_file
        Path to the wavefunction input file.
    work_dir
        Directory used for the working data.  Created if it does not
        exist.
    json_path
        Controls JSON persistence:

        * ``None`` (the default) — results are cached in memory only;
          no file is written to disk.
        * A :class:`~pathlib.Path` — results are written to that exact
          file every time :meth:`store` is called.  If the file already
          exists it is loaded on construction so that previous results
          are available immediately.

        The value can be changed at any time via the :attr:`json_path`
        property.  Setting it from ``None`` to a ``Path`` will
        immediately flush the current in-memory data to disk.

    """

    def __init__(
        self,
        input_file: Path,
        work_dir: Path,
        json_path: Path | None = None,
    ) -> None:
        self._input_file = Path(input_file)
        self._work_dir = Path(work_dir)
        self._work_dir.mkdir(parents=True, exist_ok=True)

        self._json_path: Path | None = (
            Path(json_path) if json_path is not None else None
        )
        self._data: dict[str, Any] = self._load()

    @property
    def json_path(self) -> Path | None:
        """Path to the JSON file, or ``None`` if persistence is disabled."""
        return self._json_path

    @json_path.setter
    def json_path(self, value: Path | None) -> None:
        self._json_path = Path(value) if value is not None else None
        if self._json_path is not None:
            # Flush current in-memory data to disk immediately.
            self._save()

    @property
    def data(self) -> dict[str, Any]:
        """Return a *copy* of the stored data."""
        return dict(self._data)

    # ── persistence ──────────────────────────────────────────────────────

    def _load(self) -> dict[str, Any]:
        if self._json_path is not None and self._json_path.exists():
            with Path.open(self._json_path, encoding="utf-8") as f:
                return json.load(f)
        return {
            "input_file": str(self._input_file),
            "analyses": {},
        }

    def _save(self) -> None:
        if self._json_path is None:
            return
        self._json_path.parent.mkdir(parents=True, exist_ok=True)
        with Path.open(self._json_path, "w", encoding="utf-8") as f:
            json.dump(self._data, f, indent=2, default=str)

    # ── read / write ─────────────────────────────────────────────────────

    def has_result(self, analysis: Menu) -> bool:
        """Check whether a parsed result already exists for *analysis*."""
        return analysis.name in self._data.get("analyses", {})

    def get_result(self, analysis: Menu) -> dict[str, Any] | None:
        """Retrieve a previously stored parsed result, or ``None``."""
        return self._data.get("analyses", {}).get(analysis.name)

    def store(self, mwfn_result: MultiwfnResult) -> None:
        """Cache a :class:`MultiwfnResult` in memory.

        If :attr:`json_path` is not ``None``, the result is also
        written to the JSON file on disk.

        Parameters
        ----------
        mwfn_result
            A fully parsed ``MultiwfnResult`` whose ``.result`` list
            is non-empty.

        """
        if not mwfn_result.result:
            return

        entry: dict[str, Any] = {
            "parsed": mwfn_result.to_dict(),
            "timestamp": datetime.now().isoformat(),
        }
        self._data.setdefault("analyses", {})[mwfn_result.analysis.name] = (
            entry
        )
        self._save()

    def store_from_stdout(
        self,
        analysis: Menu,
        stdout: str,
    ) -> MultiwfnResult | None:
        """Parse *stdout*, persist, and return the :class:`MultiwfnResult`.

        Convenience method combining :meth:`MultiwfnResult.parse` and
        :meth:`store` in a single call.

        Returns ``None`` if no parser is available or parsing yields no
        results.
        """
        result = MultiwfnResult(analysis=analysis)
        result.parse(stdout)
        if not result.result:
            return None
        self.store(result)
        return result

data property

Return a copy of the stored data.

json_path property writable

Path to the JSON file, or None if persistence is disabled.

get_result(analysis)

Retrieve a previously stored parsed result, or None.

Source code in src/pymultiwfn/analysis/result.py
1617
1618
1619
def get_result(self, analysis: Menu) -> dict[str, Any] | None:
    """Retrieve a previously stored parsed result, or ``None``."""
    return self._data.get("analyses", {}).get(analysis.name)

has_result(analysis)

Check whether a parsed result already exists for analysis.

Source code in src/pymultiwfn/analysis/result.py
1613
1614
1615
def has_result(self, analysis: Menu) -> bool:
    """Check whether a parsed result already exists for *analysis*."""
    return analysis.name in self._data.get("analyses", {})

store(mwfn_result)

Cache a :class:MultiwfnResult in memory.

If :attr:json_path is not None, the result is also written to the JSON file on disk.

Parameters

mwfn_result A fully parsed MultiwfnResult whose .result list is non-empty.

Source code in src/pymultiwfn/analysis/result.py
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
def store(self, mwfn_result: MultiwfnResult) -> None:
    """Cache a :class:`MultiwfnResult` in memory.

    If :attr:`json_path` is not ``None``, the result is also
    written to the JSON file on disk.

    Parameters
    ----------
    mwfn_result
        A fully parsed ``MultiwfnResult`` whose ``.result`` list
        is non-empty.

    """
    if not mwfn_result.result:
        return

    entry: dict[str, Any] = {
        "parsed": mwfn_result.to_dict(),
        "timestamp": datetime.now().isoformat(),
    }
    self._data.setdefault("analyses", {})[mwfn_result.analysis.name] = (
        entry
    )
    self._save()

store_from_stdout(analysis, stdout)

Parse stdout, persist, and return the :class:MultiwfnResult.

Convenience method combining :meth:MultiwfnResult.parse and :meth:store in a single call.

Returns None if no parser is available or parsing yields no results.

Source code in src/pymultiwfn/analysis/result.py
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
def store_from_stdout(
    self,
    analysis: Menu,
    stdout: str,
) -> MultiwfnResult | None:
    """Parse *stdout*, persist, and return the :class:`MultiwfnResult`.

    Convenience method combining :meth:`MultiwfnResult.parse` and
    :meth:`store` in a single call.

    Returns ``None`` if no parser is available or parsing yields no
    results.
    """
    result = MultiwfnResult(analysis=analysis)
    result.parse(stdout)
    if not result.result:
        return None
    self.store(result)
    return result

Spectrum dataclass

Bases: ParsedMultiwfnResult

Result for spectrum analysis.

Source code in src/pymultiwfn/analysis/result.py
509
510
511
512
513
514
515
516
517
518
519
520
@dataclass
class Spectrum(ParsedMultiwfnResult):
    """Result for spectrum analysis."""

    maximum: list[int] | None = None
    X: list[float] | None = None
    value: list[float] | None = None
    frequencies: list[float] | None = None
    intensities: list[float] | None = None
    wavelengths: list[float] | None = None
    atom_indices: list[int] | None = None
    chemical_shifts: list[float] | None = None

SpectrumCurveExtrema dataclass

Bases: ParsedMultiwfnResult

Collection of extrema reported for a spectrum curve.

Source code in src/pymultiwfn/analysis/result.py
533
534
535
536
537
@dataclass
class SpectrumCurveExtrema(ParsedMultiwfnResult):
    """Collection of extrema reported for a spectrum curve."""

    extrema: list[SpectrumExtremum] = field(default_factory=list)

SpectrumExtremum dataclass

Bases: ParsedMultiwfnResult

Single extremum point on a simulated spectrum curve.

Source code in src/pymultiwfn/analysis/result.py
523
524
525
526
527
528
529
530
@dataclass
class SpectrumExtremum(ParsedMultiwfnResult):
    """Single extremum point on a simulated spectrum curve."""

    kind: Literal["maximum", "minimum"]
    index: int
    x: float
    value: float

SuperdelocalizabilityEntry dataclass

Per-atom superdelocalizability values.

Source code in src/pymultiwfn/analysis/result.py
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
@dataclass
class SuperdelocalizabilityEntry:
    """Per-atom superdelocalizability values."""

    atom_id: int
    atom_element: str
    d_n: float
    d_e: float
    d_n_0: float
    d_e_0: float

SuperdelocalizabilityResult dataclass

Bases: ParsedMultiwfnResult

Complete superdelocalizability analysis.

Contains the alpha parameter, per-atom values, and sums.

Source code in src/pymultiwfn/analysis/result.py
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
@dataclass
class SuperdelocalizabilityResult(ParsedMultiwfnResult):
    """Complete superdelocalizability analysis.

    Contains the alpha parameter, per-atom values, and sums.
    """

    alpha_parameter: float | None = None
    entries: list[SuperdelocalizabilityEntry] = field(default_factory=list)
    sum_d_n: float | None = None
    sum_d_e: float | None = None
    sum_d_n_0: float | None = None
    sum_d_e_0: float | None = None

    def to_dict(self) -> dict[str, Any]:
        return {
            "alpha_parameter": self.alpha_parameter,
            "entries": [asdict(e) for e in self.entries],
            "sum_d_n": self.sum_d_n,
            "sum_d_e": self.sum_d_e,
            "sum_d_n_0": self.sum_d_n_0,
            "sum_d_e_0": self.sum_d_e_0,
        }

SurfaceAnalysisResult dataclass

Bases: ParsedMultiwfnResult

Complete surface analysis for one mapped property.

Bundles geometry, extrema, and statistics so that each sequence (ESP, ALIE, etc.) is stored as a single coherent result that won't overwrite other sequences.

Parameters

mapped_property Standardized identifier: "esp", "alie", "lea", "leae", "edr", "maxedr", "edensity", "lambda2_rho".

Source code in src/pymultiwfn/analysis/result.py
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
@dataclass
class SurfaceAnalysisResult(ParsedMultiwfnResult):
    """Complete surface analysis for one mapped property.

    Bundles geometry, extrema, and statistics so that each
    sequence (ESP, ALIE, etc.) is stored as a single coherent
    result that won't overwrite other sequences.

    Parameters
    ----------
    mapped_property
        Standardized identifier: ``"esp"``, ``"alie"``, ``"lea"``,
        ``"leae"``, ``"edr"``, ``"maxedr"``, ``"edensity"``,
        ``"lambda2_rho"``.
    """

    mapped_property: str
    geometry: SurfaceGeometry | None = None
    minima: list[SurfaceExtremum] = field(default_factory=list)
    maxima: list[SurfaceExtremum] = field(default_factory=list)
    statistics: SurfaceStatistics | None = None

    @property
    def area(self) -> float | None:
        if self.geometry is None:
            return None
        return self.geometry.area_angstrom2

    @property
    def volume(self) -> float | None:
        if self.geometry is None:
            return None
        return self.geometry.volume_angstrom3

    @property
    def V_S_plus(self) -> float | None:  # noqa: N802
        if self.statistics is None:
            return None
        return self.statistics.positive_surface_volume

    @property
    def V_S_minus(self) -> float | None:  # noqa: N802
        if self.statistics is None:
            return None
        return self.statistics.negative_surface_volume

SurfaceExtremum dataclass

Bases: ParsedMultiwfnResult

A single surface extremum (minimum or maximum).

Source code in src/pymultiwfn/analysis/result.py
604
605
606
607
608
609
610
611
612
613
614
615
616
@dataclass
class SurfaceExtremum(ParsedMultiwfnResult):
    """A single surface extremum (minimum or maximum)."""

    type: Literal["min", "max"]
    index: int
    value_au: float
    value_eV: float  # noqa: N815
    value_kcal_mol: float
    x_angstrom: float
    y_angstrom: float
    z_angstrom: float
    is_global: bool = False

SurfaceGeometry dataclass

Bases: ParsedMultiwfnResult

Isosurface geometry statistics.

Extracted once per surface calculation regardless of mapped property.

Source code in src/pymultiwfn/analysis/result.py
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
@dataclass
class SurfaceGeometry(ParsedMultiwfnResult):
    """Isosurface geometry statistics.

    Extracted once per surface calculation regardless of mapped
    property.
    """

    volume_bohr3: float | None = None
    volume_angstrom3: float | None = None
    area_bohr2: float | None = None
    area_angstrom2: float | None = None
    sphericity: float | None = None
    density_g_cm3: float | None = None
    n_vertices: int | None = None
    n_edges: int | None = None
    n_facets: int | None = None

SurfaceStatistics dataclass

Bases: ParsedMultiwfnResult

Summary statistics for a mapped surface property.

Parameters

mapped_property Standardized identifier for what was mapped onto the surface. One of: "esp", "alie", "lea", "leae", "edr", "maxedr", "edensity", "lambda2_rho".

Source code in src/pymultiwfn/analysis/result.py
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
@dataclass
class SurfaceStatistics(ParsedMultiwfnResult):
    """Summary statistics for a mapped surface property.

    Parameters
    ----------
    mapped_property
        Standardized identifier for what was mapped onto the
        surface.  One of: ``"esp"``, ``"alie"``, ``"lea"``,
        ``"leae"``, ``"edr"``, ``"maxedr"``, ``"edensity"``,
        ``"lambda2_rho"``.
    """

    mapped_property: str

    # Global extrema
    global_min_au: float | None = None
    global_max_au: float | None = None
    global_min_kcal_mol: float | None = None
    global_max_kcal_mol: float | None = None

    # Area breakdown
    overall_area_bohr2: float | None = None
    overall_area_angstrom2: float | None = None
    positive_area_bohr2: float | None = None
    positive_area_angstrom2: float | None = None
    negative_area_bohr2: float | None = None
    negative_area_angstrom2: float | None = None

    # Averages
    overall_average_au: float | None = None
    overall_average_kcal_mol: float | None = None
    positive_average_au: float | None = None
    positive_average_kcal_mol: float | None = None
    negative_average_au: float | None = None
    negative_average_kcal_mol: float | None = None

    # Variances
    sigma2_total_au2: float | None = None
    sigma2_total_kcal_mol2: float | None = None
    positive_variance_au2: float | None = None
    positive_variance_kcal_mol2: float | None = None
    negative_variance_au2: float | None = None
    negative_variance_kcal_mol2: float | None = None

    # Descriptors
    nu: float | None = None
    sigma2_tot_times_nu_au2: float | None = None
    sigma2_tot_times_nu_kcal_mol2: float | None = None
    pi_au: float | None = None
    pi_kcal_mol: float | None = None
    mpi_eV: float | None = None  # noqa: N815
    mpi_kcal_mol: float | None = None

    # Polar surface area
    nonpolar_area_angstrom2: float | None = None
    nonpolar_area_pct: float | None = None
    polar_area_angstrom2: float | None = None
    polar_area_pct: float | None = None

    # Skewness
    overall_skewness: float | None = None
    positive_skewness: float | None = None
    negative_skewness: float | None = None

    negative_area_pct: float | None = None

    positive_surface_volume: float | None = None
    negative_surface_volume: float | None = None

TopologyPath dataclass

Bases: ParsedMultiwfnResult

A gradient path connecting two critical points.

Source code in src/pymultiwfn/analysis/result.py
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
@dataclass
class TopologyPath(ParsedMultiwfnResult):
    """A gradient path connecting two critical points."""

    path_id: int
    bcp_index: int
    bcp_type: Literal["nuclear", "bond", "ring", "cage", "unknown"]
    target_cp_index: int
    target_cp_type: Literal["nuclear", "bond", "ring", "cage", "unknown"]
    length_bohr: float

    @property
    def atom1_id(self) -> int:
        return self.bcp_index

    @property
    def atom2_id(self) -> int:
        return self.target_cp_index

    @property
    def path_length(self) -> float:
        return self.length_bohr

Transition dataclass

Bases: ParsedMultiwfnResult

Result for transition analysis.

Source code in src/pymultiwfn/analysis/result.py
540
541
542
543
544
545
546
547
548
@dataclass
class Transition(ParsedMultiwfnResult):
    """Result for transition analysis."""

    state: int
    energy_eV: float  # noqa: N815
    wavelength_nm: float
    osc_strength: float
    rot_strength: float | None = None

Valence dataclass

Bases: ParsedMultiwfnResult

Result for valence analysis.

Source code in src/pymultiwfn/analysis/result.py
429
430
431
432
433
434
435
@dataclass
class Valence(ParsedMultiwfnResult):
    """Result for valence analysis."""

    atom_id: int
    type: Literal["total_valence", "free_valence"]
    valence: float

WeakInteraction dataclass

Bases: ParsedMultiwfnResult

Result for weak interaction analysis.

Source code in src/pymultiwfn/analysis/result.py
1130
1131
1132
1133
1134
1135
1136
1137
@dataclass
class WeakInteraction(ParsedMultiwfnResult):
    """Result for weak interaction analysis."""

    delta_g_inter: float = 0.0
    delta_g_intra: float = 0.0
    isosurface_integral: float | None = None
    cube_names: list[str] | None = None