mirror of
https://github.com/pcvolkmer/mv64e-onkostar-data.git
synced 2025-09-13 16:02:52 +00:00
feat: add "Stützende molekulare Alterationen"
This commit is contained in:
160
src/main/java/dev/pcvolkmer/onco/datamapper/genes/Gene.java
Normal file
160
src/main/java/dev/pcvolkmer/onco/datamapper/genes/Gene.java
Normal file
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
* This file is part of mv64e-onkostar-data
|
||||
*
|
||||
* Copyright (C) 2025 Paul-Christian Volkmer
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package dev.pcvolkmer.onco.datamapper.genes;
|
||||
|
||||
import dev.pcvolkmer.mv64e.mtb.Chromosome;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Represents a gene
|
||||
*
|
||||
* @author Paul-Christian Volkmer
|
||||
* @since 0.1.0
|
||||
*/
|
||||
// Originally taken from https://github.com/pcvolkmer/onkostar-plugin-genes/blob/master/api/src/main/java/dev/pcvolkmer/onkostar/genes/Gene.java
|
||||
public class Gene {
|
||||
|
||||
private final String hgncId;
|
||||
|
||||
private final String ensembleId;
|
||||
|
||||
private final String symbol;
|
||||
|
||||
private final String name;
|
||||
|
||||
private final String chromosome;
|
||||
|
||||
Gene(
|
||||
String hgncId,
|
||||
String ensembleId,
|
||||
String symbol,
|
||||
String name,
|
||||
String chromosome
|
||||
) {
|
||||
this.hgncId = hgncId;
|
||||
this.ensembleId = ensembleId;
|
||||
this.symbol = symbol;
|
||||
this.name = name;
|
||||
this.chromosome = chromosome;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the HGNC ID of this gene
|
||||
*
|
||||
* @return the HGNC ID
|
||||
*/
|
||||
public String getHgncId() {
|
||||
return hgncId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the EnsemblID of this gene
|
||||
*
|
||||
* @return the EnsemblID
|
||||
*/
|
||||
public String getEnsemblId() {
|
||||
return ensembleId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Symbol of this gene
|
||||
*
|
||||
* @return the Symbol
|
||||
*/
|
||||
public String getSymbol() {
|
||||
return symbol;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of this gene
|
||||
*
|
||||
* @return the name
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the chromosome(s) the gene is located at
|
||||
*
|
||||
* @return the chromosome(s)
|
||||
*/
|
||||
public String getChromosome() {
|
||||
return chromosome;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of chromosomes using form 'chr?'
|
||||
*
|
||||
* @return a list of chromosomes
|
||||
*/
|
||||
public List<Chromosome> getChromosomesInPropertyForm() {
|
||||
return Arrays.stream(this.chromosome.split(" "))
|
||||
.map(value -> {
|
||||
try {
|
||||
var pattern = Pattern.compile("^(\\d+|X|Y)");
|
||||
var matcher = pattern.matcher(value);
|
||||
if (matcher.find()) {
|
||||
return Chromosome.forValue(String.format("chr%s", matcher.group(0)));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// Nop
|
||||
}
|
||||
return null;
|
||||
})
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a chromosome using form 'chr...?' if one (single) chromosome listed
|
||||
*
|
||||
* @return an <code>Optional</code> containing the chromosome
|
||||
*/
|
||||
public Optional<Chromosome> getSingleChromosomeInPropertyForm() {
|
||||
var fixedChromosomes = this.getChromosomesInPropertyForm();
|
||||
|
||||
if (fixedChromosomes.size() == 1) {
|
||||
return Optional.of(fixedChromosomes.get(0));
|
||||
}
|
||||
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
Gene gene = (Gene) o;
|
||||
return Objects.equals(hgncId, gene.hgncId) && Objects.equals(ensembleId, gene.ensembleId) && Objects.equals(symbol, gene.symbol) && Objects.equals(name, gene.name) && Objects.equals(chromosome, gene.chromosome);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(hgncId, ensembleId, symbol, name, chromosome);
|
||||
}
|
||||
}
|
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* This file is part of mv64e-onkostar-data
|
||||
*
|
||||
* Copyright (C) 2025 Paul-Christian Volkmer
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package dev.pcvolkmer.onco.datamapper.genes;
|
||||
|
||||
import org.apache.commons.csv.CSVFormat;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* Utility class for genes
|
||||
*
|
||||
* @author Paul-Christian Volkmer
|
||||
* @since 0.1
|
||||
*/
|
||||
public class GeneUtils {
|
||||
|
||||
private GeneUtils() {
|
||||
// Empty
|
||||
}
|
||||
|
||||
public static Optional<Gene> findByHgncId(String hgncId) {
|
||||
return genes().stream().filter(gene -> gene.getHgncId().equalsIgnoreCase(hgncId)).findFirst();
|
||||
}
|
||||
|
||||
public static Optional<Gene> findBySymbol(String symbol) {
|
||||
return genes().stream().filter(gene -> gene.getSymbol().equalsIgnoreCase(symbol)).findFirst();
|
||||
}
|
||||
|
||||
private static List<Gene> genes() {
|
||||
var result = new ArrayList<Gene>();
|
||||
|
||||
try {
|
||||
var inputStream = GeneUtils.class.getClassLoader().getResourceAsStream("genes.csv");
|
||||
var parser = CSVFormat.RFC4180.builder()
|
||||
.setHeader()
|
||||
.setSkipHeaderRecord(true)
|
||||
.setDelimiter('\t')
|
||||
.get()
|
||||
.parse(new InputStreamReader(inputStream));
|
||||
for (var row : parser) {
|
||||
result.add(
|
||||
new Gene(
|
||||
row.get("HGNC ID"),
|
||||
row.get("Ensembl ID(supplied by Ensembl)"),
|
||||
row.get("Approved symbol"),
|
||||
row.get("Approved name"),
|
||||
row.get("Chromosome")
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return result;
|
||||
} catch (IOException e) {
|
||||
return List.of();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -72,6 +72,13 @@ public class EinzelempfehlungProzedurDataMapper extends AbstractEinzelempfehlung
|
||||
);
|
||||
}
|
||||
|
||||
// As of now: Simple variant and CSV only! - Not used but present for completeness
|
||||
if (null != resultSet.getString("st_mol_alt_variante_json")) {
|
||||
resultBuilder.supportingVariants(
|
||||
JsonToMolAltVarianteMapper.map(resultSet.getString("st_mol_alt_variante_json"))
|
||||
);
|
||||
}
|
||||
|
||||
return resultBuilder.build();
|
||||
}
|
||||
|
||||
|
@@ -42,7 +42,7 @@ public class EinzelempfehlungStudieDataMapper extends AbstractEinzelempfehlungDa
|
||||
|
||||
@Override
|
||||
protected MtbStudyEnrollmentRecommendation map(ResultSet resultSet) {
|
||||
return MtbStudyEnrollmentRecommendation.builder()
|
||||
var resultBuilder = MtbStudyEnrollmentRecommendation.builder()
|
||||
.id(resultSet.getString("id"))
|
||||
.patient(resultSet.getPatientReference())
|
||||
// TODO Fix id?
|
||||
@@ -56,8 +56,16 @@ public class EinzelempfehlungStudieDataMapper extends AbstractEinzelempfehlungDa
|
||||
)
|
||||
.medication(JsonToMedicationMapper.map(resultSet.getString("wirkstoffe_json")))
|
||||
.levelOfEvidence(getLevelOfEvidence(resultSet))
|
||||
.study(JsonToStudyMapper.map(resultSet.getString("studien_alle_json")))
|
||||
.build();
|
||||
.study(JsonToStudyMapper.map(resultSet.getString("studien_alle_json")));
|
||||
|
||||
// As of now: Simple variant and CSV only!
|
||||
if (null != resultSet.getString("st_mol_alt_variante_json")) {
|
||||
resultBuilder.supportingVariants(
|
||||
JsonToMolAltVarianteMapper.map(resultSet.getString("st_mol_alt_variante_json"))
|
||||
);
|
||||
}
|
||||
|
||||
return resultBuilder.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -83,8 +83,11 @@ public class EinzelempfehlungWirkstoffDataMapper extends AbstractEinzelempfehlun
|
||||
);
|
||||
}
|
||||
|
||||
if (null != resultSet.getString("st_mol_alt_variante")) {
|
||||
// Empty for now
|
||||
// As of now: Simple variant and CSV only!
|
||||
if (null != resultSet.getString("st_mol_alt_variante_json")) {
|
||||
resultBuilder.supportingVariants(
|
||||
JsonToMolAltVarianteMapper.map(resultSet.getString("st_mol_alt_variante_json"))
|
||||
);
|
||||
}
|
||||
|
||||
return resultBuilder.build();
|
||||
|
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* This file is part of mv64e-onkostar-data
|
||||
*
|
||||
* Copyright (C) 2025 Paul-Christian Volkmer
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package dev.pcvolkmer.onco.datamapper.mapper;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import dev.pcvolkmer.mv64e.mtb.Coding;
|
||||
import dev.pcvolkmer.mv64e.mtb.GeneAlterationReference;
|
||||
import dev.pcvolkmer.mv64e.mtb.Reference;
|
||||
import dev.pcvolkmer.onco.datamapper.exceptions.DataAccessException;
|
||||
import dev.pcvolkmer.onco.datamapper.genes.GeneUtils;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Maps JSON strings used in Einzelempfehlung MolAltVariante
|
||||
*
|
||||
* @author Paul-Christian Volkmer
|
||||
* @since 0.1
|
||||
*/
|
||||
public class JsonToMolAltVarianteMapper {
|
||||
|
||||
private JsonToMolAltVarianteMapper() {
|
||||
// intentionally left empty
|
||||
}
|
||||
|
||||
public static List<GeneAlterationReference> map(String studyJson) {
|
||||
if (studyJson == null) {
|
||||
return List.of();
|
||||
}
|
||||
try {
|
||||
return new ObjectMapper().readValue(studyJson, new TypeReference<List<MolAltVariante>>() {
|
||||
}).stream()
|
||||
.map(variante -> {
|
||||
var resultBuilder = GeneAlterationReference.builder();
|
||||
GeneUtils.findBySymbol(variante.getGen()).ifPresent(gene -> {
|
||||
resultBuilder
|
||||
.gene(
|
||||
Coding.builder()
|
||||
.code(gene.getHgncId())
|
||||
.display(gene.getSymbol())
|
||||
.system("https://www.genenames.org/")
|
||||
.build()
|
||||
)
|
||||
.variant(
|
||||
Reference.builder().id(variante.id).type("Variant").build()
|
||||
);
|
||||
});
|
||||
return resultBuilder.build();
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
} catch (Exception e) {
|
||||
throw new DataAccessException(String.format("Cannot map gene alteration for %s", studyJson));
|
||||
}
|
||||
}
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
private static class MolAltVariante {
|
||||
private String id;
|
||||
private String gen;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getGen() {
|
||||
return gen;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
44245
src/main/resources/genes.csv
Normal file
44245
src/main/resources/genes.csv
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user