0

我有一个现有的snakemake RNAseq 工作流程,它可以与如下目录树一起正常工作。我需要更改工作流程,以便它可以容纳另一层目录。目前,我使用 os.walks 父目录并为示例通配符创建一个 json 文件的 python 脚本(示例通配符的 json 文件也包括在下面)。我对 python 不是很熟悉,在我看来,为额外的目录层调整代码应该不会太困难,希望有人能善意地指出我正确的方向。

RNAseqTutorial/
├── Sample_70160
│   ├── 70160_ATTACTCG-TATAGCCT_S1_L001_R1_001.fastq.gz
│   └── 70160_ATTACTCG-TATAGCCT_S1_L001_R2_001.fastq.gz
├── Sample_70161
│   ├── 70161_TCCGGAGA-ATAGAGGC_S2_L001_R1_001.fastq.gz
│   └── 70161_TCCGGAGA-ATAGAGGC_S2_L001_R2_001.fastq.gz
├── Sample_70162
│   ├── 70162_CGCTCATT-ATAGAGGC_S3_L001_R1_001.fastq.gz
│   └── 70162_CGCTCATT-ATAGAGGC_S3_L001_R2_001.fastq.gz
├── Sample_70166
│   ├── 70166_CTGAAGCT-ATAGAGGC_S7_L001_R1_001.fastq.gz
│   └── 70166_CTGAAGCT-ATAGAGGC_S7_L001_R2_001.fastq.gz
├── scripts
├── groups.txt
└── Snakefile
{
    "Sample_70162": {
        "R1": [ "/gpfs/accounts/SlurmMiKTMC/Sample_70162/Sample_70162.R1.fq.gz"
        ],
        "R2": [  "/gpfs/accounts//SlurmMiKTMC/Sample_70162/Sample_70162.R2.fq.gz"
        ]
    },
{
    "Sample_70162": {
        "R1": [          "/gpfs/accounts/SlurmMiKTMC/Sample_70162/Sample_70162.R1.fq.gz"
        ],
        "R2": [     "/gpfs/accounts/SlurmMiKTMC/Sample_70162/Sample_70162.R2.fq.gz"
        ]
    }
}

我需要适应的结构如下

RNAseqTutorial/
├── part1
│   ├── 030-150-G
│   │   ├── 030-150-GR1_clipped.fastq.gz
│   │   └── 030-150-GR2_clipped.fastq.gz
│   ├── 030-151-G
│   │   ├── 030-151-GR1_clipped.fastq.gz
│   │   └── 030-151-GR2_clipped.fastq.gz
│   ├── 100T
│   │   ├── 100TR1_clipped.fastq.gz
│   │   └── 100TR2_clipped.fastq.gz
├── part2
│   ├── 030-025G
│   │   ├── 030-025GR1_clipped.fastq.gz
│   │   └── 030-025GR2_clipped.fastq.gz
│   ├── 030-131G
│   │   ├── 030-131GR1_clipped.fastq.gz
│   │   └── 030-131GR2_clipped.fastq.gz
│   ├── 030-138G
│   │   ├── 030-138R1_clipped.fastq.gz
│   │   └── 030-138R2_clipped.fastq.gz
├── part3
│   ├── 030-103G
│   │   ├── 030-103GR1_clipped.fastq.gz
│   │   └── 030-103GR2_clipped.fastq.gz
│   ├── 114T
│   │   ├── 114TR1_clipped.fastq.gz
│   │   └── 114TR2_clipped.fastq.gz
├── scripts
├── groups.txt
└── Snakefile

为示例通配符生成 json 文件的主脚本如下

    for root, dirs, files in os.walk(args):
        for file in files:
            if file.endswith("fq.gz"):
                full_path = join(root, file)
                #R1 will be forward reads, R2 will be reverse reads
                m = re.search(r"(.+).(R[12]).fq.gz", file)
                if m:
                    sample = m.group(1)
                    reads = m.group(2)  
                    FILES[sample][reads].append(full_path)

我似乎无法想出一种方法来容纳那个额外的层。除了 os.walk,还有其他模块或功能吗?我可以以某种方式强制 os.walk 跳过目录并合并部分和示例前缀吗?任何的意见都将会有帮助!

编辑添加:我不清楚描述我的问题,并注意到第二个示例不能代表问题,我相应地修复了示例,因为第二个树取自其他人处理的目录。我得到的数据有两种形式,一种是仅一种组织的样本,其中目录由 WD、采样文件夹和 fastq 文件组成,其中 fastq 文件与它们所在的样本文件夹具有相同的前缀。第二个示例是来自两个组织的样本。这些组织必须彼此分开处理。但是两种类型的组织都可以在单独的“部分”中找到,但是来自不同“部分”的相同类型的组织必须一起处理。如果我能让 os.walk 返回四个元组,甚至使用

root,dirs,files*=os.walk('Somedirectory')

其中 * 会将目录字符串的其余部分附加到 files 变量。不幸的是,此方法不会转到第三个子目录“root/part/sample/fastq”的文件级别。在理想情况下,相同的蛇形管道将能够在用户输入最少的情况下处理这两种情况。我知道这可能是不可能的,但我想我会问,看看是否有一个模块可以返回每个示例目录字符串的所有部分。

4

2 回答 2

0

在我看来,您的问题与如何容纳第二层没有太大关系。相反,问题在于您期望的目录树和文件名的规范。

在第一种情况下,您似乎可以从文件名的第一部分提取样本名称。在第二种情况下,文件名都相同,示例名称来自父目录。所以,要么你实现一些逻辑来告诉你正在解析哪个命名方案(这取决于谁/什么提供文件),或者你总是从父目录中提取示例名称,因为这也适用于第一种情况(但同样,假设您可以依赖这样的命名方案)。

如果你想选择第二个选项,应该这样做:

FILES = {}
for root, dirs, files in os.walk('RNAseqTutorial'):
    for file in files:
        if file.endswith("fastq.gz"):
            sample = os.path.basename(root)
            full_path = os.path.join(root, file)
            if sample not in FILES:
                FILES[sample]= {}
            if 'R1' in file:
                reads = 'R1'
            elif 'R2' in file:
                reads = 'R2'
            else:
                raise Exception('Unexpected file name')
            if reads not in FILES[sample]:
                FILES[sample][reads] = []
            FILES[sample][reads].append(full_path)
于 2019-10-16T13:46:48.443 回答
0

不知道我是否理解正确,但你去:

for root, dirs, files in os.walk(args):
    for file in files:
        if file.endswith("fq.gz"):
            full_path = join(root, file)
            reads = 'R1' if 'R1' in file else 'R2'
            sample = root.split('/')[-1]
            FILES[sample][reads].append(full_path)
于 2019-10-16T13:47:14.867 回答