1
- from typing import Union , List , Dict
1
+ from typing import Union , List , Dict , Optional
2
2
from phenex .phenotypes .phenotype import Phenotype
3
+ from phenex .filters .value import Value
3
4
from phenex .filters .codelist_filter import CodelistFilter
4
5
from phenex .filters .relative_time_range_filter import RelativeTimeRangeFilter
5
6
from phenex .filters .date_range_filter import DateRangeFilter
@@ -32,30 +33,72 @@ class ContinuousCoveragePhenotype(Phenotype):
32
33
>>> phenotype = ContinuousCoveragePhenotype(coverage_period_min=coverage_min_filter)
33
34
"""
34
35
35
- def __init__ (self , domain , start_date , end_date , gap_days = 30 , name = None ):
36
+ def __init__ (self ,
37
+ name :Optional [str ] = 'continuous_coverage' ,
38
+ domain :Optional [str ] = 'OBSERVATION_PERIOD' ,
39
+ relative_time_range :Optional [RelativeTimeRangeFilter ] = None ,
40
+ min_days : Optional [Value ] = None ,
41
+ anchor_phenotype :Optional [Phenotype ] = None ,
42
+ ):
36
43
super ().__init__ ()
44
+ self .name = name
37
45
self .domain = domain
38
- self .start_date = start_date
39
- self .end_date = end_date
40
- self .gap_days = gap_days
41
- self .name = name or f"ContinuousCoverage_{ domain } "
46
+ self .relative_time_range = relative_time_range
47
+ self .min_days = min_days
42
48
43
49
def _execute (self , tables : Dict [str , Table ]) -> PhenotypeTable :
44
50
coverage_table = tables [self .domain ]
51
+ # first perform time range filter on observation period start date
52
+ coverage_table = coverage_table .mutate (EVENT_DATE = coverage_table .OBSERVATION_PERIOD_START_DATE )
53
+ coverage_table = self ._perform_time_filtering (coverage_table )
54
+ # ensure that coverage end extends past the anchor date
55
+ coverage_table = self ._filter_observation_period_end (coverage_table )
45
56
coverage_table = self ._filter_coverage_period (coverage_table )
46
- coverage_table = self ._check_continuous_coverage (coverage_table )
47
- return select_phenotype_columns (coverage_table )
57
+ return coverage_table
58
+
59
+ def _perform_time_filtering (self , coverage_table ):
60
+ '''
61
+ Filter the observation period start
62
+ '''
63
+ if self .relative_time_range is not None :
64
+ coverage_table = self .relative_time_range .filter (coverage_table )
65
+ return coverage_table
66
+
67
+ def _filter_observation_period_end (self , coverage_table ):
68
+ '''
69
+ Get only rows where the observation period end date is after the anchor date
70
+ '''
71
+ if self .relative_time_range is not None :
72
+ if self .relative_time_range .anchor_phenotype is not None :
73
+ reference_column = self .relative_time_range .anchor_phenotype .table .EVENT_DATE
74
+ else :
75
+ reference_column = coverage_table .INDEX_DATE
76
+
77
+ coverage_table = coverage_table .filter (
78
+ coverage_table .OBSERVATION_PERIOD_END_DATE >= reference_column
79
+ )
80
+ return coverage_table
81
+
48
82
49
83
def _filter_coverage_period (self , coverage_table : Table ) -> Table :
50
- return coverage_table .filter (
51
- (coverage_table ['COVERAGE_START_DATE' ] <= self .end_date ) &
52
- (coverage_table ['COVERAGE_END_DATE' ] >= self .start_date )
53
- )
84
+ if self .min_days .operator == '>' :
85
+ coverage_table = coverage_table .filter (
86
+ (coverage_table ['DAYS_FROM_ANCHOR' ] > self .min_days .value )
87
+ )
88
+ elif self .min_days .operator == '>=' :
89
+ coverage_table = coverage_table .filter (
90
+ (coverage_table ['DAYS_FROM_ANCHOR' ] >= self .min_days .value )
91
+ )
92
+ elif self .min_days .operator == '<' :
93
+ coverage_table = coverage_table .filter (
94
+ (coverage_table ['DAYS_FROM_ANCHOR' ] < self .min_days .value )
95
+ )
96
+ elif self .min_days .operator == '<=' :
97
+ coverage_table = coverage_table .filter (
98
+ (coverage_table ['DAYS_FROM_ANCHOR' ] <= self .min_days .value )
99
+ )
100
+ return coverage_table
54
101
55
- def _check_continuous_coverage (self , coverage_table : Table ) -> Table :
56
- # Logic to check for continuous coverage with allowed gap_days
57
- # This is a placeholder and should be replaced with actual implementation
58
- return coverage_table .mutate (BOOLEAN = True )
59
102
60
103
def get_codelists (self ):
61
- return []
104
+ return []
0 commit comments