Dans_Diffraction.classes_fdmnes (version 2.0)
index
c:\users\grp66007\onedrive - diamond light source ltd\pythonprojects\dans_diffraction\dans_diffraction\classes_fdmnes.py

FDMNES class "classes_fdmnes.py"
 functions for generating fdmnes files
 
By Dan Porter, PhD
Diamond
2018
 
Version 2.0
Last updated: 20/07/23
 
Version History:
17/04/18 0.9    Program created
04/06/18 1.0    Program completed and tested
11/06/18 1.1    Analysis updated to find density with _sd1 and _sd0
13/07/19 1.2    Small updates for gui functionality
07/08/19 1.3    Changed reflist in FdmnesAnalysis to list of hkl
16/08/19 1.4    Added BavFile to read parts of .bav file
18/03/20 1.5    Corrected density file for new headers
22/04/20 1.6    Added FdmnesCompare and __add__ method for FdmnesAnalysis
20/07/23 2.0    Refactored program and updated, added new methods and put indata writer in classes_properties
 
@author: DGPorter

 
Modules
       
Dans_Diffraction.functions_crystallography
Dans_Diffraction.functions_general
numpy
os
matplotlib.pyplot
re

 
Classes
       
builtins.object
BavFile
Density
Fdmnes
FdmnesAnalysis
FdmnesCompare
Reflection
Spherical
Xanes

 
class BavFile(builtins.object)
    BavFile(text)
 

 
  Methods defined here:
__init__(self, text)
Initialize self.  See help(type(self)) for accurate signature.
charge_str(self)
returns final cycle ion charge
:return: str
cycle_energy(self)
Return array of total energy per atom for each cycle
cycles(self)
Returns the number of cycles completed
:return:
edge(self)
Returns the resoant edge used in calculation
:return: str
fdmnes_version(self)
Returns the version date of FDMNES used in the calculation
:return: str
header(self)
Returns the top part of the file
:return:
plot_cycle_energy(self)
Plot progress of energy during SCF cycles
potrmt_str(self)
Return final cycle "Potrmt" string
:return: str
radius(self)
Returns the radius used for the calculation
:return: float
reflections(self)
Return list of reflections specified in the header
:return: list
time(self)
Returns the date and time the calculation was run on
:return: str

Data descriptors defined here:
__dict__
dictionary for instance variables (if defined)
__weakref__
list of weak references to the object (if defined)

 
class Density(builtins.object)
    Density(file)
 

 
  Methods defined here:
__init__(self, file)
Load Density of states file from FDMNES calculations '..._sd0.txt'
:param file: filename
__repr__(self)
Return repr(self).
plot(self)
Creates a plot of the DOS spectra, with all d states in one plot
:return: None

Data descriptors defined here:
__dict__
dictionary for instance variables (if defined)
__weakref__
list of weak references to the object (if defined)

 
class Fdmnes(builtins.object)
    Fdmnes(xtl=Crystal with 1 atomic positions, 1 symmetries)
 
FDMNES class: Create input files for the FDMNES software and run the program inside a python console
 
FDMNES (Finite Difference Method for Near Edge Structure) is an abinitio DFT program for
simulating x-ray absorption spectra and resonant diffraction.
FDMNES is developed by Yves Joly at CNRS and can be freely downloaded from here:
  www.fdmnes.neel.cnrs.fr
 
In case of publication, please include the following citation:
  O. Bunau and Y. Joly "Self-consistent aspects of x-ray absorption calculations"
  J. Phys.: Condens. Matter 21, 345501 (2009)
 
This class creates a simple wrapper to automatically generate input files from Dans_Diffraction
Crystal structures. The output files from the calculation can also be automatically plotted.
 
