num_data_all = 8000

    # test
    #path = 'test_data/'
    #first_number = 1
    #num_data_all = 2000

    crystal_structure = 'fcc'

    material = 'Au'

    lc = 4.065

    spatial_domain = (51.2, 51.2)  # A

    qstem = PyQSTEM('HRTEM')

    image_size = (256, 256)  # px

    resolution = spatial_domain[0] / image_size[0]  # [A/px]


    print("Running on host '{}'".format(platform.node()))

    for data_index in range(first_number, num_data_all):

        print('Processing Data [{}/{}]'.format(data_index, num_data_all))

        random_size = random.uniform(20, 30)  # A

        random_NP = Random_NP(crystal_structure,material, lc, random_size, spatial_domain)
Esempio n. 2
0
num_data_all = 8000

# test
#path = 'test_data/'
#first_number = 1
#num_data_all = 2000

crystal_structure = 'fcc'

material = 'Au'

lc = 4.065

spatial_domain = (51.2, 51.2)  # A

qstem = PyQSTEM('TEM')

image_size = (256, 256)  # px

resolution = spatial_domain[0] / image_size[0]  # [A/px]


def HRTEM_multiprocessing(data_index):

    print('Processing data [{}/{}]'.format(data_index, num_data_all))

    random_size = random.uniform(10, 20)  # A

    random_NP = Random_NP(crystal_structure, material, lc, random_size, spatial_domain)

    random_NP_model = random_NP.get_model()
Esempio n. 3
0
def IMG_sim(system,temparams):
    qstem = PyQSTEM('TEM') # Initialize a QSTEM simulation of TEM image.
    #Read the TEM parameters (given in a temparams list.)   
    tilt,plane_grid,num_slices,resample,dose,v0,defocus,Cs,df,MTF_param,blur,temsurface,rotation = temparams
    
    #Define defocus function to calculate Scherzer defocus (and offset from Scherzer defocus):
    def defocusfunc(focus):
        result=[0,focus[1]]
        if focus[0]=='Scherzer':
            prov_sys=molecule('H',vacuum=2)
            qstem.set_atoms(prov_sys)
            qstem.build_wave('plane',v0,plane_grid)
            prov_wave=qstem.get_wave()
            lam=prov_wave.wavelength
            result[0]=-1.2*math.sqrt(lam*Cs)
        else:
            result[0]=0
        return sum(result)
    
    defocus=defocusfunc(defocus)
    
    # Rotate temsurface to the top:
    system.rotate(temsurface,[0,1,0],center='COU')
    
    # Apply rotation to system and reference system.
    system.rotate(rotation,v=[0,1,0],center="COU")

    # Apply the tilt
    system.rotate(tilt,[1,0,0],center="COU")
    
    qstem.set_atoms(system) #Set the atoms for the first PyQSTEM simulation.
    qstem.build_wave('plane',v0,plane_grid) #Build the plane wave on the defined grid.
    wave=qstem.get_wave() #Save the plane wave in Python.
    qstem.build_potential(num_slices) #Build the electrostatic potential from the system using tabulated data for each atom. From Rez et al.: "Dirac-Fock calculations of X-ray scattering factors and contributions to the mean inner potential for electron scattering".
    potential=qstem.get_potential_or_transfunc() #Save the potential in Python. Have a look at it. 
    qstem.run() #Run the qstem simulation.
    wave=qstem.get_wave() #Get the exit wave.
    ctf = CTF(defocus=defocus,Cs=Cs,focal_spread=df) #Define a contrast transfer function from relevant parameters.
    img_wave=wave.apply_ctf(ctf) #Apply the CTF to the exit wave and save the resulting image wave.
    img=img_wave.detect(dose=dose,resample=resample,MTF_param=MTF_param,blur=blur) # Apply the detector PSF and resample the image. 
    
    # Remove the tilt of the system.
    system.rotate(-tilt,[1,0,0],center="COU")
    
    # Rotate the system back.
    system.rotate(-rotation,v=[0,1,0],center="COU")
    
    # Rotate temsurface back.
    system.rotate([0,1,0],temsurface,center='COU')
    
    return img,img_wave,defocus
