This repository has been archived by the owner on Apr 8, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 20
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #385 from ehrbase/refactoring/sofascore
Refactor SOFA score
- Loading branch information
Showing
15 changed files
with
15,410 additions
and
14,502 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
64 changes: 60 additions & 4 deletions
64
...rg/ehrbase/fhirbridge/ehr/converter/specific/sofascore/SofaScoreCompositionConverter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,18 +1,74 @@ | ||
/* | ||
* Copyright 2020-2021 the original author or authors. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* https://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
|
||
package org.ehrbase.fhirbridge.ehr.converter.specific.sofascore; | ||
|
||
import org.ehrbase.fhirbridge.ehr.converter.ConversionException; | ||
import org.ehrbase.fhirbridge.ehr.converter.generic.ObservationToCompositionConverter; | ||
import org.ehrbase.fhirbridge.ehr.opt.sofacomposition.SOFAComposition; | ||
import org.ehrbase.fhirbridge.ehr.opt.sofacomposition.definition.SofaScoreKategorieElement; | ||
import org.ehrbase.fhirbridge.ehr.opt.sofacomposition.definition.StatusDefiningCode; | ||
import org.hl7.fhir.r4.model.Coding; | ||
import org.hl7.fhir.r4.model.Observation; | ||
import org.springframework.lang.NonNull; | ||
|
||
import java.util.List; | ||
import java.util.stream.Collectors; | ||
|
||
@SuppressWarnings("java:S6212") | ||
public class SofaScoreCompositionConverter extends ObservationToCompositionConverter<SOFAComposition> { | ||
|
||
private final SofaScoreObservationConverter sofaScoreObservationConverter = new SofaScoreObservationConverter(); | ||
|
||
@Override | ||
public SOFAComposition convertInternal(@NonNull Observation resource) { | ||
SOFAComposition composition = new SOFAComposition(); | ||
composition.setSofaScore(sofaScoreObservationConverter.convert(resource)); | ||
return composition; | ||
public SOFAComposition convertInternal(@NonNull Observation observation) { | ||
SOFAComposition result = new SOFAComposition(); | ||
result.setStatusDefiningCode(convertStatus(observation)); | ||
result.setKategorie(convertCategory(observation)); | ||
result.setSofaScore(sofaScoreObservationConverter.convert(observation)); | ||
return result; | ||
} | ||
|
||
public StatusDefiningCode convertStatus(Observation observation) { | ||
Observation.ObservationStatus status = observation.getStatus(); | ||
switch (status) { | ||
case PRELIMINARY: | ||
return StatusDefiningCode.VORLAEUFIG; | ||
case FINAL: | ||
return StatusDefiningCode.FINAL; | ||
case REGISTERED: | ||
return StatusDefiningCode.REGISTRIERT; | ||
case AMENDED: | ||
return StatusDefiningCode.GEAENDERT; | ||
default: | ||
throw new ConversionException("Invalid Code " + status + "" + " for mapping of 'status', valid codes are: registered, final, amended and preliminary"); | ||
} | ||
} | ||
|
||
public List<SofaScoreKategorieElement> convertCategory(Observation observation) { | ||
return observation.getCategory() | ||
.stream() | ||
.flatMap(concept -> concept.getCoding().stream()) | ||
.filter(Coding::hasCode) | ||
.map(coding -> { | ||
SofaScoreKategorieElement element = new SofaScoreKategorieElement(); | ||
element.setValue(coding.getCode()); | ||
return element; | ||
}) | ||
.collect(Collectors.toList()); | ||
} | ||
} |
354 changes: 179 additions & 175 deletions
354
...rg/ehrbase/fhirbridge/ehr/converter/specific/sofascore/SofaScoreObservationConverter.java
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
70 changes: 70 additions & 0 deletions
70
src/test/java/org/ehrbase/fhirbridge/fhir/observation/SofaScoreIT.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
package org.ehrbase.fhirbridge.fhir.observation; | ||
|
||
import org.ehrbase.fhirbridge.comparators.CustomTemporalAcessorComparator; | ||
import org.ehrbase.fhirbridge.ehr.converter.ConversionException; | ||
import org.ehrbase.fhirbridge.ehr.converter.specific.sofascore.SofaScoreCompositionConverter; | ||
import org.ehrbase.fhirbridge.ehr.opt.sofacomposition.SOFAComposition; | ||
import org.ehrbase.fhirbridge.ehr.opt.sofacomposition.definition.SofaScoreKategorieElement; | ||
import org.ehrbase.fhirbridge.ehr.opt.sofacomposition.definition.SofaScoreObservation; | ||
import org.ehrbase.fhirbridge.fhir.AbstractMappingTestSetupIT; | ||
import org.hl7.fhir.r4.model.Observation; | ||
import org.javers.core.Javers; | ||
import org.javers.core.JaversBuilder; | ||
import org.javers.core.diff.Diff; | ||
import org.javers.core.metamodel.clazz.ValueObjectDefinition; | ||
import org.junit.jupiter.api.Test; | ||
|
||
import java.io.IOException; | ||
import java.time.temporal.TemporalAccessor; | ||
import java.util.List; | ||
|
||
import static org.junit.jupiter.api.Assertions.assertEquals; | ||
import static org.junit.jupiter.api.Assertions.assertThrows; | ||
|
||
class SofaScoreIT extends AbstractMappingTestSetupIT { | ||
|
||
public SofaScoreIT() { | ||
super("Observation/SofaScore/", Observation.class); | ||
} | ||
|
||
@Test | ||
void createSofaScore() throws IOException { | ||
create("create-sofa-score.json"); | ||
} | ||
|
||
@Test | ||
void createSofaScoreMapping() throws IOException { | ||
testMapping("create-sofa-score.json", "paragon-create-sofa-score.json"); | ||
} | ||
|
||
@Test | ||
void createSofaScoreGesamtergebnisMapping() throws IOException { | ||
testMapping("create-sofa-score_gesamtergebnis.json", "paragon-create-sofa-score_gesamtergebnis.json"); | ||
} | ||
|
||
@Override | ||
public Javers getJavers() { | ||
return JaversBuilder.javers() | ||
.registerValue(TemporalAccessor.class, new CustomTemporalAcessorComparator()) | ||
.registerValueObject(new ValueObjectDefinition(SOFAComposition.class, List.of("location", "feederAudit"))) | ||
.registerValueObject(SofaScoreObservation.class) | ||
.registerValueObject(SofaScoreKategorieElement.class) | ||
.build(); | ||
} | ||
|
||
@Override | ||
public Exception executeMappingException(String resource) throws IOException { | ||
Observation observation = (Observation) testFileLoader.loadResource(resource); | ||
SofaScoreCompositionConverter converter = new SofaScoreCompositionConverter(); | ||
return assertThrows(ConversionException.class, () -> converter.convert(observation)); | ||
} | ||
|
||
@Override | ||
public void testMapping(String resourcePath, String paragonPath) throws IOException { | ||
Observation observation = (Observation) super.testFileLoader.loadResource(resourcePath); | ||
SofaScoreCompositionConverter converter = new SofaScoreCompositionConverter(); | ||
SOFAComposition composition = converter.convert(observation); | ||
Diff diff = compareCompositions(getJavers(), paragonPath, composition); | ||
assertEquals(0, diff.getChanges().size()); | ||
} | ||
} |
176 changes: 176 additions & 0 deletions
176
src/test/resources/Observation/SofaScore/create-sofa-score.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,176 @@ | ||
{ | ||
"resourceType": "Observation", | ||
"status": "final", | ||
"meta": { | ||
"profile": [ | ||
"https://www.netzwerk-universitaetsmedizin.de/fhir/StructureDefinition/sofa-score" | ||
] | ||
}, | ||
"category": [ | ||
{ | ||
"coding": [ | ||
{ | ||
"system": "http://terminology.hl7.org/CodeSystem/observation-category", | ||
"code": "survey" | ||
} | ||
] | ||
} | ||
], | ||
"code": { | ||
"coding": [ | ||
{ | ||
"system": "https://www.netzwerk-universitaetsmedizin.de/fhir/CodeSystem/aaaaaa", | ||
"code": "aaa", | ||
"display": "SOFA-Scorea" | ||
}, | ||
{ | ||
"system": "https://www.netzwerk-universitaetsmedizin.de/fhir/CodeSystem/ecrf-parameter-codes", | ||
"code": "06", | ||
"display": "SOFA-Score" | ||
} | ||
], | ||
"text": "Sepsis-related organ failure assessment score" | ||
}, | ||
"subject": { | ||
"identifier": { | ||
"system": "urn:ietf:rfc:4122", | ||
"value": "{{patientId}}" | ||
} | ||
}, | ||
"effectiveDateTime": "2020-09-16", | ||
"component": [ | ||
{ | ||
"code": { | ||
"coding": [ | ||
{ | ||
"system": "https://www.netzwerk-universitaetsmedizin.de/fhir/CodeSystem/sofa-score", | ||
"code": "resp", | ||
"display": "Respiratory system" | ||
} | ||
], | ||
"text": "SOFA Respiratory system scoring category" | ||
}, | ||
"valueCodeableConcept": { | ||
"coding": [ | ||
{ | ||
"system": "https://www.netzwerk-universitaetsmedizin.de/fhir/CodeSystem/sofa-score", | ||
"code": "resp3", | ||
"display": "Respiratory system SOFA score 3" | ||
} | ||
], | ||
"text": "PaO2/FiO2 [mmHg (kPa)] < 200 (26.7) and mechanically ventilated" | ||
} | ||
}, | ||
{ | ||
"code": { | ||
"coding": [ | ||
{ | ||
"system": "https://www.netzwerk-universitaetsmedizin.de/fhir/CodeSystem/sofa-score", | ||
"code": "ns", | ||
"display": "Nervous system" | ||
} | ||
], | ||
"text": "SOFA Nervous system scoring category" | ||
}, | ||
"valueCodeableConcept": { | ||
"coding": [ | ||
{ | ||
"system": "https://www.netzwerk-universitaetsmedizin.de/fhir/CodeSystem/sofa-score", | ||
"code": "ns4", | ||
"display": "Nervous system SOFA score 4" | ||
} | ||
], | ||
"text": "Glasgow Coma Scale (GCS) < 6" | ||
} | ||
}, | ||
{ | ||
"code": { | ||
"coding": [ | ||
{ | ||
"system": "https://www.netzwerk-universitaetsmedizin.de/fhir/CodeSystem/sofa-score", | ||
"code": "cvs", | ||
"display": "Cardiovascular system" | ||
} | ||
], | ||
"text": "SOFA Cardiovascular system scoring category" | ||
}, | ||
"valueCodeableConcept": { | ||
"coding": [ | ||
{ | ||
"system": "https://www.netzwerk-universitaetsmedizin.de/fhir/CodeSystem/sofa-score", | ||
"code": "cvs0", | ||
"display": "Cardiovascular system SOFA score 0" | ||
} | ||
], | ||
"text": "Mean arterial pressure (MAP) ≥ 70 mmHg" | ||
} | ||
}, | ||
{ | ||
"code": { | ||
"coding": [ | ||
{ | ||
"system": "https://www.netzwerk-universitaetsmedizin.de/fhir/CodeSystem/sofa-score", | ||
"code": "liv", | ||
"display": "Liver" | ||
} | ||
], | ||
"text": "SOFA Liver scoring category" | ||
}, | ||
"valueCodeableConcept": { | ||
"coding": [ | ||
{ | ||
"system": "https://www.netzwerk-universitaetsmedizin.de/fhir/CodeSystem/sofa-score", | ||
"code": "liv1", | ||
"display": "Liver SOFA score 1" | ||
} | ||
], | ||
"text": "Bilirubin (mg/dl) [umol/L] 1.2-1.9 [20-32]" | ||
} | ||
}, | ||
{ | ||
"code": { | ||
"coding": [ | ||
{ | ||
"system": "https://www.netzwerk-universitaetsmedizin.de/fhir/CodeSystem/sofa-score", | ||
"code": "coa", | ||
"display": "Coagulation" | ||
} | ||
], | ||
"text": "SOFA Coagulation scoring category" | ||
}, | ||
"valueCodeableConcept": { | ||
"coding": [ | ||
{ | ||
"system": "https://www.netzwerk-universitaetsmedizin.de/fhir/CodeSystem/sofa-score", | ||
"code": "coa2", | ||
"display": "Coagulation SOFA score 2" | ||
} | ||
], | ||
"text": "Platelets×10^3/ul < 100" | ||
} | ||
}, | ||
{ | ||
"code": { | ||
"coding": [ | ||
{ | ||
"system": "https://www.netzwerk-universitaetsmedizin.de/fhir/CodeSystem/sofa-score", | ||
"code": "kid", | ||
"display": "Kidneys" | ||
} | ||
], | ||
"text": "SOFA Kidneys scoring category" | ||
}, | ||
"valueCodeableConcept": { | ||
"coding": [ | ||
{ | ||
"system": "https://www.netzwerk-universitaetsmedizin.de/fhir/CodeSystem/sofa-score", | ||
"code": "kid4", | ||
"display": "Kidneys SOFA score 4" | ||
} | ||
], | ||
"text": "Creatinine (mg/dl) [umol/L] (or urine output) > 5.0 [> 440] (or < 200 ml/d)" | ||
} | ||
} | ||
], | ||
"valueInteger": 15 | ||
} |
Oops, something went wrong.