labimotion 2.0.0.rc2 → 2.0.0.rc8
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.
- checksums.yaml +4 -4
- data/lib/labimotion/apis/standard_api.rb +1 -2
- data/lib/labimotion/apis/standard_layer_api.rb +4 -17
- data/lib/labimotion/apis/vocabulary_api.rb +5 -19
- data/lib/labimotion/constants.rb +25 -0
- data/lib/labimotion/entities/dataset_entity.rb +0 -1
- data/lib/labimotion/entities/element_entity.rb +1 -0
- data/lib/labimotion/entities/properties_entity.rb +102 -41
- data/lib/labimotion/entities/segment_entity.rb +0 -2
- data/lib/labimotion/entities/vocabulary_entity.rb +0 -10
- data/lib/labimotion/helpers/element_helpers.rb +4 -3
- data/lib/labimotion/helpers/generic_helpers.rb +6 -1
- data/lib/labimotion/helpers/param_helpers.rb +0 -16
- data/lib/labimotion/libs/converter.rb +0 -1
- data/lib/labimotion/libs/data/mapper/Chemwiki.json +236 -0
- data/lib/labimotion/libs/data/mapper/Source.json +78 -0
- data/lib/labimotion/libs/dataset_builder.rb +70 -0
- data/lib/labimotion/libs/export_dataset.rb +343 -98
- data/lib/labimotion/libs/nmr_mapper.rb +204 -247
- data/lib/labimotion/models/concerns/generic_klass_revisions.rb +1 -0
- data/lib/labimotion/models/concerns/generic_revisions.rb +3 -0
- data/lib/labimotion/models/element.rb +3 -0
- data/lib/labimotion/utils/mapper_utils.rb +169 -0
- data/lib/labimotion/utils/utils.rb +21 -0
- data/lib/labimotion/version.rb +1 -1
- data/lib/labimotion.rb +3 -3
- metadata +7 -2
@@ -8,47 +8,174 @@ module Labimotion
|
|
8
8
|
DEFAULT_ROW_WIDTH = 100
|
9
9
|
DEFAULT_ROW_HEIGHT = 20
|
10
10
|
|
11
|
-
def initialize(
|
11
|
+
def initialize(id)
|
12
12
|
@xfile = Axlsx::Package.new
|
13
|
-
@file_extension = 'xlsx'
|
14
13
|
@xfile.workbook.styles.fonts.first.name = 'Calibri'
|
14
|
+
@file_extension = 'xlsx'
|
15
|
+
|
16
|
+
@id = id
|
17
|
+
@dataset = Labimotion::Dataset.find_by(element_id: @id, element_type: 'Container')
|
18
|
+
return if @dataset.nil?
|
19
|
+
|
20
|
+
@klass = @dataset.dataset_klass
|
21
|
+
@ols_term_id = @klass.ols_term_id
|
22
|
+
@label = @klass.label
|
23
|
+
@analysis = @dataset&.element&.parent
|
24
|
+
@element = @analysis&.root&.containable if @analysis.present?
|
25
|
+
@element_type = @element.class.name if @element.present?
|
26
|
+
@spectra_values = []
|
15
27
|
end
|
16
28
|
|
17
|
-
def
|
18
|
-
|
19
|
-
|
29
|
+
def read
|
30
|
+
@xfile.to_stream.read
|
31
|
+
end
|
32
|
+
|
33
|
+
def res_name
|
34
|
+
element_name = Container.find(@id)&.root_element&.short_label
|
35
|
+
ols = ols_name
|
20
36
|
"#{element_name}_#{ols.gsub(' ', '_')}.xlsx"
|
21
37
|
rescue StandardError => e
|
22
38
|
Labimotion.log_exception(e)
|
23
39
|
end
|
24
40
|
|
25
|
-
def
|
26
|
-
|
27
|
-
|
41
|
+
def export
|
42
|
+
return if @dataset.nil? || @analysis.nil? || @element.nil?
|
43
|
+
|
44
|
+
description
|
45
|
+
dataset_info
|
46
|
+
spectra_info
|
47
|
+
chemwiki_info
|
48
|
+
rescue StandardError => e
|
49
|
+
Labimotion.log_exception(e)
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
def chemwiki_info
|
55
|
+
@spectra_values
|
56
|
+
config = Labimotion::MapperUtils.load_config(File.read(Constants::Mapper::WIKI_CONFIG))
|
57
|
+
return if config.nil? || config[@ols_term_id].nil?
|
58
|
+
|
59
|
+
sheet = @xfile.workbook.add_worksheet(name: 'ChemWiki')
|
60
|
+
map_index = config.dig(@ols_term_id, 'index')
|
61
|
+
map_mapper = config.dig(@ols_term_id, 'mapper')
|
62
|
+
map_source = config.dig(@ols_term_id, 'source')
|
63
|
+
|
64
|
+
return if map_index.nil? || map_mapper.nil? || map_source.nil?
|
65
|
+
|
66
|
+
return unless map_index.is_a?(Array) && map_mapper.is_a?(Hash) && map_source.is_a?(Hash)
|
28
67
|
|
29
|
-
|
68
|
+
# sheet.column_info.each { |col| col.width = map_width }
|
69
|
+
|
70
|
+
if @spectra_values.length == 0
|
71
|
+
@spectra_values.push([])
|
72
|
+
end
|
73
|
+
|
74
|
+
@spectra_values.each_with_index do |spdata, idx|
|
75
|
+
array_header = []
|
76
|
+
array_data = []
|
77
|
+
map_index.each do |key|
|
78
|
+
mapper = map_mapper.dig(key)
|
79
|
+
next if mapper.nil? || mapper['sources'].nil? || !mapper.is_a?(Hash)
|
80
|
+
|
81
|
+
col_header = ''
|
82
|
+
col_value = ''
|
83
|
+
mapper['sources'].each_with_index do |source_key, idx|
|
84
|
+
source = map_source&.dig(source_key)
|
85
|
+
next if source.nil? || source['title'].nil?
|
86
|
+
|
87
|
+
col_header = source['title']
|
88
|
+
|
89
|
+
if col_value.present?
|
90
|
+
col_value += (mapper['separator'] || '') + source_data(source, spdata)
|
91
|
+
else
|
92
|
+
col_value = source_data(source, spdata)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
array_header.push(col_header || '')
|
96
|
+
array_data.push(col_value || '')
|
97
|
+
end
|
98
|
+
if idx == 0
|
99
|
+
sheet.add_row(array_header)
|
100
|
+
end
|
101
|
+
sheet.add_row(array_data)
|
102
|
+
|
103
|
+
## for Redox potential
|
104
|
+
last_row = sheet.rows.last
|
105
|
+
last_row.cells[3].type = :string
|
106
|
+
end
|
107
|
+
|
108
|
+
|
109
|
+
rescue StandardError => e
|
110
|
+
Labimotion.log_exception(e)
|
111
|
+
end
|
30
112
|
|
31
|
-
match = name.match(/\((.*?)\)/)
|
32
|
-
name = match && match.length > 1 ? match[1] : name
|
33
113
|
|
34
|
-
|
35
|
-
|
114
|
+
def conv_value(field, properties)
|
115
|
+
return '' if field.nil?
|
116
|
+
|
117
|
+
case field['type']
|
118
|
+
when 'select'
|
119
|
+
return '' if field['value'].empty?
|
120
|
+
Labimotion::Utils.find_options_val(field, properties) || field['value']
|
121
|
+
else
|
122
|
+
field['value']
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
def source_data(source, spdata)
|
127
|
+
param = source['param']
|
128
|
+
return '' if param.nil? || source['type'].nil?
|
129
|
+
|
130
|
+
val = case source['type']
|
131
|
+
when 'string'
|
132
|
+
param
|
133
|
+
when 'spc'
|
134
|
+
spdata.length.positive? && param.is_a?(Integer) ? spdata.pluck(param).join(';') : ''
|
135
|
+
when 'sample'
|
136
|
+
@element.send(param) if @element.respond_to?(param)
|
137
|
+
when 'molecule'
|
138
|
+
@element.molecule.send(param) if @element_type == 'Sample' && @element&.molecule&.respond_to?(param)
|
139
|
+
when 'dataset'
|
140
|
+
field = Labimotion::Utils.find_field(@dataset.properties, param)
|
141
|
+
conv_value(field, @dataset.properties)
|
142
|
+
end
|
143
|
+
val || ''
|
144
|
+
rescue StandardError => e
|
145
|
+
Labimotion.log_exception(e)
|
146
|
+
end
|
147
|
+
|
148
|
+
def element_info
|
149
|
+
if @element.class.name == 'Sample'
|
150
|
+
sheet = @xfile.workbook.add_worksheet(name: 'Element')
|
151
|
+
sheet.add_row(['inchikey', @element.molecule_inchikey])
|
152
|
+
sheet.add_row(['molfile', @element.molfile])
|
153
|
+
end
|
154
|
+
rescue StandardError => e
|
155
|
+
Labimotion.log_exception(e)
|
156
|
+
end
|
157
|
+
|
158
|
+
def ols_name
|
159
|
+
match = @label.match(/\((.*?)\)/)
|
160
|
+
name = match && match.length > 1 ? match[1] : @label
|
161
|
+
|
162
|
+
name = '1H NMR' if @ols_term_id == 'CHMO:0000593'
|
163
|
+
name = '13C NMR' if @ols_term_id == 'CHMO:0000595'
|
36
164
|
name.slice(0, 26)
|
37
165
|
rescue StandardError => e
|
38
166
|
Labimotion.log_exception(e)
|
39
167
|
'ols_name'
|
40
168
|
end
|
41
169
|
|
42
|
-
def description
|
43
|
-
wb = @xfile.workbook
|
170
|
+
def description
|
44
171
|
sheet = @xfile.workbook.add_worksheet(name: 'Description')
|
45
172
|
header_style = sheet.styles.add_style(sz: 12, fg_color: 'FFFFFF', bg_color: '00008B', border: { style: :thick, color: 'FF777777', edges: [:bottom] })
|
46
|
-
sheet.add_row(['File name', res_name
|
173
|
+
sheet.add_row(['File name', res_name])
|
47
174
|
sheet.add_row(['Time', Time.now.strftime("%Y-%m-%d %H:%M:%S %Z")] )
|
48
175
|
sheet.add_row(['(This file is automatically generated by the system.)'])
|
49
176
|
sheet.add_row([''])
|
50
177
|
sheet.add_row([''])
|
51
|
-
sheet.add_row(['Fields description of sheet:' +
|
178
|
+
sheet.add_row(['Fields description of sheet:' + @dataset.dataset_klass.label])
|
52
179
|
sheet.add_row(['Fields', 'Field description'], style: header_style)
|
53
180
|
sheet.add_row(['Layer Label', 'The label of the layer'])
|
54
181
|
sheet.add_row(['Field Label', 'The label of the field'])
|
@@ -65,66 +192,211 @@ module Labimotion
|
|
65
192
|
Labimotion.log_exception(e)
|
66
193
|
end
|
67
194
|
|
68
|
-
def
|
69
|
-
|
70
|
-
return if ds.nil?
|
71
|
-
|
72
|
-
description(ds, id)
|
73
|
-
|
74
|
-
wb = @xfile.workbook
|
75
|
-
name = ols_name(id)
|
195
|
+
def dataset_info
|
196
|
+
name = ols_name
|
76
197
|
return if name.nil?
|
77
198
|
|
199
|
+
sheet = create_dataset_sheet(name)
|
200
|
+
process_layers(sheet)
|
201
|
+
rescue StandardError => e
|
202
|
+
Labimotion.log_exception(e)
|
203
|
+
end
|
204
|
+
|
205
|
+
def create_dataset_sheet(name)
|
78
206
|
sheet = @xfile.workbook.add_worksheet(name: name)
|
79
|
-
sheet.add_row([
|
80
|
-
|
81
|
-
|
82
|
-
|
207
|
+
sheet.add_row([@dataset.dataset_klass.label])
|
208
|
+
sheet.add_row(header, style: create_header_style(sheet))
|
209
|
+
sheet
|
210
|
+
end
|
83
211
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
212
|
+
def process_layers(sheet)
|
213
|
+
layers = @dataset.properties[Labimotion::Prop::LAYERS] || {}
|
214
|
+
options = @dataset.properties[Labimotion::Prop::SEL_OPTIONS]
|
215
|
+
|
216
|
+
sort_layers(layers).each do |key|
|
88
217
|
layer = layers[key]
|
89
|
-
sheet
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
type = field['type']
|
95
|
-
from_device = field['device'].present? ? 'Device' : ''
|
96
|
-
from_device = field['system'].present? ? 'Chemotion' : from_device
|
97
|
-
type = "#{field['type']}-#{field['option_layers']}" if field['type'] == Labimotion::FieldType::SELECT || field['type'] == Labimotion::FieldType::SYSTEM_DEFINED
|
98
|
-
|
99
|
-
show_value = field['value'] =~ /\A\d+,\d+\z/ ? field['value']&.gsub(',', '.') : field['value']
|
100
|
-
ols_short_form = (field['ontology'] && field['ontology']['short_form']) || ''
|
101
|
-
ols_label = (field['ontology'] && field['ontology']['label']) || ''
|
102
|
-
ols_iri = (field['ontology'] && field['ontology']['iri']) || ''
|
103
|
-
sheet.add_row([' ', field['label'], nil, field['value_system'], field['field'], type, from_device, field['dkey'], nil, ols_short_form, ols_label, ols_iri].freeze)
|
104
|
-
|
105
|
-
case field['type']
|
106
|
-
when Labimotion::FieldType::SELECT
|
107
|
-
sheet.rows.last.cells[2].type = :string
|
108
|
-
sheet.rows.last.cells[8].type = :string
|
109
|
-
show_value = opt_value(field, options) if show_value.present?
|
110
|
-
when Labimotion::FieldType::SYSTEM_DEFINED, Labimotion::FieldType::INTEGER
|
111
|
-
sheet.rows.last.cells[2].type = :float
|
112
|
-
sheet.rows.last.cells[8].type = :float
|
113
|
-
else
|
114
|
-
sheet.rows.last.cells[2].type = :string
|
115
|
-
sheet.rows.last.cells[8].type = :string
|
116
|
-
end
|
117
|
-
sheet.rows.last.cells[2].value = show_value
|
118
|
-
sheet.rows.last.cells[8].value = field['system'] || field['device']
|
218
|
+
add_layer_row(sheet, layer)
|
219
|
+
process_fields(sheet, layer, options)
|
220
|
+
end
|
221
|
+
end
|
119
222
|
|
223
|
+
def sort_layers(layers)
|
224
|
+
layers.keys.sort_by { |key| layers[key]['position'] }
|
225
|
+
end
|
120
226
|
|
121
|
-
|
122
|
-
|
227
|
+
def add_layer_row(sheet, layer)
|
228
|
+
layer_style = sheet.styles.add_style(b: true, bg_color: 'CEECF5')
|
229
|
+
sheet.add_row([layer['label']] + [' '] * 8, style: layer_style)
|
230
|
+
end
|
231
|
+
|
232
|
+
def process_fields(sheet, layer, options)
|
233
|
+
sorted_fields = sort_fields(layer)
|
234
|
+
|
235
|
+
sorted_fields.each do |field|
|
236
|
+
next if field['type'] == 'dummy'
|
237
|
+
|
238
|
+
add_field_row(sheet, field)
|
239
|
+
set_field_types(sheet, field, options)
|
123
240
|
end
|
241
|
+
end
|
242
|
+
|
243
|
+
def sort_fields(layer)
|
244
|
+
layer[Labimotion::Prop::FIELDS].sort_by { |obj| obj['position'] }
|
245
|
+
end
|
246
|
+
|
247
|
+
def add_field_row(sheet, field)
|
248
|
+
type = determine_field_type(field)
|
249
|
+
from_device = determine_source(field)
|
250
|
+
show_value = format_value(field['value'])
|
251
|
+
ontology_data = extract_ontology_data(field)
|
252
|
+
|
253
|
+
row_data = [
|
254
|
+
' ',
|
255
|
+
field['label'],
|
256
|
+
nil,
|
257
|
+
field['value_system'],
|
258
|
+
field['field'],
|
259
|
+
type,
|
260
|
+
from_device,
|
261
|
+
field['dkey'],
|
262
|
+
nil
|
263
|
+
] + ontology_data
|
264
|
+
|
265
|
+
sheet.add_row(row_data.freeze)
|
266
|
+
end
|
267
|
+
|
268
|
+
def determine_field_type(field)
|
269
|
+
return "#{field['type']}-#{field['option_layers']}" if [
|
270
|
+
Labimotion::FieldType::SELECT,
|
271
|
+
Labimotion::FieldType::SYSTEM_DEFINED
|
272
|
+
].include?(field['type'])
|
273
|
+
|
274
|
+
field['type']
|
275
|
+
end
|
276
|
+
|
277
|
+
def determine_source(field)
|
278
|
+
return 'Chemotion' if field['system'].present?
|
279
|
+
return 'Device' if field['device'].present?
|
280
|
+
''
|
281
|
+
end
|
282
|
+
|
283
|
+
def format_value(value)
|
284
|
+
return value&.gsub(',', '.') if value =~ /\A\d+,\d+\z/
|
285
|
+
value
|
286
|
+
end
|
287
|
+
|
288
|
+
def extract_ontology_data(field)
|
289
|
+
ontology = field['ontology'] || {}
|
290
|
+
[
|
291
|
+
ontology['short_form'] || '',
|
292
|
+
ontology['label'] || '',
|
293
|
+
ontology['iri'] || ''
|
294
|
+
]
|
295
|
+
end
|
296
|
+
|
297
|
+
def set_field_types(sheet, field, options)
|
298
|
+
last_row = sheet.rows.last
|
299
|
+
|
300
|
+
case field['type']
|
301
|
+
when Labimotion::FieldType::SELECT
|
302
|
+
set_select_field_type(last_row, field, options)
|
303
|
+
when Labimotion::FieldType::SYSTEM_DEFINED, Labimotion::FieldType::INTEGER
|
304
|
+
set_numeric_field_type(last_row)
|
305
|
+
else
|
306
|
+
set_string_field_type(last_row)
|
307
|
+
end
|
308
|
+
|
309
|
+
set_field_values(last_row, field)
|
310
|
+
end
|
311
|
+
|
312
|
+
def set_select_field_type(row, field, options)
|
313
|
+
row.cells[2].type = :string
|
314
|
+
row.cells[8].type = :string
|
315
|
+
row.cells[2].value = opt_value(field, options) if field['value'].present?
|
316
|
+
end
|
317
|
+
|
318
|
+
def set_numeric_field_type(row)
|
319
|
+
row.cells[2].type = :float
|
320
|
+
row.cells[8].type = :float
|
321
|
+
end
|
322
|
+
|
323
|
+
def set_string_field_type(row)
|
324
|
+
row.cells[2].type = :string
|
325
|
+
row.cells[8].type = :string
|
326
|
+
end
|
327
|
+
|
328
|
+
def set_field_values(row, field)
|
329
|
+
row.cells[8].value = field['system'] || field['device']
|
330
|
+
end
|
331
|
+
|
332
|
+
def spectra_info
|
333
|
+
name_mapping = process_csv_files
|
334
|
+
return if name_mapping.nil? || name_mapping.length <= 1
|
335
|
+
|
336
|
+
create_mapping_sheet(name_mapping)
|
124
337
|
rescue StandardError => e
|
125
338
|
Labimotion.log_exception(e)
|
126
339
|
end
|
127
340
|
|
341
|
+
def process_csv_files
|
342
|
+
cds_csv = Container.find(@id).attachments.where(aasm_state: 'csv').order(:filename)
|
343
|
+
return if cds_csv.empty?
|
344
|
+
|
345
|
+
cds_csv.each_with_index.map do |att, index|
|
346
|
+
process_single_csv(att, index)
|
347
|
+
end.compact
|
348
|
+
end
|
349
|
+
|
350
|
+
def process_single_csv(attachment, index)
|
351
|
+
sheet_name = "Sheet#{index + 1}"
|
352
|
+
sheet = @xfile.workbook.add_worksheet(name: sheet_name)
|
353
|
+
|
354
|
+
File.open(attachment.attachment_url) do |file|
|
355
|
+
first_line = file.readline.chomp
|
356
|
+
next unless cv_spc?(first_line)
|
357
|
+
|
358
|
+
process_csv_content(first_line, file, sheet)
|
359
|
+
end
|
360
|
+
[sheet_name, attachment.filename]
|
361
|
+
end
|
362
|
+
|
363
|
+
def process_csv_content(first_line, file, sheet)
|
364
|
+
lines = []
|
365
|
+
file.each_line.with_index do |line, index|
|
366
|
+
line = first_line if index.zero?
|
367
|
+
row_data = line.split(',')
|
368
|
+
sheet.add_row(row_data)
|
369
|
+
lines << row_data if cv_data?(row_data, index)
|
370
|
+
end
|
371
|
+
@spectra_values << lines if lines.any?
|
372
|
+
end
|
373
|
+
|
374
|
+
def create_mapping_sheet(name_mapping)
|
375
|
+
first_sheet = @xfile.workbook.worksheets&.first
|
376
|
+
return unless first_sheet
|
377
|
+
|
378
|
+
header_style = create_header_style(first_sheet)
|
379
|
+
first_sheet.add_row(['Sheet name', 'File name'], style: header_style)
|
380
|
+
|
381
|
+
name_mapping.each do |sheet_name, filename|
|
382
|
+
first_sheet.add_row([sheet_name.to_s, filename.to_s])
|
383
|
+
end
|
384
|
+
end
|
385
|
+
|
386
|
+
|
387
|
+
def create_header_style(sheet)
|
388
|
+
sheet.styles.add_style(
|
389
|
+
sz: 12,
|
390
|
+
fg_color: 'FFFFFF',
|
391
|
+
bg_color: '00008B',
|
392
|
+
border: {
|
393
|
+
style: :thick,
|
394
|
+
color: 'FF777777',
|
395
|
+
edges: [:bottom]
|
396
|
+
}
|
397
|
+
)
|
398
|
+
end
|
399
|
+
|
128
400
|
def opt_value(field, options)
|
129
401
|
return nil if field.nil? || options.nil? || field['value']&.empty? || field['option_layers']&.empty?
|
130
402
|
return nil unless opts = options.fetch(field['option_layers'], nil)&.fetch('options', nil)
|
@@ -136,45 +408,18 @@ module Labimotion
|
|
136
408
|
field['value']
|
137
409
|
end
|
138
410
|
|
139
|
-
def
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
cds = Container.find(id)
|
144
|
-
cds_csv = cds.attachments.where(aasm_state: 'csv').order(:filename)
|
145
|
-
csv_length = cds_csv.length
|
146
|
-
return if csv_length.zero?
|
147
|
-
cds_csv.each_with_index do |att, idx|
|
148
|
-
sheet_name = "Sheet#{idx+1}"
|
149
|
-
sheet = @xfile.workbook.add_worksheet(name: sheet_name)
|
150
|
-
name_mapping.push([sheet_name, att.filename])
|
151
|
-
File.open(att.attachment_url) do |fi|
|
152
|
-
fi.each_line do |line|
|
153
|
-
sheet.add_row(line.split(','))
|
154
|
-
end
|
155
|
-
end
|
156
|
-
end
|
157
|
-
|
158
|
-
if name_mapping.length > 1
|
159
|
-
first_sheet = @xfile.workbook.worksheets&.first
|
160
|
-
header_style = first_sheet&.styles.add_style(sz: 12, fg_color: 'FFFFFF', bg_color: '00008B', border: { style: :thick, color: 'FF777777', edges: [:bottom] })
|
161
|
-
first_sheet&.add_row(['Sheet name', 'File name'], style: header_style)
|
162
|
-
name_mapping&.each do |mapping|
|
163
|
-
next if mapping.length < 2
|
164
|
-
|
165
|
-
@xfile.workbook.worksheets&.first&.add_row([mapping[0].to_s, mapping[1].to_s])
|
166
|
-
end
|
167
|
-
end
|
411
|
+
def cv_spc?(first_line)
|
412
|
+
data = first_line.split(',')
|
413
|
+
data && data.length > 2 && data[2] == Constants::CHMO::CV
|
414
|
+
end
|
168
415
|
|
416
|
+
def cv_data?(data, idx)
|
417
|
+
data.length > 7 && idx > 7
|
169
418
|
end
|
170
419
|
|
171
420
|
def header
|
172
421
|
['Layer Label', 'Field Label', 'Value', 'Unit', 'Name', 'Type', 'Source?', 'Source identifier', 'Source data', 'Ontology', 'Ontology Label', 'iri'].freeze
|
173
422
|
end
|
174
423
|
|
175
|
-
def read
|
176
|
-
@xfile.to_stream.read
|
177
|
-
end
|
178
|
-
|
179
424
|
end
|
180
425
|
end
|