Skip to content

Commit 53a3f21

Browse files
authored
Merge branch 'main' into POL3116_bugfix_issue_115
2 parents 64206a2 + 9a8df7b commit 53a3f21

23 files changed

+339
-621
lines changed

README.md

Lines changed: 82 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -84,19 +84,9 @@ intens = np.array([
8484
[1, 4, 6, 1, 1],
8585
[4, 1, 6, 4, 1],
8686
[4, 4, 6, 4, 1]],
87-
88-
[[1, 4, 4, 1, 1],
89-
[1, 1, 6, 1, 1],
90-
[1, 1, 3, 1, 1],
91-
[4, 4, 6, 1, 1]]
9287
])
9388

9489
seg = np.array([
95-
[[1, 1, 1, 1, 1],
96-
[1, 1, 1, 1, 1],
97-
[1, 1, 1, 1, 1],
98-
[1, 1, 1, 1, 1]],
99-
10090
[[1, 1, 1, 1, 1],
10191
[1, 1, 1, 1, 1],
10292
[0, 1, 1, 1, 1],
@@ -122,10 +112,8 @@ for these columns, the optional arguments `intensity_names` and `label_names` ar
122112
The length of the lists must be the same as the length of the mask and intensity arrays. To name the images, use
123113

124114
```python
125-
126115
intens_names = ['custom_intens_name1', 'custom_intens_name2']
127116
seg_names = ['custom_seg_name1', 'custom_seg_name2']
128-
129117
features = nyx.featurize(intens, seg, intens_name, seg_name)
130118
```
131119

@@ -157,7 +145,6 @@ nyx = Nyxus(["*ALL*"])
157145
intensityDir = "/path/to/images/intensities/"
158146
maskDir = "/path/to/images/labels/"
159147
features = nyx.featurize_directory (intensityDir, maskDir)
160-
161148
nyx.set_params(coarse_gray_depth=256, gabor_f0=0.1)
162149
```
163150

@@ -171,7 +158,6 @@ nyx = Nyxus(["*ALL*"])
171158
intensityDir = "/path/to/images/intensities/"
172159
maskDir = "/path/to/images/labels/"
173160
features = nyx.featurize_directory (intensityDir, maskDir)
174-
175161
print(nyx.get_params())
176162
```
177163

@@ -203,15 +189,16 @@ nyx = Nyxus(["*ALL*"])
203189
intensityDir = "/path/to/images/intensities/"
204190
maskDir = "/path/to/images/labels/"
205191
features = nyx.featurize_directory (intensityDir, maskDir)
206-
207192
print(nyx.get_params('coarse_gray_depth', 'features', 'gabor_f0'))
208193
```
209194
will print the dictionary
210195

211-
```bash
212-
{'coarse_gray_depth': 256,
213-
'features': ['*ALL*'],
214-
'gabor_f0': 0.1}
196+
```python
197+
{
198+
'coarse_gray_depth': 256,
199+
'features': ['*ALL*'],
200+
'gabor_f0': 0.1
201+
}
215202
```
216203

217204
## Available features
@@ -307,57 +294,108 @@ Assuming you [built the Nyxus binary](#building-from-source) as outlined below,
307294

308295
---
309296

310-
### Example: Running Nyxus to process images of specific image channel
297+
## Examples
298+
299+
<span style="color:blue">Example 1:</span> __Running Nyxus to process images of specific image channel__
311300

312301
Suppose we need to process intensity/mask images of channel 1 :
313-
```
302+
```
314303
./nyxus --features=*all_intensity*,*basic_morphology* --intDir=/path/to/intensity/images --segDir=/path/to/mask/images --outDir=/path/to/output --filePattern=.*_c1\.ome\.tif --csvFile=singlecsv
315304
```
316-
### Example: Running Nyxus to process specific image
305+
<span style="color:blue">Example 2:</span> __Running Nyxus to process specific image__
317306

318307
Suppose we need to process intensity/mask file p1_y2_r68_c1.ome.tif :
319308
```
320309
./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 --csvFile=singlecsv
321310
```
322311

323-
### Example: Running Nyxus to extract only intensity and basic morphology features
312+
<span style="color:blue">Example 3:</span> __Running Nyxus to extract only intensity and basic morphology features__
324313

325314
```
326315
./nyxus --features=*all_intensity*,*basic_morphology* --intDir=/path/to/intensity/images --segDir=/path/to/mask/images --outDir=/path/to/output --filePattern=.* --csvFile=singlecsv
327316
```
328317

329-
### Example: Skipping specified ROIs while extracting features
318+
<span style="color:blue">Example 4:</span> __Skipping specified ROIs while extracting features__
330319

331-
Suppose we need to blacklist ROI labels 15, 16, and 17 from feature extraction :
332-
```
333-
./nyxus --skiproi=15,16,17 --features=*all* --intDir=/path/to/intensity/images --segDir=/path/to/mask/images --outDir=/path/to/output --filePattern=.* --csvFile=singlecsv
320+
Suppose 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__ :
321+
```shell
322+
./nyxus --skiproi=2,3 --features=KURTOSIS --intDir=/path/to/intensity/images --segDir=/path/to/mask/images --outDir=/path/to/output --filePattern=.* --csvFile=singlecsv
334323
```
335324

336-
## Nested features
325+
As a result, the default feature extraction result produced without option --skiproi looking like
337326

338-
A separate command line executable "nyxushie" for the hierarchical ROI analysis by finding nested ROIs and aggregating features of child ROIs within corresponding parent features is available. Its command line format is:
327+
<pre>
328+
mask_image intensity_image label KURTOSIS
329+
0 p0_y1_r1_c0.tif p0_y1_r1_c0.tif 1 -0.134216
330+
1 p0_y1_r1_c0.tif p0_y1_r1_c0.tif 2 -0.130024<b>
331+
2 p0_y1_r1_c0.tif p0_y1_r1_c0.tif 3 -1.259801
332+
3 p0_y1_r1_c0.tif p0_y1_r1_c0.tif 4 -0.934786</b>
333+
4 p0_y1_r1_c0.tif p0_y1_r1_c0.tif 5 -1.072111
334+
.. ... ... ... ...
335+
</pre>
336+
337+
will start looking like
338+
339+
<pre>
340+
mask_image intensity_image label KURTOSIS
341+
0 p0_y1_r1_c0.tif p0_y1_r1_c0.tif 1 -0.134216
342+
1 p0_y1_r1_c0.tif p0_y1_r1_c0.tif 4 -0.934786
343+
2 p0_y1_r1_c0.tif p0_y1_r1_c0.tif 5 -1.072111
344+
3 p0_y1_r1_c0.tif p0_y1_r1_c0.tif 6 -0.347741
345+
4 p0_y1_r1_c0.tif p0_y1_r1_c0.tif 7 -1.283468
346+
.. ... ... ... ...
347+
</pre>
348+
349+
350+
Note the comma character separator <span style="background-color:lightgrey">&nbsp;&nbsp;<b>,</b>&nbsp;&nbsp;</span> in the blacklisted ROI label list.
351+
352+
If 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 :
339353
```
340-
nyxushie <segment image collection dir> <file pattern> <channel signature> <parent channel> <child channel> <features dir> [-aggregate=<aggregation method>]
354+
./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=.* --csvFile=singlecsv
341355
```
342-
where
356+
Note the colon character <span style="background-color:lightgrey">&nbsp;&nbsp;<b>:</b>&nbsp;&nbsp;</span> between the file name and backlisted labels within this file and semicolon character separator <span style="background-color:lightgrey">&nbsp;&nbsp;<b>;</b>&nbsp;&nbsp;</span> of file blacklists.
343357

344-
*\<segment image collection dir\>* is directory of the segment images collection ;
358+
<span style="color:blue">Example 5:</span> __Skipping specified ROIs while extracting features (via Python API)__
345359

346-
*\<file pattern\>* is a regular expression to filter files in \<segment image collection dir\> ;
360+
The 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:
361+
```python
362+
from nyxus import Nyxus
363+
nyx = Nyxus(features=["KURTOSIS"])
364+
nyx.blacklist_roi('15,16,17')
365+
features = nyx.featurize_directory (intensity_dir="/path/to/intensity/images", label_dir="/path/to/mask/images", file_pattern=".*")
366+
```
347367

348-
*\<channel signature\>* is a signature of the channel part in an image file name ;
368+
Similarly, per-file ROI blacklists are defined in a way similar to the command line interface:
369+
```python
370+
from nyxus import Nyxus
371+
nyx = Nyxus(features=["KURTOSIS"])
372+
nyx.blacklist_roi('p0_y1_r1_c0.ome.tif:15,16;p0_y1_r2_c0.ome.tif:17')
373+
features = nyx.featurize_directory (intensity_dir="/path/to/intensity/images", label_dir="/path/to/mask/images", file_pattern=".*")
374+
```
349375

350-
*\<parent channel\>* is an integer channel number where parent ROIs are expected ;
376+
See also methods __clear_roi_blacklist()__ and __roi_blacklist_get_summary()__ .
351377

352-
*\<child channel\>* is an integer channel number where child ROIs are expected ;
378+
## Nested features
353379

354-
*\<features dir\>* is a directory used as the output of parent-child ROI relations and, if aggregation is requested, where CSV files of Nyxus features produced with Nyxus command line option --csvfile=separatecsv is located ;
380+
A separate command line executable __nyxushie__ for the hierarchical ROI analysis by finding nested ROIs and aggregating features of child ROIs within corresponding parent features is available. Its command line format is:
381+
```
382+
nyxushie <segmentation dir> <file pattern> <channel signature> <parent channel> <child channel> <features dir> [-aggregate=<aggregation method>]
383+
```
384+
where
355385

356-
(optional) *\<aggregation method\>* is a method instructing how to aggregate child ROI features under a parent ROI.
386+
&nbsp;&nbsp;&nbsp; *\<<u>segmentation dir</u>\>* is directory of the segment images collection \
387+
&nbsp;&nbsp;&nbsp; *\<<u>file pattern</u>\>* is a regular expression to filter files in \<<u>segment image collection dir</u>\> \
388+
&nbsp;&nbsp;&nbsp; *\<<u>channel signature</u>\>* is a signature of the channel part in an image file name \
389+
&nbsp;&nbsp;&nbsp; *\<<u>parent channel</u>\>* is an integer channel number where parent ROIs are expected \
390+
&nbsp;&nbsp;&nbsp; *\<<u>child channel</u>\>* is an integer channel number where child ROIs are expected \
391+
&nbsp;&nbsp;&nbsp; *\<<u>features dir</u>\>* is a directory used as the output of parent-child ROI relations and, if aggregation is requested, where CSV files of Nyxus features produced with Nyxus command line option ```--csvfile=separatecsv``` is located \
392+
&nbsp;&nbsp;&nbsp; (optional) *\<<u>aggregation method</u>\>* is a method instructing how to aggregate child ROI features under a parent ROI.
357393

358394
Valid aggregation method options are: SUM, MEAN, MIN, MAX, or WMA (weighted mean average).
359395

360-
__Example__: we need to process collection of mask images located in directory "\~/data/image-collection1/seg" considering only images named "train_.*\\.tif" whose channel information begins with characters "\_ch" (\_ch0, \_ch1, etc.) telling Nyxushie to treat channel 1 images as source of parent ROIs and channel 0 images as source of child ROIs. The output directory needs to be "\~/results/result1". The command line will be
396+
<span style="color:blue">Example 6:</span> __Processing an image set containing ROI hierarchy__
397+
398+
We need to process collection of mask images located in directory "\~/data/image-collection1/seg" considering only images named "train_.*\\.tif" whose channel information begins with characters "\_ch" (\_ch0, \_ch1, etc.) telling Nyxushie to treat channel 1 images as source of parent ROIs and channel 0 images as source of child ROIs. The output directory needs to be "\~/results/result1". The command line will be
361399
```
362400
nyxushie ~/data/image-collection1/seg train_.*\\.tif _ch 1 0 ~/results/result1
363401
```
@@ -375,7 +413,7 @@ The `featurize` method takes in the parent-child mapping along with the features
375413
is 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.
376414

377415

378-
__Example__: Using aggregate functions
416+
__Example 7__: Using aggregate functions
379417

380418
``` python
381419

@@ -422,7 +460,7 @@ and the aggregated DataFrame is
422460

423461
```
424462

425-
__Example__: Without aggregate functions
463+
<span style="color:blue">Example 8:</span> __Without aggregate functions__
426464

427465
``` python
428466

@@ -461,7 +499,7 @@ the parent-child map remains the same but the `featurize` result becomes
461499

462500
Nyxus can either be build inside a `conda` environment or independently outside of it. For the later case, we provide a script to make it easier to download and build all the necessary dependencies.
463501

464-
### Inside Conda
502+
### __Inside Conda__
465503
Nyxus uses a CMake build system. To build the command line interface, pass `-DBUILD_CLI=ON` in the `cmake` command. For building with GPU support, use `-DUSEGPU=ON` flag in the `cmake` command. Here are the few notes on building with GPU support.
466504

467505
* Currently, GPU builds on Mac OS is not supported.
@@ -495,7 +533,7 @@ git clone https://github.com/PolusAI/nyxus.git
495533
cd nyxus/ci-utils
496534
./build_conda.sh ..
497535
```
498-
### Without Using Conda
536+
### __Without Using Conda__
499537
To build Nyxus outside of a `conda` environment, use the following example.
500538
```bash
501539
git clone https://github.com/PolusAI/nyxus.git
@@ -539,6 +577,7 @@ Nyxus is tested with Python 3.6+. Nyxus relies on the the following packages:
539577
[pybind11](https://github.com/pybind/pybind11) >= 2.8.1 <br>
540578
[libTIFF](http://www.libtiff.org) >= 3.6.1 <br>
541579
[Z5](https://github.com/constantinpape/z5) >=2.0.15 <br>
580+
542581
Each of these dependencies also have hierarchical dependencies and so we recommend using the `conda` build system when building from source.
543582

544583
## WIPP Usage

0 commit comments

Comments
 (0)