pcntoolkit 0.29.post1__tar.gz → 0.30__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/LICENSE +0 -0
- {pcntoolkit-0.29.post1/pcntoolkit.egg-info → pcntoolkit-0.30}/PKG-INFO +1 -5
- {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/pcntoolkit/model/hbr.py +1 -1
- {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/pcntoolkit/normative.py +13 -3
- {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/pcntoolkit/normative_model/norm_hbr.py +14 -7
- {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/pcntoolkit/normative_parallel.py +158 -81
- {pcntoolkit-0.29.post1 → pcntoolkit-0.30/pcntoolkit.egg-info}/PKG-INFO +1 -5
- {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/pcntoolkit.egg-info/requires.txt +1 -1
- {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/requirements.txt +1 -1
- {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/setup.py +5 -1
- pcntoolkit-0.30/tests/test_normative_parallel.py +49 -0
- pcntoolkit-0.29.post1/tests/test_normative_parallel.py +0 -35
- {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/MANIFEST.in +0 -0
- {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/README.md +0 -0
- {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/pcntoolkit/__init__.py +0 -0
- {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/pcntoolkit/configs.py +0 -0
- {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/pcntoolkit/dataio/__init__.py +0 -0
- {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/pcntoolkit/dataio/fileio.py +0 -0
- {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/pcntoolkit/model/NP.py +0 -0
- {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/pcntoolkit/model/NPR.py +0 -0
- {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/pcntoolkit/model/SHASH.py +0 -0
- {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/pcntoolkit/model/__init__.py +0 -0
- {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/pcntoolkit/model/architecture.py +0 -0
- {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/pcntoolkit/model/bayesreg.py +0 -0
- {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/pcntoolkit/model/gp.py +0 -0
- {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/pcntoolkit/model/rfa.py +0 -0
- {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/pcntoolkit/normative_NP.py +0 -0
- {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/pcntoolkit/normative_model/__init__.py +0 -0
- {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/pcntoolkit/normative_model/norm_base.py +0 -0
- {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/pcntoolkit/normative_model/norm_blr.py +0 -0
- {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/pcntoolkit/normative_model/norm_gpr.py +0 -0
- {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/pcntoolkit/normative_model/norm_np.py +0 -0
- {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/pcntoolkit/normative_model/norm_rfa.py +0 -0
- {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/pcntoolkit/normative_model/norm_utils.py +0 -0
- {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/pcntoolkit/trendsurf.py +0 -0
- {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/pcntoolkit/util/__init__.py +0 -0
- {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/pcntoolkit/util/hbr_utils.py +0 -0
- {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/pcntoolkit/util/utils.py +0 -0
- {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/pcntoolkit.egg-info/SOURCES.txt +0 -0
- {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/pcntoolkit.egg-info/dependency_links.txt +0 -0
- {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/pcntoolkit.egg-info/not-zip-safe +0 -0
- {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/pcntoolkit.egg-info/top_level.txt +0 -0
- {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/setup.cfg +0 -0
- {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/tests/testHBR.py +0 -0
- {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/tests/testHBR_transfer.py +0 -0
- {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/tests/test_NP.py +0 -0
- {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/tests/test_ST_NP.py +0 -0
- {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/tests/test_blr.py +0 -0
- {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/tests/test_gpr.py +0 -0
- {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/tests/test_hbr_pymc.py +0 -0
- {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/tests/test_normative.py +0 -0
- {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/tests/test_rand_feat.py +0 -0
|
File without changes
|
|
@@ -1,13 +1,9 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: pcntoolkit
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.30
|
|
4
4
|
Summary: Predictive Clinical Neuroscience toolkit
|
|
5
5
|
Home-page: http://github.com/amarquand/PCNtoolkit
|
|
6
6
|
Author: Andre Marquand
|
|
7
7
|
Author-email: andre.marquand@donders.ru.nl
|
|
8
8
|
License: GNU GPLv3
|
|
9
|
-
Platform: UNKNOWN
|
|
10
9
|
License-File: LICENSE
|
|
11
|
-
|
|
12
|
-
UNKNOWN
|
|
13
|
-
|
|
@@ -580,7 +580,7 @@ class HBR:
|
|
|
580
580
|
modeler = self.get_modeler()
|
|
581
581
|
with modeler(X, y, batch_effects, self.configs, idata=self.idata):
|
|
582
582
|
self.idata = pm.sample_posterior_predictive(
|
|
583
|
-
self.idata, extend_inferencedata=True, progressbar=True
|
|
583
|
+
self.idata, extend_inferencedata=True, progressbar=True, var_names=self.vars_to_sample
|
|
584
584
|
)
|
|
585
585
|
pred_mean = self.idata.posterior_predictive["y_like"].mean(axis=(0, 1))
|
|
586
586
|
pred_var = self.idata.posterior_predictive["y_like"].var(axis=(0, 1))
|
|
@@ -819,7 +819,6 @@ def predict(covfile, respfile, maskfile=None, **kwargs):
|
|
|
819
819
|
Xz = X
|
|
820
820
|
|
|
821
821
|
# estimate the models for all variabels
|
|
822
|
-
# TODO Z-scores adaptation for SHASH HBR
|
|
823
822
|
for i, m in enumerate(models):
|
|
824
823
|
print("Prediction by model ", i+1, "of", feature_num)
|
|
825
824
|
nm = norm_init(Xz)
|
|
@@ -842,6 +841,19 @@ def predict(covfile, respfile, maskfile=None, **kwargs):
|
|
|
842
841
|
else:
|
|
843
842
|
Yhat[:, i] = yhat.squeeze()
|
|
844
843
|
S2[:, i] = s2.squeeze()
|
|
844
|
+
if respfile is not None:
|
|
845
|
+
Y, maskvol = load_response_vars(respfile, maskfile)
|
|
846
|
+
Y = Y[:, i:i+1]
|
|
847
|
+
if alg == 'hbr':
|
|
848
|
+
if outscaler in ['standardize', 'minmax', 'robminmax']:
|
|
849
|
+
Yz = scaler_resp[fold].transform(Y)
|
|
850
|
+
else:
|
|
851
|
+
Yz = Y
|
|
852
|
+
Z[:,i] = nm.get_mcmc_zscores(Xz, Yz, **kwargs)
|
|
853
|
+
else:
|
|
854
|
+
Z[:,i] = (Y - Yhat[:, i]) / np.sqrt(S2[:, i])
|
|
855
|
+
|
|
856
|
+
|
|
845
857
|
|
|
846
858
|
if respfile is None:
|
|
847
859
|
save_results(None, Yhat, S2, None, outputsuffix=outputsuffix)
|
|
@@ -881,8 +893,6 @@ def predict(covfile, respfile, maskfile=None, **kwargs):
|
|
|
881
893
|
else:
|
|
882
894
|
warp = False
|
|
883
895
|
|
|
884
|
-
Z = (Y - Yhat) / np.sqrt(S2)
|
|
885
|
-
|
|
886
896
|
print("Evaluating the model ...")
|
|
887
897
|
if meta_data and not warp:
|
|
888
898
|
|
|
@@ -545,14 +545,21 @@ class NormHBR(NormBase):
|
|
|
545
545
|
if 'posterior_predictive' in self.hbr.idata.groups():
|
|
546
546
|
del self.hbr.idata.posterior_predictive
|
|
547
547
|
|
|
548
|
+
if self.configs["transferred"] == True:
|
|
549
|
+
self.predict_on_new_sites(
|
|
550
|
+
X=X,
|
|
551
|
+
batch_effects=batch_effects
|
|
552
|
+
)
|
|
553
|
+
#var_names = ["y_like"]
|
|
554
|
+
else:
|
|
555
|
+
self.hbr.predict(
|
|
548
556
|
# Do a forward to get the posterior predictive in the idata
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
)
|
|
557
|
+
X=X,
|
|
558
|
+
batch_effects=batch_effects,
|
|
559
|
+
batch_effects_maps=self.batch_effects_maps,
|
|
560
|
+
pred="single",
|
|
561
|
+
var_names=var_names+["y_like"],
|
|
562
|
+
)
|
|
556
563
|
|
|
557
564
|
# Extract the relevant samples from the idata
|
|
558
565
|
post_pred = az.extract(
|
|
@@ -30,7 +30,8 @@ import fileinput
|
|
|
30
30
|
import time
|
|
31
31
|
import numpy as np
|
|
32
32
|
import pandas as pd
|
|
33
|
-
from
|
|
33
|
+
from datetime import datetime
|
|
34
|
+
from subprocess import run, check_output
|
|
34
35
|
|
|
35
36
|
|
|
36
37
|
try:
|
|
@@ -87,6 +88,7 @@ def execute_nm(processing_dir,
|
|
|
87
88
|
:param testrespfile_path: Full path to a .txt file that contains all test features
|
|
88
89
|
:param log_path: Path for saving log files
|
|
89
90
|
:param binary: If True uses binary format for response file otherwise it is text
|
|
91
|
+
:param cluster_spec: 'torque' for PBS Torque and 'slurm' for Slurm clusters.
|
|
90
92
|
:param interactive: If False (default) the user should manually
|
|
91
93
|
rerun the failed jobs or collect the results.
|
|
92
94
|
If 'auto' the job status are checked until all
|
|
@@ -106,7 +108,7 @@ def execute_nm(processing_dir,
|
|
|
106
108
|
cv_folds = kwargs.get('cv_folds', None)
|
|
107
109
|
testcovfile_path = kwargs.get('testcovfile_path', None)
|
|
108
110
|
testrespfile_path = kwargs.get('testrespfile_path', None)
|
|
109
|
-
outputsuffix = kwargs.get('outputsuffix', '
|
|
111
|
+
outputsuffix = kwargs.get('outputsuffix', '_estimate')
|
|
110
112
|
cluster_spec = kwargs.pop('cluster_spec', 'torque')
|
|
111
113
|
log_path = kwargs.get('log_path', None)
|
|
112
114
|
binary = kwargs.pop('binary', False)
|
|
@@ -129,6 +131,8 @@ def execute_nm(processing_dir,
|
|
|
129
131
|
|
|
130
132
|
kwargs.update({'batch_size': str(batch_size)})
|
|
131
133
|
job_ids = []
|
|
134
|
+
start_time = datetime.now().strftime("%Y-%m-%dT%H:%M:%S")
|
|
135
|
+
|
|
132
136
|
for n in range(1, number_of_batches+1):
|
|
133
137
|
kwargs.update({'job_id': str(n)})
|
|
134
138
|
if testrespfile_path is not None:
|
|
@@ -163,7 +167,7 @@ def execute_nm(processing_dir,
|
|
|
163
167
|
memory=memory,
|
|
164
168
|
duration=duration)
|
|
165
169
|
job_ids.append(job_id)
|
|
166
|
-
elif cluster_spec == '
|
|
170
|
+
elif cluster_spec == 'slurm':
|
|
167
171
|
# update the response file
|
|
168
172
|
kwargs.update({'testrespfile_path':
|
|
169
173
|
batch_testrespfile_path})
|
|
@@ -177,8 +181,11 @@ def execute_nm(processing_dir,
|
|
|
177
181
|
memory=memory,
|
|
178
182
|
duration=duration,
|
|
179
183
|
**kwargs)
|
|
180
|
-
|
|
181
|
-
|
|
184
|
+
|
|
185
|
+
job_id = sbatch_nm(job_path=batch_job_path)
|
|
186
|
+
job_ids.append(job_id)
|
|
187
|
+
|
|
188
|
+
|
|
182
189
|
elif cluster_spec == 'new':
|
|
183
190
|
# this part requires addition in different envioronment [
|
|
184
191
|
sbatchwrap_nm(processing_dir=batch_processing_dir,
|
|
@@ -207,7 +214,7 @@ def execute_nm(processing_dir,
|
|
|
207
214
|
memory=memory,
|
|
208
215
|
duration=duration)
|
|
209
216
|
job_ids.append(job_id)
|
|
210
|
-
elif cluster_spec == '
|
|
217
|
+
elif cluster_spec == 'slurm':
|
|
211
218
|
sbatchwrap_nm(batch_processing_dir,
|
|
212
219
|
python_path,
|
|
213
220
|
normative_path,
|
|
@@ -218,8 +225,9 @@ def execute_nm(processing_dir,
|
|
|
218
225
|
memory=memory,
|
|
219
226
|
duration=duration,
|
|
220
227
|
**kwargs)
|
|
221
|
-
|
|
222
|
-
|
|
228
|
+
|
|
229
|
+
job_id = sbatch_nm(job_path=batch_job_path)
|
|
230
|
+
job_ids.append(job_id)
|
|
223
231
|
elif cluster_spec == 'new':
|
|
224
232
|
# this part requires addition in different envioronment [
|
|
225
233
|
bashwrap_nm(processing_dir=batch_processing_dir, func=func,
|
|
@@ -249,7 +257,7 @@ def execute_nm(processing_dir,
|
|
|
249
257
|
memory=memory,
|
|
250
258
|
duration=duration)
|
|
251
259
|
job_ids.append(job_id)
|
|
252
|
-
elif cluster_spec == '
|
|
260
|
+
elif cluster_spec == 'slurm':
|
|
253
261
|
sbatchwrap_nm(batch_processing_dir,
|
|
254
262
|
python_path,
|
|
255
263
|
normative_path,
|
|
@@ -260,8 +268,11 @@ def execute_nm(processing_dir,
|
|
|
260
268
|
memory=memory,
|
|
261
269
|
duration=duration,
|
|
262
270
|
**kwargs)
|
|
263
|
-
|
|
264
|
-
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
job_id = sbatch_nm(job_path=batch_job_path)
|
|
274
|
+
job_ids.append(job_id)
|
|
275
|
+
|
|
265
276
|
elif cluster_spec == 'new':
|
|
266
277
|
# this part requires addition in different envioronment [
|
|
267
278
|
bashwrap_nm(processing_dir=batch_processing_dir, func=func,
|
|
@@ -271,7 +282,7 @@ def execute_nm(processing_dir,
|
|
|
271
282
|
|
|
272
283
|
if interactive:
|
|
273
284
|
|
|
274
|
-
check_jobs(job_ids, delay=60)
|
|
285
|
+
check_jobs(job_ids, cluster_spec, start_time, delay=60)
|
|
275
286
|
|
|
276
287
|
success = False
|
|
277
288
|
while (not success):
|
|
@@ -288,16 +299,33 @@ def execute_nm(processing_dir,
|
|
|
288
299
|
if interactive == 'query':
|
|
289
300
|
response = yes_or_no('Rerun the failed jobs?')
|
|
290
301
|
if response:
|
|
291
|
-
|
|
302
|
+
if cluster_spec == 'torque':
|
|
303
|
+
rerun_nm(processing_dir, log_path=log_path, memory=memory,
|
|
292
304
|
duration=duration, binary=binary,
|
|
293
305
|
interactive=interactive)
|
|
306
|
+
elif cluster_spec == 'slurm':
|
|
307
|
+
sbatchrerun_nm(processing_dir,
|
|
308
|
+
memory=memory,
|
|
309
|
+
duration=duration,
|
|
310
|
+
binary=binary,
|
|
311
|
+
log_path=log_path,
|
|
312
|
+
interactive=interactive)
|
|
313
|
+
|
|
294
314
|
else:
|
|
295
315
|
success = True
|
|
296
316
|
else:
|
|
297
317
|
print('Reruning the failed jobs ...')
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
318
|
+
if cluster_spec == 'torque':
|
|
319
|
+
rerun_nm(processing_dir, log_path=log_path, memory=memory,
|
|
320
|
+
duration=duration, binary=binary,
|
|
321
|
+
interactive=interactive)
|
|
322
|
+
elif cluster_spec == 'slurm':
|
|
323
|
+
sbatchrerun_nm(processing_dir,
|
|
324
|
+
memory=memory,
|
|
325
|
+
duration=duration,
|
|
326
|
+
binary=binary,
|
|
327
|
+
log_path=log_path,
|
|
328
|
+
interactive=interactive)
|
|
301
329
|
|
|
302
330
|
if interactive == 'query':
|
|
303
331
|
response = yes_or_no('Collect the results?')
|
|
@@ -476,19 +504,15 @@ def collect_nm(processing_dir,
|
|
|
476
504
|
batch_fail = []
|
|
477
505
|
|
|
478
506
|
if (func != 'fit' and func != 'extend' and func != 'merge' and func != 'tune'):
|
|
479
|
-
file_example = []
|
|
480
507
|
# TODO: Collect_nm only depends on yhat, thus does not work when no
|
|
481
508
|
# prediction is made (when test cov is not specified).
|
|
482
|
-
|
|
483
|
-
if file_example == []:
|
|
484
|
-
file_example = glob.glob(batch + 'yhat' + outputsuffix
|
|
509
|
+
files = glob.glob(processing_dir + 'batch_*/' + 'yhat' + outputsuffix
|
|
485
510
|
+ file_extentions)
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
if binary is False:
|
|
489
|
-
file_example = fileio.load(file_example[0])
|
|
511
|
+
if len(files)>0:
|
|
512
|
+
file_example = fileio.load(files[0])
|
|
490
513
|
else:
|
|
491
|
-
|
|
514
|
+
raise ValueError(f"Missing output files (yhats at: {processing_dir + 'batch_*/' + 'yhat' + outputsuffix + file_extentions}")
|
|
515
|
+
|
|
492
516
|
numsubjects = file_example.shape[0]
|
|
493
517
|
try:
|
|
494
518
|
# doesn't exist if size=1, and txt file
|
|
@@ -931,7 +955,7 @@ def bashwrap_nm(processing_dir,
|
|
|
931
955
|
job_call = [python_path + ' ' + normative_path + ' -c ' +
|
|
932
956
|
covfile_path + ' -f ' + func]
|
|
933
957
|
else:
|
|
934
|
-
raise ValueError("""For 'estimate' function either
|
|
958
|
+
raise ValueError("""For 'estimate' function either testrespfile_path or cvfold
|
|
935
959
|
must be specified.""")
|
|
936
960
|
|
|
937
961
|
# add algorithm-specific parameters
|
|
@@ -1001,6 +1025,7 @@ def rerun_nm(processing_dir,
|
|
|
1001
1025
|
log_path,
|
|
1002
1026
|
memory,
|
|
1003
1027
|
duration,
|
|
1028
|
+
cluster_spec,
|
|
1004
1029
|
binary=False,
|
|
1005
1030
|
interactive=False):
|
|
1006
1031
|
'''This function reruns all failed batched in processing_dir after collect_nm has identified the failed batches.
|
|
@@ -1045,7 +1070,7 @@ def rerun_nm(processing_dir,
|
|
|
1045
1070
|
job_ids.append(job_id)
|
|
1046
1071
|
|
|
1047
1072
|
if interactive:
|
|
1048
|
-
check_jobs(job_ids, delay=60)
|
|
1073
|
+
check_jobs(job_ids, cluster_spec, delay=60)
|
|
1049
1074
|
|
|
1050
1075
|
|
|
1051
1076
|
# COPY the rotines above here and aadapt those to your cluster
|
|
@@ -1059,6 +1084,7 @@ def sbatchwrap_nm(processing_dir,
|
|
|
1059
1084
|
respfile_path,
|
|
1060
1085
|
memory,
|
|
1061
1086
|
duration,
|
|
1087
|
+
log_path,
|
|
1062
1088
|
func='estimate',
|
|
1063
1089
|
**kwargs):
|
|
1064
1090
|
'''This function wraps normative modelling into a bash script to run it
|
|
@@ -1098,13 +1124,14 @@ def sbatchwrap_nm(processing_dir,
|
|
|
1098
1124
|
|
|
1099
1125
|
sbatch_init = '#!/bin/bash\n'
|
|
1100
1126
|
sbatch_jobname = '#SBATCH --job-name=' + processing_dir + '\n'
|
|
1101
|
-
sbatch_account = '#SBATCH --account=p33_norment\n'
|
|
1102
1127
|
sbatch_nodes = '#SBATCH --nodes=1\n'
|
|
1103
1128
|
sbatch_tasks = '#SBATCH --ntasks=1\n'
|
|
1104
1129
|
sbatch_time = '#SBATCH --time=' + str(duration) + '\n'
|
|
1105
1130
|
sbatch_memory = '#SBATCH --mem-per-cpu=' + str(memory) + '\n'
|
|
1106
|
-
|
|
1107
|
-
|
|
1131
|
+
sbatch_log_out = '#SBATCH -o ' + log_path + '%j.out' + '\n'
|
|
1132
|
+
sbatch_log_error = '#SBATCH -e ' + log_path + '%j.err' + '\n'
|
|
1133
|
+
#sbatch_module = 'module purge\n'
|
|
1134
|
+
#sbatch_anaconda = 'module load anaconda3\n'
|
|
1108
1135
|
sbatch_exit = 'set -o errexit\n'
|
|
1109
1136
|
|
|
1110
1137
|
# echo -n "This script is running on "
|
|
@@ -1112,12 +1139,13 @@ def sbatchwrap_nm(processing_dir,
|
|
|
1112
1139
|
|
|
1113
1140
|
bash_environment = [sbatch_init +
|
|
1114
1141
|
sbatch_jobname +
|
|
1115
|
-
sbatch_account +
|
|
1116
1142
|
sbatch_nodes +
|
|
1117
1143
|
sbatch_tasks +
|
|
1118
1144
|
sbatch_time +
|
|
1119
|
-
|
|
1120
|
-
|
|
1145
|
+
sbatch_memory+
|
|
1146
|
+
sbatch_log_out+
|
|
1147
|
+
sbatch_log_error
|
|
1148
|
+
]
|
|
1121
1149
|
|
|
1122
1150
|
# creates call of function for normative modelling
|
|
1123
1151
|
if (testrespfile_path is not None) and (testcovfile_path is not None):
|
|
@@ -1134,7 +1162,7 @@ def sbatchwrap_nm(processing_dir,
|
|
|
1134
1162
|
job_call = [python_path + ' ' + normative_path + ' -c ' +
|
|
1135
1163
|
covfile_path + ' -f ' + func]
|
|
1136
1164
|
else:
|
|
1137
|
-
raise ValueError("""For 'estimate' function either
|
|
1165
|
+
raise ValueError("""For 'estimate' function either testrespfile_path or cv_folds
|
|
1138
1166
|
must be specified.""")
|
|
1139
1167
|
|
|
1140
1168
|
# add algorithm-specific parameters
|
|
@@ -1163,19 +1191,17 @@ def sbatchwrap_nm(processing_dir,
|
|
|
1163
1191
|
os.chmod(processing_dir + job_name, 0o770)
|
|
1164
1192
|
|
|
1165
1193
|
|
|
1166
|
-
def sbatch_nm(job_path
|
|
1167
|
-
log_path):
|
|
1194
|
+
def sbatch_nm(job_path):
|
|
1168
1195
|
'''This function submits a job.sh scipt to the torque custer using the qsub
|
|
1169
1196
|
command.
|
|
1170
1197
|
|
|
1171
1198
|
Basic usage::
|
|
1172
1199
|
|
|
1173
|
-
sbatch_nm(job_path
|
|
1200
|
+
sbatch_nm(job_path)
|
|
1174
1201
|
|
|
1175
1202
|
:param job_path: Full path to the job.sh file
|
|
1176
|
-
:param log_path: The logs are currently stored in the working dir
|
|
1177
1203
|
|
|
1178
|
-
:outputs: Submission of the job to the
|
|
1204
|
+
:outputs: Submission of the job to the slurm cluster.
|
|
1179
1205
|
|
|
1180
1206
|
written by (primarily) T Wolfers, (adapted) S Rutherford.
|
|
1181
1207
|
'''
|
|
@@ -1184,7 +1210,10 @@ def sbatch_nm(job_path,
|
|
|
1184
1210
|
sbatch_call = ['sbatch ' + job_path]
|
|
1185
1211
|
|
|
1186
1212
|
# submits job to cluster
|
|
1187
|
-
|
|
1213
|
+
job_id = check_output(sbatch_call, shell=True).decode(
|
|
1214
|
+
sys.stdout.encoding).replace("\n", "")
|
|
1215
|
+
|
|
1216
|
+
return job_id
|
|
1188
1217
|
|
|
1189
1218
|
|
|
1190
1219
|
def sbatchrerun_nm(processing_dir,
|
|
@@ -1193,6 +1222,7 @@ def sbatchrerun_nm(processing_dir,
|
|
|
1193
1222
|
new_memory=False,
|
|
1194
1223
|
new_duration=False,
|
|
1195
1224
|
binary=False,
|
|
1225
|
+
interactive=False,
|
|
1196
1226
|
**kwargs):
|
|
1197
1227
|
'''This function reruns all failed batched in processing_dir after collect_nm has identified he failed batches.
|
|
1198
1228
|
|
|
@@ -1210,7 +1240,12 @@ def sbatchrerun_nm(processing_dir,
|
|
|
1210
1240
|
|
|
1211
1241
|
written by (primarily) T Wolfers, (adapted) S Rutherford.
|
|
1212
1242
|
'''
|
|
1213
|
-
|
|
1243
|
+
|
|
1244
|
+
#log_path = kwargs.pop('log_path', None)
|
|
1245
|
+
|
|
1246
|
+
job_ids = []
|
|
1247
|
+
|
|
1248
|
+
start_time = datetime.now().strftime("%Y-%m-%dT%H:%M:%S")
|
|
1214
1249
|
|
|
1215
1250
|
if binary:
|
|
1216
1251
|
file_extentions = '.pkl'
|
|
@@ -1224,11 +1259,12 @@ def sbatchrerun_nm(processing_dir,
|
|
|
1224
1259
|
with fileinput.FileInput(jobpath, inplace=True) as file:
|
|
1225
1260
|
for line in file:
|
|
1226
1261
|
print(line.replace(duration, new_duration), end='')
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1262
|
+
if new_memory != False:
|
|
1263
|
+
with fileinput.FileInput(jobpath, inplace=True) as file:
|
|
1264
|
+
for line in file:
|
|
1265
|
+
print(line.replace(memory, new_memory), end='')
|
|
1266
|
+
job_id = sbatch_nm(jobpath)
|
|
1267
|
+
job_ids.append(job_id)
|
|
1232
1268
|
|
|
1233
1269
|
else:
|
|
1234
1270
|
file_extentions = '.txt'
|
|
@@ -1242,73 +1278,114 @@ def sbatchrerun_nm(processing_dir,
|
|
|
1242
1278
|
with fileinput.FileInput(jobpath, inplace=True) as file:
|
|
1243
1279
|
for line in file:
|
|
1244
1280
|
print(line.replace(duration, new_duration), end='')
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1281
|
+
if new_memory != False:
|
|
1282
|
+
with fileinput.FileInput(jobpath, inplace=True) as file:
|
|
1283
|
+
for line in file:
|
|
1284
|
+
print(line.replace(memory, new_memory), end='')
|
|
1285
|
+
job_id = sbatch_nm(jobpath)
|
|
1286
|
+
job_ids.append(job_id)
|
|
1287
|
+
|
|
1288
|
+
if interactive:
|
|
1289
|
+
check_jobs(job_ids, cluster_spec='slurm', start_time=start_time, delay=60)
|
|
1251
1290
|
|
|
1252
1291
|
|
|
1253
|
-
def retrieve_jobs():
|
|
1292
|
+
def retrieve_jobs(cluster_spec, start_time=None):
|
|
1254
1293
|
"""
|
|
1255
1294
|
A utility function to retrieve task status from the outputs of qstat.
|
|
1295
|
+
|
|
1296
|
+
:param cluster_spec: type of cluster, either 'torque' or 'slurm'.
|
|
1256
1297
|
|
|
1257
1298
|
:return: a dictionary of jobs.
|
|
1258
1299
|
|
|
1259
1300
|
"""
|
|
1260
1301
|
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1302
|
+
if cluster_spec == 'torque':
|
|
1303
|
+
|
|
1304
|
+
output = check_output('qstat', shell=True).decode(sys.stdout.encoding)
|
|
1305
|
+
output = output.split('\n')
|
|
1306
|
+
jobs = dict()
|
|
1307
|
+
for line in output[2:-1]:
|
|
1308
|
+
(Job_ID, Job_Name, User, Wall_Time, Status, Queue) = line.split()
|
|
1309
|
+
jobs[Job_ID] = dict()
|
|
1310
|
+
jobs[Job_ID]['name'] = Job_Name
|
|
1311
|
+
jobs[Job_ID]['walltime'] = Wall_Time
|
|
1312
|
+
jobs[Job_ID]['status'] = Status
|
|
1313
|
+
|
|
1314
|
+
elif cluster_spec == 'slurm':
|
|
1315
|
+
|
|
1316
|
+
end_time = datetime.now().strftime("%Y-%m-%dT%H:%M:%S")
|
|
1317
|
+
cmd = ['sacct', '-n', '-X', '--parsable2', '--noheader',
|
|
1318
|
+
'-S', start_time, '-E', end_time, '--format=JobName,State']
|
|
1319
|
+
jobs = run(cmd, capture_output=True, text=True)
|
|
1270
1320
|
|
|
1271
1321
|
return jobs
|
|
1272
1322
|
|
|
1273
1323
|
|
|
1274
|
-
def check_job_status(jobs):
|
|
1324
|
+
def check_job_status(jobs, cluster_spec, start_time=None):
|
|
1275
1325
|
"""
|
|
1276
1326
|
A utility function to count the tasks with different status.
|
|
1277
1327
|
|
|
1278
1328
|
:param jobs: List of job ids.
|
|
1279
|
-
:
|
|
1329
|
+
:param cluster_spec: type of cluster, either 'torque' or 'slurm'.
|
|
1330
|
+
:return returns the number of taks athat are queued, running, completed etc
|
|
1280
1331
|
|
|
1281
1332
|
"""
|
|
1282
|
-
running_jobs = retrieve_jobs()
|
|
1333
|
+
running_jobs = retrieve_jobs(cluster_spec, start_time)
|
|
1283
1334
|
|
|
1284
1335
|
r = 0
|
|
1285
1336
|
c = 0
|
|
1286
1337
|
q = 0
|
|
1287
1338
|
u = 0
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1339
|
+
|
|
1340
|
+
if cluster_spec == 'torque':
|
|
1341
|
+
|
|
1342
|
+
for job in jobs:
|
|
1343
|
+
try:
|
|
1344
|
+
if running_jobs[job]['status'] == 'C':
|
|
1345
|
+
c += 1
|
|
1346
|
+
elif running_jobs[job]['status'] == 'Q':
|
|
1347
|
+
q += 1
|
|
1348
|
+
elif running_jobs[job]['status'] == 'R':
|
|
1349
|
+
r += 1
|
|
1350
|
+
else:
|
|
1351
|
+
u += 1
|
|
1352
|
+
except: # probably meanwhile the job is finished.
|
|
1291
1353
|
c += 1
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
r += 1
|
|
1296
|
-
else:
|
|
1297
|
-
u += 1
|
|
1298
|
-
except: # probably meanwhile the job is finished.
|
|
1299
|
-
c += 1
|
|
1300
|
-
continue
|
|
1301
|
-
|
|
1302
|
-
print('Total Jobs:%d, Queued:%d, Running:%d, Completed:%d, Unknown:%d'
|
|
1354
|
+
continue
|
|
1355
|
+
|
|
1356
|
+
print('Total Jobs:%d, Queued:%d, Running:%d, Completed:%d, Unknown:%d'
|
|
1303
1357
|
% (len(jobs), q, r, c, u))
|
|
1358
|
+
|
|
1359
|
+
elif cluster_spec == 'slurm':
|
|
1360
|
+
|
|
1361
|
+
lines = running_jobs.stdout.strip().split('\n')
|
|
1362
|
+
|
|
1363
|
+
for line in lines:
|
|
1364
|
+
if line:
|
|
1365
|
+
parts = line.split('|')
|
|
1366
|
+
if len(parts) >= 2:
|
|
1367
|
+
job_name, state = parts[0], parts[1]
|
|
1368
|
+
if state == 'PENDING':
|
|
1369
|
+
q += 1
|
|
1370
|
+
elif state == 'RUNNING':
|
|
1371
|
+
r += 1
|
|
1372
|
+
elif state == 'COMPLETED':
|
|
1373
|
+
c += 1
|
|
1374
|
+
elif state == 'FAILED':
|
|
1375
|
+
u += 1
|
|
1376
|
+
|
|
1377
|
+
print('Total Jobs:%d, Pending:%d, Running:%d, Completed:%d, Failed:%d'
|
|
1378
|
+
% (len(jobs), q, r, c, u))
|
|
1379
|
+
|
|
1304
1380
|
return q, r, c, u
|
|
1305
1381
|
|
|
1306
1382
|
|
|
1307
|
-
def check_jobs(jobs, delay=60):
|
|
1383
|
+
def check_jobs(jobs, cluster_spec, start_time=None, delay=60):
|
|
1308
1384
|
"""
|
|
1309
1385
|
A utility function for chacking the status of submitted jobs.
|
|
1310
1386
|
|
|
1311
1387
|
:param jobs: list of job ids.
|
|
1388
|
+
:param cluster_spec: type of cluster, either 'torque' or 'slurm'.
|
|
1312
1389
|
:param delay: the delay (in sec) between two consequative checks, defaults to 60.
|
|
1313
1390
|
|
|
1314
1391
|
"""
|
|
@@ -1316,7 +1393,7 @@ def check_jobs(jobs, delay=60):
|
|
|
1316
1393
|
n = len(jobs)
|
|
1317
1394
|
|
|
1318
1395
|
while (True):
|
|
1319
|
-
q, r, c, u = check_job_status(jobs)
|
|
1396
|
+
q, r, c, u = check_job_status(jobs, cluster_spec, start_time)
|
|
1320
1397
|
if c == n:
|
|
1321
1398
|
print('All jobs are completed!')
|
|
1322
1399
|
break
|
|
@@ -1,13 +1,9 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: pcntoolkit
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.30
|
|
4
4
|
Summary: Predictive Clinical Neuroscience toolkit
|
|
5
5
|
Home-page: http://github.com/amarquand/PCNtoolkit
|
|
6
6
|
Author: Andre Marquand
|
|
7
7
|
Author-email: andre.marquand@donders.ru.nl
|
|
8
8
|
License: GNU GPLv3
|
|
9
|
-
Platform: UNKNOWN
|
|
10
9
|
License-File: LICENSE
|
|
11
|
-
|
|
12
|
-
UNKNOWN
|
|
13
|
-
|
|
@@ -9,8 +9,12 @@ def parse_requirements(filename):
|
|
|
9
9
|
|
|
10
10
|
requirements = parse_requirements('requirements.txt')
|
|
11
11
|
|
|
12
|
+
# Note: to force PyPI to overwrite a version without bumping the version number
|
|
13
|
+
# use e.g.:
|
|
14
|
+
# version = '0.29-1'
|
|
15
|
+
|
|
12
16
|
setup(name='pcntoolkit',
|
|
13
|
-
version='0.
|
|
17
|
+
version='0.30',
|
|
14
18
|
description='Predictive Clinical Neuroscience toolkit',
|
|
15
19
|
url='http://github.com/amarquand/PCNtoolkit',
|
|
16
20
|
author='Andre Marquand',
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""
|
|
3
|
+
Created on Wed Jan 18 14:34:06 2017
|
|
4
|
+
|
|
5
|
+
@author: andmar
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import os
|
|
9
|
+
import numpy as np
|
|
10
|
+
import pandas as pd
|
|
11
|
+
from pcntoolkit.normative_parallel import execute_nm
|
|
12
|
+
|
|
13
|
+
# configs
|
|
14
|
+
# specify your python path. Make sure you are using the Python in the right environement.
|
|
15
|
+
python_path = '/path/to/my/python'
|
|
16
|
+
|
|
17
|
+
# specify the working directory to sacve the results.
|
|
18
|
+
processing_dir = '/path/to/my/test/directory/'
|
|
19
|
+
sample_num = 50
|
|
20
|
+
resp_num = 10
|
|
21
|
+
cov_num = 1
|
|
22
|
+
|
|
23
|
+
# simulating data
|
|
24
|
+
pd.DataFrame(np.random.random([sample_num, resp_num])).to_pickle(os.path.join(processing_dir,'train_resp.pkl'))
|
|
25
|
+
pd.DataFrame(np.random.random([sample_num, cov_num])).to_pickle(os.path.join(processing_dir,'train_cov.pkl'))
|
|
26
|
+
pd.DataFrame(np.random.random([sample_num, resp_num])).to_pickle(os.path.join(processing_dir,'test_resp.pkl'))
|
|
27
|
+
pd.DataFrame(np.random.random([sample_num, cov_num])).to_pickle(os.path.join(processing_dir,'test_cov.pkl'))
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
respfile = os.path.join(processing_dir,'train_resp.pkl')
|
|
31
|
+
covfile = os.path.join(processing_dir,'train_cov.pkl')
|
|
32
|
+
|
|
33
|
+
testresp = os.path.join(processing_dir,'test_resp.pkl')
|
|
34
|
+
testcov = os.path.join(processing_dir,'test_cov.pkl')
|
|
35
|
+
|
|
36
|
+
job_name = 'nmp_test'
|
|
37
|
+
batch_size = 1
|
|
38
|
+
memory = '4gb'
|
|
39
|
+
duration = '01:00:00'
|
|
40
|
+
cluster = 'slurm'
|
|
41
|
+
binary='True'
|
|
42
|
+
|
|
43
|
+
execute_nm(processing_dir, python_path, job_name, covfile, respfile,
|
|
44
|
+
testcovfile_path=testcov, testrespfile_path=testresp, batch_size=batch_size,
|
|
45
|
+
memory=memory, duration=duration, cluster_spec=cluster,
|
|
46
|
+
log_path=processing_dir, interactive='auto', binary=binary,
|
|
47
|
+
savemodel='True', saveoutput='True')
|
|
48
|
+
|
|
49
|
+
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
# -*- coding: utf-8 -*-
|
|
2
|
-
"""
|
|
3
|
-
Created on Wed Jan 18 14:34:06 2017
|
|
4
|
-
|
|
5
|
-
@author: andmar
|
|
6
|
-
"""
|
|
7
|
-
# import pcntoolkit
|
|
8
|
-
import os
|
|
9
|
-
import time
|
|
10
|
-
from pcntoolkit.normative_parallel import execute_nm, collect_nm, delete_nm
|
|
11
|
-
|
|
12
|
-
data_dir = '/home/preclineu/andmar/py.sandbox/normative_oslo/'
|
|
13
|
-
respfile = os.path.join(data_dir, 'ICA100_oslo15_v2_spaces.txt')
|
|
14
|
-
covfile = os.path.join(data_dir, 'cov_oslo15_spaces.txt')
|
|
15
|
-
|
|
16
|
-
cvfolds = 2
|
|
17
|
-
|
|
18
|
-
python_path = '/home/preclineu/andmar/sfw/anaconda3/envs/py36/bin/python'
|
|
19
|
-
normative_path = '/home/preclineu/andmar/sfw/PCNtoolkit/pcntoolkit/normative.py'
|
|
20
|
-
processing_dir = '/home/preclineu/andmar/py.sandbox/demo/'
|
|
21
|
-
job_name = 'nmp_test'
|
|
22
|
-
batch_size = 10
|
|
23
|
-
memory = '4gb'
|
|
24
|
-
duration = '01:00:00'
|
|
25
|
-
cluster = 'torque'
|
|
26
|
-
|
|
27
|
-
execute_nm(processing_dir, python_path, normative_path, job_name, covfile, respfile,
|
|
28
|
-
batch_size, memory, duration, cluster_spec=cluster,
|
|
29
|
-
cv_folds=cvfolds, log_path=processing_dir) # , alg='rfa')#, configparam=4)
|
|
30
|
-
|
|
31
|
-
print("waiting for jobs to finish ...")
|
|
32
|
-
time.sleep(60)
|
|
33
|
-
|
|
34
|
-
collect_nm(processing_dir, job_name, collect=True)
|
|
35
|
-
# delete_nm(procedssing_dir)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|