Giter Site home page Giter Site logo

abtem's Introduction

abTEM: transmission electron microscopy from first principles

PyPI version License: GPL v3 Binder DOI

Docs | Install Guide | Examples

abTEM (pronounced "ab-tem", as in "ab initio") provides a Python API for running simulations of (scanning) transmission electron microscopy images and diffraction patterns using the multislice or PRISM algorithms. It is designed to closely integrate with atomistic simulations using the Atomic Simulation Environment (ASE), and to directly use ab initio electrostatic potentials from the high-performance density functional theory code GPAW. abTEM is open source, purely written in Python, very fast, and extremely versatile and easy to extend.

Installation

You can install abTEM using pip:

$ pip install abtem

For detailed instructions on installing abTEM, see the installation guide.

Getting started

To get started using abTEM, please visit our walkthrough or check out one of the examples.

To try abTEM in your web browser, please click on the following Binder link:

Binder

Citing abTEM

If you find abTEM useful in your research, please cite our methods article:

J. Madsen & T. Susi, "The abTEM code: transmission electron microscopy from first principles", Open Research Europe 1: 24 (2021), doi:10.12688/openreseurope.13015.1.

Open code from articles using abTEM is available in our repository.

Contact

Please send us bug reports, patches, code, ideas and questions.

abtem's People

Contributors

ericpre avatar eugenkozyrau avatar jacobjma avatar jan-janssen avatar matthewhelmi avatar rosedaystory avatar smribet avatar tomasusi avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

abtem's Issues

Diffuse scattering?

I would like to see diffuse scattering from ideal and manipulated crystals. would it be possible with abTEM, if yes, Can any respected Developer can help here??
Regards

raise error when use GPAW potential

Hello Jacob,
When I use the DFT potential in abTEM, there is always error, even when just copy the code of walkthroughs jupyter file '10_DFT.ipynb' and paste them into a new python file

here is the code:
'''
import numpy as np
import matplotlib.pyplot as plt
from gpaw import GPAW
from abtem.dft import GPAWPotential
from ase.io import read
from abtem import *

atoms = read('./hexagonal_graphene.cif')

gpaw = GPAW(h=.1, txt=None, kpts=(3,3,1))
atoms.calc = gpaw
print(atoms.get_potential_energy())

gpaw.write('./8_graphene.gpw')

dft_pot = GPAWPotential(gpaw, sampling=.02)
dft_array = dft_pot.build()
'''

here is the error:
'''
Traceback (most recent call last):
File "", line 1, in
File "/opt/pycharm-2020.2.3/plugins/python/helpers/pydev/_pydev_bundle/pydev_umd.py", line 197, in runfile
pydev_imports.execfile(filename, global_vars, local_vars) # execute the script
File "/opt/pycharm-2020.2.3/plugins/python/helpers/pydev/_pydev_imps/_pydev_execfile.py", line 18, in execfile
exec(compile(contents+"\n", file, 'exec'), glob, loc)
File "/mnt/d/CODE/PYTHON_CODE/mycode/test_all/abtem_test/8_gpaw_test.py", line 16, in
dft_array = dft_pot.build()
File "/mnt/d/CODE/PYTHON_CODE/abTEM-master/abTEM-master/abtem/potentials.py", line 230, in build
for start, end, potential_slice in generator:
File "/mnt/d/CODE/PYTHON_CODE/abTEM-master/abTEM-master/abtem/dft.py", line 261, in generate_slices
sampling)
TypeError: not enough arguments: expected 8, got 7
'''

After cheching the code, the 'interpolate_radial_functions' was called but only transfer 7 arguments, ‘rle_encoding: np.ndarray’ was missed.
What is the ‘rle_encoding: np.ndarray’? And how to fixed this? Is there anything wrong with my usage?

Looking forward to your reply soon!

Error encountered when running abTEM with multiple GPUs

Dear abTEM users,

I recently tested out some code on a supercomputer and ran into an issue when attempting to use multiple GPUs with a slightly adapted version (using an S-matrix and pixelated detector instead) of the code from here. The SLURM output read: "ValueError: Array device must be same as the current device: array device = 0 while current = 1". Does anybody have any experience with using multiple GPUs?

Regards.

Gearóid.

PixelatedDetector setting

Hello. I have a small question. For 4dstem simulation, the "semiangle_cutoff" in Probe function i used is 20 mrad, that is the convergent angle if I understand it correctly. But when i define "max_angle" in PixelatedDetector as 100 mard, it show me an error that the max_angle is larger than max scattering angle. but how could i change the max angle of the PixelatedDetector. If i use "valid" rather than 100 mrad, the detector is only 4 mrad when i check the pacbed pattern. Could you help me what is wrong with my setting. Thank you.

multislice hangs when used with multiprocessing on Unix

Hi Jacob,

We try to generate a lot of images in parallel, using the multiprocessing module. If the PlaneWave.multislice() method is first called directly, and later using multiprocessing, the child processes hang. It happens on Unix, where the default method for starting new processes is the 'fork' method. Changing to the 'spawn' method (default on Windows) or the 'forkserver' method prevents the problem from occurring.

It could be some kind of shared global resource that is causing the problem. With the fork method, the child processes inherits the used resource from the parent process, whereas with the spawn method a new Python process is created, and abtem is loaded again.

The attached script shows the problem.

CC: @matthewhelmi

Help tuning ePIE parameters for low dose 4DSTEM data

Dear users and authors,

I am wondering if anyone has any advice on how to tune the parameters of ePIE for phase recovery from low dose diffraction data. I have seen papers (here is an example) where they used doses as low as 5.7 e / A**2 when recording real 4DSTEM datasets and managed to get fantastic looking reconstructions using the ePIE.

For context, here is some experimental information that could be relevant:

  1. We are simulating a 4DSTEM experiment with an iron nanoparticle embedded in ice. The lattice parameters of the nanoparticle are a=b=c = 18 A and alpha=beta=gamma=90°. All sides are surrounded by about 11 A of ice, such that the effective dimensions of the input structure file are 40 x 40 x 40 A**3.
  2. We have tuned the 4DSTEM experimental parameters to ensure that the overlap of the scanning probes is 86 %.
  3. We record 3844 patterns in a 40 x 40 A2 area. Each pattern has 182 x 182 pixels2, with a maximum detection angle of approximately 95 mrad.
  4. The size of the ePIE reconstruction is also 182 x 182 pixels**2.
  5. For the images we provided, we ran the ePIE 50 times. We tested for alpha set to 1 and 0.05, while choosing not to update the probe -the probe guess was the one used in the simulation- to reduce the number of tunable parameters.

