brkraw 0.3.11__py3-none-any.whl → 0.5.0__py3-none-any.whl

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 (113) hide show
  1. brkraw/__init__.py +9 -3
  2. brkraw/apps/__init__.py +12 -0
  3. brkraw/apps/addon/__init__.py +30 -0
  4. brkraw/apps/addon/core.py +35 -0
  5. brkraw/apps/addon/dependencies.py +402 -0
  6. brkraw/apps/addon/installation.py +500 -0
  7. brkraw/apps/addon/io.py +21 -0
  8. brkraw/apps/hook/__init__.py +25 -0
  9. brkraw/apps/hook/core.py +636 -0
  10. brkraw/apps/loader/__init__.py +10 -0
  11. brkraw/apps/loader/core.py +622 -0
  12. brkraw/apps/loader/formatter.py +288 -0
  13. brkraw/apps/loader/helper.py +797 -0
  14. brkraw/apps/loader/info/__init__.py +11 -0
  15. brkraw/apps/loader/info/scan.py +85 -0
  16. brkraw/apps/loader/info/scan.yaml +90 -0
  17. brkraw/apps/loader/info/study.py +69 -0
  18. brkraw/apps/loader/info/study.yaml +156 -0
  19. brkraw/apps/loader/info/transform.py +92 -0
  20. brkraw/apps/loader/types.py +220 -0
  21. brkraw/cli/__init__.py +5 -0
  22. brkraw/cli/commands/__init__.py +2 -0
  23. brkraw/cli/commands/addon.py +327 -0
  24. brkraw/cli/commands/config.py +205 -0
  25. brkraw/cli/commands/convert.py +903 -0
  26. brkraw/cli/commands/hook.py +348 -0
  27. brkraw/cli/commands/info.py +74 -0
  28. brkraw/cli/commands/init.py +214 -0
  29. brkraw/cli/commands/params.py +106 -0
  30. brkraw/cli/commands/prune.py +288 -0
  31. brkraw/cli/commands/session.py +371 -0
  32. brkraw/cli/hook_args.py +80 -0
  33. brkraw/cli/main.py +83 -0
  34. brkraw/cli/utils.py +60 -0
  35. brkraw/core/__init__.py +13 -0
  36. brkraw/core/config.py +380 -0
  37. brkraw/core/entrypoints.py +25 -0
  38. brkraw/core/formatter.py +367 -0
  39. brkraw/core/fs.py +495 -0
  40. brkraw/core/jcamp.py +600 -0
  41. brkraw/core/layout.py +451 -0
  42. brkraw/core/parameters.py +781 -0
  43. brkraw/core/zip.py +1121 -0
  44. brkraw/dataclasses/__init__.py +14 -0
  45. brkraw/dataclasses/node.py +139 -0
  46. brkraw/dataclasses/reco.py +33 -0
  47. brkraw/dataclasses/scan.py +61 -0
  48. brkraw/dataclasses/study.py +131 -0
  49. brkraw/default/__init__.py +3 -0
  50. brkraw/default/pruner_specs/deid4share.yaml +42 -0
  51. brkraw/default/rules/00_default.yaml +4 -0
  52. brkraw/default/specs/metadata_dicom.yaml +236 -0
  53. brkraw/default/specs/metadata_transforms.py +92 -0
  54. brkraw/resolver/__init__.py +7 -0
  55. brkraw/resolver/affine.py +539 -0
  56. brkraw/resolver/datatype.py +69 -0
  57. brkraw/resolver/fid.py +90 -0
  58. brkraw/resolver/helpers.py +36 -0
  59. brkraw/resolver/image.py +188 -0
  60. brkraw/resolver/nifti.py +370 -0
  61. brkraw/resolver/shape.py +235 -0
  62. brkraw/schema/__init__.py +3 -0
  63. brkraw/schema/context_map.yaml +62 -0
  64. brkraw/schema/meta.yaml +57 -0
  65. brkraw/schema/niftiheader.yaml +95 -0
  66. brkraw/schema/pruner.yaml +55 -0
  67. brkraw/schema/remapper.yaml +128 -0
  68. brkraw/schema/rules.yaml +154 -0
  69. brkraw/specs/__init__.py +10 -0
  70. brkraw/specs/hook/__init__.py +12 -0
  71. brkraw/specs/hook/logic.py +31 -0
  72. brkraw/specs/hook/validator.py +22 -0
  73. brkraw/specs/meta/__init__.py +5 -0
  74. brkraw/specs/meta/validator.py +156 -0
  75. brkraw/specs/pruner/__init__.py +15 -0
  76. brkraw/specs/pruner/logic.py +361 -0
  77. brkraw/specs/pruner/validator.py +119 -0
  78. brkraw/specs/remapper/__init__.py +27 -0
  79. brkraw/specs/remapper/logic.py +924 -0
  80. brkraw/specs/remapper/validator.py +314 -0
  81. brkraw/specs/rules/__init__.py +6 -0
  82. brkraw/specs/rules/logic.py +263 -0
  83. brkraw/specs/rules/validator.py +103 -0
  84. brkraw-0.5.0.dist-info/METADATA +81 -0
  85. brkraw-0.5.0.dist-info/RECORD +88 -0
  86. {brkraw-0.3.11.dist-info → brkraw-0.5.0.dist-info}/WHEEL +1 -2
  87. brkraw-0.5.0.dist-info/entry_points.txt +13 -0
  88. brkraw/lib/__init__.py +0 -4
  89. brkraw/lib/backup.py +0 -641
  90. brkraw/lib/bids.py +0 -0
  91. brkraw/lib/errors.py +0 -125
  92. brkraw/lib/loader.py +0 -1220
  93. brkraw/lib/orient.py +0 -194
  94. brkraw/lib/parser.py +0 -48
  95. brkraw/lib/pvobj.py +0 -301
  96. brkraw/lib/reference.py +0 -245
  97. brkraw/lib/utils.py +0 -471
  98. brkraw/scripts/__init__.py +0 -0
  99. brkraw/scripts/brk_backup.py +0 -106
  100. brkraw/scripts/brkraw.py +0 -744
  101. brkraw/ui/__init__.py +0 -0
  102. brkraw/ui/config.py +0 -17
  103. brkraw/ui/main_win.py +0 -214
  104. brkraw/ui/previewer.py +0 -225
  105. brkraw/ui/scan_info.py +0 -72
  106. brkraw/ui/scan_list.py +0 -73
  107. brkraw/ui/subj_info.py +0 -128
  108. brkraw-0.3.11.dist-info/METADATA +0 -25
  109. brkraw-0.3.11.dist-info/RECORD +0 -28
  110. brkraw-0.3.11.dist-info/entry_points.txt +0 -3
  111. brkraw-0.3.11.dist-info/top_level.txt +0 -2
  112. tests/__init__.py +0 -0
  113. {brkraw-0.3.11.dist-info → brkraw-0.5.0.dist-info/licenses}/LICENSE +0 -0
