IAMconsortium / units

Common unit definitions for integrated assessment research
GNU General Public License v3.0
20 stars 11 forks source link

Refactor defs to avoid defining non-quantities #12

Closed khaeru closed 4 years ago

khaeru commented 4 years ago

This issue is to carry forward discussion from in https://github.com/IAMconsortium/units/pull/7#issuecomment-597013770, #9, and #10.

Details

The goal in using pint for unit handling (in the 'client' packages of this repo) is to be scientific and rigorous about measurement.

  1. One way pint helps us do this is by ensuring common definitions are used, rather than constants hardcoded in many places across other code.
  2. Another way is ensuring precision about what is being measured, and forcing implicit conversions to become explicit.

Per the second point, we should follow, rather than circumvent, the logic of SI, as encoded by pint. The International vocabulary of metrology (VIM) is the best reference here, defining e.g.:

quantity:

property of a phenomenon, body, or substance, where the property has a magnitude that can be expressed as a number and a reference.

quantity value:

number and reference together expressing magnitude of a quantity.

EXAMPLE 2 Mass of a given body: 0.152 kg or 152 g

EXAMPLE 8 Mass fraction of cadmium of a given sample of copper: 3 μg/kg or 3 ×10^-9

nominal property:

property of a phenomenon, body, or substance, where the property has no magnitude.

EXAMPLE 1 Sex of a human being. EXAMPLE 2 Colour of a paint sample. … EXAMPLE 5 Sequence of amino acids in a polypeptide.

NOTE 1 A nominal property has a value, which can be expressed in words, by alphanumerical codes, or by other means.

In "quantity value" example 8, note that nominal properties and other information about the quantity value are supplied together with the quantity value:

These are essential information. But only "µg/kg" is the unit (reference) in this quantity value.

As a convention in many disciplines, we often mix these things together, e.g.:

tl;dr:

Actions

danielhuppmann commented 4 years ago

Thanks @khaeru for this detailed description of the issue.

Comment 1: I don't think that the current approach is violating the two principles above - it allows using common definitions in a central location, and it is (more) explicit (than other implementations I have seen used in practice).

Comment 2: I don't think it's a good strategy to only provide example code to process the refactored definitions, which would then have to implemented (and updated with new features) across multiple packages. The elegance of the current approach that it only requires one line of code in any application depending on these definitions.

So if going forward, I'd suggest to refactor and provide a class to be used instead of a pint.UnitRegistry, which provides the auxiliary functions. This is the strategy followed by the scmdata.ScmUnitRegistry (though I would suggest IamUnitRegistry for generality).

khaeru commented 4 years ago

Agreed that this takes us in the direction of providing a (very simple) package. However, I'm not sure it's necessary to create a subclass of UnitRegistry—only some simple helper functions that make use of one. To be seen, at the point we attempt it!