原始出處: http://www.tpj.com/
本文作者: Lincoln Steinx
本文譯者: tcwu
Reprinted courtesy of the Perl Journal, http://www.tpj.com/
Lincoln Stein's Website is http://stein.cshl.org/
位置:英國劍橋,歐洲最大的 DNA 定序研究中心的會議室
場合:本中心與美國最大的 DNA 定序研究中心的電腦科學家的高階層會議
問題:雖然這兩個中心使用幾乎相同的實驗技術,幾乎相同的數據庫,還有幾乎相同的資料分析工具,卻仍然無法交換或者比較出有意義的結果。
解決方案:Perl
人類基因計劃在大約 1990 開始雄心勃勃的開始發展,期望能以國際合作的力量找出人類以及部分實驗動物的完整 DNA 序列。這項工作的性質兼具科學與醫藥。藉由了解生物起源的構造,以及種種令人苦惱的細節,我們希望能夠了解有機體如何由一顆卵發展到復雜的多細胞生物,食物如何代謝以及被轉換成身體的一部分,以及神經系統如何流暢的工作。從醫學的角度來看,從全盤了解完整的 DNA 序列得來的知道,能夠有效的加速找出人類疾病(以及可能的疾病)的原因。
經過六年的努力,基因計劃已經超越原先的計劃日程了。人類以及實驗動物的詳細基因地圖已經完成了(用一連串的標記來安排 DNA 是決定完整序列的第一步)。最小的有機體,酵母,已經近乎完成,接著下一個,細小的蠕蟲也不遠了。幾個月以前大規模的人類 DAN 定序工作已經在各中心展開,并且在整年中都會全力進行。
從資訊處理的角度來看,DNA 是一個非常長的字串且由四個字母構成,分別是 A,T,G,C(這四個字母分別為四種化學物質的縮寫,是構成雙股螺旋的基礎。字串的長度令人印象深刻但也不是讓人特別驚訝: 3 x 10^9 的字母長,或者如果你用一個位元來儲存每個字母的話,需要 3GB 的儲存空間。
3GB 不小但是以今天的標準無疑的可以被管理。不幸的是,這只是儲存結果所需要的空間。要得到這些結果所需要的儲存空間遠遠大的多。根本的問題在於,目前的 DNA 定序技術一次最多只能讀到 500 個連續的字母。為了決定更長的序列,必須將 DNA 定序為一小塊一小塊部分重疊的片段,稱為”reads”,這些拼圖般的區域用演算法來檢查并找出相配的地方。因為 DNA 序列并非隨機的(相似但并非完全一樣的基本圖案在基因中出現很多次),而且因為 DNA 定序技術有雜訊且傾向於錯誤,必須針對某個區域作 5 到 10 次,才能可靠的把”reads”片段重組成真正的序列,這增加了要管理的資料的數量。在這之上的是與實驗室工作相關的資訊: 誰進行了實驗,什麼時候完成的,被定序的基因區段,用哪個軟件以及哪個版本重組序列,對實驗加上的注解,等等。除此之外,一般人通常想要將定序用的機器產生的原始資料儲存下來,每 500 個字母會產生 20-30kilobytes 長度的資料檔案!
這還并非全部。只決定 DNA 序列是不夠的。在這些序列里面,有功能的區域散布在很長的沒有功\能的區域中。人類 DNA 中有基因,控制區域,結構區域,甚至有些病毒卷入人體中并且變成了化石遺跡。因為基因跟控制區域負責健康與疾病,研究者會想要標示以其注解它們當它們被重組的時候。這類的注解產生了更多的資料需要被追蹤與儲存。
某些人評估居會有 1 至 10TB 的資訊需要被儲存才能看出人類基因計劃的結論。
所以 Perl 能做什麼呢??從一開始研究者就了解到資訊學將會在基因計劃中扮演很重要的角色。一個整合每個基因中心的資訊學核心被建立了。這些核心的任務有兩個: 提供電腦支援和數據庫福對給他們相關的實驗室,還有發展資料分析和管理軟件給整個基因研究社群。
公平的來說,資訊科學小組一開始的結果是好壞參雜的。有些小組試圖在復雜的關聯數據庫上面建立大型的系統,它們一次又一次的受到生物研究的高度動態的阻撓。當一套系統里里外外運作都與復雜的實驗室協定正常配合,被實作出來且經過除錯,新的科技已經取代了舊的協定,於是軟件工程師又得回到設計版前。
然而,大多數的小組學會了建構模組化的,松散結合的系統,這些系統的部分可以被拿出來或放進去而不需要重新更換整套系統。舉例來說,在我的小組里面,我們發現許多資料分析工作牽涉到一連串的半獨立的步驟,假想某人想要操作一個剛剛被定只好的位元(圖一)。首先需要一個基本的品質測試:序列夠不夠長 ? 含糊不清的字元是不是在最大限制以下? 接著有”向量檢查”。為了技術上的理由,人類 DNA 在被定序前必須經過細菌處理(這就是”復制”的程序)。并不常發生,但是人類 DNA 有時候會在處理的過程中遺失,而且整個序列包含了細菌的向量。向量檢查確保只有人類的基因被記載到數據庫里面。接下來是反覆序列的檢查。人類 DNA 充滿了重復的元素,使得將拼圖安裝在一起變的富有挑戰性。重復序列測試試圖由一個已知重復序列的數據庫找出新序列,倒數第二個測試則是試圖找出新的序列靠著對照於一個很大的社群的 DNA 序列數據庫。在這時候一個比對成功通常能提供線索找到新序列的功\能。完成這些測試之後,序列以及它的資訊已經被收集且載入了實驗室的區域性數據庫。
將 DNA 序列通過這些獨立分析步驟的過程看起來很像一根水管,因此不用多久我們就了解 Unix 系統上面的”pipe”可以操作項工作。我們發展了一個簡單的以 Perl 為基礎的資料交換格式,叫做”boulderio”,這格式允許松散連結的程序加入資訊到以導管(pipe)為基礎的輸入/輸入字串流。 Boulderio 的基礎是一對一對標簽/值。Perl 模組讓獲得輸入很容易,取出他們有興趣的標簽,在上面作一些事情,然後丟回輸出字串流。所有該程序不感興趣的標簽被傳到標準輸出,所以其他的程序可以使用它們。
在這種形式的設計下,分析一個新 DNA 序列看起來像是這樣(這并非我們真正在用的程序源代碼,但已經很接近了)
name_sequence.pl < new.dna |
quality_check.pl |
vector_check.pl |
find_repeats.pl |
search_big_database.pl |
load_lab_database.pl
1 一個包含新的 DNA 序列的檔案會一個叫做 "name_sequence.pl" 的 perl script 處理,該程序的任務只是給予這個序列一個新的且唯一的名字并且將他輸出成 boulder 格式,它的輸出看起來像:
NAME=L26P93.2
SEQUENCE=GATTTCAGAGTCCCAGATTTCCCCCAGGGGGTTTCCAGAGAGCCC......
來自 name_sequence.pl 的輸入接著被傳入品質檢查程序,它會找尋 SEQUENCE 標簽,跑品質檢查演算法,然後把它的結論寫到資料字串流里面。資料字串流現在看起來像:
NAME=L26P93.2
SEQUENCE=GATTTCAGAGTCCCAGATTTCCCCCAGGGGGTTTCCAGAGAGCCC......
QUALITY_CHECK=OK
現在資料字串流進入了向量檢查。它會從字串流中取出 SEQUENCE 標簽并且執行向量檢查演算法。資料字串流現在看起來:
NAME=L26P93.2
SEQUENCE=GATTTCAGAGTCCCAGATTTCCCCCAGGGGGTTTCCAGAGAGCCC......
QUALITY_CHECK=OK
VECTOR_CHECK=OK
VECTOR_START=10
VECTOR_LENGTH=300
這些東西繼續通過導管(pipeline),直到最後 "load_lab_database.pl" 程序核對所有收集的資料,將一些最後的結論是否適合未來適合標記起來,以及把所有的結果送入實驗室的數據庫。Boulderio 格式的一個很好的特性就是許多個序列的紀錄可以被連續的在 Unix 導管里面被處理。用一個”=”表示表示一筆記錄的結尾,以及下筆資料的開始:
NAME=L26P93.2
SEQUENCE=GATTTCAGAGTCCCAGATTTCCCCCAGGGGGTTTCCAGAGAGCCC......
=
NAME=L26P93.3
SEQUENCE=CCCCTAGAGAGAGAGAGCCGAGTTCAAAGTCAAAACCCATTCTCTCTCCTC...
=
也可以在紀錄中再建立子紀錄,這使得我們可以使用結構化的資料型態。
以下為范例源代碼,這個源代碼處理 boulderio 格式。它有物件導向的風格,紀錄被從輸入字串流中拉出來,修改,然後丟回字串流中。
use Boulder::Stream;
$stream = new Boulder::Stream;
while ($record = $stream->read_record('NAME','SEQUENCE')) {
$name = $record->get('NAME');
$sequence = $record->get('SEQUENCE');
...[continue processing]...
$record->add(QUALITY_CHECK=>"OK");
$stream->write_record($record);
}
(如果你對 boulderio 格式有興趣,可以在 http://stein.cshl.org/software/boulder/找到更多資訊以及操作它所需要的 Perl 函式庫)
有趣的是,好幾個資訊小組不約而同的發展出類似 boulderio 的主意。舉例來說,好幾個參予的小組蠕蟲定序計劃使用了一個資料交換格式叫做”.ace”。雖然這個格式一開始被設計用來作 ACE(一種生物資料用的數據庫)數據庫的資料傾印以及重復載入格式,可是它用了一個標簽/值格式與 boulderio 很像。很快的,.ace檔案被用 Perl 程序導管所處理,并且在最後一個步驟載入數據庫。
Perlll 實驗室管理的其他部分也找到用途。舉個例子,許多中心,包括我的,使用以網頁為基礎的介面來顯示專案狀態,并且讓研究者采取行動。Perl 文稿語言是寫作網頁 CGI 引擎的完美語言。同樣的,Perl 執行郵件數據庫查詢服務器,管理定期的工作,準備每天晚上的實驗室活動總結報告,建立控制機器人的指令檔案,以其操作幾乎每個忙碌的基因實驗室都會需要的資訊管理工作。
就實驗室管理來看,資訊核心小組合理的成功了。就發展與散布性的一般用途,事情就沒有這麼樂觀了。
這些問題與那些參與一個大型,松散的組織軟件專案的人的問題將會很相似。盡管盡了最大的力,專案仍開始飄移。程序員進行那些令他們感興趣的想法,需要互相溝通介面的模組被獨立的設計,而且同樣的問題被以不同的,不能相同的方法解決了好幾次。當需要將所有部分放在一起的時刻來臨,沒有一個能夠正常運作。這些情形也發生在基因計劃上面。盡管事實是所有人都在同一個專案中工作,沒有兩個小組采用同樣的解法。用來解決已知問題的程序被寫了又寫好幾次。當不能保證一段程序片段工作的比其他地方發展出來的類似程序好的時候,你只能指望夸耀它特殊的使用者介面以及資料格式。一個典型的例子是重組數以千計的短 DNA reads 成為一個排序過的重疊片段的集合用的核心演算法,至少有六種不同版本在各地被使用,而且沒有任何兩個有相同的資料輸入或輸出格式。
這種缺乏交換性表現出基因中心的嚴重的困境。沒有可交換性,一個資訊小組被鎖住只能用他們自家發展的軟件。如果其他基因中心做出更好的工具軟件來解決同樣的問題,前者必須重新更患他們的系統來使用這個新工具。
這個問題長遠的解法是提出每個基因軟件都該遵循的制式化的資料交換標準。這也讓公用的模組可以輕易的被裝入或卸下。然而,這樣的標準需要時間使大家都認可,而當不同的小組間參與討論與協商的時候,仍然有緊急的需求要用既有的工具來完成當下的任務。
這時候再度用到了 Perl 并且達成了緊急救援。劍橋高級會議引述這篇文章并且請求商業資料交換的問題。盡管事實上這兩個小組的關系是親密的合作者,而且粗淺的來看,似乎用同樣的工具來解決同樣的問題,但是再接近一點觀察後可以發現他們做的事情沒有一件是一樣的。
在 DNA 定序專案中主要的軟件元件有: 一個追蹤編輯器,用來分析,顯示小片段的來自DNA定序機器的 DNA reads 色層。 一個 read 組譯器,找出 reads 之間重復的部分并且重組他們成為連續的區間。 一個組譯器編輯器,觀看組譯器的結果并且在發現組譯錯誤的時候能改變內容。 一個能夠追蹤以上一切的數據庫。
經過數年時間,這兩個小組已經分別開發出在他們手上可以順利工作的套件。照著類似的基因中心模式,有些元件是自己發展而有些是從外面引進的。如圖二所示, Perl 用來當作膠水,把這些軟件片段組合在一起。在每對交互作用的模組之間,是一個或多個 Perl 文稿負責將某個元件的輸出調整成另一個模組預期的樣子。然而,當需要交換資料的時候來臨,這兩個小組遇到了困難。在他們兩組之間,有兩種追蹤編程器,三種組譯器,兩種組譯器編輯器以及(感謝上帝)一種數據庫。如果兩個元件之間需要兩個 Perl 文稿的話(一個方向一個),會需要 62 個不同的文稿來滿足所有可能的互相交換的工作。每次當其中一個模組的輸出或輸入格式改變,將要更動檢查和修正 14 個文稿。
在這個會議中得的結論在圖三。這兩個小組決定采用一個共圖的資料交換格式,叫做 CAF。CAF 將會包含雙方的分析與編輯工具的的交集。對每個模組,有兩個模組分別將 CAF 轉換成該模組的資料格式,以及將其格式轉換成 CAF。這簡化了寫程序以及維護的工作?,F在只需要寫 16 個文稿了;當其中一個模組改變了,只有兩個模組需要跟著被檢查。
這個事件并非獨一無二的。Perl 已經變成基因中心的解決方案,當他們需要資料交換的時候,或是翻新某中心的模組來跟其他中心的一起工作的時候。
因此 Perl 已然成為基因中心之間計算的主要軟件,就好像膠水將它們連結在一起。雖然基因資訊小組總是在思考有沒有其他高階語言,例如 Python,Tcl 還有最近的 Java,卻沒有能像 Perl 這樣普及的。Perl 如何達成了這樣的非凡成就?
我想有以下幾個因素: Perl 非常擅長於切割,扭轉,絞,弄平,總結,以及其他的操作文字文件。雖然生物科學開始采用數用分析,然而大部分的資料仍然是文字文件:繁殖名稱,注解,評住,目錄查閱。甚至DNA序列也是類文字的?;ハ嘟粨Q不相容的資料格式是在文字文件上用創造性的猜測來處理的議題。Perl強大的正規表示式(regular expression)比對以及字串操作使這個工作變得簡單而沒有其他語言能相比。 Perl 能容錯。生物資料通常是不完全的,欄位可以被忽略,或是某個欄位被預期要出現好幾次(舉例來說,一個實驗可能被重復的操作),或是資料以手動輸入所以有錯誤。 Perl并不介意某個值是空的或是有奇怪的字元。正規表示式能夠被寫成取出并且更正錯誤的一般錯誤。當然這種彈性也可能是各壞處。我將會在之後提後。 Perl 是元件導向的。Perl 鼓勵人們將他們的軟件寫成小模組,不問適用 Perl 函式庫模組或是正統的 Unix 工具導向的方式。外部程序能夠輕易的被整合進 Perl 程序,靠著管道(pipe),系統呼叫,或是插座(socket)。Perl5 引進的動態載入器允許人們使用 C 的函式,或者讓整個編程過的函式庫,被使用在 Perl 直譯器中。最近的成果是世界各地的智慧結晶都會收錄在一組模組里面,稱為”bioPerl”(請參考 Perl Journal) Perl 很容易去寫并且能很快開發完。直譯器讓你不需要宣告你所有的函數型式以及資料型態,當未定義的函式被呼叫時只會引起一個錯誤,除錯器也能與Emacs很好的合作并且讓你能用令人舒服的交談式的開發模式。 Perl 是良好的原型語言。因為它快而且臟(quick and dirty),用 Perl 建構新演算的原型比直接寫成一個快的需要編程過的語言來的有意義。有時候發現結果是Perl已經夠快了,所以程序變不需要移植;更多情形是某人可以用C寫一個小的核心程序,編程成動態載入的模組或是外部的可執行程序,然後其他的部分用Perl來完成。這部分的例子可以參考 http://waldo.wi.mit.edu/ftp/distribution/software/rhmapper/)。 Perl 在寫作網頁 CGI 方面非常優秀,而且重要性隨著各實驗將資料發表在網絡上之後更是增加。我在基因中心環境下使用 Perl 的經驗從頭到尾都是值得稱贊的。然而我發現 Perl 也有它的問題。它的松散的程序風格導致許多錯誤,這些在其他嚴格的語言都會被抓到。舉例來說,Perl 讓你在一個變數在被指定值之前就能使用,這是個很有用的特性當你需要的時候,但是卻是一個災難當你單純的打錯了辨識名稱。同樣的,很容易忘記要宣告一個函式里面的區域變數,導致不小心地改到了全域變數。
最後,Perl 的不足之處在於建立圖形化的使用者介面。雖然 Unix 忠實信徒所有事情都能在命令模式下完成,大多數的終端使用者卻不同意。視窗,選單,彈跳的圖案已經變成了必要的時尚。
直到最近,Perl 的使用者界面(GUI)發展仍是不成熟的。然而 Nick Ing-Simmons 的努力使得 perlTK(pTK) 的整合使得以 Perl 驅動的使用者介面在 X-window 上面成為可能。我的夥伴和我曾經在 MIT 基因中心寫過幾個 pTK 為基礎的應用程序供互連網使用者,而且從頭到尾都是一個令人滿意的經驗。其他的基因中心則更大規模的使用 pTK,在某些地方已經成為主要的生產力。
不幸的,我很難過的坦承,幾個月以前當我需要將一個我寫的 C++ 的圖形分析系統放上去,我使用了標準的 Tcl/Tk 函式庫而不是 pTK。我做了這個決定因為我希望這個應用程序能廣泛流傳。我發現 pTK 在輸入方面仍然太不穩定:一個 pTK 的新發行版本發現 lurking 的問題。更進一步,我發現即使是經驗豐富的系統管理者編程及安裝 Perl 模組的時候也會遇到問題,而我擔心在安裝 pTK 或是我的應用程序所需要的 Perl 模組的時候遇到大問題,而就此放棄。相反的,許多系統擁有 Tcl/TK 函式庫;即使沒有,安裝也是快又無痛的。
總之,當基因計劃奠基在一片不相容的資料格式的海洋,快速變化的科技,以及龐大的,在發布當天就已時的資料分析程序上時。Perl 拯救了這一切。雖然它并不完美。 Perl 似乎明顯的滿足了許多基因中心需要,而且經常是當我們遇到問題時第一個想到的工具。