Skip to content

Conversation

@milenaveneziani
Copy link
Collaborator

@milenaveneziani milenaveneziani commented Mar 14, 2017

This PR is intended to accomplish the following:

  1. add a general meridional_overturning_circulation script, which will eventually plot both the results of the MOC analysis member (if enabled) and/or the postprocessed MOC, for the global ocean and for a selected number of oceanic basins. Presently, it supports the computation and plotting of the postprocessed MOC only.

  2. add a plot_vertical_section routine in the plotting module, meant to plot an MPAS vertical slice (as lat vs z, lon vs z, or spherical distance vs z) using the native MPAS grid (no vertical or horizontal interpolation).

  3. modify plotting to make it PEP8 compliant.

@milenaveneziani
Copy link
Collaborator Author

@xylar, @pwolfram: this is not ready to merge, but it is a big PR (for me, at least), so it would be great if you could provide some feedback as soon as it is possible for you.

Things that I tried to address and things that I still would like to address:

  1. raising an error if timeSeriesStats is disabled (to start addressing Clean return for specific analysis if a specific AM turned off in model #58)
  2. check whether MOCam was enabled: if not, go ahead with current post-processing of MOC. (About this: can you please confirm that the open_mf_dataset raises an error if specific variables are not found in the input files? This is in case even the variables needed for MOC postprocessing are not found)
  3. separate global MOC calculation from the regional calculation. This should have a similar structure as the MOC am, but will have to change when we finally have a more definite version of the regional mask files (and associated MOCbasin southern transects)
  4. save computed MOC (annual climatology) to output file
  5. todo: create small functions for the two steps that are needed to compute MOC (we can hopefully talk a bit more about this in the review process)
  6. todo: add timeseries plot of AtlanticMOC at 26.5N. This should be easy to do, but will benefit from 5. We also would want to save the computed time series to file.

@milenaveneziani
Copy link
Collaborator Author

Here are the results, from the beta0 run, and a climatology computed over year 4:

moc_atlantic_20161117 beta0 a_wcycl1850 ne30_oec edison_years0004-0004
moc_global_20161117 beta0 a_wcycl1850 ne30_oec edison_years0004-0004

@xylar
Copy link
Collaborator

xylar commented Mar 14, 2017

this is not ready to merge, but it is a big PR (for me, at least), so it would be great if you could provide some feedback as soon as it is possible for you.

Yep, happy to take a look as soon as I can. I agree, it's a big PR. It looks like a lot of hard work and a very nice job, based on what I've seen so far.

can you please confirm that the open_mf_dataset raises an error if specific variables are not found in the input files? This is in case even the variables needed for MOC postprocessing are not found

I would have to look more closely at the mpas_xarray code but I don't think this will cause an error. The first exception would be raised when you try to access a variable in the data set that doesn't exist. I would think this would be a ValueError or an IndexError and that it would be relatively clear that a variable was missing. But checking on this before calling open_mf_dataset would be even better if the namelist and/or streams files can tell you whether the necessary data will be there.

create small functions for the two steps that are needed to compute MOC (we can hopefully talk a bit more about this in the review process)

Yep, breaking things into smaller functions can often be a good move. Happy to advise where I can.

add timeseries plot of AtlanticMOC at 26.5N. This should be easy to do, but will benefit from 5. We also would want to save the computed time series to file.

Let me know if you need help or advise here, or if it's really just a question of time.

@milenaveneziani
Copy link
Collaborator Author

But checking on this before calling open_mf_dataset would be even better if the namelist and/or streams files can tell you whether the necessary data will be there

ok, I can see to add a check

@milenaveneziani
Copy link
Collaborator Author

@xylar: one other thing that perhaps this could include, since plotting.py is being updated, is to add the setup_colorbar function in plotting, rather than in ocean_modelvsobs. What do you think?

Also, quick dumb question: why some functions start with an underscore? (sorry..)

@xylar
Copy link
Collaborator

xylar commented Mar 14, 2017

one other thing that perhaps this could include, since plotting.py is being updated, is to add the setup_colorbar function in plotting, rather than in ocean_modelvsobs. What do you think?

Sure, that sounds good. You could make a function to parse the colorbar info from the config given a section name, right? Then, different plot routines would call this same function to set up the colorbar?

Also, quick dumb question: why some functions start with an underscore? (sorry..)

No worries, glad you asked. The convention is that functions starting with underscores are "non-public" meaning other python files aren't meant to use them. In practice, you can use whatever you want, but functions with underscores get less documentation and they're allowed to change without warning and don't have to be backwards compatible. It won't get mentioned in the list of functions available at the top of the module.

I typically try to use underscores at the beginning of function names to indicate that it's kind of a helper function. You don't have to do this if you don't want.

@milenaveneziani
Copy link
Collaborator Author

You could make a function to parse the colorbar info from the config given a section name, right? Then, different plot routines would call this same function to set up the colorbar?

yes, that's exactly what I was thinking.

The convention is that functions starting with underscores are "non-public" meaning other python files aren't meant to use them.

ah! great. Thanks.

@xylar
Copy link
Collaborator

xylar commented Mar 15, 2017

@milenaveneziani, could you rebase onto develop and resolve the conflicts in the plotting function? I think you copied over some (maybe all) of my changes into one of your commits, which is going to be a little bit confusing. As a result, it might actually be easier to squash all the commits that modify plotting.py before rebasing.

config.default Outdated
# Mask file for post-processing regional MOC computation
regionMaskFiles = /path/to/MOCregional/mapping/file

# colormap for model/observations
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since there are no observations, maybe change the comment?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@xylar
Copy link
Collaborator

xylar commented Mar 15, 2017

@milenaveneziani, could you post instructions for creating the regional mask files for a given grid? That way, I could create them for some other grids we want to support.

@milenaveneziani
Copy link
Collaborator Author

ok, I have added the Atlantic MOC timeseries (see some results below) and rebased.
It will need some cleanup, and at least a couple of functions, but at least it does what it is supposed to do.
Now for some sleep..

moctimeseries_20161117 beta0 a_wcycl1850 ne30_oec edison

@xylar
Copy link
Collaborator

xylar commented Mar 15, 2017

@milenaveneziani, I can only run the MOC analysis on wolf right now because of not having read permission for the mask on Edison (see above) and not having a mask file for the G-UQ240 run (the only one I can test on my laptop).

I ran successfully with the default settings for the 20161117.beta0.A_WCYCL1850S.ne30_oEC_ICG.edison run on wolf. But when I switch to:

[timeSeries]
startYear = 1
endYear = 9999

which would be settings I would typically use to plot the whole time series, I get an error:

...
     month =  12
   save Atlantic MOC at 26.5N to yearly file...
   year =  4
     month =  1
     month =  2
Traceback (most recent call last):
  File "./run_analysis.py", line 267, in <module>
    analysis(config)
  File "./run_analysis.py", line 196, in analysis
    variableMap=oceanVariableMap)
  File "/turquoise/usr/projects/climate/xylar/mustang/mpas_work/analysis/add_moc_postprocess/mpas_analysis/ocean/meridional_overturning_circulation.py", line 371, in moc_streamfunction
    horizontalVel = ds.avgNormalVelocity[ncount, :, :].values
  File "/usr/projects/climate/SHARED_CLIMATE/anaconda_envs/default-2.7/lib/python2.7/site-packages/xarray/core/dataarray.py", line 469, in __getitem__
    return self.isel(**self._item_key_to_dict(key))
  File "/usr/projects/climate/SHARED_CLIMATE/anaconda_envs/default-2.7/lib/python2.7/site-packages/xarray/core/dataarray.py", line 657, in isel
    ds = self._to_temp_dataset().isel(drop=drop, **indexers)
  File "/usr/projects/climate/SHARED_CLIMATE/anaconda_envs/default-2.7/lib/python2.7/site-packages/xarray/core/dataset.py", line 1119, in isel
    new_var = var.isel(**var_indexers)
  File "/usr/projects/climate/SHARED_CLIMATE/anaconda_envs/default-2.7/lib/python2.7/site-packages/xarray/core/variable.py", line 547, in isel
    return self[tuple(key)]
  File "/usr/projects/climate/SHARED_CLIMATE/anaconda_envs/default-2.7/lib/python2.7/site-packages/xarray/core/variable.py", line 1191, in __getitem__
    values = self._indexable_data[key]
  File "/usr/projects/climate/SHARED_CLIMATE/anaconda_envs/default-2.7/lib/python2.7/site-packages/xarray/core/indexing.py", line 535, in __getitem__
    result = self.array[key]
  File "/usr/projects/climate/SHARED_CLIMATE/anaconda_envs/default-2.7/lib/python2.7/site-packages/pandas/indexes/base.py", line 1423, in __getitem__
    return getitem(key)
