pyfplo.fploio¶
This module contains the parser interface to read data from =.in
type
files.
It can also be used to change data in the file.
WARNING: it is better to use pyfplo.fedit
for changing input.
The fedit
interface is kept reasonably clean, while the naming conventions
in =.in
which is accessed directly by the parser is at times chaotic.
Furthermore, there are semantic dependencies in the file, as e.g. descriptors
which are for readability only. If the user changes the underlying value
but not the descriptor the idea of having descriptors is lost.
Furthermore, there are data which depend on the symmetry.
fedit
takes care of all of that.
Please note, that the underlying data representation is in str
format.
This allows to use '1/3'
insted of 0.33333...
for real values.
Hence, the natural return value of the data is str
. If however an explicite
int
or float
representation is wanted and if the type of the specific
data conforms to these types an int
value is returned by PObj.L
and a
float
by PObj.D
.
Logicals are handled as 'f'
or 't'
internally. Hence, PObj.S
returns these
values. However, if returned by PObj.L
, True
and False
are
represented by 1
or 0
respectively.
When writing a logical via PObj.S
't'
, 'T'
and '+'
are considered to be
True
any other string as False
.
When writing a logical via PObj.L
0
and any nonzero int
represent False
and True
, respectively.
Character variables defined as ‘char some_char=’x’; ‘ in the =. file (which
are not used currently) are returned as str
by PObj.S
and as int
by
PObj.L
. The latter interpretation is machine dependend and not recommended.
Similarily, the variable can be written in both ways.
-
fploExecutable
(suffix='')¶ Parameters: suffix (str) – for convenience, suffix is appended to the exec name Return the name of the fplo executable as
str
, which fits the pyfplo version. This is an educated guess. There is no garantee that it is correct. If you compiled with a non-default build branch, this function does not return the name including the build branch suffix but just the generic name. Use suffix to select the correct executable or just write it out explicitely anyway.
INParser¶
-
class
INParser
¶ This class is a low-level class for reading the
=.in
files. For manipulating=.in
use thepyfplo.fedit
class. This is safer, since it ensures data (semantics) consistency.To see how to use some of the low-level routines consult Reading =.in files, Write =.in with low level routines and =.files to json.
Create an instance of the FPLO parser for files of type
=.in
in the following way:import pyfplo.fploio as fploio p=fploio.INParser()
-
parseFile
(filename)¶ Parameters: filename (str) – the filename of an existing file in FPLO =.-format This opens and reads the file given in filename. Safe use:
import os import pyfplo.fploio as fploio p=fploio.INParser() if not os.path.exists('=.in'): raise RuntimeError('cannot find the file') try: p.parseFile("=.in") except RuntimeError,ex: print(ex) pass # do whatever to handle the error or quit the program
-
writeFile
(filename)¶ Parameters: filename (str) – the filename of the new file in FPLO =.-format Write the parser content to a file called filename.
-
__call__
()¶ Return the root of the data tree. The returned object is an instance of class
PObj
, which can be used to access individual data.
-
varExists
(varname)¶ Parameters: varname (str) – the name of the queried variable Returns: existence of variable definition Return type: bool
Check if a variable definition exists in the parse table. Return
True
if it does. This function tests the struct array definition not the actual elements. Example:d=p() # p is a INParser object and d is parser root d2=d('wyckoff_positions')# d2 is node wyckoff_positions (struct array) print d2[0].varExists('element') # -> True print d.varExists('wyckoff_positions.element') # -> False but print p.varExists('wyckoff_positions.element') # -> True #also print d.varExists('wyckoff_positions[1].element') # -> True print d('wyckoff_positions')[1].varExists('element') # -> True
Compare this to
PObj.varExists
.
-
PObj¶
-
class
PObj
¶ This class is a low-level class for reading the
=.in
files. For manipulating=.in
use thepyfplo.fedit
class. This is safer, since it ensures data (semantics) consistency.To see how to use some of the low-level routines consult Reading =.in files, Write =.in with low level routines and =.files to json.
Usually
PObj
instances are returned by other methods. One does not create aPObj
by itself.-
fullName
()¶ Return the full node name. This includes element access (e.g.
nkxyz[3]
).
-
varExists
(varname)¶ Parameters: varname (str) – the name of the queried variable Returns: existence of variable definition Return type: bool
Check if a variable exists under the current node. Return
True
if it does. This function tests struct array elements in detail. Example:d=p() # p is a INParser object and d is parser root d2=d('wyckoff_positions')# d2 is node wyckoff_positions (struct array) print d2[0].varExists('element') # -> True print d.varExists('wyckoff_positions.element') # -> False but print p.varExists('wyckoff_positions.element') # -> True #also print d.varExists('wyckoff_positions[1].element') # -> True print d('wyckoff_positions')[1].varExists('element') # -> True
Compare this to
INParser.varExists
.
-
size
(dim=1)¶ Parameters: dim (int) – dimension Returns: size of the dimension Return type: int
If
PObj
is array-like return its size`For struct arrays and rank-one arrays
size()
returns the array size.For
rank>1
arrayssize(dim)
returns the size of the dim-th dimension.
-
sizes
()¶ Returns: a list
of all array sizes, such thatrank==len(n.sizes())
Return type: list
ofint
-
resize
(size)¶ Parameters: size ( int
orlist
) – can be a scalarint
or a list ofint
in case of multidimensional arrays.If
PObj
is an array or struct array, resize it. Note, that for multidimensional arrays only the last dimension can be resized in the moment. But=.in
does not use multidimensional arrays. (=.dens
does though, which however should not be touched.)
-
__call__
(name)¶ Parameters: name (str) – name of the node Return a new
PObj
which references the node called name under the currentPObs
parse tree node:d=p() # parse tree root ds=d('spin') print ds('mspin').L
Compound names are possible:
d=p() # parse tree root print d('spin.mspin').L
-
__getitem__
(*args)¶ If the node pointed to by
PObj
represents a 1d array type the operator[i]
returns thePObj
, which represents thei
-th element. For flag arrays the operator[flagname]
returns thePObj
, which represents this flag (if it exists). UseS
to print the full flag name and useL
to read or set the flags value. IfPObj
represents a multidimensional array (up to 5d) the operator[i,j,...]
returns the correspondingPObj
of the element.args can be:
index1, index2,…: between one and five
int
indices:dw2=d('wyckoff_positions')[2]
flagname: a single
str
which names a flag in a flag array:d('options')['FULLBZ'].L=True
-
name
()¶ Return the node name. This excludes element access (e.g.
nkxyz[3]
).
-
first
()¶ Returns: first node on the current level. See =.files to json Return type: PObj
-
next
()¶ Returns: the next node on the current level. See =.files to json Return type: PObj
-
hasNext
()¶ Returns: True
if next node exists. See =.files to jsonReturn type: bool
-
isScalar
()¶ Returns: True
if node is a scalar. See =.files to jsonReturn type: bool
-
isArray
()¶ Returns: True
if node is an array. See =.files to jsonReturn type: bool
-
isStruct
()¶ Returns: True
if node is a srtuct. See =.files to jsonReturn type: bool
-
isStructArray
()¶ Returns: True
if node is a srtuct array. See =.files to jsonReturn type: bool
-
isInt
()¶ Returns: True
if node is a scalar int. See =.files to jsonReturn type: bool
-
isReal
()¶ Returns: True
if node is a scalar int. See =.files to jsonReturn type: bool
-
isLogical
()¶ Returns: True
if node is a scalar int. See =.files to jsonReturn type: bool
-
isString
()¶ Returns: True
if node is a scalar int. See =.files to jsonReturn type: bool
-
isChar
()¶ Returns: True
if node is a scalar int. See =.files to jsonReturn type: bool
-
isFlag
()¶ Returns: True
if node is a scalar int. See =.files to jsonReturn type: bool
-
__str__
()¶ return printable representation. You do not need to call this explicitly. An object obj with this function provides usefull info when printed:
print(obj)
-
listS
¶ If
PObj
refers to a 1d array, return it’s elements as a list ofstr
or assign a list ofstr
to the array elements. On assignment to a fixed size array the list must have the proper length On assignment to a variable size array, the array is resized accordingly. One can assign a list ofstr
to integer and real arrays as long as the list’s elements represent the correct type:d('wyckoff_positions')[1]('tau').listD=[1./2,2./3,1./4] d('wyckoff_positions')[1]('tau').listS=['1/2','2/3','1/4']
Note, the dot in
2./3
, which is needed to havefloat
division while in the string version it is not allowed.
-
listD
¶ If
PObj
refers to a real 1d array, return the elements as a list offloat
or assign the list (seelistS
).
-
listL
¶ If
PObj
refers to an integer 1d array, return is elements as a list ofint
or assign the list (seelistS
).
-
L
¶ If the current node refers to an integer type, return it as
int
. If it refers to a flag,1
is returned if the flag is switched on,0
otherwise. Assignment is possible:d('spin.mspin').L=2
-
D
¶ If the current node refers to a real type, return it as
float
. Assignment is possible:d('wyckoff_positions')[0]('tau')[1].D=5.4
-
S
¶ The current
PObj
instance sits at a certain node of the data tree, depending on the history of calls, which created it.If the current
PObj
instance refers to a node, which represents a single value (scalar) the value is returned asstr
representation.If
PObj
refers to a flag the flagname followed by(+)
or(-)
is returned.A new
str
value can be assigned to S. The user must ensure the correctness of the data, e.g. that astr
representing an underlyingfloat
is actually a validfloat
.Let us assume there is a
real tolerance=1e-12;
in=.in
. Then one can set this value as:# d is assumed to be the PObj under which the node tolerance sits. d('tolerance').D=1e-13 # or d('tolerance').S='1e-13'
-
FPLOInput¶
-
class
FPLOInput
(fname=None)¶ FPLOInput
is used to manage the manipulation of=.in
files. It creates new files or reads existing files. The symmetry update functionality of fedit is hidden in this class. This is a low level interface. It is strongly recommended to usepyfplo.fedit
for manipulating data instead.An example of proper usage is found in Write =.in with mid level routines.
Parameters: fname – the name of an existing =.in
file orNone
or nothingCreate a fresh
FPLOInput
object via:import pyfplo.fploio as fploio ... fio=fploio.FPLOInput()
Create a fresh
FPLOInput
object and read a file and update the version, if needed, or create fresh input if the file does not exist via:import pyfplo.fploio as fploio ... fio=fploio.FPLOInput('=.in')
which is equivalent to the following code:
import os import pyfplo.fploio as fploio ... fio=fploio.FPLOInput() if os.path.exists('=.in'): fio.parseInFile(True,'=.in') else: fio.createNewFileContent() # make fresh content ... # or handle this case differently
-
parseInFile
(forceupdate, fname='=.in', newifnonexistent=False)¶ Read the
=.
file called fname into an internal parse tree and optional update version or create fresh content. If something goes wrong an exception is raised.Parameters: - forceupdate (int) – If
True
, convert older version files into new ones - fname (str) –
=.in
-type file name - newifnonexistent (int) – If
True
and the file called fname does not exist, create fresh content in the parse tree (does not cretae a file).
- forceupdate (int) – If
-
symmetryUpdate
()¶ After changing symmetry settings call this to update the rest of the data. A message is returned.
-
resetNonSymmetrySections
()¶ Reset all data in the internal parse table except for the symmetry section. This is used to reset all non symmetry data to default values.
-
writeFile
(name)¶ Parameters: name (str) – filename of =.in
-type fileWrite the parser content to the file called fname.
-
structureFromCIFFile
(ciffilename, wyckofftolerance=1e-06, symblockindex=0, symoptionindex=0, determinesymmetry=False, keeprotation=False)¶ Read the cif-file called ciffilename and import the structure data into the parse tree.
To see how to use this consult Reading cif-files.
wyckofftolerance is used to convert approximations like 0.3333 into 1/3. If the round off error (as in 0.3333) is smaller than wyckofftolerance all numbers which are approximate fractionals n/d, d in [1,12] are replaced by the fractional. This is especially necessary for hexagonal structures where an approximation like 0.3333 for 1/3 leads to trouble (doubling of atoms, missing symmetry operations and such).
Some cif files contain more than one data block. If several blocks are present and if several of these contain symmetry information symblockindex selects the corresponding symmetry block. By default symblockindex is 0, which selects the first such block. The available blocks are written to the output. An example could produce the following output:
------------------------------------------------------------------------ Blocks contained in cif file 'cg049782osi20040706_123518.cif': ------------------------------------------------------------------------ symmetry block No. name ------------------------------------------------------------------------ global 0 cu2as2o7 1 cuasbeta profile ------------------------------------------------------------------------
There are four blocks of which two contain structure/symmetry information. Possible values for symblockindex are 0 or 1.
In principle it is possible that a symmetry containing block has contradicting group information. Often the cif files contains a Hall-symbol, the xyz-operation symbol table and the space group number (or combinations of these). The space group number is not a good indicator, since it does not encode settings. Hence, we analyse the Hall- and xyz-symbols to determine the group. Only if both are missing we rely on the space group number. If, however, Hall- and xyz-symbols lead to different groups (rare but possible), we can select, which of the two to use. The possible symmetry options are written to the output and symoptionindex selects the corresponding option. By default symoptionindex is 0, which selects the first such option. The output of symmetry options could look like this:
Symmetry information for datablock: data_1 Space group number: 227 Name-Hall : F 4d 2 3 -1d xyz-symbol : gives hallsymbol -F 4vw 2vw 3 Hall symbol: OK xyz symbols: OK but not equivalent The following symmetry options are available: 0 'Hall symbol' 1 'xyz-symbols'
You can see that the xyz symbols give a different setting than the Hall symbol. Hence, we have to chose symoptionindex from 0 or 1. You also understand that 227 is not a complete description.
If determinesymmetry is
True
the cif data are symmetry analysed before creating =.in.If determinesymmetry is
True
and keeprotation isTrue
the orientation of the cell is retained during symmetry analysis.A possible way of importing a cif file works like this:
import pyfplo.fploio as fploio import pyfplo.fedit as fedit fio=fploio.FPLOInput('=.in') fio.structureFromCIFFile('data.cif',wyckofftolerance=1e-4, symblockindex=0,symoptionindex=0) fio.writeFile('=.in') # now we have created or update =.in from the cif file fed=fedit.Fedit(recreate=True) # reset default input (except symmetry) fed.iteration(n=100) # ... and more settings fed.pipeFedit() # apply the settings
-
reset
()¶ Reset the internal parse tree to nothing. The resulting
FPLOInput
object is like a newly created one.
-
createNewFileContent
()¶ Create a completely new default file in the internal parse tree.
-
OutGrep¶
-
class
OutGrep
(outfilename='out', dir='.')¶ OutGrep helps to grep results from fplo output files directly into python variables.
Parameters: - outfilename (str) – the name of the fplo output file
- dir (str) – the directory in which it sits
This reads the whole output file, so that using
grep
in a loop is more efficient.Example: grep last total energy and gap:
import pyfplo.fploio as fploio ... og=fploio.OutGrep('out') print('etot=',og.grep('EE')[-1],', gap=',og.grep('gap')[-1])
Example: show iteration progress:
import os import pyfplo.fploio as fploio ... og=fploio.OutGrep('out') with open('res','w') as fh: res=og.grep('it') for i,r in enumerate(res): fh.write('{} {}\n'.format(i,r)) os.system('xfbp res')
Example: grep all atom spins (as a function of iteration) and write them to file
res
:import os import pyfplo.fploio as fploio og=fploio.OutGrep('out') si=og.sites() with open('res','w') as fh: for i,s in enumerate(si): site=i+1 res=og.grep('SSat',site) fh.write('# {}{}\n'.format(s.element,site)) for it,r in enumerate(res): fh.write('{} {}\n'.format(it,r)) fh.write('\n') os.system('xfbp res')
More exmples in Extract =.basdef from output file
-
modes
¶ Type: dict
of mode:long-nameclass variable of all available
OutGrep
modes as ingrepfplo -h
for k in fploio.OutGrep.modes.keys(): print('mode: {0:15s} : {1}'.format(k,fploio.OutGrep.modes[k]))
-
sites
()¶ return a
list
ofpyfplo.common.Site
, which contains info for sites in output file.
-
grep
(mode, site=1, orbital=0)¶ Parameters: - mode (str) – one of the modes defined as keys in
dict
OutGrep.modes
- site (int) – some modes need a site number (one-based, as in fplo output)
- orbital (int) – some modes (population analysis modes) need an orbital number.
orbital is the one-based number of the wanted orbital in the
order as printed in the population analysis.
If orbital is out of range (e.g. 0) the total site population number is printed.
For the mode
N_gros
there is one more number than forN_net
andS_...
, which is the number of excess electrons of the site.
return a
list
ofstr
of mode-dependend results for all iterations found in the output file. Some modes return a single result since it is not iteration dependend. If you needfloat
results, convert likefloat(og.grep('EE')[-1])
orlist(map(float,og.grep('EE')))
.See, examples under
OutGrep
.- mode (str) – one of the modes defined as keys in
Basis¶
-
class
Basis
(version=None, elementsoratomicnumbers=None, basdeffile=None)¶ Basis
gives a low-level access to the basis definition. The basic operations are:- Create a default basis for all sorts via input: basis-version + list of elements/atomic numbers.
- Optionally, read basis definitions from
=.basdef
(overwrites the default). - Modify the basis thusly obtained.
- Write file
=.basdef
.
Consequently, at minimum one needs to know the list of elements. See examples Extract default basis into =.basdef and User defined basis (in =.basdef). If a
=.in
already exists one can obtain this list via:import pyfplo.common as com import pyfplo.fploio as fploio p=fploio.INParser() p.parseFile('=.in') d=p()('wyckoff_positions') elements=[d[i]('element').S for i in range(d.size())] # optionally: atomicnumbers=list(map(lambda x: com.c_elements.index(x),elements)) print(elements) print(atomicnumbers)
To create an FPLO9 default basis in
=.basdef
do this:import pyfplo.fploio as fploio ... b=fploio.Basis('default FPLO9 basis',elements) # modify b if needed, then b.writeFile('=.basdef')
To read and modify
=.basdef
do this:import pyfplo.fploio as fploio ... b=fploio.Basis('default FPLO9 basis',elements,basdeffile='=.basdef') # modify b if needed, then b.writeFile('=.basdef')
Note
Note, that you always need to provide the default version and the element/atomic number list, because some adjustments take place internally based on the elements.
Parameters: - version (
int
orstr
) – ID (int
) or unique search string (case sensitive) into version table. The version table is obtained via the class variablepyfplo.fploio.Basis.versions
, which is a list of available basis versions, where each list member has two members: a unique ID (int
) and astr
, which can be used for searching. - elementsoratomicnumbers (
list
ofstr
and/orint
) – list of element names or atomic numbers for each sort - basdeffile (
str
orNone
) – read (and overwrite default) from file basdeffile if notNone
!
-
versions
¶ class variable of all available Basis versions
Type: list of 2-lists of structure [ID,versionname]
-
writeFile
(filename='=.basdef')¶ Parameters: filename (str) – the basis definitions file name. For use with fplo this needs to be =.basdef
.Write the basis definitions to file filename.
BasDef¶
-
class
BasDef
¶ BasDef
contains the basis of a particular atom. This class is return bypyfplo.fploio.Basis.__getitem__
and cannot be instantiated otherwise.-
__str__
()¶ return printable representation. You do not need to call this explicitly. An object obj with this function provides usefull info when printed:
print(obj)
-
core
¶
-
semicore
¶
-
valence
¶
-
BasDefSection¶
-
class
BasDefSection
¶ -
append
(nl, Q=None, P=None, S=None)¶ Parameters: - nl (str) – multiorbital name, e.g.
'3d'
- Q (
float
orlist
offloat
-s) – - P (
float
orlist
offloat
-s) – - S (
float
orlist
offloat
-s) –
append a double 4f-orbtial like
D4f Q=(q1,q2) P=(p1,p2)
via:basdef.valence.append('4f',Q=[q1,q2],P=[p1,p2])
or a single 4f-orbtial like
s4f Q=(q1) P=(p1)
via:basdef.valence.append('4f',Q=q1,P=p1)
- nl (str) – multiorbital name, e.g.
-
remove
(i)¶ Parameters: i (int) –
-
__len__
()¶ len(b)
returns the size of the Basis section (number of multi-orbitals).
-
__getitem__
()¶ BasDefSection[i]
returns thei
-th MultiOrbital
-
__str__
()¶ return printable representation. You do not need to call this explicitly. An object obj with this function provides usefull info when printed:
print(obj)
-
MultiOrbital¶
-
class
MultiOrbital
¶ This class is return by
pyfplo.fploio.BasDefSection.__getitem__
and such-
append
(Q=0.0, P=1.0, S=0.0)¶ Parameters: - Q (float) –
- P (float) –
- S (float) –
-
removeLast
()¶
-
removeFirst
()¶
-
qns
(mult)¶ Parameters: mult (int) – Returns: Return type: str
-
Q
(mult)¶ Parameters: mult (int) – Returns: Return type: float
-
S
(mult)¶ Parameters: mult (int) – Returns: Return type: float
-
P
(mult)¶ Parameters: mult (int) – Returns: Return type: float
-
set
(mult, Q=None, P=None, S=None)¶ Parameters: - mult (int) –
- Q (
float
orNone
) – - P (
float
orNone
) – - S (
float
orNone
) –
-
__str__
()¶ return printable representation. You do not need to call this explicitly. An object obj with this function provides usefull info when printed:
print(obj)
-
name
¶
-
multiplicity
¶
-
Data¶
For convenience:
-
version
¶ copy of
pyfplo.common.version
-
Version
¶ copy of
pyfplo.common.Version
-
c_elements
¶ copy of
pyfplo.common.c_elements