امتداد Python ، مكتوب في C ، للوصول السريع إلى الملفات الكبيرة والوصول إلى ملفات BigWig وإنشاءها. يستخدم هذا الامتداد libbigwig للوصول إلى الملفات المحلية والبعيدة.
يمكنك تثبيت هذا الامتداد مباشرة من Github مع:
pip install pyBigWig
أو مع كوندا
conda install pybigwig -c conda-forge -c bioconda
يجب تثبيت المتطلبات غير المتابعة:
curl-config
)الرؤوس والمكتبات لهذه مطلوبة.
الاستخدام الأساسي على النحو التالي:
>>> import pyBigWig
سيعمل هذا إذا كان دليل العمل الخاص بك هو دليل رمز المصدر Pybigwig.
>>> bw = pyBigWig.open("test/test.bw")
لاحظ أنه إذا لم يكن الملف موجودًا ، فسترى رسالة خطأ وسيتم إرجاع None
. كن افتراضيًا ، يتم فتح جميع الملفات للقراءة وعدم الكتابة. يمكنك تغيير هذا عن طريق تمرير وضع يحتوي على w
:
>>> bw = pyBigWig.open("test/output.bw", "w")
لاحظ أنه لا يمكن الاستعلام عن ملف تم فتحه للكتابة لفتراته أو إحصائياته ، ولا يمكن كتابته إلا . إذا فتحت ملفًا للكتابة ، فستحتاج بعد ذلك إلى إضافة رأس (انظر القسم الموجود في هذا أدناه).
يتم دعم الوصول إلى القراءة الكبرى المحلية والبعيدة أيضًا:
>>> bb = pyBigWig.open("https://www.encodeproject.org/files/ENCFF001JBR/@@download/ENCFF001JBR.bigBed")
بينما يمكنك تحديد وضع للملفات الكبيرة ، يتم تجاهله. الكائن الذي تم إرجاعه بواسطة pyBigWig.open()
هو نفسه بغض النظر عما إذا كنت تفتح ملفًا كبيرًا أو ملفًا كبيرًا.
نظرًا لأنه يمكن فتح ملفات BigWig و BigBed ، فقد يكون من الضروري تحديد ما إذا كان كائن bigWigFile
معينًا يشير إلى ملف Bigwig أو BigBed. تحقيقا لهذه الغاية ، يمكن للمرء استخدام وظائف isBigWig()
و isBigBed()
:
>>> bw = pyBigWig.open("test/test.bw")
>>> bw.isBigWig()
True
>>> bw.isBigBed()
False
تحتوي كائنات bigWigFile
على قاموس يحمل أطوال الكروموسوم ، والتي يمكن الوصول إليها باستخدام ملحق chroms()
.
>>> bw.chroms()
dict_proxy({'1': 195471971L, '10': 130694993L})
يمكنك أيضًا الاستعلام مباشرة عن كروموسوم معين.
>>> bw.chroms("1")
195471971L
يتم تخزين الأطوال من نوع عدد صحيح "طويل" ، وهذا هو السبب في وجود لاحقة L
إذا حددت كروموسوم غير موجود ، فلا يوجد شيء مخرج.
>>> bw.chroms("c")
>>>
من المفيد في بعض الأحيان طباعة رأس Bigwig. يتم تقديم هذا هنا على أنه قاموس بيثون يحتوي على: الإصدار (عادة 4
) ، وعدد مستويات التكبير ( nLevels
) ، وعدد القواعد الموصوفة ( nBasesCovered
) ، والقيمة الدنيا ( minVal
) ، والقيمة القصوى ( maxVal
) ، و مجموع جميع القيم ( sumData
) ، ومجموع جميع القيم التربيعة ( sumSquared
). هناك حاجة إلى آخر اثنين من هؤلاء لتحديد المتوسط والانحراف المعياري.
>>> bw.header()
{'maxVal': 2L, 'sumData': 272L, 'minVal': 0L, 'version': 4L, 'sumSquared': 500L, 'nLevels': 1L, 'nBasesCovered': 154L}
لاحظ أن هذا ممكن أيضًا للملفات الكبيرة ونفس مفاتيح القاموس. إدخالات مثل maxVal
و sumData
و minVal
و sumSquared
ليست ذات معنى إلى حد كبير.
يتم استخدام ملفات BigWig لتخزين القيم المرتبطة بالمواقف ونطاقاتها. عادةً ما نريد الوصول بسرعة إلى متوسط القيمة على نطاق ، وهو أمر بسيط للغاية:
>>> bw.stats("1", 0, 3)
[0.2000000054637591]
لنفترض بدلاً من القيمة المتوسطة ، نريد بدلاً من ذلك القيمة القصوى:
>>> bw.stats("1", 0, 3, type="max")
[0.30000001192092896]
الخيارات الأخرى هي "min" (الحد الأدنى للقيمة) ، "التغطية" (جزء من القواعد المغطاة) ، و "STD" (الانحراف المعياري للقيم).
غالبًا ما نود بدلاً من ذلك حساب قيم بعض عدد من الصناديق المتبعة بالتساوي في فاصل زمني معين ، وهو أمر بسيط أيضًا:
>>> bw.stats("1",99, 200, type="max", nBins=2)
[1.399999976158142, 1.5]
تتخلف nBins
إلى 1 ، تمامًا كما mean
type
الافتراضية.
إذا تم حذف المواضع البدء والنهاية ، فسيتم استخدام الكروموسوم بأكمله:
>>> bw.stats("1")
[1.3351851569281683]
ملاحظة للقارئ العادي: هذا القسم فني إلى حد ما ويتضمن فقط من أجل الاكتمال. الملخص هو أنه إذا كانت احتياجاتك تتطلب متوسطًا دقيقًا/بحد أقصى/إلخ. القيم الموجزة للفاصل الزمني أو الفواصل الزمنية وأن المفاضلة الصغيرة في السرعة مقبولة ، وأنه يجب عليك استخدام الخيار
exact=True
في وظيفةstats()
.
افتراضيًا ، هناك بعض الجوانب غير البديلة لحساب إحصائيات على النطاقات في ملف Bigwig. تم إنشاء تنسيق Bigwig في الأصل في سياق متصفحات الجينوم. هناك ، فإن حساب إحصائيات الموجزة الدقيقة لفاصل زمني معين أقل أهمية من القدرة على حساب إحصاء تقريبي (بعد كل شيء ، يجب أن تكون المتصفحات قادرة على عرض عدد من الفواصل الزمنية المتجاورة بسرعة ودعم التمرير/التكبير). ولهذا السبب ، لا تحتوي ملفات BigWig على جمعيات القيمة الفاصلة فحسب ، بل تحتوي أيضًا sum of values
/ sum of squared values
/ minimum value
/ maximum value
/ number of bases covered
بالحجم المتساوي من الأحجام المختلفة. يشار إلى هذه الأحجام المختلفة باسم "مستويات التكبير". يحتوي أصغر مستوى التكبير على صناديق تبلغ 16 ضعف متوسط حجم الفاصل الزمني في الملف وكل مستوى التكبير اللاحق له صناديق أكبر 4 مرات من السابق. يتم استخدام هذه المنهجية في أدوات Kent ، وبالتالي ، من المحتمل أن تستخدم في كل ملف BigWig الحالي تقريبًا.
عندما يتم الاستعلام عن ملف bigwig للحصول على إحصاء موجز ، يتم استخدام حجم الفاصل الزمني لتحديد ما إذا كان سيتم استخدام مستوى التكبير ، وإذا كان الأمر كذلك ، أي واحد. مستوى التكبير الأمثل هو الذي يحتوي على أكبر صناديق لا يزيد عن نصف عرض الفاصل الزمني المطلوب. إذا لم يكن هناك مستوى تكبير من هذا القبيل ، يتم استخدام الفواصل الزمنية الأصلية بدلاً من ذلك للحساب.
من أجل الاتساق مع الأدوات الأخرى ، يعتمد Pybigwig هذه المنهجية نفسها. ومع ذلك ، نظرًا لأن هذا (أ) غير بديهي و (ب) غير مرغوب فيه في بعض التطبيقات ، فإن Pybigwig يتيح حساب إحصاءات الملخص الدقيقة بغض النظر عن حجم الفاصل (أي ، يسمح بتجاهل مستويات التكبير). تم اقتراح هذا في الأصل هنا ومثال أدناه:
>>> import pyBigWig
>>> from numpy import mean
>>> bw = pyBigWig.open("http://hgdownload.cse.ucsc.edu/goldenPath/hg19/encodeDCC/wgEncodeMapability/wgEncodeCrgMapabilityAlign75mer.bigWig")
>>> bw.stats('chr1', 89294, 91629)
[0.20120902053804418]
>>> mean(bw.values('chr1', 89294, 91629))
0.22213841940688142
>>> bw.stats('chr1', 89294, 91629, exact=True)
[0.22213841940688142]
بينما يمكن استخدام طريقة stats()
لاسترداد القيم الأصلية لكل قاعدة (على سبيل المثال ، عن طريق تعيين nBins
على عدد القواعد) ، من الأفضل بدلاً من ذلك استخدام values()
الإكسسور.
>>> bw.values("1", 0, 3)
[0.10000000149011612, 0.20000000298023224, 0.30000001192092896]
ستحتوي القائمة المنتجة دائمًا على قيمة واحدة لكل قاعدة في النطاق المحدد. إذا لم يكن لدى قاعدة معينة قيمة مرتبطة في ملف BigWig ، فستكون القيمة التي تم إرجاعها nan
.
>>> bw.values("1", 0, 4)
[0.10000000149011612, 0.20000000298023224, 0.30000001192092896, nan]
في بعض الأحيان يكون من المناسب استرداد جميع الإدخالات المتداخلة بعض النطاق. يمكن القيام بذلك مع وظيفة intervals()
:
>>> bw.intervals("1", 0, 3)
((0, 1, 0.10000000149011612), (1, 2, 0.20000000298023224), (2, 3, 0.30000001192092896))
ما تم إرجاعه هو قائمة من tuples التي تحتوي على: موضع البداية ، وضع النهاية ، والقيمة. وبالتالي ، فإن المثال أعلاه له قيم 0.1
و 0.2
و 0.3
في المواضع 0
و 1
و 2
على التوالي.
إذا تم حذف الوضع البدء والنهاية ، فسيتم إرجاع جميع الفواصل الزمنية على الكروموسوم المحددة:
>>> bw.intervals("1")
((0, 1, 0.10000000149011612), (1, 2, 0.20000000298023224), (2, 3, 0.30000001192092896), (100, 150, 1.399999976158142), (150, 151, 1.5))
على عكس ملفات BigWig ، تحتوي الملفات الكبيرة على إدخالات ، وهي فترات مع سلسلة مرتبطة. يمكنك الوصول إلى هذه الإدخالات باستخدام وظيفة entries()
:
>>> bb = pyBigWig.open("https://www.encodeproject.org/files/ENCFF001JBR/@@download/ENCFF001JBR.bigBed")
>>> bb.entries('chr1', 10000000, 10020000)
[(10009333, 10009640, '61035t130t-t0.026t0.42t404'), (10014007, 10014289, '61047t136t-t0.029t0.42t404'), (10014373, 10024307, '61048t630t-t5.420t0.00t2672399')]
الإخراج هو قائمة من tuples الدخول. عناصر tuple هي الموضع start
end
لكل إدخال ، تليها string
المرتبطة بها. يتم إرجاع السلسلة تمامًا كما هو محتجز في الملف الكبير ، لذلك يتم تحليلها لك. لتحديد ماهية الحقول المختلفة في هذه السلسلة ، استشر سلسلة SQL:
>>> bb.SQL()
table RnaElements
"BED6 + 3 scores for RNA Elements data"
(
string chrom; "Reference sequence chromosome or scaffold"
uint chromStart; "Start position in chromosome"
uint chromEnd; "End position in chromosome"
string name; "Name of item"
uint score; "Normalized score from 0-1000"
char[1] strand; "+ or - or . for unknown"
float level; "Expression level such as RPKM or FPKM. Set to -1 for no data."
float signif; "Statistical significance such as IDR. Set to -1 for no data."
uint score2; "Additional measurement/count e.g. number of reads. Set to 0 for no data."
)
لاحظ أن الإدخالات الثلاثة الأولى في سلسلة SQL ليست جزءًا من السلسلة.
إذا كنت بحاجة فقط إلى معرفة مكان الإدخالات وليس القيم المرتبطة بها ، فيمكنك حفظ الذاكرة من خلال تحديد withString=False
في entries()
:
>>> bb.entries('chr1', 10000000, 10020000, withString=False)
[(10009333, 10009640), (10014007, 10014289), (10014373, 10024307)]
إذا قمت بفتح ملف للكتابة ، فستحتاج إلى منحه رأسًا قبل أن تتمكن من إضافة أي إدخالات. يحتوي الرأس على جميع الكروموسومات ، بالترتيب ، وأحجامها. إذا كان لدى الجينوم اثنين من الكروموسومات ، Chr1 و Chr2 ، أطوال 1 و 1.5 مليون قاعدة ، فإن ما يلي سيضيف رأسًا مناسبًا:
>>> bw.addHeader([("chr1", 1000000), ("chr2", 1500000)])
رؤوس Bigwig حساسة للحالة ، لذلك chr1
و Chr1
مختلفان. وبالمثل ، 1
و chr1
ليسا متماثلين ، لذلك لا يمكنك مزج أسماء كروموسوم Ensembl و UCSC. بعد إضافة رأس ، يمكنك بعد ذلك إضافة إدخالات.
بشكل افتراضي ، يتم إنشاء ما يصل إلى 10 "مستويات التكبير" لملفات BigWig. يمكنك تغيير هذا الرقم الافتراضي مع الوسيطة الاختيارية maxZooms
. الاستخدام الشائع لهذا هو إنشاء ملف Bigwig الذي يحمل ببساطة فترات ولا توجد مستويات تكبير:
>>> bw.addHeader([("chr1", 1000000), ("chr2", 1500000)], maxZooms=0)
إذا قمت بتعيين maxTooms=0
، فيرجى ملاحظة أن IGV والعديد من الأدوات الأخرى لن تعمل لأنها تفترض أن مستوى تكبير واحد على الأقل سيكون موجودًا. يُنصح باستخدام الافتراضي إلا إذا كنت لا تتوقع استخدام ملفات BigWig بواسطة الحزم الأخرى.
على افتراض أنك فتحت ملفًا للكتابة وإضافة رأس ، يمكنك بعد ذلك إضافة إدخالات. لاحظ أنه يجب إضافة الإدخالات بالترتيب ، حيث تحتوي ملفات BigWig دائمًا على فترات مرتبة. هناك ثلاثة تنسيقات يمكن لملفات BigWig استخدامها داخليًا لتخزين الإدخالات. التنسيق الأكثر شيوعًا مطابقًا لملف السرير:
chr1 0 100 0.0
chr1 100 120 1.0
chr1 125 126 200.0
ستتم إضافة هذه الإدخالات على النحو التالي:
>>> bw.addEntries(["chr1", "chr1", "chr1"], [0, 100, 125], ends=[5, 120, 126], values=[0.0, 1.0, 200.0])
يحتل كل إدخال 12 بايت قبل الضغط.
يستخدم التنسيق الثاني فترة ثابتة ، ولكن حجم خطوة متغير بين الإدخالات. يمكن تمثيلها في ملف Wiggle على النحو التالي:
variableStep chrom=chr1 span=20
500 -2.0
600 150.0
635 25.0
تصف الإدخالات أعلاه (1) المواضع 501-520 و 601-620 و 636-655. ستتم إضافة هذه على النحو التالي:
>>> bw.addEntries("chr1", [500, 600, 635], values=[-2.0, 150.0, 25.0], span=20)
يشغل كل إدخال من هذا النوع 8 بايت قبل الضغط.
يستخدم التنسيق النهائي خطوة ثابتة وممتدة لكل إدخال ، المقابلة لتنسيق Wiggle ثابت:
fixedStep chrom=chr1 step=30 span=20
-5.0
-20.0
25.0
تصف الإدخالات أعلاه (المستندة إلى 1) القواعد 901-920 و 931-950 و 961-980 وسيتم إضافتها على النحو التالي:
>>> bw.addEntries("chr1", 900, values=[-5.0, -20.0, 25.0], span=20, step=30)
كل إدخال من هذا النوع يحتل 4 بايت.
لاحظ أن Pybigwig سيحاول منعك من إضافة إدخالات بترتيب غير صحيح. هذا ، ومع ذلك ، يتطلب الإفراط في رأسه. إذا لم يكن ذلك مقبولًا ، يمكنك ببساطة تحديد validate=False
عند إضافة الإدخالات:
>>> bw.addEntries(["chr1", "chr1", "chr1"], [100, 0, 125], ends=[120, 5, 126], values=[0.0, 1.0, 200.0], validate=False)
من الواضح أنك مسؤول بعد ذلك عن ضمان عدم إضافة إدخالات خارج الترتيب. الملفات الناتجة لن تكون قابلة للاستخدام.
يمكن إغلاق ملف مع bw.close()
بسيط ، كما هو شائع مع أنواع الملفات الأخرى. بالنسبة للملفات التي تم فتحها للكتابة ، يكتب إغلاق ملف أي إدخالات مخزنة إلى القرص ، وبناء وتكتب فهرس الملف ، ويقوم ببناء مستويات التكبير. وبالتالي ، يمكن أن يستغرق هذا بعض الوقت.
اعتبارًا من الإصدار 0.3.0 ، يدعم Pybigwig مدخلات الإحداثيات باستخدام أعداد صحيحة ومتجهات Numpy في بعض الوظائف إذا تم تثبيت Numpy قبل تثبيت Pybigwig . لتحديد ما إذا تم تثبيت Pybigwig بدعم numpy من خلال التحقق من ملحق numpy
:
>>> import pyBigWig
>>> pyBigWig.numpy
1
إذا كان pyBigWig.numpy
هو 1
، فسيتم تجميع Pybigwig بدعم numpy. هذا يعني أن addEntries()
يمكن أن تقبل إحداثيات numpy:
>>> import pyBigWig
>>> import numpy
>>> bw = pyBigWig.open("/tmp/delete.bw", "w")
>>> bw.addHeader([("1", 1000)], maxZooms=0)
>>> chroms = np.array(["1"] * 10)
>>> starts = np.array([0, 10, 20, 30, 40, 50, 60, 70, 80, 90], dtype=np.int64)
>>> ends = np.array([5, 15, 25, 35, 45, 55, 65, 75, 85, 95], dtype=np.int64)
>>> values0 = np.array(np.random.random_sample(10), dtype=np.float64)
>>> bw.addEntries(chroms, starts, ends=ends, values=values0)
>>> bw.close()
بالإضافة إلى ذلك ، يمكن values()
إخراج متجه numpy مباشرة:
>>> bw = bw.open("/tmp/delete.bw")
>>> bw.values('1', 0, 10, numpy=True)
[ 0.74336642 0.74336642 0.74336642 0.74336642 0.74336642 nan
nan nan nan nan]
>>> type(bw.values('1', 0, 10, numpy=True))
<type 'numpy.ndarray'>
إذا لم يكن لديك حليقة مثبتة ، فسيتم تثبيت Pybigwig دون القدرة على الوصول إلى الملفات عن بُعد. يمكنك تحديد ما إذا كنت ستتمكن من الوصول إلى الملفات عن بُعد باستخدام pyBigWig.remote
. إذا تم إرجاع ذلك 1 ، فيمكنك الوصول إلى الملفات عن بُعد. إذا عاد 0 فلا يمكنك ذلك.
اعتبارًا من الإصدار 0.3.5 ، يمكن لـ Pybigwig قراءة وكتابة ملفات BigWig التي تفتقر إلى الإدخالات. يرجى ملاحظة أن هذه الملفات غير متوافقة بشكل عام مع البرامج الأخرى ، نظرًا لعدم وجود تعريف لكيفية ظهور ملف BigWig الذي لا ينبغي أن يبدو عليه أي إدخالات. بالنسبة لمثل هذا الملف ، سيعود الإكسسوارات intervals()
None
، وستقوم وظيفة stats()
بإرجاع قائمة None
من الطول المطلوب ، وستعود values()
[]
(قائمة فارغة). يجب أن يسمح هذا بشكل عام برامج باستخدام Pybigwig للاستمرار دون مشكلة.
بالنسبة لأولئك الذين يرغبون في تقليد وظائف Pybigwig/Libbigwig في هذا الصدد ، يرجى ملاحظة أنه ينظر إلى عدد القواعد المغطاة (كما ورد في رأس الملف) للتحقق من ملفات "فارغة".
تستخدم ملفات Wiggle و BigWig و Bigbed إحداثيات نصف مفتوحة على أساس 0 ، والتي تستخدمها هذا الامتداد أيضًا. لذلك للوصول إلى قيمة القاعدة الأولى على chr1
، يحدد المرء موضع البداية على أنه 0
وموضع النهاية كـ 1
. وبالمثل ، فإن القواعد من 100 إلى 115 ستكون بداية 99
ونهاية 115
. هذا ببساطة من أجل الاتساق مع ملف Bigwig الأساسي وقد يتغير في المستقبل.
Pybigwig متوفر أيضًا كحزمة في Galaxy. يمكنك العثور عليها في أدوات SHED و IUC تستضيف حاليًا تعريف XML لهذا على Github.