package com.github.lindenb.jvarkit.tools.splitbytitle;
import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
import com.beust.jcommander.Parameter;
import com.beust.jcommander.ParametersDelegate;
import com.github.lindenb.jvarkit.util.jcommander.Launcher;
import com.github.lindenb.jvarkit.util.jcommander.Program;
import com.github.lindenb.jvarkit.util.log.Logger;
import htsjdk.samtools.util.CloserUtil;
import htsjdk.samtools.SAMFileHeader;
import htsjdk.samtools.SAMFileWriter;
import htsjdk.samtools.SAMRecord;
import htsjdk.samtools.SAMRecordIterator;
import htsjdk.samtools.SamReader;
@Program(name="splitbytile",description="Split Bam By tile")
public class SplitByTile extends Launcher
{
private static final String TILEWORD="__TILE__";
private static final Logger LOG = Logger.build(SplitByTile.class).make();
@Parameter(names={"-o","--output"},description="Output file. Must contain "+TILEWORD,required=true)
private String OUTPUT = null;
@ParametersDelegate
private WritingBamArgs writingBamArgs =new WritingBamArgs();
public static void main(final String[] argv)
{
new SplitByTile().instanceMainWithExit(argv);
}
@Override
public int doWork(List<String> args) {
if(OUTPUT==null || !OUTPUT.contains(TILEWORD) || !OUTPUT.endsWith(".bam"))
{
LOG.error("Bad OUPUT name "+OUTPUT+". must contain "+TILEWORD+" and ends with .bam");
return -1;
}
SamReader samReader = null;
Map<Integer, SAMFileWriter> tile2writer=new HashMap<Integer, SAMFileWriter>();
Pattern colon=Pattern.compile("[\\:]");
SAMRecordIterator iter=null;
try
{
samReader= super.openSamReader(oneFileOrNull(args));
final SAMFileHeader header=samReader.getFileHeader();
iter=samReader.iterator();
while(iter.hasNext())
{
SAMRecord rec=iter.next();
String tokens[]=colon.split(rec.getReadName(),6);
if(tokens.length<5)
{
LOG.error("Cannot get the 6th field in "+rec.getReadName());
samReader.close();samReader=null;
return -1;
}
int tile=-1;
try {
tile=Integer.parseInt(tokens[4]);
}
catch (Exception e)
{
}
if(tile<0)
{
LOG.error("Bad tile in read: "+rec.getReadName());
samReader.close();samReader=null;
return -1;
}
SAMFileWriter sfw=tile2writer.get(tile);
if(sfw==null)
{
final File outFile=new File(OUTPUT.replaceAll(TILEWORD, String.valueOf(tile)));
LOG.info("create output for "+outFile );
if(outFile.getParentFile()!=null)
{
outFile.getParentFile().mkdirs();
}
sfw= this.writingBamArgs.openSAMFileWriter(outFile,header,true);
tile2writer.put(tile, sfw);
}
sfw.addAlignment(rec);
}
for(SAMFileWriter sfw:tile2writer.values())
{
sfw.close();
}
}
catch (Exception e) {
LOG.error(e);
return -1;
}
finally
{
if(iter!=null) iter.close();
CloserUtil.close(samReader);
}
return 0;
}
}