Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Read INCAR SYSTEM as is, check_params use proc_val #4136

Merged
merged 14 commits into from
Nov 12, 2024

Conversation

DanielYang59
Copy link
Contributor

@DanielYang59 DanielYang59 commented Oct 26, 2024

Summary

@@ -800,10 +800,10 @@ def run_type(self) -> str:
"--",
"None",
}:
incar_tag = self.incar.get("METAGGA", "").strip().upper()
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this would be covered by

return val.strip().capitalize()

@@ -484,7 +484,7 @@ def _parse(
or elem.attrib["comment"]
== "INVERSE MACROSCOPIC DIELECTRIC TENSOR (including local field effects in RPA (Hartree))"
):
if self.incar.get("ALGO", "Normal").upper() == "BSE":
if self.incar.get("ALGO", "Normal") == "Bse":
Copy link
Contributor Author

@DanielYang59 DanielYang59 Oct 26, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After #4122 we should be confident that string values are now capitalized (except for those in lower_str_keys and as_is_str_keys), these case conversion may not be needed.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If they are capitalized, why comparing with "Bse" (non-capitalized)

Copy link
Contributor Author

@DanielYang59 DanielYang59 Oct 26, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry I may not understand your question? The value Bse is capitalized? The key ALGO is in uppercase.

print("BSE".capitalize())  # Bse

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sory, I got completely confused. Mostly because of apparent inconsistency between the code and VASP wiki. If you look at https://www.vasp.at/wiki/index.php/ALGO, you will see that BSE and many other values are all capitals:

ALGO = Normal | VeryFast | Fast | Conjugate | All | Damped | Subrot | Eigenval | Exact | None | Nothing | CHI | G0W0 | GW0 | GW | scGW0 | scGW | G0W0R | GW0R | GWR | scGW0R | scGWR | ACFDT | RPA | ACFDTR | RPAR | BSE | TDHF

So, the code reads awkward now.

Copy link
Contributor Author

@DanielYang59 DanielYang59 Oct 27, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I got completely confused. Mostly because of apparent inconsistency between the code and VASP wiki

Yes I find it confusing too #4122 (comment), and @esoteric-ephemera said it's a convention to pymatgen #4122 (comment)

This is likely like this since the start:
image

As VASP itself is largely case insensitive, we just need to internally standardize for easy handling (no need to cast to upper/capitalize when comparing values and so on). I personally prefer to cast both value and tag to uppercase for the following reason:

  • VASP Wiki large prefer upper case for keys, and get rid of the headache to memorize "key is uppercase", but "case is capitalized" and so on
  • Most values (just like keys) are first-letter abbreviations of some sort, capitalizing them doesn't make much sense, though there're values that is indeed proper words like "Fast/Conjugate/All/..."

But this would be badly breaking (every downstream package would find the INCAR key in a different case) so I guess it's not worth the price. So we'd better come up with something that is not breaking. In any case I would leave this for a future PR.


I'm not sure it's doable or not, a good alternative is to subclass a "case insensitive string" as an inplace replacement of built in str to avoid the headache altogether (but I currently don't have a good way to overwrite the membership check), I might have another try later.

class CaseInsensitiveStr(str):
    def __new__(cls, value):
        return super().__new__(cls, value.casefold())

    def __eq__(self, other):
        if isinstance(other, str):
            return super().__eq__(other.casefold())
        return NotImplemented

    def __hash__(self):
        return hash(self.casefold())

str_a = CaseInsensitiveStr("HELLO")

print(str_a)  # hello

print(str_a == "hello")  # True
print(str_a == "HELLO")  # True

print(str_a in {"hello", "world"})  # True
print(str_a in {"HELLO", "world"})  # False, should be True
print(str_a in {"world"})  # False

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes I find it confusing too #4122 (comment), and @esoteric-ephemera said it's a convention to pymatgen #4122 (comment)

I see, and I agree that abstracting things out into case-sensitive/insensitive class is the most robust way to go.

As for the convention, it annoyingly has exceptions:

class Incar(UserDict, MSONable):
    """
    A case-insensitive dictionary to read/write INCAR files with additional helper functions.

    - Keys are stored in uppercase to allow case-insensitive access (set, get, del, update, setdefault).
    - String values are capitalized by default, except for keys specified
        in the `lower_str_keys` of the `proc_val` method.
    """

As you can see, capitalization is documented, except "keys specified in lower_str_keys". Currently it is a single key - ML_MODE.

However, do note that Incar.check_params does not expect such exceptions:

            if allowed_values is not None:
                # Note: param_type could be a Union type, e.g. "str | bool"
                if "str" in param_type:
                    allowed_values = [item.capitalize() if isinstance(item, str) else item for item in allowed_values]

(aside: incar_parameters.json does not even list ML_MODE)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As you can see, capitalization is documented, except "keys specified in lower_str_keys". Currently it is a single key - ML_MODE.

Yep I updated the docstring to reflect this key/value case issue, but I'm not sure about the casing of ML_MODE either (I thought VASP is largely case insensitive ) #4122 (comment)

I never use that tag so cannot comment, it would be great if you (or someone else) could confirm this behaviour.

However, do note that Incar.check_params does not expect such exceptions:

Thanks I would update it (one exception makes everything hard to handle)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I never use that tag so cannot comment, it would be great if you (or someone else) could confirm this behaviour.

I do not use this tag either, but clearly its value is case-sensitive - #3625
I looked up https://www.vasp.at/wiki/index.php/ML_MODE and it says

Warning: If any option other than the above is chosen or there is a spelling error (be careful to write everything in upper case or lower case letters) the code will exit with an error.

I conclude that case-insensitivity is not universal.

Ironically, simply upcasing (rathen than capitalizing) everything would not require making an exception for ML_MODE.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not use this tag either, but clearly its value is case-sensitive - #3625

Yes I did see this PR and the VASP comment as well.

I conclude that case-insensitivity is not universal.
Ironically, simply upcasing (rathen than capitalizing) everything would not require making an exception for ML_MODE.

I believe ML_MODE is the only exception for now. upcase everything (except for SYSTEM) would make everything easy, but I guess ML_MODE was not there when this part of code was written (12 years ago), and it's hard to change it now without breakage

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

t's hard to change it now without breakage

100% agree.

@DanielYang59 DanielYang59 changed the title Update incar_parameters.json Read INCAR SYSTEM as is, ignore comment for equality compare of Kpoints/Incar Oct 26, 2024
@DanielYang59 DanielYang59 changed the title Read INCAR SYSTEM as is, ignore comment for equality compare of Kpoints/Incar Read INCAR SYSTEM as is, ignore comment for equality compare of Kpoints/Incar/Poscar Oct 26, 2024
@DanielYang59 DanielYang59 changed the title Read INCAR SYSTEM as is, ignore comment for equality compare of Kpoints/Incar/Poscar Read INCAR SYSTEM as is Oct 26, 2024
@DanielYang59
Copy link
Contributor Author

DanielYang59 commented Oct 26, 2024

@yantar92 Hope this looks good to you

The issue with incar_parameters.json is not completely resolved as we cannot reply on manual upgrade of tags and values, a script is certainly needed but I don't have time to work on this at this moment.

@DanielYang59 DanielYang59 marked this pull request as ready for review October 26, 2024 11:58
@yantar92
Copy link
Contributor

a script is certainly needed but I don't have time to work on this at this moment.

#4119 (comment)

@DanielYang59 DanielYang59 marked this pull request as draft October 27, 2024 11:16
@DanielYang59 DanielYang59 force-pushed the vasp-eq-ignore-comment branch 2 times, most recently from e724dbe to 43113fd Compare October 27, 2024 12:19
@DanielYang59 DanielYang59 force-pushed the vasp-eq-ignore-comment branch from 43113fd to b89da9d Compare October 27, 2024 12:26
@DanielYang59 DanielYang59 marked this pull request as ready for review October 27, 2024 13:45
@DanielYang59 DanielYang59 changed the title Read INCAR SYSTEM as is Read INCAR SYSTEM as is, check_param use proc_val Oct 27, 2024
@DanielYang59 DanielYang59 changed the title Read INCAR SYSTEM as is, check_param use proc_val Read INCAR SYSTEM as is, check_params use proc_val Oct 27, 2024
@shyuep
Copy link
Member

shyuep commented Nov 12, 2024

I am merging this. In the end, we are using the 80/20 rule. VASP keys are always all caps. VASP values are a mess of different things (int, floats, case-insensitive strings, case-sensitive strings, etc.). For now, we will just use capitalize since that works for most of the cases, e.g., ALGO=Fast,Normal, etc. I get that BSE should be full caps since it is an acronym but since it makes no difference to actual functionality, we are going to live with it.

@shyuep shyuep merged commit 29b21bf into materialsproject:master Nov 12, 2024
43 checks passed
@DanielYang59 DanielYang59 deleted the vasp-eq-ignore-comment branch November 13, 2024 01:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

VaspInput setter and Incar.check_params() are inconsistent
3 participants