IndexError: index 37 is out of bounds for axis 0 with size 37

I will make some comments around the code relating to this error.

@milenaveneziani
Copy link
Collaborator Author

milenaveneziani commented Mar 15, 2017

good catch. I imagine why it gives an error.

About the masks: @mark-petersen made them, you can ask him for instructions on how to do it. Or we can try to address the problem with extracting the southern boundary in the MPAS-Tool that you created a while back (right after this), so that we can create the region masks and transect masks with this newer workflow.

And I will change permissions on the edison mask files, sorry about that.

Copy link
Contributor

@pwolfram pwolfram left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Big picture comments:

  • The code does a nice job of providing two options for plotting of the MOC (pre- and post-processed options) within the current MPAS-Analysis framework.
  • Documentation / overall PEP8 compliance is great.
  • The script is long-- most functions should be 50-100 lines long at most, optimally. This one is around 400. It would be good to break this up into subfunctions if possible, especially related to regions of logic, e.g., A) plot precomputed MOC, B) plot post-process computed MOC
  • I think it is ok to violate PEP8 for the greater interest of clarity in reading the code, as noted below.

# referenceRunName is the name of a reference run to compare against (or None
# to turn off comparison with a reference, e.g. if no reference case is
# available)
referenceRunName = None
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think you need the above lines because referenceRunName = None is specified in the defaults. If it is needed here I recommend a more specific comment than the generic one.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

oceanNamelistFileName = mpas-o_in
oceanStreamsFileName = streams.ocean
seaIceNamelistFileName = mpas-cice_in
seaIceStreamsFileName = streams.cice
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, these appear to be default values so I don't think we need these lines above in this script. They obviously don't hurt, but they do provide additional clutter that a user has to navigate.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

baseDirectory = /lustre/atlas/proj-shared/cli115/observations
sstSubdirectory = SST
sssSubdirectory = SSS
mldSubdirectory = MLD
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similarly, these subdirectories are not unique relative to the defaults and including them here appears redundant.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with your other similar comments, but this one, because we have slightly different directory structures on different machines, so it may be clearer to specify subdirectories.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This makes sense. Thank you for clarifying.

## compared

# directory where sea ice reference simulation results are stored
baseDirectory = /lustre/atlas/proj-shared/cli115/milena/ACMEv0_lowres/B1850C5_ne30_v0.4/ice/postprocessing
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! This makes the input file much cleaner. 👍

raise RuntimeError('*** MPAS-Analysis relies on the existence of '
'monthly\n*** averaged files: make sure to '
'enable the\n*** timeSeriesStatsMonthly '
'analysis member!')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer this be written as

raise RuntimeError('*** MPAS-Analysis relies on the existence of monthly \n'
                   '*** averaged files: make sure to enable the \n'
                   '*** timeSeriesStatsMonthly analysis member!')

to that the error message is easier to read in the code, even if this means we violate PEP8.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The message above is hard to read in its current form, e.g., due to PEP8 compliance.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm good with violating PEP8 in this case.

colorbarLevels = config.getExpression(
sectionNameClimo,
'{}ColorbarLevels'.format(regionName))

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is where the colormapName code, etc, as highlighted above, should go.

time[:] = ds.Time[ncount-12:ncount].values
fldAtlantic26[:] = mocRegional26[ncount-12:ncount]
ncFile.close()
else:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Large if/else loops are difficult to understand. This can be clarified by using more functions as possible to keep code in if/else sections to some small number of lines, e.g., <<50.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alternatively, move the simpler section up front to the if/else to make this clearer.

movingAveragePoints, title,
xLabel, yLabel, figureName,
lineStyles=['k-'], lineWidths=[1.5],
calendar=calendar)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to do all the plotting at the end in designated sections for each particular plot? As it is now plotting occurs throughout the script, which is somewhat confusing.

"""
monthlyClimatology = compute_monthly_climatology(ds, calendar)
annualClimatology = monthlyClimatology.mean('month')
return annualClimatology
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is really beautiful and is demonstrating the power of having modular, easy to understand code!

run_analysis.py Outdated
# print "Plotting Meridional Overturning Circulation (MOC)..."
# from mpas_analysis.ocean.meridional_overturning_circulation import moc_postprocess
# moc_postprocess(config, streamMap=oceanStreamMap,
# variableMap=oceanVariableMap)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need this commented code above? My preference is to remove it from the final merged code.

Copy link
Collaborator

@xylar xylar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@milenaveneziani, I think this is some good progress. Like @pwolfram, I see some places for improvement in terms of organizing into smaller helper functions wherever possible. I think it would be helpful for the future to give some more thought to making code a bit more generic and reusable, like not having variables specific to the Atlantic but rather for whichever region you might be analyzing, and looping over regions (even though there's only one for now).

run_analysis.py Outdated
variableMap=oceanVariableMap)

if checkGenerate(config, analysisName='streamfunctionMOC', mpasCore='ocean',
analysisCategory='regriddedHorizontal'):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would suggest leaving analysisCategory=None for this or inventing a new category (I thought of 'transect' or 'verticalSection', but that's not really correct for the streamfunction...), because I don't think this analysis task really fits in regriddedHorizontal.

As a separate PR later on, I will probably change the name of regriddedHorziontal and the associated tasks to something like climatologyMap. I think the MOC streamfunction still doesn't fit in that category.

print ""
print "Plotting streamfunction of Meridional Overturning Circulation (MOC)..."
from mpas_analysis.ocean.meridional_overturning_circulation import moc_streamfunction
moc_streamfunction(config, streamMap=oceanStreamMap,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Several of these lines are too long to pass PEP8. If you use spyder to edit your code, make sure to go to Preferences > Editor > Code Inspection/Analysis and turn on 'Code analysis'. That way, you will get warnings in orange on the side anytime there's a PEP8 problem. If you're using vim or something else to edit the code, I'm afraid you'll have to use flake8 afterward to check for issues.

import matplotlib.colors as cols

import xarray as xr
import datetime
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

datetime is not used and can be removed

import open_multifile_dataset

from ..shared.timekeeping.utility import get_simulation_start_time, \
days_to_datetime
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

days_to_datetime is not used and can be removed.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have reintroduced it because we do use it now.

refTopDepth[1:nVertLevels+1] = refBottomDepth[0:nVertLevels]
refLayerThickness = np.zeros(nVertLevels)
refLayerThickness[0] = refBottomDepth[0]
refLayerThickness[1:nVertLevels] = refBottomDepth[1:nVertLevels] - \
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Various PEP8 issues starting here. See my other comment about setting up spyder to detect these as you write code. Or use flake8 to find them.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was one specific case when flake8 didn't like what I did, no matter what. which is why I decided to choose the best indent for readability.
I think this was the only option that flake8 liked, from what I remember:

refLayerThickness[1:nVertLevels] =  refBottomDepth[1:nVertLevels] - \
    refBottomDepth[0:nVertLevels-1]

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's complaining that there are 2 spaces after the equal sign. The formatting is fine. Here's how I would handle this one, though:

refLayerThickness[1:nVertLevels] = (refBottomDepth[1:nVertLevels] - 
                                    refBottomDepth[0:nVertLevels-1])

print '\n Compute and/or plot post-processed MOC climatological '\
'streamfunction...'
if not os.path.exists(outputFileClimo):
print ' Load data...'
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This part inside the "if" section could also make sense as a separate helper function.

ncFile.close()
else:
# Read from file
print ' Read previously computed MOC streamfunction from file...'
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This part is small enough that it doesn't necessarily need to be a helper function, but it could be if you wanted to keep things kind of symmetric with the helper function you would add above to compute and write the MOC streamfunction.

## circulation (MOC)

# Mask file for ocean basin regional computation
regionMaskFiles = /global/project/projectdirs/acme/mapping/grids/EC60to30v1_SingleRegionAtlanticWTransportTransects_masks.nc
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@milenaveneziani, could you please change the permissions on this file? The easiest would be changing the group to acme.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

latBinGlobal.description = \
'latitude bins for MOC Global streamfunction'
latBinGlobal.units = 'degrees (-90 to 90)'
latBinAtlantic = ncFile.createVariable(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@milenaveneziani, for now, I think this is fine but I wonder if it would make sense to rewrite everything explicitly referencing the Atlantic so it doesn't have to know which region it's referring to in anticipation of having a list of regions. If you want, we could discuss this by phone.

outputFileTseries = '{}/mocTimeSeries_year{:04d}.nc'.format(
outputDirectory, year)
if not os.path.exists(outputFileTseries):
for nm in range(12):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this outer looping over nyears and inner looping over months is problematic because the time series may not start and end t the beginning and end of a year, as I found when I set endYear=9999 on wolf.

I also don't see the value of saving a netcdf file for each year as opposed to processing all years into a single file. If the idea would be to add data to your existing file as the run continues, that would be possible with an unlimited dimension for time. The existing approach is problematic if a given year is incomplete because the file might exist from the previous run of analysis but it might be incomplete (because the output for the full final year didn't yet exist) so breaking the output into yearly files doesn't really change the need for an unlimited time dimension and checking to see if you need to append to an existing file or create a new one.

Here is an example of a script where I use an unlimited dimension for time and either create a new file or append to and existing one, depending on whether the file exists already:
https://github.com/MPAS-Dev/MPAS/blob/ocean/develop/testing_and_setup/compass/ocean/isomip_plus/viz/computeOverturningStreamfunction.py#L132

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps we should discuss this by phone.

@milenaveneziani
Copy link
Collaborator Author

Thanks so much for the prompt review!
I went through your comments quickly, trying to get a sense of the big picture first. Two comments from me at this point:

  1. Do you both agree that it would be better to ignore the PEP8 too long a line compliance, in the interest of readability? I payed attention and tried to keep the lines within 79 characters long, but in some cases readability has suffered, I agree with @pwolfram, and in other cases I just did not like any alternative..
  2. I have thought about making this more generic in terms of the regions, but decided against it because we are using temporary region/transect maskfiles at the moment. Within the newer workflow, we will have 1 BasinMOC_regiongroup maskfile and an associated southern transect file, with a corresponding region group name and appropriate region names. We do not have any of this at the moment. So my feeling is that we either solve the issues of the newer workflow before continuing with this PR, or we leave this as Atlantic-only and generalize it later.

I will address or reply to your comments one by one now.

@xylar
Copy link
Collaborator

xylar commented Mar 15, 2017

Do you both agree that it would be better to ignore the PEP8 too long a line compliance, in the interest of readability? I payed attention and tried to keep the lines within 79 characters long, but in some cases readability has suffered, I agree with @pwolfram, and in other cases I just did not like any alternative..

Okay, well I guess I can go along with this. I've been trying to be very strict about the PEP8 standard. My preference would be to try very hard to maintain the standard but to have long lines in rare instances (e.g. very long strings, particularly when it puts \n commands in the logical place). The 79 character limit is frankly quite inconvenient and there are lots of cases where I think readability would be better without it but then one might as well throw out the standard...

We do not have any of this at the moment. So my feeling is that we either solve the issues of the newer workflow before continuing with this PR, or we leave this as Atlantic-only and generalize it later.

Okay, I'm fine with generalizing later. If I were writing this, I'd want to save myself work down the road by writing the generalized version now. But since it's already written this way, I think it's fine to leave it for now.

@milenaveneziani
Copy link
Collaborator Author

If I were writing this, I'd want to save myself work down the road by writing the generalized version now.

I know, I feel the same way. I guess what I could do is revisit the MPAS-Tool you created a few months ago, and see what I get with the script that I have now. We could try to reiterate a bit there to see if we can solve any issue relatively quickly, and then go from there. What do you think?


ax = plt.gca()

# Add a x=0 line if y ranges between positive and negative values
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you mean y = 0, not x = 0, right?

@xylar
Copy link
Collaborator

xylar commented Mar 18, 2017

making setup_colormap a function in plotting.py, meant that in some cases I needed to define a colormapName (and colormapIndices) for a few cases within the same analysis, even though they were all the same.

This all seems great! I'm not bothered by the redundancy because it allows flexibility we might want in the future and makes things very clear. The longer config.default isn't a problem, since it won't affect the config files for specific jobs.

I took the liberty, since plotting.py has been changed substantially in this PR, to add 4 lines of code to plot_timeseries that add a x=0 line when the y axis spans negative and positive values.

Looking at the code, I think you mean y = 0, not x = 0. If you just update the comment, I think everything looks good and I agree this can go into the PR.

@xylar
Copy link
Collaborator

xylar commented Mar 18, 2017

Looking at the code, there are still a number of PEP8 formatting issues that should preferably be addressed before this gets merged. I can point out individual ones if you need. spyder should be able to help with indentation issues.

@xylar
Copy link
Collaborator

xylar commented Mar 18, 2017

Tests on my laptop seem to suggest that _compute_moc_postprocess is very memory intensive (requiring nearly 32 GB of ram, which is the entire memory plus swap on my laptop). I suspect optimizations might be possible to reduce the memory consumption.

For now, I am just flagging this as a potential issue to possibly be addressed in a follow-up PR.

print '\n Compute and/or plot post-processed MOC climatological '\
'streamfunction...'
simulationStartTime = get_simulation_start_time(streams)
outputDirectory = buildConfigFullPath(config, 'output',
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This output directory is appropriate for the streamfunction but maybe it's kind of confusing to write files for the time series here? Should we make a separate directory for writing out time series data? We could also cache extractions of time series from other analysis tasks.

@xylar
Copy link
Collaborator

xylar commented Mar 18, 2017

@milenaveneziani, I went ahead an made the changes I suggested above because I needed them to test the code. I also did a little bit of clean up. If you want, you can just do a hard reset (or a cherry-pick) to 7370db9.

@xylar
Copy link
Collaborator

xylar commented Mar 18, 2017

@milenaveneziani, if you are okay with my last fix, I think we're in good shape. I have tested with these changes using the 20161117.beta0.A_WCYCL1850S.ne30_oEC_ICG.edison run on both my laptop, on wolf and on edison. I ran twice to make sure things still work when reloading the results from files, and they do.

I also tested the beta1 run (20170313.beta1.A_WCYCL1850S.ne30_oECv3_ICG.edison) and that seems to work, too.

@xylar
Copy link
Collaborator

xylar commented Mar 18, 2017

Note: I'm not able to run on an alpha8 run:

./run_analysis.py --generate streamfunctionMOC config.20161006bugfix.alpha8.A_WCYCL1850S.ne30_oEC_ICG.edison 

Plotting streamfunction of Meridional Overturning Circulation (MOC)...
Traceback (most recent call last):
  File "./run_analysis.py", line 259, in <module>
    analysis(config)
  File "./run_analysis.py", line 196, in analysis
    variableMap=oceanVariableMap)
  File "/global/u2/x/xylar/mpas_work/analysis/add_moc_postprocess/mpas_analysis/ocean/meridional_overturning_circulation.py", line 79, in moc_streamfunction
    'config_am_timeseriesstatsmonthly_enable')
  File "/global/u2/x/xylar/mpas_work/analysis/add_moc_postprocess/mpas_analysis/shared/io/namelist_streams_interface.py", line 93, in get
    return self.nml[key]
  File "/global/u2/x/xylar/mpas_work/analysis/add_moc_postprocess/mpas_analysis/shared/containers.py", line 21, in __getitem__
    return self._data[key]
KeyError: 'config_am_timeseriesstatsmonthly_enable'

Maybe that's okay but we should make a decision if we're not supporting backward compatibility to older runs.

@xylar
Copy link
Collaborator

xylar commented Mar 18, 2017

20161117.beta0.A_WCYCL1850S.ne30_oEC_ICG.edison on edison:

mocatlantic_20161117 beta0 a_wcycl1850 ne30_oec edison_years0041-0050
mocglobal_20161117 beta0 a_wcycl1850 ne30_oec edison_years0041-0050
moctimeseries_20161117 beta0 a_wcycl1850 ne30_oec edison

@xylar
Copy link
Collaborator

xylar commented Mar 18, 2017

@milenaveneziani, I'm looking forward to having these available for a doing actual analysis. The beta1 run seems to have a weaker Atlantic MOC and also less variability.

One suggestion might be changing the colormap and/or removing the tick at 0 Sv in the Global MOC plot because the transition just look like noise in all the plots and it's rather distracting.

@milenaveneziani
Copy link
Collaborator Author

ah, that's because the am was not called timeseriesstatsmonthly back then.. That means it has to go through variable map? Not too worried about alpha8, but maybe we can make it more robust to future changes.
I am hopefully going to work on this a bit more later today. Thanks for the review.

@xylar
Copy link
Collaborator

xylar commented Mar 18, 2017

I am hopefully going to work on this a bit more later today. Thanks for the review.

Sounds good. Let me know when you're happy. I'll do one last test on Edison (on the theory that the longer tests across multiple runs will catch more problems) and then I'm happy to merge.

I'm assuming @mark-petersen isn't going to do a review?

@xylar
Copy link
Collaborator

xylar commented Mar 18, 2017

@milenaveneziani, just remove the "don't merge" tag and I'll take that as the sign it's ready to merge. There are a lot of commits in this branch. I think that's likely appropriate, but if you decide you want to rebase and squash some of the commits, that is also fine.

@milenaveneziani
Copy link
Collaborator Author

@xylar: I addressed all your remaining comments, except for the one related to the failing for alpha8.
I think I understand that I would need to create a name map for the timeSeriesStats config option, in much the same way as we do now for variables and streams. But I do not have the energy (and enough knowledge now) to put this into practice. If it's something easy for you, and you have the time and energy to explain what I should do, I'd be happy to include this last change.
If not, I squashed commits: you can go ahead and test one more time before merging. Thanks.

@milenaveneziani
Copy link
Collaborator Author

milenaveneziani commented Mar 19, 2017

btw, here is an example of Global MOC streamfunction with newer colorbar levels:

mocglobal_20170313 beta1 a_wcycl1850s ne30_oecv3_icg edison_years0011-0020

@xylar
Copy link
Collaborator

xylar commented Mar 19, 2017

Sounds good. I don't think alpha8 is a problem but if we find we should be supporting it, we can do a fix later on.

I like the change to the color levels. It looks much less noisy.

@xylar
Copy link
Collaborator

xylar commented Mar 19, 2017

@milenaveneziani, I tried running a full test of the beta1 run on Edison and I don't have permission to read the mapping file: /global/project/projectdirs/acme/mapping/maps/map_oEC60to30v3_TO_0.5x0.5degree_blin.nc Could you please change all files in that folder to be in the acme group?

I was able to successfully run beta1 by commenting out the path to the mapping file so it was generated.

@xylar xylar merged commit f27166d into MPAS-Dev:develop Mar 19, 2017
@milenaveneziani milenaveneziani deleted the add_moc_postprocess branch March 20, 2017 02:19
@milenaveneziani
Copy link
Collaborator Author

Thanks @xylar. Sorry about the permissions for the mapping file. So glad this is integrated now.

@xylar
Copy link
Collaborator

xylar commented Mar 20, 2017

Very nice work!

@milenaveneziani
Copy link
Collaborator Author

one last thing about this one, about the slow performance of _compute_transport: it does not surprise me too much. I have tried to remove the loop that I think it is causing it, but did not have much success. At some point, I will talk with @mark-petersen about it and see if he has ideas on how to simplify that search over the transect Edges.

@pwolfram
Copy link
Contributor

@milenaveneziani, please see #164 for the removal of the loop if you are interested.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants