Skip to content

User Guide for QUDT

steveraysteveray edited this page Mar 28, 2024 · 66 revisions

This guide attempts to explain how the QUDT model should be used.

Contents

1. Simple use case

2. Introducing Quantity Kinds

3. Introducing Dimension Vectors (for SI units)

4. Conversion Multipliers in QUDT

5. Unit Conversion in QUDT

6. Using Quantity Kinds with Dimensionless Quantities

7. Special case of Quantity Kind with no Dimension Vector

8. A Quantity with multiple units

9. Other Systems of Units

Please refer to the following architecture diagram for the key QUDT classes (the QUDT architecture overview can be read here.

QUDT core classes

1. Simple use case

Let's suppose you have a smart thermostat and it generates a digital signal for the temperature setting in degrees Fahrenheit. You could name the QUDT Quantity something like wiki-examples:MyThermostatSetting. The Quantity instance is yours - you can name it whatever you want, but in a professional/interoperability scenario the name might include other information, such as the location of the thermostat. One way or another, the name establishes the context of the value you are storing. For the simple case, the Quantity instance has a property qudt:value, which you could assign the value 72.0. The Quantity instance also points to an instance of qudt:Unit called unit:DEG_F.

Here's the Turtle source code for this:

wiki-examples:MyThermostatSetting
rdf:type qudt:Quantity ;
qudt:hasUnit unit:DEG_F ;
qudt:value "72.0"^^xsd:float ;
.

Here's how it fits into the QUDT model. (Orange is your new instance, blue is defined by QUDT).

image

2. Introducing Quantity Kinds

The next important concept to understand is the QuantityKind. Simply stated, a QuantityKind is just that: a kind, and answers the question "What is this measurement and unit a measure of?". Answers might be things like "Thermodynamic Temperature" (i.e. quantitykind:ThermodynamicTemperature). So the QuantityKind vocabulary is a set of all the kinds of things we might measure... length, area, electrical capacitance, torque, and really obscure ones like power per area quartic temperature. This last one is measured in units of Watts Per Square Meter Per Quartic Kelvin by the way.

Every Unit is associated with at least one QuantityKind - sometimes more than one if there are different ways people refer to a QuantityKind, but usually just one. You don't need to populate that link, it is already populated. For example, the following SPARQL query produces 2 quantity kinds associated with the unit unit:A-PER-MilliM:

SELECT ?un ?qk
WHERE {
    BIND (unit:A-PER-MilliM AS ?arg1) .
    ?un rdf:type qudt:Unit .
    BIND (afn:localname(?un) AS ?unn) .
    FILTER (?un = ?arg1) .
    ?un qudt:hasQuantityKind ?qk
} ORDER BY ?un

which produces the following:

un	                qk
unit:A-PER-MilliM	quantitykind:LinearElectricCurrent
unit:A-PER-MilliM	quantitykind:MagneticFieldStrength

Of course, each QuantityKind could be measured in any of several units, such as different units for temperature, or different units for length. For example, the following SPARQL query shows the different units associated with the quantity kind quantitykind:Force:

SELECT ?qk ?qku ?qkl
WHERE {
    BIND (quantitykind:Force AS ?arg1) .
    ?qk rdf:type qudt:QuantityKind .
    FILTER (?qk = ?arg1) .
    ?qku qudt:hasQuantityKind ?qk .
   ?qku a qudt:Unit .
   ?qku rdfs:label ?qkl .
} ORDER BY ?qku

which results in 16 values for ?qku:

    qk			qku			qkl
quantitykind:Force	unit:DYN	        Dyne
quantitykind:Force	unit:KIP_F	        Kip
quantitykind:Force	unit:KiloGM_F	        Kilogram Force
quantitykind:Force	unit:KiloN	        KiloN
quantitykind:Force	unit:KiloP	        Kilopond
quantitykind:Force	unit:KiloPOND	        KiloPOND
quantitykind:Force	unit:LB_F	        Pound Force
quantitykind:Force	unit:MegaLB_F	        Mega Pound Force
quantitykind:Force	unit:MegaN	        MegaN
quantitykind:Force	unit:MicroN	        MicroN
quantitykind:Force	unit:MilliN	        MilliN
quantitykind:Force	unit:N	                Newton
quantitykind:Force	unit:OZ_F	        Imperial Ounce Force
quantitykind:Force	unit:PDL	        Poundal
quantitykind:Force	unit:PlanckForce	Planck Force
quantitykind:Force	unit:TON_F_US	        TON_F_US

3. Introducing Dimension Vectors (for SI units)

Here is where the power of the QUDT ontology starts to reveal itself. In the SI system of units, all physical measurements can be described in terms of 7 basic dimensions, and the associated base units:

The SI Dimensions and Units

  • Amount of substance - mole (mole)
  • Electric current - ampere (A)
  • Length - meter (m)
  • Luminous intensity - candela (cd)
  • Mass - kilogram (kg)
  • Temperature - kelvin (K)
  • Time - second (s)

(Note that the choice of what the basic dimensions are could have been different. The SI community could have chosen Electric charge instead of Electric current, for example, in which case the Coulomb would have been the base unit for SI. This is important, because there are other systems of units, such as the CGS-EMU system, and the CGS-ESU system, that made different choices for the base dimensions.)

In QUDT every dimension vector is comprised of each of the above base dimensions and an associated exponent in the following way:

(Dimension1 * dimensional_exponent1) * (Dimension2 * dimensional_exponent2) * ...

This is repeated for all 7 dimensions and the dimensionless indicator in the following order:

Amount of substance, Electric current, Length, Luminous intensity, Mass, Temperature, Time, Dimensionless

The dimensions and the dimensionless value are indicated with single letter codes which, for the above dimensions and dimensionless are, in order, as above:

A E L I M H T D

An example for the QuantityKindDimensionVector associated with Force is:

qkdv:A0E0L1I0M1H0T-2D0

where the only non-zero exponents are for L (length), M (mass), and T (time), i.e., M1L1T-2. (Please note that in QUDT we add a coefficient for dimensionless quantity kinds. This is the last item, D, in the example above. When a quantity kind is dimensionless all the base units will have zero exponents except D. An example of a dimensionless quantity kind is TemperatureRatio:

qkdv:A0E0L0I0M0H0T0D1

Using the base dimensions is how you can determine whether one unit can be converted into another. They must be commensurate, which means they must be associated with the same "dimension vector". The dimension vector (known in QUDT as the QuantityKindDimensionVector_SI for the SI dimension vector) is simply a description of a given unit in terms of the appropriate powers of the underlying base dimensions. For example, speed is (Length / Time); acceleration is (Length / Time**2).

The QUDT vocabulary contains over a thousand units compliant with ISO 80000 and several other standards including IEC 61360. For example, we could execute the following SPARQL query to produce all of the units in the vocabulary associated with the base units of M * L / T^2. We get to this through the DimensionVector:

SELECT ?un ?unl
WHERE {
    BIND ("A0E0L1I0M1H0T-2D0" AS ?arg1) .
    ?dv rdf:type qudt:QuantityKindDimensionVector_SI .
    BIND (afn:localname(?dv) AS ?dvn) .
    FILTER (fn:contains(fn:upper-case(?dvn), fn:upper-case(?arg1))) .
    ?qk qudt:hasDimensionVector ?dv .
    ?un qudt:hasQuantityKind ?qk .
    ?un rdfs:label ?unl .
} ORDER BY ?un

which produces the following:

un                          unl
unit:DYN                    Dyne
unit:KIP_F                  Kip
unit:KiloEV-PER-MicroM      Kilo Electron Volt per Micrometer
unit:KiloGM_F               Kilogram Force
unit:KiloN                  KiloN
unit:KiloP                  Kilopond
unit:KiloPOND               KiloPOND
unit:LB_F                   Pound Force
unit:MegaEV-PER-CentiM      Mega Electron Volt per Centimeter
unit:MegaLB_F               Mega Pound Force
unit:MegaN                  MegaN
unit:MicroN                 MicroN
unit:MilliN                 MilliN
unit:N                      Newton
unit:OZ_F                   Imperial Ounce Force
unit:PDL                    Poundal
unit:PlanckForce            Planck Force
unit:TON_F_US               TON_F_US

Every unit has an associated quantity kind and dimension vector. You cannot add a speed to a temperature because Length / Time is different from Temperature. You can add a furlong to a kilometer, because they both have a dimension vector of Length. Of course, you need to convert one unit into the other before adding the numbers, which leads us to...

4. Conversion Multipliers in QUDT

Each instance of Unit has a property called qudt:conversionMultiplier. The value of the multiplier tells you what number to multiply to convert a given unit into the SI version of that unit. So, for example the conversionMultiplier for an inch (unit:IN) is 0.0245. That is, 1 Inch equals 0.0245 Meters.

Measurements that have the same QuantityKind can often be combined mathematically. You can add two lengths, once you accommodate their conversion multipliers, but it doesn't make sense to add a length and a temperature - they are of different quantity kinds. As an example of how to use conversion multipliers in QUDT, consider the following relationship to calculate the circumference of a rectangle:

rectangleCircumference = 2 x length + 2 * width

Lets say that, for the purposes of discussion, the length is measured in inches (IN) and the width is measured in centimeters (CentiM). Then if the length is 19 and the width is 12 we could use the following to calculate the circumference in the base unit of Meters. The essence of the query, after doing some bindings for the values and the unit types, comes down to getting the conversion multipliers for the units and performing the calculation:

SELECT ?rectCircum
WHERE {
    BIND (19 AS ?length) .
    BIND (12 AS ?width) .
    BIND (unit:IN AS ?arg1) .
    BIND (unit:CentiM AS ?arg2) .
    ?arg1  qudt:conversionMultiplier ?cm1 .
    ?arg2  qudt:conversionMultiplier ?cm2 .
    BIND (((2 * ?length * ?cm1) + (2 * ?width * ?cm2)) AS ?rectCircum) .
}

The query above produces the value of 1.2052, which is now in SI units of meter (M). Of course, we could add another last line (e.g., BIND ((?rectCircum / ?cm1) AS ?rectCircumIN) ., which produces 47.44881 in, or BIND ((?rectCircum / ?cm2) AS ?rectCircumCentiM) ., which produces 120.52 cm) to the query to return the circumference in either inches or centimeters, respectively. Alternatively, we could have just converted one of the two (length or width) to the other before calculating the circumference.

5. Unit Conversion Example in QUDT

Building on the above discussion of dimension vectors and conversion multipliers leads us to an elegant way to do unit conversions. (Important caveat: The following example works to convert incremental values of units where the only important factor is the relative size of the unit. This example does not handle absolute values for units with offsets (think Celsius and Fahrenheit degrees). QUDT supports that too - the QUDT treatment of absolute and incremental values is discussed here.

The approach we will use is shown in the following pseudocode:

1. start with a given instance of a Unit
   1.1 find out what QuantityKind it has
       1.1.1 determine its QuantityKindDimensionVector
   1.2 find out all the QuantityKinds that have that same QuantityKindDimensionVector
   1.3 find all the Units with those QuantityKinds
2. multiply your starting unit by its conversionMultiplier
   2.1 divide the result by the target unit conversionMultiplier

That is the logic behind the following SPARQL query:

PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX qudt: <http://qudt.org/schema/qudt/>
SELECT DISTINCT ?toConvert ?label ?into ?otherUnitLabel ?multiplyBy ?multiplier
WHERE {
BIND ("To convert" AS ?toConvert) .
BIND ("into" AS ?into) .
BIND ("multiply by" AS ?multiplyBy) .
?unit a qudt:Unit .
?unit rdfs:label ?label .
FILTER(CONTAINS (LCASE(STR(?label)), "milligray")) .
?unit qudt:conversionMultiplier ?cm1 .
?unit qudt:hasQuantityKind/qudt:hasDimensionVector ?qkdv .
?otherUnit qudt:hasQuantityKind/qudt:hasDimensionVector ?qkdv .
?otherUnit a qudt:Unit .
FILTER (?otherUnit != ?unit) .
?otherUnit qudt:conversionMultiplier ?cm2 .
?otherUnit rdfs:label ?otherUnitLabel .
BIND ((?cm1/?cm2) AS ?multiplier) .
}
ORDER BY ?label ?multiplier

Executing this query produces output that looks like this:

To convert	MilliGRAY	into	Kilocalorie per Gram			multiply by	2.390057361376673E-10
To convert	MilliGRAY	into	MegaJ PER KiloGM			multiply by	1.0E-9
To convert	MilliGRAY	into	CAL_IT PER GM				multiply by	2.388458966274959E-7
To convert	MilliGRAY	into	calorieIT per gram (calIT/g)		multiply by	2.388458966274959E-7
To convert	MilliGRAY	into	CAL_TH PER GM				multiply by	2.390057361376673E-7
To convert	MilliGRAY	into	calorieTH per gram (calTH/g)		multiply by	2.390057361376673E-7
To convert	MilliGRAY	into	BTU-IT-PER-lb				multiply by	4.299226139294927E-7
To convert	MilliGRAY	into	British Thermal Unit (TH) Per Pound	multiply by	4.30210433032265E-7
To convert	MilliGRAY	into	J PER GM				multiply by	1.0E-6
To convert	MilliGRAY	into	BTU_IT PER LB_F				multiply by	4.216100966554345E-6
To convert	MilliGRAY	into	Gray					multiply by	0.001e0
To convert	MilliGRAY	into	Joule per Kilogram			multiply by	0.001e0
To convert	MilliGRAY	into	Sievert					multiply by	0.001e0
To convert	MilliGRAY	into	Rad					multiply by	0.1e0
To convert	MilliGRAY	into	Rem					multiply by	0.1e0
To convert	MilliGRAY	into	MilliSV					multiply by	1.0e0
To convert	MilliGRAY	into	ERG PER GM				multiply by	10.0e0
To convert	MilliGRAY	into	Erg per Gram				multiply by	10.0e0
To convert	MilliGRAY	into	MilliR equivalent man			multiply by	3875.968992248062e0
To convert	MilliGRAY	into	MilliR					multiply by	3875.968992248062e0

None of these pairwise relationships had to be stored. The query simply returns all the other units that have the same associated dimension vector. You can try queries for both incremental and absolute unit conversion using our EDG server. There is an introductory video there that shows how to bring up the SPARQL query interface.

6. Using Quantity Kinds with Dimensionless Quantities

A whole category of units are actually dimensionless, and QUDT has a specific modeling pattern to handle these. Think about the unit "relative humidity" which is generally expressed as a percentage. In QUDT, the instance is unit:PERCENT_RH. While the unit is a dimensionless number, it is actually the ratio of two partial pressures, and the dimensions cancel out because of the ratio. It is important to capture this, because it would be nonsensical to compare a relative humidity percentage with a savings account yield percentage, even though they are both just nondimensional percentages.

To capture the full semantics, unit:PERCENT_RH points to quantitykind:PressureRatio using the qudt:hasQuantityKind relation. The quantitykind:PressureRatio has a dimensionality that is the result of a combination of other quantity kinds. In this specific case, it is the ratio of two pressures. quantitykind:PressureRatio points to the dimension vector of qkdv:A0E0L0I0M0H0T0D1 (the dimensionless dimension vector), but it also has two other properties, qudt:qkdvDenominator and qudt:qkdvNumerator. In this example, they are both populated with qkdv:A0E0L-1I0M1H0T-2D0, the dimension vector for a pressure. Using this pattern, the model captures the fact that unit:PERCENT_RH is dimensionless, but also that it derives from the ratio of two pressures.

Finally, quantitykind:PressureRatio also uses the skos:broader relation to position it in a hierarchy that, in this case, broadens to quantitykind:DimensionlessRatio, and then to quantitykind:Dimensionless.

Here's a diagram that shows the final result:

Relative Humidity Example

Most of the dimensionless quantity kind instances are simple ratios of a single kind of quantitykind, but this may not always be the case. Sometimes the final dimensionality hides the fact that some of the dimensions in the definition formula "cancel out", and this can be made explicit using the numerator and denominator properties.

7. Special case of Quantity Kind with no Dimension Vector

On rare occasions, one encounters a quantity kind that has no dimension vector. (Normally, all quantity kinds are required to have an associated dimension vector). It is important to recognize this as distinct from quantity kinds that have a dimensionless dimension vector (i.e. A0E0L0I0M0H0T0D1). These quantity kinds might be useful to refer to in some specialized domain, but they are ambiguous. For example, quantitykind:VisionThresholds refers to the sensitivity of the eye to light. It might be reported as the number of photons incident on a prescribed part of the retina, or it might be in terms of luminance, or even illuminance. It is arguable that such concepts don't really even belong in QUDT as defined Quantity Kinds and are best treated as contextual Quantity instances instead. As of the writing of this wiki, QUDT only has 7 such quantity kinds.

8. A Quantity with multiple units

Let's say your smart thermostat is even smarter than the one in the first example, and communicates in both Fahrenheit and Kelvin (the SI unit for temperature). Here's how we could store all that information. Keep in mind that the "concept" of the temperature setting is still a single concept, even when its value is represented in multiple units. So in this case, instead of using the built-in data property qudt:hasUnit inside the qudt:Quantity class, we use the object property qudt:quantityValue that points to the class qudt:QuantityValue in the first diagram on this page. There will be two instances of qudt:QuantityValue, one that points to the unit:DEG_F unit instance, and one that points to the unit:K unit instance. Here's the code:

wiki-examples:MySmarterThermostatSetting
a qudt:Quantity ;
qudt:quantityValue wiki-examples:FahrenheitSetting ;
qudt:quantityValue wiki-examples:KelvinSetting ;
.
wiki-examples:FahrenheitSetting
rdf:type qudt:QuantityValue ;
qudt:hasUnit unit:DEG_F ;
qudt:value "72.0"^^xsd:float ;
.
wiki-examples:KelvinSetting
rdf:type qudt:QuantityValue ;
qudt:hasUnit unit:K ;
qudt:value "295.37"^^xsd:float ;
.

9. Other Systems of Units