--- type: "doc" source: "source/profiling-examples.html" --- \[%settitle Profiling FHIR%\] \[%file newheader%\] \[%file newnavbar%\] \[%profilesheader examples%\] ## Slicing and Discriminator Examples | Responsible Owner: [\[%wgt fhir%\]]([%wg fhir%]) Work Group | [Standards Status](versions#std-process):[Informative](versions#std-process) | | --- | --- | ### Slicing Patient Telecom element One common use of slicing is to describe different constraints on different kinds of patient contact details. In this example, Patient.telecom is defined as: ContactPoint \[0..\*\] where the ContactPoint has system, value and use. Consider the case where the profile should say: - There must be a single home phone number - The patient may have a work phone number - The patient may have an email address - No other types of contact are allowed An example of a patient resource that meets these rules: ... snip ... ... snip ... To do this, the profile that implements these rules needs to do the following: - On the base Patient.telecom element: define that slicing is discriminated by system and use, and that the slices are closed ("No other types of contact are allowed"). Order is left unfixed - Then define 3 slices: 1. home phone: fixed values for system and use, and slice cardinality 1..1 2. work phone: fixed values for system and use, and slice cardinality 0..1 3. email: fixed value for system, cardinality 0..0 for use, and slice cardinality 0..1 In a StructureDefinition, this will look like: Note: much of the definition detail has been left out, and only the parts relevant to the pattern are shown. Also, providing a fixed value makes the minimum cardinality irrelevant, but it is shown here for completeness. This table illustrates the relationship between the instance and the ElementDefinitions: | | **Path** | **Name** | **Min** | **Max** | **Fixed** | | --- | --- | --- | --- | --- | --- | | | Patient | | | | | | | Patient.telecom | | 1 | 3 | | | | Patient.telecom | HomePhone | 1 | 1 | | |   | Patient.telecom.system | | 1 | 1 | phone | |   | Patient.telecom.value | | 1 | 1 | | |   | Patient.telecom.use | | 1 | 1 | home | | | | | | | | | | Patient.telecom | WorkPhone | 0 | 1 | | | | Patient.telecom | Email | 0 | 1 | | |   | Patient.telecom.system | | 1 | 1 | email | |   | Patient.telecom.value | | 1 | 1 | | |   | Patient.telecom.use | | | | | ### Fixed Order Slicing A variant to this that looks simpler but turns out to be deceptively complicated is to fix the order and make all slices mandatory. In this case the profile says: - The cardinality of `telecom` is 3..3 - The slicing is closed, and ordered, no discriminator - The first slice is home phone number - The second slice is work phone number - The third slice is email address An example of a patient resource that meets these rules: { "resourceType" : "Patient", "telecom" : \[ { "system" : "phone", "value" : "5551234567", "use" : "home" }, { "system" : "phone", "value" : "5551234567", "use" : "work" }, { "system" : "email", "value" : "someone@acme.org" } \] } In a StructureDefinition, this will look like: A simple content model like this is attractive because it's both easier to specify and to work with. There's no need to think about the values of system and use - implementers can just grab first telecom value etc. The problem with this approach is that such simple requirements are rarely valid in production healthcare systems, and even if they are valid during implementation, they rarely stay that way. Implementing multiple applications based on simple offsets will make the overall eco-system fragile against change, either internally, or as the scope of the eco-system grows. Since the discriminator could be system+use in this case, it's best for future compatibility to specify it anyway. ### Blood Pressure Example Another use of Slicing is for Blood Pressure Measurements, where the profile says: - There must be two components - The first has LOINC code 8480-6, and a quantity - The second has LOINC code 8462-4, and a quantity - Other components are allowed (posture, etc., but not profiled in the base blood pressure profile) An example of an observation resource that conforms such constrained StructureDefinitions looks like this: ... To do this, the profile that implements these rules needs to do the following: - On the base Observation.component element: define that slicing is discriminated by code. Order is left unfixed, and rules are left open. - Then define 2 slices: 1. systolic: fixed values for code, cardinality 1..1, value is a Quantity 2. diastolic: fixed values for code, cardinality 1..1, value is a Quantity In a StructureDefinition, this will look like: Note: much of the definition detail has been left out, and only the parts relevant to the pattern are shown. e.g., A real blood pressure profile would fix unit, an overall Observation code etc. ### Extensions For another example, consider slicing extensions. The base extension on every element is defined as a list (0..\*) of extensions, and each extension has a url that identifies it, and a value. Consider an example where a profile defines that for a particular element (named Patient), there are two extensions, with URLs http://acme.com/a and http://acme.com/b. In addition, the profile allows other extensions to be used. Technically, the profile achieves this by "slicing" the extension list, into two slices, and saying that the slicing is "open" - that there can be other slices introduced. Here are the relevant parts of the Profile on patient: Here is a patient example that conforms to this profile: ### Diagnostic Report & Observation In this example, a profile on a diagnostic report says that it must have four observations, each with a different LOINC code (e.g., a classic lab panel). In this case (taken from the [Example Lipid Profile](diagnosticreport-example-lipid-panel)), the structure that applies to DiagnosticReport will say that there are four slices on DiagnosticReport.result, each conforming to a different structure, which are also contained in the same profile. Each of those structures will constrain the LOINC code in the observation. Here is an instance that meets the rules for this profile: Note that this version is not valid, because the slices are not in the correct order: ### Composition Sections Most uses of Composition involve conformance to a profile that specifies which sections will exist, and what their contents will be. This is yet another example of slicing. A typical document content profile might specify a section structure something like this: - Reason for visit Narrative, LOINC Code 29299-5 - Medications, LOINC Code 46057-6 - Prescribed Medications, LOINC Code 66149-6 - OTC medications, 66150-4 (optional) - Vital Signs, LOINC Code 8716-3 Real profiles will contain lots of detail about the sections, but these are omitted here in the interests of clarity. An example of a Composition that meets these rules: ... snip ...
... snip ...
... snip ...
... snip ...
... snip ...
... snip ...
To do this, the profile that implements these rules needs to do the following: - On the base Composition.section element: define that slicing is discriminated by code, and that the slices are closed and ordered - Then define 3 slices on Composition.section: 1. reason-for-visit: fixed code, cardinality 1..1 2. medication: fixed code, cardinality 1..1 3. vital-signs: fixed code, cardinality 1..1 - Then, in the medication slice, slice the Composition.section.section: define that slicing is discriminated by code, and that the slices are closed and ordered - Then define 2 slices on the Composition.section.section in medication: 1. prescribed: fixed code, cardinality 1..1 2. otc: fixed code, cardinality 0..1 In a StructureDefinition, this will look like: ### Re-slicing For some use cases, it is necessary to further re-slice in a derivative profile. This is when Profile A derives from Profile B, Profile A slices an element in Slice A and B, and Profile B further slices Slice A into A1 and A2. As an example, assume that institution implementation guide specifies that a medication list is represented by a List resource, where the items into the list are split up into 3 slices, based on resource type: - MedicationRequest - MedicationAdministration - MedicationStatement These slices must come in order. Now, a particular application creates an additional profile that specifies the following rules in addition to the base rules of the institution: 1. the medicationRequests will be sliced into active and non-active, where all the active requests will come first, and then the inactive ones 2. only active MedicationAdministrations will be encountered 3. Medication statements are not supported An example of a List resource that meets these rules: ... snip ... ... snip ... The StructureDefinition differential for the first profile sets up the slicing, and then defines 3 slices: The derived StructureDefinition differential re-slices the first slice into 2 slices, constrains the second slice, and prohibits the 3rd: \[%file newfooter%\]