SDTM Genomics Findings (GF) Domain: Tabulate Pharmacogenomic Findings for CDISC

Tabulate called genomic findings — mutations, variants, gene expression — into the CDISC SDTM Genomics Findings (GF) domain in R, link them to the biospecimen domains, and keep raw sequence files out of the submission

Pharma & Clinical

A runnable introduction to the CDISC SDTM Genomics Findings (GF) domain — the SDTMIG v3.4 Findings-class domain for pharmacogenomic data. Learn the cardinal principle that GF tabulates called findings (variants and gene expression), never raw FASTQ/BAM/VCF sequence files; how GF supersedes the deprecated provisional PF domain; the core Findings-class variables (GFSEQ, GFTESTCD, GFTEST, GFCAT, GFORRES, GFSTRESC, GFSPEC, GFREFID) and where their controlled terminology comes from; and how a GF finding links back to the biospecimen domains (BE/BS/RELSPEC). Then build a first GF dataset in R from a molecular-pathology export and join it to real biospecimen data.

Published

July 1, 2026

Modified

July 7, 2026

TipKey takeaways
  • GF is a Findings-class domain for genomic results. The SDTM (Study Data Tabulation Model) GF (Genomics Findings) domain tabulates called genomic findings — DNA variants and gene-expression measures — in the same one-record-per-test shape as labs and vital signs, keyed by a test code GFTESTCD.
  • GF stores findings, never raw reads. A submission’s GF domain holds the called result (a variant, an expression value), not the FASTQ/BAM/VCF sequence files those results were called from — those live in specialized genomic repositories, out of SDTM scope.
  • GF supersedes the deprecated PF domain. GF is published in SDTMIG v3.4; CDISC recommends it over the older provisional PF (Pharmacogenomics/Genetics Findings) domain and the deprecated SDTMIG-PGx guide.
  • Controlled terminology comes from NCI EVS. The GFTESTCD test code is governed by the CDISC subset C181178, and the paired GFTEST name by C181179 — do not coin your own and treat them as official. The category groupings (GFCAT/GFSCAT) are sponsor-defined, with no CDISC codelist.
  • A GF finding links back to the specimen it came from. The biospecimen domains — BE (Biospecimen Events), BS (Biospecimen Findings), RELSPEC (Related Specimens) — track the sample, and a GF record references it, so a variant is always traceable to a collected specimen.

Introduction

The oncology trial sequenced every tumour. Now the genomic findings have to reach the FDA in the same SDTM shape as the labs and the vital signs — without shipping a single BAM file. That is the job of the GF domain.

SDTM — the Study Data Tabulation Model — is the CDISC (Clinical Data Interchange Standards Consortium) standard that sorts collected trial data into fixed, reviewable domains. GF (Genomics Findings) is the domain for pharmacogenomic data: the mutations, variants, and gene-expression measures a molecular lab called from a subject’s specimen. It is a Findings-class domain — one record per test, keyed by a test code — published in the CDISC Genomics standard as part of SDTMIG v3.4, the SDTM Implementation Guide.

The cardinal principle runs through everything below: GF tabulates the called findings, not the raw sequence files. A variant call (EGFR p.L858R, detected) belongs in GF; the FASTQ, BAM, and VCF files it was called from do not — they stay in specialized genomic repositories, outside SDTM. Get that boundary right and the rest is ordinary Findings-class tabulation.

Here is where we are headed — a small GF domain built from a molecular-pathology export, showing which driver mutations were called on each subject’s tumour specimen:

A subject-by-gene grid (oncoprint style) of called genomic findings for three lung-tumour subjects. Rows are subjects (01-701-1033, 01-701-1034, 01-701-1047); columns are the tested genes EGFR, KRAS, BRAF, TP53. A filled azure tile marks a detected variant, labelled with its HGVS notation (subject 1033: EGFR p.L858R, KRAS p.G12C, TP53 p.R273H; subject 1034: KRAS p.G12C; subject 1047: TP53 p.R248Q); a pale grey tile marks a gene tested but not detected. The point is that a set of called variant results has become a tidy, standardized SDTM domain, queryable by subject and gene.

Each azure tile is one GF record — a called variant on a collected specimen. By the end of this lesson you will have built all of them from a raw export and linked each back to its biospecimen.

Note

This is tabulation, not analysis — and that is the whole point. The Bioinformatics pillar teaches the upstream work: aligning reads and calling variants or quantifying expression from sequencing data (RNA-seq, variant calling). This lesson starts where that ends — from a table of already-called findings — and tabulates them downstream into CDISC SDTM for a submission. Call the variants there; tabulate them here. The two never overlap.

What the GF domain is

SDTM sorts every observation into one of three general observation classes, and the class fixes the shape of a record. GF is a Findings domain, so it inherits the Findings shape — one record per test, keyed by a test code:

Observation class What it records Example domains Topic variable
Interventions Things given to or done to the subject CM (con meds), EX (exposure) --TRT
Events Things that happened to the subject AE (adverse events), MH (medical history) --TERM
Findings Measurements and assessments LB (labs), VS (vital signs), GF (genomics) --TESTCD

A genomic finding is a measurement — “was this variant present?”, “what was this gene’s expression?” — so it is a Findings record: the topic variable is a test code (GFTESTCD, “what was tested”), and each row answers “what was tested and what was the result.” That makes GF structurally the same as a lab result; the genomics live in which tests it carries and how the results are coded, not in a new record shape.

The cardinal rule: findings, not raw files

The single idea that governs the whole domain: GF holds called findings, not the raw sequencing data. A finding is a result a lab produced — a variant call, a genotype, a normalized expression value. The FASTQ (raw reads), BAM (aligned reads), and VCF (called-variant) files those results come from are out of SDTM scope; they are archived in specialized genomic data repositories, referenced but not tabulated.

Belongs in GF (a finding) Does not belong in SDTM (raw data)
EGFR p.L858R — detected The BAM alignment the call was made from
KRAS genotype: mutant The VCF file listing every variant
A normalized gene-expression value The FASTQ reads / the RNA-seq count matrix

Why the line matters: SDTM is a tabulation standard a reviewer reads record by record, not a sequence archive. A single whole-genome BAM is gigabytes; a submission dataset holds the handful of called results that actually inform the analysis. Put a variant call in GF; keep the file it came from in the repository the study documents separately.

GF supersedes the deprecated PF domain

If you find older genomics guidance, check the vintage. The current domain is GF; the earlier provisional PF (Pharmacogenomics/Genetics Findings) domain and the whole provisional SDTMIG-PGx v1.0 guide it lived in are deprecated. Per the CDISC Genomics standard, “CDISC strongly recommends use of GF over the previous provisional domain, PF,” and “the provisional SDTMIG-PGx v1.0 has been deprecated.” Build new studies on GF; treat PF only as legacy you may have to read.

The GF variable structure

GF carries the standard Findings-class variables. These roles are the verifiable backbone of the domain — the same pattern as any --TESTCD Findings domain, with a GF prefix:

Variable Role Carries
STUDYID, DOMAIN, USUBJID Identifiers Study, domain code (GF), subject.
GFSEQ Identifier Unique sequence number per record within a subject.
GFREFID / GFSPID Reference IDs Sponsor/specimen reference that links the finding to its biospecimen.
GFTESTCD, GFTEST Topic The short test code and its name — what was tested (e.g. an EGFR mutation test).
GFCAT, GFSCAT Grouping Category / subcategory, e.g. genetic variation vs gene expression.
GFORRES, GFORRESU Result (as collected) The result the lab reported and its unit.
GFSTRESC, GFSTRESN, GFSTRESU Result (standardized) The result in standard character/numeric form and unit.
GFSPEC Specimen The specimen type the finding was measured on (e.g. TUMOR TISSUE).
GFMETHOD, GFNAM Method / lab The assay/method and the lab that ran it.
GFDTC Timing Collection/assessment date in ISO 8601.

Two conventions do the heavy lifting. First, GFTESTCD is the topic — it names the test, and every other column qualifies it. Second, GFTESTCD and GFTEST are controlled terminology: the test code values come from the CDISC subset C181178 — CDISC SDTM Genomic Findings Test Code Terminology and the paired test name values from C181179 — Genomic Findings Test Name, both maintained by NCI EVS (the National Cancer Institute’s Enterprise Vocabulary Services), the same source as all SDTM controlled terminology. (The category groupings GFCAT/GFSCAT are sponsor-defined — they have no published CDISC codelist.) GFTESTCD follows a suffix-fragment convention — a gene/analyte root plus a fragment denoting the kind of measurement — but the authoritative list is C181178. Do not invent a test code and present it as CDISC-official; look it up there first.

Note

GF also defines genomics-specific qualifiers — for the gene, the allele/variant, the reference sequence, and the like — beyond this Findings-class core. Those, and the exact category values, are specified in SDTMIG v3.4. This lesson builds the Findings-class skeleton every GF dataset shares; the variant-level and expression-level detail are the subjects of the next two lessons in this series.

Build a GF domain from a molecular-pathology export

Two inputs drive the build: the raw findings export from the molecular lab, and knowledge of the GF structure to map it into. The lab exports one wide row per gene test — a subject, the specimen it tested, the gene, the called result — in whatever column names its system uses. We build that raw table first. The specimen references (SPEC4.1, SPEC5.1, SPEC6.1) are real biospecimen IDs from the be example data we link to later — three lung-tumour specimens.

library(sdtm.oak)

# A raw genomic-findings export: one row per gene test on a tumour specimen.
# Variants are written in HGVS notation (the Human Genome Variation Society
# standard for naming sequence variants, e.g. p.L858R = protein change at codon 858).
gf_raw <- data.frame(
  SUBJ    = c("01-701-1033","01-701-1033","01-701-1033",
              "01-701-1034","01-701-1034","01-701-1034",
              "01-701-1047","01-701-1047","01-701-1047"),
  SPECREF = c("SPEC4.1","SPEC4.1","SPEC4.1",
              "SPEC5.1","SPEC5.1","SPEC5.1",
              "SPEC6.1","SPEC6.1","SPEC6.1"),
  GENE    = c("EGFR","KRAS","TP53", "EGFR","KRAS","BRAF", "EGFR","KRAS","TP53"),
  VARIANT = c("p.L858R","p.G12C","p.R273H", "Not detected","p.G12C","Not detected",
              "Not detected","Not detected","p.R248Q"),
  RESULT  = c("Detected","Detected","Detected", "Not detected","Detected","Not detected",
              "Not detected","Not detected","Detected"),
  ASSAY   = rep("NGS targeted panel", 9),
  COLLDT  = c("2025-09-10","2025-09-10","2025-09-10",
              "2025-10-05","2025-10-05","2025-10-05",
              "2025-11-01","2025-11-01","2025-11-01"),
  stringsAsFactors = FALSE
)

head(gf_raw)
         SUBJ SPECREF GENE      VARIANT       RESULT              ASSAY
1 01-701-1033 SPEC4.1 EGFR      p.L858R     Detected NGS targeted panel
2 01-701-1033 SPEC4.1 KRAS       p.G12C     Detected NGS targeted panel
3 01-701-1033 SPEC4.1 TP53      p.R273H     Detected NGS targeted panel
4 01-701-1034 SPEC5.1 EGFR Not detected Not detected NGS targeted panel
5 01-701-1034 SPEC5.1 KRAS       p.G12C     Detected NGS targeted panel
6 01-701-1034 SPEC5.1 BRAF Not detected Not detected NGS targeted panel
      COLLDT
1 2025-09-10
2 2025-09-10
3 2025-09-10
4 2025-10-05
5 2025-10-05
6 2025-10-05

Each row is one called finding: a subject, the tumour specimen (SPECREF), the gene tested, the variant in HGVS notation when detected, and the assay. NGS here is next-generation sequencing — but note we already have the called result; the reads are not in this table and never reach SDTM.

Map the raw export to the GF structure

Now fill the GF columns from the raw fields with base R. Identifiers are constant assignments; the topic (GFTESTCD/GFTEST) and result (GFORRES/GFSTRESC) come from the raw gene and result. We build GFTESTCD from the gene following the suffix-fragment convention — and flag it plainly as illustrative, to be verified against C181178, not asserted as an official code.

# GFTESTCD below is ILLUSTRATIVE (gene root + "MUT"), following the GF suffix-fragment
# convention. The authoritative code list is NCI EVS subset C181178 — verify there.
gf <- data.frame(
  STUDYID  = "CDISCPILOT01",
  DOMAIN   = "GF",
  USUBJID  = gf_raw$SUBJ,
  GFREFID  = gf_raw$SPECREF,                            # links to the biospecimen
  GFTESTCD = paste0(gf_raw$GENE, "MUT"),                # illustrative — see C181178
  GFTEST   = paste(gf_raw$GENE, "Mutation"),
  GFCAT    = "GENETIC VARIATION",
  GFORRES  = ifelse(gf_raw$RESULT == "Detected", gf_raw$VARIANT, "Not detected"),
  GFSTRESC = toupper(gf_raw$RESULT),                    # DETECTED / NOT DETECTED
  GFSPEC   = "TUMOR TISSUE",
  GFMETHOD = gf_raw$ASSAY,
  GFDTC    = gf_raw$COLLDT,
  stringsAsFactors = FALSE
)

head(gf[, c("USUBJID", "GFREFID", "GFTESTCD", "GFTEST", "GFCAT")])
      USUBJID GFREFID GFTESTCD        GFTEST             GFCAT
1 01-701-1033 SPEC4.1  EGFRMUT EGFR Mutation GENETIC VARIATION
2 01-701-1033 SPEC4.1  KRASMUT KRAS Mutation GENETIC VARIATION
3 01-701-1033 SPEC4.1  TP53MUT TP53 Mutation GENETIC VARIATION
4 01-701-1034 SPEC5.1  EGFRMUT EGFR Mutation GENETIC VARIATION
5 01-701-1034 SPEC5.1  KRASMUT KRAS Mutation GENETIC VARIATION
6 01-701-1034 SPEC5.1  BRAFMUT BRAF Mutation GENETIC VARIATION

The topic side is in place: one row per gene test, each with a test code, its name, and its category. GFORRES keeps the result as reported (the HGVS variant, or Not detected); GFSTRESC standardizes it to a controlled DETECTED/NOT DETECTED — the split between the collected result and the standardized one that every Findings domain draws.

Number the records with derive_seq

A conformant Findings record needs a sequence number unique within each subject. derive_seq() from sdtm.oak — the pharmaverse raw-to-SDTM engine — orders the rows and numbers them per subject, exactly as it does for AESEQ or VSSEQ.

gf <- derive_seq(gf, tgt_var = "GFSEQ",
                 rec_vars = c("USUBJID", "GFTESTCD"),
                 sbj_vars = "USUBJID")
gf <- as.data.frame(gf)
gf <- gf[, c("STUDYID", "DOMAIN", "USUBJID", "GFSEQ", "GFREFID", "GFTESTCD",
             "GFTEST", "GFCAT", "GFORRES", "GFSTRESC", "GFSPEC", "GFMETHOD", "GFDTC")]

head(gf[, c("USUBJID", "GFSEQ", "GFTESTCD", "GFORRES", "GFSTRESC", "GFSPEC")])
      USUBJID GFSEQ GFTESTCD      GFORRES     GFSTRESC       GFSPEC
1 01-701-1033     1  EGFRMUT      p.L858R     DETECTED TUMOR TISSUE
2 01-701-1033     2  KRASMUT       p.G12C     DETECTED TUMOR TISSUE
3 01-701-1033     3  TP53MUT      p.R273H     DETECTED TUMOR TISSUE
4 01-701-1034     1  BRAFMUT Not detected NOT DETECTED TUMOR TISSUE
5 01-701-1034     2  EGFRMUT Not detected NOT DETECTED TUMOR TISSUE
6 01-701-1034     3  KRASMUT       p.G12C     DETECTED TUMOR TISSUE

That is a conformant GF skeleton: identifiers, a per-subject GFSEQ, the topic test code, and the collected + standardized results, each tied to a TUMOR TISSUE specimen. A quick structural check confirms the contract:

cat("one domain code:            ", length(unique(gf$DOMAIN)) == 1, "\n")
one domain code:             TRUE 
cat("GFSEQ unique within subject:", !any(duplicated(gf[c("USUBJID", "GFSEQ")])), "\n")
GFSEQ unique within subject: TRUE 
cat("every finding has a specimen:", all(nchar(gf$GFREFID) > 0), "\n")
every finding has a specimen: TRUE 

Three TRUEs — structurally sound. In production a conformance tool (Pinnacle 21) runs the full rule set a regulator would; here the point is that a GF domain is an ordinary Findings build, once the findings are called.

Common issues

You try to load a VCF or BAM file into SDTM and nothing fits. It never will — raw and aligned sequence files (FASTQ/BAM/VCF) are out of SDTM scope. GF tabulates the called finding (the variant, the genotype, the expression value), not the file it came from. Extract the called results into GF rows; archive the sequence files in the study’s specialized genomic repository and reference them, don’t tabulate them.

You coin a GFTESTCD like EGFRMUT and treat it as CDISC-official. The controlled terminology for GFTESTCD/GFTEST is the CDISC subset C181178 maintained by NCI EVS. A code you invented to follow the suffix-fragment convention is a placeholder until you confirm it there — never present an unverified code as standard. When no published code fits, that is a controlled-terminology question for your standards team, not a value to make up.

You build GF and forget the specimen link. A finding with no traceable specimen is not auditable. Populate GFREFID/GFSPID so each GF record points at a biospecimen in BE/BS/RELSPEC, and document the relationship in RELREC. If you cannot say which physical sample a variant was called from, the domain is incomplete.

You start from the old PF domain. PF (Pharmacogenomics/Genetics Findings) and the SDTMIG-PGx v1.0 guide are deprecated. Map new genomic data to GF (SDTMIG v3.4); only read PF when handling legacy studies.

Frequently asked questions

The GF (Genomics Findings) domain is the CDISC SDTM Findings-class domain that tabulates pharmacogenomic findings — DNA variants and gene-expression measures — from a clinical trial. Each record is one genomic test on a specimen, keyed by the test code GFTESTCD, with a result (GFORRES/GFSTRESC), a specimen type (GFSPEC), a method, and a link back to the biospecimen. It is published in SDTMIG v3.4 and is where genomic results enter a regulatory submission.

No. SDTM — and the GF domain specifically — stores the called findings (a variant, a genotype, an expression value), never the raw FASTQ/BAM/VCF sequence files. Those files are out of SDTM scope; they are archived in specialized genomic data repositories and referenced from the study, while GF carries only the tabulated results a reviewer reads record by record.

PF (Pharmacogenomics/Genetics Findings) was a provisional genomics domain in the now-deprecated SDTMIG-PGx v1.0 guide. GF (Genomics Findings) replaces it in SDTMIG v3.4: per CDISC, “CDISC strongly recommends use of GF over the previous provisional domain, PF.” Build new studies on GF; treat PF as legacy content you may need to read but should not author.

Through the biospecimen domainsBE (Biospecimen Events), BS (Biospecimen Findings), and RELSPEC (Related Specimens) — which track the physical sample. A GF record carries a specimen reference (GFREFID/GFSPID) that matches a specimen in BE, and the relationship is formally documented in RELREC. That chain makes every genomic finding traceable to the specimen it was called from, which is what makes it auditable in a submission.

From CDISC controlled terminology, maintained by NCI EVS: the subset C181178 — CDISC SDTM Genomic Findings Test Code Terminology. GFTESTCD follows a suffix-fragment convention (a gene/analyte root plus a fragment for the measurement type), but the allowed values are governed by C181178 — look a code up there rather than inventing one and treating it as standard.

Test your understanding

The build above tabulated DNA variant findings (GFCAT = "GENETIC VARIATION"). Suppose the same tumour specimens were also assayed for PDL1 gene expression, reported as a normalized numeric value. Sketch how a GF row for that finding differs from a variant row: which GFCAT would it carry, and which result variables would hold a numeric expression value?

Expression is a number, not a detected/not-detected call — so the standardized result is numeric, not character. GF separates the category of finding (variant vs expression) with GFCAT, and it has both a character result variable and a numeric one.

A gene-expression finding is still a Findings record, but:

  • GFCAT becomes "GENE EXPRESSION" (instead of "GENETIC VARIATION").
  • The result goes in the numeric standardized variable GFSTRESN (with a unit in GFSTRESU), because expression is a measured value — whereas a variant call used the character GFSTRESC (DETECTED/NOT DETECTED).
  • GFTESTCD/GFTEST name the expression test (e.g. a PDL1 expression test), verified against C181178, and GFSPEC/GFREFID/GFMETHOD still tie it to the specimen and assay.

Same domain, same Findings shape — a different GFCAT and the numeric result variables carry the value. The variant-level and expression-level detail are the next two lessons in this series.

A. The BAM file of aligned sequencing reads for a subject’s tumour B. The called variant KRAS p.G12C, detected on a tumour specimen C. The raw FASTQ reads from the sequencer

B. GF tabulates called findings — a variant call like KRAS p.G12C is exactly that, and it becomes a GF record on the specimen it was called from. A and C are raw/aligned sequence files (BAM, FASTQ), which are out of SDTM scope — archived in a specialized genomic repository and referenced, never tabulated into SDTM.

Conclusion

The GF domain makes genomic results submission-ready by treating them as what they are: Findings. Tabulate the called result — the variant, the genotype, the expression value — one record per test, keyed by GFTESTCD with controlled terminology from C181178; keep the raw FASTQ/BAM/VCF files out of SDTM; and link every finding to its specimen through the biospecimen domains BE/BS/RELSPEC. That is the whole foundation. The next two lessons in this series go deep on the two kinds of finding — DNA variants and gene expression — but each is the same Findings build you just ran, with richer genomics-specific qualifiers.

Note

This lesson is reproducible: every result on this page was produced by the code shown — copy any block and run it to reproduce them. The runtime is the judge.

Reuse

Citation

BibTeX citation:
@online{2026,
  author = {},
  title = {SDTM {Genomics} {Findings} {(GF)} {Domain:} {Tabulate}
    {Pharmacogenomic} {Findings} for {CDISC}},
  date = {2026-07-01},
  url = {https://www.datanovia.com/learn/pharma-clinical/02-sdtm-programming/genomics-findings-gf-domain},
  langid = {en}
}
For attribution, please cite this work as:
“SDTM Genomics Findings (GF) Domain: Tabulate Pharmacogenomic Findings for CDISC.” 2026. July 1. https://www.datanovia.com/learn/pharma-clinical/02-sdtm-programming/genomics-findings-gf-domain.