[Pw_forum] band and dos input files in xcrysden

O. Baris Malcioglu baris.malcioglu at gmail.com
Thu Feb 26 11:09:08 CET 2009


Dear Paolo,

I, being a script-happy person, like the "seperate steps" approach of
pw.x very very much. Although not as high level as a python one,
please find a script written in TCL which I use for preparing DOS and
PDOS plots.

Use this at your own risk! Being a script I modify it constantly for
my needs, and I am not sure this is the "most corrected" version.

Basically you use it like this :

makedosgraph.tcl "pw.x input file" "pw.x output file for latest
coordinates or -- to use coordinates in input file" -i "mpi related
things + directory"

run the script without parameters to see available options.

some examples:
Prepare the pdos showing atoms 1 3 5 with a degauss of 0.002 from a pwscf result

makedosgraph.tcl in.grapheneO -- -i "/home/obm/Progs/pwscf/bin/"
-plot_dg 0.002 -fermi_at_zero -atoms "1 3 5"

Prepare a nscf file using the latest coordinates from a output file of
a relaxation run

makedosgraph.tcl in.grapheneO out.grapheneO -s 1

Prepare gnuplot files for an already run projwfc.x/dos.x

makedosgraph.tcl in.grapheneO -- -s 4 -fermi_at_zero -atoms "1 3 5"


(I also remember having something for bands and workfunctions somewhere)

Best,
Baris Malcioglu
SISSA .


makedosgraph.tcl

#!/bin/sh
# the next line restarts using tclsh \
exec tclsh8.4 "$0" "$@"

###########################
# this script will
# 1) read an input file for prefix and outdir
# 2) read an output file for latest coordinates
# 2) do a nscf calculation according to above data
# 3) do a dos.x calculation according to above data
# 4) do a projwfc.x calculation according to above data
# 5) prepare gnuplot files
#
# Osman Baris Malcioglu 2007 v.1 alpha
#
##########################

proc ::main {argc argv} {

global pw_input_file
global pw_output_file
global plot_dg
global stag
global spref
global plotlist
global nspin

	
	set plot_dg 0
	set stag 0
	set spref ""
	set plotlist ""

	get_commandline $argc $argv
        do_calcs
}

