File: vibration.py

package info (click to toggle)
python-emmet-core 0.84.2-2
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 77,220 kB
  • sloc: python: 16,355; makefile: 30
file content (120 lines) | stat: -rw-r--r-- 3,825 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
from typing import List
from hashlib import blake2b

from pydantic import Field

from pymatgen.core.structure import Molecule

from emmet.core.mpid import MPculeID
from emmet.core.material import PropertyOrigin
from emmet.core.qchem.task import TaskDocument
from emmet.core.molecules.molecule_property import PropertyDoc


__author__ = "Evan Spotte-Smith <ewcspottesmith@lbl.gov>"


class VibrationDoc(PropertyDoc):
    property_name: str = "vibrations"

    molecule: Molecule = Field(..., description="Molecular structure")

    frequencies: List[float] = Field(
        ..., description="List of molecular vibrational frequencies"
    )

    frequency_modes: List[List[List[float]]] = Field(
        ..., description="Vibrational frequency modes of the molecule"
    )

    ir_intensities: List[float] = Field(
        ...,
        title="IR intensities",
        description="Intensities for IR vibrational spectrum peaks",
    )

    ir_activities: List = Field(
        ...,
        title="IR activities",
        description="List indicating if frequency-modes are IR-active",
    )

    @classmethod
    def from_task(
        cls,
        task: TaskDocument,
        molecule_id: MPculeID,
        deprecated: bool = False,
        **kwargs,
    ):  # type: ignore[override]
        """
        Construct a vibration document from a task document

        :param task: document from which vibrational properties can be extracted
        :param molecule_id: MPculeID
        :param deprecated: bool. Is this document deprecated?
        :param kwargs: to pass to PropertyDoc
        :return:
        """

        if task.output.frequencies is None:
            raise Exception("No frequencies in task!")

        if task.output.optimized_molecule is not None:
            mol = task.output.optimized_molecule
        else:
            mol = task.output.initial_molecule

        frequencies = task.output.frequencies
        frequency_modes = None
        intensities = None
        active = None
        for calc in task.calcs_reversed:
            if (
                calc.get("frequency_mode_vectors", None) is not None
                and frequency_modes is None
            ):
                frequency_modes = calc.get("frequency_mode_vectors")

            if calc.get("IR_intens", None) is not None and intensities is None:
                intensities = calc.get("IR_intens")

            if calc.get("IR_active", None) is not None and active is None:
                active = calc.get("IR_active")

            if all([x is not None for x in [frequency_modes, intensities, active]]):
                break

        if frequency_modes is None:
            raise Exception("No frequency modes in task!")
        elif intensities is None:
            raise Exception("No IR intensities in task!")
        elif active is None:
            raise Exception("No IR activities in task!")

        warnings = list()
        if frequencies[0] < 0.0:
            warnings.append("Imaginary frequencies")

        id_string = f"vibrations-{molecule_id}-{task.task_id}-{task.lot_solvent}"
        h = blake2b()
        h.update(id_string.encode("utf-8"))
        property_id = h.hexdigest()

        return super().from_molecule(
            meta_molecule=mol,
            property_id=property_id,
            molecule_id=molecule_id,
            level_of_theory=task.level_of_theory,
            solvent=task.solvent,
            lot_solvent=task.lot_solvent,
            molecule=mol,
            frequencies=frequencies,
            frequency_modes=frequency_modes,
            ir_intensities=intensities,
            ir_activities=active,
            warnings=warnings,
            origins=[PropertyOrigin(name="vibrations", task_id=task.task_id)],
            deprecated=deprecated,
            **kwargs,
        )