w3c / sdw-sosa-ssn

Repository of the Spatial Data on the Web Working Group for the SOSA/SSN vocabulary
7 stars 5 forks source link

Units of measure on simple results #144

Open dr-shorthair opened 6 months ago

dr-shorthair commented 6 months ago

I've had a go at summarizing various options for providing units-of-measure on simple results - see this non-normative section.

https://raw.githack.com/w3c/sdw-sosa-ssn/update-examples-2/ssn/index.html#quantity-values-and-unit-of-measures

The last option is possibly the neatest - I noticed it as a proposal in a GeoSPARQL thread, from @oldskeptic Do you have any further documentation for this pattern?

oldskeptic commented 6 months ago

Will roll this into an example for documentation.

avillar commented 5 months ago

One (possibly unrelated and/or wrong) question about this: why are custom datatypes not strictly compatible with OWL? Is this a reference to custom datatypes in general or to Custom Datatypes?

dr-shorthair commented 5 months ago

(I was referring to custom data types in general. )

TBH I'm very unsure on this.

On the one hand there is this https://www.w3.org/TR/owl2-primer/#Advanced_Use_of_Datatypes

On the other hand this seems to say that the set of data types in the OWL2 data type map is bounded https://www.w3.org/TR/owl2-syntax/#Datatype_Maps

On the third hand, maybe we don't care about OWL reasoners, since in 2024 we will usually rely on SHACL or Python etc.

What's your take?

avillar commented 5 months ago

From my reading of OWL2 Syntax section 5.2, datatype URLs must fulfil one of three criteria (be rdfs:Literal or one of the datatypes from section 4 or not be part of the reserved vocabulary). Section11.2 insists on this (and adds some constraints), and Section 9.4 even has an example with the definition of a custom SSN type.

It does seem that reasoner support for custom datatypes is... insufficient. But I think it's a sound strategy for defining simple results, I really like it, and IMO it appears to be compliant with the spec. If other RDF/OWL tools (like those you mention) can work with this, I woulnd't even keep the note.

dr-shorthair commented 5 months ago

Thanks @avillar - removed the warning in 74e78de

dr-shorthair commented 5 months ago

TBQH I don't think we should get hung up on OWL issues so much. Few SSN applications use OWL reasoning. Rather, they will be using RDF (typically as JSON) for data transfer, so validation will be a more relevant approach than reasoning and consistency.

rob-metalinkage commented 5 months ago

I think we should consider JSON-LD compatibility here - can we serialise to/from custom datatypes into JSON predictably, and is there any control over the JSON schema.

dr-shorthair commented 5 months ago

Good point. I took a look at how TopBraid renders this one in JSON-LD

<Observation/234534>
  rdf:type sosa:Observation ;
  sosa:hasFeatureOfInterest <apartment/134> ;
  sosa:hasSimpleResult "-29.9"^^unit:DEG_C ;
.

It comes up with this, which binds the @type to hasSimpleResult

{
  "@id" : "Observation/234534",
  "@type" : "sosa:Observation",
  "hasFeatureOfInterest" : "apartment/134",
  "hasSimpleResult" : "-29.9",
  "@context" : {
    "hasFeatureOfInterest" : {
      "@id" : "http://www.w3.org/ns/sosa/hasFeatureOfInterest",
      "@type" : "@id"
    },
    "hasSimpleResult" : {
      "@id" : "http://www.w3.org/ns/sosa/hasSimpleResult",
      "@type" : "http://qudt.org/vocab/unit/DEG_C"
    },
    "xsd" : "http://www.w3.org/2001/XMLSchema#",
    "rdfs" : "http://www.w3.org/2000/01/rdf-schema#",
    "unit" : "http://qudt.org/vocab/unit/",
    "rdf" : "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
    "sosa" : "http://www.w3.org/ns/sosa/"
  }
}
dr-shorthair commented 5 months ago

And if there is more than one value with some different unit representations, such as

<Observation/234534>
  rdf:type sosa:Observation ;
  sosa:hasFeatureOfInterest <apartment/134> ;
  sosa:hasSimpleResult "-22"^^unit:DEG_F ;
  sosa:hasSimpleResult "-29.8"^^unit:DEG_C ;
  sosa:hasSimpleResult "-29.9"^^unit:DEG_C ;
  sosa:hasSimpleResult "243.25"^^unit:K ;
.

TopBraid gives

{
  "@id" : "Observation/234534",
  "@type" : "sosa:Observation",
  "hasFeatureOfInterest" : "apartment/134",
  "hasSimpleResult" : [ "-29.9", "-29.8" ],
  "sosa:hasSimpleResult" : [ {
    "@type" : "unit:DEG_F",
    "@value" : "-22"
  }, {
    "@type" : "unit:K",
    "@value" : "243.25"
  } ],
  "@context" : {
    "hasFeatureOfInterest" : {
      "@id" : "http://www.w3.org/ns/sosa/hasFeatureOfInterest",
      "@type" : "@id"
    },
    "hasSimpleResult" : {
      "@id" : "http://www.w3.org/ns/sosa/hasSimpleResult",
      "@type" : "http://qudt.org/vocab/unit/DEG_C"
    },
    "xsd" : "http://www.w3.org/2001/XMLSchema#",
    "rdfs" : "http://www.w3.org/2000/01/rdf-schema#",
    "unit" : "http://qudt.org/vocab/unit/",
    "rdf" : "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
    "sosa" : "http://www.w3.org/ns/sosa/"
  }
}

