Bases: ColocalisationMethodInterface
eCAVIAR-based colocalisation analysis.
It extends CAVIAR framework to explicitly estimate the posterior probability
that the same variant is causal in 2 studies while accounting for the uncertainty of LD.
eCAVIAR computes the colocalization posterior probability (CLPP) by utilizing the marginal posterior probabilities.
This framework allows for multiple variants to be causal in a single locus.
Source code in src/gentropy/method/colocalisation/ecaviar.py
19
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
52
53
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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113 | class ECaviar(ColocalisationMethodInterface):
"""eCAVIAR-based colocalisation analysis.
It extends [CAVIAR](https://www.ncbi.nlm.nih.gov/pmc/articles/PMC5142122/#bib18) framework to explicitly estimate the posterior probability
that the same variant is causal in 2 studies while accounting for the uncertainty of LD.
eCAVIAR computes the colocalization posterior probability (**CLPP**) by utilizing the marginal posterior probabilities.
This framework allows for **multiple variants to be causal** in a single locus.
"""
METHOD_NAME: str = "eCAVIAR"
METHOD_METRICS: list[str] = ["clpp"]
@classmethod
def colocalise(
cls: type[ECaviar],
overlapping_signals: StudyLocusOverlap,
**kwargs: Any,
) -> Colocalisation:
"""Calculate bayesian colocalisation based on overlapping signals.
Args:
overlapping_signals (StudyLocusOverlap): overlapping signals.
**kwargs (Any): Additional parameters passed to the colocalise method.
Currently not used for this method.
Returns:
Colocalisation: colocalisation results based on eCAVIAR.
"""
return Colocalisation(
_df=(
overlapping_signals.df.withColumns(
{
"clpp": ECaviar._get_clpp(
f.col("statistics.left_posteriorProbability"),
f.col("statistics.right_posteriorProbability"),
),
"tagVariantSource": cls.get_tag_variant_source(
f.col("statistics")
),
}
)
.groupBy(
"leftStudyLocusId",
"rightStudyLocusId",
"rightStudyType",
"chromosome",
)
.agg(
# Count the number of tag variants that can be found in both loci:
f.sum(
f.when(f.col("tagVariantSource") == "both", 1).otherwise(0)
)
.cast(t.LongType())
.alias("numberColocalisingVariants"),
f.sum(f.col("clpp")).alias("clpp"),
)
.withColumn("colocalisationMethod", f.lit(cls.METHOD_NAME))
.join(
overlapping_signals.calculate_beta_ratio(),
on=["leftStudyLocusId", "rightStudyLocusId", "chromosome"],
how="left",
)
),
_schema=Colocalisation.get_schema(),
)
@staticmethod
def _get_clpp(left_pp: Column, right_pp: Column) -> Column:
"""Calculate the colocalisation posterior probability (CLPP).
If the fact that the same variant is found causal for two studies are independent events,
CLPP is defined as the product of posterior porbabilities that a variant is causal in both studies.
Args:
left_pp (Column): left posterior probability
right_pp (Column): right posterior probability
Returns:
Column: CLPP
Examples:
>>> d = [{"left_pp": 0.5, "right_pp": 0.5}, {"left_pp": 0.25, "right_pp": 0.75}]
>>> df = spark.createDataFrame(d)
>>> df.withColumn("clpp", ECaviar._get_clpp(f.col("left_pp"), f.col("right_pp"))).show()
+-------+--------+------+
|left_pp|right_pp| clpp|
+-------+--------+------+
| 0.5| 0.5| 0.25|
| 0.25| 0.75|0.1875|
+-------+--------+------+
<BLANKLINE>
"""
return left_pp * right_pp
|
colocalise(overlapping_signals: StudyLocusOverlap, **kwargs: Any) -> Colocalisation
classmethod
Calculate bayesian colocalisation based on overlapping signals.
Parameters:
| Name |
Type |
Description |
Default |
overlapping_signals
|
StudyLocusOverlap
|
|
required
|
**kwargs
|
Any
|
Additional parameters passed to the colocalise method.
Currently not used for this method.
|
{}
|
Returns:
| Name | Type |
Description |
Colocalisation |
Colocalisation
|
colocalisation results based on eCAVIAR.
|
Source code in src/gentropy/method/colocalisation/ecaviar.py
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
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 | @classmethod
def colocalise(
cls: type[ECaviar],
overlapping_signals: StudyLocusOverlap,
**kwargs: Any,
) -> Colocalisation:
"""Calculate bayesian colocalisation based on overlapping signals.
Args:
overlapping_signals (StudyLocusOverlap): overlapping signals.
**kwargs (Any): Additional parameters passed to the colocalise method.
Currently not used for this method.
Returns:
Colocalisation: colocalisation results based on eCAVIAR.
"""
return Colocalisation(
_df=(
overlapping_signals.df.withColumns(
{
"clpp": ECaviar._get_clpp(
f.col("statistics.left_posteriorProbability"),
f.col("statistics.right_posteriorProbability"),
),
"tagVariantSource": cls.get_tag_variant_source(
f.col("statistics")
),
}
)
.groupBy(
"leftStudyLocusId",
"rightStudyLocusId",
"rightStudyType",
"chromosome",
)
.agg(
# Count the number of tag variants that can be found in both loci:
f.sum(
f.when(f.col("tagVariantSource") == "both", 1).otherwise(0)
)
.cast(t.LongType())
.alias("numberColocalisingVariants"),
f.sum(f.col("clpp")).alias("clpp"),
)
.withColumn("colocalisationMethod", f.lit(cls.METHOD_NAME))
.join(
overlapping_signals.calculate_beta_ratio(),
on=["leftStudyLocusId", "rightStudyLocusId", "chromosome"],
how="left",
)
),
_schema=Colocalisation.get_schema(),
)
|