##########################
#A procedure to read commandline
##########################
proc ::get_commandline {argc argv} {

global pw_input_file
global pw_output_file
global plot_dg
global stag
global spref
global plotlist
global fatzero

        set fatzero 0

        if { $argc < 2} {
                puts stderr "Usage: makedosgraph <input file> <otput
file>\[parameters\]"
                puts stderr "Parameters:"
		puts stderr "-s : set calculation stage "
		puts stderr "     1 : prepare nscf files and exit"
		puts stderr "     2 : use present files and run nscf, and quit"
		puts stderr "     3 : prepare for and run dos.x and  projwfc.x"
		puts stderr "     4 : prepare gnuplot baches for pdos output only"
		puts stderr "-plot_dg <float> : set the plotting degauss in dos.x"
		puts stderr "-i <\"prefix to pwscf\"> : the prefix to be appended to runs"
		puts stderr "-atoms <\"space seperated list of atoms\">: will draw
these atoms only"
                puts stderr "-fermi_at_zero move the graphs such that
Ef is at 0"
		exit 1
        }

	if { $argc > 0 } {
		set state first
		foreach arg $argv {
   			switch -- $state {
      		first {
			set state second
			#check if the infile exists
			set pw_input_file $arg
		        if { [file exists $pw_input_file] } {
                		puts "using input file $pw_input_file"
		        } else {
                		puts stderr "Input file $pw_input_file does not exits"
		                exit 1
        		}

		}
		second {
			set state flag
			#check if the outfile exists
		        set pw_output_file $arg
		        if { [file exists $pw_output_file] || $pw_output_file == "--"} {
		                puts "using output file $pw_output_file"
		        } else {
                		puts stderr "Output file $pw_output_file does not exist"
		                exit 1
		        }	
		}
		flag {
         		switch -glob -- $arg {
			-plot_dg {
				set state p_dg
			}
			-s {
				set state sstag
 			}
			-i { set state sspref }
			-atoms {set state splotlist}
                        -fermi_at_zero {set fatzero 1}
            		default {
				puts stderr "unknown flag $arg"
 				exit 2
				}
         		}
      		}
      		
		p_dg {
                        if { [ regexp -- {-?[0-9]+\.?[0-9]*} $arg plot_dg ] } {
                        	puts "using plot degauss = $plot_dg"
                        	set state flag
                        } else {
                         puts stderr " I didn't understand $arg after -plot_dg "
                         exit 2
                        }
                }
		sstag {
                        if { [ regexp -- {[1-4]} $arg stag ] } {
                        	puts "Calculation stage set to $stag"
                        	set state flag
                        } else {
                         puts stderr " I didn't understand $arg after -s "
                         exit 2
                        }
                }
		sspref {
			set spref $arg
                        puts "run prefix is $spref"
			set state flag
                }
		splotlist {
			set plotlist $arg
                        puts "Plotlist is $plotlist"
			set state flag
                }



                        }
                }
      }
	if {![file exists [file join $spref "pw.x"]]} {
		puts "Warning: I can not find [file join $spref pw.x ]"
	}	
	if {![file exists [file join $spref "dos.x"]]} {
		puts "Warning: I can not find [file join $spref dos.x ]"
	}	
	if {![file exists [file join $spref "projwfc.x"]]} {
		puts "Warning: I can not find [file join $spref projwfc.x ]"
	}	

}
#######################
#This procedure reads the input file, prepares input files for nscf
dos.x projwfc.x
#and runs them
######################
proc ::do_calcs {} {

global pw_input_file
global pw_output_file
global pw_outdir
global n_at
global pw_prefix
global lc_pos
global lc_posin
global stag
global spref
global nspin
global e_fermi
global plotlist
global plot_dg
global fatzero
        if [catch {open $pw_input_file r} fileId] {
                puts stderr "Cannot open $pw_input_file: $fileId"
                exit 1
        }
        set tmpfile [read $fileId]
        close $fileId
	if { ! [regexp -linestop -- {outdir\s*=\s*'?"?(.*?)[!',]*} $tmpfile
match pw_outdir] } {
		puts stderr "outdir not found !"	
 		exit 1
	} else {
		puts "The outdir is : $pw_outdir"
	}
	if { ! [regexp -linestop  -- {prefix\s*=\s*'?"?(.*?)[!',]*} $tmpfile
match pw_prefix] } {
		puts stderr "prefix not found !"	
 		exit 1
	} else {
		puts "The prefix is : $pw_prefix"
	}
	# read number of atoms
	 if {![regexp -linestop -- {nat\s*=\s*([0-9]+)} $tmpfile match n_at]} {
		puts "Error reading n_at, exiting"
		exit 2
 	}	
 	puts "nat=$n_at"
	# read nspin
	 if {![regexp -linestop -- {nspin\s*=\s*([1-2])} $tmpfile match nspin]} {
		puts "no nspin line found, setting nspin to 1"
		set nspin 1
 	}	
	puts "nspin=$nspin"

	# do this only if stage is 0 or 1
	if {$stag<2} {
        regsub -nocase -linestop -- {calculation.*} $tmpfile
{calculation = 'nscf'} tmpfile2
        regsub -nocase -linestop -- {restart_mode.*} $tmpfile2 {} tmpfile2
        if { $pw_output_file != "--" } {
	if [catch {open $pw_output_file r} fileId] {
                puts stderr "Cannot open $pw_output_file: $fileId"
                exit 1
        }
        set tmpoutfile [read $fileId]
        close $fileId
	if {[regexp -all -indices -nocase --
{ATOMIC_POSITIONS\s*\([a-z]+\)\s*} $tmpoutfile lc_pos] == 0 } {
		puts stderr "Error locating latest coordinates in $pw_output_file "
		exit 1
	}
	set lc_pos [lindex [split $lc_pos] 1]
	puts "Latest coordinates at index:$lc_pos in output file"
	if {[regexp -all -indices -nocase --
{ATOMIC_POSITIONS\s*\{?\(?[a-z]+\)?\}?\s*} $tmpfile2 lc_posin] == 0 }
{
		puts stderr "Error locating latest coordinates in $pw_input_file "
		exit 1
	}
	set lc_posin [lindex [split $lc_posin] 1]
	puts "Coordinates at index:$lc_posin in input file"

	for {set i 0} {$i<$n_at} {incr i 1} {
		set search "regexp -start $lc_pos -linestop -nocase --
{\[a-z\]+\\s+-?\[0-9\]+\\.?\[0-9\]*\\s+-?\[0-9\]+\\.?\[0-9\]*\\s+-?\[0-9\]+\\.?\[0-9\]*}
\$tmpoutfile match"
		#puts "$search"
		eval $search
		set search "regexp -start $lc_posin -linestop -nocase --
{\[a-z\]+\\s+-?\[0-9\]+\\.?\[0-9\]*\\s+-?\[0-9\]+\\.?\[0-9\]*\\s+-?\[0-9\]+\\.?\[0-9\]*}
\$tmpfile2 match2"
		#puts "$search"
		eval $search
		puts "replacing $match2 with $match"
		puts "[regsub -linestop "$match2" $tmpfile2 "$match" tmpfile2]
replacements was made"
		set search "regexp -start $lc_pos -linestop -nocase -indices --
{\[a-z\]+\\s+-?\[0-9\]+\\.?\[0-9\]*\\s+-?\[0-9\]+\\.?\[0-9\]*\\s+-?\[0-9\]+\\.?\[0-9\]*\\s*}
\$tmpoutfile match"
		#puts $search
		eval $search
		set lc_pos [lindex [split $match] 1]
		set search "regexp -start $lc_posin -linestop -nocase -indices --
{\[a-z\]+\\s+-?\[0-9\]+\\.?\[0-9\]*\\s+-?\[0-9\]+\\.?\[0-9\]*\\s+-?\[0-9\]+\\.?\[0-9\]*\\s*}
\$tmpfile2 match2"
		#puts $search
		eval $search
		set lc_posin [lindex [split $match2] 1]

	}
	unset tmpoutfile
	} else {
	 puts "using input coordinates"
	}
	if {![regexp -nocase -linestop -- {diagonalization} $tmpfile2]} {
		puts "The diagonalization method is now set to cg"
		regsub -- {\&electrons} $tmpfile2 "\\&electrons\n
diagonalization='cg'" tmpfile2
	}


	puts "Preparing nscf input in.$pw_prefix.nscf"
        if [catch {open in.$pw_prefix.nscf w} fileId] {
                puts stderr "Cannot open in.$pw_prefix.nscf: $fileId"
                exit 1
        }
	
	puts $fileId $tmpfile2
	close $fileId
	}
	# do this only if stage is 2 or 0
	if {$stag == 2 || $stag == 0} {
	puts "Running nscf calculation"
	 exec [file join $spref pw.x ] < in.$pw_prefix.nscf > out.$pw_prefix.nscf
	}
	#do this if stage is anyhing but 4
	if {$stag < 4 } {

	puts "preparing DOS input : in.$pw_prefix.dosx"
	if [catch {open in.$pw_prefix.dosx w} fileId] {
             puts stderr "Cannot open in.$pw_prefix.dosx: $fileId"
             exit 1
        }
	
	puts $fileId "&inputpp"
	puts $fileId "   outdir='$pw_outdir'"
	puts $fileId "   prefix='$pw_prefix'"
	if {$plot_dg > 0} {
		puts $fileId "   degauss = $plot_dg"
	}
	puts $fileId "/"
	close $fileId
	puts "Running Dos.x"
	exec [file join $spref dos.x ] <in.$pw_prefix.dosx >out.$pw_prefix.dosx
	puts "Preparing gnuplot batch for DOS: $pw_prefix.dosx.gnu"
	if [catch {open $pw_prefix.dosx.gnu w} gnufile] {
             puts stderr "Cannot open in.$pw_prefix.dosx: $gnufile"
             exit 1
        }
	puts $gnufile "set term jpeg size 1024,768"
	puts $gnufile "set output '$pw_prefix-dos.jpg'"
	puts $gnufile "set key below"
	puts $gnufile "set title '$pw_prefix'"
        puts $gnufile "set xlabel 'Energy in (eV)'"
	puts $gnufile "set ylabel 'DOS'"
	if {$nspin == 2} {
		puts $gnufile "plot '$pw_prefix.dos' using 1:2 w l title 'Spin
up','$pw_prefix.dos' using 1:3 w l title 'Spin down'"
	} else {
		puts $gnufile "unset key"
		puts $gnufile "plot '$pw_prefix.dos' using 1:2 w l "
	}
        close $gnufile
	
	puts "Running PDOS"
	exec [file join $spref projwfc.x ] <in.$pw_prefix.dosx >out.$pw_prefix.pdosx
	}
	# do anyhow, preparation for further stages
	if {$stag < 5 } {
	puts "preparing gnuplot file for pdos : $pw_prefix-pdos.gnu"
	if [catch {open out.$pw_prefix.nscf r} fileId] {
                puts "Warning : Cannot open out.$pw_prefix.nscf:
$fileId , setting Fermi Energy to zero"
                set e_fermi 0
        } else {
        set tmpoutfile [read $fileId]
        close $fileId
	if {[regexp -linestop -- {the Fermi energy is\s+(-?[0-9]+\.?[0-9]*)}
$tmpoutfile match e_fermi]} {
		puts "NSCF calculation yields an Efermi of $e_fermi"
	} else {
		puts "Error reading E_fermi, set to 0"
		set e_fermi 0
	}
        }

	if [catch {open $pw_prefix-pdos.gnu w} gnufile] {
             puts stderr "Cannot open in.$pw_prefix.dosx: $gnufile"
             exit 1
        }
	puts $gnufile "set term jpeg size 1024,768"
        puts $gnufile "set output '$pw_prefix-pdos.jpg'"
	puts $gnufile "set key below"
        puts $gnufile "set title '$pw_prefix'"
	puts $gnufile "set xlabel 'Energy in (eV)'"
        puts $gnufile "unset ylabel"
	puts $gnufile "unset ytics"
	puts $gnufile "set yrange \[0:[expr {[llength $plotlist]*1.5 + 2}]\]"
	if {[llength $plotlist]==0} {
		if {$nspin == 2} {
		puts $gnufile "plot '$pw_prefix.pdos_tot' using 1:4 w l title 'Spin
up','$pw_prefix.pdos_tot' using 1:5 w l title 'Spin down'"
		} else {
			puts $gnufile "unset key"
			puts $gnufile "plot '$pw_prefix.pdos_tot' using 1:3 w l "
		}
	} else {
		puts $gnufile "unset key"
		if {$nspin == 2} {
                        if { $fatzero == 0 } {
			 puts $gnufile "set label \"Ef=$e_fermi\" at [expr
{$e_fermi+0.2}],0.6 front rotate"
                        } else {
                         puts $gnufile "set label \"Ef\" at 0.2,0.6
front rotate"
                        }
			puts $gnufile "set label \"S\" at graph 0,1.02 point lt 1"
			puts $gnufile "set label \"Pz\" at graph 0.1,1.02 point lt 2"
			puts $gnufile "set label \"Px\" at graph 0.2,1.02 point lt 3"
			puts $gnufile "set label \"Py\" at graph 0.3,1.02 point lt 4"
			set plot_incr 0
			foreach atom_no $plotlist {
				puts $gnufile "set label \"Atom $atom_no\" at graph -0.01,first
[expr {$plot_incr+0.6}] rotate"
				set plot_incr [ expr {$plot_incr + 1.5} ]	
			}
			puts $gnufile "set label \"Tot Pdos\" at graph -0.01, first [expr
{[llength $plotlist]*1.5 + 0.7}] rotate"
			puts -nonewline $gnufile "plot "
			set plot_incr 0
			foreach atom_no $plotlist {
			 foreach file [glob -nocomplain $pw_prefix.pdos_atm#$atom_no* ] {
				if {[regexp "$pw_prefix.pdos_atm#$atom_no\\(.+?\\)_wfc#1\\(s\\)"
$file match]} {
				 if { $fatzero == 0 } {
				  puts -nonewline $gnufile "'$match' using 1:($plot_incr+\$4) w l lt 1,"
                                 } else {
          			  puts -nonewline $gnufile "'$match' using
(\$1-$e_fermi):($plot_incr+\$4) w l lt 1,"
				 }
				}
				 if {[regexp "$pw_prefix.pdos_atm#$atom_no\\(.+?\\)_wfc#2\\(p\\)"
$file match]} {
				 if { $fatzero == 0 } {
                                 puts -nonewline $gnufile "'$match' u
1:($plot_incr+\$4) w l lt 2,'$match' u 1:($plot_incr+\$6) w l lt
3,'$match' u 1:($plot_incr+\$8) w l lt 4,"
				 } else {
				  puts -nonewline $gnufile "'$match' u
(\$1-$e_fermi):($plot_incr+\$4) w l lt 2,'$match' u
(\$1-$e_fermi):($plot_incr+\$6) w l lt 3,'$match' u
(\$1-$e_fermi):($plot_incr+\$8) w l lt 4,"
                                 }
                                }
			 }
			set plot_incr [expr {$plot_incr + 1.5}]	
			}
			if { $fatzero == 0 } {
			 puts $gnufile "'$pw_prefix.pdos_tot' using 1:(\$2/4+$plot_incr) w
l lt 1,'-' w l lt 8"
			 puts $gnufile "$e_fermi 0"
			 puts $gnufile "$e_fermi [expr {$plot_incr+10}]"
			 puts $gnufile "e"
                        } else {
        		 puts $gnufile "'$pw_prefix.pdos_tot' using
(\$1-$e_fermi):(\$2/4+$plot_incr) w l lt 1,'-' w l lt 8"
                	 puts $gnufile "0 0"
                         puts $gnufile "0 [expr {$plot_incr+10}]"
                         puts $gnufile "e"

                        }
			
		} else {
	                if { $fatzero == 0 } {
			 puts $gnufile "set label \"Ef=$e_fermi\" at [expr
{$e_fermi+0.2}],0.6 front rotate"
                        } else {
                         puts $gnufile "set label \"Ef\" at 0.2,0.6
front rotate"
                        }
			puts $gnufile "set label \"S\" at graph 0,1.02 point lt 1"
			puts $gnufile "set label \"Pz\" at graph 0.1,1.02 point lt 2"
			puts $gnufile "set label \"Px\" at graph 0.2,1.02 point lt 3"
			puts $gnufile "set label \"Py\" at graph 0.3,1.02 point lt 4"
			set plot_incr 0
			foreach atom_no $plotlist {
				puts $gnufile "set label \"Atom $atom_no\" at graph -0.01,first
[expr {$plot_incr+0.6}] rotate"
				set plot_incr [ expr {$plot_incr + 1.5} ]	
			}
			puts $gnufile "set label \"Tot Pdos\" at graph -0.01, first [expr
{[llength $plotlist]*1.5 + 0.7}] rotate"
			puts -nonewline $gnufile "plot "
			set plot_incr 0
			foreach atom_no $plotlist {
			 foreach file [glob -nocomplain $pw_prefix.pdos_atm#$atom_no* ] {
				if {[regexp "$pw_prefix.pdos_atm#$atom_no\\(.+?\\)_wfc#1\\(s\\)"
$file match]} {
				 if { $fatzero == 0 } {
				  puts -nonewline $gnufile "'$match' using 1:($plot_incr+\$3) w l lt 1,"
                                 } else {
          			  puts -nonewline $gnufile "'$match' using
(\$1-$e_fermi):($plot_incr+\$3) w l lt 1,"
				 }
				}
				 if {[regexp "$pw_prefix.pdos_atm#$atom_no\\(.+?\\)_wfc#2\\(p\\)"
$file match]} {
        		          if { $fatzero == 0 } {
                                   puts -nonewline $gnufile "'$match'
u 1:($plot_incr+\$3) w l lt 2,'$match' u 1:($plot_incr+\$4) w l lt
3,'$match' u 1:($plot_incr+\$5) w l lt 4,"
				 } else {
				  puts -nonewline $gnufile "'$match' u
(\$1-$e_fermi):($plot_incr+\$3) w l lt 2,'$match' u
(\$1-$e_fermi):($plot_incr+\$4) w l lt 3,'$match' u
(\$1-$e_fermi):($plot_incr+\$5) w l lt 4,"
                                 }
                                }
			 }
			set plot_incr [expr {$plot_incr + 1.5}]	
			}
			if { $fatzero == 0 } {
			 puts $gnufile "'$pw_prefix.pdos_tot' using 1:(\$2/4+$plot_incr) w
l lt 1,'-' w l lt 8"
			 puts $gnufile "$e_fermi 0"
			 puts $gnufile "$e_fermi [expr {$plot_incr+10}]"
			 puts $gnufile "e"
                        } else {
			 puts $gnufile "'$pw_prefix.pdos_tot' using
(\$1-$e_fermi):(\$2/4+$plot_incr) w l lt 1,'-' w l lt 8"
                         puts $gnufile "0 0"
                         puts $gnufile "0 [expr {$plot_incr+10}]"
                         puts $gnufile "e"

                        }

		}
			
	}
	close $gnufile
	}



}

