Scores or scales with mixed data types or explicit NULL values

These are formally two different vocabularies - the null_flavours is sourced from openEHR terminology, while reason text/codes are on a per archetype basis.

I’d suggest that we don’t want people being able to edit the null_flavours vocabulary in an uncontrolled way (this will wreck any computability). I can imagine however that AD and similar tools would make it easy to see the vocabulary and potentially post a change request.

Well it depends on how computable we want data marked with a null flavour to be. Not applicable is very different from Not available for example.

FYI - ‘masked’ originally was designed to be a NF that is set by a server when it hides (i.e. removes) some data item because it is ‘sensitive’, when it provides the data to some client system or application. Whether this still makes sense is an open question, since I don’t think we seriously envisage marking data as sensitive or not at the ELEMENT level.

Yes - this makes sense and I think it would be good to add this to some documentation/specification.

One use-case could be extract of openEHR data where it could make sense to mask free text (DV_TEXT). By using the masked code the server/routine could inform that some data exist or not.

As you write; data access control on ELEMENT level will be extremely hard to design and implement. If we want to follow this pattern of access controll (to filter data) we could visit the idea of a NULL_FLAVOUR on higher level structures. In some situations it could be relevant to mask an ENTRY or CLUSTER structure. Not that we have seen this in a concrete use-case yet. Still I have from a theoretical view seen this need.

That’s not what I was suggesting …

What if the tooling / visualisation / from build were to allow this visually

Not applicable
Not asked

Essentially the ability to visually add ‘null’ type terms to a normal list, or as a pesudo alternative datatype.

Under the hood these would actually be Null reasons/ null_falvour codes

Not applicable [Reason: Not indicated Null_flavour: not_applicable]
Not asked [Reason: Not asked Null_flavour: ]

which would be represented at run-time exactly as currently intended.

i.e Mild, Moderate, Severe → value
Not applicable → null.null_flavour = not_applicable, null.reason = “Not applicable”

I think we could probably do this with current ADL but I do wonder if this can cope with both ‘technical integration’ constraints (fall back for null data in integrations) and clinical null constraints, essentially specifying allowed null terms that can be entered.


That’s probably a step too weird for me (since it makes values and non-values look like one value space), but I now get what you are suggesting and can see some attraction in it, since normal people (including docs who design healthcare forms etc) often build this kind of mixed value list.

I think to make it work properly, you’d want some way of visually distinguishing the null values, e.g. in a different colour, and to get them added in the first place, you’d have some button for ‘add exception value’ or similar.

I do think it’s necessary to be able to present this visually as if both the ordinal values and the null values belonged to the same value set. But I don’t think it needs to be difficult to visually distinguish them from each other. The paper form screenshot I included in the initial post of this topic does this beautifully: the ordinal values are presented with their respective values to the left, and the null values are presented with, well, nothing :smile:

Agree. I have no problem with making it clear somehow both in tooling and end-user apps that these are nulls but I do think this is probably how they have to be handled to make them useable in archetyping/templating and UI. Under the hood, I 'm happy for these to resolve into the current RM approach. though not sure if anything needs to change to support constraints of null_flavour codes, along with one or more ‘Reason’ codes - this is a pattern quite similar to ism_transitions, I guess and I wonder if the RM might need to change to make constraining easier.


I wouldn’t agree with that: I think it’s reasonable that they can be made to appear that way (as you have shown), but to make them literally part of the same value set, when the 0-3 are values resulting from assessment, and the other two indicate that no assessment was done (or maybe ‘not evaluable’ is actually a kind of evaluation?), would greatly confuse any subsequent inferencing.

Essentially it is mxing values with non-values, which we humans are good at because we are cognitively very sophisticated, and we are abstracting over the difference. But computers just do what they’re told…

Conclusion for now, from the modellers perspective:

