1
+ package org .broadinstitute .hellbender .testutils ;
2
+
3
+ import htsjdk .beta .plugin .IOUtils ;
4
+ import htsjdk .io .IOPath ;
5
+ import htsjdk .samtools .util .FileExtensions ;
6
+ import htsjdk .samtools .util .ProcessExecutor ;
7
+ import java .nio .file .Files ;
8
+ import java .nio .file .Path ;
9
+ import java .nio .file .Paths ;
10
+
11
+ /**
12
+ * Test utilities for running samtools from htsjdk tests.
13
+ */
14
+ public class SamtoolsTestUtils {
15
+ private static final String SAMTOOLS_BINARY_ENV_VARIABLE = "HTSJDK_SAMTOOLS_BIN" ;
16
+ public final static String expectedSamtoolsVersion = "1.21" ;
17
+
18
+ /**
19
+ * @return true if samtools is available, otherwise false
20
+ */
21
+ public static boolean isSamtoolsAvailable () {
22
+ final String binPath = getSamtoolsBin ();
23
+ final Path binFile = Paths .get (binPath );
24
+ return Files .exists (binFile );
25
+ }
26
+
27
+ /**
28
+ * @return true if a local samtools executable is available, otherwise throws a runtimeException
29
+ */
30
+ public static void assertSamtoolsAvailable () {
31
+ if (!isSamtoolsAvailable ()) {
32
+ throw new RuntimeException (
33
+ String .format (
34
+ "No samtools executable can be found." +
35
+ " The %s environment variable must be set to the name of the local samtools executable." ,
36
+ SAMTOOLS_BINARY_ENV_VARIABLE ));
37
+ }
38
+ }
39
+
40
+ /**
41
+ * @return the name and location of the local samtools executable as specified by the environment
42
+ * variable HTSJDK_SAMTOOLS_BIN, or the default value of "/usr/local/bin/samtools" if the environment
43
+ * variable is not set
44
+ */
45
+ public static String getSamtoolsBin () {
46
+ final String samtoolsPath = System .getenv (SAMTOOLS_BINARY_ENV_VARIABLE );
47
+ return samtoolsPath == null ? "/usr/local/bin/samtools" : samtoolsPath ;
48
+ }
49
+
50
+ /**
51
+ * Execute a samtools command line if a local samtools executable is available see {@link #isSamtoolsAvailable()}.
52
+ *
53
+ * @param commandLine samtools command line string, excluding the "samtools" prefix. For example:
54
+ * {@code "view -h -b my.sam -o my.bam"}
55
+ * @return the {@link ProcessExecutor.ExitStatusAndOutput} resulting from the command execution, if
56
+ * the command succeeds
57
+ * @throws RuntimeException if the command fails, or if a local samtools executable is not available.
58
+ */
59
+ public static ProcessExecutor .ExitStatusAndOutput executeSamToolsCommand (final String commandLine ) {
60
+ assertSamtoolsAvailable ();
61
+ final String commandString = String .format ("%s %s" , getSamtoolsBin (), commandLine );
62
+ final ProcessExecutor .ExitStatusAndOutput processStatus =
63
+ ProcessExecutor .executeAndReturnInterleavedOutput (commandString );
64
+ if (processStatus .exitStatus != 0 ) {
65
+ // samtools seems to write some errors to stdout
66
+ throw new RuntimeException (
67
+ String .format ("Failure code %d returned from samtools command %s\n (stderr: %.500s)\n (stdout: %.500s)\n " ,
68
+ processStatus .exitStatus ,
69
+ commandString ,
70
+ processStatus .stderr == null ? "" : processStatus .stderr ,
71
+ processStatus .stdout == null ? "" : processStatus .stdout ));
72
+ }
73
+ return processStatus ;
74
+ }
75
+
76
+ /**
77
+ * Convert an input sam/bam/cram file to a temporary CRAM file using the samtools "view" command. The temp
78
+ * file will be deleted when the process exits. Use {@link #isSamtoolsAvailable()} to determine if its safe
79
+ * to use this method.
80
+ *
81
+ * @param inputSAMBAMCRAMFile input file to convert
82
+ * @param referenceFile a valid reference file
83
+ * @param commandLineOptions additional command line options (--input-fmt-option or --output-fmt-option)
84
+ * @return a temporary file containing the samtools-generated results.
85
+ */
86
+ public static final IOPath convertToCRAM (
87
+ final IOPath inputSAMBAMCRAMFile ,
88
+ final IOPath referenceFile ,
89
+ final String commandLineOptions ) {
90
+ assertSamtoolsAvailable ();
91
+ final IOPath tempCRAMPath = IOUtils .createTempPath ("samtoolsTemporaryCRAM" , FileExtensions .CRAM );
92
+ tempCRAMPath .toPath ().toFile ().deleteOnExit ();
93
+ final String commandString = String .format ("view -h -C -T %s %s %s -o %s" ,
94
+ referenceFile .toPath ().toAbsolutePath (),
95
+ commandLineOptions == null ? "" : commandLineOptions ,
96
+ inputSAMBAMCRAMFile .toPath ().toAbsolutePath (),
97
+ tempCRAMPath .toPath ().toAbsolutePath ());
98
+ executeSamToolsCommand (commandString );
99
+ return tempCRAMPath ;
100
+ }
101
+
102
+ public static final void convertToCRAM (
103
+ final IOPath inputSAMBAMCRAMPath ,
104
+ final IOPath outputPath ,
105
+ final IOPath referencePath ,
106
+ final String commandLineOptions ) {
107
+ assertSamtoolsAvailable ();
108
+ final String commandString = String .format ("view -h -C -T %s %s %s -o %s" ,
109
+ referencePath .toPath ().toAbsolutePath (),
110
+ commandLineOptions == null ? "" : commandLineOptions ,
111
+ inputSAMBAMCRAMPath .toPath ().toAbsolutePath (),
112
+ outputPath .toPath ().toAbsolutePath ());
113
+ executeSamToolsCommand (commandString );
114
+ }
115
+ }
0 commit comments