qmenta-client 1.1.dev1373__py3-none-any.whl → 1.1.dev1382__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.
- qmenta/client/Project.py +206 -211
- {qmenta_client-1.1.dev1373.dist-info → qmenta_client-1.1.dev1382.dist-info}/METADATA +1 -1
- {qmenta_client-1.1.dev1373.dist-info → qmenta_client-1.1.dev1382.dist-info}/RECORD +4 -4
- {qmenta_client-1.1.dev1373.dist-info → qmenta_client-1.1.dev1382.dist-info}/WHEEL +0 -0
qmenta/client/Project.py
CHANGED
|
@@ -20,186 +20,6 @@ logger_name = "qmenta.client"
|
|
|
20
20
|
OPERATOR_LIST = ["eq", "ne", "gt", "gte", "lt", "lte"]
|
|
21
21
|
|
|
22
22
|
|
|
23
|
-
def show_progress(done, total, finish=False):
|
|
24
|
-
bytes_in_mb = 1024 * 1024
|
|
25
|
-
progress_message = "\r[{:.2f} %] Uploaded {:.2f} of {:.2f} Mb".format(
|
|
26
|
-
done / float(total) * 100, done / bytes_in_mb, total / bytes_in_mb
|
|
27
|
-
)
|
|
28
|
-
sys.stdout.write(progress_message)
|
|
29
|
-
sys.stdout.flush()
|
|
30
|
-
if not finish:
|
|
31
|
-
pass
|
|
32
|
-
# sys.stdout.write("")
|
|
33
|
-
# sys.stdout.flush()
|
|
34
|
-
else:
|
|
35
|
-
sys.stdout.write("\n")
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
def get_session_id(file_path):
|
|
39
|
-
m = hashlib.md5()
|
|
40
|
-
m.update(file_path.encode("utf-8"))
|
|
41
|
-
return str(time.time()).replace(".", "") + "_" + m.hexdigest()
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
def check_upload_file(file_path):
|
|
45
|
-
"""
|
|
46
|
-
Check whether a file has the correct extension to upload.
|
|
47
|
-
|
|
48
|
-
Parameters
|
|
49
|
-
----------
|
|
50
|
-
file_path : str
|
|
51
|
-
Path to the file
|
|
52
|
-
|
|
53
|
-
Returns
|
|
54
|
-
-------
|
|
55
|
-
bool
|
|
56
|
-
True if correct extension, False otherwise.
|
|
57
|
-
"""
|
|
58
|
-
|
|
59
|
-
# TODO: Add a file zipper here so zips files in a folder
|
|
60
|
-
|
|
61
|
-
file_parts = file_path.split(".")
|
|
62
|
-
extension = file_parts[-1]
|
|
63
|
-
|
|
64
|
-
if extension != "zip":
|
|
65
|
-
logging.getLogger(logger_name).error("You must upload a zip.")
|
|
66
|
-
return False
|
|
67
|
-
else:
|
|
68
|
-
return True
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
def operation(reference_value, operator, input_value):
|
|
72
|
-
"""
|
|
73
|
-
The method performs an operation by comparing the two input values.
|
|
74
|
-
The Operation is applied to the Input Value in comparison to the Reference
|
|
75
|
-
Value.
|
|
76
|
-
|
|
77
|
-
Parameters
|
|
78
|
-
----------
|
|
79
|
-
reference_value : str, list, or int
|
|
80
|
-
Reference value.
|
|
81
|
-
operator : str
|
|
82
|
-
Operation.
|
|
83
|
-
input_value : str, list, or int
|
|
84
|
-
Input value.
|
|
85
|
-
|
|
86
|
-
Returns
|
|
87
|
-
-------
|
|
88
|
-
bool
|
|
89
|
-
True if the operation is satisfied, False otherwise.
|
|
90
|
-
"""
|
|
91
|
-
if input_value is None or input_value == "":
|
|
92
|
-
return False
|
|
93
|
-
|
|
94
|
-
if operator == "in":
|
|
95
|
-
return reference_value in input_value
|
|
96
|
-
|
|
97
|
-
elif operator == "in-list":
|
|
98
|
-
return all([el in input_value for el in reference_value])
|
|
99
|
-
|
|
100
|
-
elif operator == "eq":
|
|
101
|
-
return input_value == reference_value
|
|
102
|
-
|
|
103
|
-
elif operator == "gt":
|
|
104
|
-
return input_value > reference_value
|
|
105
|
-
|
|
106
|
-
elif operator == "gte":
|
|
107
|
-
return input_value >= reference_value
|
|
108
|
-
|
|
109
|
-
elif operator == "lt":
|
|
110
|
-
return input_value < reference_value
|
|
111
|
-
|
|
112
|
-
elif operator == "lte":
|
|
113
|
-
return input_value <= reference_value
|
|
114
|
-
else:
|
|
115
|
-
return False
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
def wrap_search_criteria(search_criteria={}):
|
|
119
|
-
"""
|
|
120
|
-
Wraps the conditions specified within the Search Criteria in order for
|
|
121
|
-
other methods to handle it easily. The conditions are grouped only into
|
|
122
|
-
three groups: Modality, Tags and the File Metadata (if DICOM it corresponds
|
|
123
|
-
to the DICOM information), and each of them is output in a different
|
|
124
|
-
variable.
|
|
125
|
-
|
|
126
|
-
Parameters
|
|
127
|
-
----------
|
|
128
|
-
search_criteria : dict
|
|
129
|
-
Each element is a string and is built using the formatting
|
|
130
|
-
"KEYTYPE;VALUE", or "KEYTYPE;OPERATOR|VALUE".
|
|
131
|
-
|
|
132
|
-
Full list of keys avaiable for the dictionary:
|
|
133
|
-
|
|
134
|
-
search_criteria = {
|
|
135
|
-
"pars_patient_secret_name": "string;SUBJECTID",
|
|
136
|
-
"pars_ssid": "integer;OPERATOR|SSID",
|
|
137
|
-
"pars_modalities": "string;MODALITY",
|
|
138
|
-
"pars_tags": "tags;TAGS",
|
|
139
|
-
"pars_age_at_scan": "integer;OPERATOR|AGE_AT_SCAN",
|
|
140
|
-
"pars_[dicom]_KEY": "KEYTYPE;KEYVALUE",
|
|
141
|
-
"pars_PROJECTMETADATA": "METADATATYPE;METADATAVALUE",
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
See documentation for a complete definition.
|
|
145
|
-
|
|
146
|
-
Returns
|
|
147
|
-
-------
|
|
148
|
-
modality : str
|
|
149
|
-
String containing the modality of the search criteria extracted from
|
|
150
|
-
'pars_modalities'
|
|
151
|
-
|
|
152
|
-
tags : list of str
|
|
153
|
-
List of strings containing the tags of the search criteria extracted
|
|
154
|
-
'from pars_tags'
|
|
155
|
-
|
|
156
|
-
file_metadata : Dict
|
|
157
|
-
Dictionary containing the file metadata of the search criteria
|
|
158
|
-
extracted from 'pars_[dicom]_KEY'
|
|
159
|
-
"""
|
|
160
|
-
|
|
161
|
-
# The keys not included bellow apply to the whole session.
|
|
162
|
-
modality, tags, file_metadata = "", list(), dict()
|
|
163
|
-
for key, value in search_criteria.items():
|
|
164
|
-
if key == "pars_modalities":
|
|
165
|
-
modalities = value.split(";")[1].split(",")
|
|
166
|
-
if len(modalities) != 1:
|
|
167
|
-
raise ValueError(f"A file can only have one modality. "
|
|
168
|
-
f"Provided Modalities: "
|
|
169
|
-
f"{', '.join(modalities)}.")
|
|
170
|
-
modality = modalities[0]
|
|
171
|
-
elif key == "pars_tags":
|
|
172
|
-
tags = value.split(";")[1].split(",")
|
|
173
|
-
elif "pars_[dicom]_" in key:
|
|
174
|
-
d_tag = key.split("pars_[dicom]_")[1]
|
|
175
|
-
d_type = value.split(";")[0]
|
|
176
|
-
if d_type == "string":
|
|
177
|
-
file_metadata[d_tag] = {
|
|
178
|
-
"operation": "in",
|
|
179
|
-
"value": value.replace(d_type + ";", "")
|
|
180
|
-
}
|
|
181
|
-
elif d_type == "integer":
|
|
182
|
-
d_operator = value.split(";")[1].split("|")[0]
|
|
183
|
-
d_value = value.split(";")[1].split("|")[1]
|
|
184
|
-
file_metadata[d_tag] = {
|
|
185
|
-
"operation": d_operator,
|
|
186
|
-
"value": int(d_value)}
|
|
187
|
-
elif d_type == "decimal":
|
|
188
|
-
d_operator = value.split(";")[1].split("|")[0]
|
|
189
|
-
d_value = value.split(";")[1].split("|")[1]
|
|
190
|
-
file_metadata[d_tag] = {
|
|
191
|
-
"operation": d_operator,
|
|
192
|
-
"value": float(d_value)
|
|
193
|
-
}
|
|
194
|
-
elif d_type == "list":
|
|
195
|
-
value.replace(d_type + ";", "")
|
|
196
|
-
file_metadata[d_tag] = {
|
|
197
|
-
"operation": "in-list",
|
|
198
|
-
"value": value.replace(d_type + ";", "").split(";")
|
|
199
|
-
}
|
|
200
|
-
return modality, tags, file_metadata
|
|
201
|
-
|
|
202
|
-
|
|
203
23
|
def convert_qc_value_to_qcstatus(value):
|
|
204
24
|
"""
|
|
205
25
|
Convert input string to QCStatus class.
|
|
@@ -577,7 +397,7 @@ class Project:
|
|
|
577
397
|
content = self.get_subjects_metadata(search_criteria, items=(0, 9999))
|
|
578
398
|
|
|
579
399
|
# Wrap search criteria.
|
|
580
|
-
modality, tags, dicoms =
|
|
400
|
+
modality, tags, dicoms = self.__wrap_search_criteria(search_criteria)
|
|
581
401
|
|
|
582
402
|
# Iterate over the files of each subject selected to include/exclude
|
|
583
403
|
# them from the results.
|
|
@@ -602,7 +422,7 @@ class Project:
|
|
|
602
422
|
d_operator = dict_value["operation"]
|
|
603
423
|
d_value = dict_value["value"]
|
|
604
424
|
result_values.append(
|
|
605
|
-
|
|
425
|
+
self.__operation(d_value, d_operator, f_value)
|
|
606
426
|
)
|
|
607
427
|
|
|
608
428
|
if not all(result_values):
|
|
@@ -731,17 +551,17 @@ class Project:
|
|
|
731
551
|
Parameters
|
|
732
552
|
----------
|
|
733
553
|
search_condition : dict
|
|
734
|
-
- p_n: str Analysis name
|
|
735
|
-
- type: str Type
|
|
736
|
-
- from_d: str
|
|
737
|
-
- to_d: str dd.mm.yyyy Date to
|
|
738
|
-
- qa_status: str pass/fail/nd QC status
|
|
739
|
-
- secret_name: str Subject ID
|
|
740
|
-
- tags: str
|
|
741
|
-
- with_child_analysis: 1 if 1, child analysis of workflows will appear
|
|
742
|
-
- id: str ID
|
|
743
|
-
- state: running, completed, pending, exception
|
|
744
|
-
- username: str
|
|
554
|
+
- p_n: str or None Analysis name
|
|
555
|
+
- type: str or None Type
|
|
556
|
+
- from_d: str or None dd.mm.yyyy Date from
|
|
557
|
+
- to_d: str or None dd.mm.yyyy Date to
|
|
558
|
+
- qa_status: str or None pass/fail/nd QC status
|
|
559
|
+
- secret_name: str or None Subject ID
|
|
560
|
+
- tags: str or None
|
|
561
|
+
- with_child_analysis: 1 or None if 1, child analysis of workflows will appear
|
|
562
|
+
- id: str or None ID
|
|
563
|
+
- state: running, completed, pending, exception or None
|
|
564
|
+
- username: str or None
|
|
745
565
|
|
|
746
566
|
items : List[int]
|
|
747
567
|
list containing two elements [min, max] that correspond to the
|
|
@@ -770,7 +590,7 @@ class Project:
|
|
|
770
590
|
for key in search_condition.keys():
|
|
771
591
|
if key not in search_keys.keys():
|
|
772
592
|
raise Exception((f"This key '{key}' is not accepted by this" "search condition"))
|
|
773
|
-
if not isinstance(search_condition[key], search_keys[key]):
|
|
593
|
+
if not isinstance(search_condition[key], search_keys[key]) and search_condition[key] is not None:
|
|
774
594
|
raise Exception((f"The key {key} in the search condition" f"is not type {search_keys[key]}"))
|
|
775
595
|
req_headers = {"X-Range": f"items={items[0]}-{items[1] - 1}"}
|
|
776
596
|
return platform.parse_response(
|
|
@@ -881,17 +701,17 @@ class Project:
|
|
|
881
701
|
Parameters
|
|
882
702
|
----------
|
|
883
703
|
search_condition : dict
|
|
884
|
-
- p_n: str Analysis name
|
|
885
|
-
- type: str Type
|
|
886
|
-
- from_d: str
|
|
887
|
-
- to_d: str dd.mm.yyyy Date to
|
|
888
|
-
- qa_status: str pass/fail/nd QC status
|
|
889
|
-
- secret_name: str Subject ID
|
|
890
|
-
- tags: str
|
|
891
|
-
- with_child_analysis: 1 if 1, child analysis of workflows will appear
|
|
892
|
-
- id: str ID
|
|
893
|
-
- state: running, completed, pending, exception
|
|
894
|
-
- username: str
|
|
704
|
+
- p_n: str or None Analysis name
|
|
705
|
+
- type: str or None Type
|
|
706
|
+
- from_d: str or None dd.mm.yyyy Date from
|
|
707
|
+
- to_d: str or None dd.mm.yyyy Date to
|
|
708
|
+
- qa_status: str or None pass/fail/nd QC status
|
|
709
|
+
- secret_name: str or None Subject ID
|
|
710
|
+
- tags: str or None
|
|
711
|
+
- with_child_analysis: 1 or None if 1, child analysis of workflows will appear
|
|
712
|
+
- id: str or None ID
|
|
713
|
+
- state: running, completed, pending, exception or None
|
|
714
|
+
- username: str or None
|
|
895
715
|
items : List[int]
|
|
896
716
|
list containing two elements [min, max] that correspond to the
|
|
897
717
|
mininum and maximum range of analysis listed
|
|
@@ -1533,7 +1353,7 @@ class Project:
|
|
|
1533
1353
|
logger.error("Cannot upload empty file {}".format(file_path))
|
|
1534
1354
|
return False
|
|
1535
1355
|
uploaded = 0
|
|
1536
|
-
session_id =
|
|
1356
|
+
session_id = self.__get_session_id(file_path)
|
|
1537
1357
|
chunk_num = 0
|
|
1538
1358
|
retries_count = 0
|
|
1539
1359
|
uploaded_bytes = 0
|
|
@@ -1592,7 +1412,7 @@ class Project:
|
|
|
1592
1412
|
retries_count = 0
|
|
1593
1413
|
uploaded_bytes += chunk_size
|
|
1594
1414
|
elif int(response.status_code) == 200:
|
|
1595
|
-
|
|
1415
|
+
self.__show_progress(file_size, file_size, finish=True)
|
|
1596
1416
|
break
|
|
1597
1417
|
elif int(response.status_code) == 416:
|
|
1598
1418
|
retries_count += 1
|
|
@@ -1610,7 +1430,7 @@ class Project:
|
|
|
1610
1430
|
break
|
|
1611
1431
|
|
|
1612
1432
|
uploaded += chunk_size
|
|
1613
|
-
|
|
1433
|
+
self.__show_progress(uploaded, file_size)
|
|
1614
1434
|
|
|
1615
1435
|
try:
|
|
1616
1436
|
platform.parse_response(response)
|
|
@@ -1639,7 +1459,7 @@ class Project:
|
|
|
1639
1459
|
True if upload was correctly done, False otherwise.
|
|
1640
1460
|
"""
|
|
1641
1461
|
|
|
1642
|
-
if
|
|
1462
|
+
if self.__check_upload_file(file_path):
|
|
1643
1463
|
return self.upload_file(file_path, subject_name)
|
|
1644
1464
|
|
|
1645
1465
|
def upload_gametection(self, file_path, subject_name):
|
|
@@ -1658,7 +1478,7 @@ class Project:
|
|
|
1658
1478
|
True if upload was correctly done, False otherwise.
|
|
1659
1479
|
"""
|
|
1660
1480
|
|
|
1661
|
-
if
|
|
1481
|
+
if self.__check_upload_file(file_path):
|
|
1662
1482
|
return self.upload_file(file_path, subject_name, input_data_type="parkinson_gametection")
|
|
1663
1483
|
return False
|
|
1664
1484
|
|
|
@@ -1678,7 +1498,7 @@ class Project:
|
|
|
1678
1498
|
True if upload was correctly done, False otherwise.
|
|
1679
1499
|
"""
|
|
1680
1500
|
|
|
1681
|
-
if
|
|
1501
|
+
if self.__check_upload_file(file_path):
|
|
1682
1502
|
return self.upload_file(file_path, subject_name, result=True)
|
|
1683
1503
|
return False
|
|
1684
1504
|
|
|
@@ -2183,3 +2003,178 @@ class Project:
|
|
|
2183
2003
|
return False
|
|
2184
2004
|
|
|
2185
2005
|
return res["guidance_text"]
|
|
2006
|
+
|
|
2007
|
+
def __show_progress(self, done, total, finish=False):
|
|
2008
|
+
bytes_in_mb = 1024 * 1024
|
|
2009
|
+
progress_message = "\r[{:.2f} %] Uploaded {:.2f} of {:.2f} Mb".format(
|
|
2010
|
+
done / float(total) * 100, done / bytes_in_mb, total / bytes_in_mb
|
|
2011
|
+
)
|
|
2012
|
+
sys.stdout.write(progress_message)
|
|
2013
|
+
sys.stdout.flush()
|
|
2014
|
+
if not finish:
|
|
2015
|
+
pass
|
|
2016
|
+
# sys.stdout.write("")
|
|
2017
|
+
# sys.stdout.flush()
|
|
2018
|
+
else:
|
|
2019
|
+
sys.stdout.write("\n")
|
|
2020
|
+
|
|
2021
|
+
def __get_session_id(self, file_path):
|
|
2022
|
+
m = hashlib.md5()
|
|
2023
|
+
m.update(file_path.encode("utf-8"))
|
|
2024
|
+
return str(time.time()).replace(".", "") + "_" + m.hexdigest()
|
|
2025
|
+
|
|
2026
|
+
def __check_upload_file(self, file_path):
|
|
2027
|
+
"""
|
|
2028
|
+
Check whether a file has the correct extension to upload.
|
|
2029
|
+
|
|
2030
|
+
Parameters
|
|
2031
|
+
----------
|
|
2032
|
+
file_path : str
|
|
2033
|
+
Path to the file
|
|
2034
|
+
|
|
2035
|
+
Returns
|
|
2036
|
+
-------
|
|
2037
|
+
bool
|
|
2038
|
+
True if correct extension, False otherwise.
|
|
2039
|
+
"""
|
|
2040
|
+
|
|
2041
|
+
# TODO: Add a file zipper here so zips files in a folder
|
|
2042
|
+
|
|
2043
|
+
file_parts = file_path.split(".")
|
|
2044
|
+
extension = file_parts[-1]
|
|
2045
|
+
|
|
2046
|
+
if extension != "zip":
|
|
2047
|
+
logging.getLogger(logger_name).error("You must upload a zip.")
|
|
2048
|
+
return False
|
|
2049
|
+
else:
|
|
2050
|
+
return True
|
|
2051
|
+
|
|
2052
|
+
def __operation(self, reference_value, operator, input_value):
|
|
2053
|
+
"""
|
|
2054
|
+
The method performs an operation by comparing the two input values.
|
|
2055
|
+
The Operation is applied to the Input Value in comparison to the Reference
|
|
2056
|
+
Value.
|
|
2057
|
+
|
|
2058
|
+
Parameters
|
|
2059
|
+
----------
|
|
2060
|
+
reference_value : str, list, or int
|
|
2061
|
+
Reference value.
|
|
2062
|
+
operator : str
|
|
2063
|
+
Operation.
|
|
2064
|
+
input_value : str, list, or int
|
|
2065
|
+
Input value.
|
|
2066
|
+
|
|
2067
|
+
Returns
|
|
2068
|
+
-------
|
|
2069
|
+
bool
|
|
2070
|
+
True if the operation is satisfied, False otherwise.
|
|
2071
|
+
"""
|
|
2072
|
+
if input_value is None or input_value == "":
|
|
2073
|
+
return False
|
|
2074
|
+
|
|
2075
|
+
if operator == "in":
|
|
2076
|
+
return reference_value in input_value
|
|
2077
|
+
|
|
2078
|
+
elif operator == "in-list":
|
|
2079
|
+
return all([el in input_value for el in reference_value])
|
|
2080
|
+
|
|
2081
|
+
elif operator == "eq":
|
|
2082
|
+
return input_value == reference_value
|
|
2083
|
+
|
|
2084
|
+
elif operator == "gt":
|
|
2085
|
+
return input_value > reference_value
|
|
2086
|
+
|
|
2087
|
+
elif operator == "gte":
|
|
2088
|
+
return input_value >= reference_value
|
|
2089
|
+
|
|
2090
|
+
elif operator == "lt":
|
|
2091
|
+
return input_value < reference_value
|
|
2092
|
+
|
|
2093
|
+
elif operator == "lte":
|
|
2094
|
+
return input_value <= reference_value
|
|
2095
|
+
else:
|
|
2096
|
+
return False
|
|
2097
|
+
|
|
2098
|
+
def __wrap_search_criteria(self, search_criteria={}):
|
|
2099
|
+
"""
|
|
2100
|
+
Wraps the conditions specified within the Search Criteria in order for
|
|
2101
|
+
other methods to handle it easily. The conditions are grouped only into
|
|
2102
|
+
three groups: Modality, Tags and the File Metadata (if DICOM it corresponds
|
|
2103
|
+
to the DICOM information), and each of them is output in a different
|
|
2104
|
+
variable.
|
|
2105
|
+
|
|
2106
|
+
Parameters
|
|
2107
|
+
----------
|
|
2108
|
+
search_criteria : dict
|
|
2109
|
+
Each element is a string and is built using the formatting
|
|
2110
|
+
"KEYTYPE;VALUE", or "KEYTYPE;OPERATOR|VALUE".
|
|
2111
|
+
|
|
2112
|
+
Full list of keys avaiable for the dictionary:
|
|
2113
|
+
|
|
2114
|
+
search_criteria = {
|
|
2115
|
+
"pars_patient_secret_name": "string;SUBJECTID",
|
|
2116
|
+
"pars_ssid": "integer;OPERATOR|SSID",
|
|
2117
|
+
"pars_modalities": "string;MODALITY",
|
|
2118
|
+
"pars_tags": "tags;TAGS",
|
|
2119
|
+
"pars_age_at_scan": "integer;OPERATOR|AGE_AT_SCAN",
|
|
2120
|
+
"pars_[dicom]_KEY": "KEYTYPE;KEYVALUE",
|
|
2121
|
+
"pars_PROJECTMETADATA": "METADATATYPE;METADATAVALUE",
|
|
2122
|
+
}
|
|
2123
|
+
|
|
2124
|
+
See documentation for a complete definition.
|
|
2125
|
+
|
|
2126
|
+
Returns
|
|
2127
|
+
-------
|
|
2128
|
+
modality : str
|
|
2129
|
+
String containing the modality of the search criteria extracted from
|
|
2130
|
+
'pars_modalities'
|
|
2131
|
+
|
|
2132
|
+
tags : list of str
|
|
2133
|
+
List of strings containing the tags of the search criteria extracted
|
|
2134
|
+
'from pars_tags'
|
|
2135
|
+
|
|
2136
|
+
file_metadata : Dict
|
|
2137
|
+
Dictionary containing the file metadata of the search criteria
|
|
2138
|
+
extracted from 'pars_[dicom]_KEY'
|
|
2139
|
+
"""
|
|
2140
|
+
|
|
2141
|
+
# The keys not included bellow apply to the whole session.
|
|
2142
|
+
modality, tags, file_metadata = "", list(), dict()
|
|
2143
|
+
for key, value in search_criteria.items():
|
|
2144
|
+
if key == "pars_modalities":
|
|
2145
|
+
modalities = value.split(";")[1].split(",")
|
|
2146
|
+
if len(modalities) != 1:
|
|
2147
|
+
raise ValueError(f"A file can only have one modality. "
|
|
2148
|
+
f"Provided Modalities: "
|
|
2149
|
+
f"{', '.join(modalities)}.")
|
|
2150
|
+
modality = modalities[0]
|
|
2151
|
+
elif key == "pars_tags":
|
|
2152
|
+
tags = value.split(";")[1].split(",")
|
|
2153
|
+
elif "pars_[dicom]_" in key:
|
|
2154
|
+
d_tag = key.split("pars_[dicom]_")[1]
|
|
2155
|
+
d_type = value.split(";")[0]
|
|
2156
|
+
if d_type == "string":
|
|
2157
|
+
file_metadata[d_tag] = {
|
|
2158
|
+
"operation": "in",
|
|
2159
|
+
"value": value.replace(d_type + ";", "")
|
|
2160
|
+
}
|
|
2161
|
+
elif d_type == "integer":
|
|
2162
|
+
d_operator = value.split(";")[1].split("|")[0]
|
|
2163
|
+
d_value = value.split(";")[1].split("|")[1]
|
|
2164
|
+
file_metadata[d_tag] = {
|
|
2165
|
+
"operation": d_operator,
|
|
2166
|
+
"value": int(d_value)}
|
|
2167
|
+
elif d_type == "decimal":
|
|
2168
|
+
d_operator = value.split(";")[1].split("|")[0]
|
|
2169
|
+
d_value = value.split(";")[1].split("|")[1]
|
|
2170
|
+
file_metadata[d_tag] = {
|
|
2171
|
+
"operation": d_operator,
|
|
2172
|
+
"value": float(d_value)
|
|
2173
|
+
}
|
|
2174
|
+
elif d_type == "list":
|
|
2175
|
+
value.replace(d_type + ";", "")
|
|
2176
|
+
file_metadata[d_tag] = {
|
|
2177
|
+
"operation": "in-list",
|
|
2178
|
+
"value": value.replace(d_type + ";", "").split(";")
|
|
2179
|
+
}
|
|
2180
|
+
return modality, tags, file_metadata
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
qmenta/__init__.py,sha256=jv2YF__bseklT3OWEzlqJ5qE24c4aWd5F4r0TTjOrWQ,65
|
|
2
2
|
qmenta/client/Account.py,sha256=MEljEy9cmg2uP2FG1d3TZAgfj66EE2_3PQAZ9rvpCXY,9647
|
|
3
3
|
qmenta/client/File.py,sha256=ZgvSqejIosUt4uoX7opUnPnp5XGEaJNMRwFC0mQVB8k,5344
|
|
4
|
-
qmenta/client/Project.py,sha256
|
|
4
|
+
qmenta/client/Project.py,sha256=-Smnh6NCv-N-xF07f1OtTH1VpqVEMLl7fbemwK3Aayk,77848
|
|
5
5
|
qmenta/client/Subject.py,sha256=lhxxVdQ6d-GNoQC8mrJwa4L1f44nJc4PcJtDspmKN7I,8756
|
|
6
6
|
qmenta/client/__init__.py,sha256=AjTojBhZeW5nl0i605KS8S1Gl5tPNc1hdzD47BGNfoI,147
|
|
7
7
|
qmenta/client/utils.py,sha256=5DK2T_HQprrCwLS0Ycm2CjseaYmAUKaJkJvYoW-Rqzc,2479
|
|
8
|
-
qmenta_client-1.1.
|
|
9
|
-
qmenta_client-1.1.
|
|
10
|
-
qmenta_client-1.1.
|
|
8
|
+
qmenta_client-1.1.dev1382.dist-info/METADATA,sha256=E0qXlYKpgxu_Uh-1tuvWKs_FHUrbn6Kcy9YqXyCN82Y,672
|
|
9
|
+
qmenta_client-1.1.dev1382.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
|
|
10
|
+
qmenta_client-1.1.dev1382.dist-info/RECORD,,
|
|
File without changes
|