Skip to content

Commit 7662576

Browse files
authored
POL5803 whole 3d workflow updated (PolusAI#289)
1 parent 3955ab4 commit 7662576

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+1335
-228
lines changed

CMakeLists.txt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -234,10 +234,11 @@ set(SOURCE
234234
src/nyx/roi_cache_basic.cpp
235235
src/nyx/slideprops.cpp
236236
src/nyx/strpat.cpp
237-
src/nyx/workflow_3d.cpp
237+
src/nyx/workflow_2d_segmented.cpp
238+
src/nyx/workflow_2d_whole.cpp
239+
src/nyx/workflow_3d_segmented.cpp
240+
src/nyx/workflow_3d_whole.cpp
238241
src/nyx/workflow_pythonapi.cpp
239-
src/nyx/workflow_segmented.cpp
240-
src/nyx/workflow_wholeslide.cpp
241242
)
242243

243244
# CLI

README.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,29 @@ mdir = [
176176
nyx.featurize_files (idir, mdir, False) # pass True to featurize intensity files as whole segments
177177
```
178178

179+
### Whole-slide and whole-volume feature extraction
180+
181+
Nyxus provides dedicated workflows for extracting features from whole 2D slides and volumes. The workflows scale across CPU cores as controlled by constructor parameter `n_feature_calc_threads` of classes Nyxus and Nyxus3D.
182+
183+
Example -- whole-slide featurization with 4 threads:
184+
185+
```
186+
dir = "/2d_dataset/intensity"
187+
import nyxus
188+
nyx = nyxus.Nyxus (features=["*ALL*"], n_feature_calc_threads=4)
189+
f = nyx.featurize_directory (intensity_dir=dir, label_dir=dir)
190+
```
191+
192+
Example -- whole-volume featurization of a NIFTI dataset with 4 threads:
193+
194+
```
195+
dir = "/3d_dataset"
196+
import nyxus
197+
nyx = nyxus.Nyxus3D (features=["*3D_ALL*"], n_feature_calc_threads=4)
198+
f = nyx.featurize_directory (intensity_dir=dir, label_dir=dir, file_pattern=".*\\.nii\\.gz")
199+
```
200+
201+
179202
## Further steps
180203

181204
For more information on all of the available options and features, check out [the documentation](#).

docs/source/featurelist.rst

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -717,7 +717,16 @@ Nyxus-provided features
717717
- volume of the triangle mesh of ROI's convex hull
718718
* - 3VOXEL_VOLUME
719719
- total of volumes of voxels of the ROI
720-
720+
* - 3MAJOR_AXIS_LEN
721+
- measure of the largest principal component of the ROI voxel cloud
722+
* - 3MINOR_AXIS_LEN
723+
- measure of the 2nd largest principal component of the ROI voxel cloud
724+
* - 3LEAST_AXIS_LEN
725+
- measure of the smallest principal component of the ROI voxel cloud
726+
* - 3ELONGATION
727+
- ratio of the two largest principal components of the ROI voxel cloud
728+
* - 3FLATNESS
729+
- ratio of the largest and smallest principal components of the ROI voxel cloud
721730

722731
**3D texture features:**
723732

src/nyx/dirs_and_files.cpp

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,42 @@ namespace Nyxus
415415
return 0;
416416
}
417417

418+
int read_3D_dataset_wholevolume (
419+
// input:
420+
const std::string& dirIntens,
421+
const StringPattern& filePatt,
422+
const std::string& dirOut,
423+
// output:
424+
std::vector <std::string>& intensFiles)
425+
{
426+
if (!existsOnFilesystem(dirIntens))
427+
{
428+
std::cout << "Error: nonexisting directory " << dirIntens << std::endl;
429+
return 1;
430+
}
431+
if (!existsOnFilesystem(dirOut))
432+
{
433+
std::cout << "Error: nonexisting directory " << dirOut << std::endl;
434+
return 2;
435+
}
436+
437+
// Common case - no ad hoc intensity-label file mapping, 1-to-1 correspondence instead
438+
439+
// read file names into a plain vector of strings (non-wholevolume counterpart: readDirectoryFiles_3D() )
440+
std::vector<std::string> fnamesOnly;
441+
std::string p = filePatt.get_cached_pattern_string();
442+
readDirectoryFiles_2D (dirIntens, p, intensFiles, fnamesOnly);
443+
444+
// Check if the dataset isn't blank
445+
if (intensFiles.size() == 0)
446+
{
447+
std::cout << "No intensity file pairs to process, probably due to file pattern " << filePatt.get_cached_pattern_string() << std::endl;
448+
return 3;
449+
}
450+
451+
return 0;
452+
}
453+
418454
Imgfile3D_layoutA::Imgfile3D_layoutA(const std::string& possibly_full_path)
419455
{
420456
auto p = fs::path(possibly_full_path);

src/nyx/dirs_and_files.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,14 @@ namespace Nyxus
6666
std::vector <Imgfile3D_layoutA>& intensFiles,
6767
std::vector <Imgfile3D_layoutA>& labelFiles);
6868

69+
int read_3D_dataset_wholevolume(
70+
// input:
71+
const std::string& dirIntens,
72+
const StringPattern& filePatt,
73+
const std::string& dirOut,
74+
// output:
75+
std::vector <std::string>& intensFiles);
76+
6977
/// @brief checks if the Tiff file is tiled or not
7078
/// @param filePath File name with complete path
7179
bool check_tile_status(const std::string& filePath);

src/nyx/features/3d_glcm.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1253,3 +1253,12 @@ void D3_GLCM_feature::reduce(size_t start, size_t end, std::vector<int>* ptrLabe
12531253
f.save_value(r.fvals);
12541254
}
12551255
}
1256+
1257+
/*static*/ void D3_GLCM_feature::extract (LR& r)
1258+
{
1259+
D3_GLCM_feature f;
1260+
f.calculate(r);
1261+
f.save_value(r.fvals);
1262+
}
1263+
1264+

src/nyx/features/3d_glcm.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ class D3_GLCM_feature : public FeatureMethod, public TextureFeature
127127
void save_value(std::vector<std::vector<double>>& feature_vals);
128128
static void parallel_process_1_batch(size_t start, size_t end, std::vector<int>* ptrLabels, std::unordered_map <int, LR>* ptrLabelData);
129129
static void reduce(size_t start, size_t end, std::vector<int>* ptrLabels, std::unordered_map <int, LR>* ptrLabelData);
130+
static void extract(LR& r);
130131

131132
private:
132133

src/nyx/features/3d_gldm.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -542,3 +542,9 @@ void D3_GLDM_feature::reduce (size_t start, size_t end, std::vector<int>* ptrLab
542542
}
543543
}
544544

545+
/*static*/ void D3_GLDM_feature::extract (LR& r)
546+
{
547+
D3_GLDM_feature f;
548+
f.calculate(r);
549+
f.save_value(r.fvals);
550+
}

src/nyx/features/3d_gldm.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ class D3_GLDM_feature : public FeatureMethod, public TextureFeature
4747
void osized_calculate(LR& r, ImageLoader& imloader);
4848
void save_value(std::vector<std::vector<double>>& feature_vals);
4949
static void reduce (size_t start, size_t end, std::vector<int>* ptrLabels, std::unordered_map <int, LR>* ptrLabelData);
50+
static void extract (LR& r);
5051

5152
// 1. Small Dependence Emphasis(SDE)
5253
double calc_SDE();

src/nyx/features/3d_gldzm.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,13 @@ void D3_GLDZM_feature::reduce (size_t start, size_t end, std::vector<int>* ptrLa
2424
}
2525
}
2626

27+
/*static*/ void D3_GLDZM_feature::extract(LR& r)
28+
{
29+
D3_GLDZM_feature f;
30+
f.calculate(r);
31+
f.save_value(r.fvals);
32+
}
33+
2734
void D3_GLDZM_feature::clear_buffers()
2835
{
2936
f_SDE =

0 commit comments

Comments
 (0)