Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Method to retrieve weights as a DataArray #27

Closed
aulemahal opened this issue Sep 23, 2020 · 7 comments
Closed

Method to retrieve weights as a DataArray #27

aulemahal opened this issue Sep 23, 2020 · 7 comments

Comments

@aulemahal
Copy link
Collaborator

While coding the spatial averaging in #24, I realized that the Regridder object was missing an option to retrieve a usable array of the regridding weights. While this is not common when performing conventional regridding, I think that most users doing spatial averaging would like to see or save the weights masks.

The Regridder object could have a simple get_weights method that returns a DataArray of the expanded sparse matrix with 4 or 3 dimensions. Dimensions would be renamed with "_in" and "_out" suffixes.

@raphaeldussin
Copy link
Contributor

my understanding is that ESMF only produces 2d regridding matrices (I could be wrong).
The size of the sparse matrix being (nx_src * ny_src) x (nx_dst * ny_dst), are you suggesting something like:

def get_weights(regridder):
    return xr.DataArray(regridder.weights.toarray(), dims=('nxy_src', 'nxy_src'))

@aulemahal
Copy link
Collaborator Author

aulemahal commented Sep 30, 2020

I would suggest something a bit more complex that outputs an array of shape (lon_in, lat_in, lon_out, lat_out) or (lon_in, lat_in, locations) in a locstream/polylist_out case. This adds a reshaping operation, but shouldn't be difficult.

@huard
Copy link
Contributor

huard commented Sep 30, 2020

@aulemahal Could you repurpose or generalize smm.read_weights ?

@aulemahal
Copy link
Collaborator Author

I'm not sure how that would serve the purpose. May be the issue is not clear, I am suggesting pretty much this:

def get_weights(self):
    if self.locstream_in:
        dims = ['locations_in']
        shape = [self.n_in]
    else:
        dims = [dim + '_in' for dim in self.input_horiz_dims]
         shape = list(self.shape_in)

    if self.locstream_out:
        dims.append('locations_out)]
        shape.append(self.n_out)
    else:
        dims.extend([dim  + '_out' for dim in self.out_horiz_dims])]
         shape.extend(self.shape_out)
    return xr.DataArray(self.weights.toarray().reshape(shape), dims=dims)

This would also need the new attribute input_horiz_dims to be set in the __init__, it could still be overridden in the regrid methods anyway.

@raphaeldussin
Copy link
Contributor

@aulemahal I'm not sure that would work for large arrays. Say if I regrid a 1/4 degree regular grid onto a 1 degree (pretty standard stuff), a 4d matrix would be of size 1440x720x360x180 = 67e9 elements = 269 GB for single precision

@aulemahal
Copy link
Collaborator Author

You're right... I was thinking of the cases using polygons, where the weights could actually be useful themselves. This could be a small example in the doc instead. So, if the user explodes their ram, it's their own fault.

@aulemahal
Copy link
Collaborator Author

Just remembered this issue. It was "solved" by an example in the doc of #24.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants