# scanreader
Python TIFF Stack Reader for ScanImage 5 scans (including multiROI).
We treat a scan as a collection of recording fields:
rectangular planes at a given x, y, z position in the scan
recorded in a number of channels during a preset amount of time.
All fields have the same number of channels (or z-planes) and number of frames/timesteps.
## Installation
Install the latest version with `pip`
```shell
pip3 install git+https://github.com/MillerBrainObservatory/scanreader.git
```
## Usage
```python
import scanreader
scan = scanreader.read_scan('/data/my_scan_*.tif')
print(scan.version)
print(scan.num_frames)
print(scan.num_channels)
print(scan.num_fields)
x = scan[:] # 5D array [ROI, X, Y, Z, T]
y = scan[:, :, :, 0:4, -1000:] # last 1000 frames of first 4 planes
z = scan[1] # 4-d array: the second ROI (over all z-plane and time)
scan = scanreader.read_scan('/data/my_scan_*.tif', dtype=np.float32, join_contiguous=True)
```
Scan object indexes can be:
- integers
- slice objects (:)
- lists/tuples/arrays of integers
No boolean indexing is yet supported.
## Details on data loading (for future developers)
### Preamble
Matlab stores data column by column ("Fortran order"), while NumPy by default stores them row by row ("C order").
This **doesn't affect indexing**, but **may affect performance**.
For example, in Matlab efficient loop will be over columns (e.g. for n = 1:10 a(:, n) end),
while in NumPy it's preferable to iterate over rows (e.g. for n in range(10): a[n, :] -- note n in the first position, not the last).
As of this version, `scanreader` relies on [`tifffile`](https://pypi.org/project/tifffile/) to read the underlying tiff files.
Reading a scan happens in three stages:
1. `scan = scanreader.read_scan(filename)` will create a list of `tifffile.TiffFile`s, one per each tiff file in the scan. This entails opening a file handle and reading the tags of the first page of each; tags for the rest of pages are ignored (they have the same info).
2. `scan.num_frames`, `scan.shape` or another operation that requires the number of frames in the scan---which includes the first stage of any data loading operation---will need the number of pages in each tiff file. `tifffile` was designed for files with pages of varying shapes so it iterates over each page looking for its offset (number of bytes from the start of the file until the very first byte of the page), which it saves to use for reading. After this operation, it knows the number of pages per file.
3. Once the file has been opened and the offset to each page has been calculated we can load the actual data. We load each page sequentially and take care of reformatting them to match the desired output.
This reader and documentation are based off of is based on a previous [version](https://github.com/atlab/scanreader) developed by [atlab](https://github.com/atlab/).
Some of the older scans have been removed for general cleanliness. These can be reimplemented by cherry-picking the commit. See documentation on `git reflog` to find the commits you want and `git cherry-pick` to apply changes that were introduced by those commits.
Raw data
{
"_id": null,
"home_page": "https://github.com/MillerBrainObservtory/scanreader",
"name": "scanreader",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.9",
"maintainer_email": null,
"keywords": "ScanImage scanreader multiROI 2019 tiff",
"author": "Flynn OConnell",
"author_email": "foconnell@rockefeller.edu",
"download_url": "https://files.pythonhosted.org/packages/6a/70/2d1d48f05c09eaba99f7c85ccb29d35e2a62297530469e621bf0246788dd/scanreader-0.6.0.tar.gz",
"platform": null,
"description": "# scanreader\r\n\r\nPython TIFF Stack Reader for ScanImage 5 scans (including multiROI).\r\n\r\nWe treat a scan as a collection of recording fields:\r\nrectangular planes at a given x, y, z position in the scan\r\nrecorded in a number of channels during a preset amount of time.\r\nAll fields have the same number of channels (or z-planes) and number of frames/timesteps.\r\n\r\n## Installation\r\n\r\nInstall the latest version with `pip`\r\n\r\n```shell\r\npip3 install git+https://github.com/MillerBrainObservatory/scanreader.git\r\n```\r\n\r\n## Usage\r\n\r\n```python\r\nimport scanreader\r\n\r\nscan = scanreader.read_scan('/data/my_scan_*.tif')\r\n\r\nprint(scan.version)\r\nprint(scan.num_frames)\r\nprint(scan.num_channels)\r\nprint(scan.num_fields)\r\n\r\nx = scan[:] # 5D array [ROI, X, Y, Z, T]\r\ny = scan[:, :, :, 0:4, -1000:] # last 1000 frames of first 4 planes\r\nz = scan[1] # 4-d array: the second ROI (over all z-plane and time)\r\n\r\nscan = scanreader.read_scan('/data/my_scan_*.tif', dtype=np.float32, join_contiguous=True)\r\n```\r\n\r\nScan object indexes can be:\r\n\r\n- integers\r\n- slice objects (:)\r\n- lists/tuples/arrays of integers\r\n\r\nNo boolean indexing is yet supported.\r\n\r\n## Details on data loading (for future developers)\r\n\r\n### Preamble\r\n\r\nMatlab stores data column by column (\"Fortran order\"), while NumPy by default stores them row by row (\"C order\").\r\nThis **doesn't affect indexing**, but **may affect performance**.\r\nFor example, in Matlab efficient loop will be over columns (e.g. for n = 1:10 a(:, n) end),\r\nwhile in NumPy it's preferable to iterate over rows (e.g. for n in range(10): a[n, :] -- note n in the first position, not the last). \r\n\r\nAs of this version, `scanreader` relies on [`tifffile`](https://pypi.org/project/tifffile/) to read the underlying tiff files.\r\n\r\nReading a scan happens in three stages:\r\n1. `scan = scanreader.read_scan(filename)` will create a list of `tifffile.TiffFile`s, one per each tiff file in the scan. This entails opening a file handle and reading the tags of the first page of each; tags for the rest of pages are ignored (they have the same info).\r\n2. `scan.num_frames`, `scan.shape` or another operation that requires the number of frames in the scan---which includes the first stage of any data loading operation---will need the number of pages in each tiff file. `tifffile` was designed for files with pages of varying shapes so it iterates over each page looking for its offset (number of bytes from the start of the file until the very first byte of the page), which it saves to use for reading. After this operation, it knows the number of pages per file.\r\n3. Once the file has been opened and the offset to each page has been calculated we can load the actual data. We load each page sequentially and take care of reformatting them to match the desired output.\r\n\r\nThis reader and documentation are based off of is based on a previous [version](https://github.com/atlab/scanreader) developed by [atlab](https://github.com/atlab/).\r\n\r\nSome of the older scans have been removed for general cleanliness. These can be reimplemented by cherry-picking the commit. See documentation on `git reflog` to find the commits you want and `git cherry-pick` to apply changes that were introduced by those commits.\r\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Tiff reader for ScanImage BigTiff files.",
"version": "0.6.0",
"project_urls": {
"Homepage": "https://github.com/MillerBrainObservtory/scanreader",
"documentation": "https://millerbrainobservatory.github.io/scanreader/index.html",
"homepage": "https://millerbrainobservatory.github.io/",
"source": "https://github.com/MillerBrainObservatory/scanreader/"
},
"split_keywords": [
"scanimage",
"scanreader",
"multiroi",
"2019",
"tiff"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "10d385277a3ab3769cf072ebeb11e992a799d62fc4cfcbb082e71f52a3b97a44",
"md5": "43fc45e7085d2fc6e9d2d5d1abdd1550",
"sha256": "67e933413383131e5663ded5acca7a7be5d0da4182b19a38f0e530aed0657e40"
},
"downloads": -1,
"filename": "scanreader-0.6.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "43fc45e7085d2fc6e9d2d5d1abdd1550",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.9",
"size": 25674,
"upload_time": "2024-09-27T15:57:38",
"upload_time_iso_8601": "2024-09-27T15:57:38.296454Z",
"url": "https://files.pythonhosted.org/packages/10/d3/85277a3ab3769cf072ebeb11e992a799d62fc4cfcbb082e71f52a3b97a44/scanreader-0.6.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "6a702d1d48f05c09eaba99f7c85ccb29d35e2a62297530469e621bf0246788dd",
"md5": "6b5856c67d7f734940fff413db29dc6d",
"sha256": "8c51d255a2d4cebf694acfa6dfdf0720b421500ed7d1ecae7b86ecc1cb365b33"
},
"downloads": -1,
"filename": "scanreader-0.6.0.tar.gz",
"has_sig": false,
"md5_digest": "6b5856c67d7f734940fff413db29dc6d",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.9",
"size": 26106,
"upload_time": "2024-09-27T15:57:40",
"upload_time_iso_8601": "2024-09-27T15:57:40.072681Z",
"url": "https://files.pythonhosted.org/packages/6a/70/2d1d48f05c09eaba99f7c85ccb29d35e2a62297530469e621bf0246788dd/scanreader-0.6.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-09-27 15:57:40",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "MillerBrainObservtory",
"github_project": "scanreader",
"github_not_found": true,
"lcname": "scanreader"
}