text: user10588: I have a little pipeline that I want to execute using Snakemake.
  One of my rules (let's call it create_somefile) creates a file somefile_{n_dims}.json, and when running the pipeline can specify that I want to run the pipeline for a pre-defined set of values for n_dims, which is why I specified this as a wildcard.
  Now I want to have another rule, that takes as input any of these files. It can take either somefile_1.json or somefile_2.json or somefile_32402348.json, it doesn't matter which one as long as any of these exists. The rule then creates a file that does not depend on the number of dimensions, and thus doesn't want and need the n_dims in its output.
  When I try to have the wildcard only in the input, like this:
  rule do_stuff:
      input:
          "somefile_{n_dims}.json"
      output:
          "general_file.json"
      shell:
          "echo {input} &&"
          "touch {output}"
  
  Snakemake gives me the error Wildcards in input files cannot be determined from output files: n_dims.
  I don't want the output file to contain n_dims whatsoever, and unfortunately it's also impossible in snakemake to just create an additional throwaway temporary(..)-output that does depend on the n_dims just so snakemake is happy (error message then: ot all output, log and benchmark files of rule do_stuff contain the same wildcards. This is crucial though, in order to avoid that two or more jobs write to the same file..
  Is there any way in snakemake to specify a rule's inputs as "take any of these", without wildcards?
  Looking at the documentation, the only thing I found is the concept of checkpoints (https://snakemake.readthedocs.io/en/stable/snakefiles/rules.html#data-dependent-conditional-execution), however that doesn't seem to work as well - I tried making the rule create_somefile a checkpoint and changing the do_stuff rule to
  rule do_stuff:
      input:
          lambda wildcards: checkpoints.create_somefile.get(**wildcards).output
      output:
          "general_file.json",
      shell:
          "echo {input} &&"
          "touch {output}"
  
  however then I get the error WorkflowError: Missing wildcard values for n_dims.
  Is there any concept in snakemake to allow me to do what I want? To have "wildcards" in inputs, that just stand for "execute this rule as soon as the input for any value of the wildcard is fulfilled, execute only once and be done with it"?
  
  user4980: I don't think Snakemake can follow a "use any of these" pattern with a unified dependency graph and without additional assumptions, but you can do it if you break the workflow into two pieces.
  This will take whatever somefile_*.json shows up first, or throw an exception if there aren't any:
  from pathlib import Path
  
  def input_for_do_stuff(wildcards):
      try:
          return next(Path(".").glob("somefile_*.json"))
      except StopIteration as err:
          raise Exception("No n_dims JSON files found") from err
  
  rule do_stuff:
      input: input_for_do_stuff
      output:
          "general_file.json",
      shell:
          "echo {input} &&"
          "touch {output}"
  
  rule create_somefile:
      output: "somefile_{n_dims}.json"
      shell: "touch {output}"
  
  For example if you have somefile_2.json already there:
  $ snakemake -nrp
  Building DAG of jobs...
  Job stats:
  job         count    min threads    max threads
  --------  -------  -------------  -------------
  do_stuff        1              1              1
  total           1              1              1
  
  
  [Sun Oct 10 12:22:14 2021]
  rule do_stuff:
      input: somefile_2.json
      output: general_file.json
      jobid: 0
      reason: Missing output files: general_file.json
      resources: tmpdir=/tmp
  
  echo somefile_2.json &&touch general_file.json
  Job stats:
  job         count    min threads    max threads
  --------  -------  -------------  -------------
  do_stuff        1              1              1
  total           1              1              1
  
  This was a dry-run (flag -n). The order of jobs does not reflect the order of execution.
  
  With that, you'll never be able to run the workflow by just requesting the final output, which kind of breaks Snakemake's way of thinking about things.  But at least it'll work like you want if you run it in two pieces.  If having a default makes sense for your case, you could also do something like this:
  def input_for_do_stuff(wildcards):
      try:
          return next(Path(".").glob("somefile_*.json"))
      except StopIteration as err:
          return "somefile_1.json"
  
  That way, even if no files exist to start with, Snakemake can come up with a way to make the output you ask for.
  
original_text: 10588: <p>I have a little pipeline that I want to execute using Snakemake.</p>
  <p>One of my rules (let's call it <code>create_somefile</code>) creates a file <code>somefile_{n_dims}.json</code>, and when running the pipeline can specify that I want to run the pipeline for a pre-defined set of values for <code>n_dims</code>, which is why I specified this as a wildcard.</p>
  <p>Now I want to have another rule, that takes as input <strong>any of</strong> these files. It can take either <code>somefile_1.json</code> or <code>somefile_2.json</code> or <code>somefile_32402348.json</code>, it doesn't matter which one as long as any of these exists. The rule then creates a file that does not depend on the number of dimensions, and thus doesn't want and need the n_dims in its output.</p>
  <p>When I try to have the wildcard only in the input, like this:</p>
  <pre><code>rule do_stuff:
      input:
          &quot;somefile_{n_dims}.json&quot;
      output:
          &quot;general_file.json&quot;
      shell:
          &quot;echo {input} &amp;&amp;&quot;
          &quot;touch {output}&quot;
  </code></pre>
  <p>Snakemake gives me the error <code>Wildcards in input files cannot be determined from output files: n_dims</code>.
  I don't want the output file to contain <code>n_dims</code> whatsoever, and unfortunately it's also impossible in snakemake to just create an additional throwaway <code>temporary(..)</code>-output that does depend on the n_dims just so snakemake is happy (error message then: <code>ot all output, log and benchmark files of rule do_stuff contain the same wildcards. This is crucial though, in order to avoid that two or more jobs write to the same file.</code>.</p>
  <p>Is there any way in snakemake to specify a rule's inputs as &quot;take any of these&quot;, without wildcards?</p>
  <p>Looking at the documentation, the only thing I found is the concept of <code>checkpoints</code> (<a href="https://snakemake.readthedocs.io/en/stable/snakefiles/rules.html#data-dependent-conditional-execution" rel="nofollow noreferrer">https://snakemake.readthedocs.io/en/stable/snakefiles/rules.html#data-dependent-conditional-execution</a>), however that doesn't seem to work as well - I tried making the rule <code>create_somefile</code> a checkpoint and changing the <code>do_stuff</code> rule to</p>
  <pre><code>rule do_stuff:
      input:
          lambda wildcards: checkpoints.create_somefile.get(**wildcards).output
      output:
          &quot;general_file.json&quot;,
      shell:
          &quot;echo {input} &amp;&amp;&quot;
          &quot;touch {output}&quot;
  </code></pre>
  <p>however then I get the error <code>WorkflowError: Missing wildcard values for n_dims</code>.</p>
  <p>Is there any concept in snakemake to allow me to do what I want? To have &quot;wildcards&quot; in inputs, that just stand for &quot;execute this rule as soon as the input for any value of the wildcard is fulfilled, execute only once and be done with it&quot;?</p>
   4980: <p>I don't think Snakemake can follow a &quot;use any of these&quot; pattern with a unified dependency graph and without additional assumptions, but you can do it if you break the workflow into two pieces.</p>
  <p>This will take whatever <code>somefile_*.json</code> shows up first, or throw an exception if there aren't any:</p>
  <pre><code>from pathlib import Path
  
  def input_for_do_stuff(wildcards):
      try:
          return next(Path(&quot;.&quot;).glob(&quot;somefile_*.json&quot;))
      except StopIteration as err:
          raise Exception(&quot;No n_dims JSON files found&quot;) from err
  
  rule do_stuff:
      input: input_for_do_stuff
      output:
          &quot;general_file.json&quot;,
      shell:
          &quot;echo {input} &amp;&amp;&quot;
          &quot;touch {output}&quot;
  
  rule create_somefile:
      output: &quot;somefile_{n_dims}.json&quot;
      shell: &quot;touch {output}&quot;
  </code></pre>
  <p>For example if you have <code>somefile_2.json</code> already there:</p>
  <pre><code>$ snakemake -nrp
  Building DAG of jobs...
  Job stats:
  job         count    min threads    max threads
  --------  -------  -------------  -------------
  do_stuff        1              1              1
  total           1              1              1
  
  
  [Sun Oct 10 12:22:14 2021]
  rule do_stuff:
      input: somefile_2.json
      output: general_file.json
      jobid: 0
      reason: Missing output files: general_file.json
      resources: tmpdir=/tmp
  
  echo somefile_2.json &amp;&amp;touch general_file.json
  Job stats:
  job         count    min threads    max threads
  --------  -------  -------------  -------------
  do_stuff        1              1              1
  total           1              1              1
  
  This was a dry-run (flag -n). The order of jobs does not reflect the order of execution.
  </code></pre>
  <p>With that, you'll never be able to run the workflow by just requesting the final output, which kind of breaks Snakemake's way of thinking about things.  But at least it'll work like you want if you run it in two pieces.  If having a default makes sense for your case, you could also do something like this:</p>
  <pre><code>def input_for_do_stuff(wildcards):
      try:
          return next(Path(&quot;.&quot;).glob(&quot;somefile_*.json&quot;))
      except StopIteration as err:
          return &quot;somefile_1.json&quot;
  </code></pre>
  <p>That way, even if no files exist to start with, Snakemake can come up with a way to make the output you ask for.</p>
  