SDC: Form Population
One of the objectives of the SDC implementation guide is to reduce data entry into forms when the relevant data already exists in discrete form within the clinical or administrative system completing the form. This saves the user time and increases accuracy. If a Questionnaire is created with knowledge of where the data for different questions within the form is expected to come from, the Form Filler or Form Fill Manager system can query for the relevant information and automatically fill in some of the answers. FHIR's REST interface provides a standard way to query this data, regardless of the type of client.
This 'population' process can happen in one of two ways:
- The SDC Form Filler can invoke $populate operation on a SDC Form Fill Manager to create an initial QuestionnaireResponse before exposing the form to the user. This approach is known as 'pre-population' and is used by 'simple' Form Fillers that don't have the capacity to execute the logic needed to populate the form themselves. This approach is more limited because the population process can't take into account any user-provided information, nor can it provide guidance to the user. Either the population process can fill in an answer or it can't.
- Alternatively, the SDC Form Filler can "interactively" handle the population process internally without invoking an operation. This is called "continuous population". In this case, there is no need to try to populate answers for all questions at once and answers to previous questions can be used as part of the logic used to populate subsequent ones. As well, the population process can provide guidance rather than always providing outright answers.
Population operations
The primary method of form pre-population is the $populate operation. It performs the population process and returns a QuestionnaireResponse, with relevant fields pre-filled based on the information provided or already known by the server.
- $populate will pass back the results of the operation in a QuestionnaireResponse, meaning that the continued filling of the form will require a Form Filler to handle the rendering.
Note: The $populate-html and $populate-link operations have been deprecated due to a lack of any known implementation in the entire time it's been present, and the adaptive questionnaires possibly having been used instead.
If using a populate operation, the operation will typically only be invoked once. However, there are two circumstances where it might be invoked more than once:
- If the user has saved a QuestionnaireResponse "in progress" and comes back to it later, it is possible they might choose to re-run the populate process, for example to load information they know has been entered or imported into the EHR since the last time the $populate process was run.
- If the user is creating a net new QuestionnaireResponse by copying a previous QuestionnaireResponse, the user might also want to re-run the population process to take advantage of new data that wasn't available in the original form.
Both of these situations involve starting from an existing QuestionnaireResponse, which means that "re-populating" a form is only relevant using $populate.
If choosing to re-populate a form, there are several considerations to keep in mind:
- Re-population SHOULD only be done at user request because it may bring back data that had previously been removed or add additional selections to 'repeat' questions that the user had previously reviewed.
- Users SHOULD be warned about both of these effects (return of previously removed data and addition of additional answers to questions whose answers had previously been reviewed).
- Re-population SHOULD NOT revert elements that had been changed without user request. (If a user wants data to be fully reverted, they can always start the form from scratch).
- If data is changed or reverted as part of a re-population process, these changes should be highlighted to the user.
- Re-population can also be run in a mode where the Form Filler runs $populate on a blank form and then displays net new or changed answers alongside the original answers and provides the user with the option of propagating some or all of the answers across from the newly populated form into the 'current' form.
- This same approach can also be used where the user starts with a newly populated form and then is given the option of propagating answers across from a previously completed QuestionnaireResponse.
- Some sophisticated systems might have algorithms that determine whether reverting or supplementing data is appropriate based on what data is newer, where it came from, or other considerations. However, there is no standard algorithm for doing this and requirements might vary by Questionnaire and by item.
- A single Questionnaire can sometimes include data from multiple subjects. The population process needs to be aware of what the subject for a given section of the Questionnaire is and take that into account when retrieving data to populate the record. (E.g. don't populate an answer asking for a mother's blood type with the child's blood type.) In SDC, the fact that a particular 'group' in a Questionnaire has a distinct subject is communicated using the isSubject extension. An equivalent extension flags the element within the QuestionnaireResponse.
Population modes
There are three different modes of "population" possible:
- Automated population: The questionnaire can identify the specific data element (or set of data elements) that should be used to populate the form. No user intervention is required other than to review the content. E.g. capturing the patient's gender, birth date, most recent weight measurement, etc. In some cases, this might involve performing a calculation based on data retrieved. For example, determining the patient's BMI by querying the most recent weight and height observations. This is the only type of population the $populate operation can perform (and then, only if the logic is based entirely on context or on answers to prior questions that were able to be populated automatically).
- Choice selection: The questionnaire can identify the candidate answers, but the user must choose which of those should be included in the form response. For example, a question might say "List any relevant concomitant medical conditions". The notion of "relevant" will typically require human decision-making. However, the system rendering the questionnaire can easily bring up a list of concomitant medical conditions and allow the user to select which ones are "relevant" and include those in the answer. Choice selection can only occur during interactive population.
- Answer context: The specific answer to the question will not exist as data in the client system, but might be able to be determined by the user based on data that is available in the clinical system. For example, the question "Has the patient ever exhibited a similar reaction in the past?" with a yes/no/unknown answer choice is not a data element that will exist in the clinical system. However, it is possible to provide the clinician with a list of AdverseEvent, Observation and Condition instances that might be relevant they can scan in choosing how to answer the question. Providing answer contexts can likewise only done interactively, not with the $populate operation.
"Choice selection" and "answer context" options will generally only be exposed when the user is interacting with the associated question (typically when a user clicks on an icon indicating they want to see the context or EHR choices).
Caveats and considerations with form population
-
For form population to work, the designer of the Questionnaire must do a fair bit of work defining the queries and the filters needed to select what elements to use in populating specific questions. While there are standard expectations for querying demographics like gender, birth date or even most recent weight (due to the HL7-mandated vital signs profiles), there is little international guidance on what codes or conventions to use when representing other data such as medications, procedures, lab results, etc. For form population to work with such data, the Questionnaire will have to be designed presuming the use of particular profiles and conventions - for example, national implementation guides such as US Core or Australian Base. The more sophisticated a Questionnaire's population rules, the more dependent it will be on systems exposing their data in accordance with specified profiles. Note: The mechanisms to do this in a more automated way are under consideration for the next release.
-
Even if data exists and is exposed in accordance with agreed profiles, that does not necessarily mean that the source system will have the necessary query capabilities to find and appropriately filter the data. While some degree of filtering is possible using FHIRPath or CQL, loading thousands or tens of thousands of records for local filtering by the client is likely to pose a challenge from the perspective of performance, memory usage, access control logging, etc. National and other implementation guides that set minimum expectations on search for capabilities on clinical and administrative systems can be helpful here as well.
-
Any queries performed to populate the form will need to be subject to appropriate access controls. Users
SHALL NOTbe able to see information populated into a form that they would not be able to see when navigating the source system directly (I.e. it is a mandatory requirement that the population process not populate information in the form if the user completing the questionnaire would not have permission to see that data if they queried it directly). In some cases, this means that an answer in a form might not be populated even though the data exists - because the user does not have authority to see that data. -
Defining the rules for populating a questionnaire is essentially a mapping process. The author is mapping between the data element defined by a particular question or group item and a corresponding element in a FHIR resource or profile.
Mapping can be dangerous because it can lead to the sharing of incorrect data or, occasionally, the failure to share correct data. For this reason, it is essential that human users be given the opportunity to review questionnaire responses that have been populated by automated means.
Even with this precaution, care should be taken when performing data mappings, including:
- Be aware that the risk of incorrect mapping occurring can be significantly higher when mapping complex questionnaires and/or complex data structures and especially high when mapping both.
- The degree of risk is implementation dependent (type of data, type of questionnaire, type of source, mapping mechanism, type of user, etc.)
- Both mappings and the implementation of those mappings should be carefully verified and, in some situations, should be subject to certification or external verification
- Mapping from profiles not specifically defined for use in the context of a particular questionnaire or set of questionnaires (i.e. with a defined context) magnifies the risk of erroneous population.
-
The 'enableWhen' elements in Questionnaire mean that some elements may not be relevant in all situations. When pre-populating a questionnaire, it makes sense to "fill in" as much data as possible, even if it may not always be needed. However, such data should not be shown to the user until the given item is "enabled". And once the questionnaire is completed, data for any non-enabled elements
SHALLnot be displayed to the user completing the form. If an answer disables a portion of the QuestionnaireResponse containing significant user-entered data, the entry system SHOULD warn users that that information will be removed on submission. -
Sometimes the author interested in making a Questionnaire "populatable" does not have authority to make changes to the "official" Questionnaire. In other cases, there might be one official Questionnaire, but a need to populate it from resources that comply with different sets of profiles (e.g. that comply with requirements from different countries) - and thus a need for different metadata in the Questionnaire to support the population process. In this case, rather than invoking the population on the original Questionnaire, it can be done on a derived Questionnaire.
-
When performing population, the considerations around errors and lack of support for expressions may come into play. In addition, similar considerations can also be relevant in terms of what 'population' approach the Questionnaire supports, as opposed to what level of population capability the Form Filler has. The desired behavior of alerting the user that some elements might not have been populated and that other clients might provide more population support is the same whether the variation is "handles FHIRPath vs. CQL" or "uses Observation-based vs. expression-based".
-
When information from other sources has been used to help populate a QuestionnaireResponse, there may be a desire to capture what information sources were used, what software was used to perform the population process, etc. The way to represent this information in FHIR is using the Provenance resource. The various source records used in population would be represented using
Provenance.entity.whatwhere theProvenance.entity.rolewould be 'source'. Software information would be captured inProvenance.agent. -
When using FHIRPath and CQL, the empty set can be taken to mean 'false'. However, items of type 'boolean' actually have three states - 'true', 'false' and 'not answered'. An empty set
SHALLbe treated as 'not answered' rather than being converted to a boolean value of 'false'.
Pre-population service
Populating a QuestionnaireResponse is a complex task. The system must be able to query resources, use FHIRPath or CQL to populate and potentially calculate relevant data elements, manage conditionality rules around enableWhen as part of the population process, etc. As a result, some client systems might prefer to offload the responsibility for handling pre-population of a form to a separate system. The FHIR specification defines a set of services that can be used to provide a variable degree of offloading - from just handling the population aspect through to handling the rendering of the form and interactive data capture completely through a separate site.
Operation
Description
This operation supports generating a QuestionnaireResponse instance based on a specified Questionnaire. If matching data is available for any of the questions and the server supports the pre-population capability, the answers for those questions will be populated in the returned QuestionnaireResponse instance.
In addition to the $populate operation, another alternative is to use the Adaptive Form mechanism. It hides the design of the questionnaire entirely and, in principle, allows the service to determine the next question to automatically fill in (or perhaps even suppress asking questions) based on data the service can access about the patient.
For SDC purposes, server systems claiming to support CapabilityStatements that require support for the populate operation (SDC Form Manager) SHALL, at minimum:
- Handle the input parameters
identifier,questionnaire,questionnaireRef,subjectandcontent - Support passing at least* the Patient resource using the
contentparameter - Populate the returned QuestionnaireResponse instance or rendered form for all questions that have SDC extensions defining population expectations if appropriate data exists in the underlying data repository and/or in the content passed into the populate operation.
Similarly, client systems claiming to support the populate operation (SDC Form Filler) SHALL, at a minimum:
- Be capable of invoking the operation(s) on a selected questionnaire both directly (
Questionnaire/[identifier]/$populate) as well as indirectly either byidentifierorquestionnaire - Support passing at least* the Patient resource using the
contentparameter - Be able to accept an incoming partially-populated QuestionnaireResponse and render it as if they had retrieved a saved partially-completed QuestionnaireResponse
- It is the responsibility of the SDC Form Filler to ensure the form is valid after a human has reviewed and edited the form.
* Supporting additional resources relevant to the context of the form is also encouraged. Past versions of this specification mandated support for passing C-CDA resources as FHIR Binary instances and this is still permitted. However, this specification no longer provides recommendations for extracting data elements from C-CDA and we have not yet heard of any systems that do this successfully in a production environment.
Designing Questionnaires to support 'populate'
This specification defines three different mechanisms to embed information in Questionnaires to support population:
Systems are free to experiment with other population mechanisms but cannot expect support for those from other SDC-conformant systems.
Each mechanism has its own profile that includes the additional resource elements or extensions relevant for supporting a particular mechanism: SDC Questionnaire Populate - Observation, SDC Questionnaire Populate - Expression, and SDC Questionnaire Populate - Structure Map profiles. Each profile identifies specific 'must support' elements and extensions that systems that claim to support a specific SDC population mechanism SHALL be capable of populating data, as befits the CapabilityStatement(s) they claim conformance to. Each system should choose which approach(es) it wishes to use and support based on the elements specified in that profile.
Some of these mechanisms make use of FHIR-based queries, FHIRPath and/or CQL as well as extensions that include expressions in one of these languages. Implementers should read the Using Expressions page for background and guidance on these technologies and extensions.
These three mechanisms aren't necessarily mutually exclusive. It is possible to use StructureMap-based population to perform an initial set of 'complex' population and then have different elements within the Questionnaire that are set up to perform supplemental observation-based or expression-based population. Obviously, the same element should only be populated in one way. Also, combining methods adds complexity and may reduce the number of systems that are capable of appropriately handling the Questionnaire.
Note: StructureMap-based population takes precedence over all other mechanisms. If a StructureMap is present, any observation-based or expression-based population expectations are ignored entirely. Observation-based and expression-based population may be performed simultaneously, item by item. However, if both approaches attempt to populate the same item, behavior is undefined. It is strongly recommended that Questionnaire authors avoid configuring both mechanisms to target the same question item. Systems may choose to raise an error, ignore one of the methods, or include both results in the case of repeating items.
Observation-based Population
Profile:
SDC Questionnaire Populate - Observation profile
Relevant Extensions:
Example Questionnaires:
This is the simplest of the population mechanisms. It takes advantage of the fact that most question answers in the healthcare space typically correspond to the value element of an Observation. It also takes advantage of the Questionnaire.item.code element that identifies what a concept each question or group corresponds to.
To use this method:
-
Include the
item.codeelement on each question to be populated. Typically, this will be a LOINC code, but in some jurisdictions/environments, SNOMED CT or other codes may be relevant. -
Groups can also have an
item.codepresent - this might represent the code of a panel or the Observation.code of an Observation with no value but with multipleObservation.componentelements. Child question items can then assert theitem.codeof the "member-of" Observations or theObservation.component.codevalues. -
To signal that the item.code is actually intended for use in population (as opposed to just providing metadata about the Questionnaire item, the
observationLinkPeriodextension must also be included). This extension indicates the period of time over which to search for matching observations. If there are no observations within that window, no population will occur. For observations where how recent they are does not matter (e.g. blood type), simply set the duration to a long period of time - e.g. 200 years. If anobservationLinkPeriodextension is defined at the root Questionnaire, on a group item (even if it has noitem.code), or on a question item, that period applies to all descendant questions that have anitem.code, unless a closer (i.e., nearer in the hierarchy)observationLinkPeriodis defined and overrides it.This means that placing the extension on a parent item enables auto-population behavior for all coded descendant items, using the specified period to determine which Observations to query. Items without
item.codedo not themselves get populated but pass theobservationLinkPeriodto their coded children.Observation Link Period Hierarchical Diagram: This diagram illustrates the structure and flow of
observationLinkPeriodextension in a Questionnaire. It shows how the period applies from the Questionnaire root down to group items and question items, with cases of inheritance, overriding, and items without codes.
JSON
{% fragment Questionnaire/questionnaire-sdc-profile-example-weight-height-tracking-panel JSON BASE:descendants().select(item).where(linkId='/29463-7') %}
XML
{% fragment Questionnaire/questionnaire-sdc-profile-example-weight-height-tracking-panel XML BASE:descendants().select(item).where(linkId='/29463-7') %}
JSON
{% fragment Questionnaire/questionnaire-sdc-test-fhirpath-prepop-source-query JSON BASE:extension %}
XML
{% fragment Questionnaire/questionnaire-sdc-test-fhirpath-prepop-source-query XML BASE:extension %}