Esempio n. 4
0
def snrmaster(Nanoparticle,subsys100,subsys111, temparams, nmean, indexed_surfaces,plot,debug_box):
    
    #Produce the Nanoparticle SNR reference cell
    Nanoparticlesnr = Atoms()
    for i in Nanoparticle:
        Nanoparticlesnr.append(i)
    Nanoparticlesnr.set_cell(Nanoparticle.cell)
    Nanoparticlesnr.center()

    #Same procedure for the SNR reference cell
    Referencesnr = Atoms()
    for i in Nanoparticle:
        if i.symbol==metal:
            Referencesnr.append(i)
    Referencesnr.set_cell(Nanoparticle.cell)
    Referencesnr.center()
    
    
    #Read the TEM parameters    
    tilt,plane_grid,num_slices,resample,dose,v0,defocus,Cs,df,MTF_param,blur,temsurface,rotation = temparams
    
    SNRparams=[0,plane_grid,num_slices,resample,dose,v0,defocus,Cs,df,MTF_param,blur,[0,1,0],0]
    
    qstem = PyQSTEM('TEM')
    
    #Rotate systems to the surface we wish to investigate.
    Referencesnr.rotate(temsurface,[0,1,0],center='COU')
    Nanoparticlesnr.rotate(temsurface,[0,1,0],center='COU')
    
    #Rotate the system according to rotation parameter:
    Referencesnr.rotate(rotation,[0,1,0],center='COU')
    Nanoparticlesnr.rotate(rotation,[0,1,0],center='COU')
    
    
    #Tilt NP and reference S/N in order to match the system we visualise and the system we calculate S/N from.
    Nanoparticlesnr.rotate(tilt,[1,0,0],center="COU")
    Referencesnr.rotate(tilt,[1,0,0],center="COU")

    
    # First setup of the TEM objects for the NP and the reference system.
    # The setup happens before the loop designed to get an average since we need an img_wave object to define the S/N box.
    img_snr,img_wave_snr,defocus_value=IMG_sim(Nanoparticlesnr,SNRparams)
    
   
    img_reference_snr,img_wave_reference_snr,defocus_value=IMG_sim(Referencesnr,SNRparams)
    

    #Find the height and width of the box within which to calculate the value of the signal.
    def heightbox():
        dire = abs(temsurface[0])+abs(temsurface[1])+abs(temsurface[2])
        if (dire == 1):
            subsys = subsys100
        if (dire == 3):
            subsys = subsys111
        zmax = 0
        xmax = 0
        ymax = 0
        zmaxmetal = 0
        xmaxmetal = 0
        ymaxmetal = 0
        
        #Maximum x, y and z values are found for the subsystem:
        xmin = 0
        ymin = 0
        for i in subsys:
            if(i.position[2]>zmax):
                zmax = i.position[2]
            if(i.position[2]>zmaxmetal and i.symbol == metal):
                zmaxmetal = i.position[2]
            if abs(i.position[0])>xmax:
                xmax=abs(i.position[0])
            if abs(i.position[0])>xmaxmetal and i.symbol == metal:
                xmaxmetal=abs(i.position[0])
            if abs(i.position[1])>ymax:
                ymax=abs(i.position[1])
            if abs(i.position[1])>ymax and i.symbol == metal:
                ymaxmetal=abs(i.position[1])
            if i.position[0]<xmin and i.symbol != metal:
                xmin=i.position[0]
            if i.position[1]<ymin and i.symbol !=metal:
                ymin=i.position[1]
        
        #Determine if adsorbate atoms have x-y-coordinates outside the subsystem unit cell.
        xyoffsets=[0]
        if xmax>xmaxmetal:
            xyoffsets.append(xmax-xmaxmetal)
        if ymax>ymaxmetal:
            xyoffsets.append(ymax-ymaxmetal)
        if ymin<0:
            xyoffsets.append(abs(ymin))
        if xmin<0:
            xyoffsets.append(abs(xmin))
            
        #Determine the offset in x,y,z:
        zoffset=zmax-zmaxmetal
        xyoffset=max(xyoffsets)
        
        return zoffset, xyoffset

    #Define a function to determine x,y and z coordinates for the SNR box in the nanoparticle unit cell:
    def coordinatesbox():
        xmax = 0
        height = heightbox()[0]
        ind = indexed_surfaces[tuple(temsurface)][0]
        
        zmax = 0
        for i in indexed_surfaces[tuple(temsurface)]:
            pos = Nanoparticlesnr[i].position[1]
            if(pos>zmax):
                zmax = pos
                
        zmin = zmax
        for i in indexed_surfaces[tuple(temsurface)]:
            pos = Nanoparticlesnr[i].position[1]
            if(pos<zmin):
                zmin = pos
                
        zdif = zmax-zmin
        z = zmax
        height = (height + zdif)*1.2
        
        for i in indexed_surfaces[tuple(temsurface)]:
            pos = Nanoparticlesnr[i].position[0]
            if(pos>xmax):
                xmax = pos
        xmin = xmax
        for i in indexed_surfaces[tuple(temsurface)]:
            pos = Nanoparticlesnr[i].position[0]
            if(pos<xmin):
                xmin = pos
        xmax=xmax+heightbox()[1]
        xmin=xmin-heightbox()[1]
        return (xmin,xmax,z,z+height)

    xmin,xmax,zmin,zmax = coordinatesbox()

    xmin,xmax,zmin,zmax = coordinatesbox()
    

    #Conversion between number of data points and length scale
    dpl = len(img_snr.T[0])/img_wave_snr.get_extent()[1]

    #Convert from lengths to corresponding index values in image array
    xmindata = math.floor(xmin*dpl)
    xmaxdata = math.floor(xmax*dpl)
    zmindata = math.floor(zmin*dpl)
    zmaxdata = math.floor(zmax*dpl)
    
    #Define RMS function.
    def rms(img):
        rms = np.sqrt(np.sum(img*img)/len(img.flat))
        return rms

    #Define SNR function.
    def snrfunc(signal,noise):
        
        #We find the SNR of both the image and the corresponding inverted image. We return the maximum value.
        s1 = signal
        s2 = util.invert(signal)

        n1 = noise
        n2 = util.invert(noise)

        snr1 = rms(s1)/rms(n1)
        snr2 =rms(s2)/rms(n2)

        return max(snr1,snr2)


    zlen = zmaxdata - zmindata
    
    
    
    #Define arrays to contain SNR values.
    snrarr = []
    nnrarr = []
    
    # Make first data point of the average
    imgdif = img_snr-img_reference_snr
    
    
    #Select the data points where signal and noise is calculated from:
    imgcut = imgdif[xmindata:xmaxdata,zmindata:zmaxdata]
    imgcutnoise = imgdif[0:20,0:20]
    
    #If debug_box=True, set the pixel values corresponding to the SNR boxes to 0.
    if debug_box:
        imgdif[xmindata:xmaxdata,zmindata:zmaxdata]=0
        imgdif[0:20,0:20]=0


    imgcut_reference_snr=img_reference_snr[xmindata:xmaxdata,-1-zlen:-1]
    imgcutnoise_reference_snr = img_reference_snr[0:20,0:20]
    
    
    
    #For debugging.
    extentcut = [xmindata,xmaxdata,zmindata,zmaxdata]
   
    snr = snrfunc(imgcut,imgcutnoise)
    snrref = snrfunc(imgcut_reference_snr,imgcutnoise_reference_snr)
    
    snrarr.append(snr)
    nnrarr.append(snrref)
    
    #Loop over nmean 
    
    for i in range(1,nmean):
        
        #Construct qstem objects again for use in the averaging
        img_snr,img_wave_snr,defocus_value=IMG_sim(Nanoparticlesnr,SNRparams)
        img_reference_snr,img_wave_reference_snr,defocus_value=IMG_sim(Referencesnr,SNRparams)


        #calculate SNR and NNR and append to array
        imgdif = img_snr-img_reference_snr

        imgcut = imgdif[xmindata:xmaxdata,zmindata:zmaxdata]
        imgcutnoise = imgdif[0:20,0:20]

        #imgcut_reference_snr=img_reference_snr[xmindata:xmaxdata,zmindata:zmaxdata]
        imgcut_reference_snr=img_reference_snr[xmindata:xmaxdata,-1-zlen:-1]
        imgcutnoise_reference_snr = img_reference_snr[0:20,0:20]

        extentcut = [xmindata,xmaxdata,zmindata,zmaxdata]

        snr = snrfunc(imgcut,imgcutnoise)
        snrref = snrfunc(imgcut_reference_snr,imgcutnoise_reference_snr)

        snrarr.append(snr)
        nnrarr.append(snrref)
        
        
    #Rotate and tilt back
    Nanoparticlesnr.rotate(-tilt,[1,0,0],center="COU")
    Referencesnr.rotate(-tilt,[1,0,0],center="COU")
    
    Referencesnr.rotate(-rotation,[0,1,0],center='COU')
    Nanoparticlesnr.rotate(-rotation,[0,1,0],center='COU')

    Nanoparticlesnr.rotate([0,1,0],temsurface,center='COU')
    Referencesnr.rotate([0,1,0],temsurface,center='COU')
    
    finalsnr = np.average(snrarr)
    finalsnrdb = 10*math.log10(finalsnr)
    finalnnr = np.average(nnrarr)
    finalnnrdb = 10*math.log10(finalnnr)
    
    print('Average SNR: '+str(finalsnr))
    print('Average SNR in dB:' +str(finalsnrdb))
    print('Average reference NNR: ' + str(finalnnr))
    print('Average reference NNR in dB: ' +str(finalnnrdb))
    
    
    #If plot=True, plot the different pixel arrays used in the calculation of SNR:
    if(plot):
        
        figimgsnr, axs = plt.subplots(1,3,figsize=(10,7),dpi=300)
        axs[0].imshow(img_snr.T,extent=img_wave_snr.get_extent(),cmap='gray',interpolation='nearest',origin='lower')
        axs[1].imshow(img_reference_snr.T,extent=img_wave_reference_snr.get_extent(),cmap='gray',interpolation='nearest',origin='lower')
        axs[2].imshow(imgdif.T,extent=img_wave_reference_snr.get_extent(),cmap='gray',interpolation='nearest',origin='lower')    
        
        
        figsnr = plt.figure(figsize=(5,4),dpi=200)
        x = np.arange(nmean)
        plt.plot(x,snrarr,label='S/N ratio',linewidth=2,marker='s',color='blue')
        plt.plot(x,nnrarr,label='N/N ratio',linewidth=2,marker='o',color='red')
        plt.axhline(y=np.average(snrarr), xmin=0, xmax=nmean, color='green',linestyle='--',label='Average S/N:\n {:.3} dB'.format(finalsnrdb))
        plt.axhline(y=np.average(nnrarr), xmin=0, xmax=nmean, color='black',linestyle='--',label='Average N/N:\n {:.3} dB'.format(finalnnrdb))
        plt.rcParams['mathtext.fontset'] = 'cm'
        plt.rcParams['font.family'] = 'serif'
        plt.xlabel('Data points')
        plt.ylabel('Ratio value')
        plt.title('Average value of S/N-ratio')
        plt.legend()
    
    
    #Depending on what is needed, return the following objects:
    return snrarr,nnrarr,finalsnr,finalsnrdb,img_snr,img_reference_snr,img_wave_snr,img_wave_reference_snr
     
Esempio n. 5
0
cell=atoms.get_cell()
cell[1,0]=0
atoms.set_cell(cell)

atoms.wrap() # wrap atoms outside the unit cell
atoms.center() # center the atoms in the unit cell

#atoms_plot(atoms,direction=1,scale_atoms=.5)


atoms*=(3,3,1)

scan_range=[[cell[0,0],2*cell[0,0],30],
            [cell[1,1],2*cell[1,1],30]]

qstem = PyQSTEM('STEM')
qstem.set_atoms(atoms)

resolution = (0.02,0.02) # resolution in x and y-direction [Angstrom]
samples = (300,300) # samples in x and y-direction
defocus = -10 # defocus [Angstrom]
v0 = 300 # acceleration voltage [keV]
alpha = 15 # convergence angle [mrad]
astigmatism = 0 # astigmatism magnitude [Angstrom]
astigmatism_angle = 30 # astigmatism angle [deg.]
aberrations = {'a33': 0, 'phi33': 60} # higher order aberrations [Angstrom] or [deg.]

qstem.build_probe(v0,alpha,(300,300),resolution=(0.02,0.02),defocus=defocus,astig_mag=astigmatism,
                  astig_angle=astigmatism_angle,aberrations=aberrations)
wave=qstem.get_wave()
Esempio n. 6
0
#divider = make_axes_locatable(ax2)
#cax2 = divider.append_axes("right", size="5%", pad=0.05)
#plt.colorbar(im,cax=cax2,label='e/Angstrom**2')
#plt.tight_layout()
#plt.show()

