├── License.txt ├── MANIFEST.in ├── README.md ├── conda.recipe └── meta.yaml ├── examples ├── HRTEM_dft.ipynb ├── HRTEM_introduction.ipynb ├── Image_mosaic.ipynb ├── STEM_dft.ipynb ├── STEM_potential_comparison.ipynb ├── graphene.cif ├── graphene.npy ├── image_mosaic.png └── stem_introduction.ipynb ├── fftw ├── fftw3.h ├── win32 │ ├── libfftw3-3.def │ ├── libfftw3-3.dll │ ├── libfftw3-3.exp │ ├── libfftw3-3.lib │ ├── libfftw3f-3.def │ ├── libfftw3f-3.dll │ ├── libfftw3f-3.exp │ ├── libfftw3f-3.lib │ ├── libfftw3l-3.def │ ├── libfftw3l-3.dll │ ├── libfftw3l-3.exp │ └── libfftw3l-3.lib └── win64 │ ├── libfftw3-3.def │ ├── libfftw3-3.dll │ ├── libfftw3-3.exp │ ├── libfftw3-3.lib │ ├── libfftw3f-3.def │ ├── libfftw3f-3.dll │ ├── libfftw3f-3.exp │ ├── libfftw3f-3.lib │ ├── libfftw3l-3.def │ ├── libfftw3l-3.dll │ ├── libfftw3l-3.exp │ └── libfftw3l-3.lib ├── pyqstem ├── QSTEM.cpp ├── QSTEM.h ├── __init__.py ├── detection.py ├── imaging.py ├── potentials.py ├── qstem_interface.pyx ├── thermal.py ├── util.py └── wave.py ├── setup.py ├── source ├── data_containers.cpp ├── data_containers.h ├── fileio_fftw3.cpp ├── fileio_fftw3.h ├── imagelib_fftw3.cpp ├── imagelib_fftw3.h ├── matrixlib.cpp ├── matrixlib.h ├── memory_fftw3.cpp ├── memory_fftw3.h ├── readparams.cpp ├── readparams.h ├── scatfactsRez.h ├── stem3.cpp ├── stemlib.cpp ├── stemlib.h ├── stemtypes_fftw3.h ├── stemutil.cpp └── stemutil.h └── test ├── graphene.cif ├── graphene.npy ├── test_CBED.py ├── test_stem.py ├── test_stem_dft.py ├── test_tem.py └── test_tem_dft.py /MANIFEST.in: -------------------------------------------------------------------------------- 1 | global-include *.pyx 2 | global-include *.pxd 3 | global-include *.h 4 | global-include *.dll 5 | global-include *.def 6 | global-include *.exp -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PyQSTEM 2 | 3 | QSTEM is a program for quantitative image simulation in electron microscopy, including TEM, STEM and CBED image simulation. 4 | 5 | This project interfaces the QSTEM code with Python and the Atomic Simulation Environment (ASE) to provide a single environment for building models, simulating and analysing images. 6 | 7 | *This program is no longer be maintained here. You may instead be interested in this [new Python-based multislice simulation program](https://github.com/jacobjma/abTEM).* 8 | 9 | QSTEM webpage: http://qstem.org/ 10 | ASE webpage: http://wiki.fysik.dtu.dk/ase 11 | 12 | ## Dependencies 13 | 14 | * [Python](http://www.python.org/) 2.7-3.6 15 | * [ASE](http://wiki.fysik.dtu.dk/ase) 16 | * [NumPy](http://docs.scipy.org/doc/numpy/reference/) 17 | * [FFTW](http://www.fftw.org/) 18 | * [Cython](http://cython.org/) 19 | * [matplotlib](http://matplotlib.org/) 20 | 21 | Optional: 22 | * [SciPy](https://www.scipy.org/) 23 | * [Jupyter and IPython](http://jupyter.org/) 24 | * [scikit-image](http://scikit-image.org/) 25 | * [PIL (Python Image Library)](http://www.pythonware.com/products/pil/) 26 | 27 | ## Building from Source 28 | ### Linux 29 | 30 | #### Install dependencies 31 | FFTW is installed with apt-get, the rest with pip. 32 | ``` 33 | sudo apt-get install libfftw3-dev libfftw3-single3 34 | pip install numpy scipy matplotlib ase 35 | pip install cython jupyter scikit-image 36 | ``` 37 | #### Install PyQSTEM 38 | When the dependencies are installed, download, compile and install PyQSTEM by writing. 39 | ``` 40 | git clone https://github.com/jacobjma/PyQSTEM.git 41 | cd pyqstem 42 | python setup.py install 43 | ``` 44 | You might get some warnings which can be ignored. 45 | 46 | ### Mac OS X 47 | Mac OS X comes with Python included, but installing packages into OS X's own Python is risky, as cleaning up a mess is almost impossible. For this reason, it is recommended to either install Python with Homebrew, or to install the Anaconda distribution. This guide uses homebrew's Python, as you will need to install a number of other packages with Homebrew anyway. 48 | 49 | #### Install Homebrew 50 | 51 | Install Homebrew following the instructions on the [Homebrew website](https://brew.sh/). 52 | 53 | #### Install Python with homebrew. 54 | 55 | Install Homebrew's python with the command 56 | ``` 57 | brew install python 58 | ``` 59 | or if you want Python 3 with 60 | ``` 61 | brew install python3 62 | ``` 63 | Please double-check that you get the version of `python` and `pip` installed in /usr/local/bin, and not the default one in /usr/bin. 64 | 65 | #### Install dependencies 66 | 67 | FFTW is installed with Homebrew, the rest with pip. 68 | ``` 69 | brew install fftw 70 | pip install numpy scipy matplotlib ase 71 | pip install cython jupyter scikit-image 72 | ``` 73 | #### Install PyQSTEM 74 | When the dependencies are installed, download, compile and install PyQSTEM by writing. 75 | ``` 76 | git clone https://github.com/jacobjma/PyQSTEM.git 77 | cd PyQSTEM 78 | python setup.py install 79 | ``` 80 | You might get some warnings which can be ignored. 81 | 82 | ### Windows 83 | #### Install Python 84 | If you are new to Python the easiest way to get started is downloading a bundle installer. We recommend Anaconda, this platform includes Python and makes it easier to install the dependencies. Download Anaconda [here](https://www.continuum.io/downloads). 85 | 86 | #### Install a C-compiler 87 | 88 | ##### Python 3.5 or later 89 | Compiling C++-extensions for Python 3.5 on Windows requires Microsoft Visual C++ 14.0 or later. Download Visual C++ 2015 Build Tools from [here](http://landinghub.visualstudio.com/visual-cpp-build-tools), this requires 4 gb of free space and may take 20 minutes to install. 90 | 91 | ##### Python 2.7 92 | If you are using Python 2.7 you can install [TDM-GCC](http://tdm-gcc.tdragon.net/) and in the Anaconda prompt write 93 | ``` 94 | conda install mingw libpython 95 | ``` 96 | 97 | #### FFTW 98 | Precompiled libraries for [FFTW 3.3.5](http://www.fftw.org/install/windows.html) are included for both 32 and 64-bit Windows. You should not have to do anything. 99 | 100 | #### Install dependencies 101 | When Anaconda and a C++-compiler is installed, open the `Anaconda prompt`, and type the following commands to install ASE, cython and the rest of the dependencies: 102 | ``` 103 | pip install numpy matplotlib ase 104 | conda install cython scipy 105 | ``` 106 | The other required dependencies should be included with Anaconda, otherwise install them using `pip`. 107 | 108 | #### Install PyQSTEM 109 | When the dependencies are installed, download, compile and install PyQSTEM by writing. 110 | ``` 111 | git clone https://github.com/jacobjma/PyQSTEM.git 112 | cd pyqstem 113 | python setup.py install 114 | ``` 115 | You might get some warnings which can be ignored. 116 | 117 | -------------------------------------------------------------------------------- /conda.recipe/meta.yaml: -------------------------------------------------------------------------------- 1 | package: 2 | name: pyqstem 3 | # this is nice, but only works once you have an initial annotated git tag 4 | # version: {{ GIT_DESCRIBE_TAG }}.{{ GIT_BUILD_STR }} 5 | version: 1.0 6 | 7 | source: 8 | path: .. 9 | # git_url: https://github.com/jacobjma/PyQSTEM 10 | # git_tag: (commit id or tag of release to build, defaults to master) 11 | 12 | build: 13 | script: python setup.py install --single-version-externally-managed --record=record.txt 14 | 15 | requirements: 16 | build: 17 | - cython 18 | - fftw 19 | - numpy 20 | - python 21 | - setuptools 22 | run: 23 | - ase 24 | - fftw 25 | - matplotlib 26 | - numpy 27 | - python 28 | - scikit-image 29 | - scipy 30 | 31 | test: 32 | imports: 33 | - pyqstem 34 | - pyqstem.util 35 | - pyqstem.potentials 36 | 37 | about: 38 | description: 'QSTEM is a program for quantitative image simulation in 39 | electron microscopy, including TEM, STEM and CBED image simulation. 40 | 41 | This project interfaces the QSTEM code with Python and the 42 | Atomic Simulation Environment (ASE) to provide a single 43 | environment for building models, simulating and analysing 44 | images. 45 | 46 | ' 47 | dev_url: https://github.com/jacobjma/PyQSTEM 48 | doc_url: https://github.com/jacobjma/PyQSTEM 49 | home: https://github.com/jacobjma/PyQSTEM 50 | license: GPL3 51 | license_file: License.txt 52 | summary: A Python interface to the electron microscopy simulation program QSTEM. 53 | -------------------------------------------------------------------------------- /examples/graphene.cif: -------------------------------------------------------------------------------- 1 | data_image0 2 | _cell_length_a 4.92 3 | _cell_length_b 4.26084 4 | _cell_length_c 6 5 | _cell_angle_alpha 90 6 | _cell_angle_beta 90 7 | _cell_angle_gamma 90 8 | 9 | _symmetry_space_group_name_H-M "P 1" 10 | _symmetry_int_tables_number 1 11 | 12 | loop_ 13 | _symmetry_equiv_pos_as_xyz 14 | 'x, y, z' 15 | 16 | loop_ 17 | _atom_site_label 18 | _atom_site_occupancy 19 | _atom_site_fract_x 20 | _atom_site_fract_y 21 | _atom_site_fract_z 22 | _atom_site_thermal_displace_type 23 | _atom_site_B_iso_or_equiv 24 | _atom_site_type_symbol 25 | C1 1.0000 0.87500 0.16667 0.50000 Biso 1.000 C 26 | C2 1.0000 0.12500 0.33333 0.50000 Biso 1.000 C 27 | C3 1.0000 0.12500 0.66667 0.50000 Biso 1.000 C 28 | C4 1.0000 0.37500 0.83333 0.50000 Biso 1.000 C 29 | C5 1.0000 0.37500 0.16667 0.50000 Biso 1.000 C 30 | C6 1.0000 0.62500 0.33333 0.50000 Biso 1.000 C 31 | C7 1.0000 0.62500 0.66667 0.50000 Biso 1.000 C 32 | C8 1.0000 0.87500 0.83333 0.50000 Biso 1.000 C 33 | -------------------------------------------------------------------------------- /examples/graphene.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacobjma/PyQSTEM/9172962b9ed51769a97c90278f463af3ec89181e/examples/graphene.npy -------------------------------------------------------------------------------- /examples/image_mosaic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacobjma/PyQSTEM/9172962b9ed51769a97c90278f463af3ec89181e/examples/image_mosaic.png -------------------------------------------------------------------------------- /fftw/fftw3.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2003, 2007-14 Matteo Frigo 3 | * Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology 4 | * 5 | * The following statement of license applies *only* to this header file, 6 | * and *not* to the other files distributed with FFTW or derived therefrom: 7 | * 8 | * Redistribution and use in source and binary forms, with or without 9 | * modification, are permitted provided that the following conditions 10 | * are met: 11 | * 12 | * 1. Redistributions of source code must retain the above copyright 13 | * notice, this list of conditions and the following disclaimer. 14 | * 15 | * 2. Redistributions in binary form must reproduce the above copyright 16 | * notice, this list of conditions and the following disclaimer in the 17 | * documentation and/or other materials provided with the distribution. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 20 | * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 23 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 25 | * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 27 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 28 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 29 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | */ 31 | 32 | /***************************** NOTE TO USERS ********************************* 33 | * 34 | * THIS IS A HEADER FILE, NOT A MANUAL 35 | * 36 | * If you want to know how to use FFTW, please read the manual, 37 | * online at http://www.fftw.org/doc/ and also included with FFTW. 38 | * For a quick start, see the manual's tutorial section. 39 | * 40 | * (Reading header files to learn how to use a library is a habit 41 | * stemming from code lacking a proper manual. Arguably, it's a 42 | * *bad* habit in most cases, because header files can contain 43 | * interfaces that are not part of the public, stable API.) 44 | * 45 | ****************************************************************************/ 46 | 47 | #ifndef FFTW3_H 48 | #define FFTW3_H 49 | 50 | #include 51 | 52 | #ifdef __cplusplus 53 | extern "C" 54 | { 55 | #endif /* __cplusplus */ 56 | 57 | /* If is included, use the C99 complex type. Otherwise 58 | define a type bit-compatible with C99 complex */ 59 | #if !defined(FFTW_NO_Complex) && defined(_Complex_I) && defined(complex) && defined(I) 60 | # define FFTW_DEFINE_COMPLEX(R, C) typedef R _Complex C 61 | #else 62 | # define FFTW_DEFINE_COMPLEX(R, C) typedef R C[2] 63 | #endif 64 | 65 | #define FFTW_CONCAT(prefix, name) prefix ## name 66 | #define FFTW_MANGLE_DOUBLE(name) FFTW_CONCAT(fftw_, name) 67 | #define FFTW_MANGLE_FLOAT(name) FFTW_CONCAT(fftwf_, name) 68 | #define FFTW_MANGLE_LONG_DOUBLE(name) FFTW_CONCAT(fftwl_, name) 69 | #define FFTW_MANGLE_QUAD(name) FFTW_CONCAT(fftwq_, name) 70 | 71 | /* IMPORTANT: for Windows compilers, you should add a line 72 | */ 73 | #define FFTW_DLL 74 | /* 75 | here and in kernel/ifftw.h if you are compiling/using FFTW as a 76 | DLL, in order to do the proper importing/exporting, or 77 | alternatively compile with -DFFTW_DLL or the equivalent 78 | command-line flag. This is not necessary under MinGW/Cygwin, where 79 | libtool does the imports/exports automatically. */ 80 | #if defined(FFTW_DLL) && (defined(_WIN32) || defined(__WIN32__)) 81 | /* annoying Windows syntax for shared-library declarations */ 82 | # if defined(COMPILING_FFTW) /* defined in api.h when compiling FFTW */ 83 | # define FFTW_EXTERN extern __declspec(dllexport) 84 | # else /* user is calling FFTW; import symbol */ 85 | # define FFTW_EXTERN extern __declspec(dllimport) 86 | # endif 87 | #else 88 | # define FFTW_EXTERN extern 89 | #endif 90 | 91 | enum fftw_r2r_kind_do_not_use_me { 92 | FFTW_R2HC=0, FFTW_HC2R=1, FFTW_DHT=2, 93 | FFTW_REDFT00=3, FFTW_REDFT01=4, FFTW_REDFT10=5, FFTW_REDFT11=6, 94 | FFTW_RODFT00=7, FFTW_RODFT01=8, FFTW_RODFT10=9, FFTW_RODFT11=10 95 | }; 96 | 97 | struct fftw_iodim_do_not_use_me { 98 | int n; /* dimension size */ 99 | int is; /* input stride */ 100 | int os; /* output stride */ 101 | }; 102 | 103 | #include /* for ptrdiff_t */ 104 | struct fftw_iodim64_do_not_use_me { 105 | ptrdiff_t n; /* dimension size */ 106 | ptrdiff_t is; /* input stride */ 107 | ptrdiff_t os; /* output stride */ 108 | }; 109 | 110 | typedef void (*fftw_write_char_func_do_not_use_me)(char c, void *); 111 | typedef int (*fftw_read_char_func_do_not_use_me)(void *); 112 | 113 | /* 114 | huge second-order macro that defines prototypes for all API 115 | functions. We expand this macro for each supported precision 116 | 117 | X: name-mangling macro 118 | R: real data type 119 | C: complex data type 120 | */ 121 | 122 | #define FFTW_DEFINE_API(X, R, C) \ 123 | \ 124 | FFTW_DEFINE_COMPLEX(R, C); \ 125 | \ 126 | typedef struct X(plan_s) *X(plan); \ 127 | \ 128 | typedef struct fftw_iodim_do_not_use_me X(iodim); \ 129 | typedef struct fftw_iodim64_do_not_use_me X(iodim64); \ 130 | \ 131 | typedef enum fftw_r2r_kind_do_not_use_me X(r2r_kind); \ 132 | \ 133 | typedef fftw_write_char_func_do_not_use_me X(write_char_func); \ 134 | typedef fftw_read_char_func_do_not_use_me X(read_char_func); \ 135 | \ 136 | FFTW_EXTERN void X(execute)(const X(plan) p); \ 137 | \ 138 | FFTW_EXTERN X(plan) X(plan_dft)(int rank, const int *n, \ 139 | C *in, C *out, int sign, unsigned flags); \ 140 | \ 141 | FFTW_EXTERN X(plan) X(plan_dft_1d)(int n, C *in, C *out, int sign, \ 142 | unsigned flags); \ 143 | FFTW_EXTERN X(plan) X(plan_dft_2d)(int n0, int n1, \ 144 | C *in, C *out, int sign, unsigned flags); \ 145 | FFTW_EXTERN X(plan) X(plan_dft_3d)(int n0, int n1, int n2, \ 146 | C *in, C *out, int sign, unsigned flags); \ 147 | \ 148 | FFTW_EXTERN X(plan) X(plan_many_dft)(int rank, const int *n, \ 149 | int howmany, \ 150 | C *in, const int *inembed, \ 151 | int istride, int idist, \ 152 | C *out, const int *onembed, \ 153 | int ostride, int odist, \ 154 | int sign, unsigned flags); \ 155 | \ 156 | FFTW_EXTERN X(plan) X(plan_guru_dft)(int rank, const X(iodim) *dims, \ 157 | int howmany_rank, \ 158 | const X(iodim) *howmany_dims, \ 159 | C *in, C *out, \ 160 | int sign, unsigned flags); \ 161 | FFTW_EXTERN X(plan) X(plan_guru_split_dft)(int rank, const X(iodim) *dims, \ 162 | int howmany_rank, \ 163 | const X(iodim) *howmany_dims, \ 164 | R *ri, R *ii, R *ro, R *io, \ 165 | unsigned flags); \ 166 | \ 167 | FFTW_EXTERN X(plan) X(plan_guru64_dft)(int rank, \ 168 | const X(iodim64) *dims, \ 169 | int howmany_rank, \ 170 | const X(iodim64) *howmany_dims, \ 171 | C *in, C *out, \ 172 | int sign, unsigned flags); \ 173 | FFTW_EXTERN X(plan) X(plan_guru64_split_dft)(int rank, \ 174 | const X(iodim64) *dims, \ 175 | int howmany_rank, \ 176 | const X(iodim64) *howmany_dims, \ 177 | R *ri, R *ii, R *ro, R *io, \ 178 | unsigned flags); \ 179 | \ 180 | FFTW_EXTERN void X(execute_dft)(const X(plan) p, C *in, C *out); \ 181 | FFTW_EXTERN void X(execute_split_dft)(const X(plan) p, R *ri, R *ii, \ 182 | R *ro, R *io); \ 183 | \ 184 | FFTW_EXTERN X(plan) X(plan_many_dft_r2c)(int rank, const int *n, \ 185 | int howmany, \ 186 | R *in, const int *inembed, \ 187 | int istride, int idist, \ 188 | C *out, const int *onembed, \ 189 | int ostride, int odist, \ 190 | unsigned flags); \ 191 | \ 192 | FFTW_EXTERN X(plan) X(plan_dft_r2c)(int rank, const int *n, \ 193 | R *in, C *out, unsigned flags); \ 194 | \ 195 | FFTW_EXTERN X(plan) X(plan_dft_r2c_1d)(int n,R *in,C *out,unsigned flags); \ 196 | FFTW_EXTERN X(plan) X(plan_dft_r2c_2d)(int n0, int n1, \ 197 | R *in, C *out, unsigned flags); \ 198 | FFTW_EXTERN X(plan) X(plan_dft_r2c_3d)(int n0, int n1, \ 199 | int n2, \ 200 | R *in, C *out, unsigned flags); \ 201 | \ 202 | \ 203 | FFTW_EXTERN X(plan) X(plan_many_dft_c2r)(int rank, const int *n, \ 204 | int howmany, \ 205 | C *in, const int *inembed, \ 206 | int istride, int idist, \ 207 | R *out, const int *onembed, \ 208 | int ostride, int odist, \ 209 | unsigned flags); \ 210 | \ 211 | FFTW_EXTERN X(plan) X(plan_dft_c2r)(int rank, const int *n, \ 212 | C *in, R *out, unsigned flags); \ 213 | \ 214 | FFTW_EXTERN X(plan) X(plan_dft_c2r_1d)(int n,C *in,R *out,unsigned flags); \ 215 | FFTW_EXTERN X(plan) X(plan_dft_c2r_2d)(int n0, int n1, \ 216 | C *in, R *out, unsigned flags); \ 217 | FFTW_EXTERN X(plan) X(plan_dft_c2r_3d)(int n0, int n1, \ 218 | int n2, \ 219 | C *in, R *out, unsigned flags); \ 220 | \ 221 | FFTW_EXTERN X(plan) X(plan_guru_dft_r2c)(int rank, const X(iodim) *dims, \ 222 | int howmany_rank, \ 223 | const X(iodim) *howmany_dims, \ 224 | R *in, C *out, \ 225 | unsigned flags); \ 226 | FFTW_EXTERN X(plan) X(plan_guru_dft_c2r)(int rank, const X(iodim) *dims, \ 227 | int howmany_rank, \ 228 | const X(iodim) *howmany_dims, \ 229 | C *in, R *out, \ 230 | unsigned flags); \ 231 | \ 232 | FFTW_EXTERN X(plan) X(plan_guru_split_dft_r2c)( \ 233 | int rank, const X(iodim) *dims, \ 234 | int howmany_rank, \ 235 | const X(iodim) *howmany_dims, \ 236 | R *in, R *ro, R *io, \ 237 | unsigned flags); \ 238 | FFTW_EXTERN X(plan) X(plan_guru_split_dft_c2r)( \ 239 | int rank, const X(iodim) *dims, \ 240 | int howmany_rank, \ 241 | const X(iodim) *howmany_dims, \ 242 | R *ri, R *ii, R *out, \ 243 | unsigned flags); \ 244 | \ 245 | FFTW_EXTERN X(plan) X(plan_guru64_dft_r2c)(int rank, \ 246 | const X(iodim64) *dims, \ 247 | int howmany_rank, \ 248 | const X(iodim64) *howmany_dims, \ 249 | R *in, C *out, \ 250 | unsigned flags); \ 251 | FFTW_EXTERN X(plan) X(plan_guru64_dft_c2r)(int rank, \ 252 | const X(iodim64) *dims, \ 253 | int howmany_rank, \ 254 | const X(iodim64) *howmany_dims, \ 255 | C *in, R *out, \ 256 | unsigned flags); \ 257 | \ 258 | FFTW_EXTERN X(plan) X(plan_guru64_split_dft_r2c)( \ 259 | int rank, const X(iodim64) *dims, \ 260 | int howmany_rank, \ 261 | const X(iodim64) *howmany_dims, \ 262 | R *in, R *ro, R *io, \ 263 | unsigned flags); \ 264 | FFTW_EXTERN X(plan) X(plan_guru64_split_dft_c2r)( \ 265 | int rank, const X(iodim64) *dims, \ 266 | int howmany_rank, \ 267 | const X(iodim64) *howmany_dims, \ 268 | R *ri, R *ii, R *out, \ 269 | unsigned flags); \ 270 | \ 271 | FFTW_EXTERN void X(execute_dft_r2c)(const X(plan) p, R *in, C *out); \ 272 | FFTW_EXTERN void X(execute_dft_c2r)(const X(plan) p, C *in, R *out); \ 273 | \ 274 | FFTW_EXTERN void X(execute_split_dft_r2c)(const X(plan) p, \ 275 | R *in, R *ro, R *io); \ 276 | FFTW_EXTERN void X(execute_split_dft_c2r)(const X(plan) p, \ 277 | R *ri, R *ii, R *out); \ 278 | \ 279 | FFTW_EXTERN X(plan) X(plan_many_r2r)(int rank, const int *n, \ 280 | int howmany, \ 281 | R *in, const int *inembed, \ 282 | int istride, int idist, \ 283 | R *out, const int *onembed, \ 284 | int ostride, int odist, \ 285 | const X(r2r_kind) *kind, unsigned flags); \ 286 | \ 287 | FFTW_EXTERN X(plan) X(plan_r2r)(int rank, const int *n, R *in, R *out, \ 288 | const X(r2r_kind) *kind, unsigned flags); \ 289 | \ 290 | FFTW_EXTERN X(plan) X(plan_r2r_1d)(int n, R *in, R *out, \ 291 | X(r2r_kind) kind, unsigned flags); \ 292 | FFTW_EXTERN X(plan) X(plan_r2r_2d)(int n0, int n1, R *in, R *out, \ 293 | X(r2r_kind) kind0, X(r2r_kind) kind1, \ 294 | unsigned flags); \ 295 | FFTW_EXTERN X(plan) X(plan_r2r_3d)(int n0, int n1, int n2, \ 296 | R *in, R *out, X(r2r_kind) kind0, \ 297 | X(r2r_kind) kind1, X(r2r_kind) kind2, \ 298 | unsigned flags); \ 299 | \ 300 | FFTW_EXTERN X(plan) X(plan_guru_r2r)(int rank, const X(iodim) *dims, \ 301 | int howmany_rank, \ 302 | const X(iodim) *howmany_dims, \ 303 | R *in, R *out, \ 304 | const X(r2r_kind) *kind, unsigned flags); \ 305 | \ 306 | FFTW_EXTERN X(plan) X(plan_guru64_r2r)(int rank, const X(iodim64) *dims, \ 307 | int howmany_rank, \ 308 | const X(iodim64) *howmany_dims, \ 309 | R *in, R *out, \ 310 | const X(r2r_kind) *kind, unsigned flags); \ 311 | \ 312 | FFTW_EXTERN void X(execute_r2r)(const X(plan) p, R *in, R *out); \ 313 | \ 314 | FFTW_EXTERN void X(destroy_plan)(X(plan) p); \ 315 | FFTW_EXTERN void X(forget_wisdom)(void); \ 316 | FFTW_EXTERN void X(cleanup)(void); \ 317 | \ 318 | FFTW_EXTERN void X(set_timelimit)(double t); \ 319 | \ 320 | FFTW_EXTERN void X(plan_with_nthreads)(int nthreads); \ 321 | FFTW_EXTERN int X(init_threads)(void); \ 322 | FFTW_EXTERN void X(cleanup_threads)(void); \ 323 | FFTW_EXTERN void X(make_planner_thread_safe)(void); \ 324 | \ 325 | FFTW_EXTERN int X(export_wisdom_to_filename)(const char *filename); \ 326 | FFTW_EXTERN void X(export_wisdom_to_file)(FILE *output_file); \ 327 | FFTW_EXTERN char *X(export_wisdom_to_string)(void); \ 328 | FFTW_EXTERN void X(export_wisdom)(X(write_char_func) write_char, \ 329 | void *data); \ 330 | FFTW_EXTERN int X(import_system_wisdom)(void); \ 331 | FFTW_EXTERN int X(import_wisdom_from_filename)(const char *filename); \ 332 | FFTW_EXTERN int X(import_wisdom_from_file)(FILE *input_file); \ 333 | FFTW_EXTERN int X(import_wisdom_from_string)(const char *input_string); \ 334 | FFTW_EXTERN int X(import_wisdom)(X(read_char_func) read_char, void *data); \ 335 | \ 336 | FFTW_EXTERN void X(fprint_plan)(const X(plan) p, FILE *output_file); \ 337 | FFTW_EXTERN void X(print_plan)(const X(plan) p); \ 338 | FFTW_EXTERN char *X(sprint_plan)(const X(plan) p); \ 339 | \ 340 | FFTW_EXTERN void *X(malloc)(size_t n); \ 341 | FFTW_EXTERN R *X(alloc_real)(size_t n); \ 342 | FFTW_EXTERN C *X(alloc_complex)(size_t n); \ 343 | FFTW_EXTERN void X(free)(void *p); \ 344 | \ 345 | FFTW_EXTERN void X(flops)(const X(plan) p, \ 346 | double *add, double *mul, double *fmas); \ 347 | FFTW_EXTERN double X(estimate_cost)(const X(plan) p); \ 348 | FFTW_EXTERN double X(cost)(const X(plan) p); \ 349 | \ 350 | FFTW_EXTERN int X(alignment_of)(R *p); \ 351 | FFTW_EXTERN const char X(version)[]; \ 352 | FFTW_EXTERN const char X(cc)[]; \ 353 | FFTW_EXTERN const char X(codelet_optim)[]; 354 | 355 | 356 | /* end of FFTW_DEFINE_API macro */ 357 | 358 | FFTW_DEFINE_API(FFTW_MANGLE_DOUBLE, double, fftw_complex) 359 | FFTW_DEFINE_API(FFTW_MANGLE_FLOAT, float, fftwf_complex) 360 | FFTW_DEFINE_API(FFTW_MANGLE_LONG_DOUBLE, long double, fftwl_complex) 361 | 362 | /* __float128 (quad precision) is a gcc extension on i386, x86_64, and ia64 363 | for gcc >= 4.6 (compiled in FFTW with --enable-quad-precision) */ 364 | #if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) \ 365 | && !(defined(__ICC) || defined(__INTEL_COMPILER) || defined(__CUDACC__) || defined(__PGI)) \ 366 | && (defined(__i386__) || defined(__x86_64__) || defined(__ia64__)) 367 | # if !defined(FFTW_NO_Complex) && defined(_Complex_I) && defined(complex) && defined(I) 368 | /* note: __float128 is a typedef, which is not supported with the _Complex 369 | keyword in gcc, so instead we use this ugly __attribute__ version. 370 | However, we can't simply pass the __attribute__ version to 371 | FFTW_DEFINE_API because the __attribute__ confuses gcc in pointer 372 | types. Hence redefining FFTW_DEFINE_COMPLEX. Ugh. */ 373 | # undef FFTW_DEFINE_COMPLEX 374 | # define FFTW_DEFINE_COMPLEX(R, C) typedef _Complex float __attribute__((mode(TC))) C 375 | # endif 376 | FFTW_DEFINE_API(FFTW_MANGLE_QUAD, __float128, fftwq_complex) 377 | #endif 378 | 379 | #define FFTW_FORWARD (-1) 380 | #define FFTW_BACKWARD (+1) 381 | 382 | #define FFTW_NO_TIMELIMIT (-1.0) 383 | 384 | /* documented flags */ 385 | #define FFTW_MEASURE (0U) 386 | #define FFTW_DESTROY_INPUT (1U << 0) 387 | #define FFTW_UNALIGNED (1U << 1) 388 | #define FFTW_CONSERVE_MEMORY (1U << 2) 389 | #define FFTW_EXHAUSTIVE (1U << 3) /* NO_EXHAUSTIVE is default */ 390 | #define FFTW_PRESERVE_INPUT (1U << 4) /* cancels FFTW_DESTROY_INPUT */ 391 | #define FFTW_PATIENT (1U << 5) /* IMPATIENT is default */ 392 | #define FFTW_ESTIMATE (1U << 6) 393 | #define FFTW_WISDOM_ONLY (1U << 21) 394 | 395 | /* undocumented beyond-guru flags */ 396 | #define FFTW_ESTIMATE_PATIENT (1U << 7) 397 | #define FFTW_BELIEVE_PCOST (1U << 8) 398 | #define FFTW_NO_DFT_R2HC (1U << 9) 399 | #define FFTW_NO_NONTHREADED (1U << 10) 400 | #define FFTW_NO_BUFFERING (1U << 11) 401 | #define FFTW_NO_INDIRECT_OP (1U << 12) 402 | #define FFTW_ALLOW_LARGE_GENERIC (1U << 13) /* NO_LARGE_GENERIC is default */ 403 | #define FFTW_NO_RANK_SPLITS (1U << 14) 404 | #define FFTW_NO_VRANK_SPLITS (1U << 15) 405 | #define FFTW_NO_VRECURSE (1U << 16) 406 | #define FFTW_NO_SIMD (1U << 17) 407 | #define FFTW_NO_SLOW (1U << 18) 408 | #define FFTW_NO_FIXED_RADIX_LARGE_N (1U << 19) 409 | #define FFTW_ALLOW_PRUNING (1U << 20) 410 | 411 | #ifdef __cplusplus 412 | } /* extern "C" */ 413 | #endif /* __cplusplus */ 414 | 415 | #endif /* FFTW3_H */ 416 | -------------------------------------------------------------------------------- /fftw/win32/libfftw3-3.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacobjma/PyQSTEM/9172962b9ed51769a97c90278f463af3ec89181e/fftw/win32/libfftw3-3.dll -------------------------------------------------------------------------------- /fftw/win32/libfftw3-3.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacobjma/PyQSTEM/9172962b9ed51769a97c90278f463af3ec89181e/fftw/win32/libfftw3-3.exp -------------------------------------------------------------------------------- /fftw/win32/libfftw3-3.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacobjma/PyQSTEM/9172962b9ed51769a97c90278f463af3ec89181e/fftw/win32/libfftw3-3.lib -------------------------------------------------------------------------------- /fftw/win32/libfftw3f-3.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacobjma/PyQSTEM/9172962b9ed51769a97c90278f463af3ec89181e/fftw/win32/libfftw3f-3.dll -------------------------------------------------------------------------------- /fftw/win32/libfftw3f-3.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacobjma/PyQSTEM/9172962b9ed51769a97c90278f463af3ec89181e/fftw/win32/libfftw3f-3.exp -------------------------------------------------------------------------------- /fftw/win32/libfftw3f-3.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacobjma/PyQSTEM/9172962b9ed51769a97c90278f463af3ec89181e/fftw/win32/libfftw3f-3.lib -------------------------------------------------------------------------------- /fftw/win32/libfftw3l-3.def: -------------------------------------------------------------------------------- 1 | LIBRARY libfftw3l-3.dll 2 | EXPORTS 3 | fftwl_alignment_of 4 | fftwl_alloc_complex 5 | fftwl_alloc_real 6 | fftwl_assertion_failed 7 | fftwl_bufdist 8 | fftwl_choose_radix 9 | fftwl_cleanup 10 | fftwl_cleanup_threads 11 | fftwl_codelet_e01_8 12 | fftwl_codelet_e10_8 13 | fftwl_codelet_hb_10 14 | fftwl_codelet_hb_12 15 | fftwl_codelet_hb_15 16 | fftwl_codelet_hb_16 17 | fftwl_codelet_hb_2 18 | fftwl_codelet_hb_20 19 | fftwl_codelet_hb2_16 20 | fftwl_codelet_hb2_20 21 | fftwl_codelet_hb2_25 22 | fftwl_codelet_hb2_32 23 | fftwl_codelet_hb2_4 24 | fftwl_codelet_hb_25 25 | fftwl_codelet_hb2_5 26 | fftwl_codelet_hb2_8 27 | fftwl_codelet_hb_3 28 | fftwl_codelet_hb_32 29 | fftwl_codelet_hb_4 30 | fftwl_codelet_hb_5 31 | fftwl_codelet_hb_6 32 | fftwl_codelet_hb_64 33 | fftwl_codelet_hb_7 34 | fftwl_codelet_hb_8 35 | fftwl_codelet_hb_9 36 | fftwl_codelet_hc2cb_10 37 | fftwl_codelet_hc2cb_12 38 | fftwl_codelet_hc2cb_16 39 | fftwl_codelet_hc2cb_2 40 | fftwl_codelet_hc2cb_20 41 | fftwl_codelet_hc2cb2_16 42 | fftwl_codelet_hc2cb2_20 43 | fftwl_codelet_hc2cb2_32 44 | fftwl_codelet_hc2cb2_4 45 | fftwl_codelet_hc2cb2_8 46 | fftwl_codelet_hc2cb_32 47 | fftwl_codelet_hc2cb_4 48 | fftwl_codelet_hc2cb_6 49 | fftwl_codelet_hc2cb_8 50 | fftwl_codelet_hc2cbdft_10 51 | fftwl_codelet_hc2cbdft_12 52 | fftwl_codelet_hc2cbdft_16 53 | fftwl_codelet_hc2cbdft_2 54 | fftwl_codelet_hc2cbdft_20 55 | fftwl_codelet_hc2cbdft2_16 56 | fftwl_codelet_hc2cbdft2_20 57 | fftwl_codelet_hc2cbdft2_32 58 | fftwl_codelet_hc2cbdft2_4 59 | fftwl_codelet_hc2cbdft2_8 60 | fftwl_codelet_hc2cbdft_32 61 | fftwl_codelet_hc2cbdft_4 62 | fftwl_codelet_hc2cbdft_6 63 | fftwl_codelet_hc2cbdft_8 64 | fftwl_codelet_hc2cf_10 65 | fftwl_codelet_hc2cf_12 66 | fftwl_codelet_hc2cf_16 67 | fftwl_codelet_hc2cf_2 68 | fftwl_codelet_hc2cf_20 69 | fftwl_codelet_hc2cf2_16 70 | fftwl_codelet_hc2cf2_20 71 | fftwl_codelet_hc2cf2_32 72 | fftwl_codelet_hc2cf2_4 73 | fftwl_codelet_hc2cf2_8 74 | fftwl_codelet_hc2cf_32 75 | fftwl_codelet_hc2cf_4 76 | fftwl_codelet_hc2cf_6 77 | fftwl_codelet_hc2cf_8 78 | fftwl_codelet_hc2cfdft_10 79 | fftwl_codelet_hc2cfdft_12 80 | fftwl_codelet_hc2cfdft_16 81 | fftwl_codelet_hc2cfdft_2 82 | fftwl_codelet_hc2cfdft_20 83 | fftwl_codelet_hc2cfdft2_16 84 | fftwl_codelet_hc2cfdft2_20 85 | fftwl_codelet_hc2cfdft2_32 86 | fftwl_codelet_hc2cfdft2_4 87 | fftwl_codelet_hc2cfdft2_8 88 | fftwl_codelet_hc2cfdft_32 89 | fftwl_codelet_hc2cfdft_4 90 | fftwl_codelet_hc2cfdft_6 91 | fftwl_codelet_hc2cfdft_8 92 | fftwl_codelet_hf_10 93 | fftwl_codelet_hf_12 94 | fftwl_codelet_hf_15 95 | fftwl_codelet_hf_16 96 | fftwl_codelet_hf_2 97 | fftwl_codelet_hf_20 98 | fftwl_codelet_hf2_16 99 | fftwl_codelet_hf2_20 100 | fftwl_codelet_hf2_25 101 | fftwl_codelet_hf2_32 102 | fftwl_codelet_hf2_4 103 | fftwl_codelet_hf_25 104 | fftwl_codelet_hf2_5 105 | fftwl_codelet_hf2_8 106 | fftwl_codelet_hf_3 107 | fftwl_codelet_hf_32 108 | fftwl_codelet_hf_4 109 | fftwl_codelet_hf_5 110 | fftwl_codelet_hf_6 111 | fftwl_codelet_hf_64 112 | fftwl_codelet_hf_7 113 | fftwl_codelet_hf_8 114 | fftwl_codelet_hf_9 115 | fftwl_codelet_n1_10 116 | fftwl_codelet_n1_11 117 | fftwl_codelet_n1_12 118 | fftwl_codelet_n1_13 119 | fftwl_codelet_n1_14 120 | fftwl_codelet_n1_15 121 | fftwl_codelet_n1_16 122 | fftwl_codelet_n1_2 123 | fftwl_codelet_n1_20 124 | fftwl_codelet_n1_25 125 | fftwl_codelet_n1_3 126 | fftwl_codelet_n1_32 127 | fftwl_codelet_n1_4 128 | fftwl_codelet_n1_5 129 | fftwl_codelet_n1_6 130 | fftwl_codelet_n1_64 131 | fftwl_codelet_n1_7 132 | fftwl_codelet_n1_8 133 | fftwl_codelet_n1_9 134 | fftwl_codelet_q1_2 135 | fftwl_codelet_q1_3 136 | fftwl_codelet_q1_4 137 | fftwl_codelet_q1_5 138 | fftwl_codelet_q1_6 139 | fftwl_codelet_q1_8 140 | fftwl_codelet_r2cb_10 141 | fftwl_codelet_r2cb_11 142 | fftwl_codelet_r2cb_12 143 | fftwl_codelet_r2cb_128 144 | fftwl_codelet_r2cb_13 145 | fftwl_codelet_r2cb_14 146 | fftwl_codelet_r2cb_15 147 | fftwl_codelet_r2cb_16 148 | fftwl_codelet_r2cb_2 149 | fftwl_codelet_r2cb_20 150 | fftwl_codelet_r2cb_25 151 | fftwl_codelet_r2cb_3 152 | fftwl_codelet_r2cb_32 153 | fftwl_codelet_r2cb_4 154 | fftwl_codelet_r2cb_5 155 | fftwl_codelet_r2cb_6 156 | fftwl_codelet_r2cb_64 157 | fftwl_codelet_r2cb_7 158 | fftwl_codelet_r2cb_8 159 | fftwl_codelet_r2cb_9 160 | fftwl_codelet_r2cbIII_10 161 | fftwl_codelet_r2cbIII_12 162 | fftwl_codelet_r2cbIII_15 163 | fftwl_codelet_r2cbIII_16 164 | fftwl_codelet_r2cbIII_2 165 | fftwl_codelet_r2cbIII_20 166 | fftwl_codelet_r2cbIII_25 167 | fftwl_codelet_r2cbIII_3 168 | fftwl_codelet_r2cbIII_32 169 | fftwl_codelet_r2cbIII_4 170 | fftwl_codelet_r2cbIII_5 171 | fftwl_codelet_r2cbIII_6 172 | fftwl_codelet_r2cbIII_64 173 | fftwl_codelet_r2cbIII_7 174 | fftwl_codelet_r2cbIII_8 175 | fftwl_codelet_r2cbIII_9 176 | fftwl_codelet_r2cf_10 177 | fftwl_codelet_r2cf_11 178 | fftwl_codelet_r2cf_12 179 | fftwl_codelet_r2cf_128 180 | fftwl_codelet_r2cf_13 181 | fftwl_codelet_r2cf_14 182 | fftwl_codelet_r2cf_15 183 | fftwl_codelet_r2cf_16 184 | fftwl_codelet_r2cf_2 185 | fftwl_codelet_r2cf_20 186 | fftwl_codelet_r2cf_25 187 | fftwl_codelet_r2cf_3 188 | fftwl_codelet_r2cf_32 189 | fftwl_codelet_r2cf_4 190 | fftwl_codelet_r2cf_5 191 | fftwl_codelet_r2cf_6 192 | fftwl_codelet_r2cf_64 193 | fftwl_codelet_r2cf_7 194 | fftwl_codelet_r2cf_8 195 | fftwl_codelet_r2cf_9 196 | fftwl_codelet_r2cfII_10 197 | fftwl_codelet_r2cfII_12 198 | fftwl_codelet_r2cfII_15 199 | fftwl_codelet_r2cfII_16 200 | fftwl_codelet_r2cfII_2 201 | fftwl_codelet_r2cfII_20 202 | fftwl_codelet_r2cfII_25 203 | fftwl_codelet_r2cfII_3 204 | fftwl_codelet_r2cfII_32 205 | fftwl_codelet_r2cfII_4 206 | fftwl_codelet_r2cfII_5 207 | fftwl_codelet_r2cfII_6 208 | fftwl_codelet_r2cfII_64 209 | fftwl_codelet_r2cfII_7 210 | fftwl_codelet_r2cfII_8 211 | fftwl_codelet_r2cfII_9 212 | fftwl_codelet_t1_10 213 | fftwl_codelet_t1_12 214 | fftwl_codelet_t1_15 215 | fftwl_codelet_t1_16 216 | fftwl_codelet_t1_2 217 | fftwl_codelet_t1_20 218 | fftwl_codelet_t1_25 219 | fftwl_codelet_t1_3 220 | fftwl_codelet_t1_32 221 | fftwl_codelet_t1_4 222 | fftwl_codelet_t1_5 223 | fftwl_codelet_t1_6 224 | fftwl_codelet_t1_64 225 | fftwl_codelet_t1_7 226 | fftwl_codelet_t1_8 227 | fftwl_codelet_t1_9 228 | fftwl_codelet_t2_10 229 | fftwl_codelet_t2_16 230 | fftwl_codelet_t2_20 231 | fftwl_codelet_t2_25 232 | fftwl_codelet_t2_32 233 | fftwl_codelet_t2_4 234 | fftwl_codelet_t2_5 235 | fftwl_codelet_t2_64 236 | fftwl_codelet_t2_8 237 | fftwl_compute_tilesz 238 | fftwl_configure_planner 239 | fftwl_cost 240 | fftwl_cpy1d 241 | fftwl_cpy2d 242 | fftwl_cpy2d_ci 243 | fftwl_cpy2d_co 244 | fftwl_cpy2d_pair 245 | fftwl_cpy2d_pair_ci 246 | fftwl_cpy2d_pair_co 247 | fftwl_cpy2d_tiled 248 | fftwl_cpy2d_tiledbuf 249 | fftwl_ct_applicable 250 | fftwl_ct_genericbuf_register 251 | fftwl_ct_generic_register 252 | fftwl_ct_uglyp 253 | fftwl_destroy_plan 254 | fftwl_dft_bluestein_register 255 | fftwl_dft_buffered_register 256 | fftwl_dft_conf_standard 257 | fftwl_dft_generic_register 258 | fftwl_dft_indirect_register 259 | fftwl_dft_indirect_transpose_register 260 | fftwl_dft_nop_register 261 | fftwl_dft_r2hc_register 262 | fftwl_dft_rader_register 263 | fftwl_dft_rank_geq2_register 264 | fftwl_dft_solve 265 | fftwl_dft_thr_vrank_geq1_register 266 | fftwl_dft_vrank_geq1_register 267 | fftwl_dft_zerotens 268 | fftwl_dht_r2hc_register 269 | fftwl_dht_rader_register 270 | fftwl_dimcmp 271 | fftwl_elapsed_since 272 | fftwl_estimate_cost 273 | fftwl_execute 274 | fftwl_execute_dft 275 | fftwl_execute_dft_c2r 276 | fftwl_execute_dft_r2c 277 | fftwl_execute_r2r 278 | fftwl_execute_split_dft 279 | fftwl_execute_split_dft_c2r 280 | fftwl_execute_split_dft_r2c 281 | fftwl_export_wisdom 282 | fftwl_export_wisdom_to_file 283 | fftwl_export_wisdom_to_filename 284 | fftwl_export_wisdom_to_string 285 | fftwl_extract_reim 286 | fftwl_factors_into 287 | fftwl_factors_into_small_primes 288 | fftwl_find_generator 289 | fftwl_first_divisor 290 | fftwl_flops 291 | fftwl_forget_wisdom 292 | fftwl_fprint_plan 293 | fftwl_free 294 | fftwl_get_crude_time 295 | fftwl_guru64_kosherp 296 | fftwl_guru_kosherp 297 | fftwl_hash 298 | fftwl_hc2hc_applicable 299 | fftwl_hc2hc_generic_register 300 | fftwl_iabs 301 | fftwl_ialignment_of 302 | fftwl_iestimate_cost 303 | fftwl_ifree 304 | fftwl_ifree0 305 | fftwl_imax 306 | fftwl_imin 307 | fftwl_import_system_wisdom 308 | fftwl_import_wisdom 309 | fftwl_import_wisdom_from_file 310 | fftwl_import_wisdom_from_filename 311 | fftwl_import_wisdom_from_string 312 | fftwl_init_threads 313 | fftwl_is_prime 314 | fftwl_isqrt 315 | fftwl_ithreads_init 316 | fftwl_kdft_dif_register 317 | fftwl_kdft_difsq_register 318 | fftwl_kdft_dit_register 319 | fftwl_kdft_register 320 | fftwl_kernel_free 321 | fftwl_kernel_malloc 322 | fftwl_khc2c_register 323 | fftwl_khc2hc_register 324 | fftwl_kr2c_register 325 | fftwl_kr2r_register 326 | fftwl_make_planner_thread_safe 327 | fftwl_malloc 328 | fftwl_malloc_plain 329 | fftwl_many_kosherp 330 | fftwl_mapflags 331 | fftwl_map_r2r_kind 332 | fftwl_md5begin 333 | fftwl_md5end 334 | fftwl_md5int 335 | fftwl_md5INT 336 | fftwl_md5putb 337 | fftwl_md5putc 338 | fftwl_md5puts 339 | fftwl_md5unsigned 340 | fftwl_measure_execution_time 341 | fftwl_mkapiplan 342 | fftwl_mkplan 343 | fftwl_mkplan_d 344 | fftwl_mkplan_dft 345 | fftwl_mkplan_dftw 346 | fftwl_mkplan_f_d 347 | fftwl_mkplan_hc2c 348 | fftwl_mkplan_hc2hc 349 | fftwl_mkplanner 350 | fftwl_mkplan_rdft 351 | fftwl_mkplan_rdft2 352 | fftwl_mkprinter 353 | fftwl_mkprinter_cnt 354 | fftwl_mkprinter_file 355 | fftwl_mkprinter_str 356 | fftwl_mkproblem 357 | fftwl_mkproblem_dft 358 | fftwl_mkproblem_dft_d 359 | fftwl_mkproblem_rdft 360 | fftwl_mkproblem_rdft_0_d 361 | fftwl_mkproblem_rdft_1 362 | fftwl_mkproblem_rdft_1_d 363 | fftwl_mkproblem_rdft2 364 | fftwl_mkproblem_rdft2_d 365 | fftwl_mkproblem_rdft2_d_3pointers 366 | fftwl_mkproblem_rdft_d 367 | fftwl_mkproblem_unsolvable 368 | fftwl_mkscanner 369 | fftwl_mksolver 370 | fftwl_mksolver_ct 371 | fftwl_mksolver_ct_threads 372 | fftwl_mksolver_dft_direct 373 | fftwl_mksolver_dft_directbuf 374 | fftwl_mksolver_hc2c 375 | fftwl_mksolver_hc2hc 376 | fftwl_mksolver_hc2hc_threads 377 | fftwl_mksolver_rdft2_direct 378 | fftwl_mksolver_rdft_r2c_direct 379 | fftwl_mksolver_rdft_r2c_directbuf 380 | fftwl_mksolver_rdft_r2r_direct 381 | fftwl_mktensor 382 | fftwl_mktensor_0d 383 | fftwl_mktensor_1d 384 | fftwl_mktensor_2d 385 | fftwl_mktensor_3d 386 | fftwl_mktensor_4d 387 | fftwl_mktensor_5d 388 | fftwl_mktensor_iodims 389 | fftwl_mktensor_iodims64 390 | fftwl_mktensor_rowmajor 391 | fftwl_mktriggen 392 | fftwl_modulo 393 | fftwl_nbuf 394 | fftwl_nbuf_redundant 395 | fftwl_next_prime 396 | fftwl_null_awake 397 | fftwl_ops_add 398 | fftwl_ops_add2 399 | fftwl_ops_cpy 400 | fftwl_ops_madd 401 | fftwl_ops_madd2 402 | fftwl_ops_other 403 | fftwl_ops_zero 404 | fftwl_pickdim 405 | fftwl_plan_awake 406 | fftwl_plan_destroy_internal 407 | fftwl_plan_dft 408 | fftwl_plan_dft_1d 409 | fftwl_plan_dft_2d 410 | fftwl_plan_dft_3d 411 | fftwl_plan_dft_c2r 412 | fftwl_plan_dft_c2r_1d 413 | fftwl_plan_dft_c2r_2d 414 | fftwl_plan_dft_c2r_3d 415 | fftwl_plan_dft_r2c 416 | fftwl_plan_dft_r2c_1d 417 | fftwl_plan_dft_r2c_2d 418 | fftwl_plan_dft_r2c_3d 419 | fftwl_plan_guru64_dft 420 | fftwl_plan_guru64_dft_c2r 421 | fftwl_plan_guru64_dft_r2c 422 | fftwl_plan_guru64_r2r 423 | fftwl_plan_guru64_split_dft 424 | fftwl_plan_guru64_split_dft_c2r 425 | fftwl_plan_guru64_split_dft_r2c 426 | fftwl_plan_guru_dft 427 | fftwl_plan_guru_dft_c2r 428 | fftwl_plan_guru_dft_r2c 429 | fftwl_plan_guru_r2r 430 | fftwl_plan_guru_split_dft 431 | fftwl_plan_guru_split_dft_c2r 432 | fftwl_plan_guru_split_dft_r2c 433 | fftwl_plan_many_dft 434 | fftwl_plan_many_dft_c2r 435 | fftwl_plan_many_dft_r2c 436 | fftwl_plan_many_r2r 437 | fftwl_planner_destroy 438 | fftwl_plan_null_destroy 439 | fftwl_plan_r2r 440 | fftwl_plan_r2r_1d 441 | fftwl_plan_r2r_2d 442 | fftwl_plan_r2r_3d 443 | fftwl_plan_with_nthreads 444 | fftwl_power_mod 445 | fftwl_printer_destroy 446 | fftwl_print_plan 447 | fftwl_problem_destroy 448 | fftwl_rader_tl_delete 449 | fftwl_rader_tl_find 450 | fftwl_rader_tl_insert 451 | fftwl_rdft2_buffered_register 452 | fftwl_rdft2_complex_n 453 | fftwl_rdft2_inplace_strides 454 | fftwl_rdft2_nop_register 455 | fftwl_rdft2_pad 456 | fftwl_rdft2_rank0_register 457 | fftwl_rdft2_rank_geq2_register 458 | fftwl_rdft2_rdft_register 459 | fftwl_rdft2_solve 460 | fftwl_rdft2_strides 461 | fftwl_rdft2_tensor_max_index 462 | fftwl_rdft2_thr_vrank_geq1_register 463 | fftwl_rdft2_vrank_geq1_register 464 | fftwl_rdft_buffered_register 465 | fftwl_rdft_conf_standard 466 | fftwl_rdft_dht_register 467 | fftwl_rdft_generic_register 468 | fftwl_rdft_indirect_register 469 | fftwl_rdft_kind_str 470 | fftwl_rdft_nop_register 471 | fftwl_rdft_rank0_register 472 | fftwl_rdft_rank_geq2_register 473 | fftwl_rdft_solve 474 | fftwl_rdft_thr_vrank_geq1_register 475 | fftwl_rdft_vrank3_transpose_register 476 | fftwl_rdft_vrank_geq1_register 477 | fftwl_rdft_zerotens 478 | fftwl_redft00e_r2hc_pad_register 479 | fftwl_regsolver_ct_directw 480 | fftwl_regsolver_ct_directwsq 481 | fftwl_regsolver_hc2c_direct 482 | fftwl_regsolver_hc2hc_direct 483 | fftwl_reodft00e_splitradix_register 484 | fftwl_reodft010e_r2hc_register 485 | fftwl_reodft11e_r2hc_odd_register 486 | fftwl_reodft11e_radix2_r2hc_register 487 | fftwl_reodft_conf_standard 488 | fftwl_rodft00e_r2hc_pad_register 489 | fftwl_safe_mulmod 490 | fftwl_scanner_destroy 491 | fftwl_set_planner_hooks 492 | fftwl_set_timelimit 493 | fftwl_solver_destroy 494 | fftwl_solver_register 495 | fftwl_solver_use 496 | fftwl_solvtab_exec 497 | fftwl_spawn_loop 498 | fftwl_sprint_plan 499 | fftwl_tensor_append 500 | fftwl_tensor_compress 501 | fftwl_tensor_compress_contiguous 502 | fftwl_tensor_copy 503 | fftwl_tensor_copy_except 504 | fftwl_tensor_copy_inplace 505 | fftwl_tensor_copy_sub 506 | fftwl_tensor_destroy 507 | fftwl_tensor_destroy2 508 | fftwl_tensor_destroy4 509 | fftwl_tensor_equal 510 | fftwl_tensor_inplace_locations 511 | fftwl_tensor_inplace_strides 512 | fftwl_tensor_inplace_strides2 513 | fftwl_tensor_kosherp 514 | fftwl_tensor_max_index 515 | fftwl_tensor_md5 516 | fftwl_tensor_min_istride 517 | fftwl_tensor_min_ostride 518 | fftwl_tensor_min_stride 519 | fftwl_tensor_print 520 | fftwl_tensor_split 521 | fftwl_tensor_strides_decrease 522 | fftwl_tensor_sz 523 | fftwl_tensor_tornk1 524 | fftwl_the_planner 525 | fftwl_threads_cleanup 526 | fftwl_threads_conf_standard 527 | fftwl_threads_register_planner_hooks 528 | fftwl_tile2d 529 | fftwl_toobig 530 | fftwl_transpose 531 | fftwl_transpose_tiled 532 | fftwl_transpose_tiledbuf 533 | fftwl_triggen_destroy 534 | fftwl_twiddle_awake 535 | fftwl_twiddle_length 536 | fftwl_zero1d_pair 537 | lfftw_cleanup_ 538 | lfftw_cleanup__ 539 | lfftw_cleanup_threads_ 540 | lfftw_cleanup_threads__ 541 | lfftw_cost_ 542 | lfftw_cost__ 543 | lfftw_destroy_plan_ 544 | lfftw_destroy_plan__ 545 | lfftw_estimate_cost_ 546 | lfftw_estimate_cost__ 547 | lfftw_execute_ 548 | lfftw_execute__ 549 | lfftw_execute_dft_ 550 | lfftw_execute_dft__ 551 | lfftw_execute_dft_c2r_ 552 | lfftw_execute_dft_c2r__ 553 | lfftw_execute_dft_r2c_ 554 | lfftw_execute_dft_r2c__ 555 | lfftw_execute_r2r_ 556 | lfftw_execute_r2r__ 557 | lfftw_execute_split_dft_ 558 | lfftw_execute_split_dft__ 559 | lfftw_execute_split_dft_c2r_ 560 | lfftw_execute_split_dft_c2r__ 561 | lfftw_execute_split_dft_r2c_ 562 | lfftw_execute_split_dft_r2c__ 563 | lfftw_export_wisdom_ 564 | lfftw_export_wisdom__ 565 | lfftw_flops_ 566 | lfftw_flops__ 567 | lfftw_forget_wisdom_ 568 | lfftw_forget_wisdom__ 569 | lfftw_import_system_wisdom_ 570 | lfftw_import_system_wisdom__ 571 | lfftw_import_wisdom_ 572 | lfftw_import_wisdom__ 573 | lfftw_init_threads_ 574 | lfftw_init_threads__ 575 | lfftw_plan_dft_ 576 | lfftw_plan_dft__ 577 | lfftw_plan_dft_1d_ 578 | lfftw_plan_dft_1d__ 579 | lfftw_plan_dft_2d_ 580 | lfftw_plan_dft_2d__ 581 | lfftw_plan_dft_3d_ 582 | lfftw_plan_dft_3d__ 583 | lfftw_plan_dft_c2r_ 584 | lfftw_plan_dft_c2r__ 585 | lfftw_plan_dft_c2r_1d_ 586 | lfftw_plan_dft_c2r_1d__ 587 | lfftw_plan_dft_c2r_2d_ 588 | lfftw_plan_dft_c2r_2d__ 589 | lfftw_plan_dft_c2r_3d_ 590 | lfftw_plan_dft_c2r_3d__ 591 | lfftw_plan_dft_r2c_ 592 | lfftw_plan_dft_r2c__ 593 | lfftw_plan_dft_r2c_1d_ 594 | lfftw_plan_dft_r2c_1d__ 595 | lfftw_plan_dft_r2c_2d_ 596 | lfftw_plan_dft_r2c_2d__ 597 | lfftw_plan_dft_r2c_3d_ 598 | lfftw_plan_dft_r2c_3d__ 599 | lfftw_plan_guru_dft_ 600 | lfftw_plan_guru_dft__ 601 | lfftw_plan_guru_dft_c2r_ 602 | lfftw_plan_guru_dft_c2r__ 603 | lfftw_plan_guru_dft_r2c_ 604 | lfftw_plan_guru_dft_r2c__ 605 | lfftw_plan_guru_r2r_ 606 | lfftw_plan_guru_r2r__ 607 | lfftw_plan_guru_split_dft_ 608 | lfftw_plan_guru_split_dft__ 609 | lfftw_plan_guru_split_dft_c2r_ 610 | lfftw_plan_guru_split_dft_c2r__ 611 | lfftw_plan_guru_split_dft_r2c_ 612 | lfftw_plan_guru_split_dft_r2c__ 613 | lfftw_plan_many_dft_ 614 | lfftw_plan_many_dft__ 615 | lfftw_plan_many_dft_c2r_ 616 | lfftw_plan_many_dft_c2r__ 617 | lfftw_plan_many_dft_r2c_ 618 | lfftw_plan_many_dft_r2c__ 619 | lfftw_plan_many_r2r_ 620 | lfftw_plan_many_r2r__ 621 | lfftw_plan_r2r_ 622 | lfftw_plan_r2r__ 623 | lfftw_plan_r2r_1d_ 624 | lfftw_plan_r2r_1d__ 625 | lfftw_plan_r2r_2d_ 626 | lfftw_plan_r2r_2d__ 627 | lfftw_plan_r2r_3d_ 628 | lfftw_plan_r2r_3d__ 629 | lfftw_plan_with_nthreads_ 630 | lfftw_plan_with_nthreads__ 631 | lfftw_print_plan_ 632 | lfftw_print_plan__ 633 | lfftw_set_timelimit_ 634 | lfftw_set_timelimit__ 635 | -------------------------------------------------------------------------------- /fftw/win32/libfftw3l-3.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacobjma/PyQSTEM/9172962b9ed51769a97c90278f463af3ec89181e/fftw/win32/libfftw3l-3.dll -------------------------------------------------------------------------------- /fftw/win32/libfftw3l-3.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacobjma/PyQSTEM/9172962b9ed51769a97c90278f463af3ec89181e/fftw/win32/libfftw3l-3.exp -------------------------------------------------------------------------------- /fftw/win32/libfftw3l-3.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacobjma/PyQSTEM/9172962b9ed51769a97c90278f463af3ec89181e/fftw/win32/libfftw3l-3.lib -------------------------------------------------------------------------------- /fftw/win64/libfftw3-3.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacobjma/PyQSTEM/9172962b9ed51769a97c90278f463af3ec89181e/fftw/win64/libfftw3-3.dll -------------------------------------------------------------------------------- /fftw/win64/libfftw3-3.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacobjma/PyQSTEM/9172962b9ed51769a97c90278f463af3ec89181e/fftw/win64/libfftw3-3.exp -------------------------------------------------------------------------------- /fftw/win64/libfftw3-3.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacobjma/PyQSTEM/9172962b9ed51769a97c90278f463af3ec89181e/fftw/win64/libfftw3-3.lib -------------------------------------------------------------------------------- /fftw/win64/libfftw3f-3.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacobjma/PyQSTEM/9172962b9ed51769a97c90278f463af3ec89181e/fftw/win64/libfftw3f-3.dll -------------------------------------------------------------------------------- /fftw/win64/libfftw3f-3.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacobjma/PyQSTEM/9172962b9ed51769a97c90278f463af3ec89181e/fftw/win64/libfftw3f-3.exp -------------------------------------------------------------------------------- /fftw/win64/libfftw3f-3.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacobjma/PyQSTEM/9172962b9ed51769a97c90278f463af3ec89181e/fftw/win64/libfftw3f-3.lib -------------------------------------------------------------------------------- /fftw/win64/libfftw3l-3.def: -------------------------------------------------------------------------------- 1 | LIBRARY libfftw3l-3.dll 2 | EXPORTS 3 | fftwl_alignment_of 4 | fftwl_alloc_complex 5 | fftwl_alloc_real 6 | fftwl_assertion_failed 7 | fftwl_bufdist 8 | fftwl_choose_radix 9 | fftwl_cleanup 10 | fftwl_cleanup_threads 11 | fftwl_codelet_e01_8 12 | fftwl_codelet_e10_8 13 | fftwl_codelet_hb_10 14 | fftwl_codelet_hb_12 15 | fftwl_codelet_hb_15 16 | fftwl_codelet_hb_16 17 | fftwl_codelet_hb_2 18 | fftwl_codelet_hb_20 19 | fftwl_codelet_hb2_16 20 | fftwl_codelet_hb2_20 21 | fftwl_codelet_hb2_25 22 | fftwl_codelet_hb2_32 23 | fftwl_codelet_hb2_4 24 | fftwl_codelet_hb_25 25 | fftwl_codelet_hb2_5 26 | fftwl_codelet_hb2_8 27 | fftwl_codelet_hb_3 28 | fftwl_codelet_hb_32 29 | fftwl_codelet_hb_4 30 | fftwl_codelet_hb_5 31 | fftwl_codelet_hb_6 32 | fftwl_codelet_hb_64 33 | fftwl_codelet_hb_7 34 | fftwl_codelet_hb_8 35 | fftwl_codelet_hb_9 36 | fftwl_codelet_hc2cb_10 37 | fftwl_codelet_hc2cb_12 38 | fftwl_codelet_hc2cb_16 39 | fftwl_codelet_hc2cb_2 40 | fftwl_codelet_hc2cb_20 41 | fftwl_codelet_hc2cb2_16 42 | fftwl_codelet_hc2cb2_20 43 | fftwl_codelet_hc2cb2_32 44 | fftwl_codelet_hc2cb2_4 45 | fftwl_codelet_hc2cb2_8 46 | fftwl_codelet_hc2cb_32 47 | fftwl_codelet_hc2cb_4 48 | fftwl_codelet_hc2cb_6 49 | fftwl_codelet_hc2cb_8 50 | fftwl_codelet_hc2cbdft_10 51 | fftwl_codelet_hc2cbdft_12 52 | fftwl_codelet_hc2cbdft_16 53 | fftwl_codelet_hc2cbdft_2 54 | fftwl_codelet_hc2cbdft_20 55 | fftwl_codelet_hc2cbdft2_16 56 | fftwl_codelet_hc2cbdft2_20 57 | fftwl_codelet_hc2cbdft2_32 58 | fftwl_codelet_hc2cbdft2_4 59 | fftwl_codelet_hc2cbdft2_8 60 | fftwl_codelet_hc2cbdft_32 61 | fftwl_codelet_hc2cbdft_4 62 | fftwl_codelet_hc2cbdft_6 63 | fftwl_codelet_hc2cbdft_8 64 | fftwl_codelet_hc2cf_10 65 | fftwl_codelet_hc2cf_12 66 | fftwl_codelet_hc2cf_16 67 | fftwl_codelet_hc2cf_2 68 | fftwl_codelet_hc2cf_20 69 | fftwl_codelet_hc2cf2_16 70 | fftwl_codelet_hc2cf2_20 71 | fftwl_codelet_hc2cf2_32 72 | fftwl_codelet_hc2cf2_4 73 | fftwl_codelet_hc2cf2_8 74 | fftwl_codelet_hc2cf_32 75 | fftwl_codelet_hc2cf_4 76 | fftwl_codelet_hc2cf_6 77 | fftwl_codelet_hc2cf_8 78 | fftwl_codelet_hc2cfdft_10 79 | fftwl_codelet_hc2cfdft_12 80 | fftwl_codelet_hc2cfdft_16 81 | fftwl_codelet_hc2cfdft_2 82 | fftwl_codelet_hc2cfdft_20 83 | fftwl_codelet_hc2cfdft2_16 84 | fftwl_codelet_hc2cfdft2_20 85 | fftwl_codelet_hc2cfdft2_32 86 | fftwl_codelet_hc2cfdft2_4 87 | fftwl_codelet_hc2cfdft2_8 88 | fftwl_codelet_hc2cfdft_32 89 | fftwl_codelet_hc2cfdft_4 90 | fftwl_codelet_hc2cfdft_6 91 | fftwl_codelet_hc2cfdft_8 92 | fftwl_codelet_hf_10 93 | fftwl_codelet_hf_12 94 | fftwl_codelet_hf_15 95 | fftwl_codelet_hf_16 96 | fftwl_codelet_hf_2 97 | fftwl_codelet_hf_20 98 | fftwl_codelet_hf2_16 99 | fftwl_codelet_hf2_20 100 | fftwl_codelet_hf2_25 101 | fftwl_codelet_hf2_32 102 | fftwl_codelet_hf2_4 103 | fftwl_codelet_hf_25 104 | fftwl_codelet_hf2_5 105 | fftwl_codelet_hf2_8 106 | fftwl_codelet_hf_3 107 | fftwl_codelet_hf_32 108 | fftwl_codelet_hf_4 109 | fftwl_codelet_hf_5 110 | fftwl_codelet_hf_6 111 | fftwl_codelet_hf_64 112 | fftwl_codelet_hf_7 113 | fftwl_codelet_hf_8 114 | fftwl_codelet_hf_9 115 | fftwl_codelet_n1_10 116 | fftwl_codelet_n1_11 117 | fftwl_codelet_n1_12 118 | fftwl_codelet_n1_13 119 | fftwl_codelet_n1_14 120 | fftwl_codelet_n1_15 121 | fftwl_codelet_n1_16 122 | fftwl_codelet_n1_2 123 | fftwl_codelet_n1_20 124 | fftwl_codelet_n1_25 125 | fftwl_codelet_n1_3 126 | fftwl_codelet_n1_32 127 | fftwl_codelet_n1_4 128 | fftwl_codelet_n1_5 129 | fftwl_codelet_n1_6 130 | fftwl_codelet_n1_64 131 | fftwl_codelet_n1_7 132 | fftwl_codelet_n1_8 133 | fftwl_codelet_n1_9 134 | fftwl_codelet_q1_2 135 | fftwl_codelet_q1_3 136 | fftwl_codelet_q1_4 137 | fftwl_codelet_q1_5 138 | fftwl_codelet_q1_6 139 | fftwl_codelet_q1_8 140 | fftwl_codelet_r2cb_10 141 | fftwl_codelet_r2cb_11 142 | fftwl_codelet_r2cb_12 143 | fftwl_codelet_r2cb_128 144 | fftwl_codelet_r2cb_13 145 | fftwl_codelet_r2cb_14 146 | fftwl_codelet_r2cb_15 147 | fftwl_codelet_r2cb_16 148 | fftwl_codelet_r2cb_2 149 | fftwl_codelet_r2cb_20 150 | fftwl_codelet_r2cb_25 151 | fftwl_codelet_r2cb_3 152 | fftwl_codelet_r2cb_32 153 | fftwl_codelet_r2cb_4 154 | fftwl_codelet_r2cb_5 155 | fftwl_codelet_r2cb_6 156 | fftwl_codelet_r2cb_64 157 | fftwl_codelet_r2cb_7 158 | fftwl_codelet_r2cb_8 159 | fftwl_codelet_r2cb_9 160 | fftwl_codelet_r2cbIII_10 161 | fftwl_codelet_r2cbIII_12 162 | fftwl_codelet_r2cbIII_15 163 | fftwl_codelet_r2cbIII_16 164 | fftwl_codelet_r2cbIII_2 165 | fftwl_codelet_r2cbIII_20 166 | fftwl_codelet_r2cbIII_25 167 | fftwl_codelet_r2cbIII_3 168 | fftwl_codelet_r2cbIII_32 169 | fftwl_codelet_r2cbIII_4 170 | fftwl_codelet_r2cbIII_5 171 | fftwl_codelet_r2cbIII_6 172 | fftwl_codelet_r2cbIII_64 173 | fftwl_codelet_r2cbIII_7 174 | fftwl_codelet_r2cbIII_8 175 | fftwl_codelet_r2cbIII_9 176 | fftwl_codelet_r2cf_10 177 | fftwl_codelet_r2cf_11 178 | fftwl_codelet_r2cf_12 179 | fftwl_codelet_r2cf_128 180 | fftwl_codelet_r2cf_13 181 | fftwl_codelet_r2cf_14 182 | fftwl_codelet_r2cf_15 183 | fftwl_codelet_r2cf_16 184 | fftwl_codelet_r2cf_2 185 | fftwl_codelet_r2cf_20 186 | fftwl_codelet_r2cf_25 187 | fftwl_codelet_r2cf_3 188 | fftwl_codelet_r2cf_32 189 | fftwl_codelet_r2cf_4 190 | fftwl_codelet_r2cf_5 191 | fftwl_codelet_r2cf_6 192 | fftwl_codelet_r2cf_64 193 | fftwl_codelet_r2cf_7 194 | fftwl_codelet_r2cf_8 195 | fftwl_codelet_r2cf_9 196 | fftwl_codelet_r2cfII_10 197 | fftwl_codelet_r2cfII_12 198 | fftwl_codelet_r2cfII_15 199 | fftwl_codelet_r2cfII_16 200 | fftwl_codelet_r2cfII_2 201 | fftwl_codelet_r2cfII_20 202 | fftwl_codelet_r2cfII_25 203 | fftwl_codelet_r2cfII_3 204 | fftwl_codelet_r2cfII_32 205 | fftwl_codelet_r2cfII_4 206 | fftwl_codelet_r2cfII_5 207 | fftwl_codelet_r2cfII_6 208 | fftwl_codelet_r2cfII_64 209 | fftwl_codelet_r2cfII_7 210 | fftwl_codelet_r2cfII_8 211 | fftwl_codelet_r2cfII_9 212 | fftwl_codelet_t1_10 213 | fftwl_codelet_t1_12 214 | fftwl_codelet_t1_15 215 | fftwl_codelet_t1_16 216 | fftwl_codelet_t1_2 217 | fftwl_codelet_t1_20 218 | fftwl_codelet_t1_25 219 | fftwl_codelet_t1_3 220 | fftwl_codelet_t1_32 221 | fftwl_codelet_t1_4 222 | fftwl_codelet_t1_5 223 | fftwl_codelet_t1_6 224 | fftwl_codelet_t1_64 225 | fftwl_codelet_t1_7 226 | fftwl_codelet_t1_8 227 | fftwl_codelet_t1_9 228 | fftwl_codelet_t2_10 229 | fftwl_codelet_t2_16 230 | fftwl_codelet_t2_20 231 | fftwl_codelet_t2_25 232 | fftwl_codelet_t2_32 233 | fftwl_codelet_t2_4 234 | fftwl_codelet_t2_5 235 | fftwl_codelet_t2_64 236 | fftwl_codelet_t2_8 237 | fftwl_compute_tilesz 238 | fftwl_configure_planner 239 | fftwl_cost 240 | fftwl_cpy1d 241 | fftwl_cpy2d 242 | fftwl_cpy2d_ci 243 | fftwl_cpy2d_co 244 | fftwl_cpy2d_pair 245 | fftwl_cpy2d_pair_ci 246 | fftwl_cpy2d_pair_co 247 | fftwl_cpy2d_tiled 248 | fftwl_cpy2d_tiledbuf 249 | fftwl_ct_applicable 250 | fftwl_ct_genericbuf_register 251 | fftwl_ct_generic_register 252 | fftwl_ct_uglyp 253 | fftwl_destroy_plan 254 | fftwl_dft_bluestein_register 255 | fftwl_dft_buffered_register 256 | fftwl_dft_conf_standard 257 | fftwl_dft_generic_register 258 | fftwl_dft_indirect_register 259 | fftwl_dft_indirect_transpose_register 260 | fftwl_dft_nop_register 261 | fftwl_dft_r2hc_register 262 | fftwl_dft_rader_register 263 | fftwl_dft_rank_geq2_register 264 | fftwl_dft_solve 265 | fftwl_dft_thr_vrank_geq1_register 266 | fftwl_dft_vrank_geq1_register 267 | fftwl_dft_zerotens 268 | fftwl_dht_r2hc_register 269 | fftwl_dht_rader_register 270 | fftwl_dimcmp 271 | fftwl_elapsed_since 272 | fftwl_estimate_cost 273 | fftwl_execute 274 | fftwl_execute_dft 275 | fftwl_execute_dft_c2r 276 | fftwl_execute_dft_r2c 277 | fftwl_execute_r2r 278 | fftwl_execute_split_dft 279 | fftwl_execute_split_dft_c2r 280 | fftwl_execute_split_dft_r2c 281 | fftwl_export_wisdom 282 | fftwl_export_wisdom_to_file 283 | fftwl_export_wisdom_to_filename 284 | fftwl_export_wisdom_to_string 285 | fftwl_extract_reim 286 | fftwl_factors_into 287 | fftwl_factors_into_small_primes 288 | fftwl_find_generator 289 | fftwl_first_divisor 290 | fftwl_flops 291 | fftwl_forget_wisdom 292 | fftwl_fprint_plan 293 | fftwl_free 294 | fftwl_get_crude_time 295 | fftwl_guru64_kosherp 296 | fftwl_guru_kosherp 297 | fftwl_hash 298 | fftwl_hc2hc_applicable 299 | fftwl_hc2hc_generic_register 300 | fftwl_iabs 301 | fftwl_ialignment_of 302 | fftwl_iestimate_cost 303 | fftwl_ifree 304 | fftwl_ifree0 305 | fftwl_imax 306 | fftwl_imin 307 | fftwl_import_system_wisdom 308 | fftwl_import_wisdom 309 | fftwl_import_wisdom_from_file 310 | fftwl_import_wisdom_from_filename 311 | fftwl_import_wisdom_from_string 312 | fftwl_init_threads 313 | fftwl_is_prime 314 | fftwl_isqrt 315 | fftwl_ithreads_init 316 | fftwl_kdft_dif_register 317 | fftwl_kdft_difsq_register 318 | fftwl_kdft_dit_register 319 | fftwl_kdft_register 320 | fftwl_kernel_free 321 | fftwl_kernel_malloc 322 | fftwl_khc2c_register 323 | fftwl_khc2hc_register 324 | fftwl_kr2c_register 325 | fftwl_kr2r_register 326 | fftwl_make_planner_thread_safe 327 | fftwl_malloc 328 | fftwl_malloc_plain 329 | fftwl_many_kosherp 330 | fftwl_mapflags 331 | fftwl_map_r2r_kind 332 | fftwl_md5begin 333 | fftwl_md5end 334 | fftwl_md5int 335 | fftwl_md5INT 336 | fftwl_md5putb 337 | fftwl_md5putc 338 | fftwl_md5puts 339 | fftwl_md5unsigned 340 | fftwl_measure_execution_time 341 | fftwl_mkapiplan 342 | fftwl_mkplan 343 | fftwl_mkplan_d 344 | fftwl_mkplan_dft 345 | fftwl_mkplan_dftw 346 | fftwl_mkplan_f_d 347 | fftwl_mkplan_hc2c 348 | fftwl_mkplan_hc2hc 349 | fftwl_mkplanner 350 | fftwl_mkplan_rdft 351 | fftwl_mkplan_rdft2 352 | fftwl_mkprinter 353 | fftwl_mkprinter_cnt 354 | fftwl_mkprinter_file 355 | fftwl_mkprinter_str 356 | fftwl_mkproblem 357 | fftwl_mkproblem_dft 358 | fftwl_mkproblem_dft_d 359 | fftwl_mkproblem_rdft 360 | fftwl_mkproblem_rdft_0_d 361 | fftwl_mkproblem_rdft_1 362 | fftwl_mkproblem_rdft_1_d 363 | fftwl_mkproblem_rdft2 364 | fftwl_mkproblem_rdft2_d 365 | fftwl_mkproblem_rdft2_d_3pointers 366 | fftwl_mkproblem_rdft_d 367 | fftwl_mkproblem_unsolvable 368 | fftwl_mkscanner 369 | fftwl_mksolver 370 | fftwl_mksolver_ct 371 | fftwl_mksolver_ct_threads 372 | fftwl_mksolver_dft_direct 373 | fftwl_mksolver_dft_directbuf 374 | fftwl_mksolver_hc2c 375 | fftwl_mksolver_hc2hc 376 | fftwl_mksolver_hc2hc_threads 377 | fftwl_mksolver_rdft2_direct 378 | fftwl_mksolver_rdft_r2c_direct 379 | fftwl_mksolver_rdft_r2c_directbuf 380 | fftwl_mksolver_rdft_r2r_direct 381 | fftwl_mktensor 382 | fftwl_mktensor_0d 383 | fftwl_mktensor_1d 384 | fftwl_mktensor_2d 385 | fftwl_mktensor_3d 386 | fftwl_mktensor_4d 387 | fftwl_mktensor_5d 388 | fftwl_mktensor_iodims 389 | fftwl_mktensor_iodims64 390 | fftwl_mktensor_rowmajor 391 | fftwl_mktriggen 392 | fftwl_modulo 393 | fftwl_nbuf 394 | fftwl_nbuf_redundant 395 | fftwl_next_prime 396 | fftwl_null_awake 397 | fftwl_ops_add 398 | fftwl_ops_add2 399 | fftwl_ops_cpy 400 | fftwl_ops_madd 401 | fftwl_ops_madd2 402 | fftwl_ops_other 403 | fftwl_ops_zero 404 | fftwl_pickdim 405 | fftwl_plan_awake 406 | fftwl_plan_destroy_internal 407 | fftwl_plan_dft 408 | fftwl_plan_dft_1d 409 | fftwl_plan_dft_2d 410 | fftwl_plan_dft_3d 411 | fftwl_plan_dft_c2r 412 | fftwl_plan_dft_c2r_1d 413 | fftwl_plan_dft_c2r_2d 414 | fftwl_plan_dft_c2r_3d 415 | fftwl_plan_dft_r2c 416 | fftwl_plan_dft_r2c_1d 417 | fftwl_plan_dft_r2c_2d 418 | fftwl_plan_dft_r2c_3d 419 | fftwl_plan_guru64_dft 420 | fftwl_plan_guru64_dft_c2r 421 | fftwl_plan_guru64_dft_r2c 422 | fftwl_plan_guru64_r2r 423 | fftwl_plan_guru64_split_dft 424 | fftwl_plan_guru64_split_dft_c2r 425 | fftwl_plan_guru64_split_dft_r2c 426 | fftwl_plan_guru_dft 427 | fftwl_plan_guru_dft_c2r 428 | fftwl_plan_guru_dft_r2c 429 | fftwl_plan_guru_r2r 430 | fftwl_plan_guru_split_dft 431 | fftwl_plan_guru_split_dft_c2r 432 | fftwl_plan_guru_split_dft_r2c 433 | fftwl_plan_many_dft 434 | fftwl_plan_many_dft_c2r 435 | fftwl_plan_many_dft_r2c 436 | fftwl_plan_many_r2r 437 | fftwl_planner_destroy 438 | fftwl_plan_null_destroy 439 | fftwl_plan_r2r 440 | fftwl_plan_r2r_1d 441 | fftwl_plan_r2r_2d 442 | fftwl_plan_r2r_3d 443 | fftwl_plan_with_nthreads 444 | fftwl_power_mod 445 | fftwl_printer_destroy 446 | fftwl_print_plan 447 | fftwl_problem_destroy 448 | fftwl_rader_tl_delete 449 | fftwl_rader_tl_find 450 | fftwl_rader_tl_insert 451 | fftwl_rdft2_buffered_register 452 | fftwl_rdft2_complex_n 453 | fftwl_rdft2_inplace_strides 454 | fftwl_rdft2_nop_register 455 | fftwl_rdft2_pad 456 | fftwl_rdft2_rank0_register 457 | fftwl_rdft2_rank_geq2_register 458 | fftwl_rdft2_rdft_register 459 | fftwl_rdft2_solve 460 | fftwl_rdft2_strides 461 | fftwl_rdft2_tensor_max_index 462 | fftwl_rdft2_thr_vrank_geq1_register 463 | fftwl_rdft2_vrank_geq1_register 464 | fftwl_rdft_buffered_register 465 | fftwl_rdft_conf_standard 466 | fftwl_rdft_dht_register 467 | fftwl_rdft_generic_register 468 | fftwl_rdft_indirect_register 469 | fftwl_rdft_kind_str 470 | fftwl_rdft_nop_register 471 | fftwl_rdft_rank0_register 472 | fftwl_rdft_rank_geq2_register 473 | fftwl_rdft_solve 474 | fftwl_rdft_thr_vrank_geq1_register 475 | fftwl_rdft_vrank3_transpose_register 476 | fftwl_rdft_vrank_geq1_register 477 | fftwl_rdft_zerotens 478 | fftwl_redft00e_r2hc_pad_register 479 | fftwl_regsolver_ct_directw 480 | fftwl_regsolver_ct_directwsq 481 | fftwl_regsolver_hc2c_direct 482 | fftwl_regsolver_hc2hc_direct 483 | fftwl_reodft00e_splitradix_register 484 | fftwl_reodft010e_r2hc_register 485 | fftwl_reodft11e_r2hc_odd_register 486 | fftwl_reodft11e_radix2_r2hc_register 487 | fftwl_reodft_conf_standard 488 | fftwl_rodft00e_r2hc_pad_register 489 | fftwl_safe_mulmod 490 | fftwl_scanner_destroy 491 | fftwl_set_planner_hooks 492 | fftwl_set_timelimit 493 | fftwl_solver_destroy 494 | fftwl_solver_register 495 | fftwl_solver_use 496 | fftwl_solvtab_exec 497 | fftwl_spawn_loop 498 | fftwl_sprint_plan 499 | fftwl_tensor_append 500 | fftwl_tensor_compress 501 | fftwl_tensor_compress_contiguous 502 | fftwl_tensor_copy 503 | fftwl_tensor_copy_except 504 | fftwl_tensor_copy_inplace 505 | fftwl_tensor_copy_sub 506 | fftwl_tensor_destroy 507 | fftwl_tensor_destroy2 508 | fftwl_tensor_destroy4 509 | fftwl_tensor_equal 510 | fftwl_tensor_inplace_locations 511 | fftwl_tensor_inplace_strides 512 | fftwl_tensor_inplace_strides2 513 | fftwl_tensor_kosherp 514 | fftwl_tensor_max_index 515 | fftwl_tensor_md5 516 | fftwl_tensor_min_istride 517 | fftwl_tensor_min_ostride 518 | fftwl_tensor_min_stride 519 | fftwl_tensor_print 520 | fftwl_tensor_split 521 | fftwl_tensor_strides_decrease 522 | fftwl_tensor_sz 523 | fftwl_tensor_tornk1 524 | fftwl_the_planner 525 | fftwl_threads_cleanup 526 | fftwl_threads_conf_standard 527 | fftwl_threads_register_planner_hooks 528 | fftwl_tile2d 529 | fftwl_toobig 530 | fftwl_transpose 531 | fftwl_transpose_tiled 532 | fftwl_transpose_tiledbuf 533 | fftwl_triggen_destroy 534 | fftwl_twiddle_awake 535 | fftwl_twiddle_length 536 | fftwl_zero1d_pair 537 | lfftw_cleanup_ 538 | lfftw_cleanup__ 539 | lfftw_cleanup_threads_ 540 | lfftw_cleanup_threads__ 541 | lfftw_cost_ 542 | lfftw_cost__ 543 | lfftw_destroy_plan_ 544 | lfftw_destroy_plan__ 545 | lfftw_estimate_cost_ 546 | lfftw_estimate_cost__ 547 | lfftw_execute_ 548 | lfftw_execute__ 549 | lfftw_execute_dft_ 550 | lfftw_execute_dft__ 551 | lfftw_execute_dft_c2r_ 552 | lfftw_execute_dft_c2r__ 553 | lfftw_execute_dft_r2c_ 554 | lfftw_execute_dft_r2c__ 555 | lfftw_execute_r2r_ 556 | lfftw_execute_r2r__ 557 | lfftw_execute_split_dft_ 558 | lfftw_execute_split_dft__ 559 | lfftw_execute_split_dft_c2r_ 560 | lfftw_execute_split_dft_c2r__ 561 | lfftw_execute_split_dft_r2c_ 562 | lfftw_execute_split_dft_r2c__ 563 | lfftw_export_wisdom_ 564 | lfftw_export_wisdom__ 565 | lfftw_flops_ 566 | lfftw_flops__ 567 | lfftw_forget_wisdom_ 568 | lfftw_forget_wisdom__ 569 | lfftw_import_system_wisdom_ 570 | lfftw_import_system_wisdom__ 571 | lfftw_import_wisdom_ 572 | lfftw_import_wisdom__ 573 | lfftw_init_threads_ 574 | lfftw_init_threads__ 575 | lfftw_plan_dft_ 576 | lfftw_plan_dft__ 577 | lfftw_plan_dft_1d_ 578 | lfftw_plan_dft_1d__ 579 | lfftw_plan_dft_2d_ 580 | lfftw_plan_dft_2d__ 581 | lfftw_plan_dft_3d_ 582 | lfftw_plan_dft_3d__ 583 | lfftw_plan_dft_c2r_ 584 | lfftw_plan_dft_c2r__ 585 | lfftw_plan_dft_c2r_1d_ 586 | lfftw_plan_dft_c2r_1d__ 587 | lfftw_plan_dft_c2r_2d_ 588 | lfftw_plan_dft_c2r_2d__ 589 | lfftw_plan_dft_c2r_3d_ 590 | lfftw_plan_dft_c2r_3d__ 591 | lfftw_plan_dft_r2c_ 592 | lfftw_plan_dft_r2c__ 593 | lfftw_plan_dft_r2c_1d_ 594 | lfftw_plan_dft_r2c_1d__ 595 | lfftw_plan_dft_r2c_2d_ 596 | lfftw_plan_dft_r2c_2d__ 597 | lfftw_plan_dft_r2c_3d_ 598 | lfftw_plan_dft_r2c_3d__ 599 | lfftw_plan_guru_dft_ 600 | lfftw_plan_guru_dft__ 601 | lfftw_plan_guru_dft_c2r_ 602 | lfftw_plan_guru_dft_c2r__ 603 | lfftw_plan_guru_dft_r2c_ 604 | lfftw_plan_guru_dft_r2c__ 605 | lfftw_plan_guru_r2r_ 606 | lfftw_plan_guru_r2r__ 607 | lfftw_plan_guru_split_dft_ 608 | lfftw_plan_guru_split_dft__ 609 | lfftw_plan_guru_split_dft_c2r_ 610 | lfftw_plan_guru_split_dft_c2r__ 611 | lfftw_plan_guru_split_dft_r2c_ 612 | lfftw_plan_guru_split_dft_r2c__ 613 | lfftw_plan_many_dft_ 614 | lfftw_plan_many_dft__ 615 | lfftw_plan_many_dft_c2r_ 616 | lfftw_plan_many_dft_c2r__ 617 | lfftw_plan_many_dft_r2c_ 618 | lfftw_plan_many_dft_r2c__ 619 | lfftw_plan_many_r2r_ 620 | lfftw_plan_many_r2r__ 621 | lfftw_plan_r2r_ 622 | lfftw_plan_r2r__ 623 | lfftw_plan_r2r_1d_ 624 | lfftw_plan_r2r_1d__ 625 | lfftw_plan_r2r_2d_ 626 | lfftw_plan_r2r_2d__ 627 | lfftw_plan_r2r_3d_ 628 | lfftw_plan_r2r_3d__ 629 | lfftw_plan_with_nthreads_ 630 | lfftw_plan_with_nthreads__ 631 | lfftw_print_plan_ 632 | lfftw_print_plan__ 633 | lfftw_set_timelimit_ 634 | lfftw_set_timelimit__ 635 | -------------------------------------------------------------------------------- /fftw/win64/libfftw3l-3.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacobjma/PyQSTEM/9172962b9ed51769a97c90278f463af3ec89181e/fftw/win64/libfftw3l-3.dll -------------------------------------------------------------------------------- /fftw/win64/libfftw3l-3.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacobjma/PyQSTEM/9172962b9ed51769a97c90278f463af3ec89181e/fftw/win64/libfftw3l-3.exp -------------------------------------------------------------------------------- /fftw/win64/libfftw3l-3.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacobjma/PyQSTEM/9172962b9ed51769a97c90278f463af3ec89181e/fftw/win64/libfftw3l-3.lib -------------------------------------------------------------------------------- /pyqstem/QSTEM.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "data_containers.h" 6 | #include "stemlib.h" 7 | 8 | namespace shapes { 9 | 10 | class QSTEM { 11 | public: 12 | MULS muls; 13 | WavePtr wave; 14 | int trans_array_state; 15 | int wave_state; 16 | int atoms_state; 17 | int box_state; 18 | 19 | std::string mode; 20 | QSTEM(std::string mode); 21 | ~QSTEM(); 22 | 23 | void set_atoms(int natom, int atomKinds, const std::vector< std::vector > & pos, 24 | const std::vector & occ,const std::vector & q, 25 | const std::vector & Znum); 26 | void set_positions(int natom, const std::vector< std::vector > & pos); 27 | void set_box(const std::vector &, int nonPeriod, int nonPeriodZ, float cellDiv); 28 | 29 | void get_resolution(float* resolutionX,float* resolutionY); 30 | void get_potential_samples(int* potNx, int* potNy, int* slices); 31 | void get_probe_samples(int* nx, int* ny); 32 | void get_scan_range(float* scanXStart, float* scanXStop, int* scanXN, float* scanYStart, float* scanYStop, int* scanYN); 33 | void get_potential_extent(float* potOffsetX,float* potOffsetY,float* potSizeX,float* potSizeY); 34 | void get_energy(float* energy); 35 | 36 | void allocate_potential(); 37 | void build_potential(int slices); 38 | void set_potential(const std::vector< std::vector< std::vector< std::vector > > > & potential, 39 | const std::vector & size, const std::vector & extent); 40 | std::vector > > >get_potential_or_transfunc(float * resolutionX,float* resolutionY,float* sliceThickness); 41 | 42 | void calculate_transfunc(); 43 | void set_scan_range(float scanXStart,float scanXStop,int scanXN,float scanYStart,float scanYStop,int scanYN); 44 | void free_wave(); 45 | void build_wave(int type,float v0,int nx,int ny,float resolutionX,float resolutionY); 46 | void build_probe(float v0,float alpha,int nx,int ny,float resolutionX,float resolutionY,std::unordered_map abberations); 47 | void set_wave(std::vector > >wave,float v0,int nx,int ny,float resolutionX,float resolutionY); 48 | std::vector > > get_wave(float * resolutionX,float* resolutionY,float *v0); 49 | //void create_detector(std::string name,float rInside,float rOutside,float shiftX,float shiftY,int detectorNum); 50 | 51 | void create_detectors(std::vector names,std::vector> properties, int detectorNum); 52 | void run(int displayProgInterval); 53 | std::vector > read_detector(int detNum); 54 | 55 | }; 56 | } 57 | -------------------------------------------------------------------------------- /pyqstem/__init__.py: -------------------------------------------------------------------------------- 1 | #import qstem_interface 2 | from pyqstem.qstem_interface import PyQSTEM 3 | -------------------------------------------------------------------------------- /pyqstem/detection.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | from .util import spatial_frequencies 3 | import scipy.ndimage 4 | from skimage.filters import gaussian 5 | import matplotlib.pyplot as plt 6 | import warnings 7 | 8 | def MTF_a(k,a1,a2,a3,a4): 9 | return (a1 - a2)/(1 + (k/(2*a3))**np.abs(a4)) + a2 10 | 11 | def detect(img,sampling,dose=None,MTF_param=None,MTF_func=None,blur=None,resample=None): 12 | 13 | if resample is not None: 14 | if not isinstance(resample, (list, tuple)): 15 | resample=(resample,)*2 16 | zoom=(sampling[0]/resample[0],sampling[1]/resample[1]) 17 | sampling=resample 18 | warnings.filterwarnings('ignore') 19 | img = scipy.ndimage.interpolation.zoom(img, zoom) 20 | warnings.filterwarnings('always') 21 | 22 | 23 | if blur is not None: 24 | img=gaussian(img,blur) 25 | 26 | if dose is not None: 27 | img = img/np.sum(img)*dose*np.product(sampling)*np.product(img.shape) 28 | 29 | img[img<0]=0 30 | #vals = len(np.unique(img)) 31 | #vals = 2**np.ceil(np.log2(vals)) 32 | #img = np.random.poisson(img * vals) / float(vals) 33 | 34 | img = np.random.poisson(img).astype(np.int64) 35 | 36 | if MTF_param is not None: 37 | if MTF_func is None: 38 | MTF_func=MTF_a 39 | 40 | kx,ky,k2=spatial_frequencies(img.shape,sampling) 41 | k=np.sqrt(k2) 42 | mtf=MTF_func(k,*MTF_param) 43 | img=np.fft.ifft2(np.fft.fft2(img)*np.sqrt(mtf)) 44 | img=(img.real+img.imag)/2 45 | 46 | return img 47 | -------------------------------------------------------------------------------- /pyqstem/imaging.py: -------------------------------------------------------------------------------- 1 | from .wave import Wave 2 | from .util import energy2wavelength, spatial_frequencies 3 | import matplotlib.pyplot as plt 4 | import numpy as np 5 | 6 | class CTF(object): 7 | 8 | def __init__(self,array=None,defocus=0.,Cs=0.,aperture=np.float('inf'),aperture_edge=0., 9 | convergence_angle=0.,focal_spread=0.,aberrations={}): 10 | 11 | self.array=array 12 | self.defocus=defocus 13 | self.Cs=Cs 14 | self.aperture=aperture*10**(-3) 15 | self.aperture_edge=aperture_edge*10**(-3) 16 | self.convergence_angle=convergence_angle*10**(-3) 17 | self.focal_spread=focal_spread 18 | 19 | symbols=["a22","phi22","a20", 20 | "a33","phi33","a31","phi31", 21 | "a44","phi44","a42","phi42","a40", 22 | "a55","phi55","a53","phi53","a51","phi51", 23 | "a66","phi66","a64","phi64","a62","phi62","a60"] 24 | self.aberrations=dict(zip(symbols,[0.]*len(symbols))) 25 | self.aberrations['a20']=self.defocus 26 | self.aberrations['a40']=self.Cs 27 | self.aberrations.update(aberrations) 28 | 29 | self.wavelength=None 30 | self.sampling=None 31 | 32 | def copy(self): 33 | return self.__class__(self.array,self.defocus,self.Cs,self.aperture,self.aperture_edge, 34 | self.convergence_angle,self.focal_spread,self.aberrations) 35 | 36 | def check_recalculate(self,shape,sampling,wavelength,tol=1e-12): 37 | 38 | if np.any([None is i for i in [self.array,self.sampling,self.wavelength]]): 39 | return True 40 | elif ((not np.isclose(self.wavelength,wavelength,rtol=tol))| 41 | (not np.isclose(self.sampling,sampling,rtol=tol).all())| 42 | (not (self.array.shape == shape))): 43 | return True 44 | else: 45 | return False 46 | 47 | def apply(self,wave,keep=True): 48 | 49 | shape=wave.array.shape 50 | sampling=wave.sampling 51 | wavelength=wave.wavelength 52 | 53 | if self.check_recalculate(shape,sampling,wavelength): 54 | ctf = self.calculate(shape,sampling,wavelength) 55 | 56 | new_wave_array=np.fft.ifft2(np.fft.fft2(wave.array)*ctf) 57 | 58 | if keep: 59 | self.sampling=sampling 60 | self.wavelength=wavelength 61 | self.array=ctf 62 | 63 | if len(new_wave_array.shape) > 2: 64 | return [Wave(a,wave.energy,wave.sampling) for a in new_wave_array] 65 | else: 66 | return Wave(new_wave_array,wave.energy,wave.sampling) 67 | 68 | def parse_wave_params(self, shape, sampling, energy, wavelength): 69 | 70 | if shape is None: 71 | if self.array is None: 72 | raise RuntimeError('Shape not set') 73 | else: 74 | shape = self.array.shape 75 | 76 | if sampling is None: 77 | if self.sampling is None: 78 | raise RuntimeError('Sampling not set') 79 | else: 80 | sampling = self.sampling 81 | 82 | if (wavelength is None)&(energy is None): 83 | if self.wavelength is None: 84 | raise RuntimeError('Wavelength not set. Provide energy or wavelength.') 85 | else: 86 | wavelength = self.wavelength 87 | 88 | if wavelength is None: 89 | wavelength=energy2wavelength(energy) 90 | 91 | return shape, sampling, wavelength 92 | 93 | def as_array(self,shape=None,sampling=None,energy=None,wavelength=None): 94 | 95 | shape, sampling, wavelength = self.parse_wave_params(shape, sampling, energy, wavelength) 96 | 97 | if self.check_recalculate(shape,sampling,wavelength): 98 | return self.calculate(shape,sampling,wavelength) 99 | else: 100 | return self.array 101 | 102 | def calculate(self,shape,sampling,wavelength,return_envelopes=False): 103 | 104 | kx,ky,k2,theta,phi=spatial_frequencies(shape,sampling,wavelength=wavelength,return_polar=True) 105 | 106 | ctf=np.exp(-1.j*self.get_chi(theta,phi,wavelength)) 107 | 108 | aperture = self.get_aperture_envelope(theta) 109 | if aperture is not None: 110 | ctf*=aperture 111 | 112 | temporal = self.get_temporal_envelope(theta,wavelength) 113 | if temporal is not None: 114 | ctf*=temporal 115 | 116 | spatial = self.get_spatial_envelope(theta,phi,wavelength) 117 | if spatial is not None: 118 | ctf*=spatial 119 | 120 | if return_envelopes: 121 | return ctf,aperture,temporal,spatial 122 | else: 123 | return ctf 124 | 125 | def get_aperture_envelope(self,theta): 126 | if np.isfinite(self.aperture): 127 | aperture=np.ones_like(theta) 128 | aperture[theta > self.aperture + self.aperture_edge]=0. 129 | ind=(theta > self.aperture)&(theta < self.aperture_edge + self.aperture) 130 | aperture[ind]*= .5*(1+np.cos(np.pi*(theta[ind]-self.aperture)/self.aperture_edge)) 131 | else: 132 | aperture=None 133 | 134 | return aperture 135 | 136 | def get_temporal_envelope(self,theta,wavelength): 137 | if self.focal_spread > 0.: 138 | temporal=np.exp(-np.sign(self.focal_spread)*(.5*np.pi/wavelength*self.focal_spread*theta**2)**2) 139 | else: 140 | temporal=None 141 | 142 | return temporal 143 | 144 | def get_spatial_envelope(self,theta,phi,wavelength): 145 | a=self.aberrations 146 | if self.convergence_angle > 0.: 147 | dchi_dq=2*np.pi/self.wavelength*(\ 148 | (a["a22"]*np.cos(2.*(phi-a["phi22"]))+a["a20"])*theta +\ 149 | (a["a33"]*np.cos(3.*(phi-a["phi33"]))+\ 150 | a["a31"]*np.cos(1.*(phi-a["phi31"])))*theta**2+\ 151 | (a["a44"]*np.cos(4.*(phi-a["phi44"]))+\ 152 | a["a42"]*np.cos(2.*(phi-a["phi42"]))+a["a40"])*theta**3+\ 153 | (a["a55"]*np.cos(5.*(phi-a["phi55"]))+\ 154 | a["a53"]*np.cos(3.*(phi-a["phi53"]))+\ 155 | a["a51"]*np.cos(1.*(phi-a["phi51"])))*theta**4+\ 156 | (a["a66"]*np.cos(6.*(phi-a["phi66"]))+\ 157 | a["a64"]*np.cos(4.*(phi-a["phi64"]))+\ 158 | a["a62"]*np.cos(2.*(phi-a["phi62"]))+a["a60"])*theta**5) 159 | dchi_dphi=-2*np.pi/self.wavelength*(\ 160 | 1/2.*(2.*a["a22"]*np.sin(2.*(phi-a["phi22"])))*theta +\ 161 | 1/3.*(3.*a["a33"]*np.sin(3.*(phi-a["phi33"]))+\ 162 | 1.*a["a31"]*np.sin(1.*(phi-a["phi31"])))*theta**2+\ 163 | 1/4.*(4.*a["a44"]*np.sin(4.*(phi-a["phi44"]))+\ 164 | 2.*a["a42"]*np.sin(2.*(phi-a["phi42"])))*theta**3+\ 165 | 1/5.*(5.*a["a55"]*np.sin(5.*(phi-a["phi55"]))+\ 166 | 3.*a["a53"]*np.sin(3.*(phi-a["phi53"]))+\ 167 | 1.*a["a51"]*np.sin(1.*(phi-a["phi51"])))*theta**4+\ 168 | 1/6.*(6.*a["a66"]*np.sin(6.*(phi-a["phi66"]))+\ 169 | 4.*a["a64"]*np.sin(4.*(phi-a["phi64"]))+\ 170 | 2.*a["a62"]*np.sin(2.*(phi-a["phi62"])))*theta**5) 171 | spatial=np.exp(-np.sign(self.convergence_angle)*(self.convergence_angle/2)**2*(dchi_dq**2+dchi_dphi**2)) 172 | else: 173 | spatial=None 174 | 175 | return spatial 176 | 177 | def get_chi(self,theta,phi,wavelength): 178 | a=self.aberrations 179 | chi=1/2.*(a["a22"]*np.cos(2.*(phi-a["phi22"]))+a["a20"])*theta**2 +\ 180 | 1/3.*(a["a33"]*np.cos(3.*(phi-a["phi33"]))+\ 181 | a["a31"]*np.cos(1.*(phi-a["phi31"])))*theta**3 +\ 182 | 1/4.*(a["a44"]*np.cos(4.*(phi-a["phi44"]))+\ 183 | a["a42"]*np.cos(2.*(phi-a["phi42"]))+a["a40"])*theta**4+\ 184 | 1/5.*(a["a55"]*np.cos(5.*(phi-a["phi55"]))+\ 185 | a["a53"]*np.cos(3.*(phi-a["phi53"]))+\ 186 | a["a51"]*np.cos(1.*(phi-a["phi51"])))*(theta**5) +\ 187 | 1/6.*(a["a66"]*np.cos(6.*(phi-a["phi66"]))+\ 188 | a["a64"]*np.cos(4.*(phi-a["phi64"]))+\ 189 | a["a62"]*np.cos(2.*(phi-a["phi62"]))+a["a60"])*theta**6 190 | chi*=2*np.pi/wavelength 191 | 192 | return chi 193 | 194 | def radial_plot(self,shape=None,sampling=None,wavelength=None,energy=None, 195 | max_freq=2,ax=None,interpolate=True): 196 | 197 | from scipy.interpolate import spline,interp1d 198 | 199 | if ax is None: 200 | fig, ax = plt.subplots() 201 | 202 | shape, sampling, wavelength = self.parse_wave_params(shape, sampling, energy, wavelength) 203 | 204 | ctf,aperture,temporal,spatial = self.calculate(shape,sampling,wavelength,True) 205 | 206 | kx,ky,k2=spatial_frequencies(ctf.shape,sampling) 207 | 208 | w=ctf.shape[0]//2 209 | kx=kx[:w,0] 210 | kx_interp = np.linspace(kx.min(),kx.max(),3000) 211 | 212 | y=np.real(ctf[:w,0]) 213 | 214 | if not interpolate: 215 | ax.plot(kx,y,'k--',label='Re(CTF)') 216 | else: 217 | f = interp1d(kx, y,'cubic') 218 | ynew = f(kx_interp,) 219 | ax.plot(kx,y,'k.') 220 | ax.plot(kx_interp,ynew,'k--',label='Re(CTF)') 221 | 222 | y=np.imag(ctf[:w,0]) 223 | if not interpolate: 224 | ax.plot(kx,y,'k-',label='Im(CTF)') 225 | else: 226 | f = interp1d(kx, y,'cubic') 227 | ynew = f(kx_interp,) 228 | ax.plot(kx,y,'k.') 229 | ax.plot(kx_interp,ynew,'k-',label='Im(CTF)') 230 | 231 | if aperture is not None: 232 | ax.plot(kx,aperture[:w,0],label='aperture') 233 | if temporal is not None: 234 | ax.plot(kx,temporal[:w,0],label='temporal') 235 | if spatial is not None: 236 | ax.plot(kx,spatial[:w,0],label='spatial') 237 | 238 | ax.set_xlabel('Spatial frequency [1/Angstrom]') 239 | ax.set_ylabel('Contrast') 240 | ax.set_title('Contrast transfer function') 241 | ax.set_xlim([0,max_freq]) 242 | ax.set_ylim([-1.05,1.05]) 243 | ax.legend(loc='center left', bbox_to_anchor=(1, 0.5)) 244 | -------------------------------------------------------------------------------- /pyqstem/potentials.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import numpy.linalg 3 | from .wave import Potential 4 | 5 | def poisson_solver(rho,atoms,smooth=0,units='QSTEM'): 6 | 7 | Lx = np.linalg.norm(atoms.get_cell()[0]) 8 | Ly = np.linalg.norm(atoms.get_cell()[1]) 9 | Lz = np.linalg.norm(atoms.get_cell()[2]) 10 | 11 | Nx,Ny,Nz = rho.shape 12 | 13 | total_density=np.sum(rho) 14 | total_protons=np.sum(atoms.get_atomic_numbers()) 15 | 16 | fft_rho = np.fft.fftn(rho) 17 | 18 | V = np.zeros(fft_rho.shape,dtype=np.complex) 19 | k = np.fft.fftshift(np.arange(-Nx/2,Nx/2)) 20 | l = np.fft.fftshift(np.arange(-Ny/2,Ny/2)) 21 | m = np.fft.fftshift(np.arange(-Nz/2,Nz/2)) 22 | 23 | for atom in atoms: 24 | scale = -atom.number/float(total_protons)*total_density 25 | x,y,z = atom.position 26 | fft_rho += scale*np.exp(-2*np.pi*1j*(k[:,None,None]/Lx*x+l[None,:,None]/Ly*y+m[None,None,:]/Lz*z)) 27 | 28 | scaling = (2**2*np.pi**2*(k[:,None,None]**2/float(Lx)**2+l[None,:,None]**2/float(Ly)**2+m[None,None,:]**2/float(Lz)**2)) 29 | 30 | nonzero = scaling > 0 31 | 32 | V[nonzero] = -fft_rho[nonzero]/scaling[nonzero] 33 | V[0,0,0] = 0 34 | 35 | V = np.fft.ifftn(V) 36 | V = np.real(V) 37 | 38 | if smooth>0.: 39 | from skimage.filters import gaussian 40 | V=gaussian(V,smooth) 41 | 42 | if units=='QSTEM': 43 | V=2/0.52917721067*V # 2/a0 44 | elif units=='ASE': 45 | V=1/0.07957747154594767*V # 1/epsilon0 46 | elif units=='SI': 47 | e=1.60217662*10**(-19) 48 | epsilon0=8.854187817*10**(-12) 49 | V=e/epsilon0*V 50 | else: 51 | raise RuntimeError('Unit convention {0} not recognized.'.format(units)) 52 | 53 | return V 54 | 55 | def create_potential_slices(V,n,box,nonneg=True): 56 | Nz=V.shape[2] 57 | 58 | if n<1: 59 | raise RuntimeError('n should be a positive integer') 60 | 61 | if Nz%n!=0: 62 | raise RuntimeError('V.shape[2] is not divisible by n ({0} % {1} != 0)'.format(Nz,n)) 63 | 64 | V_slices=np.zeros(V.shape[:2]+(n,)) 65 | 66 | dz=box[2]/float(Nz) 67 | nz=int(Nz/n) 68 | for i in range(n): 69 | V_slices[:,:,i]=np.trapz(V[:,:,i*nz:(i+1)*nz+1],dx=dz,axis=2) 70 | 71 | if nonneg: 72 | V_slices=V_slices-V_slices.min() 73 | 74 | sampling = (box[0]/V_slices.shape[0],box[1]/V_slices.shape[1],box[2]/n) 75 | potential = Potential(V_slices,sampling) 76 | 77 | return potential 78 | -------------------------------------------------------------------------------- /pyqstem/qstem_interface.pyx: -------------------------------------------------------------------------------- 1 | import warnings 2 | from libcpp.vector cimport vector 3 | import numpy as np 4 | from collections import OrderedDict 5 | import matplotlib.pyplot as plt 6 | from libcpp.unordered_map cimport unordered_map 7 | from libcpp.pair cimport pair 8 | from libcpp.string cimport string 9 | from .wave import Wave, Potential 10 | from .util import atoms_plot 11 | 12 | TOL=1e-6 13 | 14 | # c++ interface to cython 15 | cdef extern from "QSTEM.h" namespace "shapes": 16 | cdef cppclass QSTEM: 17 | QSTEM(string) except + 18 | string mode 19 | 20 | int trans_array_state 21 | int wave_state 22 | int atoms_state 23 | int box_state 24 | int scan_range_state 25 | 26 | void set_atoms(int,int,vector[vector[double]] &,vector[double] &, 27 | vector[double] &,vector[int] &) 28 | void set_positions(int,vector[vector[double]] &) 29 | void set_box(vector[double] &,int,int,float) 30 | 31 | void get_resolution(float*, float*) 32 | void get_potential_samples(int*, int*, int*) 33 | void get_probe_samples(int*, int*) 34 | void get_scan_range(float*, float*, int*, float*, float*, int*) 35 | void get_energy(float*) 36 | void get_potential_extent(float*,float*,float*,float*) 37 | 38 | void build_potential(int) 39 | void set_potential(vector[vector[vector[vector[double]]]] &,vector[int] &,vector[double] &) 40 | vector[vector[vector[vector[double]]]] get_potential_or_transfunc(float*,float*,float*) 41 | void calculate_transfunc() 42 | 43 | void set_scan_range(float,float,int,float,float,int) 44 | void build_wave(int,float,int,int,float,float) 45 | void build_probe(float,float,int,int,float,float,unordered_map[string,float]) 46 | void set_wave(vector[vector[vector[double]]],float,int,int,float,float) 47 | vector[vector[vector[double]]] get_wave(float*,float*,float*) 48 | 49 | void create_detectors(vector[string],vector[vector[double]],int) 50 | void run(int) 51 | vector[vector[double]] read_detector(int) 52 | 53 | # cython wrapper class 54 | cdef class PyQSTEM: 55 | 56 | cdef object _atoms 57 | cdef char* c_mode 58 | 59 | cdef QSTEM *thisptr # hold a C++ instance which we're wrapping 60 | def __cinit__(self, str mode): 61 | self._atoms=None 62 | 63 | if isinstance(mode, unicode): 64 | c_mode = mode.encode('UTF-8') 65 | else: 66 | c_mode = mode 67 | 68 | self.thisptr = new QSTEM(c_mode) 69 | 70 | self.thisptr.mode = c_mode; 71 | 72 | # 0: potential not created 73 | # 1: potential created 74 | # 2: potential converted to transmission function 75 | # -1: potential created, but have to be recreated (atoms or simulation box changed) 76 | # -2: potential created, but have to be recreated (energy changed) 77 | self.thisptr.trans_array_state=0 78 | 79 | # 0: wave not created 80 | # 1: wave created 81 | # -1: wave created, but have to be recreated 82 | self.thisptr.wave_state=0 83 | 84 | # 0: atoms set 85 | # 1: atoms not set 86 | self.thisptr.atoms_state=0 87 | 88 | # 0: simulation box set 89 | # 1: simulation box not set 90 | self.thisptr.box_state=0 91 | 92 | _detectors=OrderedDict() 93 | 94 | def __dealloc__(self): 95 | del self.thisptr 96 | 97 | def set_atoms(self,atoms,set_box=True,TDS=False,B_factors=None): 98 | self._atoms=atoms 99 | 100 | positions=atoms.get_positions() 101 | 102 | occ=[1.]*len(atoms) # occupancy not implemeted 103 | q=[0.]*len(atoms) # charge not implemeted 104 | 105 | Znum=atoms.get_atomic_numbers() 106 | 107 | if set_box: 108 | box=np.diag(atoms.get_cell()) 109 | self.set_box(box) 110 | 111 | self.thisptr.set_atoms(len(atoms),len(set(Znum)),positions,occ,q,Znum) 112 | self.thisptr.atoms_state = 1 113 | if self.thisptr.trans_array_state >= 1: 114 | self.thisptr.trans_array_state = -1 115 | 116 | def _set_positions(self,positions): 117 | self.thisptr.set_positions(len(self._atoms),positions) 118 | 119 | def set_box(self,box,periodic_xy=None,periodic_z=False,cell_div=1): 120 | if ((self.thisptr.mode == 'STEM')&(periodic_xy==True)): 121 | raise RuntimeError('Periodic boundary conditions not implemented for mode {0}'.format(self.thisptr.mode)) 122 | 123 | if periodic_xy is None: 124 | if self.thisptr.mode == 'STEM': 125 | periodic_xy = False 126 | elif self.thisptr.mode == 'TEM': 127 | periodic_xy = True 128 | 129 | nonperiodic_xy = not periodic_xy 130 | nonperiodic_z = not periodic_z 131 | 132 | self.thisptr.set_box(box,nonperiodic_xy,nonperiodic_z,cell_div) 133 | self.thisptr.box_state = 1 134 | if self.thisptr.trans_array_state >= 1: 135 | self.thisptr.trans_array_state = -1 136 | 137 | def get_resolution(self): 138 | cdef float resolutionX, resolutionY 139 | self.thisptr.get_resolution(&resolutionX, &resolutionY) 140 | return resolutionX, resolutionY 141 | 142 | def get_potential_samples(self): 143 | cdef int potNx, potNy, slices 144 | self.thisptr.get_potential_samples(&potNx, &potNy, &slices) 145 | return potNx, potNy, slices 146 | 147 | def get_probe_samples(self): 148 | cdef int nx, ny 149 | self.thisptr.get_probe_samples(&nx, &ny) 150 | return nx, ny 151 | 152 | def get_scan_range(self): 153 | cdef float scanXStart, scanXStop, scanYStart, scanYStop 154 | cdef int scanXN, scanYN 155 | 156 | self.thisptr.get_scan_range(&scanXStart, &scanXStop, &scanXN, &scanYStart, &scanYStop, &scanYN) 157 | return ((scanXStart, scanXStop, scanXN), (scanYStart, scanYStop, scanYN)) 158 | 159 | def get_energy(self): 160 | cdef float v0 161 | self.thisptr.get_energy(&v0) 162 | return v0 163 | 164 | def get_probe_extent(self): 165 | probe_samples = self.get_probe_samples() 166 | resolution = self.get_resolution() 167 | 168 | def get_potential_extent(self): 169 | cdef float potOffsetX, potOffsetY, potSizeX, potSizeY 170 | self.thisptr.get_potential_extent(&potOffsetX, &potOffsetY, &potSizeX, &potSizeY) 171 | return potOffsetX, potOffsetX+potSizeX, potOffsetY, potOffsetY+potSizeY 172 | 173 | def get_minimum_potential_extent(self): 174 | scan_range = self.get_scan_range() 175 | probe_samples = self.get_probe_samples() 176 | resolution = self.get_resolution() 177 | 178 | probe_size=[resolution[0]*probe_samples[0],resolution[1]*probe_samples[1]] 179 | return [scan_range[0][0]-.5*probe_size[0],scan_range[0][1]+.5*probe_size[0], 180 | scan_range[1][0]-.5*probe_size[0],scan_range[1][1]+.5*probe_size[0]] 181 | 182 | def view(self,ax=None): 183 | scan_range=self.get_scan_range() 184 | potential_extent=self.get_potential_extent() 185 | potential_samples=self.get_potential_samples() 186 | probe_extent=self.get_minimum_potential_extent() 187 | atoms_plot(self._atoms,scan_range=scan_range,potential_extent=potential_extent,probe_extent=probe_extent,ax=ax,legend=True) 188 | 189 | def build_potential(self,num_slices=None,slice_thickness=.5,scan_range=None,probe_position=None): 190 | 191 | if self.thisptr.mode == 'STEM': 192 | if scan_range is None: 193 | raise RuntimeError('Provide scan window for mode STEM') 194 | else: 195 | self.set_scan_range(scan_range) 196 | elif self.thisptr.mode == 'CBED': 197 | if probe_position is None: 198 | raise RuntimeError('Provide probe postion for mode CBED') 199 | else: 200 | scan_range = [[probe_position[0],probe_position[0],1],[probe_position[1],probe_position[1],1]] 201 | self.set_scan_range(scan_range) 202 | 203 | if ((self.thisptr.atoms_state==0)|(self.thisptr.box_state==0)): 204 | raise RuntimeError('Please set atoms and simulation box') 205 | 206 | if num_slices is None: 207 | num_slices = int(self._atoms.get_cell()[2,2]/slice_thickness) 208 | #nx_old,ny_old,slices_old = self.get_numsamples() 209 | 210 | self.thisptr.build_potential(num_slices) 211 | 212 | self.thisptr.trans_array_state = 1 213 | 214 | #if ((self.thisptr.wave_state == 1)&((nx_old!=shape[0])|(ny_old!=shape[1]))): 215 | # self.thisptr.wave_state = -1 216 | 217 | def set_potential(self,potential,scan_range=None): 218 | if self.thisptr.mode == 'STEM': 219 | if scan_range is None: 220 | raise RuntimeError('Provide scan window for mode {0}'.format(self.thisptr.mode)) 221 | else: 222 | self.set_scan_range(scan_range) 223 | 224 | array = potential.array 225 | nonperiodic_xy = not potential.periodic_xy 226 | nonperiodic_z = not potential.periodic_z 227 | size = array.shape 228 | extent = potential.get_extent() 229 | 230 | if self.thisptr.wave_state > 0: 231 | if not np.any(np.isclose(potential.sampling[:2],self.get_resolution(),rtol=1e-6,atol=1e-6)): 232 | raise RuntimeError('Potential resolution does not match wavefunction ({0},{1})!=({2},{3})' 233 | .format(potential.sampling[0],potential.sampling[1],self.get_resolution()[0],self.get_resolution()[1])) 234 | 235 | array = np.concatenate((np.real(array)[:,:,:,np.newaxis],np.imag(array)[:,:,:,np.newaxis]),axis=3) 236 | 237 | self.thisptr.set_potential(array,size,extent) 238 | 239 | self.thisptr.trans_array_state = 1 240 | #if self.thisptr.wave_state == 1: 241 | # self.thisptr.wave_state = -1 242 | 243 | def get_potential_or_transfunc(self): 244 | cdef float resolutionX, resolutionY, sliceThickness 245 | if self.thisptr.trans_array_state==0: 246 | raise RuntimeError('A potential have not been build') 247 | else: 248 | trans_array = self.thisptr.get_potential_or_transfunc(&resolutionX,&resolutionY,&sliceThickness) 249 | #trans_array = np.apply_along_axis(lambda args: [complex(*args)], 3, trans_array)[:,:,:,0] 250 | trans_array_noncplx = np.array(trans_array) 251 | trans_array = np.empty(trans_array_noncplx.shape[:-1], dtype=np.complex) 252 | trans_array.real = trans_array_noncplx[...,0] 253 | trans_array.imag = trans_array_noncplx[...,1] 254 | potential_extent = self.get_potential_extent() 255 | return Potential(trans_array,(resolutionX,resolutionY,sliceThickness)) 256 | 257 | def calculate_transfunc(self): 258 | 259 | if self.thisptr.trans_array_state==0: 260 | raise RuntimeError('Please set or build a potential') 261 | elif self.thisptr.trans_array_state==1: 262 | self.thisptr.calculate_transfunc() 263 | self.thisptr.trans_array_state=2 264 | elif self.thisptr.trans_array_state==2: 265 | pass 266 | 267 | def set_scan_range(self,scan_range): 268 | 269 | self.thisptr.set_scan_range(scan_range[0][0],scan_range[0][1],scan_range[0][2], 270 | scan_range[1][0],scan_range[1][1],scan_range[1][2]) 271 | 272 | def build_probe(self,v0,alpha,num_samples,resolution=None,window_size=None, 273 | defocus=0,Cs=0,C5=0,astig_mag=0,astig_angle=0,aberrations={}): 274 | 275 | if ((resolution is None)&(window_size is None)): 276 | raise RuntimeError("Please specify resolution or window size") 277 | 278 | if resolution is None: 279 | resolution = np.array(window_size)/np.array(num_samples) 280 | 281 | cdef unordered_map[string, float] aberrations_map 282 | 283 | symbols=[b'a22',b'phi22',b'a20', 284 | b'a33',b'phi33',b'a31',b'phi31', 285 | b'a44',b'phi44',b'a42',b'phi42',b'a40', 286 | b'a55',b'phi55',b'a53',b'phi53',b'a51',b'phi51', 287 | b'a66',b'phi66',b'a64',b'phi64',b'a62',b'phi62',b'a60'] 288 | 289 | keys = [key.encode('utf-8') for key in aberrations.keys()] 290 | 291 | for symbol in symbols: 292 | if symbol in keys: 293 | aberrations_map[symbol] = aberrations[symbol.decode('utf-8')] 294 | elif symbol == b'a20': 295 | aberrations_map[symbol] = defocus 296 | elif symbol == b'a40': 297 | aberrations_map[symbol] = Cs 298 | elif symbol == b'a60': 299 | aberrations_map[symbol] = C5 300 | elif symbol == b'a22': 301 | aberrations_map[symbol] = astig_mag 302 | elif symbol == b'phi22': 303 | aberrations_map[symbol] = astig_angle 304 | else: 305 | aberrations_map[symbol] = 0. 306 | 307 | self.thisptr.build_probe(v0,alpha,num_samples[0],num_samples[1],resolution[0],resolution[1],aberrations_map) 308 | self.thisptr.wave_state = 1 309 | 310 | def build_wave(self,str wave_type,v0,num_samples,resolution=None): 311 | 312 | if wave_type=='plane': 313 | wave_type_int=0 314 | else: 315 | raise RuntimeError('Wave type {0} not recognized'.format(wave_type)) 316 | 317 | old_v0 = self.get_energy() 318 | 319 | if resolution is None: 320 | resolution = [-1,-1] 321 | 322 | self.thisptr.build_wave(wave_type_int,v0,num_samples[0],num_samples[1],resolution[0],resolution[1]) 323 | 324 | self.thisptr.wave_state = 1 325 | if self.thisptr.trans_array_state == 2: 326 | if not np.isclose(old_v0,v0,rtol=0,atol=1e-6): 327 | self.thisptr.trans_array_state = -2 328 | 329 | def set_wave(self,wave): 330 | nx=wave.array.shape[0] 331 | ny=wave.array.shape[1] 332 | 333 | nx_old,ny_old = self.get_probe_samples() 334 | resolutionX,resolutionY = self.get_resolution() 335 | 336 | if self.thisptr.trans_array_state>0: 337 | if ((nx_old!=nx)|(ny_old!=ny)): 338 | raise RuntimeError('Wave function shape does not match QSTEM: ({0},{1}) != ({2},{3})'.format(nx,ny,nx_old,ny_old)) 339 | 340 | #if wave.sampling is not None: 341 | # if not np.any(np.isclose(wave.sampling,(resolutionX,resolutionY),rtol=0,atol=1e-06)): 342 | # warnings.warn('Wavefunction resolution will be changed to match the simulation box') 343 | 344 | array = np.concatenate((np.real(wave.array)[:,:,np.newaxis],np.imag(wave.array)[:,:,np.newaxis]),axis=2) 345 | 346 | if wave.sampling is None: 347 | resolution = [-1,-1] 348 | else: 349 | resolution = wave.sampling 350 | 351 | old_v0 = self.get_energy() 352 | self.thisptr.set_wave(array,wave.energy,nx,ny,resolution[0],resolution[1]) 353 | 354 | self.thisptr.wave_state = 1 355 | if self.thisptr.trans_array_state == 2: 356 | if not np.isclose(old_v0,wave.energy,rtol=0,atol=1e-6): 357 | self.thisptr.trans_array_state = -2 358 | 359 | def get_wave(self): 360 | if self.thisptr.wave_state == 0: 361 | raise RuntimeError('A wavefunction have not been created') 362 | 363 | cdef float resolutionX, resolutionY, v0 364 | wave_array = self.thisptr.get_wave(&resolutionX,&resolutionY,&v0) 365 | wave_array = np.apply_along_axis(lambda args: [complex(*args)], 2, wave_array)[:,:,0] 366 | 367 | return Wave(wave_array,energy=v0,sampling=(resolutionX,resolutionY)) 368 | 369 | def add_detector(self,str name,radii,shift=(0,0)): 370 | self._detectors[name]=[False,radii[0],radii[1],shift[0],shift[1]] 371 | 372 | def remove_detector(self,str name): 373 | if name not in self._detectors.keys(): 374 | raise RuntimeError('Detector name {0} not recognized'.format(name)) 375 | 376 | del self._detectors[name] 377 | 378 | def read_detector(self,str name,dwell_time=1,current=1): 379 | 380 | if name not in self._detectors.keys(): 381 | raise RuntimeError('Detector name {0} not recognized'.format(name)) 382 | 383 | if not self._detectors[name][0]: 384 | raise RuntimeError('Detector {0} is empty, add the detector before running'.format(name)) 385 | 386 | img = np.array(self.thisptr.read_detector(list(self._detectors.keys()).index(name))) 387 | img*=dwell_time*current/1.6021773e-4 388 | 389 | return img 390 | 391 | def run(self,slices_per_division=None,slice_thickness=.5,cell_divisions=1,scan_range=None,probe_position=None,display_progress_interval=None): 392 | 393 | if self.thisptr.wave_state==0: 394 | raise RuntimeError('A wavefunction have not been created') 395 | elif self.thisptr.wave_state==-1: 396 | raise RuntimeError('The wavefunction have to be recreated after changing the potential sampling') 397 | elif self.thisptr.trans_array_state==-1: 398 | raise RuntimeError('The potential have to be recreated after changing the atoms or simulation box') 399 | elif self.thisptr.trans_array_state==-2: 400 | raise RuntimeError('The transmission function energy does not match wavefunction') 401 | 402 | cdef unordered_map[string, vector[double]] detector_map 403 | 404 | if self.thisptr.mode == 'STEM': 405 | pot_ext = self.get_potential_extent() 406 | min_pot_ext = self.get_minimum_potential_extent() 407 | 408 | if ((pot_ext[0]-min_pot_ext[0]>TOL)|(min_pot_ext[1]-pot_ext[1]>TOL)| 409 | (pot_ext[2]-min_pot_ext[2]>TOL)|(min_pot_ext[3]-pot_ext[3]>TOL)): 410 | raise RuntimeError('The potential is too small to accomodate the probe size for the chosen scan range') 411 | 412 | properties=[] 413 | for name,values in self._detectors.items(): 414 | values[0]=True 415 | properties.append(values[1:]) 416 | 417 | names = [name.encode('utf-8') for name in self._detectors.keys()] 418 | self.thisptr.create_detectors(names,properties,len(self._detectors)) 419 | 420 | if display_progress_interval is None: 421 | display_progress_interval = -1 422 | 423 | box=np.diag(self._atoms.get_cell()) 424 | h=box[2]/cell_divisions 425 | if slices_per_division is None: 426 | slices_per_division = int(h/slice_thickness) 427 | 428 | if cell_divisions == 1: 429 | if self.thisptr.trans_array_state==0: 430 | self.build_potential(slices_per_division,scan_range=scan_range,probe_position=probe_position) 431 | 432 | self.calculate_transfunc() 433 | self.thisptr.run(display_progress_interval) 434 | else: 435 | box_div=[box[0],box[1],h] 436 | self.set_box(box_div) 437 | positions=self._atoms.get_positions() 438 | 439 | for i in range(cell_divisions): 440 | self._set_positions(positions-[0,0,i*h]) 441 | 442 | self.build_potential(slices_per_division,scan_range=scan_range,probe_position=probe_position) 443 | self.calculate_transfunc() 444 | self.thisptr.run(display_progress_interval) 445 | -------------------------------------------------------------------------------- /pyqstem/thermal.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | def frozen_phonon(atoms, MSD, num_structures=1): 4 | 5 | if (not isinstance(MSD,dict)) and (len(atoms) != len(MSD)): 6 | raise RuntimeError('Length of ´MSD´ have to match number of atoms') 7 | elif isinstance(MSD,dict): 8 | MSD_dict = MSD.copy() 9 | MSD = [] 10 | for i in range(len(atoms)): 11 | MSD.append(MSD_dict[atoms[i].symbol]) 12 | 13 | atoms_list = [] 14 | for i in range(num_structures): 15 | atoms_copy=atoms.copy() 16 | r = np.random.randn(len(atoms))*np.sqrt(MSD) 17 | theta = np.random.rand(len(atoms))*np.pi 18 | phi = np.random.rand(len(atoms))*2*np.pi 19 | 20 | displacement = np.array([r*np.sin(theta)*np.cos(phi), 21 | r*np.sin(theta)*np.sin(phi), 22 | r*np.cos(theta)]).T 23 | 24 | positions = atoms.get_positions() + displacement 25 | 26 | atoms_copy.set_positions(positions) 27 | 28 | atoms_list.append(atoms_copy) 29 | 30 | if num_structures == 1: 31 | return atoms_list[0] 32 | else: 33 | return atoms_list 34 | -------------------------------------------------------------------------------- /pyqstem/util.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import matplotlib.pyplot as plt 3 | import matplotlib.patches as patches 4 | import warnings 5 | from ase.data.colors import cpk_colors 6 | from ase.data import covalent_radii,chemical_symbols 7 | from matplotlib.patches import Circle 8 | from scipy.cluster.hierarchy import linkage,fcluster 9 | from ase import Atoms 10 | import collections 11 | 12 | def energy2wavelength(v0): 13 | m0=0.5109989461*10**3 # keV / c**2 14 | h=4.135667662*10**(-15)*10**(-3) # eV * s 15 | c=2.99792458*10**8 # m / s 16 | return h*c/np.sqrt(v0*(2*m0+v0))*10**10 17 | 18 | def focal_spread(Cc,energy,energy_spread,current_stability): 19 | return Cc*np.sqrt((dv0/v0)**2+2*current_stability**2) 20 | 21 | def scherzer(v0,Cs): 22 | assert Cs > 0. 23 | return -1.2*np.sqrt(wavelength(v0)*Cs) 24 | 25 | def scherzer_point_resolution(v0,Cs): 26 | assert Cs > 0. 27 | return 0.6*wavelength(v0)**(3/4.)*Cs**(1/4.) 28 | 29 | def spatial_frequencies(shape,sampling,return_polar=False,return_nyquist=False,wavelength=None): 30 | 31 | if not isinstance(shape, collections.Iterable): 32 | shape = (shape,)*2 33 | 34 | if not isinstance(sampling, collections.Iterable): 35 | sampling = (sampling,)*2 36 | 37 | dkx=1/(shape[0]*sampling[0]) 38 | dky=1/(shape[1]*sampling[1]) 39 | 40 | if shape[0]%2==0: 41 | kx = np.fft.fftshift(dkx*np.arange(-shape[0]/2,shape[0]/2,1)) 42 | else: 43 | kx = np.fft.fftshift(dkx*np.arange(-shape[0]/2-.5,shape[0]/2-.5,1)) 44 | 45 | if shape[1]%2==0: 46 | ky = np.fft.fftshift(dky*np.arange(-shape[1]/2,shape[1]/2,1)) 47 | else: 48 | ky = np.fft.fftshift(dky*np.arange(-shape[1]/2-.5,shape[1]/2-.5,1)) 49 | 50 | ky,kx = np.meshgrid(ky,kx) 51 | 52 | k2 = kx**2+ky**2 53 | 54 | ret = (kx,ky,k2) 55 | if return_nyquist: 56 | knx = 1/(2*sampling[0]) 57 | kny = 1/(2*sampling[1]) 58 | Kx=kx/knx 59 | Ky=ky/knx 60 | K2 = Kx**2+Ky**2 61 | ret += (Kx,Ky,K2) 62 | if return_polar: 63 | theta = np.sqrt(k2*wavelength**2) 64 | phi = np.arctan2(ky,kx) 65 | ret += (theta,phi) 66 | 67 | return ret 68 | 69 | def atoms_plot(atoms,direction=2,ax=None,scan_range=None,potential_extent=None,probe_extent=None,s=40,boundary=1,scale_atoms=1,legend=False): 70 | 71 | if not np.allclose(atoms.get_cell(), np.diag(np.diag(atoms.get_cell()))): 72 | warnings.warn("Ignoring non-diagonal components of unit cell") 73 | 74 | if direction == 'x': 75 | direction = 0 76 | elif direction == 'y': 77 | direction = 1 78 | elif direction == 'z': 79 | direction = 2 80 | 81 | axes=np.delete([0,1,2],direction) 82 | labels=np.delete(['x','y','z'],direction) 83 | 84 | direction_sort=np.argsort(-atoms.get_positions()[:,direction]) 85 | atoms=atoms[direction_sort] 86 | 87 | positions=atoms.get_positions()[:,axes] 88 | 89 | cell=atoms.get_cell()[axes,axes] 90 | 91 | if ax is None: 92 | fig, ax = plt.subplots() 93 | 94 | handles={} 95 | for atom,pos in zip(atoms,positions): 96 | handles[atom.symbol]=ax.add_artist(Circle(xy=(pos[0], pos[1]), facecolor=cpk_colors[atom.number], radius=scale_atoms*covalent_radii[atom.number], 97 | zorder=0,label=atom.symbol,lw=1,edgecolor='k')) 98 | 99 | handles = list(handles.values()) 100 | 101 | if potential_extent is not None: 102 | handles.append(ax.add_patch(patches.Rectangle((potential_extent[0],potential_extent[2]), 103 | potential_extent[1]-potential_extent[0],potential_extent[3]-potential_extent[2], 104 | alpha=0.2,color='g',linewidth=None,zorder=1,label='potential extent'))) 105 | ax.add_patch(patches.Rectangle((potential_extent[0],potential_extent[2]), 106 | potential_extent[1]-potential_extent[0],potential_extent[3]-potential_extent[2], 107 | linestyle='dashed',linewidth=1,fill=False,zorder=1)) 108 | 109 | if probe_extent is not None: 110 | handles.append(ax.add_patch(patches.Rectangle((probe_extent[0],probe_extent[2]), 111 | probe_extent[1]-probe_extent[0],probe_extent[3]-probe_extent[2], 112 | alpha=0.2,color='b',linewidth=None,zorder=1,label='probe max extent'))) 113 | ax.add_patch(patches.Rectangle((probe_extent[0],probe_extent[2]), 114 | probe_extent[1]-probe_extent[0],probe_extent[3]-probe_extent[2], 115 | linestyle='dashed',linewidth=1,fill=False,zorder=1)) 116 | 117 | if scan_range is not None: 118 | handles.append(ax.add_patch(patches.Rectangle((scan_range[0][0],scan_range[1][0]), 119 | scan_range[0][1]-scan_range[0][0],scan_range[1][1]-scan_range[1][0], 120 | alpha=0.2,color='r',linewidth=None,zorder=3,label='scan range'))) 121 | ax.add_patch(patches.Rectangle((scan_range[0][0],scan_range[1][0]), 122 | scan_range[0][1]-scan_range[0][0],scan_range[1][1]-scan_range[1][0], 123 | linestyle='dashed',linewidth=1,fill=False,zorder=3)) 124 | dx=(scan_range[0][1]-scan_range[0][0])/float(scan_range[0][2]) 125 | dy=(scan_range[1][1]-scan_range[1][0])/float(scan_range[1][2]) 126 | for i in range(1,scan_range[0][2]): 127 | ax.plot([scan_range[0][0]+i*dx]*2,[scan_range[1][0],scan_range[1][1]],'k-',alpha=.4,zorder=2) 128 | for i in range(1,scan_range[1][2]): 129 | ax.plot([scan_range[0][0],scan_range[0][1]],[scan_range[1][0]+i*dy]*2,'k-',alpha=.4,zorder=2) 130 | 131 | if legend: 132 | ax.legend(handles=handles) 133 | 134 | ax.plot([0,0,cell[0],cell[0],0],[0,cell[1],cell[1],0,0],'k',linewidth=1.5) 135 | ax.axis('equal') 136 | ax.set_xlim([-boundary,cell[0]+boundary]) 137 | ax.set_ylim([-boundary,cell[1]+boundary]) 138 | ax.set_xlabel('{0} [Angstrom]'.format(labels[0])) 139 | ax.set_ylabel('{0} [Angstrom]'.format(labels[1])) 140 | 141 | def project_positions(atoms,distance=1,return_counts=False): 142 | 143 | positions=atoms.get_positions()[:,:2] 144 | 145 | clusters = fcluster(linkage(positions), distance, criterion='distance') 146 | unique, indices = np.unique(clusters, return_index=True) 147 | positions = np.array([np.mean(positions[clusters == u], axis=0) for u in unique]) 148 | 149 | if return_counts: 150 | counts=np.array([np.sum(clusters == u) for u in unique]) 151 | return positions, counts 152 | else: 153 | return positions 154 | 155 | def draw_scalebar(pil_img,scale_length,sampling,units='nm',placement=[5,5],margin=3,bar_height=3, 156 | font=None,bar_color=0,bg_color=None,formatting='1f',anchor='top left'): 157 | 158 | from PIL import ImageDraw 159 | 160 | placement=list(placement) 161 | 162 | draw = ImageDraw.Draw(pil_img) 163 | bar_length=scale_length/sampling 164 | 165 | text='{0:.{formatting}} {1}'.format(scale_length,units,formatting=formatting) 166 | text_size=draw.textsize(text, font=font) 167 | text_spacing=0 168 | 169 | bg_height=text_spacing+bar_height+text_size[1] 170 | 171 | if anchor=='top right': 172 | placement[0]-=margin*2+bar_length 173 | elif anchor=='bottom left': 174 | placement[1]-=margin*2+bg_height 175 | elif anchor=='bottom right': 176 | placement[0]-=margin*2+bar_length 177 | placement[1]-=margin*2+bg_height 178 | 179 | if bg_color is not None: 180 | draw.rectangle([(placement[0],placement[1]), 181 | (placement[0]+bar_length+2*margin,placement[1]+bg_height+2*margin)], fill=bg_color) 182 | 183 | draw.rectangle([(placement[0]+margin,placement[1]+bg_height-bar_height+margin), 184 | (placement[0]+bar_length+margin,placement[1]+bg_height+margin)], fill=bar_color) 185 | 186 | draw.text((placement[0]+margin+bar_length//2-text_size[0]//2,placement[1]+margin),text,bar_color,font=font) 187 | 188 | return pil_img 189 | -------------------------------------------------------------------------------- /pyqstem/wave.py: -------------------------------------------------------------------------------- 1 | import matplotlib.pyplot as plt 2 | from mpl_toolkits.axes_grid1 import make_axes_locatable 3 | from matplotlib.widgets import Slider 4 | import scipy 5 | import scipy.ndimage 6 | import numpy as np 7 | from .detection import detect 8 | 9 | def load(name): 10 | npzfile=np.load(name) 11 | return Wave(npzfile['arr_0'],npzfile['arr_1'],npzfile['arr_2']) 12 | 13 | def view(wave,method='real',nav_axis=2,ind=-1,title=None, 14 | slider=False,ax=None,figsize=(6,6),cmap='gray',create_cbar=True,**kwargs): 15 | 16 | if len(wave.array.shape)==3: 17 | array=np.sum(wave.array,axis=2) 18 | extent=wave.get_extent()[:4] 19 | else: 20 | array=wave.array 21 | extent=wave.get_extent() 22 | 23 | reciprocal_space=False 24 | if method == 'amplitude': 25 | img=np.abs(array) 26 | elif method == 'real': 27 | img=np.real(array) 28 | elif method == 'imaginary': 29 | img=np.imag(array) 30 | elif method == 'phase': 31 | img=np.angle(array) 32 | elif method == 'intensity': 33 | img=np.abs(array)**2 34 | elif method == 'diffraction pattern': 35 | img=np.log(np.abs(np.fft.fftshift(np.fft.fft2(array)))**2) 36 | method = method + ' (log scale)' 37 | reciprocal_space=True 38 | elif method == 'diffractogram': 39 | img=np.log(np.abs(np.fft.fftshift(np.fft.fft2(np.abs(array)**2)))) 40 | method += ' (log scale)' 41 | reciprocal_space=True 42 | else: 43 | raise RuntimeError('Unknown method: {0}'.format(method)) 44 | 45 | if reciprocal_space==True: 46 | labels=['kx','ky','kz'] 47 | units = '1/Angstrom' 48 | extent=wave.get_reciprocal_extent() 49 | else: 50 | labels=['x','y','z'] 51 | units = 'Angstrom' 52 | 53 | if len(img.shape)==3: 54 | img=np.rollaxis(img,nav_axis) 55 | sig_extent=np.delete(extent,[2*nav_axis,2*nav_axis+1]) 56 | nav_extent=extent[2*nav_axis:2*nav_axis+2] 57 | sig_labels=np.delete(labels,nav_axis) 58 | nav_label=labels[nav_axis] 59 | else: 60 | img=img[None,:,:] 61 | sig_extent=extent 62 | sig_labels=labels 63 | 64 | if ax is None: 65 | fig, ax = plt.subplots(figsize=figsize) 66 | 67 | if 'vmin' not in kwargs.keys(): 68 | kwargs['vmin']=img.min() 69 | if 'vmax' not in kwargs.keys(): 70 | kwargs['vmax']=img.max() 71 | 72 | if title is None: 73 | ax.set_title(method) 74 | else: 75 | ax.set_title(title) 76 | 77 | imshow = ax.imshow(img[ind,:,:].T,extent=sig_extent,cmap=cmap,**kwargs) 78 | plt.grid(False) 79 | 80 | if create_cbar: 81 | divider = make_axes_locatable(ax) 82 | cax = divider.append_axes("right", size="5%", pad=0.05) 83 | plt.colorbar(imshow, cax=cax) 84 | 85 | if slider == True: 86 | plt.subplots_adjust(bottom=0.25) 87 | axframe = plt.axes([0.2, 0.08, 0.6, 0.04]) 88 | 89 | slider=Slider(axframe, nav_label, np.min(nav_extent), np.max(nav_extent), valinit=0.) 90 | 91 | sampling=(np.max(nav_extent)-np.min(nav_extent))/(img.shape[0]-1) 92 | 93 | def update(val): 94 | frame = np.min((img.shape[0]-1,np.around(slider.val/sampling))) 95 | imshow.set_data(img[int(frame),:,:].T) 96 | 97 | slider.on_changed(update) 98 | 99 | ax.set_xlabel('{0} [{1}]'.format(sig_labels[0],units)) 100 | ax.set_ylabel('{0} [{1}]'.format(sig_labels[1],units)) 101 | 102 | return [slider] 103 | 104 | class BaseArray(object): 105 | def __init__(self, array, sampling=None): 106 | 107 | self.array=np.array(array,dtype=complex) 108 | 109 | if len(self.array.shape)!=2 | len(self.array.shape)!=3: 110 | raise RuntimeError('Only 2d and 3d arrays are allowed') 111 | 112 | if sampling is not None: 113 | if len(self.array.shape)!=len(sampling): 114 | raise RuntimeError('Array shape does not match number of sampling entries') 115 | 116 | self.sampling=sampling 117 | self.offset=(0,0,0) 118 | 119 | self.refs=[] 120 | 121 | def get_dimensions(self): 122 | dimensions=(self.sampling[0]*self.array.shape[0],self.sampling[1]*self.array.shape[1]) 123 | if len(self.array.shape)==3: 124 | dimensions+=(self.sampling[2]*self.array.shape[2],) 125 | return dimensions 126 | 127 | def get_extent(self): 128 | extent=[self.offset[0],self.array.shape[0]*self.sampling[0]+self.offset[0], 129 | self.offset[1],self.array.shape[1]*self.sampling[1]+self.offset[1]] 130 | if len(self.array.shape)==3: 131 | extent+=[self.offset[2],self.array.shape[2]*self.sampling[2]+self.offset[2]] 132 | return extent 133 | 134 | def get_reciprocal_extent(self): 135 | 136 | dkx=1/(self.sampling[0]*self.array.shape[0]) 137 | dky=1/(self.sampling[1]*self.array.shape[1]) 138 | 139 | extent=[-1/(2*self.sampling[0]),1/(2*self.sampling[0])-dkx, 140 | -1/(2*self.sampling[1]),1/(2*self.sampling[1])-dky] 141 | 142 | if not self.array.shape[0]%2==0: 143 | extent[0]-=.5*dkx 144 | extent[1]-=.5*dkx 145 | if not self.array.shape[1]%2==0: 146 | extent[2]-=.5*dky 147 | extent[3]-=.5*dky 148 | return extent 149 | 150 | class Wave(BaseArray): 151 | 152 | def __init__(self, array, energy, sampling=None, periodic_xy=True): 153 | BaseArray.__init__(self, array, sampling) 154 | self.energy = energy 155 | 156 | @property 157 | def shape(self): 158 | return self.array.shape 159 | 160 | @property 161 | def wavelength(self): 162 | return 0.38783/np.sqrt(self.energy+9.78476*10**(-4)*self.energy**2) 163 | 164 | def z_slice(self,ind=-1): 165 | 166 | if len(self.array.shape)==2: 167 | raise RuntimeError('z_slice() only works for 3d wavefunctions') 168 | 169 | return Wavefunction(self.array[:,:,ind],self.energy,self.sampling[:2],self.offset) 170 | 171 | def apply_ctf(self,ctf): 172 | return ctf.apply(self) 173 | 174 | def resample(self,sampling): 175 | 176 | if len(self.array.shape)==3: 177 | raise RuntimeError('resample() only works for 2d wavefunctions') 178 | 179 | if not isinstance(sampling, (list, tuple)): 180 | sampling=(sampling,)*2 181 | 182 | zoom=(self.sampling[0]/sampling[0],self.sampling[1]/sampling[1]) 183 | 184 | real = scipy.ndimage.interpolation.zoom(np.real(self.array), zoom) 185 | imag = scipy.ndimage.interpolation.zoom(np.imag(self.array), zoom) 186 | 187 | sampling=(self.array.shape[0]*self.sampling[0]/real.shape[0], 188 | self.array.shape[1]*self.sampling[1]/real.shape[1]) 189 | 190 | return Wavefunction(real+1.j*imag,self.energy,sampling,self.offset) 191 | 192 | def detect(self,dose=None,MTF_param=None,MTF_func=None,blur=None,resample=None): 193 | sampling=self.sampling 194 | img=np.abs(self.array)**2 195 | return detect(img,sampling,dose=dose,MTF_param=MTF_param,MTF_func=MTF_func,blur=blur,resample=resample) 196 | 197 | def save(self,name): 198 | np.savez(name,self.array,self.energy,self.sampling) 199 | 200 | def view(self,method='intensity',nav_axis=2,ind=-1,slider=False,ax=None,**kwargs): 201 | 202 | self.refs += view(self,method=method,nav_axis=nav_axis,ind=ind,slider=slider,ax=ax,**kwargs) 203 | 204 | class WaveBundle(object): 205 | 206 | def __init__(self,wave_list=[]): 207 | if isinstance(wave_list,list): 208 | self.wave_list=wave_list 209 | else: 210 | raise RuntimeError('') 211 | 212 | self.refs=[] 213 | 214 | def append(self,wave): 215 | self.wave_list.append(wave) 216 | 217 | def apply_ctf(self,ctf): 218 | wave_list=[ctf.apply(wave) for wave in self.wave_list] 219 | return WaveBundle(wave_list) 220 | 221 | def detect(self,dose=None,MTF_param=None,MTF_func=None,blur=None,resample=None): 222 | wave_arr=np.array([wave.array for wave in self.wave_list]) 223 | sampling=self.wave_list[0].sampling 224 | img=np.mean(np.abs(wave_arr)**2,axis=0) 225 | return detect(img,sampling,dose=dose,MTF_param=MTF_param,MTF_func=MTF_func,blur=blur,resample=resample) 226 | 227 | def view(self,method='intensity',nav_axis=2,ind=-1,slider=False,ax=None,**kwargs): 228 | 229 | wave_arr=np.mean(np.array([wave.array for wave in self.wave_list]),axis=0) 230 | extent=self.wave_list[0].get_extent() 231 | labels=self.wave_list[0].labels 232 | units=self.wave_list[0].units 233 | 234 | self.refs += view(wave_arr,extent,method=method,title=method,labels=labels, 235 | units=units,nav_axis=nav_axis,ind=ind,slider=slider,ax=ax,**kwargs) 236 | 237 | 238 | class Potential(BaseArray): 239 | 240 | def __init__(self, array, sampling, periodic_xy=True, periodic_z=False): 241 | BaseArray.__init__(self, array, sampling) 242 | 243 | self.periodic_xy=periodic_xy 244 | self.periodic_z=periodic_z 245 | 246 | def view(self,method='intensity',nav_axis=2,ind=-1,slider=False,ax=None,**kwargs): 247 | projected = np.sum(self.array,axis=2) 248 | self.refs += view(self,method=method,nav_axis=nav_axis,ind=ind,slider=slider,ax=ax,**kwargs) 249 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup 2 | from setuptools import Extension 3 | from setuptools import find_packages 4 | import platform 5 | from pkg_resources import get_build_platform 6 | from Cython.Build import cythonize 7 | import numpy as np 8 | import os 9 | import sys 10 | 11 | description = "A Python interface to the electron microscopy simulation program QSTEM." 12 | 13 | long_description = """\ 14 | QSTEM is a program for quantitative image simulation in electron microscopy, including TEM, STEM and CBED image simulation. 15 | 16 | This project interfaces the QSTEM code with Python and the Atomic Simulation Environment (ASE) to provide a single environment for building models, simulating and analysing images. 17 | 18 | This package requires that the FFTW library has already been installed. 19 | """ 20 | 21 | 22 | include_dirs = [ 23 | np.get_include(), 24 | os.path.join(os.getcwd(), 'fftw'), 25 | os.path.join(os.getcwd(), 'source/'), 26 | ] 27 | 28 | # Detect Anaconda and use Anaconda's FFTW on Windows. 29 | is_conda = os.path.exists(os.path.join(sys.prefix, 'conda-meta')) 30 | is_windows = get_build_platform() in ['win32', 'win-amd64'] 31 | is_mac = 'macosx' in get_build_platform() 32 | if is_mac: 33 | is_highsierra_or_older = platform.mac_ver()[0] < '10.14' 34 | 35 | if not is_conda and get_build_platform() == 'win32': 36 | # 32-bit Windows and not Anaconda: Use FFTW packaged with PyQSTEM 37 | if sys.version_info[0] == 3: 38 | library_dirs = ['fftw/win32'] 39 | elif sys.version_info[0] == 2: 40 | library_dirs = ['fftw/win32/dll'] 41 | libraries = ['libfftw3-3', 'libfftw3f-3', 'libfftw3l-3'] 42 | elif not is_conda and get_build_platform() == 'win-amd64': 43 | # 64-bit Windows and not Anaconda: Use FFTW packaged with PyQSTEM 44 | if sys.version_info[0] == 3: 45 | library_dirs = ['fftw/win64'] 46 | elif sys.version_info[0] == 2: 47 | library_dirs = ['fftw/win64/dll'] 48 | libraries = ['libfftw3-3', 'libfftw3f-3', 'libfftw3l-3'] 49 | else: 50 | # Linux, MacOS and Anaconda on Windows. 51 | library_dirs = [] 52 | libraries = ['fftw3','fftw3f'] 53 | 54 | sources = ['memory_fftw3.cpp','data_containers.cpp','imagelib_fftw3.cpp', 55 | 'stemlib.cpp','stemutil.cpp','fileio_fftw3.cpp','matrixlib.cpp','readparams.cpp'] 56 | 57 | sources = ['source/' + x for x in sources] 58 | 59 | sources += ['pyqstem/qstem_interface.pyx','pyqstem/QSTEM.cpp'] 60 | 61 | compargs = [] 62 | linkargs = [] 63 | if is_windows: 64 | compargs += ['-D MS_WIN64'] 65 | else: 66 | compargs += ['-std=c++11'] 67 | if is_mac and is_highsierra_or_older: 68 | # These options are needed by the clang compiler on macOS X 10.13 69 | # 'High Sierra' or older, it is default on 10.14 or newer. 70 | compargs += ['-stdlib=libc++'] 71 | linkargs += ['-stdlib=libc++'] 72 | 73 | 74 | setup(name='pyqstem', 75 | packages = find_packages(), 76 | version = '1.0.3', 77 | description=description, 78 | long_description=long_description, 79 | maintainer="Jacob Madsen", 80 | maintainer_email="jacob.jma@gmail.com", 81 | url="https://github.com/jacobjma/PyQSTEM", 82 | license='GPLv3', 83 | data_files = [("", ["License.txt"])], 84 | platforms = ["Windows", "Linux", "Mac OS-X", "Unix"], 85 | install_requires=['matplotlib!=3.0.0', 'ase', 'Cython', 'scikit-image', 'pillow'], 86 | ext_modules=cythonize(Extension('pyqstem.qstem_interface', 87 | sources=sources, 88 | library_dirs=library_dirs, 89 | libraries=libraries, 90 | include_dirs=include_dirs, 91 | extra_compile_args=compargs, 92 | extra_link_args=linkargs, 93 | language='c++')), 94 | 95 | ) 96 | -------------------------------------------------------------------------------- /source/data_containers.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | QSTEM - image simulation for TEM/STEM/CBED 3 | Copyright (C) 2000-2010 Christoph Koch 4 | Copyright (C) 2010-2013 Christoph Koch, Michael Sarahan 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | */ 19 | 20 | #include "stdio.h" 21 | #include 22 | #include "data_containers.h" 23 | 24 | WAVEFUNC::WAVEFUNC(int x, int y, float_tt resX, float_tt resY) : 25 | detPosX(0), 26 | detPosY(0), 27 | iPosX(0), 28 | iPosY(0), 29 | thickness(0.0), 30 | nx(x), 31 | ny(y), 32 | resolutionX(resX), 33 | resolutionY(resY) 34 | { 35 | char waveFile[256]; 36 | const char *waveFileBase = "mulswav"; 37 | #if FLOAT_PRECISION == 1 38 | diffpat = float2D(nx,ny,"diffpat"); 39 | avgArray = float2D(nx,ny,"avgArray"); 40 | #else 41 | diffpat = double2D(nx,ny,"diffpat"); 42 | avgArray = double2D(nx,ny,"avgArray"); 43 | #endif 44 | 45 | m_imageIO=ImageIOPtr(new CImageIO(nx, ny, thickness, resolutionX, resolutionY)); 46 | 47 | 48 | #if FLOAT_PRECISION == 1 49 | wave = complex2Df(nx, ny, "wave"); 50 | fftPlanWaveForw = fftwf_plan_dft_2d(nx,ny,wave[0],wave[0],FFTW_FORWARD, FFTW_ESTIMATE); 51 | fftPlanWaveInv = fftwf_plan_dft_2d(nx,ny,wave[0],wave[0],FFTW_BACKWARD, FFTW_ESTIMATE); 52 | #else 53 | wave = complex2D(nx, ny, "wave"); 54 | fftPlanWaveForw = fftw_plan_dft_2d(nx,ny,wave[0],wave[0],FFTW_FORWARD, 55 | fftMeasureFlag); 56 | fftPlanWaveInv = fftw_plan_dft_2d(nx,ny,wave[0],wave[0],FFTW_BACKWARD, 57 | fftMeasureFlag); 58 | #endif 59 | 60 | sprintf(waveFile,"%s.img",waveFileBase); 61 | strcpy(fileout,waveFile); 62 | sprintf(fileStart,"mulswav.img"); 63 | } 64 | 65 | void WAVEFUNC::WriteWave(const char *fileName, const char *comment, 66 | std::vectorparams) 67 | { 68 | m_imageIO->SetComment(comment); 69 | m_imageIO->SetResolution(resolutionX, resolutionY); 70 | m_imageIO->SetParams(params); 71 | m_imageIO->SetThickness(thickness); 72 | m_imageIO->WriteComplexImage((void **)wave, fileName); 73 | } 74 | 75 | void WAVEFUNC::WriteDiffPat(const char *fileName, const char *comment, 76 | std::vectorparams) 77 | { 78 | m_imageIO->SetComment(comment); 79 | m_imageIO->SetResolution(1.0/(nx*resolutionX), 1.0/(ny*resolutionY)); 80 | m_imageIO->SetParams(params); 81 | m_imageIO->SetThickness(thickness); 82 | m_imageIO->WriteRealImage((void**)diffpat, fileName); 83 | } 84 | 85 | void WAVEFUNC::WriteAvgArray(const char *fileName, const char *comment, 86 | std::vectorparams) 87 | { 88 | m_imageIO->SetComment(comment); 89 | m_imageIO->SetResolution(1.0/(nx*resolutionX), 1.0/(ny*resolutionY)); 90 | m_imageIO->SetParams(params); 91 | m_imageIO->SetThickness(thickness); 92 | m_imageIO->WriteRealImage((void **)avgArray, fileName); 93 | } 94 | 95 | void WAVEFUNC::ReadWave(const char *fileName) 96 | { 97 | // printf("Debug Wavefunc::ReadWave\n"); 98 | m_imageIO->ReadImage((void **)wave, nx, ny, fileName); 99 | } 100 | 101 | void WAVEFUNC::ReadDiffPat(const char *fileName) 102 | { 103 | m_imageIO->ReadImage((void **)diffpat, nx, ny, fileName); 104 | } 105 | 106 | void WAVEFUNC::ReadAvgArray(const char *fileName) 107 | { 108 | m_imageIO->ReadImage((void **)avgArray, nx, ny, fileName); 109 | } 110 | 111 | 112 | 113 | Detector::Detector(int nx, int ny, float_tt resX, float_tt resY) : 114 | error(0), 115 | shiftX(0), 116 | shiftY(0), 117 | Navg(0), 118 | thickness(0) 119 | { 120 | #if FLOAT_PRECISION == 1 121 | image = float2D(nx,ny,"ADFimag"); 122 | image2 = float2D(nx,ny,"ADFimag"); 123 | #else 124 | image = double2D(nx,ny,"ADFimag"); 125 | image2 = double2D(nx,ny,"ADFimag"); 126 | #endif 127 | m_imageIO=ImageIOPtr(new CImageIO(nx, ny, thickness, resX, resY, std::vector(2+nx*ny), "STEM image")); 128 | } 129 | 130 | void Detector::WriteImage(const char *fileName) 131 | { 132 | m_imageIO->SetThickness(thickness); 133 | m_imageIO->WriteRealImage((void **)image, fileName); 134 | } 135 | 136 | void Detector::SetThickness(float_tt t) 137 | { 138 | thickness=t; 139 | } 140 | 141 | void Detector::SetParameter(int index, double value) 142 | { 143 | m_imageIO->SetParameter(index, value); 144 | } 145 | 146 | void Detector::SetParams(std::vector params) 147 | { 148 | m_imageIO->SetParams(params); 149 | } 150 | 151 | void Detector::SetComment(const char *comment) 152 | { 153 | m_imageIO->SetComment(comment); 154 | } 155 | -------------------------------------------------------------------------------- /source/data_containers.h: -------------------------------------------------------------------------------- 1 | /* 2 | QSTEM - image simulation for TEM/STEM/CBED 3 | Copyright (C) 2000-2010 Christoph Koch 4 | Copyright (C) 2010-2013 Christoph Koch, Michael Sarahan 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | */ 19 | 20 | #ifndef DATA_CONTAINERS_H 21 | #define DATA_CONTAINERS_H 22 | 23 | #include 24 | #include "stemtypes_fftw3.h" 25 | #include "imagelib_fftw3.h" 26 | #include 27 | #include 28 | 29 | // a structure for a probe/parallel beam wavefunction. 30 | // Separate from mulsliceStruct for parallelization. 31 | class WAVEFUNC 32 | { 33 | // shared pointer to 34 | ImageIOPtr m_imageIO; 35 | public: 36 | int iPosX,iPosY; /* integer position of probe position array */ 37 | int nx, ny; /* size of diffpat arrays */ 38 | int detPosX,detPosY; 39 | char fileStart[512]; 40 | char fileout[512]; 41 | float_tt **diffpat; 42 | float_tt **avgArray; 43 | char avgName[512]; 44 | float_tt thickness; 45 | float_tt intIntensity; 46 | // These are not used for anything aside from when saving files. 47 | float_tt resolutionX, resolutionY; 48 | 49 | #if FLOAT_PRECISION == 1 50 | fftwf_plan fftPlanWaveForw,fftPlanWaveInv; 51 | fftwf_complex **wave; /* complex wave function */ 52 | #else 53 | fftw_plan fftPlanWaveForw,fftPlanWaveInv; 54 | fftw_complex **wave; /* complex wave function */ 55 | #endif 56 | 57 | public: 58 | // initializing constructor: 59 | WAVEFUNC(int nx, int ny, float_tt resX, float_tt resY); 60 | // define a copy constructor to create new arrays 61 | WAVEFUNC(const WAVEFUNC &obj); 62 | //WAVEFUNC( WAVEFUNC& other ); 63 | 64 | void WriteWave(const char *fileName, const char *comment="Wavefunction", 65 | std::vectorparams = std::vector()); 66 | void WriteDiffPat(const char *fileName, const char *comment="Diffraction Pattern", 67 | std::vectorparams = std::vector()); 68 | void WriteAvgArray(const char *fileName, const char *comment="Average Array", 69 | std::vectorparams = std::vector()); 70 | 71 | void ReadWave(const char *fileName); 72 | void ReadDiffPat(const char *fileName); 73 | void ReadAvgArray(const char *fileName); 74 | }; 75 | 76 | //typedef boost::shared_ptr WavePtr; 77 | typedef std::shared_ptr WavePtr; 78 | 79 | 80 | 81 | class Detector { 82 | ImageIOPtr m_imageIO; 83 | float_tt thickness; 84 | public: 85 | int Navg; 86 | float_tt **image; // place for storing avg image = sum(data)/Navg 87 | float_tt **image2; // we will store sum(data.^2)/Navg 88 | float_tt rInside,rOutside; 89 | float_tt k2Inside,k2Outside; 90 | const char* name; 91 | 92 | public: 93 | Detector(int nx, int ny, float_tt resX, float_tt resY); 94 | void WriteImage(const char *fileName); 95 | void SetParams(std::vector params); 96 | void SetParameter(int index, double value); 97 | void SetThickness(float_tt t); 98 | void SetComment(const char *comment); 99 | float_tt error; 100 | float_tt shiftX,shiftY; 101 | }; 102 | 103 | //typedef boost::shared_ptr DetectorPtr; 104 | typedef std::shared_ptr DetectorPtr; 105 | 106 | 107 | class MULS { 108 | public: 109 | int mode; /* determine the mode that this program runs in 110 | * can be STEM, TEM, CBED ... */ 111 | int printLevel; /* Flag indicating how much output should appear 112 | * in the window. */ 113 | int saveLevel; 114 | int complete_pixels; //the number of pixels completed so far 115 | 116 | #if FLOAT_PRECISION == 1 117 | fftwf_plan fftPlanPotInv,fftPlanPotForw; 118 | // wave moved to probeStruct 119 | //fftwf_complex **wave; /* complex wave function */ 120 | fftwf_complex ***trans; 121 | #else 122 | fftw_plan fftPlanPotInv,fftPlanPotForw; 123 | // wave moved to probeStruct 124 | //fftw_complex **wave; /* complex wave function */ 125 | fftw_complex ***trans; 126 | #endif 127 | WavePtr wave; 128 | 129 | real **diffpat; 130 | real czOffset; 131 | real xOffset; 132 | real yOffset; 133 | 134 | char cin2[1024]; /* stacking sequence */ 135 | char fileBase[512]; 136 | char **filein; /* array of input potential files */ 137 | 138 | char fileWaveIn[512]; // RAM: input .IMG file for entry wavefunction 139 | int lpartl, lstartl; /* flags indicating partial 140 | coherence */ 141 | char atomPosFile[512]; 142 | /* and start wavefunction */ 143 | float_tt v0; /* inc. beam energy */ 144 | float_tt resolutionX; /* real space pixelsize for wave function and potential */ 145 | float_tt resolutionY; /* real space pixelsize for wave function and potential */ 146 | float_tt ctiltx,ctilty,ctiltz; /* crystal tilt in mrad */ 147 | char cfgFile[512]; /* file name for writing tilted atomic configuration */ 148 | float_tt cubex,cubey,cubez; /* dimension of crystal cube, if zero, then nx,ny,nz * 149 | * will be used */ 150 | int adjustCubeSize; 151 | float_tt btiltx,btilty; /* beam tilt in mrad*/ 152 | int tiltBack; /* tilt back the wave below the specimen */ 153 | int *hbeam,*kbeam; /* arrays to hold recorded 154 | beam indicies */ 155 | int lbeams; /* flag indicating, whether 156 | to record beams */ 157 | char filebeam[512]; /* file, that beams get recorded in */ 158 | int nbout; /* number of recorded beams */ 159 | 160 | //int nslic0; /* slice counter */ 161 | int mulsRepeat1; /* # of times to repeat structure */ 162 | int mulsRepeat2; /* for REFINE mode # of mulsRun repeats */ 163 | int slices; /* number of different slices */ 164 | int centerSlices; /* flag indicating how to cut the sample */ 165 | float_tt **pendelloesung; /* pendelloesung plot for REFINE mode */ 166 | float_tt ax,by,c; /* lattice parameters */ 167 | float_tt cAlpha,cBeta,cGamma; 168 | double **Mm; /* metric matrix Mm(ax,by,cz,alpha,beta,gamma) */ 169 | int nCellX,nCellY,nCellZ; /* number of unit cells in x-y-z dir*/ 170 | int natom; /* number of atoms in "atoms" */ 171 | atom *atoms; /* 3D atoms array */ 172 | float_tt atomRadius; /* for atom potential boxes */ 173 | float_tt potOffsetX,potOffsetY; /* offset of potential array from zero */ 174 | float_tt potSizeX,potSizeY; /* real space dimensions of potential array in A */ 175 | int potNx,potNy; /* size of projected potential in pixels */ 176 | int nx,ny; /* size of wave function arrays */ 177 | int avgCount; 178 | //float_tt thickness; 179 | 180 | float_tt C5; 181 | float_tt dE_E; 182 | float_tt dV_V; 183 | float_tt dI_I; 184 | float_tt alpha; 185 | float_tt sourceRadius; 186 | float_tt Cc; 187 | float_tt df0; /* defocus */ 188 | float_tt astigMag; /* astigmatism*/ 189 | float_tt astigAngle; /* angle of astigmatism */ 190 | 191 | int ismoth; /* smoothen the probe wave function */ 192 | int gaussFlag; 193 | float_tt gaussScale; 194 | int showProbe; 195 | int displayProgInterval; /* show progress every .. beam positions */ 196 | int displayPotCalcInterval; /* show progress every .. beam positions */ 197 | 198 | float_tt beamCurrent; // pico Ampere 199 | float_tt dwellTime; // msec 200 | float_tt electronScale; // number of electrons 201 | 202 | 203 | int totalSliceCount; 204 | int outputInterval; // output results every n slices 205 | 206 | float_tt aobj; /* obj aperture */ 207 | float_tt aAIS; /* condensor aperture in A (projected size, */ 208 | /* for Koehler illumination) */ 209 | // float_tt areaAIS; /* fractional area illuminated by AIS (def=1) */ 210 | float_tt Cs; /* spher. aberration */ 211 | ///////////////////////////////////////////// 212 | // more aberrations: 213 | float_tt a33; 214 | float_tt a31; 215 | float_tt a44; 216 | float_tt a42; 217 | float_tt a55; 218 | float_tt a53; 219 | float_tt a51; 220 | float_tt a66; 221 | float_tt a64; 222 | float_tt a62; 223 | float_tt phi33; 224 | float_tt phi31; 225 | float_tt phi44; 226 | float_tt phi42; 227 | float_tt phi55; 228 | float_tt phi53; 229 | float_tt phi51; 230 | float_tt phi66; 231 | float_tt phi64; 232 | float_tt phi62; 233 | 234 | float_tt acmax,acmin; 235 | float_tt sigmaf; 236 | float_tt dfdelt; 237 | float_tt dfa2,dfa3; 238 | float_tt dfa2phi,dfa3phi; 239 | float_tt chi,phi; 240 | float_tt *sparam; 241 | 242 | int saveFlag; /* flag indicating, whether to save the result */ 243 | float_tt rmin,rmax; /* min and max of real part */ 244 | float_tt aimin,aimax; /* min and max of imag part */ 245 | float_tt *kx2,*ky2,k2max,*kx,*ky; 246 | 247 | int nlayer; 248 | float_tt *cz; 249 | float_tt sliceThickness; 250 | int onlyFresnel; 251 | int startSpherical; 252 | float_tt startDistance; 253 | float_tt maxAngle; 254 | float_tt gaussWidth; 255 | float_tt defInfinity; 256 | int accumulateIntensity; 257 | int deconvolute; 258 | int showPhaseplate; 259 | int normHolog; 260 | int gaussianProp; /* convolute fresnel propagator with gaussian or not */ 261 | int nonPeriodZ; /* for slicecell (make non periodic in Z */ 262 | int nonPeriod; /* for slicecell (make non periodic in x,y */ 263 | int bandlimittrans; /* flag for bandwidth limiting transmission function */ 264 | int fftpotential; /* flag indicating that we should use FFT for V_proj calculation */ 265 | int plotPotential; 266 | int storeSeries; 267 | int tds; 268 | int Einstein; /* if set (default=set), the Einstein model will be used */ 269 | char phononFile[512]; /* file name for detailed phonon modes */ 270 | int atomKinds; 271 | int *Znums; 272 | double **rPotential; /* array containing real space potential LUT for each atom kind present */ 273 | double *sfkArray; 274 | double **sfTable; 275 | int sfNk; /* number of k-points in sfTable and sfkArray */ 276 | double *u2,*u2avg; /* (current/averaged) rms displacement of atoms */ 277 | float_tt tds_temp; 278 | int savePotential; 279 | int saveTotalPotential; 280 | int readPotential; 281 | float_tt scanXStart,scanXStop,scanYStart,scanYStop; 282 | int scanXN,scanYN; 283 | float_tt intIntensity; 284 | double imageGamma; 285 | char folder[1024]; 286 | int avgRuns; // RAM: What is this? 287 | int potential3D; 288 | int scatFactor; 289 | int Scherzer; 290 | std::vector chisq; 291 | int webUpdate; 292 | int cellDiv; 293 | int equalDivs; // this flag indicates whether we can reuse already pre-calculated potential data 294 | 295 | /* Parameters for STEM-detectors */ 296 | int detectorNum; 297 | /* we will alow as many detector 298 | definitions as the user wants */ 299 | std::vector > detectors; 300 | //DETECTOR *detectors; 301 | int save_output_flag; 302 | 303 | double *dE_EArray; 304 | 305 | // Tomography parameters: 306 | double tomoTilt; // current tilt in tomography series 307 | double tomoStart; // in rad 308 | double tomoStep; // in rad 309 | int tomoCount; // number of diffraction patterns. 310 | double zoomFactor; // increases the size of the super-box in x,y, in order to 311 | // make full use of atoms present, creates vacuum edge around sample. 312 | 313 | }; 314 | 315 | #endif 316 | -------------------------------------------------------------------------------- /source/fileio_fftw3.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacobjma/PyQSTEM/9172962b9ed51769a97c90278f463af3ec89181e/source/fileio_fftw3.cpp -------------------------------------------------------------------------------- /source/fileio_fftw3.h: -------------------------------------------------------------------------------- 1 | /* 2 | QSTEM - image simulation for TEM/STEM/CBED 3 | Copyright (C) 2000-2010 Christoph Koch 4 | Copyright (C) 2010-2013 Christoph Koch, Michael Sarahan 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | */ 19 | 20 | #ifndef FILEIO_H 21 | #define FILEIO_H 22 | 23 | #include "data_containers.h" 24 | #include "stemtypes_fftw3.h" 25 | 26 | atom *readUnitCell(int *natom,char *fileName,MULS *muls,int handleVacancies); 27 | void replicateUnitCell(int ncoord,int *natom,MULS *muls,atom* atoms,int handleVacancies); 28 | atom *tiltBoxed(int ncoord,int *natom, MULS *muls,atom *atoms,int handleVacancies); 29 | int writePDB(atom *atoms,int natoms,char *fileName,MULS *muls); 30 | int writeCFG(atom *atoms,int natoms,char *fileName,MULS *muls); 31 | // write CFG file using atomic positions stored in pos, Z's in Znum and DW-factors in dw 32 | // the unit cell is assumed to be cubic 33 | int writeCFGFractCubic(double *pos,int *Znum,double *dw,int natoms,char *fileName, 34 | double a,double b,double c); 35 | int readCubicCFG(double **pos,double **dw, int **Znum, double *ax,double *by,double *cz, 36 | double ctiltx, double ctilty); 37 | 38 | void writeSTEMinput(char* stemFile,char *cfgFile,MULS *muls); 39 | 40 | /* Helper functions for above functions: */ 41 | int ReadLine( FILE* fpRead, char* cRead, int cMax, const char *mesg ); 42 | int getZNumber(char *element); 43 | int readCFGCellParams(MULS *muls, double **Mm, char *fileName); 44 | int readCSSRCellParams(MULS *muls, double **Mm, char *fileName); 45 | 46 | void writeFrameWork(FILE *fp,superCellBox superCell); 47 | void writeAmorphous(FILE *fp,superCellBox superCell,int nstart,int nstop); 48 | 49 | double gasdev(long *idum); 50 | double ran1(long *idum); 51 | float ran(long *idum); 52 | int atomCompareZYX(const void *atPtr1,const void *atPtr2); 53 | int atomCompareZnum(const void *atPtr1,const void *atPtr2); 54 | #endif /* FILEIO_H */ 55 | -------------------------------------------------------------------------------- /source/imagelib_fftw3.cpp: -------------------------------------------------------------------------------- 1 | #include /* ANSI-C libraries */ 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #include 10 | 11 | //#include "boost/shared_ptr.hpp" 12 | 13 | #include "stemtypes_fftw3.h" 14 | #include "imagelib_fftw3.h" 15 | #include "memory_fftw3.h" /* memory allocation routines */ 16 | 17 | #define _CRTDBG_MAP_ALLOC 18 | #include /* ANSI C libraries */ 19 | #include 20 | #ifdef WIN32 21 | #if _DEBUG 22 | #include 23 | #endif 24 | #endif 25 | 26 | #define VERSION 1 // please update this number, if anything in the image header 27 | // format changes. 28 | 29 | CImageIO::CImageIO(int nx, int ny) : 30 | m_headerSize(56), 31 | m_params(std::vector()), 32 | m_paramSize(0), 33 | m_nx(nx), 34 | m_ny(ny), 35 | m_version(VERSION), 36 | m_t(0.0), 37 | m_dx(1.0), 38 | m_dy(1.0), 39 | m_comment("") 40 | { 41 | }; 42 | 43 | CImageIO::CImageIO(int nx, int ny, double t, double dx, double dy, 44 | std::vector params, std::string comment) : 45 | m_headerSize(56), 46 | m_params(params), 47 | m_nx(nx), 48 | m_ny(ny), 49 | m_version(VERSION), 50 | m_t(t), 51 | m_dx(dx), 52 | m_dy(dy), 53 | m_comment("") 54 | { 55 | }; 56 | 57 | void CImageIO::WriteComplexImage(void **pix, const char *fileName) { 58 | m_dataSize = 2*sizeof(float_tt); 59 | m_complexFlag = 1; 60 | 61 | WriteData(pix, fileName); 62 | } 63 | 64 | void CImageIO::WriteRealImage(void **pix, const char *fileName) { 65 | m_dataSize = sizeof(float_tt); 66 | m_complexFlag = 0; 67 | 68 | WriteData(pix, fileName); 69 | } 70 | 71 | void CImageIO::WriteData(void **pix, const char *fileName) 72 | { 73 | //FILE *fp; 74 | std::fstream file(fileName, std::ios::out|std::ios::binary); 75 | 76 | // Sychronize lengths of comments and parameters 77 | m_paramSize = m_params.size(); 78 | m_commentSize = m_comment.size(); 79 | 80 | if(!file.is_open()) 81 | { 82 | sprintf(m_buf,"WriteData: Could not open file %s for writing\n",fileName); 83 | throw std::runtime_error(m_buf); 84 | } 85 | 86 | // TODO: should we write each element individually for clarity? 87 | // write the 56-byte header 88 | printf( "DEBUG: CImageIO::WriteData: filename is %s \n", fileName ); 89 | file.write(reinterpret_cast(this), m_headerSize); 90 | /* 91 | fwrite((void *)&m_headerSize, 4, 1, fp); 92 | fwrite((void *)&m_paramSize, 4, 1, fp); 93 | fwrite((void *)&m_commentSize, 4, 1, fp); 94 | fwrite((void *)&m_nx, 4, 1, fp); 95 | fwrite((void *)&m_ny, 4, 1, fp); 96 | fwrite((void *)&m_complexFlag, 4, 1, fp); 97 | fwrite((void *)&m_dataSize, 4, 1, fp); 98 | fwrite((void *)&m_version, 4, 1, fp); 99 | fwrite((void *)&m_t, 8, 1, fp); 100 | fwrite((void *)&m_dx, 8, 1, fp); 101 | fwrite((void *)&m_dy, 8, 1, fp); 102 | */ 103 | if (m_paramSize>0) 104 | { 105 | file.write(reinterpret_cast(&m_params[0]), m_paramSize*sizeof(double)); 106 | } 107 | file.write(m_comment.c_str(), m_commentSize); 108 | file.write(reinterpret_cast(pix[0]), m_nx*m_ny*m_dataSize); 109 | file.close(); 110 | } 111 | 112 | void CImageIO::ReadHeader(const char *fileName) 113 | { 114 | FILE *fpHead; 115 | 116 | 117 | fpHead = fopen( fileName, "rb" ); 118 | if ( fpHead == NULL ) 119 | { 120 | perror("Error"); 121 | printf( "ReadHeader: Could not open file %s for reading header.\n", fileName ); 122 | 123 | sprintf(m_buf, "Could not open file %s for reading header.\n",fileName); 124 | throw std::runtime_error(m_buf); 125 | } 126 | 127 | 128 | //printf("RH Debug 2 \n"); 129 | fread( (void*)this, 1, 56, fpHead ); 130 | if (m_paramSize>0) 131 | { 132 | m_params=std::vector(m_paramSize); 133 | fread( (void *)&m_params[0], sizeof(double), m_paramSize, fpHead ); 134 | } 135 | if (m_commentSize>0) 136 | { 137 | fread( (void*)m_buf, 1, m_commentSize, fpHead ); 138 | m_comment = std::string(m_buf); 139 | } 140 | 141 | 142 | 143 | if ( fpHead != NULL ) fclose( fpHead ); 144 | } 145 | 146 | void CImageIO::ReadImage(void **pix, int nx, int ny, const char *fileName) 147 | { 148 | FILE *fpImage; 149 | size_t nRead=0; 150 | int trial=0,maxTrial=3,freadError=0; 151 | 152 | //printf("Debug A\n"); 153 | // sets the important info from the header - most importantly, where to start reading the image. 154 | ReadHeader(fileName); 155 | 156 | //printf("Debug B\n"); 157 | do { 158 | if ( (fpImage = fopen( fileName, "rb" )) == NULL ) { 159 | printf("Could not open file %s for reading\n",fileName); 160 | /* wait a short while */ 161 | while (nRead < 1e5) nRead++; 162 | } 163 | else 164 | { 165 | if ((m_nx != nx)||(m_ny != nx)) { 166 | sprintf(m_buf, "readImage: image size mismatch nx = %d (%d), ny = %d (%d)\n", m_nx,nx,m_ny,ny); 167 | throw std::runtime_error(std::string(m_buf)); 168 | } 169 | 170 | // Seek to the location of the actual data 171 | fseek( fpImage, 56 + (m_commentSize)+(2 * m_paramSize), SEEK_SET ); 172 | 173 | // this is type-agnostic - the type interpretation is done by the 174 | // function sending in the pointer. It casts it as void for the reading, 175 | // but it then "knows" that it is double, complex, whatever, based on the 176 | // type of the data that it passed into this function. 177 | // 178 | // Complex data is determined/communicated by the m_complexFlag, which is read in the header. 179 | // RAM: I am concerned that this does not read in the proper size in x for complex data, where x should be 2* 180 | // FIXED: added if/else test 181 | // printf( "DEBUG ReadImage m_complexFlag = %d \n", m_complexFlag ); 182 | // printf( "DEBUG ReadImage (nx,ny) = %d, %d \n", m_nx, m_ny ); 183 | // printf( "DEBUG ReadImage m_dataSize = %d \n", m_dataSize ); 184 | // printf( "DEBUG ReadImage (size_t)(nx*ny) = %d \n", (size_t)(nx*ny) ); 185 | 186 | // RAM: added if/else to fix complex image incomplete read bug 187 | if ( m_complexFlag == 0 ) 188 | { 189 | printf( "DEBUG ReadImage parsing real data\n" ); 190 | nRead = fread( pix[0], sizeof(m_dataSize), (size_t)(nx*ny), fpImage ); 191 | if ( nRead != nx*ny ) 192 | { 193 | freadError = 1; 194 | sprintf( m_buf, "Error while reading data from file %s:" 195 | " %d (of %d specified) elements read\n" 196 | "EOF: %d, Ferror: %d, dataSize: %d\n", 197 | fileName, nRead, nx*ny, feof( fpImage ), ferror( fpImage ), m_dataSize ); 198 | fclose( fpImage ); 199 | fpImage = NULL; 200 | throw std::runtime_error( std::string( m_buf ) ); 201 | } 202 | } 203 | else 204 | { // RAM: complex data 205 | printf( "DEBUG ReadImage parsing complex data\n" ); 206 | nRead = fread( pix[0], sizeof(m_dataSize), (size_t)(nx*ny*2), fpImage ); 207 | if ( nRead != nx*ny*2 ) 208 | { 209 | freadError = 1; 210 | sprintf( m_buf, "Error while reading data from file %s:" 211 | " %d (of %d specified) elements read\n" 212 | "EOF: %d, Ferror: %d, dataSize: %d\n", 213 | fileName, nRead, nx*ny, feof( fpImage ), ferror( fpImage ), m_dataSize ); 214 | fclose( fpImage ); 215 | fpImage = NULL; 216 | throw std::runtime_error( std::string( m_buf ) ); 217 | } 218 | } 219 | } 220 | /* we will try three times to read this file. */ 221 | } while ((freadError > 0) && (++trial < maxTrial)); 222 | 223 | if ( fpImage != NULL ) fclose( fpImage ); 224 | } 225 | 226 | /***************************************************************** 227 | * Image header routines 228 | ****************************************************************/ 229 | 230 | void CImageIO::SetComment(std::string comment) 231 | { 232 | m_comment = comment; 233 | } 234 | 235 | void CImageIO::SetThickness(double thickness) 236 | { 237 | m_t = thickness; 238 | } 239 | 240 | void CImageIO::SetResolution(double resX, double resY) 241 | { 242 | m_dx = resX; 243 | m_dy = resY; 244 | } 245 | 246 | void CImageIO::SetParams(std::vector params) 247 | { 248 | m_params=params; 249 | } 250 | 251 | void CImageIO::SetParameter(int index, double value) 252 | { 253 | if (index < m_params.size()) 254 | m_params[index] = value; 255 | else 256 | throw std::runtime_error("Tried to set out of bounds parameter."); 257 | } 258 | 259 | -------------------------------------------------------------------------------- /source/imagelib_fftw3.h: -------------------------------------------------------------------------------- 1 | #ifndef IMAGELIB_H 2 | #define IMAGELIB_H 3 | 4 | #include "stemtypes_fftw3.h" 5 | #include 6 | #include 7 | #include 8 | #include 9 | //#include "boost/shared_ptr.hpp" 10 | 11 | /************************************************************** 12 | * Here is how to use the new image writing routines 13 | * 14 | * ImageIOPtr imageio = ImageIOPtr(new CImageIO(nx,ny)) 15 | * 16 | * imageIO->WriteRealImage((void**)real_image,filename); 17 | * imageIO->WriteComplexImage((void**)complex_image,filename); 18 | * 19 | ************************************************************** 20 | * Reading an image works like this: 21 | * 22 | * ImageIOPtr imageio = ImageIOPtr(new CImageIO(nx,ny)) 23 | * imageio->ReadImage((void **)pix,nx,ny,fileName); 24 | * 25 | * Note that header parameters are persistent on any object. You 26 | * should use the various Set* functions to set parameters as 27 | * necessary. You should not need to read values from this class - 28 | * only set them. They will be recorded to any file saved from this 29 | * this object. 30 | **************************************************************/ 31 | 32 | class CImageIO { 33 | int m_headerSize; // first byte of image will be size of image header (in bytes) 34 | // This is the size without the data, parameters, and comment!!! 35 | int m_paramSize; // number of additional parameters 36 | int m_commentSize; // length of comment string 37 | int m_nx,m_ny; 38 | int m_complexFlag; 39 | int m_dataSize; // size of one data element in bytes (e.g. complex double: 16) 40 | int m_version; // The version flag will later help to find out how to 41 | // distinguish between images produced by different versions of stem 42 | double m_t; // thickness 43 | double m_dx,m_dy; // size of one pixel 44 | std::vector m_params; // array for additional parameters 45 | std::string m_comment; // comment of prev. specified length 46 | char m_buf[200]; // General purpose temporary text buffer 47 | public: 48 | CImageIO(int nx, int ny); 49 | CImageIO(int nx, int ny, double t, double dx, double dy, 50 | std::vector params=std::vector(), 51 | std::string comment=""); 52 | 53 | void WriteRealImage(void **pix, const char *fileName); 54 | void WriteComplexImage(void **pix, const char *fileName); 55 | void ReadImage(void **pix, int nx, int ny, const char *fileName); 56 | 57 | //void WriteImage( std::string fileName); 58 | 59 | void SetComment(std::string comment); 60 | void SetThickness(double thickness); 61 | void SetParams(std::vector params); 62 | void SetParameter(int index, double value); 63 | void SetResolution(double resX, double resY); 64 | private: 65 | void WriteData(void **pix, const char *fileName); 66 | // reads in the header; returns the byte offset at which we should start reading image data. 67 | void ReadHeader(const char *fileName); 68 | }; 69 | 70 | //typedef boost::shared_ptr ImageIOPtr; 71 | typedef std::shared_ptr ImageIOPtr; 72 | 73 | #endif 74 | -------------------------------------------------------------------------------- /source/matrixlib.h: -------------------------------------------------------------------------------- 1 | /* 2 | QSTEM - image simulation for TEM/STEM/CBED 3 | Copyright (C) 2000-2010 Christoph Koch 4 | Copyright (C) 2010-2013 Christoph Koch, Michael Sarahan 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | */ 19 | 20 | #ifndef MATRIXLIB_H 21 | #define MATRIXLIB_H 22 | 23 | #include "stemtypes_fftw3.h" 24 | #include "data_containers.h" 25 | 26 | #define PI 3.1415926535898 27 | #define PI180 1.7453292519943e-2 28 | 29 | void ludcmp(double **a, int n, int *indx, double *d); 30 | void lubksb(double **a, int n, int *indx, double b[]); 31 | double det_3x3 (const double *mat); 32 | void inverse_3x3 (double *res, const double *a); 33 | void trans_3x3 (double *Mt, const double *Ms); 34 | 35 | // svdcmp1 uses the NR unit-offset vectors :-( 36 | void svdcmp1(double **a, int m, int n, double w[], double **v); 37 | double pythag(double a, double b); 38 | 39 | /* vector functions: 40 | */ 41 | void crossProduct(const double *a, const double *b, double *c); 42 | double dotProduct(const double *a, const double *b); 43 | double findLambda(plane *p, float *point, int revFlag); 44 | void showMatrix(double **M,int Nx, int Ny,char *name); 45 | void vectDiff_f(float *a, double *b, double *c,int revFlag); 46 | double vectLength(double *vect); 47 | void makeCellVect(grainBox *grain, double *vax, double *vby, double *vcz); 48 | void makeCellVectMuls(MULS *muls, double *vax, double *vby, double *vcz); 49 | void rotateVect(double *vectIn,double *vectOut, double phi_x, double phi_y, double phi_z); 50 | void rotateMatrix(double *matrixIn,double *matrixOut, double phi_x, double phi_y, double phi_z); 51 | 52 | /* |vect| */ 53 | double vectLength(double *vect); 54 | 55 | /* c = a*b */ 56 | void matrixProduct(double **a,int Nxa, int Nya, double **b,int Nxb, int Nyb, double **c); 57 | void matrixProductInt(double **a,int Nxa, int Nya, int **b,int Nxb, int Nyb, double **c); 58 | 59 | #endif 60 | -------------------------------------------------------------------------------- /source/memory_fftw3.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | QSTEM - image simulation for TEM/STEM/CBED 3 | Copyright (C) 2000-2010 Christoph Koch 4 | Copyright (C) 2010-2013 Christoph Koch, Michael Sarahan 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | */ 19 | 20 | #include 21 | #include 22 | #include "fftw3.h" 23 | #include "memory_fftw3.h" 24 | 25 | #ifndef WIN32 26 | #include 27 | #endif 28 | /* 29 | #define PRINT_MESSAGE 30 | */ 31 | 32 | 33 | 34 | 35 | /*---------------------------- float1D() -------------------------------*/ 36 | /* 37 | 1D array allocator for type float 38 | make space for m[0...(n-1)] 39 | printf error message and exit if not successful 40 | 41 | this save checking for a NULL return etc every time 42 | 43 | */ 44 | float_tt *float1D( int n, const char *message ) 45 | { 46 | float_tt *m; 47 | 48 | m = (float_tt*) fftw_malloc( n * sizeof( float_tt) ); 49 | if( m == NULL ) { 50 | printf("float1D() cannot allocate memory size=%d: %s\n", 51 | n, message); 52 | exit( 0 ); 53 | } 54 | #ifdef PRINT_MESSAGE 55 | printf("allocated memory for %s\n",message); 56 | #endif 57 | 58 | return( m ); 59 | 60 | } /* end float1D() */ 61 | 62 | /*---------------------------- double1D() -------------------------------*/ 63 | /* 64 | 1D array allocator for type double 65 | make space for m[0...(n-1)] 66 | printf error message and exit if not successful 67 | 68 | this save checking for a NULL return etc every time 69 | 70 | */ 71 | double* double1D( int n, const char *message ) 72 | { 73 | double *m; 74 | 75 | m = (double*) fftw_malloc( n * sizeof( double ) ); 76 | if( m == NULL ) { 77 | printf("double1D() cannot allocate memory size=%d: %s\n", 78 | n, message); 79 | exit( 0 ); 80 | } 81 | #ifdef PRINT_MESSAGE 82 | printf("allocated memory for %s\n",message); 83 | #endif 84 | 85 | return( m ); 86 | 87 | } /* end double1D() */ 88 | 89 | 90 | /*---------------------------- short2D() -------------------------------*/ 91 | /* 92 | 2D array allocator for type short 93 | make space for m[0...(nx-1)][0..(ny-1)] 94 | 95 | message = char[] with error message 96 | 97 | */ 98 | short **short2D( int nx, int ny, const char *message ) 99 | { short **m; 100 | int i; 101 | 102 | m = (short**) fftw_malloc( nx * sizeof( short* ) ); 103 | if( m == NULL ) { 104 | printf("short2D cannot allocate pointers, size=%d : %s\n", 105 | nx, message ); 106 | exit(0); 107 | } 108 | m[0] = (short *) fftw_malloc( ny *nx* sizeof(short) ); 109 | if( m[0] == NULL ){ 110 | printf("long2D cannot allocate arrays, size=%d: %s\n", 111 | ny*nx, message ); 112 | exit(0); 113 | } 114 | for (i=1; i. 18 | */ 19 | 20 | #ifndef MEMORY_H 21 | #define MEMORY_H 22 | 23 | // #include 24 | #include 25 | // #include "floatdef.h" 26 | #include "fftw3.h" 27 | 28 | #ifndef float_tt 29 | #define float_tt float 30 | #endif 31 | 32 | 33 | /*---------------------------- float1D() -------------------------------*/ 34 | /* 35 | 1D array allocator for type float 36 | make space for m[0...(n-1)] 37 | printf error message and exit if not successful 38 | 39 | this save checking for a NULL return etc every time 40 | 41 | */ 42 | float_tt *float1D( int n, const char *message ); 43 | 44 | /*---------------------------- double1D() -------------------------------*/ 45 | /* 46 | 1D array allocator for type double 47 | make space for m[0...(n-1)] 48 | printf error message and exit if not successful 49 | 50 | this save checking for a NULL return etc every time 51 | 52 | */ 53 | double* double1D( int n, const char *message ); 54 | 55 | 56 | /*---------------------------- short2D() -------------------------------*/ 57 | /* 58 | 2D array allocator for type short 59 | make space for m[0...(nx-1)][0..(ny-1)] 60 | 61 | message = char[] with error message 62 | 63 | */ 64 | short **short2D( int nx, int ny, const char *message ); 65 | 66 | /*---------------------------- long2D() -------------------------------*/ 67 | /* 68 | 2D array allocator for type long 69 | make space for m[0...(nx-1)][0..(ny-1)] 70 | 71 | message = char[] with error message 72 | 73 | */ 74 | long **long2D( int nx, int ny, const char *message ); 75 | int **int2D( int nx, int ny, const char *message ); 76 | 77 | /*---------------------------- float2D() -------------------------------*/ 78 | /* 79 | 2D array allocator for type float 80 | make space for m[0...(nx-1)][0..(ny-1)] 81 | 82 | */ 83 | float_tt **float2D( int nx, int ny, const char *message ); 84 | float **float32_2D( int nx, int ny, const char *message ); 85 | float ***float32_3D( int nx, int ny,int nz, const char *message ); 86 | 87 | /*---------------------------- double2D() -------------------------------*/ 88 | /* 89 | 2D array allocator for type double 90 | make space for m[0...(nx-1)][0..(ny-1)] 91 | 92 | */ 93 | float_tt ***float3D( int nx, int ny,int nz, const char *message ); 94 | double **double2D( int nx, int ny, const char *message ); 95 | 96 | fftw_complex **complex2D(int nx, int ny, const char *message); 97 | fftwf_complex **complex2Df(int nx, int ny, const char *message); // single precision 98 | fftw_complex ***complex3D(int nx, int ny,int nz, const char *message); 99 | fftwf_complex ***complex3Df(int nx, int ny,int nz, const char *message); // single precision 100 | 101 | void **any2D( int nx, int ny,int size, const char *message ); 102 | void ***any3D( int nx, int ny,int nz,int size, const char *message ); 103 | 104 | #endif -------------------------------------------------------------------------------- /source/readparams.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | QSTEM - image simulation for TEM/STEM/CBED 3 | Copyright (C) 2000-2010 Christoph Koch 4 | Copyright (C) 2010-2013 Christoph Koch, Michael Sarahan 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | */ 19 | 20 | /************************************************************* 21 | * file: readparams.c 22 | * 23 | * contains functions for reading parameters from a data file 24 | * These parameters are specified by a title string 25 | * The title string will be case sensitive 26 | * Several data files can be kept open (up to STACK_SIZE) 27 | * parameter files can be pushed on/pulled off the stack 28 | * 29 | * 30 | *************************************************************/ 31 | 32 | #include /* ANSI C libraries */ 33 | #include 34 | #include 35 | #include "readparams.h" 36 | 37 | #define COMMENT '%' 38 | #define PAR_BUF_LEN 1024 39 | #define STACK_SIZE 5 40 | 41 | FILE *fpParam=NULL; 42 | FILE **fpStack = NULL; 43 | char parBuf[PAR_BUF_LEN]; 44 | char commentChar = COMMENT; 45 | // int stackheight = 0; // RAM: not implemented yet 46 | 47 | // RAM: strongly consider writing a structure here to hold the filename and individual buffers 48 | // TO DO: implement the structure as a stack below to replace what's currently being used??? 49 | /* typedef struct parFileStruct 50 | { 51 | char fileName[512]; 52 | FILE *fpPar; 53 | char parBuf[PAR_BUF_LEN]; 54 | char commentChar = COMMENT; 55 | } parFileStruct; */ 56 | 57 | /******************************************************** 58 | * open the parameter file and return 1 for success, 59 | * 0 for failure 60 | * If a file is already open, close it first 61 | *******************************************************/ 62 | int parOpen( char *fileName ) 63 | { 64 | int i; 65 | 66 | printf( "Debug: parOpen operating on: %s \n", fileName ); 67 | if ( fpStack == NULL ) 68 | { 69 | fpStack = (FILE **)malloc( STACK_SIZE*sizeof(FILE *) ); 70 | for ( i = 0; i < STACK_SIZE; i++ ) 71 | { 72 | fpStack[i] = NULL; 73 | } 74 | 75 | fpStack[0] = fpParam; 76 | } 77 | 78 | if ( fpParam != NULL ) 79 | { 80 | printf( "DEBUG: RAM, fpParam is not NULL, stack not cleared correctly\n" ); 81 | fclose( fpParam ); 82 | } 83 | 84 | 85 | fpParam = fopen( fileName, "r" ); 86 | return ( fpParam != NULL ); 87 | } 88 | 89 | /****************************************************** 90 | * push the current FILE pointer on the stack, in order 91 | * open a second (or up to 5th) parameter file 92 | */ 93 | void parFpPush() { 94 | int i; 95 | 96 | // printf( "Debug: called parFpPush() \n" ); 97 | 98 | if (fpStack == NULL) 99 | { 100 | fpStack = (FILE **)malloc(STACK_SIZE*sizeof(FILE *)); 101 | for (i=0;i. 18 | */ 19 | 20 | /************************************************************* 21 | * file: readparams.c 22 | * 23 | * contains functions for reading parameters from a data file 24 | * These parameters are specified by a title string 25 | * The title string will be case sensitive 26 | * 27 | *************************************************************/ 28 | #ifndef READPARAMS_H 29 | #define READPARAMS_H 30 | 31 | 32 | /******************************************************** 33 | * open the parameter file and return 1 for success, 34 | * 0 for failure 35 | * If a file is already open, close it first 36 | *******************************************************/ 37 | int parOpen(char *fileName); 38 | 39 | /******************************************************** 40 | * Close the parameter file, if it is open 41 | *******************************************************/ 42 | void parClose(); 43 | 44 | /****************************************************** 45 | * push the current FILE pointer on the stack, in order 46 | * open a second (or up to 5th) parameter file 47 | */ 48 | void parFpPush(); 49 | 50 | /****************************************************** 51 | * discard the current file pointer (close, if not zero) 52 | * and make the previous one on the stack active 53 | ****************************************************/ 54 | void parFpPull(); 55 | 56 | /******************************************************* 57 | * if for some reason a function needs to see the file 58 | * pointer, it can obtain it by calling this function 59 | ******************************************************/ 60 | FILE *getFp(); 61 | 62 | /*********************************************************** 63 | * setComment(char newComment) will set a new character as 64 | * the comment character 65 | **********************************************************/ 66 | void setComment(char newComment); 67 | 68 | /************************************************************ 69 | * function: int readparam(char *title, char *parString) 70 | * 71 | * returns 1 for sucess, 0 for failure 72 | * fp: file pointer to (open) parameter file 73 | * title: string defining the parameter 74 | * parString: string containing the parameter 75 | * 76 | * The function will start at the current file pointer but 77 | * start from the beginning if it could not find the parameter 78 | * It will therefore work faster if the parameters are called 79 | * in order. 80 | ************************************************************/ 81 | int readparam(char *title, char *parString,int wrapFlag); 82 | 83 | 84 | /************************************************************ 85 | * function: int readparam(char *title, char *parString) 86 | * 87 | * returns 1 for sucess, 0 for failure 88 | * title: string defining the parameter 89 | * parString: string containing the parameter 90 | * 91 | * The function will start at the current file pointer and 92 | * write the title and value (parString) of the next 93 | * (legal, i.e. at least 2 words, at least one after the colon) 94 | * parameter in the corresponding strings. 95 | ************************************************************/ 96 | int readNextParam(char *title, char *parString); 97 | 98 | /****************************************************************** 99 | * This function reads the next line of the file and copies it into 100 | * buf (at most bufLen characters). 101 | * Content of buf not altered, if unsuccessful 102 | ******************************************************************/ 103 | int readNextLine(char *buf,int bufLen); 104 | 105 | 106 | void resetParamFile(); 107 | 108 | char *strnext(char *str,char *delim); 109 | 110 | 111 | #endif /* READPARAMS_H */ 112 | -------------------------------------------------------------------------------- /source/stemlib.h: -------------------------------------------------------------------------------- 1 | /* 2 | QSTEM - image simulation for TEM/STEM/CBED 3 | Copyright (C) 2000-2010 Christoph Koch 4 | Copyright (C) 2010-2013 Christoph Koch, Michael Sarahan 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | */ 19 | 20 | #ifndef STEMLIB_H 21 | #define STEMLIB_H 22 | 23 | // #define WIN 24 | 25 | #include "stemtypes_fftw3.h" 26 | #include "data_containers.h" 27 | 28 | 29 | /********************************************** 30 | * This function creates a incident STEM probe 31 | * at position (dx,dy) 32 | * with parameters given in muls 33 | *********************************************/ 34 | // int probe(MULS *muls,double dx, double dy); 35 | void probeShiftAndCrop(MULS *muls, WavePtr wave, double dx, double dy, double cnx, double cny); 36 | void probe(MULS *muls, WavePtr wave, double dx, double dy); 37 | void probePlot(MULS *muls, WavePtr wave); 38 | 39 | void initSTEMSlices(MULS *muls, int nlayer); 40 | void interimWave(MULS *muls,WavePtr wave,int slice); 41 | void collectIntensity(MULS *muls, WavePtr wave, int slices); 42 | //void detectorCollect(MULS *muls, WavePtr wave); 43 | void saveSTEMImages(MULS *muls); 44 | 45 | void make3DSlices(MULS *muls,int nlayer,char *fileName,atom *center); 46 | void make3DSlicesFFT(MULS *muls,int nlayer,char *fileName,atom *center); 47 | void createAtomBox(MULS *muls, int Znum, atomBox *aBox); 48 | void transmit(void **wave,void **trans,int nx, int ny,int posx,int posy); 49 | void propagate_slow(void** wave,int nx, int ny,MULS *muls); 50 | fftwf_complex *getAtomPotential3D_3DFFT(int Znum, MULS *muls,double B); 51 | fftwf_complex *getAtomPotential3D(int Znum, MULS *muls,double B,int *nzSub,int *Nr,int*Nz_lut); 52 | fftwf_complex *getAtomPotentialOffset3D(int Znum, MULS *muls,double B,int *nzSub,int *Nr,int*Nz_lut,float q); 53 | fftwf_complex *getAtomPotential2D(int Znum, MULS *muls,double B); 54 | 55 | WAVEFUNC initWave(int nx, int ny); 56 | void readStartWave(WavePtr wave); 57 | /****************************************************************** 58 | * runMulsSTEM() - do the multislice propagation in STEM mode 59 | * 60 | * waver, wavei are expected to contain incident wave function 61 | * the will be updated at return 62 | *****************************************************************/ 63 | int runMulsSTEM_old(MULS *muls,int lstart); 64 | int runMulsSTEM(MULS *muls, WavePtr wave); 65 | void writePix(char *outFile,fftw_complex **pict,MULS *muls,int iz); 66 | void fft_normalize(void **array,int nx, int ny); 67 | void showPotential(fftw_complex ***pot,int nz,int nx,int ny, 68 | double dx,double dy,double dz); 69 | void atomBoxLookUp(fftw_complex *vlu,MULS *muls,int Znum,double x,double y, 70 | double z,double B); 71 | void writeBeams(MULS *muls, WavePtr wave,int ilayer, int absolute_slice); 72 | 73 | /*********************************************************************************** 74 | * old image read/write functions, may soon be outdated 75 | */ 76 | void readRealImage_old(fftw_real **pix, int nx, int ny, real *t, char *fileName); 77 | void readImage_old(fftw_complex **pix, int nx, int ny, real *t, char *fileName); 78 | void writeRealImage_old(fftw_real **pix, int nx, int ny, real t,char *fileName); 79 | void writeImage_old(fftw_complex **pix, int nx, int ny, real t,char *fileName); 80 | 81 | #endif /* STEMLIB_H */ 82 | -------------------------------------------------------------------------------- /source/stemtypes_fftw3.h: -------------------------------------------------------------------------------- 1 | /* 2 | QSTEM - image simulation for TEM/STEM/CBED 3 | Copyright (C) 2000-2010 Christoph Koch 4 | Copyright (C) 2010-2013 Christoph Koch, Michael Sarahan 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | */ 19 | 20 | #ifndef STEMTYPES_H 21 | #define STEMTYPES_H 22 | 23 | #include "memory_fftw3.h" 24 | //#include "boost/shared_ptr.hpp" 25 | 26 | //////////////////////////////////////////////////////////////////////// 27 | // define whether to use single or double precision 28 | /////////////////////////////////////////////////////////////////////// 29 | #define FLOAT_PRECISION 1 30 | 31 | 32 | #define BW (2.0F/3.0F) /* bandwidth limit */ 33 | #define DOYLE_TURNER 0 34 | #define WEICK_KOHL 1 35 | #define CUSTOM 2 36 | #define STEM 1 37 | #define CBED 2 38 | #define TEM 3 39 | #define REFINE 4 40 | #define MSCBED 5 41 | #define TOMO 6 42 | #define NBED 7 43 | 44 | //////////////////////////////////////////////////////////////////////// 45 | // Define physical constants 46 | //////////////////////////////////////////////////////////////////////// 47 | #define ELECTRON_CHARGE (1.6021773e-19) 48 | #define PICO_AMPERE (1e-12/ELECTRON_CHARGE) 49 | #define MILLISEC_PICOAMP (1e-3*PICO_AMPERE) 50 | 51 | // #include "floatdef.h" 52 | #include "fftw3.h" 53 | 54 | //////////////////////////////////////////////////////////////// 55 | #if FLOAT_PRECISION == 1 56 | #define fftw_real float 57 | #ifndef float_tt 58 | #define float_tt float 59 | #endif 60 | #define real float 61 | #else // FLOAT_PRECISION 62 | #define fftw_real double 63 | #ifndef float_tt 64 | #define float_tt float 65 | #endif 66 | #define real float 67 | #endif // FLOAT_PRECISION 68 | //////////////////////////////////////////////////////////////// 69 | 70 | typedef struct atomStruct { 71 | float z,y,x; 72 | // float dx,dy,dz; // thermal displacements 73 | float dw; // Debye-Waller factor 74 | float occ; // occupancy 75 | float q; // charge 76 | int Znum; 77 | } atom; 78 | 79 | /* Planes will be defined by the standard equation for a plane, i.e. 80 | * a point (point) and 2 vectors (vect1, vect2) 81 | */ 82 | typedef struct planeStruct { 83 | double normX,normY,normZ; 84 | double vect1X,vect1Y,vect1Z; 85 | double vect2X,vect2Y,vect2Z; 86 | double pointX,pointY,pointZ; 87 | } plane; 88 | 89 | typedef struct grainBoxStruct { 90 | int amorphFlag; 91 | double density,rmin, rFactor; /* density, atomic distance, reduced atomic distance 92 | * for amorphous material. Red. r is for making a hex. 93 | * closed packed structure, which will fill all space, 94 | * but will only be sparsely filled, and later relaxed. 95 | */ 96 | char *name; 97 | atom *unitCell; /* definition of unit cell */ 98 | int natoms; /* number of atoms in unit cell */ 99 | double ax,by,cz; /* unit cell parameters */ 100 | double alpha, beta, gamma; /* unit cell parameters */ 101 | double tiltx,tilty,tiltz; 102 | double shiftx,shifty,shiftz; 103 | plane *planes; /* pointer to array of bounding planes */ 104 | double sphereRadius, sphereX,sphereY,sphereZ; /* defines a sphere instead of a grain with straight edges */ 105 | int nplanes; /* number of planes in array planes */ 106 | } grainBox; 107 | 108 | typedef struct superCellBoxStruct { 109 | double cmx,cmy,cmz; /* fractional center of mass coordinates */ 110 | double ax,by,cz; 111 | int natoms; 112 | atom *atoms; /* contains all the atoms within the super cell */ 113 | } superCellBox; 114 | 115 | typedef struct atomBoxStruct { 116 | int used; /* indicate here whether this atom is used in the 117 | particular problem */ 118 | int nx,ny,nz; 119 | float_tt dx,dy,dz; 120 | double B; 121 | #if FLOAT_PRECISION == 1 122 | fftwf_complex ***potential; /* 3D array containg 1st quadrant of real space potential */ 123 | float_tt ***rpotential; /* 3D array containg 1st quadrant of real space potential */ 124 | #else 125 | fftw_complex ***potential; /* 3D array containg 1st quadrant of real space potential */ 126 | float_tt ***rpotential; /* 3D array containg 1st quadrant of real space potential */ 127 | #endif 128 | } atomBox; 129 | 130 | #endif // STEMTYPES_H 131 | -------------------------------------------------------------------------------- /source/stemutil.h: -------------------------------------------------------------------------------- 1 | /* 2 | QSTEM - image simulation for TEM/STEM/CBED 3 | Copyright (C) 2000-2010 Christoph Koch 4 | Copyright (C) 2010-2013 Christoph Koch, Michael Sarahan 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | */ 19 | 20 | #ifndef STEMUTIL_H 21 | #define STEMUTIL_H 22 | 23 | #include "data_containers.h" 24 | #include "stemtypes_fftw3.h" 25 | 26 | #define pNPIX 0 /* number of pix 1 for real and 2 for complex */ 27 | #define pRMAX 1 /* maximum value of the real part of the image */ 28 | #define pIMAX 2 /* maximum value of the imaginary part of the image */ 29 | #define pRMIN 3 /* minimum value of the real part of the image */ 30 | #define pIMIN 4 /* minimum value of the imaginary part of the image */ 31 | #define pXBTILT 5 /* x beam tilt in rad */ 32 | #define pYBTILT 6 /* y beam tilt in rad */ 33 | #define pC 7 /* c unit cell dimension in Angstroms */ 34 | #define pRES 8 /* real space resolution in atompot */ 35 | #define pXCTILT 9 /* x crystal tilt in rad */ 36 | #define pYCTILT 10 /* y crystal tilt in rad */ 37 | #define pDEFOCUS 11 /* defocus in Angstroms */ 38 | #define pASTIG 12 /* astigmatism in Angstroms */ 39 | #define pTHETA 13 /* angle of astigmatism in radians */ 40 | #define pDX 14 /* dimension of pixel in x direction in Angstroms */ 41 | #define pDY 15 /* dimension of pixel in y direction in Angstroms */ 42 | #define pENERGY 16 /* beam energy in keV */ 43 | #define pOAPERT 17 /* objective aperture semi-angle in radians */ 44 | #define pCS 18 /* spherical aberration in Angstroms */ 45 | #define pWAVEL 19 /* electron wavelength in Angstroms */ 46 | #define pCAPERT 21 /* condenser (CTEM) illumination angle in radians */ 47 | #define pDDF 22 /* defocus spread in Angstroms */ 48 | #define pNSLICES 29 /* number of slices */ 49 | #define pMINDET 31 /* minimum detector angle (STEM) in radians */ 50 | #define pMAXDET 32 /* maximum detector angle (STEM) in radians */ 51 | 52 | typedef struct timeval timev; 53 | typedef struct timezone timez; 54 | 55 | 56 | int writeCFG(atom *atoms,int natoms,char *fileName, MULS *muls); 57 | int phononDisplacement(double *u,MULS *muls,int id,int icx,int icy, 58 | int icz,int atomCount,double dw,int maxAtom, int Znum); 59 | 60 | void *memcopy(void *dest, const void *src, size_t n); 61 | // void saveSTEMimages(MULS *muls); 62 | // atom *readUnitCell(int *natom,char *fileName,MULS *muls,int handleVacancies); 63 | atom *readCFGUnitCell(int *natom,char *fileName,MULS *muls); 64 | 65 | double v3DatomLUT(int iz,double r,int tdsFlag,int scatFlag); 66 | double vzatomLUT( int Z, double r ,int tdsFlag,int scatFlag); 67 | double v3DzatomLUT(int Znum, real r2D, real z); // real 68 | 69 | double wavelength( double kev ); 70 | double v3Datom(int Z, double r,int tdsFlag,int scatFlag); 71 | double vzatom( int Z, double radius,int tdsFlag,int scatFlag); 72 | 73 | double gasdev(long *idum); 74 | double rangauss( unsigned long *iseed ); 75 | int ReadfeTable(int scatFlag ); 76 | int ReadLine( FILE* fpRead, char* cRead, int cMax, const char *mesg ); 77 | int getZNumber(char *element); 78 | double sigma( double kev ); 79 | void splinh( double x[], double y[], 80 | double b[], double c[], double d[], int n); 81 | double seval( double *x, double *y, double *b, double *c, 82 | double *d, int n, double x0 ); 83 | double ranflat( unsigned long *iseed ); 84 | int parlay( const char c[], int islice[], int nsmax, int lmax, 85 | int *nslice, int fperr ); 86 | /* long powerof2( long n ); */ 87 | double fe3D(int Z, double q2,int tdsFlag, double scale,int scatFlag); 88 | double sfLUT(double s,int atKind, MULS *muls); 89 | double bicubic(double **ff,int Nz, int Nx,double z,double x); 90 | int atomCompare(const void *atom1,const void *atom2); 91 | 92 | 93 | double getTime(); 94 | double cputim(); 95 | 96 | 97 | 98 | #endif 99 | -------------------------------------------------------------------------------- /test/graphene.cif: -------------------------------------------------------------------------------- 1 | data_image0 2 | _cell_length_a 4.92 3 | _cell_length_b 4.26084 4 | _cell_length_c 6 5 | _cell_angle_alpha 90 6 | _cell_angle_beta 90 7 | _cell_angle_gamma 90 8 | 9 | _symmetry_space_group_name_H-M "P 1" 10 | _symmetry_int_tables_number 1 11 | 12 | loop_ 13 | _symmetry_equiv_pos_as_xyz 14 | 'x, y, z' 15 | 16 | loop_ 17 | _atom_site_label 18 | _atom_site_occupancy 19 | _atom_site_fract_x 20 | _atom_site_fract_y 21 | _atom_site_fract_z 22 | _atom_site_thermal_displace_type 23 | _atom_site_B_iso_or_equiv 24 | _atom_site_type_symbol 25 | C1 1.0000 0.87500 0.16667 0.50000 Biso 1.000 C 26 | C2 1.0000 0.12500 0.33333 0.50000 Biso 1.000 C 27 | C3 1.0000 0.12500 0.66667 0.50000 Biso 1.000 C 28 | C4 1.0000 0.37500 0.83333 0.50000 Biso 1.000 C 29 | C5 1.0000 0.37500 0.16667 0.50000 Biso 1.000 C 30 | C6 1.0000 0.62500 0.33333 0.50000 Biso 1.000 C 31 | C7 1.0000 0.62500 0.66667 0.50000 Biso 1.000 C 32 | C8 1.0000 0.87500 0.83333 0.50000 Biso 1.000 C 33 | -------------------------------------------------------------------------------- /test/graphene.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacobjma/PyQSTEM/9172962b9ed51769a97c90278f463af3ec89181e/test/graphene.npy -------------------------------------------------------------------------------- /test/test_CBED.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | import numpy as np 3 | import matplotlib.pyplot as plt 4 | from mpl_toolkits.axes_grid1 import make_axes_locatable 5 | import matplotlib as mpl 6 | from ase.io import read 7 | from pyqstem.util import atoms_plot 8 | from pyqstem import PyQSTEM 9 | from ase.build import mx2 10 | from ase.visualize import view 11 | mpl.rc('font',**{'size' : 13}) 12 | 13 | from ase.spacegroup import crystal 14 | 15 | a = 2.64 16 | atoms = crystal(['Na', 'Cl'], [(0, 0, 0), (0.5, 0.5, 0.5)], spacegroup=225, 17 | cellpar=[a, a, a, 90, 90, 90]) 18 | #atoms_plot(atoms,direction=1,scale_atoms=.5) 19 | 20 | cell = atoms.get_cell() 21 | 22 | atoms*=(15,15,20) 23 | 24 | #view(atoms) 25 | 26 | scan_range=[[cell[0,0],2*cell[0,0],30], 27 | [cell[1,1],2*cell[1,1],30]] 28 | 29 | qstem = PyQSTEM('CBED') 30 | qstem.set_atoms(atoms) 31 | 32 | resolution = (0.02,0.02) # resolution in x and y-direction [Angstrom] 33 | samples = (400,400) # samples in x and y-direction 34 | defocus = 0 # defocus [Angstrom] 35 | v0 = 200 # acceleration voltage [keV] 36 | alpha = 8 # convergence angle [mrad] 37 | astigmatism = 0 # astigmatism magnitude [Angstrom] 38 | astigmatism_angle = 30 # astigmatism angle [deg.] 39 | aberrations = {'a33': 0, 'phi33': 60} # higher order aberrations [Angstrom] or [deg.] 40 | 41 | qstem.build_probe(v0,alpha,(800,800),resolution=(0.04,0.04),defocus=defocus,astig_mag=astigmatism, 42 | astig_angle=astigmatism_angle,aberrations=aberrations) 43 | wave=qstem.get_wave() 44 | wave.view(method='real') 45 | plt.show() 46 | 47 | #qstem.build_potential(40,probe_position=(cell[0,0]/2,cell[1,1]/2)) 48 | 49 | qstem.run(probe_position=(cell[0,0]/2,cell[1,1]/2)) 50 | 51 | wave=qstem.get_wave() 52 | 53 | wave_array = np.fft.fftshift(np.fft.fft2(wave.array)) 54 | 55 | wave_array = np.log(np.abs(wave_array)**2) 56 | 57 | plt.imshow(wave_array) 58 | plt.show() 59 | 60 | #wave.view(method='diffractogram') 61 | 62 | #plt.show() 63 | -------------------------------------------------------------------------------- /test/test_stem.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | import numpy as np 3 | import matplotlib.pyplot as plt 4 | from mpl_toolkits.axes_grid1 import make_axes_locatable 5 | import matplotlib as mpl 6 | from ase.io import read 7 | from pyqstem.util import atoms_plot 8 | from pyqstem import PyQSTEM 9 | from ase.build import mx2 10 | mpl.rc('font',**{'size' : 13}) 11 | 12 | 13 | atoms=mx2(formula='MoS2', kind='2H', a=3.18, thickness=3.19, size=(2, 2, 1), vacuum=2) 14 | 15 | cell=atoms.get_cell() 16 | cell[1,0]=0 17 | atoms.set_cell(cell) 18 | 19 | atoms.wrap() # wrap atoms outside the unit cell 20 | atoms.center() # center the atoms in the unit cell 21 | 22 | #atoms_plot(atoms,direction=1,scale_atoms=.5) 23 | 24 | 25 | atoms*=(3,3,1) 26 | 27 | scan_range=[[cell[0,0],2*cell[0,0],30], 28 | [cell[1,1],2*cell[1,1],30]] 29 | 30 | qstem = PyQSTEM('STEM') 31 | qstem.set_atoms(atoms) 32 | 33 | resolution = (0.02,0.02) # resolution in x and y-direction [Angstrom] 34 | samples = (300,300) # samples in x and y-direction 35 | defocus = -10 # defocus [Angstrom] 36 | v0 = 300 # acceleration voltage [keV] 37 | alpha = 15 # convergence angle [mrad] 38 | astigmatism = 0 # astigmatism magnitude [Angstrom] 39 | astigmatism_angle = 30 # astigmatism angle [deg.] 40 | aberrations = {'a33': 0, 'phi33': 60} # higher order aberrations [Angstrom] or [deg.] 41 | 42 | qstem.build_probe(v0,alpha,(300,300),resolution=(0.02,0.02),defocus=defocus,astig_mag=astigmatism, 43 | astig_angle=astigmatism_angle,aberrations=aberrations) 44 | wave=qstem.get_wave() 45 | 46 | qstem.build_potential(1,scan_range=scan_range) 47 | 48 | qstem.add_detector('det1',(70,200)) 49 | qstem.add_detector('det2',(0,70)) 50 | 51 | qstem.run() 52 | 53 | img=np.array(qstem.read_detector('det1')) 54 | img2=np.array(qstem.read_detector('det2')) 55 | 56 | img2=np.tile(img,(1,1)) 57 | 58 | extent=[0,scan_range[0][1]*3-scan_range[0][0],0,scan_range[1][1]*3-scan_range[1][0]] 59 | 60 | plt.imshow(img2.T,extent=extent,interpolation='nearest',cmap='gray') 61 | plt.colorbar() 62 | plt.xlabel('x [Angstrom]') 63 | plt.ylabel('y [Angstrom]') 64 | plt.show() 65 | -------------------------------------------------------------------------------- /test/test_stem_dft.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | import numpy as np 3 | import matplotlib.pyplot as plt 4 | from mpl_toolkits.axes_grid1 import make_axes_locatable 5 | import matplotlib as mpl 6 | from ase.io import read 7 | from pyqstem.util import atoms_plot 8 | from pyqstem import PyQSTEM 9 | from pyqstem.potentials import poisson_solver,create_potential_slices 10 | 11 | rho=np.load('test/graphene.npy') # all-electron density from GPAW using LDA 12 | atoms=read('test/graphene.cif',index=0) # atomic configuration 13 | 14 | Lx,Ly,Lz=np.diag(atoms.get_cell()) 15 | Nx,Ny,Nz=rho.shape 16 | res_x=Lx/Nx 17 | res_y=Ly/Ny 18 | 19 | #fig,(ax1,ax2)=plt.subplots(1,2,figsize=(10,5)) 20 | #atoms_plot(atoms,ax=ax1,scale_atoms=.5) 21 | #im=ax2.imshow(np.trapz(rho,dx=Lz/Nz,axis=2).T,extent=[0,Lx,0,Ly],cmap='inferno') 22 | #ax2.set_xlabel('x [Angstrom]') 23 | #ax2.set_ylabel('y [Angstrom]') 24 | #divider = make_axes_locatable(ax2) 25 | #cax2 = divider.append_axes("right", size="5%", pad=0.05) 26 | #plt.colorbar(im,cax=cax2,label='e/Angstrom**2') 27 | #plt.tight_layout() 28 | #plt.show() 29 | 30 | print('Total charge (in elementary charges):',np.sum(rho*Lx*Ly*Lz/(Nx*Ny*Nz))) 31 | 32 | V=poisson_solver(rho,atoms,smooth=0,units='QSTEM') 33 | V_dft=create_potential_slices(V,10,(Lx,Ly,Lz)) 34 | V_dft.array=np.tile(V_dft.array,(3,3,1)) 35 | 36 | 37 | 38 | tiled_atoms=atoms*(3,3,1) 39 | 40 | qstem=PyQSTEM('STEM') 41 | qstem.set_atoms(tiled_atoms) 42 | cell=atoms.get_cell() 43 | scan_range=[[cell[0,0],2*cell[0,0],25], 44 | [cell[1,1],2*cell[1,1],25]] 45 | 46 | resolution = (0.02,0.02) # resolution in x and y-direction [Angstrom] 47 | samples = (300,300) # samples in x and y-direction 48 | defocus = -10 # defocus [Angstrom] 49 | v0 = 300 # acceleration voltage [keV] 50 | alpha = 15 # convergence angle [mrad] 51 | astigmatism = 0 # astigmatism magnitude [Angstrom] 52 | astigmatism_angle = 0 # astigmatism angle [deg.] 53 | aberrations = {'a33': 0, 'phi33': 0} # higher order aberrations [Angstrom] or [deg.] 54 | 55 | qstem.build_probe(v0,alpha,(70,70),resolution=(res_x,res_y),defocus=defocus,astig_mag=astigmatism, 56 | astig_angle=astigmatism_angle,aberrations=aberrations) 57 | 58 | #qstem.set_scan_range(scan_range) 59 | 60 | qstem.set_potential(V_dft,scan_range) 61 | 62 | qstem.view() 63 | plt.show() 64 | 65 | qstem.add_detector('det1',(70,200)) 66 | #qstem.set_potential() 67 | #V_qstem=qstem.get_potential_or_transfunc() 68 | 69 | qstem.run() 70 | #wave_qstem=qstem.get_wave() 71 | 72 | img=qstem.read_detector('det1') 73 | 74 | plt.imshow(img.T) 75 | plt.show() 76 | -------------------------------------------------------------------------------- /test/test_tem.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | import numpy as np 3 | import matplotlib.pyplot as plt 4 | from pyqstem import PyQSTEM 5 | from pyqstem.util import atoms_plot 6 | from ase.lattice.hexagonal import Graphite 7 | 8 | directions=[[1,-2,1,0],[2,0,-2,0],[0,0,0,1]] # QSTEM requires a right-angled unit cell 9 | atoms = Graphite(symbol='C', latticeconstant={'a':2.46,'c':6.70}, directions=directions, size=(2,1,1)) 10 | 11 | del atoms[atoms.get_positions()[:,2]