Skip to content

yamaa yamaa logo

Python tests YAML validation Docs License: MIT

yamaa is a domain-specific language (DSL) for clinical trial data standardization. A yamaa specification transforms ODM XML data, extracted from an EDC system, into SDTM and ADaM datasets following CDISC standards. The engine can also generate define.xml. yamaa's rules fix what every item means, so the same specification with the same inputs always produce the same datasets in both the R and Python engines.

The one principle behind everything:

A yamaa specification has exactly one execution. Where it would have two, yamaa fails instead of choosing.

That is what makes it safe to hand a specification to an AI agent: every question gets answered while it is still cheap to answer, at the planning stage. Nothing is left for the coding stage to guess.

The language is written to be read and revised by people and AI agents together, keeping derivations reviewable, version-controlled, and consistent across implementations. The yamaa project has four components: schema, rules, engine, and benchmark.

Component Purpose Links
Schema Declares the vocabulary of the specification. Repository / Introduction
Rules Defines the meaning of each specification. Repository / Rules
Engine Runs specifications in Python and R according to the rules. Python / R
Benchmark Provides runnable specification examples. Repository / Dashboards

From ODM XML to SDTM and ADaM

The engine reads ODM XML extracted from the EDC system and transforms it into one long-form clinical-item table. Each row represents one recorded item and retains the item's study, event, form, and item-group context. A yamaa specification reads the transformed data (example) and derives SDTM and ADaM datasets.

Inheritance

yamaa design: inherited templates become study specifications that drive validated SDTM, ADaM

Reusable yamaa specification templates flow from the organization level through the compound and study levels. Approved study specifications then drive deterministic, validated builds while preserving metadata lineage.

Example

A complete specification in 24 lines:

schema_version: "1.0"
domain: ADSL
keys: [STUDYID, USUBJID]        # one row per subject
input:
  DM: {path: input/dm.csv, types: {AGE: int}}   # CSV fields are text; cut needs a numeric source
output:
  path: adsl.csv
  columns: [STUDYID, USUBJID, AGEGR1]

columns:
  - name: STUDYID
    type: str
    derivation: DM.STUDYID
  - name: USUBJID
    type: str
    derivation: DM.USUBJID
  - name: AGEGR1
    type: str
    derivation:
      cut:
        source: DM.AGE
        breaks: [18, 65]
        labels: ['<18', '18-64', '>=65']
        missing: UNKNOWN

Read it top to bottom: one input, one driver, two keys, three columns. The derivation verbs (source, cut, mapping, compute, ...) come from a closed registry (see Schema introduction).

Installation

Python engine:

pip install git+https://github.com/elong0527/yamaa.git#subdirectory=python

R engine:

# install.packages("devtools")
devtools::install_github("elong0527/yamaa", subdir = "R/cdiscbuilder")

Where to go next

  • New here? Introduction explains the model in five minutes.
  • Coming from Excel specs? Excel to yamaa translates what you already know.
  • Looking for worked examples? Benchmarks illustrate the ideas.

License

This project is licensed under the terms of the MIT license.