Snakemake с 3 различными программами, 2 директориями ввода и одним предопределенным файлом .txt с желаемыми выходами

#snakemake

#змеиный пирог

Вопрос:

Это будет немного сложный вопрос, но смерть в главной роли санкемаке доку до сих пор не дала желаемого результата, и я надеюсь, что кто-то более опытный сможет меня провести.

Позвольте мне описать, что у меня есть:

1: Три программы в оболочке, которые выполняются следующим образом:

 ./program_1 $(cat file/from/dir_1/foo.fa) $(cat file/from/dir_2/bar.fa) gt; output.txt ./program_2 $(cat file/from/dir_1/foo.fa) $(cat file/from/dir_2/bar.fa) gt; output.txt ./program_3 $(cat file/from/dir_1/foo.fa) $(cat file/from/dir_2/bar.fa) gt; output.txt  

Да, кошка необходима, они используют строки из файлов, а не сами файлы.


2: Два каталога, которые выглядят примерно так:

 hsa-let-7f-5p.fa hsa-let-7g-5p.fa hsa-miR-100-3p.fa hsa-miR-100-5p.fa hsa-miR-101-2-5p.fa  

…(подробнее)

 NM_000044.fa NM_000059.fa NM_000075.fa NM_000088.fa NM_000103.fa  

…(подробнее)


3: Файл .txt со всеми желаемыми комбинациями вывода:

 hsa-miR-29b-3p__NM_138473_programm_1.txt hsa-miR-29b-3p__NM_138473_programm_2.txt hsa-miR-29b-3p__NM_138473_programm_3.txt hsa-miR-545-3p__NM_002332_programm_1.txt hsa-miR-545-3p__NM_002332_programm_2.txt hsa-miR-545-3p__NM_002332_programm_3.txt  

…(подробнее)


Не все файлы из двух каталогов используются, некоторые используются несколько раз, я не хочу, чтобы вся комбинация, только один раз указывалась. Выходные файлы должны быть отдельными и иметь имена в соответствии с указанным выше .txt. Окончательный файл sankefile должен хорошо распараллеливаться в кластере.


Рабочий процесс довольно прост на словах:

1.Прочитайте имена выходных файлов.
2.Извлеките необходимые входные данные для комбинаций из обоих каталогов.
3.Запустите их во всех 3 программах и выведите предварительно определенный txt. путем передачи stdout программы в файл.

Done


But well … how to tell that to Snakemake? I was told this is conveniently possible but not luck so far. If there are question pls ask. Thank You in Advance (:



I adjusted the code below to my best knowledge for the situation. I’m reading out from the file now, the «programs» on top and «dirs» in «rule one» have their full paths. I also switched the two inputs in the shell command because I was confused, and they go this way. Yea, I know the file names are suboptimal.

 out = [] f = open("snakemake_output_small.txt", "r") for line in f:  out.append(line.replace('n', ''))   # Get distinct filenames hsa = set([x.split('__')[0] for x in out]) nm = [x.split('__')[1] for x in out] nm = set([re.sub('_program_.*', '', x) for x in nm]) program = ['full/path/to/program_1', 'full/path/to/program_2', 'full/path/to/program_3']  # Force snakemake to use exactly these wildcard values # i.e. do not match by regex wildcard_constraints:  hsa= '|'.join([re.escape(x) for x in hsa]),  nm= '|'.join([re.escape(x) for x in nm]),  program= '|'.join([re.escape(x) for x in program]),   rule all:  input:  out,   rule one:  input:  hsa= 'full/path/to/dir1/{hsa}.fa',  nm= 'full/path/to/dir2/{nm}.fa',  output:  '{hsa}__{nm}_{program}.txt',  shell:  r"""  {wildcards.program} {input.nm} {input.hsa} gt; {output}  """  

Now it is telling me:

 Building DAG of jobs... MissingInputException in line 21 of Snakefile: Missing input files for rule all: hsa-miR-545-3p__NM_002332_program_3.txt hsa-miR-29b-3p__NM_138473_program_1.txt hsa-miR-29b-3p__NM_138473_program_1.txt hsa-miR-545-3p__NM_002332_program_2.txt hsa-miR-29b-3p__NM_138473_program_3.txt hsa-miR-545-3p__NM_002332_program_2.txt  

Это 100% ошибка пользователя, но чего мне не хватает. Ввод dir верен, если я не совсем слеп.


Я также забыл упомянуть, что у двух программ есть свои собственные параметры, которые необходимо включить. A -d для программы 2. и a-P здесь/a/параметр/файл для программы 3. поэтому команды оболочки, возможно, потребуется разделить. Сри, все это очень грязно.

Как и раньше, если есть вопросы, пожалуйста, задавайте .

Ответ №1:

Я бы предпочел поместить имена выходных файлов с комбинациями входных данных и программ в файл csv, прочитать его с помощью pandas и использовать фрейм данных для управления рабочим процессом. Здесь вместо этого я анализирую имена выходных файлов, чтобы извлечь соответствующие входные данные, что, на мой взгляд, неясно.

Для размещения параметров, передаваемых каждой программе, используйте словарь или, лучше, файл конфигурации yaml и запросите этот словарь с помощью program подстановочного знака:

 # Read this list from file: out= ['hsa-miR-29b-3p__NM_138473_program_1.txt',  'hsa-miR-29b-3p__NM_138473_program_2.txt',  'hsa-miR-29b-3p__NM_138473_program_3.txt',  'hsa-miR-545-3p__NM_002332_program_1.txt',  'hsa-miR-545-3p__NM_002332_program_2.txt',  'hsa-miR-545-3p__NM_002332_program_3.txt']  hsa = set([x.split('__')[0] for x in out]) nm = [x.split('__')[1] for x in out] nm = set([re.sub('_program_.*', '', x) for x in nm])  # Better to put this in a yaml file and read it with `--configfile progs.yaml` programs = {'program_1':   {'path': '/path/to/program_1', 'opts': '-d foo -P bar'},   'program_2':   {'path': '/path/to/program_2', 'opts': '-P spam eggs'},   'program_3':   {'path': '/path/to/program_3', 'opts': ''}  }  wildcard_constraints:  hsa= '|'.join([re.escape(x) for x in hsa]),  nm= '|'.join([re.escape(x) for x in nm]),  program= '|'.join([re.escape(x) for x in programs.keys()]),   rule all:  input:  out,   rule one:  input:  hsa= 'dir1/{hsa}.fa',  nm= 'dir2/{nm}.fa',  output:  '{hsa}__{nm}_{program}.txt',  params:  path= lambda wc: programs[wc.program]['path'],  opts= lambda wc: programs[wc.program]['opts'],  shell:  r"""  {params.path} {params.opts} {input.hsa} {input.nm} gt; {output}  """  

Комментарии:

1. попробую сегодня и напишу ответ, тх уже

2. я попробовал и, к сожалению, столкнулся с некоторыми проблемами на данный момент

3. @Aux Я отредактировал свой ответ, чтобы решить проблемы, о которых вы упомянули.

4. джо тх, к настоящему времени я нашел обходной путь, который справляется с этой задачей, но я обязательно попробую это, потому что это намного элегантнее, следовало бы подумать об этом раньше