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

leverage QUDT to represent quantity kinds and units #338

Closed
VladimirAlexiev opened this issue Jan 23, 2024 · 14 comments
Closed

leverage QUDT to represent quantity kinds and units #338

VladimirAlexiev opened this issue Jan 23, 2024 · 14 comments

Comments

@VladimirAlexiev
Copy link

VladimirAlexiev commented Jan 23, 2024

The latest CIM version that I have (2022-07)
eg IEC61970-600-2_CGMES_3_0_1_ApplicationProfiles\v3.0\RDFSEd2Beta\RDFS\IEC61970-600-2_CGMES_3_0_0_RDFS_501Ed2CD_EQ.rdf
defines data properties something like this:

cim:ACDCConverter.idleLoss
        rdf:type         owl:FunctionalProperty , owl:DatatypeProperty ;
        rdfs:domain      cim:ACDCConverter ;
        rdfs:label       "idleLoss"@en ;
        rdfs:range       cim:ActivePower ;
        skos:definition  "Active power loss in pole at no power transfer. It is converter’s configuration data used in power flow. The attribute shall be a positive value."@en .

cim:ActivePower  rdf:type  owl:Class ;
        rdfs:label        "ActivePower"@en ;
        eq:Package        "Package_CoreEquipmentProfile" ;
        eq:isCIMDatatype  "True" ;
        skos:definition   "Product of RMS value of the voltage and the RMS value of the in-phase component of the current."@en .

cim:ActivePower.multiplier
        rdf:type     owl:FunctionalProperty , owl:DatatypeProperty ;
        rdf:value    "M" ;
        rdfs:domain  cim:ActivePower ;
        rdfs:label   "multiplier"@en ;
        rdfs:range   cim:UnitMultiplier ;
        eq:isFixed   "True " .

cim:ActivePower.unit  rdf:type  owl:FunctionalProperty , owl:DatatypeProperty ;
        rdf:value    "W" ;
        rdfs:domain  cim:ActivePower ;
        rdfs:label   "unit"@en ;
        rdfs:range   cim:UnitSymbol ;
        eq:isFixed   "True " .

cim:ActivePower.value
        rdf:type     owl:FunctionalProperty , owl:DatatypeProperty ;
        rdfs:domain  cim:ActivePower ;
        rdfs:label   "value"@en ;
        rdfs:range   xsd:float .

There are serious problems with this representation:

  • Instance data only ever carries numbers (xsd:float), not any of the "decorations" declared by its "datatype" class cim:ActivePower (unit, multiplier, etc).
  • This is borne by the property kind owl:DatatypeProperty. But cim:ActivePower is a class, so it cannot be the range of a data property
  • Since there are no ActivePower individuals, it's not a class. It's a QuantityKind (borrowing a term from QUDT)
  • There's no good reason to define unit "W" and multiplier "M" just for ActivePower because the same "MW" is used for many other kinds of "Power"

A week ago you had a presentation of QUDT and I assume you liked it.
Here's what info QUDT includes about these items:

<http://qudt.org/vocab/unit/MegaW>
  rdf:type <http://qudt.org/schema/qudt/Unit> ;
  <http://qudt.org/schema/qudt/applicableSystem> <http://qudt.org/vocab/sou/CGS> ;
  <http://qudt.org/schema/qudt/applicableSystem> <http://qudt.org/vocab/sou/CGS-EMU> ;
  <http://qudt.org/schema/qudt/applicableSystem> <http://qudt.org/vocab/sou/CGS-GAUSS> ;
  <http://qudt.org/schema/qudt/applicableSystem> <http://qudt.org/vocab/sou/PLANCK> ;
  <http://qudt.org/schema/qudt/applicableSystem> <http://qudt.org/vocab/sou/SI> ;
  <http://qudt.org/schema/qudt/conversionMultiplier> 1.0e06 ;
  <http://qudt.org/schema/qudt/hasDimensionVector> <http://qudt.org/vocab/dimensionvector/A0E0L2I0M1H0T-3D0> ;
  <http://qudt.org/schema/qudt/hasQuantityKind> <http://qudt.org/vocab/quantitykind/ActivePower> ;
  <http://qudt.org/schema/qudt/hasQuantityKind> <http://qudt.org/vocab/quantitykind/Power> ;
  <http://qudt.org/schema/qudt/prefix> <http://qudt.org/vocab/prefix/Mega> ;
  <http://qudt.org/schema/qudt/symbol> "MW" ;
  <http://qudt.org/schema/qudt/ucumCode> "MW"^^<http://qudt.org/schema/qudt/UCUMcs> ;
  <http://qudt.org/schema/qudt/uneceCommonCode> "MAW" ;
  rdfs:isDefinedBy <http://qudt.org/2.1/vocab/unit> ;
  rdfs:label "MegaW"@en ;
