labimotion 2.2.0.rc15 → 2.2.0.rc17
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/labimotion_api.rb +1 -0
- data/lib/labimotion/apis/wellplate_api.rb +60 -0
- data/lib/labimotion/libs/data/mapper/Source.json +4 -2
- data/lib/labimotion/models/elements_wellplate.rb +10 -0
- data/lib/labimotion/utils/mapper_utils.rb +55 -4
- data/lib/labimotion/version.rb +1 -1
- data/lib/labimotion.rb +2 -0
- metadata +4 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1c5a8e890d23ca465b50fcb79e7cb437d2cbecada3141b42cbbf288c5bde00ff
|
|
4
|
+
data.tar.gz: df0c4bca0642d4d29cd9844088a7a2bd656fb240c1e573e63a366bd26a3bff36
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2b1522bf995bf6d7ecc88b5f80d2c4c24bed210501cd328a79e91d07bdeda984c51aca9259f5f70b80588f6b43e19b8eb090634071b6c2ae8fd2f08481099fe2
|
|
7
|
+
data.tar.gz: df75a698a49478ae259c64bbfc854ad855ad8ed3fe096225a5bcd4a0390ebca6f04b0ccb82122d58f689d675b4b5d07dcaa3d107d35ba1ae6a3f9e9b81c6ad10
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Labimotion
|
|
4
|
+
# API for wellplates linked to a generic element
|
|
5
|
+
class WellplateAPI < Grape::API
|
|
6
|
+
resource :wellplates do
|
|
7
|
+
namespace :by_generic_element do
|
|
8
|
+
desc 'Get wellplates for a generic element'
|
|
9
|
+
params do
|
|
10
|
+
requires :element_id, type: Integer, desc: 'Generic element id'
|
|
11
|
+
end
|
|
12
|
+
route_param :element_id do
|
|
13
|
+
get do
|
|
14
|
+
element = Labimotion::Element.find_by(id: params[:element_id])
|
|
15
|
+
error!('404 Not Found', 404) unless element
|
|
16
|
+
error!('401 Unauthorized', 401) unless ElementPolicy.new(current_user, element).read?
|
|
17
|
+
|
|
18
|
+
wellplate_ids = Labimotion::ElementsWellplate.where(element_id: element.id).pluck(:wellplate_id)
|
|
19
|
+
wellplates = Wellplate.where(id: wellplate_ids)
|
|
20
|
+
.includes(:wells, wells: :sample)
|
|
21
|
+
|
|
22
|
+
serialized_wellplates = wellplates.map do |wellplate|
|
|
23
|
+
detail_levels = ElementDetailLevelCalculator.new(user: current_user, element: wellplate).detail_levels
|
|
24
|
+
Entities::WellplateEntity.represent(wellplate, detail_levels: detail_levels)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
{ wellplates: serialized_wellplates }
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
desc 'Update wellplates for a generic element'
|
|
31
|
+
params do
|
|
32
|
+
requires :wellplate_ids, type: Array, desc: 'Wellplate IDs'
|
|
33
|
+
end
|
|
34
|
+
put do
|
|
35
|
+
element = Labimotion::Element.find_by(id: params[:element_id])
|
|
36
|
+
error!('404 Not Found', 404) unless element
|
|
37
|
+
error!('401 Unauthorized', 401) unless ElementPolicy.new(current_user, element).update?
|
|
38
|
+
|
|
39
|
+
ActiveRecord::Base.transaction do
|
|
40
|
+
current_ids = Labimotion::ElementsWellplate.where(element_id: element.id).pluck(:wellplate_id)
|
|
41
|
+
new_ids = params[:wellplate_ids] || []
|
|
42
|
+
|
|
43
|
+
ids_to_remove = current_ids - new_ids
|
|
44
|
+
if ids_to_remove.any?
|
|
45
|
+
Labimotion::ElementsWellplate.where(element_id: element.id, wellplate_id: ids_to_remove).destroy_all
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
ids_to_add = new_ids - current_ids
|
|
49
|
+
ids_to_add.each do |wellplate_id|
|
|
50
|
+
Labimotion::ElementsWellplate.create!(element_id: element.id, wellplate_id: wellplate_id)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
{ wellplate_ids: Labimotion::ElementsWellplate.where(element_id: element.id).pluck(:wellplate_id) }
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
@@ -9,7 +9,6 @@
|
|
|
9
9
|
"file": "acqus",
|
|
10
10
|
"parameters": [
|
|
11
11
|
"DATE",
|
|
12
|
-
"D1",
|
|
13
12
|
"INSTRUM",
|
|
14
13
|
"NS",
|
|
15
14
|
"NUC1",
|
|
@@ -23,7 +22,10 @@
|
|
|
23
22
|
"TD",
|
|
24
23
|
"TE",
|
|
25
24
|
"TITLE"
|
|
26
|
-
]
|
|
25
|
+
],
|
|
26
|
+
"arrayParameters": {
|
|
27
|
+
"D1": { "name": "D", "index": 1 }
|
|
28
|
+
}
|
|
27
29
|
},
|
|
28
30
|
"procs": {
|
|
29
31
|
"file": "pdata/1/procs",
|
|
@@ -70,6 +70,37 @@ module Labimotion
|
|
|
70
70
|
extracted_parameters
|
|
71
71
|
end
|
|
72
72
|
|
|
73
|
+
# Extracts scalar values from Bruker array parameters such as
|
|
74
|
+
# ##$D= (0..63)
|
|
75
|
+
# 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0002 ...
|
|
76
|
+
# where the values live on the line(s) following the header. The config maps
|
|
77
|
+
# each output key to an array name + index, e.g.
|
|
78
|
+
# { "D1" => { "name" => "D", "index" => 1 } } => D1 = the 2nd value (here 1).
|
|
79
|
+
def extract_array_parameters(file_content, array_parameters)
|
|
80
|
+
return {} if file_content.blank? || array_parameters.blank?
|
|
81
|
+
|
|
82
|
+
lines = file_content.lines
|
|
83
|
+
extracted = {}
|
|
84
|
+
lines.each_with_index do |line, idx|
|
|
85
|
+
header = line.match(/^\s*##\$(?<name>[A-Za-z0-9_]+)\s*=\s*\(\s*\d+\s*\.\.\s*\d+\s*\)/)
|
|
86
|
+
next unless header
|
|
87
|
+
|
|
88
|
+
targets = array_parameters.select { |_key, cfg| cfg['name'] == header[:name] }
|
|
89
|
+
next if targets.empty?
|
|
90
|
+
|
|
91
|
+
values = collect_array_values(lines, idx + 1)
|
|
92
|
+
targets.each do |out_key, cfg|
|
|
93
|
+
value = values[cfg['index'].to_i]
|
|
94
|
+
extracted[out_key] = clean_value(value) if value.present?
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
extracted.compact_blank!
|
|
98
|
+
extracted
|
|
99
|
+
rescue StandardError => e
|
|
100
|
+
Rails.logger.error "Error extracting array parameters: #{e.message}"
|
|
101
|
+
{}
|
|
102
|
+
end
|
|
103
|
+
|
|
73
104
|
def format_timestamp(timestamp_str, give_format = nil)
|
|
74
105
|
return nil if timestamp_str.blank?
|
|
75
106
|
|
|
@@ -118,6 +149,21 @@ module Labimotion
|
|
|
118
149
|
value
|
|
119
150
|
end
|
|
120
151
|
|
|
152
|
+
# Collects whitespace-separated values from the line(s) following an array
|
|
153
|
+
# header, stopping at the next directive (line starting with '##') or a blank line.
|
|
154
|
+
def collect_array_values(lines, start_index)
|
|
155
|
+
values = []
|
|
156
|
+
index = start_index
|
|
157
|
+
while index < lines.length
|
|
158
|
+
stripped = lines[index].strip
|
|
159
|
+
break if stripped.empty? || stripped.start_with?('##')
|
|
160
|
+
|
|
161
|
+
values.concat(stripped.split(/\s+/))
|
|
162
|
+
index += 1
|
|
163
|
+
end
|
|
164
|
+
values
|
|
165
|
+
end
|
|
166
|
+
|
|
121
167
|
def process_zip_file(zip_file_url, source_map)
|
|
122
168
|
final_parameters = {}
|
|
123
169
|
|
|
@@ -137,23 +183,28 @@ module Labimotion
|
|
|
137
183
|
|
|
138
184
|
zip_file.each do |entry|
|
|
139
185
|
if source_file?(entry, source_config)
|
|
140
|
-
process_file_entry(entry, source_config
|
|
186
|
+
process_file_entry(entry, source_config, final_parameters)
|
|
141
187
|
elsif bagit_metadata_file?(entry)
|
|
142
188
|
return { is_bagit: true, metadata: nil }
|
|
143
189
|
end
|
|
144
190
|
end
|
|
145
191
|
end
|
|
146
192
|
|
|
147
|
-
def process_file_entry(entry,
|
|
193
|
+
def process_file_entry(entry, source_config, final_parameters)
|
|
148
194
|
file_content = entry.get_input_stream.read.force_encoding(Constants::File::ENCODING)
|
|
149
|
-
extracted_parameters = extract_parameters(file_content, parameters)
|
|
195
|
+
extracted_parameters = extract_parameters(file_content, source_config['parameters'])
|
|
150
196
|
final_parameters.merge!(extracted_parameters) if extracted_parameters.present?
|
|
197
|
+
|
|
198
|
+
# Array parameters (e.g. D1 from acqus ##$D) are a fallback: they only fill a
|
|
199
|
+
# value that an earlier/higher-priority source (e.g. parm.txt D1) did not provide.
|
|
200
|
+
array_parameters = extract_array_parameters(file_content, source_config['arrayParameters'])
|
|
201
|
+
final_parameters.reverse_merge!(array_parameters) if array_parameters.present?
|
|
151
202
|
end
|
|
152
203
|
|
|
153
204
|
def invalid_source_config?(source_config)
|
|
154
205
|
source_config.nil? ||
|
|
155
206
|
source_config['file'].nil? ||
|
|
156
|
-
source_config['parameters'].nil?
|
|
207
|
+
(source_config['parameters'].nil? && source_config['arrayParameters'].nil?)
|
|
157
208
|
end
|
|
158
209
|
|
|
159
210
|
def source_file?(entry, source_config)
|
data/lib/labimotion/version.rb
CHANGED
data/lib/labimotion.rb
CHANGED
|
@@ -32,6 +32,7 @@ module Labimotion
|
|
|
32
32
|
autoload :ElementVariationAPI, 'labimotion/apis/element_variation_api'
|
|
33
33
|
autoload :LabimotionDoiAPI, 'labimotion/apis/labimotion_doi_api'
|
|
34
34
|
autoload :LabimotionTemplateBrowseAPI, 'labimotion/apis/labimotion_template_browse_api'
|
|
35
|
+
autoload :WellplateAPI, 'labimotion/apis/wellplate_api'
|
|
35
36
|
|
|
36
37
|
######## Entities
|
|
37
38
|
autoload :PropertiesEntity, 'labimotion/entities/properties_entity'
|
|
@@ -123,6 +124,7 @@ module Labimotion
|
|
|
123
124
|
|
|
124
125
|
autoload :ElementsSample, 'labimotion/models/elements_sample'
|
|
125
126
|
autoload :ElementsElement, 'labimotion/models/elements_element'
|
|
127
|
+
autoload :ElementsWellplate, 'labimotion/models/elements_wellplate'
|
|
126
128
|
autoload :CollectionsElement, 'labimotion/models/collections_element'
|
|
127
129
|
|
|
128
130
|
autoload :StdLayer, 'labimotion/models/std_layer'
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: labimotion
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.2.0.
|
|
4
|
+
version: 2.2.0.rc17
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Chia-Lin Lin
|
|
@@ -9,7 +9,7 @@ authors:
|
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date: 2026-06-
|
|
12
|
+
date: 2026-06-30 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: caxlsx
|
|
@@ -73,6 +73,7 @@ files:
|
|
|
73
73
|
- lib/labimotion/apis/standard_layer_api.rb
|
|
74
74
|
- lib/labimotion/apis/user_api.rb
|
|
75
75
|
- lib/labimotion/apis/vocabulary_api.rb
|
|
76
|
+
- lib/labimotion/apis/wellplate_api.rb
|
|
76
77
|
- lib/labimotion/collection/export.rb
|
|
77
78
|
- lib/labimotion/collection/import.rb
|
|
78
79
|
- lib/labimotion/conf.rb
|
|
@@ -150,6 +151,7 @@ files:
|
|
|
150
151
|
- lib/labimotion/models/elements_element.rb
|
|
151
152
|
- lib/labimotion/models/elements_revision.rb
|
|
152
153
|
- lib/labimotion/models/elements_sample.rb
|
|
154
|
+
- lib/labimotion/models/elements_wellplate.rb
|
|
153
155
|
- lib/labimotion/models/hub_log.rb
|
|
154
156
|
- lib/labimotion/models/reaction.rb
|
|
155
157
|
- lib/labimotion/models/research_plan.rb
|