In Fig. 1 and Fig. 2, I provide examples of the results we have obtained using different doses, alpha values and iterations. When low dose conditions are simulated, setting alpha to 0.05 results in a somewhat better reconstruction than using an alpha set to 1 (see Fig. 2). Conversely, an alpha of 1 appears better than an alpha of 0.05 for high dose experiments (see Fig. 1).

We have tried several other values for alpha (and beta, before deciding to not update the probe) and we have tried increasing the number of iterations to 1000, too, and have not seen any obvious changes in the images. I note that it is possible that a 'better' reconstruction might come after many more iterations. However, I would expect that 1000 would be sufficient, considering the authors of this paper managed to get objectively clear reconstructions from real low-dose cryo-data within 300 iterations.

Furthermore, I have also added rPIE to my own installation of abTEM and the results are about the same or sometimes worse when alpha is too low ( < 0.05).

Can anyone comment on the results? Can I tune the parameters of ePIE to get a better reconstruction? And can anyone share how they choose initial guesses for alpha, beta and the number of iterations?

infinite dose alpha 1

infinite dose alpha 0 05
Fig. 1: Reconstruction with low dose turned off: (top) alpha = 1 and (bottom) alpha = 0.05. The probe was not updated at any of the 50 iterations.

200 e per A sq alpha 1
200 e per A sq alpha 0 05
Fig. 2: Reconstruction with low dose turned on (200 e / A**2): (top) alpha = 1 and (bottom) alpha = 0.05. The probe was not updated at any of the 50 iterations.

Whether the segemented detectors can be rotated?

Dear author, thanks for your reply!
I'm trying to complete a iDPC-STEM simulation that requires the 4-quadrant detectors to rotate 45 degrees
i want to ask if this abtem software can do this? or add as a future function?
such as DPC_A:-45-45 degree; DPC_B: 45-135 degree;DPC_C:135-225 degree;DPC_D:225-315 degree

potential.sampling

Dear Jacobjma

When I set sampling number in potential function, as shown below. The real space sampling x and y are slightly different.
I intend to simulate 4d datasets, in which the reciprocal space sampling kx and ky are equal. May I ask how to make sampling x and y are equal to each other?
image

Chuang

grid view size and plot intensity of peaks, Can it read .xyz file as well?

From the section of Multislice simulation. I tried to run the code on Silicon.cif file. I just followed instructions on abtem foram and obtained these results, I have limited knowledge of python and still learning. If you can guide me that how I can change/ control the gride size (in multislice), plot intensity of observed peaks, change of through the commands in python.

I noticed that grid is not defined in multislice .. How can I write it separately? Below are my results at 90keV.

Also I wanted to manipultad the atoms , wanted to make my own crystal. and i read that ASE can make .xyz file, that file can run in Multislice or not ??

2a336600-8dbd-4a22-a3e1-8e6a3affc73c
b02df212-d55b-4bba-bd2c-f84a70089352

Regards
Syed

orthogonalize_cell() requires exactly orthogonal axes

I have results results of simulations which give me unit cells with angles between 89 and 91 degrees, which are rejected by orthogonalize_cell() because there is no vertical lattice vector (with the 1e-12 tolerance) despite the fact that the unit cell is almost orthogonal. Can orthogonalize_cell() be adapted to make these almost orthogonal unit cells exactly orthogonal?

sample rotate

Hello. i have a small question for your help. After I tilt the sample from (001) to (110) or other direction with defining "rotate_cell=True" , why there is an error, like "Atoms are not orthogonal", when i want to get the potential of atoms.

If I define "rotate_cell=False", the potential function is ok. But i check the region of gridscan by the following code, which is not where I am interest. Do you konw what is the problem of my runing. Thanks a lot.

ax, im = potential.project().show();
gridscan.add_to_mpl_plot(ax)

orthogonalize_cell() repeats structure unnecessarily (?)

For typical graphene hexagonal unit cells, using orthogonalize_cell() with default parameters results in an orthogonal cell that seems to me is unnecessarily 2x repeated in the y direction (see attached for an visualization).

Am I mistaken? Would it not be possible to take half of the orthogonal cell in y instead?

image

Adding in Hyperspy/Pyxem Support

Some of the developers over at pyxem were talking about adding in support for dynamic type simulations/ 4-D STEM pyxem/diffsims#170. abTEM came up as a good alternative which we could reference and work alongside rather than trying to support dynamic type simulations.

I was wondering if you would be interested in adding support for hyperspy/pyxem to the package?

There are a couple of ways that this could be accomplished (non-exclusively):

I think that this would be an easy way to increase the visualization/ analysis tools available some simulation without too much added overhead. I would be willing to create a small pull request to make these changes if you are interested in adding in this support.

@din14970 Based on the conversation we had earlier you might have some additional thought.

How to use a 48 core server for abTEM

Dear all,

first of all, thanks a lot for this nice software!

I have a HP proliant server at hand, providing 48 cores. Unfortunately abTEM seems to use only one core. Is there a way to make them all work?

Best wishes
Markus

Simulation on 'discrete' systems like nanoparticles/clusters

Thanks for sharing the really nice program and examples. I am running test examples and find that it works great for 'periodic' systems. How to go about simulating for discrete systems? Any example notebooks available? For example, how to simulate HAADF image from the Cu nanoparticle example given in ASE.

#surfaces = [(1, 0, 0), (1, 1, 0), (1, 1, 1)]
#layers = [6, 9, 5]
#lc = 3.61000
#atoms = FaceCenteredCubic('Cu', surfaces, layers, latticeconstant=lc)

ps: I am new to ASE and python and still figuring my way around

errors happened when i tried to use segemented detecotor

when i tried to use this to simulate dpc images by divied the detecotor into 4 parts.
dpc_detector = SegmentedDetector(inner=4,outer=22,nbins_radial=1,nbins_angular=4)
"ValueError: non-broadcastable output operand with shape (25,4) doesn't match the broadcast shape (25,25,4)"

