@@ -76,7 +76,6 @@ def __init__(self, config, mpasClimatologyTask, regionMasksTask,
7676
7777 sectionName = self .taskName
7878
79- mpasFieldName = 'timeMonthly_avg_landIceFreshwaterFlux'
8079 iselValues = None
8180
8281 # read in what seasons we want to plot
@@ -109,15 +108,15 @@ def __init__(self, config, mpasClimatologyTask, regionMasksTask,
109108 mpasClimatologyTask = mpasClimatologyTask ,
110109 parentTask = self ,
111110 climatologyName = fieldName ,
112- variableList = [ mpasFieldName ] ,
111+ variableList = None ,
113112 comparisonGridNames = comparisonGridNames ,
114113 seasons = seasons ,
115114 iselValues = iselValues )
116115
117116 if controlConfig is None :
118117
119118 refTitleLabel = \
120- 'Observations (Paolo et al, 2023)'
119+ 'Observations (Paolo et al. 2023)'
121120
122121 observationsDirectory = build_obs_path (
123122 config , 'ocean' , 'meltSubdirectory' )
@@ -138,47 +137,128 @@ def __init__(self, config, mpasClimatologyTask, regionMasksTask,
138137 f'{ observationsDirectory } /Paolo/Paolo_2023_' \
139138 f'iceshelf_melt_rates_1992-2017_v1.0_6000x6000km_{ res :g} km_' \
140139 f'Antarctic_stereo.20240220.nc'
141- refFieldName = 'meltRate'
142- outFileLabel = 'meltPaolo'
143- galleryName = 'Observations: Paolo et al. (2023)'
144140
145141 remapObservationsSubtask = RemapObservedAntarcticMeltClimatology (
146142 parentTask = self , seasons = seasons , fileName = obsFileName ,
147- outFilePrefix = refFieldName ,
143+ outFilePrefix = 'meltRate' ,
148144 comparisonGridNames = comparisonGridNames )
149145 self .add_subtask (remapObservationsSubtask )
150146 diffTitleLabel = 'Model - Observations'
151147
152148 else :
153149 remapObservationsSubtask = None
154150 controlRunName = controlConfig .get ('runs' , 'mainRunName' )
155- galleryName = None
156151 refTitleLabel = f'Control: { controlRunName } '
152+ diffTitleLabel = 'Main - Control'
153+
154+ totalFluxVar = 'timeMonthly_avg_landIceFreshwaterFluxTotal'
155+ landIceFluxVar = 'timeMonthly_avg_landIceFreshwaterFlux'
156+ frazilFluxVar = 'timeMonthly_avg_frazilIceFreshwaterFlux'
157157
158+ mpasFieldName = totalFluxVar
159+
160+ if controlConfig is None :
161+ refFieldName = 'meltRate'
162+ else :
158163 refFieldName = mpasFieldName
159- outFileLabel = 'melt'
160- diffTitleLabel = 'Main - Control'
161164
162165 for comparisonGridName in comparisonGridNames :
163166 for season in seasons :
164167 # make a new subtask for this season and comparison grid
165- subtask = PlotClimatologyMapSubtask (
168+ subtaskName = f'plot_total_melt_{ season } _{ comparisonGridName } '
169+ subtask = PlotAntarcticMeltSubtask (
166170 self , season , comparisonGridName , remapClimatologySubtask ,
167- remapObservationsSubtask , controlConfig = controlConfig )
171+ remapObservationsSubtask , controlConfig = controlConfig ,
172+ subtaskName = subtaskName )
168173
169174 subtask .set_plot_info (
170- outFileLabel = outFileLabel ,
171- fieldNameInTitle = 'Melt Rate ' ,
175+ outFileLabel = 'antMeltTotal' ,
176+ fieldNameInTitle = 'Total Melt Flux ' ,
172177 mpasFieldName = mpasFieldName ,
173178 refFieldName = refFieldName ,
174179 refTitleLabel = refTitleLabel ,
175180 diffTitleLabel = diffTitleLabel ,
176- unitsLabel = r'm a$^{-1}$' ,
177- imageCaption = 'Antarctic Melt Rate ' ,
181+ unitsLabel = r'm a$^{-1}$ freshwater equiv. ' ,
182+ imageCaption = 'Antarctic Total Melt Flux ' ,
178183 galleryGroup = 'Melt Rate' ,
179184 groupSubtitle = None ,
180185 groupLink = 'antarctic_melt' ,
181- galleryName = galleryName )
186+ galleryName = 'Total Melt Flux' )
187+
188+ self .add_subtask (subtask )
189+
190+ mpasFieldName = landIceFluxVar
191+
192+ if controlConfig is None :
193+ refFieldName = 'meltRate'
194+ else :
195+ refFieldName = mpasFieldName
196+
197+ for comparisonGridName in comparisonGridNames :
198+ for season in seasons :
199+ # make a new subtask for this season and comparison grid
200+ subtaskName = \
201+ f'plot_interface_melt_{ season } _{ comparisonGridName } '
202+ subtask = PlotAntarcticMeltSubtask (
203+ self , season , comparisonGridName , remapClimatologySubtask ,
204+ remapObservationsSubtask , controlConfig = controlConfig ,
205+ subtaskName = subtaskName )
206+
207+ # In PlotAntarcticMeltSubtask, we will remove the obs from
208+ # these plots if totalFluxVar is present so we only compare one
209+ # field with obs
210+
211+ subtask .set_plot_info (
212+ outFileLabel = 'antMeltInterface' ,
213+ fieldNameInTitle = 'Melt Rate at Interface' ,
214+ mpasFieldName = mpasFieldName ,
215+ refFieldName = refFieldName ,
216+ refTitleLabel = refTitleLabel ,
217+ diffTitleLabel = diffTitleLabel ,
218+ unitsLabel = r'm a$^{-1}$ freshwater equiv.' ,
219+ imageCaption = 'Antarctic Melt Rate at Interface' ,
220+ galleryGroup = 'Melt Rate' ,
221+ groupSubtitle = None ,
222+ groupLink = 'antarctic_melt_int' ,
223+ galleryName = 'Melt Rate at the Ice-ocean Interface' )
224+
225+ self .add_subtask (subtask )
226+
227+ mpasFieldName = frazilFluxVar
228+
229+ if controlConfig is None :
230+ refTitleLabel = None
231+ refFieldName = None
232+ diffTitleLabel = None
233+
234+ else :
235+ controlRunName = controlConfig .get ('runs' , 'mainRunName' )
236+ refTitleLabel = f'Control: { controlRunName } '
237+ refFieldName = mpasFieldName
238+ diffTitleLabel = 'Main - Control'
239+
240+ for comparisonGridName in comparisonGridNames :
241+ for season in seasons :
242+ # make a new subtask for this season and comparison grid
243+ subtaskName = \
244+ f'plot_interface_frazil_{ season } _{ comparisonGridName } '
245+ subtask = PlotAntarcticMeltSubtask (
246+ self , season , comparisonGridName , remapClimatologySubtask ,
247+ controlConfig = controlConfig , subtaskName = subtaskName )
248+
249+ subtask .set_plot_info (
250+ outFileLabel = 'antFrazil' ,
251+ fieldNameInTitle = 'Frazil Accretion Rate, negative upward' ,
252+ mpasFieldName = mpasFieldName ,
253+ refFieldName = refFieldName ,
254+ refTitleLabel = refTitleLabel ,
255+ diffTitleLabel = diffTitleLabel ,
256+ unitsLabel = r'm a$^{-1}$ freshwater equiv.' ,
257+ imageCaption = 'Antarctic Accretion Rate' ,
258+ galleryGroup = 'Melt Rate' ,
259+ groupSubtitle = None ,
260+ groupLink = 'antarctic_frazil_flux' ,
261+ galleryName = 'Frazil Accretion Rate' )
182262
183263 self .add_subtask (subtask )
184264
@@ -212,11 +292,35 @@ class RemapMpasAntarcticMeltClimatology(RemapMpasClimatologySubtask):
212292 landIceMask : xarray.DataArray
213293 A mask indicating where there is land ice on the ocean grid (thus,
214294 where melt rates are valid)
295+
296+ renameDict : dict
297+ A dictionary use to rename variables in the climatology
215298 """
216299 # Authors
217300 # -------
218301 # Xylar Asay-Davis
219302
303+ def setup_and_check (self ):
304+ """
305+ Figure out which variable(s) to remap
306+ """
307+ # Authors
308+ # -------
309+ # Xylar Asay-Davis
310+
311+ totalFluxVar = 'timeMonthly_avg_landIceFreshwaterFluxTotal'
312+ landIceFluxVar = 'timeMonthly_avg_landIceFreshwaterFlux'
313+ frazilFluxVar = 'timeMonthly_avg_frazilIceFreshwaterFlux'
314+
315+ if totalFluxVar in self .mpasClimatologyTask .allVariables :
316+ # include the total and constituent fluxes
317+ self .variableList = [totalFluxVar , landIceFluxVar , frazilFluxVar ]
318+ else :
319+ # we only have the old name without the frazil accretion rate
320+ self .variableList = [landIceFluxVar ]
321+
322+ super ().setup_and_check ()
323+
220324 def run_task (self ):
221325 """
222326 Compute climatologies of melt rates from E3SM/MPAS output
@@ -260,12 +364,14 @@ def customize_masked_climatology(self, climatology, season):
260364 # -------
261365 # Xylar Asay-Davis
262366
263- fieldName = self .variableList [ 0 ]
367+ for fieldName in self .variableList :
264368
265- # scale the field to m/yr from kg/m^2/s and mask out non-land-ice areas
266- climatology [fieldName ] = \
267- constants .sec_per_year / constants .rho_fw * \
268- climatology [fieldName ].where (self .landIceMask )
369+ # scale the field to m/yr from kg/m^2/s and mask out non-land-ice
370+ # areas
371+ climatology [fieldName ] = \
372+ constants .sec_per_year / constants .rho_fw * \
373+ climatology [fieldName ].where (self .landIceMask )
374+ climatology [fieldName ].attrs ['units' ] = 'm yr^-1'
269375
270376 return climatology
271377
@@ -422,7 +528,8 @@ def run_task(self):
422528 pool = ThreadPool (1 )):
423529
424530 # Load data:
425- inFileName = self .mpasClimatologyTask .get_file_name (self .season )
531+ inFileName = \
532+ self .mpasClimatologyTask .get_file_name (self .season )
426533 mpasFieldName = 'timeMonthly_avg_landIceFreshwaterFlux'
427534 dsIn = xr .open_dataset (inFileName )
428535 freshwaterFlux = dsIn [mpasFieldName ]
@@ -445,7 +552,8 @@ def run_task(self):
445552
446553 # select only those regions we want to plot
447554 dsRegionMask = dsRegionMask .isel (nRegions = regionIndices )
448- cellMasks = dsRegionMask .regionCellMasks .chunk ({'nRegions' : 10 })
555+ cellMasks = \
556+ dsRegionMask .regionCellMasks .chunk ({'nRegions' : 10 })
449557
450558 restartFileName = \
451559 self .runStreams .readpath ('restart' )[0 ]
@@ -548,3 +656,53 @@ def run_task(self):
548656 row [controlRunName ] = \
549657 f'{ dsControl .totalMeltFlux [index ].values } '
550658 writer .writerow (row )
659+
660+
661+ class PlotAntarcticMeltSubtask (PlotClimatologyMapSubtask ):
662+ """
663+ A subtask for plotting antarctic melt fields if available
664+
665+ Attributes
666+ ----------
667+ doPlot : bool
668+ Whether the required variable from the climatology is available so that
669+ a plot should be generated
670+ """
671+ # Authors
672+ # -------
673+ # Xylar Asay-Davis
674+
675+ def setup_and_check (self ):
676+ """
677+ Perform steps to set up the analysis and check for errors in the setup.
678+ """
679+ allVariables = \
680+ self .remapMpasClimatologySubtask .mpasClimatologyTask .allVariables
681+
682+ totalFluxVar = 'timeMonthly_avg_landIceFreshwaterFluxTotal'
683+ landIceFluxVar = 'timeMonthly_avg_landIceFreshwaterFlux'
684+ plotAll = (totalFluxVar in allVariables )
685+
686+ if self .mpasFieldName == landIceFluxVar and plotAll and \
687+ self .controlConfig is None :
688+ # need to remove obs because we only wnat to plot them vs the
689+ # total flux
690+ self .remapObsClimatologySubtask = None
691+ self .refTitleLabel = None
692+ self .refFieldName = None
693+ self .diffTitleLabel = None
694+
695+ self .doPlot = (self .mpasFieldName == landIceFluxVar or plotAll )
696+
697+ if self .doPlot :
698+ super ().setup_and_check ()
699+ else :
700+ # still need to call the base class's method
701+ AnalysisTask .setup_and_check (self = self )
702+
703+ def run_task (self ):
704+ """
705+ Plot the variable if available
706+ """
707+ if self .doPlot :
708+ super ().run_task ()
0 commit comments