حل مسائل بیوانفورماتیکی با Biopython: رویکردهای عملی و نمونه کد

فهرست مطالب

حل مسائل بیوانفورماتیکی با Biopython: رویکردهای عملی و نمونه کد

دنیای زیست‌شناسی در عصر حاضر با حجم بی‌سابقه‌ای از داده‌ها مواجه است که از تکنیک‌های پرتوان توالی‌یابی نسل جدید (NGS)، مطالعات پروتئومیکس، متابولومیکس و ساختارهای سه‌بعدی مولکول‌های زیستی تولید می‌شوند. این سیل عظیم اطلاعات نیازمند ابزارهای محاسباتی قدرتمندی است که بتوانند داده‌ها را سازماندهی، تحلیل و تفسیر کنند. در این میان، بیوانفورماتیک به عنوان یک رشته بین‌رشته‌ای، نقش حیاتی ایفا می‌کند و دانش زیست‌شناسی را با علوم کامپیوتر، آمار و ریاضیات در هم می‌آمیزد تا به درک عمیق‌تری از سیستم‌های زیستی دست یابد. پایتون، با سادگی، انعطاف‌پذیری و جامعه کاربری بزرگ خود، به یکی از زبان‌های برنامه‌نویسی محبوب در حوزه بیوانفورماتیک تبدیل شده است. در قلب اکوسیستم پایتون برای بیوانفورماتیک، کتابخانه قدرتمند Biopython قرار دارد. این کتابخانه، مجموعه‌ای جامع از ابزارها و ماژول‌ها را فراهم می‌کند که کار با داده‌های زیستی را تسهیل می‌بخشد و امکان پیاده‌سازی رویکردهای محاسباتی پیچیده را فراهم می‌آورد. از دستکاری توالی‌ها و کار با فایل‌های استاندارد بیوانفورماتیک گرفته تا تعامل با پایگاه‌های داده آنلاین و انجام تحلیل‌های فیلوژنتیک و ساختاری، Biopython ابزاری ضروری برای هر بیوانفورماتیست، زیست‌شناس محاسباتی و حتی زیست‌شناسان مولکولی است که قصد دارند از قدرت محاسبات برای حل مسائل تحقیقاتی خود بهره ببرند.

این مقاله با هدف ارائه یک راهنمای جامع و عملی برای استفاده از Biopython در حل مسائل واقعی بیوانفورماتیک تدوین شده است. ما نه تنها به معرفی ماژول‌های اصلی Biopython می‌پردازیم، بلکه با ارائه نمونه کدهای کاربردی و توضیحات تفصیلی، نحوه به کارگیری این ابزارها را در سناریوهای مختلف نشان خواهیم داد. از مبانی کار با توالی‌ها و فایل‌ها تا مفاهیم پیشرفته‌تر مانند تراز توالی‌ها، تحلیل‌های فیلوژنتیک، و بیوانفورماتیک ساختاری، تلاش شده است تا طیفی وسیع از کاربردها پوشش داده شود. هدف نهایی این است که خواننده پس از مطالعه این مقاله، قادر باشد با اطمینان از Biopython برای پیشبرد تحقیقات و پروژه‌های بیوانفورماتیکی خود استفاده کند.

۱. آشنایی با Biopython: نصب و مفاهیم بنیادین

پیش از ورود به جزئیات، درک ماهیت و نحوه آغاز به کار با Biopython ضروری است. Biopython یک پروژه متن‌باز است که به عنوان رابط پایتون برای فرمت‌های فایل، پایگاه‌های داده و الگوریتم‌های رایج بیوانفورماتیک عمل می‌کند.

نصب Biopython

نصب Biopython بسیار ساده است و همانند اکثر کتابخانه‌های پایتون، می‌توان آن را با استفاده از مدیر بسته pip انجام داد:


pip install biopython

پس از نصب موفقیت‌آمیز، می‌توانید با وارد کردن (import) ماژول‌های آن در اسکریپت‌های پایتون خود، شروع به استفاده از Biopython کنید.

ساختارهای داده پایه: Seq و SeqRecord

قلب Biopython برای کار با توالی‌های زیستی، دو کلاس اصلی Seq و SeqRecord هستند. درک تفاوت و کاربرد این دو برای هر بیوانفورماتیست حیاتی است.

شیء Seq (Sequence Object)

شیء Seq در ماژول Bio.Seq، یک توالی زیستی ساده (مانند DNA، RNA یا پروتئین) را نگهداری می‌کند. این شیء در واقع یک رشته (string) پیشرفته است که امکانات زیستی خاصی را فراهم می‌آورد. شما می‌توانید یک شیء Seq را با دادن رشته توالی و (اختیاراً) نوع الفبای آن (که امروزه کمتر استفاده می‌شود و اغلب خودکار تشخیص داده می‌شود) ایجاد کنید:


from Bio.Seq import Seq

# توالی DNA
dna_seq = Seq("ATGCGTACGTACGTACGTACG")
print(f"توالی DNA: {dna_seq}")
print(f"طول توالی: {len(dna_seq)}")

# توالی RNA
rna_seq = Seq("AUGGCGCUAGCUAGCUAGCUAGCUAGCAU")
print(f"توالی RNA: {rna_seq}")

# توالی پروتئین
protein_seq = Seq("ATGTAGCTAGCTAGCATGCTAG") # این یک توالی پروتئین معتبر نیست، فقط برای نمونه
print(f"توالی پروتئین: {protein_seq}")

اشیاء Seq از بسیاری از عملیات‌های رشته‌ای پایتون مانند برش (slicing)، الحاق (concatenation) و تکرار پشتیبانی می‌کنند. علاوه بر این، متدهایی برای عملیات‌های بیولوژیکی مانند ترجمه، مکمل معکوس و غیره نیز دارند.

شیء SeqRecord (Sequence Record Object)

در حالی که Seq فقط توالی را ذخیره می‌کند، SeqRecord یک رکورد کامل از یک توالی زیستی است که علاوه بر توالی (به صورت یک شیء Seq)، شامل ابرداده‌های مهمی مانند شناسه (ID)، نام (Name)، توضیحات (Description)، حاشیه‌نویسی‌ها (Annotations) و ویژگی‌ها (Features) نیز می‌شود. این شیء برای کار با داده‌های حجیم از فایل‌هایی مانند FASTA و GenBank بسیار کاربردی است.


from Bio.Seq import Seq
from Bio.SeqRecord import SeqRecord

# ایجاد یک شیء SeqRecord
record = SeqRecord(
    Seq("ATGCGTACGTACGTACGTACG"),
    id="NC_000913.3",
    name="E_coli_K12",
    description="Complete genome of Escherichia coli K-12 MG1655",
    annotations={"molecule_type": "DNA", "organism": "Escherichia coli"}
)

print(f"شناسه رکورد: {record.id}")
print(f"نام رکورد: {record.name}")
print(f"توضیحات رکورد: {record.description}")
print(f"توالی: {record.seq}")
print(f"طول توالی: {len(record.seq)}")
print(f"نوع مولکول: {record.annotations['molecule_type']}")

ورودی/خروجی فایل‌های بیوانفورماتیک با Bio.SeqIO

ماژول Bio.SeqIO یکی از پرکاربردترین قسمت‌های Biopython است که برای خواندن و نوشتن توالی‌ها در فرمت‌های فایل رایج بیوانفورماتیک مانند FASTA، GenBank، PHYLIP، Newick و غیره استفاده می‌شود. این ماژول امکانات قدرتمندی برای مدیریت داده‌های توالی فراهم می‌کند.

خواندن فایل‌های FASTA

فایل‌های FASTA یکی از ساده‌ترین و پرکاربردترین فرمت‌ها برای ذخیره توالی‌های زیستی هستند. تابع SeqIO.parse() یک ژنراتور (generator) برمی‌گرداند که اجازه می‌دهد تا رکوردهای یک فایل را به صورت تکرار شونده (iterate) بخوانیم و از مصرف حافظه زیاد برای فایل‌های بزرگ جلوگیری کنیم.


from Bio import SeqIO

# فرض کنید فایل 'example.fasta' با محتوای زیر موجود است:
# >seq1_description
# ATGCGTACG
# >seq2_description
# CGTAGCTAGCTAGC
#
# برای ایجاد این فایل به صورت برنامه‌نویسی:
with open("example.fasta", "w") as f:
    f.write(">seq1_description\nATGCGTACG\n")
    f.write(">seq2_description\nCGTAGCTAGCTAGC\n")

# خواندن فایل FASTA
print("\n--- خواندن فایل FASTA ---")
for record in SeqIO.parse("example.fasta", "fasta"):
    print(f"شناسه: {record.id}")
    print(f"توالی: {record.seq}")
    print(f"طول: {len(record.seq)}\n")