abTEM with Dask

The Dask version of abTEM is finally reaching a state where we wish to share it for testing (and it only took 4 months longer than I expected).

The abtem-dask branch still has bugs and missing features, but if you are eager to try it or want to help push this over the finish line, we would be happy if you gave it a test. The code is tested for the basic (4D)STEM and HRTEM imaging modes.

The new code runs at about 1.5x – 2x the speed of the non-Dask version on my 8-core laptop, but the benefits really start for larger computing systems. I tested the new version on 256 cores on our HPC cluster, but it should scale beyond that, assuming enough scan position batches or frozen phonons to parallelize.

The single-GPU performance should be identical to before; however, I have not had the opportunity to test multiple GPU’s, which should now be supported through dask_cuda.

PRISM is not fully optimized yet, although it works and you can test it. There are currently a number of computational parameters that have to be optimized by the user. Compared to our old version of PRISM, the speedup ranges from 0.5x all the way up to 4x depending on the simulation and the computational parameters.

The new code also features a complete overhaul of the measurement module, as talked about here, which now also supports GPU calculations. Other new features include support for much bigger DFT potentials.

I added a notebook on Dask to the walkthrough that you might want to start with. Please let us know what is missing from this introduction.

I uploaded some benchmark notebooks that you can test to get a baseline.

"Atoms are not orthogonal" error

Hi Jacob,

I am trying to build the TEM simulation of the Ag (111) plane following your walkthrough scripts. However, I find an error when I want to get the potential. The program shows that the Ag (111) plane is not orthogonal. I am not sure how to deal with this. Should I cut the atom plane to a rectangular?

Here are the shape of Ag (111) plane and the error in the code.

Screen Shot 2021-03-30 at 9 11 52 AM

Screen Shot 2021-03-30 at 9 12 18 AM

Tilt beam or specimen

Is there any command to tilt beam or specimen?
If no, I want to you update the function of that.
Thank you!

Updating CUDA and CuPy improved memory management

Dear abTEM users,

I thought it might be useful to share some knowledge I learned through trial and error with using abTEM. I hope this is an appropriate place for this message. For reference, I present an outline of what I am trying to achieve with abTEM. For convenience, I run 4DSTEM simulations on multiple structures in a loop. To elaborate:

  • I have a folder full of structure files (e.g. PDB or CIF format)
  • My script loads the first file in that folder
  • The script then uses abTEM to generate a simulated 4DSTEM data set from the input structure
  • The script saves the data to file
  • The process repeats itself until a 4DSTEM data set is generated for all structure files in the folder.

I run these experiments on an Nvidia GPU. I found that my GPU's memory would quickly become full after a few cycles of the loop, where the number of cycles depended on the simulation parameters. I tested each input structure separately with the same parameters and my GPU was capable of handling each simulation. So, I surmised that my GPU's memory was not being cleared properly after each iteration of loop. For calculations on Nvidia GPUs, abTEM uses CuPy and CUDA. I tested some of the code shown under the heading 'Memory Pool Operations' at https://docs.cupy.dev/en/stable/user_guide/memory.html in an attempt to release memory. My GPU's memory was still not clearing after each iteration of the loop. I was using CUDA 10.2 when I first encountered this issue. After upgrading to 11.3, I have not seen any issues with my GPU's memory. All I need to do is add garbage collection with 'gc.collect()' at the end of each iteration and the memory is freed (this did not work on my system with older versions of CUDA/CuPy). I was able to run 10 identical simulations in a loop and the available memory after garbage collection was approximately the same as it was at the very start of the script execution. I have a 980Ti with 6 GB of VRAM, so these numbers are 5000 MB free at the start (not sure why it's not 6 GB) and 4850 MB free after each iteration. Without gc.collect(), the amount of free VRAM usually decreases with each iteration.

For those interested I use the code from the accepted answer from https://stackoverflow.com/questions/59567226/how-to-programmatically-determine-available-gpu-memory-with-tensorflow to check my available GPU memory.

Hope this information is helpful to someone in the future.

Best wishes.

Gearóid.

GPAW independent atom potentials with ionic form factors

The EELS code got me thinking that it will be possible to introduce a GPAW indepedent atom potential parametrization. In this implementation the radial potential would be calculated at the first stage of a simulation. This would have two benefits:

  • A very direct comparison to solid state GPAW potentials
  • Ability to include any partial charges, on any atom, from first priciples, but stay within the fast independent atom model. Some multislice codes, include an ionic parametrization for specific atoms, which is useful for simulating important cases such as oxides. I believe abTEM would be able to do this for any atom and any reasonable charge using GPAW.

TypeError on write, cupy array to numpy array conversion

This could be a numpy/cupy version issue and it might be a good idea to add version constraints to the requirements. I'm on cupy v9.4.0, numpy 1.20.3, and the latest version of abTEM on pypi. When I try to write out an exit wave through pw_exit_wave = wave.multislice(potential) I get error:

/tmp/ipykernel_26471/3948755466.py in <module>
     27 wave = PlaneWave(gpts=(300, 300), energy=300e3, device="gpu")
     28 pw_exit_wave = wave.multislice(potential)
---> 29 pw_exit_wave.write('exitwaves/test.hdf5')

~/miniconda3/envs/hyperspy-dev/lib/python3.8/site-packages/abtem/waves.py in write(self, path)
    551 
    552         with h5py.File(path, 'w') as f:
--> 553             f.create_dataset('array', data=self.array)
    554             f.create_dataset('energy', data=self.energy)
    555             f.create_dataset('extent', data=self.extent)

~/miniconda3/envs/hyperspy-dev/lib/python3.8/site-packages/h5py/_hl/group.py in create_dataset(self, name, shape, dtype, data, **kwds)
    147                     group = self.require_group(parent_path)
    148 
--> 149             dsid = dataset.make_new_dset(group, shape, dtype, data, name, **kwds)
    150             dset = dataset.Dataset(dsid)
    151             return dset

~/miniconda3/envs/hyperspy-dev/lib/python3.8/site-packages/h5py/_hl/dataset.py in make_new_dset(parent, shape, dtype, data, name, chunks, compression, shuffle, fletcher32, maxshape, compression_opts, fillvalue, scaleoffset, track_times, external, track_order, dcpl, allow_unknown_filter)
     47     if data is not None and not isinstance(data, Empty):
     48         from . import base
---> 49         data = base.array_for_new_object(data, specified_dtype=dtype)
     50 
     51     # Validate shape

~/miniconda3/envs/hyperspy-dev/lib/python3.8/site-packages/h5py/_hl/base.py in array_for_new_object(data, specified_dtype)
    116         as_dtype = guess_dtype(data)
    117 
--> 118     data = np.asarray(data, order="C", dtype=as_dtype)
    119 
    120     # In most cases, this does nothing. But if data was already an array,

~/miniconda3/envs/hyperspy-dev/lib/python3.8/site-packages/numpy/core/_asarray.py in asarray(a, dtype, order, like)
    100         return _asarray_with_like(a, dtype=dtype, order=order, like=like)
    101 
--> 102     return array(a, dtype, copy=False, order=order)
    103 
    104 

cupy/_core/core.pyx in cupy._core.core.ndarray.__array__()

TypeError: Implicit conversion to a NumPy array is not allowed. Please use `.get()` to construct a NumPy array explicitly.

Seems that the line data = np.asarray(data, order="C", dtype=as_dtype) in h5py is the culprit -- trying this on a random cupy array using my cupy/numpy versions doesn't work.

A workaround would be using the cp.asnumpy function before passing it to h5py. Would this be an acceptable solution for you/shall I open a PR, or do you have a different idea?

Defocus setting for STEM simulation

Hello, I am a user of abtem, very thanks for your effort. I am writing to ask you a question about "defocus setting" for STEM simulation. I am curious that where probe locates at when I set zero as defocus, is it the top of specimen structure or bottom plane of specimen structure? How to set defocus value if I want to set defous at the middle of model, for example, I have structure with 10nm, should defocus-setting be -5 nm or 5 nm if I want to set defous at the middle of model. Thanks for your reply.

interfacing with real data

I have two issues, one data specific and one in regards to general understanding:

The specific one is that, when i run the reconstruct.py example with device='gpu', i get a data type error:

Traceback (most recent call last):

File "C:\Users\root\Desktop\scripts in progress\PythonInDM\jupyter_nb.py", line 59, in
reconstructions_full = epie(band_limited_measurment, probe_guess, maxiter=3, return_iterations=True, fix_com=True, device='gpu')

