/// <summary>
/// Merge multiple sorted alignments.
/// SAMUtil.exe out.bam in1.bam in2.bam
/// </summary>
public void DoMerge()
{
if (FilePaths == null)
{
throw new InvalidOperationException("FilePath");
}
if (FilePaths.Length < 2)
{
throw new InvalidOperationException(Resources.MergeHelp);
}
IList<IList<BAMSortedIndex>> sortedIndexes = new List<IList<BAMSortedIndex>>();
IList<SequenceAlignmentMap> sequenceAlignmentMaps = new List<SequenceAlignmentMap>();
Parallel.For(0, FilePaths.Length, (int index) =>
{
IList<BAMSortedIndex> sortedIndex;
BAMParser parser = new BAMParser(); ;
SequenceAlignmentMap map;
if (index == 0)
{
try
{
map = parser.ParseOne<SequenceAlignmentMap>(FilePaths[0]);
}
catch
{
throw new InvalidOperationException(Resources.InvalidBAMFile);
}
if (map == null)
{
throw new InvalidOperationException(Resources.EmptyFile);
}
if (string.IsNullOrEmpty(HeaderFile) && map.Header.RecordFields.Count == 0)
{
throw new InvalidOperationException(Resources.HeaderMissing);
}
if (!string.IsNullOrEmpty(HeaderFile))
{
SAMParser parse = new SAMParser();
SequenceAlignmentMap head;
try
{
head = parse.ParseOne<SequenceAlignmentMap>(HeaderFile);
}
catch
{
throw new InvalidOperationException(Resources.IncorrectHeaderFile);
}
if (head == null)
{
throw new InvalidOperationException(Resources.EmptyFile);
}
header = head.Header;
}
else
{
header = map.Header;
}
sortedIndex = Sort(map, SortByReadName ? BAMSortByFields.ReadNames : BAMSortByFields.ChromosomeCoordinates);
}
else
{
try
{
map = parser.ParseOne<SequenceAlignmentMap>(FilePaths[index]);
}
catch
{
throw new InvalidOperationException(Resources.InvalidBAMFile);
}
if (map == null)
{
throw new InvalidOperationException(Resources.EmptyFile);
}
sortedIndex = Sort(map, SortByReadName ? BAMSortByFields.ReadNames : BAMSortByFields.ChromosomeCoordinates);
}
lock (sortedIndexes)
{
sortedIndexes.Add(sortedIndex);
sequenceAlignmentMaps.Add(map);
}
});
if (string.IsNullOrEmpty(OutputFilename))
{
OutputFilename = "out.bam";
autoGeneratedOutputFilename = true;
}
string filePath = Path.GetTempFileName();
using (FileStream fstemp = new FileStream(filePath, FileMode.Create, FileAccess.ReadWrite))
{
BAMFormatter formatter = new BAMFormatter();
formatter.WriteHeader(header, fstemp);
if (SortByReadName)
{
IList<BAMSortedIndex> sortedIndex = sortedIndexes.Select(a => a.First()).ToList();
WriteMergeFileSortedByReadName(sortedIndex, fstemp, formatter, sequenceAlignmentMaps);
}
else
{
WriteMergeFile(sortedIndexes, fstemp, formatter, sequenceAlignmentMaps);
}
using (FileStream fsoutput = new FileStream(OutputFilename, FileMode.Create, FileAccess.Write))
{
fstemp.Seek(0, SeekOrigin.Begin);
formatter.CompressBAMFile(fstemp, fsoutput);
}
}
File.Delete(filePath);
if (autoGeneratedOutputFilename)
{
Console.WriteLine(Properties.Resources.SuccessMessageWithOutputFileName, OutputFilename);
}
}