背景:
Linux上のPython2.6.6。DNA配列分析パイプラインの最初の部分。
マウントされたリモートストレージ(LAN)からgzipで圧縮された可能性のあるファイルを読み取りたいのですが、gzipで圧縮されている場合は; ストリームにgunzipで圧縮し(つまり、を使用gunzip FILENAME -c
)、ストリーム(ファイル)の最初の文字が「@」の場合は、そのストリーム全体を、標準入力で入力を受け取るフィルタリングプログラムにルーティングします。それ以外の場合は、ローカルのファイルに直接パイプします。ディスク。リモートストレージからのファイルの読み取り/シークの数を最小限に抑えたい(ファイルを1回通過するだけで不可能ではないでしょうか?)。
サンプル入力ファイルの内容、FASTQ形式の1つのレコードに対応する最初の4行:
@I328_1_FC30MD2AAXX:8:1:1719:1113/1
GTTATTATTATAATTTTTTACCGCATTTATCATTTCTTCTTTATTTTCATATTGATAATAAATATATGCAATTCG
+I328_1_FC30MD2AAXX:8:1:1719:1113/1
hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhahhhhhhfShhhYhhQhh]hhhhffhU\UhYWc
フィルタリングプログラムにパイプされるべきではないファイルには、次のようなレコードが含まれています(FASTA形式の1つのレコードに対応する最初の2行)。
>I328_1_FC30MD2AAXX:8:1:1719:1113/1
GTTATTATTATAATTTTTTACCGCATTTATCATTTCTTCTTTATTTTCATATTGATAATAAATATATGCAATTCG
何人かは、私がやりたいことを視覚化するための半擬似コードの努力をしました(これは私が書いた方法では不可能であることを私は知っています)。私はそれがある程度意味があることを願っています:
if gzipped:
gunzip = Popen(["gunzip", "-c", "remotestorage/file.gz"], stdout=PIPE)
if gunzip.stdout.peek(1) == "@": # This isn't possible
fastq = True
else:
fastq = False
if fastq:
filter = Popen(["filter", "localstorage/outputfile.fastq"], stdin=gunzip.stdout).communicate()
else:
# Send the gunzipped stream to another file
ここで書いたようにコードが実行されないという事実や、エラー処理などがないという事実は無視してください。これらはすべて、他のコードにすでに含まれています。ストリームを覗いたり、それを回避する方法を見つけたりするのに助けが必要です。できれば素晴らしいgunzip.stdout.peek(1)
のですが、それは不可能だと思います。
私がこれまでに試したこと:
subprocess.Popenがこれを達成するのに役立つかもしれないと考え、ストリームを書き込むためにある種のio.BufferedRandom()オブジェクトを使用しようとするなど、さまざまなアイデアを試しましたが、それがどのように機能するのか理解できません。ストリームはシークできないことは知っていますが、回避策としては、gunzipストリームの最初の文字を読み取ってから、ファイルの内容に応じて最初に「@」または「>」を入力してから残りを詰め込む新しいストリームを作成することが考えられます。 gunzip.stdout-streamを新しいストリームに追加します。この新しいストリームは、フィルターのPopenstdinに送られます。
ファイルサイズは、使用可能なメモリの数倍になる場合があることに注意してください。リモートストレージからのソースファイルの複数の読み取りを実行したくないし、不要なファイルアクセスを実行したくない。
どんなアイデアでも大歓迎です!十分に明確にしなかったかどうかを明確にするために、質問をしてください。