easysurfvis 0.0.1__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 (54) hide show
  1. easysurfvis-0.0.1/MANIFEST.in +1 -0
  2. easysurfvis-0.0.1/PKG-INFO +39 -0
  3. easysurfvis-0.0.1/README.md +15 -0
  4. easysurfvis-0.0.1/setup.cfg +4 -0
  5. easysurfvis-0.0.1/setup.py +32 -0
  6. easysurfvis-0.0.1/src/easysurfvis/__init__.py +0 -0
  7. easysurfvis-0.0.1/src/easysurfvis/cores/__init__.py +0 -0
  8. easysurfvis-0.0.1/src/easysurfvis/cores/afni_extension.py +206 -0
  9. easysurfvis-0.0.1/src/easysurfvis/cores/custom_matplotlib.py +218 -0
  10. easysurfvis-0.0.1/src/easysurfvis/cores/general_util.py +150 -0
  11. easysurfvis-0.0.1/src/easysurfvis/cores/surface_data.py +243 -0
  12. easysurfvis-0.0.1/src/easysurfvis/cores/surface_roi.py +186 -0
  13. easysurfvis-0.0.1/src/easysurfvis/cores/surface_util.py +113 -0
  14. easysurfvis-0.0.1/src/easysurfvis/data/ROI/Brodmann/L_roi_values.npy +0 -0
  15. easysurfvis-0.0.1/src/easysurfvis/data/ROI/Brodmann/L_roi_vertex_info.json +1 -0
  16. easysurfvis-0.0.1/src/easysurfvis/data/ROI/Brodmann/L_rois.npy +0 -0
  17. easysurfvis-0.0.1/src/easysurfvis/data/ROI/Brodmann/R_roi_values.npy +0 -0
  18. easysurfvis-0.0.1/src/easysurfvis/data/ROI/Brodmann/R_roi_vertex_info.json +1 -0
  19. easysurfvis-0.0.1/src/easysurfvis/data/ROI/Brodmann/R_rois.npy +0 -0
  20. easysurfvis-0.0.1/src/easysurfvis/data/ROI/FAN/L_roi_values.npy +0 -0
  21. easysurfvis-0.0.1/src/easysurfvis/data/ROI/FAN/L_roi_vertex_info.json +1 -0
  22. easysurfvis-0.0.1/src/easysurfvis/data/ROI/FAN/L_rois.npy +0 -0
  23. easysurfvis-0.0.1/src/easysurfvis/data/ROI/FAN/R_roi_values.npy +0 -0
  24. easysurfvis-0.0.1/src/easysurfvis/data/ROI/FAN/R_roi_vertex_info.json +1 -0
  25. easysurfvis-0.0.1/src/easysurfvis/data/ROI/FAN/R_rois.npy +0 -0
  26. easysurfvis-0.0.1/src/easysurfvis/data/Sample/l_sampling_datas1.npy +0 -0
  27. easysurfvis-0.0.1/src/easysurfvis/data/Sample/l_sampling_datas2.npy +0 -0
  28. easysurfvis-0.0.1/src/easysurfvis/data/Sample/l_virtual_strip_mask.npy +0 -0
  29. easysurfvis-0.0.1/src/easysurfvis/data/Sample/r_sampling_datas1.npy +0 -0
  30. easysurfvis-0.0.1/src/easysurfvis/data/Sample/r_sampling_datas2.npy +0 -0
  31. easysurfvis-0.0.1/src/easysurfvis/data/Sample/r_virtual_strip_mask.npy +0 -0
  32. easysurfvis-0.0.1/src/easysurfvis/data/Sample/sample_3d_data.nii.gz +0 -0
  33. easysurfvis-0.0.1/src/easysurfvis/data/Sulcus/L_sulcus.json +1 -0
  34. easysurfvis-0.0.1/src/easysurfvis/data/Sulcus/L_sulcus_sensorimotor.json +230 -0
  35. easysurfvis-0.0.1/src/easysurfvis/data/Sulcus/R_sulcus.json +1 -0
  36. easysurfvis-0.0.1/src/easysurfvis/data/Sulcus/R_sulcus_sensorimotor.json +250 -0
  37. easysurfvis-0.0.1/src/easysurfvis/data/Template/fs_LR.32k.L.flat.surf.gii +81 -0
  38. easysurfvis-0.0.1/src/easysurfvis/data/Template/fs_LR.32k.L.inflated.surf.gii +136 -0
  39. easysurfvis-0.0.1/src/easysurfvis/data/Template/fs_LR.32k.L.pial.surf.gii +1453 -0
  40. easysurfvis-0.0.1/src/easysurfvis/data/Template/fs_LR.32k.L.shape.gii +6 -0
  41. easysurfvis-0.0.1/src/easysurfvis/data/Template/fs_LR.32k.L.white.surf.gii +1453 -0
  42. easysurfvis-0.0.1/src/easysurfvis/data/Template/fs_LR.32k.R.flat.surf.gii +89 -0
  43. easysurfvis-0.0.1/src/easysurfvis/data/Template/fs_LR.32k.R.inflated.surf.gii +136 -0
  44. easysurfvis-0.0.1/src/easysurfvis/data/Template/fs_LR.32k.R.pial.surf.gii +1453 -0
  45. easysurfvis-0.0.1/src/easysurfvis/data/Template/fs_LR.32k.R.shape.gii +6 -0
  46. easysurfvis-0.0.1/src/easysurfvis/data/Template/fs_LR.32k.R.white.surf.gii +1453 -0
  47. easysurfvis-0.0.1/src/easysurfvis/profile_analysis.py +764 -0
  48. easysurfvis-0.0.1/src/easysurfvis/query_server.py +46 -0
  49. easysurfvis-0.0.1/src/easysurfvis/surface_visualization.py +971 -0
  50. easysurfvis-0.0.1/src/easysurfvis.egg-info/PKG-INFO +39 -0
  51. easysurfvis-0.0.1/src/easysurfvis.egg-info/SOURCES.txt +52 -0
  52. easysurfvis-0.0.1/src/easysurfvis.egg-info/dependency_links.txt +1 -0
  53. easysurfvis-0.0.1/src/easysurfvis.egg-info/requires.txt +2 -0
  54. easysurfvis-0.0.1/src/easysurfvis.egg-info/top_level.txt +1 -0
