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.
Files changed (52) hide show
  1. {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/LICENSE +0 -0
  2. {pcntoolkit-0.29.post1/pcntoolkit.egg-info → pcntoolkit-0.30}/PKG-INFO +1 -5
  3. {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/pcntoolkit/model/hbr.py +1 -1
  4. {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/pcntoolkit/normative.py +13 -3
  5. {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/pcntoolkit/normative_model/norm_hbr.py +14 -7
  6. {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/pcntoolkit/normative_parallel.py +158 -81
  7. {pcntoolkit-0.29.post1 → pcntoolkit-0.30/pcntoolkit.egg-info}/PKG-INFO +1 -5
  8. {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/pcntoolkit.egg-info/requires.txt +1 -1
  9. {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/requirements.txt +1 -1
  10. {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/setup.py +5 -1
  11. pcntoolkit-0.30/tests/test_normative_parallel.py +49 -0
  12. pcntoolkit-0.29.post1/tests/test_normative_parallel.py +0 -35
  13. {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/MANIFEST.in +0 -0
  14. {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/README.md +0 -0
  15. {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/pcntoolkit/__init__.py +0 -0
  16. {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/pcntoolkit/configs.py +0 -0
  17. {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/pcntoolkit/dataio/__init__.py +0 -0
  18. {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/pcntoolkit/dataio/fileio.py +0 -0
  19. {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/pcntoolkit/model/NP.py +0 -0
  20. {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/pcntoolkit/model/NPR.py +0 -0
  21. {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/pcntoolkit/model/SHASH.py +0 -0
  22. {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/pcntoolkit/model/__init__.py +0 -0
  23. {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/pcntoolkit/model/architecture.py +0 -0
  24. {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/pcntoolkit/model/bayesreg.py +0 -0
  25. {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/pcntoolkit/model/gp.py +0 -0
  26. {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/pcntoolkit/model/rfa.py +0 -0
  27. {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/pcntoolkit/normative_NP.py +0 -0
  28. {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/pcntoolkit/normative_model/__init__.py +0 -0
  29. {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/pcntoolkit/normative_model/norm_base.py +0 -0
  30. {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/pcntoolkit/normative_model/norm_blr.py +0 -0
  31. {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/pcntoolkit/normative_model/norm_gpr.py +0 -0
  32. {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/pcntoolkit/normative_model/norm_np.py +0 -0
  33. {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/pcntoolkit/normative_model/norm_rfa.py +0 -0
  34. {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/pcntoolkit/normative_model/norm_utils.py +0 -0
  35. {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/pcntoolkit/trendsurf.py +0 -0
  36. {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/pcntoolkit/util/__init__.py +0 -0
  37. {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/pcntoolkit/util/hbr_utils.py +0 -0
  38. {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/pcntoolkit/util/utils.py +0 -0
  39. {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/pcntoolkit.egg-info/SOURCES.txt +0 -0
  40. {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/pcntoolkit.egg-info/dependency_links.txt +0 -0
  41. {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/pcntoolkit.egg-info/not-zip-safe +0 -0
  42. {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/pcntoolkit.egg-info/top_level.txt +0 -0
  43. {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/setup.cfg +0 -0
  44. {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/tests/testHBR.py +0 -0
  45. {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/tests/testHBR_transfer.py +0 -0
  46. {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/tests/test_NP.py +0 -0
  47. {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/tests/test_ST_NP.py +0 -0
  48. {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/tests/test_blr.py +0 -0
  49. {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/tests/test_gpr.py +0 -0
  50. {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/tests/test_hbr_pymc.py +0 -0
  51. {pcntoolkit-0.29.post1 → pcntoolkit-0.30}/tests/test_normative.py +0 -0
  52. {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.29.post1
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
- self.hbr.predict(
550
- X=X,
551
- batch_effects=batch_effects,
552
- batch_effects_maps=self.batch_effects_maps,
553
- pred="single",
554
- var_names=var_names+["y_like"],
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 subprocess import call, check_output
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', 'estimate')
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 == 'sbatch':
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
- sbatch_nm(job_path=batch_job_path,
181
- log_path=log_path)
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 == 'sbatch':
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
- sbatch_nm(job_path=batch_job_path,
222
- log_path=log_path)
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 == 'sbatch':
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
- sbatch_nm(job_path=batch_job_path,
264
- log_path=log_path)
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
- rerun_nm(processing_dir, log_path=log_path, memory=memory,
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
- rerun_nm(processing_dir, log_path=log_path, memory=memory,
299
- duration=duration, binary=binary,
300
- interactive=interactive)
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
- for batch in batches:
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
- else:
487
- break
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
- file_example = pd.read_pickle(file_example[0])
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 testcov or cvfold
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
- sbatch_module = 'module purge\n'
1107
- sbatch_anaconda = 'module load anaconda3\n'
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
- sbatch_module +
1120
- sbatch_anaconda]
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 testcov or cvfold
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, log_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 (torque) cluster.
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
- call(sbatch_call, shell=True)
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
- log_path = kwargs.pop('log_path', None)
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
- if new_memory != False:
1228
- with fileinput.FileInput(jobpath, inplace=True) as file:
1229
- for line in file:
1230
- print(line.replace(memory, new_memory), end='')
1231
- sbatch_nm(jobpath, log_path)
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
- if new_memory != False:
1246
- with fileinput.FileInput(jobpath, inplace=True) as file:
1247
- for line in file:
1248
- print(line.replace(memory, new_memory), end='')
1249
- sbatch_nm(jobpath,
1250
- log_path)
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
- output = check_output('qstat', shell=True).decode(sys.stdout.encoding)
1262
- output = output.split('\n')
1263
- jobs = dict()
1264
- for line in output[2:-1]:
1265
- (Job_ID, Job_Name, User, Wall_Time, Status, Queue) = line.split()
1266
- jobs[Job_ID] = dict()
1267
- jobs[Job_ID]['name'] = Job_Name
1268
- jobs[Job_ID]['walltime'] = Wall_Time
1269
- jobs[Job_ID]['status'] = Status
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
- :return: returns the number of taks athat are queued, running, completed etc
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
- for job in jobs:
1289
- try:
1290
- if running_jobs[job]['status'] == 'C':
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
- elif running_jobs[job]['status'] == 'Q':
1293
- q += 1
1294
- elif running_jobs[job]['status'] == 'R':
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.29.post1
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
-
@@ -5,7 +5,7 @@ scikit-learn
5
5
  bspline
6
6
  matplotlib
7
7
  numpy
8
- scipy>=1.3.2
8
+ scipy<1.13.0,>=1.3.2
9
9
  pandas>=0.25.3
10
10
  torch>=1.1.0
11
11
  sphinx-tabs
@@ -5,7 +5,7 @@ scikit-learn
5
5
  bspline
6
6
  matplotlib
7
7
  numpy
8
- scipy>=1.3.2
8
+ scipy>=1.3.2,<1.13.0
9
9
  pandas>=0.25.3
10
10
  torch>=1.1.0
11
11
  sphinx-tabs
@@ -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.29-1',
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