Skip to content

User Guide for QUDT

Steve Ray edited this page Jun 26, 2026 · 88 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. The same dimension vector does not guarantee commensurability

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).

Simple use case

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. (This is actually a simplification of the more complex topic of commensurability, discussed here, but suffices for this introduction). You don't need to populate the association between a Unit and a QuantityKind, 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 ?un) .
    ?un qudt:hasQuantityKind ?qk
}

which produces the following:

    un	                qk
    unit:A-PER-MilliM	quantitykind:LinearElectricCurrentDensity
    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: (Try it here)

SELECT DISTINCT ?qk ?qku (COALESCE(?labelEn, ?qkl) AS ?label)
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 .
    OPTIONAL {
    ?qku rdfs:label ?labelEn .
    FILTER (lang(?labelEn) = "en")
  }
} ORDER BY ?qku

which results in 23 values for ?qku:

qk	            qku	                    label
qudtqk:Force	unit:CentiN	            CentiNewton
qudtqk:Force	unit:DYN	            Dyne
qudtqk:Force	unit:DeciN	            DeciNewton
qudtqk:Force	unit:GM_F	            Gram Force
qudtqk:Force	unit:GigaN	            GigaN
qudtqk:Force	unit:KIP_F	            Kip
qudtqk:Force	unit:KiloGM-M-PER-SEC2	    kilogram metre per second squared
qudtqk:Force	unit:KiloGM_F	            Kilogram Force
qudtqk:Force	unit:KiloLB_F	            KiloPound Force
qudtqk:Force	unit:KiloN	            Kilonewton
qudtqk:Force	unit:KiloPOND	            Kilopond
qudtqk:Force	unit:LB_F	            Pound Force
qudtqk:Force	unit:MegaLB_F	            Mega Pound Force
qudtqk:Force	unit:MegaN	            Meganewton
qudtqk:Force	unit:MicroN	            Micronewton
qudtqk:Force	unit:MilliN	            Millinewton
qudtqk:Force	unit:N	                    newton
qudtqk:Force	unit:NanoN	            NanoN
qudtqk:Force	unit:OZ_F	            Imperial Ounce Force
qudtqk:Force	unit:PDL	            Poundal
qudtqk:Force	unit:POND	            pond
qudtqk:Force	unit:PlanckForce	    Planck Force
qudtqk:Force	unit:TON_F_US	            Ton Force (US Short)

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

To determine whether one unit can be converted into another, they must at least be associated with the same "dimension vector". The dimension vector (known in QUDT as the QuantityKindDimensionVector) 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 two 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: (Try it here)

SELECT DISTINCT ?un (COALESCE(?labelEn, ?unl) AS ?label)
WHERE {
    BIND ("A0E0L1I0M1H0T-2D0" AS ?arg1) .
    ?dv rdf:type qudt:QuantityKindDimensionVector .
    BIND(REPLACE(STR(?dv), ".*[#/]", "") AS ?dvn) .
    FILTER CONTAINS(UCASE(STR(?dvn)), UCASE(STR(?arg1)))
    ?qk qudt:hasDimensionVector ?dv .
    ?un qudt:unitForQuantityKind ?qk .
    ?un a qudt:Unit .
    ?un rdfs:label ?unl .
      OPTIONAL {
    ?un rdfs:label ?labelEn .
    FILTER (lang(?labelEn) = "en")
} 
}
ORDER BY ?un

which produces the following:

un	                    label
unit:CentiN	            CentiNewton
unit:DYN	            Dyne
unit:DeciN	            DeciNewton
unit:ERG-PER-CentiM	    Erg per Centimetre
unit:EV-PER-ANGSTROM	    Electronvolt per Angstrom
unit:EV-PER-M	            Electronvolt per Metre
unit:GM_F	            Gram Force
unit:GigaN	            GigaN
unit:J-PER-M	            Joule per Metre
unit:KIP_F	            Kip
unit:KiloEV-PER-MicroM	    Kilo Electron Volt per Micrometre
unit:KiloGM-M-PER-SEC2	    kilogram metre per second squared
unit:KiloGM_F	            Kilogram Force
unit:KiloLB_F	            KiloPound Force
unit:KiloN	            Kilonewton
unit:KiloN-M-PER-DEG-M	    kilonewton metre per degree metre
unit:KiloN-M-PER-M	    Kilonewton Metre per metre
unit:KiloPOND	            Kilopond
unit:LB_F	            Pound Force
unit:LB_F-FT-PER-IN	    pound-force foot per inch
unit:LB_F-IN-PER-IN	    pound-force inch per inch
unit:MegaEV-PER-CentiM	    Mega Electron Volt per Centimetre
unit:MegaLB_F	            Mega Pound Force
unit:MegaN	            Meganewton
unit:MicroN	            Micronewton
unit:MilliN	            Millinewton
unit:N	                    newton
unit:N-M-PER-DEG-M	    Newton metre per degree metre
unit:N-M-PER-M	            Newton metre per metre
unit:N-M-PER-M-RAD	    Newton Metre per Metre Radian
unit:N-PER-RAD	            Newton per radian
unit:NanoN	            NanoN
unit:OZ_F	            Imperial Ounce Force
unit:PDL	            Poundal
unit:POND	            pond
unit:PlanckForce	    Planck Force
unit:TON_F_US	            Ton Force (US Short)

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:

