|
24 | 24 | from __future__ import absolute_import, division, print_function, \
|
25 | 25 | unicode_literals
|
26 | 26 |
|
27 |
| -import os |
28 | 27 | from optparse import OptionParser
|
29 | 28 | import xarray
|
30 | 29 |
|
31 |
| -from geometric_features import GeometricFeatures |
| 30 | +from geometric_features import GeometricFeatures, FeatureCollection, \ |
| 31 | + read_feature_collection |
32 | 32 | from mpas_tools import conversion
|
33 | 33 | from mpas_tools.io import write_netcdf
|
34 | 34 | from mpas_tools.ocean.coastline_alteration import widen_transect_edge_masks, \
|
|
37 | 37 |
|
38 | 38 |
|
39 | 39 | parser = OptionParser()
|
40 |
| -parser.add_option("--with_cavities", action="store_true", dest="with_cavities") |
| 40 | +parser.add_option("--with_cavities", action="store_true", dest="with_cavities", |
| 41 | + help="Whether the mesh should include Antarctic ice-shelf" |
| 42 | + " cavities") |
41 | 43 | parser.add_option("--with_critical_passages", action="store_true",
|
42 |
| - dest="with_critical_passages") |
| 44 | + dest="with_critical_passages", |
| 45 | + help="Whether the mesh should open the standard critical " |
| 46 | + "passages and close land blockages from " |
| 47 | + "geometric_features") |
| 48 | +parser.add_option( |
| 49 | + "--custom_critical_passages", |
| 50 | + dest="custom_critical_passages", |
| 51 | + help="A geojson file with critical passages to open. This " |
| 52 | + "file may be supplied in addition to or instead of " |
| 53 | + "the default passages (--with_critical_passages)") |
| 54 | +parser.add_option( |
| 55 | + "--custom_land_blockages", |
| 56 | + dest="custom_land_blockages", |
| 57 | + help="A geojson file with critical land blockages to close. " |
| 58 | + "This file may be supplied in addition to or instead of " |
| 59 | + "the default blockages (--with_critical_passages)") |
43 | 60 | parser.add_option("--preserve_floodplain", action="store_true",
|
44 |
| - dest="preserve_floodplain", default=False) |
| 61 | + dest="preserve_floodplain", default=False, |
| 62 | + help="Whether to use the cellSeedMask field in the base " |
| 63 | + "mesh to preserve a floodplain at elevations above z=0") |
45 | 64 | options, args = parser.parse_args()
|
46 | 65 |
|
47 | 66 | # required for compatibility with MPAS
|
48 | 67 | netcdfFormat = 'NETCDF3_64BIT'
|
49 | 68 |
|
| 69 | +critical_passages = options.with_critical_passages or \ |
| 70 | + (options.custom_critical_passages is not None) |
| 71 | + |
| 72 | +land_blockages = options.with_critical_passages or \ |
| 73 | + (options.custom_land_blockages is not None) |
| 74 | + |
50 | 75 | gf = GeometricFeatures()
|
51 | 76 |
|
52 | 77 | # start with the land coverage from Natural Earth
|
|
88 | 113 | fcSeed = gf.read(componentName='ocean', objectType='point',
|
89 | 114 | tags=['seed_point'])
|
90 | 115 |
|
91 |
| -if options.with_critical_passages: |
92 |
| - # merge transects for critical passages into critical_passages.geojson |
93 |
| - fcCritPassages = gf.read(componentName='ocean', objectType='transect', |
94 |
| - tags=['Critical_Passage']) |
| 116 | +if land_blockages: |
| 117 | + if options.with_critical_passages: |
| 118 | + # merge transects for critical land blockages into |
| 119 | + # critical_land_blockages.geojson |
| 120 | + fcCritBlockages = gf.read(componentName='ocean', objectType='transect', |
| 121 | + tags=['Critical_Land_Blockage']) |
| 122 | + else: |
| 123 | + fcCritBlockages = FeatureCollection() |
| 124 | + |
| 125 | + if options.custom_land_blockages is not None: |
| 126 | + fcCritBlockages.merge(read_feature_collection( |
| 127 | + options.custom_land_blockages)) |
| 128 | + |
| 129 | + # create masks from the transects |
| 130 | + dsCritBlockMask = conversion.mask(dsBaseMesh, fcMask=fcCritBlockages) |
| 131 | + |
| 132 | + dsLandMask = add_critical_land_blockages(dsLandMask, dsCritBlockMask) |
| 133 | + |
| 134 | +fcCritPassages = FeatureCollection() |
| 135 | +dsPreserve = [] |
| 136 | + |
| 137 | +if critical_passages: |
| 138 | + if options.with_critical_passages: |
| 139 | + # merge transects for critical passages into critical_passages.geojson |
| 140 | + fcCritPassages.merge(gf.read(componentName='ocean', |
| 141 | + objectType='transect', |
| 142 | + tags=['Critical_Passage'])) |
| 143 | + |
| 144 | + if options.custom_critical_passages is not None: |
| 145 | + fcCritPassages.merge(read_feature_collection( |
| 146 | + options.custom_critical_passages)) |
95 | 147 |
|
96 | 148 | # create masks from the transects
|
97 | 149 | dsCritPassMask = conversion.mask(dsBaseMesh, fcMask=fcCritPassages)
|
|
101 | 153 | dsCritPassMask = widen_transect_edge_masks(dsCritPassMask, dsBaseMesh,
|
102 | 154 | latitude_threshold=43.0)
|
103 | 155 |
|
104 |
| - # merge transects for critical land blockages into |
105 |
| - # critical_land_blockages.geojson |
106 |
| - fcCritBlockages = gf.read(componentName='ocean', objectType='transect', |
107 |
| - tags=['Critical_Land_Blockage']) |
108 |
| - |
109 |
| - # create masks from the transects for critical land blockages |
110 |
| - dsCritBlockMask = conversion.mask(dsBaseMesh, fcMask=fcCritBlockages) |
111 |
| - |
112 |
| - dsLandMask = add_critical_land_blockages(dsLandMask, dsCritBlockMask) |
| 156 | + dsPreserve.append(dsCritPassMask) |
113 | 157 |
|
114 |
| - # Cull the mesh based on the land mask while keeping critical passages open |
115 |
| - if options.preserve_floodplain: |
116 |
| - dsCulledMesh = conversion.cull(dsBaseMesh, dsMask=dsLandMask, |
117 |
| - dsPreserve=[dsCritPassMask, dsBaseMesh]) |
118 |
| - else: |
119 |
| - dsCulledMesh = conversion.cull(dsBaseMesh, dsMask=dsLandMask, |
120 |
| - dsPreserve=dsCritPassMask) |
| 158 | +if options.preserve_floodplain: |
| 159 | + dsPreserve.append(dsBaseMesh) |
121 | 160 |
|
122 |
| -else: |
123 | 161 |
|
124 |
| - # cull the mesh based on the land mask |
125 |
| - if options.preserve_floodplain: |
126 |
| - dsCulledMesh = conversion.cull(dsBaseMesh, dsMask=dsLandMask, |
127 |
| - dsPreserve=dsBaseMesh) |
128 |
| - else: |
129 |
| - dsCulledMesh = conversion.cull(dsBaseMesh, dsMask=dsLandMask) |
130 |
| - fcCritPassages = None |
| 162 | +# cull the mesh based on the land mask |
| 163 | +dsCulledMesh = conversion.cull(dsBaseMesh, dsMask=dsLandMask, |
| 164 | + dsPreserve=dsPreserve) |
131 | 165 |
|
132 | 166 | # create a mask for the flood fill seed points
|
133 | 167 | dsSeedMask = conversion.mask(dsCulledMesh, fcSeed=fcSeed)
|
|
137 | 171 | graphInfoFileName='culled_graph.info')
|
138 | 172 | write_netcdf(dsCulledMesh, 'culled_mesh.nc', format=netcdfFormat)
|
139 | 173 |
|
140 |
| -if options.with_critical_passages: |
| 174 | +if critical_passages: |
141 | 175 | # make a new version of the critical passages mask on the culled mesh
|
142 | 176 | dsCritPassMask = conversion.mask(dsCulledMesh, fcMask=fcCritPassages)
|
143 | 177 | write_netcdf(dsCritPassMask, 'critical_passages_mask_final.nc',
|
|
167 | 201 | variable_list=['allOnCells'],
|
168 | 202 | filename_pattern='no_ISC_culled_mesh.nc',
|
169 | 203 | out_dir='no_ISC_culled_mesh_vtk')
|
170 |
| - |
|
0 commit comments