# خواندن یک رکورد خاص از فایل (اگر می‌دانید فقط یک رکورد وجود دارد یا به رکورد اول نیاز دارید)
record_single = SeqIO.read("example.fasta", "fasta") # در اینجا مشکل ایجاد می‌شود اگر بیش از یک رکورد باشد
print(f"توالی اول (با SeqIO.read): {record_single.seq}")

نکته مهم این است که SeqIO.read() برای فایل‌هایی که انتظار می‌رود فقط یک رکورد داشته باشند استفاده می‌شود، در حالی که SeqIO.parse() برای فایل‌های شامل چندین رکورد یا فایل‌های بسیار بزرگ مناسب‌تر است.

خواندن فایل‌های GenBank

فرمت GenBank بسیار غنی‌تر از FASTA است و شامل اطلاعات دقیقی درباره توالی، ویژگی‌ها (مانند ژن‌ها، CDS، رگولیتورها)، منابع و مقالات مرتبط است. SeqIO به خوبی از این فرمت پشتیبانی می‌کند.


# برای این مثال، فرض می‌کنیم یک فایل GenBank به نام 'NC_000913.gb' داریم.
# محتوای این فایل معمولاً بسیار بزرگ است، اما می‌توان یک بخش کوچک آن را ساخت:
genbank_content = """LOCUS       NC_000913             4641652 bp    DNA     circular BCT 21-SEP-2020
DEFINITION  Escherichia coli str. K-12 substr. MG1655, complete genome.
ACCESSION   NC_000913
VERSION     NC_000913.3
KEYWORDS    RefSeq.
SOURCE      Escherichia coli str. K-12 substr. MG1655
  ORGANISM  Escherichia coli str. K-12 substr. MG1655
            Bacteria; Proteobacteria; Gammaproteobacteria; Enterobacterales;
            Enterobacteriaceae; Escherichia.
REFERENCE   1  (bases 1 to 4641652)
  AUTHORS   Blattner, F.R., Plunkett, G. 3rd, Bloch, C.A., Perna, N.T.,
            Burland, V., Riley, M., Collado-Vides, C., Glasner, J.D., Rode, C.K.,
            Mayhew, G.F., Gregor, J., Davis, N.W., Kirkpatrick, H.A.,
            Goeden, M.A., Rose, D.J., Mau, B. and Shao, Y.
  TITLE     The complete genome sequence of Escherichia coli K-12
  JOURNAL   Science 277 (5331), 1453-1462 (1997)
   PUBMED   9278503
FEATURES             Location/Qualifiers
     source          1..4641652
                     /organism="Escherichia coli str. K-12 substr. MG1655"
                     /mol_type="genomic DNA"
                     /strain="K-12"
                     /sub_strain="MG1655"
                     /db_xref="taxon:511145"
     gene            join(256..1003,1003..1608)
                     /locus_tag="b0001"
                     /gene="thrL"
                     /note="threonine operon leader peptide"
                     /db_xref="GeneID:944742"
ORIGIN
        1 agcttttcattctttgactaacgtggaaattaacaacctacaaactggcactaaatgactccat
       61 tcggcactaataa
//
"""
with open("NC_000913.gb", "w") as f:
    f.write(genbank_content)

print("\n--- خواندن فایل GenBank ---")
for record in SeqIO.parse("NC_000913.gb", "genbank"):
    print(f"شناسه: {record.id}")
    print(f"توضیحات: {record.description}")
    print(f"توالی: {record.seq[:50]}...") # نمایش 50 کاراکتر اول
    print(f"تعداد ویژگی‌ها: {len(record.features)}")
    for feature in record.features:
        if feature.type == "gene":
            print(f"  ژن: {feature.qualifiers.get('gene', ['N/A'])[0]} در موقعیت: {feature.location}")
            if 'locus_tag' in feature.qualifiers:
                print(f"  Locus Tag: {feature.qualifiers['locus_tag'][0]}")
    print("\n")

نوشتن فایل‌های توالی

SeqIO علاوه بر خواندن، امکان نوشتن توالی‌ها را نیز فراهم می‌کند. می‌توانید فهرستی از اشیاء SeqRecord را ایجاد کرده و آن‌ها را در فرمت دلخواه ذخیره کنید.


from Bio.Seq import Seq
from Bio.SeqRecord import SeqRecord
from Bio import SeqIO

# ایجاد چند شیء SeqRecord
records_to_write = [
    SeqRecord(Seq("ATGCATGC"), id="geneA", description="Hypothetical gene A"),
    SeqRecord(Seq("GCATGCATGCAT"), id="geneB", description="Putative gene B"),
    SeqRecord(Seq("TACGTACG"), id="geneC", description="Novel gene C")
]

# نوشتن به فایل FASTA
output_fasta_file = "output.fasta"
with open(output_fasta_file, "w") as output_handle:
    SeqIO.write(records_to_write, output_handle, "fasta")
print(f"فایل FASTA به '{output_fasta_file}' نوشته شد.")

# نوشتن به فایل GenBank (نیاز به ابرداده بیشتر برای یک فایل GenBank معتبر)
# برای سادگی، یک مثال ابتدایی را نشان می‌دهیم
output_gb_file = "output.gb"
with open(output_gb_file, "w") as output_handle:
    SeqIO.write(records_to_write, output_handle, "genbank")
print(f"فایل GenBank به '{output_gb_file}' نوشته شد (با اطلاعات محدود).")

با این مبانی، شما آماده‌اید تا به سراغ دستکاری و تحلیل عمیق‌تر توالی‌ها با Biopython بروید.

۲. دستکاری و تحلیل توالی‌ها در Biopython

یکی از کاربردهای اصلی Biopython، انجام عملیات مختلف بر روی توالی‌های DNA، RNA و پروتئین است. ماژول‌های Bio.Seq و Bio.SeqUtils ابزارهای متنوعی را برای این منظور فراهم می‌کنند.

عملیات پایه بر روی توالی‌های Seq

اشیاء Seq از برخی متدهای رشته‌ای پایتون پشتیبانی می‌کنند و علاوه بر آن متدهای بیولوژیکی خاص خود را نیز دارند.

برش (Slicing) و الحاق (Concatenation)


from Bio.Seq import Seq

dna_seq = Seq("ATGCGTACGTACGTACGTACG")

# برش توالی
segment = dna_seq[3:10]
print(f"بخش برش خورده: {segment}") # خروجی: CGTACGT

# الحاق توالی‌ها
another_seq = Seq("GGATTC")
combined_seq = dna_seq + another_seq
print(f"توالی ترکیب شده: {combined_seq}") # خروجی: ATGCGTACGTACGTACGTACGGATTC

مکمل معکوس (Reverse Complement)

برای توالی‌های DNA، مکمل معکوس یک عملیات بسیار رایج است که برای درک ساختار رشته مکمل یا پرایمرها استفاده می‌شود.


from Bio.Seq import Seq

dna_seq = Seq("ATGCGTACG")
rev_comp_seq = dna_seq.reverse_complement()
print(f"توالی اصلی: {dna_seq}")
print(f"مکمل معکوس: {rev_comp_seq}") # خروجی: CGTACGCAT

ترجمه (Translation) توالی DNA به پروتئین

یکی از عملیات‌های کلیدی در زیست‌شناسی مولکولی، ترجمه توالی DNA (یا mRNA) به توالی پروتئین است. متد .translate() این کار را بر اساس کد ژنتیکی استاندارد انجام می‌دهد. شما می‌توانید فریم‌های مختلف خواندن و همچنین وجود کدون‌های توقف را مدیریت کنید.


from Bio.Seq import Seq

mrna_seq = Seq("AUGGCGCUAGCUAGCUAGCUAGCUAGCAUUGA") # شامل کدون توقف UGA
protein_seq = mrna_seq.translate()
print(f"توالی mRNA: {mrna_seq}")
print(f"توالی پروتئین: {protein_seq}") # خروجی: MA*SS*S*S*S*S*S*
# * نشان‌دهنده کدون توقف است

# ترجمه با نادیده گرفتن کدون‌های توقف
protein_seq_no_stop = mrna_seq.translate(to_stop=True)
print(f"توالی پروتئین (بدون کدون توقف): {protein_seq_no_stop}") # خروجی: MA

# ترجمه با استفاده از جدول کد ژنتیکی جایگزین (مثلاً کد میتوکندریایی)
# protein_seq_mito = mrna_seq.translate(table="Vertebrate Mitochondrial")
# print(f"توالی پروتئین (میتوکندریایی): {protein_seq_mito}")