So this pattern looks quite predictable

  "sosa:hasSimpleResult" : {
    "@type" : "unit:UNITAA",
    "@value" : "valueAA"
  },
avillar commented 5 months ago

JSON-LD can also do this if the source data has different properties for hasSimpleResult:

{
  "@context": {
    "unit": "http://qudt.org/vocab/unit/",
    "sosa": "http://www.w3.org/ns/sosa/",
    "celsius": {
      "@id": "sosa:hasSimpleResult",
      "@type": "unit:DEG_C"
    },
    "fahrenheit": {
      "@id": "sosa:hasSimpleResult",
      "@type": "unit:DEG_F"
    }
  },
  "celsius": 33.2,
  "fahrenheit": 91.8
}

which results in:

@prefix sosa: <http://www.w3.org/ns/sosa/> .
@prefix unit: <http://qudt.org/vocab/unit/> .

[] sosa:hasSimpleResult "3.32E1"^^unit:DEG_C, "9.18E1"^^unit:DEG_F .
oldskeptic commented 5 months ago

Following today's sdw teleconference, I will create two exemplars for the documentation that deals with this using two consumer grade devices. Must reference OWL2 datatypes, interpretations of literals and usage in json-ld.

ldesousa commented 5 months ago

I made a few tests with the Turtle document below:

@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix sosa: <http://www.w3.org/ns/sosa/> .
@prefix unit: <http://qudt.org/vocab/unit/> .

<Observation/234534>
  rdf:type sosa:Observation ;
  sosa:hasFeatureOfInterest <apartment/134> ;
  sosa:hasSimpleResult "-22"^^unit:DEG_F ;
  sosa:hasSimpleResult "-29.8"^^unit:DEG_C ;
  sosa:hasSimpleResult "-29.9"^^unit:DEG_C ;
  sosa:hasSimpleResult "243.25"^^unit:K ;
.

This is how Protégé saves it as JSON-LD:

[ {
  "@id" : "_:genid1",
  "@type" : [ "http://www.w3.org/2002/07/owl#Ontology" ]
}, {
  "@id" : "file:/home/user/temp/Observation/234534",
  "@type" : [ "http://www.w3.org/2002/07/owl#NamedIndividual", "http://www.w3.org/ns/sosa/Observation" ],
  "http://www.w3.org/ns/sosa/hasFeatureOfInterest" : [ {
    "@id" : "file:/home/user/temp/apartment/134"
  } ],
  "http://www.w3.org/ns/sosa/hasSimpleResult" : [ {
    "@type" : "http://qudt.org/vocab/unit/DEG_C",
    "@value" : "-29.8"
  }, {
    "@type" : "http://qudt.org/vocab/unit/DEG_C",
    "@value" : "-29.9"
  }, {
    "@type" : "http://qudt.org/vocab/unit/DEG_F",
    "@value" : "-22"
  }, {
    "@type" : "http://qudt.org/vocab/unit/K",
    "@value" : "243.25"
  } ]
}, {
  "@id" : "http://qudt.org/vocab/unit/DEG_C",
  "@type" : [ "http://www.w3.org/2000/01/rdf-schema#Datatype" ]
}, {
  "@id" : "http://qudt.org/vocab/unit/DEG_F",
  "@type" : [ "http://www.w3.org/2000/01/rdf-schema#Datatype" ]
}, {
  "@id" : "http://qudt.org/vocab/unit/K",
  "@type" : [ "http://www.w3.org/2000/01/rdf-schema#Datatype" ]
}, {
  "@id" : "http://www.w3.org/ns/sosa/Observation",
  "@type" : [ "http://www.w3.org/2002/07/owl#Class" ]
}, {
  "@id" : "http://www.w3.org/ns/sosa/hasFeatureOfInterest",
  "@type" : [ "http://www.w3.org/2002/07/owl#AnnotationProperty" ]
}, {
  "@id" : "http://www.w3.org/ns/sosa/hasSimpleResult",
  "@type" : [ "http://www.w3.org/2002/07/owl#AnnotationProperty" ]
} ]

And below is the same output created with RDFLib. Much cleaner, as this tool is not focused on Ontology as is Protégé.

[
  {
    "@id": "file:///home/user/temp/Observation/234534",
    "@type": [
      "http://www.w3.org/ns/sosa/Observation"
    ],
    "http://www.w3.org/ns/sosa/hasFeatureOfInterest": [
      {
        "@id": "file:///home/user/temp/apartment/134"
      }
    ],
    "http://www.w3.org/ns/sosa/hasSimpleResult": [
      {
        "@type": "http://qudt.org/vocab/unit/DEG_F",
        "@value": "-22"
      },
      {
        "@type": "http://qudt.org/vocab/unit/DEG_C",
        "@value": "-29.8"
      },
      {
        "@type": "http://qudt.org/vocab/unit/DEG_C",
        "@value": "-29.9"
      },
      {
        "@type": "http://qudt.org/vocab/unit/K",
        "@value": "243.25"
      }
    ]
  }
]

In my experience many Observations need to condition units of measure upstream of the Result (usually as an object property to a QUDT or UNIT class). Units of measure often depend on the Property/Procedure combination in chemistry, e.g. pH, molarity dependent procedures, etc.

dr-shorthair commented 5 months ago

Good. It looks like the { @type , @value } pair is a universal JSON pattern.

We should provide JSON examples as much as possible, so I'll start with this one.

dr-shorthair commented 3 months ago

Closed by #201