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()
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()