AOM: how do you differentiate between sibling C_OBJECT if both are ARCHETYPE_ROOT and have the same archetype_id?

The issue is the UID in the RM instance doesn’t help to match/find them corresponding C_OBJECT from the template (think of data validation).

1 Like

Thanks @thomas.beale though moving to ADL2 would take a major refactoring on most 1.4 compatible apps, that is why I also try to discuss solutions for 1.4.

@thomas.beale rechecking your message, I understood the AOM2/ADL2 specs require that the archetype ID is modified when there are indistinguishable siblings in the archetype/template (e.g. two archetype slots to the same archetype ID).

So I suppose in a LOCATABLE instance that complies with that archetype/template will have the archetype_node_ids set to the modified archetype IDs, is that correct?

If so, that also implies in AQL we should use the modified archetype IDs not the original ones. So any tool that allows to edit queries should be aware of the modified archetype IDs. Doesn’t that generate issues for querying when you want/need to query by the original archetype ID?

Another design detail is that the modification on archetype IDs seems to be an actual codification of an extra field that contains some kind of numeric index, wouldn’t be clearer to have such field separated from the archetype IDs in the AOM and the RM?

That is also a solution I mentioned above for AOM/ADL 1.4:

In summary, for v1.4 the only solution to this problem is using the name to distinguish C_OBJECTs (as @damoca described on his sept 30 message), which relies on the modeler(s) to do that correctly, since no modeling tools check that, and that could generate bugs in systems that rely on this pattern without checking it, which IMO is dangerous design if not amended on v1.4.

I will actually create a validation rule on all my systems just to check this: if there are two sibling nodes in a template that have the same archetype ID and the same name (or unconstrained), then the template will not be accepted by the system. That is the only way I can provide a reliable product to my users.

Yes, that’s it.

Well it could in the same way that querying for any specialised id isn’t the same as querying for the parent. The querying engine always has to have access to the lineage, i.e. the inheritance structure. That’s why this is discussed in the Archetype Identification specification. An overlay is just a little archetype, just inside the template rather than outside - you’ll see it has a specialise section just like any other specialised archetype.

Again - ADL2 converts the whole functionality of templates to just ‘more of the same’.

This is why I was suggesting that the best workaround is to use specialised archetypes to get different ids - this mimics what ADL2 does.

I’m quite uneasy about that requirement if it applies in the data instance, as well as the template.

In the vast majority of cases, sibling objects will be created at run-time e.g multiple allergies. In other cases where we ‘clone’ e.g an ENTRY object, the real semantic variance is likely to be carried further down in the ENTRY e.g a Risk Identified archetype where the name of the risk is carried as a mandatory element, normally coded. If we have a number of risks e.g . Housebound", “Unable to recognise safety risks”, we will often clone the archetype and fix the risk name for each cloned instance. THe template tools do force us (name/value) to distinguish each archetype root but that is often helpful for developers in understanding the correct paths to follow.

Obviously it is better if name/value override is coded (for translations) but overriding the root archetypeID in the template feels pretty heavy-duty! Maybe ok if this exists in the tooling space but also in instance data?

It should be supported in the tools in a nice way to be usable, that’s for sure. But it’s not really ‘heavy’ - different archetype or overlay ids (= archetype id) just distinguish different modelling semantics for the relevant sibling nodes. If all this were done invisibly in tools, no-one would even think about it.

Are you referring to the archetype inheritance structure?

But the modification of the archetype ID is not really a specialization, because is the same archetype without any internal modification, just the archetype ID. Kind of an aliasing feature more than specialization isn’t it?

The issue here is different, the problem is: “given a RM object instance, how to get the corresponding C_OBJECT from the AOM for each node, if C_OBJECT siblings are indistinguishable”.

So you can have as many RM objects as you want added at runtime, if those sibling objects in the RM instance are constrained by a distinguishable C_OBJECT in the corresponding AOM (e.g. can be found by archetype ID + path), then there is no issue. The problem is having siblings in AOM (not in RM) that for the same archetype ID and path can match more than one C_OBJECT.

So in the case of the OPT I shared, there are sibling SECTIONs declared in the AOM which have the same archetype ID and path, and the only way of distinguish between those two is by the constraint added to the name, which should be present in any RM object that complies with the OPT. But, you could have (maybe not in the OPT I shared but in general) indeed many instances of SECTION added at runtime, for the same archetype ID + path + name.

What Thomas said, and I’m still processing since I work only with AOM/ADL/TOM 1.4 is in AOM/ADL 2 there is no need of the name constraint since if there are two sibling C_OBJECTs (AOM) with the same archetype ID + path, then one will be transformed to archetype ID-1 + path and the other one will be transformed to archetype ID-2 + path, so there is no collision. Still, your use case of adding multiple nodes in a RM object complying with archetype ID-1 and archetype ID-2 is supported without any issues.

The use case for the original issue is receiving a RM object e.g. via the REST API, like a COMPOSITION, FOLDER, PARTY or EHR_STATUS, and trying to validate that object against the corresponding OPT, so for each node in the RM object, the corresponding C_OBJECT from the template should be found in an unambiguous way, and with archetype ID + path (taken form the RM object’s nodes) alone is not possible, so the name should come into play as a workaround.

As said above, a simple solution would be to have a unique ID for each C_OBJECT in the AOM, and reference that ID from the RM objects, but that is not possible right now, in 1.4 and in AOM2, as Thomas mentioned, that is kind of encoded in the modified archetype ID, which doesn’t seem a very clean solution IMHO, I would opt for having a dedicated field for that instead of coding it inside the arch ID.

As a consequence of requiring the name to distinguish between C_OBJECT nodes in the AOM 1.4 structure is that when uploading an OPT to a system it SHOULD check sibling objects are distinguishable by using the name, since that pattern is not enforced by modeling tools so we can end up with an OPT with indistinguishable nodes if the modeler didn’t constraint the name on those C_OBJECTs that have the same archetype ID and path. And engineers shouldn’t trust modelers :slight_smile:

By the way, there is currently a bug in the Archetype Designer that removes the specialization id from these sibling nodes in the OPT export and thus prevents their use as node discriminators

An overlay is technically a specialisation - it has changes in the constraints, otherwise there is no overlay.

Please report that!

will do ASAP :slight_smile:

I’m not sure what an overlay is in this context. Though I can think of a test case that doesn’t have any changes to the constraints and still have the issue that I mentioned on my first message: can’t match one single C_OBJECT by archeype ID + path.

COMPOSITION

  • SECTION (SECTION.ad-hoc)
    – name = “X”
  • SECTION (SECTION.ad-hoc)
    – name = “Y”

For both sections, the items are not constrained, just the names, then there is a need of identifying each individually. So in ADL2, if I understood correctly, the editor tool should mark the first one as SECTION.ad-hoc-1 and the second as SECTION.ad-hoc-2. That is the border case for a whole family of test cases that show the issue at hand, and there is clearly no extra set of constraints added to neither occurrences of SECTION.ad-hoc.

Just wanted to point you to the following Jira issue which describes a similar issue and has already created some discussion as well:
https://openehr.atlassian.net/browse/SPECPR-279

But name is constrained (at least that’s what I assume you meant with that short-hand!). ADL doesn’t differentiate between different attributes being constrained. Any constraint is a constraint.

Something like that. Maybe it could do SECTION.ad-hoc-ovl1 and SECTION.ad-hoc-ovl2 to make it easier to spot overlays.

See previous comment above!

Thanks Sebastian - we got close to the same point before, and indeed, Heath’s suggestion in that thread is a nice solution I think.

True. So a name constraint in AOM2 is considered a specialization of the base archetype?

Yes, I’m not focusing on syntax but meaning. Any code or number is basically the same.

That is why I mentioned that having a specific field to represent the code/number that differentiates nodes could be a clearer solution than coding in the archetype ID. Something like archetype_id = X, template_node_id = 1 (then 2, 3, 4 for the rest of the C_OBJECTs with the same archetype_id and path). That way we can use the original archetype IDs in queries instead of the aliases.

Though I’m not familiar with the concept of an overlay, for me is just like assigning an alias to the archetype ID to keep them unique in cases of collisions.

From a formal computing point of view, any specialised property is a constraint, and creates a specialised archetype or overlay (which is just an inline specialised archetype).

Here’s an example of a full template with overlays in Github - keep scrolling down :wink:

Thanks Thomas,

It would be really helpful to have an example of a composition instance to understand the implications for querying/ backward compatibility. Could @pieterbos maybe give us an example (does not need to match that template)?

Gotcha, so overlay is actually a construct in AOM2, not really used in the computing way.

In a general computing sense, overlaying means "the process of transferring a block of program code or other data into main memory…

An example would be helpful! I was wondering how a system receiving a COMPOSITION commit (or any LOCATABLE) handles it when it’s constrained by an OPT 1.4 or an OPT 2. I mean, how the system can differentiate them for validating, processing, querying?

ah - you were thinking some kind of memory overlays like in the old PC / DB languages - no, it’s not that :wink:

BTW, Archetype Designer and Archie know how to read these ADL2 templates (for probably a couple of years at least).

I was trying to link the term to something that I know, but in this case seems to be an arbitrary name to a special case of archetype specialization. I’m still not familiar with the AOM2 spec :slight_smile: