Designing an environment
Walk through a real PK/PD study schema in mice.
Designing the schema for a study is the highest-leverage hour you'll spend in Dalea. A schema that captures the right entities and relationships will let you ask arbitrary analytical questions for the next decade. A schema that doesn't will leave you exporting CSVs and joining things in Pandas forever.
This page walks through the schema for a realistic mouse PK/PD study end to end.
The study
A 24-mouse single-dose PK study of a small-molecule kinase inhibitor (test article DLA-7) in C57BL/6 females. Three dose groups (3, 10, 30 mg/kg PO) plus vehicle. Plasma collected at 15 min, 1 h, 4 h, 24 h. Analyte is parent compound by LC-MS/MS.
The schema
Four entity tables and one result table:
Step-by-step
- Create the environmentWorkspace → Data → New environment
The dialog asks for three things: a name (
In-vivo PK), an icon, and an optional description of what the environment is for. Everything else, tables, columns and references, is added afterwards in the designer. - Add the test articles table
The most upstream entity. Give the table the record-name pattern
TA-{###}, so each row is stamped TA-001, TA-002 and so on. Columns:name(text, flagged Record label)modality(enum: small-molecule, mAb, ASO, peptide, mRNA…)lot(text)
- Add the study groups table
Bridges test article to dose level. Record-name pattern
GRP-{###}.name(text — "Vehicle", "DLA-7 3 mg/kg", …)dose(number, unitmg/kg)route(enum: PO, IV, IP, SC)test_article(reference → test articles)
- Add the animals table
The actual subjects. Record-name pattern
ANM-{###}, giving ANM-001, ANM-002 and so on.sex(enum: M, F)strain(enum: C57BL/6, BALB/c, NSG…)baseline_weight(number, unitg, validation: 15–35)study_group(reference → study groups)
Note the validation: weights outside 15–35 g flag during entry — almost certainly a typo for an adult mouse.
- Add the plasma samples table
One row per timepoint per animal. Record-name pattern
SMP-{####}.animal(reference → animals)timepoint(number, unith, min 0)collected_at(datetime)
- Add the PK results result table
The shape is different: a result table splits into dimensions and measurements.
- Dimensions:
animal(ref),timepoint(number, unith) - Measurements:
concentration(number, unitug/mL),auc_0_24(number, unitug.h/mL),cmax(number, unitug/mL),tmax(number, unith)
Dimensions are what you'll group/filter by in queries. Measurements are the values you'll aggregate. The unit is a property of each number column (pick it in the designer, any spelling such as µg/mL is accepted), never part of the name and never a separate text column: cells, charts and query results then render it for you, and compatible input such as
0.5 mg/mLconverts on entry. - Dimensions:
Why a result table — couldn't this be one big entity table?
It could. But result tables get two things for free:
- Batched recording. All four timepoints from one animal-day fit in one result batch, which carries a single operator, timestamp and origin.
- Analytical aggregation. You can ask "mean concentration grouped by dose level" without writing SQL: a query rooted at the animals table hops into the result schema and collapses its measurements per group. The dimension/measurement split is what makes that possible.
Record-name patterns recap
| Table | Pattern | Generates |
|---|---|---|
| Test articles | TA-{###} | TA-001, TA-002, … |
| Study groups | GRP-{###} | GRP-001, GRP-002, … |
| Animals | ANM-{###} | ANM-001, ANM-002, … |
| Samples | SMP-{####} | SMP-0001, SMP-0002, … |
A pattern is literal text plus tokens. The tokens are {###} or {0001} for a
zero-padded counter (the width is the number of characters inside the braces),
{A} / {AA} for an alphabetic counter, {uuid} or {uuid:8} for a random hex
fragment, and {column_name} to interpolate one of the table's own columns.
There is no date token, so a year has to come from a real column, as in
{collection_year}-{study}-{###}.
Patterns are set per table in the designer. The counter lives on the table and advances once per row; on project- or entry-scoped tables each scope keeps its own counter, so numbering restarts per study.
Tracking the physical stock
The schema above records what you measured. If you also need to track the vials themselves, how much is left in each and which freezer they sit in, add an inventory table to this same environment. It is a third table kind alongside entity and result tables, and it links back to a catalog table like Test Articles so eleven vials resolve to one compound.
See designing item types.