-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtaskGenerator.py
137 lines (106 loc) · 4.44 KB
/
taskGenerator.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# -*- coding: utf-8 -*-
"""
:Author: Dominic Hunt
"""
import copy
import collections
import warnings
import utils
from tasks.taskTemplate import Task
class TaskGeneration(object):
"""
Generates task class instances based on a task and a set of varying parameters
Parameters
----------
task_name : string
The name of the file where a tasks.taskTemplate.Task class can be found
parameters : dictionary of floats or lists of floats
Parameters are the options that you are or are likely to change across task instances. When a parameter
contains a list, an instance of the task will be created for every combination of this parameter with all
the others. Default ``None``
other_options : dictionary of float, string or binary valued elements
These contain all the the task options that describe the task being studied but do not vary across
task instances. Default ``None``
"""
def __init__(self, task_name, parameters=None, other_options=None):
self.count = -1
task_class = utils.find_class(task_name,
class_folder='tasks',
inherited_class=Task,
excluded_files=['taskTemplate', '__init__', 'taskGenerator'])
valid_task_args = utils.get_class_args(task_class)
self.task_class = task_class
if not parameters:
parameters = {}
parameter_keys = list(parameters.keys())
for p in parameter_keys:
if p not in valid_task_args:
raise KeyError(
'{} is not a valid property for model ``{}``. Use {}'.format(p, task_name,
valid_task_args))
parameter_combinations = []
for p in utils.listMergeGen(*list(parameters.values())):
pc = {k: copy.copy(v) for k, v in zip(parameter_keys, p)}
parameter_combinations.append(pc)
self.parameter_combinations = parameter_combinations
if other_options:
checked_options = {}
for k, v in other_options.items():
if k not in valid_task_args:
raise KeyError('{} is not a valid property for task ``{}``. Use {}'.format(k,
task_name,
valid_task_args))
elif k in parameter_keys:
warnings.warn("task parameter {} has been defined twice".format(k))
else:
checked_options[k] = v
self.other_options = checked_options
else:
self.other_options = {}
if parameter_combinations:
self.count_max = len(parameter_combinations)
else:
self.count_max = 1
def __iter__(self):
"""
Returns the iterator for the creation of tasks
"""
self.count = -1
return self
def __next__(self):
"""
Produces the next task instance for the iterator
Returns
-------
instance : tasks.taskTemplate.Task instance
"""
self.count += 1
if self.count >= self.count_max:
raise StopIteration
return self.new_task(self.count)
def iter_task_ID(self):
"""
Yields the tasks IDs. To be used with self.new_task(expID) to receive the next tasks instance
Returns
-------
expID : int
The ID number that refers to the next tasks parameter combination.
"""
for c in range(self.count_max):
yield c
def new_task(self, task_number):
"""
Produces the next tasks instance
Parameters
----------
task_number : int
The number of the tasks instance to be initialised
Returns
-------
instance : tasks.taskTemplate.Task instance
"""
if task_number >= self.count_max:
return None
properties = copy.copy(self.parameter_combinations[task_number])
properties.update(copy.copy(self.other_options))
return self.task_class(**properties)