From d0bd9eb4336b5e2b48395f22092a2efee4a9f0a8 Mon Sep 17 00:00:00 2001 From: Pavel Silin Date: Thu, 17 Nov 2016 18:03:29 +0300 Subject: [PATCH 1/8] fix issue 432 --- .../samtools/SAMSequenceDictionaryCodec.java | 32 ++++++++++++++++++++++ .../java/htsjdk/samtools/SAMTextHeaderCodec.java | 12 +++++--- 2 files changed, 40 insertions(+), 4 deletions(-) create mode 100644 src/main/java/htsjdk/samtools/SAMSequenceDictionaryCodec.java diff --git a/src/main/java/htsjdk/samtools/SAMSequenceDictionaryCodec.java b/src/main/java/htsjdk/samtools/SAMSequenceDictionaryCodec.java new file mode 100644 index 000000000..4b5d06955 --- /dev/null +++ b/src/main/java/htsjdk/samtools/SAMSequenceDictionaryCodec.java @@ -0,0 +1,32 @@ +package htsjdk.samtools; + +import htsjdk.samtools.util.LineReader; + +import java.io.BufferedWriter; +import java.io.Writer; + +public class SAMSequenceDictionaryCodec { + + private final SAMTextHeaderCodec codec; + + public SAMSequenceDictionaryCodec(final Writer writer) { + codec = new SAMTextHeaderCodec(); + codec.setWriter(new BufferedWriter(writer)); + } + + public void encodeSQLine(final SAMSequenceRecord sequenceRecord) { + codec.writeSQLine(sequenceRecord); + } + + public SAMSequenceDictionary decode(final LineReader reader, final String source) { + return codec.decode(reader, source).getSequenceDictionary(); + } + + public void encode(final SAMSequenceDictionary dictionary) { + dictionary.getSequences().forEach(this::encodeSQLine); + } + + public void setValidationStringency(final ValidationStringency validationStringency) { + codec.setValidationStringency(validationStringency); + } +} diff --git a/src/main/java/htsjdk/samtools/SAMTextHeaderCodec.java b/src/main/java/htsjdk/samtools/SAMTextHeaderCodec.java index 491bf9b4b..05dbc5052 100644 --- a/src/main/java/htsjdk/samtools/SAMTextHeaderCodec.java +++ b/src/main/java/htsjdk/samtools/SAMTextHeaderCodec.java @@ -70,6 +70,10 @@ public static final String COMMENT_PREFIX = HEADER_LINE_START + HeaderRecordType.CO.name() + FIELD_SEPARATOR; + void setWriter(BufferedWriter writer) { + this.writer = writer; + } + /** * Reads text SAM header and converts to a SAMFileHeader object. * @param reader Where to get header text from. @@ -80,8 +84,8 @@ public SAMFileHeader decode(final LineReader reader, final String source) { mFileHeader = new SAMFileHeader(); mReader = reader; mSource = source; - sequences = new ArrayList(); - readGroups = new ArrayList(); + sequences = new ArrayList<>(); + readGroups = new ArrayList<>(); while (advanceLine() != null) { final ParsedHeaderLine parsedHeaderLine = new ParsedHeaderLine(mCurrentLine); @@ -437,8 +441,8 @@ private void writeHDLine(final boolean keepExistingVersionNumber) { println(StringUtil.join(FIELD_SEPARATOR, fields)); } - private void writeSQLine(final SAMSequenceRecord sequenceRecord) { - final int numAttributes =sequenceRecord.getAttributes() != null ? sequenceRecord.getAttributes().size() : 0; + void writeSQLine(final SAMSequenceRecord sequenceRecord) { + final int numAttributes = sequenceRecord.getAttributes() != null ? sequenceRecord.getAttributes().size() : 0; final String[] fields = new String[3 + numAttributes]; fields[0] = HEADER_LINE_START + HeaderRecordType.SQ; fields[1] = SAMSequenceRecord.SEQUENCE_NAME_TAG + TAG_KEY_VALUE_SEPARATOR + sequenceRecord.getSequenceName(); From f5492718443445b6bba2f3e85284a732f657daa6 Mon Sep 17 00:00:00 2001 From: Pavel Silin Date: Fri, 18 Nov 2016 13:14:06 +0300 Subject: [PATCH 2/8] add test for SAMSDC --- .../samtools/SAMSequenceDictionaryCodec.java | 7 +++- .../samtools/SAMSequenceDictionaryCodecTest.java | 49 ++++++++++++++++++++++ 2 files changed, 54 insertions(+), 2 deletions(-) create mode 100644 src/test/java/htsjdk/samtools/SAMSequenceDictionaryCodecTest.java diff --git a/src/main/java/htsjdk/samtools/SAMSequenceDictionaryCodec.java b/src/main/java/htsjdk/samtools/SAMSequenceDictionaryCodec.java index 4b5d06955..f9b1d15b9 100644 --- a/src/main/java/htsjdk/samtools/SAMSequenceDictionaryCodec.java +++ b/src/main/java/htsjdk/samtools/SAMSequenceDictionaryCodec.java @@ -1,17 +1,19 @@ package htsjdk.samtools; import htsjdk.samtools.util.LineReader; +import htsjdk.samtools.util.RuntimeIOException; import java.io.BufferedWriter; +import java.io.IOException; import java.io.Writer; public class SAMSequenceDictionaryCodec { private final SAMTextHeaderCodec codec; - public SAMSequenceDictionaryCodec(final Writer writer) { + public SAMSequenceDictionaryCodec(final BufferedWriter writer) { codec = new SAMTextHeaderCodec(); - codec.setWriter(new BufferedWriter(writer)); + codec.setWriter(writer); } public void encodeSQLine(final SAMSequenceRecord sequenceRecord) { @@ -24,6 +26,7 @@ public SAMSequenceDictionary decode(final LineReader reader, final String source public void encode(final SAMSequenceDictionary dictionary) { dictionary.getSequences().forEach(this::encodeSQLine); + } public void setValidationStringency(final ValidationStringency validationStringency) { diff --git a/src/test/java/htsjdk/samtools/SAMSequenceDictionaryCodecTest.java b/src/test/java/htsjdk/samtools/SAMSequenceDictionaryCodecTest.java new file mode 100644 index 000000000..ebdd0356e --- /dev/null +++ b/src/test/java/htsjdk/samtools/SAMSequenceDictionaryCodecTest.java @@ -0,0 +1,49 @@ +package htsjdk.samtools; + +import htsjdk.samtools.util.LineReader; +import htsjdk.samtools.util.StringLineReader; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import java.io.BufferedWriter; +import java.io.StringWriter; +import java.util.Random; + +import static org.testng.Assert.*; + +public class SAMSequenceDictionaryCodecTest { + + private static final Random RANDOM = new Random(); + private SAMSequenceDictionary dictionary; + private StringWriter writer; + private SAMSequenceDictionaryCodec codec; + private BufferedWriter bufferedWriter; + + @BeforeMethod + public void setUp() throws Exception { + String[] seqs = new String[]{"chr1", "chr2", "chr12", "chr16", "chrX"}; + dictionary = new SAMSequenceDictionary(); + for (String seq : seqs) { + dictionary.addSequence(new SAMSequenceRecord(seq, RANDOM.nextInt(10_000_000))); + } + writer = new StringWriter(10); + bufferedWriter = new BufferedWriter(writer); + codec = new SAMSequenceDictionaryCodec(bufferedWriter); + } + + @Test + public void testEncodeDecode() throws Exception { + LineReader reader = null; + try { + codec.encode(dictionary); + bufferedWriter.close(); + reader = new StringLineReader(writer.toString()); + SAMSequenceDictionary actual = codec.decode(reader, null); + assertEquals(actual, dictionary); + }finally { + assert reader != null; + reader.close(); + } + } + +} \ No newline at end of file From d7c12bb3cc609aa09e4c342ecd570d983d42864c Mon Sep 17 00:00:00 2001 From: Pavel Silin Date: Fri, 18 Nov 2016 13:47:46 +0300 Subject: [PATCH 3/8] add java docs --- .../samtools/SAMSequenceDictionaryCodec.java | 44 ++++++++++++++++++++++ .../samtools/SAMSequenceDictionaryCodecTest.java | 27 +++++++++++++ 2 files changed, 71 insertions(+) diff --git a/src/main/java/htsjdk/samtools/SAMSequenceDictionaryCodec.java b/src/main/java/htsjdk/samtools/SAMSequenceDictionaryCodec.java index f9b1d15b9..3e1bf2a94 100644 --- a/src/main/java/htsjdk/samtools/SAMSequenceDictionaryCodec.java +++ b/src/main/java/htsjdk/samtools/SAMSequenceDictionaryCodec.java @@ -1,3 +1,27 @@ +/* + * The MIT License + * + * Copyright (c) 2016 The Broad Institute + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + package htsjdk.samtools; import htsjdk.samtools.util.LineReader; @@ -7,6 +31,12 @@ import java.io.IOException; import java.io.Writer; +/** + * "On fly" codec SAMSequenceDictionaryCodec. + * Encodes each sequence and directly writes it to the Dictionary file. + * + * @author Pavel_Silin@epam.com, EPAM Systems, Inc. + */ public class SAMSequenceDictionaryCodec { private final SAMTextHeaderCodec codec; @@ -16,14 +46,28 @@ public SAMSequenceDictionaryCodec(final BufferedWriter writer) { codec.setWriter(writer); } + /** + * Write {@link SAMSequenceRecord}. + * @param sequenceRecord object to be converted to text. + */ public void encodeSQLine(final SAMSequenceRecord sequenceRecord) { codec.writeSQLine(sequenceRecord); } + /** + * Reads text SAM header and converts to a SAMSequenceDictionary object. + * @param reader Where to get header text from. + * @param source Name of the input file, for error messages. May be null. + * @return complete SAMSequenceDictionary object. + */ public SAMSequenceDictionary decode(final LineReader reader, final String source) { return codec.decode(reader, source).getSequenceDictionary(); } + /** + * Convert {@link SAMSequenceDictionary} from in-memory representation to text representation. + * @param dictionary object to be converted to text. + */ public void encode(final SAMSequenceDictionary dictionary) { dictionary.getSequences().forEach(this::encodeSQLine); diff --git a/src/test/java/htsjdk/samtools/SAMSequenceDictionaryCodecTest.java b/src/test/java/htsjdk/samtools/SAMSequenceDictionaryCodecTest.java index ebdd0356e..9eb1507bc 100644 --- a/src/test/java/htsjdk/samtools/SAMSequenceDictionaryCodecTest.java +++ b/src/test/java/htsjdk/samtools/SAMSequenceDictionaryCodecTest.java @@ -1,3 +1,27 @@ +/* + * The MIT License + * + * Copyright (c) 20016 The Broad Institute + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + package htsjdk.samtools; import htsjdk.samtools.util.LineReader; @@ -11,6 +35,9 @@ import static org.testng.Assert.*; +/** + * @author Pavel_Silin@epam.com, EPAM Systems, Inc. + */ public class SAMSequenceDictionaryCodecTest { private static final Random RANDOM = new Random(); From 64a9c079bc41c18dc81bbf2949196c70081624fa Mon Sep 17 00:00:00 2001 From: Pavel Silin Date: Sun, 20 Nov 2016 15:43:19 +0300 Subject: [PATCH 4/8] correction to comments: new package-local methods & java doc --- .../samtools/SAMSequenceDictionaryCodec.java | 23 ++++++++++------ .../java/htsjdk/samtools/SAMTextHeaderCodec.java | 32 ++++++++++++++++++++-- .../samtools/SAMSequenceDictionaryCodecTest.java | 6 ++-- 3 files changed, 47 insertions(+), 14 deletions(-) diff --git a/src/main/java/htsjdk/samtools/SAMSequenceDictionaryCodec.java b/src/main/java/htsjdk/samtools/SAMSequenceDictionaryCodec.java index 3e1bf2a94..5f5e667ef 100644 --- a/src/main/java/htsjdk/samtools/SAMSequenceDictionaryCodec.java +++ b/src/main/java/htsjdk/samtools/SAMSequenceDictionaryCodec.java @@ -25,14 +25,10 @@ package htsjdk.samtools; import htsjdk.samtools.util.LineReader; -import htsjdk.samtools.util.RuntimeIOException; - import java.io.BufferedWriter; -import java.io.IOException; -import java.io.Writer; /** - * "On fly" codec SAMSequenceDictionaryCodec. + * "On the fly" codec SAMSequenceDictionaryCodec. * Encodes each sequence and directly writes it to the Dictionary file. * * @author Pavel_Silin@epam.com, EPAM Systems, Inc. @@ -50,8 +46,17 @@ public SAMSequenceDictionaryCodec(final BufferedWriter writer) { * Write {@link SAMSequenceRecord}. * @param sequenceRecord object to be converted to text. */ - public void encodeSQLine(final SAMSequenceRecord sequenceRecord) { - codec.writeSQLine(sequenceRecord); + public void encodeSequenceRecord(final SAMSequenceRecord sequenceRecord) { + codec.encodeSequenceRecord(sequenceRecord); + } + + /** + * Write Header line. + * @param keepExistingVersionNumber boolean flag to keep existing version number. + */ + public void encodeHeaderLine(final boolean keepExistingVersionNumber) { + codec.setmFileHeader(new SAMFileHeader()); + codec.encodeHeaderLine(keepExistingVersionNumber); } /** @@ -69,8 +74,8 @@ public SAMSequenceDictionary decode(final LineReader reader, final String source * @param dictionary object to be converted to text. */ public void encode(final SAMSequenceDictionary dictionary) { - dictionary.getSequences().forEach(this::encodeSQLine); - + encodeHeaderLine(false); + dictionary.getSequences().forEach(this::encodeSequenceRecord); } public void setValidationStringency(final ValidationStringency validationStringency) { diff --git a/src/main/java/htsjdk/samtools/SAMTextHeaderCodec.java b/src/main/java/htsjdk/samtools/SAMTextHeaderCodec.java index 05dbc5052..5b7181b2d 100644 --- a/src/main/java/htsjdk/samtools/SAMTextHeaderCodec.java +++ b/src/main/java/htsjdk/samtools/SAMTextHeaderCodec.java @@ -70,10 +70,14 @@ public static final String COMMENT_PREFIX = HEADER_LINE_START + HeaderRecordType.CO.name() + FIELD_SEPARATOR; - void setWriter(BufferedWriter writer) { + void setWriter(final BufferedWriter writer) { this.writer = writer; } + void setmFileHeader(final SAMFileHeader header) { + this.mFileHeader = header; + } + /** * Reads text SAM header and converts to a SAMFileHeader object. * @param reader Where to get header text from. @@ -391,6 +395,30 @@ public void encode(final Writer writer, final SAMFileHeader header, final boolea } } + /** + * Encode {@link SAMSequenceRecord}. + * Designed for using in {@link SAMSequenceDictionaryCodec}, allows you to implement recording on the fly. + * @throws IllegalStateException, if writer is null. + */ + void encodeSequenceRecord(final SAMSequenceRecord sequenceRecord) { + if (writer == null) { + throw new IllegalStateException("writer couldn't be null"); + } + writeSQLine(sequenceRecord); + } + + /** + * Encode HD line. + * Designed for using in {@link SAMSequenceDictionaryCodec}, allows you to implement recording on the fly. + * @throws IllegalStateException, if writer is null. + */ + void encodeHeaderLine(final boolean keepExistingVersionNumber) { + if (writer == null) { + throw new IllegalStateException("writer couldn't be null"); + } + writeHDLine(keepExistingVersionNumber); + } + private void println(final String s) { try { writer.append(s); @@ -441,7 +469,7 @@ private void writeHDLine(final boolean keepExistingVersionNumber) { println(StringUtil.join(FIELD_SEPARATOR, fields)); } - void writeSQLine(final SAMSequenceRecord sequenceRecord) { + private void writeSQLine(final SAMSequenceRecord sequenceRecord) { final int numAttributes = sequenceRecord.getAttributes() != null ? sequenceRecord.getAttributes().size() : 0; final String[] fields = new String[3 + numAttributes]; fields[0] = HEADER_LINE_START + HeaderRecordType.SQ; diff --git a/src/test/java/htsjdk/samtools/SAMSequenceDictionaryCodecTest.java b/src/test/java/htsjdk/samtools/SAMSequenceDictionaryCodecTest.java index 9eb1507bc..8a3f5a6df 100644 --- a/src/test/java/htsjdk/samtools/SAMSequenceDictionaryCodecTest.java +++ b/src/test/java/htsjdk/samtools/SAMSequenceDictionaryCodecTest.java @@ -62,15 +62,15 @@ public void setUp() throws Exception { public void testEncodeDecode() throws Exception { LineReader reader = null; try { + codec.encodeHeaderLine(false); codec.encode(dictionary); bufferedWriter.close(); reader = new StringLineReader(writer.toString()); SAMSequenceDictionary actual = codec.decode(reader, null); assertEquals(actual, dictionary); - }finally { + } finally { assert reader != null; reader.close(); } } - -} \ No newline at end of file +} From e63442d13c51466673101a687cf143d8f6037000 Mon Sep 17 00:00:00 2001 From: Pavel Silin Date: Sun, 20 Nov 2016 15:57:10 +0300 Subject: [PATCH 5/8] fix java docs, reorder methods --- src/main/java/htsjdk/samtools/SAMTextHeaderCodec.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/htsjdk/samtools/SAMTextHeaderCodec.java b/src/main/java/htsjdk/samtools/SAMTextHeaderCodec.java index 5b7181b2d..fb4b02ac3 100644 --- a/src/main/java/htsjdk/samtools/SAMTextHeaderCodec.java +++ b/src/main/java/htsjdk/samtools/SAMTextHeaderCodec.java @@ -397,7 +397,7 @@ public void encode(final Writer writer, final SAMFileHeader header, final boolea /** * Encode {@link SAMSequenceRecord}. - * Designed for using in {@link SAMSequenceDictionaryCodec}, allows you to implement recording on the fly. + * Designed for using in {@link SAMSequenceDictionaryCodec}, allows to implement recording on the fly. * @throws IllegalStateException, if writer is null. */ void encodeSequenceRecord(final SAMSequenceRecord sequenceRecord) { @@ -409,7 +409,7 @@ void encodeSequenceRecord(final SAMSequenceRecord sequenceRecord) { /** * Encode HD line. - * Designed for using in {@link SAMSequenceDictionaryCodec}, allows you to implement recording on the fly. + * Designed for using in {@link SAMSequenceDictionaryCodec}, allows to implement recording on the fly. * @throws IllegalStateException, if writer is null. */ void encodeHeaderLine(final boolean keepExistingVersionNumber) { From 97fbe637a10422c3cecc37df59dc5026e2949497 Mon Sep 17 00:00:00 2001 From: Pavel Silin Date: Tue, 22 Nov 2016 21:31:35 +0300 Subject: [PATCH 6/8] add java docs and rename constant field in test --- .../samtools/SAMSequenceDictionaryCodec.java | 32 +++++++++++++++++++++- .../samtools/SAMSequenceDictionaryCodecTest.java | 4 +-- 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/src/main/java/htsjdk/samtools/SAMSequenceDictionaryCodec.java b/src/main/java/htsjdk/samtools/SAMSequenceDictionaryCodec.java index 5f5e667ef..937de5090 100644 --- a/src/main/java/htsjdk/samtools/SAMSequenceDictionaryCodec.java +++ b/src/main/java/htsjdk/samtools/SAMSequenceDictionaryCodec.java @@ -31,14 +31,45 @@ * "On the fly" codec SAMSequenceDictionaryCodec. * Encodes each sequence and directly writes it to the Dictionary file. * + * To use this class you should provide BufferedWriter to it, and so you should close it as you stop using this class. + * You can work with this class as shown below. + * + * Example of using this class: + * + * List dict = ...; + * + * //open BufferedReader and close in try-with-resources + * try(BufferedWriter writer = new BufferedWriter(new FileWriter("path/to/file"))) { + * SAMSequenceDictionaryCodec codec = new SAMSequenceDictionaryCodec(writer); + * + * //we have list of sequences, so encode header line and after that encode each sequence + * codec.encodeHeaderLine(false); + * dict.forEach(codec::encodeSequenceRecord); + *} + * + * or + * + * SAMSequenceDictionary dict = ...; + * + * //open BufferedReader and close in try-with-resources + * try(BufferedWriter writer = new BufferedWriter(new FileWriter("path/to/file"))) { + * SAMSequenceDictionaryCodec codec = new SAMSequenceDictionaryCodec(writer); + * + * //we have complete SAMSequenceDictionary, so just encode it. + * codec.encode(dict); + *} + * * @author Pavel_Silin@epam.com, EPAM Systems, Inc. */ public class SAMSequenceDictionaryCodec { + private static final SAMFileHeader EMPTY_HEADER = new SAMFileHeader(); + private final SAMTextHeaderCodec codec; public SAMSequenceDictionaryCodec(final BufferedWriter writer) { codec = new SAMTextHeaderCodec(); + codec.setmFileHeader(EMPTY_HEADER); codec.setWriter(writer); } @@ -55,7 +86,6 @@ public void encodeSequenceRecord(final SAMSequenceRecord sequenceRecord) { * @param keepExistingVersionNumber boolean flag to keep existing version number. */ public void encodeHeaderLine(final boolean keepExistingVersionNumber) { - codec.setmFileHeader(new SAMFileHeader()); codec.encodeHeaderLine(keepExistingVersionNumber); } diff --git a/src/test/java/htsjdk/samtools/SAMSequenceDictionaryCodecTest.java b/src/test/java/htsjdk/samtools/SAMSequenceDictionaryCodecTest.java index 8a3f5a6df..d793d5f95 100644 --- a/src/test/java/htsjdk/samtools/SAMSequenceDictionaryCodecTest.java +++ b/src/test/java/htsjdk/samtools/SAMSequenceDictionaryCodecTest.java @@ -40,7 +40,7 @@ */ public class SAMSequenceDictionaryCodecTest { - private static final Random RANDOM = new Random(); + private static final Random random = new Random(); private SAMSequenceDictionary dictionary; private StringWriter writer; private SAMSequenceDictionaryCodec codec; @@ -51,7 +51,7 @@ public void setUp() throws Exception { String[] seqs = new String[]{"chr1", "chr2", "chr12", "chr16", "chrX"}; dictionary = new SAMSequenceDictionary(); for (String seq : seqs) { - dictionary.addSequence(new SAMSequenceRecord(seq, RANDOM.nextInt(10_000_000))); + dictionary.addSequence(new SAMSequenceRecord(seq, random.nextInt(10_000_000))); } writer = new StringWriter(10); bufferedWriter = new BufferedWriter(writer); From ec354b302184aeb6cec3ee22379a8371695a2ddc Mon Sep 17 00:00:00 2001 From: Pavel Silin Date: Wed, 23 Nov 2016 23:23:33 +0300 Subject: [PATCH 7/8] encode, java doc, tests --- .../samtools/SAMSequenceDictionaryCodec.java | 4 +- .../samtools/SAMSequenceDictionaryCodecTest.java | 61 +++++++++++++++++++--- 2 files changed, 56 insertions(+), 9 deletions(-) diff --git a/src/main/java/htsjdk/samtools/SAMSequenceDictionaryCodec.java b/src/main/java/htsjdk/samtools/SAMSequenceDictionaryCodec.java index 937de5090..a290e8079 100644 --- a/src/main/java/htsjdk/samtools/SAMSequenceDictionaryCodec.java +++ b/src/main/java/htsjdk/samtools/SAMSequenceDictionaryCodec.java @@ -55,7 +55,8 @@ * try(BufferedWriter writer = new BufferedWriter(new FileWriter("path/to/file"))) { * SAMSequenceDictionaryCodec codec = new SAMSequenceDictionaryCodec(writer); * - * //we have complete SAMSequenceDictionary, so just encode it. + * //we have complete SAMSequenceDictionary, so encode header line and {@link SAMSequenceDictionary}. + * codec.encodeHeaderLine(false); * codec.encode(dict); *} * @@ -104,7 +105,6 @@ public SAMSequenceDictionary decode(final LineReader reader, final String source * @param dictionary object to be converted to text. */ public void encode(final SAMSequenceDictionary dictionary) { - encodeHeaderLine(false); dictionary.getSequences().forEach(this::encodeSequenceRecord); } diff --git a/src/test/java/htsjdk/samtools/SAMSequenceDictionaryCodecTest.java b/src/test/java/htsjdk/samtools/SAMSequenceDictionaryCodecTest.java index d793d5f95..1430421c3 100644 --- a/src/test/java/htsjdk/samtools/SAMSequenceDictionaryCodecTest.java +++ b/src/test/java/htsjdk/samtools/SAMSequenceDictionaryCodecTest.java @@ -29,8 +29,10 @@ import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; +import javax.sound.sampled.Line; import java.io.BufferedWriter; import java.io.StringWriter; +import java.util.List; import java.util.Random; import static org.testng.Assert.*; @@ -53,24 +55,69 @@ public void setUp() throws Exception { for (String seq : seqs) { dictionary.addSequence(new SAMSequenceRecord(seq, random.nextInt(10_000_000))); } - writer = new StringWriter(10); + writer = new StringWriter(); bufferedWriter = new BufferedWriter(writer); codec = new SAMSequenceDictionaryCodec(bufferedWriter); } @Test - public void testEncodeDecode() throws Exception { - LineReader reader = null; + public void testEncodeDecodeDictionary() throws Exception { + LineReader readerOne = null; + LineReader readerTwo = null; try { codec.encodeHeaderLine(false); codec.encode(dictionary); bufferedWriter.close(); - reader = new StringLineReader(writer.toString()); - SAMSequenceDictionary actual = codec.decode(reader, null); + readerOne = new StringLineReader(writer.toString()); + SAMSequenceDictionary actual = codec.decode(readerOne, null); assertEquals(actual, dictionary); + + readerTwo = new StringLineReader(writer.toString()); + + String line = readerTwo.readLine(); + assertTrue(line.startsWith("@HD")); + + line = readerTwo.readLine(); + while (line != null) { + assertTrue(line.startsWith("@SQ")); + line = readerTwo.readLine(); + } + } finally { + assert readerOne != null; + assert readerTwo != null; + readerOne.close(); + readerTwo.close(); + } + } + + @Test + public void testEncodeDecodeListOfSeqs() throws Exception { + LineReader readerOne = null; + LineReader readerTwo = null; + + try { + List sequences = dictionary.getSequences(); + codec.encodeHeaderLine(false); + sequences.forEach(codec::encodeSequenceRecord); + bufferedWriter.close(); + readerOne = new StringLineReader(writer.toString()); + SAMSequenceDictionary actual = codec.decode(readerOne, null); + assertEquals(actual, dictionary); + readerTwo = new StringLineReader(writer.toString()); + + String line = readerTwo.readLine(); + assertTrue(line.startsWith("@HD")); + + line = readerTwo.readLine(); + while (line != null) { + assertTrue(line.startsWith("@SQ")); + line = readerTwo.readLine(); + } } finally { - assert reader != null; - reader.close(); + assert readerOne != null; + assert readerTwo != null; + readerOne.close(); + readerTwo.close(); } } } From 7536f6f76abd92d3b54763fb286ac17ee5950bf9 Mon Sep 17 00:00:00 2001 From: Pavel Silin Date: Thu, 24 Nov 2016 00:07:22 +0300 Subject: [PATCH 8/8] rollback: encode HD line in the encode method --- src/main/java/htsjdk/samtools/SAMSequenceDictionaryCodec.java | 4 ++-- src/test/java/htsjdk/samtools/SAMSequenceDictionaryCodecTest.java | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main/java/htsjdk/samtools/SAMSequenceDictionaryCodec.java b/src/main/java/htsjdk/samtools/SAMSequenceDictionaryCodec.java index a290e8079..e6e3ba592 100644 --- a/src/main/java/htsjdk/samtools/SAMSequenceDictionaryCodec.java +++ b/src/main/java/htsjdk/samtools/SAMSequenceDictionaryCodec.java @@ -55,8 +55,7 @@ * try(BufferedWriter writer = new BufferedWriter(new FileWriter("path/to/file"))) { * SAMSequenceDictionaryCodec codec = new SAMSequenceDictionaryCodec(writer); * - * //we have complete SAMSequenceDictionary, so encode header line and {@link SAMSequenceDictionary}. - * codec.encodeHeaderLine(false); + * //we have complete {@link SAMSequenceDictionary}, so just encode it. * codec.encode(dict); *} * @@ -105,6 +104,7 @@ public SAMSequenceDictionary decode(final LineReader reader, final String source * @param dictionary object to be converted to text. */ public void encode(final SAMSequenceDictionary dictionary) { + codec.encodeHeaderLine(false); dictionary.getSequences().forEach(this::encodeSequenceRecord); } diff --git a/src/test/java/htsjdk/samtools/SAMSequenceDictionaryCodecTest.java b/src/test/java/htsjdk/samtools/SAMSequenceDictionaryCodecTest.java index 1430421c3..32de1cd82 100644 --- a/src/test/java/htsjdk/samtools/SAMSequenceDictionaryCodecTest.java +++ b/src/test/java/htsjdk/samtools/SAMSequenceDictionaryCodecTest.java @@ -65,7 +65,6 @@ public void testEncodeDecodeDictionary() throws Exception { LineReader readerOne = null; LineReader readerTwo = null; try { - codec.encodeHeaderLine(false); codec.encode(dictionary); bufferedWriter.close(); readerOne = new StringLineReader(writer.toString());