SELECT DISTINCT ?toConvert ?label ?into (COALESCE(?labelEn, ?otherUnitLabel) AS ?otherlabel) ?multiplyBy ?multiplier
WHERE {
BIND ("To convert" AS ?toConvert) .
BIND ("into" AS ?into) .
BIND ("multiply by" AS ?multiplyBy) .
BIND (unit:MilliGRAY as ?unit) .
?unit rdfs:label ?label .
FILTER (lang(?label) = "en") .
?unit qudt:conversionMultiplier ?cm1 .
?unit qudt:hasQuantityKind/qudt:hasDimensionVector ?qkdv .
?otherUnit qudt:hasQuantityKind/qudt:hasDimensionVector ?qkdv .
?otherUnit a qudt:Unit .
FILTER (?otherUnit != ?unit) .
FILTER NOT EXISTS {?otherUnit qudt:deprecated true}
?otherUnit qudt:conversionMultiplier ?cm2 .
?otherUnit rdfs:label ?otherUnitLabel .
  OPTIONAL {
    ?otherUnit rdfs:label ?labelEn .
    FILTER (lang(?labelEn) = "en") .
} 
BIND ((?cm1/?cm2) AS ?multiplier) .
}
ORDER BY ?otherlabel

Executing this query produces output that looks like this:

toConvert	label	    into	otherlabel	                                                    multiplyBy	multiplier
To convert	Milligray	into	British Thermal Unit (international Definition) per Pound Mass	multiply by	0.000000429922613929492691
To convert	Milligray	into	British Thermal Unit (thermochemical Definition) per Pound Mass	multiply by	0.00000043021032504326744
To convert	Milligray	into	Centigray	                                                    multiply by	0.1
To convert	Milligray	into	Erg per Gram	                                                multiply by	10.0
To convert	Milligray	into	Gigapascal Cubic Centimetre per Gram	                        multiply by	0.000000001
To convert	Milligray	into	Gray	                                                        multiply by	0.001
To convert	Milligray	into	International Table Calorie per Gram	                        multiply by	0.000000238845896627495939
To convert	Milligray	into	Joule per Gram	                                                multiply by	0.000001
To convert	Milligray	into	Joule per Kilogram	                                            multiply by	0.001
To convert	Milligray	into	Kilo Pound Force Foot per Pound Mass	                        multiply by	0.000000334552548302427649
To convert	Milligray	into	Kilocalorie per Gram	                                        multiply by	0.000000000239005736137667
To convert	Milligray	into	Kilogray	                                                    multiply by	0.000001
To convert	Milligray	into	Kilojoule per Kilogram	                                        multiply by	0.000001
To convert	Milligray	into	Megagray	                                                    multiply by	0.000000001
To convert	Milligray	into	Megajoule per Kilogram	                                        multiply by	0.000000001
To convert	Milligray	into	Microgray	                                                    multiply by	1000.0
To convert	Milligray	into	Microsievert	                                                multiply by	1000.0
To convert	Milligray	into	Milli Roentgen Equivalent Man	                                multiply by	100.0
To convert	Milligray	into	Millijoule per Gram	                                            multiply by	0.001
To convert	Milligray	into	Millirad	                                                    multiply by	100.0
To convert	Milligray	into	Millisievert	                                                multiply by	1.0
To convert	Milligray	into	Nanogray	                                                    multiply by	1000000.0
To convert	Milligray	into	Nanosievert	                                                    multiply by	1000000.0
To convert	Milligray	into	Newton Metre per Kilogram	                                    multiply by	0.001
To convert	Milligray	into	Rad	                                                            multiply by	0.1
To convert	Milligray	into	Rem	                                                            multiply by	0.1
To convert	Milligray	into	Roentgen Equivalent Man	                                        multiply by	0.1
To convert	Milligray	into	Sievert	                                                        multiply by	0.001
To convert	Milligray	into	Square Kilometre per Square Second	                            multiply by	0.000000001
To convert	Milligray	into	Square Metre per Square Second	                                multiply by	0.001
To convert	Milligray	into	Thermochemical Calorie per Gram	                                multiply by	0.000000239005736137667304
To convert	Milligray	into	Watt Hour per Kilogram	                                        multiply by	0.000000277777777777777777

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, as well as any of the above examples, using our SPARQL endpoint.

6. The same dimension vector does not guarantee commensurability

A quantity kind's dimension vector (qudt:hasDimensionVector) captures its composition in terms of the seven SI base dimensions. It is tempting to assume that two quantity kinds with the same dimension vector are interchangeable — that their values can be compared, added, or converted between one another. In general they cannot. Sharing a dimension vector is necessary but not sufficient for commensurability.

The classic illustration is torque and energy. Both quantitykind:Torque and quantitykind:Energy have the identical dimension vector qkdv:A0E0L2I0M1H0T-2D0 (M·L²·T⁻²), and both are even measured with the same unit — the newton metre, since 1 J = 1 N·m. Yet a torque is not an energy: it makes no physical sense to add a torque to an energy, or to convert one into the other. Neither the dimension nor the unit tells them apart; only the quantity kind does.

QUDT therefore decides commensurability not from the dimension vector alone but also from explicit, curated relations — chiefly qudt:specializationOf and qudt:exactMatch. quantitykind:ThermalEnergy is qudt:specializationOf quantitykind:Energy - they share the same dimension and are genuinely commensurable (fully interconvertible), so they sit in one commensurability family. Torque carries that very same dimension vector but has no such link to Energy or Thermal Energy, so it forms a separate family.

Same dimension vector does not guarantee commensurability

In short, the dimension vector tells you whether two quantity kinds could be related by a numeric factor at all; the commensurability relations tell you whether they actually are. For the full treatment — including how units, and ultimately individual qudt:Quantity instances, fit into this picture — see Commensurability, Composition, Semantics and Context.

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

Clone this wiki locally