In-Place Code Translation

 

Smile CDR can apply ConceptMap $translate mappings directly to a FHIR resource before it is persisted, adding the translated coding alongside the original.

This is a mapping-on-the-way-in approach: the translated code is added to the resource before it is stored, so downstream consumers see standardized codes immediately. The original coding is preserved unchanged. This contrasts with FHIR Response Terminology Enhancement, which applies mappings on the way out without modifying stored data.

In-place translation targets a single, fixed mapping: Observation.code is translated to LOINC (http://loinc.org). The resource type and target system are hard-coded.

How It Works

For each create or update of an Observation:

  1. Reads Observation.code (the CodeableConcept translated in place).
  2. Checks whether that CodeableConcept already contains a coding in LOINC. If so, translation is considered complete and no action is taken.
  3. Iterates over all Coding elements in Observation.code.
  4. For each coding whose system is not already LOINC, calls the ConceptMap $translate operation using that coding's system and code, targeting LOINC.
  5. If a match is found: adds the translated Coding to the CodeableConcept alongside the original, which is preserved unchanged.
  6. If no match is found for any coding in the concept: the codings are left unchanged. If missing-translation suggestion is enabled, the unmapped code is dispatched for asynchronous resolution.
  7. The result is considered translated if any coding was successfully translated.

What counts as a "match"

A $translate result is treated as a match when ConceptMap returns at least one mapping whose equivalence is not unmatched or disjoint. The first such mapping is used (results are not re-ranked). An equivalent mapping is the ideal case; other equivalences (equal, wider, narrower, subsumes, specializes, inexact, relatedto) are also accepted, with the usual caveat that a non-equivalent mapping may broaden or narrow meaning. If multiple ConceptMaps could apply, ConceptMap-based selection follows the standard $translate resolution rules — this service does not impose its own ranking.

Relationship to Other Translation Features

FeatureDirectionModifies Stored DataUse Case
Response Terminology EnhancementOn the way outNoReturn standardized codes to clients without altering stored resources
Terminology Mapping ($translate)On demandNoManual or programmatic ConceptMap lookups
In-Place Code TranslationOn the way inYes (when enabled as a storage interceptor)Adds ConceptMap-based LOINC codings to Observation.code before storage

Activation Methods

 

In-place translation can be activated in two ways: automatically for all stored Observations via module configuration, or explicitly inside a Camel route. Both produce identical translation behaviour.

Automatic Translation

When enabled in the FHIR Storage module configuration, every Observation create and update has its Observation.code translated to LOINC before it is persisted. No code or Camel route changes are required.

Translation runs at the storage pre-storage stage:

  • STORAGE_PRESTORAGE_RESOURCE_CREATED — fires before a new resource is persisted
  • STORAGE_PRESTORAGE_RESOURCE_UPDATED — fires before an existing resource is updated

Resources other than Observation pass through unchanged.

SettingDefaultDescription
inplace_translate.interceptor.enabledfalseWhen true, Observation.code is automatically translated to LOINC on every create and update at module startup.

Camel Processor: inplaceTranslateProcessor

The inplaceTranslateProcessor is a built-in Smile Camel processor that applies in-place translation inside a Camel route. It receives an IBaseResource as the exchange body, translates its codings to the specified target system, and places the (possibly modified) resource back onto the exchange body.

  • Example URI: smile:persistence/inplaceTranslateProcessor?targetSystem=http://loinc.org
  • Input: IBaseResource — the FHIR resource whose codings should be translated
  • Output: IBaseResource — the resource after translation (original codings preserved; translated coding added if found)

URI Parameters

ParameterRequiredDescription
targetSystemYesThe target code system URI (e.g., http://loinc.org)

Example Route

The following Camel route reads Observations from a Kafka topic, applies in-place LOINC translation, and stores the result:

<routes xmlns="http://camel.apache.org/schema/spring">
    <route id="inplace-translate-observation">
        <from uri="kafka:observations-in?brokers=localhost:9092&amp;groupId=translate-group&amp;maxPollRecords=1&amp;allowManualCommit=true&amp;autoCommitEnable=false"/>
        <!-- Translate codings to LOINC in-place -->
        <to uri="smile:persistence/inplaceTranslateProcessor?targetSystem=http://loinc.org"/>
        <!-- Persist the (possibly translated) resource -->
        <to uri="smile:persistence/singleResourceProcessor"/>
        <to uri="smile:clustermgr/kafkaManualCommit"/>
    </route>
</routes>

Use this approach when translation is part of an explicit Camel integration route, or when you want fine-grained control over which resources are translated and when.

Choosing an Activation Method

Automatic TranslationCamel Processor
ActivationModule config (inplace_translate.interceptor.enabled=true)Explicit <to uri="smile:persistence/inplaceTranslateProcessor?..."/> in a route
ScopeAll Observation create/update operationsOnly resources that pass through the configured route
ControlAutomatic — applies to all callersFine-grained per-route control
Best forBlanket translation policy across all ingestion pathsIntegration pipelines with explicit flow

Missing Translation Suggestion

 

When in-place translation cannot find a ConceptMap mapping for a coding, Smile CDR can optionally dispatch the unmapped code to a missing-translation suggestion pipeline that asks a configured provider to suggest candidate codings.

The provider extension point is an internal SPI and is not a supported public API. Two providers ship built in: a non-production mock for wiring validation and a wci provider backed by the West Coast Informatics automap service.

Control Flow

flowchart TD
    A[Observation create/update] --> B{Observation.code already LOINC?}
    B -- yes --> Z[Persist unchanged]
    B -- no --> C[ConceptMap $translate to LOINC]
    C -- match --> D[Add LOINC coding alongside original] --> Z2[Persist translated]
    C -- no match --> E{missing_translation_suggestion.enabled?}
    E -- no --> Z3[Persist unchanged]
    E -- yes --> F[Create / dedupe FHIR Task for unmapped code]
    F --> G[Task Subscription delivers to broker channel]
    G --> H[Task coordinator loads the source resource from the Task focus]
    H --> H2[Coordinator invokes active provider]
    H2 --> I[Write candidate codings onto the Task]

Task State Machine

The FHIR Task representing an unmapped code transitions as follows:

stateDiagram-v2
    [*] --> requested: Task created for unmapped code
    requested --> ready: provider returned candidates, written to Task
    requested --> failed: source resource unresolvable, or provider error
    ready --> in_progress: operator selects a candidate coding
    in_progress --> completed: ConceptMap updated, bulk patch submitted
    in_progress --> failed: required selection inputs missing
    requested --> cancelled: operator cancels

While a requested Task is being processed, the coordinator briefly sets it to the transient FHIR received status before it reaches ready or failed. This status is not a stable resting state — it may be observed momentarily by UI/webadmin observers polling the Task but is not a distinct step operators act on.

The source resource (the Task's focus reference) is required for suggestion processing. If it has been deleted or cannot be resolved by the time the Task is processed, the Task transitions directly to failed, the same as a provider error.

Module Configuration

The suggestion pipeline is gated by two settings on the FHIR Storage module:

SettingDefaultDescription
inplace_translate.missing_translation_suggestion.enabledfalseWhen true, codings that in-place translation cannot map via ConceptMap $translate are dispatched to the configured provider asynchronously through a FHIR Task. When false, unmapped codings are left untouched and no Task is ever created.
missing_translation_suggestion.provider.active_name(empty)The name of the provider to use. Only consulted when missing_translation_suggestion.enabled is true; when that flag is on and this is blank, startup fails with a ConfigurationException. When set to a value that does not match any discovered provider, startup also fails with a ConfigurationException listing the known providers.

Built-In mock Provider

A mock provider ships with Smile CDR for end-to-end wiring validation only. It becomes active only if you explicitly set missing_translation_suggestion.provider.active_name=mock. When active it ignores the request and always returns the same fixed list of five LOINC candidate codings with decreasing confidence (12345-6 at 0.95, 23456-7 at 0.80, 34567-8 at 0.65, 45678-9 at 0.50, 56789-0 at 0.35).

Do not select the mock provider in production. It is a placeholder and always returns the same stub result regardless of the input code.

Built-In wci Provider

A wci provider integrates with the West Coast Informatics (WCI) automap service. When active (missing_translation_suggestion.provider.active_name=wci), it builds a mapping request from the unmapped code's source system and code plus a WCI entity type derived from the source resource — the resource type, refined by the resource's category where one is defined (for example, an Observation categorized as vital-signs is submitted as a vital-sign term rather than the default lab result). It posts the request to the WCI service and maps the response into candidate codings. Candidates whose system does not match the requested target system are dropped, as are candidates below the confidence threshold; the remainder are ordered by confidence descending and capped at five.

The wci provider's configuration is hardcoded: the WCI service base URL is http://localhost:8080, the minimum confidence threshold is 0.75, and at most 5 candidates are returned. The provider does not stand up or manage the WCI service itself — a reachable WCI instance must already be running.

If the source resource's type has no WCI entity-type mapping, or the WCI service is unreachable, returns a non-2xx status, or returns an unparseable body, the suggestion Task is recorded as failed.

Relationship to Other Translation Features

FeatureTriggerModifies Stored DataUses ConceptMap
Response Terminology EnhancementOn the way outNoYes
Terminology Mapping ($translate)On demandNoYes
In-Place Code TranslationOn the way inYes (when enabled)Yes
Missing Translation SuggestionAsync, after ConceptMap missNo (suggestions written to a Task)No