Snakemake 입력을 선택 사항이지만 비어 있지 않게 만드는 방법은 무엇입니까?

Dec 10 2020

텍스트 데이터로 SQL 스크립트를 작성하고 있습니다. (일부) 스크립트는 CREATE TABLE문장과 선택적 INSERT INTO문장으로 구성되어야 합니다. INSERT INTOstatement에 대한 값 은 파일 목록에서 가져 오며 각 파일이 존재하거나 존재하지 않을 수 있습니다. 기존 파일의 모든 값이 병합됩니다. 중요한 부분은 INSERT INTO데이터 파일이 하나도 없을 때마다 명령문을 건너 뛰어야한다는 것입니다.

Snakemake에서 그렇게하는 스크립트를 만들었습니다. 스크립트를 생성하는 두 가지 모호한 규칙이 있습니다. 하나는 빈 데이터에 대한 스크립트를 생성하는 것이고 다른 하나는 테이블을 생성하지만 데이터를 삽입하는 것입니다 (모호성은 ruleorder문 으로 해결됩니다 ).

흥미로운 부분은 데이터 파일의 값을 병합하는 규칙입니다. 적어도 하나의 입력이있을 때마다 출력을 생성해야하며이 규칙은 달리 고려되지 않습니다. 두 가지 어려움이 있습니다. 각 입력을 선택적으로 만들고 파일이 없을 때마다이 규칙을 사용하여 Snakemake를 방지하는 것입니다. 나는 속임수로 그것을했다.

def require_at_least_one(filelist):
    existing = [file for file in filelist if os.path.isfile(file)]
    return existing if len(existing) else "non_existing_file"

rule merge_values:
    input: require_at_least_one(expand("path_to_data/{dataset}/values", dataset=["A", "B", "C"]))
    output: ...
    shell: ...

require_at_least_one함수는 파일 이름 목록을 가져 와서 파일을 나타내지 않는 파일 이름을 필터링합니다. 이를 통해 각 입력을 선택 사항으로 만들 수 있습니다. 파일이 하나도없는 경우에이 함수는 존재하지 않는 파일을 나타내는 특수 값을 반환합니다. 이를 통해이 분기를 정리하고 INSERT명령문 없이 스크립트를 생성하는 분기를 선호 할 수 있습니다 .

나는 바퀴를 재발 명하고 싶다고 느낀다. 게다가 "non_existing_file"트릭은 약간 더러워 보인다. Snakemake에서 더 좋고 관용적 인 방법이 있습니까?

답변

silence Feb 11 2021 at 16:24

내 솔루션은 snakemake가 규칙 내에서 규칙을 사용하거나 사용하지 않도록 강요해서는 안되지만 필요한 출력을 지정하면 snakemake가 규칙을 사용 해야하는지 결정할 것입니다. 따라서 귀하의 예를 들어 다음과 같이 할 것입니다.

def required_files(filelist):
    return [file for file in filelist if os.path.isfile(file)]

rule what_to_gen:
    input: 
        merged = [] if required_files(expand("path_to_data/{dataset}/values", dataset=["A", "B", "C"])) else 'merged_files.txt'

rule merge_values:
    input: required_files(expand("path_to_data/{dataset}/values", dataset=["A", "B", "C"]))
    output: 'merged_files.txt'
    shell: ...

이는 required_files가 비어 있지 않은 경우에만 merge_values ​​규칙을 실행합니다.