Skip to content
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

Developing sco class #33

Draft
wants to merge 21 commits into
base: main
Choose a base branch
from
Draft

Developing sco class #33

wants to merge 21 commits into from

Conversation

oceandie
Copy link
Contributor

  • Closes #xxxx
  • Tests added
  • Passes pre-commit run --all-files
  • Changes are documented in whats-new.rst
  • New functions/methods are listed in api.rst
  • Project, label, and assignee tabs are populated

@codecov
Copy link

codecov bot commented Jun 15, 2021

Codecov Report

Merging #33 (1d80a84) into main (9002bb0) will decrease coverage by 13.18%.
The diff coverage is 14.63%.

Impacted file tree graph

@@             Coverage Diff             @@
##             main      #33       +/-   ##
===========================================
- Coverage   94.85%   81.67%   -13.19%     
===========================================
  Files           5        5               
  Lines         214      251       +37     
===========================================
+ Hits          203      205        +2     
- Misses         11       46       +35     
Flag Coverage Δ
unittests 81.67% <14.63%> (-13.19%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
pydomcfg/utils.py 52.00% <5.40%> (-45.37%) ⬇️
pydomcfg/domzgr/zco.py 92.38% <100.00%> (ø)
pydomcfg/domzgr/zgr.py 100.00% <100.00%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 9002bb0...1d80a84. Read the comment docs.

@oceandie
Copy link
Contributor Author

if self._stretch:

Worthy to implement the same strategy for zco? ... will allow to get rid of the quite annoying ldbletanh boolean flag ...

Copy link
Member

@malmans2 malmans2 left a comment

Choose a reason for hiding this comment

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

I introduced a few changes in Zgr with #31.
I think it makes sense to review and merge #31, so we build Sco starting from the most recent version.

Also, mypy is fully integrated in #31, while here you are not really checking xarray objects as xarray is not an additional dependency in the config file.

The only major change that #31 introduces is that _init_ds is gone, as we don't have to initialize e3 and z3 variables anymore. But If you want to start translating from fortran using it, I would introduce _init_ds in the child class. I.e., we will do something like for Zco (1. translate from fortran, 2. refactor to make more use of xarray) but we don't have to change/refactor anything in the base class.

Comment on lines 113 to 115
# set stretching parameters after checking their consistency
if self._stretch:
self._set_stretch_par(psurf, pbott, alpha, efold, pbot2)
Copy link
Member

@malmans2 malmans2 Jun 16, 2021

Choose a reason for hiding this comment

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

When we append variables to self in separate methods, they're kind of hidden. I would do something like in Zco, so self._set_stretch_par returns psurf, pbott, alpha, efold, pbot2.

Actually, what you are doing so far (basically self._psurf = psurf or None, ...) is easy enough that I think you can set these variables directly in __call__, and rename the function to something like check_stetch_par.

if self._stretch:
self._set_stretch_par(psurf, pbott, alpha, efold, pbot2)

ds = self._init_ds()
Copy link
Member

Choose a reason for hiding this comment

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

_init_ds is gone in #31 as we don't need to initialize e3 and z3 variables anymore.

ds_env = self._compute_env(ds)

# compute sigma-coordinates for z3 computation
kindx = ds_env["z"]
Copy link
Member

Choose a reason for hiding this comment

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

When we merge #31 you can do this:

        kindx = self._z


# compute sigma-coordinates for z3 computation
kindx = ds_env["z"]
sigma = (self._compute_sigma(kk) for kk in kindx)
Copy link
Member

Choose a reason for hiding this comment

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

Should this be:

Suggested change
sigma = (self._compute_sigma(kk) for kk in kindx)
sigma = self._compute_sigma(kindx)

Comment on lines 151 to 159
msg = (
srf
+ " and "
+ bot
+ "MUST be set when using "
+ self._stretch
+ " stretching."
)
raise ValueError(msg)
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
msg = (
srf
+ " and "
+ bot
+ "MUST be set when using "
+ self._stretch
+ " stretching."
)
raise ValueError(msg)
raise ValueError(
f"{srf} and {bot} MUST be set when using {self._stretch} stretching."
)

Comment on lines 168 to 172
self._psurf = psurf if psurf else 0.0
self._pbott = pbott if pbott else 0.0
self._alpha = alpha if alpha else 0.0
self._efold = efold if efold else 0.0
self._pbot2 = pbot2 if pbot2 else 0.0
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
self._psurf = psurf if psurf else 0.0
self._pbott = pbott if pbott else 0.0
self._alpha = alpha if alpha else 0.0
self._efold = efold if efold else 0.0
self._pbot2 = pbot2 if pbot2 else 0.0
self._psurf = psurf or 0
self._pbott = pbott or 0
self._alpha = alpha or 0
self._efold = efold or 0
self._pbot2 = pbot2 or 0

Also, I think you can do this directly in __call__

@@ -26,6 +27,51 @@ def is_nemo_none(var: Optional[float] = None) -> bool:
return var in [None, 999999.0]


# -----------------------------------------------------------------------------
def calc_rmax(depth: DataArray) -> DataArray:
Copy link
Member

Choose a reason for hiding this comment

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

Same used by the Bathymetry class, right?
Then we could delete it in tests/bathymetry.py and import from here.

@malmans2
Copy link
Member

malmans2 commented Jun 16, 2021

if self._stretch:

Worthy to implement the same strategy for zco? ... will allow to get rid of the quite annoying ldbletanh boolean flag ...

Right, although I think the best we can do with ldbletanh is to work around it because it's defined in the namelist.
Is this what you mean?

ldbletanh_out = ldbletanh if (ldbletanh is not None) else not any(pp_are_none)

I.e., default is None, set to True/False if the user defines it, otherwise False if the tanh parameters are not set (and viceversa).

Comment on lines +142 to +150
if self._stretch == "sh94":
srf = "rn_theta"
bot = "rn_bb"
elif self._stretch == "md96":
srf = "rn_theta"
bot = "rn_thetb"
elif self._stretch == "sf12":
srf = "rn_zs"
bot = "rn_zb_a"
Copy link
Member

Choose a reason for hiding this comment

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

Missing a final else with a slightly different error (i.e., typo or the stretch is not supported)

Copy link
Contributor

@jdha jdha left a comment

Choose a reason for hiding this comment

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

calc_rmax is now in utils.py which I guess makes _calc_rmax in tests/bathymetry.py redundant. Unless told otherwise I'll raise an issue to tidy after this PR.

@oceandie
Copy link
Contributor Author

oceandie commented Jun 16, 2021

@malmans2 Yes I know, all your comments are correct but as I specified in the committ this was just to start the work, so just a quick structure of the module, surely not ready for review ;)
Considering your recent modifications (and the next ones after @jdha review) to the main branch, I will delete this PR and associated branch and start from a clean one directly from the more recent main.

@jdha
Copy link
Contributor

jdha commented Jun 16, 2021

OK - I should have read the whole thread first. @malmans2 has already commented on calc_rmax, perhaps we just tidy in this PR (that would be me being lazy - @malmans2: would you prefer things like this to be dealt with as separate issues?)

@oceandie
Copy link
Contributor Author

if self._stretch:

Worthy to implement the same strategy for zco? ... will allow to get rid of the quite annoying ldbletanh boolean flag ...

Right, although I think the best we can do with ldbletanh is to work around it because it's defined in the namelist.
Is this what you mean?

ldbletanh_out = ldbletanh if (ldbletanh is not None) else not any(pp_are_none)

I.e., default is None, set to True/False if the user defines it, otherwise False if the tanh parameters are not set (and viceversa).

My idea is to introduce an intermediate step (function) where we translate (map) from NEMO-like namelist parameters to pyDOMCFG-like parameters.

@malmans2
Copy link
Member

@jdha I think it would make more sense to do it here

@oceandie no need to open a new PR, we'll just rebase once we merge #31
Also, I suggest to convert this PR into a draft (top right, under reviewer), and then change the status when you are ready for a full review. That's how I view it:

  1. I don't want any feedback: Fork on you private account, don't open a PR
  2. Draft PR: I'm OK with feedback if you have time to glance through, but it's really work in progress so don't spend too much time on it.
  3. Remove the draft status: I want to merge this, ready for a full review and I need someone's approval

@malmans2
Copy link
Member

My idea is to introduce an intermediate step (function) where we translate (map) from NEMO-like namelist parameters to pyDOMCFG-like parameters.

I like it, it would make everything much easier! I suggest we open an issue about this and we address it in a separate PR.

@jdha
Copy link
Contributor

jdha commented Jun 16, 2021

@jdha I think it would make more sense to do it here

@oceandie no need to open a new PR, we'll just rebase once we merge #31
Also, I suggest to convert this PR into a draft (top right, under reviewer), and then change the status when you are ready for a full review. That's how I view it:

  1. I don't want any feedback: Fork on you private account, don't open a PR
  2. Draft PR: I'm OK with feedback if you have time to glance through, but it's really work in progress so don't spend too much time on it.
  3. Remove the draft status: I want to merge this, ready for a full review and I need someone's approval
  1. (alternative) create a local branch and when you're ready set up an upstream branch, push and open a PR

@oceandie
Copy link
Contributor Author

@jdha I think it would make more sense to do it here
@oceandie no need to open a new PR, we'll just rebase once we merge #31
Also, I suggest to convert this PR into a draft (top right, under reviewer), and then change the status when you are ready for a full review. That's how I view it:

  1. I don't want any feedback: Fork on you private account, don't open a PR
  2. Draft PR: I'm OK with feedback if you have time to glance through, but it's really work in progress so don't spend too much time on it.
  3. Remove the draft status: I want to merge this, ready for a full review and I need someone's approval
1. (alternative) create a local branch and when you're ready set up an upstream branch, push and open a PR

Perfect, thanks a lot both for the clarifications - I thought opening a PR was kind of "mandatory" everytime you open a branch ... good to know ;) I think for this one I will do as suggested by @malmans2, I'll put draft status

@oceandie oceandie marked this pull request as draft June 16, 2021 12:05
@malmans2
Copy link
Member

malmans2 commented Jun 16, 2021

@oceandie you'll need to merge main into this. The only conflict with main is basically just the # ------ comment you introduced (I personally don't love those kind of separators because of these conflicts + python indentation already works pretty good, but it's really a personal preference).

Anyways, if you haven't done it before, here is what I would do from terminal

git clone https://github.com/pyNEMO/pyDOMCFG.git
cd pyDOMCFG
git fetch origin
git checkout -b sco_dev origin/sco_dev
git merge main

Fix conflicts:
Open pydomcfg/utils.py and remove everything between <<<<<<< HEAD and >>>>>>> main.

Git add, commit and push sco_dev as usual.

(I think you can do it from GH as well, but I don't see the button. Maybe you do as it's your draft PR?)
Edit: Actually the Resolve conflicts button showed up for me as well...

@malmans2
Copy link
Member

malmans2 commented Jun 19, 2021

Don't worry about the CI/upstream-dev action failing. We'll add typing_extensions to the environment file if it doesn't get fixed upstream in a few days.

# Do we actually need this? mypy complains since
# DataArray.reset_indexe() returns Optional["DataArray"]
#
# depth = depth.reset_index(list(depth.dims))
Copy link
Member

Choose a reason for hiding this comment

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

Interesting, not sure why they assigned that type annotation to reset_index. One quick solution is DataArray(depth.reset_index(list(depth.dims))).

_calc_rmax doesn't really need this, the problem is that if we don't use it a DataArray with different indexes is returned. This means that we'll get conflicts when we try to merge in the main dataset.

I was just lazy though... it's quite easy in this case to properly use the indexes. I'll open a separate PR for that as you haven't removed calc_rmax from Bathymetry yet.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok, I will implement the quick solution DataArray(depth.reset_index(list(depth.dims))) for now i my branch since it seems we need it also in _calc_rmax: if I remove it, I get the following error:
ValueError: cannot reindex or align along dimension 'y' because the index has duplicate values

Copy link
Contributor Author

Choose a reason for hiding this comment

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

BTW, forza azzurri !!!!

@@ -59,6 +56,8 @@ def _calc_rmax(depth: DataArray) -> float:
depth_diff = depth.diff(dim)
depth_rolling_sum = depth.rolling({dim: 2}).sum().dropna(dim)
rmax = depth_diff / depth_rolling_sum
# dealing with nans at land points
Copy link
Contributor Author

@oceandie oceandie Jun 21, 2021

Choose a reason for hiding this comment

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

@jdha and @malmans2 I think we need something like this in #40 for managing nans (0/0) in the case of land points

pydomcfg/domzgr/sco.py Outdated Show resolved Hide resolved
@oceandie
Copy link
Contributor Author

not sure why mypy is failing ... any idea?

pydomcfg/domzgr/sco.py Outdated Show resolved Hide resolved
@malmans2 malmans2 mentioned this pull request Jun 30, 2021
malmans2 and others added 2 commits June 30, 2021 11:41
* refactor to avoid loops

* apply Diego's suggestions

* remove useless return after error
@malmans2
Copy link
Member

malmans2 commented Jul 5, 2021

Looks like there aren't conflicts right now, so I'd merge main into sco_dev whenever you get a chance.
Once you merge, can you please try adding the decorator to Sco __call__? See:

@_check_parameters
def __call__(

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants