Replies: 4 comments 3 replies
-
I like this idea. Curious to see how BidsInput would be structured, would it be based off something that already exists? |
Beta Was this translation helpful? Give feedback.
-
yep that all makes sense to me! |
Beta Was this translation helpful? Give feedback.
-
I'm fully on board for transitioning the output of I like the idea in principle of providing a shorthand for the long |
Beta Was this translation helpful? Give feedback.
-
This sounds good to me - like the idea of transitioning to a class. |
Beta Was this translation helpful? Give feedback.
-
A while back, we discussed how the current attributes available on the dict returned by
generate_inputs()
are somewhat confusing, especially"input_lists"
and"input_zip_lists"
. The challenge with"input_lists"
is that when you use it withexpand()
, it will expand to all possible combinations of bids attributes, some of which may not exist. The fastest work-around if this attribute must be used is probably to filter theexpand()
list withPath.exists()
.On the other hand,
input_zip_lists
will always return files that do exist, but for it to work correctly, users must callexpand()
asexpand("/path/to/{wildcard}", zip, generate_inputs(...)["input_zip_lists"])
. Thezip
is necessary to change the default behaviour ofexpand
away fromproduct
.I would propose two things to remedy this. First, add a function to the return of
generate_inputs()
calledexpand()
or something similar that takes one positional argument: the path to be expanded. It will call thesnakemake.io.expand()
function usingzip
and all of the bids parameters originally passed togenerate_inputs()
. It will also have a**kwargs
intended for any additional arguments. In this case, twoexpands()
will be performed, the first usingzip
and the bids parameters, the second usingproduct
and the**kwargs
. Something like:Optionally, we could also allow the user to specify
**kwargs
that were already passed togenerate_inputs()
as bids parameters. These would be used to filter the bids parameters. However, this feature would be inherently messy, and my personal preference would be for users to use the filter capabilities withingenerate_inputs()
.Second, in order to simplify the use and documentation of the
generate_inputs()
return, I suggest transitioning it from aDict
to a class calledBidsInputs
. This transition would need to be gradual to prevent breaking changes. First, add a keyword arg togenerate_inputs()
calleduse_dict
that defaults toNone
. IfFalse
,generate_inputs()
will return theBidsInputs
class instead of theDict
. IfTrue
, aDict
will be used as before. If left asNone
, we will initially treat it asTrue
to prevent breaking changes, but a deprecation warning will print saying that in a few versions,use_dict
will default toFalse
. (Note that if we useattrs
to define the class, we can useattr.asdict
to get aDict
for free, so it won't be a lot of extra logic to maintain both).One last point as a corollary to the above suggestion: switching to a
class
over aDict
would preventupdate()
ing theconfig
withgenerate_inputs()
, as currently recommended by the tutorial. However, I would suggest that recommendation should be phased out anyway, as it needlessly obfuscates thegenerate_inputs()
return value . If an unaccustomed user seesconfig["input_lists"]
in theSnakefile
, they might assume"input_lists"
is a variable defined inconfig.yaml
and become mystified when they fail to find it.config.update(generate_inputs(...))
secretly adds all those values to the config, and the only way to find out what values it adds is by reading the Snakebids documentation. In my own code, I store thegenerate_inputs()
in a variable calledinputs
, and I'd suggest this as a clearer standard.Beta Was this translation helpful? Give feedback.
All reactions