def start(file_info,lattice_info,directory): """ Version 3.0 This function must intake 3 parameter: file_info: The name of the file the spin information is found on. All of the following lines should contain information about the spin objects at certain positions in the Lattice. After the script has encountered enough spin objects to fill the lattice it will assume the rest of the objects belong on following frames. lattice_info: The name of the file the information about the lattice if found. There is a very specific template the file shouls follow. Please see an example for instructions on how to create the file. directory: The desired name for the directory of all the files to be outputted in. All the files in the directory will have a similar name with different extensions. name but with varying extensions. """ #Check to see if the directory already exists, if so stop the program: if os.path.isdir(directory): print('The new directory name requested already exists, please try again') return -1 #The files which will be accessed during the script f_i=open(file_info,'r') #Data file f_l=open(lattice_info,'r') #Lattice file D=os.getcwd()+'/'+directory #Name of the new directory os.mkdir(D) #Create the new directory exe=open(D+'/'+'execute','w') #Name of the execution file pov=open(D+'/'+directory+'.pov','w') #Name of the .pov file #Gather information about the lattice size l_info=f_l.readlines() print(l_info) #Determine what kind of activity is present s_act='#Sites\n' in l_info or '#Sites\r\n' in l_info b_act='#Bonds_a\n' in l_info or '#Bonds_a\r\n' in l_info b_noact='#Bonds_na\n' in l_info or '#Bonds_na\r\n' in l_info p_act='#Plaquettes\n' in l_info or '#Plaquettes\r\n' in l_info Frames=int(l_info[0]) Lx,Ly,Lz=size(l_info[1]) #Size of lattice bx,by,bz=vectors(l_info[3:]) #Lattice vectors if s_act: #If there is activity on sites, determine the co-ordinates i=index_locator(l_info,'#Sites\n','#Sites\r\n') Site=basis(l_info[i+1:]) s_len=len(Site) #keep track of the number of sites with activity else: s_len=0 if b_act: #Similary, the co-ordinates for the bonds need to be determined i=index_locator(l_info,'#Bonds_a\n','#Bonds_a\r\n') Bonds=basis(l_info[i+1:]) b_len=len(Bonds) #keep track of the number of bonds with activity else: #Even the bonds don't have any ativity on them they still need to be located i=index_locator(l_info,'#Bonds_na\n','#Bonds_na\r\n') Bonds=basis(l_info[i+1:]) b_len=0 if p_act: #Finally, determine the co-ordinates of the plaquettes, if there are any i=index_locator(l_info,'#Plaquettes\n','#Plaquettes\r\n') Plaquettes=basis(l_info[i+1:]) p_len=len(Plaquettes) #keep track of the number of plaquettes with activity else: p_len=0 Total_len=s_len+b_len+p_len #keep track of the total amount of sites+bonds+plaquettes with activity f_l.close() #All of the data from the lattice file has been extracted #Extract info from the data file info=filter(lambda i: i!='\n' and i!='\r\n' and '#' not in i, f_i.readlines()) #Recall: All lines with a '#' are ignored info=[i.split() for i in info] I=[] for i in info: I+=[int(activity) for activity in i] #List of all the activity f_i.close() #All of the data has been analyzed and the data file can be closed #This is a check to ensure the amount of data expected is equal to the amount of data given if Total_len*Frames*Lx*Ly*Lz!=len(I): return """There is an error in the information provided, either in the lattice file or the data file. The amount of data provided (number of entries in the data file) does not match the amount of data expected: Lx*Ly*Lz*Frames*T where T is the total number of objects with activity defined on the lattice.""" #Create activity lists specific to sites, bonds and plaquettes: if s_act: SI=[] for m in range(Frames*Lx*Ly*Lz): for n in range(s_len): SI+=[I[n+m*Total_len]] if b_act: BI=[] for m in range(Frames*Lx*Ly*Lz): for n in range(b_len): BI+=[I[s_len+n+m*Total_len]] if p_act: PI=[] for m in range(Frames*Lx*Ly*Lz): for n in range(p_len): PI+=[I[s_len+b_len+n+m*Total_len]] #Later we use the shortest bond length in calculations, it is calculated here: sbl=shortest(Bonds) #Now the user will be asked a series of questions regarding the desired output: #If there is activity on the sites these questions are asked if s_act: s_colour_0=colour_question('site',0) if s_colour_0!='None': s_size_0=size_question('site',0,0.1,0.4) s_trans_0=trans_question1('sites',0,0,0.25) s_colour_1=colour_question('site',1) if s_colour_1!='None': s_size_1=size_question('site',1,0.1,0.4) s_trans_1=trans_question1('sites',1,0,0.25) #If there is activity on the bonds these questions are asked if b_act: b_colour_0=colour_question('bond',0) if b_colour_0!='None': b_rep_0=rep_question(0) b_size_0=size_question('bond+act',0,0.05,0.35) b_trans_0=trans_question1('bonds',0,0,0.25) b_colour_1=colour_question('bond',1) if b_colour_1!='None': b_rep_1=rep_question(1) b_size_1=size_question('bond+act',1,0.05,0.35) b_trans_1=trans_question1('bonds',1,0,0.25) #If there is no activity on the bonds these question are asked else: b_colour=colour_question('bond_noact',0) if b_colour!='None': b_rep=rep_question('none') b_size=size_question('bond+noact',0,0.05,0.35) b_trans=trans_question1('bonds+noact',0,0,0.25) #If there is activity on the plaquettes these questions are asked if p_act: p_colour_0=colour_question('plaquette',0) if p_colour_0!='None': p_trans_0=trans_question1('plaquettes',0,0,0.25) p_colour_1=colour_question('plaquette',1) if p_colour_1!='None': p_trans_1=trans_question1('plaquettes',1,0,0.25) #General questions regarding everything else gen_trans=trans_question2() im_type=image_question() processors=processors_question(min(Frames/2,multiprocessing.cpu_count())) fps=fps_question() cam_location=camera_question() Bkg=colour_question('background',0) res=resolution_question() #Create all of the .ini files: for i in range(1,processors+1): first_frame=1+Frames*(i-1)/processors #determine the first and last frame each processor will be handling final_frame=Frames*i/processors tmp=open(D+'/'+directory+" - "+str(i)+'.ini','w') #Open the .ini file tmp.write(ini_creator(first_frame,final_frame,res,im_type,directory+'.pov')) #Writes to the .ini file tmp.close() #Close the .ini file exe.write("povray '%s' +I'%s' &\n" %(directory+' - '+str(i)+'.ini',directory+'.pov')) #Write to the execution file #After all of the .ini files have been created, the execution file will also be finished and can be closed exe.close() #Now its time to create the .pov file, first we will create a set of light locations to improve image quality: Lights=lights(Lx,Ly,Lz,bx,by,bz) #Add the general info, camera info and light info to the .pov file now: pov.write(general_info(Bkg)) pov.write(camera_info(cam_location,Lx,Ly,Lz,bx,by,bz)) pov.write(light_info(Lights)) #Now to add the sites, bonds and plaquettes for frame in range(Frames): pov.write("\n#if (frame_number = %d)\n" %(frame+1)) for i in range(Lx): for j in range(Ly): for k in range(Lz): #First look at the sites: if s_act: for s in range(s_len): #Determine the activity activity=SI[s+s_len*(i+Lx*(j+Ly*(k+Lz*frame)))] #Determine if theres any transparency t_factor=0.5-k*0.5/(Lz-1) if gen_trans=='yes' else 0 #Do stuff relating to an activity of zero: if activity==0 and s_colour_0!='None': t_factor+=s_trans_0 center=Vector(Site[s][0]).translate({tuple(bx):i,tuple(by):j,tuple(bz):k}) temp=Sphere(center,s_size_0*sbl,s_colour_0,t_factor) pov.write(temp.msg()) #Do other stuff if the activity is one: elif activity==1 and s_colour_1!='None': t_factor+=s_trans_1 center=Vector(Site[s][0]).translate({tuple(bx):i,tuple(by):j,tuple(bz):k}) temp=Sphere(center,s_size_1*sbl,s_colour_1,t_factor) pov.write(temp.msg()) #Now look at the bonds (with activity): if b_act: for b in range(b_len): #Determine the activity activity=BI[b+b_len*(i+Lx*(j+Ly*(k+Lz*frame)))] #Determine if theres any transparency t_factor=0.5-k*0.5/(Lz-1) if gen_trans=='yes' else 0 #Do stuff relating to an activity of zero: if activity==0 and b_colour_0!='None': t_factor+=b_trans_0 end1=Vector(Bonds[b][0]).translate({tuple(bx):i,tuple(by):j,tuple(bz):k}) end2=Vector(Bonds[b][1]).translate({tuple(bx):i,tuple(by):j,tuple(bz):k}) if b_rep_0=='cylinders': temp=Cylinder(end1,end2,b_size_0*sbl/2.0,b_colour_0,t_factor) pov.write(temp.msg()) else: temp=Dimer(end1,end2,b_size_0*sbl/2.0,b_colour_0,t_factor) pov.write(temp.msg()) #Do other stuff if the activity is one: elif activity==1 and b_colour_1!='None': t_factor+=b_trans_1 end1=Vector(Bonds[b][0]).translate({tuple(bx):i,tuple(by):j,tuple(bz):k}) end2=Vector(Bonds[b][1]).translate({tuple(bx):i,tuple(by):j,tuple(bz):k}) if b_rep_1=='cylinders': temp=Cylinder(end1,end2,b_size_1*sbl/2.0,b_colour_1,t_factor) pov.write(temp.msg()) else: temp=Dimer(end1,end2,b_size_1*sbl/2.0,b_colour_1,t_factor) pov.write(temp.msg()) #Finally, look at the plaquettes: if p_act: for p in range(p_len): #Determine the activity activity=PI[p+p_len*(i+Lx*(j+Ly*(k+Lz*frame)))] #Determine if theres any transparency t_factor=0.5-k*0.5/(Lz-1) if gen_trans=='yes' else 0 #Do stuff relating to an activity of zero: if activity==0 and p_colour_0!='None': t_factor+=p_trans_0 Plaq=Plaquettes[p] temp_clist="" for c in Plaq: c=Vector(c).translate({tuple(bx):i,tuple(by):j,tuple(bz):k}) temp_clist+=",<%f,%f,%f>" %(c[0],c[1],c[2]) temp=Polygon(len(Plaq),temp_clist,p_colour_0,t_factor) pov.write(temp.msg()) #Do other stuff if the activity is one: elif activity==1 and p_colour_1!='None': t_factor+=p_trans_1 Plaq=Plaquettes[p] temp_clist="" for c in Plaq: c=Vector(c).translate({tuple(bx):i,tuple(by):j,tuple(bz):k}) temp_clist+=",<%f,%f,%f>" %(c[0],c[1],c[2]) temp=Polygon(len(Plaq),temp_clist,p_colour_1,t_factor) pov.write(temp.msg()) #Now everything is added to the image in the frame and end statement is required in the .pov file pov.write("#end\n") #If the cylinders don't have activity on them add them to the image now: if b_noact and b_colour!='None': for bpair in Bonds: for i in range(Lx): for j in range(Ly): for k in range(Lz): t_factor=0.5-k*0.5/(Lz-1)+b_trans if gen_trans=='yes' else b_trans end1=Vector(bpair[0]).translate({tuple(bx):i,tuple(by):j,tuple(bz):k}) end2=Vector(bpair[1]).translate({tuple(bx):i,tuple(by):j,tuple(bz):k}) if b_rep=='cylinders': temp=Cylinder(end1,end2,b_size*sbl/2.0,b_colour,t_factor) pov.write(temp.msg()) else: temp=Dimer(end1,end2,b_size*sbl/2.0,b_colour,t_factor) pov.write(temp.msg()) #Everything has been written on the .pov file, now we can close it pov.close() #And start rendering the images os.system("cd '%s' && . ./execute" %(D)) #Before the animation is made, all of the images must be rendered so the program waits until povray is no #longer one of your computers tasks time.sleep(20) while 'povray' in commands.getoutput('ps -A'): time.sleep(15) #Change the variable im_type for simplicity: im_type='png' if im_type=='N' else 'jpg' #For the animation to be in the right order, the images must be renamed to be in lexicogrpahic order os.chdir('%s' %(directory)) for f_name in glob.glob("*.%s" %(im_type)): num=f_name[len(directory):-len(im_type)-1] num=1 if num=='' else int(num) new="%s%.06d.%s" %(directory,num,im_type) os.system("mv '%s' '%s'" %(f_name,new)) #Lastly, create the animation using imagemagick os.system('convert -delay %f *.%s animation.gif' %(100.0/fps,im_type)) return """The program has finished, now just wait til imagemagick finishes converting
def start(file_info,directory,res=[640,480]): """ Version 1.3 This function must intake 2 parameter: file_info: The name of the file the information is found on. All of the following lines should contain information about the spin objects at certain positions in the Lattice. After the script has encountered enough spin objects to fill the lattice it will assume the rest of the objects belong on following frames. directory: The desired name for the directory of all the files to be outputted in. All the files in the directory will have a similar name with different extensions. name but with varying extensions. The optional parameter determines the resolution of the images created. The default is 640x480. To view the other options please call the function: poss_resolutions(). It must be entered in the form: [W,H]. Where W and H are integers (image witdth and height) when the different resolutions are printed they are in the form WxH. If a valid resolution is not entered, the default will be used. """ #Gather information about the lattice size Lx,Ly,Lz=dimensions_q() #The files which will be accessed during the script f_i=open(file_info,'r') Lattice={(i,j,k):[] for i in range(Lx) for j in range(Ly) for k in range(Lz)} #Note: #Lattice is a dictionary where (i,j) will represent the location of the object on the lattice #And the value will represent a list of all spins at that location. counter=0 #A counter to determine how many frames are needed info=filter(lambda i: i!='\n', f_i.readlines()) info=[i.split() for i in info] j,k=0,0 for spins in info: if j==Ly: j=0 k+=1 if k==Lz: k=0 counter+=1 i=0 for spin in spins: Lattice[(i,j,k)]+=[int(spin)] i+=1 j+=1 counter+=1 #Doesn't update the last frame #After the for-loop has finished running all of the data has been analyzed #Hence the information file can be closed: f_i.close() #Gather more information from the user: offset=offset_q() cam=cam_q() form=format_q() image=image_q() spinrep=spinrep_q(form) trans=transparency_q() processors=processors_q(multiprocessing.cpu_count()) res=[640,480] if res not in resolutions() else res processors=1 if form=='average' else processors OS=determine() #Determine the operating system #Create a directory to store all the files as well as a .pov file: if OS=='Windows': #Different os systems use different path names sc='\\' D=os.getcwd()+sc+directory os.mkdir(D) exe=open(D+sc+'execute.bat','w') else: sc='/' D=os.getcwd()+sc+directory os.mkdir(D) exe=open(D+sc+'execute','w') pov=open(D+sc+directory+'.pov','w') if OS=='Windows': #pvengine should be in the same directory as your files if you are using windows os.system('copy pvengine.exe %s' %(D)) #Create all of the .ini files: ratio=counter/processors for i in range(1,processors+1): first_frame=1+counter*(i-1)/processors final_frame=counter*i/processors tmp=open(D+sc+directory+" - "+str(i)+'.ini','w') tmp.write(ini_creator(first_frame,final_frame,res,image,directory+'.pov')) tmp.close() if OS=='Windows': exe.write("pvengine /render '%s' &\n" %(directory+' - '+str(i)+'.ini')) else: exe.write("povray '%s' +I'%s' &\n" %(directory+' - '+str(i)+'.ini',directory+'.pov')) exe.close() #Create the .pov file #First add greneral and camera info about the camera pov.write(general_info()) pov.write(camera_info(cam,offset,Lx,Ly,Lz)) #Add the sphapes to the image if form=='animation': frame=1 while frame<=counter: pov.write("#if (frame_number = %d)\n" %(frame)) for pos in Lattice: if trans=="yes" and cam=='x' and Lx>1: t_factor=0.5-pos[0]*0.5/Lx elif trans=="yes" and cam=='y' and Ly>1: t_factor=0.5-pos[1]*0.5/Ly elif trans=="yes" and cam=='z' and Lz>1: t_factor=0.5-pos[2]*0.5/Lz else: t_factor=0 if spinrep=='colours': temp=Sphere_C(Lattice[pos][frame-1],(pos[0],pos[1],pos[2]),t_factor) pov.write(temp.msg()) elif spinrep=='arrows': temp=Arrow(Lattice[pos][frame-1],(pos[0],pos[1],pos[2]),t_factor) pov.write(temp.msg()) else: temp=Arrow_C(Lattice[pos][frame-1],(pos[0],pos[1],pos[2]),t_factor) pov.write(temp.msg()) pov.write("#end\n") frame+=1 elif form=='average': pov.write("#if (frame_number = 1)\n") for pos in Lattice: if trans=="yes" and cam=='x' and Lx>1: t_factor=0.5-pos[0]*0.5/Lx elif trans=="yes" and cam=='y' and Ly>1: t_factor=0.5-pos[1]*0.5/Ly elif trans=="yes" and cam=='z' and Lz>1: t_factor=0.5-pos[2]*0.5/Lz else: t_factor=0 avg=sum(filter(lambda i: i==1, Lattice[pos]))/float(counter) if spinrep=='colours': temp=Sphere_C(avg,(pos[0],pos[1],pos[2]),t_factor) pov.write(temp.msg()) else: temp=Arrow_C(avg,(pos[0],pos[1],pos[2]),t_factor) pov.write(temp.msg()) pov.write("#end\n") #Adds the cylinders ('bonds') to the image Bx=[(i,j,k) for i in range(Lx-1) for j in range(Ly) for k in range(Lz)] By=[(i,j,k) for i in range(Lx) for j in range(Ly-1) for k in range(Lz)] Bz=[(i,j,k) for i in range(Lx) for j in range(Ly) for k in range(Lz-1)] for bond in Bx: i=bond[0] j=bond[1] k=bond[2] s="cylinder{<%d,%d,%d>,<%d,%d,%d>,0.07 texture{pigment{color NewTan} finish{phong 1}}}\n" %(i,j,k,i+1,j,k) pov.write(s) for bond in By: i=bond[0] j=bond[1] k=bond[2] s="cylinder{<%d,%d,%d>,<%d,%d,%d>,0.07 texture{pigment{color NewTan} finish{phong 1}}}\n" %(i,j,k,i,j+1,k) pov.write(s) for bond in Bz: i=bond[0] j=bond[1] k=bond[2] s="cylinder{<%d,%d,%d>,<%d,%d,%d>,0.07 texture{pigment{color NewTan} finish{phong 1}}}\n" %(i,j,k,i,j,k+1) pov.write(s) pov.close() #Start rendering the images if OS=='Windows': os.system("cd\ && cd %s && execute.bat" %(D)) else: os.system("cd '%s' && . ./execute" %(D))