nextflow (groovy) check if item in Channel list - list

I am struggling to use an if/else on a containsAll() statement. It returns the correct true false value when tested with println(), but when put in an if statement it seems to always evaluate to true -- see below.
def examine_phenotype(pheno){
condition_values = \
Channel
.fromPath(pheno)
.splitCsv(header: true, sep: ',')
.map{ row ->
def condition = row.condition
return condition
}
.toList().view()
println(condition_values.containsAll('control'))
if(condition_values.containsAll('control')){
exit 1, "eval true"
}else{
exit 1, "eval false"
}
}
Console output for two different files, one with 'control' and one without 'control' in the column 'condition', which is the point of the function.
[normal, normal, normal, tumor, tumor, tumor]
DataflowInvocationExpression(value=false)
eval true
[control, control, control, tumor, tumor, tumor]
DataflowInvocationExpression(value=true)
eval true
Using collect() instead of toList() where each item within condition_values is enclosed with single quotes did not resolve the issue either. The clue might be in DataflowInvocationExpression but I am not up to speed on Groovy yet and am not sure how to proceed.

Testing the conditional within the function was not working, but applying filter{} and ifEmpty{} was able to produce the desired check:
ch_phenotype = Channel.empty()
if(pheno_path){
pheno_file = file(pheno_path)
ch_phenotype = examine_phenotype(pheno_file)
ch_phenotype.filter{ it =~/control/ }
.ifEmpty{ exit 1, "no control values in condition column"}
}
def examine_phenotype(pheno){
Channel
.fromPath(pheno)
.splitCsv(header: true, sep: ',')
.map{ row ->
def condition = row.condition
return condition
}
.toList()
}

Related

Checking values across multiple location and returning a match only if the sources are unique

Lets say I have a list of Vendors: Asda, Tesco, Spar.
And I have a list of Sources (or suppliers in this analogy): Kellogg, Cadbury, Nestle, Johnsons, Pampers, Simple, etc. (there is a defined list of around 20).
Elsewhere in the flow of data. I am returning a result, which is Yes/No for each vendor, for multiple different things.
For example: Asda: ukOnly = "Yes"; Spar: ukOnly = "No" etc.
In this specific section, I am collating results.
Mostly it doesn't matter if the sources from the vendors overlap. So I can just say:
function concatResults(x) -- concats the result of "x" for each vendor
local pathAsda = *this is where I call the path location specific to Asda*
local pathTesco = *this is where I call the path location specific to Tesco*
local pathSpar = *this is where I call the path location specific to Spar*
if (pathAsda == "Yes" or pathTesco == "Yes" or pathSpar == "Yes") then
return "Yes"
else
return "No"
end
end
ukOnlyAgr = concatResults("ukOnly")
Great!
Now, say I want to do something more comple.
I want to know how many unique suppliers are providing chocolate and cereal. The example below is being used further up the process to produce a fact suppliesSweet, only if there is at least two sources (suppliers) involved and they must be at least supplying chocolate. This will be done for each vendor separately (please assume I have already defined my variables based on the input data:
if (suppliesChoc > 0 and suppliesCereal > 0 and numSources > 1) or (suppliesChoc > 1) then
then suppliesSweet = "Yes"
else suppliesSweet = "No"
end
Not a problem yet.
The issue comes when I try to aggregate these results across vendors (as I did before with ukOnly).
I already have the following function being used:
table.contains = function(t, value) -- Finds if "value" exists inside the table "t"
for index = 1, #t do
if t[index] == value then
return index
end
end
end
And was thinking of creating this:
table.overlap = function(t,g) -- Finds if tables "g" and "t" have any overlapping values
for i=1,#t do
if table.contains(g,t[i]) then
return true
else
return false
end
end
end
But I'm just not sure where to go from there.
You can assume I have already got a list of unique sources for each vendor and I don't mind if we're over restrictive. I.e. if any sources overlap between the two vendors, that would invalidate the entire result.
You can also assume I have each "fact": suppliesChoc, suppliesCereal, numSources and suppliesSweet for each vendor returned separately.
I believe your looking for the intersection of two sets.
https://en.wikipedia.org/wiki/Intersection_(set_theory)
One set being your vendor's suppliers and the other being the suppliers who supply sweets.
local vendors = {
Asda = {Kellogg = true, Cadbury = true, Nestle = true, Johnsons = true, Pampers = true, Simple = true},
Tesco = {Kellogg = true, Cadbury = true, Nestle = true, Johnsons = true},
Spar ={Nestle = true, Johnsons = true, Pampers = true, Simple = true}
}
function intersection(s1, s2)
local output = {}
for key in pairs(s1) do
output[#output + 1] = s2[key]
end
return output
end
local sweetSuppliers = {Kellogg = true, Cadbury = true, Nestle = true}
for name, suppliers in pairs(vendors) do
local result = intersection(sweetSuppliers, suppliers)
print(name .. " has " .. #result .. " sweets suppliers")
end
Here are some examples of a libraries for handling sets:
odkr's properset.lua
Windower's sets.lua
Both can give you an idea of how you can use sets to accomplish things like intersection, and much more

How does "if" work with registers in verilog?

a = reg[3:0].
what values of "a" return true in: "if(a)"?.
which cell of the register a does the "if" check in the previous format?.
Does it return 0 only for a=0000 or are there other values for a that make if(a)=0?.
If a is reg [3:0], it evaluates to false inside if statement only when a == 4'b0000.

How to get the list of all booleans set to true?

I have a table model named History and all its attributes are boolean.
How can I select only the attributes set to true?
I tried
History.select {|h| h == true}
what am I missing?
For all ones with all true:
boolean_columns = Model.columns.map(&:name) - %w(id created_at updated_at)
Model.where(boolean_columns.zip([true].cycle).to_h)
Attributes only works on an instance, and in that case you probably just want to query it.
For a single one:
Model.first.attributes.select { |_, v| v == true }
The reason I do v == true instead of v is because you want explicit boolean true, not necessarily truthy.

java.util.NoSuchElementException when using inject method of groovy List

i try to get the AND logic among boolean elments from groovy list .
def list=[true,false,true];
For example , when i apply inject as following :
list.inject{a,b->a && b};
i get
true && false && true=false
However , when i apply this closure to an empty list i get this error message
Cannot call inject() on an empty collection without passing an initial value.
How can passing initial value to avoid this exception ?
thanks
Inject with no initial parameter uses the first element in the list as the initial value, and then runs the closure over all further elements in the list.
If the list is empty, it cannot get the initial value, so you need to specify an initial parameter to inject:
ie:
list.inject( true ) { a, b -> a && b }
This will return true for empty lists, but in your original example will return false, as it will evaluate:
true && true && false && true
Obviously, if you're doing or instead of and, you should pass false as the inital parameter:
list.inject( false ) { a, b -> a || b }

In Lua what does an if statement with only one argument mean?

I've been taught to program in Java. Lua is new to me and I've tried to do my homework but am not sure what an if statement of the following nature means.
The code is as follows:
local function getMinHeight(self)
local minHeight = 0
for i=1, minimizedLines do
local line = select(9+i, self:GetRegions())
**if(line) then
minHeight = minHeight + line:GetHeight() + 2.5
end**
end
if(minHeight == 0) then
minHeight = select(2, self:GetFont()) + 2.5
end
return minHeight
end
The if statement with the ** before and after is the part I'm not sure about. I don't know what the if statement is checking. If the line is not nil? If the line exists? If what?
In Lua, anything that's not nil or false evaluates to true in a conditional.
If the line is not nil? If the line exists?
Yes to both, because they kinda mean the same thing.
The select function returns a specific argument from it's list of arguments. It's used primarily with ..., but in this case it's being used to select the (i+9)th value returned by self:GetRegions. If there is no such value (for instance, if GetRegions only returns 5 values), then select returns nil.
if(line) is checking to see that it got a value back from select.
if(line) is being used as a shortcut for if(line ~= nil), since nil evaluates to false in a conditional.
It's worth pointing out that this shortcut is not always appropriate. For instance, we can iterate all the values in a table like this:
key, val = next(lookup)
while key do
print(key, val)
key, val = next(lookup, key)
end
However, this will fail if one of the table's keys happens be false:
lookup = {
["fred"] = "Fred Flinstone",
[true] = "True",
[false] = "False",
}
So we have to explicitly check for nil:
key, val = next(lookup)
while key ~= nil do
print(key, val)
key, val = next(lookup, key)
end
As Mud says, in lua anything other than nil and false is considered truthy. So the if above will pass as long as line is not nil or false.
That said, it worries me a bit the way you have phrased the question - "an if with only one argument".
First, it's not called "argument" - it's called expression. And in most languages is always one. In java, for example, you could do something like this:
bool found = false
...
if(found) {
...
}
ifs only care about the final value of the expression; they don't care whether it's a single variable or a more complex construction.