שְׁאֵלָה:
כיצד לקבוע משנה של BAM לפי רשימת QNAME?
EB2127
2018-01-24 00:41:27 UTC
view on stackexchange narkive permalink

יש לי קובץ טקסט 'qnames.txt' עם QNAME בפורמט הבא:

  דוגמא: QNAME1EXAMPLE: QNAME2EXAMPLE: QNAME3EXAMPLE: QNAME4EXAMPLE: QNAME5  

ברצוני להגדיר את ה- BAM file.bam שלי דרך כל ה- QNAME הללו ל- SAM חדש.

באופן טבעי, אני יכול לעשות זאת בנפרד, למשל

samtools להציג file.bam | grep 'דוגמא: QNAME1' > subset.bam

אבל אני לא בטוח איך לעשות זאת לרשימת QNAMES:

  1. כיצד האם אני כותב לולאה עבור שתבצע את כל השאילתות הללו, ותוציא את ה- SAM הנכון הדרוש?

    אוכל לכתוב לולאה ל קוד> שיוצר n קובצי SAM ואז cat s אותם ...

  2. האם יש דרך grep ספציפית על ידי QNAME? האמור לעיל עשוי לקרוא ב- grep שאולי לא משויכים ל- QNAME הנכון?

  3. כיצד אוכל לשמור על כותרת ה- BAM?

האם QNAME אלה אינם קשורים לחלוטין? אם, במקרה, אתה פשוט רוצה לבחור את כל הקריאות השייכות לאותה קבוצת קריאה (אשר נקבעת על ידי QNAME), אז יש פיתרון הרבה יותר יעיל ופשוט יותר.
אכפת @KonradRudolph להוסיף את הפיתרון כאן?
@Beeba בהתחשב בכך ש- OP לא אישרה אם אכן רצוי לפצל על ידי קבוצות קריאה, אני לא שואל לפרסם כאן תשובה לא קשורה. עם זאת, זה פשוט מה שהפקודה `samtools split 'עושה.
@KonradRudolph הגיוני, אין דאגות. אני אסתכל על פיצול samtools. תודה
שֵׁשׁ תשובות:
Pierre
2018-01-25 04:05:01 UTC
view on stackexchange narkive permalink

השתמש ב- picard FilterSamReads http://broadinstitute.github.io/picard/command-line-overview.html#FilterSamReads

READ_LIST_FILE (קובץ) רשימת קריאה קובץ המכיל קריאות שייכלל או לא ייכלל בקובץ OUTPUT SAM או BAM. ערך ברירת מחדל: null.

Bioathlete
2018-01-24 00:49:23 UTC
view on stackexchange narkive permalink

(1) זה לא יהיה מהיר במיוחד, אבל אתה יכול לספק ל- grep קובץ QNAMES.

  samtools view file.bam | grep -f 'qnames.txt > subset.sam  

where qnames.txt has

  דוגמא: QNAME1EXAMPLE: QNAME2EXAMPLE: QNAME3EXAMPLE: QNAME4EXAMPLE: QNAME5  קוד> 

(2) זה יהיה קצת יותר מסובך, אך האם אתה יכול לתת דוגמה שבה ל- grep יכול להיות QNAME הנכון?

(3) כדי לשמור על כותרת BAM הייתי משתמש ב samtools -H file.bam > header.txt כדי להשיג את הכותרת ואז חתול את קובץ הכותרת עם הקובץ grep'ed

זה די איטי אם קובץ ה- bam או רשימת הקריאות שיש לשמור הם בגודל ניכר.
מכיוון ששמות המילה כולם מחרוזות קבועות, השימוש ב- fgrep במקום grep יספק מהירות * משמעותית * - כמה סדרי גודל. _עם זאת, שתי הגישות עשויות להוביל לתוצאות מזויפות: אם ברשימה שלנו יש שם qo 'foo, וקובץ BAM מכיל גם שמות q' fooX 'ו-' fooY ', האחרון יוחזר גם בתוצאות שלך, בטעות.
Devon Ryan
2018-01-24 02:21:35 UTC
view on stackexchange narkive permalink

להלן קטע קטן של קוד פיתון שמראה דרך אחת נאיבית אך ניתנת לניהול (הערה, אני מצפה ש- grep יהיה מהיר יותר, אם כי לגרום לו להוציא את הכותרת יהיה מעצבן):

  ייבוא ​​pysamqnames = set (...) # שמות קריאה עבור לכאןbam = pysam.AlignmentFile ("איזה קובץ קלט.באם") obam = pysam. AlignmentFile ("קובץ פלט כלשהו. Bam", "w", תבנית = bam) עבור b ב bam.fetch (עד_ eof = נכון): אם b.query_name בשמות שמות: obam.write (b) bam.close () obam. סגור ()  

עכשיו זה יעבוד, אבל אם יש לך הרבה שמות לעיין אז זה יהיה די איטי (כמו ש- grep -f. .. ). אם עליך לבחור רשימה גדולה של קריאות לפי שם, אז אסטרטגיה יעילה יותר היא:

  1. שם מיון קובץ ה- BAM ( samtools sort -n או picard) , שניתן לעשות עם מספר שרשורים.
  2. מיין את רשימת שמות הקריאה שיתאימו (זה יהיה מסובך יותר ממה שאפשר היה לחשוב בתמימות, מכיוון ש- samtools ו- picard יתנו שם אחרת, אז הקפד לשים חשבו על זה).
  3. בצע את אותו סוג של איטרציה כמו לעיל, אך השווה רק לשם הקריאה העליון ברשימה שלך משלב 2 (הסרת אותו אלמנט מהערימה לאחר התאמה).
שמירה על כותרת ה- BAM בגישת 'grep' היא פשוט עניין של הד לראשונה: '(samtools -H input.bam; samtools input.bam | grep ...) | samtools -b - -o output.bam`
James Hawley
2019-09-27 18:32:04 UTC
view on stackexchange narkive permalink

ביצוע grep ב $ n $ יישור ל $ m $ שמות יתן לך פעולות $ O (mn) $ . אם תחליט למיין תחילה את שמות ה- BAM והשמות שלך, תוכל לצמצם אותם ל $ O (\ min \ {m, n \}) $ על ידי הקפצת קריאות ושמות qn. ערימותיהם. אתה גם לא קורא את כל ה- BAM בבת אחת ככה, מה שמגביל את צריכת הזיכרון. אני די בטוח שגם פיקארד עושה משהו כזה.

הנה דוגמה ב- Python שכתבתי בדיוק למטרה זו:

import pysamdef filter_qname ( bamfile, idfile, outfile): '' 'המסנן קורא בקובץ SAM / BAM לפי שמות השאילתות שלהם. פרמטרים ---------- bamfile: str מיון נתיב קובץ BAM idfile: str נתיב קובץ טקסט המכיל שמות שמירה outfile: str קובץ פלט לכתוב ל- '' '# לקרוא בקובץ BAM ממוין לפי שם bam = pysam.AlignmentFile (bamfile, "rb") אם outfile.endswith ('. sam '): output = pysam.AlignmentFile (filefile, "w", תבנית = bam) elif outfile.endswith ('. bam'): output = pysam.AlignmentFile (filefile, "wb", template = bam) אחר: העלה את ValueError ("פורמט קובץ פלט לא ידוע עבור 'outfile': {} ". פורמט (outfile)) # לקרוא במזהים שיש להסיר (list (set (...)) כדי לשמור רק מזהים ייחודיים) ids = list (set ([l.rstrip () for l in open (idfile) , 'r'). readlines ()])) # מזהי מיון שתואמים BAM לעיבוד יעיל (פונקציה הרסנית) ids.sort (key = str.lower, reverse = True) n_ids = len (ids) # משתנה להבטחת BAM ממוין לפי שם השאילתה last_q = אין קריאה = bam.fetch (עד_eof = True ) read = הבא (קורא) בעוד ש- True: # אם שם הקריאה גדול מהחלק העליון של המחסנית הנוכחי אם read.query_name > ids [-1]: # אם זה המזהה האחרון אם n_ids == 1: # כתוב קריאות שנותרו קובץ חדש ונפרץ מ- loop בזמן output.write (קרא) עבור r in bam: output.write (read) break # אחרת הקפץ את המזהה הזה, נסה שוב אחר: ids.pop () n_ids - = 1 # דלג על קריאות התואמות לראש הערימה elif read.query_name == ids [- 1]: read = הבא (קורא) # אם שם הקריאה פחות מזה של הערימה, כתוב אותו והעבור הלאה: output.write (read) read = next (קורא) output.close () מראש>

יישמתי את זה בחבילת הכלים השונים שלי לביואינפורמטיקה כאן אם אתה רוצה לראות את זה בפעולה

Karel Brinda
2018-02-09 03:30:12 UTC
view on stackexchange narkive permalink

ניתן להשתמש ב SAMsift:

  samsift -i file.bam -0 'q = open ("qnames .txt "). קרא (). splitlines () '-f' QNAME ב- q ' 

-i file.bam מציין את קובץ ה- BAM הקלט. -0 'q = open ("qnames.txt"). קרא (). splitlines ()' טוען את רשימת ה- QNAME שלך. -f 'QNAME in q' מציין את המסנן ליישור.

עם SAMsift אפשר להשתמש בכל ביטוי Python לסינון. החיסרון הוא שהוא איטי יותר מהכלים האחרים.

wjv
2019-09-25 13:28:48 UTC
view on stackexchange narkive permalink

מרבית הפתרונות שפורסמו עד כה הם איטיים או יכולים להניב תוצאות מזויפות במקרים מסוימים. (לא בדקתי את פיקארד, מה שאני מניח שהוא יעבוד כמתוכנן. אבל באופן אישי אני נוטה לרתוע כשאצטרך להקים מכשיר JVM!)

בוא ניגש לבעיה מזווית אחרת:

לפונקציות hash טובות יש מורכבות ~ O (1) לבדיקה. אם אנו יכולים ליצור טבלת hash של ה- QNAME שלנו, אז חיפוש קובץ BAM צריך להיות O (n) במספר הרשומות. מפתחי ה- Python גאים מאוד בפונקציית ה- hash ב- cpython, אז בואו נשתמש בזה:

  #! / Usr / bin / env python3import syswith open (sys.argv [1], 'r' ) כקובץ אינדקס: ids = set (l.rstrip ('\ r \ n') עבור l בקובץ index) עבור שורה ב- sys.stdin: qname, _ = line.split ('\ t', 1) אם qname בתעודות : sys.stdout.write (line)  

עם ערכת בדיקה המורכבת מקובץ BAM ~ 3GB ו qnames.txt עם ~ 65,000 ערכים, פועל samtools להציג input.bam | ./idfilter.py qnames.txt לוקח בערך 6.5 שניות בשרת הבדיקה שלי. לשם השוואה, צנרת ה- SAM ל fgrep -f qnames.txt (באמצעות GNU grep) אורכת כ- 8.5 שניות (אך עשויה להניב תוצאות מזויפות).

(מדוע אולי grep מניב תוצאות מזויפות? אם יש לך foo QNAME ב- qnames.txt , אך קובץ ה- BAM שלך מכיל גם fooX ו- fooY , כולם יותאמו על ידי fgrep . הפיתרון הוא לעגן כל אחד מדפוסי החיפוש שלך בין תחילת השורה לכרטיסייה, למשל ^ foo \ t , אך אז עליך להשתמש ב grep סטנדרטי אשר יצטרך לבנות NFA עבור כל תבנית, ולא ב fgrep אשר מיישם את Aho-Corasick, ו- תהיה סדרי גודל איטיים יותר.)

כתבתי מחדש את סקריפט הפיתון הקטן שלי ב- Rust באמצעות std :: אוספים :: HashMap לפונקציית ה- hash, ובאמצעות הארגז rust_htslib לקרוא ולכתוב היישר מ- BAM, וזה עוד מהר פי שניים מהפייתון, גם כשקוראים וכותבים BAM. עם זאת, החלודה שלי לא ממש מתאימה לצריכה ציבורית ...

זו תשובה נהדרת! זה די מקיף, ואני מסכים עם הסלידה שלך מהקמת JVM :)


שאלה ותשובה זו תורגמה אוטומטית מהשפה האנגלית.התוכן המקורי זמין ב- stackexchange, ואנו מודים לו על רישיון cc by-sa 3.0 עליו הוא מופץ.
Loading...