Skip to content

Specimens

Specimen

Bases: BaseModel

Store a single specimen specimen.

Parameters:

Name Type Description Default
id str

unique ID

required
genome str

genome

required
is_mutant bool

is this a mutant?

required
mass float

mass (g)

required
Source code in src/snailz/specimens.py
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
class Specimen(BaseModel):
    """Store a single specimen specimen."""

    id: str = Field(description="unique ID")
    genome: str = Field(min_length=1, description="genome")
    is_mutant: bool = Field(description="is this a mutant?")
    mass: float = Field(gt=0, description="mass (g)")

    _id_generator: ClassVar = generic_id_generator(lambda i: f"S{i:04d}")

    @staticmethod
    def generate(params, ref_genome, is_mutant, susc_locus, susc_base):
        """Generate a single specimen."""

        genome = [
            random.choice(OTHERS[b])
            if random.uniform(0.0, 1.0) < params.mut_prob
            else b
            for i, b in enumerate(ref_genome)
        ]
        mass = abs(random.gauss(params.mass_mean, params.mass_sd))

        if is_mutant:
            genome[susc_locus] = susc_base
            mass *= params.mut_mass_scale

        return Specimen(
            id=next(Specimen._id_generator),
            genome="".join(genome),
            is_mutant=is_mutant,
            mass=mass,
        )

generate(params, ref_genome, is_mutant, susc_locus, susc_base) staticmethod

Generate a single specimen.

Source code in src/snailz/specimens.py
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
@staticmethod
def generate(params, ref_genome, is_mutant, susc_locus, susc_base):
    """Generate a single specimen."""

    genome = [
        random.choice(OTHERS[b])
        if random.uniform(0.0, 1.0) < params.mut_prob
        else b
        for i, b in enumerate(ref_genome)
    ]
    mass = abs(random.gauss(params.mass_mean, params.mass_sd))

    if is_mutant:
        genome[susc_locus] = susc_base
        mass *= params.mut_mass_scale

    return Specimen(
        id=next(Specimen._id_generator),
        genome="".join(genome),
        is_mutant=is_mutant,
        mass=mass,
    )

AllSpecimens

Bases: BaseModel

Store a set of specimens.

Parameters:

Name Type Description Default
params SpecimenParams

generation parameters

required
ref_genome str

reference genome

required
susc_locus int

susceptible locus

required
susc_base str

susceptible mutation

required
samples list[Specimen]

specimens

required
Source code in src/snailz/specimens.py
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
class AllSpecimens(BaseModel):
    """Store a set of specimens."""

    params: SpecimenParams = Field(description="generation parameters")
    ref_genome: str = Field(description="reference genome")
    susc_locus: int = Field(description="susceptible locus")
    susc_base: str = Field(description="susceptible mutation")
    samples: list[Specimen] = Field(description="specimens")

    @staticmethod
    def generate(params, num):
        """Generate specimens."""

        if num <= 0:
            raise ValueError(f"invalid number of specimens {num}")

        ref_genome = "".join(random.choices(BASES, k=params.genome_length))
        susc_locus = random.choice(list(range(len(ref_genome))))
        susc_base = random.choice(OTHERS[ref_genome[susc_locus]])

        mutant_ids = set(
            random.choices(list(range(num)), k=math.ceil(params.mut_frac * num))
        )

        samples = [
            Specimen.generate(
                params, ref_genome, i in mutant_ids, susc_locus, susc_base
            )
            for i in range(num)
        ]

        return AllSpecimens(
            params=params,
            ref_genome=ref_genome,
            susc_locus=susc_locus,
            susc_base=susc_base,
            samples=samples,
        )

    def to_csv(self, writer):
        """Save specimens as CSV."""
        writer.writerow(["id", "genome", "mass"])
        writer.writerows(
            [s.id, s.genome, round(s.mass, PRECISION)] for s in self.samples
        )

generate(params, num) staticmethod

Generate specimens.

Source code in src/snailz/specimens.py
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
@staticmethod
def generate(params, num):
    """Generate specimens."""

    if num <= 0:
        raise ValueError(f"invalid number of specimens {num}")

    ref_genome = "".join(random.choices(BASES, k=params.genome_length))
    susc_locus = random.choice(list(range(len(ref_genome))))
    susc_base = random.choice(OTHERS[ref_genome[susc_locus]])

    mutant_ids = set(
        random.choices(list(range(num)), k=math.ceil(params.mut_frac * num))
    )

    samples = [
        Specimen.generate(
            params, ref_genome, i in mutant_ids, susc_locus, susc_base
        )
        for i in range(num)
    ]

    return AllSpecimens(
        params=params,
        ref_genome=ref_genome,
        susc_locus=susc_locus,
        susc_base=susc_base,
        samples=samples,
    )

to_csv(writer)

Save specimens as CSV.

Source code in src/snailz/specimens.py
93
94
95
96
97
98
def to_csv(self, writer):
    """Save specimens as CSV."""
    writer.writerow(["id", "genome", "mass"])
    writer.writerows(
        [s.id, s.genome, round(s.mass, PRECISION)] for s in self.samples
    )