Data model
The unit of data in torchcell is the experiment record: one genotype, grown in one
environment, observed to have one phenotype, paired with the reference it is measured
against and the publication it came from. The models live in
torchcell/datamodels/schema.py. They are pydantic models built on ModelStrict
(torchcell/datamodels/pydant.py), which forbids extra fields and freezes instances, so
a record either validates completely or is rejected.
An interactive view of the class hierarchy, generated from the live models at build time, is the ontology explorer.
The experiment record
Experiment
experiment_type str key into EXPERIMENT_TYPE_MAP ("fitness", "gene interaction", ...)
dataset_name str the loader class that produced it, e.g. "SmfCostanzo2016Dataset"
genotype Genotype what was changed in the strain
environment Environment what the strain was grown in
phenotype Phenotype what was measured
ExperimentReference
experiment_reference_type str
dataset_name str
genome_reference ReferenceGenome species, strain, ploidy
environment_reference Environment
phenotype_reference Phenotype the reference value (e.g. wild-type fitness 1.0)
Publication
pubmed_id, pubmed_url, doi, doi_url at least one id and one URL are required
Each experiment type pairs a subclass of Experiment with a subclass of
ExperimentReference that narrows phenotype to one phenotype class, for example
FitnessExperiment and FitnessExperimentReference with FitnessPhenotype. Two
dictionaries at the end of schema.py, EXPERIMENT_TYPE_MAP and
EXPERIMENT_REFERENCE_TYPE_MAP, map the experiment_type string to the class; every
reader that deserializes a record (the dataset loaders, Neo4jQueryRaw, the converters)
dispatches through them.
Genotype
Genotype.perturbations is a list of gene perturbations, sorted on validation by
(systematic_gene_name, perturbation_type, perturbed_gene_name) so that equal genotypes
serialize identically. Every perturbation extends GenePerturbation:
systematic_gene_name: validated against the S288C naming patterns (coding genes such asYAL001C, mitochondrialQ0010-style names, noncodingYNC...genes).perturbed_gene_name: the allele or common name, such astfc3_damp.provenance:"engineered"(made in the lab) or"natural"(found in an isolate).
The concrete perturbation classes are organized by what they change relative to the
reference genome: presence or absence of a gene (deletions, marker deletions, gene
additions, natural gene absence and presence), sequence-level alleles (DAmP,
temperature-sensitive, suppressor and sequence-variant alleles), copy number (natural
CNVs and engineered copy number), and expression modulation (CRISPRa and CRISPRi). Each
names its mechanism with a Sequence Ontology term (mechanism_so_id,
mechanism_so_name).
Environment
Environment holds a media (a Media resolved into typed components, with name,
state and is_synthetic), an optional temperature, a list of environment
perturbations (added small molecules, physical factors, biologic agents), an
aerobicity, and optional duration_hours and duration_generations.
Phenotype
Phenotype is the base class of every measured label. It carries three fields that
describe the label rather than its value:
graph_level: where the label sits on a gene graph. Validated againstedge,node,hyperedge,subgraph,global,metabolismandgene ontology.label_name: the name of the field that holds the value. A validator checks that the concrete class declares that field.label_statistic_name: the name of the field holding its uncertainty or confidence statistic, orNone.
Numeric phenotypes record their uncertainty with its kind: FitnessPhenotype, for
example, stores the source-reported number in fitness_uncertainty, names it with
fitness_uncertainty_type (an UncertaintyType: sample_sd, standard_error,
bootstrap_se, variance, ci95), records the replicate design in n_samples and
sample_unit, and derives the standard error fitness_se from those when it is not
supplied (a bootstrap SE is used as is; a sample SD is divided by the square root of
n_samples). A value the
source does not report is declared as a typed ProvenanceGap in provenance_gaps, and
the field itself must then be None.
Phenotype classes
The defaults below were read from each class’s model_fields in schema.py.
graph_level is a default, and a loader may set another value (the digenic-interaction
datasets store GeneInteractionPhenotype records at edge, the trigenic ones at
hyperedge).
Phenotype class |
Value field ( |
Value type |
|
|
|---|---|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
schema.py also defines SyntheticRescuePhenotype (is_synthetic_rescue, edge), and
EXPERIMENT_TYPE_MAP has a fourteenth entry, segregant_growth, whose experiment pairs a
SegregantGenotype (a haplotype mosaic of two parent assemblies) with an
EnvironmentResponsePhenotype.
Verification levels
Built datasets are checked record by record against five ordered levels, defined as
Level in torchcell/verification/report.py and implemented as reusable checks in
torchcell/verification/levels.py:
Level |
Name |
Checks |
|---|---|---|
L0 |
structural |
every record instantiates its schema model |
L1 |
completeness |
record counts, known keys and contiguity against an oracle |
L2 |
value fidelity |
cross-method agreement, types, ranges, no NaN |
L3 |
semantic |
units and conventions (fitness as mutant over wild type; log2 of sample over reference) |
L4 |
cross-source consistency |
entities that two sources share agree |
Each check returns a LevelResult; a per-dataset verifier (for example
torchcell/verification/morphology.py) assembles them into a VerificationReport
together with a Provenance record of the source.
Provenance of hand-entered values
A constant that a loader cannot read from a data column (a replicate count, the kind of
an uncertainty, a strain background) is stored as a SourcedValue
(torchcell/verification/sourced.py): the value, a Provenance naming the source file
by citation key and sha256, and a verbatim quote from that file that justifies it.