.

(Sorry this uses long URLs: I got it from https://qudt.org/vocab/unit/MegaW, since the downloaded version 2.1 of 2020-11 that I have is poorer).
As you see, it has all the info from CIM above, plus a lot more: links to UNECE and UCUM, prefix and conversionMultiplier, dimension vector, and which quantityKinds it applies to.

Its sibling unit "megawatt per hour" has a bit more info: also link to IEC CDD ("0112/2///62720#UAA225" is called an IRDI).

unit:MegaW-HR
  a qudt:Unit ;
  qudt:conversionMultiplier 3.6e+09 ;
  qudt:conversionOffset 0e+00 ;
  qudt:hasDimensionVector qkdv:A0E0L2I0M1H0T-2D0 ;
  qudt:hasQuantityKind quantitykind:Energy ;
  qudt:iec61360Code "0112/2///62720#UAA225" ;
  qudt:plainTextDescription "1 000 000-fold of the product of the SI derived unit watt and the unit hour" ;
  qudt:ucumCode "MW.h"^^qudt:UCUMcs ;
  qudt:uneceCommonCode "MWH" ;
  rdfs:isDefinedBy <http://qudt.org/2.1/vocab/unit> ;
  rdfs:label "Megawatt Hour"@en ;
.

Here's the quantityKind:

quantitykind:ActivePower
  a qudt:QuantityKind ;
  dcterms:description "\\(Active Power\\) is, under periodic conditions, the mean value, taken over one period \\(T\\), of the instantaneous power \\(p\\). In complex notation, \\(P = \\mathbf{Re} \\; \\underline{S}\\), where \\(\\underline{S}\\) is \\(\\textit{complex power}\\)\"."^^qudt:LatexString ;
  qudt:hasDimensionVector <http://qudt.org/vocab/dimensionvector/A0E0L2I0M1H0T-3D0> ;
  qudt:informativeReference "http://www.electropedia.org/iev/iev.nsf/display?openform&ievref=131-11-42"^^xsd:anyURI ;
  qudt:informativeReference "http://www.iso.org/iso/home/store/catalogue_tc/catalogue_detail.htm?csnumber=31891"^^xsd:anyURI ;
  qudt:latexDefinition "\\(P = \\frac{1}{T}\\int_{0}^{T} pdt\\), where \\(T\\) is the period and \\(p\\) is instantaneous power."^^qudt:LatexString ;
  qudt:symbol "P" ;
  rdfs:isDefinedBy <http://qudt.org/2.1/vocab/quantitykind> ;
  rdfs:label "Active Power"@en ;
  rdfs:seeAlso quantitykind:ComplexPower ;
  rdfs:seeAlso quantitykind:InstantaneousPower ;
  skos:broader quantitykind:ComplexPower ;
  qudt:applicableUnit unit:GigaW, unit:KiloW, unit:MegaW, unit:MicroW, unit:MilliW, unit:NanoW, unit:PicoW, unit:TeraW, unit:W
.

Or see https://qudt.org/vocab/quantitykind/ActivePower for a bit more info and rendered formulas.


My proposal is to:

  • leverage QUDT,
  • correctly define the range of the data prop and use hasQuantityKind and applicableUnit to bind to those characteristics
    • There's also qudt:unit but it would be used in an observation that doesn't leverage the default unit
  • only keep a CIM node for the quantityKind because you have an electricity-specific definition for it.
    • Link them by skos:exactMatch because owl:sameAs semantics would merge (smush) their characteristics.
    • You see that quantityKinds use skos:broader to make a hierarchy, so using
    • You could repeat some of the QUDT data about quantityKind (eg the dimensionVector etc) but I think there's no need
cim:ACDCConverter.idleLoss
        rdf:type         owl:FunctionalProperty , owl:DatatypeProperty ;
        rdfs:domain      cim:ACDCConverter ;
        rdfs:label       "idleLoss"@en ;
        rdfs:range       xsd:float;
        qudt:unit        unit:MegaW;
        qudt:hasQuantityKind cim:ActivePower ;
        skos:definition  "Active power loss in pole at no power transfer. It is converter’s configuration data used in power flow. The attribute shall be a positive value."@en .

cim:ActivePower  rdf:type  qudt:QuantityKind ;
        rdfs:label        "ActivePower"@en ;
        eq:Package        "Package_CoreEquipmentProfile" ;
        eq:isCIMDatatype  "True" ;
        skos:definition   "Product of RMS value of the voltage and the RMS value of the in-phase component of the current."@en;
        skos:exactMatch   quantitykind:ActivePower
.

Not only this representation is more correct, it's also a lot simpler than above!
It will cut the number of "UoM related terms" from 5n to 2n.

@Sveino
Copy link
Contributor

Sveino commented Jan 24, 2024

I like this a lot. This is fairly inline with what I expected.
This mean that we only need to include the float value in the instance file.
I am a bit on and off on the challenge if we should support the possibility to support both MW and kW as unit for the same profile. In that case we would have to include the unit in the instance file.
It would be good if we are documenting how this could be done to show that we evaluated this option. I personally think this would be the best solution.

@bartkl
Copy link

bartkl commented Jul 29, 2024

Great ideas, excited to see CIM moving this way. I have some questions and thoughts.

@VladimirAlexiev I believe the qudt:applicableUnit property is intended to be derived, not explicitly specified. Its comments point to a good explanation of this here.

Furthermore you speak of leveraging the "default unit" for a certain quantity kind. Can you tell me where this default is specified? It seems you mean qudt:applicableUnit but I don't think that servess as a default (it also tends to be multivalued).


I am a bit on and off on the challenge if we should support the possibility to support both MW and kW as unit for the same profile. In that case we would have to include the unit in the instance file.

@Sveino That's an interesting point. My first hunch would be to support the flexibility of providing units in the instance data. If left out in the instance data, a default from the ontology can be inferred (if possible).

Finally, are you aware there's also a QUDT SHACL schema? I'd imagine extending the SAHCL validation of the profile with some statements/rules that verify the correct use of units etc. that are specific to a specific profile is highly desired. Not only does it seem more suitable, I also believe it would be more useful, since I'd say fewer people use OWL reasoners than SHACL validators. (Note that I'm not arguing only OWL or only SHACL be used; both could play their own suitable role. Just thinking oud loud.)

