Skip to content

Commit

Permalink
Added reverse cycle and base dir lookup for tile metrics. (#1158)
Browse files Browse the repository at this point in the history
  • Loading branch information
jacarey authored Apr 13, 2018
1 parent 9e91442 commit 0b8bf5e
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ public static class IlluminaLaneMetricsCollector {
final boolean isNovaSeq) {
final Collection<Tile> tiles;
try {
File tileMetricsOutFile = TileMetricsUtil.renderTileMetricsFileFromBasecallingDirectory(illuminaRunDirectory, isNovaSeq);
File tileMetricsOutFile = TileMetricsUtil.renderTileMetricsFileFromBasecallingDirectory(illuminaRunDirectory, readStructure.totalCycles, isNovaSeq);
if (isNovaSeq) {
tiles = TileMetricsUtil.parseTileMetrics(
tileMetricsOutFile,
Expand Down
34 changes: 26 additions & 8 deletions src/main/java/picard/illumina/parser/TileMetricsUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@

import java.io.File;
import java.io.FileNotFoundException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
Expand All @@ -56,10 +58,7 @@
public class TileMetricsUtil {

private static final Log log = Log.getInstance(TileMetricsUtil.class);
/**
* The cycle directory that contain the tile metrics output. (Cycle 25 for NovaSeq)
*/
public static String CYCLE_CONTAINING_TILE_METRICS = "C25.1";

/**
* The path to the directory containing the tile metrics file relative to the basecalling directory.
*/
Expand All @@ -75,12 +74,31 @@ public class TileMetricsUtil {
/**
* Returns the path to the TileMetrics file given the basecalling directory.
*/
public static File renderTileMetricsFileFromBasecallingDirectory(final File illuminaRunDirectory, boolean isNovaSeq) {
public static File renderTileMetricsFileFromBasecallingDirectory(final File illuminaRunDirectory, Integer numCycles, boolean isNovaSeq) {
return fileTileMetricsFile(illuminaRunDirectory, numCycles, isNovaSeq);
}

private static File fileTileMetricsFile(File illuminaRunDirectory, Integer numCycles, boolean isNovaSeq) {
Path interOpDir = illuminaRunDirectory.toPath().resolve(INTEROP_SUBDIRECTORY_NAME);
final List<Path> pathsToTest = new ArrayList<>();

pathsToTest.add(interOpDir.resolve(TILE_METRICS_OUT_FILE_NAME));

if (isNovaSeq) {
return new File(new File(illuminaRunDirectory, INTEROP_SUBDIRECTORY_NAME + File.separator + CYCLE_CONTAINING_TILE_METRICS), TILE_METRICS_OUT_FILE_NAME);
} else {
return new File(new File(illuminaRunDirectory, INTEROP_SUBDIRECTORY_NAME), TILE_METRICS_OUT_FILE_NAME);
// check cycles in reverse order.
for (int i = numCycles; i > 0; i--) {
pathsToTest.add(interOpDir.resolve(String.format("C%d.1/%s", i, TILE_METRICS_OUT_FILE_NAME)));
}
}

return pathsToTest.stream().filter(Files::exists).findFirst().orElseThrow(() -> {
StringBuilder message = new StringBuilder(
String.format("No %s file found in %s", INTEROP_SUBDIRECTORY_NAME, interOpDir));
if (isNovaSeq) {
message.append(" or any of its cycle directories.");
}
return new IllegalStateException(message.toString());
}).toFile();
}

public static Collection<Tile> parseTileMetrics(final File tileMetricsOutFile,
Expand Down
83 changes: 83 additions & 0 deletions src/test/java/picard/illumina/parser/TileMetricsUtilTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package picard.illumina.parser;

import htsjdk.samtools.util.IOUtil;
import org.testng.Assert;
import org.testng.annotations.Test;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.stream.IntStream;

public class TileMetricsUtilTest {
@Test
public void testFindTileMetrics() throws IOException {
Path baseDir = createTestDirs(0, true);
File tileMetricsFile = TileMetricsUtil.renderTileMetricsFileFromBasecallingDirectory(
baseDir.toFile(), 0, false);

Assert.assertEquals(tileMetricsFile.getAbsolutePath(),
baseDir.resolve(TileMetricsUtil.INTEROP_SUBDIRECTORY_NAME)
.resolve(TileMetricsUtil.TILE_METRICS_OUT_FILE_NAME).toString());

IOUtil.deleteDirectoryTree(baseDir.toFile());
}

@Test(expectedExceptions = IllegalStateException.class)
public void testMissingTileMetrics() throws IOException {
Path baseDir = createTestDirs(0, false);
TileMetricsUtil.renderTileMetricsFileFromBasecallingDirectory(
baseDir.toFile(), 0, false);

IOUtil.deleteDirectoryTree(baseDir.toFile());
}

// put tile metrics file in 1 random cycle dir and interop based ensure we get the one in base
@Test
public void testFindTileMetricsNovaSeqInBaseInterOp() throws IOException {
Path baseDir = createTestDirs(1, true);
File tileMetricsFile = TileMetricsUtil.renderTileMetricsFileFromBasecallingDirectory(
baseDir.toFile(), 1, true);

Assert.assertEquals(tileMetricsFile.getAbsolutePath(),
baseDir.resolve(TileMetricsUtil.INTEROP_SUBDIRECTORY_NAME)
.resolve(TileMetricsUtil.TILE_METRICS_OUT_FILE_NAME).toString());

IOUtil.deleteDirectoryTree(baseDir.toFile());
}

// put a file named tile metrics in 2 cycle directories and ensure that we get the one in the highest cycle
@Test
public void testFindTileMetricsNovaSeqInCycleDirs() throws IOException {
Path baseDir = createTestDirs(2, false);
File tileMetricsFile = TileMetricsUtil.renderTileMetricsFileFromBasecallingDirectory(
baseDir.toFile(), 2, true);

Assert.assertEquals(tileMetricsFile.getAbsolutePath(),
baseDir.resolve(TileMetricsUtil.INTEROP_SUBDIRECTORY_NAME).resolve("C2.1")
.resolve(TileMetricsUtil.TILE_METRICS_OUT_FILE_NAME).toString());

IOUtil.deleteDirectoryTree(baseDir.toFile());
}

private Path createTestDirs(int numCycleMetricsFiles, boolean baseMetricsFile) throws IOException {
Path baseDir = Files.createTempDirectory("TileMetricsUtilTest");
// create 10 cycle dirs put tile metrics in the last one.
Path baseOpDir = Files.createDirectory(baseDir.resolve(TileMetricsUtil.INTEROP_SUBDIRECTORY_NAME));
IntStream.range(1, numCycleMetricsFiles + 1).forEach(i -> {
try {
Path cycleDir = Files.createDirectory(baseOpDir.resolve("C" + i + ".1"));
if (i == numCycleMetricsFiles) {
Files.createFile(cycleDir.resolve(TileMetricsUtil.TILE_METRICS_OUT_FILE_NAME));
}
} catch (IOException e) {
e.printStackTrace();
}
});
if (baseMetricsFile) {
Files.createFile(baseOpDir.resolve(TileMetricsUtil.TILE_METRICS_OUT_FILE_NAME));
}
return baseDir;
}
}
Binary file not shown.

0 comments on commit 0b8bf5e

Please sign in to comment.