main $argc $argv



On Thu, Feb 26, 2009 at 10:34 AM, Paolo Giannozzi
<giannozz at democritos.it> wrote:
>
> On Feb 21, 2009, at 17:05 , Eduardo Ariel Menendez Proupin wrote:
>
>> Let me remind how is the process to obtain the DOS. It has three
>> calculations
>> and 3 input files
>>
>> pw.x < si.scf.in > si.scf.out   # self consistent
>> pw.x <si.dos.in > si.dos.out  # non selfconsistent dense k-points
>> mesh and a few options
>> dos.x <si.dos2.in >  si.dos2.out  # postprocessing
>
> Hi Eduardo,  the issue you raise is a serious one and requires some
> though.
> Right now several standard calculations in q-e are clumsy because they
> require separate steps. While I think that it is a good idea to keep
> separate
> steps separate, I also think that at least the most common
> calculations might
> be streamlined. I am not convinced that the PWGui is the right tool
> for this,
> though, at least not in the present form (a tool to produce input data).
> The ideal  solution would be the usage of a high-level scripting
> language like
> python to "glue" the various pieces together, but this is highly
> nontrivial
> (at least for me and for 99% of q-e users).
> A simpler option could be to collapse some calculations into the same
> executable:
> for instance
> - add a call to dos after a nscf calculation in pw.x,
>   add a call to bands after a bands calculation in pw.x
> or
> - prepend a nscf calculation to dos.x,
>   prepend a band calculation to bands.x
> Suggestions are welcome
>
> Paolo
> ---
> Paolo Giannozzi, Democritos and University of Udine, Italy
>
>
> _______________________________________________
> Pw_forum mailing list
> Pw_forum at pwscf.org
> http://www.democritos.it/mailman/listinfo/pw_forum
>



More information about the users mailing list