محاسبات آماری و ویژگی‌های توالی با Bio.SeqUtils

ماژول Bio.SeqUtils مجموعه‌ای از توابع مفید را برای محاسبه خواص بیوفیزیکی و آماری توالی‌ها ارائه می‌دهد.

محتوای GC (GC Content)

محاسبه درصد بازهای گوانین و سیتوزین (GC content) در یک توالی DNA/RNA برای تحلیل پایداری حرارتی، پرایمر دیزاین و شناسایی نواحی ژنومی غنی از GC مفید است.


from Bio.Seq import Seq
from Bio.SeqUtils import GC

dna_seq_high_gc = Seq("GCGCGCGCGC")
dna_seq_low_gc = Seq("ATATATATAT")
dna_seq_mixed = Seq("ATGCGTACGTACGTACGTACG")

print(f"توالی 'GCGCGCGCGC' دارای GC content: {GC(dna_seq_high_gc):.2f}%")
print(f"توالی 'ATATATATAT' دارای GC content: {GC(dna_seq_low_gc):.2f}%")
print(f"توالی 'ATGCGTACGTACGTACGTACG' دارای GC content: {GC(dna_seq_mixed):.2f}%")

وزن مولکولی (Molecular Weight)

محاسبه وزن مولکولی برای توالی‌های DNA، RNA و پروتئین کاربردهای مختلفی در آزمایشگاه دارد، از جمله تخمین غلظت یا تعیین اندازه در ژل الکتروفورز.


from Bio.Seq import Seq
from Bio.SeqUtils import molecular_weight

dna_seq = Seq("ATGC")
rna_seq = Seq("AUGC")
protein_seq = Seq("MAV")

print(f"وزن مولکولی DNA (ATGC): {molecular_weight(dna_seq, 'DNA'):.2f} Da")
print(f"وزن مولکولی RNA (AUGC): {molecular_weight(rna_seq, 'RNA'):.2f} Da")
print(f"وزن مولکولی پروتئین (MAV): {molecular_weight(protein_seq, 'protein'):.2f} Da")

تحلیل پارامترهای پروتئین با ProtParam

ماژول Bio.SeqUtils.ProtParam به شما امکان می‌دهد تا پارامترهای مختلفی از یک توالی پروتئینی مانند نقطه ایزوالکتریک (pI)، ضرایب جذب (extinction coefficients) و پایداری (instability index) را محاسبه کنید.


from Bio.Seq import Seq
from Bio.SeqUtils.ProtParam import ProteinAnalysis

protein_seq = Seq("MAVAVADKLVCEFGHIKLMNPQRST")
analysed_seq = ProteinAnalysis(str(protein_seq)) # ProteinAnalysis انتظار رشته پایتون را دارد

print(f"طول توالی پروتئین: {analysed_seq.length}")
print(f"وزن مولکولی: {analysed_seq.molecular_weight():.2f}")
print(f"نقطه ایزوالکتریک (pI): {analysed_seq.isoelectric_point():.2f}")
print(f"تعداد آمینو اسیدها: {analysed_seq.count_amino_acids()}")
print(f"ترکیب آمینو اسیدی: {analysed_seq.get_amino_acids_percent()}")
print(f"ضریب جذب (Extinction Coefficient) در 280 نانومتر: {analysed_seq.extinction_coefficient()[0]:.2f}")
print(f"شاخص ناپایداری (Instability Index): {analysed_seq.instability_index():.2f}")

این ابزارها به بیوانفورماتیست‌ها کمک می‌کنند تا درک بهتری از خواص فیزیکوشیمیایی مولکول‌های زیستی و عملکرد آن‌ها داشته باشند.

۳. تعامل با پایگاه‌های داده زیستی (NCBI و EBI)

اکثر تحقیقات بیوانفورماتیکی شامل بازیابی داده‌ها از پایگاه‌های داده عمومی مانند NCBI (National Center for Biotechnology Information) و EBI (European Bioinformatics Institute) است. Biopython ماژول Bio.Entrez را برای تعامل برنامه‌نویسی با Entrez E-utilities از NCBI ارائه می‌دهد که امکان جستجو و بازیابی اطلاعات از پایگاه‌های داده مختلف NCBI (مانند Nucleotide، Protein، Gene، PubMed و غیره) را فراهم می‌کند.

ماژول Bio.Entrez

برای استفاده از Bio.Entrez، شما باید یک آدرس ایمیل معتبر برای شناسایی درخواست‌های خود ارائه دهید. این کار به NCBI کمک می‌کند تا حجم درخواست‌ها را مانیتور کرده و در صورت نیاز با شما تماس بگیرد.


from Bio import Entrez

Entrez.email = "your.email@example.com" # حتماً ایمیل خود را جایگزین کنید!

جستجو در پایگاه‌های داده با Entrez.esearch

تابع esearch برای جستجو در یک پایگاه داده مشخص (مانند nuccore برای نوکلئوتیدها، protein برای پروتئین‌ها، pubmed برای مقالات) و برگرداندن شناسه‌های (IDs) مطابقت یافته استفاده می‌شود.


from Bio import Entrez
import time

Entrez.email = "your.email@example.com"

# جستجو برای "insulin" در Homo sapiens در پایگاه داده Nucleotide
print("--- جستجو برای توالی انسولین در انسان ---")
handle = Entrez.esearch(db="nuccore", term="insulin[gene] AND Homo sapiens[orgn]", retmax="10")
record = Entrez.read(handle)
handle.close()

print(f"تعداد رکوردهای یافت شده: {record['Count']}")
print(f"شناسه‌های یافت شده: {record['IdList']}")

# جستجو برای مقالات در PubMed
print("\n--- جستجو برای مقالات مرتبط با CRISPR ---")
handle = Entrez.esearch(db="pubmed", term="CRISPR-Cas9 gene editing", retmax="5")
record_pubmed = Entrez.read(handle)
handle.close()

print(f"تعداد مقالات یافت شده: {record_pubmed['Count']}")
print(f"شناسه‌های مقالات یافت شده: {record_pubmed['IdList']}")

پارامتر retmax تعداد حداکثر رکوردهایی را که باید برگردانده شوند کنترل می‌کند. بدون این پارامتر، تنها ۲۰ رکورد اول بازگردانده می‌شوند. برای بازیابی تعداد زیادی از شناسه‌ها، باید از retmax با مقدار بزرگتر استفاده کرد و یا نتایج را در دسته‌های کوچک‌تر دریافت کرد.

بازیابی رکوردها با Entrez.efetch

پس از به دست آوردن شناسه‌های مورد نظر با esearch، می‌توانید از efetch برای بازیابی کامل رکوردها استفاده کنید. efetch امکان تعیین فرمت خروجی (مانند fasta، genbank، xml) را می‌دهد.


from Bio import Entrez
from Bio import SeqIO
import time

Entrez.email = "your.email@example.com"

# فرض کنید شناسه‌های توالی انسولین را از مرحله قبل داریم
insulin_ids = ['NM_000207', 'NG_007054', 'U30324'] # نمونه IDs

print("\n--- بازیابی توالی‌های انسولین از GenBank ---")
handle = Entrez.efetch(db="nuccore", id=insulin_ids, rettype="gb", retmode="text")
# SeqIO می‌تواند مستقیم از این handle بخواند
records = list(SeqIO.parse(handle, "genbank"))
handle.close()

for i, record in enumerate(records):
    print(f"--- رکورد {i+1} ---")
    print(f"شناسه: {record.id}")
    print(f"توضیحات: {record.description}")
    print(f"توالی (۵۰ کاراکتر اول): {record.seq[:50]}...")
    # اطلاعات ویژگی‌ها را می‌توان از record.features استخراج کرد
    for feature in record.features:
        if feature.type == "CDS":
            print(f"  CDS در موقعیت: {feature.location}")
            if 'product' in feature.qualifiers:
                print(f"  محصول پروتئینی: {feature.qualifiers['product'][0]}")
    print("\n")
time.sleep(1) # برای رعایت دستورالعمل‌های NCBI، بین درخواست‌ها تاخیر ایجاد کنید.

# بازیابی مقالات PubMed
pubmed_ids = ['9278503', '32135048'] # نمونه IDs

print("--- بازیابی خلاصه مقالات از PubMed ---")
handle = Entrez.efetch(db="pubmed", id=pubmed_ids, rettype="abstract", retmode="text")
pubmed_abstracts = handle.read()
handle.close()
print(pubmed_abstracts)

مهم است که پس از اتمام کار با هر handle، آن را با handle.close() ببندید. همچنین، برای جلوگیری از اضافه بار بر روی سرورهای NCBI و بلوکه شدن آدرس IP شما، بین درخواست‌های متوالی خود تاخیر (مثلاً time.sleep(0.5) یا time.sleep(1)) ایجاد کنید.

