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
rio-calc, take 1 #272
rio-calc, take 1 #272
Conversation
Like this: $ rio calc "0.10*{1} + 125" tests/data/shade.tif out.tif Results in a new hillshade with shade values of 125 instead of 0.
Is the {} indicating a band? I'd prefer an letter instead as it makes it clearer it is a variable. Currently looks like you are just doing |
1 similar comment
Also how you specify which band(s) the result is assigned to? perhaps a = in there like |
@ljbade I'm experimenting with curly braces because I like GNU Parallel's positional replacement syntax. To specify a specific raster band (a 2-D numpy ndarray), hybridization of Parallel and Numpy indexing syntax might work: Not sure about output assignment yet. I'm keeping different functions per band in mind, that's very important. I've seen good results using Python's multithreading module with Rasterio and we should use it here, definitely. |
Interesting. I look forward to use this for my normal map stuff. Save me ~600GB of intermediate data. |
1 similar comment
Also test reducing a 3-band file to 1.
1 similar comment
Here's an example of command syntax for making a fake panchromatic image from the RGB.byte.tif file in rasterio/tests. One command line (ended by $ rio calc "({1,1} + {1,2} + {1,3})/3;" tests/data/RGB.byte.tif /tmp/faux-pan.tif --dtype uint8 rio-calc could be used to copy a dataset like this: $ rio calc "{1}" tests/data/RGB.byte.tif /tmp/copy.tif --dtype uint8 Here's an example of making an RGB image from our greyscale hillshade. Three command lines, one for each output band. $ rio calc "{1,1} + 125; {1,1}; {1,1};" tests/data/shade.tif /tmp/red-shade.tif --dtype uint8 Yes? No? As I commented in the code, writing an actual parser for the commands needs to be done. Other TODOs:
|
100% coverage :)
hmm for some reason i still dont get the parallel syntax, just very confusing in complicated expressions with several input variables, i still prefer letters as it is closer to real math syntax |
the qgis thing might help with understandability tho |
Old syntax traded in for an easy to parse lisp-like syntax. No need for a temporary variable and much more secure.
Closes #276.
Conflicts: CHANGES.txt requirements-dev.txt
First I enhanced fillnodata() so that it could use direct band references. After that, I extended snuggs, giving rio-calc access to band() and fillnodata() functions.
I've patched @snorfalorpagus's Reminder, our test dataset is a RGB trapezoid surrounded by nodata pixels: Running the command $ rio calc "(asarray (fillnodata (band 1 1)) (fillnodata (band 1 2)) (fillnodata (band 1 3)))" \
> tests/data/RGB.byte.tif --dtype uint8 /tmp/out.fill.tif && \
> open /tmp/out.fill.tif Results in: Crazy, but exactly the crazy result you'd expect from GDAL's nodata filling algorithm in this case. Unlike @brendan-ward @perrygeo what do you think? This is ready to be merged if you agree. |
@sgillies This looks really good. I've not used lisp before, but I like the look of the syntax. If you add support for importing functions from other modules (e.g. scipy) it might be worth considering some sort of .rc file, so that a user can define a set of commonly used macros. |
@snorfalorpagus yes, extension from the command line or .rc would be great. I also plan to add |
Sieving of images read directly from GDAL was broken, but is now fixed, with tests.
|
||
def read_array(ix, subix=None, dtype=None): | ||
"""Change the type of a read array""" | ||
arr = snuggs._ctx.lookup(ix, subix) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@sgillies 2 comments here:
- looks like you are using a internal API from the signature
._ctx
; if you are using it outsidesnuggs
, it probably should be a public API, e.g.,snuggs.ctx.lookup()
or similar. (going here w/ the convention that leading underscores denote internal functions / objects) - some extra validation would be nice here, with simpler error messages. I can make this produce a long exception using:
$ rio calc "(read 2)" tests/data/RGB.byte.tif /tmp/test.tif
read: invalid band index
would be a fine message in this case.
@sgillies Great work here! A few overall comments:
I find myself belaboring validation here because given the complexity of the commands you can issue, it is easy to get things wrong, and simple error messages would make it a whole lot easier to find simple mistakes. I'm also struggling with |
@brendan-ward thanks for the comments. I'm working on more documentation this evening. I totally agree about more user-friendly error messages. |
Using the new friendly errors from snuggs (1.2 out soon), we get: $ rio calc "band 1 1) 42)" tests/data/shade.tif --dtype uint8 /tmp/out.sieved.tif && open /tmp/out.sieved.tif
Expression Error:
band 1 1) 42)
^
Expected "(" and $ rio calc "(steve (band 1 1) 42)" tests/data/shade.tif --dtype uint8 /tmp/out.sieved.tif && open /tmp/out.sieved.tif
Expression Error:
(steve (band 1 1) 42)
^
'steve' is not a function or operator Tests for these coming up. @brendan-ward Enhancing
|
@sgillies Ok on Thanks for the snuggs fixes. Sort of begs the question of why |
Towards closing #175.
Usage, for now, like this:
$ rio calc "0.10*{1} + 125" tests/data/shade.tif out.tif
Results in a new hillshade with shade values of 125 instead of 0.