DimensionalData: How to use a dimension whose name is stored in a variable

I have to use data with one time dimension and two spatial dimensions (longitude and latitude). I use the Rasters.jl library to manage them, that creates DimensionalData.jl arrays.

Sometimes, I have a variable, say slp, with three dimensions: Ti, longitude and latitude.

But sometimes, I can have the same variable, slp, with to dimensions: Ti and points. Points are integer numbers running from one to the number of grid points. Additionaly, in the same data set, I have two variables: longitude and latitude. And each of these two variables has one dimension: points. So, points is a dimension that is shared among slp, longitude and latitude.

If I want to select a spatial window of my data, between lon1 and lon2, and lat1 and lat2, then I can do as follows:

ds[points = Where( p -> ds["longitude"][p] ∈ lon1..lon2 && ds["latitude"][p] ∈ lat1..lat2 )]

But it is the case that sometimes, I do not know the name of the dimension points, so that it can be, instead of points, values (for example). I can detect the name of this dimension and store it as a string variable, say, spatial_dim_name. But I do not know how to use it. I have tried:

julia> spatial_dim_name = "values"
julia> ds[spatial_dim_name = Where(p->
                              ds[lon_name][p] ∈ lon1..lon2
                              &&
                              ds[lat_name][p] ∈ lat1..lat2
                              )
                           ]
┌ Warning: (Dim{:spatial_dim_name},) dims were not found in object.
└ @ DimensionalData.Dimensions ~/.julia/packages/DimensionalData/BoJag/src/Dimensions/primitives.jl:777
┌ Warning: (Dim{:spatial_dim_name},) dims were not found in object.
└ @ DimensionalData.Dimensions ~/.julia/packages/DimensionalData/BoJag/src/Dimensions/primitives.jl:777

And the selection is not made.
Does anybody know how I can do this?

otherdims is the DD function for getting unknown dimensions. It will get the “other” dimensions to the ones you know.

rebuild is a function that rebuilds most DD objects like all Dimensions with new contents.

So you can do :

thedim = first(otherdims(raster, (X, Y, Ti)))
raster[rebuild(thedim, myselector)]

Where myselector is your Where selector

(It’s a bit harder to do the keyword syntax programmatically like this, so we switch to the dimensions wrapper syntax by just rebuilding dimensions with new contents. Most of the internals of DD and Rasters look like the code above)

Great!, @Raf.
In order to be more precise and use the dimension name stored as a string in a variable, I have coded:

spatial_coord_name = "values"
spatial_dim = dims(raster, Symbol(spatial_coord_name))
raster_selected = raster[
    rebuild(
            spatial_dim,
            Where(c->
                       raster["longitude"][c] ∈ lon1..lon2
                       &&
                       raster["latitude"][c] ∈ lat1..lat2
            )#Where
    )#rebuild
]#ds

Why is that more precise? A type would usually be considered more precise than a string. In any real internal code you always should prefer the type/object because it’s easy on the compiler and will usually be a cost free abstraction.

At least just use a Symbol, the string is pretty redundant.

Couldn’t I use the getindex on the dimension instead of rebuild?
Like this:

raster[thedim[myselector]]

Ok, it is more precise to use the type than the string. What I mean by “more precise” here is “to more precisely address the original question”, that was “How to use a dimension whose name is stored in a variable”.
But, now that you say this, I will see if my code admits a recoding in which I use the type instead of the string.

Yes! this also works!
But I did not ever imagine this way of doing it.