Skip to content

Commit 6e217a4

Browse files
alex-odysseuswiverngitOleg KuzikOleg Kuzik
authored
Temporal annual distribution functionality and temporal FeatureExtraction capability enablement (#2388)
--------- Co-authored-by: wivern <[email protected]> Co-authored-by: git <[email protected]> Co-authored-by: Oleg Kuzik <[email protected]> Co-authored-by: Oleg Kuzik <[email protected]> Co-authored-by: oleg-odysseus <[email protected]>
1 parent 1327d98 commit 6e217a4

29 files changed

+957
-59
lines changed

pom.xml

+2-2
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
<shiro.version>1.12.0</shiro.version>
2424
<dom4j.version>2.1.3</dom4j.version>
2525
<hydra.version>0.4.0</hydra.version>
26-
<featureExtraction.version>3.2.0</featureExtraction.version>
26+
<featureExtraction.version>3.8.0</featureExtraction.version>
2727
<tomcat.embed.version>8.5.87</tomcat.embed.version>
2828

2929
<commons-fileupload.version>1.5</commons-fileupload.version>
@@ -1148,7 +1148,7 @@
11481148
<dependency>
11491149
<groupId>org.ohdsi</groupId>
11501150
<artifactId>SkeletonCohortCharacterization</artifactId>
1151-
<version>1.2.1</version>
1151+
<version>2.0.1</version>
11521152
<exclusions>
11531153
<exclusion>
11541154
<groupId>org.ohdsi</groupId>

src/main/java/org/ohdsi/webapi/cohortcharacterization/CcController.java

+10-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import org.ohdsi.webapi.cohortcharacterization.dto.CcPrevalenceStat;
1919
import org.ohdsi.webapi.cohortcharacterization.dto.CcResult;
2020
import org.ohdsi.webapi.cohortcharacterization.dto.CcShortDTO;
21+
import org.ohdsi.webapi.cohortcharacterization.dto.CcTemporalResult;
2122
import org.ohdsi.webapi.cohortcharacterization.dto.CcVersionFullDTO;
2223
import org.ohdsi.webapi.cohortcharacterization.dto.CohortCharacterizationDTO;
2324
import org.ohdsi.webapi.cohortcharacterization.dto.ExportExecutionResultRequest;
@@ -257,7 +258,7 @@ public CohortCharacterizationDTO update(@PathParam("id") final Long id, final Co
257258
final CohortCharacterizationEntity entity = conversionService.convert(dto, CohortCharacterizationEntity.class);
258259
entity.setId(id);
259260
final CohortCharacterizationEntity updatedEntity = service.updateCc(entity);
260-
return conversionService.convert(updatedEntity, CohortCharacterizationDTO.class);
261+
return convertCcToDto(updatedEntity);
261262
}
262263

263264
/**
@@ -445,6 +446,14 @@ public List<CcResult> getGenerationsResults(
445446
return service.findResultAsList(generationId, thresholdLevel);
446447
}
447448

449+
@GET
450+
@Path("/generation/{generationId}/temporalresult")
451+
@Produces(MediaType.APPLICATION_JSON)
452+
@Consumes(MediaType.APPLICATION_JSON)
453+
public List<CcTemporalResult> getGenerationTemporalResults(@PathParam("generationId") final Long generationId) {
454+
return service.findTemporalResultAsList(generationId);
455+
}
456+
448457
@POST
449458
@Path("/generation/{generationId}/result")
450459
@Produces(MediaType.APPLICATION_JSON)

src/main/java/org/ohdsi/webapi/cohortcharacterization/CcService.java

+6
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import org.ohdsi.webapi.cohortcharacterization.dto.CcPrevalenceStat;
77
import org.ohdsi.webapi.cohortcharacterization.dto.CcResult;
88
import org.ohdsi.webapi.cohortcharacterization.dto.CcShortDTO;
9+
import org.ohdsi.webapi.cohortcharacterization.dto.CcTemporalResult;
910
import org.ohdsi.webapi.cohortcharacterization.dto.CcVersionFullDTO;
1011
import org.ohdsi.webapi.cohortcharacterization.dto.CohortCharacterizationDTO;
1112
import org.ohdsi.webapi.cohortcharacterization.dto.ExecutionResultRequest;
@@ -15,6 +16,8 @@
1516
import org.ohdsi.webapi.cohortdefinition.event.CohortDefinitionChangedEvent;
1617
import org.ohdsi.webapi.feanalysis.event.FeAnalysisChangedEvent;
1718
import org.ohdsi.webapi.job.JobExecutionResource;
19+
import org.ohdsi.webapi.shiro.annotations.CcGenerationId;
20+
import org.ohdsi.webapi.shiro.annotations.DataSourceAccess;
1821
import org.ohdsi.webapi.tag.domain.HasTags;
1922
import org.ohdsi.webapi.tag.dto.TagNameListRequestDTO;
2023
import org.ohdsi.webapi.versioning.domain.CharacterizationVersion;
@@ -64,6 +67,9 @@ public interface CcService extends HasTags<Long> {
6467

6568
List<CcGenerationEntity> findGenerationsByCcIdAndSource(Long id, String sourceKey);
6669

70+
@DataSourceAccess
71+
List<CcTemporalResult> findTemporalResultAsList(@CcGenerationId Long generationId);
72+
6773
GenerationResults findResult(Long generationId, ExecutionResultRequest params);
6874

6975
List<CcResult> findResultAsList(Long generationId, float thresholdLevel);

src/main/java/org/ohdsi/webapi/cohortcharacterization/CcServiceImpl.java

+220-14
Large diffs are not rendered by default.

src/main/java/org/ohdsi/webapi/cohortcharacterization/GenerateCohortCharacterizationTasklet.java

+8-2
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import org.ohdsi.sql.SqlSplit;
2323
import org.ohdsi.sql.SqlTranslate;
2424
import org.ohdsi.webapi.cohortcharacterization.converter.SerializedCcToCcConverter;
25+
import org.ohdsi.webapi.cohortcharacterization.domain.CcFeAnalysisEntity;
2526
import org.ohdsi.webapi.cohortcharacterization.domain.CohortCharacterizationEntity;
2627
import org.ohdsi.webapi.cohortcharacterization.repository.AnalysisGenerationInfoEntityRepository;
2728
import org.ohdsi.webapi.common.generation.AnalysisTasklet;
@@ -37,6 +38,7 @@
3738

3839
import java.sql.SQLException;
3940
import java.util.Map;
41+
import java.util.Optional;
4042

4143
import static org.ohdsi.webapi.Constants.Params.*;
4244

@@ -72,12 +74,16 @@ protected String[] prepareQueries(ChunkContext chunkContext, CancelableJdbcTempl
7274
saveInfoWithinTheSeparateTransaction(jobId, serializedDesign, userEntity);
7375
final Integer sourceId = Integer.valueOf(jobParams.get(SOURCE_ID).toString());
7476
final Source source = sourceService.findBySourceId(sourceId);
75-
final String cohortTable = jobParams.get(TARGET_TABLE).toString();
77+
final String cohortTable = String.format("%s.%s", SourceUtils.getTempQualifier(source), jobParams.get(TARGET_TABLE).toString());
7678
final String sessionId = jobParams.get(SESSION_ID).toString();
7779
final String tempSchema = SourceUtils.getTempQualifier(source);
80+
boolean includeAnnual = cohortCharacterization.getCcFeatureAnalyses().stream()
81+
.anyMatch(fe -> Optional.ofNullable(fe.getIncludeAnnual()).orElse(false));
82+
boolean includeTemporal = cohortCharacterization.getCcFeatureAnalyses().stream()
83+
.anyMatch(fe -> Optional.ofNullable(fe.getIncludeTemporal()).orElse(false));
7884
CCQueryBuilder ccQueryBuilder = new CCQueryBuilder(cohortCharacterization, cohortTable, sessionId,
7985
SourceUtils.getCdmQualifier(source), SourceUtils.getResultsQualifier(source),
80-
SourceUtils.getVocabularyQualifier(source), tempSchema, jobId);
86+
SourceUtils.getVocabularyQualifier(source), tempSchema, jobId, includeAnnual, includeTemporal);
8187
String sql = ccQueryBuilder.build();
8288

8389
/*

src/main/java/org/ohdsi/webapi/cohortcharacterization/converter/BaseCcDTOToCcEntityConverter.java

+11-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import org.apache.commons.lang3.StringUtils;
55
import org.ohdsi.analysis.Utils;
66
import org.ohdsi.analysis.cohortcharacterization.design.CcResultType;
7+
import org.ohdsi.webapi.cohortcharacterization.domain.CcFeAnalysisEntity;
78
import org.ohdsi.webapi.cohortcharacterization.domain.CcStrataConceptSetEntity;
89
import org.ohdsi.webapi.cohortcharacterization.domain.CcParamEntity;
910
import org.ohdsi.webapi.cohortcharacterization.domain.CcStrataEntity;
@@ -49,7 +50,16 @@ public CohortCharacterizationEntity convert(T source) {
4950
fa.setStatType(CcResultType.PREVALENCE);
5051
}
5152
});
52-
cohortCharacterization.setFeatureAnalyses(converterUtils.convertSet(source.getFeatureAnalyses(), FeAnalysisEntity.class));
53+
cohortCharacterization.setFeatureAnalyses(
54+
source.getFeatureAnalyses().stream().map(fa -> {
55+
CcFeAnalysisEntity feAnalysisEntity = new CcFeAnalysisEntity();
56+
feAnalysisEntity.setFeatureAnalysis(conversionService.convert(fa, FeAnalysisEntity.class));
57+
feAnalysisEntity.setCohortCharacterization(cohortCharacterization);
58+
feAnalysisEntity.setIncludeAnnual(fa.getIncludeAnnual());
59+
feAnalysisEntity.setIncludeTemporal(fa.getIncludeTemporal());
60+
return feAnalysisEntity;
61+
}).collect(Collectors.toSet())
62+
);
5363

5464
cohortCharacterization.setParameters(converterUtils.convertSet(source.getParameters(), CcParamEntity.class));
5565
cohortCharacterization.setStratas(converterUtils.convertSet(source.getStratas(), CcStrataEntity.class));

src/main/java/org/ohdsi/webapi/cohortcharacterization/converter/CcToCcDTOConverter.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ public CohortCharacterizationDTO convert(final CohortCharacterizationEntity sour
1515
final CohortCharacterizationDTO cohortCharacterizationDTO = super.convert(source);
1616

1717
cohortCharacterizationDTO.setCohorts(converterUtils.convertSet(source.getCohortDefinitions(), CohortMetadataImplDTO.class));
18-
cohortCharacterizationDTO.setFeatureAnalyses(converterUtils.convertSet(source.getFeatureAnalyses(), FeAnalysisShortDTO.class));
18+
cohortCharacterizationDTO.setFeatureAnalyses(converterUtils.convertSet(source.getCcFeatureAnalyses(), FeAnalysisShortDTO.class));
1919
return cohortCharacterizationDTO;
2020
}
2121

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
package org.ohdsi.webapi.cohortcharacterization.domain;
2+
3+
import org.hibernate.annotations.GenericGenerator;
4+
import org.hibernate.annotations.Parameter;
5+
import org.ohdsi.analysis.cohortcharacterization.design.FeatureAnalysis;
6+
import org.ohdsi.analysis.cohortcharacterization.design.FeatureAnalysisDomain;
7+
import org.ohdsi.analysis.cohortcharacterization.design.FeatureAnalysisType;
8+
import org.ohdsi.webapi.feanalysis.domain.FeAnalysisEntity;
9+
10+
import javax.persistence.Column;
11+
import javax.persistence.Entity;
12+
import javax.persistence.GeneratedValue;
13+
import javax.persistence.Id;
14+
import javax.persistence.JoinColumn;
15+
import javax.persistence.ManyToOne;
16+
import javax.persistence.Table;
17+
import java.util.Optional;
18+
import java.util.function.Function;
19+
import java.util.function.Supplier;
20+
21+
@Entity
22+
@Table(name = "cc_analysis")
23+
public class CcFeAnalysisEntity implements FeatureAnalysis {
24+
25+
@Id
26+
@GenericGenerator(
27+
name = "cc_analysis_generator",
28+
strategy = "org.hibernate.id.enhanced.SequenceStyleGenerator",
29+
parameters = {
30+
@Parameter(name = "sequence_name", value = "cc_analysis_seq"),
31+
@Parameter(name = "increment_size", value = "1")
32+
}
33+
)
34+
@GeneratedValue(generator = "cc_analysis_generator")
35+
private Long id;
36+
@ManyToOne(optional = false)
37+
@JoinColumn(name = "cohort_characterization_id")
38+
private CohortCharacterizationEntity cohortCharacterization;
39+
@ManyToOne(optional = false)
40+
@JoinColumn(name = "fe_analysis_id")
41+
private FeAnalysisEntity featureAnalysis;
42+
@Column(name = "include_annual")
43+
private Boolean includeAnnual;
44+
@Column(name = "include_temporal")
45+
private Boolean includeTemporal;
46+
47+
public CohortCharacterizationEntity getCohortCharacterization() {
48+
return cohortCharacterization;
49+
}
50+
51+
public void setCohortCharacterization(CohortCharacterizationEntity cohortCharacterization) {
52+
this.cohortCharacterization = cohortCharacterization;
53+
}
54+
55+
public FeAnalysisEntity getFeatureAnalysis() {
56+
return featureAnalysis;
57+
}
58+
59+
public void setFeatureAnalysis(FeAnalysisEntity featureAnalysis) {
60+
this.featureAnalysis = featureAnalysis;
61+
}
62+
63+
public Long getId() {
64+
return id;
65+
}
66+
67+
public void setId(Long id) {
68+
this.id = id;
69+
}
70+
71+
public Boolean getIncludeAnnual() {
72+
return includeAnnual;
73+
}
74+
75+
public void setIncludeAnnual(Boolean includeAnnual) {
76+
this.includeAnnual = includeAnnual;
77+
}
78+
79+
public Boolean getIncludeTemporal() {
80+
return includeTemporal;
81+
}
82+
83+
public void setIncludeTemporal(Boolean includeTemporal) {
84+
this.includeTemporal = includeTemporal;
85+
}
86+
87+
private <T> T mapFeatureAnalysis(Function<FeAnalysisEntity, T> getter) {
88+
return Optional.ofNullable(featureAnalysis).map(getter).orElse(null);
89+
}
90+
91+
@Override
92+
public FeatureAnalysisType getType() {
93+
return mapFeatureAnalysis(FeatureAnalysis::getType);
94+
}
95+
96+
@Override
97+
public String getName() {
98+
return mapFeatureAnalysis(FeatureAnalysis::getName);
99+
}
100+
101+
@Override
102+
public FeatureAnalysisDomain getDomain() {
103+
return mapFeatureAnalysis(FeatureAnalysis::getDomain);
104+
}
105+
106+
@Override
107+
public String getDescr() {
108+
return mapFeatureAnalysis(FeatureAnalysis::getDescr);
109+
}
110+
111+
@Override
112+
public Object getDesign() {
113+
return mapFeatureAnalysis(FeatureAnalysis::getDesign);
114+
}
115+
}

src/main/java/org/ohdsi/webapi/cohortcharacterization/domain/CohortCharacterizationEntity.java

+14-9
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package org.ohdsi.webapi.cohortcharacterization.domain;
22

33
import java.util.*;
4+
import java.util.stream.Collectors;
45

56
import javax.persistence.CascadeType;
67
import javax.persistence.Column;
@@ -52,11 +53,9 @@ public class CohortCharacterizationEntity extends CommonEntityExt<Long> implemen
5253
inverseJoinColumns = @JoinColumn(name = "cohort_id", referencedColumnName = "id"))
5354
private Set<CohortDefinition> cohortDefinitions = new HashSet<>();
5455

55-
@ManyToMany(targetEntity = FeAnalysisEntity.class, fetch = FetchType.LAZY)
56-
@JoinTable(name = "cc_analysis",
57-
joinColumns = @JoinColumn(name = "cohort_characterization_id", referencedColumnName = "id"),
58-
inverseJoinColumns = @JoinColumn(name = "fe_analysis_id", referencedColumnName = "id"))
59-
private Set<FeAnalysisEntity> featureAnalyses = new HashSet<>();
56+
@OneToMany(orphanRemoval = true)
57+
@JoinColumn(name = "cohort_characterization_id", insertable = false, updatable = false, nullable = false)
58+
private Set<CcFeAnalysisEntity> featureAnalyses = new HashSet<>();
6059

6160
@OneToMany(mappedBy = "cohortCharacterization", fetch = FetchType.LAZY, targetEntity = CcParamEntity.class)
6261
private Set<CcParamEntity> parameters = new HashSet<>();
@@ -89,6 +88,12 @@ public Set<CohortDefinition> getCohorts() {
8988

9089
@Override
9190
public Set<FeAnalysisEntity> getFeatureAnalyses() {
91+
return featureAnalyses != null ?
92+
featureAnalyses.stream().map(CcFeAnalysisEntity::getFeatureAnalysis).collect(Collectors.toSet()) :
93+
Collections.emptySet();
94+
}
95+
96+
public Set<CcFeAnalysisEntity> getCcFeatureAnalyses() {
9297
return featureAnalyses;
9398
}
9499

@@ -97,6 +102,10 @@ public Set<CcParamEntity> getParameters() {
97102
return parameters;
98103
}
99104

105+
public void setFeatureAnalyses(Set<CcFeAnalysisEntity> featureAnalyses) {
106+
this.featureAnalyses = featureAnalyses;
107+
}
108+
100109
@Override
101110
public Long getId() {
102111
return id;
@@ -126,10 +135,6 @@ public void setParameters(final Set<CcParamEntity> parameters) {
126135
this.parameters = parameters;
127136
}
128137

129-
public void setFeatureAnalyses(final Set<FeAnalysisEntity> featureAnalyses) {
130-
this.featureAnalyses = featureAnalyses;
131-
}
132-
133138
public Set<CohortDefinition> getCohortDefinitions() {
134139
return cohortDefinitions;
135140
}

0 commit comments

Comments
 (0)