Проблема: найти идентификаторы, которые находятся в одном файле, но не в другом. Каждый файл составляет около 6,5 ГБ. В частности (для тех, кто работает в области биоинформатики), один файл представляет собой файл fastq для чтения последовательностей, а другой - файл выравнивания sam из прогона tophat. Я хотел бы определить, какие операции чтения в файле fastq отсутствуют в файле выравнивания sam.
Я получаю java.lang.OutOfMemory: Java heap space
ошибки. Как предложено ( ref1 , ref2 ), я использую ленивые последовательности. Тем не менее, мне все еще не хватает памяти. Я посмотрел этот урок , но пока не совсем понял. Поэтому я публикую свою менее изощренную попытку найти решение в надежде, что я делаю лишь незначительную ошибку.
Моя попытка:
Поскольку ни один файл не помещается в память, строки из файла sam считываются порцией за раз, и идентификаторы каждой строки в порции помещаются в набор. Ленивый список идентификаторов fastq затем фильтруется с использованием идентификаторов sam в наборе, сохраняя только те идентификаторы, которых нет в наборе. Это повторяется со следующим фрагментом строк sam и оставшимися fastq идентификаторами.
(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)))
not-in
определяет, какие идентификаторы отсутствуют в наборе.
(defn not-in
; Return the elements x of xs which are not in the set s
[s xs]
(filter (complement s) xs))
qnames
получает поле id из строки в файле sam.
(defn qnames [samlines]
(map #(first (.split #"\t" %)) samlines))
Наконец, его вместе с 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)))
Я почти уверен, что делаю все лениво. Но я, возможно, держусь за голову последовательности, которую я не замечаю.
Есть ли в приведенном выше коде ошибка, приводящая к заполнению кучи? Что еще более важно, мой подход к проблеме все неправильно? Это подходящее использование для ленивых последовательностей, я ожидаю слишком многого?
(ошибки могут быть в функциях read-sam
и read-fastq
, но мой пост уже немного длинен. Я могу показать их позже, если это будет необходимо).