|
| 1 | +#!/usr/bin/env python |
| 2 | +''' |
| 3 | +Script to allow plotting MALI output on a sphere in Paraview. |
| 4 | +This works by replacing x/y/zCell fields and modifying global attributes so |
| 5 | +Paraview will plot as a spherical mesh. Paraview only uses those 3 fields for |
| 6 | +plotting. |
| 7 | +The script modifies the file in place, so be sure to make a copy first! |
| 8 | +If you screw that up, you can always copy the planar cell coordinate fields |
| 9 | +from another file and set on_a_sphere back to NO. |
| 10 | +Note that the modified coordinates will make the file no longer compatible |
| 11 | +with MALI or many postprocessing tools, so this is meant as a modification |
| 12 | +for visuatlization in Paraview only. |
| 13 | +''' |
| 14 | + |
| 15 | +import argparse |
| 16 | +from netCDF4 import Dataset |
| 17 | +import numpy as np |
| 18 | + |
| 19 | +parser = argparse.ArgumentParser( |
| 20 | + prog='convert_cell_coordinates_to_sphere.py', |
| 21 | + description=__doc__, |
| 22 | + formatter_class=argparse.RawDescriptionHelpFormatter) |
| 23 | +parser.add_argument("-f", dest="filename", default="output.nc", |
| 24 | + help="file to convert to a spherical mesh convention") |
| 25 | +parser.add_argument("-r", dest="radius", type=float, default=6371220., |
| 26 | + help="sphere radius to use (m)") |
| 27 | +args = parser.parse_args() |
| 28 | + |
| 29 | + |
| 30 | +def compute_xyz(latCell_deg, lonCell_deg, radius=args.radius): |
| 31 | + ''' |
| 32 | + Copied from lonlat2xyz in mesh/creation/util.py |
| 33 | + ''' |
| 34 | + lat_rad = np.radians(latCell_deg) |
| 35 | + lon_rad = np.radians(lonCell_deg) |
| 36 | + |
| 37 | + xCell = radius * np.cos(lat_rad) * np.cos(lon_rad) |
| 38 | + yCell = radius * np.cos(lat_rad) * np.sin(lon_rad) |
| 39 | + zCell = radius * np.sin(lat_rad) |
| 40 | + |
| 41 | + return xCell, yCell, zCell |
| 42 | + |
| 43 | + |
| 44 | +ds = Dataset(args.filename, "r+") |
| 45 | +latCell = np.degrees(ds.variables["latCell"][:]) |
| 46 | +lonCell = np.degrees(ds.variables["lonCell"][:]) |
| 47 | + |
| 48 | +xCell, yCell, zCell = compute_xyz(latCell, lonCell) |
| 49 | + |
| 50 | +# Add to NetCDF file (assumes variables already exist) |
| 51 | +ds.variables["xCell"][:] = xCell |
| 52 | +ds.variables["yCell"][:] = yCell |
| 53 | +ds.variables["zCell"][:] = zCell |
| 54 | +# Update global attributes |
| 55 | +ds.setncattr("on_a_sphere", "YES") |
| 56 | +ds.setncattr("sphere_radius", args.radius) |
| 57 | +ds.close() |
0 commit comments