Nei*_*eil 3 io clojure bioinformatics out-of-memory lazy-evaluation
问题:找到一个文件中但不存在于另一个文件中的ID.每个文件大约6.5 GB.具体而言(对于生物信息学领域中的那些),一个文件是测序读取的fastq文件,另一个是来自tophat运行的sam对齐文件.我想确定fastq文件中的哪些读取不在sam对齐文件中.
我收到了java.lang.OutOfMemory: Java heap space
错误.正如所建议的那样(ref1,ref2)我正在使用惰性序列.但是,我的内存仍然不足.我看过这个教程,但我还不太了解它.所以我发布了一个不太复杂的尝试解决方案,希望我只是犯了一个小错误.
我的尝试:
由于这两个文件都不适合内存,因此sam文件中的行一次读取一个块,并将块中每行的id放入一个集合中.然后使用集合中的sam id过滤一个懒惰的fastq id列表,只保留那些不在集合中的id.使用下一个sam行和剩余的fastq id重复此操作.
(defn ids-not-in-sam
[ids samlines chunk-size]
(lazy-seq
(if (seq samlines)
(ids-not-in-sam (not-in (into #{} (qnames (take chunk-size samlines))) ids)
(drop chunk-size samlines) chunk-size)
ids)))
Run Code Online (Sandbox Code Playgroud)
not-in
确定哪些ID不在集合中.
(defn not-in
; Return the elements x of xs which are not in the set s
[s xs]
(filter (complement s) xs))
Run Code Online (Sandbox Code Playgroud)
qnames
从sam文件中的一行获取id字段.
(defn qnames [samlines]
(map #(first (.split #"\t" %)) samlines))
Run Code Online (Sandbox Code Playgroud)
最后,它与io放在一起(使用read-lines
和write-lines
来自clojure.contrib.io
.
(defn write-fq-not-in-sam [fqfile samfile fout chunk-size]
(io/write-lines fout (ids-not-in-sam (map fq-id (read-fastq fqfile))
(read-sam samfile) chunk-size)))
Run Code Online (Sandbox Code Playgroud)
我很确定我是以懒惰的方式做所有事情.但我可能会抓住某个我不注意的序列的头部.
上面的代码中是否有错误导致堆填满?更重要的是,我对这个问题的处理方法都错了吗?这是否适用于懒惰序列,我是否期望过多?
(错误可能在read-sam
和read-fastq
函数中,但我的帖子已经有点长了.如果需要,我可以稍后展示它们).