From 362929187e1652b7a70a7eeb245d7947dcaf867e Mon Sep 17 00:00:00 2001 From: Nils Homer Date: Wed, 27 Apr 2016 20:15:37 -0400 Subject: [PATCH] Provide a method that for each source contig gives the set of destination contigs used in liftover. --- .../htsjdk/samtools/liftover/LiftOver.java | 27 +++++++++++++++++++ .../samtools/liftover/LiftOverTest.java | 10 +++++++ 2 files changed, 37 insertions(+) diff --git a/src/main/java/htsjdk/samtools/liftover/LiftOver.java b/src/main/java/htsjdk/samtools/liftover/LiftOver.java index deb9067c1c..e422a72198 100644 --- a/src/main/java/htsjdk/samtools/liftover/LiftOver.java +++ b/src/main/java/htsjdk/samtools/liftover/LiftOver.java @@ -32,7 +32,12 @@ import java.io.File; import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; import java.util.List; +import java.util.Map; +import java.util.Set; /** * Java port of UCSC liftOver. Only the most basic liftOver functionality is implemented. @@ -47,6 +52,7 @@ public class LiftOver { private double liftOverMinMatch = DEFAULT_LIFTOVER_MINMATCH; private final OverlapDetector chains; + private final Map> contigMap = new HashMap<>(); /** * Load UCSC chain file in order to lift over Intervals. @@ -54,6 +60,20 @@ public class LiftOver { public LiftOver(File chainFile) { IOUtil.assertFileIsReadable(chainFile); chains = Chain.loadChains(chainFile); + + for (final Chain chain : this.chains.getAll()) { + final String from = chain.fromSequenceName; + final String to = chain.toSequenceName; + final Set names; + if (contigMap.containsKey(from)) { + names = contigMap.get(from); + } + else { + names = new HashSet<>(); + contigMap.put(from, names); + } + names.add(to); + } } /** @@ -139,6 +159,13 @@ public List diagnosticLiftover(final Interval interval) { return ret; } + /** + * @return the set of destination contigs for each source contig in the chains file. + */ + public Map> getContigMap() { + return Collections.unmodifiableMap(contigMap); + } + private static Interval createToInterval(final String intervalName, final boolean sourceNegativeStrand, final TargetIntersection targetIntersection) { // Compute the query interval given the offsets of the target interval start and end into the first and // last ContinuousBlocks. diff --git a/src/test/java/htsjdk/samtools/liftover/LiftOverTest.java b/src/test/java/htsjdk/samtools/liftover/LiftOverTest.java index 01aaf9b2f3..8e9f92e6f2 100644 --- a/src/test/java/htsjdk/samtools/liftover/LiftOverTest.java +++ b/src/test/java/htsjdk/samtools/liftover/LiftOverTest.java @@ -34,6 +34,7 @@ import java.io.PrintWriter; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.TreeMap; /** @@ -44,10 +45,12 @@ public class LiftOverTest { private static final File CHAIN_FILE = new File(TEST_DATA_DIR, "hg18ToHg19.over.chain"); private LiftOver liftOver; + Map> contigMap; @BeforeClass public void initLiftOver() { liftOver = new LiftOver(CHAIN_FILE); + contigMap = liftOver.getContigMap(); } @Test(dataProvider = "testIntervals") @@ -455,4 +458,11 @@ public void testWriteChain() throws Exception { } Assert.assertEquals(newChainMap, originalChainMap); } + + @Test(dataProvider = "testIntervals") + public void testGetContigMap(final Interval in, final Interval expected) { + if (expected != null) { + Assert.assertTrue(contigMap.get(in.getContig()).contains(expected.getContig())); + } + } }