-
Notifications
You must be signed in to change notification settings - Fork 192
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
Add the ElectronicBandsData
data plugin
#5033
Add the ElectronicBandsData
data plugin
#5033
Conversation
Probably need to add a |
Codecov Report
@@ Coverage Diff @@
## develop #5033 +/- ##
===========================================
+ Coverage 80.23% 80.25% +0.03%
===========================================
Files 515 517 +2
Lines 36757 36784 +27
===========================================
+ Hits 29489 29519 +30
+ Misses 7268 7265 -3
Flags with carried forward coverage won't be shown. Click here to find out more.
Continue to review full report at Codecov.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @sphuber! Just left a few questions/comments, and still have a more general one that's a bit of semantic nit-picking. The terms Fermi energy and Fermi level are often used interchangeably, but I think it's more precise to use Fermi energy for "the energy difference between the highest and lowest occupied single-particle states in a quantum system of non-interacting fermions at absolute zero temperature":
https://en.wikipedia.org/wiki/Fermi_energy
Whereas the Fermi level is the one we are adding to the BandsData
here, I think:
|
||
KEY_FERMI_ENERGY = 'fermi_energy' | ||
|
||
def __init__(self, **kwargs): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I must admit I do not like this constructor using **kwargs
from a UX point of view. ^^ Basically it's impossible to tell for a user that checks the docstring how to use it. What's the advantage of this, and does it outweigh the benefit of the user simply seeing the input arguments and having them documented in the docstring?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have changed the interface. However, it does bring other potential use problems with it. See the commit message for an explanation. Using the /
marker to make them positional only "solves" the problem somewhat.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmmm, the /
positional argument only marker is only supported for Python 3.8 and up. Not sure if there is a backport solution for this, but I doubt it since it concerns the basic syntax. @chrisjsewell do you happen to know?
Thanks for the review @mbercx . Fine for me to change to |
a1ac9f6
to
6001483
Compare
This data plugin is a subclass of the `BandsData` plugin. It adds support to define a fermi energy, which is set as an attribute. This is a typical use case for electronic band structures, which so far were using the `BandsData` type, but the latter was also being used for other band structures, such as phonons, which do not share this property. By making it a subclass, existing processes that accept `BandsData` instances will automatically also accept `ElectronicBandsData` instances and queries for `BandsData` will also match the subclasses, unless the user turns of subclassing explicitly. The constructor would have used the `/` marker to make the `kpoints`, `bands` and `fermi_energy` arguments positional only. The reason is that the constructor needs to allow for arbitrary keyword arguments to be passed to the parent constructor. This is necessary to be able to change the `user` of the node for example. Without making the other arguments positional only, a caller could define them as a keyword argument, causing them to be passed to the constructor of the parent class, which will raise an exception since it does not define those arguments. However, we unfortunately still support Python 3.7 and `/` was not added until Python 3.8, so for now we cannot use it yet.
6001483
to
e473aac
Compare
If the units in BandsData are always eV (I think this should be the case now that we are defining a Electronic type), I would vote to also force the fermi_level to be in eV and document it. I think it just makes our life too complex if we need to then define a new layer to convert units between various ElectronicBandsData. If we really want to have multiple units, I still think the units of the Fermi level should be the same as for the bands, so we would define only one unit for bands and the Fermi level. Also, if we want to go down this route of defining an ElectronicBandsData type, we should move in the new type all functionality that is specific to electronic bands (two bands channels = spin up/down, the find_bandgap function, ...)? |
I'm definitely in favor of implementing the |
Ok, my fault - I was under the false impression that there was a from aiida.tools.data.array.bands import find_bandgap
find_bandgap(bandnode) (with the additional benefit that one can do I can't find the issue on EDIT: this is the corresponding
|
The reason that there is no |
Regarding placing these in e.g. However, I would be more in favor of not having this kind of workaround, which again requires us to teach the users something to just find the utility methods they need. Instead, it would be better if we could hide methods that users typically do not need, so they can more easily find the methods that we would place in |
OK to keep it in the main class, but indeed for a user it's overwhelming to find all node methods (that they might not need) + the methods acting on the nodes. Also this makes data classes quite complex, again with a design principle that I would like to push forward that we keep data classes as stable as possible over time, just focusing on storing data in the DB in a consistent format, and move code that processes it outside. As a historical note we had tried in AiiDA 0.x to hide methods (prefixing with underscore) that might not be needed by a end user (e.g. But anyway this is also a matter of taste, and it's not crucial for this issue. |
Just a note here: This was discussed during a recent CWF meeting, and I think it was agreed that Fermi level is a slightly more correct terminology. However, I did not get the impression that everyone was as passionate about this sematic nit-picking as I. 😅 |
Will close this PR for now since it has been inactive for a long time and I don't anticipate having time soon to address the changes. Will reopen when there is a new design incorporating the suggested changes. |
Fixes #5032
This data plugin is a subclass of the
BandsData
plugin. It addssupport to define a fermi energy, which is set as an attribute. This is
a typical use case for electronic band structures, which so far were
using the
BandsData
type, but the latter was also being used for otherband structures, such as phonons, which do not share this property.
By making it a subclass, existing processes that accept
BandsData
instances will automatically also accept
ElectronicBandsData
instancesand queries for
BandsData
will also match the subclasses, unless theuser turns of subclassing explicitly.