Endometrial cancer (EC)¶
The built-in process EC simulates endometrial lesions and cancer.
This tutorial will give a parameter-by-parameter explanation to illustrate how the process works.
15# EC process
16ec = processes.EC(
17 name="ec",
18 hazard=processes.ec.data.us.hazard,
19 age_factors=processes.ec.data.us.age_factors,
20 dwell_hyperplasia=processes.ec.data.us.dwell_hyperplasia,
21 dwell_preclinical=processes.ec.data.us.dwell_preclinical,
22 cure=processes.ec.data.us.cure,
23 time_to_death=processes.ec.data.us.time_to_death,
24 onset_method="before_oc"
25)
Hazard¶
All individuals develop at most 1 lesion: either with or without atypia.
For each individual, two individual-level relative hazard ratios are drawn from an exponential distribution: one for
a lesion with atypia, and one without atypia.
The parameter hazard requires the mean hazard ratio for this exponential distribution.
This hazard can be interpreted as the individual-specific propensity to develop a lesion.
It doesn’t change throughout a simulated life history.
hazard = 30.
Age factors¶
The parameter age_factors requires a sequence with age factors determining the age of each onset.
This parameter is used to construct a PiecewiseLinear instance.
Together with the individual hazard, the age-specific risk factor determines the onset of lesions and can be considered
as the hazard function.
As such, the age-specific risk factor usually increases as age increases.
Age factors only determine the onset of lesions, and not the transition of diseases to further states.
Note that the EC process takes age factors for lesions with and without atypia separately.
age_factors = {
"without_atypia": [
(0, 0.0),
(30, 0.0000088 * 6.142857143),
(40, 0.000455 * 6.142857143),
(50, 0.000667 * 6.142857143),
(60, 0.004254 * 6.142857143),
(70, 0.000625 * 6.142857143),
(80, 0.8 * 6.142857143),
(100, 0.8 * 6.142857143),
],
"with_atypia": [
(0, 0.0),
(30, 0.0000088),
(40, 0.000455),
(50, 0.000667),
(60, 0.004254),
(70, 0.000625),
(80, 0.8),
(100, 0.8),
]
}
Onset method¶
All individuals develop at most 1 hyperplastic lesion: either with or without atypia.
For both types, an onset age is determined based on the hazard and the age_factors.
Then, which type the individual develops depends on the onset_method that is passed to the
EC process.
If the onset method is first, individuals will get the lesion for which the age of onset comes first.
If the onset method is before_oc, individuals will always get a lesion without atypia, except if the onset age of
the lesion without atypia is after that person would die from other causes (oc_death).
Note that the passed onset_method should therefore be specified as first or before_oc.
onset_method = "before_oc"
Dwell hyperplasia¶
Hyperplastic lesions may progress to preclinical cancer.
A preclinical cancer is a cancer which does not give clinical symptoms yet.
The dwell time from onset until the transition to preclinical cancer is drawn from a Weibull distribution.
The mean and shape of this Weibull distribution must be specified in dwell_hyperplasia.
Note that this distribution may be different for lesions with and without hyperplasia.
dwell_hyperplasia = {
"without_atypia": {"shape": .75, "mean": 114.40339},
"with_atypia": {"shape": .75, "mean": 7.766915},
}
Dwell preclinical¶
Preclinical cancers may start showing clinical symptoms and be detected.
In the model, these lesions progress to a clinical cancer.
The dwell time of the preclinical phase is also drawn from a Weibull distribution.
The mean and shape of this Weibull distribution must be specified in dwell_preclinical.
Here the model does not distinguish between lesions with and without atypia.
dwell_preclinical = {"shape": .75, "mean": 5.}
Cure¶
Once a lesion becomes clinical, the model determines whether the cancer is cured based on the cure parameter.
This parameter specifies the probability to cure for a specific age of clinical detection.
The data is used to construct a PiecewiseLinear instance.
cure = [
(0, 0.780),
(20, 0.780),
(20, 0.811),
(25, 0.811),
(25, 0.873),
(30, 0.873),
(30, 0.845),
(35, 0.845),
(35, 0.815),
(40, 0.815),
(40, 0.817),
(45, 0.817),
(45, 0.812),
(50, 0.812),
(50, 0.833),
(55, 0.833),
(55, 0.831),
(60, 0.831),
(60, 0.806),
(65, 0.806),
(65, 0.761),
(70, 0.761),
(70, 0.712),
(75, 0.712),
(75, 0.661),
(80, 0.661),
(80, 0.442),
(100, 0.442),
]
Time to Death¶
If the cancer is not cured, the model determines a time until the person dies from endometrial cancer.
The time_to_death parameter is data for a PiecewiseLinear function.
The model draws a random number and plugs this into the time_to_death function to determine the number of years
the woman still lives.
time_to_death = [
(0.000000000, 0),
(0.309278351, 1),
(0.515463918, 2),
(0.659793814, 3),
(0.752577320, 4),
(0.804123711, 5),
(0.840206186, 6),
(0.865979381, 7),
(0.891752577, 8),
(0.912371134, 9),
(0.927835052, 10),
(0.927835052, 11),
(0.927835052, 12),
(0.927835052, 13),
(0.938144330, 14),
(0.948453608, 15),
(0.963917526, 16),
(0.963917526, 17),
(0.963917526, 18),
(0.974226804, 19),
(1.000000000, 20),
]
Name¶
The parameter name requires a string that contains the name of the process.
It defaults to ‘ec’.
name = "ec"
Example code¶
Below is an example script using the built-in process EC.
1from miscore import Model, processes, Universe
2
3# Birth process
4birth = processes.Birth(
5 name="birth",
6 year=1938
7)
8
9# OC process
10oc = processes.OC(
11 name="oc",
12 life_table=processes.oc.data.us_2017.life_table_female
13)
14
15# EC process
16ec = processes.EC(
17 name="ec",
18 hazard=processes.ec.data.us.hazard,
19 age_factors=processes.ec.data.us.age_factors,
20 dwell_hyperplasia=processes.ec.data.us.dwell_hyperplasia,
21 dwell_preclinical=processes.ec.data.us.dwell_preclinical,
22 cure=processes.ec.data.us.cure,
23 time_to_death=processes.ec.data.us.time_to_death,
24 onset_method="before_oc"
25)
26
27# Universes
28no_screening = Universe(
29 name="no_screening",
30 processes=[
31 birth,
32 oc,
33 ec
34 ]
35)
36
37# Model
38model = Model(
39 universes=[
40 no_screening
41 ]
42)
43
44# Run model
45result = model.run(
46 n=1e5,
47 seeds_properties={
48 "birth": 1646,
49 "oc": 9321,
50 "ec": 4841
51 },
52 seeds_properties_tmp={
53 "ec": 8010
54 },
55 event_ages=range(40, 101, 1),
56 event_years=range(1938, 2039, 1),
57 duration_ages=range(40, 101, 1),
58 duration_years=range(1938, 2039, 1),
59 verbose=True
60)
61
62# Export
63result.events.to_csv("events.csv")
64result.durations.to_csv("durations.csv")