1 | """ |
---|
2 | Support for generating the options for a SelectToolParameter dynamically (based |
---|
3 | on the values of other parameters or other aspects of the current state) |
---|
4 | """ |
---|
5 | |
---|
6 | import operator, sys, os, logging |
---|
7 | import basic, validation |
---|
8 | from galaxy.util import string_as_bool |
---|
9 | |
---|
10 | log = logging.getLogger(__name__) |
---|
11 | |
---|
12 | class Filter( object ): |
---|
13 | """ |
---|
14 | A filter takes the current options list and modifies it. |
---|
15 | """ |
---|
16 | @classmethod |
---|
17 | def from_element( cls, d_option, elem ): |
---|
18 | """Loads the proper filter by the type attribute of elem""" |
---|
19 | type = elem.get( 'type', None ) |
---|
20 | assert type is not None, "Required 'type' attribute missing from filter" |
---|
21 | return filter_types[type.strip()]( d_option, elem ) |
---|
22 | def __init__( self, d_option, elem ): |
---|
23 | self.dynamic_option = d_option |
---|
24 | self.elem = elem |
---|
25 | def get_dependency_name( self ): |
---|
26 | """Returns the name of any depedencies, otherwise None""" |
---|
27 | return None |
---|
28 | def filter_options( self, options, trans, other_values ): |
---|
29 | """Returns a list of options after the filter is applied""" |
---|
30 | raise TypeError( "Abstract Method" ) |
---|
31 | |
---|
32 | class StaticValueFilter( Filter ): |
---|
33 | """ |
---|
34 | Filters a list of options on a column by a static value. |
---|
35 | |
---|
36 | Type: static_value |
---|
37 | |
---|
38 | Required Attributes: |
---|
39 | value: static value to compare to |
---|
40 | column: column in options to compare with |
---|
41 | Optional Attributes: |
---|
42 | keep: Keep columns matching value (True) |
---|
43 | Discard columns matching value (False) |
---|
44 | """ |
---|
45 | def __init__( self, d_option, elem ): |
---|
46 | Filter.__init__( self, d_option, elem ) |
---|
47 | self.value = elem.get( "value", None ) |
---|
48 | assert self.value is not None, "Required 'value' attribute missing from filter" |
---|
49 | column = elem.get( "column", None ) |
---|
50 | assert column is not None, "Required 'column' attribute missing from filter, when loading from file" |
---|
51 | self.column = d_option.column_spec_to_index( column ) |
---|
52 | self.keep = string_as_bool( elem.get( "keep", 'True' ) ) |
---|
53 | def filter_options( self, options, trans, other_values ): |
---|
54 | rval = [] |
---|
55 | for fields in options: |
---|
56 | if ( self.keep and fields[self.column] == self.value ) or ( not self.keep and fields[self.column] != self.value ): |
---|
57 | rval.append( fields ) |
---|
58 | return rval |
---|
59 | |
---|
60 | class DataMetaFilter( Filter ): |
---|
61 | """ |
---|
62 | Filters a list of options on a column by a dataset metadata value. |
---|
63 | |
---|
64 | Type: data_meta |
---|
65 | |
---|
66 | When no 'from_' source has been specified in the <options> tag, this will populate the options list with (meta_value, meta_value, False). |
---|
67 | Otherwise, options which do not match the metadata value in the column are discarded. |
---|
68 | |
---|
69 | Required Attributes: |
---|
70 | ref: Name of input dataset |
---|
71 | key: Metadata key to use for comparison |
---|
72 | column: column in options to compare with (not required when not associated with input options) |
---|
73 | Optional Attributes: |
---|
74 | multiple: Option values are multiple, split column by separator (True) |
---|
75 | separator: When multiple split by this (,) |
---|
76 | """ |
---|
77 | def __init__( self, d_option, elem ): |
---|
78 | Filter.__init__( self, d_option, elem ) |
---|
79 | self.ref_name = elem.get( "ref", None ) |
---|
80 | assert self.ref_name is not None, "Required 'ref' attribute missing from filter" |
---|
81 | d_option.has_dataset_dependencies = True |
---|
82 | self.key = elem.get( "key", None ) |
---|
83 | assert self.key is not None, "Required 'key' attribute missing from filter" |
---|
84 | self.column = elem.get( "column", None ) |
---|
85 | if self.column is None: |
---|
86 | assert self.dynamic_option.file_fields is None and self.dynamic_option.dataset_ref_name is None, "Required 'column' attribute missing from filter, when loading from file" |
---|
87 | else: |
---|
88 | self.column = d_option.column_spec_to_index( self.column ) |
---|
89 | self.multiple = string_as_bool( elem.get( "multiple", "False" ) ) |
---|
90 | self.separator = elem.get( "separator", "," ) |
---|
91 | def get_dependency_name( self ): |
---|
92 | return self.ref_name |
---|
93 | def filter_options( self, options, trans, other_values ): |
---|
94 | def compare_meta_value( file_value, dataset_value ): |
---|
95 | if isinstance( dataset_value, list ): |
---|
96 | if self.multiple: |
---|
97 | file_value = file_value.split( self.separator ) |
---|
98 | for value in dataset_value: |
---|
99 | if value not in file_value: |
---|
100 | return False |
---|
101 | return True |
---|
102 | return file_value in dataset_value |
---|
103 | if self.multiple: |
---|
104 | return dataset_value in file_value.split( self.separator ) |
---|
105 | return file_value == dataset_value |
---|
106 | assert self.ref_name in other_values or ( trans is not None and trans.workflow_building_mode), "Required dependency '%s' not found in incoming values" % self.ref_name |
---|
107 | ref = other_values.get( self.ref_name, None ) |
---|
108 | if not isinstance( ref, self.dynamic_option.tool_param.tool.app.model.HistoryDatasetAssociation ): |
---|
109 | return [] #not a valid dataset |
---|
110 | meta_value = ref.metadata.get( self.key, None ) |
---|
111 | if meta_value is None: #assert meta_value is not None, "Required metadata value '%s' not found in referenced dataset" % self.key |
---|
112 | return [ ( disp_name, basic.UnvalidatedValue( optval ), selected ) for disp_name, optval, selected in options ] |
---|
113 | |
---|
114 | if self.column is not None: |
---|
115 | rval = [] |
---|
116 | for fields in options: |
---|
117 | if compare_meta_value( fields[self.column], meta_value ): |
---|
118 | rval.append( fields ) |
---|
119 | return rval |
---|
120 | else: |
---|
121 | if not isinstance( meta_value, list ): |
---|
122 | meta_value = [meta_value] |
---|
123 | for value in meta_value: |
---|
124 | options.append( ( value, value, False ) ) |
---|
125 | return options |
---|
126 | |
---|
127 | class ParamValueFilter( Filter ): |
---|
128 | """ |
---|
129 | Filters a list of options on a column by the value of another input. |
---|
130 | |
---|
131 | Type: param_value |
---|
132 | |
---|
133 | Required Attributes: |
---|
134 | ref: Name of input value |
---|
135 | column: column in options to compare with |
---|
136 | Optional Attributes: |
---|
137 | keep: Keep columns matching value (True) |
---|
138 | Discard columns matching value (False) |
---|
139 | ref_attribute: Period (.) separated attribute chain of input (ref) to use as value for filter |
---|
140 | """ |
---|
141 | def __init__( self, d_option, elem ): |
---|
142 | Filter.__init__( self, d_option, elem ) |
---|
143 | self.ref_name = elem.get( "ref", None ) |
---|
144 | assert self.ref_name is not None, "Required 'ref' attribute missing from filter" |
---|
145 | column = elem.get( "column", None ) |
---|
146 | assert column is not None, "Required 'column' attribute missing from filter" |
---|
147 | self.column = d_option.column_spec_to_index( column ) |
---|
148 | self.keep = string_as_bool( elem.get( "keep", 'True' ) ) |
---|
149 | self.ref_attribute = elem.get( "ref_attribute", None ) |
---|
150 | if self.ref_attribute: |
---|
151 | self.ref_attribute = self.ref_attribute.split( '.' ) |
---|
152 | else: |
---|
153 | self.ref_attribute = [] |
---|
154 | def get_dependency_name( self ): |
---|
155 | return self.ref_name |
---|
156 | def filter_options( self, options, trans, other_values ): |
---|
157 | if trans is not None and trans.workflow_building_mode: return [] |
---|
158 | assert self.ref_name in other_values, "Required dependency '%s' not found in incoming values" % self.ref_name |
---|
159 | ref = other_values.get( self.ref_name, None ) |
---|
160 | for ref_attribute in self.ref_attribute: |
---|
161 | if not hasattr( ref, ref_attribute ): |
---|
162 | return [] #ref does not have attribute, so we cannot filter, return empty list |
---|
163 | ref = getattr( ref, ref_attribute ) |
---|
164 | ref = str( ref ) |
---|
165 | rval = [] |
---|
166 | for fields in options: |
---|
167 | if ( self.keep and fields[self.column] == ref ) or ( not self.keep and fields[self.column] != ref ): |
---|
168 | rval.append( fields ) |
---|
169 | return rval |
---|
170 | |
---|
171 | class UniqueValueFilter( Filter ): |
---|
172 | """ |
---|
173 | Filters a list of options to be unique by a column value. |
---|
174 | |
---|
175 | Type: unique_value |
---|
176 | |
---|
177 | Required Attributes: |
---|
178 | column: column in options to compare with |
---|
179 | """ |
---|
180 | def __init__( self, d_option, elem ): |
---|
181 | Filter.__init__( self, d_option, elem ) |
---|
182 | column = elem.get( "column", None ) |
---|
183 | assert column is not None, "Required 'column' attribute missing from filter" |
---|
184 | self.column = d_option.column_spec_to_index( column ) |
---|
185 | def get_dependency_name( self ): |
---|
186 | return self.dynamic_option.dataset_ref_name |
---|
187 | def filter_options( self, options, trans, other_values ): |
---|
188 | rval = [] |
---|
189 | skip_list = [] |
---|
190 | for fields in options: |
---|
191 | if fields[self.column] not in skip_list: |
---|
192 | rval.append( fields ) |
---|
193 | skip_list.append( fields[self.column] ) |
---|
194 | return rval |
---|
195 | |
---|
196 | class MultipleSplitterFilter( Filter ): |
---|
197 | """ |
---|
198 | Turns a single line of options into multiple lines, by splitting a column and creating a line for each item. |
---|
199 | |
---|
200 | Type: multiple_splitter |
---|
201 | |
---|
202 | Required Attributes: |
---|
203 | column: column in options to compare with |
---|
204 | Optional Attributes: |
---|
205 | separator: Split column by this (,) |
---|
206 | """ |
---|
207 | def __init__( self, d_option, elem ): |
---|
208 | Filter.__init__( self, d_option, elem ) |
---|
209 | self.separator = elem.get( "separator", "," ) |
---|
210 | columns = elem.get( "column", None ) |
---|
211 | assert columns is not None, "Required 'columns' attribute missing from filter" |
---|
212 | self.columns = [ d_option.column_spec_to_index( column ) for column in columns.split( "," ) ] |
---|
213 | def filter_options( self, options, trans, other_values ): |
---|
214 | rval = [] |
---|
215 | for fields in options: |
---|
216 | for column in self.columns: |
---|
217 | for field in fields[column].split( self.separator ): |
---|
218 | rval.append( fields[0:column] + [field] + fields[column+1:] ) |
---|
219 | return rval |
---|
220 | |
---|
221 | class AttributeValueSplitterFilter( Filter ): |
---|
222 | """ |
---|
223 | Filters a list of attribute-value pairs to be unique attribute names. |
---|
224 | |
---|
225 | Type: attribute_value_splitter |
---|
226 | |
---|
227 | Required Attributes: |
---|
228 | column: column in options to compare with |
---|
229 | Optional Attributes: |
---|
230 | pair_separator: Split column by this (,) |
---|
231 | name_val_separator: Split name-value pair by this ( whitespace ) |
---|
232 | """ |
---|
233 | def __init__( self, d_option, elem ): |
---|
234 | Filter.__init__( self, d_option, elem ) |
---|
235 | self.pair_separator = elem.get( "pair_separator", "," ) |
---|
236 | self.name_val_separator = elem.get( "name_val_separator", None ) |
---|
237 | self.columns = elem.get( "column", None ) |
---|
238 | assert self.columns is not None, "Required 'columns' attribute missing from filter" |
---|
239 | self.columns = [ int ( column ) for column in self.columns.split( "," ) ] |
---|
240 | def filter_options( self, options, trans, other_values ): |
---|
241 | attr_names = [] |
---|
242 | rval = [] |
---|
243 | for fields in options: |
---|
244 | for column in self.columns: |
---|
245 | for pair in fields[column].split( self.pair_separator ): |
---|
246 | ary = pair.split( self.name_val_separator ) |
---|
247 | if len( ary ) == 2: |
---|
248 | name, value = ary |
---|
249 | if name not in attr_names: |
---|
250 | rval.append( fields[0:column] + [name] + fields[column:] ) |
---|
251 | attr_names.append( name ) |
---|
252 | return rval |
---|
253 | |
---|
254 | |
---|
255 | class AdditionalValueFilter( Filter ): |
---|
256 | """ |
---|
257 | Adds a single static value to an options list. |
---|
258 | |
---|
259 | Type: add_value |
---|
260 | |
---|
261 | Required Attributes: |
---|
262 | value: value to appear in select list |
---|
263 | Optional Attributes: |
---|
264 | name: Display name to appear in select list (value) |
---|
265 | index: Index of option list to add value (APPEND) |
---|
266 | """ |
---|
267 | def __init__( self, d_option, elem ): |
---|
268 | Filter.__init__( self, d_option, elem ) |
---|
269 | self.value = elem.get( "value", None ) |
---|
270 | assert self.value is not None, "Required 'value' attribute missing from filter" |
---|
271 | self.name = elem.get( "name", None ) |
---|
272 | if self.name is None: |
---|
273 | self.name = self.value |
---|
274 | self.index = elem.get( "index", None ) |
---|
275 | if self.index is not None: |
---|
276 | self.index = int( self.index ) |
---|
277 | def filter_options( self, options, trans, other_values ): |
---|
278 | rval = list( options ) |
---|
279 | add_value = [] |
---|
280 | for i in range( self.dynamic_option.largest_index + 1 ): |
---|
281 | add_value.append( "" ) |
---|
282 | add_value[self.dynamic_option.columns['value']] = self.value |
---|
283 | add_value[self.dynamic_option.columns['name']] = self.name |
---|
284 | if self.index is not None: |
---|
285 | rval.insert( self.index, add_value ) |
---|
286 | else: |
---|
287 | rval.append( add_value ) |
---|
288 | return rval |
---|
289 | |
---|
290 | class RemoveValueFilter( Filter ): |
---|
291 | """ |
---|
292 | Removes a value from an options list. |
---|
293 | |
---|
294 | Type: remove_value |
---|
295 | |
---|
296 | Required Attributes: |
---|
297 | value: value to remove from select list |
---|
298 | or |
---|
299 | ref: param to refer to |
---|
300 | or |
---|
301 | meta_ref: dataset to refer to |
---|
302 | key: metadata key to compare to |
---|
303 | """ |
---|
304 | def __init__( self, d_option, elem ): |
---|
305 | Filter.__init__( self, d_option, elem ) |
---|
306 | self.value = elem.get( "value", None ) |
---|
307 | self.ref_name = elem.get( "ref", None ) |
---|
308 | self.meta_ref = elem.get( "meta_ref", None ) |
---|
309 | self.metadata_key = elem.get( "key", None ) |
---|
310 | assert self.value is not None or ( ( self.ref_name is not None or self.meta_ref is not None )and self.metadata_key is not None ), ValueError( "Required 'value' or 'ref' and 'key' attributes missing from filter" ) |
---|
311 | self.multiple = string_as_bool( elem.get( "multiple", "False" ) ) |
---|
312 | self.separator = elem.get( "separator", "," ) |
---|
313 | def filter_options( self, options, trans, other_values ): |
---|
314 | if trans is not None and trans.workflow_building_mode: return options |
---|
315 | assert self.value is not None or ( self.ref_name is not None and self.ref_name in other_values ) or (self.meta_ref is not None and self.meta_ref in other_values ) or ( trans is not None and trans.workflow_building_mode), Exception( "Required dependency '%s' or '%s' not found in incoming values" % ( self.ref_name, self.meta_ref ) ) |
---|
316 | def compare_value( option_value, filter_value ): |
---|
317 | if isinstance( filter_value, list ): |
---|
318 | if self.multiple: |
---|
319 | option_value = option_value.split( self.separator ) |
---|
320 | for value in filter_value: |
---|
321 | if value not in filter_value: |
---|
322 | return False |
---|
323 | return True |
---|
324 | return option_value in filter_value |
---|
325 | if self.multiple: |
---|
326 | return filter_value in option_value.split( self.separator ) |
---|
327 | return option_value == filter_value |
---|
328 | value = self.value |
---|
329 | if value is None: |
---|
330 | if self.ref_name is not None: |
---|
331 | value = other_values.get( self.ref_name ) |
---|
332 | else: |
---|
333 | data_ref = other_values.get( self.meta_ref ) |
---|
334 | if not isinstance( data_ref, self.dynamic_option.tool_param.tool.app.model.HistoryDatasetAssociation ): |
---|
335 | return options #cannot modify options |
---|
336 | value = data_ref.metadata.get( self.metadata_key, None ) |
---|
337 | return [ ( disp_name, optval, selected ) for disp_name, optval, selected in options if not compare_value( optval, value ) ] |
---|
338 | |
---|
339 | class SortByColumnFilter( Filter ): |
---|
340 | """ |
---|
341 | Sorts an options list by a column |
---|
342 | |
---|
343 | Type: sort_by |
---|
344 | |
---|
345 | Required Attributes: |
---|
346 | column: column to sort by |
---|
347 | """ |
---|
348 | def __init__( self, d_option, elem ): |
---|
349 | Filter.__init__( self, d_option, elem ) |
---|
350 | column = elem.get( "column", None ) |
---|
351 | assert column is not None, "Required 'column' attribute missing from filter" |
---|
352 | self.column = d_option.column_spec_to_index( column ) |
---|
353 | def filter_options( self, options, trans, other_values ): |
---|
354 | rval = [] |
---|
355 | for i, fields in enumerate( options ): |
---|
356 | for j in range( 0, len( rval ) ): |
---|
357 | if fields[self.column] < rval[j][self.column]: |
---|
358 | rval.insert( j, fields ) |
---|
359 | break |
---|
360 | else: |
---|
361 | rval.append( fields ) |
---|
362 | return rval |
---|
363 | |
---|
364 | |
---|
365 | filter_types = dict( data_meta = DataMetaFilter, |
---|
366 | param_value = ParamValueFilter, |
---|
367 | static_value = StaticValueFilter, |
---|
368 | unique_value = UniqueValueFilter, |
---|
369 | multiple_splitter = MultipleSplitterFilter, |
---|
370 | attribute_value_splitter = AttributeValueSplitterFilter, |
---|
371 | add_value = AdditionalValueFilter, |
---|
372 | remove_value = RemoveValueFilter, |
---|
373 | sort_by = SortByColumnFilter ) |
---|
374 | |
---|
375 | class DynamicOptions( object ): |
---|
376 | """Handles dynamically generated SelectToolParameter options""" |
---|
377 | def __init__( self, elem, tool_param ): |
---|
378 | def load_from_parameter( from_parameter, transform_lines = None ): |
---|
379 | obj = self.tool_param |
---|
380 | for field in from_parameter.split( '.' ): |
---|
381 | obj = getattr( obj, field ) |
---|
382 | if transform_lines: |
---|
383 | obj = eval( transform_lines ) |
---|
384 | return self.parse_file_fields( obj ) |
---|
385 | self.tool_param = tool_param |
---|
386 | self.columns = {} |
---|
387 | self.filters = [] |
---|
388 | self.file_fields = None |
---|
389 | self.largest_index = 0 |
---|
390 | self.dataset_ref_name = None |
---|
391 | # True if the options generation depends on one or more other parameters |
---|
392 | # that are dataset inputs |
---|
393 | self.has_dataset_dependencies = False |
---|
394 | self.validators = [] |
---|
395 | self.converter_safe = True |
---|
396 | |
---|
397 | # Parse the <options> tag |
---|
398 | self.separator = elem.get( 'separator', '\t' ) |
---|
399 | self.line_startswith = elem.get( 'startswith', None ) |
---|
400 | data_file = elem.get( 'from_file', None ) |
---|
401 | dataset_file = elem.get( 'from_dataset', None ) |
---|
402 | from_parameter = elem.get( 'from_parameter', None ) |
---|
403 | tool_data_table_name = elem.get( 'from_data_table', None ) |
---|
404 | |
---|
405 | # Options are defined from a data table loaded by the app |
---|
406 | self.tool_data_table = None |
---|
407 | if tool_data_table_name: |
---|
408 | app = tool_param.tool.app |
---|
409 | assert tool_data_table_name in app.tool_data_tables, \ |
---|
410 | "Data table named '%s' is required by tool but not configured" % tool_data_table_name |
---|
411 | self.tool_data_table = app.tool_data_tables[ tool_data_table_name ] |
---|
412 | # Column definitions are optional, but if provided override those from the table |
---|
413 | if elem.find( "column" ) is not None: |
---|
414 | self.parse_column_definitions( elem ) |
---|
415 | else: |
---|
416 | self.columns = self.tool_data_table.columns |
---|
417 | |
---|
418 | # Options are defined by parsing tabular text data from an data file |
---|
419 | # on disk, a dataset, or the value of another parameter |
---|
420 | elif data_file is not None or dataset_file is not None or from_parameter is not None: |
---|
421 | self.parse_column_definitions( elem ) |
---|
422 | if data_file is not None: |
---|
423 | data_file = data_file.strip() |
---|
424 | if not os.path.isabs( data_file ): |
---|
425 | data_file = os.path.join( self.tool_param.tool.app.config.tool_data_path, data_file ) |
---|
426 | self.file_fields = self.parse_file_fields( open( data_file ) ) |
---|
427 | elif dataset_file is not None: |
---|
428 | self.dataset_ref_name = dataset_file |
---|
429 | self.has_dataset_dependencies = True |
---|
430 | self.converter_safe = False |
---|
431 | elif from_parameter is not None: |
---|
432 | transform_lines = elem.get( 'transform_lines', None ) |
---|
433 | self.file_fields = list( load_from_parameter( from_parameter, transform_lines ) ) |
---|
434 | |
---|
435 | # Load filters |
---|
436 | for filter_elem in elem.findall( 'filter' ): |
---|
437 | self.filters.append( Filter.from_element( self, filter_elem ) ) |
---|
438 | |
---|
439 | # Load Validators |
---|
440 | for validator in elem.findall( 'validator' ): |
---|
441 | self.validators.append( validation.Validator.from_element( self.tool_param, validator ) ) |
---|
442 | |
---|
443 | def parse_column_definitions( self, elem ): |
---|
444 | for column_elem in elem.findall( 'column' ): |
---|
445 | name = column_elem.get( 'name', None ) |
---|
446 | assert name is not None, "Required 'name' attribute missing from column def" |
---|
447 | index = column_elem.get( 'index', None ) |
---|
448 | assert index is not None, "Required 'index' attribute missing from column def" |
---|
449 | index = int( index ) |
---|
450 | self.columns[name] = index |
---|
451 | if index > self.largest_index: |
---|
452 | self.largest_index = index |
---|
453 | assert 'value' in self.columns, "Required 'value' column missing from column def" |
---|
454 | if 'name' not in self.columns: |
---|
455 | self.columns['name'] = self.columns['value'] |
---|
456 | |
---|
457 | def parse_file_fields( self, reader ): |
---|
458 | rval = [] |
---|
459 | for line in reader: |
---|
460 | if line.startswith( '#' ) or ( self.line_startswith and not line.startswith( self.line_startswith ) ): |
---|
461 | continue |
---|
462 | line = line.rstrip( "\n\r" ) |
---|
463 | if line: |
---|
464 | fields = line.split( self.separator ) |
---|
465 | if self.largest_index < len( fields ): |
---|
466 | rval.append( fields ) |
---|
467 | return rval |
---|
468 | |
---|
469 | def get_dependency_names( self ): |
---|
470 | """ |
---|
471 | Return the names of parameters these options depend on -- both data |
---|
472 | and other param types. |
---|
473 | """ |
---|
474 | rval = [] |
---|
475 | if self.dataset_ref_name: |
---|
476 | rval.append( self.dataset_ref_name ) |
---|
477 | for filter in self.filters: |
---|
478 | depend = filter.get_dependency_name() |
---|
479 | if depend: |
---|
480 | rval.append( depend ) |
---|
481 | return rval |
---|
482 | |
---|
483 | def get_fields( self, trans, other_values ): |
---|
484 | if self.dataset_ref_name: |
---|
485 | dataset = other_values.get( self.dataset_ref_name, None ) |
---|
486 | assert dataset is not None, "Required dataset '%s' missing from input" % self.dataset_ref_name |
---|
487 | if not dataset: return [] #no valid dataset in history |
---|
488 | options = self.parse_file_fields( open( dataset.file_name ) ) |
---|
489 | elif self.tool_data_table: |
---|
490 | options = self.tool_data_table.get_fields() |
---|
491 | else: |
---|
492 | options = list( self.file_fields ) |
---|
493 | for filter in self.filters: |
---|
494 | options = filter.filter_options( options, trans, other_values ) |
---|
495 | return options |
---|
496 | |
---|
497 | def get_options( self, trans, other_values ): |
---|
498 | rval = [] |
---|
499 | if self.file_fields is not None or self.tool_data_table is not None or self.dataset_ref_name is not None: |
---|
500 | options = self.get_fields( trans, other_values ) |
---|
501 | for fields in options: |
---|
502 | rval.append( ( fields[self.columns['name']], fields[self.columns['value']], False ) ) |
---|
503 | else: |
---|
504 | for filter in self.filters: |
---|
505 | rval = filter.filter_options( rval, trans, other_values ) |
---|
506 | return rval |
---|
507 | |
---|
508 | def column_spec_to_index( self, column_spec ): |
---|
509 | """ |
---|
510 | Convert a column specification (as read from the config file), to an |
---|
511 | index. A column specification can just be a number, a column name, or |
---|
512 | a column alias. |
---|
513 | """ |
---|
514 | # Name? |
---|
515 | if column_spec in self.columns: |
---|
516 | return self.columns[column_spec] |
---|
517 | # Int? |
---|
518 | return int( column_spec ) |
---|