The published GOSE archetype uses the ordinal ‘99’ to indicate an unscored value, similar to NANO’s “not assessed” and “not evaluable”. This is similar to option #2, but makes it possible for business logic to tell the actual values apart from the unscored values from the ordinal value itself and not just from the at-codes. We’ll use this pattern for both NANO and NIHSS. Business logic will have to make sure any of the ‘99’s are excluded from any graphing or summing, but this is easier than extracting the numerical value from a string. The plan is to finish review of the archetype and then pause it waiting for the “proper” solution (option 1) to be implemented in tools.

Is there any progression in tooling development wrt how to solve this kind of issue? We’ve now gotten around to doing the NIHSS, which has a similar issue requiring both null_flavour and null_reason. These elements need to be constrainable on the archetype level, and possible to use/visualise through the CKM, in OPTs, in implementations/lowcode tools and renderers, and in CDRs.

@borut.fabjan @sebastian.garde @bna

I think the answer is no but perhaps we can get together as modellers and express a common clear requirement.

So I want to be able to specify, in both

  1. That null_flavours are explicitly available or explicitly not available on an ELEMENT.

  2. If they are available, which null_flavours are allowed ( we already have that)

Perhaps we can make this work already with the existing constraints.

i.e. If you want to permit a null_flavour, you need to make at least one of the null_flavours available, otherwise nulls are not allowed.

One issue to think about is whether as well as having a null reason comment, whether there is any value in allowing other types of term to be used instead of, or alongside the official null_flavours Perhaps a bit like current_state and careflow_step in ACTIONs.

Is it important that we stick absolutely to the current list for computational reasons? Personally I think not. Allowing local null_flavours would solve the problem as with this example


which expects 'Not assessed and ‘Not evaluable’ and not the current terms

Whatever, the tooling should (IMO) be able to show the visually combined lists of true valueset + allowed nulls., but agree with Thomas that these are not actually mixed into a single valueset.

1 Like

Not 100% sure why you need this, but would

null_flavour existence matches {0}

not do this from a specs point of view (tooling is a different issue of course)?

To me the spec is not 100% clear whether we can just use other codes as null_flavour:

4.1. Item Structure Package / Overview

Values from the openEHR null flavours vocabulary, including 253|unknown|, 271|no information|, 272|masked|, and 273|not applicable| are used to populate it. Only a small number of generic codes are defined, in order to avoid complex processing for most data instances, for which this simple classification of null is sufficient.


5.2.3. ELEMENT Class

null_flavour: DV_CODED_TEXT Flavour of null value, e.g. 253|unknown|, 271|no information|, 272|masked|, and 273|not applicable|.

The first seems to mandate or at least strongly encourage a fixed set of null_flavour codes, whereas the second uses “e.g.” to indicate that these are examples only (in my understanding).

Now I guess it depends on the value of having “computable” null_flavours. I suspect that very little can actually be done in terms of computation… If these generic null_flavours are not so useful anyway (due to problems like the ones already described by e.g. @thomas.beale, @bna and myself above already), we might just add custom ones?
If not, I think @ian.mcnicoll has suggested that we could think about custom null_flavours mapping to the core ones (roughly similar in spirit to what we have for ISM_TRANSITION), if I understood you correctly, @ian.mcnicoll? This of course is a somewhat bigger change.

Hi @siljelb ,
This thread you started asking how to model the NANO scale containing elements with a mix of ordinal and NULL values has been marked as solved with this post here. The solution described here is based on solution #2 you proposed, with the difference that NULL values are represented by ‘99’ instead of ‘0’.

However, the current version of the NANO scale (Observation Archetype: Neurologic Assessment in Neuro-Oncology (NANO) scale [Nasjonal IKT Clinical Knowledge Manager], Rev. 2) lists only the measured / observed values in the ordinal data elements and does not list any substitutes for NULL values (neither ‘99’ nor ‘0’), contrary to the post marked as ‘solution’ (I should of course mention that the creation date of this archetype revision is older than this discourse thread).

Is that because you eventually decided to follow your proposed solution #1 after all?

Have you tried to constrain the null_reason RM element with ADL (as it is not supported by modelling tools)?

What are your plans for the modelling of the NANO score?

