Data structures 改变snakemake工作流以预测和适应不同的数据结构

Data structures 改变snakemake工作流以预测和适应不同的数据结构,data-structures,snakemake,directory-tree,Data Structures,Snakemake,Directory Tree,我有一个现有的snakemake RNAseq工作流,它可以很好地处理目录树,如下所示。我需要改变工作流程,以便它可以容纳另一层目录。目前,我使用一个python脚本,os.0遍历父目录并为示例通配符创建一个json文件(下面还包括示例widlcards的json文件)。我对python不是很熟悉,而且在我看来,为额外的一层目录修改代码应该不会太困难,希望有人能给我指出正确的方向 rnaseq教程/ ├── 样本_70160 │ ├── 70160_附件CG-TATAGCT_S1_L001_

我有一个现有的snakemake RNAseq工作流,它可以很好地处理目录树,如下所示。我需要改变工作流程,以便它可以容纳另一层目录。目前,我使用一个python脚本,os.0遍历父目录并为示例通配符创建一个json文件(下面还包括示例widlcards的json文件)。我对python不是很熟悉,而且在我看来,为额外的一层目录修改代码应该不会太困难,希望有人能给我指出正确的方向

rnaseq教程/
├── 样本_70160
│   ├── 70160_附件CG-TATAGCT_S1_L001_R1_001.fastq.gz
│   └── 70160_附件CG-TATAGCT_S1_L001_R2_001.fastq.gz
├── 样本_70161
│   ├── 70161_TCCGGAGA-ATAGAGGC_S2_L001_R1_001.fastq.gz
│   └── 70161_TCCGGAGA-ATAGAGGC_S2_L001_R2_001.fastq.gz
├── 样本_70162
│   ├── 70162_CGCTCATT-ATAGAGGC_S3_L001_R1_001.fastq.gz
│   └── 70162_CGCTCATT-ATAGAGGC_S3_L001_R2_001.fastq.gz
├── 样本号:70166
│   ├── 70166_CTGAAGCT-ATAGAGC_S7_L001_R1_001.fastq.gz
│   └── 70166_CTGAAGCT-ATAGAGC_S7_L001_R2_001.fastq.gz
├── 剧本
├── groups.txt
└── 蛇锉
{
“样本_70162”:{
“R1”:[“/gpfs/accounts/SlurmMiKTMC/Sample_70162/Sample_70162.R1.fq.gz”
],
“R2”:[“/gpfs/accounts//SlurmMiKTMC/Sample_70162/Sample_70162.R2.fq.gz”
]
},
{
“样本_70162”:{
“R1”:[“/gpfs/accounts/SlurmMiKTMC/Sample_70162/Sample_70162.R1.fq.gz”
],
“R2”:[“/gpfs/accounts/SlurmMiKTMC/Sample_70162/Sample_70162.R2.fq.gz”
]
}
}
我需要适应的结构如下所示

rnaseq教程/
├── 第一部分
│   ├── 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
│   ├── 100吨
│   │   ├── 100TR1_clipped.fastq.gz
│   │   └── 100TR2_clipped.fastq.gz
├── 第二部分
│   ├── 030-025G
│   │   ├── 030-025GR1_clipped.fastq.gz
│   │   └── 030-025GR2_clipped.fastq.gz
│   ├── 030-131G
│   │   ├── 030-131GR1_clipped.fastq.gz
│   │   └── 030-131GR2_剪裁快速Q.gz
│   ├── 030-138G
│   │   ├── 030-138R1_clipped.fastq.gz
│   │   └── 030-138R2_clipped.fastq.gz
├── 第三部分
│   ├── 030-103G
│   │   ├── 030-103GR1_clipped.fastq.gz
│   │   └── 030-103GR2_clipped.fastq.gz
│   ├── 114吨
│   │   ├── 114TR1_clipped.fastq.gz
│   │   └── 114TR2_clipped.fastq.gz
├── 剧本
├── groups.txt
└── 蛇锉
下面是为示例通配符生成json文件的主脚本

对于os.walk(args)中的根目录、目录和文件:
对于文件中的文件:
如果文件.endswith(“fq.gz”):
完整路径=连接(根,文件)
#R1为正向读取,R2为反向读取
m=re.search(r“(.+)(r[12]).fq.gz”,文件)
如果m:
样本=m组(1)
reads=m.group(2)
文件[sample][reads].append(完整路径)
我似乎无法集中精力来容纳那个额外的层。除了os.walk,还有其他模块或函数吗?我能强迫os.walk跳过一个目录并合并部分和示例前缀吗?任何建议都会很有帮助

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

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

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

在我看来,您的问题与如何适应第二层无关。相反,问题是关于您期望的目录树和文件名的规范

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

如果您想选择第二个选项,应该执行以下操作:

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)
不知道我是否理解
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)