@Sveino
Copy link
Contributor

Sveino commented Jul 30, 2024

That's an interesting point. My first hunch would be to support the flexibility of providing units in the instance data. If left out in the instance data, a default from the ontology can be inferred (if possible).
@bartkl remember that we are not really limiting the use of CIM in the semantic web space, but rather for the object oriented implementation. I like flexibility - but that come with a cost. Our current position is that we can defined the unit in the profile.

Finally, are you aware there's also a QUDT SHACL schema?
No, but SHACL rules should in general be associated with a profile rather than a vocabulary. There are work being done on QUDT to support reasoning described in OWL. Agree that one does not exclude the other - but they have different purpose.

@bartkl
Copy link

bartkl commented Jul 30, 2024

@Sveino Clear. And yes I agree SHACL should not be used for the vocabulary, I was talking about using SHACL for use in profiles. Just wanted to point out that there exists a QUDT SHACL model we can use for validating profiles.

@Sveino
Copy link
Contributor

Sveino commented Jul 30, 2024

@bartkl Can you add a link tot eh QUDT SHACL?

@bartkl
Copy link

bartkl commented Jul 30, 2024

@Sveino: QUDT SHACL graph: https://qudt.org/2.1/schema/shacl/qudt

@VladimirAlexiev
Copy link
Author

VladimirAlexiev commented Aug 12, 2024

@bartkl You're right, qudt:applicableUnit is not intended for this, I fixed my last code block to use qudt:unit.

"default unit" for a certain quantity kind. Can you tell me where this default is specified?

That would be the inverse of qudt:derivedCoherentUnitOfSystem "unit system in which the unit is derived from the system's base units with a proportionality constant of one".

I think these are the units with conversionMultiplier=1.0, eg that is the case for https://qudt.org/vocab/unit/W .
But I'll check for all: see (qudt/qudt-public-repo#952).

@VladimirAlexiev
Copy link
Author

@bartkl, https://qudt.org/2.1/schema/shacl/qudt is quite big and not modular: qudt/qudt-public-repo#953

@VladimirAlexiev
Copy link
Author

Sveino/Inst4CIM-KG#29 is very similar to this but addresses some other aspects.

@VladimirAlexiev
Copy link
Author

Closed by Sveino/Inst4CIM-KG#38

@VladimirAlexiev
Copy link
Author

This is documented at https://github.com/Sveino/Inst4CIM-KG/tree/develop/rdfs-improved#quantitykinds-and-units-of-measure.

@bartkl I'd appreciate if you can review this fairly large section. Thanks in advance!

@bartkl
Copy link

bartkl commented Jan 3, 2025

Hi Vladimir,

This looks really good. As you know I applaud the effort of moving towards QUDT.

I do have some questions and remarks.

Questions of compliance with the CIM

How do these choices affect questions of CIM compatibility?

