package picard.illumina.parser; import htsjdk.samtools.util.IOUtil; import picard.illumina.parser.fakers.MultiTileBclFileFaker; import java.io.File; import java.util.ArrayList; import java.util.Collections; import java.util.List; /** * NextSeq-style bcl's have all tiles for a cycle in a single file. */ public class MultiTileBclFileUtil extends ParameterizedFileUtil { final File basecallLaneDir; final File bci; final TileIndex tileIndex; final CycleIlluminaFileMap cycleFileMap = new CycleIlluminaFileMap(); MultiTileBclFileUtil(final File basecallLaneDir, final int lane) { // Since these file names do not contain lane number, first two args to ctor are the same. super("^(\\d{4}).bcl.bgzf$", ".bcl.bgzf", basecallLaneDir, new MultiTileBclFileFaker(), lane); this.basecallLaneDir = basecallLaneDir; bci = new File(basecallLaneDir, "s_" + lane + ".bci"); // Do this once rather than when deciding if these files exist and again later. final File[] cycleFiles = IOUtil.getFilesMatchingRegexp(base, matchPattern); if (bci.exists()) { tileIndex = new TileIndex(bci); if (cycleFiles != null) { for (final File file : cycleFiles) { final String fileName = file.getName(); final String cycleNum = fileName.substring(0, fileName.indexOf('.')); final IlluminaFileMap fileMap = new IlluminaFileMap(); for(final Integer tile : tileIndex.getTiles()) { fileMap.put(tile, file); } cycleFileMap.put(Integer.valueOf(cycleNum), fileMap); } } } else { tileIndex = null; } } public CycleIlluminaFileMap getFiles(final List<Integer> tiles, final int[] cycles) { // Filter input list of cycles according to which actually exist final ArrayList<Integer> goodCycleList = new ArrayList<Integer>(cycles.length); for (final int cycle : cycles) { if (cycleFileMap.containsKey(cycle)) { goodCycleList.add(cycle); } } // Ensure cycles are sorted. Collections.sort(goodCycleList); final int[] goodCycles = new int[goodCycleList.size()]; for (int i = 0; i < goodCycles.length; ++i) { goodCycles[i] = goodCycleList.get(i); } // Create the map. final CycleIlluminaFileMap cycledMap = new CycleIlluminaFileMap(); if (goodCycles.length > 0) { for(final int cycle : goodCycles) { final IlluminaFileMap fileMap = cycleFileMap.get(cycle).keep(tiles); cycledMap.put(cycle, fileMap); } } return cycledMap; } @Override public boolean filesAvailable() { return bci.exists() && cycleFileMap.size() > 0; } @Override public List<Integer> getTiles() { if (tileIndex == null) { return Collections.emptyList(); } return tileIndex.getTiles(); } @Override public List<String> verify(final List<Integer> expectedTiles, final int[] expectedCycles) { if (tileIndex == null) { return Collections.singletonList("Tile index(" + bci.getAbsolutePath() + ") does not exist!"); } final List<String> ret = tileIndex.verify(expectedTiles); for (final int expectedCycle : expectedCycles) { if (!cycleFileMap.containsKey(expectedCycle)) { ret.add(expectedCycle + ".bcl.bgzf not found in " + base); } } return ret; } @Override public List<String> fakeFiles(final List<Integer> expectedTiles, final int[] expectedCycles, final IlluminaFileUtil.SupportedIlluminaFormat format) { if (tileIndex == null) { return Collections.singletonList("Tile index(" + bci.getAbsolutePath() + ") does not exist!"); } final List<String> ret = tileIndex.verify(expectedTiles); for (final int expectedCycle : expectedCycles) { if (!cycleFileMap.containsKey(expectedCycle)) { ret.add(expectedCycle + ".bcl.bgzf not found in " + base); } } return ret; } }