2021-11-26

# -*- coding: utf-8 -*-

# callCodeML

# Verson: 2.0

# Date: 2021.11.15

# This is used to call Codeml to calculate the positive selection of gene in Branch-Sites Model.(Require codon sequence)

# Usage: python3 callCodeml.py seqDir treeFile

# Refactoring code and running logic to support multiprocess

import re

import sys

import os

from scipy.stats import chi2

import time

def help_info():

    print("This script is used to call codeML.\nUsage: python3 callCodeml.py Dir treeFile\n")

def getArgs():

    global workDir

    global tree_file

    global dir_path


    start_time = time.strftime('%Y%m%d-%H%M%S') # to keep the working dircitory name

    workDir = f"{os.getcwd()}/WorkingDir_{start_time}"

    args = sys.argv[1:]

    if len(args) == 0:

        help_info()

    if os.path.isdir(args[0]) is True:

        dir_path = os.path.abspath(args[0])  # path of seqences

        seqs = os.listdir(dir_path)

        seqs = [x for x in seqs if not str(x).startswith('.') ] # remove hided files

        tree_file = os.path.abspath(args[1])

        print(f"The drictory is: {dir_path}\nThe treeFile is: {tree_file}")

        #os.chdir(os.path.abspath(args[0]))

        return (dir_path, seqs, tree_file)

    else:

        help_info()

def create_dir(name):

    try:

        os.mkdir(f'{workDir}/')

    except:pass

    try:

        os.mkdir(f'{workDir}/{name}')

    except:pass

    try:

        os.mkdir(f'{workDir}/{name}/null')

        os.mkdir(f'{workDir}/{name}/alte')

    except:pass

def creat_ctl(name, tree_file):


    ctl_null = f'''

    seqfile = {dir_path}/{name}

    treefile = {tree_file}

    outfile = {workDir}/{name}/null/{name}_null.res

    noisy = 9 

    verbose = 0 

    runmode = 0 

    seqtype = 1 

    CodonFreq = 2 

    clock = 0 

    aaDist = 0

    model = 0

    NSsites = 0 

    icode = 0 

    Mgene = 0

    fix_kappa = 0 

    kappa = 2 

    fix_omega = 0 

    omega = 1 

    fix_alpha = 1 

    alpha = .0 

    Malpha = 0 

    ncatG = 3 

    getSE = 0 

    RateAncestor = 0 

    fix_blength = 0 

    method = 0 

    Small_Diff = .45e-6

    cleandata = 1

    '''

    ctl_alte = ctl_null.replace(f'{workDir}/{name}/null/{name}_null.res',  f'{workDir}/{name}/alte/{name}_alte.res')\

        .replace('model = 0', 'model = 2')


    with open(f'{workDir}/{name}/null/null_profile.ctl', 'w') as f:

        f.write(ctl_null)


    with open(f'{workDir}/{name}/alte/alte_profile.ctl', 'w') as f:

        f.write(ctl_alte)

def run_create(dir_path, seqs, tree_file):


    for i in (seqs):


        name= i.split('/')[-1]

        create_dir(name)

        creat_ctl(name, tree_file)


    with open(f'{workDir}/codeml.sh', 'w') as f:

        f.write('''

#!/bin/bash

list=`ls -1 |grep OG`

count=`ls -1 |grep OG|wc|awk '{print $1}'`

echo "Total number: $count"

dir=`pwd`

echo "Start Now..."

for i in $list

do

    {

    cd $dir/$i/null

    codeml ./null_profile.ctl  >log.txt

    cd $dir/$i/alte

    codeml ./alte_profile.ctl  >log.txt

    #echo "Finished $i..."

    }&

done

wait

''')


    print(f"{time.strftime('%Y-%m-%d %H:%M:%S')} Files created.\n")



def run_codeml():

    os.chdir(workDir)

    os.system('bash codeml.sh')

    print(f"\n{time.strftime('%Y-%m-%d %H:%M:%S')} Codeml Done...\n")

def run_stat(name):

    def get_res(path):

        with open(path, "r") as f:

            t =  f.read()

            kappa = re.findall(r"kappa.+", t)[0].split(' ')[-1].replace('\n', '')

            ls = re.findall(r'lnL.+', t)[0].split(' ')

            ls=[x for x in ls if x!='']

            lnL = ls[4]

            np = ls[3].replace("):","")

            return([lnL, np, kappa])

    path1 = f'{workDir}/{name}/alte/{name}_alte.res'

    path2 = f'{workDir}/{name}/null/{name}_null.res'


    try:

        res_alte = get_res(path1)

        res_null = get_res(path2)


        lnL0 = float(res_null[0])

        lnL1 = float(res_alte[0])

        np0 = int(res_null[1])

        np1 = int(res_alte[1])

        kappa = float(res_alte[2])

        lnl = abs(lnL0 - lnL1 )*2

        np = abs(np0 - np1)

        pvalue = 1 - chi2.cdf(lnl, np)

        #if pvalue <= 0.05:

        with open(f'{workDir}/result.tsv', 'a') as f:

            f.write(f"{name}\t{lnL0}\t{lnL1}\t{np0}\t{np1}\t{kappa}\t{pvalue}\n")

    except:

        print(f"{time.strftime('%Y-%m-%d %H:%M:%S')}  {name} failed to stats.")

def main(): 


    arges = getArgs()

    run_create(arges[0], arges[1], arges[2])

    run_codeml()

    for i in  os.listdir(workDir):

        run_stat(i)

if __name__ == "__main__":

    t0 = time.time()


    main()


    print(f'Total time used: {time.time() - t0} S\n')

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,635评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,628评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,971评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,986评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,006评论 6 394
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,784评论 1 307
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,475评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,364评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,860评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,008评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,152评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,829评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,490评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,035评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,156评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,428评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,127评论 2 356

推荐阅读更多精彩内容

  • 作者:plutoese 链接:https://www.jianshu.com/p/d8578362245a Pyt...
    Golonger阅读 4,592评论 0 3
  • 查看路径: open3d open3d的功能查看“print(dir(o3d))
    bibivivien阅读 149评论 0 0
  • Clinical Can Res | 新抗原特异性TCR转基因细胞疗法治疗小鼠神经胶质瘤 原创图灵基因图灵基因今天...
    图灵基因阅读 166评论 0 0
  • Cancer Cell丨非小细胞肺癌单细胞分析细化了肿瘤分类和患者分层 原创珍奇图灵基因今天 收录于话题#前沿分子...
    图灵基因阅读 419评论 0 0
  • Docker安装与使用 一、docker安装。 1、安装要求: 1)docker要求服务CentOS6以上,ker...
    卬之别录阅读 1,949评论 0 1