(ns cljam.io.bam-index.reader
(:require [clojure.java.io :as cio]
[cljam.io.util.lsb.io-stream :as lsb]
[cljam.io.bam-index.common :refer [bai-magic]]
[cljam.io.util.chunk :as chunk]
[cljam.util :as util])
(:import java.util.Arrays
[java.io FileInputStream Closeable IOException]
[cljam.io.util.chunk Chunk])) | |
(deftype BAIReader [url reader]
Closeable
(close [this]
(.close ^Closeable (.reader this)))) | |
(defn- skip-chunks!
[rdr]
(let [n-chunks (int (lsb/read-int rdr))]
(loop [i 0]
(when (< i n-chunks)
(lsb/skip rdr 16)
(recur (inc i)))))) | |
(defn- skip-bin-index!
[rdr]
(let [n-bidx (int (lsb/read-int rdr))]
(loop [i 0]
(when (< i n-bidx)
(lsb/skip rdr 4)
(skip-chunks! rdr)
(recur (inc i)))))) | |
(defn- skip-linear-index!
[rdr]
(let [n-lidx (int (lsb/read-int rdr))]
(loop [i 0]
(when (< i n-lidx)
(lsb/skip rdr 8)
(recur (inc i)))))) | |
(defn- skip-index!
[rdr ^long n]
(loop [i 0]
(when (< i n)
(skip-bin-index! rdr)
(skip-linear-index! rdr)
(recur (inc i))))) | |
(defn- read-chunks!
[rdr]
(let [n (int (lsb/read-int rdr))]
(loop [i 0, chunks []]
(if (< i n)
(recur (inc i) (conj chunks (Chunk. (lsb/read-long rdr) (lsb/read-long rdr))))
chunks)))) | |
(defn- read-bin-index**!
[rdr]
(let [n (int (lsb/read-int rdr))]
(loop [i 0, bidx []]
(if (< i n)
(let [bin (lsb/read-int rdr)
chunks (read-chunks! rdr)]
(recur (inc i) (conj bidx {:bin bin, :chunks chunks})))
bidx)))) | |
(defn- read-bin-index*!
[rdr ^long ref-idx]
(let [n-ref (int (lsb/read-int rdr))]
(when (>= ref-idx n-ref)
(throw (IndexOutOfBoundsException. "The reference index number is invalid")))
(skip-index! rdr ref-idx)
(read-bin-index**! rdr))) | |
(defn- read-linear-index**!
[rdr]
(let [n (int (lsb/read-int rdr))]
(loop [i 0, lidx []]
(if (< i n)
(recur (inc i) (conj lidx (lsb/read-long rdr)))
lidx)))) | |
(defn- read-linear-index*!
[rdr ^long ref-idx]
(let [n-ref (int (lsb/read-int rdr))]
(when (>= ref-idx n-ref)
(throw (IndexOutOfBoundsException. "The reference index number is invalid")))
(skip-index! rdr ref-idx)
(skip-bin-index! rdr)
(read-linear-index**! rdr))) | |
Reads a binning index eagerly for the given reference index. Returns a vector of maps containing :bin and :chunks. | (defn read-bin-index! [^BAIReader rdr ref-idx] (read-bin-index*! (.reader rdr) ref-idx)) |
Reads a linear index eagerly for the given reference index. Returns a vector of linear index numbers | (defn read-linear-index! [^BAIReader rdr ref-idx] (read-linear-index*! (.reader rdr) ref-idx)) |
Reads all linear indices and bin indices. Returns a vector of maps containing :bidx and :lidx. | (defn read-all-index!
[^BAIReader r]
(let [rdr (.reader r)
n-ref (lsb/read-int rdr)
refs (range n-ref)
all-idx (map (fn [_] [(read-bin-index**! rdr) (read-linear-index**! rdr)]) refs)
bidx-seq (map first all-idx)
bidx (zipmap
refs
(map (fn [bins]
(zipmap (map :bin bins) (map :chunks bins)))
bidx-seq))
lidx (zipmap refs (map second all-idx))]
{:bidx bidx
:lidx lidx})) |
Returns an open cljam.io.bam_index.reader.BAIReader of f. Should be used inside with-open to ensure the reader is properly closed. | (defn reader
[f]
(let [url (util/as-url f)
r (if (= (.getProtocol url) "file")
(FileInputStream. (cio/file url))
(.openStream url))]
(when-not (Arrays/equals ^bytes (lsb/read-bytes r 4) (.getBytes ^String bai-magic))
(throw (IOException. "Invalid BAI file")))
(->BAIReader url r))) |