labimotion 2.3.0.rc6 → 2.3.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7f03974c2c4a8918a74bd6ff6ae9eb077e0ad38507f716b5fc952792d12bb3d3
4
- data.tar.gz: f00fb94a263cb13172fea15710f616fa851ccfc233c576ede27a5b8cf23a9923
3
+ metadata.gz: 50d1572a0d16e5ac73fdf5aa6a22e5188c9fd2f008c671fc9705a310fbd090ac
4
+ data.tar.gz: 85631425352102b56f1c0c9998710c0e9af6c4f416b272cee3e05cffd6c4209e
5
5
  SHA512:
6
- metadata.gz: ca257450ec28948d51ea014423c9caed27df2d10d187d7b7eab45d92a34fa9c2e66ede32fe27badcc9aab58f8dea92c0fe6691cf65cb2032982b6604829a7c52
7
- data.tar.gz: ed06f0529322828dbf24473e0d3a7775800c8d960253491af35f0525c0586358e642faf05d71e8a36406cd8da3244304d8cde1e652a659f809d4537a15f8413d
6
+ metadata.gz: a8d4af5906da69a5ce49e100fb5ac4d63ea399bd4cc587af58dff73b2563eebe196d7658aa0257665b439be486b5f1d2bc851226bc265cd14b309e04120ae842
7
+ data.tar.gz: 57e90440bc487d8fc950bb408e5c8794fa0566bad76d3a731f3cc92460623234a4893fdd1f6e61ed9f2730a1ec2b045b78ff940556fa49f6e92a6bc73c7475e6
@@ -28,5 +28,11 @@ module Labimotion
28
28
  DATASET = 'DatasetKlass'
29
29
  ALL = [ELEMENT, SEGMENT, DATASET].freeze
30
30
  end
31
+
32
+ module Tpa
33
+ # Segments and layers sent along with reaction variations to a third-party
34
+ # app (see ExportTpaSegments), as segment-klass label => layer keys.
35
+ SEGMENT_LAYERS = { 'Mol interactions' => %w[binding_props bind_partners].freeze }.freeze
36
+ end
31
37
  end
32
38
  end
@@ -29,7 +29,10 @@ module Labimotion
29
29
  dsr = []
30
30
  ols = nil
31
31
  Zip::File.open(att.attachment_attacher.file.url) do |zip_file|
32
- res = Labimotion::Converter.collect_metadata(zip_file, current_user) if att.filename.split('.')&.last == 'zip'
32
+ if att.filename.split('.')&.last == 'zip'
33
+ res = Labimotion::Converter.collect_metadata(zip_file, current_user)
34
+ Labimotion::Converter.collect_reaction_converter_metadata(att, zip_file)
35
+ end
33
36
  ols = res[:o] unless res&.dig(:o).nil?
34
37
  dsr.push(res[:d]) unless res&.dig(:d).nil?
35
38
  end
@@ -93,6 +96,33 @@ module Labimotion
93
96
  { a: oa, f: folder }
94
97
  end
95
98
 
99
+ def self.collect_reaction_converter_metadata(oat, zip_file)
100
+ zip_file.each do |entry|
101
+ next unless entry.name == 'metadata/reaction_variation.json'
102
+
103
+ # Create temp file
104
+ tmp_file = Tempfile.new(['reaction_variation', '.json'])
105
+ tmp_file.binmode
106
+
107
+ # Write ZIP entry content into temp file
108
+ entry.extract(tmp_file.path) { true }
109
+
110
+ # Create attachment
111
+ att = Attachment.create!(
112
+ filename: 'reaction_variation.json',
113
+ file_path: tmp_file.path,
114
+ content_type: 'application/json',
115
+ attachable_id: oat.attachable_id,
116
+ attachable_type: 'Container',
117
+ con_state: Labimotion::ConState::CONVERTED,
118
+ created_by: oat.created_by,
119
+ created_for: oat.created_for
120
+ )
121
+
122
+ att.save! if att.valid?
123
+ end
124
+ end
125
+
96
126
  def self.collect_metadata(zip_file, current_user = {}) # rubocop: disable Metrics/PerceivedComplexity
