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

System types and individuals #107

Closed
maximelefrancois86 opened this issue Oct 25, 2023 · 85 comments · Fixed by #254
Closed

System types and individuals #107

maximelefrancois86 opened this issue Oct 25, 2023 · 85 comments · Fixed by #254

Comments

@maximelefrancois86
Copy link
Contributor

maximelefrancois86 commented Oct 25, 2023

It is still unclear when one wants to model a generic kind of system (aka, model, category, class, ...), whether they should model it as an instance of ssn:System, or a subclass of ssn:System.

As ssn:System is a superclass of sosa:Sensor, sosa:Actuator, sosa:Sampler, this confusion also applies to these class.

This ambiguity is reported in https://www.w3.org/TR/vocab-ssn/#SSNSystem-instances

In the SOSA/SSN examples, systems/sensors/actuators sometimes model generic sensor kinds, and sometimes a unique actual instance of sensor:

  • B.1 iPhone Barometer describes <sensor/35-207306-844818-0/BMP282> as the actual instance of a BMP282 high-precision barometric pressure sensor hosted on the iphone with IMEI 35-207306-844818-0.
  • B.2 Coal Oil Point Reserve describes <HUMICAP-H> which is a kind of Vaisala HUMICAP H-chip, a model of accurate temperature and relative humidity probe
  • B.12 Examples from O&M refers to a a graph corresponding to the OMXML examples. Four sensors are referred to: <http://www.csiro.au/people/ps205.html>, <http://www.example.org/register/process/scales34.xml>, <http://www.example.org/party/individual/abc123>, <urn:ogc:object:feature:Sensor:NASA:xyz345>

It would help a lot to be able to identify kinds of systems generically, the same way we do with property kinds. One advantage would be that we could reuse existing code lists, vocabularies, and taxonomies. Identifiers could be for example:

Another advantage is that it would encourage manufacturers and vendors to define permanent URIs for their devices, and to expose structured data at the page that describes a device in a catalogue. Some examples of product IDs from manufacturer and vendor catalogues:

My proposal to disambiguate the concept while maintaining backward compatibility with previous usages would be to split ssn:System in two classes:

sosa:SystemOfInterest

System is a unit of abstraction for real-world pieces of infrastructure that implement Procedures. A System may have components, its subsystems, which are other Systems.

By the way, we should extend this definition to account for use cases when one wants to identify the digital twin of a system using that same class in SOSA (the digital model of a system of interest is also a system of interest).

sosa:SystemKind

An instance of sosa:SystemKind describes a datasheet, vendor specification, or normative specification, of a sensor (in the sense of a prototypical description).

EXAMPLE: system with European Union energy label A++ , Energy Star labeled appliance, BMP282, DHT22, Adafruit 5187, ...

NOTE: Concepts from existing code lists, vocabularies, and taxonomies, may be used as instances of sosa:SystemKind.

NOTE: alternative names could be: sosa:SystemModel, sosa:SystemType, ...

@dr-shorthair
Copy link
Collaborator

@alexrobin @KathiSchleidt do you have an opinion on this?

@alexrobin
Copy link
Collaborator

@maximelefrancois86 At the moment, we are using Procedure to provide the datasheet of a System since we consider that the datasheet is the specification that is implemented by the Systeminstance. I think it is the intended usage when the system is a piece of hardware equipment.

@KathiSchleidt @dr-shorthair Can you comment on this usage of Procedure?

If Procedureis indeed intended to be used in this way, then I think we either don´t need a new SystemKindclass or, if we introduce the new class, it should probably be a subclass of Procedure.

@dr-shorthair
Copy link
Collaborator

@alexrobin at first sight at least that is a reasonable approach.

@maximelefrancois86
Copy link
Contributor Author

@alexrobin I'm not convinced at all.

The spec itself mentions that ssn:System can be used to generically refer to a type/kind of system. So it shouldn't be an option to suggest an completely alternative way to model is.

What's more, Procedure describes receipes. It's aligned to dul:Method. oldssn:Process, OM_Process, oboe:Protocol, prov:Plan ... I don't think it's appropriate to use this class to describe the capabilities and other characteristics of the system.

If I model the DHT22 temperature and humidity sensor type as a kind of sosa:Sensor, then I model the fact it observes temperature and humidity using the sosa:observes property.
If instead I model this sensor type as a kind of sosa:Procedure, then I cannot link it to the temperature and humidity properties.
Some systems/sensors implement more than one procedure, although they are described in exactly one datasheet.

@alexrobin
Copy link
Collaborator

@maximelefrancois86 I actually agree with you. I have never really liked the idea of using Procedure to describe a "kind of System" but I have been told by the OMS/O&M group that it is way we should model it. Since I didn't want to reinvent the wheel, I decided to go with that approach.

You're right that the link between Procedure and ObservedProperty is missing, but this addition has been requested in issue #47 (Note that it was originally requested by @sgrellet).

@maximelefrancois86
Copy link
Contributor Author

maximelefrancois86 commented Nov 30, 2023

While discussing for the new version of ETSI SAREF with @rgcmme , it was agreed to keep only two classes. In particular, to avoid having a common super-class that we hope nobody will use.

As sosa:Device is most commonly used to represent actual devices, not types/kinds of devices, we would keep it for this purpose.

For the class that models device types/kinds , different proposals were made:

DeviceKind / Type / Model / Category /Specification / Prototype / ...