print('Total charge (in elementary charges):',
      np.sum(rho * Lx * Ly * Lz / (Nx * Ny * Nz)))

V = poisson_solver(rho, atoms, smooth=0, units='QSTEM')
V_dft = create_potential_slices(V, 10, (Lx, Ly, Lz))
V_dft.array = np.tile(V_dft.array, (3, 3, 1))

tiled_atoms = atoms * (3, 3, 1)

qstem = PyQSTEM('STEM')
qstem.set_atoms(tiled_atoms)
cell = atoms.get_cell()
scan_range = [[cell[0, 0], 2 * cell[0, 0], 25],
              [cell[1, 1], 2 * cell[1, 1], 25]]

resolution = (0.02, 0.02)  # resolution in x and y-direction [Angstrom]
samples = (300, 300)  # samples in x and y-direction
defocus = -10  # defocus [Angstrom]
v0 = 300  # acceleration voltage [keV]
alpha = 15  # convergence angle [mrad]
astigmatism = 0  # astigmatism magnitude [Angstrom]
astigmatism_angle = 0  # astigmatism angle [deg.]
aberrations = {
    'a33': 0,
    'phi33': 0
Esempio n. 7
0
              [0, 0, 0, 1]]  # QSTEM requires a right-angled unit cell
atoms = Graphite(symbol='C',
                 latticeconstant={
                     'a': 2.46,
                     'c': 6.70
                 },
                 directions=directions,
                 size=(2, 1, 1))

