Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
1fa1d69
Support for datetime calculations in cohort definitions
jcnamendiOdysseus Dec 18, 2023
b9b5820
update
jcnamendiOdysseus Dec 29, 2023
6fd8ecd
update/412023
jcnamendiOdysseus Jan 4, 2024
07a7160
add sql test
jcnamendiOdysseus Jan 8, 2024
eaf44d5
fix
jcnamendiOdysseus Jan 9, 2024
6dc3918
Merge remote-tracking branch 'origin/is/2886' into issues-2886
jcnamendiOdysseus Jan 9, 2024
603c800
update test
jcnamendiOdysseus Jan 9, 2024
fe4f7e5
fix indent on editor
jcnamendiOdysseus Jan 9, 2024
75a2906
Merge pull request #6 from OHDSI/master
alex-odysseus Jan 15, 2024
3210fae
Merge remote-tracking branch 'remotes/origin/master' into issues-2886
Jan 15, 2024
e7f90a6
remove jar
jcnamendiOdysseus Jan 15, 2024
0036dc0
Merge remote-tracking branch 'origin/issues-2886' into issues-2886
jcnamendiOdysseus Jan 15, 2024
4d0cb33
Support for datetime calculations in cohort definitions
jcnamendiOdysseus Dec 18, 2023
55b2eef
update
jcnamendiOdysseus Dec 29, 2023
806c85b
update/412023
jcnamendiOdysseus Jan 4, 2024
8a4eb23
add sql test
jcnamendiOdysseus Jan 8, 2024
f819d5e
fix
jcnamendiOdysseus Jan 9, 2024
5e03963
update test
jcnamendiOdysseus Jan 9, 2024
de9527c
fix indent on editor
jcnamendiOdysseus Jan 9, 2024
ca6bbfd
remove jar
jcnamendiOdysseus Jan 15, 2024
cebb8c5
Revert "fix"
jcnamendiOdysseus Jan 16, 2024
2ada34d
Merge remote-tracking branch 'origin/issues-2886' into issues-2886
jcnamendiOdysseus Jan 17, 2024
6fb7fd2
add tests
jcnamendiOdysseus Jan 17, 2024
a674bfe
Adding IntervalUnit to Criteria to specify datetime table columns whi…
Jan 23, 2024
4ca364a
Handling the "UseDatetime" Cohort option so that the event datetime v…
Feb 5, 2024
3a4786d
Leaving intermediate tables undeleted
Feb 19, 2024
6acb70d
Supplementing places which didn't handle useDatetime from Cohort Expr…
Feb 23, 2024
caca415
OMOP CDM 5.3.1 doesn't have procedure_end_datetime so that using proc…
May 20, 2024
6978dbc
Reverting back temporary tables truncating and deleting which was com…
Jul 15, 2024
674b028
issues-2886: Comparisons fix
Jul 22, 2024
77a2338
Merge remote-tracking branch 'upstream/master'
Aug 7, 2024
b1f11e8
Merge remote-tracking branch 'remotes/upstream/master'
Nov 11, 2024
a2d1384
Merge remote-tracking branch 'remotes/origin/datetime-support'
Dec 9, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ target
/.settings
/nbactions.xml
/nb-configuration.xml
/bin/
52 changes: 41 additions & 11 deletions src/main/java/org/ohdsi/circe/check/checkers/Comparisons.java
Original file line number Diff line number Diff line change
Expand Up @@ -102,18 +102,48 @@ public static Predicate<Concept> compare(Concept source) {
.build();
}

public static int compareTo(ObservationFilter filter, Window window) {

int range1 = filter.postDays + filter.priorDays;
int range2Start = 0, range2End = 0;
if (Objects.nonNull(window.start) && Objects.nonNull(window.start.days)) {
range2Start = window.start.coeff * window.start.days;
}
if (Objects.nonNull(window.end) && Objects.nonNull(window.end.days)) {
range2End = window.end.coeff * window.end.days;
}
return range1 - (range2End - range2Start);
/**
* If timeUnit is equal to values such as Hours, Minutes, Seconds, the values will be converted to seconds
* Otherwise it will return to the previous logic.
* @param filter
* @param window
* @return
*/
public static int compareTo(ObservationFilter filter, Window window) {
int range1, range2Start = 0, range2End = 0;
if (Objects.nonNull(window.start) && Objects.nonNull(window.start.timeUnit) && !IntervalUnit.DAY.getName().equals(window.start.timeUnit)) {
range1 = (filter.postDays + filter.priorDays) * 24 * 60 * 60;
range2Start = getTimeInSeconds(window.start);
range2End = getTimeInSeconds(window.end);
} else {
range1 = filter.postDays + filter.priorDays;
if (Objects.nonNull(window.start) && Objects.nonNull(window.start.days)) {
range2Start = window.start.coeff * window.start.days;
}
if (Objects.nonNull(window.end) && Objects.nonNull(window.end.days)) {
range2End = window.end.coeff * window.end.days;
}
}
return range1 - (range2End - range2Start);
}

/**
* @return Convert values to seconds.
*/
private static int getTimeInSeconds(Window.Endpoint endpoint) {
if (Objects.isNull(endpoint)) {
return 0;
}
int convertRate;
if (IntervalUnit.HOUR.getName().equals(endpoint.timeUnit)) {
convertRate = 60 * 60;
} else if (IntervalUnit.MINUTE.getName().equals(endpoint.timeUnit)) {
convertRate = 60;
} else convertRate = 1;
return Objects.nonNull(endpoint.timeUnitValue)
? endpoint.coeff * endpoint.timeUnitValue * convertRate
: 0;
}

public static boolean compare(Criteria c1, Criteria c2) {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,20 @@

package org.ohdsi.circe.check.checkers;

import static org.ohdsi.circe.check.operations.Operations.match;
import static org.ohdsi.circe.cohortdefinition.DateOffsetStrategy.DateField.StartDate;

import java.util.Objects;
import org.ohdsi.circe.check.WarningSeverity;
import org.ohdsi.circe.cohortdefinition.CohortExpression;
import org.ohdsi.circe.cohortdefinition.DateOffsetStrategy;

import java.util.Arrays;
import java.util.List;
import java.util.Objects;

import static org.ohdsi.circe.check.operations.Operations.match;
import static org.ohdsi.circe.cohortdefinition.DateOffsetStrategy.DateField.StartDate;

public class ExitCriteriaDaysOffsetCheck extends BaseCheck {

private static final String DAYS_OFFSET_WARNING = "Cohort Exit criteria: Days offset from start date should be greater than 0";
private static final String DAYS_OFFSET_WARNING = "Cohort Exit criteria: %ss offset from start date should be greater than 0";

@Override
protected WarningSeverity defineSeverity() {
Expand All @@ -40,9 +43,9 @@ protected WarningSeverity defineSeverity() {
protected void check(CohortExpression expression, WarningReporter reporter) {

match(expression.endStrategy)
.isA(DateOffsetStrategy.class)
.then(s -> match((DateOffsetStrategy)s)
.when(dateOffsetStrategy -> Objects.equals(StartDate, dateOffsetStrategy.dateField) && 0 == dateOffsetStrategy.offset)
.then(() -> reporter.add(DAYS_OFFSET_WARNING)));
.isA(DateOffsetStrategy.class)
.then(s -> match((DateOffsetStrategy)s)
.when(dateOffsetStrategy -> Objects.equals(StartDate, dateOffsetStrategy.dateField) && 0 == dateOffsetStrategy.offsetUnitValue)
.then(dateOffsetStrategy -> reporter.add(String.format(DAYS_OFFSET_WARNING, dateOffsetStrategy.offsetUnit))));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,10 @@ protected void checkCriteria(CorelatedCriteria criteria, String groupName, Warni
String name = CriteriaNameHelper.getCriteriaName(criteria.criteria) + " at " + groupName;
Execution addWarning = () -> reporter.add(WARNING, name);
match(criteria)
.when(c -> c.startWindow != null && ((c.startWindow.start != null
&& c.startWindow.start.days != null) || (c.startWindow.end != null
&& c.startWindow.end.days != null)))
.when(c -> c.startWindow != null && ((c.startWindow.start != null && c.startWindow.start.days != null)
|| (c.startWindow.end != null && c.startWindow.end.days != null))
|| c.startWindow != null && (( c.startWindow.start != null && c.startWindow.start.timeUnitValue != null)
|| (c.startWindow.end != null) && c.startWindow.end.timeUnitValue != null))
.then(cc -> match(cc.criteria)
.isA(ConditionEra.class)
.then(c -> match((ConditionEra)c)
Expand Down
22 changes: 14 additions & 8 deletions src/main/java/org/ohdsi/circe/check/checkers/RangeCheck.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import org.ohdsi.circe.cohortdefinition.Window;

import java.util.Objects;
import java.util.Optional;

public class RangeCheck extends BaseValueCheck {
private static final String NEGATIVE_VALUE_ERROR = "Time window in criteria \"%s\" has negative value %d at %s";
Expand Down Expand Up @@ -52,19 +53,24 @@ protected void checkInclusionRules(final CohortExpression expression, WarningRep
}

private void checkWindow(Window window, WarningReporter reporter, String name) {
if (Objects.isNull(window)) {
return;
}
checkAndReportIfNegative(window.start, reporter, name, "start");
checkAndReportIfNegative(window.end, reporter, name, "end");

if (Objects.nonNull(window)) {
if (Objects.nonNull(window.start) && Objects.nonNull(window.start.days) && window.start.days < 0) {
reporter.add(NEGATIVE_VALUE_ERROR, name, window.start.days, "start");
}
if (Objects.nonNull(window.end) && Objects.nonNull(window.end.days) && window.end.days < 0) {
reporter.add(NEGATIVE_VALUE_ERROR, name, window.end.days, "end");
}
}

private void checkAndReportIfNegative(Window.Endpoint windowDetails, WarningReporter reporter, String name, String type) {
if (Objects.nonNull(windowDetails) && Objects.nonNull(windowDetails.days) && windowDetails.days < 0) {
reporter.add(NEGATIVE_VALUE_ERROR, name, windowDetails.days, type);
} else if (Objects.nonNull(windowDetails) && Objects.nonNull(windowDetails.timeUnitValue) && windowDetails.timeUnitValue < 0) {
reporter.add(NEGATIVE_VALUE_ERROR, name, windowDetails.timeUnitValue, type);
}
}

private void checkObservationFilter(ObservationFilter filter, WarningReporter reporter, String name) {

private void checkObservationFilter(ObservationFilter filter, WarningReporter reporter, String name) {
if (Objects.nonNull(filter)) {
if (filter.priorDays < 0) {
reporter.add(NEGATIVE_VALUE_ERROR, name, filter.priorDays, "prior days");
Expand Down
23 changes: 16 additions & 7 deletions src/main/java/org/ohdsi/circe/check/checkers/TimePatternCheck.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,7 @@

package org.ohdsi.circe.check.checkers;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import org.ohdsi.circe.check.WarningSeverity;
Expand Down Expand Up @@ -83,16 +80,28 @@ private String formatTimeWindow(TimeWindowInfo ti) {
}

private String formatDays(Window.Endpoint endpoint) {
return Objects.nonNull(endpoint.days) ? String.valueOf(endpoint.days) : "all";
return Objects.nonNull(endpoint.days) ? String.valueOf(endpoint.days) :
Objects.nonNull(endpoint.timeUnitValue) ? String.valueOf(endpoint.timeUnitValue) : "all";

}

private String formatCoeff(Window.Endpoint endpoint) {
return endpoint.coeff < 0 ? "before " : "after ";
}


private Integer startDays(Window window) {
return Objects.nonNull(window) && Objects.nonNull(window.start) ?
(Objects.nonNull(window.start.days) ? window.start.days : 0) * window.start.coeff : 0;
return Optional.ofNullable(window)
.map(w -> w.start)
.map(start -> {
int coefficient = Optional.ofNullable(start.coeff).orElse(0);
return Optional.ofNullable(start.days)
.map(days -> days * coefficient)
.orElseGet(() -> Optional.ofNullable(start.timeUnitValue)
.map(timeUnitValue -> timeUnitValue * coefficient)
.orElse(0));
})
.orElse(0);
}

class TimeWindowInfo {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,13 @@ public class CohortExpression implements CdmCompatibilitySpec {

@JsonProperty("CensorWindow")
public Period censorWindow;

/**
* If specified the datetime columns should be used in Criteria instead of date
*/
@JsonProperty("UseDatetime")
public Boolean useDatetime;


@Override
public String getCdmVersionRange() {
Expand Down
Loading