File "C:\ProgramData\Anaconda3\lib\site-packages\abtem\reconstruct.py", line 187, in epie
result = _run_epie(diffraction_patterns.shape[-2:],

File "C:\ProgramData\Anaconda3\lib\site-packages\abtem\reconstruct.py", line 87, in _run_epie
com = center_of_mass(xp.fft.fftshift(xp.abs(probe) ** 2))

File "C:\ProgramData\Anaconda3\lib\site-packages\scipy\ndimage\measurements.py", line 1406, in center_of_mass
results = [sum(input * grids[dir].astype(float), labels, index) / normalizer

File "C:\ProgramData\Anaconda3\lib\site-packages\scipy\ndimage\measurements.py", line 1406, in
results = [sum(input * grids[dir].astype(float), labels, index) / normalizer

File "cupy_core\core.pyx", line 1115, in cupy._core.core.ndarray.mul

File "cupy_core\core.pyx", line 1491, in cupy._core.core.ndarray.array_ufunc

File "cupy_core_kernel.pyx", line 1119, in cupy._core._kernel.ufunc.call

File "cupy_core_kernel.pyx", line 110, in cupy._core._kernel._preprocess_args

TypeError: Unsupported type <class 'numpy.ndarray'>

This seems to be an issue with cupy, since device='cpu' works without issue. I could list my package environment, but i think a general reply whether there are known issues with version conflicts would be useful. I am using cupy-9.4.0 and abtem-1.0.0b24.

The other question is regarding interfacing with experimental data from Gatan GMS3.x in order to run the ePie reconstruction and compare with simulations. I am a complete amateur, but as an example this works partially (using dm3-lib to import GMS data and meta tags):

import dm3_lib as dm3
import os
import numpy as np
import cupy as cp
from abtem import *
import math

listfiles = []

this_path= os.getcwd()
for filename in os.listdir(this_path):
   if  '.dm3' in filename: 
       lastname = os.path.join(this_path, filename)
       listfiles.append(lastname)
       
dm3f = dm3.DM3(listfiles[0])
grid_x=int(float(dm3f.tags['root.ImageList.1.ImageTags.nx']))   #the information on the size of the scan area is stored in custom tags
grid_y=int(float(dm3f.tags['root.ImageList.1.ImageTags.ny']))
diff_x=np.shape(dm3f.imagedata)[0]
diff_y=np.shape(dm3f.imagedata)[1]

sampling_x = float(dm3f.tags['root.ImageList.1.ImageData.Calibrations.Dimension.0.Scale'])
offset_x=((np.shape(dm3f.imagedata)[0])/2)*(-sampling_x)
units_x= str(dm3f.tags['root.ImageList.1.ImageData.Calibrations.Dimension.0.Units'])
name_x= 'dx_cal'
dfx_cal= measure.Calibration(offset_x,sampling_x,units_x,name_x)

sampling_y = float(dm3f.tags['root.ImageList.1.ImageData.Calibrations.Dimension.1.Scale'])
offset_y=((np.shape(dm3f.imagedata)[1])/2)*(-sampling_y)
units_y= str(dm3f.tags['root.ImageList.1.ImageData.Calibrations.Dimension.1.Units'])
name_y= 'dy_cal'
dfy_cal= measure.Calibration(offset_y,sampling_y,units_y,name_y)

sampling_x = 10*float(dm3f.tags['root.ImageList.1.ImageTags.dx'])  #the calibration values are stored in nm
offset_x=0
units_x= 'A'
name_x= 'x_cal'
x_cal= measure.Calibration(offset_x,sampling_x,units_x,name_x)

sampling_y = 10*float(dm3f.tags['root.ImageList.1.ImageTags.dy'])
offset_y=0
units_y= 'A'
name_y= 'y_cal'
y_cal= measure.Calibration(offset_y,sampling_y,units_y,name_y)

array = np.zeros_like(np.empty((grid_x,grid_y,diff_x,diff_y)), dtype=np.float32)
calibration = (x_cal,y_cal,dfx_cal,dfy_cal)
measurement = Measurement(array, calibration)

for i in range(len(listfiles)):
    dm3f = dm3.DM3(listfiles[i])
    x = i%grid_x
    y = math.trunc(i/grid_x)
    measurement.array[x, y] += cp.asnumpy(dm3f.imagedata)

When i run this code snippet and attempt to run the reconstruction, it kind of sortof works, but the grid that the scan area is cast on is wrong/of the size of the diffraction pattern. There seems to be some basic property of the measurement object that i am missing or do not understand.

Would it be possible to get a layout of the required entries in the measurement class, in some "beginners' guide" kind of way?

edit: After some more testing, it seems that the probe_guess shape is actually what determines the output grid, but if i fix a larger grid the reconstruction bins the probe down again, which seems both counterintuitive and unncessary. It should be possible to pad the probe for large scan grids so that the illumination wave is never undefined?

Possible bug in poisson_noise

Thanks for the great tool in TEM image simulation.

I have currently used the tool to simulate several images, but I have now encountered an error when I attempt to add noise to these images using the poisson_noise function.
image

This same error occurs when running the last cell in the quick_hrtem_and_saed.ipynb notebook provided in this repository.

I believe that this error occurs as the function attempts to find the sampling for the first two elements [indices 0 and 1] in the calibrations: the stack of images and x-direction. Here the sampling for the stack is a Nonetype and hence an error is returned. I believe the code function meant to look at the sampling in the x- and y-direction [indices 1 and 2] as it did before this commit.

Rolling back the change done in line 175 in abtem/noise.py seems to solve the issue. As such I propose the following change to line 175 in order to fix the bug:

pixel_area = np.product([calibration.sampling for calibration in measurement.calibrations[:2]])
->
pixel_area = np.product([calibration.sampling for calibration in measurement.calibrations[-2:]])

This is my best guess at why the error occurs, I hope you can tell me if I am making an error.

Thanks again for a great tool!

ValueError in abtem.potentials.soft_function()

When running a STEM scan using abtem 1.0.0b24 and numpy 1.21.2, the following error occurs:

Earlier versions of numpy fail due to the use of the "sliding_window_view" routine.

File "/home/vol02/scarf982/anaconda3/lib/python3.8/site-packages/abtem/potentials.py", line 798, in get_integrator
return self._integrators[number]
KeyError: 8

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "images.py", line 113, in
measurement = probe.scan(scan, haadf_detector, potential, pbar=True)
File "/home/vol02/scarf982/anaconda3/lib/python3.8/site-packages/abtem/waves.py", line 1953, in scan
for indices, exit_probes in probe_generator:
File "/home/vol02/scarf982/anaconda3/lib/python3.8/site-packages/abtem/waves.py", line 1848, in _generate_probes
for potential_config in potential.generate_frozen_phonon_potentials(pbar=potential_pbar):
File "/home/vol02/scarf982/anaconda3/lib/python3.8/site-packages/abtem/potentials.py", line 990, in generate_frozen_phonon_potentials
yield self.build(pbar=pbar)
File "/home/vol02/scarf982/anaconda3/lib/python3.8/site-packages/abtem/potentials.py", line 262, in build
for start, end, potential_slice in generator:
File "/home/vol02/scarf982/anaconda3/lib/python3.8/site-packages/abtem/potentials.py", line 904, in _generate_slices_finite
max_cutoff = max(self.get_integrator(number).cutoff for number in unique)
File "/home/vol02/scarf982/anaconda3/lib/python3.8/site-packages/abtem/potentials.py", line 904, in
max_cutoff = max(self.get_integrator(number).cutoff for number in unique)
File "/home/vol02/scarf982/anaconda3/lib/python3.8/site-packages/abtem/potentials.py", line 807, in get_integrator
self._integrators[number] = PotentialIntegrator(soft_function, r, max_interval, cutoff)
File "/home/vol02/scarf982/anaconda3/lib/python3.8/site-packages/abtem/potentials.py", line 331, in init
value, error_estimate, step_size, order = integrate(f, -1, 1, self._tolerance)
File "/home/vol02/scarf982/anaconda3/lib/python3.8/site-packages/abtem/tanh_sinh.py", line 145, in integrate
left_summands = f_left(y0) * weights
File "/home/vol02/scarf982/anaconda3/lib/python3.8/site-packages/abtem/tanh_sinh.py", line 112, in f_left
return f(a + s)
File "/home/vol02/scarf982/anaconda3/lib/python3.8/site-packages/abtem/potentials.py", line 329, in f
return self._function(np.sqrt(self.r[0] ** 2 + (z * max_interval / 2 + max_interval / 2) ** 2))
File "/home/vol02/scarf982/anaconda3/lib/python3.8/site-packages/abtem/potentials.py", line 777, in soft_function
result[valid] = self._function(r[valid], self.parameters[number])
TypeError: expected dtype object, got 'numpy.dtype[float64]'

ctf

I'm struggling with the ctf terminology you are using. I think there is different lingo in materials science communities vs life science cryoEM communities.

I am used to the formulation in these resources
https://pubmed.ncbi.nlm.nih.gov/26278980/ (introduction of this paper, a commonly software program to fit the ctf)
https://github.com/asarnow/pyem/blob/master/pyem/ctf.py
https://en.wikipedia.org/wiki/Contrast_transfer_function

Could you please point me to a reference? I'm more familiar with spatial frequency (k-space). How do I convert alpha and semiangle_cutoff to this?

4D STEM simulation

Dear Sir,
I tried to run the quick_4D-STEM codes to simulate a 4D dataset. And I have a question about how to set my desired pixel numbers of Ronchigrams like (256x256, 128*128). When I had set sampling in potential function, then set gpts=(256,256) in Probe function. The results showed Ronchigrams were not (256,256). Could you help me to solve this problem?

Chuang

apply_ctf not updating array

Once I do apply_ctf, how should I get at the updated array values? This is how I'm doing it. I can't seem to apply the ctf.

I cloned the github repo today. I'm actually pip installing to get all the dependencies (ase) and then putting the abtem folder from the github repo where pip does).

exit_wave = PlaneWave(energy=300e3,sampling=.3).multislice(potential)
ewa = exit_wave.array.copy() # save for comparison later

ctf = CTF(defocus=2.5e4, # 2.5 um
          Cs=2e7, # 2 mm
          energy=3e5 # 300 kV
          )
exit_wave.apply_ctf(ctf)

ewa_ = exit_wave.array.copy()
np.allclose(ewa,ewa_) # returns True, so the ctf wasn't applied

Maybe there's some issue with overwrite_x etc

Differing coordinate syntax for interpolate_line() vs. plt.plot()

The abTEM interpolate_line() function accepts coordinate arguments in the form
interpolate_line(start = (x1, y1), end = (x2, y2))
while to plot a line in matplotlib, the plotting arguments are instead
plot(x, y),
which for a horizontal line would use x = (x1, x2), y = (y0, y0) and for a vertical one x = (x0, x0), y = (y1, y2).

This can often result in a hassle for the user where they have to denote the same coordinates in two different ways for this commonly used functionality (create and plot a line profile).

Would it still be possible to harmonize the interpolate_line() syntax with the matplotlib syntax? We'd have to fix a couple of examples, but I think it would be worth it. Or would it conflict with some other conventions in abTEM?

display the complex number with original magnitude and phase

For displaying the complex number, the current domain_coloring function convert the complex value to RGB values and hence the colorbar added for plt.imshow loses their meaning for their orginal magnitude or phase. I am wondering if can still make the colorbar meaningful, for instance similar to cplot, which is useful for showing the wave function or EELS potential.

latest release on pypi

The latest tag is not available non pypi, would it be possible to upload the latest tag on pypi? Once, it is on pypi, the conda-forge bot will create a PR to update the feedstock.

On a similar topic, would you be interested in setting a github workflow to automate the release process? We have been using these for various packages and it works very well, see for example https://github.com/hyperspy/hyperspy_gui_ipywidgets/blob/master/.github/workflows/release.yml
and a corresponding CI run: https://github.com/hyperspy/hyperspy_gui_ipywidgets/actions/runs/745309960

I can make a PR with the relevant documentation, etc.

Quest for help on Probe customization

Dear author:
I have a problem with probe customization. I set the magnitude as Å, and angel to mrad

I have 2 problems:

  1. the experimental semi convergence angle is 15 mrad. i tried to find how to set it but failed.
  2. i listed all parameters seted in the experiment, but the CTF seems wrong. could you please help me check the code?

the parameters were attached in the bottom
the resulting ctf completely different from the expiriment
image

and the experimental ctf are
image

The codes are listed as follows:
——
parameters = {
'C10':25.02, 'C12':56.78, 'phi12':27.1/180pi1000,
'C21':100.5, 'phi21':-148.1/180pi1000, 'C23':1073, 'phi23':-84.9/180pi1000,
'C30':5907, 'C32':3612, 'phi32':32.9/180pi1000, 'C34':3862, 'phi34':170.9/180pi1000,
'C41':19260, 'phi41':95.7/180pi1000, 'C43':32530, 'phi43':96.1/180pi1000, 'C45':39360, 'phi45':-112.6/180pi1000,
'C50':2570000, 'C52':747600, 'phi52':-143.8/180pi1000, 'C54':386300, 'phi54':32.7/180pi1000, 'C56':1646000, 'phi56':82.5/180pi1000}

ctf = CTF(parameters=parameters, energy=300e3)
probe = Probe(energy=300e3, semiangle_cutoff=15, ctf=ctf)
image
image

Problem running the program

File "h5py\h5.pyx", line 1, in init h5py.h5
ImportError: DLL load failed: The specified procedure could not be found.

I created a new environment of abtem, I installed by using pip install abtem.. I install h5py as well. i can see everything is perfectly install in my computer when i find the conda list abtem .. but still i am getting this error.

Add a function to calculate the redundancies of an ePIE reconstruction

Dear abTEM authors,

It might be useful to some users to include a method to calculate the redundancies of a ptychographic data set. The authors of this paper give an equation in Note 6 of their supplementary material to estimate the redundancy of a ptychographic data set. I have made a function below that I think should do the job. Feel free to use it in one way or another if you'd like. If you spot any problems with the implementation, let me know so I can correct it on my end.

def calculate_epie_redundancy(measurement, reconstructions, bandlimit_angle = None):

        #get number of used pixels for all diffraction patterns
        measurement_shape = measurement.array.shape
        num_patterns = measurement_shape[0]*measurement_shape[1]
    
        #the bandlimit controls the number of pixels used in the calculation
        #use ratio bandlimit to cutoff to find the area of the image (number of  pixels) used in the calculation
        if bandlimit_angle is None:
            pixels_per_pattern = measurement_shape[2]*measurement_shape[3]
        else:
            pixels_per_pattern = (bandlimit_angle/S.cutoff_scattering_angles[0])*measurement_shape[2]*\
                                              (bandlimit_angle/S.cutoff_scattering_angles[1])*measurement_shape[3]
    
        #calculate the number of pixels for the phase reconstruction
        phase_reconstruction_shape = np.angle(reconstructions[0][i].array).T.shape
        pixels_per_phase_reconstruction = phase_reconstruction_shape[0]*phase_reconstruction_shape[1]
    
        #calculate the number of pixels for the probe reconstruction
        probe_reconstruction_shape = np.abs(reconstructions[1][i].array).T.shape
        pixels_per_probe_reconstruction = probe_reconstruction_shape[0]*probe_reconstruction_shape[1]
        return (num_patterns*pixels_per_pattern)/(2*(pixels_per_phase_reconstruction + pixels_per_probe_reconstruction))

crop_to_center / _crop_to_center

Line 9 and 171 in waves.py references abtem.detect._crop_to_center.

9: from abtem.detect import AbstractDetector, _crop_to_center
171:         pattern = asnumpy(abs2(_crop_to_center(xp.fft.fftshift(fft2(self.array, overwrite_x=False)))))

But there is only crop_to_center (without the underscore) in detect.py

Changing the calculation device of GPU

There are 2 GPU on my workstation and they are different GPU each other.

So, how can I change the GPU setting to calculate in abTEM??

For example, in PyTorch which is deep learning framework, I can change GPU setting with the command like "device = 'cuda:1', device = 'cuda:0'".

Is there any command to do this in abTEM?

abtem.waves.FresnelPropagator - _fftn_dispatcher() got an unexpected keyword argument 'overwrite_x'

I am getting an error when I try to use abtem.waves.FresnelPropagator. This notebook shows exactly what I'm doing, and you can reproduce what I'm seeing.

for potential_slice in potential:
    transmit(wave, potential_slice)
    propagator.propagate(wave, potential_slice.thickness)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-49-11a0527c3aa9> in <module>()
      1 for potential_slice in potential:
      2     transmit(wave, potential_slice)
----> 3     propagator.propagate(wave, potential_slice.thickness)

2 frames
/usr/local/lib/python3.6/dist-packages/abtem/device.py in _fft_convolve(array, kernel, overwrite_x)
     48 def fft2_convolve(array, kernel, overwrite_x=True):
     49     def _fft_convolve(array, kernel, overwrite_x):
---> 50         mkl_fft.fft2(array, overwrite_x=overwrite_x)
     51         array *= kernel
     52         mkl_fft.ifft2(array, overwrite_x=overwrite_x)

<__array_function__ internals> in fft2(*args, **kwargs)

TypeError: _fftn_dispatcher() got an unexpected keyword argument 'overwrite_x'

Overhaul of measurement module

The current measurement module, used for finalizing simulation results, is too flexible and unsustainable to support in practice.

For example, it allows you to take slices across and reduce arbitrary axes, but I am not sure it always treats the resulting calibrations correctly. Some functions like Fourier space integration; can be done across arbitrary axes, even when it does not make sense, and when the calibrations do not match the units of the integration limits.

There are many rare but difficult to handle special cases like these, and we do not need to support them when hyperspy and xarray already do it better.

Nonetheless, we still need to support a "post-processing" step to finish many simulations. A collection of diffraction patterns representing a 4D-STEM dataset may need to be reduced to a PACBED pattern by taking the mean over the scan axes. A collection of diffraction patterns may also represent a frozen phonon ensemble, in which case we have to take the mean along the ensemble axis.

I think the "measure" module should handle targetted simulation-related cases like these and not try to be a multi-dimensional data analysis package. We will support easy conversion to hyperspy and xarray for such tasks.

The code will be simplified by introducing strongly typed measurements and axes. I believe five different types should cover all cases.

  • Images
    • Ensembles of HRTEM images
    • Ensembles of STEM images
  • DiffractionPatterns
    • 4D-STEM
    • Ensembles of diffraction patterns
  • LineProfiles
    • STEM linescan simulations
    • Line profiles obtained from images
  • PolarMeasurements (should think of a better name)
    • DPC-STEM
    • Virtual annular detector
  • SpectroscopicMeasurement
    • For future features

We should be able to assume certain things for each of these objects, for example, that the last two axes of a DiffractionPatterns represent the centered diffraction pattern; further axes may represent scan axes and ensemble axes, strictly in that order.
This allows confident implementation of a selected set of methods that are guaranteed to work as expected for each measurement type.

Code duplication between classes will be avoided using a mixin pattern.

Strong typing also allows special handling of certain operations, e.g., we can now easily treat interpolation differently for diffraction patterns.

To simplify things, we will only support the same units as the rest of abTEM, this is in practice already the case. If other units are desired, they could be supported when plotting or at the conversion to a hyperspy signal.

Minor issue with setting the sampling

A user tried to run a 4D-STEM simulation with settings like so:

probe = abtem.Probe(gpts=(1024,1024), energy=80e3, semiangle_cutoff=25, defocus=-1*def_val)
potential = abtem.Potential(model, sampling=0.05, parametrization='lobato')
... etc.

When they then tried to change the cell size (in model.cell), the sampling value was overridden. I am pretty sure this is due to the conflict between these 3 values:

gpts=(1024,1024)
sampling=0.05
model.cell

Because only 2 of these 3 values can be free parameters. Suggested fix: throw a warning if the user specifies incompatible dimensions / sampling.

License?

Is the code available under a opensource license ?

measure.py and noise.py: using the Calibrations object and Measurement Object in order to add noise to detected wave

Awesome project - really enjoying abtem and all the new features/documentation, so thank you!

I am trying to implement my old pyqstem code, and am struggling to resample and add noise to my exit_wave.

I see that poisson_noise takes a Measurement object as its input. So I am trying to make a Measurement object using my exit_wave.intensity(), and a Calibration object.

Somewhere I am going wrong, because my measurement object array property is an array of measurement objects, not floats. This throws an error when trying to use poisson_noise as it tries to divide a measurement object:

Screen Shot 2020-10-14 at 10 46 02 AM

I'm sure I am making an error somewhere but I am having trouble finding it. Maybe an example of resampling and dosage would help! Thanks again

Numba / Cuda issue

I ran 1_million_probe_positions.pyon a cluster successfully a couple of times on my local HPC (CentOS-7, V-100, Cuda 10.1), it worked a multiple times (I was running repeats to get an idea of perforamnce), but then it stopped and produces the following error (below). It runs the potential and multislice, and fails on measurement part of a code. I can get it to run the script using CPU only, and I can get cbed_8_million_atoms and run_STEM_MoS2.py to run using GPU, I've tried a couple of fresh differet conda envrionments (pasted below). I suspect that its an issue with the HPC, as I haven't been able to reproduce it locally, but while I wait on HPC support I thought I'd check if anyone has seen this

  File "/data/homezvol2/arakowsk/.conda/envs/abtem/lib/python3.7/site-packages/numba/core/typing/context.py", line 353, in resolve_argument_type
    return typeof(val, Purpose.argument)
  File "/data/homezvol2/arakowsk/.conda/envs/abtem/lib/python3.7/site-packages/numba/core/typing/typeof.py", line 35, in typeof
    raise ValueError(msg)
ValueError: Cannot determine Numba type of <class 'cupy.core.core.ndarray'>

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/data/homezvol2/arakowsk/.conda/envs/abtem/lib/python3.7/site-packages/numba/cuda/cudadrv/driver.py", line 237, in initialize
    self.cuInit(0)
  File "/data/homezvol2/arakowsk/.conda/envs/abtem/lib/python3.7/site-packages/numba/cuda/cudadrv/driver.py", line 300, in safe_cuda_api_call
    self._check_error(fname, retcode)
  File "/data/homezvol2/arakowsk/.conda/envs/abtem/lib/python3.7/site-packages/numba/cuda/cudadrv/driver.py", line 335, in _check_error
    raise CudaAPIError(retcode, msg)
numba.cuda.cudadrv.driver.CudaAPIError: [-1] Call to cuInit results in UNKNOWN_CUDA_ERROR

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "test_script.py", line 47, in <module>
    measurements = S.scan(scan, [detector], potential, max_batch_expansion=35)
  File "/data/homezvol2/arakowsk/.conda/envs/abtem/lib/python3.7/site-packages/abtem/waves.py", line 1544, in scan
    new_measurement = detector.detect(exit_probes)
  File "/data/homezvol2/arakowsk/.conda/envs/abtem/lib/python3.7/site-packages/abtem/detect.py", line 424, in detect
    sum_run_length_encoded(intensity, result, separators)
  File "/data/homezvol2/arakowsk/.conda/envs/abtem/lib/python3.7/site-packages/abtem/cuda_kernels.py", line 91, in launch_sum_run_length_encoded
    sum_run_length_encoded[blockspergrid, threadsperblock](array, result, separators)
  File "/data/homezvol2/arakowsk/.conda/envs/abtem/lib/python3.7/site-packages/numba/cuda/compiler.py", line 773, in __call__
    self.stream, self.sharedmem)
  File "/data/homezvol2/arakowsk/.conda/envs/abtem/lib/python3.7/site-packages/numba/cuda/compiler.py", line 877, in call
    for a in args])
  File "/data/homezvol2/arakowsk/.conda/envs/abtem/lib/python3.7/site-packages/numba/cuda/compiler.py", line 877, in <listcomp>
    for a in args])
  File "/data/homezvol2/arakowsk/.conda/envs/abtem/lib/python3.7/site-packages/numba/core/typing/context.py", line 356, in resolve_argument_type
    return typeof(numba.cuda.as_cuda_array(val), Purpose.argument)
  File "/data/homezvol2/arakowsk/.conda/envs/abtem/lib/python3.7/site-packages/numba/cuda/api.py", line 61, in as_cuda_array
    owner=obj)
  File "/data/homezvol2/arakowsk/.conda/envs/abtem/lib/python3.7/site-packages/numba/cuda/cudadrv/devices.py", line 223, in _require_cuda_context
    with _runtime.ensure_context():
  File "/data/homezvol2/arakowsk/.conda/envs/abtem/lib/python3.7/contextlib.py", line 112, in __enter__
    return next(self.gen)
  File "/data/homezvol2/arakowsk/.conda/envs/abtem/lib/python3.7/site-packages/numba/cuda/cudadrv/devices.py", line 121, in ensure_context
    with driver.get_active_context():
  File "/data/homezvol2/arakowsk/.conda/envs/abtem/lib/python3.7/site-packages/numba/cuda/cudadrv/driver.py", line 393, in __enter__
    driver.cuCtxGetCurrent(byref(hctx))
  File "/data/homezvol2/arakowsk/.conda/envs/abtem/lib/python3.7/site-packages/numba/cuda/cudadrv/driver.py", line 280, in __getattr__
    self.initialize()
  File "/data/homezvol2/arakowsk/.conda/envs/abtem/lib/python3.7/site-packages/numba/cuda/cudadrv/driver.py", line 240, in initialize
    raise CudaSupportError("Error at driver init: \n%s:" % e)
