Skip to content

Commit e67fe94

Browse files
authored
More informative error messages when dictionaries don't match (#1870)
1 parent 78892bf commit e67fe94

13 files changed

+154
-31
lines changed

src/main/java/picard/analysis/CollectOxoGMetrics.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,12 @@
4040
import org.broadinstitute.barclay.argparser.CommandLineProgramProperties;
4141
import org.broadinstitute.barclay.help.DocumentedFeature;
4242
import picard.PicardException;
43-
import htsjdk.samtools.util.SequenceUtil;
4443
import picard.cmdline.CommandLineProgram;
4544
import picard.cmdline.StandardOptionDefinitions;
4645
import picard.cmdline.programgroups.DiagnosticsAndQCProgramGroup;
4746
import picard.util.DbSnpBitSetUtil;
4847
import picard.util.help.HelpConstants;
48+
import picard.util.SequenceDictionaryUtils;
4949

5050
import java.io.File;
5151
import java.util.*;
@@ -239,8 +239,11 @@ protected int doWork() {
239239
final SamReader in = SamReaderFactory.makeDefault().referenceSequence(REFERENCE_SEQUENCE).open(INPUT);
240240

241241
if (!in.getFileHeader().getSequenceDictionary().isEmpty()) {
242-
SequenceUtil.assertSequenceDictionariesEqual(in.getFileHeader().getSequenceDictionary(),
243-
refWalker.getSequenceDictionary());
242+
SequenceDictionaryUtils.assertSequenceDictionariesEqual(
243+
in.getFileHeader().getSequenceDictionary(),
244+
INPUT.getAbsolutePath(),
245+
refWalker.getSequenceDictionary(),
246+
REFERENCE_SEQUENCE.getAbsolutePath());
244247
}
245248

246249
final Set<String> samples = new HashSet<>();

src/main/java/picard/analysis/CollectWgsMetrics.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
import org.broadinstitute.barclay.argparser.ArgumentCollection;
4949
import org.broadinstitute.barclay.argparser.CommandLineProgramProperties;
5050
import org.broadinstitute.barclay.help.DocumentedFeature;
51+
import picard.PicardException;
5152
import picard.cmdline.CommandLineProgram;
5253
import picard.cmdline.StandardOptionDefinitions;
5354
import picard.cmdline.argumentcollections.IntervalArgumentCollection;
@@ -57,6 +58,7 @@
5758
import picard.filter.CountingFilter;
5859
import picard.filter.CountingMapQFilter;
5960
import picard.filter.CountingPairedFilter;
61+
import picard.util.SequenceDictionaryUtils;
6062

6163
import java.io.File;
6264
import java.util.ArrayList;
@@ -211,7 +213,11 @@ protected int doWork() {
211213

212214
// Verify the sequence dictionaries match
213215
if (!this.header.getSequenceDictionary().isEmpty()) {
214-
SequenceUtil.assertSequenceDictionariesEqual(this.header.getSequenceDictionary(), refWalker.getSequenceDictionary());
216+
SequenceDictionaryUtils.assertSequenceDictionariesEqual(
217+
this.header.getSequenceDictionary(),
218+
INPUT.getAbsolutePath(),
219+
refWalker.getSequenceDictionary(),
220+
REFERENCE_SEQUENCE.getAbsolutePath());
215221
}
216222

217223
final List<SamRecordFilter> filters = new ArrayList<>();

src/main/java/picard/analysis/SinglePassSamProgram.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,14 @@
3535
import htsjdk.samtools.util.IOUtil;
3636
import htsjdk.samtools.util.Log;
3737
import htsjdk.samtools.util.ProgressLogger;
38-
import htsjdk.samtools.util.SequenceUtil;
3938
import org.broadinstitute.barclay.argparser.Argument;
4039
import org.broadinstitute.barclay.argparser.ArgumentCollection;
4140
import picard.PicardException;
4241
import picard.cmdline.CommandLineProgram;
4342
import picard.cmdline.StandardOptionDefinitions;
4443
import picard.cmdline.argumentcollections.OutputArgumentCollection;
4544
import picard.cmdline.argumentcollections.RequiredOutputArgumentCollection;
45+
import picard.util.SequenceDictionaryUtils;
4646

4747
import java.io.File;
4848
import java.util.Arrays;
@@ -114,8 +114,11 @@ public static void makeItSo(final File input,
114114
walker = new ReferenceSequenceFileWalker(referenceSequence);
115115

116116
if (!in.getFileHeader().getSequenceDictionary().isEmpty()) {
117-
SequenceUtil.assertSequenceDictionariesEqual(in.getFileHeader().getSequenceDictionary(),
118-
walker.getSequenceDictionary());
117+
SequenceDictionaryUtils.assertSequenceDictionariesEqual(
118+
in.getFileHeader().getSequenceDictionary(),
119+
input.getAbsolutePath(),
120+
walker.getSequenceDictionary(),
121+
referenceSequence.getAbsolutePath());
119122
}
120123
}
121124

src/main/java/picard/analysis/directed/CollectTargetedMetrics.java

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,14 @@
1515
import htsjdk.samtools.util.ProgressLogger;
1616
import htsjdk.samtools.util.SequenceUtil;
1717
import org.broadinstitute.barclay.argparser.Argument;
18+
import picard.PicardException;
1819
import picard.analysis.MetricAccumulationLevel;
1920
import picard.analysis.TheoreticalSensitivity;
2021
import picard.analysis.TheoreticalSensitivityMetrics;
2122
import picard.cmdline.CommandLineProgram;
2223
import picard.cmdline.StandardOptionDefinitions;
2324
import picard.metrics.MultilevelMetrics;
25+
import picard.util.SequenceDictionaryUtils;
2426

2527
import java.io.File;
2628
import java.util.*;
@@ -121,22 +123,26 @@ protected int doWork() {
121123
final IntervalList targetIntervals = IntervalList.fromFiles(TARGET_INTERVALS);
122124

123125
// Validate that the targets and baits have the same references as the reads file
124-
SequenceUtil.assertSequenceDictionariesEqual(
126+
SequenceDictionaryUtils.assertSequenceDictionariesEqual(
125127
reader.getFileHeader().getSequenceDictionary(),
126-
targetIntervals.getHeader().getSequenceDictionary());
127-
SequenceUtil.assertSequenceDictionariesEqual(
128+
INPUT.getAbsolutePath(),
129+
targetIntervals.getHeader().getSequenceDictionary(),
130+
"target intervals");
131+
SequenceDictionaryUtils.assertSequenceDictionariesEqual(
128132
reader.getFileHeader().getSequenceDictionary(),
129-
getProbeIntervals().getHeader().getSequenceDictionary()
130-
);
133+
INPUT.getAbsolutePath(),
134+
getProbeIntervals().getHeader().getSequenceDictionary(),
135+
"probe intervals");
131136

132137
ReferenceSequenceFile ref = null;
133138
if (REFERENCE_SEQUENCE != null) {
134139
IOUtil.assertFileIsReadable(REFERENCE_SEQUENCE);
135140
ref = ReferenceSequenceFileFactory.getReferenceSequenceFile(REFERENCE_SEQUENCE);
136-
SequenceUtil.assertSequenceDictionariesEqual(
137-
reader.getFileHeader().getSequenceDictionary(), ref.getSequenceDictionary(),
138-
INPUT, REFERENCE_SEQUENCE
139-
);
141+
SequenceDictionaryUtils.assertSequenceDictionariesEqual(
142+
reader.getFileHeader().getSequenceDictionary(),
143+
INPUT.getAbsolutePath(),
144+
ref.getSequenceDictionary(),
145+
REFERENCE_SEQUENCE.getAbsolutePath());
140146
}
141147

142148
final COLLECTOR collector = makeCollector(

src/main/java/picard/analysis/replicates/CollectIndependentReplicateMetrics.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@
4545
import htsjdk.samtools.util.IOUtil;
4646
import htsjdk.samtools.util.Log;
4747
import htsjdk.samtools.util.ProgressLogger;
48-
import htsjdk.samtools.util.SequenceUtil;
4948
import htsjdk.utils.ValidationUtils;
5049
import htsjdk.variant.variantcontext.Allele;
5150
import htsjdk.variant.variantcontext.VariantContext;
@@ -67,6 +66,7 @@
6766
import picard.cmdline.StandardOptionDefinitions;
6867
import picard.cmdline.programgroups.DiagnosticsAndQCProgramGroup;
6968
import picard.filter.CountingPairedFilter;
69+
import picard.util.SequenceDictionaryUtils;
7070

7171
import java.io.File;
7272
import java.util.HashMap;
@@ -207,8 +207,11 @@ protected int doWork() {
207207
final VCFFileReader vcf = new VCFFileReader(VCF, false);
208208
final VCFHeader vcfFileHeader = vcf.getFileHeader();
209209

210-
211-
SequenceUtil.assertSequenceDictionariesEqual(in.getFileHeader().getSequenceDictionary(), vcfFileHeader.getSequenceDictionary());
210+
SequenceDictionaryUtils.assertSequenceDictionariesEqual(
211+
in.getFileHeader().getSequenceDictionary(),
212+
INPUT.getAbsolutePath(),
213+
vcfFileHeader.getSequenceDictionary(),
214+
VCF.getAbsolutePath());
212215

213216
final List<String> samples = vcfFileHeader.getSampleNamesInOrder();
214217

src/main/java/picard/fingerprint/CheckFingerprint.java

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -248,9 +248,16 @@ protected int doWork() {
248248
final FingerprintChecker checker = new FingerprintChecker(HAPLOTYPE_MAP);
249249
checker.setReferenceFasta(REFERENCE_SEQUENCE);
250250

251-
SequenceUtil.assertSequenceDictionariesEqual(SAMSequenceDictionaryExtractor.extractDictionary(inputPath), SAMSequenceDictionaryExtractor.extractDictionary(genotypesPath), true);
252-
SequenceUtil.assertSequenceDictionariesEqual(SAMSequenceDictionaryExtractor.extractDictionary(inputPath), checker.getHeader().getSequenceDictionary(), true);
253-
251+
try {
252+
SequenceUtil.assertSequenceDictionariesEqual(SAMSequenceDictionaryExtractor.extractDictionary(inputPath), SAMSequenceDictionaryExtractor.extractDictionary(genotypesPath), true);
253+
} catch (final SequenceUtil.SequenceListsDifferException e) {
254+
throw new PicardException("Dictionary in " + inputPath + " does not match dictionary in " + genotypesPath, e);
255+
}
256+
try {
257+
SequenceUtil.assertSequenceDictionariesEqual(SAMSequenceDictionaryExtractor.extractDictionary(inputPath), checker.getHeader().getSequenceDictionary(), true);
258+
} catch (final SequenceUtil.SequenceListsDifferException e) {
259+
throw new PicardException("Dictionary in " + inputPath + " does not match dictionary in " + HAPLOTYPE_MAP, e);
260+
}
254261

255262

256263
final String observedSampleAlias = extractObservedSampleName(inputPath, OBSERVED_SAMPLE_ALIAS);

src/main/java/picard/fingerprint/FingerprintChecker.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -223,9 +223,13 @@ private void checkDictionaryGoodForFingerprinting(final SAMSequenceDictionary se
223223
final SAMSequenceDictionary activeDictionary = getActiveDictionary(haplotypes);
224224

225225
if (sequenceDictionaryToCheck.getSequences().size() < activeDictionary.size()) {
226-
throw new IllegalArgumentException("Dictionary on fingerprinted file smaller than that on Haplotype Database!");
226+
throw new SequenceUtil.SequenceListsDifferException("Dictionary on fingerprinted file smaller than that on Haplotype Database!");
227+
}
228+
try {
229+
SequenceUtil.assertSequenceDictionariesEqual(activeDictionary, sequenceDictionaryToCheck, true);
230+
} catch (final SequenceUtil.SequenceListsDifferException e) {
231+
throw new PicardException("Dictionary on fingerprinted file does not match dictionary in Haplotype Database.", e);
227232
}
228-
SequenceUtil.assertSequenceDictionariesEqual(activeDictionary, sequenceDictionaryToCheck, true);
229233
}
230234

231235
private static SAMSequenceDictionary getActiveDictionary(final HaplotypeMap haplotypes) {

src/main/java/picard/reference/ExtractSequences.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
import org.broadinstitute.barclay.argparser.CommandLineProgramProperties;
4040
import picard.cmdline.programgroups.ReferenceProgramGroup;
4141
import picard.cmdline.StandardOptionDefinitions;
42+
import picard.util.SequenceDictionaryUtils;
4243

4344
import java.io.BufferedWriter;
4445
import java.io.File;
@@ -93,7 +94,11 @@ protected int doWork() {
9394

9495
final IntervalList intervals = IntervalList.fromFile(INTERVAL_LIST);
9596
final ReferenceSequenceFile ref = ReferenceSequenceFileFactory.getReferenceSequenceFile(REFERENCE_SEQUENCE);
96-
SequenceUtil.assertSequenceDictionariesEqual(intervals.getHeader().getSequenceDictionary(), ref.getSequenceDictionary());
97+
SequenceDictionaryUtils.assertSequenceDictionariesEqual(
98+
intervals.getHeader().getSequenceDictionary(),
99+
INTERVAL_LIST.getAbsolutePath(),
100+
ref.getSequenceDictionary(),
101+
REFERENCE_SEQUENCE.getAbsolutePath());
97102

98103
final BufferedWriter out = IOUtil.openFileForBufferedWriting(OUTPUT);
99104

src/main/java/picard/util/BaitDesigner.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -450,8 +450,11 @@ protected int doWork() {
450450
final ReferenceSequenceFileWalker referenceWalker = new ReferenceSequenceFileWalker(REFERENCE_SEQUENCE);
451451

452452
// Check that the reference and the target list have matching headers
453-
SequenceUtil.assertSequenceDictionariesEqual(referenceWalker.getSequenceDictionary(),
454-
targets.getHeader().getSequenceDictionary());
453+
SequenceDictionaryUtils.assertSequenceDictionariesEqual(
454+
referenceWalker.getSequenceDictionary(),
455+
REFERENCE_SEQUENCE.getAbsolutePath(),
456+
targets.getHeader().getSequenceDictionary(),
457+
TARGETS.getAbsolutePath());
455458

456459
// Design the baits!
457460
int discardedBaits = 0;

src/main/java/picard/util/SequenceDictionaryUtils.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
*/
2424
package picard.util;
2525

26+
import htsjdk.samtools.SAMSequenceDictionary;
2627
import htsjdk.samtools.SAMSequenceDictionaryCodec;
2728
import htsjdk.samtools.SAMSequenceRecord;
2829
import htsjdk.samtools.reference.ReferenceSequence;
@@ -32,6 +33,7 @@
3233
import htsjdk.samtools.util.IOUtil;
3334
import htsjdk.samtools.util.RuntimeIOException;
3435
import htsjdk.samtools.util.SortingCollection;
36+
import htsjdk.samtools.util.SequenceUtil;
3537
import htsjdk.samtools.util.StringUtil;
3638
import picard.PicardException;
3739

@@ -192,6 +194,30 @@ public static SortingCollection<String> makeSortingCollection() {
192194
);
193195
}
194196

197+
/**
198+
* Throw an exception if the two provided sequence dictionaries are not equal.
199+
*
200+
* @param firstDict first dictionary to compare
201+
* @param firstDictSource a user-recognizable message identifying the source of the first dictionary, preferably a file path
202+
* @param secondDict second dictionary to compare
203+
* @param secondDictSource a user-recognizable message identifying the source of the second dictionary, preferably a file path
204+
*/
205+
public static void assertSequenceDictionariesEqual(
206+
final SAMSequenceDictionary firstDict,
207+
final String firstDictSource,
208+
final SAMSequenceDictionary secondDict,
209+
final String secondDictSource) {
210+
try {
211+
SequenceUtil.assertSequenceDictionariesEqual(firstDict, secondDict);
212+
} catch (final SequenceUtil.SequenceListsDifferException e) {
213+
throw new PicardException(
214+
String.format("Sequence dictionary for (%s) does not match sequence dictionary for (%s)",
215+
firstDictSource,
216+
secondDictSource),
217+
e);
218+
}
219+
}
220+
195221
private static class StringCodec implements SortingCollection.Codec<String> {
196222
private DataInputStream dis;
197223
private DataOutputStream dos;

0 commit comments

Comments
 (0)