From 3bf73f713dff14ed5b3b2481e30a7a761aa79d7d Mon Sep 17 00:00:00 2001 From: "bart.charbon" Date: Tue, 2 Apr 2024 09:15:06 +0200 Subject: [PATCH 1/3] Remove blood relative check because it is broken --- .../matcher/InheritanceService.java | 3 +- .../matcher/util/InheritanceUtils.java | 39 ------------------- .../matcher/util/InheritanceUtilsTest.java | 22 ----------- 3 files changed, 1 insertion(+), 63 deletions(-) delete mode 100644 src/test/java/org/molgenis/vcf/inheritance/matcher/util/InheritanceUtilsTest.java diff --git a/src/main/java/org/molgenis/vcf/inheritance/matcher/InheritanceService.java b/src/main/java/org/molgenis/vcf/inheritance/matcher/InheritanceService.java index 1d093dd..c871891 100644 --- a/src/main/java/org/molgenis/vcf/inheritance/matcher/InheritanceService.java +++ b/src/main/java/org/molgenis/vcf/inheritance/matcher/InheritanceService.java @@ -149,8 +149,7 @@ private Inheritance calculateInheritanceForFamily( Map> geneVariantMap, VariantContext variantContext, Pedigree family, Sample sample) { - Pedigree filteredFamily = InheritanceUtils.filterBloodRelatives(family, sample); - return pedigreeInheritanceChecker.calculatePedigreeInheritance(geneVariantMap, variantContext, sample, filteredFamily, arCompoundChecker); + return pedigreeInheritanceChecker.calculatePedigreeInheritance(geneVariantMap, variantContext, sample, family, arCompoundChecker); } private static VCFFileReader createReader(Path vcfPath) { diff --git a/src/main/java/org/molgenis/vcf/inheritance/matcher/util/InheritanceUtils.java b/src/main/java/org/molgenis/vcf/inheritance/matcher/util/InheritanceUtils.java index 29992e6..13cb04a 100644 --- a/src/main/java/org/molgenis/vcf/inheritance/matcher/util/InheritanceUtils.java +++ b/src/main/java/org/molgenis/vcf/inheritance/matcher/util/InheritanceUtils.java @@ -2,25 +2,12 @@ import htsjdk.variant.variantcontext.Allele; import htsjdk.variant.variantcontext.Genotype; -import org.molgenis.vcf.utils.sample.model.Pedigree; -import org.molgenis.vcf.utils.sample.model.Person; import org.molgenis.vcf.utils.sample.model.Sample; -import java.util.HashMap; -import java.util.Map; - public class InheritanceUtils { private InheritanceUtils() { } - public static Pedigree filterBloodRelatives(Pedigree family, Sample sample) { - Map filteredFamily = new HashMap<>(); - filteredFamily.put(sample.getPerson().getIndividualId(), sample); - addParents(family, sample, filteredFamily); - addChildren(sample, family, filteredFamily); - return Pedigree.builder().id(family.getId()).members(filteredFamily).build(); - } - public static boolean hasParents(Sample sample) { return !(sample.getPerson().getMaternalId().isEmpty() || sample.getPerson().getMaternalId().equals("0")) && !(sample.getPerson().getPaternalId().isEmpty() || sample.getPerson().getPaternalId().equals("0")); @@ -41,30 +28,4 @@ public static boolean isHomAlt(Genotype genotype) { public static boolean isAlt(Allele allele) { return allele.isCalled() && allele.isNonReference(); } - - - private static void addChildren(Sample proband, Pedigree family, Map filteredFamily) { - for (Sample sample : family.getMembers().values()) { - Person person = sample.getPerson(); - Person probandPerson = proband.getPerson(); - if (person.getPaternalId().equals(probandPerson.getPaternalId()) && person.getMaternalId().equals(probandPerson.getMaternalId()) - || filteredFamily.containsKey(person.getPaternalId()) && filteredFamily.containsKey(person.getMaternalId())) { - filteredFamily.put(person.getIndividualId(), sample); - } - } - } - - private static void addParents(Pedigree family, Sample sample, Map sampleMap) { - Person person = sample.getPerson(); - Sample father = family.getMembers().get(person.getPaternalId()); - Sample mother = family.getMembers().get(person.getMaternalId()); - if (father != null) { - sampleMap.put(father.getPerson().getIndividualId(), father); - addParents(family, father, sampleMap); - } - if (mother != null) { - sampleMap.put(mother.getPerson().getIndividualId(), mother); - addParents(family, mother, sampleMap); - } - } } diff --git a/src/test/java/org/molgenis/vcf/inheritance/matcher/util/InheritanceUtilsTest.java b/src/test/java/org/molgenis/vcf/inheritance/matcher/util/InheritanceUtilsTest.java deleted file mode 100644 index 7dae101..0000000 --- a/src/test/java/org/molgenis/vcf/inheritance/matcher/util/InheritanceUtilsTest.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.molgenis.vcf.inheritance.matcher.util; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.junit.jupiter.MockitoExtension; -import org.molgenis.vcf.inheritance.matcher.checker.PedigreeTestUtil; -import org.molgenis.vcf.utils.sample.model.*; - -import java.util.Set; - -import static org.junit.jupiter.api.Assertions.*; -@ExtendWith(MockitoExtension.class) -class InheritanceUtilsTest { - @Test - void testFilterBloodRelatives() { - Sample sample = Sample.builder().person(Person.builder().individualId("Patient").sex(Sex.MALE).affectedStatus(AffectedStatus.AFFECTED).maternalId("Mother").paternalId("Father").familyId("TEST").build()).build(); - Pedigree actual = InheritanceUtils.filterBloodRelatives(PedigreeTestUtil.createExtendedFamily(), sample); - - Set expectedMembers = Set.of("Patient","Mother","Father","Brother","Grandmother","Grandfather","GreatGrandfather","GreatGrandmother","Uncle"); - assertEquals(expectedMembers,actual.getMembers().keySet()); - } -} \ No newline at end of file From dbece50eedfce5014d22872d7fe53e9036dbf7a9 Mon Sep 17 00:00:00 2001 From: "bart.charbon" Date: Tue, 2 Apr 2024 09:36:26 +0200 Subject: [PATCH 2/3] update version --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 43cb4dc..97414cf 100644 --- a/pom.xml +++ b/pom.xml @@ -12,7 +12,7 @@ org.molgenis vip-inheritance-matcher - 3.0.1 + 3.1.0 vip-inheritance-matcher Annotates VCF samples with mendelian violation and possible compound flags and From 291db82bbb3890c020846087046757d99c59e49a Mon Sep 17 00:00:00 2001 From: "bart.charbon" Date: Tue, 2 Apr 2024 09:40:46 +0200 Subject: [PATCH 3/3] update version --- .../matcher/AppCommandLineRunner.java | 36 ++++++-------- .../matcher/InheritanceService.java | 32 +++++-------- .../util/InheritanceServiceFactory.java | 7 +++ .../util/InheritanceServiceFactoryImpl.java | 29 ++++++++++++ .../util/VepMetadataServiceFactory.java | 7 +++ .../util/VepMetadataServiceFactoryImpl.java | 47 +++++++++++++++++++ .../InheritanceServiceFactoryImplTest.java | 31 ++++++++++++ .../VepMetadataServiceFactoryImplTest.java | 19 ++++++++ 8 files changed, 167 insertions(+), 41 deletions(-) create mode 100644 src/main/java/org/molgenis/vcf/inheritance/matcher/util/InheritanceServiceFactory.java create mode 100644 src/main/java/org/molgenis/vcf/inheritance/matcher/util/InheritanceServiceFactoryImpl.java create mode 100644 src/main/java/org/molgenis/vcf/inheritance/matcher/util/VepMetadataServiceFactory.java create mode 100644 src/main/java/org/molgenis/vcf/inheritance/matcher/util/VepMetadataServiceFactoryImpl.java create mode 100644 src/test/java/org/molgenis/vcf/inheritance/matcher/util/InheritanceServiceFactoryImplTest.java create mode 100644 src/test/java/org/molgenis/vcf/inheritance/matcher/util/VepMetadataServiceFactoryImplTest.java diff --git a/src/main/java/org/molgenis/vcf/inheritance/matcher/AppCommandLineRunner.java b/src/main/java/org/molgenis/vcf/inheritance/matcher/AppCommandLineRunner.java index d6245a5..e9e0a8c 100644 --- a/src/main/java/org/molgenis/vcf/inheritance/matcher/AppCommandLineRunner.java +++ b/src/main/java/org/molgenis/vcf/inheritance/matcher/AppCommandLineRunner.java @@ -1,31 +1,24 @@ package org.molgenis.vcf.inheritance.matcher; -import static java.util.Objects.requireNonNull; -import static org.molgenis.vcf.inheritance.matcher.AppCommandLineOptions.OPT_DEBUG; -import static org.molgenis.vcf.inheritance.matcher.AppCommandLineOptions.OPT_FORCE; -import static org.molgenis.vcf.inheritance.matcher.AppCommandLineOptions.OPT_INPUT; -import static org.molgenis.vcf.inheritance.matcher.AppCommandLineOptions.OPT_OUTPUT; -import static org.molgenis.vcf.inheritance.matcher.AppCommandLineOptions.OPT_PED; -import static org.molgenis.vcf.inheritance.matcher.AppCommandLineOptions.OPT_PROBANDS; -import static org.molgenis.vcf.inheritance.matcher.PathUtils.parsePaths; - import ch.qos.logback.classic.Level; -import java.nio.file.Path; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import org.apache.commons.cli.CommandLine; -import org.apache.commons.cli.CommandLineParser; -import org.apache.commons.cli.DefaultParser; -import org.apache.commons.cli.HelpFormatter; -import org.apache.commons.cli.ParseException; +import org.apache.commons.cli.*; import org.molgenis.vcf.inheritance.matcher.model.Settings; +import org.molgenis.vcf.inheritance.matcher.util.InheritanceServiceFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.CommandLineRunner; import org.springframework.stereotype.Component; +import java.nio.file.Path; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import static java.util.Objects.requireNonNull; +import static org.molgenis.vcf.inheritance.matcher.AppCommandLineOptions.*; +import static org.molgenis.vcf.inheritance.matcher.PathUtils.parsePaths; + @Component class AppCommandLineRunner implements CommandLineRunner { @@ -37,15 +30,15 @@ class AppCommandLineRunner implements CommandLineRunner { private final String appName; private final String appVersion; private final CommandLineParser commandLineParser; - private final InheritanceService inheritanceService; + private final InheritanceServiceFactory inheritanceServiceFactory; AppCommandLineRunner( @Value("${app.name}") String appName, @Value("${app.version}") String appVersion, - InheritanceService inheritanceService) { + InheritanceServiceFactory inheritanceServiceFactory) { this.appName = requireNonNull(appName); this.appVersion = requireNonNull(appVersion); - this.inheritanceService = requireNonNull(inheritanceService); + this.inheritanceServiceFactory = requireNonNull(inheritanceServiceFactory); this.commandLineParser = new DefaultParser(); } @@ -76,6 +69,7 @@ public void run(String... args) { CommandLine commandLine = getCommandLine(args); org.molgenis.vcf.inheritance.matcher.AppCommandLineOptions.validateCommandLine(commandLine); Settings settings = mapSettings(commandLine); + InheritanceService inheritanceService = inheritanceServiceFactory.create(); try { inheritanceService.run(settings); } catch (Exception e) { diff --git a/src/main/java/org/molgenis/vcf/inheritance/matcher/InheritanceService.java b/src/main/java/org/molgenis/vcf/inheritance/matcher/InheritanceService.java index c871891..f7286a1 100644 --- a/src/main/java/org/molgenis/vcf/inheritance/matcher/InheritanceService.java +++ b/src/main/java/org/molgenis/vcf/inheritance/matcher/InheritanceService.java @@ -1,15 +1,16 @@ package org.molgenis.vcf.inheritance.matcher; -import static java.lang.String.format; -import static java.util.Collections.singletonMap; -import static org.molgenis.vcf.inheritance.matcher.InheritanceMatcher.matchInheritance; -import static org.molgenis.vcf.utils.sample.mapper.PedToSamplesMapper.mapPedFileToPedigrees; - import htsjdk.variant.variantcontext.VariantContext; import htsjdk.variant.variantcontext.writer.VariantContextWriter; import htsjdk.variant.variantcontext.writer.VariantContextWriterBuilder; import htsjdk.variant.vcf.VCFFileReader; import htsjdk.variant.vcf.VCFHeader; +import org.molgenis.vcf.inheritance.matcher.checker.ArCompoundChecker; +import org.molgenis.vcf.inheritance.matcher.model.*; +import org.molgenis.vcf.inheritance.matcher.util.InheritanceUtils; +import org.molgenis.vcf.utils.metadata.FieldMetadataService; +import org.molgenis.vcf.utils.sample.model.*; + import java.io.IOException; import java.io.UncheckedIOException; import java.nio.file.Files; @@ -19,19 +20,11 @@ import java.util.List; import java.util.Map; -import org.molgenis.vcf.inheritance.matcher.checker.*; -import org.molgenis.vcf.inheritance.matcher.model.*; -import org.molgenis.vcf.inheritance.matcher.util.InheritanceUtils; -import org.molgenis.vcf.utils.metadata.FieldMetadataService; -import org.molgenis.vcf.utils.sample.model.AffectedStatus; -import org.molgenis.vcf.utils.sample.model.Pedigree; -import org.molgenis.vcf.utils.sample.model.Person; -import org.molgenis.vcf.utils.sample.model.Sample; -import org.molgenis.vcf.utils.sample.model.Sex; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.stereotype.Component; - -@Component +import static java.lang.String.format; +import static java.util.Collections.singletonMap; +import static org.molgenis.vcf.inheritance.matcher.InheritanceMatcher.matchInheritance; +import static org.molgenis.vcf.utils.sample.mapper.PedToSamplesMapper.mapPedFileToPedigrees; + public class InheritanceService { private final FieldMetadataService fieldMetadataService; @@ -40,8 +33,7 @@ public class InheritanceService { private final PedigreeInheritanceChecker pedigreeInheritanceChecker; public InheritanceService( - Annotator annotator, @Qualifier("vepMetadataService") - FieldMetadataService fieldMetadataService, PedigreeInheritanceChecker pedigreeInheritanceChecker) { + Annotator annotator, FieldMetadataService fieldMetadataService, PedigreeInheritanceChecker pedigreeInheritanceChecker) { this.annotator = annotator; this.fieldMetadataService = fieldMetadataService; this.pedigreeInheritanceChecker = pedigreeInheritanceChecker; diff --git a/src/main/java/org/molgenis/vcf/inheritance/matcher/util/InheritanceServiceFactory.java b/src/main/java/org/molgenis/vcf/inheritance/matcher/util/InheritanceServiceFactory.java new file mode 100644 index 0000000..478df39 --- /dev/null +++ b/src/main/java/org/molgenis/vcf/inheritance/matcher/util/InheritanceServiceFactory.java @@ -0,0 +1,7 @@ +package org.molgenis.vcf.inheritance.matcher.util; + +import org.molgenis.vcf.inheritance.matcher.InheritanceService; + +public interface InheritanceServiceFactory { + InheritanceService create(); +} diff --git a/src/main/java/org/molgenis/vcf/inheritance/matcher/util/InheritanceServiceFactoryImpl.java b/src/main/java/org/molgenis/vcf/inheritance/matcher/util/InheritanceServiceFactoryImpl.java new file mode 100644 index 0000000..2ce34d5 --- /dev/null +++ b/src/main/java/org/molgenis/vcf/inheritance/matcher/util/InheritanceServiceFactoryImpl.java @@ -0,0 +1,29 @@ +package org.molgenis.vcf.inheritance.matcher.util; + +import org.molgenis.vcf.inheritance.matcher.Annotator; +import org.molgenis.vcf.inheritance.matcher.InheritanceService; +import org.molgenis.vcf.inheritance.matcher.PedigreeInheritanceChecker; +import org.springframework.stereotype.Component; + +import static java.util.Objects.requireNonNull; + +/** + * Quirky class to enable use of local {@link org.molgenis.vcf.utils.vep.VepMetadataService} + */ +@Component +public class InheritanceServiceFactoryImpl implements InheritanceServiceFactory { + private final Annotator annotator; + private final VepMetadataServiceFactory vepMetadataServiceFactory; + private final PedigreeInheritanceChecker pedigreeInheritanceChecker; + + public InheritanceServiceFactoryImpl(Annotator annotator, VepMetadataServiceFactory vepMetadataServiceFactory, PedigreeInheritanceChecker pedigreeInheritanceChecker) { + this.annotator = requireNonNull(annotator); + this.vepMetadataServiceFactory = requireNonNull(vepMetadataServiceFactory); + this.pedigreeInheritanceChecker = requireNonNull(pedigreeInheritanceChecker); + } + + @Override + public InheritanceService create() { + return new InheritanceService(annotator, vepMetadataServiceFactory.create(), pedigreeInheritanceChecker); + } +} diff --git a/src/main/java/org/molgenis/vcf/inheritance/matcher/util/VepMetadataServiceFactory.java b/src/main/java/org/molgenis/vcf/inheritance/matcher/util/VepMetadataServiceFactory.java new file mode 100644 index 0000000..19d4fed --- /dev/null +++ b/src/main/java/org/molgenis/vcf/inheritance/matcher/util/VepMetadataServiceFactory.java @@ -0,0 +1,7 @@ +package org.molgenis.vcf.inheritance.matcher.util; + +import org.molgenis.vcf.utils.metadata.FieldMetadataService; + +public interface VepMetadataServiceFactory { + FieldMetadataService create(); +} diff --git a/src/main/java/org/molgenis/vcf/inheritance/matcher/util/VepMetadataServiceFactoryImpl.java b/src/main/java/org/molgenis/vcf/inheritance/matcher/util/VepMetadataServiceFactoryImpl.java new file mode 100644 index 0000000..7309fba --- /dev/null +++ b/src/main/java/org/molgenis/vcf/inheritance/matcher/util/VepMetadataServiceFactoryImpl.java @@ -0,0 +1,47 @@ +package org.molgenis.vcf.inheritance.matcher.util; + +import htsjdk.variant.vcf.VCFInfoHeaderLine; +import org.molgenis.vcf.utils.metadata.FieldMetadataService; +import org.molgenis.vcf.utils.metadata.AbstractFieldMetadataService; +import org.molgenis.vcf.utils.model.FieldMetadata; +import org.molgenis.vcf.utils.vep.VepMetadataService; +import org.springframework.stereotype.Component; + +import java.io.ByteArrayInputStream; + +import static java.nio.charset.StandardCharsets.UTF_8; + +/** + * Quirky class to enable reuse of {@link VepMetadataService} from vip-utils + */ +@Component +public class VepMetadataServiceFactoryImpl implements VepMetadataServiceFactory { + + @Override + public FieldMetadataService create() { + return new VepMetadataService(new EmptyFieldMetadataService()); + } + + /** + * vip-inheritance-matcher does not require knowledge of custom VEP metadata + */ + static class EmptyFieldMetadataService extends AbstractFieldMetadataService { + private static final String EMPTY_METADATA_JSON = """ + { + "format": { + }, + "info": { + "CSQ": { + "nestedFields": { + } + } + } + } + """; + + @Override + public FieldMetadata load(VCFInfoHeaderLine vcfInfoHeaderLine) { + return this.load(new ByteArrayInputStream(EMPTY_METADATA_JSON.getBytes(UTF_8)), vcfInfoHeaderLine); + } + } +} diff --git a/src/test/java/org/molgenis/vcf/inheritance/matcher/util/InheritanceServiceFactoryImplTest.java b/src/test/java/org/molgenis/vcf/inheritance/matcher/util/InheritanceServiceFactoryImplTest.java new file mode 100644 index 0000000..ef0f7f3 --- /dev/null +++ b/src/test/java/org/molgenis/vcf/inheritance/matcher/util/InheritanceServiceFactoryImplTest.java @@ -0,0 +1,31 @@ +package org.molgenis.vcf.inheritance.matcher.util; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.molgenis.vcf.inheritance.matcher.Annotator; +import org.molgenis.vcf.inheritance.matcher.PedigreeInheritanceChecker; + +import static org.mockito.Mockito.verify; + +@ExtendWith(MockitoExtension.class) +class InheritanceServiceFactoryImplTest { + @Mock + private Annotator annotator; + @Mock + private VepMetadataServiceFactory vepMetadataServiceFactory; + @Mock + private PedigreeInheritanceChecker pedigreeInheritanceChecker; + private InheritanceServiceFactoryImpl inheritanceServiceFactoryImpl; + @BeforeEach + void setUp() { + inheritanceServiceFactoryImpl = new InheritanceServiceFactoryImpl(annotator, vepMetadataServiceFactory, pedigreeInheritanceChecker); + } + @Test + void create() { + inheritanceServiceFactoryImpl.create(); + verify(vepMetadataServiceFactory).create(); + } +} \ No newline at end of file diff --git a/src/test/java/org/molgenis/vcf/inheritance/matcher/util/VepMetadataServiceFactoryImplTest.java b/src/test/java/org/molgenis/vcf/inheritance/matcher/util/VepMetadataServiceFactoryImplTest.java new file mode 100644 index 0000000..b5a1a49 --- /dev/null +++ b/src/test/java/org/molgenis/vcf/inheritance/matcher/util/VepMetadataServiceFactoryImplTest.java @@ -0,0 +1,19 @@ +package org.molgenis.vcf.inheritance.matcher.util; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +class VepMetadataServiceFactoryImplTest { + private VepMetadataServiceFactoryImpl vepMetadataServiceFactoryImpl; + + @BeforeEach + void setUp() { + vepMetadataServiceFactoryImpl = new VepMetadataServiceFactoryImpl(); + } + + @Test + void create() { + // test that no exception is thrown + vepMetadataServiceFactoryImpl.create(); + } +} \ No newline at end of file