numba.cuda.cudadrv.error.CudaSupportError: Error at driver init: 
[-1] Call to cuInit results in UNKNOWN_CUDA_ERROR:
_libgcc_mutex             0.1                        main  
abtem                     1.0.0b13                 pypi_0    pypi
ase                       3.20.1                   pypi_0    pypi
blas                      1.0                         mkl  
ca-certificates           2020.12.8            h06a4308_0  
cached-property           1.5.2                    pypi_0    pypi
certifi                   2020.12.5        py37h06a4308_0  
cudatoolkit               10.1.243             h6bb024c_0    anaconda
cupy-cuda101              8.2.0                    pypi_0    pypi
cycler                    0.10.0                   pypi_0    pypi
fastrlock                 0.5                      pypi_0    pypi
h5py                      3.1.0                    pypi_0    pypi
imageio                   2.9.0                    pypi_0    pypi
intel-openmp              2020.2                      254  
kiwisolver                1.3.1                    pypi_0    pypi
ld_impl_linux-64          2.33.1               h53a641e_7  
libedit                   3.1.20191231         h14c3975_1  
libffi                    3.3                  he6710b0_2  
libgcc-ng                 9.1.0                hdf63c60_0  
libstdcxx-ng              9.1.0                hdf63c60_0  
llvmlite                  0.35.0                   pypi_0    pypi
matplotlib                3.3.3                    pypi_0    pypi
mkl                       2020.2                      256  
mkl-service               2.3.0            py37he8ac12f_0  
mkl_fft                   1.2.0            py37h23d657b_0  
mkl_random                1.1.1            py37h0573a6f_0  
ncurses                   6.2                  he6710b0_1  
numba                     0.52.0                   pypi_0    pypi
numpy                     1.19.4                   pypi_0    pypi
numpy-base                1.19.2           py37hfa32c7d_0  
openssl                   1.1.1i               h27cfd23_0  
pandas                    1.1.3            py37he6710b0_0  
pillow                    8.0.1                    pypi_0    pypi
pip                       20.3.1           py37h06a4308_0  
psutil                    5.7.3                    pypi_0    pypi
pyfftw                    0.12.0                   pypi_0    pypi
pyparsing                 2.4.7                    pypi_0    pypi
python                    3.7.9                h7579374_0  
python-dateutil           2.8.1                      py_0  
pytz                      2020.4             pyhd3eb1b0_0  
readline                  8.0                  h7b6447c_0  
scipy                     1.5.4                    pypi_0    pypi
setuptools                51.0.0           py37h06a4308_2  
six                       1.15.0           py37h06a4308_0  
sqlite                    3.33.0               h62c20be_0  
tk                        8.6.10               hbc83047_0  
tqdm                      4.54.1                   pypi_0    pypi
wheel                     0.36.1             pyhd3eb1b0_0  
xz                        5.2.5                h7b6447c_0  
zlib                      1.2.11               h7b6447c_3  

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.