コード例 #1
0
ファイル: ptb_mol.py プロジェクト: koniweb/pwtoolbox
 def argumentHandler(self,argv):
         #no argument: start GUI
         if len(argv) == 1:
                 self.gui = MainWindow(self)
         else:
                 self.gui = MainWindow(self)
                 for i in range(1,len(argv)):
                         #load a single configuration, start GUI
                         if argv[i] == '-pwi':
                                 self.readFile('PWScf Input',argv[i+1])
                                 self.gui.centralWidget().loadView()
                         if argv[i] == '-pwo':
                                 self.readFile('PWScf Output',argv[i+1])
                                 self.gui.centralWidget().loadView()
                         elif argv[i] == '-xyz':
                                 self.readFile('xyz',argv[i+1])
                                 self.gui.centralWidget().loadView()
コード例 #2
0
ファイル: ptb_mol.py プロジェクト: koniweb/pwtoolbox
class TBController(QApplication):

        def __init__(self,argv):
                super(TBController,self).__init__(argv)
                self.mol = []
                self.pwdata = []
                self.indict = OrderedDict([('xyz',self.parseXyz),
                               ('PWScf Input',self.parsePwi),
                               ('PWScf Output' , self.parsePwo)])
                self.outdict= OrderedDict([('PWScf Input',self.writePwi),
                               ('xyz',self.writeXyz)])
                self.argumentHandler(argv)


#####################################################################
# Handle command line arguments:
#####################################################################
        def argumentHandler(self,argv):
                #no argument: start GUI
                if len(argv) == 1:
                        self.gui = MainWindow(self)
                else:
                        self.gui = MainWindow(self)
                        for i in range(1,len(argv)):
                                #load a single configuration, start GUI
                                if argv[i] == '-pwi':
                                        self.readFile('PWScf Input',argv[i+1])
                                        self.gui.centralWidget().loadView()
                                if argv[i] == '-pwo':
                                        self.readFile('PWScf Output',argv[i+1])
                                        self.gui.centralWidget().loadView()
                                elif argv[i] == '-xyz':
                                        self.readFile('xyz',argv[i+1])
                                        self.gui.centralWidget().loadView()


#####################################################################
# GET FUNCTIONS
#####################################################################

        def get_mol(self,index,step):
                return self.mol[index][step]

        def get_lmol(self,index):
                return len(self.mol[index])

        def get_nmol(self):
                return len(self.mol)

        def get_pw(self,index):
                return self.pwdata[index]

        def get_npw(self):
                return len(self.pwdata)


