Module: Unitsml::Utility
- Defined in:
- lib/unitsml/utility.rb
Constant Summary collapse
- U2D =
Unit to dimension
{ "m" => { dimension: "Length", order: 1, symbol: "L" }, "g" => { dimension: "Mass", order: 2, symbol: "M" }, "kg" => { dimension: "Mass", order: 2, symbol: "M" }, "s" => { dimension: "Time", order: 3, symbol: "T" }, "A" => { dimension: "ElectricCurrent", order: 4, symbol: "I" }, "K" => { dimension: "ThermodynamicTemperature", order: 5, symbol: "Theta" }, "degK" => { dimension: "ThermodynamicTemperature", order: 5, symbol: "Theta" }, "mol" => { dimension: "AmountOfSubstance", order: 6, symbol: "N" }, "cd" => { dimension: "LuminousIntensity", order: 7, symbol: "J" }, "deg" => { dimension: "PlaneAngle", order: 8, symbol: "phi" }, }.freeze
- DIM2D =
Dimesion for dim_(dimesion) input
{ "dim_L" => U2D["m"], "dim_M" => U2D["g"], "dim_T" => U2D["s"], "dim_I" => U2D["A"], "dim_Theta" => U2D["K"], "dim_N" => U2D["mol"], "dim_J" => U2D["cd"], "dim_phi" => U2D["deg"], }.freeze
- DIMS_VECTOR =
%w[ ThermodynamicTemperature AmountOfSubstance LuminousIntensity ElectricCurrent PlaneAngle Length Mass Time ].freeze
- UNKNOWN =
"unknown"- PREFIX_SYMBOL_METHODS =
{ ASCII: :to_asciimath, unicode: :to_unicode, LaTeX: :to_latex, HTML: :to_html, }.freeze
Class Method Summary collapse
- .combine_prefixes(p1, p2) ⇒ Object
- .decompose_unit(u) ⇒ Object
- .decompose_units_list(units) ⇒ Object
- .dim_id(dims) ⇒ Object
- .dimension(norm_text) ⇒ Object
- .dimension1(dim, dims_hash) ⇒ Object
- .dimension_components(dims) ⇒ Object
- .dimid2dimensions(normtext) ⇒ Object
- .float_to_display(float) ⇒ Object
- .format_unit_id(unit, text) ⇒ Object
- .gather_units(units) ⇒ Object
- .html_entity_to_unicode(string) ⇒ Object
- .model_quantity_xml(id, url) ⇒ Object
- .numerator_value(unit_hash, unit_array) ⇒ Object
- .prefix_attributes(prefix, options) ⇒ Object
- .prefix_id(prefix, adapter) ⇒ Object
- .prefix_name(prefix, adapter) ⇒ Object
- .prefix_symbols(prefix, options) ⇒ Object
- .prefix_xml(prefix, options) ⇒ Object
- .prefixes(units, options) ⇒ Object
- .quantity(normtext, instance) ⇒ Object
- .quantity_dimension_id(quantity) ⇒ Object
- .quantity_instance(id) ⇒ Object
- .quantity_name(id) ⇒ Object
- .rootunits(units) ⇒ Object
- .set_to_fence(set) ⇒ Object
- .string_to_html_entity(string) ⇒ Object
- .to_i_value(object) ⇒ Object
- .underscore(str) ⇒ Object
- .unit(units, formula, dims, norm_text, name, options) ⇒ Object
- .unit_dimension_id(unit) ⇒ Object
- .unit_en_name(unit) ⇒ Object
- .unit_id(text) ⇒ Object
- .unit_instance(unit) ⇒ Object
- .unit_nist_id(unit) ⇒ Object
- .unit_numerator_float(object_hash) ⇒ Object
- .unit_or_quantity(unit, quantity) ⇒ Object
- .unitname(text, name) ⇒ Object
- .units2dimensions(units) ⇒ Object
- .unitsymbols(formula, options) ⇒ Object
- .unitsystem(units) ⇒ Object
Class Method Details
.combine_prefixes(p1, p2) ⇒ Object
147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 |
# File 'lib/unitsml/utility.rb', line 147 def combine_prefixes(p1, p2) a1 = PrefixAdapter.wrap(p1) a2 = PrefixAdapter.wrap(p2) return nil if a1.null? && a2.null? return a1.symbolid if a2.null? return a2.symbolid if a1.null? return UNKNOWN if a1.base != a2.base Unitsdb.prefixes_array.each do |prefix_name| candidate = PrefixAdapter.from_name(prefix_name) return candidate.raw if candidate.base == a1.base && candidate.power == a1.power + a2.power end UNKNOWN end |
.decompose_unit(u) ⇒ Object
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 |
# File 'lib/unitsml/utility.rb', line 104 def decompose_unit(u) if u&.unit_name == "g" || Lutaml::Model::Utils.snake_case(u.system_type) == "si_base" { unit: u, prefix: u&.prefix } elsif u.si_derived_bases.nil? || u.si_derived_bases.empty? { unit: Unit.new(UNKNOWN) } else u.si_derived_bases.each_with_object([]) do |k, object| prefix = if k.prefix_reference.nil? u.prefix else combine_prefixes(k.prefix_reference, u.prefix) end unit_name = Unitsdb.units.find_by_id(k.unit_reference.id).symbols.first.id exponent = (k.power&.to_i || 1) * (u.power_numerator&.to_f || 1) object << { prefix: prefix, unit: Unit.new(unit_name, exponent, prefix: prefix) } end end end |
.decompose_units_list(units) ⇒ Object
100 101 102 |
# File 'lib/unitsml/utility.rb', line 100 def decompose_units_list(units) gather_units(units.map { |u| decompose_unit(u) }.flatten) end |
.dim_id(dims) ⇒ Object
78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/unitsml/utility.rb', line 78 def dim_id(dims) return nil if dims.nil? || dims.empty? dim_hash = dims.to_h { |h| [h[:dimension], h] } dims_vector = DIMS_VECTOR.map do |h| dim_hash.dig(h, :exponent) end.join(":") id = Unitsdb.dimensions.find_by_vector(dims_vector)&.id and return id.to_s "D_" + dims.map do |d| (U2D.dig(d[:unit], :symbol) || DIM2D.dig(d[:id], :symbol)) + (to_i_value(d[:exponent]) == 1 ? "" : float_to_display(d[:exponent])) end.join end |
.dimension(norm_text) ⇒ Object
221 222 223 224 225 226 227 228 229 230 231 232 |
# File 'lib/unitsml/utility.rb', line 221 def dimension(norm_text) dim_id = unit_dimension_id(unit_instance(norm_text)) return unless dim_id dim_attrs = { id: dim_id } dimid2dimensions(dim_id)&.compact&.each { |u| dimension1(u, dim_attrs) } xml = Model::Dimension.new( dim_attrs, lutaml_register: Configuration.context.id, ).to_xml xml.force_encoding("UTF-8") end |
.dimension1(dim, dims_hash) ⇒ Object
234 235 236 237 238 239 240 241 242 |
# File 'lib/unitsml/utility.rb', line 234 def dimension1(dim, dims_hash) dim_name = dim[:dimension] dim_klass = Model::DimensionQuantities.const_get(dim_name) dims_hash[underscore(dim_name).to_sym] = dim_klass.new( symbol: dim[:symbol], power_numerator: float_to_display(dim[:exponent]), lutaml_register: Configuration.context.id, ) end |
.dimension_components(dims) ⇒ Object
359 360 361 362 363 364 365 366 367 368 369 |
# File 'lib/unitsml/utility.rb', line 359 def dimension_components(dims) return if dims.nil? || dims.empty? dim_attrs = { id: dim_id(dims) } dims.map { |u| dimension1(u, dim_attrs) } xml = Model::Dimension.new( **dim_attrs, lutaml_register: Configuration.context.id, ).to_xml xml.force_encoding("UTF-8") end |
.dimid2dimensions(normtext) ⇒ Object
253 254 255 256 257 258 259 260 261 262 263 264 265 266 |
# File 'lib/unitsml/utility.rb', line 253 def dimid2dimensions(normtext) dims = Unitsdb.dimensions.find_by_id(normtext) dims&.processed_keys&.map do |processed_key| humanized = processed_key.split("_").map(&:capitalize).join next unless DIMS_VECTOR.include?(humanized) dim_quantity = dims.public_send(processed_key) { dimension: humanized, symbol: dim_quantity.symbol, exponent: dim_quantity.power, } end end |
.float_to_display(float) ⇒ Object
244 245 246 247 248 249 250 251 |
# File 'lib/unitsml/utility.rb', line 244 def float_to_display(float) case float when Integer, Float float.to_f.round(1).to_s.sub(/\.0$/, "") when Number, Fenced float.float_to_display end end |
.format_unit_id(unit, text) ⇒ Object
353 354 355 356 357 |
# File 'lib/unitsml/utility.rb', line 353 def format_unit_id(unit, text) return unit_nist_id(unit)&.gsub("'", "_") if unit text&.gsub("*", ".")&.gsub("^", "") end |
.gather_units(units) ⇒ Object
124 125 126 127 128 129 130 131 132 133 134 135 136 |
# File 'lib/unitsml/utility.rb', line 124 def gather_units(units) units.sort_by { |a| a[:unit]&.unit_name }.each_with_object([]) do |k, m| if m.empty? || m[-1][:unit]&.unit_name != k[:unit]&.unit_name m << k else m[-1][:unit]&.power_numerator = Number.new(numerator_value(k, m)) m[-1] = { prefix: combine_prefixes(m[-1][:prefix], k[:prefix]), unit: m[-1][:unit], } end end end |
.html_entity_to_unicode(string) ⇒ Object
438 439 440 |
# File 'lib/unitsml/utility.rb', line 438 def html_entity_to_unicode(string) HTMLEntities.new.decode(string) end |
.model_quantity_xml(id, url) ⇒ Object
412 413 414 415 416 417 418 419 420 |
# File 'lib/unitsml/utility.rb', line 412 def model_quantity_xml(id, url) xml = Model::Quantity.new( id: id, name: quantity_name(id), dimension_url: url, lutaml_register: Configuration.context.id, ).to_xml xml.force_encoding("UTF-8") end |
.numerator_value(unit_hash, unit_array) ⇒ Object
138 139 140 141 |
# File 'lib/unitsml/utility.rb', line 138 def numerator_value(unit_hash, unit_array) unit_numerator_float(unit_hash) + unit_numerator_float(unit_array[-1]) end |
.prefix_attributes(prefix, options) ⇒ Object
283 284 285 286 287 288 289 290 291 292 |
# File 'lib/unitsml/utility.rb', line 283 def prefix_attributes(prefix, ) adapter = PrefixAdapter.wrap(prefix) { prefix_base: adapter.base, prefix_power: adapter.power, id: prefix_id(prefix, adapter), name: prefix_name(prefix, adapter), symbol: prefix_symbols(prefix, ), } end |
.prefix_id(prefix, adapter) ⇒ Object
294 295 296 297 298 299 300 301 302 |
# File 'lib/unitsml/utility.rb', line 294 def prefix_id(prefix, adapter) if prefix.is_a?(Unitsml::Prefix) prefix.id else adapter.raw&.identifiers&.find do |i| i.type == "nist" end&.id end end |
.prefix_name(prefix, adapter) ⇒ Object
304 305 306 307 308 309 310 311 312 313 314 |
# File 'lib/unitsml/utility.rb', line 304 def prefix_name(prefix, adapter) name_value = if prefix.is_a?(Unitsml::Prefix) prefix.name elsif adapter.raw.is_a?(::Unitsdb::Prefix) adapter.raw.names.find { |n| n.lang == "en" }&.value end Model::Prefixes::Name.new( content: name_value, lutaml_register: Configuration.context.id, ) end |
.prefix_symbols(prefix, options) ⇒ Object
316 317 318 319 320 321 322 323 324 325 |
# File 'lib/unitsml/utility.rb', line 316 def prefix_symbols(prefix, ) adapter = PrefixAdapter.wrap(prefix) PREFIX_SYMBOL_METHODS.map do |type, method_name| Model::Prefixes::Symbol.new( type: type, content: adapter.raw&.public_send(method_name, ), lutaml_register: Configuration.context.id, ) end end |
.prefix_xml(prefix, options) ⇒ Object
275 276 277 278 279 280 281 |
# File 'lib/unitsml/utility.rb', line 275 def prefix_xml(prefix, ) xml = Model::Prefix.new( prefix_attributes(prefix, ), lutaml_register: Configuration.context.id, ).to_xml Xml::Formatter.format_prefix(xml) end |
.prefixes(units, options) ⇒ Object
268 269 270 271 272 273 |
# File 'lib/unitsml/utility.rb', line 268 def prefixes(units, ) uniq_prefixes = units.filter_map(&:prefix).uniq(&:prefix_name) uniq_prefixes.map do |prefix| prefix_xml(prefix, ) end.join("\n") end |
.quantity(normtext, instance) ⇒ Object
371 372 373 374 375 376 377 378 379 |
# File 'lib/unitsml/utility.rb', line 371 def quantity(normtext, instance) unit = unit_instance(normtext) return unless unit_or_quantity(unit, instance) model_quantity_xml( instance || unit.quantity_references&.first&.id, "##{unit_dimension_id(unit)}", ) end |
.quantity_dimension_id(quantity) ⇒ Object
403 404 405 |
# File 'lib/unitsml/utility.rb', line 403 def quantity_dimension_id(quantity) quantity&.dimension_reference&.id end |
.quantity_instance(id) ⇒ Object
57 58 59 |
# File 'lib/unitsml/utility.rb', line 57 def quantity_instance(id) Unitsdb.quantities.find_by_id(id) end |
.quantity_name(id) ⇒ Object
422 423 424 425 426 427 428 429 |
# File 'lib/unitsml/utility.rb', line 422 def quantity_name(id) quantity_instance(id)&.names&.filter_map do |name| next unless name.lang == "en" Model::Quantities::Name.new(content: name.value, lutaml_register: Configuration.context.id) end end |
.rootunits(units) ⇒ Object
327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 |
# File 'lib/unitsml/utility.rb', line 327 def rootunits(units) return if units.size == 1 && !units[0].prefix enum_root_units = units.map do |unit| attributes = { unit: unit.enumerated_name } attributes[:prefix] = unit.prefix_name if unit.prefix unit.power_numerator && unit.power_numerator != "1" and attributes[:power_numerator] = unit.power_numerator.raw_value Model::Units::EnumeratedRootUnit.new( **attributes, lutaml_register: Configuration.context.id, ) end Model::Units::RootUnits.new( enumerated_root_unit: enum_root_units, lutaml_register: Configuration.context.id, ) end |
.set_to_fence(set) ⇒ Object
446 447 448 449 450 |
# File 'lib/unitsml/utility.rb', line 446 def set_to_fence(set) return set if set.is_a?(Fenced) Fenced.new("(", set, ")") end |
.string_to_html_entity(string) ⇒ Object
431 432 433 434 435 436 |
# File 'lib/unitsml/utility.rb', line 431 def string_to_html_entity(string) HTMLEntities.new.encode( string.frozen? ? string : string.force_encoding("UTF-8"), :hexadecimal, ) end |
.to_i_value(object) ⇒ Object
93 94 95 96 97 98 |
# File 'lib/unitsml/utility.rb', line 93 def to_i_value(object) case object when Integer, Float then object when Number, Fenced then object.to_i end end |
.underscore(str) ⇒ Object
442 443 444 |
# File 'lib/unitsml/utility.rb', line 442 def underscore(str) str.gsub(/([a-z])([A-Z])/, '\1_\2').downcase end |
.unit(units, formula, dims, norm_text, name, options) ⇒ Object
164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 |
# File 'lib/unitsml/utility.rb', line 164 def unit(units, formula, dims, norm_text, name, ) attributes = { id: unit_id(norm_text), system: unitsystem(units), name: unitname(norm_text, name), symbol: unitsymbols(formula, ), root_units: rootunits(units), } attributes[:dimension_url] = "##{dim_id(dims)}" if dims xml = Model::Unit.new( **attributes, lutaml_register: Configuration.context.id, ).to_xml Xml::Formatter.format_unit(xml) end |
.unit_dimension_id(unit) ⇒ Object
395 396 397 398 399 400 401 |
# File 'lib/unitsml/utility.rb', line 395 def unit_dimension_id(unit) return unless unit return unit.dimension_url if unit.is_a?(Unitsml::Unitsdb::Unit) unit.dimension_reference&.id || quantity_dimension_id(quantity_instance(unit.quantity_references&.first&.id)) end |
.unit_en_name(unit) ⇒ Object
388 389 390 391 392 393 |
# File 'lib/unitsml/utility.rb', line 388 def unit_en_name(unit) return unless unit return unit.en_name if unit.is_a?(Unitsml::Unitsdb::Unit) unit.names&.find { |name| name.lang == "en" }&.value end |
.unit_id(text) ⇒ Object
346 347 348 349 350 351 |
# File 'lib/unitsml/utility.rb', line 346 def unit_id(text) text = text&.gsub(/[()]/, "") unit = unit_instance(text) format_unit_id(unit, text)&.insert(0, "U_") end |
.unit_instance(unit) ⇒ Object
53 54 55 |
# File 'lib/unitsml/utility.rb', line 53 def unit_instance(unit) Unitsdb.units.find_by_symbol_id(unit) end |
.unit_nist_id(unit) ⇒ Object
381 382 383 384 385 386 |
# File 'lib/unitsml/utility.rb', line 381 def unit_nist_id(unit) return unless unit return unit.nist_id if unit.is_a?(Unitsml::Unitsdb::Unit) unit.identifiers&.find { |identifier| identifier.type == "nist" }&.id end |
.unit_numerator_float(object_hash) ⇒ Object
143 144 145 |
# File 'lib/unitsml/utility.rb', line 143 def unit_numerator_float(object_hash) object_hash[:unit]&.power_numerator&.to_f || 1 end |
.unit_or_quantity(unit, quantity) ⇒ Object
407 408 409 410 |
# File 'lib/unitsml/utility.rb', line 407 def unit_or_quantity(unit, quantity) (unit && unit.quantity_references.size == 1) || quantity_instance(quantity) end |
.unitname(text, name) ⇒ Object
180 181 182 183 184 185 186 |
# File 'lib/unitsml/utility.rb', line 180 def unitname(text, name) name ||= unit_en_name(unit_instance(text)) || text Model::Units::Name.new( name: name, lutaml_register: Configuration.context.id, ) end |
.units2dimensions(units) ⇒ Object
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
# File 'lib/unitsml/utility.rb', line 61 def units2dimensions(units) norm = decompose_units_list(units) return if norm.any? do |u| u.nil? || u[:unit]&.unknown_name? || u[:prefix] == UNKNOWN end norm.map do |u| unit_name = u[:unit].unit_name { dimension: U2D[unit_name][:dimension], unit: unit_name, exponent: u[:unit].power_numerator || 1, symbol: U2D[unit_name][:symbol], } end.sort { |a, b| U2D[a[:unit]][:order] <=> U2D[b[:unit]][:order] } end |
.unitsymbols(formula, options) ⇒ Object
188 189 190 191 192 193 194 195 196 |
# File 'lib/unitsml/utility.rb', line 188 def unitsymbols(formula, ) %w[HTML MathMl].map do |lang| Model::Units::Symbol.new( type: lang, content: formula.public_send(:"to_#{lang.downcase}", ), lutaml_register: Configuration.context.id, ) end end |
.unitsystem(units) ⇒ Object
198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 |
# File 'lib/unitsml/utility.rb', line 198 def unitsystem(units) ret = [] if units.any? { |u| !u.si_system_type? } ret << Model::Units::System.new( name: "not_SI", type: "not_SI", lutaml_register: Configuration.context.id, ) end if units.any?(&:si_system_type?) if units.size == 1 base = units[0].downcase_system_type == "si_base" base = true if units[0].unit_name == "g" && units[0]&.prefix_name == "k" end ret << Model::Units::System.new( name: "SI", type: (base ? "SI_base" : "SI_derived"), lutaml_register: Configuration.context.id, ) end ret end |