Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to convert to °API #31

Open
fxgallego opened this issue Sep 7, 2016 · 4 comments
Open

How to convert to °API #31

fxgallego opened this issue Sep 7, 2016 · 4 comments

Comments

@fxgallego
Copy link

I'm not sure how to add a new unit that works like °F - °C.
This API Gravity unit is very common in the Oil and Gas industry and is explained here:
https://en.wikipedia.org/wiki/API_gravity

Please, could you help me to add this unit?

@fxgallego
Copy link
Author

fxgallego commented Oct 19, 2016

My solution for this is:

Define functions in functional.rb

    def self.from_apid(x)
      denominator = 131.5 + x
      return 0 if denominator == 0
      141.5 / denominator * 10**6 * 0.999016 #water density at 60°F expressed in Kg/l
    end

    def self.to_apid(x)
      term = x == 0 ? 0 : 141.5 / (x / 10**6 / 0.999016)
      term - 131.5
    end

Add a new derived unit in derived_unit.yml

    - :names: API gravity
      :symbol: "°API"
      :primary_code: Api
      :secondary_code: API
      :scale:
        :function_code: apid
        :value: 1
        :unit_code: 'g/m3'
      :classification: api
      :property: oil density
      :metric: true
      :special: true
      :arbitrary: false

But I don't see if there is an extension point for derived units without need to patch the code.

@fxgallego
Copy link
Author

fxgallego commented Oct 19, 2016

I'm on rails so I've added an initializer as:

require 'unitwise'
api = {
    :names => "API gravity",
    :symbol => "°API",
    :primary_code => "Api",
    :secondary_code => "API",
    :scale => {
        :function_code => "apid",
        :value => 1,
        :unit_code => "g/m3"
    },
    :classification => "api",
    :property => "oil density",
    :metric => true,
    :special => true,
    :arbitrary => false
}
Unitwise::Atom.data << api

module Unitwise
  class Functional < Scale
    def self.from_apid(x)
      denominator = 131.5 + x
      return 0 if denominator == 0
      141.5 / denominator * 10**6 * 0.999016 #water density at 60°F expressed in Kg/l
    end

    def self.to_apid(x)
      term = x == 0 ? 0 : 141.5 / (x / 10**6 / 0.999016)
      term - 131.5
    end
  end
end

@joshwlewis
Copy link
Owner

That's pretty cool. I'm glad you got it worked out. This might be an indication that we need a more official custom units API.

If that's a pretty standard unit, you could consider submitting a patch upstream to unitsofmeasure.org to add it, which in turn would add it to this library.

@fxgallego
Copy link
Author

fxgallego commented Oct 24, 2016

@joshwlewis a better API to functional would be fine. This API unit is really very common but I don't believe it would be acepted by UCUM, it has some quirks like the temperature in which the magnitude is expressed because the calculation is based on water density.

By the time, maybe it's a good idea to add this custom unit definition recipe to the docs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants