# ptychopy

## Quickstart

Need to install python3 to run the GUI and ptychopy, other needed library is

in requirement.txt.(Tested OS RHEL 6.0, 7.0). This library could also be

compiled as a CUDA-C library. Inside src folder, change build.sh with your

HDF library path.

Recommend conda virtual environment, for example

```
conda create -n py36 python=3.6 hdf5-external-filter-plugins-lz4
```

- Activate the virtual environment

```
source activate py36
```

- To install and build the python package, set environment variables HDF5_BASE

and CUDAHOME, which point to the installed path of the HDF5 and CUDA

libraries. Also, set the cuda computing based on your GPU. For example the

2080 Ti has compute capability 7.5. The GPU computing capability number can

be found on the NVidia website

```
export CUDACOMPUTE=7.5
export CUDAHOME=/user/local/cuda-8.0
export HDF5_BASE=$CONDA_PREFIX
```

- Then just call the following

```
./install.sh
```

- For testing, you can use epie.py or mls.py

```
python epie.py
```

## Description

This software package is implemented with ePIE, DM, MLs, reconstruction

algorithm. It supports list, spiral, cartesian, scan position file. To load a

predefined scan position file, object value files, probe value files, use the

following parameters to do the reconstruction.

## API

There are two sets API for doing the reonstrunction, one set is for the whole

mode and the other set is for step mode. ย The step mode is used mostly for

debug purpose, so the result for each reconstruction step could be checked. And

the whole mode would finish the whole reconstruction process and write the

result to the disk. The step mode would be slower than the whole mode, since

each step would need to transfer data back from GPU to CPU side.

The following example is based on the simulation data. For real data, the -fp

parameter has to be specified. The file format must be a bunch of HDF5 files

and the file path would be like filename_data_#06d.h5. The library will go

though all the HDF5 files and load the diffraction pattern into the library.

Whole mode API example with simulation images:

=======

```
Use simulation image as the example input
ptychopy.epie(jobID="epiesimu1", beamSize=110e-9, scanDimsx=30, scanDimsy=30, stepx=50e-9, \
stepy=50e-9, lambd=2.4796837508399954e-10, iter=3, size=512, dx_d=172e-6, z=1, simulate=1);
ptychopy.dm(jobID="dmsimu1", beamSize=110e-9, scanDimsx=30, scanDimsy=30, stepx=50e-9, \
stepy=50e-9, lambd=2.4796837508399954e-10, iter=3, size=512, dx_d=172e-6, z=1, simulate=1);
ptychopy.mls(jobID="mlssimu1", beamSize=110e-9, scanDimsx=30, scanDimsy=30, stepx=50e-9, \
stepy=50e-9, lambd=2.4796837508399954e-10, iter=3, size=512, dx_d=172e-6, z=1, simulate=0);
Use real data as the example input
ptychopy.epie(jobID="ePIEIOTestr256", fp="/home/scan152/scan152_data_#06d.h5", \
fs=1, hdf5path="/entry/data/data", beamSize=110e-6, qx=276, qy=616, scanDimsx=51, scanDimsy=51, stepx=100e-9, \
stepy=100e-9, lambd=1.408911284090909e-10, iter=100, size=256, dx_d=75e-6, z=1.92, dpf=51, \
probeModes=5)
ptychopy.dm(jobID="DMIOTestr256", fp="/home/scan152/scan152_data_#06d.h5", \
fs=1, hdf5path="/entry/data/data", beamSize=110e-6, qx=276, qy=616, scanDimsx=51, scanDimsy=51, stepx=100e-9, \
stepy=100e-9, lambd=1.408911284090909e-10, iter=100, size=256, dx_d=75e-6, z=1.92, dpf=51, \
probeModes=1)
ptychopy.mls(jobID="MLSIOTestr256", fp="/home/scan152/scan152_data_#06d.h5", \
fs=1, hdf5path="/entry/data/data", beamSize=110e-6, qx=276, qy=616, scanDimsx=51, scanDimsy=51, stepx=100e-9, \
stepy=100e-9, lambd=1.408911284090909e-10, iter=100, size=256, dx_d=75e-6, z=1.92, dpf=51, \
probeModes=1, delta_p=0.1, PPS=20)
```

Pass diffraction pattern as a 3D numpy array, diffractionNP, objectNP, probeNP

```
ptychopy.epienp(jobID="ePIEIOTestr256", diffractionNP=dp,\
fs=1, beamSize=110e-6, qx=276, qy=616, scanDimsx=51, scanDimsy=51, stepx=100e-9, \
stepy=100e-9, lambd=1.408911284090909e-10, iter=10, size=256, dx_d=75e-6, z=1.92,\
probeModes=2)
ptychopy.dmnp(jobID="dmIOTestr256", diffractionNP=dp,\
fs=1, beamSize=110e-6, qx=276, qy=616, scanDimsx=51, scanDimsy=51, stepx=100e-9, \
stepy=100e-9, lambd=1.408911284090909e-10, iter=10, size=256, dx_d=75e-6, z=1.92,\
probeModes=2)
ptychopy.mlsnp(jobID="mlsIOTestr256", diffractionNP=dp,\
fs=1, beamSize=110e-6, qx=276, qy=616, scanDimsx=51, scanDimsy=51, stepx=100e-9, \
stepy=100e-9, lambd=1.408911284090909e-10, iter=10, size=256, dx_d=75e-6, z=1.92, \
probeModes=2)
```

Step mode API example:

```
epienpinit(jobID="ePIEIOTestr256", diffractionNP=dp,\
fs=1, beamSize=110e-6, qx=276, qy=616, scanDimsx=51, scanDimsy=51, stepx=100e-9, \
stepy=100e-9, lambd=1.408911284090909e-10, iter=10, size=256, dx_d=75e-6, z=1.92,\
probeModes=2)
epiestep()
episresobj()
epiresprobe()
epipost()
```

For implentation example, please check example folder.

## Parameters

Name | Type | Description | Default |
---|---|---|---|

jobID | string | An identifying tag to the reconstruction run | `` |

algorithm | string | The algorithm to use for reconstruction. Accepted values ( `ePIE,DM, MLs` ) |
`ePIE` |

fp | path | A c-style formatted string for the location of the HDF5 files. For file name string substitution starting at `fs` . Example: `-fp=/data/diff_#03d.h5` for files in the form `diff_000.h5, diff_001.h5, ...` |
`N/A` |

fs | integer | The file index of the file containing the first diffraction pattern (top left corner for Cartesian scans) | `0` |

hdf5path | string | Diffraction data HDF5 dataset name | `/entry/data/data` |

dpf | integer | The number of diffraction patterns per file | `1` |

beamSize | real | The theoretical incident beam size in meters | `110e-9` |

probeGuess | path | The location of a CSV complex valued file used as the initial probe guess for reconstruction (The file can be saved with python using np.savetxt(numpyProbe, delimiter=', ') and it has to have the same dimensions as the `size` parameter |
`N/A` |

objectGuess | path | The location of a CSV complex valued file used as the initial object guess for reconstruction | `N/A` |

size | integer | The desired size for cropping the diffraction patterns and probe size. Preferably a multiple of 2: 128, 256, 512, etc... | `256` |

qxy | integer, integer | The center of the diffraction pattern in pixels (image pixel location Y, image pixel location X). Diffraction patterns will be cropped to a square image of sizeXsize pixels around qxy. | `128, 128` |

nxy | integer, integer | The size of the diffraction pattern before pre-processing (rows, columns). Only required for .csv and .bin files; the dataset dimensions can be detected automatically in HDF5 files. | `256, 256` |

scanDims | integer, integer | The grid dimensions for Cartesian scans (rows, columns) | `26, 26` |

spiralScan | (0, 1) | Use a spiral scan mesh instead of a Cartesian grid | `0` |

flipScanAxis | (0, 1) | Flips the raster scan direction from horizontal to vertical | `0` |

mirror1stScanAxis | (0, 1) | Flips the raster scan direction along the first axis (vertically, downwards to upwards, if flipScanAxis=0) | `0` |

mirror2ndScanAxis | (0, 1) | Flips the raster scan direction along the second axis (horizontally, left-to-right to right-to-left, if flipScanAxis=0) | `0` |

step | real, real | The step size in meters for each of the scan grid dimensions (row step, column step) | `40e-9, 40e-9` |

probeModes | integer | Number of orthogonal probe modes to simulate partial incoherence of the beam | `1` |

lambda | real | Wavelength of the incident beam in meters (calculated from the energy used) | `2.3843e-10` |

dx_d | real | Detector pixel size in meters | `172e-6` |

z | real | Distance between sample and detector in meters | `2.2` |

iter | integer | Number of reconstruction iterations | `100` |

T | integer | Maximum allowed reconstruction time (in sec). Overrides iterations. | `N/A` |

jitterRadius | integer | Radius in pixels for random displacement of raster scan positions | `0` |

delta_p | real | LSQ damping constant, used only for MLs method | 0.1 |

threshold | integer | To remove noise from the diffraction patterns. Any count below this number will be set to zero in the diffraction data. | `0` |

rotate90 | (0, 1, 2, 3) | Number of times to rotate the diffraction patterns by 90 degrees. (Currently only a value of 1 is supported) | `0` |

sqrtData | flag | Take the sqrt of the loaded diffraction pattern magnitudes | `N/A` |

fftShiftData | flag | Apply an fftshift operation to the diffraction patterns | `N/A` |

blind | (0, 1) | Turn visualization on(0)/off(1). Only has an effect when the library is built with SDL support or running from the GUI | `1` |

binaryOutput | (0, 1) | Write results in binary format (1), or CSV format (0) | `0` |

simulate | (0, 1) | Run a test simulation from lena and baboon images as magnitude and phase profiles of a synthetic sample wavefront. (Only works with -size=128, 256, 512, 1024) | `0` |

overlap | integer | Only has an effect when the library is built with DIY support and is running on multiple GPUs. The size of a halo in raster scan dimensions where the data is shared between multiple reconstructions running on multiple GPUs | `0` |

shareFrequency | integer | Only has an effect when the library is built with DIY support and is running on multiple GPUs. Determines the frequency of data sharing among GPUs, in terms of number of iterations | `10` |

phaseConstraint | integer | The number of iterations to keep applying a phase constraint (forcing the reconstructed phase in the range [-2pi, 0]) | `1` |

updateProbe | integer | The number of iterations after which to start updating the primary probe mode | `10` |

updateModes | integer | The number of iterations after which to start updating all probe modes | `20` |

updateVis | integer | The number of iterations after which to start updating the visualization. Only has an effect when the library is built with SDL support or running from the GUI | `10` |

beamstopMask | (0, 1) | Determine whether the beamstop area (0 values, set by a binary array "beamstopMask.h5" which is put in the data directory) is applied with Fourier modulus constraint or not | `0` |

lf | path | The location of a CSV complex valued file for positions (The file can be saved with python using np.savetxt(numpyProbe, delimiter=', ') and it has to be arranged with position y, x in each row, the unit is m | `N/A` |

PPS | integer | The number of iterations after which to start probe position search, only work for MLs method | `20` |

Name | Type | Description | Default |
---|---|---|---|

diffractionNP | real | numpy array for diffraction | `numpy array for diffraction` |

objectNP | complex | numpy array for object array | `numpy array for object array` |

probeNP | complex | numpy array for probe array | `numpy array for probe array` |

## Reference Paper

```
@inproceedings{yue2021ptychopy,
title={Ptychopy: GPU framework for ptychographic data analysis},
author={Yue, Ke and Deng, Junjing and Jiang, Yi and Nashed, Youssef and Vine, David}
}
```