Сравнение двух больших файлов в Clojure (то есть поиск несопоставленных операций чтения в выравнивании tophat) - PullRequest
3 голосов
/ 16 августа 2011

Проблема: найти идентификаторы, которые находятся в одном файле, но не в другом. Каждый файл составляет около 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, но мой пост уже немного длинен. Я могу показать их позже, если это будет необходимо).

1 Ответ

6 голосов
/ 16 августа 2011
  1. сортировка наборов данных (чтение фрагментов в память, сортировка, запись во временный файл, объединение отсортированных файлов)
  2. итерация по обоим наборам для поиска пересекающихся / отсутствующих элементов (надеюсь, алгоритм ясен)
...