Metadata-Version: 2.4
Name: malac-hd
Version: 1.9.2a837
Summary: Mapping Language Compiler for Health Data.
Author-email: cdeHealth-Team <contact-project+cdehealth-malac-hd-52276676-issue-@incoming.gitlab.com>
Project-URL: Homepage, https://gitlab.com/cdehealth/malac-hd
Project-URL: Documentation, https://gitlab.com/cdehealth/malac-hd
Project-URL: Release notes, https://gitlab.com/cdehealth/malac-hd/-/releases
Project-URL: Source, https://gitlab.com/cdehealth/malac-hd
Project-URL: Tracker, https://gitlab.com/cdehealth/malac-hd/-/issues
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Console
Classifier: Intended Audience :: Information Technology
Classifier: Intended Audience :: Healthcare Industry
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)
Classifier: Natural Language :: English
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Topic :: Software Development :: Code Generators
Classifier: Topic :: Software Development :: Libraries
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: malac-utils>=1.4.1a0
Requires-Dist: malac-models-fhir>=1.1.7a0
Requires-Dist: malac-models-cda>=1.1.3a0
Requires-Dist: malac-transformer-fhir>=1.1.3
Requires-Dist: antlr4-python3-runtime>=4.13.0
Requires-Dist: antlr4-tools>=0.2.1
Provides-Extra: cda
Requires-Dist: malac-models-cda>=1.1.3a0; extra == "cda"
Provides-Extra: test
Requires-Dist: pytest<10,>=9; extra == "test"
Requires-Dist: pytest-cov>=4.0.0; extra == "test"
Provides-Extra: docs
Requires-Dist: mkdocs-material>=9.5; extra == "docs"
Requires-Dist: mkdocs-glightbox>=0.4; extra == "docs"
Requires-Dist: mike>=2.1; extra == "docs"
Dynamic: license-file

# MaLaC-HD