Hi! We haven’t decided otherwise, as solution #1 (which we still think is the best) is unimplementable with our current tooling. @varntzen, do you know what happened here?

Hi Silje, Thank you for your answer!

For the score I’m modelling (Delirium Observation Screening Scale = DOS) I don’t need to distinguish between null_reasons. So, I think I can still use the solution #1 you described:

  • Using DV_ORDINAL for the two values per element/characteristic to be evaluated
  • Using the RM attribute ‘null_flavour’ ‘unknown’ if the user has not been able to score this characteristic.
  • Restricting the RM attribute ‘null_flavour’ to ‘unknown’.

I can’t prevent compositions with an ordinal value and the RM attribute ‘null_flavour’ set to ‘unknown’ for the same data element from being validated by the openEHR REST API, but at least the DOS scale can be modelled using your solution #1 this way.

1 Like

From what I can see there is an unpublished version from Nov 2023 on the branch at Observation Archetype: Neurologic Assessment in Neuro-Oncology (NANO) scale [openEHR Clinical Knowledge Manager], which contains the two data ‘null’ elements with values of 99. This is the latest version, which follows the pattern in GOSE and an adaptation of Option 2.

I vaguely remember a conversation about updating this archetype with this pattern as a temporary measure (was it this one :thinking:), and pausing the review/publication process until the tooling catches up to the modeling needs. Or have I misremembered?

I vaguely remember that too, and our meeting notes from November supports it, as referenced by @varntzen above: Scores or scales with mixed data types or explicit NULL values - #29 by varntzen

1 Like

Thank you for today’s meeting, Silje, Heather and Vebjørn!

Based on the clarifications in this thread here and in our meeting, I will now model the Delirium Observation Screening Scale (DOS) using the same pattern as the current version of the NANO Scale, i.e. with an ordinal value of 99 for ‘null’ values.

This means that I will not be modelling the DOS in the way I described a few days ago in this thread (Scores or scales with mixed data types or explicit NULL values - #35 by emmanuel.eschmann).

The reason for this change is that the modelling I did back then is hidden / not made explicit by the tooling and that the actual tooling doesn’t support the needs. However, using an ordinal value of 99 for ‘null’ values is only a temporary measure and a workaround until there is a better way of supplementing ordinals with null values.


One more alternative for discussion:

Use a DV_SCALE with a fairly simple spec change making the value attribute (but not the symbol attribute) optional*.


Rationale: DV_SCALE has been explicitly developed to pragmatically support the oddities of scores/scales and if this what is explicitly modelled in such scales it should be directly supported by the datatype as well. Seems to be more straightforward to me than trying to make null_flavours work for this.

(* Minor detail: This may also need a tweak to the wording of is_strictly_comparable_to and maybe an invariant to indicate that it is not possible for symbol/code_string to be blank and the value attribute null)


Exactly the solution we need.

@Lucas @emmanuel.eschmann @Daniel_Ratschiller - an evolution of the specs to match a modelling need, rather than a modelling ‘fudge’, just as we discussed!


Just as an addendum, until @sebastian.garde came up with this great suggestion, I was looking at what might need to change in RM/AOM to allow null_flavours to work more easily with DV_ORDINAL, and other datatypes, a was being discussed earlier in the thread.

It turns out that this would require some significant changes. Right now all we can really do is constrain the list of null_flavours than can be used as and when an Element.null is required. We can;t say anything about how to force these to sit alongside a list of ‘normal’ terms as above.

While there is very definitely a need for ELEMENT.null to handle integration failures, I am starting to question whether it ever makes sense to try to make this part of ‘routine clinical modelling’ practice. We already add ‘pseudo-nulls’ like unknown in questionnaire resources and in fine-grain datapoints e.g. in cancer pathology reports.

I’ll start a new thread to pick this up. Just for clarity, I think we have nulls and negations broadly correct in most areas but I’m no longer sure that trying to use ELEMENT.null in other places esp within Observations, makes sense. If nothing else, even if ELENT.null does make sense, it is certainly not going to be a simple tweak to the RM or in tooling.