استخراج اطلاعات از فایل‌های XML

گاهی اوقات efetch نتایج را در فرمت XML برمی‌گرداند (retmode="xml") که نیاز به پردازش دارد. Entrez.read() یک دیکشنری پایتون از XML برمی‌گرداند که کار با آن را آسان می‌کند.


from Bio import Entrez
import time

Entrez.email = "your.email@example.com"

# جستجو برای یک ژن و بازیابی اطلاعات به صورت XML
gene_id = "944742" # Gene ID برای thrL در E. coli K-12

print("\n--- بازیابی اطلاعات ژن به صورت XML ---")
handle = Entrez.efetch(db="gene", id=gene_id, retmode="xml")
gene_record_xml = Entrez.read(handle)
handle.close()

# Entrez.read() خروجی XML را به یک دیکشنری پایتون تبدیل می‌کند
if gene_record_xml and gene_record_xml[0]:
    print(f"نام ژن: {gene_record_xml[0]['Entrezgene_gene']['Gene-ref_locus']}")
    print(f"توضیحات: {gene_record_xml[0]['Entrezgene_gene']['Gene-ref_desc']}")
    # اطلاعات بیشتری را می‌توان از این دیکشنری استخراج کرد
    print(f"ارگانیسم: {gene_record_xml[0]['Entrezgene_source']['BioSource_organism']['Org-ref_taxname']}")

با استفاده از Bio.Entrez، می‌توانید اسکریپت‌های پایتون خود را برای خودکارسازی فرآیند جمع‌آوری داده‌ها از منابع آنلاین بیولوژیکی و ادغام آن‌ها در گردش کار تحلیلی خود بنویسید.

۴. تراز و فیلوژنتیک با Biopython

تراز توالی‌ها (Sequence Alignment) و تحلیل فیلوژنتیک (Phylogenetic Analysis) از پایه‌های بیوانفورماتیک هستند که برای شناسایی شباهت‌ها، استنتاج روابط تکاملی و پیش‌بینی عملکرد پروتئین‌ها و ژن‌ها استفاده می‌شوند. Biopython ماژول‌هایی را برای انجام این تحلیل‌ها یا حداقل برای کار با خروجی ابزارهای خارجی فراهم می‌کند.

تراز توالی‌ها با Bio.pairwise2

ماژول Bio.pairwise2 امکان انجام تراز توالی‌های جفتی (pairwise sequence alignment) را با استفاده از الگوریتم‌های Needleman-Wunsch (تراز سراسری) و Smith-Waterman (تراز محلی) فراهم می‌کند. این ماژول برای تراز کردن تعداد کمی از توالی‌ها مناسب است.


from Bio import pairwise2
from Bio.pairwise2 import format_alignment
from Bio.Seq import Seq

seq1 = Seq("ATGCGT")
seq2 = Seq("ATTGC")

print("--- تراز سراسری (Global Alignment - Needleman-Wunsch) ---")
# match=2, mismatch=-1, gap open=-0.5, gap extend=-0.1
alignments_global = pairwise2.align.globalms(seq1, seq2, 2, -1, -0.5, -0.1)
for a in alignments_global:
    print(format_alignment(*a))

print("\n--- تراز محلی (Local Alignment - Smith-Waterman) ---")
# match=2, mismatch=-1, gap open=-0.5, gap extend=-0.1
alignments_local = pairwise2.align.localms(seq1, seq2, 2, -1, -0.5, -0.1)
for a in alignments_local:
    print(format_alignment(*a))

توابع تراز مختلفی در pairwise2 وجود دارند (مانند globalxx، localxx، globalmx، localms و غیره) که تفاوت‌هایی در نحوه تخصیص امتیازات (scoring) و جریمه شکاف (gap penalty) دارند. تابع format_alignment یک نمایش متنی خوانا از تراز را برمی‌گرداند.

کار با فایل‌های تراز با Bio.AlignIO

برای ترازهای چندگانه (Multiple Sequence Alignment – MSA) که معمولاً با ابزارهای خارجی مانند Clustal Omega یا MUSCLE تولید می‌شوند، Bio.AlignIO به شما امکان می‌دهد تا فایل‌های تراز را بخوانید و دستکاری کنید. این ماژول مشابه Bio.SeqIO عمل می‌کند، اما برای اشیاء تراز (Alignments) به جای توالی‌ها.


from Bio import AlignIO
from Bio.Align import MultipleSeqAlignment
from Bio.Seq import Seq
from Bio.SeqRecord import SeqRecord

# ایجاد یک فایل تراز نمونه (مانند Clustal)
clustal_content = """CLUSTAL O(1.2.4) multiple sequence alignment


seq1            ATGCGTACG
seq2            AT-CGTAC-
seq3            ATGCGCA--
"""
with open("example.aln", "w") as f:
    f.write(clustal_content)

print("\n--- خواندن یک فایل تراز Clustal ---")
alignment = AlignIO.read("example.aln", "clustal")
print(f"تعداد توالی‌ها در تراز: {len(alignment)}")
print(f"طول تراز: {alignment.get_alignment_length()}")

# چاپ تراز
for record in alignment:
    print(f"{record.id}: {record.seq}")

# دسترسی به یک توالی خاص
print(f"\nتوالی seq2: {alignment[1].seq}")

# استخراج یک ستون خاص از تراز (مثلاً ستون سوم)
print(f"ستون سوم تراز: {alignment[:, 2]}") # خروجی: T-G

Bio.AlignIO از فرمت‌های مختلفی مانند Clustal، MAF، Nexus، Phylip و Stockholm پشتیبانی می‌کند.

تحلیل فیلوژنتیک با Bio.Phylo

ماژول Bio.Phylo برای کار با درختان فیلوژنتیک، خواندن و نوشتن فایل‌های درخت (مانند Newick و Nexus) و انجام عملیات بر روی آن‌ها طراحی شده است. این ماژول برای ساخت درخت از ابتدا طراحی نشده است، بلکه برای تحلیل درختان موجود کاربرد دارد.


from Bio import Phylo
import io

# ایجاد یک فایل Newick نمونه
newick_content = "(A:0.1,B:0.2,(C:0.3,D:0.4):0.5);"
with open("example.nwk", "w") as f:
    f.write(newick_content)

print("\n--- خواندن یک درخت فیلوژنتیک Newick ---")
tree = Phylo.read("example.nwk", "newick")

# چاپ درخت به صورت ASCII (متنی)
Phylo.draw_ascii(tree)

print(f"\nتعداد شاخه‌ها (Branches): {len(tree.get_nonterminals())}")
print(f"تعداد برگ‌ها (Leaves): {len(tree.get_terminals())}")

# دسترسی به برگ‌ها
print("\nبرگ‌های درخت:")
for clade in tree.get_terminals():
    print(f"  {clade.name} با طول شاخه: {clade.branch_length}")

# دسترسی به ریشه
root = tree.root
print(f"\nریشه درخت: {root}")

# یافتن مسیر بین دو برگ
path = tree.trace(tree.get_terminals()[0], tree.get_terminals()[1])
print(f"\nمسیر بین {tree.get_terminals()[0].name} و {tree.get_terminals()[1].name}: {[c.name if c.name else 'Internal' for c in path]}")

# محاسبه فاصله بین دو برگ
dist = tree.distance(tree.get_terminals()[0], tree.get_terminals()[1])
print(f"فاصله بین {tree.get_terminals()[0].name} و {tree.get_terminals()[1].name}: {dist:.2f}")

# نوشتن درخت به فرمت دیگر
Phylo.write(tree, "output.nexus", "nexus")
print("\nدرخت به 'output.nexus' نوشته شد.")

ماژول Bio.Phylo قابلیت‌های پیشرفته‌تری مانند پیمایش درخت، دستکاری شاخه‌ها، تغییر ریشه و همچنین ادغام با ابزارهای ترسیم (مانند Matplotlib) برای ایجاد نمودارهای بصری از درختان را نیز ارائه می‌دهد. با ترکیب این ماژول‌ها، Biopython یک پلتفرم قوی برای تحلیل روابط تکاملی فراهم می‌کند.

۵. بیوانفورماتیک ساختاری با Biopython.PDB

بیوانفورماتیک ساختاری به مطالعه ساختار سه‌بعدی مولکول‌های زیستی، عمدتاً پروتئین‌ها و اسیدهای نوکلئیک، و ارتباط آن با عملکرد بیولوژیکی می‌پردازد. ماژول Bio.PDB در Biopython ابزارهای قدرتمندی برای تجزیه و تحلیل فایل‌های PDB (Protein Data Bank) که ساختارهای اتمی مولکول‌ها را ذخیره می‌کنند، فراهم می‌کند.

ماژول Bio.PDB: Parsing و کار با ساختارها

با استفاده از Bio.PDB، می‌توانید فایل‌های PDB را بخوانید، به سلسله مراتب ساختار (مدل، زنجیره، باقی‌مانده، اتم) دسترسی پیدا کنید، و محاسبات مختلفی مانند فواصل و زوایا را انجام دهید.

دانلود و Parsing فایل PDB

Biopython ابزارهایی برای دانلود خودکار فایل‌های PDB از پایگاه داده PDB فراهم می‌کند. سپس می‌توانید فایل را با PDBParser تجزیه کنید.


from Bio.PDB import PDBList, PDBParser
import os

# تعیین مسیری برای ذخیره فایل‌های PDB
pdb_dir = "pdb_files"
os.makedirs(pdb_dir, exist_ok=True)

# دانلود یک فایل PDB (مثلاً 1CRN که یک پروتئین کوچک است)
pdb_id = "1crn"
pdbl = PDBList()
pdb_file = pdbl.retrieve_pdb_file(pdb_id, pdir=pdb_dir, file_format="pdb")

print(f"فایل PDB برای {pdb_id} دانلود شد به: {pdb_file}")

# تجزیه (Parsing) فایل PDB
parser = PDBParser()
structure = parser.get_structure(pdb_id, pdb_file)

print(f"\n--- اطلاعات ساختار {pdb_id} ---")
print(f"تعداد مدل‌ها: {len(structure)}")

# ساختار PDB از سلسله مراتب زیر پیروی می‌کند:
# Structure -> Model -> Chain -> Residue -> Atom

پیمایش سلسله مراتب ساختار

شما می‌توانید از طریق مدل‌ها، زنجیره‌ها، باقی‌مانده‌ها و اتم‌های یک ساختار PDB حلقه بزنید تا اطلاعات خاصی را استخراج کنید.


from Bio.PDB import PDBList, PDBParser
import os
import numpy as np

pdb_dir = "pdb_files"
pdb_id = "1crn"
pdb_file = os.path.join(pdb_dir, f"pdb{pdb_id}.ent") # مسیر فایل دانلود شده

parser = PDBParser()
structure = parser.get_structure(pdb_id, pdb_file)

print("\n--- پیمایش ساختار 1CRN ---")
for model in structure:
    print(f"  مدل: {model.id}")
    for chain in model:
        print(f"    زنجیره: {chain.id}")
        for residue in chain:
            # Residue_id شامل نام باقی‌مانده، شماره باقی‌مانده و یک کد الحاقی است
            print(f"      باقی‌مانده: {residue.get_resname()} {residue.id[1]}")
            for atom in residue:
                print(f"        اتم: {atom.name} ({atom.get_coord()})")
                # مثال: فقط اولین اتم از اولین باقی‌مانده را چاپ کنید تا خروجی زیاد نشود
                # break # برای دیدن همه اتم‌ها این خط را حذف کنید
            # break # برای دیدن همه باقی‌مانده‌ها این خط را حذف کنید
        # break # برای دیدن همه زنجیره‌ها این خط را حذف کنید
    # break # برای دیدن همه مدل‌ها این خط را حذف کنید

محاسبه فاصله بین اتم‌ها

یکی از عملیات‌های رایج، محاسبه فاصله اقلیدسی بین دو اتم است. این کار با استفاده از مختصات اتم‌ها انجام می‌شود.


from Bio.PDB import PDBList, PDBParser
import os
import numpy as np

pdb_dir = "pdb_files"
pdb_id = "1crn"
pdb_file = os.path.join(pdb_dir, f"pdb{pdb_id}.ent")

parser = PDBParser()
structure = parser.get_structure(pdb_id, pdb_file)

# یافتن دو اتم برای محاسبه فاصله
# برای مثال، اتم آلفا-کربن (CA) از باقی‌مانده ۱ و باقی‌مانده ۱۰ در زنجیره A
atom1 = None
atom2 = None

for model in structure:
    for chain in model:
        if chain.id == 'A':
            for residue in chain:
                if residue.id[1] == 1 and 'CA' in residue: # باقی‌مانده ۱
                    atom1 = residue['CA']
                elif residue.id[1] == 10 and 'CA' in residue: # باقی‌مانده ۱۰
                    atom2 = residue['CA']
            break # بعد از پیدا کردن زنجیره A، دیگر به زنجیره‌های دیگر نیازی نیست
    break # بعد از پیدا کردن مدل اول، دیگر به مدل‌های دیگر نیازی نیست

if atom1 and atom2:
    distance = np.linalg.norm(atom1.get_coord() - atom2.get_coord())
    print(f"\nفاصله بین CA باقی‌مانده 1 ({atom1.get_parent().get_resname()}) و CA باقی‌مانده 10 ({atom2.get_parent().get_resname()}) در زنجیره A: {distance:.2f} آنگستروم")
else:
    print("\nاتم‌های مورد نظر یافت نشدند.")

ساخت فضای توالی و ساختار (Surface and Volume)

Bio.PDB ابزارهایی برای محاسبه مساحت سطح دسترسی‌پذیر (Accessible Surface Area – ASA) با استفاده از ماژول DSSP (که نیاز به نصب ابزار DSSP خارجی دارد) یا برای محاسبه حجم فضایی اشغال شده توسط یک مولکول را نیز ارائه می‌دهد. این موارد کمی پیچیده‌تر هستند و اغلب نیاز به ابزارهای جانبی یا دانش عمیق‌تری از بیوانفورماتیک ساختاری دارند، اما امکانات Biopython این مسیر را تسهیل می‌کند. در نهایت، Bio.PDB یک ابزار حیاتی برای هر کسی است که با ساختارهای پروتئینی و اسید نوکلئیک کار می‌کند، و امکان برنامه‌نویسی برای تحلیل‌های پیچیده ساختاری را فراهم می‌آورد.

۶. مباحث پیشرفته و یکپارچه‌سازی در Biopython

Biopython فراتر از دستکاری توالی‌های ساده و تعامل با پایگاه‌های داده است. این کتابخانه امکانات قدرتمندی برای یکپارچه‌سازی با ابزارهای خارجی، اجرای تحلیل‌های پیشرفته و کارآمد با داده‌های بزرگ را فراهم می‌کند.

یکپارچه‌سازی با ابزارهای خارجی (مثلاً BLAST)

یکی از قدرت‌های Biopython، قابلیت آن در یکپارچه‌سازی با ابزارهای بیوانفورماتیکی خارجی محبوب مانند BLAST (Basic Local Alignment Search Tool) است. این یکپارچه‌سازی می‌تواند هم به صورت آنلاین با سرورهای NCBI و هم به صورت محلی با یک نصب BLAST مستقل انجام شود.

اجرای BLAST آنلاین با Bio.Blast.NCBIWWW

ماژول Bio.Blast.NCBIWWW به شما امکان می‌دهد تا درخواست‌های BLAST را به صورت برنامه‌نویسی به سرورهای NCBI ارسال کنید و نتایج را بازیابی کنید.


from Bio.Blast import NCBIWWW
from Bio.Blast import NCBIXML
from Bio.Seq import Seq
from Bio.SeqRecord import SeqRecord
import io
import time

Entrez.email = "your.email@example.com" # دوباره ایمیل خود را تنظیم کنید

# یک توالی پروتئینی نمونه
query_sequence = SeqRecord(Seq("MGCKLKSLVLDGAANLAFGSVVD"), id="test_protein", description="A short test protein sequence")

print("--- اجرای BLAST آنلاین (blastp) ---")
# ارسال درخواست BLASTp به NCBI
# db="nr" برای پایگاه داده غیررداندانت، organism="Homo sapiens" برای محدود کردن نتایج
# expect=1e-10 برای تعیین آستانه E-value
# اگر توالی شما طولانی باشد، این مرحله زمانبر خواهد بود.
# از io.StringIO برای شبیه‌سازی فایل متنی برای SeqIO.read() استفاده می‌کنیم.
try:
    result_handle = NCBIWWW.qblast("blastp", "nr", str(query_sequence.seq),
                                   entrez_query="Homo sapiens", expect=1e-10)
    time.sleep(5) # صبر برای نتایج
    
    # Parsing نتایج XML BLAST
    blast_records = NCBIXML.parse(result_handle)
    
    print("\n--- تحلیل نتایج BLAST ---")
    first_record = next(blast_records) # گرفتن اولین رکورد (اگر توالی ورودی شما فقط یکی است)
    
    print(f"توالی جستجو شده: {first_record.query[:50]}...")
    print(f"تعداد تطابق‌ها: {len(first_record.alignments)}")
    
    # چاپ بهترین تطابق‌ها
    for alignment in first_record.alignments[:5]: # چاپ 5 تطابق برتر
        for hsp in alignment.hsps: # HSP: High-scoring Segment Pair
            print(f"  تطابق با: {alignment.title[:70]}...")
            print(f"    طول: {alignment.length}")
            print(f"    E-value: {hsp.expect:.2e}")
            print(f"    Score: {hsp.score:.2f}")
            print(f"    Query: {hsp.query[0:75]}...")
            print(f"    Match: {hsp.match[0:75]}...")
            print(f"    Subject: {hsp.sbjct[0:75]}...")
            print("-" * 80)
    result_handle.close()

except Exception as e:
    print(f"خطا در اجرای BLAST آنلاین: {e}")
    print("شاید شما به اینترنت وصل نیستید، یا NCBI پاسخ نمی‌دهد، یا توالی خیلی کوتاه است.")

استفاده از NCBIWWW آسان است، اما به اتصال اینترنت و سرورهای NCBI وابسته است. برای تحلیل‌های پرحجم یا برای کنترل بیشتر بر پارامترها، اجرای BLAST محلی ترجیح داده می‌شود.

اجرای BLAST محلی با Bio.Blast.Applications (نیازمند نصب BLAST+)

برای اجرای BLAST به صورت محلی، ابتدا باید نرم‌افزار BLAST+ را از وب‌سایت NCBI دانلود و نصب کنید و پایگاه‌های داده BLAST را (مانند nr یا nt) دانلود کنید. سپس می‌توانید از Bio.Blast.Applications برای اجرای دستورات BLAST از طریق پایتون استفاده کنید.


# این کد تنها در صورتی کار می‌کند که BLAST+ به صورت محلی نصب شده باشد.
# فرض کنید blastp و پایگاه داده محلی به نام "my_protein_db" در دسترس هستند.

from Bio.Blast.Applications import NcbiblastpCommandline
from Bio.Blast import NCBIXML
import io

# ایجاد یک فایل توالی کوئری (مثلاً query.fasta)
with open("query.fasta", "w") as f:
    f.write(">test_protein\nMGCKLKSLVLDGAANLAFGSVVD\n")

# تعریف خط فرمان BLASTp
# db = نام پایگاه داده محلی شما
# out = فایل خروجی
# outfmt = فرمت خروجی (5 برای XML)
blastp_cline = NcbiblastpCommandline(query="query.fasta", db="my_protein_db",
                                     evalue=0.001, outfmt=5, out="local_blast_results.xml")

print(f"\n--- اجرای BLAST محلی: {blastp_cline} ---")
# اجرای دستور BLAST
try:
    stdout, stderr = blastp_cline()
    print("BLAST محلی با موفقیت اجرا شد.")
    
    # Parsing نتایج XML
    with open("local_blast_results.xml", "r") as result_handle:
        blast_records = NCBIXML.parse(result_handle)
        first_record = next(blast_records)
        print(f"تعداد تطابق‌ها در BLAST محلی: {len(first_record.alignments)}")
        # می‌توانید مانند مثال آنلاین، تطابق‌ها را چاپ کنید.

except Exception as e:
    print(f"خطا در اجرای BLAST محلی: {e}")
    print("مطمئن شوید BLAST+ نصب شده، متغیرهای محیطی درست تنظیم شده‌اند و پایگاه داده 'my_protein_db' وجود دارد.")

Bio.Blast یک رابط قدرتمند برای اتوماسیون تحلیل‌های شباهت توالی است.

مدیریت فایل‌های بزرگ با ژنراتورها (Generators)

هنگام کار با فایل‌های توالی بسیار بزرگ (مانند کل ژنوم‌ها یا متاژنوم‌ها)، خواندن کل فایل در حافظه می‌تواند باعث اتمام حافظه (out-of-memory errors) شود. Bio.SeqIO.parse() به طور پیش‌فرض یک ژنراتور برمی‌گرداند که توالی‌ها را یکی یکی و به محض نیاز بارگذاری می‌کند و از مصرف زیاد حافظه جلوگیری می‌کند.


from Bio import SeqIO

# ایجاد یک فایل FASTA بزرگتر برای مثال
large_fasta_content = ""
for i in range(10000): # 10000 توالی
    large_fasta_content += f">seq_{i}\n{'ATGC' * 250}\n" # هر توالی 1000 کاراکتر
with open("large_example.fasta", "w") as f:
    f.write(large_fasta_content)

print("\n--- پردازش فایل بزرگ با ژنراتور ---")
count = 0
for record in SeqIO.parse("large_example.fasta", "fasta"):
    count += 1
    if count % 1000 == 0:
        print(f"پردازش {count} توالی...")
    # عملیات بر روی هر رکورد (مثلاً محاسبه GC content)
    # gc_content = Bio.SeqUtils.GC(record.seq)
print(f"در مجموع {count} توالی پردازش شد.")

این رویکرد برای کار با داده‌های NGS و متاژنومیک ضروری است.

ادغام با سایر کتابخانه‌های پایتون

Biopython به خوبی با سایر کتابخانه‌های علمی پایتون مانند NumPy (برای محاسبات عددی)، SciPy (برای تحلیل‌های آماری پیشرفته) و Matplotlib (برای تجسم داده‌ها) یکپارچه می‌شود. این ادغام، قدرت تحلیل‌های بیوانفورماتیکی شما را به شدت افزایش می‌دهد.


import matplotlib.pyplot as plt
import numpy as np
from Bio import SeqIO
from Bio.SeqUtils import GC

# فرض کنید یک فایل FASTA با توالی‌های مختلف داریم
# (از همان large_example.fasta استفاده می‌کنیم)

gc_contents = []
for record in SeqIO.parse("large_example.fasta", "fasta"):
    gc_contents.append(GC(record.seq))

# رسم توزیع GC content با Matplotlib
plt.hist(gc_contents, bins=20, edgecolor='black')
plt.title('توزیع GC content')
plt.xlabel('GC Content (%)')
plt.ylabel('تعداد توالی‌ها')
plt.grid(axis='y', alpha=0.75)
# plt.show() # برای نمایش نمودار
print("\nنمودار توزیع GC Content (برای مشاهده نیاز به plt.show() است).")

# مثال NumPy: تبدیل توالی به آرایه عددی برای پردازش
# این کار معمولاً برای مدل‌سازی ماشینی یا محاسبات ماتریسی استفاده می‌شود
def seq_to_numeric(seq_obj):
    mapping = {'A': 0, 'T': 1, 'G': 2, 'C': 3}
    return np.array([mapping.get(base, -1) for base in str(seq_obj)])

dna_seq_numeric = seq_to_numeric(Seq("ATGC"))
print(f"\nتوالی عددی 'ATGC': {dna_seq_numeric}")

با ترکیب Biopython با این کتابخانه‌ها، می‌توانید جریان‌های کاری پیچیده‌ای را برای تحلیل داده‌های زیستی ایجاد کنید که شامل پردازش داده، مدل‌سازی آماری و تجسم نتایج باشد.

۷. مطالعه موردی: تحلیل همسانی ژن‌ها و ساخت درخت فیلوژنتیک ساده

در این بخش، یک مطالعه موردی عملی را بررسی می‌کنیم که چندین ماژول Biopython را برای حل یک سوال بیولوژیکی رایج ترکیب می‌کند: یافتن ژن‌های همسان در گونه‌های مختلف و استنتاج روابط تکاملی آن‌ها با ساخت یک درخت فیلوژنتیک ساده. این مثال یکپارچگی ابزارهای مختلف Biopython را نشان می‌دهد.

سوال بیولوژیکی:

فرض کنید به دنبال درک روابط تکاملی ژن CYC1 (سیتوکروم C1) در چند گونه مخمر هستیم.

گام‌ها و پیاده‌سازی با Biopython:

گام ۱: بازیابی توالی ژن‌های CYC1 از گونه‌های مختلف با Entrez

از Bio.Entrez برای جستجو و بازیابی توالی‌های نوکلئوتیدی ژن CYC1 از گونه‌های مختلف مخمر استفاده می‌کنیم.


from Bio import Entrez
from Bio import SeqIO
import time
import os

Entrez.email = "your.email@example.com"

species_list = [
    "Saccharomyces cerevisiae",
    "Schizosaccharomyces pombe",
    "Candida albicans",
    "Kluyveromyces lactis"
]

cyc1_records = []
print("--- بازیابی توالی‌های CYC1 از NCBI ---")
for species in species_list:
    search_term = f"CYC1[gene] AND {species}[organism] AND RefSeq[filter]"
    try:
        handle = Entrez.esearch(db="nuccore", term=search_term, retmax="1") # فرض می‌کنیم یک رکورد اصلی کافی است
        record_ids = Entrez.read(handle)
        handle.close()
        
        if record_ids['IdList']:
            gene_id = record_ids['IdList'][0]
            print(f"  یافتن ID: {gene_id} برای {species}")
            fetch_handle = Entrez.efetch(db="nuccore", id=gene_id, rettype="fasta", retmode="text")
            seq_record = SeqIO.read(fetch_handle, "fasta")
            fetch_handle.close()
            # اصلاح ID برای خوانایی بهتر در درخت فیلوژنتیک
            seq_record.id = species.replace(" ", "_")
            seq_record.description = "" # حذف توضیحات طولانی برای سادگی
            cyc1_records.append(seq_record)
        else:
            print(f"  توالی CYC1 برای {species} یافت نشد.")
        time.sleep(0.5) # رعایت فاصله بین درخواست‌ها
    except Exception as e:
        print(f"خطا در بازیابی برای {species}: {e}")

if not cyc1_records:
    print("هیچ توالی CYC1 یافت نشد. نمی‌توان ادامه داد.")
else:
    # ذخیره توالی‌های بازیابی شده در یک فایل FASTA
    output_fasta = "cyc1_sequences.fasta"
    with open(output_fasta, "w") as out_handle:
        SeqIO.write(cyc1_records, out_handle, "fasta")
    print(f"\nتوالی‌های CYC1 در '{output_fasta}' ذخیره شدند.")

گام ۲: تراز چندگانه توالی‌ها (Multiple Sequence Alignment – MSA)

Biopython یک ابزار بومی برای تراز چندگانه ندارد، اما می‌تواند با ابزارهای خارجی مانند Clustal Omega یا MUSCLE کار کند. برای سادگی، در اینجا تنها به صورت مفهومی از این گام عبور می‌کنیم و از خروجی فرضی یک ابزار MSA استفاده می‌کنیم. در یک سناریوی واقعی، شما باید ClustalOmegaCommandline را از Bio.Align.Applications اجرا کنید یا از یک سرویس وب استفاده کنید.


from Bio.Align.Applications import ClustalOmegaCommandline # نیاز به نصب Clustal Omega
import subprocess

# فرض کنید cyc1_sequences.fasta همان فایل خروجی گام ۱ است
input_fasta = "cyc1_sequences.fasta"
output_aln = "cyc1_alignment.aln"

# این بخش نیاز به نصب Clustal Omega بر روی سیستم دارد
# و ممکن است نیاز به تنظیم PATH محیطی برای پیدا کردن "clustalo" باشد.
print("\n--- انجام تراز چندگانه با Clustal Omega (در صورت نصب) ---")
try:
    clustalomega_cline = ClustalOmegaCommandline(infile=input_fasta, outfile=output_aln,
                                                  seqtype="DNA", verbose=True, auto=True)
    # خروجی استاندارد و خطای استاندارد را نادیده بگیرید مگر اینکه برای اشکال‌زدایی نیاز داشته باشید
    # stdout, stderr = clustalomega_cline()
    # print(f"stdout: {stdout}, stderr: {stderr}") # برای اشکال‌زدایی
    print(f"دستور Clustal Omega: {clustalomega_cline}")
    subprocess.run(str(clustalomega_cline), shell=True, check=True)
    print(f"تراز چندگانه در '{output_aln}' ذخیره شد.")

    # اگر Clustal Omega نصب نشده بود، از یک فایل تراز فرضی استفاده می‌کنیم:
except Exception as e:
    print(f"خطا در اجرای Clustal Omega: {e}")
    print("لطفاً Clustal Omega را نصب کنید یا از یک فایل تراز از پیش آماده استفاده کنید.")
    # ایجاد یک فایل تراز فرضی برای ادامه مثال
    fake_alignment_content = """CLUSTAL O(1.2.4) multiple sequence alignment


Saccharomyces_cerevisiae  ATGCGTACGTAGCTA-GCTAGCTA
Schizosaccharomyces_pombe ATGCGTAC--AGCTAGCTAGCTA
Candida_albicans          ATTCGTACGT-GCTAGCTAGCTA
Kluyveromyces_lactis      ATGCGTACGTAGTTA-GCTAGCTA
"""
    with open(output_aln, "w") as f:
        f.write(fake_alignment_content)
    print(f"یک فایل تراز فرضی در '{output_aln}' برای ادامه ایجاد شد.")

گام ۳: ساخت درخت فیلوژنتیک

با استفاده از فایل تراز، می‌توانیم یک ماتریس فاصله ایجاد کنیم و سپس از آن برای ساخت یک درخت فیلوژنتیک استفاده کنیم. ماژول Bio.Phylo.TreeConstruction ابزارهایی برای این کار فراهم می‌کند.


from Bio import AlignIO
from Bio.Phylo.TreeConstruction import DistanceCalculator, DistanceTreeConstructor
from Bio import Phylo
import matplotlib.pyplot as plt

alignment_file = "cyc1_alignment.aln"

print("\n--- ساخت درخت فیلوژنتیک ---")
try:
    alignment = AlignIO.read(alignment_file, "clustal")
    print(f"فایل تراز با {len(alignment)} توالی با موفقیت بارگذاری شد.")

    # محاسبه ماتریس فاصله (با استفاده از مدل P-distance)
    calculator = DistanceCalculator('identity') # 'identity' یا 'blosum62' برای پروتئین‌ها
    dm = calculator.get_distance(alignment)
    print("\nماتریس فاصله:")
    print(dm)

    # ساخت درخت فیلوژنتیک (با استفاده از روش UPGMA)
    constructor = DistanceTreeConstructor()
    tree = constructor.upgma(dm) # یا 'nj' برای Neighbor Joining

    # ریشه‌گذاری درخت (اختیاری)
    # tree.root_with_outgroup(tree.find_clades("Saccharomyces_cerevisiae").pop()) # مثال برای ریشه‌گذاری با یک برون‌گروه

    # نوشتن درخت به فرمت Newick
    output_tree_file = "cyc1_phylogenetic_tree.nwk"
    Phylo.write(tree, output_tree_file, "newick")
    print(f"\nدرخت فیلوژنتیک در '{output_tree_file}' ذخیره شد.")

    # نمایش درخت به صورت ASCII
    print("\nنمایش درخت به صورت ASCII:")
    Phylo.draw_ascii(tree)

    # نمایش بصری درخت با Matplotlib (اگر بخواهید)
    # fig = Phylo.draw(tree, do_show=False)
    # plt.title("Phylogenetic Tree of CYC1 Genes")
    # plt.show()

except FileNotFoundError:
    print(f"فایل تراز '{alignment_file}' یافت نشد. مطمئن شوید گام ۲ با موفقیت اجرا شده است.")
except Exception as e:
    print(f"خطا در ساخت درخت فیلوژنتیک: {e}")

این مطالعه موردی نشان می‌دهد که چگونه می‌توان با ترکیب ماژول‌های Bio.Entrez، Bio.AlignIO، و Bio.Phylo یک گردش کار کامل بیوانفورماتیکی برای تحلیل روابط تکاملی ژن‌ها ایجاد کرد. این یک الگوی اساسی است که می‌تواند برای تحلیل سایر خانواده‌های ژنی یا پروتئینی نیز به کار رود، با توجه به اینکه ابزارهای خارجی (مانند نرم‌افزار MSA) به درستی تنظیم شده باشند.

۸. بهترین روش‌ها و مسیرهای آینده

استفاده مؤثر از Biopython نه تنها مستلزم تسلط بر ماژول‌های آن است، بلکه پیروی از بهترین روش‌های برنامه‌نویسی و آگاهی از مسیرهای آینده این حوزه نیز اهمیت دارد.