[![PyPI Version](https://img.shields.io/pypi/v/malac-hd?label=version&color=purple)](https://pypi.org/project/malac-hd/)
[![PyPI Status](https://img.shields.io/pypi/status/malac-hd)](https://gitlab.com/cdehealth/malac-hd/)
[![PyPI Downloads](https://static.pepy.tech/personalized-badge/malac-hd?period=total&units=INTERNATIONAL_SYSTEM&left_color=GRAY&right_color=ORANGE&left_text=downloads)](https://pepy.tech/projects/malac-hd)
[![Top Language](https://img.shields.io/gitlab/languages/cdehealth%2Fmalac-hd)](https://gitlab.com/cdehealth/malac-hd/-/graphs/main/charts)
[![PyPI Pipeline](https://gitlab.com/cdehealth/malac-hd/badges/main/pipeline.svg)](https://gitlab.com/cdehealth/malac-hd/-/pipelines?page=1&scope=branches&ref=main)
[![DOI](https://img.shields.io/badge/citeme-10.3389/fmed.2025.1661091-52a9ff)](https://doi.org/10.3389/fmed.2025.1661091)
[![License](https://img.shields.io/pypi/l/malac-hd?color=yellow)](https://gitlab.com/cdehealth/malac-hd/-/blob/main/LICENSE)

MaLaC-HD (MApping LAnguage Compiler for Health Data) is a tool that you can use to convert mappings between different health data formats to executable code — Python by default, JavaScript for Node.js and web browsers, Java, or C# for .NET. It can also be used as a library to dynamically execute mappings — see the [library / API guide](docs/API.md).

[TOC]

## Contributing and Support

Please read [CONTRIBUTING.md](CONTRIBUTING.md) for contributing to cdeHealth projects which are hosted in the [cdeHealth group](https://gitlab.com/cdehealth) on GitLab.com.
Please read [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md) to make participation in our community a harassment-free experience for everyone.

## Getting Started

These instructions will get you a copy of the project up and running.

### Installation

Install malac-hd and its dependencies via pip, e.g. with CDA support:

```
pip install malac-hd[cda]
```

... or from npm, Maven or NuGet, whose packages run the Python package with a
Python 3.10 or later (which they check for, and install malac-hd into an
environment of their own, see [wrappers/README.md](wrappers/README.md)):

```
npx malac-hd --help                                  # npm: malac-hd
java -jar malac-hd.jar --help                        # Maven: io.gitlab.cdehealth:malac-hd
dotnet tool install -g Malac.Hd && malac-hd --help   # NuGet: Malac.Hd
```

... or, if you want to build from source:


```
git clone https://gitlab.com/cdehealth/malac/models.git
pip install -e models/python/fhir

git clone https://gitlab.com/cdehealth/malac/utils.git
pip install -e utils/python

git clone https://gitlab.com/cdehealth/malac/transformer.git
pip install -e transformer/fhir

git clone https://gitlab.com/cdehealth/malac-hd.git
pip install -e malac-hd
```

... and if you need to transform to or from cda:
```
git clone https://gitlab.com/cdehealth/malac/models.git
pip install -e models/python/cda
```

... and if you want to generate JavaScript code:
```
cd utils/js
npm install
npm run build:browser
```

... and if you want to generate Java code (needs a JDK 17 or later and Maven,
see [Java runtime and models](#java-runtime-and-models)):
```
(cd utils/java && mvn package)
(cd models/java/fhir && mvn package)
(cd models/java/cda && mvn package)
```

... and if you want to generate C# code (needs the .NET SDK 10 or later, and -
for the models - xsd.exe, see [.NET runtime and models](#net-runtime-and-models)):
```
(cd utils/dotnet && dotnet build -c Release)
(cd models/dotnet/fhir && dotnet build -c Release)
(cd models/dotnet/cda && dotnet build -c Release)
```

### Using MaLaC-HD

with `malac-hd --help` you will get an overview:

```
____________________ MaLaC-HD 1.9.2-alpha.837 started ____________________
usage: malac-hd [-h] -m MAPPING [-co CONVERT_OUTPUT] [-l {python,javascript,java,csharp}] [-ju [JS_UTILS_OUTPUT]] [-ti TRANSFORM_INPUT] [-to TRANSFORM_OUTPUT] [-mod MODELS [MODELS ...]] [-sr SUPPORTING_RESOURCE [SUPPORTING_RESOURCE ...]] [-s]

You are using the MApping LAnguage Compiler for Health Data, short MaLaC-HD.
We differentiate between two modes, CONVERTING and TRANSFORMING.
The CONVERSION is done by compiling a given mapping to Python (default), JavaScript, Java or C# code, that itself can be run with its own argument handling for TRANSFORMING input files.
Additionally, the TRANSFORMATION can also be be done by MaLaC-HD directly after CONVERSION, i.e. for direct testing purposes.

options:
  -h, --help            show this help message and exit
  -m, --mapping MAPPING
                        the mapping file path, the conversion/mapping rule language is detected by file ending, right now FML maps (*.map), FHIR R4 (*.4.fhir.xml) StructureMaps and ConceptMaps can be given as mappings
  -co, --convert_output CONVERT_OUTPUT
                        the conversion output file path (a .py, .js, .java or .cs file, depending on --language), if not given, saved in the working directory with the map-file name.
                        A Java or C# class is named like its file, so the name of a .java or .cs file has to be one such a class can have
                        (and no reserved word)
  -l, --language {python,javascript,java,csharp}
                        the language the mapping is compiled to (default: python). JavaScript code needs the malac-utils JS runtime
                        (`require('malac-utils')`) and, for a direct TRANSFORMATION, Node.js; it reads and writes JSON only,
                        except for a source model without a JSON form (CDA), which it reads as XML. Java code needs the Java side of
                        malac-utils and the Java models of malac-models (their jars, see their README.md) and, for a direct TRANSFORMATION,
                        a JDK (javac and java). C# code needs the .NET side of malac-utils and the .NET models of malac-models (their
                        assemblies, see their README.md) and, for a direct TRANSFORMATION, a .NET SDK (dotnet)
  -ju, --js_utils [JS_UTILS_OUTPUT]
                        with --language javascript: also write the malac-utils JS runtime the mapping needs, i.e. the self-contained
                        malac-utils.js of the installed malac-utils package, which works in a web browser as well as with Node.js.
                        Without a path it is written as malac-utils.js next to the conversion output (-co), or into the working directory
  -ti, --transform_input TRANSFORM_INPUT
                        the transformation input file path, the ressource type is detected by its root node inside the xml
  -to, --transform_output TRANSFORM_OUTPUT
                        the transformation output file path, the ressource type is detected by its root node inside the xml
  -mod, --models MODELS [MODELS ...]
                        register additional model packages: importable module names or paths to Python files, each exposing a list_i_o_modules dict (see malac.hd.load_model_packages); the MALAC_HD_MODELS environment variable is read as well
  -sr SUPPORTING_RESOURCE [SUPPORTING_RESOURCE ...], --supporting-resource SUPPORTING_RESOURCE [SUPPORTING_RESOURCE ...]
                        additional FHIR resources that support the mapping (currently ConceptMaps), resolved by canonical URL when translate() references a map not defined inline. Each value is a directory of JSON/XML resources, an npm package .tgz, or a single .json/.xml file. If not given, the MALAC_HD_SUPPORTING_RESOURCES environment variable is used instead
  -s, --silent          do not print the converted mapping to console
```

Supply ConceptMaps that a mapping's `translate()` calls reference by canonical URL, without inlining them into the map source:
```
malac-hd -m my-map.map -co my-map.py -sr path/to/conceptmaps/ another-conceptmap.json
```

A source may be a directory of JSON/XML resources, a single `.json`/`.xml` file or an
npm package `.tgz`; plain `.zip` archives and `http(s)`/git URLs are not supported yet
and report a clear error. Every resource found is indexed by its `resourceType` and
canonical `url`, so a mixed FHIR package or IG output directory can be passed as is —
but **only ConceptMaps are consumed at the moment**. Other resource types (e.g.
supporting StructureMaps and StructureDefinitions) are loaded and ignored; they can
start being used later without a new flag.

#### Example Usage 

Convert an FML map to Python and directly execute it:
```
malac-hd -m tests/fml/r4/aut_lab/CdaToBundle.4.map -co cdaToBundle.py -ti tests/structuremap/r4/aut_lab/Lab_Allgemeiner_Laborbefund.at.cda.xml -to bundle.4.fhir.xml
```

Execute the generated Python code:
```
python cdaToBundle.py -s tests/structuremap/r4/aut_lab/Lab_Allgemeiner_Laborbefund.at.cda.xml -t bundle.4.fhir.xml
```

The same map compiled to JavaScript, run by MaLaC-HD and then on its own with
Node.js (the generated script takes the source and target path as its two
arguments; `-ju` writes the runtime it needs to where Node looks for it, see
[JavaScript runtime](#javascript-runtime)):
```
malac-hd -m tests/fml/r4/aut_lab/CdaToBundle.4.map -l javascript -co cdaToBundle.js -ju node_modules/malac-utils/index.js -ti tests/structuremap/r4/aut_lab/Lab_Allgemeiner_Laborbefund.at.cda.xml -to bundle.4.fhir.json
node cdaToBundle.js tests/structuremap/r4/aut_lab/Lab_Allgemeiner_Laborbefund.at.cda.xml bundle.4.fhir.json
```

The same map compiled to Java, run by MaLaC-HD and then on its own (the class
path is printed by `python -m malac.hd.runtime.java`, see
[Java runtime and models](#java-runtime-and-models)):
```
malac-hd -m tests/fml/r4/aut_lab/CdaToBundle.4.map -l java -co CdaToBundle.java -ti tests/structuremap/r4/aut_lab/Lab_Allgemeiner_Laborbefund.at.cda.xml -to bundle.4.fhir.xml
CP=$(python -m malac.hd.runtime.java)
javac -cp "$CP" CdaToBundle.java
java -cp "$CP:." CdaToBundle -s tests/structuremap/r4/aut_lab/Lab_Allgemeiner_Laborbefund.at.cda.xml -t bundle.4.fhir.xml
```

The same map compiled to C# and run by MaLaC-HD (see
[.NET runtime and models](#net-runtime-and-models) for running it on its own):
```
malac-hd -m tests/fml/r4/aut_lab/CdaToBundle.4.map -l csharp -co CdaToBundle.cs -ti tests/structuremap/r4/aut_lab/Lab_Allgemeiner_Laborbefund.at.cda.xml -to bundle.4.fhir.xml
```

The input files for the examples are included in the source.

##### Reading from stdin and writing to stdout

The generated Python script also accepts `-` for `--source` and/or `--target` to read
from stdin and write to stdout, so transformations can be chained together in a
shell pipeline. Because there is no file extension to detect the format from, a
stream must be accompanied by an explicit format flag, `-st/--source-type` and
`-tt/--target-type` (`xml` or `json`); for real file paths the format is still
detected from the extension. Progress messages are written to stderr, so stdout
carries only the transformed payload.

```
cat patient.xml | python step1.py -s - -t - -st xml -tt xml | python step2.py -s - -t - -st xml -tt json > result.json
```

(JSON is only available where the mapping's source/target model supports it,
which MaLaC-HD detects from the model package: JSON input where the package
provides `utils.parse_json`, JSON output where the mapping's root target class
has `exportJson`. The FHIR models have both; XML-only models such as CDA have
neither.)

#### Generating JavaScript

With `-l javascript` (`--language javascript`) a mapping is compiled to a
JavaScript module instead of a Python one. StructureMaps, FML maps and
ConceptMaps are all supported, and the result transforms the same inputs to the
same output as the Python code does. The module
- runs with Node.js as `node mapping.js <source> <target>`, and
  `malac-hd -l javascript -ti ... -to ...` does exactly that,
- also runs in a web browser: load `malac-utils.js` (written by `-ju`, see
  [JavaScript runtime](#javascript-runtime)) and then the generated
  script with `<script>` tags, and call `transformText(sourceText)`, which
  returns the result as a JSON string,
- exports `transform(sourcePath, targetPath)` and `transformText(sourceText)`
  when it is `require()`d as a Node module,
- needs the malac-utils JavaScript runtime (`require('malac-utils')`, or the
  `malacUtils` global the browser bundle defines).

Formats differ from the Python code in three respects:
- the output is always **JSON** — XML serialization needs the schema's element
  order and namespaces, which the JavaScript runtime does not have. So a
  mapping whose target model has no JSON form (FHIR to CDA, for instance) can be
  compiled, but not usefully run;
- the input is **JSON** for a source model that has a JSON form (FHIR), and
  **XML** for one that has not (CDA). For the latter, the generated code carries
  the parts of the source schema it needs to read the XML (which elements
  repeat, which type each one has);
- there is no reading from stdin or writing to stdout.

For a source checkout, `tests/structuremap/transform-in-browser.html` runs any
compiled test mapping in a browser. The StructureMap tests keep its list of
mappings up to date; see the comment at the top of the page for how to open it.

#### JavaScript runtime

Mappings compiled to JavaScript need the JavaScript side of malac-utils. The
malac-utils package, which is installed with malac-hd, ships it as one
self-contained file for Node.js and web browsers alike:
`malac/utils/js/malac-utils.js` inside the installed package.
`malac-hd -l javascript -ti ... -to ...` finds it by itself, so running
JavaScript mappings through MaLaC-HD only needs Node.js to be installed.

When building from source, that file is built in the `js/` directory of the
malac-utils checkout (where `npm install` is also what lets Node use the
sources directly, which `pip install -e utils/python` does):

To use a generated mapping outside of MaLaC-HD, let `-ju` (`--js_utils`) write
the runtime of the installed malac-utils package along with it. Without a path
it is written as `malac-utils.js` next to the compiled mapping, ready for a
`<script>` tag in a web browser:

```
malac-hd -m map.5.map -l javascript -co mapping.js -ju
```

Node.js needs it as the Node package `malac-utils` instead. The runtime is
published to npm under that name, with the same version as the malac-utils
Python package, so it can simply be installed:

```
malac-hd -m map.5.map -l javascript -co mapping.js
npm install malac-utils
node mapping.js input.json output.json
```

Without npm, give `-ju` the path where Node looks for that package:

```
malac-hd -m map.5.map -l javascript -co mapping.js -ju node_modules/malac-utils/index.js
node mapping.js input.json output.json
```

In a web browser, the file can also come from the npm package, e.g. via
`https://cdn.jsdelivr.net/npm/malac-utils/dist/malac-utils.js`.

In a source checkout of malac-utils, `-ju` warns if `malac-utils.js` is older
than the `js/src` sources: run `npm run build:browser` in `js/` to rebuild it.
Alternatively, Node can use the sources of a checkout directly after
`npm install ../utils/js`.

#### Generating Java

With `-l java` (`--language java`) a mapping is compiled to a Java class
instead of a Python module. StructureMaps, FML maps and ConceptMaps are all
supported, and the result transforms the same inputs to the same output as the
Python code does, in XML as well as in JSON. The class
- is named like the file it is written to (`-co Mapping.java` gives the class
  `Mapping`), as Java requires,
- has a `main` that takes the same options as the generated Python script
  (`-s`/`--source`, `-t`/`--target`, `-st`/`--source-type`, `-tt`/`--target-type`,
  the formats otherwise taken from the file endings),
  and `malac-hd -l java -ti ... -to ...` compiles and runs it,
- offers `transformText(sourceText, sourceType, targetType)` and
  `transform(sourcePath, targetPath, sourceType, targetType)` to other Java
  code; the class of a ConceptMap offers `translate(params)` and a `main` that
  takes the parameters of `$translate` as options (`--code`, `--system`, ...),
- works on the typed Java models of malac-models: the code reads and sets
  elements through their getters and setters, with the types the compiler
  resolved for the map's variables. Where a map uses a value in a way no Java
  type fits - a group called with values of different types, an element set to
  a value of an unrelated type - the code falls back to accessing elements by
  name (`Model.get`, `Model.set`), as Python does.

#### Java runtime and models

Mappings compiled to Java need the Java side of malac-utils and the Java
models of malac-models, which their Python packages ship as jars:
`malac/utils/java/malac-utils.jar` (self-contained, with the JAXB API the
models use and Jackson, which writes the JSON) and `malac/models/<fhir|cda>/java/malac-models-<fhir|cda>.jar`.
The models are generated by JAXB's xjc from the same XML schemas as the Python
models, with classes named like the Python ones; next to each jar, a JSON file
describes the classes for the compiler, which needs no JVM itself.

`python -m malac.hd.runtime.java` prints the class path of all of them, and
`malac-hd -l java -ti ... -to ...` uses it to compile and run a mapping, so
running Java mappings through MaLaC-HD only needs a JDK (17 or later).

In a source checkout, the jars are built with `mvn package` in `java/` of the
utils checkout and in `java/fhir` and `java/cda` of the models one (see their
README.md);
`malac-hd -l java -ti ... -to ...` warns if `malac-utils.jar` is older than
the Java sources of its checkout.

#### Generating C#

With `-l csharp` (`--language csharp`) a mapping is compiled to a C# class
instead of a Python module. StructureMaps, FML maps and ConceptMaps are all
supported, and the result transforms the same inputs to the same output as the
Python code does, in XML as well as in JSON. The C# code is the Java code (see
above) in another language - it is generated by the same reasoning about
types, and the .NET runtime has the Java runtime's classes and methods - so
the class
- is named like the file it is written to (`-co Mapping.cs` gives the class
  `Mapping`), or like the map where the file name is no name for a class,
- has a `Main` that takes the same options as the generated Python script,
  and `malac-hd -l csharp -ti ... -to ...` compiles and runs it,
- offers `transformText(sourceText, sourceType, targetType)` and
  `transform(sourcePath, targetPath, sourceType, targetType)` to other .NET
  code; the class of a ConceptMap offers `translate(params)` and a `Main` that
  takes the parameters of `$translate` as options,
- works on the typed .NET models of malac-models: the code reads and sets
  elements through their properties, with the types the compiler resolved for
  the map's variables. Where the models hold an element in a way a property
  cannot give (an element of a choice, like FHIR's `value[x]`, or of mixed
  content; a value type that may be unset), and where a map uses a value in a
  way no C# type fits, the code accesses it by name (`Model.get`,
  `Model.set`), as Python does.

#### .NET runtime and models

Mappings compiled to C# need the .NET side of malac-utils and the .NET models
of malac-models, which their Python packages ship as assemblies:
`malac/utils/dotnet/malac-utils.dll` and
`malac/models/<fhir|cda>/dotnet/malac-models-<fhir|cda>.dll`. The models are
generated by xsd.exe from the same XML schemas as the Python models (which
xsd.exe gets prepared for it, see the README.md of malac-models); next to each
assembly, a JSON file describes the classes for the compiler, which needs no
.NET itself.

`python -m malac.hd.runtime.dotnet` prints the paths of all of them, and
`malac-hd -l csharp -ti ... -to ...` compiles a mapping with them, with the C#
compiler of the .NET SDK, and runs it, so running C# mappings through MaLaC-HD
only needs the .NET SDK (10 or later). To run a mapping on its own, compile
it in a project that references those assemblies, and run the program with
them next to it:
```
dotnet CdaToBundle.dll -s tests/structuremap/r4/aut_lab/Lab_Allgemeiner_Laborbefund.at.cda.xml -t bundle.4.fhir.xml
```

In a source checkout, the assemblies are built with `dotnet build -c Release`
in `dotnet/` of the utils checkout and in `dotnet/fhir` and `dotnet/cda` of the
models one (see their README.md); `malac-hd -l csharp -ti ... -to ...` warns if
`malac-utils.dll` is older than the C# sources of its checkout.

#### Using MaLaC-HD as a library

MaLaC-HD can also be driven from Python: convert a mapping to code and run
transformations programmatically, without the command-line tool. See the
[library / API guide](docs/API.md) for runnable examples.

#### Model package plugins

Model packages that are not part of the `malac.models.*` distributions (for
example, project-specific logical models) can be registered without modifying
MaLaC-HD. A plugin is any Python module that exposes `list_i_o_modules`: a
dict mapping canonical URL prefixes (the `uses` URL up to the last path
segment) to the Python module holding the model classes — the same contract
`malac.models.fhir` and `malac.models.cda` fulfil:

```python
# my_models_plugin.py
from malac.models.fhir import r5

list_i_o_modules = {
    "http://example.org/fhir/StructureDefinition": r5,
}
```

Plugins are given as importable module names or as paths to Python files,
either on the command line:

```
malac-hd -m map.5.map -co map.py -mod my_models_plugin.py other.models
```

or through the `MALAC_HD_MODELS` environment variable (comma- or
`os.pathsep`-separated), or programmatically via
`malac.hd.load_model_packages([...])`. Loading failures of explicitly
requested plugins raise immediately instead of being swallowed.


## Why?

When having parallel operations of some sort or another, there is one requirement that is challenging in the context of standardized APIs: mapping data, to make it accessible to the different worlds at least.

There are many methods to map from one semi-structured data format to another. Most of the time, when a mapping requirement reveals, it is solved by a quick small script. After some time, that script needs technical or rule updates. As the rules are directly coded, they can only be altered by someone having knowledge about the mapping content, the mapping rules and the mapping technology. 

To divide these concerns, HL7 FHIR created resources for mapping purposes, like the [StructureMap](https://www.hl7.org/fhir/structuremap.html) for [transformation](https://www.hl7.org/fhir/structuremap-operation-transform.html) and [ConceptMap](https://www.hl7.org/fhir/conceptmap.html) for [translation](https://www.hl7.org/fhir/conceptmap-operation-translate.html). Additionally, a more human-readable metalanguage for creating such StructureMap and ConceptMap resources was created, called [FHIR Mapping Language, or in short FML](https://www.hl7.org/fhir/mapping-language.html). Interestingly enough, FML is not restricted to FHIR as a source or target for the mapping. It could also be used i.e. to map from HL7 CDA to OHDSI OMOP CDM.

Current FML or StructureMap/ConceptMap tools are quite slow in the transformation/translation of the content to be mapped, as both steps, the processing of the rules and the transformation/translation itself are done every time. As a gold standard and sparring partner for this project, the Canadian open source project [HAPI](https://github.com/hapifhir) with its Suisse extension [matchbox](https://www.matchbox.health/) has been used. Additionally, we got notice about an Italian project speeding up matchbox, but couldn't find any public references.

We can't use current tools to map data synchronously, as nearly all mapping executions need more time than the [dorethy threshold of 0.4 seconds](https://lawsofux.com/doherty-threshold/), resulting in the user's perception of "it got stuck". Also, the practical but restricted FHIR mapping language does not offer any possibilities to extend it with further functions, in contrast to the StructureMap and ConceptMap resources themselves, that could be easily extended.

## How?

Focusing on but not restricting to the health information technology world, a partnership was created out of the experts in the CDA2FHIR HL7 Austria Working Group, to solve this issue. On one side with expertise in research and on the other side with expertise in EHRs.

By applying the MVP concept of build-measure-learn-repeat, the first versions were created and tested against already existing FML-mappings in the HL7 community and matchbox as a mapping tool. 

As the partners are themselves heavy users of the resulting MVPs, using them immediately after release, quick iterations of four months are planned.

## What?

MaLaC-HD is intended to focus on transformation speed and easy extensibility after compilation/conversion. This is achieved by separation of 
* the processing from FML to StructureMap/ConceptMap, 
* the conversion from StructureMap/ConceptMap to Python or JavaScript code, 
* the execution of the translation itself from source to target. 
It uses the mappings and requirements of some preliminary projects (i.e. https://github.com/HL7Austria/CDA2FHIR) as testing data.

MaLaC-HD is not limited to the use of FML or StructureMap/ConceptMap for the translation, but has already implemented a conversion from StructureMap/ConceptMaps to Python and JavaScript code. It can be used to transform/translate different input formats to different output formats, using some conversion/mapping rule language and the XSD or JSON schemas of the input and output format. It also makes it easier to develop new conversion or mapping rule languages, further input formats and/or extensions.

## Detailed Workflow

The processing and conversion from FML/StructureMap/ConceptMap to Python code is handled in different components of MaLaC-HD. The following graph shows which components are responsible and in what order they are called.

[![Detailed workflow of conversion process](https://gitlab.com/cdehealth/malac-hd/-/raw/main/images/workflow.drawio.svg)](https://gitlab.com/cdehealth/malac-hd/-/blob/main/images/workflow.drawio.svg)

Our pipeline is able to directly process FML code, but can also convert StructureMap or ConceptMap resources to Python. For the FML to StructureMap/ConceptMap conversion and the ConceptMap to Python conversion, individual generators/parsers for the supported FHIR versions exist. Even though they share a lot of code, they contain specific logic for each FHIR version. For the StructureMap to Python conversion, only a generator for the latest FHIR version exists. Legacy StructureMaps are internally transformed to the latest version to ensure backwards compatibility. As this is the most complex step in the conversion, this allows us to simplify things by only having a single codebase. The StructureMap and ConceptMap generators come in a Python and a JavaScript flavour that share the traversal of the mapping and differ only in the code they emit; `-l/--language` selects which one is used.

## Pursued Objectives
The development of MaLaC-HD focuses on the following three main objectives and their respective sub-objectives:

- The compilation of the conversion/mapping rules by MaLaC-HD and the resulting mapping of these rules in a common programming language must be easily readable and directly related to the conversion/mapping rules.
  - The conversion/mapping rules must be ballotable so that they can be queried and discussed for completeness and correctness as part of a guideline or even as a standalone part in a community, such as the HL7 community.
- MaLaC-HD must not be dependent on any conversion rule language in order to be able to easily process conversion/mapping rules that can be mapped in different conversion rule languages.
  - In particular, the limits of the respective conversion rule language require simple narrative extensibility in order to draw attention to the fact that further code must be added manually in the respective generated code by means of placeholders.
- The result of compiling the conversion/mapping rules must be trimmed for speed and stability so as not to add any obstructive delays.
  - The compiled conversion/mapping rules should be executable as stand-alone program code without MaLaC-HD.

## Timeline

[![Timeline of the MaLaC-HD project](https://gitlab.com/cdehealth/malac-hd/-/raw/main/images/timeline.png)](https://gitlab.com/cdehealth/malac-hd/-/blob/main/images/timeline.png)

## Authors and acknowledgment
We want to thank
- [ELGA GmbH](https://www.elga.gv.at/) with their [CDA2FHIR](https://collab.hl7.at/display/BAL/AG+ELGA+CDA+Laborbefund+zu+FHIR) projects and
- [AIT Austrian Institute of Technology GmbH](https://www.ait.ac.at/) with their [SmartFOX](https://www.smart-fox.at/) project.

Additionally, we want to thank 
- [Dave Kuhlman](https://davekuhlman.org/) with his open source implementation of [generateDS](https://www.davekuhlman.org/generateDS.html), making quick serializations of new data structures from their XSD schemas possible. 

## License
This is a LGPL licensed project, with a small addition that any usage of this project or the results of this project should contain a malac icon which is visible to the consumer. Multiple versions of the malac icon can be found in the [images directory](https://gitlab.com/cdehealth/malac-hd/-/tree/main/images). Changing the color of any malac_simple version is allowed if the icon itself is still visible on your background.
