Skip to content

deprotonation

Deprotonation modification methods.

CRESTDeprotonation dataclass

Bases: DeprotonationMaker, CRESTCalculator, PymatGenMaker[InputType, OutputType]


              flowchart TD
              jfchemistry.modification.deprotonation.CRESTDeprotonation[CRESTDeprotonation]
              jfchemistry.modification.deprotonation.base.DeprotonationMaker[DeprotonationMaker]
              jfchemistry.modification.base.StructureModification[StructureModification]
              jfchemistry.calculators.crest.crest_calculator.CRESTCalculator[CRESTCalculator]
              jfchemistry.calculators.base.Calculator[Calculator]
              jfchemistry.core.makers.pymatgen_maker.PymatGenMaker[PymatGenMaker]
              jfchemistry.core.makers.jfchem_maker.JFChemMaker[JFChemMaker]
              jfchemistry.core.makers.core_maker.CoreMaker[CoreMaker]

                              jfchemistry.modification.deprotonation.base.DeprotonationMaker --> jfchemistry.modification.deprotonation.CRESTDeprotonation
                                jfchemistry.modification.base.StructureModification --> jfchemistry.modification.deprotonation.base.DeprotonationMaker
                

                jfchemistry.calculators.crest.crest_calculator.CRESTCalculator --> jfchemistry.modification.deprotonation.CRESTDeprotonation
                                jfchemistry.calculators.base.Calculator --> jfchemistry.calculators.crest.crest_calculator.CRESTCalculator
                

                jfchemistry.core.makers.pymatgen_maker.PymatGenMaker --> jfchemistry.modification.deprotonation.CRESTDeprotonation
                                jfchemistry.core.makers.jfchem_maker.JFChemMaker --> jfchemistry.core.makers.pymatgen_maker.PymatGenMaker
                                jfchemistry.core.makers.core_maker.CoreMaker --> jfchemistry.core.makers.jfchem_maker.JFChemMaker
                




              click jfchemistry.modification.deprotonation.CRESTDeprotonation href "" "jfchemistry.modification.deprotonation.CRESTDeprotonation"
              click jfchemistry.modification.deprotonation.base.DeprotonationMaker href "" "jfchemistry.modification.deprotonation.base.DeprotonationMaker"
              click jfchemistry.modification.base.StructureModification href "" "jfchemistry.modification.base.StructureModification"
              click jfchemistry.calculators.crest.crest_calculator.CRESTCalculator href "" "jfchemistry.calculators.crest.crest_calculator.CRESTCalculator"
              click jfchemistry.calculators.base.Calculator href "" "jfchemistry.calculators.base.Calculator"
              click jfchemistry.core.makers.pymatgen_maker.PymatGenMaker href "" "jfchemistry.core.makers.pymatgen_maker.PymatGenMaker"
              click jfchemistry.core.makers.jfchem_maker.JFChemMaker href "" "jfchemistry.core.makers.jfchem_maker.JFChemMaker"
              click jfchemistry.core.makers.core_maker.CoreMaker href "" "jfchemistry.core.makers.core_maker.CoreMaker"
            

Generate deprotonated structures using CREST.

Uses CREST's automated deprotonation workflow to identify acidic sites and generate low-energy deprotonated structures. The method systematically explores different deprotonation sites and optimizes the resulting structures using GFN2-xTB.

ATTRIBUTE DESCRIPTION
name

Name of the job (default: "CREST Deprotonation").

TYPE: str

ewin

Energy window [kcal/mol] for selecting deprotonated structures (default: None, uses CREST default). Structures within ewin of the lowest energy structure are retained.

TYPE: str

References
  • CREST Documentation: https://crest-lab.github.io/crest-docs/

Examples:

>>> from jfchemistry.modification import CRESTDeprotonation
>>> from pymatgen.core import Molecule
>>> from ase.build import molecule
>>> ethane = Molecule.from_ase_atoms(molecule("C2H6"))
>>> # Deprotonate a ethane
>>> deprot = CRESTDeprotonation(ewin=6.0)
>>> job = deprot.make(ethane)
>>> deprotonated_structures = job.output["structure"]
>>>
>>> deprot_default = CRESTDeprotonation()
>>> job = deprot_default.make(ethane)
Source code in jfchemistry/modification/deprotonation/crest_deprotonation.py
 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
@dataclass
class CRESTDeprotonation[InputType: Molecule, OutputType: Molecule](
    DeprotonationMaker, CRESTCalculator, PymatGenMaker[InputType, OutputType]
):
    """Generate deprotonated structures using CREST.

    Uses CREST's automated deprotonation workflow to identify acidic sites
    and generate low-energy deprotonated structures. The method systematically
    explores different deprotonation sites and optimizes the resulting structures
    using GFN2-xTB.

    Attributes:
        name: Name of the job (default: "CREST Deprotonation").
        ewin: Energy window [kcal/mol] for selecting deprotonated structures
            (default: None, uses CREST default). Structures within ewin of the
            lowest energy structure are retained.

    References:
        - CREST Documentation: https://crest-lab.github.io/crest-docs/

    Examples:
        >>> from jfchemistry.modification import CRESTDeprotonation # doctest: +SKIP
        >>> from pymatgen.core import Molecule # doctest: +SKIP
        >>> from ase.build import molecule # doctest: +SKIP
        >>> ethane = Molecule.from_ase_atoms(molecule("C2H6")) # doctest: +SKIP
        >>> # Deprotonate a ethane
        >>> deprot = CRESTDeprotonation(ewin=6.0) # doctest: +SKIP
        >>> job = deprot.make(ethane) # doctest: +SKIP
        >>> deprotonated_structures = job.output["structure"] # doctest: +SKIP
        >>>
        >>> deprot_default = CRESTDeprotonation() # doctest: +SKIP
        >>> job = deprot_default.make(ethane) # doctest: +SKIP
    """

    name: str = "CREST Deprotonation"

    # INTERNAL
    _runtype: Literal["deprotonate"] = "deprotonate"
    _output_filename: str = "deprotonated.xyz"

    def _make_commands(self):
        """Make the CLI for the CREST input."""
        super()._make_commands()
        self._commands.append(f"--{self._runtype}")
        self._commands.append("--newversion")

    def _operation(
        self, input: InputType, **kwargs
    ) -> tuple[OutputType | list[OutputType], Properties | list[Properties] | None]:
        """Generate deprotonated structures using CREST.

        Runs CREST's deprotonation workflow to identify acidic sites and
        generate optimized deprotonated structures. The calculation uses
        GFN2-xTB with Wiberg bond order analysis.

        Args:
            input: Input molecular structure with 3D coordinates. The
                molecule's charge is used for the CREST calculation.
            **kwargs: Additional kwargs to pass to the operation.

        Returns:
            Tuple containing:
                - List of deprotonated structures sorted by energy
                - None (no additional properties)

        Examples:
            >>> from pymatgen.core import Molecule # doctest: +SKIP
            >>> from ase.build import molecule # doctest: +SKIP
            >>> ethane = Molecule.from_ase_atoms(molecule("C2H6")) # doctest: +SKIP
            >>> deprot = CRESTDeprotonation(ewin=8.0) # doctest: +SKIP
            >>> structures, props = deprot.operation(ethane) # doctest: +SKIP
            >>> print(f"Generated {len(structures)} deprotonated structures") # doctest: +SKIP
        """
        input.to("input.xyz", fmt="xyz")
        if self.charge is None and input.charge is not None:
            self.charge = input.charge
        super()._make_dict()
        super()._write_toml()
        self._make_commands()
        super()._run()
        if not os.path.exists(self._output_filename):
            raise FileNotFoundError(
                "No deprotonated structures found. Please check your CREST settings and log file."
            ) from None
        molecules = XYZ.from_file(self._output_filename).all_molecules
        for i, deprotonated_structure in enumerate(molecules):
            molecules[i] = deprotonated_structure.set_charge_and_spin(
                charge=deprotonated_structure.charge - 1,
                spin_multiplicity=int(deprotonated_structure.charge - 1) // 2 + 1,
            )
        return cast("list[OutputType]", molecules), cast("list[Properties]", Properties())

make

make(input: InputType | list[InputType], **kwargs) -> Response[_output_model]

Create a workflow job for processing structure(s).

Automatically handles job distribution for lists of structures. Each structure in a list is processed as a separate job for parallel execution.

PARAMETER DESCRIPTION
input

Single Pymatgen SiteCollection or list of SiteCollections.

TYPE: InputType | list[InputType]

**kwargs

Additional kwargs to pass to the operation.

DEFAULT: {}

RETURNS DESCRIPTION
Response[_output_model]

Response containing: - structure: Processed structure(s) - files: XYZ format file(s) of the structure(s) - properties: Computed properties from the operation

Examples:

>>> from jfchemistry.conformers import CRESTConformers
>>> from pymatgen.core import Molecule
>>> molecule = Molecule.from_ase_atoms(molecule("C2H6"))
>>> # Generate conformers
>>> conformer_gen = CRESTConformers(ewin=6.0)
>>> job = conformer_gen.make(input)
Source code in jfchemistry/core/makers/jfchem_maker.py
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
@jfchem_job()
def make(
    self,
    input: InputType | list[InputType],
    **kwargs,
) -> Response[_output_model]:
    """Create a workflow job for processing structure(s).

    Automatically handles job distribution for lists of structures. Each
    structure in a list is processed as a separate job for parallel execution.

    Args:
        input: Single Pymatgen SiteCollection or list of SiteCollections.
        **kwargs: Additional kwargs to pass to the operation.

    Returns:
        Response containing:
            - structure: Processed structure(s)
            - files: XYZ format file(s) of the structure(s)
            - properties: Computed properties from the operation

    Examples:
        >>> from jfchemistry.conformers import CRESTConformers # doctest: +SKIP
        >>> from pymatgen.core import Molecule # doctest: +SKIP
        >>> molecule = Molecule.from_ase_atoms(molecule("C2H6")) # doctest: +SKIP
        >>> # Generate conformers
        >>> conformer_gen = CRESTConformers(ewin=6.0) # doctest: +SKIP
        >>> job = conformer_gen.make(input) # doctest: +SKIP
    """
    return self._run_job(input, **kwargs)