omop-constructs 0.3.5__tar.gz → 0.3.7__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {omop_constructs-0.3.5 → omop_constructs-0.3.7}/PKG-INFO +1 -1
- {omop_constructs-0.3.5 → omop_constructs-0.3.7}/pyproject.toml +1 -1
- {omop_constructs-0.3.5 → omop_constructs-0.3.7}/src/omop_constructs/alchemy/episodes/__init__.py +10 -0
- omop_constructs-0.3.7/src/omop_constructs/alchemy/episodes/course_joins.py +56 -0
- omop_constructs-0.3.7/src/omop_constructs/alchemy/episodes/course_mv.py +40 -0
- omop_constructs-0.3.7/src/omop_constructs/alchemy/episodes/cycle_join.py +38 -0
- omop_constructs-0.3.7/src/omop_constructs/alchemy/episodes/cycle_mv.py +34 -0
- omop_constructs-0.3.7/src/omop_constructs/alchemy/episodes/fraction_joins.py +37 -0
- omop_constructs-0.3.7/src/omop_constructs/alchemy/episodes/fraction_mv.py +33 -0
- omop_constructs-0.3.7/src/omop_constructs/alchemy/episodes/systemic_treatment_joins.py +53 -0
- omop_constructs-0.3.7/src/omop_constructs/alchemy/episodes/systemic_treatment_mv.py +40 -0
- omop_constructs-0.3.7/src/omop_constructs/alchemy/episodes/treatment_summary_joins.py +68 -0
- omop_constructs-0.3.7/src/omop_constructs/alchemy/episodes/treatment_summary_mv.py +47 -0
- {omop_constructs-0.3.5 → omop_constructs-0.3.7}/src/omop_constructs/alchemy/events/__init__.py +4 -0
- omop_constructs-0.3.7/src/omop_constructs/alchemy/events/dx_linked_obs_mv.py +51 -0
- {omop_constructs-0.3.5 → omop_constructs-0.3.7}/src/omop_constructs/alchemy/events/event_factories.py +62 -1
- omop_constructs-0.3.7/src/omop_constructs/alchemy/events/observation_queries.py +16 -0
- {omop_constructs-0.3.5 → omop_constructs-0.3.7}/src/omop_constructs/alchemy/modifiers/__init__.py +5 -1
- omop_constructs-0.3.7/src/omop_constructs/alchemy/modifiers/procedure_modifier_joins.py +37 -0
- omop_constructs-0.3.7/src/omop_constructs/alchemy/modifiers/procedure_modifier_mv.py +30 -0
- {omop_constructs-0.3.5 → omop_constructs-0.3.7}/src/omop_constructs/semantics/runtime_lookups.py +8 -0
- omop_constructs-0.3.5/src/omop_constructs/alchemy/episodes/treatment_summary_joins.py +0 -25
- {omop_constructs-0.3.5 → omop_constructs-0.3.7}/README.md +0 -0
- {omop_constructs-0.3.5 → omop_constructs-0.3.7}/src/omop_constructs/__init__.py +0 -0
- {omop_constructs-0.3.5 → omop_constructs-0.3.7}/src/omop_constructs/alchemy/__init__.py +0 -0
- {omop_constructs-0.3.5 → omop_constructs-0.3.7}/src/omop_constructs/alchemy/adapters.py +0 -0
- {omop_constructs-0.3.5 → omop_constructs-0.3.7}/src/omop_constructs/alchemy/concepts/__init__.py +0 -0
- {omop_constructs-0.3.5 → omop_constructs-0.3.7}/src/omop_constructs/alchemy/concepts/concept_mappers.py +0 -0
- {omop_constructs-0.3.5 → omop_constructs-0.3.7}/src/omop_constructs/alchemy/concepts/concept_standardisation.py +0 -0
- {omop_constructs-0.3.5 → omop_constructs-0.3.7}/src/omop_constructs/alchemy/conditions/__init__.py +0 -0
- {omop_constructs-0.3.5 → omop_constructs-0.3.7}/src/omop_constructs/alchemy/conditions/condition_joins.py +0 -0
- {omop_constructs-0.3.5 → omop_constructs-0.3.7}/src/omop_constructs/alchemy/conditions/condition_mappers.py +0 -0
- {omop_constructs-0.3.5 → omop_constructs-0.3.7}/src/omop_constructs/alchemy/demography/__init__.py +0 -0
- {omop_constructs-0.3.5 → omop_constructs-0.3.7}/src/omop_constructs/alchemy/demography/demography_matview.py +0 -0
- {omop_constructs-0.3.5 → omop_constructs-0.3.7}/src/omop_constructs/alchemy/demography/demography_queries.py +0 -0
- {omop_constructs-0.3.5 → omop_constructs-0.3.7}/src/omop_constructs/alchemy/episodes/condition_episode_mv.py +0 -0
- {omop_constructs-0.3.5 → omop_constructs-0.3.7}/src/omop_constructs/alchemy/episodes/condition_episode_objects.py +0 -0
- {omop_constructs-0.3.5 → omop_constructs-0.3.7}/src/omop_constructs/alchemy/episodes/episode_factories.py +0 -0
- {omop_constructs-0.3.5 → omop_constructs-0.3.7}/src/omop_constructs/alchemy/episodes/episode_joins.py +0 -0
- {omop_constructs-0.3.5 → omop_constructs-0.3.7}/src/omop_constructs/alchemy/episodes/surgical_joins.py +0 -0
- {omop_constructs-0.3.5 → omop_constructs-0.3.7}/src/omop_constructs/alchemy/episodes/surgical_procedure_mv.py +0 -0
- {omop_constructs-0.3.5 → omop_constructs-0.3.7}/src/omop_constructs/alchemy/events/dx_linked_event_mv.py +0 -0
- {omop_constructs-0.3.5 → omop_constructs-0.3.7}/src/omop_constructs/alchemy/events/dx_linked_procedure_mv.py +0 -0
- {omop_constructs-0.3.5 → omop_constructs-0.3.7}/src/omop_constructs/alchemy/events/event_queries.py +0 -0
- {omop_constructs-0.3.5 → omop_constructs-0.3.7}/src/omop_constructs/alchemy/events/procedure_queries.py +0 -0
- {omop_constructs-0.3.5 → omop_constructs-0.3.7}/src/omop_constructs/alchemy/modifiers/condition_modifier_join.py +0 -0
- {omop_constructs-0.3.5 → omop_constructs-0.3.7}/src/omop_constructs/alchemy/modifiers/condition_modifier_mv.py +0 -0
- {omop_constructs-0.3.5 → omop_constructs-0.3.7}/src/omop_constructs/alchemy/modifiers/modifier_factories.py +0 -0
- {omop_constructs-0.3.5 → omop_constructs-0.3.7}/src/omop_constructs/alchemy/modifiers/modifier_joins.py +0 -0
- {omop_constructs-0.3.5 → omop_constructs-0.3.7}/src/omop_constructs/alchemy/modifiers/modifier_mappers.py +0 -0
- {omop_constructs-0.3.5 → omop_constructs-0.3.7}/src/omop_constructs/alchemy/source_factories.py +0 -0
- {omop_constructs-0.3.5 → omop_constructs-0.3.7}/src/omop_constructs/core/__init__.py +0 -0
- {omop_constructs-0.3.5 → omop_constructs-0.3.7}/src/omop_constructs/core/base.py +0 -0
- {omop_constructs-0.3.5 → omop_constructs-0.3.7}/src/omop_constructs/core/constructs.py +0 -0
- {omop_constructs-0.3.5 → omop_constructs-0.3.7}/src/omop_constructs/core/ddl.py +0 -0
- {omop_constructs-0.3.5 → omop_constructs-0.3.7}/src/omop_constructs/core/errors.py +0 -0
- {omop_constructs-0.3.5 → omop_constructs-0.3.7}/src/omop_constructs/core/materialized.py +0 -0
- {omop_constructs-0.3.5 → omop_constructs-0.3.7}/src/omop_constructs/core/plan.py +0 -0
- {omop_constructs-0.3.5 → omop_constructs-0.3.7}/src/omop_constructs/core/registry.py +0 -0
- {omop_constructs-0.3.5 → omop_constructs-0.3.7}/src/omop_constructs/py.typed +0 -0
- {omop_constructs-0.3.5 → omop_constructs-0.3.7}/src/omop_constructs/semantics/__init__.py +0 -0
- {omop_constructs-0.3.5 → omop_constructs-0.3.7}/src/omop_constructs/semantics/adapters.py +0 -0
- {omop_constructs-0.3.5 → omop_constructs-0.3.7}/src/omop_constructs/semantics/lookups.py +0 -0
- {omop_constructs-0.3.5 → omop_constructs-0.3.7}/src/omop_constructs/services/__init__.py +0 -0
- {omop_constructs-0.3.5 → omop_constructs-0.3.7}/src/omop_constructs/services/concept.py +0 -0
- {omop_constructs-0.3.5 → omop_constructs-0.3.7}/src/omop_constructs/services/person.py +0 -0
- {omop_constructs-0.3.5 → omop_constructs-0.3.7}/src/omop_constructs/typing.py +0 -0
{omop_constructs-0.3.5 → omop_constructs-0.3.7}/src/omop_constructs/alchemy/episodes/__init__.py
RENAMED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
from .condition_episode_mv import OverarchingDiseaseEpisodeMV, TreatmentRegimenCycleMV, ConditionEpisodeMV, DxTreatStartMV
|
|
2
2
|
from .condition_episode_objects import ConditionEpisodeObject
|
|
3
3
|
from .surgical_procedure_mv import SurgicalProcedureMV
|
|
4
|
+
from .systemic_treatment_mv import SACTRegimenMV
|
|
5
|
+
from .cycle_mv import CycleMV
|
|
6
|
+
from .course_mv import RTCourseMV
|
|
7
|
+
from .fraction_mv import FractionMV
|
|
8
|
+
from .treatment_summary_mv import ConditionTreatmentEpisode
|
|
4
9
|
|
|
5
10
|
__all__ = [
|
|
6
11
|
"OverarchingDiseaseEpisodeMV",
|
|
@@ -9,4 +14,9 @@ __all__ = [
|
|
|
9
14
|
"ConditionEpisodeObject",
|
|
10
15
|
"SurgicalProcedureMV",
|
|
11
16
|
"DxTreatStartMV",
|
|
17
|
+
"SACTRegimenMV",
|
|
18
|
+
"CycleMV",
|
|
19
|
+
"RTCourseMV",
|
|
20
|
+
"FractionMV",
|
|
21
|
+
"ConditionTreatmentEpisode",
|
|
12
22
|
]
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import sqlalchemy as sa
|
|
2
|
+
import sqlalchemy.orm as so
|
|
3
|
+
from omop_alchemy.cdm.model import Episode, Episode_Event, Concept
|
|
4
|
+
from omop_semantics.runtime.default_valuesets import runtime
|
|
5
|
+
from ..modifiers import ModifiedProcedure
|
|
6
|
+
from .fraction_mv import FractionMV
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
course_concept = so.aliased(Concept, name='course_concept')
|
|
10
|
+
|
|
11
|
+
frac_summary_join = (
|
|
12
|
+
sa.select(
|
|
13
|
+
FractionMV.person_id,
|
|
14
|
+
FractionMV.fraction_id,
|
|
15
|
+
FractionMV.fraction_number,
|
|
16
|
+
FractionMV.course_id,
|
|
17
|
+
FractionMV.fraction_name,
|
|
18
|
+
sa.func.min(FractionMV.procedure_datetime).label('first_exposure_date'),
|
|
19
|
+
sa.func.max(FractionMV.procedure_datetime).label('last_exposure_date'),
|
|
20
|
+
sa.func.count(FractionMV.procedure_occurrence_id).label('fraction_count'),
|
|
21
|
+
)
|
|
22
|
+
.group_by(FractionMV.person_id, FractionMV.fraction_id, FractionMV.fraction_number, FractionMV.course_id, FractionMV.fraction_name)
|
|
23
|
+
.subquery()
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
course_join = (
|
|
27
|
+
sa.select(
|
|
28
|
+
*frac_summary_join.c,
|
|
29
|
+
sa.func.row_number().over().label('mv_id'),
|
|
30
|
+
Episode.episode_number.label('course_number'),
|
|
31
|
+
Episode.episode_parent_id.label('condition_episode_id'),
|
|
32
|
+
ModifiedProcedure.procedure_occurrence_id.label('course_prescription_id'),
|
|
33
|
+
ModifiedProcedure.procedure_concept_id.label('course_concept_id'),
|
|
34
|
+
ModifiedProcedure.procedure_concept.label('course_concept'),
|
|
35
|
+
ModifiedProcedure.intent_concept,
|
|
36
|
+
ModifiedProcedure.intent_concept_id,
|
|
37
|
+
ModifiedProcedure.intent_datetime
|
|
38
|
+
)
|
|
39
|
+
.join(
|
|
40
|
+
Episode,
|
|
41
|
+
sa.and_(
|
|
42
|
+
Episode.episode_id == frac_summary_join.c.course_id,
|
|
43
|
+
Episode.episode_concept_id==runtime.types.treatment_episode_types.treatment_regimen
|
|
44
|
+
),
|
|
45
|
+
isouter=True
|
|
46
|
+
)
|
|
47
|
+
.join(
|
|
48
|
+
Episode_Event,
|
|
49
|
+
sa.and_(
|
|
50
|
+
Episode_Event.episode_id == Episode.episode_id,
|
|
51
|
+
Episode_Event.episode_event_field_concept_id == runtime.modifiers.modifier_fields.procedure_occurrence_id
|
|
52
|
+
),
|
|
53
|
+
isouter=True
|
|
54
|
+
)
|
|
55
|
+
.join(ModifiedProcedure, ModifiedProcedure.procedure_occurrence_id==Episode_Event.event_id, isouter=True)
|
|
56
|
+
)
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import sqlalchemy as sa
|
|
2
|
+
import sqlalchemy.orm as so
|
|
3
|
+
from orm_loader.helpers import Base
|
|
4
|
+
from datetime import date
|
|
5
|
+
from typing import Optional
|
|
6
|
+
from .course_joins import course_join
|
|
7
|
+
from .fraction_mv import FractionMV
|
|
8
|
+
from ...core.materialized import MaterializedViewMixin
|
|
9
|
+
from ...core.constructs import register_construct
|
|
10
|
+
|
|
11
|
+
@register_construct
|
|
12
|
+
class RTCourseMV(
|
|
13
|
+
MaterializedViewMixin,
|
|
14
|
+
Base,
|
|
15
|
+
):
|
|
16
|
+
__mv_name__ = "rt_course_mv"
|
|
17
|
+
__mv_select__ = course_join.select()
|
|
18
|
+
__mv_index__ = "course_id"
|
|
19
|
+
__deps__ = (FractionMV.__mv_name__,)
|
|
20
|
+
__tablename__ = __mv_name__
|
|
21
|
+
__table_args__ = {"extend_existing": True}
|
|
22
|
+
|
|
23
|
+
mv_id: so.Mapped[int] = so.mapped_column(sa.Integer, primary_key=True)
|
|
24
|
+
person_id: so.Mapped[int] = so.mapped_column(sa.Integer)
|
|
25
|
+
fraction_id: so.Mapped[int] = so.mapped_column(sa.Integer)
|
|
26
|
+
fraction_number: so.Mapped[int] = so.mapped_column(sa.Integer)
|
|
27
|
+
fraction_count: so.Mapped[int] = so.mapped_column(sa.Integer)
|
|
28
|
+
fraction_name: so.Mapped[str] = so.mapped_column(sa.String)
|
|
29
|
+
first_exposure_date: so.Mapped[date] = so.mapped_column(sa.Date)
|
|
30
|
+
last_exposure_date: so.Mapped[date] = so.mapped_column(sa.Date)
|
|
31
|
+
course_id: so.Mapped[int] = so.mapped_column(sa.Integer)
|
|
32
|
+
course_number: so.Mapped[int] = so.mapped_column(sa.Integer)
|
|
33
|
+
condition_episode_id: so.Mapped[int] = so.mapped_column(sa.Integer)
|
|
34
|
+
course_prescription_id: so.Mapped[int] = so.mapped_column(sa.Integer)
|
|
35
|
+
course_concept_id: so.Mapped[int] = so.mapped_column(sa.Integer)
|
|
36
|
+
course_concept: so.Mapped[str] = so.mapped_column(sa.String)
|
|
37
|
+
intent_datetime: so.Mapped[Optional[date]] = so.mapped_column(sa.DateTime, nullable=True)
|
|
38
|
+
intent_concept_id: so.Mapped[Optional[int]] = so.mapped_column(sa.Integer, nullable=True)
|
|
39
|
+
intent_concept: so.Mapped[Optional[str]] = so.mapped_column(sa.String, nullable=True)
|
|
40
|
+
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import sqlalchemy as sa
|
|
2
|
+
from omop_semantics.runtime.default_valuesets import runtime
|
|
3
|
+
import sqlalchemy.orm as so
|
|
4
|
+
from omop_alchemy.cdm.model import Concept, Drug_Exposure, Episode, Episode_Event
|
|
5
|
+
|
|
6
|
+
drug_concept = so.aliased(Concept, name='drug_concept')
|
|
7
|
+
route_concept = so.aliased(Concept, name='route_concept')
|
|
8
|
+
cycle_concept = so.aliased(Concept, name='cycle_concept')
|
|
9
|
+
|
|
10
|
+
cycle_join = (
|
|
11
|
+
sa.select(
|
|
12
|
+
sa.func.row_number().over().label('mv_id'),
|
|
13
|
+
Drug_Exposure.person_id,
|
|
14
|
+
Drug_Exposure.drug_exposure_start_date,
|
|
15
|
+
Drug_Exposure.drug_exposure_end_date,
|
|
16
|
+
Drug_Exposure.drug_exposure_id,
|
|
17
|
+
Drug_Exposure.quantity,
|
|
18
|
+
Drug_Exposure.drug_concept_id,
|
|
19
|
+
Drug_Exposure.dose_unit_source_value,
|
|
20
|
+
drug_concept.concept_name.label('drug_name'),
|
|
21
|
+
route_concept.concept_name.label('route'),
|
|
22
|
+
Episode.episode_id.label('cycle_id'),
|
|
23
|
+
Episode.episode_number.label('cycle_number'),
|
|
24
|
+
Episode.episode_parent_id.label('regimen_id'),
|
|
25
|
+
cycle_concept.concept_name.label('cycle_concept')
|
|
26
|
+
)
|
|
27
|
+
.join(drug_concept, drug_concept.concept_id==Drug_Exposure.drug_concept_id)
|
|
28
|
+
.join(route_concept, route_concept.concept_id==Drug_Exposure.route_concept_id)
|
|
29
|
+
.join(
|
|
30
|
+
Episode_Event,
|
|
31
|
+
sa.and_(
|
|
32
|
+
Episode_Event.event_id==Drug_Exposure.drug_exposure_id,
|
|
33
|
+
Episode_Event.episode_event_field_concept_id==runtime.modifiers.modifier_fields.drug_exposure_id
|
|
34
|
+
)
|
|
35
|
+
)
|
|
36
|
+
.join(Episode, Episode.episode_id==Episode_Event.episode_id)
|
|
37
|
+
.join(cycle_concept, cycle_concept.concept_id==Episode.episode_concept_id)
|
|
38
|
+
)
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import sqlalchemy as sa
|
|
2
|
+
import sqlalchemy.orm as so
|
|
3
|
+
from orm_loader.helpers import Base
|
|
4
|
+
from datetime import date
|
|
5
|
+
from .cycle_join import cycle_join
|
|
6
|
+
from ...core.materialized import MaterializedViewMixin
|
|
7
|
+
from ...core.constructs import register_construct
|
|
8
|
+
|
|
9
|
+
@register_construct
|
|
10
|
+
class CycleMV(
|
|
11
|
+
MaterializedViewMixin,
|
|
12
|
+
Base,
|
|
13
|
+
):
|
|
14
|
+
__mv_name__ = "cycle_mv"
|
|
15
|
+
__mv_select__ = cycle_join.select()
|
|
16
|
+
__mv_index__ = "cycle_id"
|
|
17
|
+
__deps__ = ()
|
|
18
|
+
__tablename__ = __mv_name__
|
|
19
|
+
__table_args__ = {"extend_existing": True}
|
|
20
|
+
|
|
21
|
+
mv_id: so.Mapped[int] = so.mapped_column(sa.Integer, primary_key=True)
|
|
22
|
+
person_id: so.Mapped[int] = so.mapped_column(sa.Integer)
|
|
23
|
+
drug_exposure_id: so.Mapped[int] = so.mapped_column(sa.Integer)
|
|
24
|
+
drug_exposure_start_date: so.Mapped[date] = so.mapped_column(sa.Date)
|
|
25
|
+
drug_exposure_end_date: so.Mapped[date] = so.mapped_column(sa.Date)
|
|
26
|
+
quantity: so.Mapped[float] = so.mapped_column(sa.Numeric)
|
|
27
|
+
drug_concept_id: so.Mapped[int] = so.mapped_column(sa.Integer)
|
|
28
|
+
dose_unit_source_value: so.Mapped[str] = so.mapped_column(sa.String)
|
|
29
|
+
drug_name: so.Mapped[str] = so.mapped_column(sa.String)
|
|
30
|
+
route: so.Mapped[str] = so.mapped_column(sa.String)
|
|
31
|
+
cycle_id: so.Mapped[int] = so.mapped_column(sa.Integer)
|
|
32
|
+
cycle_number: so.Mapped[int] = so.mapped_column(sa.Integer)
|
|
33
|
+
cycle_concept: so.Mapped[int] = so.mapped_column(sa.Integer)
|
|
34
|
+
regimen_id: so.Mapped[int] = so.mapped_column(sa.Integer)
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import sqlalchemy as sa
|
|
2
|
+
import sqlalchemy.orm as so
|
|
3
|
+
from omop_alchemy.cdm.model import Episode, Episode_Event, Concept
|
|
4
|
+
from omop_semantics.runtime.default_valuesets import runtime
|
|
5
|
+
from ..modifiers import ModifiedProcedure
|
|
6
|
+
from ...semantics import registry
|
|
7
|
+
|
|
8
|
+
rt_proc_concept = so.aliased(Concept, name='rt_proc_concept')
|
|
9
|
+
fraction_concept = so.aliased(Concept, name='fraction_concept')
|
|
10
|
+
|
|
11
|
+
fraction_join = (
|
|
12
|
+
sa.select(
|
|
13
|
+
sa.func.row_number().over().label('mv_id'),
|
|
14
|
+
ModifiedProcedure.person_id,
|
|
15
|
+
ModifiedProcedure.procedure_datetime,
|
|
16
|
+
ModifiedProcedure.procedure_occurrence_id,
|
|
17
|
+
ModifiedProcedure.procedure_concept_id,
|
|
18
|
+
ModifiedProcedure.procedure_concept,
|
|
19
|
+
ModifiedProcedure.intent_concept,
|
|
20
|
+
ModifiedProcedure.intent_concept_id,
|
|
21
|
+
ModifiedProcedure.intent_datetime,
|
|
22
|
+
Episode.episode_id.label('fraction_id'),
|
|
23
|
+
Episode.episode_number.label('fraction_number'),
|
|
24
|
+
Episode.episode_parent_id.label('course_id'),
|
|
25
|
+
fraction_concept.concept_name.label('fraction_name')
|
|
26
|
+
)
|
|
27
|
+
.join(
|
|
28
|
+
Episode_Event,
|
|
29
|
+
sa.and_(
|
|
30
|
+
Episode_Event.event_id==ModifiedProcedure.procedure_occurrence_id,
|
|
31
|
+
Episode_Event.episode_event_field_concept_id==runtime.modifiers.modifier_fields.procedure_occurrence_id
|
|
32
|
+
)
|
|
33
|
+
)
|
|
34
|
+
.join(Episode, Episode.episode_id==Episode_Event.episode_id)
|
|
35
|
+
.join(fraction_concept, fraction_concept.concept_id==Episode.episode_object_concept_id)
|
|
36
|
+
.filter(ModifiedProcedure.procedure_concept_id.in_(list(registry['metastatic_disease'].all_concepts)))
|
|
37
|
+
)
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import sqlalchemy as sa
|
|
2
|
+
import sqlalchemy.orm as so
|
|
3
|
+
from orm_loader.helpers import Base
|
|
4
|
+
from datetime import date
|
|
5
|
+
from .fraction_joins import fraction_join
|
|
6
|
+
from ...core.materialized import MaterializedViewMixin
|
|
7
|
+
from ...core.constructs import register_construct
|
|
8
|
+
|
|
9
|
+
@register_construct
|
|
10
|
+
class FractionMV(
|
|
11
|
+
MaterializedViewMixin,
|
|
12
|
+
Base,
|
|
13
|
+
):
|
|
14
|
+
__mv_name__ = "fraction_mv"
|
|
15
|
+
__mv_select__ = fraction_join.select()
|
|
16
|
+
__mv_index__ = "fraction_id"
|
|
17
|
+
__deps__ = ()
|
|
18
|
+
__tablename__ = __mv_name__
|
|
19
|
+
__table_args__ = {"extend_existing": True}
|
|
20
|
+
|
|
21
|
+
mv_id: so.Mapped[int] = so.mapped_column(sa.Integer, primary_key=True)
|
|
22
|
+
person_id: so.Mapped[int] = so.mapped_column(sa.Integer)
|
|
23
|
+
procedure_occurrence_id: so.Mapped[int] = so.mapped_column(sa.Integer)
|
|
24
|
+
procedure_datetime: so.Mapped[date] = so.mapped_column(sa.DateTime)
|
|
25
|
+
procedure_concept_id: so.Mapped[int] = so.mapped_column(sa.Integer)
|
|
26
|
+
procedure_concept: so.Mapped[str] = so.mapped_column(sa.String)
|
|
27
|
+
intent_datetime: so.Mapped[date] = so.mapped_column(sa.DateTime)
|
|
28
|
+
intent_concept_id: so.Mapped[int] = so.mapped_column(sa.Integer)
|
|
29
|
+
intent_concept: so.Mapped[str] = so.mapped_column(sa.String)
|
|
30
|
+
fraction_id: so.Mapped[int] = so.mapped_column(sa.Integer)
|
|
31
|
+
fraction_number: so.Mapped[int] = so.mapped_column(sa.Integer)
|
|
32
|
+
course_id: so.Mapped[int] = so.mapped_column(sa.Integer)
|
|
33
|
+
fraction_name: so.Mapped[str] = so.mapped_column(sa.String)
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import sqlalchemy as sa
|
|
2
|
+
from omop_alchemy.cdm.model import Episode, Episode_Event
|
|
3
|
+
from omop_semantics.runtime.default_valuesets import runtime
|
|
4
|
+
from ..modifiers import ModifiedProcedure
|
|
5
|
+
from .cycle_mv import CycleMV
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
cycle_summary_join = (
|
|
9
|
+
sa.select(
|
|
10
|
+
CycleMV.person_id,
|
|
11
|
+
CycleMV.cycle_id,
|
|
12
|
+
CycleMV.cycle_number,
|
|
13
|
+
CycleMV.regimen_id,
|
|
14
|
+
CycleMV.cycle_concept,
|
|
15
|
+
sa.func.min(CycleMV.drug_exposure_start_date).label('first_exposure_date'),
|
|
16
|
+
sa.func.max(CycleMV.drug_exposure_end_date).label('last_exposure_date'),
|
|
17
|
+
sa.func.count(CycleMV.drug_exposure_id).label('exposure_count'),
|
|
18
|
+
)
|
|
19
|
+
.group_by(CycleMV.person_id, CycleMV.cycle_id, CycleMV.cycle_number, CycleMV.regimen_id, CycleMV.cycle_concept)
|
|
20
|
+
.subquery()
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
regimen_join = (
|
|
24
|
+
sa.select(
|
|
25
|
+
*cycle_summary_join.c,
|
|
26
|
+
sa.func.row_number().over().label('mv_id'),
|
|
27
|
+
Episode.episode_number.label('regimen_number'),
|
|
28
|
+
Episode.episode_parent_id.label('condition_episode_id'),
|
|
29
|
+
ModifiedProcedure.procedure_occurrence_id.label('regimen_prescription_id'),
|
|
30
|
+
ModifiedProcedure.procedure_concept_id.label('regimen_concept_id'),
|
|
31
|
+
ModifiedProcedure.procedure_concept.label('regimen_concept'),
|
|
32
|
+
ModifiedProcedure.intent_concept,
|
|
33
|
+
ModifiedProcedure.intent_concept_id,
|
|
34
|
+
ModifiedProcedure.intent_datetime,
|
|
35
|
+
)
|
|
36
|
+
.join(
|
|
37
|
+
Episode,
|
|
38
|
+
sa.and_(
|
|
39
|
+
Episode.episode_id == cycle_summary_join.c.regimen_id,
|
|
40
|
+
Episode.episode_concept_id==runtime.types.treatment_episode_types.treatment_regimen
|
|
41
|
+
),
|
|
42
|
+
isouter=True
|
|
43
|
+
)
|
|
44
|
+
.join(
|
|
45
|
+
Episode_Event,
|
|
46
|
+
sa.and_(
|
|
47
|
+
Episode_Event.episode_id==Episode.episode_id,
|
|
48
|
+
Episode_Event.episode_event_field_concept_id==runtime.modifiers.modifier_fields.procedure_occurrence_id
|
|
49
|
+
),
|
|
50
|
+
isouter=True
|
|
51
|
+
)
|
|
52
|
+
.join(ModifiedProcedure, ModifiedProcedure.procedure_occurrence_id==Episode_Event.event_id, isouter=True)
|
|
53
|
+
)
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import sqlalchemy as sa
|
|
2
|
+
import sqlalchemy.orm as so
|
|
3
|
+
from orm_loader.helpers import Base
|
|
4
|
+
from datetime import date
|
|
5
|
+
from typing import Optional
|
|
6
|
+
from .systemic_treatment_joins import regimen_join
|
|
7
|
+
from .cycle_mv import CycleMV
|
|
8
|
+
from ...core.materialized import MaterializedViewMixin
|
|
9
|
+
from ...core.constructs import register_construct
|
|
10
|
+
|
|
11
|
+
@register_construct
|
|
12
|
+
class SACTRegimenMV(
|
|
13
|
+
MaterializedViewMixin,
|
|
14
|
+
Base,
|
|
15
|
+
):
|
|
16
|
+
__mv_name__ = "sact_treatment_mv"
|
|
17
|
+
__mv_select__ = regimen_join.select()
|
|
18
|
+
__mv_index__ = "regimen_id"
|
|
19
|
+
__deps__ = (CycleMV.__mv_name__,)
|
|
20
|
+
__tablename__ = __mv_name__
|
|
21
|
+
__table_args__ = {"extend_existing": True}
|
|
22
|
+
|
|
23
|
+
mv_id: so.Mapped[int] = so.mapped_column(sa.Integer, primary_key=True)
|
|
24
|
+
person_id: so.Mapped[int] = so.mapped_column(sa.Integer)
|
|
25
|
+
cycle_id: so.Mapped[int] = so.mapped_column(sa.Integer)
|
|
26
|
+
cycle_number: so.Mapped[int] = so.mapped_column(sa.Integer)
|
|
27
|
+
cycle_concept: so.Mapped[int] = so.mapped_column(sa.Integer)
|
|
28
|
+
exposure_count: so.Mapped[int] = so.mapped_column(sa.Integer)
|
|
29
|
+
first_exposure_date: so.Mapped[date] = so.mapped_column(sa.Date)
|
|
30
|
+
last_exposure_date: so.Mapped[date] = so.mapped_column(sa.Date)
|
|
31
|
+
regimen_id: so.Mapped[int] = so.mapped_column(sa.Integer)
|
|
32
|
+
regimen_number: so.Mapped[int] = so.mapped_column(sa.Integer)
|
|
33
|
+
condition_episode_id: so.Mapped[int] = so.mapped_column(sa.Integer)
|
|
34
|
+
regimen_prescription_id: so.Mapped[int] = so.mapped_column(sa.Integer)
|
|
35
|
+
regimen_concept_id: so.Mapped[int] = so.mapped_column(sa.Integer)
|
|
36
|
+
regimen_concept: so.Mapped[str] = so.mapped_column(sa.String)
|
|
37
|
+
intent_datetime: so.Mapped[Optional[date]] = so.mapped_column(sa.DateTime, nullable=True)
|
|
38
|
+
intent_concept_id: so.Mapped[Optional[int]] = so.mapped_column(sa.Integer, nullable=True)
|
|
39
|
+
intent_concept: so.Mapped[Optional[str]] = so.mapped_column(sa.String, nullable=True)
|
|
40
|
+
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import sqlalchemy as sa
|
|
2
|
+
import sqlalchemy.orm as so
|
|
3
|
+
from .systemic_treatment_mv import SACTRegimenMV
|
|
4
|
+
from .course_mv import RTCourseMV
|
|
5
|
+
from omop_alchemy.cdm.model import Episode_Event, Condition_Occurrence, Concept
|
|
6
|
+
from omop_semantics.runtime.default_valuesets import runtime
|
|
7
|
+
|
|
8
|
+
condition_concept = so.aliased(Concept, name='condition_concept')
|
|
9
|
+
|
|
10
|
+
regimen_summary_join = (
|
|
11
|
+
sa.select(
|
|
12
|
+
SACTRegimenMV.person_id,
|
|
13
|
+
SACTRegimenMV.regimen_concept,
|
|
14
|
+
SACTRegimenMV.regimen_id,
|
|
15
|
+
SACTRegimenMV.regimen_number,
|
|
16
|
+
SACTRegimenMV.condition_episode_id,
|
|
17
|
+
SACTRegimenMV.intent_concept_id.label('sact_intent_concept_id'),
|
|
18
|
+
SACTRegimenMV.intent_concept.label('sact_intent_concept'),
|
|
19
|
+
sa.func.min(SACTRegimenMV.first_exposure_date).label('regimen_start_date'),
|
|
20
|
+
sa.func.max(SACTRegimenMV.last_exposure_date).label('regimen_end_date'),
|
|
21
|
+
sa.func.sum(SACTRegimenMV.exposure_count).label('exposure_count'),
|
|
22
|
+
sa.func.count(SACTRegimenMV.regimen_id).label('regimen_count'),
|
|
23
|
+
)
|
|
24
|
+
.group_by(SACTRegimenMV.person_id, SACTRegimenMV.regimen_concept, SACTRegimenMV.regimen_id, SACTRegimenMV.regimen_number, SACTRegimenMV.condition_episode_id, SACTRegimenMV.intent_concept_id, SACTRegimenMV.intent_concept)
|
|
25
|
+
.subquery()
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
course_summary_join = (
|
|
29
|
+
sa.select(
|
|
30
|
+
RTCourseMV.person_id,
|
|
31
|
+
RTCourseMV.course_concept,
|
|
32
|
+
RTCourseMV.course_id,
|
|
33
|
+
RTCourseMV.course_number,
|
|
34
|
+
RTCourseMV.condition_episode_id,
|
|
35
|
+
RTCourseMV.intent_concept_id.label('rt_intent_concept_id'),
|
|
36
|
+
RTCourseMV.intent_concept.label('rt_intent_concept'),
|
|
37
|
+
sa.func.min(RTCourseMV.first_exposure_date).label('course_start_date'),
|
|
38
|
+
sa.func.max(RTCourseMV.last_exposure_date).label('course_end_date'),
|
|
39
|
+
sa.func.sum(RTCourseMV.fraction_count).label('fraction_count'),
|
|
40
|
+
sa.func.count(RTCourseMV.course_id).label('course_count'),
|
|
41
|
+
)
|
|
42
|
+
.group_by(RTCourseMV.person_id, RTCourseMV.course_concept, RTCourseMV.course_id, RTCourseMV.course_number, RTCourseMV.condition_episode_id, RTCourseMV.intent_concept_id, RTCourseMV.intent_concept)
|
|
43
|
+
.subquery()
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
condition_treatment_join = (
|
|
47
|
+
sa.select(
|
|
48
|
+
sa.func.row_number().over().label('mv_id'),
|
|
49
|
+
Condition_Occurrence.person_id,
|
|
50
|
+
Condition_Occurrence.condition_occurrence_id,
|
|
51
|
+
Condition_Occurrence.condition_start_date,
|
|
52
|
+
Condition_Occurrence.condition_end_date,
|
|
53
|
+
Episode_Event.episode_id.label('condition_episode_id'),
|
|
54
|
+
*regimen_summary_join.c,
|
|
55
|
+
*course_summary_join.c,
|
|
56
|
+
)
|
|
57
|
+
.join(
|
|
58
|
+
Episode_Event,
|
|
59
|
+
sa.and_(
|
|
60
|
+
Episode_Event.event_id==Condition_Occurrence.condition_occurrence_id,
|
|
61
|
+
Episode_Event.episode_event_field_concept_id==runtime.modifiers.modifier_fields.condition_occurrence_id
|
|
62
|
+
),
|
|
63
|
+
isouter=True
|
|
64
|
+
)
|
|
65
|
+
.join(regimen_summary_join, regimen_summary_join.c.condition_episode_id==Episode_Event.episode_id, isouter=True)
|
|
66
|
+
.join(course_summary_join, course_summary_join.c.condition_episode_id==Episode_Event.episode_id, isouter=True)
|
|
67
|
+
.subquery()
|
|
68
|
+
)
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import sqlalchemy as sa
|
|
2
|
+
import sqlalchemy.orm as so
|
|
3
|
+
from orm_loader.helpers import Base
|
|
4
|
+
from datetime import date
|
|
5
|
+
from typing import Optional
|
|
6
|
+
from .treatment_summary_joins import condition_treatment_join
|
|
7
|
+
from .course_mv import RTCourseMV
|
|
8
|
+
from .systemic_treatment_mv import SACTRegimenMV
|
|
9
|
+
from ...core.materialized import MaterializedViewMixin
|
|
10
|
+
from ...core.constructs import register_construct
|
|
11
|
+
|
|
12
|
+
@register_construct
|
|
13
|
+
class ConditionTreatmentEpisode(
|
|
14
|
+
MaterializedViewMixin,
|
|
15
|
+
Base,
|
|
16
|
+
):
|
|
17
|
+
__mv_name__ = "condition_treatment_episode_mv"
|
|
18
|
+
__mv_select__ = condition_treatment_join.select()
|
|
19
|
+
__mv_index__ = "condition_episode_id"
|
|
20
|
+
__deps__ = (RTCourseMV.__mv_name__, SACTRegimenMV.__mv_name__)
|
|
21
|
+
__tablename__ = __mv_name__
|
|
22
|
+
__table_args__ = {"extend_existing": True}
|
|
23
|
+
|
|
24
|
+
mv_id: so.Mapped[int] = so.mapped_column(sa.Integer, primary_key=True)
|
|
25
|
+
person_id: so.Mapped[int] = so.mapped_column(sa.Integer)
|
|
26
|
+
condition_episode_id: so.Mapped[int] = so.mapped_column(sa.Integer)
|
|
27
|
+
condition_occurrence_id: so.Mapped[int] = so.mapped_column(sa.Integer)
|
|
28
|
+
condition_start_date: so.Mapped[date] = so.mapped_column(sa.Date)
|
|
29
|
+
condition_end_date: so.Mapped[date] = so.mapped_column(sa.Date)
|
|
30
|
+
course_concept: so.Mapped[str] = so.mapped_column(sa.String)
|
|
31
|
+
course_id: so.Mapped[int] = so.mapped_column(sa.Integer)
|
|
32
|
+
course_number: so.Mapped[int] = so.mapped_column(sa.Integer)
|
|
33
|
+
course_start_date: so.Mapped[date] = so.mapped_column(sa.Date)
|
|
34
|
+
course_end_date: so.Mapped[date] = so.mapped_column(sa.Date)
|
|
35
|
+
rt_intent_concept_id: so.Mapped[int] = so.mapped_column(sa.Integer)
|
|
36
|
+
rt_intent_concept: so.Mapped[int] = so.mapped_column(sa.Integer)
|
|
37
|
+
fraction_count: so.Mapped[int] = so.mapped_column(sa.Integer)
|
|
38
|
+
course_count: so.Mapped[int] = so.mapped_column(sa.Integer)
|
|
39
|
+
regimen_concept: so.Mapped[str] = so.mapped_column(sa.String)
|
|
40
|
+
regimen_id: so.Mapped[int] = so.mapped_column(sa.Integer)
|
|
41
|
+
regimen_number: so.Mapped[int] = so.mapped_column(sa.Integer)
|
|
42
|
+
regimen_start_date: so.Mapped[date] = so.mapped_column(sa.Date)
|
|
43
|
+
regimen_end_date: so.Mapped[date] = so.mapped_column(sa.Date)
|
|
44
|
+
sact_intent_concept_id: so.Mapped[int] = so.mapped_column(sa.Integer)
|
|
45
|
+
sact_intent_concept: so.Mapped[int] = so.mapped_column(sa.Integer)
|
|
46
|
+
exposure_count: so.Mapped[int] = so.mapped_column(sa.Integer)
|
|
47
|
+
regimen_count: so.Mapped[int] = so.mapped_column(sa.Integer)
|
{omop_constructs-0.3.5 → omop_constructs-0.3.7}/src/omop_constructs/alchemy/events/__init__.py
RENAMED
|
@@ -15,6 +15,9 @@ from .dx_linked_event_mv import (
|
|
|
15
15
|
from .dx_linked_procedure_mv import (
|
|
16
16
|
DxProcedureMV,
|
|
17
17
|
)
|
|
18
|
+
from .dx_linked_obs_mv import (
|
|
19
|
+
DxObservationMV,
|
|
20
|
+
)
|
|
18
21
|
|
|
19
22
|
__all__ = [
|
|
20
23
|
"WeightDxMV",
|
|
@@ -29,4 +32,5 @@ __all__ = [
|
|
|
29
32
|
"SmokingPYHDxMV",
|
|
30
33
|
"DxMeasurementMV",
|
|
31
34
|
"DxProcedureMV",
|
|
35
|
+
"DxObservationMV",
|
|
32
36
|
]
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import sqlalchemy as sa
|
|
2
|
+
import sqlalchemy.orm as so
|
|
3
|
+
from datetime import date
|
|
4
|
+
from typing import Optional
|
|
5
|
+
from orm_loader.helpers import Base
|
|
6
|
+
|
|
7
|
+
from omop_constructs.alchemy.episodes.condition_episode_mv import ConditionEpisodeMV
|
|
8
|
+
from ...core.materialized import MaterializedViewMixin
|
|
9
|
+
from ...core.constructs import register_construct
|
|
10
|
+
from ..episodes import ConditionEpisodeMV
|
|
11
|
+
from .observation_queries import (
|
|
12
|
+
dx_all_observations
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
class ConditionEpisodeObservationCols:
|
|
16
|
+
__table_args__ = {"extend_existing": True}
|
|
17
|
+
|
|
18
|
+
mv_id: so.Mapped[int] = so.mapped_column(primary_key=True)
|
|
19
|
+
|
|
20
|
+
person_id: so.Mapped[int] = so.mapped_column(sa.Integer)
|
|
21
|
+
event_id: so.Mapped[int] = so.mapped_column(sa.Integer)
|
|
22
|
+
event_date: so.Mapped[date] = so.mapped_column(sa.Date)
|
|
23
|
+
event_concept_id: so.Mapped[int] = so.mapped_column(sa.Integer)
|
|
24
|
+
event_label: so.Mapped[Optional[str]] = so.mapped_column(sa.String, nullable=True)
|
|
25
|
+
|
|
26
|
+
value_as_number: so.Mapped[Optional[float]] = so.mapped_column(sa.Float, nullable=True)
|
|
27
|
+
qualifier_concept_id: so.Mapped[Optional[int]] = so.mapped_column(sa.Integer, nullable=True)
|
|
28
|
+
value_concept_id: so.Mapped[Optional[int]] = so.mapped_column(sa.Integer, nullable=True)
|
|
29
|
+
|
|
30
|
+
episode_id: so.Mapped[Optional[int]] = so.mapped_column(sa.Integer, nullable=True)
|
|
31
|
+
episode_concept_id: so.Mapped[Optional[int]] = so.mapped_column(sa.Integer, nullable=True)
|
|
32
|
+
episode_label: so.Mapped[Optional[str]] = so.mapped_column(sa.String, nullable=True)
|
|
33
|
+
|
|
34
|
+
episode_start_date: so.Mapped[Optional[date]] = so.mapped_column(sa.Date, nullable=True)
|
|
35
|
+
episode_end_date: so.Mapped[Optional[date]] = so.mapped_column(sa.Date, nullable=True)
|
|
36
|
+
|
|
37
|
+
episode_delta_days: so.Mapped[Optional[int]] = so.mapped_column(sa.Integer, nullable=True)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
@register_construct
|
|
41
|
+
class DxObservationMV(ConditionEpisodeObservationCols, MaterializedViewMixin, Base):
|
|
42
|
+
__mv_name__ = "dx_observation_mv"
|
|
43
|
+
__mv_select__ = dx_all_observations.select()
|
|
44
|
+
__mv_index__ = "person_id"
|
|
45
|
+
__deps__ = (ConditionEpisodeMV.__mv_name__,)
|
|
46
|
+
__tablename__ = __mv_name__
|
|
47
|
+
|
|
48
|
+
observation_concept_id: so.Mapped[int] = so.mapped_column(sa.Integer)
|
|
49
|
+
observation_date: so.Mapped[Optional[date]] = so.mapped_column(sa.DateTime)
|
|
50
|
+
value_concept_id: so.Mapped[Optional[int]] = so.mapped_column(sa.Integer, nullable=True)
|
|
51
|
+
qualifier_concept_id: so.Mapped[Optional[int]] = so.mapped_column(sa.Integer, nullable=True)
|
|
@@ -5,13 +5,14 @@ from typing import Iterable, Any, Sequence, Union
|
|
|
5
5
|
from omop_constructs.alchemy.episodes import ConditionEpisodeMV
|
|
6
6
|
from omop_alchemy.cdm.model.structural import Episode_Event
|
|
7
7
|
from omop_semantics.runtime.default_valuesets import runtime # type: ignore
|
|
8
|
-
from omop_alchemy.cdm.model import Measurement, Concept, Procedure_Occurrence
|
|
8
|
+
from omop_alchemy.cdm.model import Measurement, Concept, Procedure_Occurrence, Observation
|
|
9
9
|
from sqlalchemy.orm.attributes import InstrumentedAttribute
|
|
10
10
|
|
|
11
11
|
SQLExpr = Union[ColumnElement[Any], InstrumentedAttribute[Any]]
|
|
12
12
|
|
|
13
13
|
modifier_concept = so.aliased(Concept, name="modifier_concept")
|
|
14
14
|
procedure_concept = so.aliased(Concept, name="procedure_concept")
|
|
15
|
+
observation_concept = so.aliased(Concept, name="observation_concept")
|
|
15
16
|
|
|
16
17
|
def attach_to_condition_episode_via_episode_event(
|
|
17
18
|
base_event_subq: sa.Subquery,
|
|
@@ -230,6 +231,66 @@ def measurement_attached_to_condition_episode(
|
|
|
230
231
|
name=name,
|
|
231
232
|
)
|
|
232
233
|
|
|
234
|
+
def observation_event_core(
|
|
235
|
+
*,
|
|
236
|
+
concept_ids: Iterable[int] | None = None,
|
|
237
|
+
name: str = "observation_core",
|
|
238
|
+
include_cols: Sequence[SQLExpr] = (),
|
|
239
|
+
unlinked_only: bool = True,
|
|
240
|
+
) -> sa.Subquery:
|
|
241
|
+
"""
|
|
242
|
+
Minimal observation event surface (person/id/date/concept/label + extras).
|
|
243
|
+
"""
|
|
244
|
+
q = (
|
|
245
|
+
sa.select(
|
|
246
|
+
Observation.person_id.label("person_id"),
|
|
247
|
+
Observation.observation_id.label("event_id"),
|
|
248
|
+
Observation.observation_date.label("event_date"),
|
|
249
|
+
Observation.observation_concept_id.label("event_concept_id"),
|
|
250
|
+
observation_concept.concept_name.label("event_label"),
|
|
251
|
+
Observation.value_as_concept_id.label("value_concept_id"),
|
|
252
|
+
Observation.qualifier_concept_id.label("qualifier_concept_id"),
|
|
253
|
+
*include_cols,
|
|
254
|
+
)
|
|
255
|
+
.join(
|
|
256
|
+
observation_concept,
|
|
257
|
+
observation_concept.concept_id == Observation.observation_concept_id,
|
|
258
|
+
isouter=True,
|
|
259
|
+
)
|
|
260
|
+
)
|
|
261
|
+
|
|
262
|
+
if unlinked_only:
|
|
263
|
+
q = q.where(Observation.observation_event_id == None)
|
|
264
|
+
|
|
265
|
+
if concept_ids is not None:
|
|
266
|
+
q = q.where(Observation.observation_concept_id.in_(list(concept_ids)))
|
|
267
|
+
|
|
268
|
+
return q.subquery(name=name)
|
|
269
|
+
|
|
270
|
+
def observation_attached_to_condition_episode(
|
|
271
|
+
*,
|
|
272
|
+
concept_ids: Iterable[int] | None = None,
|
|
273
|
+
include_cols: Sequence[SQLExpr] = (),
|
|
274
|
+
name: str,
|
|
275
|
+
unlinked_only: bool = True,
|
|
276
|
+
prefer_explicit_link: bool = True,
|
|
277
|
+
) -> sa.Subquery:
|
|
278
|
+
core = observation_event_core(
|
|
279
|
+
concept_ids=concept_ids,
|
|
280
|
+
include_cols=include_cols,
|
|
281
|
+
name=f"{name}_core",
|
|
282
|
+
unlinked_only=unlinked_only,
|
|
283
|
+
)
|
|
284
|
+
|
|
285
|
+
return attach_to_condition_episode(
|
|
286
|
+
core,
|
|
287
|
+
event_id_col=core.c.event_id,
|
|
288
|
+
date_col=core.c.event_date,
|
|
289
|
+
person_col=core.c.person_id,
|
|
290
|
+
name=name,
|
|
291
|
+
prefer_explicit_link=prefer_explicit_link,
|
|
292
|
+
)
|
|
293
|
+
|
|
233
294
|
def episode_relevant_window(
|
|
234
295
|
starting_query: sa.Subquery,
|
|
235
296
|
*,
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
from .event_factories import observation_attached_to_condition_episode, episode_relevant_window
|
|
2
|
+
from omop_alchemy.cdm.model import Observation
|
|
3
|
+
dx_all_observations = episode_relevant_window(
|
|
4
|
+
observation_attached_to_condition_episode(
|
|
5
|
+
concept_ids=None, # all obs
|
|
6
|
+
include_cols=[
|
|
7
|
+
Observation.value_as_number,
|
|
8
|
+
Observation.qualifier_concept_id,
|
|
9
|
+
],
|
|
10
|
+
name="dx_all_observations",
|
|
11
|
+
unlinked_only=False,
|
|
12
|
+
),
|
|
13
|
+
max_days_post=365,
|
|
14
|
+
max_days_prior=30,
|
|
15
|
+
name="dx_all_observations_windowed",
|
|
16
|
+
)
|
{omop_constructs-0.3.5 → omop_constructs-0.3.7}/src/omop_constructs/alchemy/modifiers/__init__.py
RENAMED
|
@@ -10,6 +10,9 @@ from .modifier_mappers import (
|
|
|
10
10
|
AllStageModifierMV
|
|
11
11
|
)
|
|
12
12
|
from .condition_modifier_mv import ModifiedCondition, StageModifier
|
|
13
|
+
from .procedure_modifier_mv import (
|
|
14
|
+
ModifiedProcedure,
|
|
15
|
+
)
|
|
13
16
|
|
|
14
17
|
__all__ = [
|
|
15
18
|
"TStageMV",
|
|
@@ -22,5 +25,6 @@ __all__ = [
|
|
|
22
25
|
"ModifiedCondition",
|
|
23
26
|
"MetastaticDiseaseModifierMV",
|
|
24
27
|
"AllStageModifierMV",
|
|
25
|
-
"StageModifier"
|
|
28
|
+
"StageModifier",
|
|
29
|
+
"ModifiedProcedure"
|
|
26
30
|
]
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
from datetime import datetime
|
|
2
|
+
import sqlalchemy as sa
|
|
3
|
+
import sqlalchemy.orm as so
|
|
4
|
+
from omop_alchemy.cdm.model import Concept, Procedure_Occurrence, Measurement
|
|
5
|
+
from omop_semantics.runtime.default_valuesets import runtime
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
modifier_concept = so.aliased(Concept, name='modifier_concept')
|
|
9
|
+
procedure_concept = so.aliased(Concept, name='procedure_concept')
|
|
10
|
+
|
|
11
|
+
modified_procedure_join = (
|
|
12
|
+
sa.select(
|
|
13
|
+
Procedure_Occurrence.person_id,
|
|
14
|
+
Procedure_Occurrence.procedure_datetime,
|
|
15
|
+
Procedure_Occurrence.procedure_occurrence_id,
|
|
16
|
+
Procedure_Occurrence.procedure_source_value,
|
|
17
|
+
Procedure_Occurrence.procedure_concept_id,
|
|
18
|
+
procedure_concept.concept_name.label('procedure_concept'),
|
|
19
|
+
Measurement.measurement_id.label('intent_id'),
|
|
20
|
+
Measurement.measurement_datetime.label('intent_datetime'),
|
|
21
|
+
Measurement.measurement_concept_id.label('intent_concept_id'),
|
|
22
|
+
modifier_concept.concept_name.label('intent_concept'),
|
|
23
|
+
sa.func.row_number().over().label('mv_id')
|
|
24
|
+
)
|
|
25
|
+
.join(
|
|
26
|
+
Measurement,
|
|
27
|
+
sa.and_(
|
|
28
|
+
Measurement.modifier_of_field_concept_id==runtime.modifiers.modifier_fields.procedure_occurrence_id,
|
|
29
|
+
Procedure_Occurrence.procedure_occurrence_id==Measurement.modifier_of_event_id,
|
|
30
|
+
Measurement.measurement_concept_id.in_(runtime.treatment_modifiers.treatment_intent.ids)
|
|
31
|
+
),
|
|
32
|
+
isouter=True
|
|
33
|
+
)
|
|
34
|
+
.join(procedure_concept, procedure_concept.concept_id==Procedure_Occurrence.procedure_concept_id)
|
|
35
|
+
.join(modifier_concept, modifier_concept.concept_id==Measurement.measurement_concept_id, isouter=True)
|
|
36
|
+
)
|
|
37
|
+
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import sqlalchemy as sa
|
|
2
|
+
from orm_loader.helpers import Base
|
|
3
|
+
from ...core.materialized import MaterializedViewMixin
|
|
4
|
+
from ...core.constructs import register_construct
|
|
5
|
+
from .procedure_modifier_joins import modified_procedure_join
|
|
6
|
+
|
|
7
|
+
@register_construct
|
|
8
|
+
class ModifiedProcedure(MaterializedViewMixin, Base):
|
|
9
|
+
"""
|
|
10
|
+
this class contains all stage modifier records no matter the sub-type, nor does it preference
|
|
11
|
+
clin / path stage etc - just a dump of all, along with the identifier to link to condition ep
|
|
12
|
+
"""
|
|
13
|
+
__mv_name__ = 'modified_procedure_mv'
|
|
14
|
+
__mv_select__ = modified_procedure_join.select()
|
|
15
|
+
__mv_pk__ = ["mv_id"]
|
|
16
|
+
__table_args__ = {"extend_existing": True}
|
|
17
|
+
__tablename__ = __mv_name__
|
|
18
|
+
__deps__ = ()
|
|
19
|
+
mv_id = sa.Column(sa.Integer,primary_key=True)
|
|
20
|
+
person_id = sa.Column(sa.Integer)
|
|
21
|
+
procedure_datetime = sa.Column(sa.Date)
|
|
22
|
+
procedure_occurrence_id = sa.Column(sa.Integer)
|
|
23
|
+
procedure_source_value = sa.Column(sa.String)
|
|
24
|
+
procedure_concept_id = sa.Column(sa.Integer)
|
|
25
|
+
procedure_concept = sa.Column(sa.String)
|
|
26
|
+
intent_id = sa.Column(sa.Integer)
|
|
27
|
+
intent_datetime = sa.Column(sa.Date)
|
|
28
|
+
intent_concept_id = sa.Column(sa.Integer)
|
|
29
|
+
intent_concept = sa.Column(sa.String)
|
|
30
|
+
stage_label = sa.Column(sa.String)
|
{omop_constructs-0.3.5 → omop_constructs-0.3.7}/src/omop_constructs/semantics/runtime_lookups.py
RENAMED
|
@@ -38,6 +38,14 @@ DEFAULT_RESOLVER_BUILDERS = {
|
|
|
38
38
|
parent_list=list(runtime.condition_modifiers.tumor_grade.ids),
|
|
39
39
|
resolver_name="tumor_grade",
|
|
40
40
|
),
|
|
41
|
+
"rt_procedures": lambda session: build_parent_resolver(
|
|
42
|
+
session,
|
|
43
|
+
parent_list=[
|
|
44
|
+
runtime.cancer_procedures.cancer_procedure_types.rt_externalbeam, # type: ignore
|
|
45
|
+
runtime.cancer_procedures.cancer_procedure_types.rt_procedure
|
|
46
|
+
],
|
|
47
|
+
resolver_name="rt_procedures",
|
|
48
|
+
)
|
|
41
49
|
}
|
|
42
50
|
|
|
43
51
|
def get_registry_engine(env_path: str = __file__):
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import sqlalchemy as sa
|
|
2
|
-
from omop_semantics.runtime.default_valuesets import runtime
|
|
3
|
-
from .condition_episode_mv import TreatmentRegimenCycleMV
|
|
4
|
-
|
|
5
|
-
treatment_summary = (
|
|
6
|
-
sa.select(
|
|
7
|
-
TreatmentRegimenCycleMV.person_id,
|
|
8
|
-
TreatmentRegimenCycleMV.episode_parent_id.label("condition_episode_id"),
|
|
9
|
-
TreatmentRegimenCycleMV.episode_concept_id,
|
|
10
|
-
TreatmentRegimenCycleMV.episode_label,
|
|
11
|
-
|
|
12
|
-
sa.func.min(TreatmentRegimenCycleMV.episode_start_date).label("treatment_start_date"),
|
|
13
|
-
sa.func.max(TreatmentRegimenCycleMV.episode_end_date).label("treatment_end_date"),
|
|
14
|
-
|
|
15
|
-
sa.func.count(sa.distinct(TreatmentRegimenCycleMV.episode_id)).label("regimen_count"),
|
|
16
|
-
sa.func.count(sa.distinct(TreatmentRegimenCycleMV.cycle_episode_id)).label("cycle_count"),
|
|
17
|
-
)
|
|
18
|
-
.group_by(
|
|
19
|
-
TreatmentRegimenCycleMV.person_id,
|
|
20
|
-
TreatmentRegimenCycleMV.episode_parent_id,
|
|
21
|
-
TreatmentRegimenCycleMV.episode_concept_id,
|
|
22
|
-
TreatmentRegimenCycleMV.episode_label,
|
|
23
|
-
)
|
|
24
|
-
.subquery("treatment_summary")
|
|
25
|
-
)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{omop_constructs-0.3.5 → omop_constructs-0.3.7}/src/omop_constructs/alchemy/concepts/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{omop_constructs-0.3.5 → omop_constructs-0.3.7}/src/omop_constructs/alchemy/conditions/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{omop_constructs-0.3.5 → omop_constructs-0.3.7}/src/omop_constructs/alchemy/demography/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{omop_constructs-0.3.5 → omop_constructs-0.3.7}/src/omop_constructs/alchemy/events/event_queries.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{omop_constructs-0.3.5 → omop_constructs-0.3.7}/src/omop_constructs/alchemy/source_factories.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|