97
127
  dsr = []
98
128
  ols = nil
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'labimotion/constants'
4
+
5
+ module Labimotion
6
+ ## ExportTpaSegments
7
+ # Builds the `segment` section of the reaction-variations payload handed to a
8
+ # third-party app (TPA). Segment values are element-wide -- one set per
9
+ # element, not per variation -- so they travel once, next to the variations.
10
+ #
11
+ # Only the segments and layers named in `segment_layers` (by default
12
+ # Constants::Tpa::SEGMENT_LAYERS) are exported, each field reduced to what the
13
+ # app needs:
14
+ #
15
+ # { "<segment klass label>" => { "<layer key>" => { "<field>" => { label:, value:, unit:, type: } } } }
16
+ #
17
+ # A segment the element does not carry, or a layer its segment does not carry,
18
+ # is left out.
19
+ class ExportTpaSegments
20
+ # Mirrors Labimotion::Prop::LAYERS / ::FIELDS. Held locally because
21
+ # requiring `labimotion/utils/prop` here would race the gem's autoload.
22
+ LAYERS = 'layers'
23
+ FIELDS = 'fields'
24
+
25
+ class << self
26
+ def call(element, segment_layers: Labimotion::Constants::Tpa::SEGMENT_LAYERS)
27
+ segment_layers.each_with_object({}) do |(segment_label, layer_keys), payload|
28
+ segment = element.segments.detect { |s| s.segment_klass&.label == segment_label }
29
+ next unless segment
30
+
31
+ payload[segment_label] = layers(segment, layer_keys)
32
+ end
33
+ end
34
+
35
+ private
36
+
37
+ def layers(segment, layer_keys)
38
+ stored = segment.properties&.dig(LAYERS) || {}
39
+ Array(layer_keys).each_with_object({}) do |layer_key, acc|
40
+ layer = stored[layer_key]
41
+ acc[layer_key] = fields(layer) if layer
42
+ end
43
+ end
44
+
45
+ def fields(layer)
46
+ Array(layer[FIELDS]).to_h do |field|
47
+ [field['field'],
48
+ { label: field['label'], value: field['value'], unit: field['value_system'], type: field['type'] }]
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -41,9 +41,10 @@ module Labimotion
41
41
 
42
42
  def process(att)
43
43
  config = Labimotion::MapperUtils.load_brucker_config
44
- return if config.nil?
45
-
46
44
  attacher = att&.attachment_attacher
45
+ return Labimotion::MapperUtils.check_if_bagit(attacher&.file&.url) if config.nil?
46
+
47
+
47
48
  extracted_data = Labimotion::MapperUtils.extract_data_from_zip(attacher&.file&.url, config['sourceMap'])
48
49
  return if extracted_data.nil?
49
50
 
@@ -46,6 +46,22 @@ module Labimotion
46
46
  nil
47
47
  end
48
48
 
49
+ def check_if_bagit(zip_file_url)
50
+ return nil if zip_file_url.nil?
51
+ Zip::File.open(zip_file_url) do |zip_file|
52
+ zip_file.each do |entry|
53
+ return { is_bagit: true, metadata: nil } if bagit_metadata_file?(entry)
54
+ end
55
+ end
56
+
57
+ rescue Zip::Error => e
58
+ Rails.logger.error "Zip file error: #{e.message}"
59
+ nil
60
+ rescue StandardError => e
61
+ Rails.logger.error "Unexpected error extracting metadata: #{e.message}"
62
+ nil
63
+ end
64
+
49
65
  def extract_parameters(file_content, parameter_names)
50
66
  return nil if file_content.blank? || parameter_names.blank?
51
67
 
@@ -9,7 +9,7 @@ module Labimotion
9
9
  "default": "",
10
10
  "position": 10,
11
11
  "placeholder": "acceleration",