بهترین روش‌ها در برنامه‌نویسی بیوانفورماتیک با Biopython

  1. کد خوانا و مستند: اسکریپت‌های بیوانفورماتیکی اغلب پیچیده هستند. استفاده از نام‌های متغیر معنادار، توضیحات (comments) کافی و مستندسازی کد (docstrings) برای توابع و کلاس‌ها، خوانایی و قابلیت نگهداری کد را به شدت افزایش می‌دهد.
  2. مدیریت خطا (Error Handling): همیشه امکان مواجهه با داده‌های ناسازگار، خطاهای شبکه یا مشکلات ابزارهای خارجی وجود دارد. استفاده از بلاک‌های try-except برای مدیریت gracefully (با وقار) خطاها، از توقف ناگهانی برنامه جلوگیری کرده و به کاربر کمک می‌کند تا مشکل را شناسایی کند.
  3. استفاده از ژنراتورها برای داده‌های بزرگ: همانطور که قبلاً ذکر شد، برای فایل‌های بزرگ توالی، از SeqIO.parse() به جای SeqIO.read() برای بارگذاری یک توالی در هر زمان استفاده کنید. این کار مصرف حافظه را بهینه می‌کند.
  4. رعایت محدودیت‌های سرویس وب: هنگام استفاده از Bio.Entrez یا Bio.Blast.NCBIWWW، همیشه به آدرس ایمیل خود را مشخص کنید و بین درخواست‌ها تأخیر (time.sleep()) قرار دهید تا از مسدود شدن IP خود توسط سرورهای عمومی جلوگیری کنید.
  5. جداسازی منطق: توابع کوچک و مشخص بنویسید که هر کدام یک وظیفه خاص را انجام دهند (مثلاً یک تابع برای خواندن فایل، یک تابع برای محاسبه GC content، یک تابع برای نوشتن نتایج). این کار باعث می‌شود کد شما ماژولارتر و قابل تست‌تر باشد.
  6. استفاده از محیط‌های مجازی: برای مدیریت وابستگی‌های پروژه خود، همیشه از محیط‌های مجازی (virtual environments) مانند venv یا conda استفاده کنید. این کار از تداخل نسخه‌های کتابخانه‌ها بین پروژه‌های مختلف جلوگیری می‌کند.

منابع و جامعه Biopython

  • مستندات رسمی: وب‌سایت Biopython دارای مستندات جامع، آموزش‌ها و مثال‌های فراوان است. این بهترین نقطه شروع برای یادگیری عمیق‌تر است.
  • لیست پستی: Biopython یک لیست پستی فعال دارد که می‌توانید سوالات خود را مطرح کرده و از جامعه کمک بگیرید.
  • GitHub: کد منبع Biopython در GitHub میزبانی می‌شود. می‌توانید به توسعه پروژه کمک کنید، باگ‌ها را گزارش دهید یا تغییرات خود را پیشنهاد دهید.
  • کتاب‌ها و دوره‌های آنلاین: بسیاری از کتاب‌ها و دوره‌های آنلاین در زمینه بیوانفورماتیک از Biopython به عنوان ابزار اصلی استفاده می‌کنند که می‌تواند منابع یادگیری ارزشمندی باشند.

مسیرهای آینده و ادغام با فناوری‌های نوین

Biopython به طور مداوم در حال تکامل است تا با پیشرفت‌های سریع در بیوانفورماتیک همگام شود. در آینده، می‌توان انتظار داشت که Biopython بیشتر با فناوری‌های نوظهور مانند هوش مصنوعی و یادگیری ماشین (AI/ML) در زیست‌شناسی، تحلیل داده‌های تک‌سلولی، و داده‌های چنداومیکس (multi-omics) ادغام شود. قابلیت‌های Biopython در پردازش و آماده‌سازی داده‌های بیولوژیکی، آن را به یک جزء ضروری در خطوط لوله تحلیل AI/ML تبدیل می‌کند. همچنین، پشتیبانی از فرمت‌های جدید داده‌ها و بهینه‌سازی عملکرد برای داده‌های حجیم‌تر از جمله روندهای توسعه آتی خواهد بود.

بیوانفورماتیک به طور فزاینده‌ای به سمت تحلیل‌های چندبعدی و یکپارچه حرکت می‌کند. Biopython، با انعطاف‌پذیری و ماژولار بودن خود، بستر مناسبی را برای توسعه ابزارهای سفارشی و خطوط لوله تحلیلی فراهم می‌آورد که می‌تواند نیازهای تحقیقاتی آینده را برآورده سازد. از این رو، سرمایه‌گذاری در یادگیری و تسلط بر Biopython، سرمایه‌گذاری در آینده توانایی‌های تحلیلی شما در علم زیست‌شناسی است.

نتیجه‌گیری

Biopython به وضوح یکی از ستون‌های اصلی ابزارهای برنامه‌نویسی برای بیوانفورماتیک مدرن است. این کتابخانه قدرتمند پایتون، با ارائه مجموعه‌ای جامع از ماژول‌ها، از دستکاری ابتدایی توالی‌ها و فایل‌های فرمت استاندارد گرفته تا تعامل پیچیده با پایگاه‌های داده زیستی آنلاین، انجام تحلیل‌های تراز و فیلوژنتیک، و کندوکاو در ساختارهای سه‌بعدی پروتئین‌ها، ابزاری ضروری برای هر محقق و توسعه‌دهنده‌ای در این حوزه به شمار می‌رود.

ما در این مقاله به بررسی عمیق مفاهیم بنیادین Biopython، نحوه نصب و استفاده از اشیاء کلیدی Seq و SeqRecord پرداختیم. سپس، نحوه کار با ماژول Bio.SeqIO برای خواندن و نوشتن فرمت‌های رایج فایل‌های بیوانفورماتیکی مانند FASTA و GenBank را فرا گرفتیم. گام‌های بعدی ما شامل دستکاری و تحلیل توالی‌ها با استفاده از متدهای ترجمه، مکمل معکوس و محاسبه خواص بیوفیزیکی بود. توانایی تعامل با پایگاه‌های داده عمومی NCBI از طریق Bio.Entrez نیز مورد تأکید قرار گرفت که به اتوماسیون بازیابی داده‌های حیاتی کمک شایانی می‌کند. علاوه بر این، ابزارهای Biopython برای تراز توالی‌های جفتی با Bio.pairwise2 و همچنین تحلیل و تجسم درختان فیلوژنتیک با Bio.Phylo، مسیر را برای مطالعات تکاملی هموار ساخت. در نهایت، ماژول Bio.PDB درهای بیوانفورماتیک ساختاری را گشود و امکان پردازش و تحلیل ساختارهای مولکولی را فراهم آورد.

با مطالعه موردی ارائه شده در این مقاله، توانایی Biopython در یکپارچه‌سازی وظایف مختلف بیوانفورماتیکی برای پاسخ به سوالات بیولوژیکی پیچیده به وضوح نمایان شد. از بازیابی توالی‌ها از پایگاه‌های داده گرفته تا انجام تراز چندگانه و ساخت درختان فیلوژنتیک، Biopython به عنوان یک چسب عمل می‌کند که ابزارهای مختلف را به هم متصل کرده و یک جریان کاری یکپارچه را ایجاد می‌کند.

درک و به کارگیری Biopython نه تنها سرعت و کارایی تحقیقات بیوانفورماتیکی را افزایش می‌دهد، بلکه به محققان این امکان را می‌دهد که سوالات جدیدی را مطرح کنند و به کشفیات نوینی دست یابند. با توجه به سرعت بالای تولید داده در زیست‌شناسی و نیاز روزافزون به تحلیل‌های محاسباتی، تسلط بر ابزارهایی مانند Biopython نه یک مزیت، بلکه یک ضرورت است. امیدواریم این راهنمای جامع، شما را در سفرتان به سوی استفاده از قدرت پایتون و Biopython در حل مسائل هیجان‌انگیز بیوانفورماتیکی توانمند سازد.

اکنون زمان آن فرا رسیده است که با استفاده از دانش و نمونه کدهای ارائه شده، به کاوش و پیاده‌سازی راه‌حل‌های نوآورانه در دنیای بیوانفورماتیک بپردازید.

“تسلط به برنامه‌نویسی پایتون با هوش مصنوعی: آموزش کدنویسی هوشمند با ChatGPT”

قیمت اصلی 2.290.000 ریال بود.قیمت فعلی 1.590.000 ریال است.

"تسلط به برنامه‌نویسی پایتون با هوش مصنوعی: آموزش کدنویسی هوشمند با ChatGPT"

"با شرکت در این دوره جامع و کاربردی، به راحتی مهارت‌های برنامه‌نویسی پایتون را از سطح مبتدی تا پیشرفته با کمک هوش مصنوعی ChatGPT بیاموزید. این دوره، با بیش از 6 ساعت محتوای آموزشی، شما را قادر می‌سازد تا به سرعت الگوریتم‌های پیچیده را درک کرده و اپلیکیشن‌های هوشمند ایجاد کنید. مناسب برای تمامی سطوح با زیرنویس فارسی حرفه‌ای و امکان دانلود و تماشای آنلاین."

ویژگی‌های کلیدی:

بدون نیاز به تجربه قبلی برنامه‌نویسی

زیرنویس فارسی با ترجمه حرفه‌ای

۳۰ ٪ تخفیف ویژه برای دانشجویان و دانش آموزان