-
Notifications
You must be signed in to change notification settings - Fork 14
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
Add functions for computing and plotting transects #144
Conversation
TestingThis has been used in testing the branch https://github.com/xylar/polaris/tree/add-isomip-plus-init and produced plots like these: Sigma coordinate with 10 layers and a thin-film regionZ-star coordinate with 36 layers (and no thin-film region) |
a70f1d1
to
8531f70
Compare
polaris/ocean/viz/transect.py
Outdated
ds_transect = find_transect_levels_and_weights( | ||
ds_transect, ds_3d_mesh.layerThickness, | ||
ds_3d_mesh.bottomDepth, ds_3d_mesh.maxLevelCell - 1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you explain why triangles (and tripcolor) are preferable to quadrilaterals (and pcolormesh)? I realize that MPAS-Tools is already written for triangles so it would be more expedient to go that route, but I don't understand the motivation for the additional layer of complexity. Quadrilaterals would be nice because you can plot the edges and they are meaningful.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will need to remind myself about the details but I didn't decide to move to triangles lightly. It was a huge pain in the ass to make the change. So I must have had a good reason that I couldn't use quads anymore that I am not remembering now. I'll look into it and keep you posted. If we can move back to quads, that would be great for a lot of reasons. One is that labeled contours don't work right on triangles.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking through the docstrings and such, I don't see why we couldn't use quads. For example,
https://github.com/MPAS-Dev/MPAS-Tools/blob/master/conda_package/mpas_tools/ocean/transects.py#L40-L46
but I don't see why we couldn't use flat
or gouraud
shading to accomplish the same.
What I recall being tricky was masking out the invalid cells (e.g. below bathymetry). It's straightforward with flat shading -- you just have NaNs for invalid cell values. But for gouraud, you have a problem that you could have an invalid cell surrounded by 4 valid nodes (e.g. because you have a local column of high bathymetry). A way to handle this and still use pcolormesh
would be to add mid-point values to each transect segment. This would fix the masking issue for bathymetry and would make the interpolation of field values along the transect slightly more accurate. But it would mean that there would be vertical lines both at intersections of the transect with cell edges and at the midpoint between cell edges. This would make the outlines of quads less meaningful.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could use the straightforward approach for flat shading and add an midpoint to the transect segments for gouraud shading (presumably discouraging cell outlines in that case).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can see how this goes at least.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It took me more than a week but I got the transect plotting to work on quads. Showing the edges of the quads still does not have the effect that you were after because the quads do not correspond to MPAS-ocean cells (the cells have to be divided into triangles horizontally and half-levels vertically for interpolation to nodes to work correctly). However, I have stored segments that can be plotted to get MPAS-Ocean layer interfaces and vertical cell boundaries so you can get the effect that you were after.
The code added here is similar to functionality in MPAS-Tools but it works with data on quads, rather than triangles. Visualization on triangles has proven to have a number of major drawbacks. It is not very intuitive, functionality for matplotlib functions and methods on triangles have fewer features and are less robust than their counterparts for quads, and there does not seem to be support for labeled contours on triangles.
8531f70
to
c1efd85
Compare
@cbegeman, I spent about a week rewriting the transect functionality to use quads. There are a lot of good reasons for us to do this, high among them:
For now, I have the functionality here in Polaris rather than in MPAS-Tools. This is partly to make it easier to test and make bug fixes. It is also partly to prevent breaking anything that relies on the current MPAS-Tools implementation. Since it's a big change to the API, I don't want to put it into MPAS-Tools until everything that relies on the old API (probably just MPAS-Analysis) has either been updated or declared deprecated. I will post some new plots with this approach shortly. You can try it out on your case(s) as well. I believe it will fix the issue you pointed out to me on Slack but I haven't tried your branch out myself yet. |
Awesome! I'm excited to try this out. I'm having a little bit of trouble because it seems like |
Two questions:
Here is an example of me using |
Taking a look at the code: polaris/polaris/ocean/viz/transect/vert.py Lines 202 to 231 in c1efd85
it seems like maybe you're passing something for da that doesn't have the expected dimensions (nCells , nVertLevels ). I don't see where nVertLevels would be expected in ds_transect and indeed it's also not in mine.
|
@xylar Thanks! I forgot that I had I'm a little confused about the vertical lines because I would expect them to change position if they are the boundaries between cells. However, I've tried 3 different line positions so far and I can't get them to change. |
These vertical lines are from setting
You're calling |
I got the line locations to change by moving diagonally across the domain, so I guess the transects did cut across the cells in similar ways (the lines were perpendicular). Sorry for the false alarm! |
@cbegeman, thanks. I did a test where I have a transect zigzagging through the ISOMIP+ domain. I do seem to be seeing the right cell boundaries (red) and skipping the internal triangle boundaries (blue dots): |
I know what it is. I'm not removing the periodic edges from the mesh and they're contaminating the plot (most likely) and the cell boundaries (for sure) |
Polaris' version of the funciton handles periodicity in planar as well as spherical meshes.
@xylar Should I go ahead and review now? |
a99cb49
to
d9b666d
Compare
@cbegeman, yes you can try this again. I believe I have handling of periodic boundaries in here correctly now. I added plots to baroclinic channel to test it out: |
d9b666d
to
07930eb
Compare
Still working on this... |
07930eb
to
0e2fd48
Compare
if field_name not in ds: | ||
raise ValueError( | ||
f'{field_name} must be present in ds before plotting.') | ||
|
||
if patches is not None: | ||
if patch_mask is None: | ||
raise ValueError('You must supply both patches and patch_mask ' | ||
'from a previous call to plot_horiz_field()') | ||
|
||
if (transect_x is None) != (transect_y is None): | ||
raise ValueError('You must supply both transect_x and transect_y or ' | ||
'neither') | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just consolidated these at the top because it's a good practice to raise errors early before wasting any time.
@xylar My understanding is that if you want to plot the interface locations that correspond to the same time slice that the field is derived from, you have to include the mesh stream in the output stream so that those variables are available when you pass the output dataset to |
I don't really understand yet what Omega thinks of as mesh variables and what are not. Until I understand the boundary, I can't really design around it. For now, I've been assuming anything that is generic to any MPAS mesh can be shared but variables like I'm happy to design the transect for 2 different input files but it's not clear to me that |
Sounds good. We can certainly wait on this. |
@cbegeman, how would you feel about there being a
and can optionally have |
@xylar I think that makes sense but maybe you're right that we should just wait for OMEGA streams to be worked out so we don't waste time. Your comment triggered another question though: Can you explain how you're using |
I'm actually not using landIceFraction right now. It was used in MPAS-Analysis to make the background light blue where there was ice and brown elsewhere but I didn't try to do that here. So we could remove it for now. |
This should allow the horizontal mesh and constituents of the vertical coordinate to come from different data sets as needed.
@cbegeman, I added more parameters to One thing to be careful about is that you now have to subtract 1 from I removed |
Late but re: separate input for the mesh variables, uxarray has been assuming that the data is in one file and the mesh is in another because we think modeling groups won't put time-invariant things like the mesh info in every output file. |
Some mesh info will be time-dependent - both for wetting/drying and for when we start exercising more of the Lagrangian vertical mesh. For Omega, I suspect that will mean that much of the horz mesh can sit in separate static mesh file, but that some masks and much of the vertical mesh is likely to end up with other time-dependent prognostic/diagnostic vars (in terms of output). We'll know more once we start putting that design doc together. |
@philipwjones, that's helpful and follows what I was thinking. To support diverse vertical coordinates and processes like glacial isostatic adjustment, The solution I have here only assumes (for purposes of transects) that the horizontal mesh is in its own dataset so we should be good. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@xylar Thanks so much for your work on this! I have successfully run the transect routine on a number of test cases. I just have a few minor comments, but feel free to merge when you're happy with it.
plot_transect(ds_transect=ds_transect, mpas_field=mpas_field, | ||
title=f'{field_name} at x={1e-3 * x_mid:.1f} km', | ||
out_filename=f'final_{field_name}_section.png', | ||
vmin=9., vmax=13., cmap='cmo.thermal', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here and below: maybe we want to just define the limits to be the min, max of mpas_field
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, probably the best idea.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done!
Remove confusing references to "3D" and indicate that only fields with `nCells` and `nVertLevels` as dimensions can be plotted.
Color the start and end axes of the transects (now off by default). Use the median to compute the x location of the transect. Use vertices to determine the start and end of the transect in y (so the transects doesn't start in the middle of a cell). Use the min and max of temperature to determine `vmin` and `vmax`, rather than hard-coding.
I ran the baroclinic channel default test one more time and results were as expected. |
Thanks for an excellent review, @cbegeman. You had a ton of useful suggestions that made the final result much better. |
Checklist
api.md
) has any new or modified class, method and/or functions listedTesting
comment in the PR documents testing used to verify the changes