After some discussion with @dr-shorthair , only DeviceKind / and DeviceType are good candidates. They are the most generic ones. Some considerations:

  • In the Semantic Web context, using "type" in the name would be considered bad practice. Given it's used in rdf:type, it's commonly agreed that types should be classes, not individuals.
  • the convention in QUDT is to use "Kind" (quantity kind), so that's a good option.
  • the convention in OMS is to use "Type": (feature type, property type).

@alexrobin
Copy link
Collaborator

@maximelefrancois86 is sosa:Device defined somewhere? I cannot find it in the current draft.
Are you referring to the ssn:Device class that existed before the alignment with SOSA?

I liked your idea of having SystemKind, although I would like to have the ability to provide capabilities and characteristics of platforms as well (and Platform is NOT a System in the current ontology, which I find a bit strange...).

Thanks,

@maximelefrancois86
Copy link
Contributor Author

Device is from SAREF. I mixed this up a bit.

Please read: sosa:System, sosa:Sensor, sosa:Actuator, sosa:Sampler, would be for the actual systems,
And: sosa:SystemKind, sosa:SensorKind, sosa:ActuatorKind, sosa:SamplerKind for the kinds/types.

Indeed we could also differentiate Platform vs PlatformKind

In SOSA Platform is NOT a System because it was decided not to define subclasses.
We could have added that axiom in SSN, but we didn't. I wouldn't be able to explain why. This may be the object of a separate issue?

@alexrobin
Copy link
Collaborator

@maximelefrancois86 Ok, that makes sense to me.

@dr-shorthair what are your thoughts on this? Is using Procedure to provide datasheet type info (i.e. system characteristics and capabilities) still considered good practice or should we move to the SystemKind approach in addition to Procedure?

@rob-metalinkage
Copy link
Contributor

Device characteristics are not part of a procedure. I saw recently a case where the identical open source sensor was used to measure ostensibly the same feature type (air quality in a room) but significant differences in procedure resulted in incompatible data.

One aspect of the difference was standardisation of siting - arguably this is nuanced sampling etc, but the point is differences in level of abstraction in one dimension tend to result in shifting the specialisation to another, finer grained semantics between instance and kind seems to be a pattern that helps.

I also wonder about FoIKind . If a referenced feature is polymorphic is it important to understand the context and which view of that feature has the relevant properties if you want to make an observation on the state of it...

@alexrobin
Copy link
Collaborator

alexrobin commented Dec 1, 2023

@rob-metalinkage Yes, as I said I tend to agree with this (it actually solves some of my problems), but be aware that the OMS v3 conceptual model kind of hints at using the Procedure class to describe sensor/observer types.

From https://docs.ogc.org/as/20-082r4/20-082r4.html#_observingprocedure

NOTE 5: The observing procedure cannot describe a sensor instance, but it can describe the sensor type.

From https://docs.ogc.org/as/20-082r4/20-082r4.html#_observer

NOTE 2: The Observer is the entity instance, not the entity type. Pertaining to sensors, the Observer would reference the explicit sensor, while the Procedure would reference the methodology utilized by that sensor type.

And I clearly remember discussions with the OMS folks where they recommended using the Procedure class to describe a sensor "datasheet". @KathiSchleidt @sgrellet Am I wrong, could you comment on this?

@sgrellet
Copy link
Contributor

sgrellet commented Dec 2, 2023

@alexrobin : indeed, the underlying rationale in OMS was

to try and desambiguate what people were doing with OM:OM_Process (depending on communities/best practices it was either used for Sensor Types or for Sensor Instances)

@alexrobin
Copy link
Collaborator

alexrobin commented Dec 5, 2023

Thanks for the confirmation @sgrellet. That's what I understood from our conversations and I thought having two separate classes Observer and ObservingProcedure was a great improvement over OM_Process.

However, apparently there is still ambiguity between Procedure to describe a methodology and Procedure to describe a sensor type (i.e. datasheet). And it's true that in many cases one uses a sensor of a particular type, but also follows a certain procedure to use that sensor. So you end up with two Procedures (if we follow the OMS definition of Procedure).

The way I have solved this in Connected Systems is by attaching one Procedure to the Observer/Sensor instance (this one describes the sensor type) and another Procedure to the Deployment to describe how the sensor is used in that particular deployment (i.e. the methodology).

I like the new proposal for new ***Kind classes, but how do we reconcile the semantics?

@dr-shorthair
Copy link
Collaborator

Could we just allow more than one usedProcedure link on an Observation/Actuation/Sampling activity?
Else retain the [1..1] cardinality but define a 'Procedure container' which in turn refers to both a datasheet and a methodology?

@ldesousa
Copy link
Contributor

ldesousa commented Jan 5, 2024

I would rather retain the [1..1] cardinality, but I would still see the "Procedure container" option as less than optimal. The case that @alexrobin described makes me wonder if instead we are missing something such as a SensorSetup class, to be instanced with e. g. a datasheet, wavelength interval, etc. The term "procedure" conveys a somewhat different concept, in my view.

@rob-metalinkage
Copy link
Contributor

This is the same pattern we see for every dimension of the problem. IMHO symmetry will reduce complexity, so what we do for observed property should also apply to procedure, sensor, and perhaps metadata such as result, foi type etc.

IMHO we should describe the requirements, the pattern, and then the places it is applied in a separate section.

Let's do this first before risking different solutions and naming.

There are at least three layers...

The semantics of kind, with relationships between levels of generalisation

The implementation metadata the user needs.. I.e. the schema and data model used to describe the description

The instance

It's analogous to Web links, where we are inheriting rather adhoc mixtures of solutions to these when we come to schemas, generalised links, feature Type, features Schema properties etc.

