Skip to content

Commit

Permalink
fix(temporalconstraint): allow multistage temporal constraints
Browse files Browse the repository at this point in the history
  • Loading branch information
pl-buiquang committed Jan 28, 2025
1 parent a340dc6 commit 9910aa2
Show file tree
Hide file tree
Showing 9 changed files with 198 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ class QueryBuilderTemporalConstraint(val options: QueryExecutionOptions) {
temporalConstraintDataFrame: DataFrame,
firstCriterionId: Short,
groupId: Short,
isInTemporalConstraint: Boolean,
withOrganizations: Boolean): Option[DataFrame] = {
// @todo: when we will enable groups to be constrained by, we will need to koin on and keep more columns (encounter_id and dates)
// @todo: not a left semi if not "andGroup"
Expand All @@ -121,12 +122,23 @@ class QueryBuilderTemporalConstraint(val options: QueryExecutionOptions) {
val organizationColumnName = QueryBuilderUtils.getOrganizationsColumn(firstCriterionId)
val selectedColumns = List(criterionIdColumnName) ++ (if (withOrganizations)
List(organizationColumnName)
else List())
else
List()) ++ (if (isInTemporalConstraint)
List(
QueryBuilderUtils
.getEncounterColumn(
firstCriterionId))
else List())
var patientListDataFrame =
temporalConstraintDataFrame
.select(selectedColumns.map(F.col): _*)
.withColumnRenamed(criterionIdColumnName, groupIdColumName)
.dropDuplicates(groupIdColumName)
.dropDuplicates()
if (isInTemporalConstraint) {
patientListDataFrame = patientListDataFrame
.withColumnRenamed(QueryBuilderUtils.getEncounterColumn(firstCriterionId),
QueryBuilderUtils.getEncounterColumn(groupId))
}
if (withOrganizations) {
patientListDataFrame = patientListDataFrame
.withColumnRenamed(QueryBuilderUtils.getOrganizationsColumn(firstCriterionId),
Expand Down Expand Up @@ -404,6 +416,7 @@ class QueryBuilderTemporalConstraint(val options: QueryExecutionOptions) {
criterionTagsMap: Map[Short, CriterionTags]): DataFrame = {

val withOrganizations = criterionTagsMap(groupId).withOrganizations
val isInTemporalConstraint = criterionTagsMap(groupId).isInTemporalConstraint
// tagsPerId is updated for the criteria with id "group_id"
// dict_df is filtered for the temporal criterion (to be used only locally so in_dict_df is returned)
var criterionConcernedByATemporalConstraintIdList: List[Short] = List()
Expand Down Expand Up @@ -443,11 +456,14 @@ class QueryBuilderTemporalConstraint(val options: QueryExecutionOptions) {
)
} else
throw new Exception("required temporal constraints are not implemented")
applyTemporalConstraintOnGroupDataFrame(criterionConcernedByATemporalConstraintDataFrame,
patientListOfTemporalConstraintDataFrame,
idList.head,
groupId,
withOrganizations)
applyTemporalConstraintOnGroupDataFrame(
criterionConcernedByATemporalConstraintDataFrame,
patientListOfTemporalConstraintDataFrame,
idList.head,
groupId,
isInTemporalConstraint,
withOrganizations
)
} else criterionConcernedByATemporalConstraintDataFrame
})

Expand All @@ -460,7 +476,11 @@ class QueryBuilderTemporalConstraint(val options: QueryExecutionOptions) {
List(
QueryBuilderUtils.getOrganizationsColumn(
groupId))
else List())
else List()) ++ (if (isInTemporalConstraint)
List(
QueryBuilderUtils
.getEncounterColumn(groupId))
else List())

joinAllCriteriaConcernedOrNotByATemporalConstraint(
criterionConcernedByATemporalConstraintDataFrame: Option[DataFrame],
Expand Down
4 changes: 4 additions & 0 deletions src/test/resources/testCases/liveTestTmp/expected.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
subject_id
3
1
2
79 changes: 79 additions & 0 deletions src/test/resources/testCases/liveTestTmp/request.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
{
"_type": "request",
"instance_id": "b4cd6a68-94e0-4539-87aa-f4f80323c645",
"request": {
"_id": 0,
"_type": "andGroup",
"criteria": [
{
"_id": 1,
"_type": "basicResource",
"criteria": [],
"dateRangeList": [],
"filterFhir": "subject.active=true&class=urg&start-age-visit=le6570",
"filterSolr": "fq=class:*\\\\|urg\\\\|*&fq=extension.startAgeVisit:[* TO 6570]&fq=_ref.patient.active:(true)&fq=-meta.security:\"http://terminology.hl7.org/CodeSystem/v3-ActCode|NOLIST\"",
"isInclusive": true,
"occurrence": {
"n": 1,
"operator": ">="
},
"resourceType": "Encounter",
"temporalConstraints": []
},
{
"_id": -1,
"_type": "andGroup",
"criteria": [
{
"_id": 2,
"_type": "basicResource",
"criteria": [],
"dateRangeList": [],
"filterFhir": "subject.active=true&code=V,X60-X84&_source=ORBIS",
"filterSolr": "fq=code:*\\\\|V\\\\|* OR code:*\\\\|X60\\\\-X84\\\\|*&fq=meta.source:(ORBIS)&fq=-meta.security:\"http://terminology.hl7.org/CodeSystem/v3-ActCode|NOLIST\"",
"isInclusive": true,
"occurrence": {
"n": 1,
"operator": ">="
},
"resourceType": "Condition",
"temporalConstraints": []
},
{
"_id": 3,
"_type": "basicResource",
"criteria": [],
"dateRangeList": [],
"filterFhir": "subject.active=true&start-age-visit=le6570",
"filterSolr": "fq=extension.startAgeVisit:[* TO 6570]&fq=_ref.patient.active:(true)&fq=-meta.security:\"http://terminology.hl7.org/CodeSystem/v3-ActCode|NOLIST\"",
"isInclusive": true,
"occurrence": {
"n": 1,
"operator": ">="
},
"resourceType": "Encounter",
"temporalConstraints": []
}
],
"dateRangeList": [],
"isInclusive": true,
"temporalConstraints": []
}
],
"dateRangeList": [],
"isInclusive": true,
"temporalConstraints": [
{
"constraintType": "sameEncounter",
"idList": "all"
}
]
},
"sourcePopulation": {
"caresiteCohortList": [
44121,
87992
]
},
"temporalConstraints": []
}
7 changes: 7 additions & 0 deletions src/test/resources/testCases/liveTestTmp/resource_1.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
_subject;_visit
1;1
2;2
3;3
4;4
5;5
6;6
6 changes: 6 additions & 0 deletions src/test/resources/testCases/liveTestTmp/resource_2.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
_subject;_visit
1;1
2;2
3;3
4;4
5;5
4 changes: 4 additions & 0 deletions src/test/resources/testCases/liveTestTmp/resource_3.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
_subject;_visit
1;1
2;2
3;3
Original file line number Diff line number Diff line change
@@ -1,51 +1,79 @@
{
"sourcePopulation": {
"caresiteCohortList": [
69166,
42699
]
},
"_type": "request",
"instance_id": "b4cd6a68-94e0-4539-87aa-f4f80323c645",
"request": {
"_type": "andGroup",
"_id": 0,
"isInclusive": true,
"_type": "andGroup",
"criteria": [
{
"_type": "basicResource",
"_id": 1,
"_type": "basicResource",
"criteria": [],
"dateRangeList": [],
"filterFhir": "subject.active=true&class=urg&start-age-visit=le6570",
"filterSolr": "fq=class:*\\\\|urg\\\\|*&fq=extension.startAgeVisit:[* TO 6570]&fq=_ref.patient.active:(true)&fq=-meta.security:\"http://terminology.hl7.org/CodeSystem/v3-ActCode|NOLIST\"",
"isInclusive": true,
"resourceType": "conditionAphp",
"filterSolr": "(codeList:R26) AND active:true",
"filterFhir": "codeList=R26",
"occurrence": {
"n": 1,
"operator": ">=",
"sameEncounter": false,
"sameDay": false
}
"operator": ">="
},
"resourceType": "Encounter",
"temporalConstraints": []
},
{
"_type": "basicResource",
"_id": 2,
"_id": -1,
"_type": "andGroup",
"criteria": [
{
"_id": 2,
"_type": "basicResource",
"criteria": [],
"dateRangeList": [],
"filterFhir": "subject.active=true&code=V,X60-X84&_source=ORBIS",
"filterSolr": "fq=code:*\\\\|V\\\\|* OR code:*\\\\|X60\\\\-X84\\\\|*&fq=meta.source:(ORBIS)&fq=-meta.security:\"http://terminology.hl7.org/CodeSystem/v3-ActCode|NOLIST\"",
"isInclusive": true,
"occurrence": {
"n": 1,
"operator": ">="
},
"resourceType": "Condition",
"temporalConstraints": []
},
{
"_id": 3,
"_type": "basicResource",
"criteria": [],
"dateRangeList": [],
"filterFhir": "subject.active=true&start-age-visit=le6570",
"filterSolr": "fq=extension.startAgeVisit:[* TO 6570]&fq=_ref.patient.active:(true)&fq=-meta.security:\"http://terminology.hl7.org/CodeSystem/v3-ActCode|NOLIST\"",
"isInclusive": true,
"occurrence": {
"n": 1,
"operator": ">="
},
"resourceType": "Encounter",
"temporalConstraints": []
}
],
"dateRangeList": [],
"isInclusive": true,
"resourceType": "observationAphp",
"filterSolr": "((part-of:A0283* OR part-of:E6954* OR part-of:F9934* OR part-of:G7716* OR part-of:J5184*))",
"filterFhir": "part-of=A0283,E6954,F9934,G7716,J5184",
"occurrence": {
"n": 1,
"operator": ">=",
"sameEncounter": false,
"sameDay": false
}
"temporalConstraints": []
}
],
"dateRangeList": [],
"isInclusive": true,
"temporalConstraints": [
{
"idList": "all",
"constraintType": "sameEncounter"
"constraintType": "sameEncounter",
"idList": "all"
}
]
},
"id": 1230
"sourcePopulation": {
"caresiteCohortList": [
44121,
87992
]
},
"temporalConstraints": []
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
_subject;_visit
1;1
2;2
3;3
4;4
5;5
6;6
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,11 @@ class QueryBuilderTest extends AnyFunSuiteLike with DatasetComparer {
}
result
}

test("liveTest") {
testCaseEvaluate("liveTestTmp")
}

test("custom") {
testCaseEvaluate("testCustom")
}
Expand Down

0 comments on commit 9910aa2

Please sign in to comment.