brkraw/lib/orient.py DELETED
@@ -1,194 +0,0 @@
1
- import math
2
- from copy import copy as cp
3
-
4
- import numpy as np
5
- from nibabel.affines import from_matvec, to_matvec
6
-
7
- from .reference import ERROR_MESSAGES
8
-
9
-
10
- def build_affine_from_orient_info(resol, rmat, pose,
11
- subj_pose, subj_type, slice_orient):
12
- if slice_orient in ['axial', 'sagital']:
13
- resol = np.diag(np.array(resol))
14
- else:
15
- resol = np.diag(np.array(resol) * np.array([1, 1, -1]))
16
- rmat = rmat.T.dot(resol)
17
-
18
- affine = from_matvec(rmat, pose)
19
-
20
- # convert space from image to subject
21
- # below positions are all reflect human-based position
22
- if subj_pose:
23
- if subj_pose == 'Head_Supine':
24
- affine = apply_rotate(affine, rad_z=np.pi)
25
- elif subj_pose == 'Head_Prone':
26
- pass
27
- # From here, not urgent, extra work to determine correction matrix needed.
28
- elif subj_pose == 'Head_Left':
29
- affine = apply_rotate(affine, rad_z=np.pi/2)
30
- elif subj_pose == 'Head_Right':
31
- affine = apply_rotate(affine, rad_z=-np.pi/2)
32
- elif subj_pose in ['Foot_Supine', 'Tail_Supine']:
33
- affine = apply_rotate(affine, rad_x=np.pi)
34
- elif subj_pose in ['Foot_Prone', 'Tail_Prone']:
35
- affine = apply_rotate(affine, rad_y=np.pi)
36
- elif subj_pose in ['Foot_Left', 'Tail_Left']:
37
- affine = apply_rotate(affine, rad_z=np.pi/2)
38
- elif subj_pose in ['Foot_Right', 'Tail_Right']:
39
- affine = apply_rotate(affine, rad_z=-np.pi/2)
40
- else: # in case Bruker put additional value for this header
41
- raise Exception(ERROR_MESSAGES['NotIntegrated'])
42
-
43
- if subj_type != 'Biped':
44
- # correct subject space if not biped (human or non-human primates)
45
- # not sure this rotation is independent with subject pose, so put here instead last
46
- affine = apply_rotate(affine, rad_x=-np.pi/2, rad_y=np.pi)
47
- return affine
48
-
49
-
50
- def reversed_pose_correction(pose, rmat, distance):
51
- reversed_pose = rmat.dot(pose)
52
- reversed_pose[-1] += distance
53
- corrected_pose = rmat.T.dot(reversed_pose)
54
- return corrected_pose
55
-
56
-
57
- def is_rotation_matrix(matrix):
58
- t_matrix = np.transpose(matrix)
59
- should_be_identity = np.dot(t_matrix, matrix)
60
- i = np.identity(3, dtype=matrix.dtype)
61
- n = np.linalg.norm(i - should_be_identity)
62
- return n < 1e-6
63
-
64
-
65
- def apply_flip(matrix, axis, mat=True, vec=True):
66
- '''axis = x or y or z'''
67
- flip_idx = dict(x=0, y=1, z=2)
68
- orig_mat, orig_vec = to_matvec(matrix)
69
-
70
- aff_mat = np.ones(3)
71
- aff_mat[flip_idx[axis]] = -1
72
- aff_mat = np.diag(aff_mat)
73
- if mat:
74
- flip_mat = aff_mat.dot(orig_mat)
75
- else:
76
- flip_mat = orig_mat
77
- if vec:
78
- flip_vec = aff_mat.dot(orig_vec)
79
- else:
80
- flip_vec = orig_vec
81
- return from_matvec(flip_mat, flip_vec)
82
-
83
-
84
- def calc_eulerangle(matrix):
85
- assert (is_rotation_matrix(matrix))
86
-
87
- sy = math.sqrt(matrix[0, 0] * matrix[0, 0] + matrix[1, 0] * matrix[1, 0])
88
- singular = sy < 1e-6
89
- if not singular:
90
- x = math.atan2(matrix[2, 1], matrix[2, 2])
91
- y = math.atan2(-matrix[2, 0], sy)
92
- z = math.atan2(matrix[1, 0], matrix[0, 0])
93
- else:
94
- x = math.atan2(-matrix[1, 2], matrix[1, 1])
95
- y = math.atan2(-matrix[2, 0], sy)
96
- z = 0
97
- return np.array([math.degrees(x),
98
- math.degrees(y),
99
- math.degrees(z)])
100
-
101
-
102
- def apply_rotate(matrix, rad_x=0, rad_y=0, rad_z=0):
103
- ''' axis = x or y or z '''
104
- rmat = dict(x = np.array([[1, 0, 0],
105
- [0, np.cos(rad_x), -np.sin(rad_x)],
106
- [0, np.sin(rad_x), np.cos(rad_x)]]).astype('float'),
107
- y = np.array([[np.cos(rad_y), 0, np.sin(rad_y)],
108
- [0, 1, 0],
109
- [-np.sin(rad_y), 0, np.cos(rad_y)]]).astype('float'),
110
- z = np.array([[np.cos(rad_z), -np.sin(rad_z), 0],
111
- [np.sin(rad_z), np.cos(rad_z), 0],
112
- [0, 0, 1]]).astype('float'))
113
- af_mat, af_vec = to_matvec(matrix)
114
- rotated_mat = rmat['z'].dot(rmat['y'].dot(rmat['x'].dot(af_mat)))
115
- rotated_vec = rmat['z'].dot(rmat['y'].dot(rmat['x'].dot(af_vec)))
116
- return from_matvec(rotated_mat, rotated_vec)
117
-
118
-
119
- def apply_affine(matrix, affine):
120
- return affine.dot(matrix)
121
-
122
-
123
- def swap_orient_matrix(orient_matrix, axis_orient):
124
-
125
- orient_matrix = cp(orient_matrix)
126
-
127
- axis_for_swap = []
128
- for origin, destination in enumerate(axis_orient):
129
- if origin != destination:
130
- axis_for_swap.append(destination)
131
- orient_matrix.T[axis_for_swap] = orient_matrix.T[axis_for_swap[::-1]]
132
- return orient_matrix
133
-
134
-
135
- def get_origin(slice_position, gradient_orient):
136
- """ TODO: the case was not fully tested, if any coordinate mismatch happened, this function will be the issue.
137
- Args:
138
- slice_position: visu_pars.parameters['VisuCorePosition']
139
- gradient_orient: method.parameters['PVM_SPackArrGradOrient']
140
-
141
- Returns:
142
- x, y, z coordinate for origin of image matrix
143
- """
144
- slice_position = cp(slice_position)
145
- dx, dy, dz = map(lambda x: x.max() - x.min(), slice_position.T)
146
- max_delta_axis = np.argmax([dx, dy, dz])
147
- rx, ry, rz = [None, None, None]
148
-
149
- if isinstance(gradient_orient, np.ndarray):
150
- zmat = np.zeros(gradient_orient[0].shape)
151
- for cid, col in enumerate(gradient_orient[0].T):
152
- yid = np.argmax(abs(col))
153
- zmat[cid, yid] = np.round(col[yid], decimals=0)
154
- rx, ry, rz = calc_eulerangle(np.round(zmat.T))
155
-
156
- if max_delta_axis == 0: # sagital
157
- if rx != None: # PV 5 filter, only PV6 has gradient_orient info
158
- if rz == 90: # typical case
159
- idx = slice_position.T[max_delta_axis].argmin()
160
- else:
161
- idx = slice_position.T[max_delta_axis].argmax()
162
- else:
163
- idx = slice_position.T[max_delta_axis].argmax()
164
- elif max_delta_axis == 1: # coronal
165
- if rx != None:
166
- if rx == -90: # FOV flipped
167
- if ry == -90: # Cyceron cases # 5 and 9
168
- idx = slice_position.T[max_delta_axis].argmax()
169
- else:
170
- idx = slice_position.T[max_delta_axis].argmin()
171
- else: # rx == -90 are the typical case
172
- idx = slice_position.T[max_delta_axis].argmax()
173
- else:
174
- idx = slice_position.T[max_delta_axis].argmaxs()
175
- elif max_delta_axis == 2: # axial
176
- if rx != None:
177
- if (abs(ry) == 180) or ((abs(rx) == 180) and (abs(rz) == 180)):
178
- # typical case
179
- idx = slice_position.T[max_delta_axis].argmax()
180
- else:
181
- idx = slice_position.T[max_delta_axis].argmin()
182
- else:
183
- idx = slice_position.T[max_delta_axis].argmin()
184
- else:
185
- raise Exception
186
- origin = slice_position[idx]
187
- return origin
188
-
189
-
190
- def reverse_swap(swap_code):
191
- reversed_code = [0, 0, 0]
192
- for target, origin in enumerate(swap_code):
193
- reversed_code[origin] = target
194
- return reversed_code
brkraw/lib/parser.py DELETED
@@ -1,48 +0,0 @@
1
- from .utils import *
2
-
3
-
4
- class Parameter:
5
- def __init__(self, stringlist):
6
- # parse the parameter dictionaries from stringlist
7
- self._set_param(*load_param(stringlist))
8
-
9
- @property
10
- def parameters(self):
11
- return self._parameters
12
-
13
- @property
14
- def headers(self):
15
- return self._headers
16
-
17
- def _set_param(self, params, param_addr, contents):
18
- # get distance between each parameter
19
- addr_diff = np.diff(param_addr)
20
-
21
- # for debugging
22
- self._contents = contents
23
- # build dictionary for parameters
24
- self._headers = OrderedDict()
25
- self._parameters = OrderedDict()
26
- for index, addr in enumerate(param_addr[:-1]):
27
- dtype, key, value = params[addr]
28
- shape = -1
29
- # if there are spaces before next parameter apears
30
- if addr_diff[index] > 1:
31
- # collect all text within spaces
32
- c_lines = contents[(addr + 1):(addr + addr_diff[index])]
33
- # merge lines into single text as data
34
- data = " ".join([line.strip() for line in c_lines if not re.match(ptrn_comment, line)])
35
- # no contents in data
36
- if not data:
37
- data = convert_string_to(value)
38
- else:
39
- shape = value
40
- else:
41
- data = convert_string_to(value)
42
-
43
- if dtype is PARAMETER:
44
- self._parameters[key] = convert_data_to(data, shape)
45
- elif dtype is HEADER:
46
- self._headers[key] = data
47
- else:
48
- raise Exception
brkraw/lib/pvobj.py DELETED
@@ -1,301 +0,0 @@
1
- import os
2
- import zipfile as zf
3
- import functools
4
- from collections import namedtuple
5
- from .parser import Parameter
6
- from .utils import get_value
7
-
8
- _2dseq = namedtuple('img_2dseq', ['reco_id', 'idx'])
9
- _visu_pars = namedtuple('visu_pars', ['reco_id', 'idx'])
10
- _reco = namedtuple('reco', ['reco_id', 'idx'])
11
-
12
-
13
- class PvDatasetBase:
14
- path = None
15
- _subject = None
16
- _fid = None
17
- _traj = None
18
- _method = None
19
- _acqp = None
20
- _avail_scanid = None
21
- _avail_recoid = None
22
-
23
- def __init__(self, path):
24
- self._reset()
25
-
26
- def _reset(self):
27
- self._fid = dict()
28
- self._traj = dict()
29
- self._method = dict()
30
- self._acqp = dict()
31
- self._visu_pars = dict()
32
- self._reco = dict()
33
- self._2dseq = dict()
34
-
35
- def _update_studyinfo(self):
36
- if self._subject != None:
37
- subject = self._subject
38
- self.user_account = subject.headers['OWNER']
39
- self.subj_id = get_value(subject, 'SUBJECT_id')
40
- self.study_id = get_value(subject, 'SUBJECT_study_nr')
41
- self.session_id = get_value(subject, 'SUBJECT_study_name')
42
-
43
- # [20210820] Add-paravision 360 related.
44
- title = subject.headers['TITLE']
45
- if "360" in title:
46
- self.subj_entry = get_value(subject, 'SUBJECT_study_instrument_position').split('_')[0]
47
- self.subj_pose = get_value(subject, 'SUBJECT_study_instrument_position').split('_')[1]
48
- else:
49
- self.subj_entry = get_value(subject, 'SUBJECT_entry').split('_')[-1]
50
- self.subj_pose = get_value(subject, 'SUBJECT_position').split('_')[-1]
51
-
52
- #self.subj_entry = get_value(subject, 'SUBJECT_entry').split('_')[-1]
53
- #self.subj_pose = get_value(subject, 'SUBJECT_position').split('_')[-1]
54
-
55
- self.subj_sex = get_value(subject, 'SUBJECT_sex')
56
- self.subj_type = get_value(subject, 'SUBJECT_type')
57
- self.subj_weight = get_value(subject, 'SUBJECT_weight')
58
- self.subj_dob = get_value(subject, 'SUBJECT_dbirth')
59
- self.user_name = get_value(subject, 'SUBJECT_name_string')
60
- else:
61
- self.user_account = None
62
- self.subj_id = None
63
- self.study_id = None
64
- self.session_id = None
65
- self.subj_entry = None
66
- self.subj_pose = None
67
- self.subj_sex = None
68
- self.subj_type = None
69
- self.subj_weight = None
70
- self.subj_dob = None
71
- self.user_name = None
72
-
73
- def _parse_info(self):
74
- pass
75
-
76
- @property
77
- def avail_scan_id(self):
78
- self._avail_scanid = sorted(self._visu_pars.keys())
79
- return self._avail_scanid
80
-
81
- @property
82
- def avail_reco_id(self):
83
- self._avail_recoid = {}
84
- for scan_id in self.avail_scan_id:
85
- try:
86
- self._avail_recoid[scan_id] = sorted(list(map(lambda x: x.reco_id, self._visu_pars[scan_id])))
87
- except:
88
- self.avail_scan_id.remove(scan_id)
89
- return self._avail_recoid
90
-
91
- def _open_binary(self, path):
92
- pass
93
-
94
- def _open_string(self, path):
95
- pass
96
-
97
- def get_dataobj(self, scan_id, reco_id):
98
- import numpy as np
99
- from .reference import BYTEORDER, WORDTYPE
100
- from .utils import get_value, is_all_element_same
101
-
102
- # parse datatype
103
- visu_pars = self.get_visu_pars(scan_id, reco_id)
104
- dtype_code = np.dtype('{}{}'.format(BYTEORDER[get_value(visu_pars, 'VisuCoreByteOrder')],
105
- WORDTYPE[get_value(visu_pars, 'VisuCoreWordType')]))
106
- # load dataobject
107
- _2dseq = np.frombuffer(self.get_2dseq(scan_id, reco_id), dtype_code)
108
-
109
- # Below code had integrated into header instead changing the value
110
- # correction data slope and offset
111
- # data_slp = get_value(visu_pars, 'VisuCoreDataSlope')
112
- # if isinstance(data_slp, list):
113
- # data_slp = data_slp[0] if is_all_element_same(data_slp) else data_slp
114
- # data_off = get_value(visu_pars, 'VisuCoreDataOffs')
115
- # if isinstance(data_off, list):
116
- # data_off = data_off[0] if is_all_element_same(data_off) else data_off
117
- # try:
118
- # recovered_2dseq = _2dseq * data_slp + data_off
119
- # except:
120
- # raise Exception('size mismatch between data with slope or offset parameter.')
121
- # return recovered_2dseq
122
- return _2dseq
123
-
124
- def get_fid(self, scan_id):
125
- return self._open_binary(self._fid[scan_id])
126
-
127
- def get_traj(self, scan_id):
128
- return self._open_binary(self._traj[scan_id])
129
-
130
- def get_2dseq(self, scan_id, reco_id):
131
- # return 2dseq binary string
132
- for tpl in filter(functools.partial(lambda x, y: True if x.reco_id == y else False,
133
- y=reco_id), self._2dseq[scan_id]):
134
- return self._open_binary(tpl.idx)
135
-
136
- def get_visu_pars(self, scan_id, reco_id):
137
- for tpl in filter(functools.partial(lambda x, y: True if x.reco_id == y else False,
138
- y=reco_id), self._visu_pars[scan_id]):
139
- return Parameter(self._open_string(tpl.idx))
140
-
141
- def get_reco(self, scan_id, reco_id):
142
- for tpl in filter(functools.partial(lambda x, y: True if x.reco_id == y else False,
143
- y=reco_id), self._reco[scan_id]):
144
- return Parameter(self._open_string(tpl.idx))
145
-
146
- def __repr__(self):
147
- return 'PvDataset( storageLocation: "{}" )'.format(self.path)
148
-
149
- def __del__(self):
150
- self.close()
151
-
152
- def close(self):
153
- pass
154
-
155
-
156
- class PvDatasetDir(PvDatasetBase):
157
- def __init__(self, path):
158
- super(PvDatasetDir, self).__init__(path)
159
- self.__path = path
160
- self.path = os.path.basename(path)
161
- self._parse_info()
162
- self._update_studyinfo()
163
-
164
- def _parse_info(self):
165
- self._reset()
166
- root_path_fregs = None
167
- for root, subdir, files in os.walk(self.__path):
168
- if 'subject' in files:
169
- if root_path_fregs is None:
170
- root_path_fregs = len(root.split(os.sep))
171
- with open(os.path.join(root, 'subject'), 'r') as f:
172
- self._subject = Parameter(f.read().split('\n'))
173
- else:
174
- pass
175
- elif 'method' in files and 'acqp' in files:
176
- if len(root.split(os.sep)) == root_path_fregs + 1:
177
- scan_id = os.path.basename(root)
178
- if scan_id.isdigit():
179
- with open(os.path.join(root, 'method'), 'r') as f:
180
- self._method[int(scan_id)] = Parameter(f.read().split('\n'))
181
- with open(os.path.join(root, 'acqp'), 'r') as f:
182
- self._acqp[int(scan_id)] = Parameter(f.read().split('\n'))
183
- fid_path = os.path.join(root, 'fid')
184
- traj_path = os.path.join(root, 'traj')
185
- if os.path.exists(fid_path):
186
- self._fid[int(scan_id)] = fid_path
187
- else:
188
- fid_path = os.path.join(root, 'rawdata.job0')
189
- if os.path.exists(fid_path):
190
- self._fid[int(scan_id)] = fid_path
191
- if os.path.exists(traj_path):
192
- self._traj[int(scan_id)] = traj_path
193
- elif '2dseq' in files and 'visu_pars' in files:
194
- path_freg = root.split(os.sep)
195
- if len(root.split(os.sep)) == root_path_fregs + 3:
196
- scan_id = path_freg[-3]
197
- reco_id = path_freg[-1]
198
- if scan_id.isdigit() and reco_id.isdigit():
199
- if int(scan_id) in self._2dseq.keys():
200
- self._2dseq[int(scan_id)].append(_2dseq(reco_id=int(reco_id),
201
- idx=os.path.join(root, '2dseq')))
202
- else:
203
- self._2dseq[int(scan_id)] = [_2dseq(reco_id=int(reco_id),
204
- idx=os.path.join(root, '2dseq'))]
205
- if int(scan_id) in self._visu_pars.keys():
206
- self._visu_pars[int(scan_id)].append(_visu_pars(reco_id=int(reco_id),
207
- idx=os.path.join(root, 'visu_pars')))
208
- else:
209
- self._visu_pars[int(scan_id)] = [_visu_pars(reco_id=int(reco_id),
210
- idx=os.path.join(root, 'visu_pars'))]
211
- if int(scan_id) in self._reco.keys():
212
- self._reco[int(scan_id)].append(_reco(reco_id=int(reco_id),
213
- idx=os.path.join(root, 'reco')))
214
- else:
215
- self._reco[int(scan_id)] = [_reco(reco_id=int(reco_id),
216
- idx=os.path.join(root, 'reco'))]
217
-
218
- def _open_object(self, path):
219
- return open(path, 'rb')
220
-
221
- def _open_binary(self, path):
222
- return open(path, 'rb').read()
223
-
224
- def _open_string(self, path):
225
- return open(path, 'r').read().split('\n')
226
-
227
-
228
- class PvDatasetZip(zf.ZipFile, PvDatasetBase):
229
- def __init__(self, path):
230
- super(PvDatasetZip, self).__init__(path)
231
- self._parse_info()
232
- self._update_studyinfo()
233
-
234
- def _parse_info(self):
235
- self._reset()
236
- # parse subject information
237
- for idx, full_path in enumerate(self.namelist()):
238
- # path_freg = full_path.split(os.path.sep)
239
- path_freg = full_path.split('/') # zipfile uses / instead of os.sep
240
- n_freg = len(path_freg)
241
-
242
- if n_freg == 1:
243
- # database object
244
- pass
245
-
246
- elif n_freg == 2:
247
- if self.path is None:
248
- self.path = path_freg[0]
249
- if path_freg[1] == 'subject':
250
- with self.open(full_path) as f:
251
- self._subject = Parameter(f.read().decode('UTF-8').split('\n'))
252
-
253
- elif n_freg == 3 and path_freg[1].isdigit():
254
- scan_id = int(path_freg[1])
255
- filename = path_freg[2]
256
-
257
- if filename == 'method':
258
- with self.open(full_path) as f:
259
- self._method[scan_id] = Parameter(f.read().decode('UTF-8').split('\n'))
260
- elif filename == 'acqp':
261
- with self.open(full_path) as f:
262
- self._acqp[scan_id] = Parameter(f.read().decode('UTF-8').split('\n'))
263
- elif filename == 'fid':
264
- self._fid[scan_id] = idx
265
- elif filename == 'rawdata.job0':
266
- self._fid[scan_id] = idx
267
- elif filename == 'traj':
268
- self._traj[scan_id] = idx
269
- else:
270
- pass
271
-
272
- elif n_freg == 5 and path_freg[2] == 'pdata':
273
- scan_id = int(path_freg[1])
274
- if path_freg[3].isdigit():
275
- reco_id = int(path_freg[3])
276
- filename = path_freg[4]
277
-
278
- if filename == '2dseq':
279
- if scan_id in self._2dseq.keys():
280
- self._2dseq[scan_id].append(_2dseq(reco_id=reco_id, idx=idx))
281
- else:
282
- self._2dseq[scan_id] = [_2dseq(reco_id=reco_id, idx=idx)]
283
- elif filename == 'visu_pars':
284
- if scan_id in self._visu_pars.keys():
285
- self._visu_pars[scan_id].append(_visu_pars(reco_id=reco_id, idx=idx))
286
- else:
287
- self._visu_pars[scan_id] = [_visu_pars(reco_id=reco_id, idx=idx)]
288
- elif filename == 'reco':
289
- if scan_id in self._reco.keys():
290
- self._reco[scan_id].append(_reco(reco_id=reco_id, idx=idx))
291
- else:
292
- self._reco[scan_id] = [_reco(reco_id=reco_id, idx=idx)]
293
-
294
- def _open_object(self, path):
295
- return self.open(self.namelist()[path])
296
-
297
- def _open_binary(self, path):
298
- return self.open(self.namelist()[path]).read()
299
-
300
- def _open_string(self, path):
301
- return self.open(self.namelist()[path]).read().decode('UTF-8').split('\n')