12
- "units": [{ "key": "mm_s2", "label": "mm/s<sup>2</sup>" }]
12
+ "units": [{ "key": "mm_s2", "label": "mm/s²" }]
13
13
  },
14
14
  {
15
15
  "type": "numeric",
@@ -59,10 +59,10 @@ module Labimotion
59
59
  "position": 38,
60
60
  "placeholder": "areal density",
61
61
  "units": [
62
- { "key": "kg_m2", "label": "kg m<sup>-2</sup>", "nm": 1 },
63
- { "key": "t_m2", "label": "t m<sup>-2</sup>", "nm": 0.001 },
64
- { "key": "kg_cm2", "label": "kg cm<sup>-2</sup>", "nm": 1e-4 },
65
- { "key": "g_m2", "label": "g m<sup>-2</sup>", "nm": 1000 }
62
+ { "key": "kg_m2", "label": "kg m⁻²", "nm": 1 },
63
+ { "key": "t_m2", "label": "t m⁻²", "nm": 0.001 },
64
+ { "key": "kg_cm2", "label": "kg cm⁻²", "nm": 1e-4 },
65
+ { "key": "g_m2", "label": "g m⁻²", "nm": 1000 }
66
66
  ]
67
67
  },
68
68
  {
@@ -97,7 +97,7 @@ module Labimotion
97
97
  "position": 60,
98
98
  "placeholder": "concentration",
99
99
  "units": [
100
- { "key": "ng_l", "label": "ng/L", "nm": 1000000 },
100
+ { "key": "ng_l", "label": "ng/L", "nm": 1000000000 },
101
101
  { "key": "mg_l", "label": "mg/L", "nm": 1000 },
102
102
  { "key": "g_l", "label": "g/L", "nm": 1 }
103
103
  ]
@@ -171,7 +171,7 @@ module Labimotion
171
171
  "position": 75,
172
172
  "placeholder": "density",
173
173
  "units": [
174
- { "key": "g_cm3", "label": "g/cm<sup>3</sup>", "nm": 1 },
174
+ { "key": "g_cm3", "label": "g/cm³", "nm": 1 },
175
175
  { "key": "kg_l", "label": "kg/l", "nm": 1 }
176
176
  ]
177
177
  },
@@ -198,7 +198,8 @@ module Labimotion
198
198
  { "key": "d", "label": "d", "nm": 1 },
199
199
  { "key": "h", "label": "h", "nm": 24 },
200
200
  { "key": "min", "label": "m", "nm": 1440 },
201
- { "key": "s", "label": "s", "nm": 86400 }
201
+ { "key": "s", "label": "s", "nm": 86400 },
202
+ { "key": "y", "label": "y", "nm": 0.0027378507871321013 }
202
203
  ]
203
204
  },
204
205
  {
@@ -280,7 +281,8 @@ module Labimotion
280
281
  { "key": "eV", "label": "eV", "nm": 6.241509e21 },
281
282
  { "key": "keV", "label": "keV", "nm": 6.241509e18 },
282
283
  { "key": "j", "label": "J", "nm": 1000 },
283
- { "key": "k_j", "label": "kJ", "nm": 1 }
284
+ { "key": "k_j", "label": "kJ", "nm": 1 },
285
+ { "key": "kWh", "label": "kWh", "nm": 2.7777778e-4 }
284
286
  ]
285
287
  },
286
288
  {
@@ -357,9 +359,9 @@ module Labimotion
357
359
  { "key": "k_min", "label": "K/min", "nm": 1 },
358
360
  { "key": "k_s", "label": "K/s", "nm": 0.016666666666667 },
359
361
  { "key": "k_h", "label": "K/h", "nm": 60 },
360
- { "key": "degc_min", "label": "°C min<sup>-1</sup>", "nm": 1 },
361
- { "key": "degc_s", "label": "°C s<sup>-1</sup>", "nm": 0.016666666666667 },
362
- { "key": "degc_h", "label": "°C h<sup>-1</sup>", "nm": 60 }
362
+ { "key": "degc_min", "label": "°C min⁻¹", "nm": 1 },
363
+ { "key": "degc_s", "label": "°C s⁻¹", "nm": 0.016666666666667 },
364
+ { "key": "degc_h", "label": "°C h⁻¹", "nm": 60 }
363
365
  ]
364
366
  },
365
367
  {
@@ -394,7 +396,23 @@ module Labimotion
394
396
  "units": [
395
397
  { "key": "g", "label": "g", "nm": 1 },
396
398
  { "key": "mg", "label": "mg", "nm": 1000 },
397
- { "key": "ug", "label": "µg", "nm": 1000000 }
399
+ { "key": "ug", "label": "µg", "nm": 1000000 },
400
+ { "key": "kg", "label": "kg", "nm": 0.001 }
401
+ ]
402
+ },
403
+ {
404
+ "type": "numeric",
405
+ "field": "mass_flow",
406
+ "label": "Mass flow",
407
+ "default": "",
408
+ "position": 121,
409
+ "placeholder": "mass flow",
410
+ "units": [
411
+ { "key": "g_min", "label": "g/min", "nm": 1 },
412
+ { "key": "kg_h", "label": "kg/h", "nm": 0.06 },
413
+ { "key": "kg_s", "label": "kg/s", "nm": 0.000016666666666667 },
414
+ { "key": "g_s", "label": "g/s", "nm": 0.016666666666667 },
415
+ { "key": "mg_s", "label": "mg/s", "nm": 16.666666666667 }
398
416
  ]
399
417
  },
400
418
  {
@@ -416,8 +434,8 @@ module Labimotion
416
434
  "position": 125,
417
435
  "placeholder": "mass loading",
418
436
  "units": [
419
- { "key": "g_cm2", "label": "g cm<sup>-2</sup>", "nm": 1 },
420
- { "key": "mg_cm2", "label": "mg cm<sup>-2</sup>", "nm": 1000 }
437
+ { "key": "g_cm2", "label": "g cm⁻²", "nm": 1 },
438
+ { "key": "mg_cm2", "label": "mg cm⁻²", "nm": 1000 }
421
439
  ]
422
440
  },
423
441
  {
@@ -440,7 +458,7 @@ module Labimotion
440
458
  "position": 127,
441
459
  "placeholder": "molar conductivity",
442
460
  "units": [
443
- { "key": "s_cm2_mol", "label": "S cm<sup>2</sup> mol<sup>-1</sup>", "nm": 1 }
461
+ { "key": "s_cm2_mol", "label": "S cm² mol⁻¹", "nm": 1 }
444
462
  ]
445
463
  },
446
464
  {
@@ -492,6 +510,7 @@ module Labimotion
492
510
  { "key": "atm", "label": "atm", "nm": 1 },
493
511
  { "key": "pa", "label": "Pa", "nm": 101325 },
494
512
  { "key": "kpa", "label": "kPa", "nm": 101.325 },
513
+ { "key": "mpa", "label": "MPa", "nm": 0.101325 },
495
514
  { "key": "hpa", "label": "hPa", "nm": 1013.25 },
496
515
  { "key": "torr", "label": "Torr", "nm": 760 },
497
516
  { "key": "bar", "label": "bar", "nm": 1.01325 },
@@ -530,8 +549,8 @@ module Labimotion
530
549
  "position": 150,
531
550
  "placeholder": "Reaction rate",
532
551
  "units": [
533
- { "key": "mol_lmin", "label": "mol L<sup>-1</sup> min<sup>-1</sup>", "nm": 1 },
534
- { "key": "mol_lsec", "label": "mol L<sup>-1</sup> s<sup>-1</sup>", "nm": 0.016666666666667 }
552
+ { "key": "mol_lmin", "label": "mol L⁻¹ min⁻¹", "nm": 1 },
553
+ { "key": "mol_lsec", "label": "mol L⁻¹ s⁻¹", "nm": 0.016666666666667 }
535
554
  ]
536
555
  },
