Mercurial > repos > iuc > bcftools_consensus
comparison macros.xml @ 7:2363ef414c9b draft
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/bcftools commit 2684e1443f03bfe2ae20c31d23817415ec8f7e69
author | iuc |
---|---|
date | Thu, 21 Feb 2019 15:54:32 -0500 |
parents | 1829900b5dcd |
children | 70b8e9908ea8 |
comparison
equal
deleted
inserted
replaced
6:1829900b5dcd | 7:2363ef414c9b |
---|---|
1 <macros> | 1 <macros> |
2 <token name="@VERSION@">1.4.0</token> | 2 <token name="@TOOL_VERSION@">1.9</token> |
3 <xml name="stdio"> | 3 <xml name="stdio"> |
4 <stdio> | 4 <stdio> |
5 <exit_code range="1:" /> | 5 <exit_code range="1:" /> |
6 <exit_code range=":-1" /> | 6 <exit_code range=":-1" /> |
7 <regex match="Error:" /> | 7 <regex match="Error:" /> |
8 <regex match="Exception:" /> | 8 <regex match="Exception:" /> |
9 </stdio> | 9 </stdio> |
10 </xml> | 10 </xml> |
11 <xml name="requirements"> | 11 <xml name="requirements"> |
12 <requirements> | 12 <requirements> |
13 <requirement type="package" version="1.4">bcftools</requirement> | 13 <requirement type="package" version="@TOOL_VERSION@">bcftools</requirement> |
14 <requirement type="package" version="1.4">htslib</requirement> | 14 <requirement type="package" version="1.9">htslib</requirement> |
15 <yield /> | 15 <yield /> |
16 </requirements> | 16 </requirements> |
17 </xml> | 17 </xml> |
18 <xml name="samtools_requirement"> | 18 <xml name="samtools_requirement"> |
19 <requirement type="package" version="1.3.1">samtools</requirement> | 19 <requirement type="package" version="1.9">samtools</requirement> |
20 </xml> | 20 </xml> |
21 <xml name="version_command"> | 21 <xml name="version_command"> |
22 <version_command>bcftools 2>&1 | grep 'Version:'</version_command> | 22 <version_command>bcftools 2>&1 | grep 'Version:'</version_command> |
23 </xml> | 23 </xml> |
24 | 24 |
37 <![CDATA[ | 37 <![CDATA[ |
38 export BCFTOOLS_PLUGINS=`which bcftools | sed 's,bin/bcftools,libexec/bcftools,'`; | 38 export BCFTOOLS_PLUGINS=`which bcftools | sed 's,bin/bcftools,libexec/bcftools,'`; |
39 ]]> | 39 ]]> |
40 </token> | 40 </token> |
41 <xml name="macro_input"> | 41 <xml name="macro_input"> |
42 <param name="input_file" type="data" format="vcf,vcf_bgzip,bcf,bcf_bgzip" label="VCF/BCF Data" /> | 42 <param name="input_file" type="data" format="vcf,vcf_bgzip,bcf" label="VCF/BCF Data" /> |
43 </xml> | 43 </xml> |
44 <token name="@PREPARE_INPUT_FILE@"> | 44 <token name="@PREPARE_INPUT_FILE@"> |
45 <![CDATA[ | 45 <![CDATA[ |
46 ## May need to symlink input if there is an associated | 46 ## May need to symlink input if there is an associated |
47 #set $input_vcf = 'input.vcf.gz' | 47 #set $input_vcf = 'input.vcf.gz' |
48 #if $input_file.is_of_type('vcf') | 48 #if $input_file.is_of_type('vcf') |
49 bgzip -c '$input_file' > $input_vcf && | 49 bgzip -c '$input_file' > $input_vcf && |
50 bcftools index $input_vcf && | 50 bcftools index $input_vcf && |
51 #elif $input_file.is_of_type('vcf_bgzip') | 51 #elif $input_file.is_of_type('vcf_bgzip') |
52 ln -s '$input_file' $input_vcf && | 52 ln -s '$input_file' $input_vcf && |
53 #if $input_file.metadata.tabix_index: | |
54 ln -s '${input_file.metadata.tabix_index}' ${input_vcf}.tbi && | |
55 #else | |
56 bcftools index $input_vcf && | |
57 #end if | |
53 #elif $input_file.is_of_type('bcf') | 58 #elif $input_file.is_of_type('bcf') |
54 #set $input_vcf = 'input.bcf' | 59 #set $input_vcf = 'input.bcf' |
55 ln -s '$input_file' $input_vcf && | 60 ln -s '$input_file' $input_vcf && |
56 #if $input_file.metadata.bcf_index: | 61 #if $input_file.metadata.bcf_index: |
57 ln -s '${input_file.metadata.bcf_index}' ${input_vcf}.csi && | 62 ln -s '${input_file.metadata.bcf_index}' ${input_vcf}.csi && |
58 #else | 63 #else |
59 bcftools index $input_vcf && | 64 bcftools index $input_vcf && |
60 #end if | 65 #end if |
61 #elif $input_file.is_of_type('bcf_bgzip') | |
62 ln -s '$input_file' $input_vcf && | |
63 #end if | 66 #end if |
64 ]]> | 67 ]]> |
65 </token> | 68 </token> |
66 <token name="@INPUT_FILE@"> | 69 <token name="@INPUT_FILE@"> |
67 $input_vcf | 70 $input_vcf |
68 </token> | 71 </token> |
69 | 72 |
70 <xml name="macro_inputs"> | 73 <xml name="macro_inputs"> |
71 <param name="input_files" type="data" format="vcf,bcf" label="Other VCF/BCF Datasets" multiple="True" /> | 74 <param name="input_files" type="data" format="vcf,vcf_bgzip,bcf" label="Other VCF/BCF Datasets" multiple="True" /> |
72 </xml> | 75 </xml> |
73 <token name="@PREPARE_INPUT_FILES@"> | 76 <token name="@PREPARE_INPUT_FILES@"> |
74 <![CDATA[ | 77 <![CDATA[ |
75 ## May need to symlink input if there is an associated | 78 ## May need to symlink input if there is an associated |
76 #set $input_vcfs = [] | 79 #set $input_vcfs = [] |
78 #for (i, input_file) in enumerate($input_files): | 81 #for (i, input_file) in enumerate($input_files): |
79 #set $input_vcf = 'input' + str($i) + '.vcf.gz' | 82 #set $input_vcf = 'input' + str($i) + '.vcf.gz' |
80 #if $input_file.is_of_type('vcf') | 83 #if $input_file.is_of_type('vcf') |
81 bgzip -c '$input_file' > $input_vcf && | 84 bgzip -c '$input_file' > $input_vcf && |
82 bcftools index $input_vcf && | 85 bcftools index $input_vcf && |
83 #elif $input_file.is_of_type('vcf_bgz') | 86 #elif $input_file.is_of_type('vcf_bgzip') |
84 ln -s '$input_file' $input_vcf | 87 ln -s '$input_file' $input_vcf && |
88 #if $input_file.metadata.tabix_index: | |
89 ln -s '${input_file.metadata.tabix_index}' ${input_vcf}.tbi && | |
90 #else | |
91 bcftools index $input_vcf && | |
92 #end if | |
85 #elif $input_file.is_of_type('bcf') | 93 #elif $input_file.is_of_type('bcf') |
86 #set $input_vcf = 'input' + str($i) + '.bcf.gz' | 94 #set $input_vcf = 'input' + str($i) + '.bcf.gz' |
87 ln -s '$input_file' $input_vcf && | 95 ln -s '$input_file' $input_vcf && |
88 #if $input_file.metadata.bcf_index: | 96 #if $input_file.metadata.bcf_index: |
89 ln -s '${input_file.metadata.bcf_index}' ${input_vcf}.csi && | 97 ln -s '${input_file.metadata.bcf_index}' ${input_vcf}.csi && |
90 #else | 98 #else |
91 bcftools index $input_vcf && | 99 bcftools index $input_vcf && |
92 #end if | 100 #end if |
93 #elif $input_file.is_of_type('bcfvcf_bgz') | |
94 ln -s '$input_file' $input_vcf && | |
95 #end if | 101 #end if |
96 echo '$input_vcf' >> $vcfs_list_file && | 102 echo '$input_vcf' >> $vcfs_list_file && |
97 $input_vcfs.append($input_vcf) | 103 $input_vcfs.append($input_vcf) |
98 #end for | 104 #end for |
99 ]]> | 105 ]]> |
104 <token name="@INPUT_LIST_FILE@"> | 110 <token name="@INPUT_LIST_FILE@"> |
105 $vcfs_list_file | 111 $vcfs_list_file |
106 </token> | 112 </token> |
107 | 113 |
108 <xml name="macro_fasta_ref"> | 114 <xml name="macro_fasta_ref"> |
109 <param name="fasta_ref" argument="--fasta-ref" type="data" format="data" label="Reference sequence in FASTA format" optional="True" /> | 115 <param name="fasta_ref" argument="--fasta-ref" type="data" format="data" optional="true" label="Reference sequence in FASTA format" /> |
110 </xml> | 116 </xml> |
111 <token name="@PREPARE_FASTA_REF@"> | 117 <token name="@PREPARE_FASTA_REF@"> |
112 <![CDATA[ | 118 <![CDATA[ |
113 #set $input_fa_ref = None | 119 #set $input_fa_ref = None |
114 #if 'fasta_ref' in $section and $section.fasta_ref: | 120 #if 'fasta_ref' in $section and $section.fasta_ref: |
146 </conditional> | 152 </conditional> |
147 </xml> | 153 </xml> |
148 | 154 |
149 | 155 |
150 <xml name="macro_AF_file"> | 156 <xml name="macro_AF_file"> |
151 <param name="AF_file" argument="--AF-file" type="data" format="tabular" label="Allele frequencies file" optional="True" help="Tab-delimited file containing the columns CHR,POS,REF,ALT,AF" /> | 157 <param name="AF_file" argument="--AF-file" type="data" format="tabular" optional="true" label="Allele frequencies file" help="Tab-delimited file containing the columns CHR,POS,REF,ALT,AF" /> |
152 </xml> | 158 </xml> |
153 <!-- This may need to bgzip and tabix the file --> | 159 <!-- This may need to bgzip and tabix the file --> |
154 <token name="@PREPARE_AF_FILE@"> | 160 <token name="@PREPARE_AF_FILE@"> |
155 <![CDATA[ | 161 <![CDATA[ |
156 #if 'AF_file' in $section and $section.AF_file: | 162 #if 'AF_file' in $section and $section.AF_file: |
163 --AF-file '${section.AF_file}' | 169 --AF-file '${section.AF_file}' |
164 #end if | 170 #end if |
165 </token> | 171 </token> |
166 | 172 |
167 <xml name="macro_estimate_AF"> | 173 <xml name="macro_estimate_AF"> |
168 <param name="estimate_AF" argument="--estimate-AF" type="data" format="data" label="Estimate allele frequency" optional="True" help="calculate AC,AN counts on the fly, using either all samples ("-") or samples listed in <file>" /> | 174 <param name="estimate_AF" argument="--estimate-AF" type="data" format="data" optional="true" label="Estimate allele frequency" help="Calculate AC,AN counts on the fly, using either all samples ("-") or samples listed in <file>" /> |
169 </xml> | 175 </xml> |
170 <token name="@ESTIMATE_AF@"> | 176 <token name="@ESTIMATE_AF@"> |
171 #if 'estimate_AF' in $section and $section.estimate_AF: | 177 #if 'estimate_AF' in $section and $section.estimate_AF: |
172 --estimate-AF "${section.estimate_AF}" | 178 --estimate-AF "${section.estimate_AF}" |
173 #end if | 179 #end if |
174 </token> | 180 </token> |
175 | 181 |
176 <xml name="macro_exons_file"> | 182 <xml name="macro_exons_file"> |
177 <param name="exons_file" type="data" format="tabular" label="exons file" optional="True" help="tab-delimited file with exons for indel frameshifts (chr,from,to; 1-based, inclusive, bgzip compressed)" /> | 183 <param name="exons_file" type="data" format="tabular" optional="true" label="Exons file" help="Tab-delimited file with exons for indel frameshifts (chr,from,to; 1-based, inclusive, bgzip compressed)" /> |
178 </xml> | 184 </xml> |
179 <token name="@PREPARE_EXONS_FILE@"> | 185 <token name="@PREPARE_EXONS_FILE@"> |
180 <![CDATA[ | 186 <![CDATA[ |
181 #set $exons_path = None | 187 #set $exons_path = None |
182 #if 'exons_file' in $section and $section.exons_file: | 188 #if 'exons_file' in $section and $section.exons_file: |
191 --exons $exons_path | 197 --exons $exons_path |
192 #end if | 198 #end if |
193 </token> | 199 </token> |
194 | 200 |
195 <xml name="macro_ploidy_file"> | 201 <xml name="macro_ploidy_file"> |
196 <param name="ploidy_file" type="data" format="tabular" label="Ploidy file" optional="True" help="tab-delimited list of CHROM,FROM,TO,SEX,PLOIDY" /> | 202 <param name="ploidy_file" type="data" format="tabular" optional="true" label="Ploidy file" help="Tab-delimited list of CHROM,FROM,TO,SEX,PLOIDY" /> |
197 </xml> | 203 </xml> |
198 <token name="@PLOIDY_FILE@"> | 204 <token name="@PLOIDY_FILE@"> |
199 #if 'ploidy_file' in $section and $section.ploidy_file: | 205 #if 'ploidy_file' in $section and $section.ploidy_file: |
200 --ploidy "${section.ploidy_file}" | 206 --ploidy "${section.ploidy_file}" |
201 #end if | 207 #end if |
206 </xml> | 212 </xml> |
207 <xml name="macro_collapse_opt_id"> | 213 <xml name="macro_collapse_opt_id"> |
208 <option value="id">id - only records with identical ID column are compatible. </option> | 214 <option value="id">id - only records with identical ID column are compatible. </option> |
209 </xml> | 215 </xml> |
210 <xml name="macro_collapse"> | 216 <xml name="macro_collapse"> |
211 <param name="collapse" type="select" label="Collapse" optional="True" help="Controls how to treat records with duplicate positions and defines compatible records across multiple input files"> | 217 <param name="collapse" type="select" optional="true" label="Collapse" help="Controls how to treat records with duplicate positions and defines compatible records across multiple input files"> |
212 <option value="snps">snps - allow different alleles, as long as they all are SNPs</option> | 218 <option value="snps">snps - allow different alleles, as long as they all are SNPs</option> |
213 <option value="indels">indels - allow different alleles, as long as they all are indels</option> | 219 <option value="indels">indels - allow different alleles, as long as they all are indels</option> |
214 <option value="both">both - indels and snps </option> | 220 <option value="both">both - indels and snps </option> |
215 <option value="some">some - at least some of the ALTs must match</option> | 221 <option value="some">some - at least some of the ALTs must match</option> |
216 <option value="any">any - any combination of alleles</option> | 222 <option value="any">any - any combination of alleles</option> |
222 --collapse ${section.collapse} | 228 --collapse ${section.collapse} |
223 #end if | 229 #end if |
224 </token> | 230 </token> |
225 | 231 |
226 <xml name="macro_apply_filters"> | 232 <xml name="macro_apply_filters"> |
227 <param name="apply_filters" type="text" value="" label="Apply Filters" optional="true" | 233 <param argument="--apply_filters" type="text" value="" optional="true" label="Apply filters" |
228 help="(-f --apply-filters) Skip sites where FILTER column does not contain any of the strings listed (e.g. "PASS,.")"> | 234 help="Skip sites where FILTER column does not contain any of the strings listed (e.g. "PASS,.")"> |
229 <validator type="regex" message="FILTER terms separated by commas">^([^ \t\n\r\f\v,]+(,[^ \t\n\r\f\v,]+)*)?$</validator> | 235 <validator type="regex" message="FILTER terms separated by commas">^([^ \t\n\r\f\v,]+(,[^ \t\n\r\f\v,]+)*)?$</validator> |
230 </param> | 236 </param> |
231 </xml> | 237 </xml> |
232 <token name="@APPLY_FILTERS@"> | 238 <token name="@APPLY_FILTERS@"> |
233 #if $section.apply_filters: | 239 #if $section.apply_filters: |
269 <option value="regions">regions</option> | 275 <option value="regions">regions</option> |
270 <option value="regions_file">regions-file</option> | 276 <option value="regions_file">regions-file</option> |
271 </param> | 277 </param> |
272 <when value="__none__"/> | 278 <when value="__none__"/> |
273 <when value="regions"> | 279 <when value="regions"> |
274 <param name="regions" type="text" value="" label="restrict to comma-separated list of regions" optional="true" | 280 <param name="regions" type="text" value="" optional="true" label="Restrict to comma-separated list of regions" |
275 help="Each region is specifed as: chr or chr:pos or chr:from-to"> | 281 help="Each region is specifed as: chr or chr:pos or chr:from-to"> |
276 <validator type="regex" message="">^(\w+(:\d+(-\d+)?)?(,\w+(:\d+(-\d+)?)?)*)?$</validator> | 282 <validator type="regex" message="">^(\w+(:\d+(-\d+)?)?(,\w+(:\d+(-\d+)?)?)*)?$</validator> |
277 </param> | 283 </param> |
278 </when> | 284 </when> |
279 <when value="regions_file"> | 285 <when value="regions_file"> |
280 <param name="regions_file" type="data" format="vcf,bed,tabular" label="Regions File" optional="True" help="restrict to regions listed in a file" /> | 286 <param name="regions_file" type="data" format="vcf,bed,tabular" optional="true" label="Regions file" help="Restrict to regions listed in a file" /> |
281 </when> | 287 </when> |
282 </conditional> | 288 </conditional> |
283 </xml> | 289 </xml> |
284 <token name="@PREPARE_REGIONS_FILE@"> | 290 <token name="@PREPARE_REGIONS_FILE@"> |
285 <![CDATA[ | 291 <![CDATA[ |
344 <option value="targets">targets</option> | 350 <option value="targets">targets</option> |
345 <option value="targets_file">targets-file</option> | 351 <option value="targets_file">targets-file</option> |
346 </param> | 352 </param> |
347 <when value="__none__"/> | 353 <when value="__none__"/> |
348 <when value="targets"> | 354 <when value="targets"> |
349 <param name="targets" type="text" value="" label="Restrict to comma-separated list of targets" optional="true" | 355 <param name="targets" type="text" value="" optional="true" label="Restrict to comma-separated list of targets" |
350 help="Each target is specifed as: chr or chr:pos or chr:from-to"> | 356 help="Each target is specifed as: chr or chr:pos or chr:from-to"> |
351 <validator type="regex" message="">^(\w+(:\d+(-\d+)?)?(,\w+(:\d+(-\d+)?)?)*)?$</validator> | 357 <validator type="regex" message="">^(\w+(:\d+(-\d+)?)?(,\w+(:\d+(-\d+)?)?)*)?$</validator> |
352 </param> | 358 </param> |
353 <param name="invert_targets_file" type="boolean" truevalue="^" falsevalue="" label="Invert Targets" help="inverts the query/filtering applied by the targets" /> | 359 <param name="invert_targets_file" type="boolean" truevalue="^" falsevalue="" label="Invert Targets" help="inverts the query/filtering applied by the targets" /> |
354 </when> | 360 </when> |
371 #end if | 377 #end if |
372 ]]> | 378 ]]> |
373 </token> | 379 </token> |
374 | 380 |
375 <xml name="macro_samples"> | 381 <xml name="macro_samples"> |
376 <param name="samples" type="text" value="" label="Samples" optional="true" | 382 <param argument="--samples" type="text" value="" optional="true" label="Samples" |
377 help="(-s) comma separated list of samples to annotate (or exclude)"> | 383 help="Comma separated list of samples to annotate (or exclude)"> |
378 <validator type="regex" message="">^(\w+(,\w+)*)?$</validator> | 384 <validator type="regex" message="">^(\w+(,\w+)*)?$</validator> |
379 </param> | 385 </param> |
380 <param name="invert_samples" type="boolean" truevalue="^" falsevalue="" checked="false" label="Invert Samples" | 386 <param name="invert_samples" type="boolean" truevalue="^" falsevalue="" checked="false" label="Invert Samples" |
381 help="inverts the query/filtering applied by Samples (adds "^" prefix to exclude)" /> | 387 help="Inverts the query/filtering applied by Samples (adds "^" prefix to exclude)" /> |
382 <param name="samples_file" type="data" format="tabular" label="Samples File" optional="True" | 388 <param argument="--samples_file" type="data" format="tabular" optional="true" label="Samples file" |
383 help="(-S) file of samples to include" /> | 389 help="File of samples to include" /> |
384 <param name="invert_samples_file" type="boolean" truevalue="^" falsevalue="" checked="false" label="Invert Samples File" | 390 <param name="invert_samples_file" type="boolean" truevalue="^" falsevalue="" checked="false" label="Invert Samples file" |
385 help="inverts the query/filtering applied by Samples File" /> | 391 help="inverts the query/filtering applied by Samples file" /> |
386 </xml> | 392 </xml> |
387 <token name="@SAMPLES@"> | 393 <token name="@SAMPLES@"> |
388 #set $samples_defined = False | 394 #set $samples_defined = False |
389 #if str($section.samples) != '': | 395 #if str($section.samples) != '': |
390 #set $samples_defined = True | 396 #set $samples_defined = True |
395 --samples-file "${section.invert_samples_file}${section.samples_file}" | 401 --samples-file "${section.invert_samples_file}${section.samples_file}" |
396 #end if | 402 #end if |
397 </token> | 403 </token> |
398 | 404 |
399 <xml name="macro_sample"> | 405 <xml name="macro_sample"> |
400 <param name="sample" type="text" label="Sample" optional="True" help="apply variants of the given sample" /> | 406 <param name="sample" type="text" optional="true" label="Sample" help="Apply variants of the given sample" /> |
401 </xml> | 407 </xml> |
402 <token name="@SAMPLE@"> | 408 <token name="@SAMPLE@"> |
403 #if $section.sample: | 409 #if $section.sample: |
404 --sample '${section.sample}' | 410 --sample '${section.sample}' |
405 #end if | 411 #end if |
406 </token> | 412 </token> |
407 | 413 |
408 | 414 |
409 <xml name="macro_include"> | 415 <xml name="macro_include"> |
410 <param name="include" type="text" label="Include" optional="True" help="(-i) select sites for which the expression is true"> | 416 <param argument="--include" type="text" optional="true" label="Include" help="Select sites for which the expression is true"> |
411 <validator type="regex" message="Single quote not allowed">^[^']*$</validator> | 417 <validator type="regex" message="Single quote not allowed">^[^']*$</validator> |
412 <sanitizer sanitize="False"/> | 418 <sanitizer sanitize="False"/> |
413 </param> | 419 </param> |
414 </xml> | 420 </xml> |
415 <token name="@INCLUDE@"> | 421 <token name="@INCLUDE@"> |
417 --include '${section.include}' | 423 --include '${section.include}' |
418 #end if | 424 #end if |
419 </token> | 425 </token> |
420 | 426 |
421 <xml name="macro_exclude"> | 427 <xml name="macro_exclude"> |
422 <param name="exclude" type="text" label="Exclude" optional="True" help="(-e) exclude sites for which the expression is true"> | 428 <param argument="--exclude" type="text" optional="true" label="Exclude" help="Exclude sites for which the expression is true"> |
423 <validator type="regex" message="Single quote not allowed">^[^']*$</validator> | 429 <validator type="regex" message="Single quote not allowed">^[^']*$</validator> |
424 <sanitizer sanitize="False"/> | 430 <sanitizer sanitize="False"/> |
425 </param> | 431 </param> |
426 </xml> | 432 </xml> |
427 <token name="@EXCLUDE@"> | 433 <token name="@EXCLUDE@"> |
429 --exclude '${section.exclude}' | 435 --exclude '${section.exclude}' |
430 #end if | 436 #end if |
431 </token> | 437 </token> |
432 | 438 |
433 <xml name="macro_columns"> | 439 <xml name="macro_columns"> |
434 <param name="columns" type="text" value="" label="Columns" optional="true" | 440 <param name="columns" type="text" value="" optional="true" label="Columns" |
435 help="list of columns in the annotation file, e.g. CHROM,POS,REF,ALT,-,INFO/TAG. See man page for details"> | 441 help="List of columns in the annotation file, e.g. CHROM,POS,REF,ALT,-,INFO/TAG. See man page for details"> |
436 <validator type="regex" message="COLUMN names separated by commas">^([^,]+(,[^,]+)*)?$</validator> | 442 <validator type="regex" message="COLUMN names separated by commas">^([^,]+(,[^,]+)*)?$</validator> |
437 </param> | 443 </param> |
438 </xml> | 444 </xml> |
439 <token name="@COLUMNS@"> | 445 <token name="@COLUMNS@"> |
440 #if $section.columns != '': | 446 #if $section.columns != '': |