#####################################################################
# READ FUNCTIONS
#####################################################################

        def readFile(self,fmt,filename):
                data = open(filename,'r').readlines()
                self.indict[fmt](data)
                #return data

        def parseXyz(self,data):
                # create list of mol, trajectory support
                tlist = []
                # if first line does not contain nat exit
                if not data[0].strip().isdigit():
                        print 'not a xyz file'
                        return
                i=0
                while i < len(data):
                        # handle empty lines at eof or between molecules
                        if not data[i].strip().isdigit(): i+=1
                        # create new molecule
                        tmol = Molecule()
                        #fixed format nat and comment
                        nat = int(data[i])
                        tmol.comment = data[i+1]
                        #read coordinates and types
                        for j in range(i+2,i+nat+2):
                                line = data[j].split()
                                tmol.create_atom(line[0],float(line[1]),float(line[2]),float(line[3]))
                        i+=nat+2
                        tlist.append(tmol)
                #append to list of molecules
                self.mol.append(tlist)

        def parsePwi(self,data):
                # no need for list, only one molecule per file
                tmol = Molecule()
                tparam = PWParam()
                tcoord = []
                #parse data and create tparam
                while data:
                        header = data.pop(0).strip().split()
                        # ignore empty lines
                        if not header:
                                pass
                                #debug output. case not really needed.
                        # parse namelists
                        elif header[0][0] == '&':
                                tnl = {}
                                # parse entries
                                line = data.pop(0).strip().split(',')
                                while line[0] != '/':
                                        for j in range(len(line)):
                                                tnl[line[j].split('=')[0].strip()]=line[j].split('=')[1].strip()
                                        line = data.pop(0).strip().split(',')
                                tparam[header[0]]=tnl
                                #debug output
                        # parse card
                        elif header[0][0].isupper():
                                # 7 types of cards, need hardcoding
                                # 4 supported for now

                                #ATOMIC_SPECIES:
                                #Name   Weight  PP-file
                                if header[0] == 'ATOMIC_SPECIES':
                                        for i in range(int(tparam['&system']['ntyp'])):
                                                line = data.pop(0).strip().split()
                                                tparam['pse'][line[0]][1] = float(line[1])
                                                tparam['pse'][line[0]].append(line[2])

                                #ATOMIC_POSITIONS fmt
                                #Name   x   y   z
                                #Saved in temp list for parsing
                                elif header[0] == 'ATOMIC_POSITIONS':
                                        fmt = header[1]
                                        for i in range(int(tparam['&system']['nat'])):
                                                #support empty lines
                                                temp = data.pop(0).strip().split()
                                                while not temp:
                                                        temp = data.pop(0).strip().split()
                                                tcoord.append(temp)

                                #K_POINTS fmt
                                elif header[0] == 'K_POINTS':
                                        #Gamma point only
                                        if header[1] == 'gamma':
                                                tparam['K_POINTS']=['gamma']
                                        #MPGrid:
                                        #x y z offset
                                        #passed as whole string for now
                                        elif header[1] == 'automatic':
                                                #line = data.pop(0).strip().split()
                                                line = data.pop(0)
                                                #tparam['K_POINTS']=['automatic',[line[0:3],line[3:7]]]
                                                tparam['K_POINTS']=['automatic',line]
                                        #else:
                                        #number of kpoints
                                        #x y z weight
                                        #passed as whole string for now
                                        else:
                                                nk = data.pop(0).strip().split()
                                                kpoints = []
                                                for i in range(nk):
                                                        #kpoints.append(data.pop(0).strip().split())
                                                        kpoints.append(data.pop(0))
                                                taparam['K_POINTS']=[header[1],nk,kpoints]

                                #TODO: care for different formats
                                elif header[0] == 'CELL_PARAMETERS':
                                        vec=[[0,0,0],[0,0,0],[0,0,0]]
                                        for i in range(3):
                                                line = data.pop(0).strip().split()
                                                vec[i]=[float(x)for x in line]
                                        tmol.set_vec(vec)
                                else:
                                        pass

                #Create Molecule after getting the cell parameters
                #set celldm from input
                tmol.set_celldm(tparam['&system']['celldm(1)'])
                #create atoms:
                for i in range(len(tcoord)):
                        tmol.create_atom(tcoord[i][0],float(tcoord[i][1]),float(tcoord[i][2]),float(tcoord[i][3]),fmt)
                #delete nat and ntype before returning to controller
                del tparam['&system']['nat']
                del tparam['&system']['ntyp']

                #Append to controller
                self.mol.append([tmol])
                self.pwdata.append(tparam)

        #TODO: 2nd routine that only reads final config?
        def parsePwo(self,data):
                #Multiple configs supported
                tlist = []
                #no parameters for now
                #tparam=PWParam()
                #read list of molecules:
                i=0
                vec=[[0,0,0],[0,0,0],[0,0,0]]
                while i<len(data):
                        line = data[i].split()
                        #ignore empty lines
                        if not line:
                                pass
                        #read number of atoms
                        elif line[0:3] == ['number', 'of', 'atoms/cell']:
                                nat = int(line[4])
                        #TODO: tweak to recognize celldm(n), save if !0 in param
                        #read cell dimension
                        elif line[0] == 'celldm(1)=':
                                celldm = float(line[1])
                        #TODO: care for different formats
                        #read initial cell vectors
                        elif line[0:2] == ['crystal','axes:']:
                                for j in range(3):
                                        temp = data[i+1+j].split()
                                        vec[j]=[float(x) for x in temp[3:6]]
                        # read initial positions:
                        elif line[0] == 'site':
                                tmol = Molecule()
                                tmol.set_celldm(celldm)
                                tmol.set_vec(vec)
                                for j in range(i+1,i+nat+1):
                                        atom = data[j].split()
                                        tmol.create_atom(atom[1],float(atom[6]),float(atom[7]),float(atom[8]),'alat')
                                i+=nat
                                tlist.append(tmol)
                        #read step-vectors if cell is variable
                        elif line[0] == 'CELL_PARAMETERS':
                                for j in range(3):
                                        temp = data[i+1+j].split()
                                        vec[j]=[float(x) for x in temp[0:3]]
                        #read step-coordinates
                        elif line[0] == 'ATOMIC_POSITIONS':
                                tmol = Molecule()
                                tmol.set_celldm(celldm)
                                tmol.set_vec(vec)
                                for j in range(i+1,i+nat+1):
                                        atom = data[j].split()
                                        tmol.create_atom(atom[0],float(atom[1]),float(atom[2]),float(atom[3]),line[1].strip(')').strip('('))
                                i+=nat
                                tlist.append(tmol)
                        #break on reaching final coordinates (duplicate)
                        elif line[0] == 'Begin':
                                break
                        #ignore everything else
                        else:
                                pass
                        i+=1
                self.mol.append(tlist)