E.G.
xtl = Crystal('Co.cif')
fdm = Fdmnes(xtl)
fdm.setup(folder_name='New_Calculation',
          comment='Test',
          absorber='Co',
          edge='K'
          azi_ref=[0,0,1],
          hkl_reflections=[[1,0,0],[0,1,0],[1,1,0]]
fdm.create_files()
fdm.write_fdmfile()
fdm.run_fdmnes()
###Wait for program completion###
analysis = fdm.analyse()
print(analysis)
analysis.xanes.plot()
analysis.density.plot()
for ref in analysis:
    ref.plot3D()
 
  Methods defined here:
__init__(self, xtl=Crystal with 1 atomic positions, 1 symmetries)
Initialize self.  See help(type(self)) for accurate signature.
__repr__(self)
Return repr(self).
__str__(self)
Return str(self).
analyse(self, folder_name=None)
Analyse the completed calculation
:param folder_name: str name or directory of calculation (None to use current calculation)
:return: FdmnesAnalysis Object
azimuthal_reference(self, hkl=(1, 0, 0))
Generate the azimuthal reference
:param hkl: (1*3) array [h,k,l]
:return: None
create_directory(self)
Create a directory in the FDMNES/Sim folder
:return: None
create_files(self, param_string=None)
Create FDMNES calculation directory and files
 - creates new directory
 - writes the input file to that directory
:param param_string: str text to add to indata file (None will generate)
:return: None
find_fdmnes_exe(self, initial_dir=None, fdmnes_filename='fdmnes_win64.exe', reset=False)
Find fdmnes executable
generate_input_path(self)
Returns the input file pathname
 E.G. 'c:\FDMNES\Sim\Fe2O3\FDMNES_Fe2O3.txt'
:return: filepath
generate_output_path(self, folder_name=None, overwrite=False)
Creates an automatic output path in the FDMNES/Sim directory
 If overwrite is False and the directory already exists, a number will be appended to the name
:param folder_name: str or None, if None xtl.name will be used
:param overwrite: True/False
:return: str directory E.G. 'c:\FDMNES\Sim\Fe2O3'
generate_parameters_string(self)
Create the string of parameters and comments for the input file
:return: str
info(self)
Print setup info
:return: str
run_fdmnes(self)
Run the fdmnes code, waits until the program completes
Remember to use self.create_files and self.write_fdmfile first!
:return: subprocess.call output
setup(self, exe_path=None, output_path=None, output_name=None, folder_name=None, input_name=None, comment=None, energy_range=None, radius=None, edge=None, absorber=None, green=None, scf=None, quadrupole=None, azi_ref=None, correct_azi=None, hkl_reflections=None)
Set FDMNES Parameters
:param exe_path: Location of FDMNES executable, e.g. 'c:\FDMNES\fdmnes_win64.exe'
:param output_path: Specify the output path
:param folder_name: Specify output folder name (replaces output_path)
:param output_name: Name of FDMNES output files
:param input_name: Name of FDMNES input file
:param comment: A comment written in the input file
:param energy_range: str energy range in eV relative to Fermi energy
:param radius: calculation radius
:param edge: absorptin edge, 'K', 'L3', 'L2'
:param absorber: absorbing element, 'Co'
:param green: Green's function (muffin-tin potential)
:param scf: True/False, Self consistent solution
:param quadrupole: False/True, E1E2 terms allowed
:param azi_ref: azimuthal reference, [1,0,0]
:param correct_azi: if True, correct azimuthal reference for real cell (use in hexagonal systems)
:param hkl_reflections: list of hkl reflections [[1,0,0],[0,1,0]]
:return: None
write_fdmfile(self, file_list=None)
Create fdmfile with list of calculations
:param file_list: list of parameter file names for fdmfile, or None to only calculate current parameters
:return: None
write_runfile(self, param_string=None)
Write FDMNES input data to a file
:param param_string: str text to add to indata file (None will generate)
:return: None

Data descriptors defined here:
__dict__
dictionary for instance variables (if defined)
__weakref__
list of weak references to the object (if defined)

 
class FdmnesAnalysis(builtins.object)
    FdmnesAnalysis(output_path, output_name='out', calc_name=None)
 
Create fdmnes object from *_scan_conv.txt file
 
Usage:
    fdm = FdmnesAnalysis(output_path, output_name)
 
    fdm contains all calculated reflections and xanes spectra, as well as spherical tensors
    Automated plotting of azimuths, spectra and density of states.
 
    fdm.xanes.plot()
    fdm.density.plot()
    fdm.I100sp.plot3D()
    fdm.sph_I100sp.plot()
 
  Methods defined here:
__add__(self, other)
__getitem__(self, item)
Return Reflection
__init__(self, output_path, output_name='out', calc_name=None)
Loads data from an FDMNES calculation, allowing plotting and data cuts
 E.G.
 fdm = FdmnesAnalysis('c:\FDMNES\Fe2O3','out')
 fdm.xanes.plot()
 plt.show()
 
:param output_path: directory of the calculation to be loaded
:param output_name: base output name for the calculation (default='out')
__repr__(self)
Return repr(self).
__str__(self)
Return str(self).
info(self)
Returns header of calculation output fipe (*_bav.txt)
:return: str

Data descriptors defined here:
__dict__
dictionary for instance variables (if defined)
__weakref__
list of weak references to the object (if defined)

Data and other attributes defined here:
angle = array([0])
energy = array([0])
refkeys = []
reflections = {}
reflist = []
sphkeys = []

 
class FdmnesCompare(builtins.object)
    FdmnesCompare(fdm_objects)
 
Compare FDMNES Calculations
Method of joining sevearl FdmnesAnalysis objects to plot spectra on the same plot for comparison.
Usage:
    fd1 = FdmnesAnalysis('calc_dir/calc1')
    fd2 = FdmnesAnalysis('calc_dir/calc2')
    fd3 = FdmnesAnalysis('calc_dir/calc3')
    fdms = FdmnesCompare([fd1, fd2, fd3])
    *or*
    fdms = fd1 + fd2 + fd3
    *or*
    fdms = load_fdmnes_files('calc_dir') # loads all calculations ind calc_dir
 
    fdms.plot_xanes()
    fdms.plot_reflection_spectra('I003sp', 0) # specify azimuthal angle in deg
    fdms.plot_reflection_azimuth('I003sp', 2838) # specify energy in eV
 
  Methods defined here:
__add__(self, other)
__init__(self, fdm_objects)
Initialize self.  See help(type(self)) for accurate signature.
__repr__(self)
Return repr(self).
info(self)
load(self, bav_files=())
Load a series of calculation files
plot_all_azimuth(self, energy=0, normalise=False, new_figure=True)
Plot all available azimuths across calculations
:param energy: point at which to cut energy
:param normalise: normalise each spectra by max point
:return:
plot_all_spectra(self, psi=0, normalise=False)
Plot all available spectra across calculations
:param psi: azimuthal angle [Deg]
:param normalise: normalise each spectra by max point
:return:
plot_reflection_azimuth(self, refkey, energy=0, normalise=False, new_figure=True)
Plot all energy spectra for a reflection
:param refkey: str, reflection key as in name_conv.txt
:param energy: float, energy [eV]
:param normalise: normalise each spectra by max point
:param new_figure: create a new figure if True, otherwise plot on the current axis
:return: None
plot_reflection_spectra(self, refkey, psi=0, normalise=False, new_figure=True)
Plot all energy spectra for a reflection
:param refkey: str, reflection key as in name_conv.txt
:param psi: float, azimuthal angle
:param normalise: normalise each spectra by max point
:param new_figure: create a new figure if True, otherwise plot on the current axis
:return: None
plot_xanes(self, normalise=False, new_figure=True)
Plot XANES spectra for each calculation
:param normalise: normalise each spectra by max point
:param new_figure: create a new figure if True, otherwise plot on the current axis
:return: None

Data descriptors defined here:
__dict__
dictionary for instance variables (if defined)
__weakref__
list of weak references to the object (if defined)

 
class Reflection(builtins.object)
    Reflection(energy, angle, intensity, refname, calc_name)
 

 
  Methods defined here:
__init__(self, energy, angle, intensity, refname, calc_name)
Container for FDMNES RXS calculations for each reflection
:param energy: array of energy values [1xm]
:param angle: array of angle values [1xn]
:param intensity: array of intensity values [mxn]
:param refname: reflection name, for plot title
:param calc_name: calculation name, for plot title
__repr__(self)
Return repr(self).
azi_cut(self, cutenergy=None)
Returns the array of intensitiy values at a particular energy
:param cutenergy: energy of cut (eV)
:return: array of intensities
eng_cut(self, cutangle=None)
Returns the array of intensitiy values at a particular angle
:param cutangle: angle of cut (deg)
:return: array of intensities
plot3D(self)
Generate a 3D figure of energy vs angle vs intensity
:return: None
plot_azi(self, cutenergy='max')
Generate a plot of azimuthal dependence at a particular energy
:param cutenergy: 'max' to use the maximum height energy, or an energy in eV
:return: None
plot_eng(self, cutangle='max')
Generate a plot of energy dependence at a particular azimuth
:param cutangle: 'max' to use the maximum intensity height angle, or an angle in deg
:return: None

Data descriptors defined here:
__dict__
dictionary for instance variables (if defined)
__weakref__
list of weak references to the object (if defined)

 
class Spherical(builtins.object)
    Spherical(data, refname, calc_name)
 

 
  Methods defined here:
__init__(self, data, refname, calc_name)
Load contribution from spherical harmonics from out_sph_signal_rxs1.txt
:param data: data array from read_spherical()
:param refname: reflection name for plot title
:param calc_name: calculation name for plot title
__repr__(self)
Return repr(self).
plot(self)
Plot the spherical components
:return: None

Data descriptors defined here:
__dict__
dictionary for instance variables (if defined)
__weakref__
list of weak references to the object (if defined)

 
class Xanes(builtins.object)
    Xanes(energy, intensity, calc_name)
 

 
  Methods defined here:
__init__(self, energy, intensity, calc_name)
Container for XANES spectra from FDMNES
:param energy: array of energy values
:param intensity: array of intensity values
:param calc_name: calculation name for plot title
__repr__(self)
Return repr(self).
plot(self)
Plot the Xanes spectra
:return: None

Data descriptors defined here:
__dict__
dictionary for instance variables (if defined)
__weakref__
list of weak references to the object (if defined)

 
Functions
       
azi_cut(storeeng, intensities, cutenergy=None)
Generate azimuthal cut at a particular energy
cutintensity = azi_cut(storeeng,intensities,cutenergy)
    storeeng = [nx1] array of energies from read_scan_conv
    intensities = [nxm] array of simulated intensities for a single reflection (e.g. storevals['I(100)sp'])
    cutenergy = energy to take the cut at, will take value closest to cutenergy. In eV.
    cutenergy = 'max' - take the cut energy at the maximum intensity.
    cutintensity = [mx1] array of simulated intensity at this energy
 
e.g.
 energy,angle,intensities = read_scan_conv(filename)
 cutintensity = azi_cut(energy,intensities['I(100)sp'],cutenergy='max')
eng_cut(storeang, intensities, cutangle=None)
Generate energy cut at a particular azimuthal angle
cutintensity = eng_cut(storeang,intensities,cutangle)
    storeang = [mx1] array of angles from read_scan_conv
    intensities = [nxm] array of simulated intensities for a single reflection (e.g. storevals['I(100)sp'])
    cutangle = angle to take the cut at, will take value closest to cutenergy. In Deg.
    cutangle = 'max' - take the cut angle at the maximum intensity.
    cutintensity = [nx1] array of simulated intensity at this angle
 
e.g.
 energies,angles,intensities = read_scan_conv(filename)
 cutintensity = eng_cut(angles,intensities['I(100)sp'],cutangle=180)
fdmnes_checker(activate=False, fdmnes_filename='fdmnes_win64.exe', initial_dir=None)
Returns True if fdmnes available and activated
find_fdmnes(fdmnes_filename='fdmnes_win64.exe', reset=False, initial_dir=None)
Finds the path of the fdmnes_win64.exe file
 The name of the file is taken from the envrionment varialbe fdmnes_filename
 The first time this is run, it will take a while, searching through every folder for the file
 On completion, a file will be generated in the /data directory with the filepath
 Subsequent runs will quickly load from this file
:param fdmnes_filename: name of the executable to search for
:param reset: if True, pointerfile will be ignored.
:param initial_dir: None or str, if directory, look here for file
:return: str : location of fdmnes executable file
find_fdmnes_files(parent_directory=None, output_name='out')
Finds all fdmnes calculations below a parent directory
Assumes all files have the same output name
:param parent_directory: top directory, searches lower directories recursivley
:param output_name: e.g. 'out.txt'
:return: list of filenames ['dir/out.txt']
load_fdmnes_files(parent_directory=None, output_name='out')
Finds all fdmnes calculations below a parent directory, loads each file
Assumes all files have the same output name
:param parent_directory: top directory, searches lower directories recursivley
:param output_name: e.g. 'out.txt'
:return: FdmnesCompare
potrmt(bav_text)
Get the final cycle charge values from the _bav.txt file
 
:param bav_text: str _bav.txt file
:return: dict with keys ['Z', 'charge', 'ch_ion', 'Vmft', 'Ionic radius']
read_conv(filename='out_conv.txt', plot=False)
Reads fdmnes output file out_conv.txt, that gives the XANES spectra
  energy, intensity = read_conv(filename)
read_density(filename)
Load Density of states file from FDMNES calculations '..._sd0.txt'
read_scan_conv(filename='out_scan_conv.txt')
Read FDMNES _scan_conv.txt files, return simulated azimuthal and energy values
   energy, angle, intensity = read_scan_conv('out_scan_conv.txt')
You can see all the available reflections with intensity.keys()
:param filename: str name of '*_scan_conv.txt' file from FDMNED calculation
:return energy: [nx1] array of energy values
:return angle: [mx1] array on angle values
:return intensity:  {'I(100)ss'}[nxm] dict of arrays of simulated intensities for each reflection
read_spherical(filename)
Load contribution from spherical harmonics to resonant reflection, from e.g. out_sph_signal_rxs1.txt
sim_folder(folder_name='', new_folder=False)
Generates a calculation path directory in the FDMNES/Sim directory
  If new_folder is True and the directory already exists, a number will be appended to the name
:param folder_name: str folder name
:param new_folder: True/False*
:return: str directory E.G. 'c:\FDMNES\Sim\folder_name'