Map and List are ok as container built-ins, although I don’t think anyone has any problem with the Set type either. Interval is a type you don’t want to throw out in health, it’s so heavily used, not having it just makes life unnecessarily hard. In ADL, Interval looks like |0.0..<1000.0|; in ODIN (the openEHR JSON equivalent) it’s the same; in JSON, it is: “list”: [ { “lower”: 0.0, “upper”: 1000.0, “upper_included”: false } ] And in XML: 0.0 1000.0 <upper_included>False</upper_included> This is not to say don’t use JSON or XML, just that having a native syntax, and a native AOM type that goes with it vastly simplifies things. Note that all cardinality and optionality constraints are intervals! Personally I am a fan of nested maps. In ODIN, the main term_definition structure looks like: term_definitions = < [“en”] = < [“at0000”] = < text = <“Blood Pressure”> description = <“The local measurement of arterial blood pressure which is a surrogate for arterial. pressure in the systemic circulation. Most commonly, use of the term ‘blood pressure’ refers to measurement of brachial artery pressure in the upper arm.”> > [“at0001”] = < text = <“history”> description = <“history Structural node”> > which is, as you can see, a nested map. And in an archetype serialised from AOM objects to ODIN and JSON you get: definition = < rm_type_name = <“OBSERVATION”> node_id = <“at0000”> attributes = < [“1”] = < rm_attribute_name = <“data”> children = < [“1”] = (P_C_COMPLEX_OBJECT) < rm_type_name = <“HISTORY”> node_id = <“at0001”> and “definition”: { “rm_type_name”: “OBSERVATION”, “node_id”: “at0000”, “attributes”: [ { “rm_attribute_name”: “data”, “children”: [ { “rm_type_name”: “HISTORY”, “node_id”: “at0001”, i.e. nested maps. The native types of these are something like Hash <Hash <ValueType, KeyType>, OtherKeyType>. Unfortunately, nearly everyone who hits this in the AOM specification (e.g. in the ONTOLOGY classes) complains about it, and in fact, there were more Hashes and nested Hashes in the RM previously that we changed to other types because of complaints. I have never understood the complaints really, and maybe it’s ok now, because we did the initial modelling before Java had proper generic types, and way before JSON ever existed. Note that we used Cluster / Element mainly to have a base data structure in common with EN13606 (as it was at the time). Whether it is a good idea to throw that out is an interesting question. I think the date/time types need to work as logical primitives, so does a basic ‘coded term’ type. Although they are often modelled as subtypes of String, I don’t really agree with this, because that’s subtyping on the basis of representation not interface. But I suppose if one considered their true nature as syntactical objects, then that’s acceptable. I don’t care about it that much, and it’s possible that String substitutability would sometimes help. well it can already, and often is, but of course the proper types like Interval and some others are serialised out into dumb JSON structures. I have been thinking for some years about {1,10}
what you have below is something like the translation that already exists from Operational Template (fully resolved and substituted templated archetype) to ‘Template Data Schema’, which is an XML schema whose tag set matches exactly what you have in the square brackets below. I have to admit, I had never though of doing that transform in ADL syntax and post-processing that (mainly because some people continually complain about ADL and only want XML, so we tried to make them happy). I would not be looking to replace existing archetypes, but to the below from existing archetypes - it’s just a different TDS transform. Just to show this, consider this ADL Workbench serialised archetype (pregnancy summary from CKM) - note how the comments are serialised on the right: EVALUATION[at0000] matches { – Pregnancy summary data matches { ITEM_TREE[at0001] matches { – Tree items cardinality matches {1..; unordered} matches { ELEMENT[at0002] matches { – Maternity states value matches { DV_CODED_TEXT matches { defining_code matches { [local:: at0003, – Active - viable at0004, – Active - non-viable at0005, – Breast feeding at0006] – Completed } } } } CLUSTER[at0007] occurrences matches {0..1} matches { – Conception items matches { ELEMENT[at0008] occurrences matches {0..1} matches { – Date of LMP value matches { DV_DATE matches {} } } Now imagine it is serialised as follows: EVALUATION matches { data matches { ITEM_TREE matches { items cardinality matches {1..; unordered} matches { ELEMENT[] matches { value matches { DV_CODED_TEXT matches { defining_code matches { [local:: at0003, – Active - viable at0004, – Active - non-viable at0005, – Breast feeding at0006] – Completed } } } } CLUSTER[] occurrences matches {0..1} matches { items matches { ELEMENT[] occurrences matches {0..1} matches { value matches { DV_DATE matches {} } } Then, remove the attribute lines (what to do with cardinality and existence constraints?) EVALUATION matches { ITEM_TREE matches { ELEMENT matches { DV_CODED_TEXT matches { [local:: at0003, – Active - viable at0004, – Active - non-viable at0005, – Breast feeding at0006] – Completed } } CLUSTER occurrences matches {0..1} matches { ELEMENT occurrences matches {0..1} matches { DV_DATE matches {*} } It’s not hard to imagine further steps to get what you have done. Now, the above isn’t legal ADL, but it’s not hard to imagine it as a new hybrid syntax, a sort of ADL-schema or so. However, today it isn’t, and there aren’t any tools for the above (unless you have built one). you might want to have a look at the TDS transform in the - it does exactly this kind of thing. Here’s an example XSD from generated from one of its sample templates, as seen in Oxygen: you can see the highlighted tags are from the archetypes in the template (you can even see one with what is probably a bug in the converter, where the ‘(’ character has been converted to the text ‘openBrkt’. The non-highlighted tags retain their reference model values, since an archetype doesn’t archetype everything, but a content XSD like the above has to include a full definition of all the data, not just the archetyped bits. I’m not saying that this particular transform is the best possible, or even that good, but I think it is qualitatively the same transform as you are talking about; I think you are doing the same thing by a different route. so the real question is whether we want to lose semantic power in the source models - the RM and the archetypes, in order to have an easier transform path to the end target, which is some ‘easy to use’ XSD or other ‘friendly’ artefact. Some of the RM simplifications should be done, and I expect in the next few months, they will appear in a new openEHR release. I don’t think that we should throw out useful constructs that prevent modellers expressing what they need to express, just to achieve a particular mapping to a ‘dumb target’. On the other hand, I think we should try not to make the transformation path too difficult either. There are some other things we are doing to simplify AOM/ADL, which I have been working on with Harold Solbrig at Mayo, who has provided some in-depth review and suggestions on AOM. I’ll post about this in the next few days. So my feeling is that with simplifications, and more work on the downstream transformers (which after all, you only need one of, for each transform target), we can have rich models and ‘friendly’ final outputs as well. I don’t think it’s a very interesting option, given that most things that are in the RM and the AOM / ADL were put there to make clinical modelling as it is today possible! But some things can be removed, and improvements remain to be made… the current type of archetypes are all trees, and you are right, at the gross structure level, they are not complicated. But there is a whole ‘second order’ level of models on the horizon for describing shared care plans, and other structures, which are more complex… But the real richness is in two places: see the above TDS transform. Note that it is performed on the OPT transform which comes from the flattened template. You can see how this is done in the ADL 1.5 workbench - there are ADL, ODIN, JSON, XML and YAML ‘OPT’ outputs. One of these would be a basis for the TDS generator. You might think that this transform can be greatly improved, and I think many of us would agree; in fact there should probably be a number of alternative transforms available for generating different flavours of schema. Other related transforms generate source code APIs and WSDLs, as well as form definitions. many people have had similar thoughts I guess. We can throw out all the power, but then we can’t express anything much. It seems kind of pointless. Most computing and software done today based on ‘simple this and easy that’ produce just what you’d expect - simplistic results that never scale, can’t deal with edge cases, and are basically not useful in a serious way. Personally, I think we need to get the level of complexity in the source side (ie. RM, AOM, archeytpes) a bit cleaner, and then we need to do a lot better on downstream transformations from the OPT. ANd then publish that. If we get that right, it completely replaces all manually built message schemas, ‘document’ models and other XML structures. Others may think differently, and I guess the community as a whole will decide. Personally I want to make sure the next few months are used to clean up the annoying parts of the RM and AOM, and I am sure you would have a lot to contribute to that. It would be very helpful if you were to play with the and consider whether the XML and JSON it is outputting now is right for the next stage transforms in the way you are thinking of them. - thomas
(attachments)