The master CIM model is still the UML in Sparx EA, and - whether we like it or not (and we don't) - in it the CIM data types are represtented as classes and not scalars. Changing this breaks backward compatibility, which can be worthwile, but we should be aware of this and not take this too lightly.

Note

This is not just theoretical. As discussed before, there are users who actually adhere to the standard as precisely as to represent CIM data types as classes. In fact, the data products created by my team for Netbeheer Nederland do too.

Mapping to QUDT or using it directly

Using QUDT quantity kinds directly

Again, happy to see QUDT being leveraged. Having values be actual scalars of a proper datatype is proper and simply much, much better than the convoluted CIM data type classes we have now.

I do have a few questions though.

You write:

Keep the CIM-specific quantity kind since it often has a more electricity-specific description than is available in QUDT

Just asking out loud: can't we just use the QUDT quantity kind directly and add extra descriptions to it? These extra statements would be part of our ontology, and therefore their scope is clear.

For example:

qk:ApparentPower rdfs:comment  "Product of the RMS value of the voltage and the RMS value of the current." .

or perhaps something more semantically rich like:

cim:description rdfs:subPropertyOf rdfs:comment .

qk:ApparentPower cim:description  "Product of the RMS value of the voltage and the RMS value of the current." .

On the other hand, semantically it does seem more explicit to maintain our own URI (cim:ApparentPower) and make statements about that. Happy to learn from your breadth of experience here!

One last question regarding the alignment between the CIM and QUDT: I take it you deliberately align using SKOS and not more formally using OWL. Why is that? Would a statement like cim:ApparentPower owl:sameAs qk:ApparentPower be too committing because you don't wish to imply that those are the same individuals?

Why cim:unitMultiplier and cim:unitSymbol?

You write:

Link to a global QUDT unit, but also give the multiplier and unitSymbol separately, using cims: props

This regards, specifically, the new cim:unitMultiplier and cim:unitSymbol properties I guess, and their range classes. Why do we want those at all?

Instead of:

cim:UnitSymbol a owl:Class ;
  skos:exactMatch qudt:Unit.

cim:UnitSymbol.VA a cim:UnitSymbol ;
  qudt:hasQuantityKind cim:ApparentPower;
  skos:exactMatch unit:V-A.

Why not:

cim:UnitSymbol.VA a qudt:Unit ;
  qudt:hasQuantityKind cim:ApparentPower;
  skos:exactMatch unit:V-A.

And frankly, here I still wonder why we create our own unit symbol when QUDT has the one we need (as evidenced by the exact match statement.

So why not simply leave out the custom CIM unit symbols and multipliers if we have then in QUDT anyways:

cim:ACDCConverter.baseS a owl:FunctionalProperty , owl:DatatypeProperty ;
  rdfs:domain          cim:ACDCConverter ;
  rdfs:range           xsd:float ;
  qudt:hasQuantityKind cim:ApparentPower;
  qudt:hasUnit         unit:MegaV-A;

Perhaps, similar to with the quantity kind, you want to retain the possibility of providing extra descriptions. But I would doubt the need for that for something like SI symbols and multipliers. Wouldn't we gladly take our hands off of this?

Now, in those cases where QUDT does not cover our needs, we could still create our own QUDT units, symbols and multipliers. That's perfectly valid of course. But again, for those already available to us I don't understand why we would create our own layer of indirection (except for with quantity kinds, where I understand the need for extra descriptions).

Fixing unit symbols and multipliers and defaults

It's not entirely clear to me what we want to do with the fixing of symbols and multipliers. I guess some profiles might want to fix those for some quantity kind at the profile-level, others might have good reason to be more lenient and for example expect mega volt in one place, but kilo volt in another in the same dataset. Have we decided yet how we want to move forward here? And if so, do we know how to represent this technically?

At the very least it seems to me that the vocabulary should not state any fixed multipliers or symbols, nor should it state defaults. It should define the vocabulary that can be used to express such things, but since all of that is use case dependent - and even as specific as equipment dependent - I think this is properly the responsibility of schemas and validation, i.e. of your LinkML and SHACL models. Would you agree?

Final remarks

  • Any ideas how some of the typos (such as trailing spaces) could have gotten into the models? A decent serializer should be able to solve this, right?
  • If not done already, domain experts should perhaps have a look at the final mapping table. But it looks good to me!
  • LinkML supports QUDT right from its metamodel. As part of my work of describing how to map to the LinkML, I at some point would like to include writing about how to map all of the above properly.

@bartkl
Copy link

bartkl commented Jan 3, 2025

By the way, if this is not the best place for the review, please let me know.

@VladimirAlexiev
Copy link
Author

moved the discussion to Sveino/Inst4CIM-KG#152

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

3 participants