dos¶
(
- data_context,
- **kwargs
)
The density of states (DOS) describes the number of states per energy.
The DOS quantifies the distribution of electronic states within an energy range in a material. It provides information about the number of electronic states at each energy level and offers insights into the material’s electronic structure. On-site projections near the atoms (projected DOS) offer a more detailed view. This analysis breaks down the DOS contributions by atom, orbital and spin. Investigating the projected DOS is often a useful step to understand the electronic properties because it shows how different orbitals and elements contribute and influence the material’s properties.
VASP writes the DOS after every calculation and the projected DOS if you set LORBIT in the INCAR file. You can use this class to extract this data. Typically you want to run a non self consistent calculation with a denser mesh for a smoother DOS but the class will work independent of it. If you generated a projected DOS, you can use this class to select which subset of these orbitals to read or plot.
Examples
First, we create some example data do that you can follow along. Please define a variable path with the path to a directory that exists and does not contain any VASP calculation data. Alternatively, you can use your own data if you have run VASP with LORBIT.
>>> from py4vasp import demo
>>> calculation = demo.calculation(path)
If you want to visualize the total DOS, you can use the plot method. This will show the different spin components if ISPIN = 2
>>> calculation.dos.plot()
Graph(series=[Series(x=array(...), y=array(...), label='total', ...)],
xlabel='Energy (eV)', ..., ylabel='DOS (1/eV)', ...)
If you need the raw data, you can read the DOS into a Python dictionary
>>> calculation.dos.read()
{'energies': array(...), 'total': array(...), 'fermi_energy': ...}
These methods also accept selections for specific orbitals if you used VASP with LORBIT. You can get a list of the allowed choices with
>>> calculation.dos.selections()
{'dos': ['default', 'kpoints_opt'], 'atom': [...], 'orbital': [...], 'spin': [...]}
path
plot
Almost same as the to_graph() function.
All arguments will be passed to to_graph. If the to_graph() would
produce multiple graphs this method will merge them into a single one.
read
selections
dict
Returns possible alternatives for this particular quantity VASP can produce.
The returned dictionary contains a single item with the name of the quantity mapping to all possible selections. Each of these selection may be passed to other functions of this quantity to select which output of VASP is used. Some quantities provide additional elements which can be passed as selection for other routines.
Returns
dict- The key indicates this quantity and the values possible choices for arguments to other functions of this quantity.
to_csv
(
- *args,
- filename:
str | Path= None, - **kwargs
)
Writes the data to a csv file.
Writes out a csv file for data stored in a dataframe generated with
the to_frame() method. Useful for creating external plots
for further analysis.
If no filename is provided a default filename is deduced from the name of the class.
Note that the filename must be a keyword argument, i.e., you explicitly
need to write filename=”name_of_file” because the arguments are passed
on to the to_graph() method. Please check the documentation of that
method to learn which arguments are allowed.
Parameters
- filename:
str | Path= None - Name of the csv file which the data is exported to.
to_dict
str = None) → dict
Read the DOS into a dictionary.
You will always get an “energies” component that describes the energy mesh for the density of states. The energies are shifted with respect to VASP such that the Fermi energy is at 0. py4vasp returns also the original “fermi_energy” so you can revert this if you want. If ISPIN = 2, you will get the total DOS spin resolved as “up” and “down” component. Otherwise, you will get just the “total” DOS. When you set LORBIT in the INCAR file and pass in a selection, you will obtain the projected DOS with a label corresponding to the projection.
We create some example data do that you can follow along. Please define a variable path with the path to a directory that exists and does not contain any VASP calculation data. Alternatively, you can use your own data if you have run VASP with LORBIT.
>>> from py4vasp import demo
>>> calculation = demo.calculation(path)
>>> collinear_calculation = demo.calculation(path, selection="collinear")
>>> noncollinear_calculation = demo.calculation(path, selection="noncollinear")
Parameters
- selection:
str= None - A string specifying the projection of the orbitals. There are four distinct
possibilities:
-
To specify the atom, you can either use its element name (Si, Al, …) or its index as given in the input file (1, 2, …). For the latter option it is also possible to specify ranges (e.g. 1:4).
-
To select a particular orbital you can give a string (s, px, dxz, …) or select multiple orbitals by their angular momentum (s, p, d, f).
-
For the spin, you have the options up, down, or total.
-
If you used a different k-point mesh choose “kpoints_opt” or “kpoints_wan” to select them instead of the default mesh specified in the KPOINTS file.
You separate multiple selections by commas or whitespace and can nest them using parenthesis, e.g. Sr(s, p) or s(up), p(down). The order of the selections does not matter, but it is case sensitive to distinguish p (angular momentum l = 1) from P (phosphorus).
It is possible to add or subtract different components, e.g., a selection of “Ti(d) - O(p)” would project onto the d orbitals of Ti and the p orbitals of O and then compute the difference of these two selections.
If you are unsure about the specific projections that are available, you can use
>>> calculation.projector.selections() {'atom': [...], 'orbital': [...], 'spin': [...]}to get a list of all available ones.
-
Returns
dict- Contains the energies at which the DOS was evaluated aligned to the Fermi energy and the total DOS or the spin-resolved DOS for spin-polarized calculations. If available and a selection is passed, the orbital resolved DOS for the selected orbitals is included.
Examples
To obtain the total DOS along with the energy mesh and the Fermi energy you do not need any arguments. For ISPIN = 2, this will “up” and “down” DOS as two separate entries.
>>> calculation.dos.to_dict()
{'energies': array(...), 'total': array(...), 'fermi_energy': ...}
Select the p orbitals of the first atom in the POSCAR file:
>>> calculation.dos.to_dict(selection="1(p)")
{'energies': array(...), 'total': array(...), 'Sr_1_p': array(...),
'fermi_energy': ...}
Select the d orbitals of Sr and Ti:
>>> calculation.dos.to_dict("d(Sr, Ti)")
{'energies': array(...), 'total': array(...), 'Sr_d': array(...),
'Ti_d': array(...), 'fermi_energy': ...}
Collinear calculations separate the DOS into two spin components
>>> collinear_calculation.dos.read()
{'energies': array(...), 'up': array(...), 'down': array(...), ...}
You can also select spin contribution of specific atoms or orbitals, e.g. the spin-up contribution of the first three atoms combined
>>> collinear_calculation.dos.to_dict("up(1:3)")
{'energies': array(...), 'up': array(...), 'down': array(...),
'1:3_up': array(...), 'fermi_energy': ...}
Noncollinear calculations contain four spin components but by default only the total DOS is shown
>>> noncollinear_calculation.dos.to_dict()
{'energies': array(...), 'total': array(...), 'fermi_energy': ...}
You can select specific spin components if you want, e.g. the spin projection along the z axis
>>> noncollinear_calculation.dos.to_dict("sigma_z")
{'energies': array(...), 'total': array(...), 'sigma_z': array(...),
'fermi_energy': ...}
You can also use simple addition and subtraction to combine the contributions of different orbitals, e.g. add the contribution of three d orbitals
>>> calculation.dos.to_dict("dxy + dxz + dyz")
{'energies': array(...), 'total': array(...), 'dxy + dxz + dyz': array(...),
'fermi_energy': ...}
Read the density of states generated by the ‘’’k’’’-point mesh in the KPOINTS_OPT file (analogously for KPOINTS_WAN)
>>> calculation.dos.to_dict("kpoints_opt")
{'energies': array(...), 'total': array(...), 'fermi_energy': ...}
to_frame
str = None) → pd.DataFrame
Read the data into a pandas DataFrame.
We create some example data do that you can follow along. Please define a variable path with the path to a directory that exists and does not contain any VASP calculation data. Alternatively, you can use your own data if you have run VASP with LORBIT.
>>> from py4vasp import demo
>>> calculation = demo.calculation(path)
>>> collinear_calculation = demo.calculation(path, selection="collinear")
>>> noncollinear_calculation = demo.calculation(path, selection="noncollinear")
Parameters
- selection:
str= None - A string specifying the projection of the orbitals. There are four distinct
possibilities:
-
To specify the atom, you can either use its element name (Si, Al, …) or its index as given in the input file (1, 2, …). For the latter option it is also possible to specify ranges (e.g. 1:4).
-
To select a particular orbital you can give a string (s, px, dxz, …) or select multiple orbitals by their angular momentum (s, p, d, f).
-
For the spin, you have the options up, down, or total.
-
If you used a different k-point mesh choose “kpoints_opt” or “kpoints_wan” to select them instead of the default mesh specified in the KPOINTS file.
You separate multiple selections by commas or whitespace and can nest them using parenthesis, e.g. Sr(s, p) or s(up), p(down). The order of the selections does not matter, but it is case sensitive to distinguish p (angular momentum l = 1) from P (phosphorus).
It is possible to add or subtract different components, e.g., a selection of “Ti(d) - O(p)” would project onto the d orbitals of Ti and the p orbitals of O and then compute the difference of these two selections.
If you are unsure about the specific projections that are available, you can use
>>> calculation.projector.selections() {'atom': [...], 'orbital': [...], 'spin': [...]}to get a list of all available ones.
-
Returns
pd.DataFrame- Contains the energies at which the DOS was evaluated aligned to the Fermi energy and the total DOS or the spin-resolved DOS for spin-polarized calculations. If available and a selection is passed, the orbital resolved DOS for the selected orbitals is included.
Examples
>>> calculation.dos.to_frame()
energies total
0 ...
Select the p orbitals of the first atom in the POSCAR file:
>>> calculation.dos.to_frame(selection="1(p)")
energies total Sr_1_p
0 ...
Select the d orbitals of Sr and Ti:
>>> calculation.dos.to_frame("d(Sr, Ti)")
energies total Sr_d Ti_d
0 ...
Collinear calculations separate the DOS into two spin components
>>> collinear_calculation.dos.to_frame()
energies up down
0 ...
You can also select spin contribution of specific atoms or orbitals, e.g. the spin-up contribution of the first three atoms combined
>>> collinear_calculation.dos.to_frame("up(1:3)")
energies up down 1:3_up
0 ...
Noncollinear calculations contain four spin components but by default only the total DOS is shown
>>> noncollinear_calculation.dos.to_frame()
energies total
0 ...
You can select specific spin components if you want, e.g. the spin projection along the z axis
>>> noncollinear_calculation.dos.to_frame("sigma_z")
energies total sigma_z
0 ...
You can also use simple addition and subtraction to combine the contributions of different orbitals, e.g. add the contribution of three d orbitals
Add the contribution of three d orbitals
>>> calculation.dos.to_frame("dxy + dxz + dyz")
energies total dxy + dxz + dyz
0 ...
Read the density of states generated by the ‘’’k’’’-point mesh in the KPOINTS_OPT file (analogously for KPOINTS_WAN)
>>> calculation.dos.to_frame("kpoints_opt")
energies total
0 ...
to_graph
str = None) → Graph
Read the DOS and convert it into a graph.
The x axis is the energy mesh used in the calculation shifted such that the Fermi energy is at 0. On the y axis, we show the DOS. For ISPIN = 2, the different spin components are shown with opposite sign: “up” with a positive sign and “down” with a negative one. If you used LORBIT in your VASP calculation and you pass in a selection, py4vasp will add additional lines corresponding to the selected projections.
We create some example data do that you can follow along. Please define a variable path with the path to a directory that exists and does not contain any VASP calculation data. Alternatively, you can use your own data if you have run VASP with LORBIT.
>>> from py4vasp import demo
>>> calculation = demo.calculation(path)
>>> collinear_calculation = demo.calculation(path, selection="collinear")
>>> noncollinear_calculation = demo.calculation(path, selection="noncollinear")
Parameters
- selection:
str= None - A string specifying the projection of the orbitals. There are four distinct
possibilities:
-
To specify the atom, you can either use its element name (Si, Al, …) or its index as given in the input file (1, 2, …). For the latter option it is also possible to specify ranges (e.g. 1:4).
-
To select a particular orbital you can give a string (s, px, dxz, …) or select multiple orbitals by their angular momentum (s, p, d, f).
-
For the spin, you have the options up, down, or total.
-
If you used a different k-point mesh choose “kpoints_opt” or “kpoints_wan” to select them instead of the default mesh specified in the KPOINTS file.
You separate multiple selections by commas or whitespace and can nest them using parenthesis, e.g. Sr(s, p) or s(up), p(down). The order of the selections does not matter, but it is case sensitive to distinguish p (angular momentum l = 1) from P (phosphorus).
It is possible to add or subtract different components, e.g., a selection of “Ti(d) - O(p)” would project onto the d orbitals of Ti and the p orbitals of O and then compute the difference of these two selections.
If you are unsure about the specific projections that are available, you can use
>>> calculation.projector.selections() {'atom': [...], 'orbital': [...], 'spin': [...]}to get a list of all available ones.
-
Returns
Graph- Graph containing the total DOS. If the calculation was spin polarized, the resulting DOS is spin resolved and the spin-down DOS is plotted towards negative values. If a selection is given the orbital-resolved DOS is given for the specified projectors.
Examples
For the total DOS, you do not need any arguments. py4vasp will automatically use two separate lines, if you used ISPIN = 2 in the VASP calculation
>>> calculation.dos.to_graph()
Graph(series=[Series(x=array(...), y=array(...), label='total', ...)],
xlabel='Energy (eV)', ..., ylabel='DOS (1/eV)', ...)
Select the p orbitals of the first atom in the POSCAR file:
>>> calculation.dos.to_graph(selection="1(p)")
Graph(series=[Series(..., label='total', ...), Series(..., label='Sr_1_p', ...)], ...)
Select the d orbitals of Sr and Ti:
>>> calculation.dos.to_graph("d(Sr, Ti)")
Graph(series=[Series(..., label='total', ...), Series(..., label='Sr_d', ...),
Series(..., label='Ti_d', ...)], ...)
Collinear calculations separate the DOS into two spin components
>>> collinear_calculation.dos.to_graph()
Graph(series=[Series(..., label='up', ...), Series(..., label='down', ...)], ...)
You can also select spin contribution of specific atoms or orbitals, e.g. the spin-up contribution of the first three atoms combined
>>> collinear_calculation.dos.to_graph("up(1:3)")
Graph(series=[Series(..., label='up', ...), Series(..., label='down', ...),
Series(..., label='1:3_up', ...)], ...)
Noncollinear calculations contain four spin components but by default only the total DOS is shown
>>> noncollinear_calculation.dos.to_graph()
Graph(series=[Series(..., label='total', ...)], ...)
You can select specific spin components if you want, e.g. the spin projection along the z axis
>>> noncollinear_calculation.dos.to_graph("sigma_z")
Graph(series=[Series(..., label='total', ...), Series(..., label='sigma_z', ...)], ...)
You can also use simple addition and subtraction to combine the contributions of different orbitals, e.g. add the contribution of three d orbitals
>>> calculation.dos.to_graph("dxy + dxz + dyz")
Graph(series=[Series(..., label='total', ...), Series(..., label='dxy + dxz + dyz', ...)], ...)
Read the density of states generated by the ‘’’k’’’-point mesh in the KPOINTS_OPT file (analogously for KPOINTS_WAN)
>>> calculation.dos.to_graph("kpoints_opt")
Graph(series=[Series(..., label='total', ...)], ...)
to_image
(
- *args,
- filename = None,
- **kwargs
)
Read the data and generate an image writing to the given filename.
The filetype is automatically deduced from the filename; possible are common raster (png, jpg) and vector (svg, pdf) formats. If no filename is provided a default filename is deduced from the name of the class and the picture has png format.
Note that the filename must be a keyword argument, i.e., you explicitly
need to write filename=”name_of_file” because the arguments are passed
on to the to_graph() method. Please check the documentation of that
method to learn which arguments are allowed.
to_plotly
Produces a graph and convertes it to a plotly figure.
The arguments to this function are passed on to the to_graph() method.
Takes the resulting graph and converts it to a plotly figure.