Welcome and apologies | |
|
Actions from last week | | - Actions from last week:
- Update ABNF with additional UTF characters - please refer to:
- SLPG members to bring back a use case for historical associations in queries
|
Executing maps | | Proposed extension to ECL to support the execution of maps (focusing on the resolution of historical refsets) - The specific use-case here comes initially from Jeremy and relates to being able to work with inactive concepts via the historical association maps. For example, given an ECL expression that identifies a set of concepts 'c' to be used for retrieving patient records, you probably also want to retrieve records for sameAs (c) and replacedWith (c)
- Example:
(< 72704001 |Fracture| AND ^ 900000000000527005 |SAME AS association reference set|) . 900000000000533001 |Association target component| - (900000000000527005 |SAME AS association reference set| . 900000000000533001 |Association target component| ): |Referenced component| = < |Fracture|
- Michael's existing approach: mapsTo(|SAME AS|, < |Fracture|)
Or mappedTo(…)
mappedFrom(|SAME AS|, |inactive concept|)
mappedFrom(|REPLACED BY|, |inactive concept|)
- Alternative suggestion: Use the substrate to include historical snapshots.
- E.g. Historical and current concepts that are fractures and have an associated morphology, but not historical morphologies
- ( < |Fracture of bone| {{ substrate >= http://snomed.info/sct/900000000000207008/version/20140131 }}) AND (* : |Associated morphology| = *)
- Alternative use case - Substance (int) to substance (AMT) map (SNOMED-to-SNOMED)
- ^ (711112009 |ICNP diagnoses simple map reference set| {{ M.mapTarget = “R-FF2E9” }} )
|
Returning attributes | Michael Lawley | Proposal from Michael: - Currently ECL expressions can match (return) concepts that are either the source or the target of a relationship triple (target is accessed via the 'reverse' notation or 'dot notation', but not the relationship type (ie attribute name) itself.
For example, I can write: << 404684003|Clinical finding| : 363698007|Finding site| = <<66019005|Limb structure| << 404684003|Clinical finding| . 363698007|Finding site| But I can't get all the attribute names that are used by << 404684003|Clinical finding| - Perhaps something like:
- ?? R.type ?? (<< 404684003 |Clinical finding|)
- This could be extended to, for example, return different values - e.g.
- ?? |Simple map refset|.|maptarget| ?? (^|Simple map refset| AND < |Fracture|)
|
Template Syntax | Linda Bird | New requirements - 2 replacement slots must have the same/different or subsumed/not-subsumed values - for example, same morphology, finding sites not subsume each other (within a row of input data):
[[ +id ]]: { 116676008 |Associated morphology| = [[ +id @morphology ]], 363698007 |finding site| = [[ +id @findingSite1 constraint ( != << $findingSite2) ]] }, { 116676008 |Associated morphology| = [[ +id @morphology ]], 363698007 |finding site| = [[ +id @findingSite2 constraint (!= << $findingSite1) ]] } - [[+id]]: [[1..*]] { |Associated morphology| = [[ +id @morphology ]], |Finding site| = [[ +id @site constraint ($site[n] != <<$site[!n] ]] }
- Example - 208510002 |Multiple fracture of clavicle, scapula and humerus (disorder)|
- Default value for slots - for example:
- [[ + id ]] : { |Finding site| = [[ +id (<< 72673000|Bone structure|) @site default = 72673000 |Bone structure (body structure)| ]]
- Specifying the definition status of a slot - for example (proximal primitive modelling):
- [[ + << 64572001 |Disease| {{ c.definitionStatus = primitive }} ]]
- Specifying the definition status of an expression - for example
- [[ +tok ]] [[ +id ]] : { |Finding site| = [[+id]] }
- [[ +tok ("===" "<<<") ]] [[ +id ]] : { |Finding site| = [[+id]] }
- [[ +tok (< |Definition status|) ]] [[ +id ]] : { |Finding site| = [[+id]] }
- Repeating role groups must have the same set of attributes (with respect to optional attributes) - for example (using #same or #allOrNone):
[[+id]]: [[1..* @group1]] { [[0..1 #same in group1]] |finding site| = [[+id]], [[0..1 #same in group1]] |associated morphology| = [[+id]], [[0..1]] |pathological process| = [[+id]] } [[+id]]: [[1..* @group1]] { [[1..1]] |Associated morphology| = [[ +id @morphology ]], [[0..1 #allOrNone in group1]] |Finding site| = [[ +id @site]], [[0..1 #allOrNone in gropu1]] |Occurrence| = [[ +id @occurrence ]] } Instance 1: Injury of head, neck and chest [[ |Disease| ]]: [ @rolegroup[1] ] { |Associated morphology| = |Injury|, |Finding site| = |Head structure| } [ @rolegroup[2] ] { |Associated morphology| = |Injury|, |Finding site| = |Neck structure| } [ @rolegroup[3] ]{ |Associated morphology| = |Injury|, |Finding site| = |Chest structure| }
Instance 2: Congenital malformation of head and neck [[ |Disease| ]]: [ @rolegroup[1] ] { |Associated morphology| = |malformation|, |Finding site| = |Head structure|, |Occurrence| = |Gongenital| } [ @rolegroup[2] ] { |Associated morphology| = |malformation|, |Finding site| = |Neck structure|, |Occurrence| = |Gongenital| }
|
URI Standard | | - Finalize and publish language and language instance URIs
|
Query Language - Summary from previous meetings
| | Examples: version and language Notes
- Allow nested where, version, language
- Scope of variables is inner query
|
| Examples: where Notes - Allow nested variable definitions, but recommend that people don't due to readability
- Scope of variables is the inner query
- No recursion e.g X WHERE X = 1234 MINUS X
- ie can't use a variable in its own definition
- ie X is only known on the left of the corresponding WHERE, and not on the right of the WHERE
|
Keywords for Term-based searching: - D.term
- D.term = "*heart*"
- D.term = wild:"*heart*"
- D.term = regex:".*heart.*"
- D.term = match:"hear att"
- D.term = (sv) wild: "*heart*"
- D.languageCode
- D.languageCode = "en"
- D.languageCode = "es"
- D.caseSignificanceId
- D.caseSignificanceId = 900000000000448009 |entire term case insensitive|
- D.caseSignificanceId = 900000000000017005 |entire term case sensitive|
- D.caseSignificanceId = 900000000000020002 |only initial character case insensitive|
- D.caseSignificance
- D.caseSignificance = "insensitive"
- D.caseSignificance = "sensitive"
- D.caseSignificance = "initialCharInsensitive"
- D.typeId
- D.typeId = 900000000000003001 |fully specified name|
- D.typeId = 900000000000013009 |synonym|
- D.typeId = 900000000000550004 |definition|
- D.type
- D.type = "FSN"
- D.type = "fullySpecifiedName"
- D.type = "synonym"
- D.type = "textDefinition"
- D.acceptabilityId
- D.acceptabilityId = 900000000000549004 |acceptable|
- D.acceptabilityId = 900000000000548007 |preferred|
- D.acceptability
- D.acceptability = "acceptable"
- D.acceptability = "preferred"
Additional Syntactic Sugar - FSN
- FSN = "*heart"
- D.term = "*heart", D.type = "FSN"
- D.term = "*heart", D.typeId = 900000000000003001 |fully specified name|
- FSN = "*heart" LANGUAGE X
- D.term = "*heart", D.type = "FSN", D.acceptability = * LANGUAGE X
- D.term = "*heart", D.typeId = 900000000000003001 |fully specified name|, acceptabilityId = * LANGUAGE X
- synonym
- synonym = "*heart"
- D.term = "*heart", D.type = "synonym"
- D.term = "*heart", D.typeId = 900000000000013009 |synonym|
- synonym = "*heart" LANGUAGE X
- D.term = "*heart", D.type = "synonym", D.acceptability = * LANGUAGE X
- D.term = "*heart", D.typeId = 900000000000013009 |synonym|, (D.acceptabilityId = 900000000000549004 |acceptable| OR D.acceptabilityId = 900000000000548007 |preferred|) LANGUAGE X
- synonymOrFSN
- synonymOrFSN = "*heart"
- synonym = "*heart" OR FSN = "*heart"
- D.term = "*heart", (D.type = "synonym" OR D.type = "fullySpecifiedName")
- synonymOrFSN = "*heart" LANGUAGE X
- synonym = "*heart" OR FSN = "*heart" LANGUAGE X
- D.term = "*heart", (D.type = "synonym" OR D.type = "fullySpecifiedName"), D.acceptability = * LANGUAGE X
- textDefinition
- textDefinition = "*heart"
- D.term = "*heart", D.type = "definition"
- D.term = "*heart", D.typeId = 900000000000550004 |definition|
- textDefinition = "*heart" LANGUAGE X
- D.term = "*heart", D.type = "definition", D.acceptability = * LANGUAGE X
- D.term = "*heart", D.typeId = 900000000000550004 |definition|, D.acceptabilityId = * LANGUAGE X
- Unacceptable Terms
- (D.term = "*heart") MINUS (D.term = "*heart", D.acceptability = * LANGUAGE X)
|
Language preferences using multiple language reference sets LRSs that use the same Language tend to use 'Addition' - i.e. child LRS only includes additional acceptable terms, but can override the preferred term E.g. Regional LRS that adds local dialect to a National LRS E.g. Specialty-specific LRS E.g. Irish LRS that adds local preferences to the en-GB LRS
LRSs that define a translation to a different language tend to use 'Replacement' - i.e. child LRS replaces set of acceptable and preferred terms for any associated concept
|
Other topics | | |
Confirm next meeting date/time | | The next SLPG meeting will be held in 2 weeks at 20:00 UTC on Wednesday 6th February. |
6 Comments
Daniel Karlsson
Regarding item 2, the ECL parser on github is/was already updated:
https://github.com/IHTSDO/snomed-ecl-parser/tree/master/src/main/antlr4/org/snomed/langauges/ecl/generated/parser
There is an updated guide for how to tweak/hack ANTLR generated from ABNF (not the most beautiful process):
https://github.com/IHTSDO/snomed-ecl-parser/blob/master/generate_antlr4_grammar.md
...and there is a test case testing non-ASCII characters from several SNOMED member country character sets (and some non-member sets).
/Daniel
Yongsheng Gao
Linda Bird Many thanks for including those enhancements for the template syntax in the agenda.
Ed Cheetham
Would it be possible to have more examples to support/explain the extended template features presented at the last call (no probs with the default value one, but the 'Equal and Not Equal Values' and 'Conditional occurrence' discussions were very abstract).
With specific reference to the latter, the requirement speaks of "Repeating role groups" - it would be good to know what these actually are. Given the example it is tempting to think that a series of role groups that refer to multiple structural defects of a congenital disorder are somehow 'repeating' (in an authoring workflow sense), where each newly added group would necessarily have certain features (congenital occurrence) common to those that precede. But this seems to ignore the possibility of representing conditions that legitimately include congenital and acquired features (e.g. acquired ventricular failure in a patient with uncorrected congenital aortic valve stenosis). I know it's down in the detail, but how could a template distinguish a set of 'repeating' role groups from a set of 'non-repeating' role groups where the template is set to impose cross-group constraints?
Ed
Linda Bird
Thanks for your comments Ed! I have done my best to include examples of each of the proposed template syntax extensions in the meeting minutes for this week's meeting - 2019-03-13 - SLPG Meeting. We can talk through these examples at the meeting, and identify where we need to provide further examples and explanations.
Thanks!
Linda.
Ed Cheetham
Thanks Linda
Another question (for all) which I know we've considered indirectly before:
Is there any sense of a functional boundary for the sorts of features we would include in a 'declarative language' (such as the languages discussed in these calls) as compared to a more 'exhaustive' imperative language?
The recent extended feature request look like a requirement to represent entire authoring 'business rules' (with conditional branching and what-not), and I'm curious as to whether there are any feature requests that we can realistically turn down - and if so, why.
Thanks
Ed
Daniel Karlsson
Ed,
I agree. Perhaps the distinction between declaration and constraints should be more easily distinguishable in the syntax, e.g. like in FHIR (no other comparison made).