Snakemake इनपुट को वैकल्पिक कैसे बनाएं लेकिन खाली नहीं?
मैं एक एसक्यूएल स्क्रिप्ट का निर्माण कर रहा हूं। स्क्रिप्ट का हिस्सा) एक CREATE TABLE
बयान और एक वैकल्पिक INSERT INTO
बयान से मिलकर बनेगा। INSERT INTO
बयान के लिए मान फाइलों की सूची से लिए गए हैं, जिनमें से प्रत्येक मौजूद हो सकता है या नहीं; मौजूदा फ़ाइलों के सभी मान मर्ज किए गए हैं। महत्वपूर्ण हिस्सा यह है कि 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
समारोह फ़ाइल नामों की एक सूची लेता है, और उन फ़ाइल नाम है कि एक फ़ाइल का प्रतिनिधित्व नहीं करते बाहर फिल्टर। यह प्रत्येक इनपुट को वैकल्पिक बनाने की अनुमति देता है। कोने के मामले में जब कोई फ़ाइल मौजूद नहीं होती है, तो यह फ़ंक्शन एक विशेष मान देता है जो गैर-मौजूदा फ़ाइल का प्रतिनिधित्व करता है। यह इस शाखा को prune करने की अनुमति देता है और उस व्यक्ति को पसंद करता है जो INSERT
बयान के बिना एक स्क्रिप्ट बनाता है ।
मुझे लगता है कि पहिया को फिर से मजबूत करना, "non_existing_file" चाल को थोड़ा गंदा लगता है। क्या Snakemake में ऐसा करने के लिए बेहतर और मुहावरेदार तरीके हैं?
जवाब
मेरा समाधान लाइनों के साथ कुछ होगा जिसे आपको नियम के अंदर एक नियम का उपयोग करने या न करने के लिए 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: ...
यह नियम मर्ज_वेल्यू को तभी निष्पादित करेगा जब आवश्यक_फाइल गैर-रिक्त हो।