@alexrobin
Copy link
Collaborator

@dr-shorthair I think the [1..1] cardinality on usedProcedure in Observation/Actuation/Sampling is fine if we only use this association to specify the procedure/method used for this particular obs, but not to point to a procedure/datasheet.

The datasheet is something that is mostly associated to the system itself because it is usually provided by the manufacturer and assumed to be valid no matter how the system is deployed or used (although some elements in the datasheet can be specified for different deployment conditions). So I don't think there is a real need to associate the datasheet to the Observation/Actuation/Sampling directly. One can get to it transitively through the System instance.

Perhaps we just need to clarify that the implements association on System can point to a different Procedure than the one on the Observation/Actuation/Sampling generated by that system? Although it is not clearly said, I think now there is an assumption that everything would link to the same Procedure.

This would handle the use case where the System represents a hardware device and points to the procedure/datasheet using the implements link, while the Observation/Actuation/Sampling (or an entire collection of these) references the procedure/method using the usingProcedure link.

In the case where the System represents a human observer, then perhaps the datasheet does not make sense so both links would point to the same Procedure.

I still like the SystemKind proposal, but this would be a way to make this work better without having to introduce new classes.

@dr-shorthair
Copy link
Collaborator

dr-shorthair commented Jan 9, 2024

Thanks @alexrobin

As I don't work in this part of the space much, I'm finding it a bit hard to follow. Would it be possible to generate (or point to) some examples to support the approach(es) that you are describing?

TBH I'm very happy to be guided by you and @maximelefrancois86 who I think have the most experience in this space. If it involves new terms, then that's OK providing we have evidence of implementation for any normative terms. However, also note that I won't be able to generate either the sections in ssn/index.html or the definitions in ssn/integrated/sosa.ttl, ssn.ttl, ssn-system.ttl etc, so resolving this will depend on you guys doing the work and preparing the PR(s).

@alexrobin
Copy link
Collaborator

alexrobin commented Jan 10, 2024

@dr-shorthair Sorry I think trying to explain things in plain English makes things confusing :-) Or maybe I don´t speak English correctly !

It boils down to the following.
We currently have the following association chains:

Observation ---- madeBySensor  ----> Sensor ---- implements ----> Procedure (1)
          |----- usedProcedure ----> Procedure (2)

Is there a requirement that Procedure (1) is the same as Procedure (2) ?

If not, then this could be a way of specifying the methodology used separately from the sensor specs (datasheet), by pointing to 2 different Procedure instances:

  • Procedure (1) would be the sensor datasheet.
  • Procedure (2) would be the methodology used when making these particular observations with that sensor.

The same applies to Actuation and Sampling since we have the following association chains:

Actuation ---- madeByActuator ----> Actuator ---- implements ----> Procedure (1)
        |----- usedProcedure  ----> Procedure (2) 

Sampling ---- madeBySampler ----> Sampler ---- implements ----> Procedure (1)
       |----- usedProcedure ----> Procedure (2) 

@alexrobin
Copy link
Collaborator

Maybe that's how it was always intended to be used but I don't think it clearly says this anywhere...

@dr-shorthair
Copy link
Collaborator

Thanks @alexrobin - I'm cogitating on it.
There should be a relationship between Procedure (1) and Procedure (2) I think?

@alexrobin
Copy link
Collaborator

alexrobin commented Jan 11, 2024

@dr-shorthair Yes, there is some kind of relationship for sure. I would say that Procedure (2) always involves Procedure (1) in some way, if it is set. I see mostly 2 cases:

  • Procedure (1) is not set at all. For example, in the case of a human observer or sampler. Because a human can implement many different procedures at different times, it's cumbersome to associate the human to the procedure directly via the implements association (which to me is a more 'permanent' association). Procedure (2) defines the methodology used by the human operator.

  • Procedure (1) is a datasheet that represents a System/Sensor/Actuator/Sampler kind. Procedure (2) refers to Procedure (1) and explains how it is setup or being used, and perhaps how it can change some of the capabilities specified in the datasheet. I believe this is essentially the SensorSetup idea that @ldesousa was mentioning.

I think we can do all this with the current model, so perhaps initially, simple clarifications in the documentation could suffice. But creating subclasses of Procedure such as SystemSetup/SystemKind, SensorSetup/SensorKind, ActuatorSetup/ActuatorKind, SamplerSetup/SamplerKind would certainly clarify things.

@ldesousa @maximelefrancois86 @sgrellet Does it make sense to you guys?

@sgrellet
Copy link
Contributor

+1 on relationship between Procedure (1) and Procedure (2) I think