@@ -0,0 +1 @@
1
+ recursive-include src/easysurfvis/data *
@@ -0,0 +1,39 @@
1
+ Metadata-Version: 2.4
2
+ Name: easysurfvis
3
+ Version: 0.0.1
4
+ Summary: visualize surface map easily
5
+ Home-page: https://github.com/SeojinYoon/easy_surf_vis
6
+ Author: seojin
7
+ Author-email: pures1@hanyang.ac.kr
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Operating System :: OS Independent
11
+ Requires-Python: >=3.8
12
+ Description-Content-Type: text/markdown
13
+ Requires-Dist: numpy
14
+ Requires-Dist: pandas
15
+ Dynamic: author
16
+ Dynamic: author-email
17
+ Dynamic: classifier
18
+ Dynamic: description
19
+ Dynamic: description-content-type
20
+ Dynamic: home-page
21
+ Dynamic: requires-dist
22
+ Dynamic: requires-python
23
+ Dynamic: summary
24
+
25
+
26
+ # easysurfvis
27
+
28
+ This library is based on rsatoolbox(https://github.com/rsagroup/rsatoolbox).
29
+
30
+ # Installation
31
+ - pip install easysurfvis
32
+
33
+ # Dependencies
34
+
35
+ - numpy
36
+ - SUITPy
37
+ - matplotlib
38
+
39
+ # License - GPL-3.0 license
@@ -0,0 +1,15 @@
1
+
2
+ # easysurfvis
3
+
4
+ This library is based on rsatoolbox(https://github.com/rsagroup/rsatoolbox).
5
+
6
+ # Installation
7
+ - pip install easysurfvis
8
+
9
+ # Dependencies
10
+
11
+ - numpy
12
+ - SUITPy
13
+ - matplotlib
14
+
15
+ # License - GPL-3.0 license
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,32 @@
1
+ from setuptools import setup, find_packages
2
+
3
+ with open("README.md", "r") as fh:
4
+ long_description = fh.read()
5
+
6
+ setup(
7
+ name = "easysurfvis",
8
+ version = "0.0.1",
9
+ author = "seojin",
10
+ author_email = "pures1@hanyang.ac.kr",
11
+ description = "visualize surface map easily",
12
+ long_description = long_description,
13
+ long_description_content_type="text/markdown",
14
+ url = "https://github.com/SeojinYoon/easy_surf_vis",
15
+
16
+ packages = find_packages(where = "src"),
17
+ package_dir = {"": "src"},
18
+
19
+ include_package_data=True,
20
+
21
+ classifiers = [
22
+ "Programming Language :: Python :: 3",
23
+ "License :: OSI Approved :: MIT License",
24
+ "Operating System :: OS Independent",
25
+ ],
26
+ python_requires='>=3.8',
27
+ install_requires = [
28
+ "numpy",
29
+ "pandas",
30
+ ]
31
+ )
32
+
File without changes
File without changes
@@ -0,0 +1,206 @@
1
+
2
+ # Common Libraries
3
+ import os
4
+ import subprocess
5
+ import numpy as np
6
+ import pandas as pd
7
+
8
+ # Custom Libraries
9
+ if os.getenv("easysurfvis_isRunSource"):
10
+ sys.path.append(os.getenv("easysurfvis_source_home"))
11
+ from cores.general_util import get_multiple_elements_in_list
12
+ else:
13
+ from easysurfvis.cores.general_util import get_multiple_elements_in_list
14
+
15
+ # Functions
16
+ def set_afni_abin(abin_path):
17
+ """
18
+ set abin path
19
+
20
+ :param abin_path: path of afni binnary ex) "/Users/clmn/abin/afni"
21
+ """
22
+ os.environ['PATH'] = os.environ['PATH'] + ":" + abin_path
23
+
24
+ def whereami(x,
25
+ y,
26
+ z,
27
+ coord = "spm",
28
+ atlas = None,
29
+ is_show_command = False,
30
+ is_parsing = True):
31
+ """
32
+ Where is the location?
33
+
34
+ https://afni.nimh.nih.gov/pub/dist/doc/program_help/whereami.html
35
+
36
+ :param x: (int)
37
+ :param y: (int)
38
+ :param z: (int)
39
+ :param coord: (string) spm, dicom
40
+ -meaning spm: is equal to RAS+, lpi coords
41
+ -meaning dicom: is equal to LPS+ rai coords
42
+
43
+ :param atlas: (string)
44
+ -Haskins_Pediatric_Nonlinear_1.0
45
+ -CA_ML_18_MNI
46
+ -and so on...
47
+
48
+ return (pd.DataFrame)
49
+ -row: atlas info
50
+ """
51
+
52
+ if atlas != None:
53
+ command = f"whereami {x} {y} {z} -{coord} -atlas {atlas}"
54
+ else:
55
+ command = f"whereami {x} {y} {z} -{coord}"
56
+
57
+ if is_show_command:
58
+ print(command)
59
+
60
+ # command
61
+ output = subprocess.check_output(command, shell=True)
62
+ output = output.decode('utf-8').split("\n")
63
+
64
+ if is_parsing == False:
65
+ return output
66
+ else:
67
+ atlas_lines = search_stringAcrossTarget(output,
68
+ search_keys = ["Atlas"],
69
+ exclude_keys=["nearby"],
70
+ return_type = "index")
71
+
72
+ search_atlas = []
73
+ search_infos = []
74
+ search_names = []
75
+ for i in range(len(atlas_lines)):
76
+ if len(atlas_lines) == 1:
77
+ start_line_i = atlas_lines[0]
78
+ end_line_i = search_stringAcrossTarget(output,
79
+ search_keys = ["Please", "caution"],
80
+ return_type = "index")[0]
81
+ else:
82
+ if i + 1 < len(atlas_lines):
83
+ # Search region name based on each atlas
84
+ start_line_i = atlas_lines[i]
85
+ end_line_i = atlas_lines[i+1] - 1
86
+ else:
87
+ continue
88
+
89
+ atlas_name = output[start_line_i].split(": ")[0].replace("Atlas ", "")
90
+ selected_output = output[start_line_i:end_line_i]
91
+
92
+ # search result
93
+ search_results = search_stringAcrossTarget(selected_output,
94
+ search_keys = ["Focus", "Within"],
95
+ search_type = "any")
96
+
97
+ for result in search_results:
98
+ sp_result = result.split(":")
99
+
100
+ info = sp_result[0].strip()
101
+ name = sp_result[1].strip()
102
+
103
+ search_atlas.append(atlas_name)
104
+ search_infos.append(info)
105
+ search_names.append(name)
106
+
107
+
108
+ result_df = pd.DataFrame({
109
+ "atlas" : search_atlas,
110
+ "info" : search_infos,
111
+ "name" : search_names,
112
+ })
113
+
114
+ return result_df
115
+
116
+ def search_string(target, search_keys, search_type = "any", exclude_keys = []):
117
+ """
118
+ Search string with keys in target
119
+
120
+ :param target(str): target string
121
+ :param keys(list - str): search key
122
+ :param search_type(str): search type - 'any', 'all', any is 'or' condition, all is 'and' condition
123
+ :param exclude_keys(list - str): exclude key
124
+
125
+ return boolean
126
+ """
127
+ if search_type == "any":
128
+ search_result = any([key in target for key in search_keys])
129
+ elif search_type == "all":
130
+ search_result = all([key in target for key in search_keys])
131
+ elif search_type == "correct":
132
+ assert(len(search_keys) == 1), "please input only one search key"
133
+ search_result = search_keys[0] == target
134
+
135
+ if exclude_keys != None and exclude_keys != []:
136
+ exclude_result = not any([key in target for key in exclude_keys])
137
+
138
+ return search_result and exclude_result
139
+ else:
140
+ return search_result
141
+
142
+ def search_stringAcrossTarget(targets,
143
+ search_keys,
144
+ search_type = "any",
145
+ exclude_keys = [],
146
+ validation_type = None,
147
+ return_type = "string"):
148
+ """
149
+ Search string across target strings
150
+
151
+ :param target(list): target string
152
+ :param keys(str): search key
153
+ :param search_type(str): search type - 'any', 'all', any is or condition, all is and condition
154
+ :param exclude_keys(list - str): exclude key
155
+ :param validation_type(File_validation): kinds of validation checking from search result
156
+ :param return_type(string): 'string' or 'index'
157
+
158
+ return list of searched string
159
+ """
160
+ search_results = [search_string(target = target,
161
+ search_keys = search_keys,
162
+ search_type = search_type,
163
+ exclude_keys = exclude_keys) for target in targets]
164
+ search_flags = np.array(search_results)
165
+ indexes = np.where(search_flags == True)[0]
166
+ result = get_multiple_elements_in_list(targets, indexes)
167
+
168
+ # search validation
169
+ if validation_type == None:
170
+ pass
171
+ else:
172
+ if validation_type.value & File_validation.exist.value != 0:
173
+ # Check the search result existed
174
+ assert len(result) != 0, "Please check to exist file"
175
+ if validation_type.value & File_validation.only.value != 0:
176
+ if len(result) > 1:
177
+ print(result)
178
+ raise Exception("Multiple similar files")
179
+
180
+ # return
181
+ def return_func():
182
+ if return_type == "index":
183
+ return indexes
184
+ elif return_type == "flag":
185
+ return search_flags
186
+ else:
187
+ return result
188
+
189
+ if validation_type == None:
190
+ return return_func()
191
+ else:
192
+ if validation_type.value & File_validation.only.value != 0:
193
+ if return_type == "index":
194
+ return indexes[0]
195
+ elif return_type == "flag":
196
+ return search_flags
197
+ else:
198
+ return result[0]
199
+ else:
200
+ return return_func()
201
+
202
+
203
+
204
+ if __name__ == "__main__":
205
+ set_afni_abin("/Users/clmn/abin/afni")
206
+ whereami(x = 10, y = 10, z = 10)
@@ -0,0 +1,218 @@
1
+
2
+ """
3
+ This file contains the basic source code to visualize graph using matplotlib
4
+ """
5
+ # Common Libraries
6
+ import numpy as np
7
+ import matplotlib.pylab as plt
8
+ from scipy.stats import cumfreq
9
+ from matplotlib.lines import Line2D
10
+ from matplotlib.ticker import FuncFormatter
11
+
12
+ # Custom Libraries
13
+ if os.getenv("easysurfvis_isRunSource"):
14
+ sys.path.append(os.getenv("easysurfvis_source_home"))
15
+ from cores.general_util import search_stringAcrossTarget, find_consecutive_ranges
16
+ else:
17
+ from easysurfvis.cores.general_util import search_stringAcrossTarget, find_consecutive_ranges
18
+
19
+ # Functions
20
+ def draw_title(axis, title_info = {}):
21
+ """
22
+ Draw title in the axis
23
+
24
+ :param title_info(dictionary):
25
+ -k, title(string): title
26
+ -k, title_weight(string): weight of font
27
+ -k, title_size(string): size of title
28
+ -k, title_y_pos(string): y pos of title
29
+ """
30
+ title = title_info.get("title", "")
31
+ title_weight = title_info.get("title_weight", "bold")
32
+ title_size = title_info.get("title_size", 20)
33
+ title_y_pos = title_info.get("title_y_pos", 1.0)
34
+
35
+ axis.set_title(title,
36
+ fontweight = title_weight,
37
+ size = title_size,
38
+ y = title_y_pos)
39
+
40
+ def draw_label(axis, label_info = {}):
41
+ """
42
+ Draw label in the axis
43
+
44
+ :param label_info(dictionary):
45
+ -k, color(string): label color
46
+ -k, x_label(string): x label text
47
+ -k, y_label(string): y label text
48
+ -k, x_weight(string): x label weight
49
+ -k, y_weight(string): y label weight
50
+ -k, x_size(float): x label size
51
+ -k, y_size(float): y label size
52
+ """
53
+ color = label_info.get("color", "black")
54
+
55
+ x_label = label_info.get("x_label", "")
56
+ y_label = label_info.get("y_label", "")
57
+
58
+ x_weight = label_info.get("x_weight", "normal")
59
+ y_weight = label_info.get("y_weight", "normal")
60
+
61
+ x_label_size = label_info.get("x_size", 16)
62
+ y_label_size = label_info.get("y_size", 16)
63
+
64
+ x_label_pad = label_info.get("x_label_pad", 10)
65
+ y_label_pad = label_info.get("y_label_pad", 10)
66
+
67
+ axis.set_xlabel(x_label,
68
+ color = color,
69
+ weight = x_weight,
70
+ size = x_label_size,
71
+ labelpad = x_label_pad)
72
+
73
+ axis.set_ylabel(y_label,
74
+ color = color,
75
+ weight = y_weight,
76
+ size = y_label_size,
77
+ labelpad = y_label_pad)
78
+
79
+ def draw_ticks(axis, tick_info = {}):
80
+ """
81
+ Draw ticks in the axis
82
+
83
+ :param tick_info(dictionary): tick style configuration
84
+ -k, x_data(list): x tick positions ex) [1,2,3]
85
+ -k, x_names(list): x tick text ex) ["a", "b", "c"]
86
+ -k, x_tick_weight(string): x tick weight
87
+ -k, x_tick_size(float): x tick size
88
+ -k, x_tick_rotation(int): x tick rotation
89
+
90
+ -k, y_data(list): y tick positions ex) [1,2,3]
91
+ -k, y_names(list): y tick text ex) ["a", "b", "c"]
92
+ -k, y_tick_precision(float): Number of decimal places to display on y-axis ticks
93
+ -k, y_tick_weight(string): y tick weight
94
+ -k, y_tick_size(float): y tick size
95
+ -k, y_tick_rotation(int): y tick rotation
96
+ -k, y_divided(int): the number of division for showing y-tick
97
+ -k, y_need_tick(list): the y-tick which must to show
98
+ """
99
+ x_data = tick_info.get("x_data", [])
100
+ x_names = tick_info.get("x_names", [])
101
+
102
+ x_tick_weight = tick_info.get("x_tick_weight", "normal")
103
+ x_tick_size = tick_info.get("x_tick_size", 14)
104
+ x_tick_rotation = tick_info.get("x_tick_rotation", 90)
105
+ x_tick_viewType = tick_info.get("x_tick_viewType", "remove_duplication")
106
+
107
+ y_data = tick_info.get("y_data", [])
108
+ y_names = tick_info.get("y_names", [])
109
+
110
+ y_tick_weight = tick_info.get("y_tick_weight", "normal")
111
+ y_tick_size = tick_info.get("y_tick_size", 14)
112
+ y_tick_rotation = tick_info.get("y_tick_rotation", 0)
113
+ y_tick_precision = tick_info.get("y_tick_precision", None)
114
+
115
+ # X
116
+ x_data = np.array(x_data)
117
+ x_names = np.array(x_names)
118
+
119
+ if x_tick_viewType == "remove_duplication":
120
+ x_tick_duplication = np.array([int((start + end) / 2) for start, end in find_consecutive_ranges(x_names)], dtype = int)
121
+ x_tick_data = np.array([(x_data[start] + x_data[end]) / 2 for start, end in find_consecutive_ranges(x_names)])
122
+
123
+ if len(x_tick_duplication) > 0:
124
+ x_names = x_names[x_tick_duplication]
125
+ x_data = x_tick_data
126
+
127
+ axis.set_xticks(x_data,
128
+ x_names,
129
+ rotation = x_tick_rotation,
130
+ weight = x_tick_weight,
131
+ size = x_tick_size)
132
+
133
+ # Y
134
+ axis.set_yticks(y_data,
135
+ y_names,
136
+ rotation = y_tick_rotation,
137
+ weight = y_tick_weight,
138
+ size = y_tick_size)
139
+ if y_tick_precision is not None:
140
+ axis.yaxis.set_major_formatter(FuncFormatter(lambda y, _: f"{y:.{y_tick_precision}f}"))
141
+
142
+ def draw_spine(axis, spine_info = {}):
143
+ """
144
+ Draw spine in the axis
145
+
146
+ :param spine_info(dictionary):
147
+ -k, spine_linewidth(float): spine line width ex) 2
148
+ -k, spine_color(string): spine line color ex) "black"
149
+ -k, invisibles(list): invisible informations ex) ["right", "top"]
150
+ """
151
+ spine_line_width = spine_info.get("spine_linewidth", 1)
152
+ spine_color = spine_info.get("spine_color", "black")
153
+ invisibles = spine_info.get("invisibles", ["right", "top"])
154
+
155
+ all_spines = ["bottom", "top", "left", "right"]
156
+ for invisible in invisibles:
157
+ axis.spines[invisible].set_visible(False)
158
+ all_spines.remove(invisible)
159
+
160
+ for ax_name in all_spines:
161
+ axis.spines[ax_name].set_linewidth(spine_line_width)
162
+ axis.spines[ax_name].set_linewidth(spine_line_width)
163
+ axis.spines[ax_name].set_color(spine_color)
164
+
165
+ def make_colorbar(vmin,
166
+ vmax,
167
+ figsize = (2, 6),
168
+ n_inner_ticks = 3,
169
+ cmap = "jet",
170
+ tick_precision = 4,
171
+ orientation = "horizontal",
172
+ fontsize = 12):
173
+ """
174
+ Creates a customizable colorbar using matplotlib.
175
+
176
+
177
+ :param vmin (float): The minimum value for the colorbar.
178
+ :param vmax (float): The maximum value for the colorbar.
179
+ :param figsize (tuple): The size of the figure (width, height). Defaults to (2, 6).
180
+ :param n_div (int): Number of divisions (ticks) on the colorbar. Defaults to 4.
181
+ :param cmap (str): Colormap to use for the colorbar. Defaults to "jet".
182
+ :param tick_precision (int): Number of decimal places to display on the tick labels. Defaults to 4.
183
+ :param orientation (str): Orientation of the colorbar, either "horizontal" or "vertical". Defaults to "horizontal".
184
+
185
+ return (tuple): A tuple containing the matplotlib figure and axis objects.
186
+ """
187
+ n_div = n_inner_ticks + 1
188
+
189
+ interval = (vmax - vmin) / n_div
190
+ ticks = np.linspace(vmin, vmax, n_div + 1)
191
+
192
+ # Create the figure and axis for the colorbar
193
+ fig = plt.figure(figsize = figsize)
194
+
195
+ if orientation == "vertical":
196
+ axis = fig.add_axes([0.05, 0.05, 0.15, 0.9]) # [left, bottom, width, height]
197
+ else:
198
+ axis = fig.add_axes([0.1, 0.5, 0.8, 0.3]) # [left, bottom, width, height]
199
+
200
+ # Create the colorbar
201
+ cmap = plt.get_cmap(cmap)
202
+ norm = plt.Normalize(vmin = vmin, vmax = vmax)
203
+ cbar = fig.colorbar(plt.cm.ScalarMappable(norm=norm, cmap=cmap), cax=axis, orientation=orientation)
204
+
205
+ # Set the ticks and labels
206
+ if orientation == "vertical":
207
+ axis.set_yticks(ticks)
208
+ axis.set_yticklabels([f"{tick:.{tick_precision}f}" for tick in ticks], fontsize = fontsize)
209
+ axis.get_xaxis().set_visible(False)
210
+ else:
211
+ axis.set_xticks(ticks)
212
+ axis.set_xticklabels([f"{tick:.{tick_precision}f}" for tick in ticks], fontsize = fontsize)
213
+ axis.get_yaxis().set_visible(False)
214
+
215
+ return fig, axis, ticks
216
+
217
+ if __name__=="__main__":
218
+ pass
@@ -0,0 +1,150 @@
1
+
2
+ # Common Libraries
3
+ import re
4
+ import numpy as np
5
+ from enum import Enum
6
+
7
+ # Classes
8
+ class File_validation(Enum):
9
+ exist = 1 << 0
10
+ only = 1 << 1
11
+
12
+ exist_only = exist | only
13
+
14
+ # Functions
15
+ def search_string(target, search_keys, search_type = "any", exclude_keys = []):
16
+ """
17
+ Search string with keys in target
18
+
19
+ :param target(str): target string
20
+ :param keys(list - str): search key
21
+ :param search_type(str): search type - 'any', 'all', any is 'or' condition, all is 'and' condition
22
+ :param exclude_keys(list - str): exclude key
23
+
24
+ return boolean
25
+ """
26
+ if search_type == "any":
27
+ search_result = any([key in target for key in search_keys])
28
+ elif search_type == "all":
29
+ search_result = all([key in target for key in search_keys])
30
+ elif search_type == "correct":
31
+ assert(len(search_keys) == 1), "please input only one search key"
32
+ search_result = search_keys[0] == target
33
+
34
+ if exclude_keys != None and exclude_keys != []:
35
+ exclude_result = not any([key in target for key in exclude_keys])
36
+
37
+ return search_result and exclude_result
38
+ else:
39
+ return search_result
40
+
41
+ def search_stringAcrossTarget(targets,
42
+ search_keys,
43
+ search_type = "any",
44
+ exclude_keys = [],
45
+ validation_type = None,
46
+ return_type = "string"):
47
+ """
48
+ Search string across target strings
49
+
50
+ :param target(list): target string
51
+ :param keys(str): search key
52
+ :param search_type(str): search type - 'any', 'all', any is or condition, all is and condition
53
+ :param exclude_keys(list - str): exclude key
54
+ :param validation_type(File_validation): kinds of validation checking from search result
55
+ :param return_type(string): 'string' or 'index'
56
+
57
+ return list of searched string
58
+ """
59
+ search_results = [search_string(target = target,
60
+ search_keys = search_keys,
61
+ search_type = search_type,
62
+ exclude_keys = exclude_keys) for target in targets]
63
+ search_flags = np.array(search_results)
64
+ indexes = np.where(search_flags == True)[0]
65
+ result = list(np.array(targets)[indexes])
66
+
67
+ # search validation
68
+ if validation_type is not None:
69
+ if validation_type.value & File_validation.exist.value != 0: # check existence
70
+ assert len(result) != 0, "Please check to exist file"
71
+ if validation_type.value & File_validation.only.value != 0: # check the number of files
72
+ if len(result) > 1:
73
+ raise Exception("Multiple similar files")
74
+
75
+ # return
76
+ if return_type == "index":
77
+ out = indexes
78
+ elif return_type == "flag":
79
+ out = search_flags
80
+ else:
81
+ out = results
82
+
83
+ # only 옵션이면 scalar로 축약
84
+ if (validation_type is not None
85
+ and (validation_type.value & File_validation.only.value)
86
+ and return_type != "flag"
87
+ ):
88
+ return out[0]
89
+
90
+ return out
91
+
92
+ def find_consecutive_ranges(data):
93
+ """
94
+ Find index ranges of consecutive identical values
95
+
96
+ :param data: (list)
97
+
98
+ return [(start index, stop index)]
99
+ """
100
+ if not isinstance(data, list):
101
+ data = list(data)
102
+
103
+ if not data:
104
+ return []
105
+
106
+ result = []
107
+ start = 0
108
+
109
+ for i in range(1, len(data)):
110
+ if data[i] != data[i - 1]:
111
+ result.append((start, i - 1))
112
+ start = i
113
+
114
+ result.append((start, len(data) - 1))
115
+ return result
116
+
117
+ def get_multiple_elements_in_list(in_list, in_indices):
118
+ """
119
+ Get multiple element using indexes
120
+
121
+ :param in_list: data(list)
122
+ :param in_indices: indexes to be extracted from in_list
123
+ """
124
+ return [in_list[i] for i in in_indices]
125
+
126
+ def get_unique_values(data):
127
+ """
128
+ Get unique values from data
129
+
130
+ :param data: (list)
131
+
132
+ return (list)
133
+ """
134
+
135
+ unique_values = []
136
+ for e in data:
137
+ if e in unique_values:
138
+ pass
139
+ else:
140
+ unique_values.append(e)
141
+ return unique_values
142
+
143
+ # Examples
144
+ if __name__ == "__main__":
145
+ a_string = "A string is more than its parts!"
146
+ matches = ["more", "d"]
147
+ search_string(a_string, matches, search_type = "all")
148
+
149
+ search_stringAcrossTarget(targets = ["1","2","3"], search_keys=["1"], return_type = "flag")
150
+ find_consecutive_ranges([1,1,2,3])