Mercurial > repos > ecology > xarray_select
changeset 3:bf595d613af4 draft
"planemo upload for repository https://github.com/galaxyecology/tools-ecology/tree/master/tools/data_manipulation/xarray/ commit 2166974df82f97557b082a9e55135098e61640c4"
line wrap: on
line diff
--- a/README.md Sun Jun 06 08:51:41 2021 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,8 +0,0 @@ -# Xarray tools for netCDF -## netCDF metadata information - -The first tool `xarray_metadata_info ` uses xarray to provide users with general information about variable names, dimensions -and attributes. -Variables that can be extracted and dimensions available are printed in a tabular file. - -The tool also print a general information file. It's the result of the xarray method info().
--- a/macros.xml Sun Jun 06 08:51:41 2021 +0000 +++ b/macros.xml Thu Jan 20 17:07:19 2022 +0000 @@ -1,185 +1,28 @@ -<macros> - <token name="@TOOL_VERSION@">0.18.2</token> - <token name="@VERSION_SUFFIX@">0</token> - <xml name="edam_ontology"> - <edam_topics> - <edam_topic>topic_0610</edam_topic> - <edam_topic>topic_3050</edam_topic> - </edam_topics> - </xml> - <xml name="citations"> - <citations> - <citation type="bibtex"> - @article{hoyer2017xarray, - title = {xarray: {N-D} labeled arrays and datasets in {Python}}, - author = {Hoyer, S. and J. Hamman}, - journal = {Journal of Open Research Software}, - volume = {5}, - number = {1}, - year = {2017}, - publisher = {Ubiquity Press}, - doi = {10.5334/jors.148}, - url = {http://doi.org/10.5334/jors.148} - } - </citation> - </citations> - </xml> - <xml name="customize_appearance_plots"> - <param name="borders" type="float" optional="true" label="Add country borders with alpha value [0-1] (optional)" /> - <param name="coastline" type="float" optional="true" label="Add coastline with alpha value [0-1] (optional)" /> - <param name="ocean" type="float" optional="true" label="Add ocean with alpha value [0-1] (optional)" /> - <param name="land" type="float" optional="true" label="Add land with alpha value [0-1] (optional)" /> - <param name="title" type="text" optional="true" label="Specify plot title (optional)" /> - <param name="colorbar_label" type="text" optional="true" label="Set a label for colormap (optional)" /> - <param name="cmap" type="select" optional="true" label="Specify which colormap to use for plotting (optional)"> - <option value="cm.batlow">batlow</option> - <option value="cm.batlowW">batlowW</option> - <option value="cm.batlowK">batlowK</option> - <option value="cm.devon">devon</option> - <option value="cm.davos">davos</option> - <option value="cm.oslo">oslo</option> - <option value="cm.lapaz">lapaz</option> - <option value="cm.acton">acton</option> - <option value="cm.lajolla">lajolla</option> - <option value="cm.bilbao">bilbao</option> - <option value="cm.grayC">grayC</option> - <option value="cm.tokyo">tokyo</option> - <option value="cm.turku">turku</option> - <option value="cm.bamako">bamako</option> - <option value="cm.nuuk">nuuk</option> - <option value="cm.hawaii">hawaii</option> - <option value="cm.buda">buda</option> - <option value="cm.imola">imola</option> - <option value="cm.broc">broc</option> - <option value="cm.lisbon">lisbon</option> - <option value="cm.roma">roma</option> - <option value="cm.cork">cork</option> - <option value="cm.tofino">tofino</option> - <option value="cm.bam">bam</option> - <option value="cm.vik">vik</option> - <option value="cm.berlin">berlin</option> - <option value="cm.vanimo">vanimo</option> - <option value="cm.oleron">oleron</option> - <option value="cm.bukavu">bukavu</option> - <option value="cm.fes">fes</option> - <option value="cm.romaO">romaO</option> - <option value="cm.bamO">bamO</option> - <option value="cm.brocO">brocO</option> - <option value="cm.corkO">corkO</option> - <option value="cm.vikO">vikO</option> - <option value="cm.batlow_r">batlow_r</option> - <option value="cm.batlowW_r">batlowW_r</option> - <option value="cm.batlowK_r">batlowK_r</option> - <option value="cm.devon_r">devon_r</option> - <option value="cm.davos_r">davos_r</option> - <option value="cm.oslo_r">oslo_r</option> - <option value="cm.lapaz_r">lapaz_r</option> - <option value="cm.acton_r">acton_r</option> - <option value="cm.lajolla_r">lajolla_r</option> - <option value="cm.bilbao_r">bilbao_r</option> - <option value="cm.grayC_r">grayC_r</option> - <option value="cm.tokyo_r">tokyo_r</option> - <option value="cm.turku_r">turku_r</option> - <option value="cm.bamako_r">bamako_r</option> - <option value="cm.nuuk_r">nuuk_r</option> - <option value="cm.hawaii_r">hawaii_r</option> - <option value="cm.buda_r">buda_r</option> - <option value="cm.imola_r">imola_r</option> - <option value="cm.broc_r">broc_r</option> - <option value="cm.lisbon_r">lisbon_r</option> - <option value="cm.roma_r">roma_r</option> - <option value="cm.cork_r">cork_r</option> - <option value="cm.tofino_r">tofino_r</option> - <option value="cm.bam_r">bam_r</option> - <option value="cm.vik_r">vik_r</option> - <option value="cm.berlin_r">berlin_r</option> - <option value="cm.vanimo_r">vanimo_r</option> - <option value="cm.oleron_r">oleron_r</option> - <option value="cm.bukavu_r">bukavu_r</option> - <option value="cm.fes_r">fes_r</option> - <option value="cm.romaO_r">romaO_r</option> - <option value="cm.bamO_r">bamO_r</option> - <option value="cm.brocO_r">brocO_r</option> - <option value="cm.corkO_r">corkO_r</option> - <option value="cm.vikO_r">vikO_r</option> - <option value="Accent">Accent</option> - <option value="Blues">Blues</option> - <option value="BrBG">BrBG</option> - <option value="BuGn">BuGn</option> - <option value="BuPu">BuPu</option> - <option value="CMRmap">CMRmap</option> - <option value="Dark2">Dark2</option> - <option value="GnBu">GnBu</option> - <option value="Greens">Greens</option> - <option value="Greys">Greys</option> - <option value="OrRd">OrRd</option> - <option value="Oranges">Oranges</option> - <option value="PRGn">PRGn</option> - <option value="Paired">Paired</option> - <option value="Pastel1">Pastel1</option> - <option value="Pastel2">Pastel2</option> - <option value="PiYG">PiYG</option> - <option value="PuBu">PuBu</option> - <option value="PuBuGn">PuBuGn</option> - <option value="PuOr">PuOr</option> - <option value="PuRd">PuRd</option> - <option value="Purples">Purples</option> - <option value="RdBu">RdBu</option> - <option value="RdGy">RdGy</option> - <option value="RdPu">RdPu</option> - <option value="RdBu_r">RdBu_r</option> - <option value="RdGy_r">RdGy_r</option> - <option value="RdPu_r">RdPu_r</option> - <option value="RdYlBu">RdYlBu</option> - <option value="RdYlGn">RdYlGn</option> - <option value="Reds">Reds</option> - <option value="Set1">Set1</option> - <option value="Set2">Set2</option> - <option value="Set3">Set3</option> - <option value="Spectral">Spectral</option> - <option value="Wistia">Wistia</option> - <option value="YlGn">YlGn</option> - <option value="YlGnBu">YlGnBu</option> - <option value="YlOrBr">YlOrBr</option> - <option value="YlOrRd">YlOrRd</option> - <option value="afmhot">afmhot</option> - <option value="autumn">autumn</option> - <option value="binary">binary</option> - <option value="bone">bone</option> - <option value="brg">brg</option> - <option value="bwr">bwr</option> - <option value="cool">cool</option> - <option value="coolwarm" selected="true">coolwarm</option> - <option value="copper">copper</option> - <option value="cubehelix">cubehelix</option> - <option value="flag">flag</option> - <option value="gist_earth">gist_earth</option> - <option value="gist_gray">gist_gray</option> - <option value="gist_heat">gist_heat</option> - <option value="gist_ncar">gist_ncar</option> - <option value="gist_rainbow">gist_rainbow</option> - <option value="gist_stern">gist_stern</option> - <option value="gist_yarg">gist_yarg</option> - <option value="gnuplot">gnuplot</option> - <option value="gnuplot2">gnuplot2</option> - <option value="gray">gray</option> - <option value="hot">hot</option> - <option value="hsv">hsv</option> - <option value="jet">jet</option> - <option value="nipy_spectral">nipy_spectral</option> - <option value="ocean">ocean</option> - <option value="pink">pink</option> - <option value="prism">prism</option> - <option value="rainbow">rainbow</option> - <option value="seismic">seismic</option> - <option value="spring">spring</option> - <option value="summer">summer</option> - <option value="tab10">tab10</option> - <option value="tab20">tab20</option> - <option value="tab20b">tab20b</option> - <option value="tab20c">tab20c</option> - <option value="terrain">terrain</option> - <option value="winter">winter</option> - </param> - </xml> -</macros> +<macros> + <token name="@TOOL_VERSION@">0.20.2</token> + <token name="@VERSION_SUFFIX@">0</token> + <token name="@PROFILE@">20.05</token> + <xml name="edam_ontology"> + <edam_topics> + <edam_topic>topic_0610</edam_topic> + <edam_topic>topic_3050</edam_topic> + </edam_topics> + </xml> + <xml name="citations"> + <citations> + <citation type="bibtex"> + @article{hoyer2017xarray, + title = {xarray: {N-D} labeled arrays and datasets in {Python}}, + author = {Hoyer, S. and J. Hamman}, + journal = {Journal of Open Research Software}, + volume = {5}, + number = {1}, + year = {2017}, + publisher = {Ubiquity Press}, + doi = {10.5334/jors.148}, + url = {http://doi.org/10.5334/jors.148} + } + </citation> + </citations> + </xml> +</macros>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/macros_mapplot.xml Thu Jan 20 17:07:19 2022 +0000 @@ -0,0 +1,213 @@ +<macros> + <xml name="config_map"> + <configfiles> + <configfile name="map_customization"><![CDATA[ +{ +#if $condi_datetime.datetime=="yes" +"time":"$condi_datetime.time_values", +#end if +"latitude":'$lat_dim', +"longitude":'$lon_dim', +#if $colorbar_label +"label":'$colorbar_label', +#end if +#if $title +"title":"$title", +#end if +#if $cmap +"cmap":'$cmap', +#end if +#if $land +"land":'$land', +#end if +#if $ocean +"ocean":'$ocean', +#end if +#if $coastline +"coastline":'$coastline', +#end if +#if $borders +"borders":'$borders', +#end if +#if $threshold +"threshold":'$threshold', +#end if +#if $range +"range":'$range', +#end if +#if $xlim +"xlim":'$xlim', +#end if +#if $ylim +"ylim":'$ylim', +#end if +} + ]]> + </configfile> + <configfile name="map_projection"><![CDATA[ +#if $proj +'$proj' +#end if + ]]> + </configfile> + </configfiles> + </xml> + <xml name="customize_appearance_plots"> + <param name="borders" type="float" optional="true" label="Add country borders with alpha value [0-1] (optional)" /> + <param name="coastline" type="float" optional="true" label="Add coastline with alpha value [0-1] (optional)" /> + <param name="ocean" type="float" optional="true" label="Add ocean with alpha value [0-1] (optional)" /> + <param name="land" type="float" optional="true" label="Add land with alpha value [0-1] (optional)" /> + <param name="title" type="text" optional="true" label="Specify plot title (optional)" /> + <param name="colorbar_label" type="text" optional="true" label="Set a label for colormap (optional)" /> + <param name="cmap" type="select" optional="true" label="Specify which colormap to use for plotting (optional)"> + <option value="cm.batlow">batlow</option> + <option value="cm.batlowW">batlowW</option> + <option value="cm.batlowK">batlowK</option> + <option value="cm.devon">devon</option> + <option value="cm.davos">davos</option> + <option value="cm.oslo">oslo</option> + <option value="cm.lapaz">lapaz</option> + <option value="cm.acton">acton</option> + <option value="cm.lajolla">lajolla</option> + <option value="cm.bilbao">bilbao</option> + <option value="cm.grayC">grayC</option> + <option value="cm.tokyo">tokyo</option> + <option value="cm.turku">turku</option> + <option value="cm.bamako">bamako</option> + <option value="cm.nuuk">nuuk</option> + <option value="cm.hawaii">hawaii</option> + <option value="cm.buda">buda</option> + <option value="cm.imola">imola</option> + <option value="cm.broc">broc</option> + <option value="cm.lisbon">lisbon</option> + <option value="cm.roma">roma</option> + <option value="cm.cork">cork</option> + <option value="cm.tofino">tofino</option> + <option value="cm.bam">bam</option> + <option value="cm.vik">vik</option> + <option value="cm.berlin">berlin</option> + <option value="cm.vanimo">vanimo</option> + <option value="cm.oleron">oleron</option> + <option value="cm.bukavu">bukavu</option> + <option value="cm.fes">fes</option> + <option value="cm.romaO">romaO</option> + <option value="cm.bamO">bamO</option> + <option value="cm.brocO">brocO</option> + <option value="cm.corkO">corkO</option> + <option value="cm.vikO">vikO</option> + <option value="cm.batlow_r">batlow_r</option> + <option value="cm.batlowW_r">batlowW_r</option> + <option value="cm.batlowK_r">batlowK_r</option> + <option value="cm.devon_r">devon_r</option> + <option value="cm.davos_r">davos_r</option> + <option value="cm.oslo_r">oslo_r</option> + <option value="cm.lapaz_r">lapaz_r</option> + <option value="cm.acton_r">acton_r</option> + <option value="cm.lajolla_r">lajolla_r</option> + <option value="cm.bilbao_r">bilbao_r</option> + <option value="cm.grayC_r">grayC_r</option> + <option value="cm.tokyo_r">tokyo_r</option> + <option value="cm.turku_r">turku_r</option> + <option value="cm.bamako_r">bamako_r</option> + <option value="cm.nuuk_r">nuuk_r</option> + <option value="cm.hawaii_r">hawaii_r</option> + <option value="cm.buda_r">buda_r</option> + <option value="cm.imola_r">imola_r</option> + <option value="cm.broc_r">broc_r</option> + <option value="cm.lisbon_r">lisbon_r</option> + <option value="cm.roma_r">roma_r</option> + <option value="cm.cork_r">cork_r</option> + <option value="cm.tofino_r">tofino_r</option> + <option value="cm.bam_r">bam_r</option> + <option value="cm.vik_r">vik_r</option> + <option value="cm.berlin_r">berlin_r</option> + <option value="cm.vanimo_r">vanimo_r</option> + <option value="cm.oleron_r">oleron_r</option> + <option value="cm.bukavu_r">bukavu_r</option> + <option value="cm.fes_r">fes_r</option> + <option value="cm.romaO_r">romaO_r</option> + <option value="cm.bamO_r">bamO_r</option> + <option value="cm.brocO_r">brocO_r</option> + <option value="cm.corkO_r">corkO_r</option> + <option value="cm.vikO_r">vikO_r</option> + <option value="Accent">Accent</option> + <option value="Blues">Blues</option> + <option value="BrBG">BrBG</option> + <option value="BuGn">BuGn</option> + <option value="BuPu">BuPu</option> + <option value="CMRmap">CMRmap</option> + <option value="Dark2">Dark2</option> + <option value="GnBu">GnBu</option> + <option value="Greens">Greens</option> + <option value="Greys">Greys</option> + <option value="OrRd">OrRd</option> + <option value="Oranges">Oranges</option> + <option value="PRGn">PRGn</option> + <option value="Paired">Paired</option> + <option value="Pastel1">Pastel1</option> + <option value="Pastel2">Pastel2</option> + <option value="PiYG">PiYG</option> + <option value="PuBu">PuBu</option> + <option value="PuBuGn">PuBuGn</option> + <option value="PuOr">PuOr</option> + <option value="PuRd">PuRd</option> + <option value="Purples">Purples</option> + <option value="RdBu">RdBu</option> + <option value="RdGy">RdGy</option> + <option value="RdPu">RdPu</option> + <option value="RdBu_r">RdBu_r</option> + <option value="RdGy_r">RdGy_r</option> + <option value="RdPu_r">RdPu_r</option> + <option value="RdYlBu">RdYlBu</option> + <option value="RdYlGn">RdYlGn</option> + <option value="Reds">Reds</option> + <option value="Set1">Set1</option> + <option value="Set2">Set2</option> + <option value="Set3">Set3</option> + <option value="Spectral">Spectral</option> + <option value="Wistia">Wistia</option> + <option value="YlGn">YlGn</option> + <option value="YlGnBu">YlGnBu</option> + <option value="YlOrBr">YlOrBr</option> + <option value="YlOrRd">YlOrRd</option> + <option value="afmhot">afmhot</option> + <option value="autumn">autumn</option> + <option value="binary">binary</option> + <option value="bone">bone</option> + <option value="brg">brg</option> + <option value="bwr">bwr</option> + <option value="cool">cool</option> + <option value="coolwarm" selected="true">coolwarm</option> + <option value="copper">copper</option> + <option value="cubehelix">cubehelix</option> + <option value="flag">flag</option> + <option value="gist_earth">gist_earth</option> + <option value="gist_gray">gist_gray</option> + <option value="gist_heat">gist_heat</option> + <option value="gist_ncar">gist_ncar</option> + <option value="gist_rainbow">gist_rainbow</option> + <option value="gist_stern">gist_stern</option> + <option value="gist_yarg">gist_yarg</option> + <option value="gnuplot">gnuplot</option> + <option value="gnuplot2">gnuplot2</option> + <option value="gray">gray</option> + <option value="hot">hot</option> + <option value="hsv">hsv</option> + <option value="jet">jet</option> + <option value="nipy_spectral">nipy_spectral</option> + <option value="ocean">ocean</option> + <option value="pink">pink</option> + <option value="prism">prism</option> + <option value="rainbow">rainbow</option> + <option value="seismic">seismic</option> + <option value="spring">spring</option> + <option value="summer">summer</option> + <option value="tab10">tab10</option> + <option value="tab20">tab20</option> + <option value="tab20b">tab20b</option> + <option value="tab20c">tab20c</option> + <option value="terrain">terrain</option> + <option value="winter">winter</option> + </param> + </xml> +</macros>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/macros_netcdf2netcdf.xml Thu Jan 20 17:07:19 2022 +0000 @@ -0,0 +1,143 @@ +<macros> + <xml name="coord_range"> + <repeat name="user_choice" title="Filter by coordinate values" min="0" max="20" help="Use this option to filter on the values of the selected coordinate"> + <param name="dim" type="select" label="Dimensions"> + <options from_dataset="var_tab"> + <column name="value" index="0"/> + </options> + </param> + <conditional name="condi_between"> + <param name="comparator" type="select" label="Comparator"> + <option value="is">is</option> + <option value="from">from</option> + <option value="to">to</option> + <option value="sl">slice(threshold1,threshold2)</option> + </param> + <when value="sl"> + <param name="t1" type="text" value="" label="Choose the start value for slice"/> + <param name="t2" type="text" value="" label="Choose the end value for slice"/> + </when> + <when value="to"> + <param name="value" type="text" value="" label="Choose the end value"/> + </when> + <when value="from"> + <param name="value" type="text" value="" label="Choose the start value"/> + </when> + <when value="is"> + <param name="value" type="text" value="" label="Choose the value to select"/> + <yield /> + </when> + </conditional> + </repeat> + </xml> + <xml name="section_variables"> + <section name="variable" title="Select variables"> + <param name="var" type="select" multiple="true" label="Choose variables to extract"> + <options from_dataset="var_tab"> + <column name="name" index="0"/> + <column name="value" index="0"/> + </options> + </param> + <param type="float" name="scale" optional="true" help="scale factor (float) to apply to the selected variable (optional and only if a variable is selected)"/> + <param name="write_all" type="boolean" checked="false" label="Write all variables to new netCDF file (only if a variable is selected)"/> + <param name="keep_attributes" type="boolean" checked="true" label="Keep all attributes (only if a variable is selected)"/> + </section> + </xml> + <xml name="section_coords"> + <section name="subset_coords" title="Subset by coordinates"> + <conditional name="tsel"> + <param name="by_click" type="select" optional="true" label="Coordinate values"> + <option value="sel">Coordinate values (sel)</option> + <option value="isel">Coordinate indices (isel)</option> + <option value="isel_list" selected="true">Coordinate values from list</option> + </param> + <when value="sel"> + <expand macro="coord_range"> + <param name="method" type="select" multiple="false" label="Choose selection method"> + <option value="None">only exact matches</option> + <option value="nearest">use nearest valid index value</option> + <option value="pad">propagate last valid index value forward</option> + <option value="backfill">propagate next valid index value backward</option> + </param> + </expand> + </when> + <when value="isel"> + <expand macro="coord_range"/> + </when> + <when value="isel_list"> + <repeat name="user_choice" title="Filter by coordinate values" min="0" max="20" help="Use this option to filter on the values of the selected coordinate"> + <param name="dim" type="select" label="Dimensions"> + <options from_dataset="var_tab"> + <column name="value" index="0"/> + </options> + </param> + <param type="data" label="Tabular containing values of this dimension" name="dim_tab" format="tabular" help="File containing values for this dimension."/> + <conditional name="condi_between"> + <param name="comparator" type="select" label="Comparator"> + <option value="is">is</option> + <option value="from">from</option> + <option value="to">to</option> + <option value="sl">slice(threshold1,threshold2)</option> + </param> + <when value="sl"> + <param name="t1" type="select" multiple="false" label="Choose the start value for slice"> + <options from_dataset="dim_tab"> + <column name="name" index="1"/> + <column name="value" index="0"/> + </options> + </param> + <param name="t2" type="select" multiple="false" label="Choose the end value for slice"> + <options from_dataset="dim_tab"> + <column name="name" index="1"/> + <column name="value" index="0"/> + </options> + </param> + </when> + <when value="is"> + <param name="value" type="select" multiple="false" label="Choose the value to select"> + <options from_dataset="dim_tab"> + <column name="name" index="1"/> + <column name="value" index="0"/> + </options> + </param> + </when> + <when value="to"> + <param name="value" type="select" multiple="false" label="Choose the end value"> + <options from_dataset="dim_tab"> + <column name="name" index="1"/> + <column name="value" index="0"/> + </options> + </param> + </when> + <when value="from"> + <param name="value" type="select" multiple="false" label="Choose the start value"> + <options from_dataset="dim_tab"> + <column name="name" index="1"/> + <column name="value" index="0"/> + </options> + </param> + </when> + </conditional> + </repeat> + </when> + </conditional> + </section> + </xml> + <xml name="section_where"> + <section name="mask_values" title="Advanced options to mask by values"> + <conditional name="mask_condi"> + <param name="mask_option" type="select" multiple="false" label="Option for masked values"> + <option value="keep" selected="true">Fill with NA</option> + <option value="drop">Drop values</option> + <option value="other">Set constant</option> + </param> + <when value="keep"/> + <when value="drop"/> + <when value="other"> + <param name="set_other" type="float" value="0" label="Value to use for locations in this object where cond is False." /> + </when> + </conditional> + <param name="where_condition" type="data" optional="true" format="txt" label="file containing a where expression" /> + </section> + </xml> +</macros>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/macros_tests_netcdf2netcdf.xml Thu Jan 20 17:07:19 2022 +0000 @@ -0,0 +1,263 @@ +<macros> + <xml name="section_tests"> + <tests> + <test> + <param name="input" value="dataset-ibi-reanalysis-bio-005-003-monthly-regulargrid_1510914389133.nc"/> + <param name="var_tab" value="var_tab_dataset-ibi"/> + <section name="variable"> + <param name="var" value="chl"/> + <param name="scale" value="1000.5"/> + </section> + <section name="subset_coords"> + <conditional name="tsel"> + <param name="by_click" value="isel_list"/> + <repeat name="user_choice"> + <param name="dim" value="time"/> + <conditional name="condi_between"> + <param name="comparator" value="sl"/> + <param name="t1" value="10"/> + <param name="t2" value="12"/> + </conditional> + </repeat> + <repeat name="user_choice"> + <param name="dim" value="latitude"/> + <param name="dim_tab" value="latitude.tabular"/> + <conditional name="condi_between"> + <param name="comparator" value="sl"/> + <param name="t1" value="5"/> + <param name="t2" value="10"/> + </conditional> + </repeat> + <repeat name="user_choice"> + <param name="dim" value="longitude"/> + <param name="dim_tab" value="longitude.tabular"/> + <conditional name="condi_between"> + <param name="comparator" value="sl"/> + <param name="t1" value="4"/> + <param name="t2" value="10"/> + </conditional> + </repeat> + </conditional> + </section> + <output name="output_netcdf" file="small.netcdf" compare="sim_size" delta="1000"/> + </test> + <test> + <param name="input" value="dataset-ibi-reanalysis-bio-005-003-monthly-regulargrid_1510914389133.nc"/> + <param name="var_tab" value="var_tab_dataset-ibi"/> + <section name="variable"> + <param name="var" value="chl"/> + <param name="scale" value="1000.5"/> + <param name="write_all" value="true"/> + <param name="keep_attribute" value="false"/> + </section> + <section name="subset_coords"> + <conditional name="tsel"> + <param name="by_click" value="isel_list"/> + <repeat name="user_choice"> + <param name="dim" value="time"/> + <conditional name="condi_between"> + <param name="comparator" value="sl"/> + <param name="t1" value="10"/> + <param name="t2" value="12"/> + </conditional> + </repeat> + <repeat name="user_choice"> + <param name="dim" value="latitude"/> + <param name="dim_tab" value="latitude.tabular"/> + <conditional name="condi_between"> + <param name="comparator" value="sl"/> + <param name="t1" value="5"/> + <param name="t2" value="10"/> + </conditional> + </repeat> + <repeat name="user_choice"> + <param name="dim" value="longitude"/> + <param name="dim_tab" value="longitude.tabular"/> + <conditional name="condi_between"> + <param name="comparator" value="sl"/> + <param name="t1" value="4"/> + <param name="t2" value="10"/> + </conditional> + </repeat> + </conditional> + </section> + <output name="output_netcdf" file="all.netcdf" compare="sim_size" delta="1000"/> + </test> + <test> + <param name="input" value="dataset-ibi-reanalysis-bio-005-003-monthly-regulargrid_1510914389133.nc"/> + <param name="var_tab" value="var_tab_dataset-ibi"/> + <section name="subset_coords"> + <conditional name="tsel"> + <param name="by_click" value="isel_list"/> + <repeat name="user_choice"> + <param name="dim" value="time"/> + <param name="dim_tab" value="time.tabular"/> + <conditional name="condi_between"> + <param name="comparator" value="to"/> + <param name="value" value="12"/> + </conditional> + </repeat> + <repeat name="user_choice"> + <param name="dim" value="latitude"/> + <param name="dim_tab" value="latitude.tabular"/> + <conditional name="condi_between"> + <param name="comparator" value="is"/> + <param name="value" value="5"/> + </conditional> + </repeat> + <repeat name="user_choice"> + <param name="dim" value="longitude"/> + <param name="dim_tab" value="longitude.tabular"/> + <conditional name="condi_between"> + <param name="comparator" value="is"/> + <param name="value" value="4"/> + </conditional> + </repeat> + </conditional> + </section> + <output name="output_netcdf" file="small_all_variables.netcdf" compare="sim_size" delta="500"/> + </test> + <test> + <param name="input" value="dataset-ibi-reanalysis-bio-005-003-monthly-regulargrid_1510914389133.nc"/> + <param name="var_tab" value="var_tab_dataset-ibi"/> + <section name="subset_coords"> + <conditional name="tsel"> + <param name="by_click" value="isel"/> + <repeat name="user_choice"> + <param name="dim" value="time"/> + <param name="dim_tab" value="time.tabular"/> + <conditional name="condi_between"> + <param name="comparator" value="to"/> + <param name="value" value="12"/> + </conditional> + </repeat> + <repeat name="user_choice"> + <param name="dim" value="latitude"/> + <param name="dim_tab" value="latitude.tabular"/> + <conditional name="condi_between"> + <param name="comparator" value="is"/> + <param name="value" value="5"/> + </conditional> + </repeat> + <repeat name="user_choice"> + <param name="dim" value="longitude"/> + <param name="dim_tab" value="longitude.tabular"/> + <conditional name="condi_between"> + <param name="comparator" value="is"/> + <param name="value" value="4"/> + </conditional> + </repeat> + </conditional> + </section> + <output name="output_netcdf" file="small_all_variables.netcdf" compare="sim_size" delta="500"/> + </test> + <test> + <param name="input" value="dataset-ibi-reanalysis-bio-005-003-monthly-regulargrid_1510914389133.nc"/> + <param name="var_tab" value="var_tab_dataset-ibi"/> + <section name="variable"> + <param name="var" value="chl,nh4"/> + </section> + <output name="output_netcdf" file="chl_nh4.netcdf" compare="sim_size" delta="500"/> + </test> + <test> + <param name="input" value="data_to_20040615.nc,data_from_20040615.nc"/> + <param name="var_tab" value="var_tab_dataset-ibi"/> + <section name="variable"> + <param name="var" value="nh4"/> + </section> + <output name="output_netcdf" file="chl_alltimes.nc" compare="sim_size" delta="500"/> + </test> + <test> + <param name="input" value="dataset-ibi-reanalysis-bio-005-003-monthly-regulargrid_1510914389133.nc"/> + <param name="var_tab" value="var_tab_dataset-ibi"/> + <section name="subset_coords"> + <conditional name="tsel"> + <param name="by_click" value="sel"/> + <repeat name="user_choice"> + <param name="dim" value="latitude"/> + <param name="dim_tab" value="latitude.tabular"/> + <conditional name="condi_between"> + <param name="comparator" value="sl"/> + <param name="t1" value="44.5"/> + <param name="t2" value="45.0"/> + </conditional> + </repeat> + <repeat name="user_choice"> + <param name="dim" value="longitude"/> + <param name="dim_tab" value="longitude.tabular"/> + <conditional name="condi_between"> + <param name="comparator" value="is"/> + <param name="value" value="-3.5"/> + <param name="method" value="nearest"/> + </conditional> + </repeat> + </conditional> + </section> + <output name="output_netcdf" file="select_by_values.netcdf" compare="sim_size" delta="500"/> + </test> + <test> + <param name="input" value="dataset-ibi-reanalysis-bio-005-003-monthly-regulargrid_1510914389133.nc"/> + <param name="var_tab" value="var_tab_dataset-ibi"/> + <section name="variable"> + <param name="var" value="chl,phy"/> + </section> + <section name="mask_values"> + <conditional name="mask_condi"> + <param name="mask_option" value="other"/> + <param name="set_other" value="1000"/> + </conditional> + <param name="where_condition" ftype="txt" value="where_condition.txt"/> + </section> + <output name="output_netcdf" file="chl_phy_where.netcdf" compare="sim_size" delta="500"/> + </test> + <test> + <param name="input" value="dataset-ibi-reanalysis-bio-005-003-monthly-regulargrid_1510914389133.nc"/> + <param name="var_tab" value="var_tab_dataset-ibi"/> + <section name="variable"> + <param name="var" value="chl"/> + <param name="scale" value="1000.5"/> + <param name="write_all" value="true"/> + <param name="keep_attribute" value="true"/> + </section> + <section name="subset_coords"> + <conditional name="tsel"> + <param name="by_click" value="isel_list"/> + <repeat name="user_choice"> + <param name="dim" value="time"/> + <conditional name="condi_between"> + <param name="comparator" value="sl"/> + <param name="t1" value="10"/> + <param name="t2" value="12"/> + </conditional> + </repeat> + <repeat name="user_choice"> + <param name="dim" value="latitude"/> + <param name="dim_tab" value="latitude.tabular"/> + <conditional name="condi_between"> + <param name="comparator" value="sl"/> + <param name="t1" value="0"/> + <param name="t2" value="10"/> + </conditional> + </repeat> + <repeat name="user_choice"> + <param name="dim" value="longitude"/> + <param name="dim_tab" value="longitude.tabular"/> + <conditional name="condi_between"> + <param name="comparator" value="sl"/> + <param name="t1" value="1"/> + <param name="t2" value="20"/> + </conditional> + </repeat> + </conditional> + </section> + <section name="mask_values"> + <conditional name="mask_condi"> + <param name="mask_option" value="drop"/> + </conditional> + <param name="where_condition" ftype="txt" value="where_condition_simple.txt"/> + </section> + <output name="output_netcdf" file="chl_where_drop.netcdf" compare="sim_size" delta="500"/> + </test> + </tests> + </xml> +</macros>
Binary file test-data/dataset-ibi-reanalysis-bio-005-003-monthly-regulargrid_1510914389133_time0.png has changed
Binary file test-data/dataset-ibi-reanalysis-bio-005-003-monthly-regulargrid_1510914389133_time0_title.png has changed
Binary file test-data/dataset-ibi-reanalysis-bio-005-003-monthly-regulargrid_1510914389133_time1.png has changed
Binary file test-data/dataset-ibi-reanalysis-bio-005-003-monthly-regulargrid_1510914389133_time50.png has changed
--- a/test-data/info_file.txt Sun Jun 06 08:51:41 2021 +0000 +++ b/test-data/info_file.txt Thu Jan 20 17:07:19 2022 +0000 @@ -1,9 +1,9 @@ xarray.Dataset { dimensions: + time = 145 ; depth = 1 ; latitude = 97 ; longitude = 103 ; - time = 145 ; variables: float32 phy(time, depth, latitude, longitude) ;
--- a/test-data/version.tabular Sun Jun 06 08:51:41 2021 +0000 +++ b/test-data/version.tabular Thu Jan 20 17:07:19 2022 +0000 @@ -1,1 +1,1 @@ -Galaxy xarray version 0.18.2 +Galaxy xarray version 0.20.2
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test-data/where_condition.txt Thu Jan 20 17:07:19 2022 +0000 @@ -0,0 +1,1 @@ +((chl > 1) | (chl < 45)) & (nh4 > 1)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test-data/where_condition_simple.txt Thu Jan 20 17:07:19 2022 +0000 @@ -0,0 +1,1 @@ +nh4 > 5.15
--- a/xarray_mapplot.py Sun Jun 06 08:51:41 2021 +0000 +++ b/xarray_mapplot.py Thu Jan 20 17:07:19 2022 +0000 @@ -1,457 +1,411 @@ -#!/usr/bin/env python3 -# -# -# usage: xarray_mapplot.py [-h] [--proj PROJ] -# [--cmap CMAP] -# [--output OUTPUT] -# [--time TIMES] -# [--nrow NROW] -# [--ncol NCOL] -# [--title title] -# [--latitude LATITUDE] -# [--longitude LONGITUDE] -# [--land ALPHA-LAND] -# [--ocean ALPHA-OCEAN] -# [--coastline ALPHA-COASTLINE] -# [--borders ALPHA-BORDERS] -# [--xlim "x1,x2"] -# [--ylim "y1,y2"] -# [--range "valmin,valmax"] -# [--threshold VAL] -# [--label label-colorbar] -# [--shift] -# [-v] -# input varname -# -# positional arguments: -# input input filename with geographical coordinates (netCDF -# format) -# varname Specify which variable to plot (case sensitive) -# -# optional arguments: -# -h, --help show this help message and exit -# --proj PROJ Specify the projection on which we draw -# --cmap CMAP Specify which colormap to use for plotting -# --output OUTPUT output filename to store resulting image (png format) -# --time TIMES time index from the file for multiple plots ("0 1 2 3") -# --title plot or subplot title -# --latitude variable name for latitude -# --longitude variable name for longitude -# --land add land on plot with alpha value [0-1] -# --ocean add oceans on plot with alpha value [0-1] -# --coastline add coastline with alpha value [0-1] -# --borders add country borders with alpha value [0-1] -# --xlim limited geographical area longitudes "x1,x2" -# --ylim limited geographical area latitudes "y1,y2" -# --range "valmin,valmax" for plotting -# --threshold do not plot values below threshold -# --label set a label for colormap -# --shift shift longitudes if specified -# -v, --verbose switch on verbose mode -# - -import argparse -import ast -import warnings -from pathlib import Path - -import cartopy.crs as ccrs -import cartopy.feature as feature - -from cmcrameri import cm - -import matplotlib as mpl -mpl.use('Agg') -from matplotlib import pyplot # noqa: I202,E402 - -import xarray as xr # noqa: E402 - - -class MapPlotXr (): - def __init__(self, input, proj, varname, cmap, output, verbose=False, - time=[], title="", latitude="latitude", - longitude="longitude", land=0, ocean=0, - coastline=0, borders=0, xlim=[], ylim=[], - threshold="", label="", shift=False, - range_values=[]): - self.input = input - print("PROJ", proj) - if proj != "" and proj is not None: - self.proj = proj.replace('X', ':') - else: - self.proj = proj - self.varname = varname - self.get_cmap(cmap) - self.time = time - self.latitude = latitude - self.longitude = longitude - self.land = land - self.ocean = ocean - self.coastline = coastline - self.borders = borders - self.xlim = xlim - self.ylim = ylim - self.range = range_values - self.threshold = threshold - self.shift = shift - self.xylim_supported = False - self.colorbar = True - self.title = title - if output is None: - self.output = Path(input).stem + '.png' - else: - self.output = output - self.verbose = verbose - self.dset = xr.open_dataset(self.input, use_cftime=True) - - self.label = {} - if label != "" and label is not None: - self.label['label'] = label - if verbose: - print("input: ", self.input) - print("proj: ", self.proj) - print("varname: ", self.varname) - print("time: ", self.time) - print("minval, maxval: ", self.range) - print("title: ", self.title) - print("output: ", self.output) - print("label: ", self.label) - print("shift: ", self.shift) - print("ocean: ", self.ocean) - print("land: ", self.land) - print("coastline: ", self.coastline) - print("borders: ", self.borders) - print("latitude: ", self.latitude) - print("longitude: ", self.longitude) - print("xlim: ", self.xlim) - print("ylim: ", self.ylim) - - def get_cmap(self, cmap): - if cmap[0:3] == 'cm.': - self.cmap = cm.__dict__[cmap[3:]] - else: - self.cmap = cmap - - def projection(self): - if self.proj is None: - return ccrs.PlateCarree() - - proj_dict = ast.literal_eval(self.proj) - - user_proj = proj_dict.pop("proj") - if user_proj == 'PlateCarree': - self.xylim_supported = True - return ccrs.PlateCarree(**proj_dict) - elif user_proj == 'AlbersEqualArea': - return ccrs.AlbersEqualArea(**proj_dict) - elif user_proj == 'AzimuthalEquidistant': - return ccrs.AzimuthalEquidistant(**proj_dict) - elif user_proj == 'EquidistantConic': - return ccrs.EquidistantConic(**proj_dict) - elif user_proj == 'LambertConformal': - return ccrs.LambertConformal(**proj_dict) - elif user_proj == 'LambertCylindrical': - return ccrs.LambertCylindrical(**proj_dict) - elif user_proj == 'Mercator': - return ccrs.Mercator(**proj_dict) - elif user_proj == 'Miller': - return ccrs.Miller(**proj_dict) - elif user_proj == 'Mollweide': - return ccrs.Mollweide(**proj_dict) - elif user_proj == 'Orthographic': - return ccrs.Orthographic(**proj_dict) - elif user_proj == 'Robinson': - return ccrs.Robinson(**proj_dict) - elif user_proj == 'Sinusoidal': - return ccrs.Sinusoidal(**proj_dict) - elif user_proj == 'Stereographic': - return ccrs.Stereographic(**proj_dict) - elif user_proj == 'TransverseMercator': - return ccrs.TransverseMercator(**proj_dict) - elif user_proj == 'UTM': - return ccrs.UTM(**proj_dict) - elif user_proj == 'InterruptedGoodeHomolosine': - return ccrs.InterruptedGoodeHomolosine(**proj_dict) - elif user_proj == 'RotatedPole': - return ccrs.RotatedPole(**proj_dict) - elif user_proj == 'OSGB': - self.xylim_supported = False - return ccrs.OSGB(**proj_dict) - elif user_proj == 'EuroPP': - self.xylim_supported = False - return ccrs.EuroPP(**proj_dict) - elif user_proj == 'Geostationary': - return ccrs.Geostationary(**proj_dict) - elif user_proj == 'NearsidePerspective': - return ccrs.NearsidePerspective(**proj_dict) - elif user_proj == 'EckertI': - return ccrs.EckertI(**proj_dict) - elif user_proj == 'EckertII': - return ccrs.EckertII(**proj_dict) - elif user_proj == 'EckertIII': - return ccrs.EckertIII(**proj_dict) - elif user_proj == 'EckertIV': - return ccrs.EckertIV(**proj_dict) - elif user_proj == 'EckertV': - return ccrs.EckertV(**proj_dict) - elif user_proj == 'EckertVI': - return ccrs.EckertVI(**proj_dict) - elif user_proj == 'EqualEarth': - return ccrs.EqualEarth(**proj_dict) - elif user_proj == 'Gnomonic': - return ccrs.Gnomonic(**proj_dict) - elif user_proj == 'LambertAzimuthalEqualArea': - return ccrs.LambertAzimuthalEqualArea(**proj_dict) - elif user_proj == 'NorthPolarStereo': - return ccrs.NorthPolarStereo(**proj_dict) - elif user_proj == 'OSNI': - return ccrs.OSNI(**proj_dict) - elif user_proj == 'SouthPolarStereo': - return ccrs.SouthPolarStereo(**proj_dict) - - def plot(self, ts=None): - if self.shift: - if self.longitude == 'longitude': - self.dset = self.dset.assign_coords( - longitude=((( - self.dset[self.longitude] - + 180) % 360) - 180)) - elif self.longitude == 'lon': - self.dset = self.dset.assign_coords( - lon=(((self.dset[self.longitude] - + 180) % 360) - 180)) - - pyplot.figure(1, figsize=[20, 10]) - - # Set the projection to use for plotting - ax = pyplot.subplot(1, 1, 1, projection=self.projection()) - if self.land: - ax.add_feature(feature.LAND, alpha=self.land) - - if self.ocean: - ax.add_feature(feature.OCEAN, alpha=self.ocean) - if self.coastline: - ax.coastlines(resolution='10m', alpha=self.coastline) - if self.borders: - ax.add_feature(feature.BORDERS, linestyle=':', alpha=self.borders) - - if self.xlim: - min_lon = min(self.xlim[0], self.xlim[1]) - max_lon = max(self.xlim[0], self.xlim[1]) - else: - min_lon = self.dset[self.longitude].min() - max_lon = self.dset[self.longitude].max() - - if self.ylim: - min_lat = min(self.ylim[0], self.ylim[1]) - max_lat = max(self.ylim[0], self.ylim[1]) - else: - min_lat = self.dset[self.latitude].min() - max_lat = self.dset[self.latitude].max() - - if self.xylim_supported: - pyplot.xlim(min_lon, max_lon) - pyplot.ylim(min_lat, max_lat) - - # Fix extent - if self.threshold == "" or self.threshold is None: - threshold = self.dset[self.varname].min() - else: - threshold = float(self.threshold) - - if self.range == []: - minval = self.dset[self.varname].min() - maxval = self.dset[self.varname].max() - else: - minval = self.range[0] - maxval = self.range[1] - - if self.verbose: - print("minval: ", minval) - print("maxval: ", maxval) - - # pass extent with vmin and vmax parameters - proj_t = ccrs.PlateCarree() - if ts is None: - self.dset.where( - self.dset[self.varname] > threshold - )[self.varname].plot(ax=ax, - vmin=minval, - vmax=maxval, - transform=proj_t, - cmap=self.cmap, - cbar_kwargs=self.label - ) - if self.title != "" and self.title is not None: - pyplot.title(self.title) - pyplot.savefig(self.output) - else: - if self.colorbar: - self.dset.where( - self.dset[self.varname] > threshold - )[self.varname].isel(time=ts).plot(ax=ax, - vmin=minval, - vmax=maxval, - transform=proj_t, - cmap=self.cmap, - cbar_kwargs=self.label - ) - else: - self.dset.where( - self.dset[self.varname] > minval - )[self.varname].isel(time=ts).plot(ax=ax, - vmin=minval, - vmax=maxval, - transform=proj_t, - cmap=self.cmap, - add_colorbar=False) - if self.title != "" and self.title is not None: - pyplot.title(self.title + "(time = " + str(ts) + ')') - pyplot.savefig(self.output[:-4] + "_time" + str(ts) + - self.output[-4:]) # assume png format - - -if __name__ == '__main__': - warnings.filterwarnings("ignore") - parser = argparse.ArgumentParser() - parser.add_argument( - 'input', - help='input filename with geographical coordinates (netCDF format)' - ) - - parser.add_argument( - '--proj', - help='Specify the projection on which we draw' - ) - parser.add_argument( - 'varname', - help='Specify which variable to plot (case sensitive)' - ) - parser.add_argument( - '--cmap', - help='Specify which colormap to use for plotting' - ) - parser.add_argument( - '--output', - help='output filename to store resulting image (png format)' - ) - parser.add_argument( - '--time', - help='list of times to plot for multiple plots' - ) - parser.add_argument( - '--title', - help='plot title' - ) - parser.add_argument( - '--latitude', - help='variable name for latitude' - ) - parser.add_argument( - '--longitude', - help='variable name for longitude' - ) - parser.add_argument( - '--land', - help='add land on plot with alpha value [0-1]' - ) - parser.add_argument( - '--ocean', - help='add oceans on plot with alpha value [0-1]' - ) - parser.add_argument( - '--coastline', - help='add coastline with alpha value [0-1]' - ) - parser.add_argument( - '--borders', - help='add country borders with alpha value [0-1]' - ) - parser.add_argument( - '--xlim', - help='limited geographical area longitudes "x1,x2"' - ) - parser.add_argument( - '--ylim', - help='limited geographical area latitudes "y1,y2"' - ) - parser.add_argument( - '--range', - help='min and max values for plotting "minval,maxval"' - ) - parser.add_argument( - '--threshold', - help='do not plot values below threshold' - ) - parser.add_argument( - '--label', - help='set a label for colorbar' - ) - parser.add_argument( - '--shift', - help='shift longitudes if specified', - action="store_true" - ) - parser.add_argument( - "-v", "--verbose", - help="switch on verbose mode", - action="store_true") - args = parser.parse_args() - - if args.time is None: - time = [] - else: - time = list(map(int, args.time.split(","))) - if args.xlim is None: - xlim = [] - else: - xlim = list(map(float, args.xlim.split(","))) - if args.ylim is None: - ylim = [] - else: - ylim = list(map(float, args.ylim.split(","))) - if args.range is None: - range_values = [] - else: - range_values = list(map(float, args.range.split(","))) - if args.latitude is None: - latitude = "latitude" - else: - latitude = args.latitude - if args.longitude is None: - longitude = "longitude" - else: - longitude = args.longitude - if args.land is None: - land = 0 - else: - land = float(args.land) - if args.ocean is None: - ocean = 0 - else: - ocean = float(args.ocean) - if args.coastline is None: - coastline = 0 - else: - coastline = float(args.coastline) - if args.borders is None: - borders = 0 - else: - borders = float(args.borders) - - dset = MapPlotXr(input=args.input, proj=args.proj, varname=args.varname, - cmap=args.cmap, output=args.output, verbose=args.verbose, - time=time, title=args.title, - latitude=latitude, longitude=longitude, land=land, - ocean=ocean, coastline=coastline, borders=borders, - xlim=xlim, ylim=ylim, threshold=args.threshold, - label=args.label, shift=args.shift, - range_values=range_values) - - if dset.time == []: - dset.plot() - else: - for t in dset.time: - dset.plot(t) - dset.shift = False # only shift once - dset.colorbar = True +#!/usr/bin/env python3 +# +# +# usage: xarray_mapplot.py [-h] [--proj PROJ] +# [--cmap CMAP] +# [--output OUTPUT] +# [--time TIMES] +# [--nrow NROW] +# [--ncol NCOL] +# [--title title] +# [--latitude LATITUDE] +# [--longitude LONGITUDE] +# [--land ALPHA-LAND] +# [--ocean ALPHA-OCEAN] +# [--coastline ALPHA-COASTLINE] +# [--borders ALPHA-BORDERS] +# [--xlim "x1,x2"] +# [--ylim "y1,y2"] +# [--range "valmin,valmax"] +# [--threshold VAL] +# [--label label-colorbar] +# [--config config-file] +# [--shift] +# [-v] +# input varname +# +# positional arguments: +# input input filename with geographical coordinates (netCDF +# format) +# varname Specify which variable to plot (case sensitive) +# +# optional arguments: +# -h, --help show this help message and exit +# --proj PROJ Specify the projection on which we draw +# --cmap CMAP Specify which colormap to use for plotting +# --output OUTPUT output filename to store resulting image (png format) +# --time TIMES time index from the file for multiple plots ("0 1 2 3") +# --title plot or subplot title +# --latitude variable name for latitude +# --longitude variable name for longitude +# --land add land on plot with alpha value [0-1] +# --ocean add oceans on plot with alpha value [0-1] +# --coastline add coastline with alpha value [0-1] +# --borders add country borders with alpha value [0-1] +# --xlim limited geographical area longitudes "x1,x2" +# --ylim limited geographical area latitudes "y1,y2" +# --range "valmin,valmax" for plotting +# --threshold do not plot values below threshold +# --label set a label for colormap +# --config plotting parameters are passed via a config file +# (overwrite other plotting options) +# --shift shift longitudes if specified +# -v, --verbose switch on verbose mode +# + +import argparse +import ast +import warnings +from pathlib import Path + +import cartopy.crs as ccrs +import cartopy.feature as feature + +from cmcrameri import cm + +import matplotlib as mpl +mpl.use('Agg') +from matplotlib import pyplot # noqa: I202,E402 + +import xarray as xr # noqa: E402 + + +class MapPlotXr (): + def __init__(self, input, varname, output, verbose=False, + config_file="", proj="", shift=False): + + li = list(input.split(",")) + if len(li) > 1: + self.input = li + else: + self.input = input + + if proj != "" and proj is not None and Path(proj).exists(): + f = open(proj) + sdict = ''.join( + f.read().replace("\n", "").split('{')[1].split('}')[0] + ) + self.proj = '{' + sdict.strip() + '}' + else: + self.proj = None + self.varname = varname + self.shift = shift + self.xylim_supported = False + self.colorbar = True + if output is None: + if type(self.input) is list: + self.output = Path(self.input[0]).stem + '.png' + else: + self.output = Path(self.input).stem + '.png' + else: + self.output = output + self.verbose = verbose + self.label = {} + self.time = [] + self.xlim = [] + self.ylim = [] + self.range = [] + self.latitude = "latitude" + self.longitude = "longitude" + self.land = 0 + self.ocean = 0 + self.coastline = 0 + self.borders = 0 + self.cmap = "coolwarm" + self.threshold = "" + self.title = "" + + if config_file != "" and config_file is not None: + with open(config_file) as f: + sdict = ''.join( + f.read().replace("\n", "").split('{')[1].split('}')[0] + ) + tmp = ast.literal_eval('{' + sdict.strip() + '}') + for key in tmp: + if key == 'time': + time = tmp[key] + self.time = list(map(int, time.split(","))) + if key == 'cmap': + self.get_cmap(tmp[key]) + if key == 'latitude': + self.latitude = tmp[key] + if key == 'longitude': + self.longitude = tmp[key] + if key == 'land': + self.land = float(tmp[key]) + if key == 'ocean': + self.ocean = float(tmp[key]) + if key == 'coastline': + self.coastline = float(tmp[key]) + if key == 'borders': + self.borders = float(tmp[key]) + if key == 'xlim': + xlim = tmp[key] + self.xlim = list(map(float, xlim.split(","))) + if key == 'ylim': + ylim = tmp[key] + self.ylim = list(map(float, ylim.split(","))) + if key == 'range': + range_values = tmp[key] + self.range = list(map(float, range_values.split(","))) + if key == 'threshold': + self.threshold = float(tmp[key]) + if key == 'label': + self.label['label'] = tmp[key] + if key == 'title': + self.title = tmp[key] + + if type(self.input) is list: + self.dset = xr.open_mfdataset(self.input, use_cftime=True) + else: + self.dset = xr.open_dataset(self.input, use_cftime=True) + + if verbose: + print("input: ", self.input) + print("proj: ", self.proj) + print("varname: ", self.varname) + print("time: ", self.time) + print("minval, maxval: ", self.range) + print("title: ", self.title) + print("output: ", self.output) + print("label: ", self.label) + print("shift: ", self.shift) + print("ocean: ", self.ocean) + print("land: ", self.land) + print("coastline: ", self.coastline) + print("borders: ", self.borders) + print("latitude: ", self.latitude) + print("longitude: ", self.longitude) + print("xlim: ", self.xlim) + print("ylim: ", self.ylim) + + def get_cmap(self, cmap): + if cmap[0:3] == 'cm.': + self.cmap = cm.__dict__[cmap[3:]] + else: + self.cmap = cmap + + def projection(self): + if self.proj is None: + return ccrs.PlateCarree() + + proj_dict = ast.literal_eval(self.proj) + user_proj = proj_dict.pop("proj") + if user_proj == 'PlateCarree': + self.xylim_supported = True + return ccrs.PlateCarree(**proj_dict) + elif user_proj == 'AlbersEqualArea': + return ccrs.AlbersEqualArea(**proj_dict) + elif user_proj == 'AzimuthalEquidistant': + return ccrs.AzimuthalEquidistant(**proj_dict) + elif user_proj == 'EquidistantConic': + return ccrs.EquidistantConic(**proj_dict) + elif user_proj == 'LambertConformal': + return ccrs.LambertConformal(**proj_dict) + elif user_proj == 'LambertCylindrical': + return ccrs.LambertCylindrical(**proj_dict) + elif user_proj == 'Mercator': + return ccrs.Mercator(**proj_dict) + elif user_proj == 'Miller': + return ccrs.Miller(**proj_dict) + elif user_proj == 'Mollweide': + return ccrs.Mollweide(**proj_dict) + elif user_proj == 'Orthographic': + return ccrs.Orthographic(**proj_dict) + elif user_proj == 'Robinson': + return ccrs.Robinson(**proj_dict) + elif user_proj == 'Sinusoidal': + return ccrs.Sinusoidal(**proj_dict) + elif user_proj == 'Stereographic': + return ccrs.Stereographic(**proj_dict) + elif user_proj == 'TransverseMercator': + return ccrs.TransverseMercator(**proj_dict) + elif user_proj == 'UTM': + return ccrs.UTM(**proj_dict) + elif user_proj == 'InterruptedGoodeHomolosine': + return ccrs.InterruptedGoodeHomolosine(**proj_dict) + elif user_proj == 'RotatedPole': + return ccrs.RotatedPole(**proj_dict) + elif user_proj == 'OSGB': + self.xylim_supported = False + return ccrs.OSGB(**proj_dict) + elif user_proj == 'EuroPP': + self.xylim_supported = False + return ccrs.EuroPP(**proj_dict) + elif user_proj == 'Geostationary': + return ccrs.Geostationary(**proj_dict) + elif user_proj == 'NearsidePerspective': + return ccrs.NearsidePerspective(**proj_dict) + elif user_proj == 'EckertI': + return ccrs.EckertI(**proj_dict) + elif user_proj == 'EckertII': + return ccrs.EckertII(**proj_dict) + elif user_proj == 'EckertIII': + return ccrs.EckertIII(**proj_dict) + elif user_proj == 'EckertIV': + return ccrs.EckertIV(**proj_dict) + elif user_proj == 'EckertV': + return ccrs.EckertV(**proj_dict) + elif user_proj == 'EckertVI': + return ccrs.EckertVI(**proj_dict) + elif user_proj == 'EqualEarth': + return ccrs.EqualEarth(**proj_dict) + elif user_proj == 'Gnomonic': + return ccrs.Gnomonic(**proj_dict) + elif user_proj == 'LambertAzimuthalEqualArea': + return ccrs.LambertAzimuthalEqualArea(**proj_dict) + elif user_proj == 'NorthPolarStereo': + return ccrs.NorthPolarStereo(**proj_dict) + elif user_proj == 'OSNI': + return ccrs.OSNI(**proj_dict) + elif user_proj == 'SouthPolarStereo': + return ccrs.SouthPolarStereo(**proj_dict) + + def plot(self, ts=None): + if self.shift: + if self.longitude == 'longitude': + self.dset = self.dset.assign_coords( + longitude=((( + self.dset[self.longitude] + + 180) % 360) - 180)) + elif self.longitude == 'lon': + self.dset = self.dset.assign_coords( + lon=(((self.dset[self.longitude] + + 180) % 360) - 180)) + + pyplot.figure(1, figsize=[20, 10]) + + # Set the projection to use for plotting + ax = pyplot.subplot(1, 1, 1, projection=self.projection()) + if self.land: + ax.add_feature(feature.LAND, alpha=self.land) + + if self.ocean: + ax.add_feature(feature.OCEAN, alpha=self.ocean) + if self.coastline: + ax.coastlines(resolution='10m', alpha=self.coastline) + if self.borders: + ax.add_feature(feature.BORDERS, linestyle=':', alpha=self.borders) + + if self.xlim: + min_lon = min(self.xlim[0], self.xlim[1]) + max_lon = max(self.xlim[0], self.xlim[1]) + else: + min_lon = self.dset[self.longitude].min() + max_lon = self.dset[self.longitude].max() + + if self.ylim: + min_lat = min(self.ylim[0], self.ylim[1]) + max_lat = max(self.ylim[0], self.ylim[1]) + else: + min_lat = self.dset[self.latitude].min() + max_lat = self.dset[self.latitude].max() + + if self.xylim_supported: + pyplot.xlim(min_lon, max_lon) + pyplot.ylim(min_lat, max_lat) + + # Fix extent + if self.threshold == "" or self.threshold is None: + threshold = self.dset[self.varname].min() + else: + threshold = float(self.threshold) + + if self.range == []: + minval = self.dset[self.varname].min() + maxval = self.dset[self.varname].max() + else: + minval = self.range[0] + maxval = self.range[1] + + if self.verbose: + print("minval: ", minval) + print("maxval: ", maxval) + + # pass extent with vmin and vmax parameters + proj_t = ccrs.PlateCarree() + if ts is None: + self.dset.where( + self.dset[self.varname] > threshold + )[self.varname].plot(ax=ax, + vmin=minval, + vmax=maxval, + transform=proj_t, + cmap=self.cmap, + cbar_kwargs=self.label + ) + if self.title != "" and self.title is not None: + pyplot.title(self.title) + pyplot.savefig(self.output) + else: + if self.colorbar: + self.dset.where( + self.dset[self.varname] > threshold + )[self.varname].isel(time=ts).plot(ax=ax, + vmin=minval, + vmax=maxval, + transform=proj_t, + cmap=self.cmap, + cbar_kwargs=self.label + ) + else: + self.dset.where( + self.dset[self.varname] > minval + )[self.varname].isel(time=ts).plot(ax=ax, + vmin=minval, + vmax=maxval, + transform=proj_t, + cmap=self.cmap, + add_colorbar=False) + if self.title != "" and self.title is not None: + pyplot.title(self.title + "(time = " + str(ts) + ')') + pyplot.savefig(self.output[:-4] + "_time" + str(ts) + + self.output[-4:]) # assume png format + + +if __name__ == '__main__': + warnings.filterwarnings("ignore") + parser = argparse.ArgumentParser() + parser.add_argument( + 'input', + help='input filename with geographical coordinates (netCDF format)' + ) + parser.add_argument( + '--proj', + help='Config file with the projection on which we draw' + ) + parser.add_argument( + 'varname', + help='Specify which variable to plot (case sensitive)' + ) + parser.add_argument( + '--output', + help='output filename to store resulting image (png format)' + ) + parser.add_argument( + '--config', + help='pass plotting parameters via a config file' + ) + parser.add_argument( + '--shift', + help='shift longitudes if specified', + action="store_true" + ) + parser.add_argument( + "-v", "--verbose", + help="switch on verbose mode", + action="store_true") + args = parser.parse_args() + + dset = MapPlotXr(input=args.input, varname=args.varname, + output=args.output, verbose=args.verbose, + config_file=args.config, proj=args.proj, + shift=args.shift) + + if dset.time == []: + dset.plot() + else: + for t in dset.time: + dset.plot(t) + dset.shift = False # only shift once + dset.colorbar = True
--- a/xarray_netcdf2netcdf.py Sun Jun 06 08:51:41 2021 +0000 +++ b/xarray_netcdf2netcdf.py Thu Jan 20 17:07:19 2022 +0000 @@ -1,133 +1,268 @@ -#!/usr/bin/env python3 -# -# Apply operations on selected variables -# - scale -# one can also select the range of time (for timeseries) -# to apply these operations over the range only -# when a range of time is selected and when scaling, one -# can choose to save the entire timeseries or -# the selected range only. -# when scaling, one can add additional filters on dimensions -# (typically used to filter over latitudes and longitudes) - - -import argparse -import warnings - -import xarray as xr # noqa: E402 - - -class netCDF2netCDF (): - def __init__(self, infile, varname, scale="", - output="output.netcdf", - write_all=False, - filter_list="", - verbose=False): - self.infile = infile - self.verbose = verbose - self.varname = varname - self.write_all = write_all - self.filter = filter_list - self.selection = {} - if scale == "" or scale is None: - self.scale = 1 - else: - self.scale = float(scale) - if output is None: - self.output = "output.netcdf" - else: - self.output = output - # initialization - self.dset = None - self.subset = None - if self.verbose: - print("infile: ", self.infile) - print("varname: ", self.varname) - print("filter_list: ", self.filter) - print("scale: ", self.scale) - print("write_all: ", self.write_all) - print("output: ", self.output) - - def dimension_selection(self, single_filter): - split_filter = single_filter.split('#') - dimension_varname = split_filter[0] - op = split_filter[1] - ll = int(split_filter[2]) - if (op == 'sl'): - rl = int(split_filter[3]) - self.selection[dimension_varname] = slice(ll, rl) - elif (op == 'to'): - self.selection[dimension_varname] = slice(None, ll) - elif (op == 'from'): - self.selection[dimension_varname] = slice(ll, None) - elif (op == 'is'): - self.selection[dimension_varname] = ll - - def filter_selection(self): - for single_filter in self.filter: - self.dimension_selection(single_filter) - if self.write_all: - self.ds[self.varname] = \ - self.ds[self.varname].isel(self.selection)*self.scale - else: - self.dset = \ - self.ds[self.varname].isel(self.selection)*self.scale - - def compute(self): - if self.dset is None: - self.ds = xr.open_dataset(self.infile) - if self.filter: - self.filter_selection() - if self.verbose: - print(self.selection) - elif self.write_all is not None: - self.dset = self.ds[self.varname] - - def save(self): - if self.write_all: - self.ds.to_netcdf(self.output) - else: - self.dset.to_netcdf(self.output) - - -if __name__ == '__main__': - warnings.filterwarnings("ignore") - parser = argparse.ArgumentParser() - parser.add_argument( - 'input', - help='input filename in netCDF format' - ) - parser.add_argument( - 'varname', - help='Specify which variable to plot (case sensitive)' - ) - parser.add_argument( - '--filter', - nargs="*", - help='Filter list variable#operator#value_s#value_e' - ) - parser.add_argument( - '--output', - help='Output filename to store the resulting netCDF file' - ) - parser.add_argument( - '--scale', - help='scale factor to apply to selection (float)' - ) - parser.add_argument( - "--write_all", - help="write all data to netCDF", - action="store_true") - parser.add_argument( - "-v", "--verbose", - help="switch on verbose mode", - action="store_true") - args = parser.parse_args() - - dset = netCDF2netCDF(infile=args.input, varname=args.varname, - scale=args.scale, output=args.output, - filter_list=args.filter, - write_all=args.write_all, - verbose=args.verbose) - dset.compute() - dset.save() +#!/usr/bin/env python3 +# +# Apply operations on selected variables +# - scale +# one can also select the range of time (for timeseries) +# to apply these operations over the range only +# when a range of time is selected and when scaling, one +# can choose to save the entire timeseries or +# the selected range only. +# when scaling, one can add additional filters on dimensions +# (typically used to filter over latitudes and longitudes) + + +import argparse +import re +import warnings +from pathlib import Path + +import xarray as xr # noqa: E402 + + +class netCDF2netCDF (): + def __init__(self, infile, varname, scale="", + output="output.netcdf", + write_all=False, + keep_attributes=True, + filter_list="", + where_config="", + other="", + sel=False, + drop=False, + verbose=False): + self.drop = drop + if Path(where_config).exists(): + f = open(where_config) + self.where = f.read().replace("\n", "") + else: + self.where = "" + self.other = other + self.sel = sel + li = list(infile.split(",")) + if len(li) > 1: + self.infile = li + else: + self.infile = infile + self.verbose = verbose + if varname == 'None' or varname is None: + self.varname = varname + else: + li = list(varname.split(",")) + self.varname = li + self.write_all = write_all + self.keep_attributes = keep_attributes + if self.keep_attributes: + xr.set_options(keep_attrs=True) + self.filter = filter_list + self.selection = {} + self.method = {} + if scale == "" or scale is None: + self.scale = 1 + else: + self.scale = float(scale) + if output is None: + self.output = "output.netcdf" + else: + self.output = output + # initialization + self.dset = None + self.subset = None + if self.verbose: + print("infile: ", self.infile) + print("varname: ", self.varname) + print("filter_list: ", self.filter) + print("scale: ", self.scale) + print("write_all: ", self.write_all) + print("keep_attributes: ", self.keep_attributes) + print("sel: ", self.sel) + print("output: ", self.output) + + def apply_selection(self): + self.dset = self.ds + for key in self.selection: + if 'slice' in str(self.selection[key]): + self.dset = self.dset.sel( + {key: self.selection[key]} + ) + else: + self.dset = self.dset.sel( + {key: self.selection[key]}, + method=self.method[key] + ) + + def dimension_selection(self, single_filter): + split_filter = single_filter.split('#') + dimension_varname = split_filter[0] + op = split_filter[1] + if self.sel: + ll = float(split_filter[2]) + else: + ll = int(split_filter[2]) + if (op == 'sl'): + if self.sel: + rl = float(split_filter[3]) + else: + rl = int(split_filter[3]) + self.selection[dimension_varname] = slice(ll, rl) + elif (op == 'to'): + self.selection[dimension_varname] = slice(None, ll) + elif (op == 'from'): + self.selection[dimension_varname] = slice(ll, None) + elif (op == 'is'): + self.selection[dimension_varname] = ll + if self.sel: + rl = split_filter[3] + if 'None' in rl: + self.method[dimension_varname] = None + else: + self.method[dimension_varname] = rl + + def filter_selection(self): + for single_filter in self.filter: + self.dimension_selection(single_filter) + + if self.sel: + self.apply_selection() + else: + self.dset = \ + self.ds.isel(self.selection) + + if self.varname != 'None' and self.varname is not None: + for var in self.varname: + self.dset[var] = \ + self.dset[var]*self.scale + + def compute(self): + if self.dset is None: + if type(self.infile) is list: + self.ds = xr.open_mfdataset(self.infile) + else: + self.ds = xr.open_dataset(self.infile) + if self.where != "": + if self.drop: + if self.verbose: + print("Where with drop=True") + self.ds = self.ds.where( + self.eval_where(self.where), + drop=True + ) + elif self.other is not None and self.other != "": + if self.verbose: + print("Where with other=", float(self.other)) + self.ds = self.ds.where( + self.eval_where(self.where), + other=float(self.other) + ) + else: + self.ds = self.ds.where( + self.eval_where(self.where) + ) + self.filter_selection() + if self.verbose: + print(self.selection) + + def save(self): + if self.varname != 'None' and \ + self.varname is not None and \ + not self.write_all: + self.dset[self.varname].to_netcdf(self.output) + else: + self.dset.to_netcdf(self.output) + + def is_float(self, element) -> bool: + try: + float(element) + return True + except ValueError: + return False + + def eval_where(self, where_condition): + eval_cond = None + list_names = list(set( + list(self.ds.keys()) + + list(self.ds.coords.keys())) + ) + wcond = where_condition + check_cond = where_condition + for var in list_names: + wcond = wcond.replace(var, ' self.ds.' + var + ' ') + check_cond = check_cond.replace(var, '') + to_remove = "[><=&|()]" + check_cond = re.sub(to_remove, "", check_cond).replace("!", "") + check_cond = re.sub(' +', ' ', check_cond).strip() + list_flt = check_cond.split(" ") + no_convert = False + for num in list_flt: + if not self.is_float(num): + no_convert = True + if not no_convert: + eval_cond = eval(wcond) + return eval_cond + + +if __name__ == '__main__': + warnings.filterwarnings("ignore") + parser = argparse.ArgumentParser() + parser.add_argument( + 'input', + help='input filename in netCDF format' + ) + parser.add_argument( + 'varname', + help='Specify which variable to plot (case sensitive)' + ) + parser.add_argument( + '--filter', + nargs="*", + help='Filter list variable#operator#value_s#value_e' + ) + parser.add_argument( + '--where', + help='filename with where condition to be evaluated' + ) + parser.add_argument( + '--output', + help='Output filename to store the resulting netCDF file' + ) + parser.add_argument( + '--scale', + help='scale factor to apply to selection (float)' + ) + parser.add_argument( + '--other', + help='Value to use for locations where condition is False (float)' + ) + parser.add_argument( + "--write_all", + help="write all data to netCDF", + action="store_true") + parser.add_argument( + "--keep_attributes", + help="Keep all attributes", + action="store_true") + parser.add_argument( + "-v", "--verbose", + help="switch on verbose mode", + action="store_true") + parser.add_argument( + "--selection", + help="select by values", + action="store_true") + parser.add_argument( + "--drop", + help="drop values where condition is not met", + action="store_true") + args = parser.parse_args() + + print("args.selection", args.selection) + dset = netCDF2netCDF(infile=args.input, varname=args.varname, + scale=args.scale, output=args.output, + write_all=args.write_all, + sel=args.selection, + keep_attributes=args.keep_attributes, + filter_list=args.filter, + where_config=args.where, + drop=args.drop, other=args.other, + verbose=args.verbose) + dset.compute() + dset.save()
--- a/xarray_select.xml Sun Jun 06 08:51:41 2021 +0000 +++ b/xarray_select.xml Thu Jan 20 17:07:19 2022 +0000 @@ -1,317 +1,317 @@ -<tool id="xarray_select" name="NetCDF xarray Selection" version="@TOOL_VERSION@+galaxy@VERSION_SUFFIX@"> - <description>extracts variable values with custom conditions on dimensions</description> - <macros> - <import>macros.xml</import> - </macros> - <expand macro="edam_ontology"/> - <requirements> - <requirement type="package" version="3">python</requirement> - <requirement type="package" version="1.5.6">netcdf4</requirement> - <requirement type="package" version="@TOOL_VERSION@">xarray</requirement> - <requirement type="package" version="0.9.0">geopandas</requirement> - <requirement type="package" version="1.7.1">shapely</requirement> - </requirements> - <command detect_errors="exit_code"><![CDATA[ - mkdir output_dir && - #if $condi_source_coord.coord_source=="coord_from_file" - echo "Galaxy xarray version @TOOL_VERSION@" > output_dir/version.tabular && - #end if - python '$__tool_directory__/xarray_tool.py' '$input' --select '$var' - --verbose - --filter - #for $i,$uc in enumerate($user_choice) - #if $uc.condi_between.comparator=="bi" - '${uc.dim}#${uc.condi_between.comparator}#${uc.condi_between.t1}#${uc.condi_between.t2}' - #else - '${uc.dim}#${uc.condi_between.comparator}#${uc.condi_between.value}' - #end if - #end for - - #if $time.condi_datetime.datetime=="yes" - --time - #if $time.condi_datetime.condi_between.comparator=="sl" - '${time.condi_datetime.dim}#${time.condi_datetime.condi_between.comparator}#${time.condi_datetime.condi_between.t1}#${time.condi_datetime.condi_between.t2}' - #else - '${time.condi_datetime.dim}#${time.condi_datetime.condi_between.comparator}#${time.condi_datetime.condi_between.t1}' - #end if - #end if - - #if $condi_source_coord.coord_source=="coord_from_file" - --coords '$coord_tabular' - --latname '$condi_source_coord.lat_dim' --lonname '$condi_source_coord.lon_dim' - --outputdir output_dir - #if $condi_source_coord.tolerance - --tolerance '$condi_source_coord.tolerance' - #end if - #else - --outfile 'final.tabular' - #if $condi_source_coord.condi_coord.coord=='single' - --latname $condi_source_coord.condi_coord.lat_dim - --latvalN $condi_source_coord.condi_coord.lat_val - --lonname $condi_source_coord.condi_coord.lon_dim - --lonvalE $condi_source_coord.condi_coord.lon_val - #if $condi_source_coord.condi_coord.no_missing - --no_missing - #end if - #if $condi_source_coord.condi_coord.tolerance - --tolerance '$condi_source_coord.condi_coord.tolerance' - #end if - #elif $condi_source_coord.condi_coord.coord=='subregion' - --latname $condi_source_coord.condi_coord.lat_dim - --latvalN $condi_source_coord.condi_coord.lat_valN - --latvalS $condi_source_coord.condi_coord.lat_valS - --lonname $condi_source_coord.condi_coord.lon_dim - --lonvalE $condi_source_coord.condi_coord.lon_valE - --lonvalW $condi_source_coord.condi_coord.lon_valW - #end if - #end if - ]]></command> - <inputs> - <param type="data" name="input" label="Input netcdf file" format="netcdf"/> - <param type="data" label="Tabular of variables" name="var_tab" format="tabular" help="Select the tabular file which summarize the available variables and dimensions."/> - - <param name="var" type="select" label="Choose the variable to extract"> - <options from_dataset="var_tab"> - <column name="name" index="0"/> - <column name="value" index="0"/> - </options> - </param> - - <conditional name="condi_source_coord"> - <param name="coord_source" type="select" label="Source of coordinates"> - <option value="coord_from_stdin">Manually enter coordinates</option> - <option value="coord_from_file">Use coordinates from input file</option> - </param> - - <when value="coord_from_file"> - <param type="data" label="Tabular of coord" name="coord_tabular" format="tabular" help="Format : Latitude Longitude"/> - <param name="lat_dim" type="select" label="Name of latitude coordinate" > - <options from_dataset="var_tab"> - <column name="value" index="0"/> - </options> - </param> - <param name="lon_dim" type="select" label="Name of longitude coordinate" > - <options from_dataset="var_tab"> - <column name="value" index="0"/> - </options> - </param> - <param type="float" name="tolerance" optional="true" label="Maximum distance between original and selected value for inexact matches e.g. abs(original, index) is lower or equal to tolerance"/> - </when> - - <when value="coord_from_stdin"> - <conditional name="condi_coord"> - <param name="coord" type="select" label="Geographical area" help="Use this option to get valid values at your custom coordinates."> - <option value="global">Whole available region</option> - <option value="single">Single location</option> - <option value="subregion">Sub-region extraction</option> - </param> - <when value="single"> - <param name="lat_dim" type="select" label="Name of latitude coordinate" > - <options from_dataset="var_tab"> - <column name="value" index="0"/> - </options> - </param> - <param name="lat_val" type="float" value="0" label="Latitude"/> - <param name="lon_dim" type="select" label="Name of longitude coordinate" > - <options from_dataset="var_tab"> - <column name="value" index="0"/> - </options> - </param> - <param name="lon_val" type="float" value="0" label="Longitude"/> - <param name="no_missing" type="boolean" value="false" label="Do not handle null/missing values (only valid for single location and multiple columns)"/> - <param name="tolerance" type="float" optional="true" label="Maximum distance between original and selected value for inexact matches e.g. abs(original, index) is lower or equal to tolerance"/> - </when> - <when value="subregion"> - <param name="lat_dim" type="select" label="Name of latitude coordinate" > - <options from_dataset="var_tab"> - <column name="value" index="0"/> - </options> - </param> - <param name="lat_valN" type="float" value="0" label="Latitude North"/> - <param name="lat_valS" type="float" value="0" label="Latitude South"/> - <param name="lon_dim" type="select" label="Name of longitude coordinate" > - <options from_dataset="var_tab"> - <column name="value" index="0"/> - </options> - </param> - <param name="lon_valE" type="float" value="0" label="Longitude East"/> - <param name="lon_valW" type="float" value="0" label="Longitude West"/> - </when> - <when value="global"></when> - </conditional> - </when> - - </conditional> - - <section name="time" title="Select Time series" expanded="false"> - <conditional name="condi_datetime"> - <param name="datetime" type="select" label="Datetime selection" help="Use this option to extract timeseries from your dataset"> - <option value="no">No</option> - <option value="yes">Yes</option> - </param> - <when value="no"></when> - <when value="yes"> - <param name="dim" type="select" label="Select datetime dimension" help="Use this option only if your dataset contains a date/time dimension"> - <options from_dataset="var_tab"> - <column name="value" index="0"/> - </options> - </param> - <conditional name="condi_between"> - <param name="comparator" type="select" label="date/Time selection"> - <option value="is">is</option> - <option value="sl">slice</option> - <option value="ne">nearest</option> - <option value="to">to</option> - <option value="from">from</option> - </param> - <when value="sl"> - <param name="t1" type="text" value="" label="Start date/time"/> - <param name="t2" type="text" value="" label="End date/time"/> - </when> - <when value="is"> - <param name="t1" type="text" value="" label="date/time"/> - </when> - <when value="ne"> - <param name="t1" type="text" value="" label="date/time"/> - </when> - <when value="to"> - <param name="t1" type="text" value="" label="date/time"/> - </when> - <when value="from"> - <param name="t1" type="text" value="" label="date/time"/> - </when> - </conditional> - </when> - </conditional> - </section> - <repeat name="user_choice" title="additional filter" help="Use this option to filter on the selected dataset"> - <param name="dim" type="select" label="Dimensions"> - <options from_dataset="var_tab"> - <column name="value" index="0"/> - </options> - </param> - <conditional name="condi_between"> - <param name="comparator" type="select" label="Comparator"> - <option value="e">Equal</option> - <option value="ge">Greater or equal</option> - <option value="le">Less or equal</option> - <option value="bi">Between-include [threshold1,threshold2]</option> - </param> - <when value="bi"> - <param name="t1" type="text" value="0" label="Inferior threshold"/> - <param name="t2" type="text" value="0" label="Superior threshold"/> - </when> - <when value="e"> - <param name="value" type="text" value="0" label="Value"/> - </when> - <when value="ge"> - <param name="value" type="text" value="0" label="Value"/> - </when> - <when value="le"> - <param name="value" type="text" value="0" label="Value"/> - </when> - </conditional> - </repeat> - </inputs> - <outputs> - <collection type="list" name="output"> - <discover_datasets pattern="__designation_and_ext__" visible="false" format="tabular" directory="output_dir"/> - <filter>condi_source_coord['coord_source'] == 'coord_from_file'</filter> - </collection> - <data name="simpleoutput" from_work_dir="final.tabular" format="tabular"> - <filter>condi_source_coord['coord_source'] == 'coord_from_stdin'</filter> - </data> - </outputs> - <tests> - <test> - <param name="input" value="dataset-ibi-reanalysis-bio-005-003-monthly-regulargrid_1510914389133.nc"/> - <param name="var" value="phy"/> - <param name="var_tab" value="var_tab_dataset-ibi"/> - <conditional name="condi_source_coord"> - <param name="coord_source" value="coord_from_stdin"/> - <conditional name="condi_coord"> - <param name="coord" value="single"/> - <param name="lat_dim" value="latitude"/> - <param name="lat_val" value="44.0"/> - <param name="lon_dim" value="longitude"/> - <param name="lon_val" value="-2.0"/> - </conditional> - </conditional> - <output name="simpleoutput" value="Test1.tabular"> - <assert_contents> - <has_text_matching expression="0\t2002-12-15\t0.5"/> - <has_text_matching expression="144\t2014-12-15\t0.5"/> - </assert_contents> - </output> - </test> - <test> - <param name="input" value="dataset-ibi-reanalysis-bio-005-003-monthly-regulargrid_1510914389133.nc"/> - <param name="var_tab" value="var_tab_dataset-ibi"/> - <param name="var" value="nh4"/> - - <conditional name="condi_source_coord"> - <param name="coord_source" value="coord_from_stdin"/> - <conditional name="condi_coord"> - <param name="coord" value="global"/> - </conditional> - </conditional> - <section name="time"> - <conditional name="condi_datetime"> - <param name="datetime" value="yes"/> - <conditional name="condi_between"> - <param name="comparator" value="sl"/> - <param name="t1" value="2003-12-15" /> - <param name="t2" value="2004-12-15" /> - </conditional> - </conditional> - </section> - <repeat name="user_choice"> - <param name="dim" value="nh4"/> - <conditional name="condi_between"> - <param name="comparator" value="ge"/> - <param name="value" value="50."/> - </conditional> - </repeat> - <output name="simpleoutput" value="Test2.tabular"> - <assert_contents> - <has_text_matching expression="0\t2003-12-15\t0.5"/> - <has_text_matching expression="23\t2004-12-15\t0.5"/> - </assert_contents> - </output> - </test> - </tests> - <help><![CDATA[ -**What it does** - -This tool extracts variable values with custom conditions on dimensions. - -It can use manualy given coordinates or automaticaly take them from a tabular file to filter informations. - -If no values are availables at a coordinate X, the tool will search the closest coordinate with a non NA value. - -Filter can be set on every dimension. Available filtering operations are : =, >, <, >=, <=, [interval], ]interval[. - - - -**Input** - -A netcdf file (.nc). - -Variable tabular file from 'Netcdf Metadate Info'. - -Tabular file with coordinates (only coordinates, no header!) and the following structure : 'lat' 'lon'. - - -**Outputs** - -A single output with values for the wanted variable if there is only one coordinate. - -A data collection where one file is created for every coordinate, if multiple coordinates from tabular file. - - -------------------------------------------------- - -The xarray select tool can be used after the xarray Info. - ]]></help> - <expand macro="citations"/> -</tool> +<tool id="xarray_select" name="NetCDF xarray Selection" version="@TOOL_VERSION@+galaxy@VERSION_SUFFIX@" profile="@PROFILE@"> + <description>extracts variable values with custom conditions on dimensions</description> + <macros> + <import>macros.xml</import> + </macros> + <expand macro="edam_ontology"/> + <requirements> + <requirement type="package" version="@TOOL_VERSION@">xarray</requirement> + <requirement type="package" version="3">python</requirement> + <requirement type="package" version="1.5.6">netcdf4</requirement> + <requirement type="package" version="0.9.0">geopandas</requirement> + <requirement type="package" version="1.7.1">shapely</requirement> + </requirements> + <command detect_errors="exit_code"><![CDATA[ + mkdir output_dir && + #if $condi_source_coord.coord_source=="coord_from_file" + echo "Galaxy xarray version @TOOL_VERSION@"> output_dir/version.tabular && + #end if + python '$__tool_directory__/xarray_tool.py' '$input' --select '$var' + --verbose + --filter + #for $i,$uc in enumerate($user_choice) + #if $uc.condi_between.comparator=="bi" + '${uc.dim}#${uc.condi_between.comparator}#${uc.condi_between.t1}#${uc.condi_between.t2}' + #else + '${uc.dim}#${uc.condi_between.comparator}#${uc.condi_between.value}' + #end if + #end for + + #if $time.condi_datetime.datetime=="yes" + --time + #if $time.condi_datetime.condi_between.comparator=="sl" + '${time.condi_datetime.dim}#${time.condi_datetime.condi_between.comparator}#${time.condi_datetime.condi_between.t1}#${time.condi_datetime.condi_between.t2}' + #else + '${time.condi_datetime.dim}#${time.condi_datetime.condi_between.comparator}#${time.condi_datetime.condi_between.t1}' + #end if + #end if + + #if $condi_source_coord.coord_source=="coord_from_file" + --coords '$coord_tabular' + --latname '$condi_source_coord.lat_dim' --lonname '$condi_source_coord.lon_dim' + --outputdir output_dir + #if $condi_source_coord.tolerance + --tolerance '$condi_source_coord.tolerance' + #end if + #else + --outfile 'final.tabular' + #if $condi_source_coord.condi_coord.coord=='single' + --latname $condi_source_coord.condi_coord.lat_dim + --latvalN $condi_source_coord.condi_coord.lat_val + --lonname $condi_source_coord.condi_coord.lon_dim + --lonvalE $condi_source_coord.condi_coord.lon_val + #if $condi_source_coord.condi_coord.no_missing + --no_missing + #end if + #if $condi_source_coord.condi_coord.tolerance + --tolerance '$condi_source_coord.condi_coord.tolerance' + #end if + #elif $condi_source_coord.condi_coord.coord=='subregion' + --latname $condi_source_coord.condi_coord.lat_dim + --latvalN $condi_source_coord.condi_coord.lat_valN + --latvalS $condi_source_coord.condi_coord.lat_valS + --lonname $condi_source_coord.condi_coord.lon_dim + --lonvalE $condi_source_coord.condi_coord.lon_valE + --lonvalW $condi_source_coord.condi_coord.lon_valW + #end if + #end if + ]]> </command> + <inputs> + <param type="data" name="input" label="Input netcdf file" format="netcdf"/> + <param type="data" label="Tabular of variables" name="var_tab" format="tabular" help="Select the tabular file which summarize the available variables and dimensions."/> + + <param name="var" type="select" label="Choose the variable to extract"> + <options from_dataset="var_tab"> + <column name="name" index="0"/> + <column name="value" index="0"/> + </options> + </param> + + <conditional name="condi_source_coord"> + <param name="coord_source" type="select" label="Source of coordinates"> + <option value="coord_from_stdin">Manually enter coordinates</option> + <option value="coord_from_file">Use coordinates from input file</option> + </param> + + <when value="coord_from_file"> + <param type="data" label="Tabular of coord" name="coord_tabular" format="tabular" help="Format : Latitude Longitude"/> + <param name="lat_dim" type="select" label="Name of latitude coordinate"> + <options from_dataset="var_tab"> + <column name="value" index="0"/> + </options> + </param> + <param name="lon_dim" type="select" label="Name of longitude coordinate"> + <options from_dataset="var_tab"> + <column name="value" index="0"/> + </options> + </param> + <param type="float" name="tolerance" optional="true" label="Maximum distance between original and selected value for inexact matches e.g. abs(original, index) is lower or equal to tolerance"/> + </when> + + <when value="coord_from_stdin"> + <conditional name="condi_coord"> + <param name="coord" type="select" label="Geographical area" help="Use this option to get valid values at your custom coordinates."> + <option value="global">Whole available region</option> + <option value="single">Single location</option> + <option value="subregion">Sub-region extraction</option> + </param> + <when value="single"> + <param name="lat_dim" type="select" label="Name of latitude coordinate"> + <options from_dataset="var_tab"> + <column name="value" index="0"/> + </options> + </param> + <param name="lat_val" type="float" value="0" label="Latitude"/> + <param name="lon_dim" type="select" label="Name of longitude coordinate"> + <options from_dataset="var_tab"> + <column name="value" index="0"/> + </options> + </param> + <param name="lon_val" type="float" value="0" label="Longitude"/> + <param name="no_missing" type="boolean" value="false" label="Do not handle null/missing values (only valid for single location and multiple columns)"/> + <param name="tolerance" type="float" optional="true" label="Maximum distance between original and selected value for inexact matches e.g. abs(original, index) is lower or equal to tolerance"/> + </when> + <when value="subregion"> + <param name="lat_dim" type="select" label="Name of latitude coordinate"> + <options from_dataset="var_tab"> + <column name="value" index="0"/> + </options> + </param> + <param name="lat_valN" type="float" value="0" label="Latitude North"/> + <param name="lat_valS" type="float" value="0" label="Latitude South"/> + <param name="lon_dim" type="select" label="Name of longitude coordinate"> + <options from_dataset="var_tab"> + <column name="value" index="0"/> + </options> + </param> + <param name="lon_valE" type="float" value="0" label="Longitude East"/> + <param name="lon_valW" type="float" value="0" label="Longitude West"/> + </when> + <when value="global"></when> + </conditional> + </when> + + </conditional> + + <section name="time" title="Select Time series" expanded="false"> + <conditional name="condi_datetime"> + <param name="datetime" type="select" label="Datetime selection" help="Use this option to extract timeseries from your dataset"> + <option value="no">No</option> + <option value="yes">Yes</option> + </param> + <when value="no"></when> + <when value="yes"> + <param name="dim" type="select" label="Select datetime dimension" help="Use this option only if your dataset contains a date/time dimension"> + <options from_dataset="var_tab"> + <column name="value" index="0"/> + </options> + </param> + <conditional name="condi_between"> + <param name="comparator" type="select" label="date/Time selection"> + <option value="is">is</option> + <option value="sl">slice</option> + <option value="ne">nearest</option> + <option value="to">to</option> + <option value="from">from</option> + </param> + <when value="sl"> + <param name="t1" type="text" value="" label="Start date/time"/> + <param name="t2" type="text" value="" label="End date/time"/> + </when> + <when value="is"> + <param name="t1" type="text" value="" label="date/time"/> + </when> + <when value="ne"> + <param name="t1" type="text" value="" label="date/time"/> + </when> + <when value="to"> + <param name="t1" type="text" value="" label="date/time"/> + </when> + <when value="from"> + <param name="t1" type="text" value="" label="date/time"/> + </when> + </conditional> + </when> + </conditional> + </section> + <repeat name="user_choice" title="additional filter" help="Use this option to filter on the selected dataset"> + <param name="dim" type="select" label="Dimensions"> + <options from_dataset="var_tab"> + <column name="value" index="0"/> + </options> + </param> + <conditional name="condi_between"> + <param name="comparator" type="select" label="Comparator"> + <option value="e">Equal</option> + <option value="ge">Greater or equal</option> + <option value="le">Less or equal</option> + <option value="bi">Between-include [threshold1,threshold2]</option> + </param> + <when value="bi"> + <param name="t1" type="text" value="0" label="Inferior threshold"/> + <param name="t2" type="text" value="0" label="Superior threshold"/> + </when> + <when value="e"> + <param name="value" type="text" value="0" label="Value"/> + </when> + <when value="ge"> + <param name="value" type="text" value="0" label="Value"/> + </when> + <when value="le"> + <param name="value" type="text" value="0" label="Value"/> + </when> + </conditional> + </repeat> + </inputs> + <outputs> + <collection type="list" name="output"> + <discover_datasets pattern="__designation_and_ext__" visible="false" format="tabular" directory="output_dir"/> + <filter>condi_source_coord['coord_source'] == 'coord_from_file'</filter> + </collection> + <data name="simpleoutput" from_work_dir="final.tabular" format="tabular"> + <filter>condi_source_coord['coord_source'] == 'coord_from_stdin'</filter> + </data> + </outputs> + <tests> + <test> + <param name="input" value="dataset-ibi-reanalysis-bio-005-003-monthly-regulargrid_1510914389133.nc"/> + <param name="var" value="phy"/> + <param name="var_tab" value="var_tab_dataset-ibi"/> + <conditional name="condi_source_coord"> + <param name="coord_source" value="coord_from_stdin"/> + <conditional name="condi_coord"> + <param name="coord" value="single"/> + <param name="lat_dim" value="latitude"/> + <param name="lat_val" value="44.0"/> + <param name="lon_dim" value="longitude"/> + <param name="lon_val" value="-2.0"/> + </conditional> + </conditional> + <output name="simpleoutput" value="Test1.tabular"> + <assert_contents> + <has_text_matching expression="0\t2002-12-15\t0.5"/> + <has_text_matching expression="144\t2014-12-15\t0.5"/> + </assert_contents> + </output> + </test> + <test> + <param name="input" value="dataset-ibi-reanalysis-bio-005-003-monthly-regulargrid_1510914389133.nc"/> + <param name="var_tab" value="var_tab_dataset-ibi"/> + <param name="var" value="nh4"/> + + <conditional name="condi_source_coord"> + <param name="coord_source" value="coord_from_stdin"/> + <conditional name="condi_coord"> + <param name="coord" value="global"/> + </conditional> + </conditional> + <section name="time"> + <conditional name="condi_datetime"> + <param name="datetime" value="yes"/> + <conditional name="condi_between"> + <param name="comparator" value="sl"/> + <param name="t1" value="2003-12-15" /> + <param name="t2" value="2004-12-15" /> + </conditional> + </conditional> + </section> + <repeat name="user_choice"> + <param name="dim" value="nh4"/> + <conditional name="condi_between"> + <param name="comparator" value="ge"/> + <param name="value" value="50."/> + </conditional> + </repeat> + <output name="simpleoutput" value="Test2.tabular"> + <assert_contents> + <has_text_matching expression="0\t2003-12-15\t0.5"/> + <has_text_matching expression="23\t2004-12-15\t0.5"/> + </assert_contents> + </output> + </test> + </tests> + <help><![CDATA[ +**What it does** + +This tool extracts variable values with custom conditions on dimensions. + +It can use manualy given coordinates or automaticaly take them from a tabular file to filter informations. + +If no values are availables at a coordinate X, the tool will search the closest coordinate with a non NA value. + +Filter can be set on every dimension. Available filtering operations are : =, >, <, >=, <=, [interval], ]interval[. + + + +**Input** + +A netcdf file (.nc). + +Variable tabular file from 'Netcdf Metadate Info'. + +Tabular file with coordinates (only coordinates, no header!) and the following structure : 'lat' 'lon'. + + +**Outputs** + +A single output with values for the wanted variable if there is only one coordinate. + +A data collection where one file is created for every coordinate, if multiple coordinates from tabular file. + + +------------------------------------------------- + +The xarray select tool can be used after the xarray Info. + ]]> </help> + <expand macro="citations"/> +</tool>
--- a/xarray_tool.py Sun Jun 06 08:51:41 2021 +0000 +++ b/xarray_tool.py Thu Jan 20 17:07:19 2022 +0000 @@ -1,365 +1,365 @@ -# xarray tool for: -# - getting metadata information -# - select data and save results in csv file for further post-processing - -import argparse -import csv -import os -import warnings - -import geopandas as gdp - -import pandas as pd - -from shapely.geometry import Point -from shapely.ops import nearest_points - -import xarray as xr - - -class XarrayTool (): - def __init__(self, infile, outfile_info="", outfile_summary="", - select="", outfile="", outputdir="", latname="", - latvalN="", latvalS="", lonname="", lonvalE="", - lonvalW="", filter_list="", coords="", time="", - verbose=False, no_missing=False, coords_info=None, - tolerance=None): - self.infile = infile - self.outfile_info = outfile_info - self.outfile_summary = outfile_summary - self.select = select - self.outfile = outfile - self.outputdir = outputdir - self.latname = latname - if tolerance != "" and tolerance is not None: - self.tolerance = float(tolerance) - else: - self.tolerance = -1 - if latvalN != "" and latvalN is not None: - self.latvalN = float(latvalN) - else: - self.latvalN = "" - if latvalS != "" and latvalS is not None: - self.latvalS = float(latvalS) - else: - self.latvalS = "" - self.lonname = lonname - if lonvalE != "" and lonvalE is not None: - self.lonvalE = float(lonvalE) - else: - self.lonvalE = "" - if lonvalW != "" and lonvalW is not None: - self.lonvalW = float(lonvalW) - else: - self.lonvalW = "" - self.filter = filter_list - self.time = time - self.coords = coords - self.verbose = verbose - self.no_missing = no_missing - # initialization - self.dset = None - self.gset = None - self.coords_info = coords_info - if self.verbose: - print("infile: ", self.infile) - print("outfile_info: ", self.outfile_info) - print("outfile_summary: ", self.outfile_summary) - print("outfile: ", self.outfile) - print("select: ", self.select) - print("outfile: ", self.outfile) - print("outputdir: ", self.outputdir) - print("latname: ", self.latname) - print("latvalN: ", self.latvalN) - print("latvalS: ", self.latvalS) - print("lonname: ", self.lonname) - print("lonvalE: ", self.lonvalE) - print("lonvalW: ", self.lonvalW) - print("filter: ", self.filter) - print("time: ", self.time) - print("coords: ", self.coords) - print("coords_info: ", self.coords_info) - - def info(self): - f = open(self.outfile_info, 'w') - ds = xr.open_dataset(self.infile) - ds.info(f) - f.close() - - def summary(self): - f = open(self.outfile_summary, 'w') - ds = xr.open_dataset(self.infile) - writer = csv.writer(f, delimiter='\t') - header = ['VariableName', 'NumberOfDimensions'] - for idx, val in enumerate(ds.dims.items()): - header.append('Dim' + str(idx) + 'Name') - header.append('Dim' + str(idx) + 'Size') - writer.writerow(header) - for name, da in ds.data_vars.items(): - line = [name] - line.append(len(ds[name].shape)) - for d, s in zip(da.shape, da.sizes): - line.append(s) - line.append(d) - writer.writerow(line) - for name, da in ds.coords.items(): - line = [name] - line.append(len(ds[name].shape)) - for d, s in zip(da.shape, da.sizes): - line.append(s) - line.append(d) - writer.writerow(line) - f.close() - - def rowfilter(self, single_filter): - split_filter = single_filter.split('#') - filter_varname = split_filter[0] - op = split_filter[1] - ll = float(split_filter[2]) - if (op == 'bi'): - rl = float(split_filter[3]) - if filter_varname == self.select: - # filter on values of the selected variable - if op == 'bi': - self.dset = self.dset.where( - (self.dset <= rl) & (self.dset >= ll) - ) - elif op == 'le': - self.dset = self.dset.where(self.dset <= ll) - elif op == 'ge': - self.dset = self.dset.where(self.dset >= ll) - elif op == 'e': - self.dset = self.dset.where(self.dset == ll) - else: # filter on other dimensions of the selected variable - if op == 'bi': - self.dset = self.dset.sel({filter_varname: slice(ll, rl)}) - elif op == 'le': - self.dset = self.dset.sel({filter_varname: slice(None, ll)}) - elif op == 'ge': - self.dset = self.dset.sel({filter_varname: slice(ll, None)}) - elif op == 'e': - self.dset = self.dset.sel({filter_varname: ll}, - method='nearest') - - def selection(self): - if self.dset is None: - self.ds = xr.open_dataset(self.infile) - self.dset = self.ds[self.select] # select variable - if self.time: - self.datetime_selection() - if self.filter: - self.filter_selection() - - self.area_selection() - if self.gset.count() > 1: - # convert to dataframe if several rows and cols - self.gset = self.gset.to_dataframe().dropna(how='all'). \ - reset_index() - self.gset.to_csv(self.outfile, header=True, sep='\t') - else: - data = { - self.latname: [self.gset[self.latname].values], - self.lonname: [self.gset[self.lonname].values], - self.select: [self.gset.values] - } - - df = pd.DataFrame(data, columns=[self.latname, self.lonname, - self.select]) - df.to_csv(self.outfile, header=True, sep='\t') - - def datetime_selection(self): - split_filter = self.time.split('#') - time_varname = split_filter[0] - op = split_filter[1] - ll = split_filter[2] - if (op == 'sl'): - rl = split_filter[3] - self.dset = self.dset.sel({time_varname: slice(ll, rl)}) - elif (op == 'to'): - self.dset = self.dset.sel({time_varname: slice(None, ll)}) - elif (op == 'from'): - self.dset = self.dset.sel({time_varname: slice(ll, None)}) - elif (op == 'is'): - self.dset = self.dset.sel({time_varname: ll}, method='nearest') - - def filter_selection(self): - for single_filter in self.filter: - self.rowfilter(single_filter) - - def area_selection(self): - - if self.latvalS != "" and self.lonvalW != "": - # Select geographical area - self.gset = self.dset.sel({self.latname: - slice(self.latvalS, self.latvalN), - self.lonname: - slice(self.lonvalW, self.lonvalE)}) - elif self.latvalN != "" and self.lonvalE != "": - # select nearest location - if self.no_missing: - self.nearest_latvalN = self.latvalN - self.nearest_lonvalE = self.lonvalE - else: - # find nearest location without NaN values - self.nearest_location() - if self.tolerance > 0: - self.gset = self.dset.sel({self.latname: self.nearest_latvalN, - self.lonname: self.nearest_lonvalE}, - method='nearest', - tolerance=self.tolerance) - else: - self.gset = self.dset.sel({self.latname: self.nearest_latvalN, - self.lonname: self.nearest_lonvalE}, - method='nearest') - else: - self.gset = self.dset - - def nearest_location(self): - # Build a geopandas dataframe with all first elements in each dimension - # so we assume null values correspond to a mask that is the same for - # all dimensions in the dataset. - dsel_frame = self.dset - for dim in self.dset.dims: - if dim != self.latname and dim != self.lonname: - dsel_frame = dsel_frame.isel({dim: 0}) - # transform to pandas dataframe - dff = dsel_frame.to_dataframe().dropna().reset_index() - # transform to geopandas to collocate - gdf = gdp.GeoDataFrame(dff, - geometry=gdp.points_from_xy(dff[self.lonname], - dff[self.latname])) - # Find nearest location where values are not null - point = Point(self.lonvalE, self.latvalN) - multipoint = gdf.geometry.unary_union - queried_geom, nearest_geom = nearest_points(point, multipoint) - self.nearest_latvalN = nearest_geom.y - self.nearest_lonvalE = nearest_geom.x - - def selection_from_coords(self): - fcoords = pd.read_csv(self.coords, sep='\t') - for row in fcoords.itertuples(): - self.latvalN = row[0] - self.lonvalE = row[1] - self.outfile = (os.path.join(self.outputdir, - self.select + '_' + - str(row.Index) + '.tabular')) - self.selection() - - def get_coords_info(self): - ds = xr.open_dataset(self.infile) - for c in ds.coords: - filename = os.path.join(self.coords_info, - c.strip() + - '.tabular') - pd = ds.coords[c].to_pandas() - pd.index = range(len(pd)) - pd.to_csv(filename, header=False, sep='\t') - - -if __name__ == '__main__': - warnings.filterwarnings("ignore") - parser = argparse.ArgumentParser() - - parser.add_argument( - 'infile', - help='netCDF input filename' - ) - parser.add_argument( - '--info', - help='Output filename where metadata information is stored' - ) - parser.add_argument( - '--summary', - help='Output filename where data summary information is stored' - ) - parser.add_argument( - '--select', - help='Variable name to select' - ) - parser.add_argument( - '--latname', - help='Latitude name' - ) - parser.add_argument( - '--latvalN', - help='North latitude value' - ) - parser.add_argument( - '--latvalS', - help='South latitude value' - ) - parser.add_argument( - '--lonname', - help='Longitude name' - ) - parser.add_argument( - '--lonvalE', - help='East longitude value' - ) - parser.add_argument( - '--lonvalW', - help='West longitude value' - ) - parser.add_argument( - '--tolerance', - help='Maximum distance between original and selected value for ' - ' inexact matches e.g. abs(index[indexer] - target) <= tolerance' - ) - parser.add_argument( - '--coords', - help='Input file containing Latitude and Longitude' - 'for geographical selection' - ) - parser.add_argument( - '--coords_info', - help='output-folder where for each coordinate, coordinate values ' - ' are being printed in the corresponding outputfile' - ) - parser.add_argument( - '--filter', - nargs="*", - help='Filter list variable#operator#value_s#value_e' - ) - parser.add_argument( - '--time', - help='select timeseries variable#operator#value_s[#value_e]' - ) - parser.add_argument( - '--outfile', - help='csv outfile for storing results of the selection' - '(valid only when --select)' - ) - parser.add_argument( - '--outputdir', - help='folder name for storing results with multiple selections' - '(valid only when --select)' - ) - parser.add_argument( - "-v", "--verbose", - help="switch on verbose mode", - action="store_true" - ) - parser.add_argument( - "--no_missing", - help="""Do not take into account possible null/missing values - (only valid for single location)""", - action="store_true" - ) - args = parser.parse_args() - - p = XarrayTool(args.infile, args.info, args.summary, args.select, - args.outfile, args.outputdir, args.latname, - args.latvalN, args.latvalS, args.lonname, - args.lonvalE, args.lonvalW, args.filter, - args.coords, args.time, args.verbose, - args.no_missing, args.coords_info, args.tolerance) - if args.info: - p.info() - if args.summary: - p.summary() - if args.coords: - p.selection_from_coords() - elif args.select: - p.selection() - elif args.coords_info: - p.get_coords_info() +# xarray tool for: +# - getting metadata information +# - select data and save results in csv file for further post-processing + +import argparse +import csv +import os +import warnings + +import geopandas as gdp + +import pandas as pd + +from shapely.geometry import Point +from shapely.ops import nearest_points + +import xarray as xr + + +class XarrayTool (): + def __init__(self, infile, outfile_info="", outfile_summary="", + select="", outfile="", outputdir="", latname="", + latvalN="", latvalS="", lonname="", lonvalE="", + lonvalW="", filter_list="", coords="", time="", + verbose=False, no_missing=False, coords_info=None, + tolerance=None): + self.infile = infile + self.outfile_info = outfile_info + self.outfile_summary = outfile_summary + self.select = select + self.outfile = outfile + self.outputdir = outputdir + self.latname = latname + if tolerance != "" and tolerance is not None: + self.tolerance = float(tolerance) + else: + self.tolerance = -1 + if latvalN != "" and latvalN is not None: + self.latvalN = float(latvalN) + else: + self.latvalN = "" + if latvalS != "" and latvalS is not None: + self.latvalS = float(latvalS) + else: + self.latvalS = "" + self.lonname = lonname + if lonvalE != "" and lonvalE is not None: + self.lonvalE = float(lonvalE) + else: + self.lonvalE = "" + if lonvalW != "" and lonvalW is not None: + self.lonvalW = float(lonvalW) + else: + self.lonvalW = "" + self.filter = filter_list + self.time = time + self.coords = coords + self.verbose = verbose + self.no_missing = no_missing + # initialization + self.dset = None + self.gset = None + self.coords_info = coords_info + if self.verbose: + print("infile: ", self.infile) + print("outfile_info: ", self.outfile_info) + print("outfile_summary: ", self.outfile_summary) + print("outfile: ", self.outfile) + print("select: ", self.select) + print("outfile: ", self.outfile) + print("outputdir: ", self.outputdir) + print("latname: ", self.latname) + print("latvalN: ", self.latvalN) + print("latvalS: ", self.latvalS) + print("lonname: ", self.lonname) + print("lonvalE: ", self.lonvalE) + print("lonvalW: ", self.lonvalW) + print("filter: ", self.filter) + print("time: ", self.time) + print("coords: ", self.coords) + print("coords_info: ", self.coords_info) + + def info(self): + f = open(self.outfile_info, 'w') + ds = xr.open_dataset(self.infile) + ds.info(f) + f.close() + + def summary(self): + f = open(self.outfile_summary, 'w') + ds = xr.open_dataset(self.infile) + writer = csv.writer(f, delimiter='\t') + header = ['VariableName', 'NumberOfDimensions'] + for idx, val in enumerate(ds.dims.items()): + header.append('Dim' + str(idx) + 'Name') + header.append('Dim' + str(idx) + 'Size') + writer.writerow(header) + for name, da in ds.data_vars.items(): + line = [name] + line.append(len(ds[name].shape)) + for d, s in zip(da.shape, da.sizes): + line.append(s) + line.append(d) + writer.writerow(line) + for name, da in ds.coords.items(): + line = [name] + line.append(len(ds[name].shape)) + for d, s in zip(da.shape, da.sizes): + line.append(s) + line.append(d) + writer.writerow(line) + f.close() + + def rowfilter(self, single_filter): + split_filter = single_filter.split('#') + filter_varname = split_filter[0] + op = split_filter[1] + ll = float(split_filter[2]) + if (op == 'bi'): + rl = float(split_filter[3]) + if filter_varname == self.select: + # filter on values of the selected variable + if op == 'bi': + self.dset = self.dset.where( + (self.dset <= rl) & (self.dset >= ll) + ) + elif op == 'le': + self.dset = self.dset.where(self.dset <= ll) + elif op == 'ge': + self.dset = self.dset.where(self.dset >= ll) + elif op == 'e': + self.dset = self.dset.where(self.dset == ll) + else: # filter on other dimensions of the selected variable + if op == 'bi': + self.dset = self.dset.sel({filter_varname: slice(ll, rl)}) + elif op == 'le': + self.dset = self.dset.sel({filter_varname: slice(None, ll)}) + elif op == 'ge': + self.dset = self.dset.sel({filter_varname: slice(ll, None)}) + elif op == 'e': + self.dset = self.dset.sel({filter_varname: ll}, + method='nearest') + + def selection(self): + if self.dset is None: + self.ds = xr.open_dataset(self.infile) + self.dset = self.ds[self.select] # select variable + if self.time: + self.datetime_selection() + if self.filter: + self.filter_selection() + + self.area_selection() + if self.gset.count() > 1: + # convert to dataframe if several rows and cols + self.gset = self.gset.to_dataframe().dropna(how='all'). \ + reset_index() + self.gset.to_csv(self.outfile, header=True, sep='\t') + else: + data = { + self.latname: [self.gset[self.latname].values], + self.lonname: [self.gset[self.lonname].values], + self.select: [self.gset.values] + } + + df = pd.DataFrame(data, columns=[self.latname, self.lonname, + self.select]) + df.to_csv(self.outfile, header=True, sep='\t') + + def datetime_selection(self): + split_filter = self.time.split('#') + time_varname = split_filter[0] + op = split_filter[1] + ll = split_filter[2] + if (op == 'sl'): + rl = split_filter[3] + self.dset = self.dset.sel({time_varname: slice(ll, rl)}) + elif (op == 'to'): + self.dset = self.dset.sel({time_varname: slice(None, ll)}) + elif (op == 'from'): + self.dset = self.dset.sel({time_varname: slice(ll, None)}) + elif (op == 'is'): + self.dset = self.dset.sel({time_varname: ll}, method='nearest') + + def filter_selection(self): + for single_filter in self.filter: + self.rowfilter(single_filter) + + def area_selection(self): + + if self.latvalS != "" and self.lonvalW != "": + # Select geographical area + self.gset = self.dset.sel({self.latname: + slice(self.latvalS, self.latvalN), + self.lonname: + slice(self.lonvalW, self.lonvalE)}) + elif self.latvalN != "" and self.lonvalE != "": + # select nearest location + if self.no_missing: + self.nearest_latvalN = self.latvalN + self.nearest_lonvalE = self.lonvalE + else: + # find nearest location without NaN values + self.nearest_location() + if self.tolerance > 0: + self.gset = self.dset.sel({self.latname: self.nearest_latvalN, + self.lonname: self.nearest_lonvalE}, + method='nearest', + tolerance=self.tolerance) + else: + self.gset = self.dset.sel({self.latname: self.nearest_latvalN, + self.lonname: self.nearest_lonvalE}, + method='nearest') + else: + self.gset = self.dset + + def nearest_location(self): + # Build a geopandas dataframe with all first elements in each dimension + # so we assume null values correspond to a mask that is the same for + # all dimensions in the dataset. + dsel_frame = self.dset + for dim in self.dset.dims: + if dim != self.latname and dim != self.lonname: + dsel_frame = dsel_frame.isel({dim: 0}) + # transform to pandas dataframe + dff = dsel_frame.to_dataframe().dropna().reset_index() + # transform to geopandas to collocate + gdf = gdp.GeoDataFrame(dff, + geometry=gdp.points_from_xy(dff[self.lonname], + dff[self.latname])) + # Find nearest location where values are not null + point = Point(self.lonvalE, self.latvalN) + multipoint = gdf.geometry.unary_union + queried_geom, nearest_geom = nearest_points(point, multipoint) + self.nearest_latvalN = nearest_geom.y + self.nearest_lonvalE = nearest_geom.x + + def selection_from_coords(self): + fcoords = pd.read_csv(self.coords, sep='\t') + for row in fcoords.itertuples(): + self.latvalN = row[0] + self.lonvalE = row[1] + self.outfile = (os.path.join(self.outputdir, + self.select + '_' + + str(row.Index) + '.tabular')) + self.selection() + + def get_coords_info(self): + ds = xr.open_dataset(self.infile) + for c in ds.coords: + filename = os.path.join(self.coords_info, + c.strip() + + '.tabular') + pd = ds.coords[c].to_pandas() + pd.index = range(len(pd)) + pd.to_csv(filename, header=False, sep='\t') + + +if __name__ == '__main__': + warnings.filterwarnings("ignore") + parser = argparse.ArgumentParser() + + parser.add_argument( + 'infile', + help='netCDF input filename' + ) + parser.add_argument( + '--info', + help='Output filename where metadata information is stored' + ) + parser.add_argument( + '--summary', + help='Output filename where data summary information is stored' + ) + parser.add_argument( + '--select', + help='Variable name to select' + ) + parser.add_argument( + '--latname', + help='Latitude name' + ) + parser.add_argument( + '--latvalN', + help='North latitude value' + ) + parser.add_argument( + '--latvalS', + help='South latitude value' + ) + parser.add_argument( + '--lonname', + help='Longitude name' + ) + parser.add_argument( + '--lonvalE', + help='East longitude value' + ) + parser.add_argument( + '--lonvalW', + help='West longitude value' + ) + parser.add_argument( + '--tolerance', + help='Maximum distance between original and selected value for ' + ' inexact matches e.g. abs(index[indexer] - target) <= tolerance' + ) + parser.add_argument( + '--coords', + help='Input file containing Latitude and Longitude' + 'for geographical selection' + ) + parser.add_argument( + '--coords_info', + help='output-folder where for each coordinate, coordinate values ' + ' are being printed in the corresponding outputfile' + ) + parser.add_argument( + '--filter', + nargs="*", + help='Filter list variable#operator#value_s#value_e' + ) + parser.add_argument( + '--time', + help='select timeseries variable#operator#value_s[#value_e]' + ) + parser.add_argument( + '--outfile', + help='csv outfile for storing results of the selection' + '(valid only when --select)' + ) + parser.add_argument( + '--outputdir', + help='folder name for storing results with multiple selections' + '(valid only when --select)' + ) + parser.add_argument( + "-v", "--verbose", + help="switch on verbose mode", + action="store_true" + ) + parser.add_argument( + "--no_missing", + help="""Do not take into account possible null/missing values + (only valid for single location)""", + action="store_true" + ) + args = parser.parse_args() + + p = XarrayTool(args.infile, args.info, args.summary, args.select, + args.outfile, args.outputdir, args.latname, + args.latvalN, args.latvalS, args.lonname, + args.lonvalE, args.lonvalW, args.filter, + args.coords, args.time, args.verbose, + args.no_missing, args.coords_info, args.tolerance) + if args.info: + p.info() + if args.summary: + p.summary() + if args.coords: + p.selection_from_coords() + elif args.select: + p.selection() + elif args.coords_info: + p.get_coords_info()