Overall, I feel that we are entangled in that discussion in

  • a granularity issue : sensorType VS datasheet. In OMS when mentioning sensor type we never opened the "datasheet" door (to me that's a different beast with specific semantics and hopefully specified somewhere in the industry)
  • without a full-blown example,
  • and maybe missing of a finer Procedure description or even Datasheet concept (depending on the full-blown example outcomes and our joint needs).

I've seen above the mention of

  • the usedProcedure which could be super fine grain or just the sensorType (because that's the only info people have in their information system UseCase).
  • a datasheet but how would it be semanticized using SOSA ? would hasInput/hasOuput be sufficient ?
  • deployment related configuration => Re Rob ("standardisation of siting") and Alex ("explains how it is setup") above

What do we want here ?

  • A°/ to enable fine grain description of how the system works (how close to an electronic/industry spec ?)
  • B°/ to point out that a sensor/system procedure is compliant to a given observation protocol constraint defined in a norm (ex: ISO 17378-2:2014, Water quality, Determination of arsenic and antimony Part 2: Method using hydride generation atomic absorption spectrometry (HG-AAS)). Keeping in mind that a norm can defined several ways to obtain a result.
  • C°/ to create a link between usedProcedure and implements so that we could test coherence between the description of the observing system and the observation generated.

=> Could we discuss this during a webconf with an example (and drawings to help abstraction) ?

@alexrobin
Copy link
Collaborator

alexrobin commented Jan 11, 2024

@sgrellet All good points. I know OMS does not go as far as describing datasheets but SSN kinda does already by defining System Capabilities.

To me, the idea of a "SensorKind" is just to factor out some of these capabilities so they can be reused by many instances of the same sensor model, instead of repeating them in each instance. It's different from sensor type that is usually just a classifier.

That said, I don't necessarily expect SOSA/SSN to provide everything to specify datasheet level info, but what I would like is that the SOSA/SSN model clearly identifies the place where this information should be provided (i.e. in what class and via which association), and how it works when a procedure/methodology is also provided.

As mentionned by @maximelefrancois86 at the beginning of this thread, there is clearly some confusion right now since the ssn:System class (or the derived classes sosa:Sensor, sosa:Actuator, etc.) is sometimes used to describe a system kind (i.e. datasheet), and sometimes used to describe a system instance.

My understanding was that this issue was solved in OMS by separating out the Observer (equivalent to sosa:Sensor) and Procedure (equivalent to sosa:Procedure) concepts. What I discovered here is that not everybody is aligned on that approach and since it's not documented in SOSA/SSN, it is still up to interpretation.

@KathiSchleidt
Copy link
Contributor

KathiSchleidt commented Jan 11, 2024

In OMS, we skirted by the datasheet issue by ignoring it, letting users provide a reference in the Observer if they wish. But I've always worried a bit about this omission, do think we need all 3 levels of:

  • Procedure: abstract process followed
  • SensorKind: datasheet
  • Sensor: specific instance

What's still unclear to me from the discussion above are the relations to/between these concepts. I've done a quick sketch from some existing diagrams to illustrate the various cases described above (e.g. a human observer not having a datasheet, a sensor implementing 2 different procedures) we can use to discuss this evening

@alexrobin
Copy link
Collaborator

alexrobin commented Jan 16, 2024

@KathiSchleidt I agree with you but now that we are talking about all this, I think I'm unclear about what "A sensor implements a procedure" even means.

I always thought in the case of a sensor device, the implements association was intended to point to the datasheet...

It's clear to me that a "human sensor" can implement a procedure, but how can a piece of hardware implement a procedure that's not already specified in its datasheet?

I'm also unfamiliar with the use case "a sensor implementing 2 different procedures". How can a sensor device implement two procedures at the same time? Are we talking about cases where a sensor has different modes? Where the sensor is highly programmable? Can you give a concrete example of this?

I can clearly see cases where a human implements a procedure that may involve a sensor, but it's not the same as the sensor itself implementing a procedure.

Just trying to connect the dots before I start drafting some ideas in the PR.

Thanks,

@rob-metalinkage
Copy link
Contributor

Can we find a compromise with a range Includes System,SystemKind. Personally I'd like an unambiguous predicate for each, and leave a deprecated ambiguous one for backwards compatibility

@dr-shorthair
Copy link
Collaborator

@kjano wrote

I have not yet seen an example where this cannot be done via patterns, CGI, metamodeling, etc.
We have known how to deal with most of these cases since Noy's work 20 years ago.

Could you spell out some small examples please?

@kjano
Copy link
Collaborator

kjano commented Jun 16, 2024 via email

@rgcmme
Copy link

rgcmme commented Jun 17, 2024

If the couple <*>Kind and <*>Instance are created, I would try to avoid making them subclass of the <*> class.

<*>Kinds are abstract entities (e.g., datasheets) and <*>Instances are physical ones. The class <*> would be something that represents both abstract and physical entities:

  • It will give problems when aligning to any top-level ontology.
  • It will be confusing for users (and some will still even instantiate it).

Also, creating this structure for FeaturesOfInterest, Systems, Sensors, Actuators, etc. would make SOSA not so straightforward as already mentioned. I would move all the <*>Kinds to some existing module.

For example, for me this information about <*>Kinds fits well in the "System Capabilities" module (at least for SystemKinds).

For the rest of kinds, maybe we have to ask ourselves is SOSA/SSN is the ontology to be used to represent (for example) kinds of features of interest. In other words, is it in our requirements to cover this?

@oldskeptic
Copy link
Contributor

I'm writing this after an extra-ordinary Sosa session that @rob-metalinkage and myself had last night over a few drinks. I think we were on our way to solving all the world's problems before I had to run and catch a train.

My understanding of the System + SystemKind or Sensor + SensorKind is this:
Untitled

However, it seems to me we are not using the RDF/OWL tools already available. Sub-classing would make things a lot easier using established type / subclass patterns (PR #196 works like this).

Untitled

As @kjano noted, the addition of OWL restrictions by implementers can force all sensors to share the same characteristics or can allow for local properties to document the idiosyncrasies of individual sensors.

To my mind, a data sheet is a human oriented document that Sosa should reference without specifying a format. I'd suggest using foaf:Document or something as a placeholder. I agree that a Procedure is not a Data Sheet but this is how our current examples are presenting it which needs to change.

As an implementer, I really want a normative property to link SystemCapabilities, and the Procedure used, to its authoritative human-readable source. I'd also like to point out the need for both the System and Platform classes: as with the case in PR #196, several sensors are often bundled together within the same immutable tangible "thing" and then bolted onto a Platform to actually record Observations within a Deployment.

I don't think we are all far apart; it's the linkages between the things that is tricky.

@oldskeptic
Copy link
Contributor

How about using prov:hadPrimarySource to link the SystemCapabilities to the data sheet?

@dr-shorthair
Copy link
Collaborator

dr-shorthair commented Jun 21, 2024

Apologies for letting this sit a week.

I believe I now understand what @kjano is proposing, and broadly how it relates to the sketch by @oldskeptic immediately above.

Pattern A. Here is an InkBird example done using sub-classing:

<https://example.org/sensor/IBS-TH2> rdf:type owl:Class ;
    rdfs:subClassOf sosa:Sensor ;
    gs1:pip <https://inkbird.com/products/hygrometer-ibs-th2> ;
    rdfs:label "Bluetooth Temperature and Humidity Sensor IBS-TH2" ;
    skos:notation "IBS-TH2" ;    skos:note "using skos:notation for the model number " ;
    sosa:observes <http://qudt.org/vocab/quantitykind/Temperature> ;
    system:hasSystemCapability [ ... details omitted ...    ] ;
. 

<https://example.org/sensorInstance/IBS-TH2-56> rdf:type <https://example.org/sensor/IBS-TH2> ;
    skos:notation "12gth456a-23190" ;    skos:note "using skos:notation for the serial number " ;
. 

<https://example.org/observation/O-3451> rdf:type sosa:Observation ;
    sosa:observedProperty <http://qudt.org/vocab/quantitykind/Temperature> ;
    sosa:madeBySensor <https://example.org/sensorInstance/IBS-TH2-56> ;
    sosa:resultTime "2024-06-21T15:33:00.00+10:00" ;
    sosa:hasSimpleResult "19.4"^^unit:DEG_C ;
. 

Here's a visual representation
Inkbird-examples-subclass

(@oldskeptic I think you have some arrows the wrong way round.)

Pattern B. Compare this with the same example done using the proposed SensorKind and SensorInstance classes:

<https://example.org/sensorKind/IBS-TH2> rdf:type sosa:SensorKind ;
    gs1:pip <https://inkbird.com/products/hygrometer-ibs-th2> ;
    rdfs:label "Bluetooth Temperature and Humidity Sensor IBS-TH2" ;
    skos:notation "IBS-TH2" ;    skos:note "using skos:notation for the model number " ;
    sosa:observes <http://qudt.org/vocab/quantitykind/Temperature> ;
    system:hasSystemCapability [ ... details omitted ... ] ;
. 

<https://example.org/sensorInstance/IBS-TH2-56> rdf:type sosa:SensorInstance ;
    sosa:ofSystemKind <https://example.org/sensorKind/IBS-TH2> ;
    skos:notation "12gth456a-23190" ;    skos:note "using skos:notation for the serial number " ;
. 

<https://example.org/observation/O-3451> rdf:type sosa:Observation ;
    sosa:observedProperty <http://qudt.org/vocab/quantitykind/Temperature> ;
    sosa:madeBySensor <https://example.org/sensorInstance/IBS-TH2-56> ;
    sosa:resultTime "2024-06-21T15:33:00.00+10:00" ;
    sosa:hasSimpleResult "19.4"^^unit:DEG_C ;
. 

Inkbird-examples-sensorKind

The a-box in the bottom half of the diagrams are essentially isomorphic.
Pattern B. uses two new classes, and requires one additional triple to link an instance to a kind.

Since there is no actual benefit from introducing the SensorKind and SensorInstance classes, then I'm inclined not to do so. Pattern A. (using sub-classing for sensor-kinds (datasheet), with individual sensors using rdf:type to link to the kind), (i) loses no information, and (ii) is arguably better OWL/RDFS.

However, some thought is required over the domains and ranges of some of the predicates, in particular:

  1. is the range of sosa:madeBySensor a class (i.e. a sub-class of sosa:Sensor) or an instance of sosa:Sensor (or one of its subclasses, including SensorKind and SensorInstance), or either
    • until now I had expected it to be an instance of sosa:Sensor which is why an explicit instance is added in the top example
    • however I believe @kjano would prefer it to be a 'kind' whenever the additional details of an individual sensor instance are not important - I agree
    • so to support that case, using the sub-classing pattern, then would madeBySensor need to link to a class?
  2. similarly, is the domain of sosa:observes a class (i.e. a sub-class of sosa:Sensor) or an instance of sosa:Sensor (or one of its subclasses, including SensorKind and SensorInstance), or either
    • for the sub-classing pattern, sosa:observes must be attached to a class
  3. ditto system:hasSystemCapability

Finally, it means that a register of Sensor kinds would be populated by OWL classes not OWL individuals.
A register of Sensor instances would still contain OWL individuals. I don't see any problem with that.

@alexrobin
Copy link
Collaborator

@dr-shorthair Thanks Simon for the detailed example.

I think using individuals for instances and classes for types makes a lot of sense, as it follows general OWL practices. I don't mind dropping the SystemKind/SystemInstance stuff completely because we can use the original classes (System/Sensor/Actuator/Sampler) to tag both instances and types in our application (i.e. SensorML and Connected Systems API).

If we do stick with pattern A, is there still a need for clarification about property ranges in this case? For example, will sosa:madeBySensor always link an Observation individual to a Sensor individual or could it also link to a Sensor subclass (question mark on your first diagram)? I think technically, in OWL, "Object properties always connect pairs of individuals" so it should NOT be used to reference the class itself. Instead, it should ALWAYS be done through a Sensor instance that then references the type using the rdf:type predicate (like in your example).

Also I think some of the issues come up in the hasSystemCapability part that you omitted because it's more cumbersome to set capabilities values in the class (I think you have to use OWL restrictions, etc...). I'm not sure that's a good enough reason to break the well known individual/class pattern though, so we probably just have to live with the verbosity of OWL in this case.

@dr-shorthair
Copy link
Collaborator

dr-shorthair commented Jun 26, 2024

For datasheets modeled as classes, the capabilities would be expressed as owl:Restrictions.

(Note: a simplified version in #107 (comment) was subsequently developed, which improves on the first part of this code)

<https://example.org/sensor/IBS-TH2-Plus>
  a owl:Class ;
  dcterms:isVersionOf <https://inkbird.com/products/ibs-th2-plus> ;
  rdfs:comment """
    An InkBird IBS-TH2-Plus is a combined Temperature/RH sensor. 
    Here I have modeled the whole thing as a System with a SubSystem for each of temperature and RH
    """ ;
  rdfs:label "IBS-TH2 PLUS Temperature and Humidity Sensor System" ;
  rdfs:subClassOf sosa:System ;
  rdfs:subClassOf [
      a owl:Restriction ;
      rdfs:comment """
          In this Restriction I'm trying to say that every instance of IBS-TH2-Plus 
          - must have two sub-systems
          - the value of one sub-system must be an instance of IBS-TH2-Plus-T - a temperature Sensor
          - the value of the other sub-system must be an instance of IBS-TH2-Plus-H - a relative-humidity sensor

          I don't think I've got there yet 
          """ ;
      owl:allValuesFrom [
          a owl:Class ;
          owl:unionOf (
              [
                a owl:Restriction ;
                owl:hasValue [
                    a owl:Class ;
                    owl:oneOf (
                        <https://example.org/sensor/IBS-TH2-Plus-T>
                      ) ;
                  ] ;
                owl:onProperty sosa:hasSubSystem ;
              ]
              [
                a owl:Restriction ;
                owl:hasValue [
                    a owl:Class ;
                    owl:oneOf (
                        <https://example.org/sensor/IBS-TH2-Plus-H>
                      ) ;
                  ] ;
                owl:onProperty sosa:hasSubSystem ;
              ]
            ) ;
        ] ;
      owl:cardinality "2"^^xsd:nonNegativeInteger ;
      owl:onProperty sosa:hasSubSystem ;
    ] ;
  rdfs:subClassOf [
      a owl:Restriction ;
      rdfs:comment """
          This Restriction says that every instance of IBS-TH2-Plus has the same overall system capability, 
          relating to sampling frequency 
          """ ;
      owl:hasValue <https://example.org/sensor/IBS-TH2-Plus/systemCapability> ;
      owl:onProperty system:hasSystemCapability ;
    ] ;
  prov:wasDerivedFrom <https://inkbird.com/products/ibs-th2-plus> ;
.
<https://example.org/sensor/IBS-TH2-Plus-H>
  a owl:Class ;
  rdfs:label "IBS-TH2 PLUS Humidity Sensor type" ;
  rdfs:subClassOf sosa:Sensor ;
  rdfs:subClassOf [
      a owl:Restriction ;
      owl:hasValue <http://qudt.org/vocab/quantitykind/RelativeHumidity> ;
      owl:onProperty sosa:observes ;
    ] ;
  rdfs:subClassOf [
      a owl:Restriction ;
      owl:hasValue <https://example.org/sensor/IBS-TH2-H/systemCapability> ;
      owl:onProperty system:hasSystemCapability ;
    ] ;
.
<https://example.org/sensor/IBS-TH2-Plus-T>
  a owl:Class ;
  rdfs:label "IBS-TH2 PLUS Temperature Sensor type" ;
  rdfs:subClassOf sosa:Sensor ;
  rdfs:subClassOf [
      a owl:Restriction ;
      owl:hasValue <http://qudt.org/vocab/quantitykind/Temperature> ;
      owl:onProperty sosa:observes ;
    ] ;
  rdfs:subClassOf [
      a owl:Restriction ;
      owl:hasValue <https://example.org/sensor/IBS-TH2-T/systemCapability> ;
      owl:onProperty system:hasSystemCapability ;
    ] ;
.
<https://example.org/sensor/IBS-TH2-Plus/systemCapability>
  a system:SystemCapability ;
  system:hasSystemProperty [
      a system:Frequency ;
      schema:maxValue "0.1"^^unit:HZ ;
      schema:minValue "5.556e-4"^^unit:HZ ;
      rdfs:comment """
          This SystemCapability describes the range of sampling frequencies available. 
          It could also be modelled as an enumeration of specific values
          """ ;
    ] ;
.
<https://example.org/sensor/IBS-TH2-H/systemCapability>
  a system:SystemCapability ;
  system:hasSystemProperty [
      a system:Accuracy ;
      schema:value "4.5"^^unit:PERCENT_RH ;
    ] ;
  system:hasSystemProperty [
      a system:MeasurementRange ;
      schema:maxValue "99.0"^^unit:PERCENT_RH ;
      schema:minValue "0.0"^^unit:PERCENT_RH ;
    ] ;
.
<https://example.org/sensor/IBS-TH2-T/systemCapability>
  a system:SystemCapability ;
  system:hasSystemProperty [
      a system:Accuracy ;
      schema:value "0.5"^^unit:DEG_C ;
    ] ;
  system:hasSystemProperty [
      a system:MeasurementRange ;
      schema:maxValue "60.0"^^unit:DEG_C ;
      schema:minValue "-40.0"^^unit:DEG_C ;
    ] ;
.

@dr-shorthair
Copy link
Collaborator

Consensus of 2024-06-26 telecon (+ @alexrobin asynchronously) is to proceed with Pattern A. - i.e. system-types (data-sheets) are subclasses of sosa:System (and its subclasses sosa:Sensor, sosa:Actuator, sosa:Sampler)

  • complete Inkbird example as illustration in rec document
  • @oldskeptic to propose simplified system-capabilities schema to support simpler owl:Restriction patterns
  • @dr-shorthair to update documentation in HTML and RDF to introduce system-type pattern

@dr-shorthair
Copy link
Collaborator

@kjano could you confirm that I got it right in #107 (comment)

@dr-shorthair
Copy link
Collaborator

and is there something better than schema.org for the value/minValue/maxValue properties of the system properties??

@dr-shorthair
Copy link
Collaborator

dr-shorthair commented Jul 1, 2024

The version above is possibly overcomplicating.
Recalling that many OWL design problems are easier when you go back to set-theory, this is simpler and maybe better:

<https://example.org/sensor/IBS-TH2-Plus>
  a owl:Class ;
  rdfs:label "IBS-TH2 PLUS Temperature and Humidity Sensor System" ;
  rdfs:subClassOf sosa:System ;
  rdfs:subClassOf [
      a owl:Restriction ;
      owl:hasValue <https://example.org/sensor/IBS-TH2-Plus/systemCapability> ;
      owl:onProperty system:hasSystemCapability ;
    ] ;
  rdfs:subClassOf [
      a owl:Restriction ;
      owl:cardinality "2"^^xsd:nonNegativeInteger ;
      owl:onProperty sosa:hasSubSystem ;
    ] ;
  rdfs:subClassOf [
      a owl:Restriction ;
      owl:onProperty sosa:hasSubSystem ;
      owl:someValuesFrom <https://example.org/sensor/IBS-TH2-Plus-H> ;
    ] ;
  rdfs:subClassOf [
      a owl:Restriction ;
      owl:onProperty sosa:hasSubSystem ;
      owl:someValuesFrom <https://example.org/sensor/IBS-TH2-Plus-T> ;
    ] ;
  prov:wasDerivedFrom <https://inkbird.com/products/ibs-th2-plus> ;
.

This says: IBS-TH2-Plus is

  • a subclass of sosa:System
  • a subclass of the anonymous class of things with the system:hasSystemCapability fixed to IBS-TH2-Plus/systemCapability (this gives the overall sampling frequency)
  • a subclass of the anonymous class of things with exactly 2 sub-systems
  • a subclass of the anonymous class of things with a sub-system of type IBS-TH2-Plus-H (relative humidity sosa:Sensor)
  • a subclass of the anonymous class of things with a sub-system of type IBS-TH2-Plus-T (temperature sosa:Sensor)

I think this is pretty close to what we want.

Cross-references are to the same things shown above.

@oldskeptic I went with https://inkbird.com/products/ibs-th2-plus because the spec-sheet is more explicit

@dr-shorthair
Copy link
Collaborator

dr-shorthair commented Jul 3, 2024

I've had a go at documenting this, with some examples. See previews at

@dr-shorthair dr-shorthair changed the title Distinguish sosa:SystemKind and sosa:SystemOfInterest System types and individuals Jul 3, 2024
@rob-metalinkage
Copy link
Contributor

Using rdf:type will not allow systems that use rdf:subClassOf reasoning to forward chain/entail to determine which value of rdf:type references the specific objectType. Agree we dont need a SystemKind class.

@maximelefrancois86
Copy link
Contributor Author

I'm unhappy with the result.

Recommending to use OWL for simple descriptions seems to me like pushing out of the way a lot of interesting use cases for SOSA. The description in #107 (comment) is not something I feel comfortable to recommend to anyone. The one in #107 (comment) is OWL full because of cardinality=2

Note that if we apply the same decision to properties, this would mean taxonomies of properties should be rewritten as hierarchies of property classes... This seems like a double standards policy

Plus, datasheets describe archetypes of sensors. We cannot be sure that a specific instance of a sensor will conserve over time the characteristics specified in its datasheet.

@oldskeptic
Copy link
Contributor

Maxime,

I think that you are misinterpreting it. We're designing it to allow OWL for complex descriptions; the problem with SystemKind was that it was fundamentally re-creating rdf:type.

For properties, we have the following use cases:

  1. A one-off sensor with properties.
  2. A model of a sensor that has properties specified by a data sheet where all of the instances in existence are explicitly assumed to always perfectly conform to the sensor model properties.
  3. A model of a sensor that has properties specified by a data sheet where all of the instances in existence are implicitly assumed to always perfectly conform to the sensor model properties. This may not be correct from an ontology / dl perspective, but that's the practice.
  4. A model of a sensor that has multiple instances in existence where sensor instance properties may or have deviated from their specifications and additional properties may be attached to some sensors.
  5. Lastly, a model of a sensor that has multiple instances in existence where no one wrote anything down.

The example shows how case 2 can be documented by OWL, through other implementers will enumerate this using rdfs only. The examples aren't normative but they communicate how Sosa can leverage OWL/RDFS to deal with and document operating conditions that are usually buried in a report narrative.

We have not addressed this in the current version of Sosa and this is a pattern that applies to #221 also. Some implementations assume that accuracy and precision properties apply to all results evenly. Obviously, this isn't so for use cases such as GPS readings where both vary across results. The example demonstrate owl-full, the rule could just as well be encoded in the software generating the rdf.

@dr-shorthair
Copy link
Collaborator

Using rdf:type will not allow systems that use rdf:subClassOf reasoning to forward chain/entail to determine which value of rdf:type references the specific objectType. Agree we dont need a SystemKind class.

I have updated the Mums-clinical-thermometer example so that the individual refers to all the classes up the hierarchy - simulating the closure I think you were concerned about.

Then this relatively simple SPARQL query can find the 'most specialized type' for the thermometer:

SELECT *
WHERE 
{
    ex:Mums-clinical-thermometer rdf:type ?c .
    FILTER NOT EXISTS { 
 	      ?s rdfs:subClassOf ?c . 
    }
}

The result is ?c = sensor:Mercury-in-glass-thermometer as required.

Is that OK @rob-metalinkage ?

@dr-shorthair
Copy link
Collaborator

Plus, datasheets describe archetypes of sensors. We cannot be sure that a specific instance of a sensor will conserve over time the characteristics specified in its datasheet.

Indeed. However, the description of the individual can add system capabilities to the ones specified for the class. If these are within the ranges specified on the class (archetype), then that's fine. If they conflict with the class, then the individual is no longer a member of the class (i.e. does not conform to the archetype) so should not make that claim.

@dr-shorthair
Copy link
Collaborator

dr-shorthair commented Jul 5, 2024

The one in #107 (comment) is OWL full because of cardinality=2

In practice we could drop the cardinality restriction with only minor loss of detail for this example.

Many variations in the dialects of OWL and even SHACL will be used for the description of system-types. I can imagine that some users would just drop some text into a comment or description. The degree of support for reasoning within the graph will vary similarly.

The intention of the examples here is merely to illustrate the general principle, for those OWL-ish users who want to approach it that way, that specialized sensors types can be represented as subclasses of sosa:Sensor with precision matching that of a typical datasheet. The key discovery is that there is no need for a SystemKind class, so introducing it would risk diminishing interoperability using SSN/SOSA.

@rob-metalinkage
Copy link
Contributor

rob-metalinkage commented Jul 5, 2024

This is a fair bit of work to find the most specific type, compared to a simple non-transitive property. There is no need for SPARQL in many applications, where graph traversal can be done in other ways. This is introducing a significant implementation burden compared to accessing a known property IMHO.

Also I don't think you can assume there are no subclasses of the specific type - even more specific types. So the SPARQL would need to be more like

SELECT *
WHERE 
{
    ex:Mums-clinical-thermometer rdf:type ?c .
    FILTER NOT EXISTS { 
              ex:Mums-clinical-thermometer rdf:type ?s .
 	      ?s rdfs:subClassOf ?c . 
    }
}```

@rob-metalinkage
Copy link
Contributor

rob-metalinkage commented Jul 8, 2024

A corollary would be an entailment rule for a node ($this)

CONSTRUCT $this sosa:systemKind ?c
WHERE 
{
    $this rdf:type ?c .
    FILTER NOT EXISTS { 
              ?s rdf:type ?s .
 	      ?s rdfs:subClassOf ?c . 
    }
}```

@dr-shorthair
Copy link
Collaborator

dr-shorthair commented Jul 9, 2024

Thanks for that correction @rob-metalinkage - indeed, my version would find additional sub-classes below the ones associated with $this. Your correction fixes that.

Thinking about the proposed sosa:hasSystemKind predicate: I have not seen sub-properties of rdf:type before, but I don't believe it is prohibited. I think it would have to be formulated this way:

sosa:hasSystemKind
  rdf:type rdf:Property ;
  rdfs:subPropertyOf rdf:type ;
.

sosa:System
  rdfs:subClassOf [
      rdf:type owl:Restriction ;
      owl:hasValue sosa:System ;
      owl:onProperty sosa:hasSystemKind ;
    ] ;
  rdfs:subClassOf [
      rdf:type owl:Restriction ;
      owl:maxCardinality "1"^^xsd:nonNegativeInteger ;
      owl:onProperty sosa:hasSystemKind ;
    ] ;
.

The prototype rdf:type has rdfs:range rdfs:Class (which covers owl:Class as well of course).
So the object of a rdf:type property is a thing of type Class.

So how do we fix the behaviour of sosa:hasSystemKind?

  • The hasValue restriction says that, in the context of a member of sosa:System, the object of any property with the predicate sosa:hasSystemKind is the class sosa:System. Any sub-class of sosa:System satisfies this. It looks a bit weirdly circular ('a system must be of type system') but I think it is what we want.

  • The maxCardinality restriction says that there should not be more than one sosa:hasSystemKind on a System, else we end up in the same troublesome place that @rob-metalinkage is trying to avoid.

Any other suggestions?

@oldskeptic
Copy link
Contributor

This is a fair bit of work to find the most specific type, compared to a simple non-transitive property. There is no need for SPARQL in many applications, where graph traversal can be done in other ways. This is introducing a significant implementation burden compared to accessing a known property IMHO.

I can see people trying to use multiple hierarchies of SystemTypes which would recreate the same problem.

@dr-shorthair
Copy link
Collaborator

I'd like to progress this issue please.
See previews linked in #107 (comment)

@dr-shorthair dr-shorthair linked a pull request Oct 15, 2024 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment