From 0f37e416a949cfaedf6361e3181f1a5a3aeefea0 Mon Sep 17 00:00:00 2001 From: Matthew Okenyi Date: Fri, 7 Jun 2019 16:35:58 +0100 Subject: [PATCH 1/2] Added option to allow second file to be interpreted as vectors to render instead of final positions. --- README.md | 5 +++++ vesta_vectors.py | 18 ++++++++++++------ 2 files changed, 17 insertions(+), 6 deletions(-) mode change 100644 => 100755 vesta_vectors.py diff --git a/README.md b/README.md index 20f323d..5a9cce3 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,11 @@ A Vesta file that contains vectors connecting the initial and final atomic posit type: string default: initial.vesta final.vesta +-cd --calculate_displacements + description: If 1, displacement between positions in Vesta files is calculated. Else, second file is assumed to contain vectors to render. + type: int + default: 1 + -r --radius description: vector radius (in angstrom) type: float diff --git a/vesta_vectors.py b/vesta_vectors.py old mode 100644 new mode 100755 index 7e4a4d2..06c9c6f --- a/vesta_vectors.py +++ b/vesta_vectors.py @@ -7,6 +7,7 @@ import numpy as np import argparse import re +from copy import deepcopy def read_in(settings): @@ -17,7 +18,7 @@ def read_in(settings): data = open(filename,'r').read() combined_data.append(data) - struct_match=re.search(r"STRUC.*THERI",data,flags=re.S)[0] + struct_match=re.search(r"STRUC.*THERI",data,flags=re.S).group(0) pos_match=re.findall(r"\d+\D+\s+\D+\d+\s+\d+\.\d+\s+(.*?)\s+\d+\D+\s+\d+",struct_match) if pos_match: @@ -86,16 +87,16 @@ def print_to_file(data,settings): VECTT_str += "{0} {1} {2} {3} {4} 0\n".format(i,settings.radius[0], settings.colour[0], settings.colour[1], settings.colour[2]) # set vector radius and colour i+=1 - ATOMT_match = re.search(r"ATOMT.*SCENE",data["initial_data"],flags=re.S)[0] + ATOMT_match = re.search(r"ATOMT.*SCENE",data["initial_data"],flags=re.S).group(0) ATOMT_corrected = re.sub(r'([a-zA-Z]+\s+)\d+\.\d+',r"\1 0.0001",ATOMT_match) # this make all atoms reaaaalllly small - SITET_match = re.search(r"SITET.*VECTR",data["initial_data"],flags=re.S)[0] + SITET_match = re.search(r"SITET.*VECTR",data["initial_data"],flags=re.S).group(0) SITET_corrected = re.sub(r'([a-zA-Z]+\d+\s+)\d+\.\d+',r"\1 0.0001",SITET_match) # this make all atoms reaaaalllly small - BONDP_match = re.search(r"BONDP.*POLYP",data["initial_data"],flags=re.S)[0] + BONDP_match = re.search(r"BONDP.*POLYP",data["initial_data"],flags=re.S).group(0) BONDP_corrected = re.sub(r'(\d+\s+\d+\s+)\d+\.\d+',r"\1 0.0001",BONDP_match) # this makes all bonds reaaaalllly small - SBOND_match = re.search(r"SBOND.*SITET",data["initial_data"],flags=re.S)[0] + SBOND_match = re.search(r"SBOND.*SITET",data["initial_data"],flags=re.S).group(0) SBOND_corrected = re.sub(r'(\s+\d\s+\d\s+\d\s+\d\s+\d\s+)\d+\.\d+',r"\1 0.0001",SBOND_match) # make all bonds reaaaalllly small # substitute the above strings into the output data string @@ -121,6 +122,8 @@ def parse_args(): parser.add_argument('--filenames','-f',type=str, nargs=2, required=False, default=["initial.vesta","final.vesta"], help="name of initial and final vesta files" ) + parser.add_argument('--calculate_displacements','-cd',type=int, nargs='?', required=False,default=1, help="If 1, displacement between positions in Vesta files is calculated. Else, second file is assumed to contain vectors to render." + ) parser.add_argument('--colour','-c',type=int, nargs=3,required=False, default=[255,0,0], help="vector colour (in RGB)") parser.add_argument('--radius','-r',type=float, nargs=1, required=False, @@ -151,7 +154,10 @@ def parse_args(): if settings.centre_atom: data = calc_bounds(data) data = delete_atoms(data) - data = calc_displacement(data) + if settings.calculate_displacements == 1: + data = calc_displacement(data) + else: + data["vectors"]=deepcopy(data["final_positions"]) print ("Printing to file") print_to_file(data,settings) From 149df70db1f24b76408fbaa88d2d4e7b96372438 Mon Sep 17 00:00:00 2001 From: Matthew Okenyi Date: Sun, 19 Apr 2020 10:31:34 +0100 Subject: [PATCH 2/2] read displacements from xyz file --- vesta_vectors.py | 50 ++++++++++++++++++++++++++++-------------------- 1 file changed, 29 insertions(+), 21 deletions(-) diff --git a/vesta_vectors.py b/vesta_vectors.py index 06c9c6f..56497fa 100755 --- a/vesta_vectors.py +++ b/vesta_vectors.py @@ -8,29 +8,32 @@ import argparse import re from copy import deepcopy +import xyz +import os def read_in(settings): combined_positions = [] combined_data = [] - for filename in [settings.filenames[0], settings.filenames[1]]: - data = open(filename,'r').read() - combined_data.append(data) - - struct_match=re.search(r"STRUC.*THERI",data,flags=re.S).group(0) - pos_match=re.findall(r"\d+\D+\s+\D+\d+\s+\d+\.\d+\s+(.*?)\s+\d+\D+\s+\d+",struct_match) - - if pos_match: - positions = [[float(y) for y in x.split()] for x in pos_match] - else: - raise ValueError("Invalid file format (I am only able to parse Vesta files)") - - + for i,filename in enumerate(settings.filenames): + if i==0 or os.path.splitext(filename)[1]=='.vesta': + data = open(filename,'r').read() + combined_data.append(data) + + struct_match=re.search(r"STRUC.*THERI",data,flags=re.S).group(0) + pos_match=re.findall(r"\d+\D+\s+\D+\d+\s+\d+\.\d+\s+(.*?)\s+\d+\D+\s+\d+",struct_match) + + if pos_match: + positions = [[float(y) for y in x.split()] for x in pos_match] + else: + raise ValueError("Invalid Vesta file!") + elif os.path.splitext(filename)[1]=='.xyz': + positions,ignore=xyz.read(filename) + positions=positions.tolist() combined_positions.append(positions) data = {"initial_data": combined_data[0], - "final_data": combined_data[1], "initial_positions": combined_positions[0], # positions in fractional coordinates "final_positions": combined_positions[1], # positions in fractional coordinates } @@ -102,17 +105,20 @@ def print_to_file(data,settings): # substitute the above strings into the output data string data["output_data"] = re.sub(r'(VECTR\n)',VECTR_str,data["initial_data"]) data["output_data"] = re.sub(r'(VECTT\n)',VECTT_str,data["output_data"]) - data["output_data"] = re.sub(r'(ATOMT.*SCENE)',ATOMT_corrected,data["output_data"],flags=re.S) - data["output_data"] = re.sub(r'(BONDP.*POLYP)',BONDP_corrected,data["output_data"],flags=re.S) - data["output_data"] = re.sub(r'(SBOND.*SITET)',SBOND_corrected,data["output_data"],flags=re.S) - data["output_data"] = re.sub(r'(SITET.*VECTR)',SITET_corrected,data["output_data"],flags=re.S) + + if settings.hide_atoms == 1: + data["output_data"] = re.sub(r'(ATOMT.*SCENE)',ATOMT_corrected,data["output_data"],flags=re.S) + data["output_data"] = re.sub(r'(BONDP.*POLYP)',BONDP_corrected,data["output_data"],flags=re.S) + data["output_data"] = re.sub(r'(SBOND.*SITET)',SBOND_corrected,data["output_data"],flags=re.S) + data["output_data"] = re.sub(r'(SITET.*VECTR)',SITET_corrected,data["output_data"],flags=re.S) data["output_data"] = re.sub(r'(VECTS).*(FORMP)',r"\1 {} \n \2".format(settings.scale_factor[0]),data["output_data"],flags=re.S) # set vector scale factor if settings.centre_atom: # centre the output structure around a particular atom data["output_data"] = re.sub(r'(BOUND).*(SBOND)',r"\1 \n {0} {1} {2} {3} {4} {5} \n 0 0 0 0 0 \n \2".format(data["min_bound"][0],data["max_bound"][0],data["min_bound"][1],data["max_bound"][1],data["min_bound"][2],data["max_bound"][2]),data["output_data"],flags=re.S) - file_out = open('vectors.vesta','w+') + file_out = open(settings.outname,'w+') file_out.write(data["output_data"]) file_out.close() + def parse_args(): @@ -138,7 +144,9 @@ def parse_args(): default=[1.0], help='scale all vector moduli by this fixed amount') parser.add_argument('--centre_atom', '-ca', type=int, nargs=1, required=False, default=None, help='the output vesta structure is centred around an atom in the initial structure, specified by this index position (indexing from one)') - + parser.add_argument('--hide_atoms', '-ha', type=int, nargs='?', required=False, default=0, help="hide atoms") + parser.add_argument('--outname','-o',type=str,nargs='?',required=False, + default='vectors.vesta',help="output file name") args = parser.parse_args() return args @@ -161,4 +169,4 @@ def parse_args(): print ("Printing to file") print_to_file(data,settings) - print ("All done.") + print ("Saved output to {0}".format(os.path.abspath(settings.outname))