{"id":28712464,"url":"https://github.com/polusai/nyxus","last_synced_at":"2025-06-14T23:06:00.324Z","repository":{"id":37087716,"uuid":"406800481","full_name":"PolusAI/nyxus","owner":"PolusAI","description":"A fully scalable robust  image feature extraction library.","archived":false,"fork":false,"pushed_at":"2025-06-06T12:23:56.000Z","size":19541,"stargazers_count":24,"open_issues_count":9,"forks_count":8,"subscribers_count":6,"default_branch":"main","last_synced_at":"2025-06-14T23:05:57.405Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/PolusAI.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2021-09-15T14:28:01.000Z","updated_at":"2025-06-06T12:23:13.000Z","dependencies_parsed_at":"2023-09-28T01:14:11.824Z","dependency_job_id":"f5904917-43d7-404a-b174-3dbd168c539b","html_url":"https://github.com/PolusAI/nyxus","commit_stats":{"total_commits":687,"total_committers":10,"mean_commits":68.7,"dds":0.6200873362445415,"last_synced_commit":"f9cc9227fbcb1a8277bf898dd9c1ae20227d2c75"},"previous_names":[],"tags_count":24,"template":false,"template_full_name":null,"purl":"pkg:github/PolusAI/nyxus","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PolusAI%2Fnyxus","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PolusAI%2Fnyxus/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PolusAI%2Fnyxus/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PolusAI%2Fnyxus/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/PolusAI","download_url":"https://codeload.github.com/PolusAI/nyxus/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PolusAI%2Fnyxus/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259896235,"owners_count":22928331,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-06-14T23:05:58.417Z","updated_at":"2025-06-14T23:06:00.300Z","avatar_url":"https://github.com/PolusAI.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Nyxus\n\n[![Documentation Status](https://readthedocs.org/projects/nyxus/badge/?version=latest)](https://nyxus.readthedocs.io/en/latest/)\n[![PyPI](https://img.shields.io/pypi/v/nyxus.svg)](https://pypi.org/project/nyxus/)\n[![PyPI Downloads](https://img.shields.io/pypi/dm/nyxus?label=PyPI%20downloads)](https://pypi.org/project/nyxus/)\n[![Conda](https://img.shields.io/conda/v/conda-forge/nyxus)](https://anaconda.org/conda-forge/nyxus)\n[![Conda Downloads](https://img.shields.io/conda/dn/conda-forge/nyxus?label=Conda%20downloads)](https://anaconda.org/conda-forge/nyxus)\n\nA scalable library for calculating features from intensity-label image data\n\n## Overview\nNyxus is a feature-rich, highly optimized, Python/C++ application capable of analyzing images of arbitrary size and assembling complex regions of interest (ROIs) split across multiple image tiles and files. This accomplished through multi-threaded tile prefetching and a three phase analysis pipeline shown below. \n\n![](docs/source/nyxus_workflow.jpg)\n\nNyxus can be used via Python or command line and is available in containerized form for reproducible execution. Nyxus computes over 450 combined intensity, texture, and morphological features at the ROI or whole image level with more in development. Key features that make Nyxus unique among other image feature extraction applications is its ability to operate at any scale, its highly validated algorithms, and its modular nature that makes the addition of new features straightforward.\n\nCurrently, Nyxus can read 2-dimensional images in TIFF, OME-TIFF, OME-Zarr, and DICOM 2D Grayscale formats. Nyxus can also read compressed and uncompressed NIFTI volume files as well as assemble 3-dimensional arrays from z-slices residing in separate TIFF or OME-TIFF files. It also has a Python API to featurize 2-dimensional NumPy arrays. \n\nThe docs can be found at [Read the Docs](https://nyxus.readthedocs.io/en/latest/).\n\n## Getting started \n\nFor use in python, the latest version of Nyxus can be installed via the [Pip package manager](https://pypi.org/project/pip) or [Conda package manager](https://docs.conda.io/en/latest/):\n\n```\npip install nyxus\n```\n\nor \n```\nconda install nyxus -c conda-forge\n```\n\n## Usage\n\nThe library provides class `Nyxus` for 2-dimensional TIFF, OME.TIFF, OME.ZARR, and DICOM slides and intensity-mask slide pairs, and class `Nyxus3D` for NIFTI volumes and intensity-volume volume pairs. Additionally to a single-file representation, a volume can be represented by its z-slices residing in separate 2-dimensional TIFF or ONE.TIFF slides (so called \"layout A\"). Slides and volumes can be featurized as all the files in a  directory filtered with a file pattern passed specified. Alternatively, explicit file name pairs and pair lists can be featurized. Alternatively, 2D and 3D NumPy arrays can be featurized. \n\n### 2D usage\n\nGiven `intensities` and `labels` folders, Nyxus pairs up intensity-segmentation mask images and extracts features from all of them. A summary of the available feature are [listed below](#available-features).\n\n```python \nfrom nyxus import Nyxus\nnyx = Nyxus ([\"*ALL*\"])\nintensityDir = \"/path/to/images/intensities/\"\nmaskDir = \"/path/to/images/labels/\"\nfeatures = nyx.featurize_directory (intensityDir, maskDir) # selecting all the .ome.tif slides (default)\n```\n\nAlternatively, Nyxus can process explicitly defined pairs of intensity-mask images thus specifying custom 1:N and M:N mapping between segmentation mask and intensity image files. \nThe following example extracts all the features (note parameter \"*ALL*\") from intensity images 'i1', 'i2', and 'i3' related with mask images 'm1' and 'm2' via a custom mapping:\n\n```python \nfrom nyxus import Nyxus\nnyx = Nyxus ([\"*ALL*\"])\nfeatures = nyx.featurize_files(\n    [\n        \"/path/to/images/intensities/i1.ome.tif\", \n        \"/path/to/images/intensities/i2.ome.tif\",\n        \"/path/to/images/intensities/i3.ome.tif\" \n    ], \n    [\n        \"/path/to/images/labels/m1.ome.tif\", \n        \"/path/to/images/labels/m2.ome.tif\",\n        \"/path/to/images/labels/m2.ome.tif\"\n    ],\n\tFalse) # pass True to featurize intensity files as whole segments\n```\n\nThe result `features` variable is a Pandas dataframe similar to what is shown below. Note that if multiple segments are stored in a segmentation mask file, each segment's features in the resultcan be identified by the mask file name and segment mask label.\n\n|     | mask_image           | intensity_image      |   label |    MEAN |   MEDIAN |...|    GABOR_6 |\n|----:|:---------------------|:---------------------|--------:|--------:|---------:|--:|-----------:|\n|   0 | p1_y2_r51_c0.ome.tif | p1_y2_r51_c0.ome.tif |       1 | 45366.9 |  46887   |...|   0.873016 |\n|   1 | p1_y2_r51_c0.ome.tif | p1_y2_r51_c0.ome.tif |       2 | 27122.8 |  27124.5 |...|   1.000000 |\n|   2 | p1_y2_r51_c0.ome.tif | p1_y2_r51_c0.ome.tif |       3 | 34777.4 |  33659   |...|   0.942857 |\n|   3 | p1_y2_r51_c0.ome.tif | p1_y2_r51_c0.ome.tif |       4 | 35808.2 |  36924   |...|   0.824074 |\n|   4 | p1_y2_r51_c0.ome.tif | p1_y2_r51_c0.ome.tif |       5 | 36739.7 |  37798   |...|   0.854067 |\n| ... | ...                  | ...                  |     ... | ...     |  ...     |...|   ...      |\n| 734 | p5_y0_r51_c0.ome.tif | p5_y0_r51_c0.ome.tif |     223 | 54573.3 |  54573.3 |...|   0.980769 |\n\nNyxus can also process intensity-mask pairs that are loaded as NumPy arrays using the `featurize` method. This method takes in either a single pair of 2D intensity-mask pairs\nor a pair of 3D arrays containing 2D intensity and mask images. There is also two optional parameters to supply names to the resulting dataframe, . \n\n```python \nfrom nyxus import Nyxus\nimport numpy as np\n\nnyx = Nyxus ([\"*ALL*\"])\n\nintens = np.array([\n    [[1, 4, 4, 1, 1],\n     [1, 4, 6, 1, 1],\n     [4, 1, 6, 4, 1],\n     [4, 4, 6, 4, 1]],\n])\n\nseg = np.array([\n    [[1, 1, 1, 1, 1],\n     [1, 1, 1, 1, 1],\n     [0, 1, 1, 1, 1],\n     [1, 1, 1, 1, 1]]\n])\n\nfeatures = nyx.featurize(intens, seg)\n```\n\nThe `features` variable is a Pandas dataframe similar to what is shown below.\n\n|     | mask_image    | intensity_image | label | MEAN    |   MEDIAN |...|    GABOR_6 |\n|----:|:--------------|:----------------|------:|--------:|---------:|--:|-----------:|\n|   0 | Segmentation1 | Intensity1      |     1 | 45366.9 |  46887   |...|   0.873016 |\n|   1 | Segmentation1 | Intensity1      |     2 | 27122.8 |  27124.5 |...|   1.000000 |\n|   2 | Segmentation1 | Intensity1      |     3 | 34777.4 |  33659   |...|   0.942857 |\n|   3 | Segmentation1 | Intensity1      |     4 | 35808.2 |  36924   |...|   0.824074 |\n| ... | ...           | ...             |   ... | ...     |  ...     |...|   ...      |\n|  14 | Segmentation2 | Intensity2      |     6 | 54573.3 |  54573.3 |...|   0.980769 |\n\nNote that in this case, default names of virtual image files were provided for the `mask_image` and `intensity_image` columns. To override default names 'Intensity\u003ck\u003e' and 'Segmentation\u003ck\u003e' appearing in these columns, the optional arguments `intensity_names` and `label_names` are used by passing lists of names in. \nThe length of the lists must be the same as the length of the mask and intensity arrays. The following example sets mask and intensity images in the output to desired values:\n\n```python \nintens_names = ['int1', 'int2']\nseg_names = ['seg1', 'seg2']\nfeatures = nyx.featurize(intens, seg, intens_name, seg_name)\n```\n\nThe `features` variable will now use the custom names, as shown below\n\n|     | mask_image       | intensity_image          | label | MEAN    |   MEDIAN |...|    GABOR_6 |\n|----:|:-----------------|:-------------------------|------:|--------:|---------:|--:|-----------:|\n|   0 | seg1 | int1      |     1 | 45366.9 |  46887   |...|   0.873016 |\n|   1 | seg1 | int1      |     2 | 27122.8 |  27124.5 |...|   1.000000 |\n|   2 | seg1 | int1      |     3 | 34777.4 |  33659   |...|   0.942857 |\n|   3 | seg1 | int1      |     4 | 35808.2 |  36924   |...|   0.824074 |\n| ... | ...              | ...                      |   ... | ...     |  ...     |...|   ...      |\n|  14 | seg2 | int2      |     6 | 54573.3 |  54573.3 |...|   0.980769 |\n\n### 3D usage\n\nFeaturizing a directory of volume files is similar to the 2D case except class `Nyxus3D` should be used, and the \"all\" feature group nickname string should be passed as \"*3D_ALL*\":\n\n```python\nimport nyxus\nnyx = nyxus.Nyxus3D ([\"*3D_ALL*\"])\n\n# dataset\nidir = \"/dataset1/input\"\nmdir = \"/dataset1/masks\"\n\n# selecting only uncompressed NIFTI files\nfeatures1 = nyx.featurize_directory (idir, mdir, file_pattern=\".*\\.nii\")\n\n# selecting only compressed NIFTI files\nfeatures2 = nyx.featurize_directory (idir, mdir, file_pattern=\".*\\.nii\\.gz\")\n```\nFeaturizing explicitly specified volume files is straightforward, too:\n\n```python\nimport nyxus\nnyx = nyxus.Nyxus3D ([\"*3D_ALL*\"])\n\nidir = [\n\t\"/patient123/mri.nii.gz\", \n\t\"/patient123/mri.nii.gz\", \n\t\"/patient123/mri.nii.gz\"]\n\nmdir = [\n\t\"/patient123/segmentation/kidney_right.nii.gz\", \n\t\"/patient123/segmentation/liver.nii.gz\", \n\t\"/patient123/segmentation/kidney_left.nii.gz\"]\n\nnyx.featurize_files (idir, mdir, False) # pass True to featurize intensity files as whole segments\n```\n## Anisotropy\n\nAnisotropy correction of input data is available via both python API and command-line variants, independent by x, y, and z dimensions. \nExample (python API):\n\n```python\nimport nyxus\nnyx = nyxus.Nyxus3D ([\"*3D_ALL*\"], anisotropy_x=1.0, anisotropy_y=1.2, anisotropy_z=1.5)\n\n# dataset\nidir = \"/dataset1/input\"\nmdir = \"/dataset1/masks\"\nf = nyx.featurize_directory (idir, mdir, file_pattern=\".*\\.nii\\.gz\")\n```\n\nAnother example (via command line):\n```\n--dim=3 --anisox=1.5  --anisoy=2  --anisoz=2.5 --filePattern=\".*\\.nii\\.gz\"  --features=*3D_GLCM*  --resultFname=f_3d_glcm --outputType=singlecsv --intDir=/dataset1/int --segDir=/dataset1/seg --outDir=/out/OUTPUT-3D\n```\n\n## Further steps\n\nFor more information on all of the available options and features, check out [the documentation](#).\n\nNyxus can also be [built from source](#building-from-source) and used from the command line, or via a pre-built Docker container. \n\n## Getting and setting parameters of Nyxus\n\nAll parameters to configure Nyxus are available to set within the constructor. These parameters can also be updated after the object is created using the `set_params`\nmethod. This method takes in keyword arguments where the key is a valid parameter in Nyxus and the value is the updated value for the parameter. For example, \nto update the `coarse_gray_depth` to 256 and the `gabor_f0` parameter to 0.1, the following can be done:\n\n```python \nfrom nyxus import Nyxus\nnyx = Nyxus([\"*ALL*\"])\nintensityDir = \"/path/to/images/intensities/\"\nmaskDir = \"/path/to/images/labels/\"\nfeatures = nyx.featurize_directory (intensityDir, maskDir)\nnyx.set_params(coarse_gray_depth=256, gabor_f0=0.1)\n```\n\nA list of valid parameters is included in the documentation for this method.\n\nTo get the values of the parameters in Nyxus, the `get_params` method is used. If no arguments are passed to this function, then a dictionary mapping all of the variable names to the respective value is returned. For example,\n\n```python \nfrom nyxus import Nyxus\nnyx = Nyxus([\"*ALL*\"])\nintensityDir = \"/path/to/images/intensities/\"\nmaskDir = \"/path/to/images/labels/\"\nfeatures = nyx.featurize_directory (intensityDir, maskDir)\nprint(nyx.get_params())\n```\n\nwill print the dictionary\n\n```bash\n{'coarse_gray_depth': 256, \n'features': ['*ALL*'], \n'gabor_f0': 0.1, \n'gabor_freqs': [1.0, 2.0, 4.0, 8.0, 16.0, 32.0, 64.0], \n'gabor_gamma': 0.1, \n'gabor_kersize': 16, \n'gabor_sig2lam': 0.8, \n'gabor_theta': 45.0, \n'gabor_thold': 0.025, \n'ibsi': 0, \n'n_loader_threads': 1, \n'n_feature_calc_threads': 4, \n'neighbor_distance': 5, \n'pixels_per_micron': 1.0}\n```\n\nThere is also the option to pass arguments to this function to only receive a subset of parameter values. The arguments should be \nvalid parameter names as string, separated by commas. For example,\n\n```python \nfrom nyxus import Nyxus\nnyx = Nyxus([\"*ALL*\"])\nintensityDir = \"/path/to/images/intensities/\"\nmaskDir = \"/path/to/images/labels/\"\nfeatures = nyx.featurize_directory (intensityDir, maskDir)\nprint(nyx.get_params('coarse_gray_depth', 'features', 'gabor_f0'))\n```\nwill print the dictionary\n\n```python\n{ \n  'coarse_gray_depth': 256, \n  'features': ['*ALL*'], \n  'gabor_f0': 0.1 \n}\n```\n\n## Using Arrow for feature results\n\nNyxus provides the ability to get the results of the feature calculations in Arrow IPC and Parquet formats. \n\nTo create an Arrow IPC or Parquet file, use `output_type=\"arrowipc\"` or `output_type=\"parquet\"` in `Nyxus.featurize*` calls. \nOptionally, an `output_path` argument can be passed to specify the location of the output file. For example,\n\n```python\n    from nyxus import Nyxus\n    import numpy as np\n\n    intens = np.array([\n        [[1, 4, 4, 1, 1],\n            [1, 4, 6, 1, 1],\n            [4, 1, 6, 4, 1],\n            [4, 4, 6, 4, 1]],\n                    \n        [[1, 4, 4, 1, 1],\n            [1, 1, 6, 1, 1],\n            [1, 1, 3, 1, 1],\n            [4, 4, 6, 1, 1]],\n        \n        [[1, 4, 4, 1, 1],\n            [1, 1, 1, 1, 1],\n            [1, 1, 6, 1, 1],\n            [1, 1, 6, 1, 1]],\n        \n        [[1, 4, 4, 1, 1],\n            [1, 1, 1, 1, 1],\n            [1, 1, 1, 1, 1],\n            [1, 1, 6, 1, 1]],\n    ])\n\n    seg = np.array([\n        [[1, 1, 1, 1, 1],\n            [1, 1, 1, 1, 1],\n            [1, 1, 1, 1, 1],\n            [1, 1, 1, 1, 1]],\n                    \n        [[1, 1, 1, 1, 1],\n            [1, 1, 1, 1, 1],\n            [0, 1, 1, 1, 1],\n            [1, 1, 1, 1, 1]],\n        \n        [[1, 1, 1, 0, 0],\n            [1, 1, 1, 1, 1],\n            [1, 1, 0, 1, 1],\n            [1, 1, 1, 1, 1]],\n                    \n        [[1, 1, 1, 0, 0],\n            [1, 1, 1, 1, 1],\n            [1, 1, 1, 1, 1],\n            [1, 1, 1, 1, 1]]\n        \n    ])\n\n    nyx = Nyxus([\"*ALL_INTENSITY*\"])\n\n    arrow_file = nyx.featurize(intens, seg, output_type=\"arrowipc\", output_path=\"some_path\")\n\n    print(arrow_file)\n\n```\n\nThe output is:\n\n```bash\n    NyxusFeatures.arrow\n```\n\nThis functionality is also available in the through the command line using the flag `--outputType`. If this flag is set to `--outputType=arrowipc` then the results will be written to an Arrow IPC file in the output directory and `--outputType=parquet` will write to a Parquet file.\n\n## Available features \nThe feature extraction plugin extracts morphology and intensity based features from pairs of intensity/binary mask images and produces a csv file output. The input image should be in tiled [OME TIFF format](https://docs.openmicroscopy.org/ome-model/6.2.0/ome-tiff/specification.html).  The plugin extracts the following features:\n\nNyxus provides a set of pixel intensity, morphology, texture, intensity distribution features, digital filter based features and image moments\n\n### 2D features\n\n------------------\n| Nyxus feature code | Description |\n|--------|-------|\n| INTEGRATED_INTENSITY | Integrated intensity of the region of interest (ROI) |\n| MEAN, MAX, MEDIAN, STANDARD_DEVIATION, MODE | Mean/max/median/stddev/mode intensity value of the ROI | \n| SKEWNESS, KURTOSIS, HYPERSKEWNESS, HYPERFLATNESS  | higher standardized moments | \n| MEAN_ABSOLUTE_DEVIATION  | Mean absolute deviation | \n| ENERGY  | ROI energy | \n| ROOT_MEAN_SQUARED  | Root of mean squared deviation | \n| ENTROPY  | ROI entropy - a measure of the amount of information in the ROI | \n| UNIFORMITY  | Uniformity - measures how uniform the distribution of ROI intensities is | \n| UNIFORMITY_PIU  | Percent image uniformity, another measure of intensity distribution uniformity | \n| P01, P10, P25, P75, P90, P99  | 1%, 10%, 25%, 75%, 90%, and 99% percentiles of intensity distribution | \n| INTERQUARTILE_RANGE  | Distribution's interquartile range | \n| ROBUST_MEAN_ABSOLUTE_DEVIATION  | Robust mean absolute deviation | \n| MASS_DISPLACEMENT  | ROI mass displacement | \n| AREA_PIXELS_COUNT | ROI area in the number of pixels |\n| COMPACTNESS  | Mean squared distance of the object’s pixels from the centroid divided by the area |\n| BBOX_YMIN | Y-position and size of the smallest axis-aligned box containing the ROI |\n| BBOX_XMIN | X-position and size of the smallest axis-aligned box containing the ROI |\n| BBOX_HEIGHT | Height of the smallest axis-aligned box containing the ROI |\n| BBOX_WIDTH | Width of the smallest axis-aligned box containing the ROI |\n| MAJOR/MINOR_AXIS_LENGTH, ECCENTRICITY, ORIENTATION, ROUNDNESS | Inertia ellipse features |\n| NUM_NEIGHBORS, PERCENT_TOUCHING | The number of neighbors bordering the ROI's perimeter and related neighbor methods |\n| EXTENT | Proportion of the pixels in the bounding box that are also in the region |\n| CONVEX_HULL_AREA | Area of ROI's convex hull |\n| SOLIDITY | Ratio of pixels in the ROI common with its convex hull image |\n| PERIMETER | Number of pixels in ROI's contour |\n| EQUIVALENT_DIAMETER | Diameter of the circle having circumference equal to the ROI's perimeter |\n| EDGE_MEAN/MAX/MIN/STDDEV_INTENSITY | Intensity statistics of ROI's contour pixels |\n| CIRCULARITY | Represents how similar a shape is to circle. Clculated based on ROI's area and its convex perimeter |\n| EROSIONS_2_VANISH | Number of erosion operations for a ROI to vanish in its axis aligned bounding box |\n| EROSIONS_2_VANISH_COMPLEMENT | Number of erosion operations for a ROI to vanish in its convex hull |\n| FRACT_DIM_BOXCOUNT, FRACT_DIM_PERIMETER | Fractal dimension features |\n| GLCM | Grey level co-occurrence Matrix features |\n| GLRLM | Grey level run-length matrix based features |\n| GLDZM | Grey level distance zone matrix based features |\n| GLSZM | Grey level size zone matrix based features |\n| GLDM | Grey level dependency matrix based features |\n| NGTDM | Neighbouring grey tone difference matrix features |\n| ZERNIKE2D, FRAC_AT_D, RADIAL_CV, MEAN_FRAC | Radial distribution features |\n| GABOR | A set of Gabor filters of varying frequencies and orientations |\n\nFor the complete list of features see [Nyxus provided features](docs/source/featurelist.rst)\n\n## 2D feature groups\n\nApart from defining your feature set by explicitly specifying comma-separated feature code, Nyxus lets a user specify popular feature groups. Supported feature groups are:\n\n------------------------------------\n| Group code | Member features |\n|--------------------|-------------|\n| \\*all_intensity\\* | integrated_intensity, mean, median, min, max, range, standard_deviation, standard_error, uniformity, skewness, kurtosis, hyperskewness, hyperflatness, mean_absolute_deviation, energy, root_mean_squared, entropy, mode, uniformity, p01, p10, p25, p75, p90, p99, interquartile_range, robust_mean_absolute_deviation, mass_displacement\n| \\*all_morphology\\* | area_pixels_count, area_um2, centroid_x, centroid_y, weighted_centroid_y, weighted_centroid_x, compactness, bbox_ymin, bbox_xmin, bbox_height, bbox_width, major_axis_length, minor_axis_length, eccentricity, orientation, num_neighbors, extent, aspect_ratio, equivalent_diameter, convex_hull_area, solidity, perimeter, edge_mean_intensity, edge_stddev_intensity, edge_max_intensity, edge_min_intensity, circularity\n| \\*basic_morphology\\* | area_pixels_count, area_um2, centroid_x, centroid_y, bbox_ymin, bbox_xmin, bbox_height, bbox_width\n| \\*geomoms\\* | shape and intensity geometric moments, equivalent to \\*igeomoms\\* and \\*sgeomoms\\* combined\n| \\*igeomoms\\* | intensity raw moments IMOM_RM_pq, central moments IMOM_CM_pq, normalized raw moments IMOM_NRM_pq, normalized central moments IMOM_NCM_pq, Hu invariants IMOM_HUk, weighted raw moments IMOM_WRM_pq, weighted central moments IMOM_WCM_pq, weighted normalized central moments IMOM_WNCM_pq, weighted Hu invariants IMOM_WHUk\n| \\*sgeomoms\\* | shape raw moments SPAT_MOMENT_pq, central moments CENTRAL_MOMENT_pq, normalized raw moments NORM_SPAT_MOMENT_pq, normalized central moments NORM_CENTRAL_MOMENT_pq, Hu invariants HU_Mk, weighted raw moments WEIGHTED_SPAT_MOMENT_pq, weighted central moments WEIGHTED_CENTRAL_MOMENT_pq, weighted normalized central moments WT_NORM_CTR_MOM_pq, weighted Hu invariants WEIGHTED_HU_Mk\n| \\*all_glcm\\* | glcm_asm, glcm_acor, glcm_cluprom, glcm_clushade, glcm_clutend, glcm_contrast, glcm_correlation, glcm_difave, glcm_difentro, glcm_difvar, glcm_dis, glcm_energy, glcm_entropy, glcm_hom1, glcm_hom2, glcm_id, glcm_idn, glcm_idm, glcm_idmn, glcm_infomeas1, glcm_infomeas2, glcm_iv, glcm_jave, glcm_je, glcm_jmax, glcm_jvar, glcm_sumaverage, glcm_sumentropy, glcm_sumvariance, glcm_variance\n| \\*all_glrlm\\* | glrlm_sre, glrlm_lre, glrlm_gln, glrlm_glnn, glrlm_rln, glrlm_rlnn, glrlm_rp, glrlm_glv, glrlm_rv, glrlm_re, glrlm_lglre, glrlm_hglre, glrlm_srlgle, glrlm_srhgle, glrlm_lrlgle, glrlm_lrhgle\n| \\*all_glszm\\* | glszm_sae, glszm_lae, glszm_gln, glszm_glnn, glszm_szn, glszm_sznn, glszm_zp, glszm_glv, glszm_zv, glszm_ze, glszm_lglze, glszm_hglze, glszm_salgle, glszm_sahgle, glszm_lalgle, glszm_lahgle\n| \\*all_gldm\\* | gldm_sde, gldm_lde, gldm_gln, gldm_dn, gldm_dnn, gldm_glv, gldm_dv, gldm_de, gldm_lgle, gldm_hgle, gldm_sdlgle, gldm_sdhgle, gldm_ldlgle, gldm_ldhgle\n| \\*all_ngtdm\\* | ngtdm_coarseness, ngtdm_contrast, ngtdm_busyness, ngtdm_complexity, ngtdm_strength\n| \\*wholeslide\\* | All the features except those irrelevant for the whole-slide use case (BasicMorphology, EnclosingInscribingCircumscribingCircle, ConvexHull, FractalDimension, GeodeticLengthThickness, Neighbor, RoiRadius, EllipseFitting, EulerNumber, Extrema, ErosionPixel, CaliperFeret, CaliperMartin, CaliperNassenstein, and Chords)\n| \\*all\\* | All the features \n\n### 3D features\n\n------------------\n| Nyxus feature code | Description |\n|--------|-------|\n| **--- intensity ---** | \n| 3COV | covariance\n| 3COVERED_IMAGE_INTENSITY_RANGE | covered volume intensity range\n| 3ENERGY | energy\n| 3ENTROPY | entrupy\n| 3EXCESS_KURTOSIS | excess kurtosis\n| 3HYPERFLATNESS | hyperflatness\n| 3HYPERSKEWNESS | hyperskewness\n| 3INTEGRATED_INTENSITY | integrated intensity\n| 3INTERQUARTILE_RANGE | interquartile range\n| 3KURTOSIS, 3SKEWNESS | kurtosis, skewness\n| 3MAX, 3MEAN, 3MIN, 3MODE, 3RANGE  | maximum, mean, minimum, mode, range\n| 3MEAN_ABSOLUTE_DEVIATION | mean absolute deviation\n| 3MEDIAN | median\n| 3MEDIAN_ABSOLUTE_DEVIATION | median absolute deviation\n| 3P01, 3P10, 3P25, 3P75, 3P90, 3P99 | percentiles\n| 3QCOD | quantile coefficient of dispersion\n| 3ROBUST_MEAN | robust mean\n| 3ROBUST_MEAN_ABSOLUTE_DEVIATION | robust mean absolute deviation\n| 3ROOT_MEAN_SQUARED | root mean squared\n| 3STANDARD_DEVIATION, 3STANDARD_DEVIATION_BIASED | standard deviation (unbiased and biased)\n| 3STANDARD_ERROR | standard error\n| 3UNIFORMITY | uniformity\n| 3VARIANCE, 3VARIANCE_BIASED | variance (unbiased and biased)\n| **--- shape ---** |\n| 3AREA | surface area\n| 3AREA_2_VOLUME | area to volume ratio\n| 3COMPACTNESS1, 3COMPACTNESS1 | compactness 1 and 2\n| 3MESH_VOLUME | mesh volume\n| 3SPHERICAL_DISPROPORTION | spherical disproportion\n| 3SPHERICITY | sphericity\n| 3VOLUME_CONVEXHULL | volume of the convex hull\n| VOXEL_VOLUME | total voxel volume\n| **--- texture ---** | \n| 3GLCM_\\\u003cfeature\\\u003e | GLCM features (cluster prominence, cluster shade, joint entropy, etc)\n| 3GLDM_\\\u003cfeature\\\u003e | GLDM features (grey level variance, etc)\n| 3GLDZM_\\\u003cfeature\\\u003e | GLDZM features (small distance high grey level emphasis, zone distance entropy, etc)\n| 3GLSZM_\\\u003cfeature\\\u003e | GLSZM features (size zone non-uniformity, high grey level zone emphasis)\n| 3NGLDM_\\\u003cfeature\\\u003e | NGLDM features (low dependence emphasis, dependence count energy, etc)\n| 3NGTDM_\\\u003cfeature\\\u003e | NGTDM features (coarseness, busyness, etc)\n| 3GLRLM_\\\u003cfeature\\\u003e | GLRLM features (run length non-uniformity, run entropy, etc)\n\n### 3D feature groups\n\n------------------------------------\n| Group code | Member features |\n|--------------------|-------------|\n| \\*3D_ALL\\* | all the features\n| \\*3D_ALL_INTENSITY\\* | all intensity features\n| \\*3D_ALL_MORPHOLOGY\\* | all shape features\n| \\*3D_ALL_TEXTURE\\* | all texture features\n\n\n## Command line usage\n\nAssuming you [built the Nyxus binary](#building-from-source) as outlined below, the following parameters are available for the command line interface:\n\n| \u003cdiv style=\"width:150px\"\u003eParameter\u003c/div\u003e | Description | Type |\n|------|-------------|------|\n--outputType | Output type for feature values (speratecsv, singlecsv, arrow, parquet). Default value: '--outputType=separatecsv' | string constant\n--features | String constant or comma-seperated list of constants requesting a group of features or particular feature. Default value: '--features=\\*ALL\\*' | string\n--filePattern | Regular expression to match image files in directories specified by parameters '--intDir' and '--segDir'. To match all the files, use '--filePattern=.\\*' | string\n--intDir | Directory of intensity image collection | path\n--outDir | Output directory | path\n--segDir | Directory of labeled image collection | path\n--useGpu | ${\\color{red}\\textsf{(optional)}}$ Calculate compute-expensive features on an NVIDIA GPU device specified by parameter --gpuDeviceID. Default: '--useGpu=false'. Example: --useGpu=true | boolean\n--gpuDeviceID | ${\\color{red}\\textsf{(optional)}}$ ID of a GPU device to be used when '--useGpu=true'. Default: '--gpuDeviceID=0'. Example 1 (single GPU device): '--useGpu=true --gpuDeviceID=2' to strictly use device 2. Example 2 (multiple GPU devices, usually in SLURM scenarios): '--useGpu=true --gpuDeviceID=0,1,3' to use the GPU device having maximum free RAM of devices 0, 1, and 3. | integer or list of integers\n--coarseGrayDepth | ${\\color{red}\\textsf{(optional)}}$ Custom number of greyscale level bins used in texture features. Default: '--coarseGrayDepth=256' | integer\n--glcmAngles | ${\\color{red}\\textsf{(optional)}}$ Enabled direction angles of the GLCM feature. Superset of values: 0, 45, 90, and 135. Default: '--glcmAngles=0,45,90,135' | list of integers\n--intSegMapDir | ${\\color{red}\\textsf{(optional)}}$ Data collection of the ad-hoc intensity-to-mask file mapping. Must be used in combination with parameter '--intSegMapFile' | path\n--intSegMapFile | ${\\color{red}\\textsf{(optional)}}$ Name of the text file containing an ad-hoc intensity-to-mask file mapping. The files are assumed to reside in corresponding intensity and label collections. Must be used in combination with parameter '--intSegMapDir' | string\n--pixelDistance | ${\\color{red}\\textsf{(optional)}}$ Number of pixels to treat ROIs within specified distance as neighbors. Default value: '--pixelDistance=5' | integer\n--pixelsPerCentimeter | ${\\color{red}\\textsf{(optional)}}$ Number of pixels in centimeter used by unit length-related features. Default value: 0 | real\n--ramLimit | ${\\color{red}\\textsf{(optional)}}$ Amount of memory not to exceed by Nyxus, in megabytes. Default value: 50\\% of available memory. Example: '--ramLimit=2000' to use 2,000 megabytes | integer\n--reduceThreads | ${\\color{red}\\textsf{(optional)}}$ Number of CPU threads used on the feature calculation step. Default: '--reduceThreads=1' | integer\n--skiproi | ${\\color{red}\\textsf{(optional)}}$ Skip ROIs having specified labels. Example: '--skiproi=image1.tif:2,3,4;image2.tif:45,56' | string\n--tempDir | ${\\color{red}\\textsf{(optional)}}$ Directory used by temporary out-of-RAM objects. Default value: system temporary directory | path\n--hsig | ${\\color{red}\\textsf{(optional)}}$ Channel signature Example: \"--hsig=_c\" to match images whose file names have channel info starting substring '_c' like in 'p0_y1_r1_c1.ome.tiff' | string\n--hpar | ${\\color{red}\\textsf{(optional)}}$ Channel number that should be used as a provider of parent segments. Example: '--hpar=1' | integer\n--hchi | ${\\color{red}\\textsf{(optional)}}$ Channel number that should be used as a provider of child segments. Example: '--hchi=0' | integer\n--hag | ${\\color{red}\\textsf{(optional)}}$ Name of a method how to aggregate features of segments recognized as children of same parent segment. Valid options are 'SUM', 'MEAN', 'MIN', 'MAX', 'WMA' (weighted mean average), and 'NONE' (no aggregation, instead, same parent child segments will be laid out horizontally) | string\n--fpimgdr | ${\\color{red}\\textsf{(optional)}}$ Desired dynamic range of voxels of a floating point TIFF image. Example: --fpimgdr=240 makes intensities be read in range 0-240. Default value: 10e4 | unsigned integer\n--fpimgmin | ${\\color{red}\\textsf{(optional)}}$ Minimum intensity of voxels of a floating point TIFF image. Default value: 0.0 | real\n--fpimgdr | ${\\color{red}\\textsf{(optional)}}$ Maximum intensity of voxels of a floating point TIFF image. Default value: 1.0 | real\n--anisox | ${\\color{red}\\textsf{(optional)}}$ x-anisotropy. Default value: 1.0 | real\n--anisoy | ${\\color{red}\\textsf{(optional)}}$ y-anisotropy. Default value: 1.0 | real\n--anisoz | ${\\color{red}\\textsf{(optional)}}$ z-anisotropy (for 3D datasets). Default value: 1.0 | real\n---\n\n## Examples\n\n\u003cspan style=\"color:blue\"\u003eExample 1:\u003c/span\u003e __Running Nyxus to process images of specific image channel__\n\nSuppose we need to process intensity/mask images of channel 1 :\n```    \n./nyxus --features=*all_intensity*,*basic_morphology* --intDir=/path/to/intensity/images --segDir=/path/to/mask/images --outDir=/path/to/output --filePattern=.*_c1\\.ome\\.tif --outputType=singlecsv \n```\n\u003cspan style=\"color:blue\"\u003eExample 2:\u003c/span\u003e __Running Nyxus to process specific image__\n\nSuppose we need to process intensity/mask file p1_y2_r68_c1.ome.tif :\n```\n./nyxus --features=*all_intensity*,*basic_morphology* --intDir=/path/to/intensity/images --segDir=/path/to/mask/images --outDir=/path/to/output --filePattern=p1_y2_r68_c1\\.ome\\.tif --outputType=singlecsv \n```\n\n\u003cspan style=\"color:blue\"\u003eExample 3:\u003c/span\u003e __Running Nyxus to extract only intensity and basic morphology features__\n\n```\n./nyxus --features=*all_intensity*,*basic_morphology* --intDir=/path/to/intensity/images --segDir=/path/to/mask/images --outDir=/path/to/output --filePattern=.* --outputType=singlecsv \n```\n\n\u003cspan style=\"color:blue\"\u003eExample 4:\u003c/span\u003e __Skipping specified ROIs while extracting features__\n\nSuppose we need to blacklist ROI labels 2 and 3 from the kurtosis feature extraction globally, in each image. The command line way to do that is using option __--skiproi__ :\n```shell \n./nyxus --skiproi=2,3 --features=KURTOSIS --intDir=/path/to/intensity/images --segDir=/path/to/mask/images --outDir=/path/to/output --filePattern=.* --outputType=singlecsv \n```\n\nAs a result, the default feature extraction result produced without option --skiproi looking like\n\n\u003cpre\u003e\n          mask_image  intensity_image  label    KURTOSIS\n0    p0_y1_r1_c0.tif  p0_y1_r1_c0.tif      1   -0.134216\n1    p0_y1_r1_c0.tif  p0_y1_r1_c0.tif      2   -0.130024\u003cb\u003e\n2    p0_y1_r1_c0.tif  p0_y1_r1_c0.tif      3   -1.259801\n3    p0_y1_r1_c0.tif  p0_y1_r1_c0.tif      4   -0.934786\u003c/b\u003e\n4    p0_y1_r1_c0.tif  p0_y1_r1_c0.tif      5   -1.072111\n..          ...             ...           ...      ...\n\u003c/pre\u003e\n\nwill start looking like \n\n\u003cpre\u003e\n          mask_image  intensity_image  label    KURTOSIS\n0    p0_y1_r1_c0.tif  p0_y1_r1_c0.tif      1   -0.134216\n1    p0_y1_r1_c0.tif  p0_y1_r1_c0.tif      4   -0.934786\n2    p0_y1_r1_c0.tif  p0_y1_r1_c0.tif      5   -1.072111\n3    p0_y1_r1_c0.tif  p0_y1_r1_c0.tif      6   -0.347741\n4    p0_y1_r1_c0.tif  p0_y1_r1_c0.tif      7   -1.283468\n..          ...             ...           ...      ...\n\u003c/pre\u003e\n\n\nNote the comma character separator \u003cspan style=\"background-color:lightgrey\"\u003e\u0026nbsp;\u0026nbsp;\u003cb\u003e,\u003c/b\u003e\u0026nbsp;\u0026nbsp;\u003c/span\u003e in the blacklisted ROI label list.\n\nIf we need to blacklist ROI labels 15 and 16 only in image image421.tif ROI label 17 in image image422.tif, we can do it via a per-file blacklist :\n```\n./nyxus --skiproi=image421.tif:15,16;image421.tif:17 --features=KURTOSIS --intDir=/path/to/intensity/images --segDir=/path/to/mask/images --outDir=/path/to/output --filePattern=.* --outputType=singlecsv \n```\nNote the colon character \u003cspan style=\"background-color:lightgrey\"\u003e\u0026nbsp;\u0026nbsp;\u003cb\u003e:\u003c/b\u003e\u0026nbsp;\u0026nbsp;\u003c/span\u003e between the file name and  backlisted labels within this file and semicolon character separator \u003cspan style=\"background-color:lightgrey\"\u003e\u0026nbsp;\u0026nbsp;\u003cb\u003e;\u003c/b\u003e\u0026nbsp;\u0026nbsp;\u003c/span\u003e of file blacklists.\n\n\u003cspan style=\"color:blue\"\u003eExample 5:\u003c/span\u003e __Skipping specified ROIs while extracting features (via Python API)__\n\nThe Nyxus Python API equivalent of global ROI blacklisting is implemented by method __blacklist_roi(*string*)__ called before a call of method __featurize...()__, for example, labels 15, 16, and 17 can be globally blacklisted as follows:\n```python\nfrom nyxus import Nyxus\nnyx = Nyxus(features=[\"KURTOSIS\"])\nnyx.blacklist_roi('15,16,17')\nfeatures = nyx.featurize_directory (intensity_dir=\"/path/to/intensity/images\", label_dir=\"/path/to/mask/images\", file_pattern=\".*\")\n```\n\nSimilarly, per-file ROI blacklists are defined in a way similar to the command line interface:\n```python\nfrom nyxus import Nyxus\nnyx = Nyxus(features=[\"KURTOSIS\"])\nnyx.blacklist_roi('p0_y1_r1_c0.ome.tif:15,16;p0_y1_r2_c0.ome.tif:17')\nfeatures = nyx.featurize_directory (intensity_dir=\"/path/to/intensity/images\", label_dir=\"/path/to/mask/images\", file_pattern=\".*\")\n```\n\nSee also methods __clear_roi_blacklist()__ and __roi_blacklist_get_summary()__ .\n\n## Nested ROIs \n\nHierarchical ROI analysis in a form of finding ROIs nested geometrically as nested AABBs and aggregating features of child ROIs within corresponding parent is available as an optional extra step after the feature extraction of the whole image set is finished. To enable this step, all the command line options '--hsig', '--hpar', '--hchi', and '--hag' need to have non-blank valid values. \n\nValid aggregation options are SUM, MEAN, MIN, MAX, WMA (weighted mean average), or NONE (no aggregation).\n\n\u003cspan style=\"color:blue\"\u003eExample 6:\u003c/span\u003e __Processing an image set with nested ROI postprocessing__ \n\n```\nnyxus --features=*ALL_intensity* --intDir=/path/to/intensity/images --segDir=/path/to/mask/images --outDir=/path/to/output/directory --filePattern=.* --outputType=separatecsv --reduceThreads=4 --hsig=_c --hpar=1 --hchi=0 --hag=WMA \n```\n\nAs a result, 2 additional CSV files will be produced for each mask image whose channel number matches the value of option '--hpar': file \n\n```\n\u003cimagename\u003e_nested_features.csv\n``` \n\nwhere features of the detected child ROIs are laid next to their parent ROIs on same lines and auxiliary file \n\n```\n\u003cimagename\u003e_nested_relations.csv\n``` \n\nserving as a relational table of  parent and child ROI labels within parent ROI channel image ```\u003cimagename\u003e```.\n\n### Nested features Python API\n\nThe nested features functionality can also be utilized in Python using the `Nested` class in `nyxus`. The `Nested` class\ncontains two methods, `find_relations` and `featurize`. \n\nThe `find_relations` method takes in a path to the label files, along with a child \nfilepattern to identify the files in the child channel and a parent filepattern to match the files in the parent channel. The `find_relation` method \nreturns a Pandas DataFrame containing a mapping between parent ROIs and the respective child ROIs.\n\nThe `featurize` method takes in the parent-child mapping along with the features of the ROIs in the child channel. If a list of aggregate functions\nis provided to the constructor, this method will return a pivoted DataFrame where the rows are the ROI labels and the columns are grouped by the features.\n\n\n__Example 7__: Using aggregate functions\n\n``` python\n\nfrom nyxus import Nyxus, Nested\nimport numpy as np\n\nint_path = 'path/to/intensity'\nseg_path = 'path/to/segmentation'\n\nnyx = Nyxus(['GABOR'])\n\nchild_features = nyx.featurize(int_path, seg_path, file_pattern='p[0-9]_y[0-9]_r[0-9]_c0\\.ome\\.tif')\n\nnest = Nested(['sum', 'mean', 'min', ('nanmean', lambda x: np.nanmean(x))])\n\ndf = nest.find_relations(seg_path, 'p{r}_y{c}_r{z}_c1.ome.tif', 'p{r}_y{c}_r{z}_c0.ome.tif')\n\ndf2 = nest.featurize(df, features)\n```\n\nThe parent-child map is\n\n``` bash\n    Image              Parent_Label  Child_Label\n    0  /path/to/image          72             65\n    1  /path/to/image          71             66\n    2  /path/to/image          70             64\n    3  /path/to/image          68             61\n    4  /path/to/image          67             65\n\n```\n\nand the aggregated DataFrame is \n\n``` bash\n            GABOR_0                                  GABOR_1                                  GABOR_2              ... \n            sum        mean      min       nanmean    sum      mean       min       nanmean   sum      mean        ...\n    label                                                                                                          ...                                                                                                      \n     1      24.010227  0.666951  0.000000  0.666951  19.096262  0.530452  0.001645  0.530452  17.037345  0.473260  ... \n     2      13.374170  0.445806  0.087339  0.445806   7.279187  0.242640  0.075000  0.242640   6.390529  0.213018  ...  \n     3       5.941783  0.198059  0.000000  0.198059   3.364149  0.112138  0.000000  0.112138   2.426409  0.080880  ...  \n     4      13.428773  0.559532  0.000000  0.559532  12.021938  0.500914  0.008772  0.500914   9.938915  0.414121  ...  \n     5       6.535722  0.181548  0.000000  0.181548   1.833463  0.050930  0.000000  0.050930   2.083023  0.057862  ...\n\n```\n\n\u003cspan style=\"color:blue\"\u003eExample 8:\u003c/span\u003e __Without aggregate functions__\n\n``` python\n\nfrom nyxus import Nyxus, Nested\nimport numpy as np\n\nint_path = 'path/to/intensity'\nseg_path = 'path/to/segmentation'\n\nnyx = Nyxus(['GABOR'])\n\nchild_features = nyx.featurize(int_path, seg_path, file_pattern='p[0-9]_y[0-9]_r[0-9]_c0\\.ome\\.tif')\n\nnest = Nested()\n\ndf = nest.find_relations(seg_path, 'p{r}_y{c}_r{z}_c1.ome.tif', 'p{r}_y{c}_r{z}_c0.ome.tif')\n\ndf2 = nest.featurize(df, features)\n```\n\nthe parent-child map remains the same but the `featurize` result becomes (intentionally putting NaN at undefined combinations):\n\n``` bash\n                     GABOR_0                                                                ...    \n    Child_Label       1          2         3         4         5    6    7    8    9    10  ...    \n    label                                                                                   ...\n    1            0.666951       NaN       NaN       NaN       NaN  NaN  NaN  NaN  NaN  NaN  ...     \n    2                 NaN  0.445806       NaN       NaN       NaN  NaN  NaN  NaN  NaN  NaN  ...     \n    3                 NaN       NaN  0.198059       NaN       NaN  NaN  NaN  NaN  NaN  NaN  ...     \n    4                 NaN       NaN       NaN  0.559532       NaN  NaN  NaN  NaN  NaN  NaN  ...     \n    5                 NaN       NaN       NaN       NaN  0.181548  NaN  NaN  NaN  NaN  NaN  ...\n\n```\n\n## Building from source\nNyxus uses `CMake` as the build system and needs a `C++17` supported compiler to build from the source.\n\n### __Dependencies__\nTo build Nyxus from source, several build dependencies are needed to be satisfied. These dependencies arise from Nyxus's need to read and write various data format. The dependencies are listed below.\n* Tiff Support:  libtiff, libdeflate, zlib\n* Zarr Support: z5, xtensor, nlohman_json, blosc, zlib\n* Dicom Support: dcmtk, fmjpeg, zlib\n* Apache Arrow Support: arrow-cpp, pyarrow\n* Python Interface: pybind11\n\nThese packages also have underlying dependencies and at times, these dependency resolution may appear challenging. We prefer     `conda` to help with resolving these dependencies. However, for users without access to a `conda` enviornment, we have also provided installation script to build and install all the dependencies except `Apache Arrow`.\n\nBy default, Nyxus can be built with a minimal set of dependecies (Tiff support and Python interface). To build Nyxus with all the supported IO options mentioned above, pass `-DALLEXTRAS=ON` in the `cmake` command.\n\n### __Adding GPU Support__\nNyxus also can be build with NVIDIA GPU support. To do so, a `CUDA` Development toolkit compatible with the host `C++` compiler need to be present in the system. For building with GPU support, pass `-DUSEGPU=ON` flag in the `cmake` command. \n\n### __Inside Conda__\nTo build the command line interface, pass `-DBUILD_CLI=ON` in the `cmake` command.\n\n\nBelow is an example of how to build Nyxus inside a `conda` environment on Linux.\n\n```bash\nconda create -n nyxus_build python=3.10\nconda activate nyxus_build\ngit clone https://github.com/PolusAI/nyxus.git\ncd nyxus\nconda install mamba -c conda-forge\nmamba install -y -c conda-forge --file ci-utils/envs/conda_cpp.txt \nexport NYXUS_DEP_DIR=$CONDA_PREFIX\nmkdir build\ncd build\ncmake -DBUILD_CLI=ON -DALLEXTRAS=ON  -DUSEGPU=ON ..\nmake -j4\n```\n\nTo install the python package in the `conda` environment on Linux, use the following direction.\n```bash\nconda create -n nyxus_build python=3.10\nconda activate nyxus_build\ngit clone https://github.com/PolusAI/nyxus.git\ncd nyxus\nconda install mamba -c conda-forge\nmamba install -y -c conda-forge --file ci-utils/envs/conda_cpp.txt --file ci-utils/envs/conda_py.txt\nexport NYXUS_DEP_DIR=$CONDA_PREFIX\nCMAKE_ARGS=\"-DUSEGPU=ON -DALLEXTRAS=ON -DPython_ROOT_DIR=$CONDA_PREFIX -DPython_FIND_VIRTUALENV=ONLY\" python -m pip install . -vv\n```\n\n### __Without Using Conda__\nTo build Nyxus outside of a `conda` environment, we will first need to build and install all the required and optional dependecies. `ci-utils/install_prereq_windwos.bat` and `ci-utils/install_prereq_linux.sh` performs the task for Windows and Linux (and Mac) respectively. These script take a `--min_build yes` option to only build the minimal dependencies. Below, we provide an example for Windows OS.\n\n```bash\ngit clone https://github.com/PolusAI/nyxus.git\ncd nyxus\nmkdir build\ncd build\n..\\ci-utils\\install_prereq_windows.bat\ncmake -DBUILD_CLI=ON -DUSEGPU=ON -DALLEXTRAS=ON -DCMAKE_PREFIX_PATH=.\\local_install -DCMAKE_INSTALL_PREFIX=.\\local_install ..\ncmake --build . --config Release\nset PATH=%PATH%;%cd%\\local_install\\bin\n```\nTo install the python package in the environment on Linux, use the following direction.\n\n```bash\npython -m virtualenv venv\nvenv\\Scripts\\activate.bat\ngit clone https://github.com/PolusAI/nyxus.git\ncd nyxus\nmkdir build_dep\ncd build_dep\n..\\ci-utils\\install_prereq_windows.bat\ncd ..\nset NYXUS_DEP_DIR=%cd%\\build_dep\\local_install\nset CMAKE_ARGS=-DUSEGPU=ON -DALLEXTRAS=ON\npython -m pip install . -vv\nxcopy /E /I /y %NYXUS_DEP_DIR%\\bin\\*.dll %VIRTUAL_ENV%\\lib\\site-packages\\nyxus\n```\nNote that, in both cases, the `dll`s of the dependencies need to be in the `PATH` (for CLI) or in the `site-packages` location (for Python package).\n\n## Running via Docker \nRunning Nyxus from a local directory freshly made Docker container is a good idea. It allows one to test-run conteinerized Nyxus before it reaches Docker cloud deployment.\n\nTo search available Nyxus images run command \n```\ndocker search nyxus\n```\nand you'll be shown that it's available at least via organization 'polusai'. To pull it, run\n```\ndocker pull polusai/nyxus\n``` \n\nThe following command line is an example of running the dockerized feature extractor (image hash 87f3b560bbf2) with only intensity features selected:\n```\ndocker run -it [--gpus all] --mount type=bind,source=/images/collections,target=/data 87f3b560bbf2 --intDir=/data/c1/int --segDir=/data/c1/seg --outDir=/data/output --filePattern=.* --outputType=separatecsv --features=entropy,kurtosis,skewness,max_intensity,mean_intensity,min_intensity,median,mode,standard_deviation\n```\n\n## WIPP Usage\n\nNyxus is available as plugin for [WIPP](https://isg.nist.gov/deepzoomweb/software/wipp). \n\n__Label image collection:__\nThe input should be a labeled image in tiled OME TIFF format (.ome.tif). Extracting morphology features, Feret diameter statistics, neighbors, hexagonality and polygonality scores requires the segmentation labels image. If extracting morphological features is not required, the label image collection can be not specified.\n\n__Intensity image collection:__\nExtracting intensity-based features requires intensity image in tiled OME TIFF format. This is an optional parameter - the input for this parameter is required only when intensity-based features needs to be extracted.\n\n__File pattern:__\nEnter file pattern to match the intensity and labeled/segmented images to extract features (https://pypi.org/project/filepattern/) Filepattern will sort and process files in the labeled and intensity image folders alphabetically if universal selector(.*.ome.tif) is used. If a more specific file pattern is mentioned as input, it will get matches from labeled image folder and intensity image folder based on the pattern implementation.\n\n__Pixel distance:__\nEnter value for this parameter if neighbors touching cells needs to be calculated. The default value is 5. This parameter is optional.\n\n__Features:__\nComma separated list of features to be extracted. If all the features are required, then choose option __*all*__.\n\n__Outputtype:__\nThere are 4 options available under this category. __*Separatecsv*__ - to save all the features extracted for each image in separate csv file. __*Singlecsv*__ - to save all the features extracted from all the images in the same csv file. __*Arrow*__ - to save all the features extracted from all the images in Apache Arrow format. __*Parquet*__ - to save all the features extracted from all the images in Apache Parquet format\n\n__Embedded pixel size:__\nThis is an optional parameter. Use this parameter only if units are present in the metadata and want to use those embedded units for the features extraction. If this option is selected, value for the length of unit and pixels per unit parameters are not required.\n\n__Length of unit:__\nUnit name for conversion. This is also an optional parameter. This parameter will be displayed in plugin's WIPP user interface only when embedded pixel size parameter is not selected (ckrresponding check box checked).\n\n__Pixels per unit:__\nIf there is a metric mentioned in Length of unit, then Pixels per unit cannot be left blank and hence the scale per unit value must be mentioned in this parameter. This parameter will be displayed in plugin's user interface only when embedded pixel size parameter is not selected.\n\n__Note:__ If Embedded pixel size is not selected and values are entered in Length of unit and Pixels per unit, then the metric unit mentioned in length of unit will be considered.\nIf Embedded pixel size, Length of unit and Pixels per unit is not selected and the unit and pixels per unit fields are left blank, the unit will be assumed to be pixels.\n\n__Output:__\nThe output is a csv file containing the value of features required.\n\nFor more information on WIPP, visit the [official WIPP page](https://github.com/usnistgov/WIPP/tree/master/user-guide).\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpolusai%2Fnyxus","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpolusai%2Fnyxus","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpolusai%2Fnyxus/lists"}