Archetype Flattening Algorithm for ADL1.4 & AOM2.0.2

Objective:

Get a flat representation (AOM and ADL) of an archetype that has slots to other archetypes.

Example:

Sources:

  • These ADLs have been shortened to clearly present the example.

openEHR-EHR-COMPOSITION.medication_list.v1

definition
	COMPOSITION[at0000] matches {	-- Medication list
		category matches {
			DV_CODED_TEXT matches {
				defining_code matches {[openehr::431]}
			}
		}
		content cardinality matches {0..*; unordered} matches {
			allow_archetype ACTION occurrences matches {0..*} matches {
				include
					archetype_id/value matches {/openEHR-EHR-ACTION.medication.v1/}
				exclude
					archetype_id/value matches {/.*/}
			}
		}
	}

openEHR-EHR-ACTION.medication.v1

definition
	ACTION[at0000] matches {	-- Medication action
		ism_transition matches {
			ISM_TRANSITION matches {
				current_state matches {
					DV_CODED_TEXT matches {
						defining_code matches {[openehr::524]}
					}
				}
				careflow_step matches {
					DV_CODED_TEXT matches {
						defining_code matches {[local::at0001]}	-- Plan
					}
				}
			}
			...
		}
		description matches {
			allow_archetype ITEM_TREE matches {
				include
					archetype_id/value matches {/openEHR-EHR-ITEM_TREE\.medication\.v1|openEHR-EHR-ITEM_TREE\.medication-vaccine\.v1/}
				exclude
					archetype_id/value matches {/.*/}
			}
		}
	}

openEHR-EHR-ITEM_TREE.medication.v1

definition
	ITEM_TREE[at0000] occurrences matches {0..*} matches {	-- Medication description
		items cardinality matches {2..*; ordered} matches {
			ELEMENT[at0012] occurrences matches {0..1} matches {		-- Generic name
				name matches {
					DV_CODED_TEXT matches {
						defining_code matches {[ac0003]}	-- Generic name OR Brand name
					}
				}
				value matches {
					DV_TEXT matches *
				}
			}

Target:

  • Node ids for resolved slots are rewritten to avoid collisions (e.g. node at0000 from the COMPOSITION archetype should be different to at0000 from ACTION archetype)
  • Constraint binding codes (acNNNN) should be rewritten too for the same reason.
  • Ontology definitions codes should be rewritten too.
  • Codes in constraints, e.g. for DV_CODED_TEXT (see ACTION careflow_step node) should be rewritten.
  • Bindings and definitions of referenced archetypes should be merged into the ontoloty section of the target flat archetype, using the new codes mentioned before.

openEHR-EHR-COMPOSITION.medication_list.v1.flat

definition
	COMPOSITION[at0000] matches {	-- Medication list
		category matches {
			DV_CODED_TEXT matches {
				defining_code matches {[openehr::431]}
			}
		}
		content cardinality matches {0..*; unordered} matches {
			ACTION[openEHR-EHR-ACTION.medication.v1.at0000] matches {	-- Medication action
				ism_transition matches {
					ISM_TRANSITION matches {
						current_state matches {
							DV_CODED_TEXT matches {
								defining_code matches {[openehr::524]}
							}
						}
						careflow_step matches {
							DV_CODED_TEXT matches {
								defining_code matches {[local::openEHR-EHR-ACTION.medication.v1.at0001]} -- Plan
							}
						}
					}
					...
				}
				description matches {
					ITEM_TREE[openEHR-EHR-ITEM_TREE.medication.v1.at0000] occurrences matches {0..*} matches {	-- Medication description
						items cardinality matches {2..*; ordered} matches {
							ELEMENT[openEHR-EHR-ITEM_TREE.medication.v1.at0012] occurrences matches {0..1} matches {		-- Generic name
								name matches {
									DV_CODED_TEXT matches {
										defining_code matches {[openEHR-EHR-ITEM_TREE.medication.v1.ac0003]}	-- Generic name OR Brand name
									}
								}
								value matches {
									DV_TEXT matches *
								}
							}
						}
					}
				}
			}
		}
	}

Algorithm logic:

Before flattening archetypes, we need to resolve all the references, that's another algorithm: archetype reference resolution

  1. The algorithm is connected to N archetype repositories, with N >= 1
  2. Input: a root archetype
  3. Output: a map of archetypID => Archetype (this will be the input for the flattening algorithm)

The algorithm:

  1. Find all the slots in the input archetype
  2. For each slot:
    1. Look-up for the matching archetypes on every repository
    2. If there are more than one archetype for the same concept (e.g. more than one version)
      1. The user should select the right archetype, or,
      2. The last version will be selected by default (this could not be done if the last version is a branch).
    3. For each referenced archetype:
      1. Invoke recursivelly with the archetype
      2. Add the archetype to the return map
  3. Return the map
    The returned structure could contain more information, e.g. the references for each archetype.

There are two ways of flattening archetypes:

  1. Dynamically load referenced archetypes with or without filtering
  2. Preloading and filtering

In both cases, a root archetype is needed.

Archetype filtering: which archetypes will be used

Filtering is to select the archetypes that should be included in the resultung flat archetype. Since archetype slots use regexes to reference archetypes, many archetypes can match a slot reference, and frequently you don't want to include all the referenced archetypes.

Archetype loading:

Preloading and filtering: the root archetype is processed by a "slot finder" and the user selects wich archetypes to include for each slot. This process is recursive: repeat with referenced archetypes until no slots are found. Then the flattening process is executed only for those archetypes.

Dynamically loading: the flattening process walks throu the archetype, and when a slot is found, it loads the matching referenced archetypes (using the slot regexp). This process is recursive. All referenced archetypes are merged into a flat archetype that matches the semantics of the root archetype. This process loads all the referenced archetypes (no filter here), but when a slot is found, the flattener could ask the user to select the right archetypes to include (interactive filtering), the user selects the archetypes and the process continues until the next slot is found.

Archetypes could be loaded from a local repository (e.g. filesystem using an adl parser) or a remote repository using some kind of service (HTTP, SOAP, ...), or use many repositories.

TBD: pseudocode

A command line tool: http://code.google.com/p/openehr-archetype-flattener/downloads/list

F:\openehr-tests>java -jar flattener.jar composi     << searches for matching substrings on the archetype repository

Matching archetypes in the repo:

 0) openEHR-EHR-COMPOSITION.encounter.v1

 1) openEHR-EHR-COMPOSITION.medication_list.v1

 2) openEHR-EHR-COMPOSITION.prescription.v1

 3) openEHR-EHR-COMPOSITION.problem_list.v1

 4) openEHR-EHR-COMPOSITION.referral.v1

 5) openEHR-EHR-COMPOSITION.report.v1

Select archetype #: 1                                         << I've selected the archetype #1

You have selected: openEHR-EHR-COMPOSITION.medication_list.v1

openEHR-EHR-COMPOSITION.medication_list.v1::/content[at0001] references:

 include this reference? openEHR-EHR-ACTION.medication.v1 [y/n]: y

openEHR-EHR-ACTION.medication.v1::/description[at0017] references:

 include this reference? openEHR-EHR-ITEM_TREE.medication-vaccine.v1 [y/n]: y

 include this reference? openEHR-EHR-ITEM_TREE.medication.v1 [y/n]: n

openEHR-EHR-COMPOSITION.medication_list.v1::/content[at0002] references:

 include this reference? openEHR-EHR-INSTRUCTION.medication.v1 [y/n]: n

openEHR-EHR-INSTRUCTION.medication.v1::/activities[at0001]/description[at0002] references:

 include this reference? openEHR-EHR-ITEM_TREE.medication-formulation.v1 [y/n]: n

... Rewriting codes (node ids, constraint cods and local terms)

... Flattening slots and ontologies

... Flat archetype written to: openEHR-EHR-COMPOSITION.medication_list.v1.flat.adl   << this will have only the selected references (ACTION, ITEM_TREE)

:D