537
556
  {
@@ -558,6 +577,22 @@ module Labimotion
558
577
  { "key": "v_s", "label": "V/s", "nm": 1 }
559
578
  ]
560
579
  },
580
+ {
581
+ "type": "numeric",
582
+ "field": "space_time_yield",
583
+ "label": "Space-time yield",
584
+ "default": "",
585
+ "position": 156,
586
+ "placeholder": "space-time yield",
587
+ "units": [
588
+ { "key": "kg_m3_d", "label": "kg/(m³*d)", "nm": 1 },
589
+ { "key": "kg_m3_h", "label": "kg/(m³*h)", "nm": 0.041666666666667 },
590
+ { "key": "g_l_h", "label": "g/(L*h)", "nm": 0.041666666666667 },
591
+ { "key": "mg_ml_h", "label": "mg/(mL*h)", "nm": 0.041666666666667 },
592
+ { "key": "g_l_min", "label": "g/(L*min)", "nm": 0.00069444444444444 },
593
+ { "key": "g_m3_s", "label": "g/(m³*s)", "nm": 0.011574074074074 }
594
+ ]
595
+ },
561
596
  {
562
597
  "type": "numeric",
563
598
  "field": "specific_current",
@@ -568,9 +603,9 @@ module Labimotion
568
603
  "units": [
569
604
  { "key": "ma_g", "label": "mA/g", "nm": 1000, "unit_type": "mass" },
570
605
  { "key": "a_g", "label": "A/g", "nm": 1, "unit_type": "mass" },
571
- { "key": "ma_cm2", "label": "mA/cm<sup>2</sup>", "nm": 1000, "unit_type": "area" },
572
- { "key": "a_cm2", "label": "A/cm<sup>2</sup>", "nm": 1, "unit_type": "area" },
573
- { "key": "a_mm2", "label": "A/mm<sup>2</sup>", "nm": 0.01, "unit_type": "area" }
606
+ { "key": "ma_cm2", "label": "mA/cm²", "nm": 1000, "unit_type": "area" },
607
+ { "key": "a_cm2", "label": "A/cm²", "nm": 1, "unit_type": "area" },
608
+ { "key": "a_mm2", "label": "A/mm²", "nm": 0.01, "unit_type": "area" }
574
609
  ]
575
610
  },
576
611
  {
@@ -593,7 +628,7 @@ module Labimotion
593
628
  "position": 158,
594
629
  "placeholder": "Specific surface area",
595
630
  "units": [
596
- { "key": "m2_g", "label": "m<sup>2</sup>/g", "nm": 1 }
631
+ { "key": "m2_g", "label": "m²/g", "nm": 1 }
597
632
  ]
598
633
  },
599
634
  {
@@ -603,7 +638,7 @@ module Labimotion
603
638
  "default": "",
604
639
  "position": 160,
605
640
  "placeholder": "Specific Volume",
606
- "units": [{ "key": "cm3_g", "label": "cm<sup>3</sup>/g", "nm": 1 }]
641
+ "units": [{ "key": "cm3_g", "label": "cm³/g", "nm": 1 }]
607
642
  },
608
643
  {
609
644
  "type": "numeric",
@@ -642,10 +677,10 @@ module Labimotion
642
677
  "position": 170,
643
678
  "placeholder": "surface",
644
679
  "units": [
645
- { "key": "a_2", "label": "A<sup>2</sup>", "nm": 1.0e16 },
646
- { "key": "um_2", "label": "µm<sup>2</sup>", "nm": 1.0e8 },
647
- { "key": "mm_2", "label": "mm<sup>2</sup>", "nm": 100 },
648
- { "key": "cm_2", "label": "cm<sup>2</sup>", "nm": 1 }
680
+ { "key": "a_2", "label": "A²", "nm": 1.0e16 },
681
+ { "key": "um_2", "label": "µm²", "nm": 1.0e8 },
682
+ { "key": "mm_2", "label": "mm²", "nm": 100 },
683
+ { "key": "cm_2", "label": "cm²", "nm": 1 }
649
684
  ]
650
685
  },
651
686
  {
@@ -682,8 +717,8 @@ module Labimotion
682
717
  "position": 186,
683
718
  "placeholder": "tensile stress",
684
719
  "units": [
685
- { "key": "n_cm2", "label": "N cm<sup>-2</sup>", "nm": 1 },
686
- { "key": "n_mm2", "label": "N mm<sup>-2</sup>", "nm": 0.01 }
720
+ { "key": "n_cm2", "label": "N cm⁻²", "nm": 1 },
721
+ { "key": "n_mm2", "label": "N mm⁻²", "nm": 0.01 }
687
722
  ]
688
723
  },
689
724
  {
@@ -693,7 +728,7 @@ module Labimotion
693
728
  "default": "",
694
729
  "position": 190,
695
730
  "placeholder": "Turnover number",
696
- "units": [{ "key": "1_s", "label": "1/s", "nm": 1 }, { "key": "1_m", "label": "1/m", "nm": 60 }]
731
+ "units": [{ "key": "1_s", "label": "1/s", "nm": 1 }, { "key": "1_m", "label": "1/min", "nm": 60 }]
697
732
  },
698
733
  {
699
734
  "type": "numeric",
@@ -714,7 +749,7 @@ module Labimotion
714
749
  "default": "",
715
750
  "position": 205,
716
751
  "placeholder": "Kinematic Viscosity",
717
- "units": [{ "key": "m2_s", "label": "m<sup>2</sup>/s", "nm": 1 }]
752
+ "units": [{ "key": "m2_s", "label": "m²/s", "nm": 1 }]
718
753
  },
719
754
  {
720
755
  "type": "numeric",
@@ -767,6 +802,6 @@ module Labimotion
767
802
  { "key": "m3", "label": "m³", "nm": 0.000001 }
768
803
  ]
769
804
  }
770
- ]
805
+ ]
771
806
  end
772
807
  end
@@ -2,5 +2,5 @@
2
2
 
3
3
  ## Labimotion Version
4
4
  module Labimotion
5
- VERSION = '2.3.0.rc6'
5
+ VERSION = '2.3.1'
6
6
  end
data/lib/labimotion.rb CHANGED
@@ -96,6 +96,7 @@ module Labimotion
96
96
  autoload :ElementVariationHeader, 'labimotion/libs/element_variation_header'
97
97
  autoload :ExportElementVariations, 'labimotion/libs/export_element_variations'
98
98
  autoload :ImportElementVariations, 'labimotion/libs/import_element_variations'
99
+ autoload :ExportTpaSegments, 'labimotion/libs/export_tpa_segments'
99
100
 
100
101
  ######## Utils
101
102
  autoload :Prop, 'labimotion/utils/prop'
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.3.0.rc6
4
+ version: 2.3.1
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-07-23 00:00:00.000000000 Z
12
+ date: 2026-09-15 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: caxlsx
@@ -135,6 +135,7 @@ files:
135
135
  - lib/labimotion/libs/export_dataset.rb
136
136
  - lib/labimotion/libs/export_element.rb
137
137
  - lib/labimotion/libs/export_element_variations.rb
138
+ - lib/labimotion/libs/export_tpa_segments.rb
138
139
  - lib/labimotion/libs/import_element_variations.rb
139
140
  - lib/labimotion/libs/nmr_mapper.rb
140
141
  - lib/labimotion/libs/properties_handler.rb
@@ -222,9 +223,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
222
223
  version: '3.4'
223
224
  required_rubygems_version: !ruby/object:Gem::Requirement
224
225
  requirements:
225
- - - ">"
226
+ - - ">="
226
227
  - !ruby/object:Gem::Version
227
- version: 1.3.1
228
+ version: '0'
228
229
  requirements: []
229
230
  rubygems_version: 3.1.6
230
231
  signing_key: