# -*- coding: utf-8 -*-
from setuptools import setup

packages = \
['pyserialem']

package_data = \
{'': ['*']}

install_requires = \
['lmfit>=1.0.1',
 'matplotlib>=3.1.2',
 'mrcfile>=1.1.2',
 'numpy>=1.17.3',
 'scikit-image>=0.17.2',
 'scipy>=1.5.0',
 'tqdm>=4.46.1']

setup_kwargs = {
    'name': 'pyserialem',
    'version': '0.3.2',
    'description': 'Python module to read/write SerialEM .nav files.',
    'long_description': "[![GitHub Workflow Status](https://img.shields.io/github/workflow/status/instamatic-dev/pyserialem/build)](https://github.com/instamatic-dev/pyserialem/actions)\n[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/pyserialem)](https://pypi.org/project/pyserialem/)\n[![PyPI](https://img.shields.io/pypi/v/pyserialem.svg?style=flat)](https://pypi.org/project/pyserialem/)\n[![PyPI - Downloads](https://img.shields.io/pypi/dm/pyserialem)](https://pypi.org/project/pyserialem/)\n\n# PySerialEM\n\nA small Python library to read and write [SerialEM][serialem] navigator files (`.nav`), and process grid maps.\n\nInstall using `pip install pyserialem`.\n\n# Usage\n\nThe main use of `pyserialem` is to manipulate coordinates in a `.nav` file written by SerialEM ([specification][serialem_nav]).\n\nReading a `.nav` file:\n\n```python\nimport pyserialem\nfrom pathlib import Path\n\np = Path('C:/path/to/data/') / 'nav.nav'\nitems = pyserialem.read_nav_file(p)  # list\n```\nYou can set the `acquire_only` toggle to return only the items with the `Acquire` tag set:\n\n```python\nitems = pyserialem.read_nav_file(p, acquire_only=True)  # list\n```\n\nThis returns a `list` of `MapItem` and `NavItem`. A `MapItem` is associated with an image in the corresponding `.mrc` file, and a `NavItem` is a marker or point on that image.\n\n```python\nmap_items = [item.kind == 'Map' for item in items]\nnav_items = [item.kind == 'Marker' for item in items]\n```\n\nAll of the tags associated with the `MapItem` or `NavItem` can be accessed as an attribute using the same name as in the `.nav` file, i.e. with the key defined [here][serialem_nav]. This is also how the values should be updated:\n\n```python\nnav_item = nav_items[0]\nstage_position = nav_item.StageXYZ  # tuple\nmap_item.StageXYZ = (100, 200, 0)   # overwrite values\n```\n\nAlternatively, the stage position can be accessed directly through:\n\n```python\nx = map_item.stage_x\ny = map_item.stage_y\nz = map_item.stage_z\nxy = map_item.stage_xy\n```\n\n## Map items\n\nA `MapItem` has all the functions of a `NavItem`, and then some. Each `MapItem` can have a list of markers associated with it:\n\n```python\nmap_item = map_items[0]\nmarkers = map_item.markers  # list\n```\n\nTo visualize them, call:\n\n```python\nmap_item.plot()\n```\n\nTo just load the image associated with the `MapItem`:\n\n```python\nimg = map_item.load()  # np.array\n```\n\nThey can be extracted as a dictionary:\n\n```python\nd = map_item.to_dict()  # dict\n```\n\n...and restored:\n\n```python\nnew_map_item = pysem.from_dict(d, tag='new_mapitem')\n```\n\nThis is also the easiest way of constructing a new `MapItem`, because some keys can be autogenerated. Otherwise, all the required keys have to be specified to the `MapItem` constructor. The `tag` specifies the name of the item when displayed in `SerialEM`. If omitted, one will be generated.\n\nIt is easy to add new markers to a `MapItem`. As a pixel coordinate (i.e. from segmentation) is the default. `PySerialEM` calculates the corresponding stage position. The `acquire` argument sets the acquire flag (default=`True`):\n\n```python\npixel_position = (0, 0)\nnew_nav_item = map_item.add_marker(\n    pixel_position,\n    tag='pixel_item',\n    acquire=True)  # NavItem\n```\n\nYou can also add a marker as a stage coordinate (although this is a bit more tricky to calculate the corresponding pixel coordinate):\n\n```python\nstage_positionion = (1000, 1000)\nnew_nav_item = map_item.add_marker(\n    pixel_position,\n    kind='stage',\n    tag='stage_item',\n    acquire=False)  # NavItem\n```\n\nTo add many markers:\n\n```python\npixel_coordinates = ((0, 0), (100, 100), (200, 200))\nnav_item_group = map_item.add_marker_group(pixel_coordinates)  # tuple\n```\n\nSpecify `replace=True` to replace the current list of markers associated with the `MapItem`.\n\nIf the `MapItem` has a set of markers associated with it `map_item.markers`, the coordinates be retrieved as followed:\n\n```python\nmap_item.markers_as_pixel_coordinates()  # np.array (Nx2)\nmap_item.markers_as_stage_coordinates()  # np.array (Nx2)\n```\n\nTo just convert between stage and pixel coordinates:\n\n```python\npixel_coord = (1024, 1024)\nstage_coord = map_item.pixel_to_stagecoords(pixel_coord)  # tuple\nnew_pixel_coord = map_item.stage_to_pixelcoords(stagecoord)  # tuple\nassert new_pixel_coord == pixel_coord\n```\n\nTo write a new file:\n\n```python\npyserialem.write_nav_file('out.nav', map_item, *nav_item_group)\n```\n\nNote the `*`. This function captures arguments in a list (`*args`, so they must be unpacked when supplied.\n\n## Stitching\n\nA basic stitching algorithm is available to get an overview of the location of all map items:\n\n```python\nmap_items = [item for item in items if item.kind == 'Map']\npyserialem.stitch_map_items(map_items)\n```\n\nFor more advanced stitching and montaging, use the `pyserialem.montage` module. A [demo notebook](demos/montage_processing_serialem.ipynb) is available to demonstrate its usage.\n\n## Mdoc files\n\nThere is also a simple function to read `.mdoc` files ([link][serialem_nav]). This returns a list of python objects where each key can be accessed as an attribute.\n\n```python\np = Path('C:/path/to/data') / 'gm.mrc.mdoc'\nmdoc = pyserialem.read_mdoc_file(p)\n```\n\n[src]: https://github.com/stefsmeets/pyserialem\n[serialem]: https://bio3d.colorado.edu/SerialEM/\n[serialem_nav]: https://bio3d.colorado.edu/SerialEM/hlp/html/about_formats.htm\n",
    'author': 'Stef Smeets',
    'author_email': 's.smeets@tudelft.nl',
    'maintainer': 'Stef Smeets',
    'maintainer_email': 's.smeets@tudelft.nl',
    'url': 'http://github.com/stefsmeets/pyserialem',
    'packages': packages,
    'package_data': package_data,
    'install_requires': install_requires,
    'python_requires': '>=3.6.1',
}


setup(**setup_kwargs)