del atoms[atoms.get_positions()[:, 2] < atoms.get_cell()[2, 2] /
          2]  # delete the one of the layers in the graphite unit cell

atoms.wrap()
atoms.center(vacuum=2, axis=2)

qstem = PyQSTEM('TEM')
qstem.set_atoms(atoms)

v0 = 300

qstem.build_wave('plane', v0, (100, 100))
wave = qstem.get_wave()

#wave.view()
#plt.show()

qstem.build_potential(5)

potential = qstem.get_potential_or_transfunc()

potential.view(method='real')
Esempio n. 8
0
from pyqstem.util import atoms_plot
from pyqstem import PyQSTEM
from pyqstem.potentials import poisson_solver,create_potential_slices
mpl.rc('font',**{'size' : 13})


rho=np.load('test/graphene.npy') # all-electron density from GPAW using LDA
atoms=read('test/graphene.cif',index=0) # atomic configuration

Lx,Ly,Lz=np.diag(atoms.get_cell())
Nx,Ny,Nz=rho.shape

V=poisson_solver(rho,atoms,smooth=0,units='QSTEM')
V_dft=create_potential_slices(V,10,(Lx,Ly,Lz))

qstem=PyQSTEM('TEM')
qstem.set_atoms(atoms)
qstem.build_wave('plane',80,(Nx,Ny))
qstem.build_potential(1)
print(qstem.get_potential_samples())

V_qstem=qstem.get_potential_or_transfunc()
V_qstem.view(method='real')

print(atoms.get_cell())
print(V_qstem.sampling)

print(Lz/10.)

qstem.run()
Esempio n. 9
0
a = 2.64
atoms = crystal(['Na', 'Cl'], [(0, 0, 0), (0.5, 0.5, 0.5)],
                spacegroup=225,
                cellpar=[a, a, a, 90, 90, 90])
#atoms_plot(atoms,direction=1,scale_atoms=.5)

cell = atoms.get_cell()

atoms *= (15, 15, 20)

#view(atoms)

scan_range = [[cell[0, 0], 2 * cell[0, 0], 30],
              [cell[1, 1], 2 * cell[1, 1], 30]]

qstem = PyQSTEM('CBED')
qstem.set_atoms(atoms)

resolution = (0.02, 0.02)  # resolution in x and y-direction [Angstrom]
samples = (400, 400)  # samples in x and y-direction
defocus = 0  # defocus [Angstrom]
v0 = 200  # acceleration voltage [keV]
alpha = 8  # convergence angle [mrad]
astigmatism = 0  # astigmatism magnitude [Angstrom]
astigmatism_angle = 30  # astigmatism angle [deg.]
aberrations = {
    'a33': 0,
    'phi33': 60
}  # higher order aberrations [Angstrom] or [deg.]

qstem.build_probe(v0,