https://github.com/instamatic-dev/pyserialem
Python module to read/write SerialEM navigator files.
https://github.com/instamatic-dev/pyserialem
electron-microscopy navigator python serialem
Last synced: 6 months ago
JSON representation
Python module to read/write SerialEM navigator files.
- Host: GitHub
- URL: https://github.com/instamatic-dev/pyserialem
- Owner: instamatic-dev
- License: bsd-3-clause
- Created: 2020-04-15T10:06:16.000Z (about 6 years ago)
- Default Branch: main
- Last Pushed: 2023-01-17T16:34:51.000Z (over 3 years ago)
- Last Synced: 2023-10-20T20:24:18.720Z (over 2 years ago)
- Topics: electron-microscopy, navigator, python, serialem
- Language: Python
- Size: 161 KB
- Stars: 9
- Watchers: 3
- Forks: 4
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
[](https://github.com/instamatic-dev/pyserialem/actions)
[](https://pypi.org/project/pyserialem/)
[](https://pypi.org/project/pyserialem/)
[](https://pypi.org/project/pyserialem/)
# PySerialEM
A small Python library to read and write [SerialEM][serialem] navigator files (`.nav`), and process grid maps.
Install using `pip install pyserialem`.
# Usage
The main use of `pyserialem` is to manipulate coordinates in a `.nav` file written by SerialEM ([specification][serialem_nav]).
Reading a `.nav` file:
```python
import pyserialem
from pathlib import Path
p = Path('C:/path/to/data/') / 'nav.nav'
items = pyserialem.read_nav_file(p) # list
```
You can set the `acquire_only` toggle to return only the items with the `Acquire` tag set:
```python
items = pyserialem.read_nav_file(p, acquire_only=True) # list
```
This 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.
```python
map_items = [item.kind == 'Map' for item in items]
nav_items = [item.kind == 'Marker' for item in items]
```
All 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:
```python
nav_item = nav_items[0]
stage_position = nav_item.StageXYZ # tuple
map_item.StageXYZ = (100, 200, 0) # overwrite values
```
Alternatively, the stage position can be accessed directly through:
```python
x = map_item.stage_x
y = map_item.stage_y
z = map_item.stage_z
xy = map_item.stage_xy
```
## Map items
A `MapItem` has all the functions of a `NavItem`, and then some. Each `MapItem` can have a list of markers associated with it:
```python
map_item = map_items[0]
markers = map_item.markers # list
```
To visualize them, call:
```python
map_item.plot()
```
To just load the image associated with the `MapItem`:
```python
img = map_item.load() # np.array
```
They can be extracted as a dictionary:
```python
d = map_item.to_dict() # dict
```
...and restored:
```python
new_map_item = pysem.from_dict(d, tag='new_mapitem')
```
This 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.
It 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`):
```python
pixel_position = (0, 0)
new_nav_item = map_item.add_marker(
pixel_position,
tag='pixel_item',
acquire=True) # NavItem
```
You can also add a marker as a stage coordinate (although this is a bit more tricky to calculate the corresponding pixel coordinate):
```python
stage_positionion = (1000, 1000)
new_nav_item = map_item.add_marker(
pixel_position,
kind='stage',
tag='stage_item',
acquire=False) # NavItem
```
To add many markers:
```python
pixel_coordinates = ((0, 0), (100, 100), (200, 200))
nav_item_group = map_item.add_marker_group(pixel_coordinates) # tuple
```
Specify `replace=True` to replace the current list of markers associated with the `MapItem`.
If the `MapItem` has a set of markers associated with it `map_item.markers`, the coordinates be retrieved as followed:
```python
map_item.markers_as_pixel_coordinates() # np.array (Nx2)
map_item.markers_as_stage_coordinates() # np.array (Nx2)
```
To just convert between stage and pixel coordinates:
```python
pixel_coord = (1024, 1024)
stage_coord = map_item.pixel_to_stagecoords(pixel_coord) # tuple
new_pixel_coord = map_item.stage_to_pixelcoords(stagecoord) # tuple
assert new_pixel_coord == pixel_coord
```
To write a new file:
```python
pyserialem.write_nav_file('out.nav', map_item, *nav_item_group)
```
Note the `*`. This function captures arguments in a list (`*args`, so they must be unpacked when supplied.
## Stitching
A basic stitching algorithm is available to get an overview of the location of all map items:
```python
map_items = [item for item in items if item.kind == 'Map']
pyserialem.stitch_map_items(map_items)
```
For more advanced stitching and montaging, use the `pyserialem.montage` module. A [demo notebook](demos/montage_processing_serialem.ipynb) is available to demonstrate its usage.
## Mdoc files
There 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.
```python
p = Path('C:/path/to/data') / 'gm.mrc.mdoc'
mdoc = pyserialem.read_mdoc_file(p)
```
[src]: https://github.com/instamatic-dev/pyserialem
[serialem]: https://bio3d.colorado.edu/SerialEM/
[serialem_nav]: https://bio3d.colorado.edu/SerialEM/hlp/html/about_formats.htm