Skip to content
This repository was archived by the owner on Feb 11, 2023. It is now read-only.

Commit bc72e94

Browse files
committed
refactor cls Experiment
* fix RTD docs * fix used resize * loading yaml
1 parent 9d8967e commit bc72e94

File tree

9 files changed

+95
-61
lines changed

9 files changed

+95
-61
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -211,8 +211,8 @@ We utilise (un)supervised segmentation according to given training examples or s
211211

212212
The previous two (un)segmentation accept [configuration file](experiments_segmentation/sample_config.yml) (YAML) by parameter `-cfg` with some extra parameters which was not passed in arguments, for instance:
213213
```yaml
214-
slic_size: 35,
215-
slic_regul: 0.2,
214+
slic_size: 35
215+
slic_regul: 0.2
216216
features:
217217
color_hsv: ['mean', 'std', 'eng']
218218
classif: 'SVM'

docs/source/conf.py

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import sys
1717
import glob
1818
import shutil
19+
import inspect
1920

2021
import m2r
2122

@@ -274,7 +275,7 @@ def setup(app):
274275
MOCK_MODULES.append(pkg.rstrip())
275276

276277
# TODO: better parse from package since the import name and package name may differ
277-
autodoc_mock_imports = MOCK_MODULES + ['sklearn', 'skimage', 'gco']
278+
autodoc_mock_imports = MOCK_MODULES + ['sklearn', 'skimage', 'gco', 'yaml']
278279

279280

280281
# Options for the linkcode extension
@@ -292,12 +293,16 @@ def find_source():
292293
obj = sys.modules[info['module']]
293294
for part in info['fullname'].split('.'):
294295
obj = getattr(obj, part)
295-
import inspect
296-
import os
297-
fn = inspect.getsourcefile(obj)
298-
fn = os.path.relpath(fn, start=os.path.abspath('..'))
296+
fname = inspect.getsourcefile(obj)
297+
# https://github.com/rtfd/readthedocs.org/issues/5735
298+
if any([s in fname for s in ('readthedocs', 'checkouts')]):
299+
path_top = os.path.abspath(os.path.join('..', '..', '..'))
300+
fname = os.path.relpath(fname, start=path_top)
301+
else:
302+
# Local build, imitate master
303+
fname = 'master/' + os.path.relpath(fname, start=os.path.abspath('..'))
299304
source, lineno = inspect.getsourcelines(obj)
300-
return fn, lineno, lineno + len(source) - 1
305+
return fname, lineno, lineno + len(source) - 1
301306

302307
if domain != 'py' or not info['module']:
303308
return None
@@ -308,7 +313,7 @@ def find_source():
308313
# import subprocess
309314
# tag = subprocess.Popen(['git', 'rev-parse', 'HEAD'], stdout=subprocess.PIPE,
310315
# universal_newlines=True).communicate()[0][:-1]
311-
return "https://github.com/%s/%s/blob/master/%s" \
316+
return "https://github.com/%s/%s/blob/%s" \
312317
% (github_user, github_repo, filename)
313318

314319

experiments_ovary_centres/run_center_candidate_training.py

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@
3131
import multiprocessing as mproc
3232
from functools import partial
3333

34-
import yaml
3534
import tqdm
3635
import pandas as pd
3736
import numpy as np
@@ -170,8 +169,7 @@ def arg_parse_params(params):
170169
ext = os.path.splitext(params['path_config'])[-1]
171170
assert (ext == '.yaml' or ext == '.yml'), \
172171
'wrong extension for %s' % params['path_config']
173-
with open(params['path_config'], 'r') as fd:
174-
data = yaml.load(fd)
172+
data = tl_expt.load_config_yaml(params['path_config'])
175173
params.update(data)
176174
params.update(paths)
177175
logging.info('ARG PARAMETERS: \n %r', params)
@@ -711,10 +709,7 @@ def main_train(params):
711709

712710
tl_expt.set_experiment_logger(params['path_expt'])
713711
logging.info(tl_expt.string_dict(params, desc='PARAMETERS'))
714-
715-
with open(os.path.join(params['path_expt'], NAME_YAML_PARAMS), 'w') as fp:
716-
yaml.dump(params, fp, default_flow_style=False)
717-
712+
tl_expt.save_config_yaml(os.path.join(params['path_expt'], NAME_YAML_PARAMS), params)
718713
tl_expt.create_subfolders(params['path_expt'], LIST_SUBDIRS)
719714

720715
df_paths, _ = load_df_paths(params)

experiments_ovary_centres/run_center_clustering.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
# import multiprocessing as mproc
1313
from functools import partial
1414

15-
import yaml
1615
import pandas as pd
1716
import numpy as np
1817
from sklearn import cluster
@@ -195,9 +194,7 @@ def main(params):
195194
"""
196195
params['path_expt'] = os.path.join(params['path_output'],
197196
FOLDER_EXPERIMENT % params['name'])
198-
with open(os.path.join(params['path_expt'], NAME_YAML_PARAMS), 'w') as fp:
199-
yaml.dump(params, fp, default_flow_style=False)
200-
197+
tl_expt.save_config_yaml(os.path.join(params['path_expt'], NAME_YAML_PARAMS), params)
201198
tl_expt.create_subfolders(params['path_expt'], LIST_SUBDIRS)
202199

203200
list_paths = [params[k] for k in ['path_images', 'path_segms', 'path_centers']]

experiments_ovary_detect/run_ovary_egg-segmentation.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@
3737
print('No display found. Using non-interactive Agg backend.')
3838
matplotlib.use('Agg')
3939

40-
import yaml
4140
import numpy as np
4241
import pandas as pd
4342
import matplotlib.pyplot as plt
@@ -158,8 +157,7 @@ def arg_parse_params(params):
158157
ext = os.path.splitext(params['path_config'])[-1]
159158
assert (ext == '.yaml' or ext == '.yml'), \
160159
'"%s" should be YAML file' % os.path.basename(params['path_config'])
161-
with open(params['path_config'], 'r') as fd:
162-
data = yaml.load(fd)
160+
data = tl_expt.load_config_yaml(params['path_config'])
163161
params.update(data)
164162
params.update(arg_params)
165163
for k in (k for k in arg_params if 'path' in k):

experiments_segmentation/run_segm_slic_model_graphcut.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@
3737
print('No display found. Using non-interactive Agg backend.')
3838
matplotlib.use('Agg')
3939

40-
import yaml
4140
from PIL import Image
4241
import numpy as np
4342
import pandas as pd
@@ -162,8 +161,7 @@ def arg_parse_params(params):
162161
# args['visual'] = bool(args['visual'])
163162
# if the config path is set load the it otherwise use default
164163
if os.path.isfile(args.get('path_config', '')):
165-
with open(args['path_config'], 'r') as fd:
166-
config = yaml.load(fd)
164+
config = tl_expt.load_config_yaml(args['path_config'])
167165
params.update(config)
168166
params.update(args)
169167
return params

imsegm/__init__.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@
1717
__license__ = 'BSD 3-clause'
1818
__homepage__ = 'https://borda.github.io/pyImSegm'
1919
__copyright__ = 'Copyright (c) 2014-2019, Jiri Borovec.'
20-
__doc__ = """
21-
# Image segmentation - general superpixel segmentation & region growing
20+
__doc__ = """# Image segmentation - general superpixel segmentation & region growing
2221
2322
This package is aiming at (un/semi)supervised segmentation on superpixels with
2423
computing some basic colour and texture features. This general segmentation

imsegm/tests/test_pipelines.py

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
import unittest
1212

1313
import matplotlib.pyplot as plt
14-
from scipy.misc import imresize
14+
from skimage.transform import resize
1515

1616
sys.path.append(os.path.abspath(os.path.join('..', '..'))) # Add path to root
1717
import imsegm.descriptors
@@ -111,7 +111,7 @@ class TestPipelinesGMM(unittest.TestCase):
111111
# img3d = get_image_path(IMAGE_DROSOPHILA_OVARY_3D)
112112

113113
def test_segm_gmm_gc_objects(self):
114-
img = imresize(self.img_obj, (256, 256))
114+
img = resize(self.img_obj, output_shape=(256, 256))
115115
logging.debug('dimension: {}'.format(img.shape))
116116

117117
dict_imgs = dict()
@@ -137,28 +137,28 @@ def test_segm_gmm_gc_stars(self):
137137
run_segm2d_gmm_gc(img, 'temp_segm-gmm-gc-stars', params=params)
138138

139139
# def sample_segm_gmm_gc_langer(self):
140-
# img = imresize(self.img_islet, (512, 512))
140+
# img = resize(self.img_islet, (512, 512))
141141
# params = copy.deepcopy(DEFAULT_SEGM_PARAMS)
142142
# params.update(dict(sp_regul=0.15, sp_size=5))
143143
# run_segm2d_gmm_gc(img, 'temp_segm-gmm-gc-langer', types_edge=['model_lT'],
144144
# list_regul=[0, 1], params=params)
145145

146146
# def sample_segm_gmm_gc_histo(self):
147-
# img = imresize(self.img_histo, (512, 512))
147+
# img = resize(self.img_histo, (512, 512))
148148
# params = copy.deepcopy(DEFAULT_SEGM_PARAMS)
149149
# params.update(dict(sp_regul=0.15, sp_size=15, pca_coef=0.98))
150150
# run_segm2d_gmm_gc(img, 'temp_segm-gmm-gc-histology', types_edge=['model'],
151151
# list_regul=[0, 1, 5], params=params)
152152

153153
# def sample_segm_gmm_gc_disc(self):
154-
# img = imresize(self.img_disc, (512, 512))
154+
# img = resize(self.img_disc, (512, 512))
155155
# params = copy.deepcopy(DEFAULT_SEGM_PARAMS)
156156
# params.update(dict(sp_regul=0.2, sp_size=15, pca_coef=0.98))
157157
# run_segm2d_gmm_gc(img, 'temp_segm-gmm-gc-disc', types_edge=['model_l2'],
158158
# list_regul=[0, 1, 5], params=params)
159159

160160
# def sample_segm_gmm_gc_ovary_2d(self):
161-
# img = imresize(self.img_ovary[:, :, 0], (512, 512))
161+
# img = resize(self.img_ovary[:, :, 0], (512, 512))
162162
# # img = np.rollaxis(np.tile(img[:, :, 0], (3, 1, 1)), 0, 3)
163163
# params = copy.deepcopy(DEFAULT_SEGM_PARAMS)
164164
# params.update(dict(nb_classes=4, pca_coef=0.95, sp_regul=0.3, sp_size=10,
@@ -180,9 +180,10 @@ class TestPipelinesClassif(unittest.TestCase):
180180
img2 = load_sample_image(IMAGE_DROSOPHILA_OVARY_2D)[:, :, 0]
181181

182182
def test_segm_supervised(self):
183-
img = imresize(self.img, (256, 256))
184-
annot = imresize(self.annot, (256, 256), interp='nearest')
185-
img2 = imresize(self.img2, (256, 256))
183+
img = resize(self.img, output_shape=(256, 256))
184+
annot = resize(self.annot, output_shape=(256, 256), order=0,
185+
preserve_range=True).astype(int)
186+
img2 = resize(self.img2, output_shape=(256, 256))
186187

187188
path_dir = os.path.join(PATH_OUTPUT, 'temp_segm-supervised_gc')
188189
if not os.path.exists(path_dir):

imsegm/utilities/experiments.py

Lines changed: 65 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -45,51 +45,67 @@ class Experiment(object):
4545
>>> shutil.rmtree(params['path_out'], ignore_errors=True)
4646
"""
4747

48-
def __init__(self, dict_params, time_stamp=True):
49-
self.params = copy.deepcopy(dict_params)
48+
def __init__(self, params, time_stamp=True):
49+
""" constructor
50+
51+
:param dict params: define experimenatl parameters
52+
:param bool time_stamp: add to experiment unique time stamp
53+
"""
54+
self.params = copy.deepcopy(params)
5055
self.params['class'] = self.__class__.__name__
51-
self.__check_exist_path()
52-
self.__create_folder(time_stamp)
56+
self._check_exist_paths()
57+
self._create_folder(time_stamp)
5358
set_experiment_logger(self.params['path_exp'])
5459
logging.info(string_dict(self.params, desc='PARAMETERS'))
5560

5661
def run(self, gt=True):
62+
""" run the main Experimental body
63+
64+
:param bool gt: try to load Ground Truth
65+
"""
5766
self._load_data(gt)
5867
self._perform()
5968
self._evaluate()
6069
self._summarise()
6170
logging.getLogger().handlers = []
6271

63-
def _load_data(self, gt):
64-
pass
72+
def _load_data(self, gt=True):
73+
""" loading the experiment data
74+
75+
:param bool gt: try to load ground truth
76+
"""
77+
logging.warning('Not implemented yet...')
6578

6679
def _perform(self):
67-
pass
80+
logging.warning('Not implemented yet...')
6881

6982
def _evaluate(self):
70-
pass
83+
logging.warning('Not implemented yet...')
7184

7285
def _summarise(self):
73-
pass
86+
logging.warning('Not implemented yet...')
7487

75-
def __check_exist_path(self):
76-
for p in [self.params[n] for n in self.params
77-
if 'dir_name' in n.lower() or 'path' in n.lower()]:
88+
def _check_exist_paths(self):
89+
""" Check all required paths in parameters whether they exist """
90+
for p in (self.params[n] for n in self.params
91+
if 'dir' in n.lower() or 'path' in n.lower()):
7892
if not os.path.exists(p):
79-
raise Exception('given folder "{}" does not exist!'.format(p))
80-
for p in [self.params[n] for n in self.params if 'file' in n.lower()]:
93+
raise Exception('given folder "%s" does not exist!' % p)
94+
for p in (self.params[n] for n in self.params if 'file' in n.lower()):
8195
if not os.path.exists(p):
82-
raise Exception('given file "{}" does not exist!'.format(p))
96+
raise Exception('given folder "%s" does not exist!' % p)
97+
98+
def _create_folder(self, time_stamp=True):
99+
""" Create the experiment folder and iterate while there is no available
83100
84-
def __create_folder(self, time_stamp):
85-
""" create the experiment folder and iterate while there is no available
101+
:param bool time_stamp: mark if you want an unique folder per experiment
86102
"""
87103
# create results folder for experiments
88-
assert os.path.isdir(self.params.get('path_out')), \
89-
'missing %s' % self.params.get('path_out')
104+
if not os.path.exists(self.params.get('path_out', 'NONE')):
105+
raise ValueError('no results folder "%r"' % self.params.get('path_out', None))
90106
self.params = create_experiment_folder(self.params,
91107
self.__class__.__name__,
92-
stamp_unique=time_stamp)
108+
time_stamp)
93109

94110

95111
# def check_exist_dirs_files(params):
@@ -146,15 +162,13 @@ def create_experiment_folder(params, dir_name, stamp_unique=True, skip_load=True
146162
if os.path.exists(path_config) and not skip_load:
147163
params_in = params
148164
logging.debug('loading saved params from file "%s"', CONFIG_YAML)
149-
with open(path_config, 'r') as fp:
150-
params = yaml.load(fp)
165+
params = load_config_yaml(path_config)
151166
params.update({k: params_in[k] for k in params_in if 'path' in k})
152167
logging.info('loaded following PARAMETERS: %s', string_dict(params))
153168
params.update({'computer': os.uname(),
154169
'path_exp': path_expt})
155170
logging.debug('saving params to file "%s"', CONFIG_YAML)
156-
with open(path_config, 'w') as fp:
157-
yaml.dump(params, fp, default_flow_style=False)
171+
save_config_yaml(path_config, params)
158172
return params
159173

160174

@@ -404,3 +418,30 @@ def __len__(self):
404418
# for out in map(wrap_func, iterate_vals):
405419
# yield out
406420
# tqdm_bar.update()
421+
422+
423+
def load_config_yaml(path_config):
424+
""" loading the
425+
426+
:param str path_config:
427+
:return dict:
428+
429+
>>> p_conf = './testing-congif.yaml'
430+
>>> save_config_yaml(p_conf, {'a': 2})
431+
>>> load_config_yaml(p_conf)
432+
{'a': 2}
433+
>>> os.remove(p_conf)
434+
"""
435+
with open(path_config, 'r') as fp:
436+
config = yaml.load(fp)
437+
return config
438+
439+
440+
def save_config_yaml(path_config, config):
441+
""" exporting configuration as YAML file
442+
443+
:param str path_config:
444+
:param dict config:
445+
"""
446+
with open(path_config, 'w') as fp:
447+
yaml.dump(config, fp, default_flow_style=False)

0 commit comments

Comments
 (0)