#############################################################################
# WRITE FUNCTIONS
#############################################################################

        def writeFile(self,ftype,mol,filename,param="",coordfmt=""):
                self.outdict[ftype](mol,filename,param,coordfmt)

        def writeXyz(self,mol,filename,param,coordfmt):
                if filename == "":
                        f=sys.stdout
                else:
                        f=open(filename,'w')
                # fixed format nat and comment
                f.write(str(mol.get_nat())+'\n')
                f.write(mol.get_comment()+'\n')
                # write coordinates
                for cntat in range(0,mol.get_nat()):
                        atom=mol.get_atom(cntat,'angstrom')
                        f.write('{:4s} {:15.10f} {:15.10f} {:15.10f}'.format(
                                     atom[0],atom[1][0],atom[1][1],atom[1][2])+'\n')
                f.close()

        def writePwi(self,mol,filename,param,coordfmt):
                if filename == "":
                        f=sys.stdout
                else:
                        f=open(filename,'w')

                #&control, &system and &electron namelists are mandatory
                for i in ['&control','&system','&electrons']:
                        f.write(i+'\n')
                        #write all parameters
                        if i == '&system':
                                f.write(' nat='+str(mol.get_nat())+'\n')
                                f.write(' ntyp='+str(mol.get_ntyp())+'\n')
                        for j in range(len(param[i])):
                                f.write(' '+param[i].keys()[j]+'='+param[i].values()[j]+'\n')
                        f.write('/\n\n')
                #&ions only when needed
                if param['&control']['calculation'] in ["'relax'","'vc-relax'","'md'","'vc-md'"]:
                        f.write('&ions'+'\n')
                        for j in range(len(param['&ions'])):
                                f.write(' '+param['&ions'].keys()[j]+'='+param['&ions'].values()[j]+'\n')
                        f.write('/\n\n')
                #&cell only when needed
                if param['&control']['calculation'] in ["'vc-relax'","'vc-md'"]:
                        f.write('&cell'+'\n')
                        for j in range(len(param['&cell'])):
                                f.write(' '+param['&cell'].keys()[j]+'='+param['&cell'].values()[j]+'\n')
                        f.write('/\n\n')

                #ATOMIC_SPECIES card:
                f.write('ATOMIC_SPECIES'+'\n')
                types = list(mol.get_types())
                for i in range(len(mol.get_types())):
                        atom = types[i]
                        f.write(atom+'    '+str(param['pse'][atom][1])+'   '+str(param['pse'][atom][2])+'\n')
                f.write('\n')

                #ATOMIC_POSITIONS
                f.write('ATOMIC_POSITIONS'+' '+coordfmt+'\n')
                for i in range(mol.get_nat()):
                        atom=mol.get_atom(i)
                        f.write('{:4s} {:15.10f} {:15.10f} {:15.10f}'.format(
                            atom[0],atom[1][0],atom[1][1],atom[1][2])+'\n')
                f.write('\n')

                #K_POINTS
                f.write('K_POINTS'+' '+param['K_POINTS'][0]+'\n')
                #Gamma point only
                if param['K_POINTS'][0] == 'gamma':
                        pass
                #MPGrid:
                #x y z offset
                #passed as whole string for now
                elif param['K_POINTS'][0] == 'automatic':
                        #f.write('{:4i}{:4i}{:4i}{:4i}{:4i}{:4i}'.format(
                        #        param['K_POINTS'][1][0][0],
                        #        param['K_POINTS'][1][0][1],
                        #        param['K_POINTS'][1][0][2],
                        #        param['K_POINTS'][1][0][0],
                        #        param['K_POINTS'][1][1][1],
                        #        param['K_POINTS'][1][1][2]
                        #        )+'\n\n')
                        f.write(param['K_POINTS'][1])
                #number of kpoints
                #x y z weight
                #passed as whole string for now
                #UNTESTED, beware!
                else:
                        f.write(param['K_POINTS'][1])
                        for i in range(param['K_POINTS'][1]):
                                f.write(param['K_POINTS'][2][i])
                f.write('\n')

                #Cell parameters
                f.write('CELL_PARAMETERS'+'\n')
                vec = mol.get_vec()
                fmt='{0[0][0]:15.10f} {0[0][1]:15.10f} {0[0][2]:15.10f}\n' + \
                    '{0[1][0]:15.10f} {0[1][1]:15.10f} {0[1][2]:15.10f}\n' + \
                    '{0[2][0]:15.10f} {0[2][1]:15.10f} {0[2][2]:15.10f}\n'
                f.write(fmt.format(mol.get_vec()))

                #Close file
                f.close()