idmtools 0.0.0.dev0__py3-none-any.whl → 0.0.2__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.
- idmtools/__init__.py +27 -8
- idmtools/analysis/__init__.py +5 -0
- idmtools/analysis/add_analyzer.py +89 -0
- idmtools/analysis/analyze_manager.py +490 -0
- idmtools/analysis/csv_analyzer.py +103 -0
- idmtools/analysis/download_analyzer.py +96 -0
- idmtools/analysis/map_worker_entry.py +100 -0
- idmtools/analysis/platform_analysis_bootstrap.py +94 -0
- idmtools/analysis/platform_anaylsis.py +291 -0
- idmtools/analysis/tags_analyzer.py +93 -0
- idmtools/assets/__init__.py +9 -0
- idmtools/assets/asset.py +453 -0
- idmtools/assets/asset_collection.py +514 -0
- idmtools/assets/content_handlers.py +19 -0
- idmtools/assets/errors.py +23 -0
- idmtools/assets/file_list.py +191 -0
- idmtools/builders/__init__.py +11 -0
- idmtools/builders/arm_simulation_builder.py +152 -0
- idmtools/builders/csv_simulation_builder.py +76 -0
- idmtools/builders/simulation_builder.py +348 -0
- idmtools/builders/sweep_arm.py +109 -0
- idmtools/builders/yaml_simulation_builder.py +82 -0
- idmtools/config/__init__.py +7 -0
- idmtools/config/idm_config_parser.py +486 -0
- idmtools/core/__init__.py +10 -0
- idmtools/core/cache_enabled.py +114 -0
- idmtools/core/context.py +68 -0
- idmtools/core/docker_task.py +207 -0
- idmtools/core/enums.py +51 -0
- idmtools/core/exceptions.py +91 -0
- idmtools/core/experiment_factory.py +71 -0
- idmtools/core/id_file.py +70 -0
- idmtools/core/interfaces/__init__.py +5 -0
- idmtools/core/interfaces/entity_container.py +64 -0
- idmtools/core/interfaces/iassets_enabled.py +58 -0
- idmtools/core/interfaces/ientity.py +331 -0
- idmtools/core/interfaces/iitem.py +206 -0
- idmtools/core/interfaces/imetadata_operations.py +89 -0
- idmtools/core/interfaces/inamed_entity.py +17 -0
- idmtools/core/interfaces/irunnable_entity.py +159 -0
- idmtools/core/logging.py +387 -0
- idmtools/core/platform_factory.py +316 -0
- idmtools/core/system_information.py +104 -0
- idmtools/core/task_factory.py +145 -0
- idmtools/entities/__init__.py +10 -0
- idmtools/entities/command_line.py +229 -0
- idmtools/entities/command_task.py +155 -0
- idmtools/entities/experiment.py +787 -0
- idmtools/entities/generic_workitem.py +43 -0
- idmtools/entities/ianalyzer.py +163 -0
- idmtools/entities/iplatform.py +1106 -0
- idmtools/entities/iplatform_default.py +39 -0
- idmtools/entities/iplatform_ops/__init__.py +5 -0
- idmtools/entities/iplatform_ops/iplatform_asset_collection_operations.py +148 -0
- idmtools/entities/iplatform_ops/iplatform_experiment_operations.py +415 -0
- idmtools/entities/iplatform_ops/iplatform_simulation_operations.py +315 -0
- idmtools/entities/iplatform_ops/iplatform_suite_operations.py +322 -0
- idmtools/entities/iplatform_ops/iplatform_workflowitem_operations.py +301 -0
- idmtools/entities/iplatform_ops/utils.py +185 -0
- idmtools/entities/itask.py +316 -0
- idmtools/entities/iworkflow_item.py +167 -0
- idmtools/entities/platform_requirements.py +20 -0
- idmtools/entities/relation_type.py +14 -0
- idmtools/entities/simulation.py +255 -0
- idmtools/entities/suite.py +188 -0
- idmtools/entities/task_proxy.py +37 -0
- idmtools/entities/templated_simulation.py +325 -0
- idmtools/frozen/frozen_dict.py +71 -0
- idmtools/frozen/frozen_list.py +66 -0
- idmtools/frozen/frozen_set.py +86 -0
- idmtools/frozen/frozen_tuple.py +18 -0
- idmtools/frozen/frozen_utils.py +179 -0
- idmtools/frozen/ifrozen.py +66 -0
- idmtools/plugins/__init__.py +5 -0
- idmtools/plugins/git_commit.py +117 -0
- idmtools/registry/__init__.py +4 -0
- idmtools/registry/experiment_specification.py +105 -0
- idmtools/registry/functions.py +28 -0
- idmtools/registry/hook_specs.py +132 -0
- idmtools/registry/master_plugin_registry.py +51 -0
- idmtools/registry/platform_specification.py +138 -0
- idmtools/registry/plugin_specification.py +129 -0
- idmtools/registry/task_specification.py +104 -0
- idmtools/registry/utils.py +119 -0
- idmtools/services/__init__.py +5 -0
- idmtools/services/ipersistance_service.py +135 -0
- idmtools/services/platforms.py +13 -0
- idmtools/utils/__init__.py +5 -0
- idmtools/utils/caller.py +24 -0
- idmtools/utils/collections.py +246 -0
- idmtools/utils/command_line.py +45 -0
- idmtools/utils/decorators.py +300 -0
- idmtools/utils/display/__init__.py +22 -0
- idmtools/utils/display/displays.py +181 -0
- idmtools/utils/display/settings.py +25 -0
- idmtools/utils/dropbox_location.py +30 -0
- idmtools/utils/entities.py +127 -0
- idmtools/utils/file.py +72 -0
- idmtools/utils/file_parser.py +151 -0
- idmtools/utils/filter_simulations.py +182 -0
- idmtools/utils/filters/__init__.py +5 -0
- idmtools/utils/filters/asset_filters.py +88 -0
- idmtools/utils/general.py +286 -0
- idmtools/utils/gitrepo.py +336 -0
- idmtools/utils/hashing.py +239 -0
- idmtools/utils/info.py +124 -0
- idmtools/utils/json.py +82 -0
- idmtools/utils/language.py +107 -0
- idmtools/utils/local_os.py +40 -0
- idmtools/utils/time.py +22 -0
- idmtools-0.0.2.dist-info/METADATA +120 -0
- idmtools-0.0.2.dist-info/RECORD +116 -0
- idmtools-0.0.2.dist-info/entry_points.txt +9 -0
- idmtools-0.0.2.dist-info/licenses/LICENSE.TXT +3 -0
- idmtools-0.0.0.dev0.dist-info/METADATA +0 -41
- idmtools-0.0.0.dev0.dist-info/RECORD +0 -5
- {idmtools-0.0.0.dev0.dist-info → idmtools-0.0.2.dist-info}/WHEEL +0 -0
- {idmtools-0.0.0.dev0.dist-info → idmtools-0.0.2.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
"""
|
|
2
|
+
idmtools FileList classes.
|
|
3
|
+
|
|
4
|
+
Copyright 2021, Bill & Melinda Gates Foundation. All rights reserved.
|
|
5
|
+
"""
|
|
6
|
+
from typing import List
|
|
7
|
+
import os
|
|
8
|
+
import re
|
|
9
|
+
from idmtools.assets import Asset, AssetCollection
|
|
10
|
+
from idmtools.utils.local_os import LocalOS
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class FileList:
|
|
14
|
+
"""
|
|
15
|
+
Special utility class to help handling user files.
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
def __init__(self, root=None, files_in_root=None, recursive=False, ignore_missing=False, relative_path=None,
|
|
19
|
+
max_depth=3):
|
|
20
|
+
"""
|
|
21
|
+
Represents a set of files that are specified RELATIVE to root.
|
|
22
|
+
|
|
23
|
+
e.g. /a/b/c.json could be : root: '/a' files_in_root: ['b/c.json']
|
|
24
|
+
:param root: The dir all files_in_root are relative to.
|
|
25
|
+
:param files_in_root: The listed files
|
|
26
|
+
"""
|
|
27
|
+
self.files: List[Asset] = []
|
|
28
|
+
self.ignore_missing = ignore_missing
|
|
29
|
+
self.max_depth = max_depth
|
|
30
|
+
|
|
31
|
+
# Make sure we have correct separator
|
|
32
|
+
# os.path.normpath(f) would be best but is not working the same way on UNIX systems
|
|
33
|
+
if files_in_root is not None:
|
|
34
|
+
if LocalOS.is_window():
|
|
35
|
+
files_in_root = [os.path.normpath(f) for f in files_in_root]
|
|
36
|
+
else:
|
|
37
|
+
files_in_root = [re.sub(r"[\\/]", os.sep, os.path.normpath(f)) for f in files_in_root]
|
|
38
|
+
|
|
39
|
+
if root:
|
|
40
|
+
self.add_path(path=root, files_in_dir=files_in_root, recursive=recursive, relative_path=relative_path)
|
|
41
|
+
|
|
42
|
+
def add_asset_file(self, af):
|
|
43
|
+
"""
|
|
44
|
+
Method used to add asset file.
|
|
45
|
+
|
|
46
|
+
Args:
|
|
47
|
+
af: asset file to add
|
|
48
|
+
|
|
49
|
+
Returns: None
|
|
50
|
+
"""
|
|
51
|
+
self.files.append(af)
|
|
52
|
+
|
|
53
|
+
def add_file(self, path, relative_path=''):
|
|
54
|
+
"""
|
|
55
|
+
Method used to add a file.
|
|
56
|
+
|
|
57
|
+
Args:
|
|
58
|
+
path: file oath
|
|
59
|
+
relative_path: file relative path
|
|
60
|
+
|
|
61
|
+
Returns: None
|
|
62
|
+
"""
|
|
63
|
+
# If already present -> bypass
|
|
64
|
+
for f in self.files:
|
|
65
|
+
if f.absolute_path and os.path.abspath(f.absolute_path) == os.path.abspath(path):
|
|
66
|
+
return
|
|
67
|
+
|
|
68
|
+
if os.path.isdir(path):
|
|
69
|
+
raise ValueError("%s is a directory. add_file is expecting a file!" % path)
|
|
70
|
+
|
|
71
|
+
absolute_path = os.path.abspath(path)
|
|
72
|
+
file_name = os.path.basename(path)
|
|
73
|
+
try:
|
|
74
|
+
af = Asset(filename=file_name, relative_path=relative_path, absolute_path=absolute_path)
|
|
75
|
+
self.add_asset_file(af)
|
|
76
|
+
except Exception as e:
|
|
77
|
+
if not self.ignore_missing:
|
|
78
|
+
raise e
|
|
79
|
+
|
|
80
|
+
def add_path(self, path, files_in_dir=None, relative_path=None, recursive=False):
|
|
81
|
+
"""
|
|
82
|
+
Add a path to the file list.
|
|
83
|
+
|
|
84
|
+
Args:
|
|
85
|
+
path: The path to add (needs to be a dictionary)
|
|
86
|
+
files_in_dir: If we want to only retrieve certain files in this path
|
|
87
|
+
relative_path: relative_path: The relative path prefixed to each added files
|
|
88
|
+
recursive: Do we want to browse recursively
|
|
89
|
+
|
|
90
|
+
Returns: None
|
|
91
|
+
|
|
92
|
+
"""
|
|
93
|
+
# Little safety
|
|
94
|
+
if not os.path.isdir(path) and not path.startswith('\\\\'):
|
|
95
|
+
raise RuntimeError("add_path() requires a directory. '%s' is not." % path)
|
|
96
|
+
|
|
97
|
+
if not recursive:
|
|
98
|
+
if files_in_dir is None:
|
|
99
|
+
files_in_dir = [f for f in os.listdir(path) if os.path.isfile(os.path.join(path, f))]
|
|
100
|
+
|
|
101
|
+
for file_name in files_in_dir:
|
|
102
|
+
file_path = os.path.join(path, file_name)
|
|
103
|
+
f_relative_path = os.path.normpath(
|
|
104
|
+
file_path.replace(path, '').strip(os.sep).replace(os.path.basename(file_path), ''))
|
|
105
|
+
if relative_path is not None:
|
|
106
|
+
f_relative_path = os.path.join(relative_path, f_relative_path)
|
|
107
|
+
self.add_file(file_path, relative_path=f_relative_path)
|
|
108
|
+
|
|
109
|
+
else:
|
|
110
|
+
# Walk through the path
|
|
111
|
+
for root, _subdirs, files in os.walk(path):
|
|
112
|
+
# Little safety to not go too deep
|
|
113
|
+
depth = root[len(path) + len(os.path.sep):].count(os.path.sep)
|
|
114
|
+
if depth > self.max_depth:
|
|
115
|
+
continue
|
|
116
|
+
|
|
117
|
+
# Add the files in the current dir
|
|
118
|
+
for f in files:
|
|
119
|
+
# Find the file relative path compared to the root folder
|
|
120
|
+
# If the relative_path is . -> change it into ''
|
|
121
|
+
f_relative_path = os.path.normpath(os.path.relpath(root, path))
|
|
122
|
+
if f_relative_path == '.':
|
|
123
|
+
f_relative_path = ''
|
|
124
|
+
|
|
125
|
+
# if files_in_dir specified -> skip the ones not included
|
|
126
|
+
if files_in_dir is not None and f not in files_in_dir and os.path.join(f_relative_path,
|
|
127
|
+
f) not in files_in_dir:
|
|
128
|
+
continue
|
|
129
|
+
|
|
130
|
+
# if we want to force a relative path -> force it
|
|
131
|
+
if relative_path is not None:
|
|
132
|
+
f_relative_path = os.path.join(relative_path, f_relative_path)
|
|
133
|
+
|
|
134
|
+
# add the file
|
|
135
|
+
self.add_file(os.path.join(root, f), relative_path=f_relative_path)
|
|
136
|
+
|
|
137
|
+
def to_asset_collection(self) -> AssetCollection:
|
|
138
|
+
"""
|
|
139
|
+
Convert a file list to an asset collection.
|
|
140
|
+
|
|
141
|
+
Returns:
|
|
142
|
+
AssetCollection version of filelist
|
|
143
|
+
"""
|
|
144
|
+
ac = AssetCollection()
|
|
145
|
+
ac.assets = self.files
|
|
146
|
+
return ac
|
|
147
|
+
|
|
148
|
+
@staticmethod
|
|
149
|
+
def from_asset_collection(asset_collection: AssetCollection) -> 'FileList':
|
|
150
|
+
"""
|
|
151
|
+
Create a FileList from a AssetCollection.
|
|
152
|
+
|
|
153
|
+
Args:
|
|
154
|
+
asset_collection: AssetCollection to convert.
|
|
155
|
+
|
|
156
|
+
Returns:
|
|
157
|
+
FileList version of AssetCollection
|
|
158
|
+
"""
|
|
159
|
+
fl = FileList()
|
|
160
|
+
fl.files = [asset_collection.assets]
|
|
161
|
+
return fl
|
|
162
|
+
|
|
163
|
+
def __len__(self):
|
|
164
|
+
"""
|
|
165
|
+
Length of FileList.
|
|
166
|
+
|
|
167
|
+
Returns:
|
|
168
|
+
Length
|
|
169
|
+
"""
|
|
170
|
+
return len(self.files)
|
|
171
|
+
|
|
172
|
+
def __iter__(self):
|
|
173
|
+
"""
|
|
174
|
+
Iterator. Basically we proxy self.files.
|
|
175
|
+
|
|
176
|
+
Returns:
|
|
177
|
+
Iterator
|
|
178
|
+
"""
|
|
179
|
+
return self.files.__iter__()
|
|
180
|
+
|
|
181
|
+
def __getitem__(self, item):
|
|
182
|
+
"""
|
|
183
|
+
Get file.
|
|
184
|
+
|
|
185
|
+
Args:
|
|
186
|
+
item: Item
|
|
187
|
+
|
|
188
|
+
Returns:
|
|
189
|
+
Item
|
|
190
|
+
"""
|
|
191
|
+
return self.files.__getitem__(item)
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"""
|
|
2
|
+
idmtools builders package.
|
|
3
|
+
|
|
4
|
+
Copyright 2021, Bill & Melinda Gates Foundation. All rights reserved.
|
|
5
|
+
"""
|
|
6
|
+
# flake8: noqa F821
|
|
7
|
+
from idmtools.builders.simulation_builder import SimulationBuilder
|
|
8
|
+
from idmtools.builders.sweep_arm import SweepArm, ArmType, TSweepFunction
|
|
9
|
+
from idmtools.builders.arm_simulation_builder import ArmSimulationBuilder
|
|
10
|
+
from idmtools.builders.csv_simulation_builder import CsvExperimentBuilder
|
|
11
|
+
from idmtools.builders.yaml_simulation_builder import YamlSimulationBuilder
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
"""
|
|
2
|
+
idmtools arm builder definition.
|
|
3
|
+
|
|
4
|
+
Copyright 2021, Bill & Melinda Gates Foundation. All rights reserved.
|
|
5
|
+
"""
|
|
6
|
+
from idmtools.builders import SweepArm
|
|
7
|
+
from itertools import tee
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class ArmSimulationBuilder:
|
|
11
|
+
"""
|
|
12
|
+
Class that represents an experiment builder.
|
|
13
|
+
|
|
14
|
+
This particular sweep builder build sweeps in "ARMS". This is particular useful in situations where you want to sweep
|
|
15
|
+
parameters that have branches of parameters. For Example, let's say we have a model with the following parameters:
|
|
16
|
+
* population
|
|
17
|
+
* susceptible
|
|
18
|
+
* recovered
|
|
19
|
+
* enable_births
|
|
20
|
+
* birth_rate
|
|
21
|
+
|
|
22
|
+
Enable births controls an optional feature that is controlled by the birth_rate parameter. If we want to sweep a set
|
|
23
|
+
of parameters on population, susceptible with enabled_births set to off but also want to sweep the birth_rate
|
|
24
|
+
we could do that like so
|
|
25
|
+
|
|
26
|
+
.. literalinclude:: ../../examples/builders/print_builder_values.py
|
|
27
|
+
|
|
28
|
+
This would result in the output
|
|
29
|
+
|
|
30
|
+
.. list-table:: Arm Example Values
|
|
31
|
+
:widths: 25 25 25 25
|
|
32
|
+
:header-rows: 1
|
|
33
|
+
|
|
34
|
+
* - enable_births
|
|
35
|
+
- population
|
|
36
|
+
- susceptible
|
|
37
|
+
- birth_rate
|
|
38
|
+
* - False
|
|
39
|
+
- 500
|
|
40
|
+
- 0.5
|
|
41
|
+
-
|
|
42
|
+
* - False
|
|
43
|
+
- 500
|
|
44
|
+
- 0.9
|
|
45
|
+
-
|
|
46
|
+
* - False
|
|
47
|
+
- 1000
|
|
48
|
+
- 0.5
|
|
49
|
+
-
|
|
50
|
+
* - False
|
|
51
|
+
- 1000
|
|
52
|
+
- 0.9
|
|
53
|
+
-
|
|
54
|
+
* - True
|
|
55
|
+
- 500
|
|
56
|
+
- 0.5
|
|
57
|
+
- 0.01
|
|
58
|
+
* - True
|
|
59
|
+
- 500
|
|
60
|
+
- 0.5
|
|
61
|
+
- 0.1
|
|
62
|
+
* - True
|
|
63
|
+
- 500
|
|
64
|
+
- 0.9
|
|
65
|
+
- 0.01
|
|
66
|
+
* - True
|
|
67
|
+
- 500
|
|
68
|
+
- 0.9
|
|
69
|
+
- 0.1
|
|
70
|
+
* - True
|
|
71
|
+
- 1000
|
|
72
|
+
- 0.5
|
|
73
|
+
- 0.01
|
|
74
|
+
* - True
|
|
75
|
+
- 1000
|
|
76
|
+
- 0.5
|
|
77
|
+
- 0.1
|
|
78
|
+
* - True
|
|
79
|
+
- 1000
|
|
80
|
+
- 0.9
|
|
81
|
+
- 0.01
|
|
82
|
+
* - True
|
|
83
|
+
- 1000
|
|
84
|
+
- 0.9
|
|
85
|
+
- 0.1
|
|
86
|
+
|
|
87
|
+
Examples:
|
|
88
|
+
.. literalinclude:: ../../examples/builders/arm_experiment_builder_python.py
|
|
89
|
+
"""
|
|
90
|
+
|
|
91
|
+
def __init__(self):
|
|
92
|
+
"""
|
|
93
|
+
Constructor.
|
|
94
|
+
"""
|
|
95
|
+
super().__init__()
|
|
96
|
+
self.arms = []
|
|
97
|
+
|
|
98
|
+
@property
|
|
99
|
+
def count(self):
|
|
100
|
+
"""
|
|
101
|
+
Total simulations to be built by builder.
|
|
102
|
+
Returns:
|
|
103
|
+
arm count
|
|
104
|
+
"""
|
|
105
|
+
return sum([arm.count for arm in self.arms])
|
|
106
|
+
|
|
107
|
+
def add_arm(self, arm):
|
|
108
|
+
"""
|
|
109
|
+
Add arm sweep definition.
|
|
110
|
+
Args:
|
|
111
|
+
arm: Arm to add
|
|
112
|
+
Returns:
|
|
113
|
+
None
|
|
114
|
+
"""
|
|
115
|
+
# create a new arm
|
|
116
|
+
arm_new = SweepArm(type=arm.type)
|
|
117
|
+
old_sweeps = []
|
|
118
|
+
new_sweeps = []
|
|
119
|
+
# make two copies of each sweep
|
|
120
|
+
for sweep in arm.sweeps:
|
|
121
|
+
old_sw, new_sw = tee(sweep, 2)
|
|
122
|
+
old_sweeps.append(old_sw)
|
|
123
|
+
new_sweeps.append(new_sw)
|
|
124
|
+
|
|
125
|
+
# keep original sweeps
|
|
126
|
+
arm.sweeps = old_sweeps
|
|
127
|
+
# copy sweeps to new arm
|
|
128
|
+
arm_new.sweeps = new_sweeps
|
|
129
|
+
# update count for new arm
|
|
130
|
+
arm_new.count = arm.count
|
|
131
|
+
|
|
132
|
+
# add new arm to arms
|
|
133
|
+
self.arms.append(arm_new)
|
|
134
|
+
# update sweep functions for new arm
|
|
135
|
+
arm_new._update_sweep_functions()
|
|
136
|
+
|
|
137
|
+
def __iter__(self):
|
|
138
|
+
"""
|
|
139
|
+
Iterator for the simulations defined.
|
|
140
|
+
Returns:
|
|
141
|
+
Iterator
|
|
142
|
+
"""
|
|
143
|
+
for arm in self.arms:
|
|
144
|
+
yield from arm.functions
|
|
145
|
+
|
|
146
|
+
def __len__(self):
|
|
147
|
+
"""
|
|
148
|
+
Total simulations to be built by builder.
|
|
149
|
+
Returns:
|
|
150
|
+
Simulation count
|
|
151
|
+
"""
|
|
152
|
+
return self.count
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"""
|
|
2
|
+
idmtools CsvExperimentBuilder definition.
|
|
3
|
+
|
|
4
|
+
Copyright 2021, Bill & Melinda Gates Foundation. All rights reserved.
|
|
5
|
+
"""
|
|
6
|
+
import pandas as pd
|
|
7
|
+
import numpy as np
|
|
8
|
+
from numbers import Number
|
|
9
|
+
from idmtools.builders import ArmSimulationBuilder, SweepArm
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class CsvExperimentBuilder(ArmSimulationBuilder):
|
|
13
|
+
"""
|
|
14
|
+
Class that represents an experiment builder.
|
|
15
|
+
Examples:
|
|
16
|
+
.. literalinclude:: ../../examples/builders/csv_builder_python.py
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
def add_sweeps_from_file(self, file_path, func_map=None, type_map=None, sep=","):
|
|
20
|
+
"""
|
|
21
|
+
Create sweeps from a CSV file.
|
|
22
|
+
Args:
|
|
23
|
+
file_path: Path to file
|
|
24
|
+
func_map: Function map
|
|
25
|
+
type_map: Type
|
|
26
|
+
sep: CSV Seperator
|
|
27
|
+
Returns:
|
|
28
|
+
None
|
|
29
|
+
"""
|
|
30
|
+
if type_map is None:
|
|
31
|
+
type_map = {}
|
|
32
|
+
if func_map is None:
|
|
33
|
+
func_map = {}
|
|
34
|
+
|
|
35
|
+
def strip_column(x):
|
|
36
|
+
"""
|
|
37
|
+
Strip white spaces for Number type column.
|
|
38
|
+
"""
|
|
39
|
+
y = x.strip() if not isinstance(x, Number) else x
|
|
40
|
+
return np.nan if y == '' else y
|
|
41
|
+
|
|
42
|
+
# make up our column converter
|
|
43
|
+
convert_map = {c: strip_column for c, v in type_map.items() if
|
|
44
|
+
v in (np.int64, np.float64, np.int64, np.float64)}
|
|
45
|
+
|
|
46
|
+
# load csv with our converter
|
|
47
|
+
# df_sweeps = pd.read_csv(file_path, sep=sep)
|
|
48
|
+
df_sweeps = pd.read_csv(file_path, sep=sep, converters=convert_map)
|
|
49
|
+
|
|
50
|
+
# go through each of rows
|
|
51
|
+
row_count = df_sweeps.shape[0]
|
|
52
|
+
for k in range(row_count):
|
|
53
|
+
self.sweeps = []
|
|
54
|
+
|
|
55
|
+
# get the current row as DataFrame
|
|
56
|
+
df = df_sweeps.iloc[[k]]
|
|
57
|
+
|
|
58
|
+
# drop columns with nan
|
|
59
|
+
df = df.dropna(axis=1)
|
|
60
|
+
|
|
61
|
+
# make parameter with the correct value type
|
|
62
|
+
type_map_t = {k: v for k, v in type_map.items() if k in df.columns.tolist()}
|
|
63
|
+
df = df.astype(type_map_t)
|
|
64
|
+
# make dict like: {'a': [1], 'b': [2]}
|
|
65
|
+
sweep = df.to_dict(orient='list')
|
|
66
|
+
|
|
67
|
+
# create an arm
|
|
68
|
+
arm = SweepArm()
|
|
69
|
+
|
|
70
|
+
# go through each (key, value)
|
|
71
|
+
for param, value in sweep.items():
|
|
72
|
+
# get the mapping function
|
|
73
|
+
func = func_map[param]
|
|
74
|
+
arm.add_sweep_definition(func, value)
|
|
75
|
+
|
|
76
|
+
self.add_arm(arm)
|