analyzefrc
Plots, analysis and resolution measurement of microscopy images using Fourier Ring Correlation (FRC)
Science Score: 54.0%
This score indicates how likely this project is to be science-related based on various indicators:
-
✓CITATION.cff file
Found CITATION.cff file -
✓codemeta.json file
Found codemeta.json file -
✓.zenodo.json file
Found .zenodo.json file -
○DOI references
-
○Academic publication links
-
✓Committers with academic emails
1 of 2 committers (50.0%) from academic institutions -
○Institutional organization owner
-
○JOSS paper metadata
-
○Scientific vocabulary similarity
Low similarity (16.5%) to scientific vocabulary
Repository
Plots, analysis and resolution measurement of microscopy images using Fourier Ring Correlation (FRC)
Basic Info
- Host: GitHub
- Owner: tmtenbrink
- License: mit
- Language: Python
- Default Branch: main
- Size: 175 KB
Statistics
- Stars: 1
- Watchers: 1
- Forks: 0
- Open Issues: 0
- Releases: 7
Metadata Files
README.md
AnalyzeFRC
Developed at the Department of Imaging Physics (ImPhys), Faculty of Applied Sciences, TU Delft.
Plots, analysis and resolution measurement of microscopy images using Fourier Ring Correlation (FRC).
AnalyzeFRC has native support for .lif files and can also easily read single images in formats supported by Pillow (PIL). Other formats require converting that image into a NumPy array and using that to instantiate AnalyzeFRC's native objects.
AnalyzeFRC provides a lot of default options and convenience functions for a specific use case. However, its core functionality, the measure_frc function in analyzefrc.process can be adapted in other workflows. You can also directly use the frc library, on which this library is built.
Defaults (please read)
- By default, when using
process_frc,preprocessis set to True. It ensures that each input image is cropped into square form and that a Tukey window is applied. Supplyproprocess=Falseto disable this behavior. - By default, when using
process_frc,concurrencyis set to False. If set to true by passingconcurrency=True, it leverages thedecopackage to leverage more cores for a 1.5x+ speedup (not higher because the most resource-intensive computations are already parallelized). !! However, please run the program inside aif __name__ == '__main__':block when concurrency is enabled! Otherwise it will fail! Note: on some platforms, this type of concurrency can cause issues, notably Linux and macOS. This is a problem caused by a dependency. - By default, if an
FRCMeasurementis processed without any presetCurveTaskand has two images, it sets the method to2FRC. Otherwise,1FRCis used. - By default, plots are grouped by
measures, i.e. every measurement will be plotted separately. Use thegroup_<grouping>. Other available groupings includeall(all curves in one plot, use this only to retrieve them to use custom groupings),sets(all curves in the same set name in one plot) andcurves(one plot per curve). - By default, 1FRC curves are computed 5 times and averaged, this can be overriden by passing
override_nto process_frc.
Installation
With (Ana)conda
If you already have Anaconda installed (or miniconda), it is easiest to create a new Python 3.9 environment. Open the Anaconda/miniconda3 prompt and write (here 'envanalyze' can be any environment name you like):
shell
conda create -n 'envanalyze' python=3.9
This package depends on a number of PyPI-only packages, some also with compiled extensions, which are difficult to port to conda. For this reason, it is recommended to have a seperate environment with only this package and then install using pip:
shell
conda activate envanalyze
pip install analyzefrc
You now have an environment called 'envanalyze' with analyzefrc installed. Configure your favorite IDE to use the newly created environment and you're good to go! See the usage examples for more details on how to use this package.
Without conda
Currently, this library only works on Python 3.9. Ensure you have a working installation. You can use tools like pyenv for managing Python versions.
It is recommended to install this library into a virtual environment. Many tools exist for this today (most IDEs can do it for you), but I recommend Poetry.
Install using:
shell
pip install analyzefrc
If using Poetry:
shell
poetry add analyzefrc
This library indirectly (through the frc library) depends on rustfrc (Rust extension) and diplib (C++ extension). These compiled extensions can sometimes cause issues, so refer to their pages as well.
Usage
Default .lif processing
To simply compute the 1FRC of all channels of a .lif dataset and plot the results, you can do the following:
```python import analyzefrc as afrc
This if-statement is required because concurrency is enabled
if name == 'main': # ./ means relative to the current folder frcsets = afrc.lifread('./data/sted/20211005XSTEDNileRedvariationexcitationpowerMLampe.lif') plotcurves = afrc.processfrc("XSTEDNileRed", frcsets, preprocess=True) afrc.plotall(plotcurves) ```
Plot series in one plot
If instead you want to plot each image inside a .lif file in a single plot, do the following:
```python ... # imports and processing
plotcurves = afrc.processfrc("XSTEDNileRed", frcsets, grouping='sets', preprocess=True, concurrency=False) afrc.plotall(plotcurves) ```
Change grouping after computation
Or if you already computed the curves with the default grouping ('all'):
```python ... # imports and processing
frcpersetsets = afrc.groupsets(plotcurves) plotall(frcperset_sets) ```
Save instead of plot
If you don't want to plot the results (in the case of many images the IDE plot buffer can easily be exceeded), but instead save them:
```python ... # imports and processing
Will save to './results/-XSTED_NileRed'
savefolder = afrc.createsave('./results', 'XSTEDNileRed', addtimestamp=True) afrc.plotall(plotcurves, show=False, save=True, savedirectory=savefolder, dpi=180)
```
Only extract data, don't plot
Plotting using your own tools can also be desired. To extract only the resulting data, do not call plot_all. Instead, use the result of process_frc, which yields a dictionary of lists of Curve-objects. A Curve-object is simply a data container for NumPy arrays and metadata. An example:
```python ... # imports and data reading from analyzefrc import Curve import matplotlib.pyplot as plt
plotcurves: dict[str, list[Curve]] = afrc.processfrc("XSTEDNileRed", frcsets, grouping='sets', preprocess=True)
plot all on your own
for curves in plotcurves.values(): firstcurve: Curve = curves[0] plt.plot(firstcurve.curvex, firstcurve.curvey) plt.plot(firstcurve.curvex, first_curve.thres) plt.show()
```
Example: 1FRC vs 2FRC from .tiff
A slightly more complex example: If you have a sample .tiff file and you want to compare the performance of 1FRC vs 2FRC, you could do the following:
```python import numpy as np import diplib as dip import frc.utility as frcu import analyzefrc as afrc from analyzefrc import FRCMeasurement, FRCSet
dataarray: np.ndarray = afrc.getimage('./data/siemens.tiff')
Blur the image (to create a frequency band)
dataarray = frcu.gaussf(dataarray, 30) datadip = dip.Image(dataarray) halfset1 = np.array(dip.PoissonNoise(datadip / 2)) halfset2 = np.array(dip.PoissonNoise(datadip / 2)) fullset = np.array(dip.PoissonNoise(datadip))
Create seperate measurement objects
frc2: FRCMeasurement = afrc.frcmeasure(halfset1, halfset2, setname='2FRC') frc1: FRCMeasurement = afrc.frcmeasure(fullset, set_name='1FRC')
Combine in one set so they can be plot together
frcset: FRCSet = afrc.frcset(frc1, frc2, name='2FRC vs 1FRC') plotcurve = afrc.processfrc("2FRC vs 1FRC", frcset, concurrency=False) afrc.plotall(plot_curve) ```
Details
The three operations of setting up the measurements, computing the curves and plotting them are all decoupled and each have their Python module (analyzefrc.read, analyzefrc.process, analyzefrc.plot, respectively). Furthermore, actual file reading convenience functions can be found in analyzefrc.file_read.
FRCSet, FRCMeasurement and FRCMeasureSettings
For setting up the measurements in preparation of processing, these three classes are essential. FRCSet-objects can be completely unrelated, they share no information. As such, if doing batch processing of different datasets, they can be divided over FRCSet-objects.
Within an FRCSet, there can be an arbitrary number of FRCMeasurement-objects, which should have similar image dimensions and should, in theory, be able to be sensibly plotted in a single figure.
FRCMeasurement is the main data container class. It can be instantiated using an FRCMeasureSettings-object, which contains important parameters that are the same across all images within the measurement (such as the objective's NA value). If these differ across the images, multiple measurements should be used.
Changing default curves
By default, when processing, a single CurveTask will be generated for each FRCMeasurement, meaning a single curve will be generated for each measurement. However, if a different threshold (other than the 1/7) is desired, or multiple curves per figure are wanted, a CurveTask can be created beforehand and given to the FRCMeasurement.
Example:
```python ... # see .tiff example from analyzefrc import CurveTask
Create seperate measurement objects
For example we want a smoothed curve for the 1FRC, as well as a non-smoothed curve
frc1tasksmooth = CurveTask(key='smoothcurve', smooth=True, avgn=3, threshold='halfbit') frc1task = CurveTask(key='standardcurve', avgn=3, threshold='half_bit')
frc2: FRCMeasurement = afrc.frcmeasure(halfset1, halfset2, setname='2FRC') frc1: FRCMeasurement = afrc.frcmeasure(fullset, setname='1FRC', curvetasks=[frc1task, frc1task_smooth])
... # process and plot ```
Changing default processing
If other measurement-based processings are desired, they can be added in two ways. Arbitrary functions (of the type MeasureProcessing = Callable[[FRCMeasurement], FRCMeasurement]) can be run for each measurement by passing them as a list to the extra_processings-argument for process_frc, or by populating the FRCMeasurement-objects' extra_processings attribute.
Note: each processing is performed in list order after the optional preprocessing step, with global extras performed before the measurement-defined extra processing tasks.
This can be useful when using a convenience file loading function. For example, to flip every image and apply a different window functon:
```python ... # .lif example from analyzefrc import FRCMeasurement import numpy as np from scipy.signal import windows as wins
def flipwindowdata(measure: FRCMeasurement) -> FRCMeasurement: measure.image = np.flip(measure.image) size = measure.image.shape[0] assert size == measure.image.shape[1]
cosine = wins.tukey(size)
cosine_square = np.ones((size, size)) * cosine.reshape((size, 1)) * cosine.reshape((1, size))
measure.image = cosine_square * measure.image
return measure
plotcurves = afrc.processfrc("XSTEDNileRed", frcsets, preprocess=False, extraprocessings=[flipwindow_data], concurrency=False)
... # plot ```
Other internal details
The general processing flow is as follows:
- (
read/read_file) CreateFRCMeasureSettingsbased on data acquisition parameters - (
read/read_file) CreateFRCMeasurementusing the previous step. - (Optionally) create custom
CurveTask-objects for theFRCMeasurement. Created by default in theprocessstep if not provided. - (
read/read_file) CreateFRCSetusing multipleFRCMeasurement-objects. - (
process) ComputeCurve-objects usingmeasure_frc. - (
process) Sort/group theCurve-objects into a dictionary with lists ofCurve-objects as entries. - (
plot) Plot thelist[Curve]-dictionary, where each entry becomes a single figure.
All steps besides the measure_frc-step can be implemented in a custom way quite trivially. In a way, all steps except step 5 are for your convenience. Step 5, which is the only step that involves actually processing all the data using the frc library, forms the core of this package.
Performance
Processing 32 measurements of 1024x1024 pixels takes about thirty seconds to read from a .lif file, process (computing each curve 5 times) and plot on my i7-8750H laptop CPU (which is decently performant even by today's standards).
Over 80% of the time is spent processing, i.e. performing the binomial splitting and computing the FRCs (with the latter taking significantly longer). All these functions are implemented through Rust (rustfrc), C++ (diplib) or C (numpy) extensions, meaning they are as fast as can be and mostly parallelized.
10-15% of the time is spent plotting using matplotlib, meaning the overhead of this library is only 5-10%.
Owner
- Login: tmtenbrink
- Kind: user
- Company: TU Delft
- Repositories: 5
- Profile: https://github.com/tmtenbrink
Citation (CITATION.cff)
cff-version: 1.2.0
title: AnalyzeFRC
message: >-
If you use this software, please cite it using the
metadata from this file.
type: software
authors:
- given-names: Tip
family-names: ten Brink
email: T.M.tenBrink@student.tudelft.nl
orcid: 'https://orcid.org/0000-0002-3090-6538'
affiliation: TU Delft
GitHub Events
Total
- Watch event: 1
Last Year
- Watch event: 1
Committers
Last synced: about 3 years ago
All Time
- Total Commits: 28
- Total Committers: 2
- Avg Commits per committer: 14.0
- Development Distribution Score (DDS): 0.286
Top Committers
| Name | Commits | |
|---|---|---|
| Tip ten Brink | T****k@s****l | 20 |
| tmtenbrink | 6****k@u****m | 8 |
Committer Domains (Top 20 + Academic)
Issues and Pull Requests
Last synced: about 1 year ago
All Time
- Total issues: 0
- Total pull requests: 1
- Average time to close issues: N/A
- Average time to close pull requests: less than a minute
- Total issue authors: 0
- Total pull request authors: 1
- Average comments per issue: 0
- Average comments per pull request: 0.0
- Merged pull requests: 1
- Bot issues: 0
- Bot pull requests: 0
Past Year
- Issues: 0
- Pull requests: 0
- Average time to close issues: N/A
- Average time to close pull requests: N/A
- Issue authors: 0
- Pull request authors: 0
- Average comments per issue: 0
- Average comments per pull request: 0
- Merged pull requests: 0
- Bot issues: 0
- Bot pull requests: 0
Top Authors
Issue Authors
Pull Request Authors
- tmtenbrink (1)
Top Labels
Issue Labels
Pull Request Labels
Packages
- Total packages: 1
-
Total downloads:
- pypi 63 last-month
- Total dependent packages: 0
- Total dependent repositories: 1
- Total versions: 9
- Total maintainers: 1
pypi.org: analyzefrc
Plots, analysis and resolution measurement of microscopy images using Fourier Ring Correlation (FRC).
- Documentation: https://analyzefrc.readthedocs.io/
- License: mit
-
Latest release: 0.2.3
published almost 4 years ago
Rankings
Maintainers (1)
Dependencies
- atomicwrites 1.4.0 develop
- attrs 21.4.0 develop
- colorama 0.4.4 develop
- iniconfig 1.1.1 develop
- pluggy 1.0.0 develop
- py 1.11.0 develop
- pytest 6.2.5 develop
- toml 0.10.2 develop
- cycler 0.11.0
- deco 0.6.3
- diplib 3.2.0
- fonttools 4.29.1
- frc 0.1.0
- kiwisolver 1.3.2
- loess 2.1.2
- matplotlib 3.5.1
- numpy 1.22.2
- packaging 21.3
- pillow 9.0.1
- plotbin 3.1.3
- pyparsing 3.0.7
- python-dateutil 2.8.2
- readlif 0.6.5
- rustfrc 1.1.2
- scipy 1.8.0
- setuptools-scm 6.4.2
- similaritymeasures 0.4.4
- six 1.16.0
- tomli 2.0.1
- pytest ^6.2 develop
- Pillow ^9.0.0
- deco ^0.6.3
- frc ^0.1.0
- loess ^2.1.1
- matplotlib ^3.4
- python ~3.9
- readlif ^0.6.5
- similaritymeasures ^0.4.4