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

Added ability to convert VIC 4.2 ascii state files to VIC 5.0 netcdf #43

Closed
wants to merge 44 commits into from

Conversation

tbohn
Copy link
Contributor

@tbohn tbohn commented Mar 17, 2016

Added ability to convert ascii state files to netcdf.

Addresses issue #35.

Joe Hamman and others added 18 commits April 2, 2014 10:42
…nced with large datasets, binary output files are not supported in this version
merge develop into master for tonic 0.1
1. optional extra columns in soil_param file
2. optional extra fcanopy in veg_lib file
3. optional blowing_snow params in veg_param file
4. optional lai, fcanopy, albedo in veg_param file
5. optional lake_param file
6. reading of veg_lib comment field
7. conditional creation of bare soil class, only if not already present
…e_blosnow_veghist

Added support for lake, blowing snow, and flexible lai/fcanopy/albedo to grid_params.py
Added support for carbon parameters to grid_params.py
@tbohn
Copy link
Contributor Author

tbohn commented Mar 19, 2016

Note: I plan on updating the code in this PR to make it consistent with development I'm currently doing in the VIC code. Some variable names will change and the set of coordinate variables in the output state file will change.

To see example ascii parameter and state files, and the corresponding netcdf parameter and state files produced by this version of tonic, please see:

meter:/raid/tbohn/VIC/test/data/NAM.tonic_test/params:

  • global.try01 - this is the VIC run that created the ascii state file
  • soil/veg/lake parameter files listed in global.try01
  • params.try01.nc - netcdf parameter file output by tonic
  • state.try01.nc - netcdf state file output by tonic

meter:/raid/tbohn/VIC/test/data/NAM.tonic_test/state:

  • state.try01_19991231 - ascii state file output by VIC

@tbohn
Copy link
Contributor Author

tbohn commented Mar 20, 2016

@jhamman - I see that tonic's write_netcdf() function names the coordinate dimensions 'ni' (for latitude) and 'nj' for longitude in the case of 2d coordinate variables. In this case, the order of the geographic part of the list of dimensions (in the definitions of other variables) is ('nj', 'ni',). Meanwhile, for 1d coordinate variables, tonic names them 'lat' and 'lon' and the order is ('lat', 'lon', ), which is the reverse of the 2d case. Any special reason for this?

VIC (in vic_store()) writes the dimension names as 'ni' and 'nj', and their order is (ny, nx) using the C convention, which is the reverse order of the python convention, so in python, they would be (nx, ny), with y corresponding to latitude and ni, and x corresponding to longitude and nj. So VIC appears to use the same convention as tonic's 2d case. This appears to be true even for VIC's 1d case.

Can I change tonic so that the dimensions are always named 'ni' and 'nj', and always appear in the order ('nj', 'ni', ) regardless of whether they are 1d or 2d?

@jhamman
Copy link
Member

jhamman commented Mar 20, 2016

@tbohn -

The domain dimension convention should be:

1D Coordinates - use lat and lon for both dimension and coordinate names. (see http://cfconventions.org/Data/cf-conventions/cf-conventions-1.6/build/cf-conventions.html#idp5553648)
2D Coordinates - use dimension names that are meaningful (nj, and ni fit) and use 2d coordinate variables (see http://cfconventions.org/Data/cf-conventions/cf-conventions-1.6/build/cf-conventions.html#idp5559280).

I'm not exactly sure what you mean by "C convention" vs. "Python convention" since they should be the same. If we need to switch the dimension order around in tonic or vic_store, that is fine.

@tbohn
Copy link
Contributor Author

tbohn commented Mar 20, 2016

Re: C vs Python - never mind. I dimly recall something about the C and Fortran netcdf libraries having opposite array index ordering conventions, but it's irrelevant. I'll just make sure that the arrays coming out of tonic are indexed the same way that VIC expects them to be indexed.

Re: coordinate dimensions and variables: OK, I'll follow the CF convention. I got confused by the 'lats' and 'lons' variables, which actually came from the soil parameter file. Tonic has been outputting both 'lat' and 'lon' 1d variables and the 'lats' and 'lons' 2d variables. Doing so certainly covers our bases, but is that really necessary? Why not just always output 2d coordinate variables called 'lat' and 'lon' (computed via grid params so that they cover cells outside the basin or land mask)? Why output the 'lats' and 'lons' variables from the soil param file (which were the inputs to calc_grid anyway, and therefore redundant)?

@tbohn
Copy link
Contributor Author

tbohn commented Mar 20, 2016

(I just now read @jhamman 's comments on UW-Hydro/VIC#367, in which some of my questions here are answered).

@tbohn
Copy link
Contributor Author

tbohn commented Mar 20, 2016

Sorry to be such a nitpicker, but for 2d, tonic appears to be inconsistent with vic and CF convention. Here's the code for the 2d case:
else:
f.createDimension('nj', target_grid[XVAR].shape[0])
f.createDimension('ni', target_grid[YVAR].shape[1])
dims2 = ('nj', 'ni', )
coordinates = "{0} {1}".format(XVAR, YVAR)

In vic and the cf convention, i = x (= lon in a regular geographic grid), and j = y (= lat). I think in this case, if vic attempted to read the ni and nj dimensions from the file written by tonic, the grid would be transposed. I'll fix it in tonic.

@tbohn
Copy link
Contributor Author

tbohn commented Mar 20, 2016

(and by 'fix', I mean I will swap i and j in the two createDimension calls; everything else will stay the same)

with open(state_file) as f:
lines = f.readlines()

gridcel = np.zeros(cells).astype(int)
Copy link
Contributor

Choose a reason for hiding this comment

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

Why not set the dtype within np.zeros as gridcel = np.zeros(cells, dtype='int')

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No good reason for it - the reason is because I'm still new to python. I'll fix it.

Copy link
Member

Choose a reason for hiding this comment

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

Do this elsewhere as well.

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

@tbohn
Copy link
Contributor Author

tbohn commented Jun 13, 2017

@jhamman I'm finally working with tonic again, a year later, and I see that this whole line of development that I did never got merged - it's still just hanging there. What do we need to do to get this merged?

It looks like I prepared an update in response to all of the comments raised, but then nothing else has happened. I also see that development has occurred since then, and I'll need to resolve merge conflicts to get this ready for a new pull request.

Any objections to my resolving conflicts and submitting a pull request?

And which branch should I shoot for? I see there's a feature/vic42 branch now. Should this be merged into both vic42 and master?

@jhamman
Copy link
Member

jhamman commented Jun 23, 2017

@tbohn - can you resolve the conflicts here then this can go in?

I'll leave it up to you and the other @UW-Hydro/vic-admins to decide where this should go (master vs. 42)...

@tbohn
Copy link
Contributor Author

tbohn commented Jun 28, 2017

@UW-Hydro/vic-admins: I think I should merge this into feature/vic42 rather than master, since this is VIC 4.2-specific. Then, we can look into porting it into VIC 5.0.

I have a question about one of the conflicts that I'm trying to merge. feature/vic42/grid_params.py, function grid_params() has an argument of lake_dict=None. In my branch, there is no default for lake_dict. I'm happy to add the lake_dict=None just to eliminate the conflict. However, I see some inconsistencies throughout the code for other similar arguments, with some having default of None, some having default of False, and some having no default.

For now, I'll just resolve the conflict and make a new pull request. But should I open an issue for the inconsistent defaults?

@jhamman jhamman changed the base branch from master to develop June 29, 2017 17:02
@bartnijssen
Copy link
Member

bartnijssen commented Jun 29, 2017

It'd be good to clarify in the name of the PR that this will convert VIC 4.2 ASCII state files into VIC 5.0 netcdf state files. It's not generic at this time (as @tbohn already points out).

@tbohn tbohn changed the title Added ability to convert ascii state files to netcdf Added ability to convert VIC 4.2 ascii state files to VIC 5.0 netcdf Jul 3, 2017
@tbohn tbohn mentioned this pull request Jul 3, 2017
Fixed miniconda setup in .travis.yml.
@tbohn
Copy link
Contributor Author

tbohn commented Jul 3, 2017

I squashed Test 1-5 of .travis.yml and then did a git push --force origin.

@tbohn
Copy link
Contributor Author

tbohn commented Jul 12, 2017

Just a note - since issue #35 was modified last year to only pertain to the ascii -> netcdf direction (the opposite direction was split out into issue #44 ), accepting this PR will allow us to close issue #35.

Copy link
Contributor

@dgergel dgergel left a comment

Choose a reason for hiding this comment

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

@tbohn here's my review - I've noted some changes in names that I think you should make, asked for some further clarification/comments and some structural mods, and I think you also have some changes showing up in here that are not part of your PR.

@@ -0,0 +1,372 @@
#!/usr/bin/env python
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm finding this naming convention to be a bit confusing. I think a more informative name for this would be netcdf2ascii.py.

class Point(object):
'''
Creates a point class for intellegently storing coordinate information and
writing to disk
Copy link
Contributor

Choose a reason for hiding this comment

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

intellegently --> intelligently

# Make sure OUTPATH is available
if not os.path.exists(config_dict['OPTIONS']['OUTPATH']):
os.makedirs(config_dict['OPTIONS']['OUTPATH'])
# ---------------------------------------------------------------- #
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 it is better to use the exist_ok=True option here to remove the if statement

raise ValueError('Binary output is not yet complete, use ascii')
for p in points:
p._open_binary()
p.append = p._append_binary
Copy link
Contributor

Choose a reason for hiding this comment

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

Confused what is going on here - you're raising a ValueError but still looping over points?

return int(value)
elif isfloat(value):
return float(value)
else:
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm a bit confused as to what's going on here - need more comments, but it also seems clunky



# -------------------------------------------------------------------- #
def state(state_file, soil_dict, veg_dict, lake_dict, version_in='4.2',
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 rename this to read_statefile or something like that

--------
retcode = vic.run(global_param_path, logdir=".", mpi_proc=4)

"""
Copy link
Contributor

Choose a reason for hiding this comment

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

I might be wrong, but it looks like some of these changes came from a different PR but are showing up as part of yours. the mpi_proc=4 I remember adding to tonic functionality to deal with MPI changes in VIC.

@@ -51,7 +84,7 @@ def run(self, global_param, logdir=None):
with open(global_param_file, mode='w') as f:
f.write(global_param)

self._call_vic('-g', global_param_file)
self._call_vic('-g', global_param_file, **kwargs)

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, I don't think this is part of your PR - Joe and I made these changes before.


self.argstring = ' '.join(self.args)

proc = subprocess.Popen(self.argstring,
Copy link
Contributor

Choose a reason for hiding this comment

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

Same as above.

# -------------------------------------------------------------------- #
def check_forcings_integrity():
return
# -------------------------------------------------------------------- #
Copy link
Contributor

Choose a reason for hiding this comment

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

Why is this all deleted?

@tbohn
Copy link
Contributor Author

tbohn commented Jul 12, 2017

Thanks @dgergel you're right, there appears to be a lot of stuff in here that I didn't do. I don't know how those changes got in - I might have accidentally merged some stuff from feature/vic42 into here. Or something else.

The only changes I made were to grid_params.py and possibly vic_util.

Maybe I should close this PR and redo it cleanly?

@dgergel
Copy link
Contributor

dgergel commented Jul 12, 2017

@tbohn yes I think it needs to be redone so the PR only has the code changes that you made. There's also a bunch of code re-formatting stuff in here that looks like it does need to be reformatted but should go into a separate PR. While you're doing that, it would also be helpful at the beginning of the PR to have a detailed list of changes that are going into it, e.g. new scripts and what they do. We've been stricter about that lately for VIC development and it's very helpful (e.g. it reminds you to run a format-checker before requesting code reviews)

@tbohn
Copy link
Contributor Author

tbohn commented Jul 12, 2017

What do you mean by format checker - uncrustify? And these format problems, are they in grid_params.py or the other stuff that's not supposed to be in my PR?

@dgergel
Copy link
Contributor

dgergel commented Jul 12, 2017

Yep, uncrustify. I meant that there are formatting changes in the PR that look like they need to be made (e.g. lines are too long) but these changes should be made in a different PR because they aren't specific to what you did. We just probably haven't run uncrustify on tonic for a while is my guess.

@tbohn
Copy link
Contributor Author

tbohn commented Jul 13, 2017

OK, I'm closing this and will open a new PR shortly.

@tbohn tbohn closed this Jul 13, 2017
@tbohn tbohn deleted the feature/add_statefile branch July 13, 2017 03:00
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.

5 participants