Skip to content

base

This module defines the base input file classes.

CardOptions

Bases: Enum

Enum type of all supported options for a PWin card.

from_string(s) classmethod

:param s: String :return: SupportedOptions

Source code in pymatgen/io/espresso/inputs/base.py
35
36
37
38
39
40
41
42
43
44
@classmethod
def from_string(cls, s: str):
    """
    :param s: String
    :return: SupportedOptions
    """
    for m in cls:
        if m.value.lower() == s.lower():
            return m
    raise ValueError(f"Can't interpret option {s}.")

BaseInputFile(namelists, cards)

Bases: ABC, MSONable

Abstract Base class for input files

Source code in pymatgen/io/espresso/inputs/base.py
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
def __init__(self, namelists: list[dict[str, Any]], cards: list["InputCard"]):
    namelist_names = [nml.value.name for nml in self.namelist_classes]
    self.namelists = OrderedDict(
        {name: namelists.get(name, None) for name in namelist_names}
    )
    card_names = [c.value.name for c in self.card_classes]
    self.cards = OrderedDict({name: cards.get(name, None) for name in card_names})
    property_names = namelist_names + card_names
    for prop_name in property_names:
        setattr(
            self.__class__,
            prop_name,
            property(
                self._make_getter(prop_name),
                self._make_setter(prop_name),
                self._make_deleter(prop_name),
            ),
        )

namelist_classes abstractmethod property

All supported namelists as a SupportedInputs enum

card_classes abstractmethod property

All supported cards as a SupportedCards enum

from_file(filename) classmethod

Reads an inputfile from file

PARAMETER DESCRIPTION
filename

path to file

TYPE: PathLike | str

RETURNS DESCRIPTION
BaseInputFile

PWin object

Source code in pymatgen/io/espresso/inputs/base.py
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
@classmethod
def from_file(cls, filename: os.PathLike | str) -> "BaseInputFile":
    """
    Reads an inputfile from file

    Args:
        filename: path to file

    Returns:
        PWin object
    """
    parser = f90nml.Parser()
    parser.comment_tokens += "#"

    pwi_str = pathlib.Path(filename).read_text()
    namelists = {}
    for k, v in parser.reads(pwi_str).items():
        Namelist = cls.namelist_classes.from_string(k)
        namelists[k] = Namelist(v)
    cards = cls._parse_cards(pwi_str)

    return cls(namelists, cards)

validate()

Very basic validation for the input file. Currently only checks that required namelists and cards are present.

Source code in pymatgen/io/espresso/inputs/base.py
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
def validate(self) -> bool:
    """
    Very basic validation for the input file.
    Currently only checks that required namelists and cards are present.
    """
    required_namelists = [
        nml.value.name for nml in self.namelist_classes if nml.value.required
    ]
    if any(self.namelists[nml] is None for nml in required_namelists):
        msg = "Input file is missing required namelists:"
        for nml in required_namelists:
            if self.namelists[nml] is None:
                msg += f" &{nml.upper()}"
        warnings.warn(msg, EspressoInputWarning)
        return False

    required_cards = [c.value.name for c in self.card_classes if c.value.required]
    if any(self.cards[card] is None for card in required_cards):
        msg = "Input file is missing required cards:"
        for card in required_cards:
            if self.cards[card] is None:
                msg += f" {card.upper()}"
        warnings.warn(msg, EspressoInputWarning)
        return False

    return True

__str__()

Return the input file as a string

Source code in pymatgen/io/espresso/inputs/base.py
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
def __str__(self):
    """
    Return the input file as a string
    """
    string = ""
    for nml in self.namelists.values():
        if nml is not None:
            nml.indent = self._indent
            string += str(nml) + "\n"

    for c in self.cards.values():
        if c is not None:
            c.indent = self._indent
            string += str(c) + "\n"

    return string

to_file(filename, indent=2)

Write the input file to a file.

PARAMETER DESCRIPTION
filename

path to file

TYPE: PathLike | str

indent

number of spaces to use for indentation

TYPE: int DEFAULT: 2

Source code in pymatgen/io/espresso/inputs/base.py
207
208
209
210
211
212
213
214
215
216
217
def to_file(self, filename: os.PathLike | str, indent: int = 2):
    """
    Write the input file to a file.

    Args:
        filename: path to file
        indent: number of spaces to use for indentation
    """
    self._indent = indent
    with open(filename, "wb") as f:
        f.write(self.__str__().encode("ascii"))

InputNamelist(*args, **kwargs)

Bases: ABC, OrderedDict

Abstract Base class for namelists in input files

Source code in pymatgen/io/espresso/inputs/base.py
227
228
def __init__(self, *args, **kwargs):
    super().__init__(*args, **kwargs)

__str__()

Convert namelist to string

Source code in pymatgen/io/espresso/inputs/base.py
230
231
232
233
234
235
236
237
def __str__(self):
    """
    Convert namelist to string
    """
    nl = f90nml.Namelist({self.name: self})
    nl.indent = self.indent * " "
    string = str(nl)
    return re.sub(r"^&(\w+)", lambda m: m.group(0).upper(), string)

InputCard(option, body)

Bases: ABC

Abstract Base class for cards in input files

PARAMETER DESCRIPTION
option

The option for the card (e.g., "RELAX")

TYPE: str

body

The body of the card

TYPE: list

body (list): The body of the card
Source code in pymatgen/io/espresso/inputs/base.py
261
262
263
264
265
266
267
268
269
270
def __init__(self, option: str | CardOptions, body: str):
    """
    Args:
        option (str): The option for the card (e.g., "RELAX")
        body (list): The body of the card
    """
    if isinstance(option, str):
        option = self.opts.from_string(option)
    self.option = option
    self._body = body

__str__()

Convert card to string This implementation is for generic (i.e., not fully implemented) cards

Source code in pymatgen/io/espresso/inputs/base.py
297
298
299
300
301
302
def __str__(self):
    """
    Convert card to string
    This implementation is for generic (i.e., not fully implemented) cards
    """
    return self.get_header() + self.get_body(" " * self.indent)

get_body(indent)

Convert card body to string This implementation is for generic (i.e., not fully implemented) cards

Source code in pymatgen/io/espresso/inputs/base.py
305
306
307
308
309
310
311
312
313
def get_body(self, indent: str) -> str:
    """
    Convert card body to string
    This implementation is for generic (i.e., not fully implemented) cards
    """
    return "".join(
        f"\n{indent}{' '.join(line) if isinstance(line, list) else line}"
        for line in self._body
    )

from_string(s) classmethod

Create card object from string This implementation is for generic (i.e., not fully implemented) cards

Source code in pymatgen/io/espresso/inputs/base.py
319
320
321
322
323
324
325
326
@classmethod
def from_string(cls, s: str) -> "InputCard":
    """
    Create card object from string
    This implementation is for generic (i.e., not fully implemented) cards
    """
    option, body = cls.split_card_string(s)
    return cls(option, body)

get_option(option) classmethod

Initializes a card's options

Source code in pymatgen/io/espresso/inputs/base.py
328
329
330
331
332
333
334
335
336
337
@classmethod
def get_option(cls, option: str) -> CardOptions:
    """Initializes a card's options"""
    if option is not None:
        return cls.opts.from_string(option)
    if cls.default_deprecated:
        logging.warning(
            f"No option specified for {cls.name} card. This is deprecated, but {cls.default_option} will be used by default."
        )
    return cls.default_option

split_card_string(s) classmethod

    Splits a card into an option and a list of values of the correct type.
    :param s: String containing a card (as it would appear in a PWin file)
    :return: option: string for the card's option or None
             values: list of lists of values for the card

    Example:
    >>> s = "ATOMIC_SPECIES

H 1.00794 H.UPF O 15.9994 O.UPF" >>> option, values = InputCard.split_card_string_string(s) >>> option, values >>> (None, [["H", 1.00794, "H.UPF"], ["O", 15.9994, "O.UPF"]])

Source code in pymatgen/io/espresso/inputs/base.py
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
@classmethod
def split_card_string(cls, s: str) -> tuple[str, list]:
    """
    Splits a card into an option and a list of values of the correct type.
    :param s: String containing a card (as it would appear in a PWin file)
    :return: option: string for the card's option or None
             values: list of lists of values for the card

    Example:
    >>> s = "ATOMIC_SPECIES\nH 1.00794 H.UPF\nO 15.9994 O.UPF"
    >>> option, values = InputCard.split_card_string_string(s)
    >>> option, values
    >>> (None, [["H", 1.00794, "H.UPF"], ["O", 15.9994, "O.UPF"]])
    """
    s = re.sub(r"\t", " ", s)
    header = s.strip().split("\n")[0]
    body = s.strip().split("\n")[1:]
    if len(header.split()) > 1:
        option = re.sub(r"[()]", "", header.split()[1])
        option = option.lower()
        option = re.sub(r"[()]", "", option)
        option = re.sub(r"[{}]", "", option)
    else:
        option = None
    return cls.get_option(option), parse_pwvals(body)

get_header()

Gets a card's header as a string

Source code in pymatgen/io/espresso/inputs/base.py
365
366
367
368
369
370
371
372
def get_header(self) -> str:
    """Gets a card's header as a string"""
    if self.name is None:
        return ""
    header = f"{self.name.upper()}"
    if self.option:
        header += f" {{{self.option}}}"
    return header

SupportedInputs

Bases: Enum

Enum type of all supported input cards and namelists.

from_string(s) classmethod

:param s: String :return: InputCard or InputNamelist

Source code in pymatgen/io/espresso/inputs/base.py
378
379
380
381
382
383
384
385
386
387
@classmethod
def from_string(cls, s: str):
    """
    :param s: String
    :return: InputCard or InputNamelist
    """
    for m in cls:
        if m.name.lower() == s.lower():
            return m.value
    raise ValueError(f"Can't interpret card or namelist {s}.")

EspressoInputWarning

Bases: UserWarning

Warning class for PWin parsing.