Hmm, es difícil pensar en una forma súper eficiente de hacer esto (asumiendo que los archivos no están ordenados de la misma manera; si lo están, entonces toda esta respuesta es básicamente redundante). Y también asumiendo que los identificadores de lectura para ambos archivos no son una intersección perfecta.
En la parte superior de mi cabeza, probablemente quiera construir un conjunto de identificadores de lectura para el archivo fastq y otro para el bam. Algo de código Python para comenzar con eso:
import pysamimport itertoolsdef get_read_id_fastq (ref_path): "" "Extrae los identificadores de lectura de un archivo fastq." "" Read_ids = set () con open ( ref_path, 'r') as ref: for line in ref: if line.startswith ('@'): # es decir, si la línea es encabezado # divida la línea en espacios, tome el primer elemento, elimine @ read_id = line.split ( '') [0] .replace ('@', '') read_ids.add (read_id) return read_idsdef get_read_id_bam (ref_path): "" "Extrae los identificadores de lectura de un archivo BAM." "" Read_ids = set () con pysam.AlignmentFile (ref_path, 'r', ignore_truncation = True) como ref: para leer en ref: # query_name es el nombre de la plantilla de consulta read_ids.add (read.query_name) return read_idsfastq_ids = get_read_id_fastq (fastq_path) bam_ids = get_read_amid_bam
Luego, tome la intersección de estos dos conjuntos y esos son sus identificadores de lectura comunes.
common_ids = fastq_ids & bam_ids
La siguiente parte será un poco más complicada. Tendrá que recorrer cada archivo de uno en uno. Sugeriría que para el primero que recorra, cree un diccionario en ejecución con la identificación de lectura que se escribió como clave y el 'número de mandril' en el que se escribió como valor. Podría crear un ciclo para el tamaño de su fragmento para administrar esto de manera efectiva
chunk_cycle = itertools.chain (* zip (range (chunk_size) * len (common_ids))) write_idx = {}
La siguiente parte probablemente requerirá que dediques algunos momentos difíciles para que funcione. Pondré un pseudocódigo aproximado para darte una idea.
para la línea en el archivo: read_id = # get line read_id si read_id en common_ids: chunk_num = chunk_cycle.next () write_idx [read_id] = chunk_num file_to_write_to = 'out. {}. bam'.format (chunk_num) # abre este archivo o escribe en él si ya está abierto
Cuando vayas a hacer el siguiente archivo cuando encuentra un id de lectura en el conjunto común, busca su valor en write_idx
y esto le dará el número de fragmento para escribir.
Las lecturas no estarán exactamente en el mismo orden entre los dos archivos, pero podría ordenar más tarde si lo necesita (¿no está seguro de que importe?).
Espero que esto ayude. Lo siento, no pude darte más, pero espero que esto te dé una ventaja.