Package net.sf.cram

Source Code of net.sf.cram.ReadWrite$CramHeader

package net.sf.cram;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import net.sf.cram.io.ByteBufferUtils;
import net.sf.cram.io.ExposedByteArrayOutputStream;
import net.sf.cram.structure.Block;
import net.sf.cram.structure.BlockCompressionMethod;
import net.sf.cram.structure.BlockContentType;
import net.sf.cram.structure.CompressionHeaderBLock;
import net.sf.cram.structure.Container;
import net.sf.cram.structure.ContainerHeaderIO;
import net.sf.cram.structure.Slice;
import net.sf.cram.structure.SliceIO;
import net.sf.picard.util.Log;
import net.sf.samtools.SAMFileHeader;
import net.sf.samtools.SAMTextHeaderCodec;
import net.sf.samtools.util.BufferedLineReader;

public class ReadWrite {
  private static final byte[] CHECK = "".getBytes();
  private static Log log = Log.getInstance(ReadWrite.class);

  private static final boolean check(InputStream is) throws IOException {
    DataInputStream dis = new DataInputStream(is);
    byte[] bytes = new byte[CHECK.length];
    dis.readFully(bytes);

    boolean result = Arrays.equals(CHECK, bytes);

    if (!result)
      log.error("Expected %s but got %s.\n", new String(CHECK),
          new String(bytes));

    return result;
  }

  private static final void check(OutputStream os) throws IOException {
    os.write(CHECK);
  }

  public static final class CramHeader {

    public static final byte[] magick = "CRAM".getBytes();
    public byte majorVersion;
    public byte minorVersion;
    public final byte[] id = new byte[20];

    public SAMFileHeader samFileHeader;

    private CramHeader() {
    }

    public CramHeader(int majorVersion, int minorVersion, String id,
        SAMFileHeader samFileHeader) {
      this.majorVersion = (byte) majorVersion;
      this.minorVersion = (byte) minorVersion;
      System.arraycopy(id.getBytes(), 0, this.id, 0,
          Math.min(id.length(), this.id.length));
      this.samFileHeader = samFileHeader;
    }

  }

  public static long writeCramHeader(CramHeader h, OutputStream os)
      throws IOException {
    os.write("CRAM".getBytes("US-ASCII"));
    os.write(h.majorVersion);
    os.write(h.minorVersion);
    os.write(h.id);

    long len = writeContainer(h.samFileHeader, os);

    return 4 + 1 + 1 + 20 + len;
  }

  public static CramHeader readCramHeader(InputStream is) throws IOException {
    CramHeader h = new CramHeader();
    for (byte b : CramHeader.magick) {
      if (b != is.read())
        throw new RuntimeException("Unknown file format.");
    }

    h.majorVersion = (byte) is.read();
    h.minorVersion = (byte) is.read();

    DataInputStream dis = new DataInputStream(is);
    dis.readFully(h.id);

    h.samFileHeader = readSAMFileHeader(new String(h.id), is);
    return h;
  }

  public static int writeContainer(Container c, OutputStream os)
      throws IOException {

    long time1 = System.nanoTime();
    ExposedByteArrayOutputStream baos = new ExposedByteArrayOutputStream();

    Block block = new CompressionHeaderBLock(c.h);
    block.write(baos);
    c.blockCount = 1;

    List<Integer> landmarks = new ArrayList<Integer>();
    SliceIO sio = new SliceIO();
    for (int i = 0; i < c.slices.length; i++) {
      Slice s = c.slices[i];
      landmarks.add(baos.size());
      sio.write(s, baos);
      c.blockCount++ ;
      c.blockCount++;
      if (s.embeddedRefBlock != null)
        c.blockCount++;
      c.blockCount += s.external.size();
    }
    c.landmarks = new int[landmarks.size()];
    for (int i = 0; i < c.landmarks.length; i++)
      c.landmarks[i] = landmarks.get(i);

    c.containerByteSize = baos.size();
    calculateSliceOffsetsAndSizes(c);

    ContainerHeaderIO chio = new ContainerHeaderIO();
    int len = chio.writeContainerHeader(c, os);
    os.write(baos.getBuffer(), 0, baos.size());
    len += baos.size();

    long time2 = System.nanoTime();

    log.debug("CONTAINER WRITTEN: " + c.toString());
    c.writeTime = time2 - time1;

    return len;
  }

  public static Container readContainer(SAMFileHeader samFileHeader,
      InputStream is) throws IOException {
    return readContainer(samFileHeader, is, 0, Integer.MAX_VALUE);
  }

  public static Container readContainerHeader(InputStream is)
      throws IOException {
    Container c = new Container();
    ContainerHeaderIO chio = new ContainerHeaderIO();
    if (!chio.readContainerHeader(c, is)) return null ;
    return c;
  }

  public static Container readContainer(SAMFileHeader samFileHeader,
      InputStream is, int fromSlice, int howManySlices)
      throws IOException {

    long time1 = System.nanoTime();
    Container c = readContainerHeader(is);
    if (c == null) return null ;

    CompressionHeaderBLock chb = new CompressionHeaderBLock(is);
    c.h = chb.getCompressionHeader();
    howManySlices = Math.min(c.landmarks.length, howManySlices);

    if (fromSlice > 0)
      is.skip(c.landmarks[fromSlice]);

    SliceIO sio = new SliceIO();
    List<Slice> slices = new ArrayList<Slice>();
    for (int s = fromSlice; s < howManySlices - fromSlice; s++) {
      Slice slice = new Slice();
      sio.readSliceHeadBlock(slice, is);
      sio.readSliceBlocks(slice, true, is);
      slices.add(slice) ;
    }

    c.slices = (Slice[]) slices.toArray(new Slice[slices.size()]);

    calculateSliceOffsetsAndSizes(c);

    long time2 = System.nanoTime();

    log.debug("READ CONTAINER: " + c.toString());
    c.readTime = time2 - time1;

    return c;
  }

  private static void calculateSliceOffsetsAndSizes(Container c) {
    for (int i = 0; i < c.slices.length - 1; i++) {
      Slice s = c.slices[i];
      s.offset = c.landmarks[i];
      s.size = c.landmarks[i + 1] - s.offset;
    }
    Slice lastSlice = c.slices[c.slices.length - 1];
    lastSlice.offset = c.landmarks[c.landmarks.length - 1];
    lastSlice.size = c.containerByteSize - lastSlice.offset;
  }

  private static byte[] toByteArray(SAMFileHeader samFileHeader) {
    ExposedByteArrayOutputStream headerBodyOS = new ExposedByteArrayOutputStream();
    OutputStreamWriter w = new OutputStreamWriter(headerBodyOS);
    new SAMTextHeaderCodec().encode(w, samFileHeader);
    try {
      w.close();
    } catch (IOException e) {
      throw new RuntimeException(e);
    }

    ByteBuffer buf = ByteBuffer.allocate(4);
    buf.order(ByteOrder.LITTLE_ENDIAN);
    buf.putInt(headerBodyOS.size());
    buf.flip();
    byte[] bytes = new byte[buf.limit()];
    buf.get(bytes);

    ByteArrayOutputStream headerOS = new ExposedByteArrayOutputStream();
    try {
      headerOS.write(bytes);
      headerOS.write(headerBodyOS.getBuffer(), 0, headerBodyOS.size());
    } catch (IOException e) {
      throw new RuntimeException(e);
    }

    return headerOS.toByteArray();
  }

  private static long writeContainer(SAMFileHeader samFileHeader,
      OutputStream os) throws IOException {
    Block block = new Block();
    block.setRawContent(toByteArray(samFileHeader));
    block.method = BlockCompressionMethod.RAW.ordinal();
    block.contentId = 0;
    block.contentType = BlockContentType.FILE_HEADER;
    block.compress();

    Container c = new Container();
    c.blockCount = 1;
    c.blocks = new Block[] { block };
    c.landmarks = new int[0];
    c.slices = new Slice[0];
    c.alignmentSpan = 0;
    c.alignmentStart = 0;
    c.bases = 0;
    c.globalRecordCounter = 0;
    c.nofRecords = 0;
    c.sequenceId = 0;

    ExposedByteArrayOutputStream baos = new ExposedByteArrayOutputStream();
    block.write(baos);
    c.containerByteSize = baos.size();

    ContainerHeaderIO chio = new ContainerHeaderIO();
    int len = chio.writeContainerHeader(c, os);
    os.write(baos.getBuffer(), 0, baos.size());

    return len + baos.size();
  }

  private static SAMFileHeader readSAMFileHeader(String id, InputStream is)
      throws IOException {
    Container readContainerHeader = readContainerHeader(is);
    Block b = new Block(is, true, true);

    is = new ByteArrayInputStream(b.getRawContent());

    ByteBuffer buf = ByteBuffer.allocate(4);
    buf.order(ByteOrder.LITTLE_ENDIAN);
    for (int i = 0; i < 4; i++)
      buf.put((byte) is.read());
    buf.flip();
    int size = buf.asIntBuffer().get();

    DataInputStream dis = new DataInputStream(is);
    byte[] bytes = new byte[size];
    dis.readFully(bytes);

    BufferedLineReader r = new BufferedLineReader(new ByteArrayInputStream(
        bytes));
    return new SAMTextHeaderCodec().decode(r, id);
  }
}
TOP

Related Classes of net.sf.cram.ReadWrite$CramHeader

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.