Submission:MtreeRing
JingningShi opened this issue · 22 comments
Submitting Author: Jingning Shi (@JingningShi )
Repository: https://github.com/JingningShi/MtreeRing
Version submitted: 1.2
Editor: @annakrystalli
Reviewer 1: @bhive01
Reviewer 2: @rorynolan
Archive: TBD
Version accepted: 1.3
- Paste the full DESCRIPTION file inside a code block below:
Package: MtreeRing
Type: Package
Title: A Shiny Application for Automatic Measurements of Tree-Ring Widths on Digital Images
Version: 1.2
Description: Use morphological image processing and edge detection algorithms to
automatically measure tree ring widths on digital images. Users can also manually mark
tree rings on species with complex anatomical structures. The arcs of inner-rings and
angles of successive inclined ring boundaries are used to correct ring-width series. The
package provides a Shiny-based application, allowing R beginners to easily analyze tree
ring images and export ring-width series in standard file formats.
Authors@R: c(person("Jingning", "Shi", role = c("aut", "cre"),
email = "snow940220@bjfu.edu.cn"),
person("Wei", "Xiang", role = "aut"))
Suggests:
testthat,
knitr
Depends:
R (>= 3.3.0),
magrittr (>= 1.5)
Imports:
png,
jpeg,
tiff,
bmp,
magick,
imager,
dplR,
dplyr,
spatstat,
measuRing,
shiny,
shinydashboard,
shinyWidgets
License: GPL-3
LazyData: TRUE
NeedsCompilation: no
Repository: CRAN
Encoding: UTF-8
VignetteBuilder: knitr
URL: https://github.com/JingningShi/MtreeRing
BugReports: https://github.com/JingningShi/MtreeRing/issues
Scope
-
Please indicate which category or categories from our package fit policies this package falls under: (Please check an appropriate box below. If you are unsure, we suggest you make a pre-submission inquiry.):
- data retrieval
- data extraction
- database access
- data munging
- data deposition
- reproducibility
- geospatial data
- text analysis
-
Explain how and why the package falls under these categories (briefly, 1-2 sentences):
The package aims to enable R users to obtain data from scanned tree-ring images.
- Who is the target audience and what are scientific applications of this package?
Anyone interested in measuring ring-width series from increment cores or stem disks, for example, meteorologists and ecologists. Scientific applications include accurate measurements of ring-width series and data correction.
- Are there other R packages that accomplish the same thing? If so, how does
yours differ or meet our criteria for best-in-category?
To our knowledge, the package measuRing can also be used for measuring tree ring widths on scanned images. Compared to measuRing, we provide two additional approaches (watershed segmentation and Canny edge detector) for the automatic identification of ring borders. Furthermore, our package provides a Shiny-based app. This beginner-friendly app allows interactive viewing and manipulation of tree ring images and data files.
- If you made a pre-submission enquiry, please paste the link to the corresponding issue, forum post, or other discussion, or @tag the editor you contacted.
Technical checks
Confirm each of the following by checking the box. This package:
- does not violate the Terms of Service of any service it interacts with.
- has a CRAN and OSI accepted license.
- contains a README with instructions for installing the development version.
- includes documentation with examples for all functions.
- contains a vignette with examples of its essential functions and uses.
- has a test suite.
- has continuous integration, including reporting of test coverage using services such as Travis CI, Coveralls and/or CodeCov.
Publication options
- Do you intend for this package to go on CRAN?
It's already there. - Do you wish to automatically submit to the Journal of Open Source Software? If so:
JOSS Options
- The package has an obvious research application according to JOSS's definition.
- The package contains a
paper.md
matching JOSS's requirements with a high-level description in the package root or ininst/
. - The package is deposited in a long-term repository with the DOI:
- (Do not submit your package separately to JOSS)
- The package contains a
- Do you wish to submit an Applications Article about your package to Methods in Ecology and Evolution? If so:
MEE Options
- The package is novel and will be of interest to the broad readership of the journal.
- The manuscript describing the package is no longer than 3000 words.
- You intend to archive the code for the package in a long-term repository which meets the requirements of the journal (see MEE's Policy on Publishing Code)
- (Scope: Do consider MEE's Aims and Scope for your manuscript. We make no guarantee that your manuscript will be within MEE scope.)
- (Although not required, we strongly recommend having a full manuscript prepared when you submit here.)
- (Please do not submit your package separately to Methods in Ecology and Evolution)
Code of conduct
- I agree to abide by rOpenSci's Code of Conduct during the review process and in maintaining my package should it be accepted.
Thank you for your submission @JingningShi - @annakrystalli has been assigned as the Editor.
Editor checks:
- Fit: The package meets criteria for fit and overlap
- Automated tests: Package has a testing suite and is tested via Travis-CI or another CI service.
- License: The package has a CRAN or OSI accepted license
- Repository: The repository link resolves correctly
- Archive (JOSS only, may be post-review): The repository DOI resolves correctly
- Version (JOSS only, may be post-review): Does the release version given match the GitHub release (v1.0.0)?
Editor comments
Hello @JingningShi. 👋
Many thanks for your submission and apologies for the delay in completing the editors checks for you!
Firstly, it looks like a really cool package 😎. There's a few issues I found during the editor's checks though that will need addressing before we proceed:
-
We require that rOpenSci packages are documented using Roxygen. That means including documentation with the functions in the
R/
directory and automatically generating theNAMESPACE
and contents of theman/
folder usingdevtools::document()
. At the minute there are no roxygen comments with the functions and theNAMESPACE
andman/
files appears to have been created manually. Please consult our guidance on documentation or the chapter on Object documentation for more information. -
We require that at least 75% code coverage by tests. Is there a reason coverage is so low (total coverage 37%) and that there are files that are not covered at all? These files especially:
R/createServer.R: 0.00% R/nearPith.R: 0.00% R/autoDetect.R: 61.68% R/visualSelect.R: 66.67%
-
Running the tests throws up these warnings for me. Any ideas:
test-imgInput.R:14: warning: imgInput plots a tree ring image and returns a magick object TIFFFetchNormalTag: Incompatible type for "RichTIFFIPTC"; tag ignored test-imgInput.R:16: warning: imgInput plots a tree ring image and returns a magick object more bytes available than required in image
-
Incomplete final line found on
'/Users/Anna/Documents/workflows/rOpenSci/editorials/MtreeRing/DESCRIPTION'
. This means the DESCRIPTION file needs a blank line at the end of it. This enables functionality which depends on parsing theDESCRIPTION
file correctly to work. There are a number of other files that need similar attention (see results ofgoodpractice::gp()
checks beflow) -
.travis.yml
needs to be added to.buildignore
so it is ignored when package is being built- use
usethis::use_build_ignore(".travis.yml")
- use
goodpractice
As mentioned above, these files need at blank line at the end of each.
incomplete final line found on '/Users/Anna/Documents/workflows/rOpenSci/editorials/MtreeRing/R/autoDetect.R'
incomplete final line found on '/Users/Anna/Documents/workflows/rOpenSci/editorials/MtreeRing/R/calcRingWidth.R'
incomplete final line found on '/Users/Anna/Documents/workflows/rOpenSci/editorials/MtreeRing/R/correct.color.R'
incomplete final line found on '/Users/Anna/Documents/workflows/rOpenSci/editorials/MtreeRing/R/createServer.R'
incomplete final line found on '/Users/Anna/Documents/workflows/rOpenSci/editorials/MtreeRing/R/createUI.R'
incomplete final line found on '/Users/Anna/Documents/workflows/rOpenSci/editorials/MtreeRing/R/f.img.middle.R'
incomplete final line found on '/Users/Anna/Documents/workflows/rOpenSci/editorials/MtreeRing/R/f.morphological.R'
incomplete final line found on '/Users/Anna/Documents/workflows/rOpenSci/editorials/MtreeRing/R/f.plot.double.R'
incomplete final line found on '/Users/Anna/Documents/workflows/rOpenSci/editorials/MtreeRing/R/f.plot.single.R'
incomplete final line found on '/Users/Anna/Documents/workflows/rOpenSci/editorials/MtreeRing/R/imgInput.R'
incomplete final line found on '/Users/Anna/Documents/workflows/rOpenSci/editorials/MtreeRing/R/nearPith.R'
incomplete final line found on '/Users/Anna/Documents/workflows/rOpenSci/editorials/MtreeRing/R/split.label.R'
incomplete final line found on '/Users/Anna/Documents/workflows/rOpenSci/editorials/MtreeRing/R/visualSelect.R'
incomplete final line found on '/Users/Anna/Documents/workflows/rOpenSci/editorials/MtreeRing/R/water.im.R'
Also, it's also good practice to:
- ✖ write short and simple functions. These functions have
high cyclomatic complexity:- createServer (254),
- autoDetect (52).
- ✖ do not use "Depends" in DESCRIPTION, as it can cause name
clashes, and poor interaction with other packages. Use "Imports"
instead. - ✖ avoid sapply(), it is not type safe. It might return a
vector, or a list, depending on the input data. Consider using
vapply() instead. - ✖ not import packages as a whole, as this can cause name
clashes between the imported packages. Instead, import only the
specific functions you need.
Let me know when these issues have been addressed and I will begin looking for reviewers. Also feel free to reach out if have any more questions
Thanks for the editor checks @annakrystalli .
I will correct these issues as soon as possible.
Thanks for checking out the package @annakrystalli . It was the first time that I had written an R package. English isn't my first language, so please excuse any mistakes. I made the following changes based on your comments:
- Generate the
NAMESPACE
andman/
files usingdevtools::document()
. - Replace the images which throw up warnings with new image files.
Sometimes the test will issue a warninglibpng warning: iCCP: known incorrect sRGB profile
. This happens because of changes in libpng version 1.6+, and will not affect the R function. - Add a blank line at the end of
DESCRIPTION
file andR code files
. - Create a
buildignore
file using the commandusethis::use_build_ignore(".travis.yml")
. - Replace the "Depends" in DESCRIPTION with “Imports”.
- Remove sapply() as suggested by
goodpractice
. - Import only the specific functions we need, rather than the whole package.
Regarding the low test coverage you mentioned, the reason is that some functions in our package use loactor()
to record mouse position for the purpose of marking tree rings manually. If we write unit tests for chunks which call locator()
, the automated tests can't record the position of the cursor and will produce error messages. Another important reason is that test_that()
can't test the Shiny app. The code file of the app (createServer.R) has 1571 lines (the package has 2868 lines in all) so the test coverage is less than 75%.
Thanks again for looking it over and please let me know if you have any other questions.
Hi @JingningShi ,
Thanks for your speedy and full response!
Regarding English as a second language, don't worry at all. If there is anything I write that doesn't make sense let me know and I will try to explain in a different way. I will do the same.
I've re-run all the checks & tests and most of the issues have been solved! 🎉
Regarding testing coverage, I have two suggestions to increase it:
- Have you seen shinytest for testing shiny apps? This should allow to test the behaviour of the shinyapp.
- You could use
mockery
package to set the output oflocator()
during testing so you can check chunks which call locator().
Finally, goodpractice::gp()
still returns a warning about the cyclomatic complexity of functions: createServer (254), autoDetect (52).
Do you think the internals of these functions could be simpler?
Thank you for the suggestions of using shinytest
and mockery
. You did me a great favor @annakrystalli .
I made the following changes:
- Use
mock()
andstub()
to mock mouse cursor, and the test coverage reaches 97%. - Create tests for the app using
recordTest()
andtestApp()
. I save these test scripts and results at a subdirectory ofinst/
as suggested by this article. - Rewrite the functions you mentioned to reduce cyclomatic complexity.
goodpractice::gp()
will not show a warning about the cyclomatic complexity now.
Thanks again for the review. I have learned many things throughout the editor checks. It was extremely helpful.
Hi @JingningShi,
So glad you found the suggestions useful! And well done on getting coverage up to 97%!! 😃💯
That completes the editor checks. I will start looking for reviewers now.
Could you please add the rOpenSci under review badge to your README?
[![](https://badges.ropensci.org/287_status.svg)](https://github.com/ropensci/software-review/issues/287)
I'll be back in touch when I have found reviewers 👍
We now have reviewers! Many thanks for agreeing to review @bhive01 & @rorynolan 🙏
Note a delay in the official start date (2018-04-09) to accommodate reviewers schedules.
Reviewers: @bhive01, @rorynolan
Due date: 2018-04-30
Hello @JingningShi, @annakrystalli and @bhive01
Here is my initial review.
@JingningShi, great job on a really nice package. I have several improvements that I'd like you to implement but I like the package a lot, it was nice to try it out.
Package Review
Please check off boxes as applicable, and elaborate in comments below. Your review is not limited to these topics, as described in the reviewer guide
- As the reviewer I confirm that there are no conflicts of interest for me to review this work (If you are unsure whether you are in conflict, please speak to your editor before starting your review).
Documentation
The package includes all the following forms of documentation:
- A statement of need clearly stating problems the software is designed to solve and its target audience in README
- Installation instructions: for the development version of package and any non-standard dependencies in README
- Vignette(s) demonstrating major functionality that runs successfully locally
- Function Documentation: for all exported functions in R help
- Examples for all exported functions in R Help that run successfully locally
- Community guidelines including contribution guidelines in the README or CONTRIBUTING, and DESCRIPTION with
URL
,BugReports
andMaintainer
(which may be autogenerated viaAuthors@R
).
Functionality
- Installation: Installation succeeds as documented.
- Functionality: Any functional claims of the software been confirmed.
- Performance: Any performance claims of the software been confirmed.
- Automated tests: Unit tests cover essential functions of the package
and a reasonable range of inputs and conditions. All tests pass on the local machine. - Packaging guidelines: The package conforms to the rOpenSci packaging guidelines
Final approval (post-review)
- The author has responded to my review and made changes to my satisfaction. I recommend approving this package.
Estimated hours spent reviewing: 4
Review Comments
Vignettes
- Take installation instructions out of vignette, they belong in the README only.
- Vignettes should be at least as extensive as the README. It's OK to duplicate examples from the README, most people will read one or the other.
- You need 2 vignettes: one for how to use the package with shiny and one for how to use from R console without shiny. Apart from
imgInput()
, there are only 4 exported functions:autoDetect()
,calcRingWidth()
,nearPith()
andvisualSelect()
. All of these should be demonstrated with a video or gif in that vignette (you could demonstrate more than one function per video/gif e.g.autoDetect()
andcalcRingWidth()
could be demonstrated in the same video/gif if you like). I know it seems like a lot of effort to demonstrate both the shiny and R console use because they're similar but most people will use one or the other and will appreciate a video/gif showing how to do it exactly the way they're trying to do it.
Code
- Why allow
magick = FALSE
, why not just insist on the use ofmagick
? - I think you should include an option not to plot the image when reading it. Some people would prefer the image to display for the first time when another function e.g.
nearPith()
is called.
Tests
- Your tests produce a lot of plots in
tests/testthat
. Your tests should either not produce these or remove them; they shouldn't still be there when the tests have finished (for some reason, when I rundevtools::test()
the plots are produced but not when I rundevtools::check()
).
Continuous Integration
- Can you add AppVeyor CI? If not, why not? It has helped me catch bugs in a few of my packages.
Documentation
- Why is
nearPith()
named like this? Is it because inner arcs might be used? - When you mention one function in the documentation of another, there should be a documentation link. For example, the mention of
visualSelect()
innearPith()
should be a clickable link.
Typos
- I've submitted a PR (ropensci/MtreeRing#2) to fix a few typos in messages displayed to users and to include a spell check when testing.
rOpenSci packaging guidelines
See https://ropensci.github.io/dev_guide/.
- You need to run
codemetar::write_codemeta()
. - Consider
snake_case
style and an object_verb() naming scheme for functions in your package. For example you could renameimgInput()
toimg_input()
. This is a matter of personal taste though, I don't insist that you do this. - Your repo should include a
README.Rmd
file which is used to buildREADME.md
. You should not editREADME.md
directly. - Create a website for your package with the
pkgdown
package and have it deploy using travis with every push to github (again, see https://ropensci.github.io/dev_guide/). - Run
usethis::use_code_of_conduct()
to add an appropriate code of conduct for potential contributors.
Package Review
Please check off boxes as applicable, and elaborate in comments below. Your review is not limited to these topics, as described in the reviewer guide
- As the reviewer I confirm that there are no conflicts of interest for me to review this work (If you are unsure whether you are in conflict, please speak to your editor before starting your review).
Documentation
The package includes all the following forms of documentation:
- A statement of need clearly stating problems the software is designed to solve and its target audience in README
- Installation instructions: for the development version of package and any non-standard dependencies in README
- Vignette(s) demonstrating major functionality that runs successfully locally
- Function Documentation: for all exported functions in R help
- Examples for all exported functions in R Help that run successfully locally
- Community guidelines including contribution guidelines in the README or CONTRIBUTING, and DESCRIPTION with
URL
,BugReports
andMaintainer
(which may be autogenerated viaAuthors@R
).
Functionality
- Installation: Installation succeeds as documented.
- Functionality: Any functional claims of the software been confirmed.
- Performance: Any performance claims of the software been confirmed.
- Automated tests: Unit tests cover essential functions of the package
and a reasonable range of inputs and conditions. All tests pass on the local machine. - Packaging guidelines: The package conforms to the rOpenSci packaging guidelines
Final approval (post-review)
- The author has responded to my review and made changes to my satisfaction. I recommend approving this package.
Estimated hours spent reviewing: 5
Review Comments
Function Naming
You have quite the mix of function naming. Many functions use camelCase, a few use _ and a lot of them use '.'. https://ropensci.github.io/dev_guide/building.html#function-and-argument-naming suggests using snake_case which is used in a few instances.
ls(getNamespace("MtreeRing"), all.names = TRUE)
[1] ".DEVTOOLS" ".NAMESPACE." ".S3MethodsTable." ".packageName" "add_path"
[6] "autoDetect" "bor.distance" "calcRingWidth" "columnIndices" "convert2gray"
[11] "correct.color" "create_path" "create.label" "draw_border1" "draw_border2"
[16] "f.bor.plot" "f.border" "f.img" "f.marker" "f.morphological"
[21] "f.plot.double" "f.plot.single" "f.rw.plot" "f.sort" "hat"
[26] "imgInput" "inclined_path" "launchMtRApp" "magick2array" "mark_arc"
[31] "nearPith" "r.det" "split.label" "visualSelect" "water.im"
[36] "watershed.im"
autoDetect.R
method = "lineardetect" fails with example and there is no indication why.
autoDetect(ring.data = t1, seg = 1, method = 'george')
, did also not throw an error. Some checking of the inputs here would go a long way for usability.
auto.path = FALSE
fails
> autoDetect(ring.data = t1, seg = 1, auto.path = FALSE)
Error in mtext(text.s1, side = 1, line = text.line, adj = 0) :
plot.new has not been called yet
autoDetect(ring.data = t1, seg = 1, manual = TRUE)
Does not load visual selection tool.
Perhaps I am misunderstanding things. If so, perhaps the documentation needs adjustment?
sample.yr defaults to the current year
sample.yr <- Sys.Date() %>% as.character %>% strtrim(4) %>% as.numeric
I think this is ok, but I think perhaps it should come with a warning when left as NULL
.
calcRingWidth.R
Two things that bugged me when I tried to use this function:
seriesID
isn't a bad name really, but it took me a while to realize it's just the name of the new column. Perhaps a better name could be given to it?- You should specify that your return unit is millimeters. The only indication of that is
dp <- x.dpi / 25.4
withrw <- round(diff.col.num / dp, 2)
. Perhaps this is a known entity in the tree world? (I work on annuals).
f.img.R
For some reason when using autoDetect, I would get an empty quartz window every time I used it. I suspect the reason is in this file, but I can't see it obviously.
I like the file type handling code here. Simple and straightforward.
launchMtRApp.R
This is good. Really good. Makes a really intuitive interface to the whole process. The only issue I had with this was when I wanted to stop running this app R would not respond. This was outside of Rstudio (gasp). In R-gui Mac, it just gave me the spinning color wheel of death until I force quit. My bad, but is this a known thing. I haven't had time to look.
When I did the auto border search I got the following message:
"27 boreders were detected"
Boreders should be borders.
The app works pretty well and is intuitive. How do you save the output?
nearPith.R
The first time it loaded up and I didn't see the instructions to click. I finally realized this and clicked, but when I wanted to click on the arcs it failed. Error in xy.coords(x, y) : 'x' and 'y' lengths differ
. I'm not sure what went wrong, but when I then tried to rerun the same code, it failed differently: Error in mtext(paste0("Step ", step.number, ": Click the left ", "mouse button to add a horizontal path."), : plot.new has not been called yet
I reloaded R and reran it and I think I messed up. You click on the edges or start and stop points of the image first. Then you click all the borders of the rings. I stopped it and had to restart R again.
I reloaded again and redid it. Seemed to be ok. It marked the middle of the path, but then I wasn't sure what to do. How do I mark that as input to the function? Or store that path for further computation? :/
visualSelect.R
The function seems to do well at removing existing borders, but when I say add = TRUE, it doesn't. Is this meant to only be run in Rstudio or something?
watershed.im.R
Seems to be a repository for functions. Perhaps this should be tools.R or something similar?
Overall
I think this is a really good fit for ropensci, but I think that perhaps it needs a bit more work to clarify what's going on with the interactive bits. I'd say it's close, but not quite there. The shiny app is awesome and one of the first examples I've come across that provide a tool to make the process of doing this sort of thing for those less familiar with the command line.
@rorynolan @bhive01 Thanks a lot for the thorough review and great suggestions. I will address these issues and report back here.
Sorry for the delay in the response. Thank you again for taking the time to thoroughly review the package @rorynolan @bhive01 . English isn't my first language, so please excuse any mistakes. I will explain to the best of my ability.
I'll first respond to @rorynolan comments:
Vignettes
- Take installation instructions out of vignette, they belong in the README only.
Installation instructions have been removed.
- Vignettes should be at least as extensive as the README. It's OK to duplicate examples from the README, most people will read one or the other. You need 2 vignettes....
Thanks for the excellent suggestion. I deleted the old vignette and wrote two new vignettes for how to use these functions from the R console. Each vignette is demonstrated with pictures.
I also wrote the third vignette for how to use the shiny app. The third vignette is demonstrated with gifs, making the workflow of shiny app more understandable.
vignette('detection-MtreeRing')
vignette('pith-MtreeRing')
vignette('app-MtreeRing')
Code
- Why allow magick = FALSE, why not just insist on the use of magick?
The major goal of magick
is to provide basic image transformations, such as image cropping and rotation, rather than reading an image.
In some cases, the image data is stored in a non-standard format. When reading such a file, we found that packages png
, jpg
and tiff
exhibited better compatibility with non-standard file formats than magick
. The former just throws up a warning which doesn't affect the image data, but magick
returns an error and stops the execution of image reading. However, the storage mode of the image data obtained by png
, jpg
and tiff
is double
, which occupies substantial amounts of memory (e.g., an image file of twelve cores at a resolution of 2540 dpi in the png format occupies 72.8 MB of disk space, whereas the corresponding raster array created by function readPNG
occupies approximately 3.8 GB of memory space). For this reason, we use png
, jpg
and tiff
to read small-size image files.
To consume less memory, we use magick
to read images whose file size is over 10MB. For large files stored in a non-standard format, we can set magick = FALSE
to avoid throwing an error.
- I think you should include an option not to plot the image when reading it. Some people would prefer the image to display for the first time when another function e.g. nearPith() is called.
This is a good suggestion. I am not thoughtful enough.
I have included an argument plot
in ring_read
. Now the user can choose not to display a tree-ring image until another function, such as ring_detect
, is called.
Tests
Your tests produce a lot of plots in tests/testthat. Your tests should either not produce these or remove them; they shouldn't still be there when the tests have finished (for some reason, when I run devtools::test() the plots are produced but not when I run devtools::check()).
I'm not sure what went wrong. When I run devtools::test
, I don't get those plots on my Windows or macOS computer.
Continuous Integration
Can you add AppVeyor CI? If not, why not? It has helped me catch bugs in a few of my packages.
This is a great suggestion. I add a new CI test using AppVeyor and this CI test passes.
Documentation
- Why is nearPith() named like this? Is it because inner arcs might be used?
Thanks for this very nice suggestion. I rename nearPith
to pith_measure
. Now, all functions in MtreeRing
use an object_verb()
naming scheme.
- When you mention one function in the documentation of another, there should be a documentation link. For example, the mention of visualSelect() in nearPith() should be a clickable link.
All functions in the documentation are now clickable.
rOpenSci packaging guidelines
- You need to run codemetar::write_codemeta().
The codemeta file has been added.
- Consider snake_case style and an object_verb() naming scheme for functions in your package. For example you could rename imgInput() to img_input(). This is a matter of personal taste though, I don't insist that you do this.
Thanks for this helpful suggestion. I rename all functions (including both internal functions and exported functions) using a snake_case style. Now, most exported functions start with ring_
and end with a verb
which indicates the primary action of a function, such as ring_read
and ring_detect
.
original function names | new function names |
---|---|
imgInput | ring_read |
autoDetect | ring_detect |
visualSelect | ring_modify |
calcRingWidth | ring_calculate |
launchMtRApp | ring_app_launch |
nearPith | pith_measure |
- Your repo should include a README.Rmd file which is used to build README.md. You should not edit README.md directly.
The README.Rmd file has been added and listsed in .Rbuildignore.
- Create a website for your package with the pkgdown package and have it deploy using travis with every push to github (again, see https://ropensci.github.io/dev_guide/).
Both HTML documentation and the _pkgdown.yml file have been added.
- Run usethis::use_code_of_conduct() to add an appropriate code of conduct for potential contributors.
The CODE_OF_CONDUCT.md file has been added, and the README.md includes a link to the CODE_OF_CONDUCT.md file.
Response to @bhive01 comments
Function Naming
You have quite the mix of function naming. Many functions use camelCase, a few use _ and a lot of them use '.'. https://ropensci.github.io/dev_guide/building.html#function-and-argument-naming suggests using snake_case which is used in a few instances.
Thanks for this helpful suggestion. I rename these functions (including both internal functions and exported functions) using a snake_case style. Now, most exported functions start with ring_
and end with a verb
which indicates the primary action of a function, such as ring_read
and ring_detect
.
original function names | new function names |
---|---|
imgInput | ring_read |
autoDetect | ring_detect |
visualSelect | ring_modify |
calcRingWidth | ring_calculate |
launchMtRApp | ring_app_launch |
nearPith | pith_measure |
ls(getNamespace("MtreeRing"), all.names = TRUE)
[1] ".NAMESPACE." ".S3MethodsTable." ".packageName"
[4] "add_path" "bor_distance" "border_det"
[7] "border_plot" "color_correct" "column_indices"
[10] "conn_calc" "convert2gray" "create_path"
[13] "draw_border1" "draw_border2" "hat"
[16] "img_plot" "inclined_path" "label_create"
[19] "label_split" "magick2array" "mark_arc"
[22] "marker_plot" "morphology_process" "pith_measure"
[25] "ring_app_launch" "ring_calculate" "ring_det"
[28] "ring_detect" "ring_modify" "ring_read"
[31] "ring_sort" "rw_plot" "single_path_plot"
[34] "two_paths_plot" "watershed_process"
autoDetect.R
- method = "lineardetect" fails with example and there is no indication why.
Sorry about that. This bug has been fixed. The following calls can now properly detect ring borders.
img.path <- system.file("001.png", package = "MtreeRing")
t1 <- ring_read(img = img.path, dpi = 1200, plot = F)
t2 <- ring_detect(t1, seg = 1, method = 'lineardetect', border.color = 'green')
- autoDetect(ring.data = t1, seg = 1, method = 'george'), did also not throw an error. Some checking of the inputs here would go a long way for usability.
Now ring_detect
will check important inputs before detecting ring borders.
- auto.path = FALSE fails
When auto.path = FALSE
, a user needs to create a path by clicking on the tree ring image produced by ring_read
. If you close this graphics window before running ring_detect
, you will get this error.
To avoid that, I have included an argument plot
in ring_read
. If plot = FALSE
(the default), ring_read
will not plot the tree-ring image until another function, such as ring_detect
, is called.
- autoDetect(ring.data = t1, seg = 1, manual = TRUE) Does not load visual selection tool.
Perhaps I am misunderstanding things. If so, perhaps the documentation needs adjustment?
Thank you for this thoughtful comment, it greatly improved the user-friendliness of tree ring measurements. In a modified version, if manual = TRUE
, ring_detect
will load ring_modify
after creating the path and the user could mark ring borders manually.
- sample.yr defaults to the current year
sample.yr <- Sys.Date() %>% as.character %>% strtrim(4) %>% as.numeric
I think this is ok, but I think perhaps it should come with a warning when left as NULL.
If sample.yr = NULL
, ring_read
will now generate a warning message like this
Warning message:
The sampling year is set to the current year
calcRingWidth.R
- seriesID isn't a bad name really, but it took me a while to realize it's just the name of the new column. Perhaps a better name could be given to it?
series ID
is already used in a dendrochronological package dplR
. It is defined as the column names of tree ring datasets. To ensure a consistent style across packages, I name this argument like this.
- You should specify that your return unit is millimeters. The only indication of that is dp <- x.dpi / 25.4 with rw <- round(diff.col.num / dp, 2). Perhaps this is a known entity in the tree world? (I work on annuals).
Thanks for this useful suggestion! The unit of ring widths is now described in the function documentation.
f.img.R
- For some reason when using autoDetect, I would get an empty quartz window every time I used it. I suspect the reason is in this file, but I can't see it obviously.
I couldn't reproduce that error on my machine. When I call ring_detect
in both RStudio and R GUI on a MacOS X computer, I do not get an empty quartz window. Could you please provide more information?
launchMtRApp.R
- This is good. Really good. Makes a really intuitive interface to the whole process. The only issue I had with this was when I wanted to stop running this app R would not respond. This was outside of Rstudio (gasp). In R-gui Mac, it just gave me the spinning color wheel of death until I force quit. My bad, but is this a known thing. I haven't had time to look.
My mistake. The function documentation doesn't provide a clear and detailed description of how to stop this app.
To stop the app, you could go to the R console and press the Escape key. This works in both R GUI and RStudio. You could also click the stop sign icon in the upper right corner of the RStudio console.
This instruction has been added to the function documentation.
- When I did the auto border search I got the following message:
"27 boreders were detected"
Boreders should be borders.
This spelling mistake has been corrected.
- The app works pretty well and is intuitive. How do you save the output?
The output of tree ring measurements can be saved in either CSV files or RWL files (a file format used in tree ring analysis). I write a vignette for how to use the shiny app. Data saving can be found in the fifth part of this vignette.
vignette('app-MtreeRing')
nearPith.R
- The first time it loaded up and I didn't see the instructions to click. I finally realized this and clicked, but when I wanted to click on the arcs it failed. Error in xy.coords(x, y) : 'x' and 'y' lengths differ. I'm not sure what went wrong, but when I then tried to rerun the same code, it failed differently: Error in mtext(paste0("Step ", step.number, ": Click the left ", "mouse button to add a horizontal path."), : plot.new has not been called yet.
I reloaded R and reran it and I think I messed up. You click on the edges or start and stop points of the image first. Then you click all the borders of the rings. I stopped it and had to restart R again.
I reloaded again and redid it. Seemed to be ok. It marked the middle of the path, but then I wasn't sure what to do. How do I mark that as input to the function? Or store that path for further computation? :/
I reproduced these two errors on my computer and figured out why these errors happened. It‘s my fault. The original function documentation isn't very clear so I write a vignette for pith_measure
. A detailed example is demonstrated with pictures in that vignette. I hope it is helpful.
vignette('pith-MtreeRing')
When you call pith_measure
, it waits for the user to click on the tree ring image. pith_measure
uses locator
to record the position of the mouse cursor, and will call it many times. The n
argument of locator
controls the number of points to record in each call. During the arc selection, locator
is used to record positions of arc endpoints.
arc.a <- locator(n = 1, type = "n")
points(arc.a$x, py, pch = border.type, col = color, cex = label.cex)
arc.b <- locator(n = 1, type = "n")
points(arc.b$x, py, pch = border.type, col = color, cex = label.cex)
If this process is terminated prematurely before clicking once on the arc (i.e., press the Escape key on MacOS computer, or click on ‘Stop’ button from the menu of the graphics device on Windows PC), locator
will assign a null
object to the variable arc.a
or arc.b
. In this case, a call to points
results in the first error.
The second error occurs because the graphics device produced by ring_read
is shut down and therefore mtext
cannot write text onto the tree ring image. In a modified version, by default, ring_read
will not open a graphics device until pith_measure
is called by a user.
visualSelect.R
- The function seems to do well at removing existing borders, but when I say add = TRUE, it doesn't. Is this meant to only be run in Rstudio or something?
Similar to pith_measure
, ring_modify
uses locator
to record the positions of points you added. locator
is supported by both R GUI and RStudio.
When you call ring_modify
with add = TRUE
, graphics devices opened by ring_detect
will be activated sequentially using dev.set
. When a graphics device is activated (device name in the top right corner of the window is tagged with ACTIVE
), it waits for the user to click on the image. After adding all borders in a device, you can terminate this process (e.g., press the Escape key on MacOS computer) and then add borders in another device.
A complete procedure demonstrated with pictures can be found in the vignette
vignette('detection-MtreeRing')
watershed.im.R
- Seems to be a repository for functions. Perhaps this should be tools.R or something similar?
Thanks for pointing this out. I've now renamed watershed.im
to watershed_process
as suggested by Packaging Guide.
Thanks for your detailed response @JingningShi! ✨
Over to you @rorynolan & @bhive01. Please let us know whether the implemented changes satisfy your comments.
Hi @JingningShi,
I'm very happy with your response to my comments. One last thing to me would be to include your above explanation of when one might not use magick
in the documentation of ring_read()
. I think it would be nice for users to have this clarified for them.
Other than that, I'm happy to sign off.
One last word of advice: be prepared for 1-2 years of basic maintenance of your package as users uncover bugs and make reasonable feature requests. This is quite a nice process really, not something to worry about.
Thanks @rorynolan , an explanation has been added to the R documentation.
In argument description:
magick
A logical value. If TRUE, magick is used to read the image file whose size is over 10MB. If FALSE, packages png, jpg and tiff are used instead. See details below.
In details:
It is highly recommended to use the default value magick = TRUE, because the package magick can significantly reduce the memory usage when reading a large file. In a few cases where image data is stored in a non-standard format, magick may return an error when reading files. If ring_read fails reading a large file, you can set magick = FALSE to avoid the use of magick.
I will do my best to maintain and improve this package 😄
Going through this today.
👏🏻👏🏻👏🏻
Well done on the vignettes, examples, and function names. It's really good and I've run through them all without major issues. The gifs are super easy to follow and things are working better for me as a "naïve" user.
I'm happy to say that this package is a go for me now.
Really well done. Thanks for your efforts Jingning Shi.
Congratulations @JingningShi! This concludes the review and the package is now approved! 🚀
Let me echo the reviewers for a really great job responding to all comments and suggestions. Many thanks as well to @rorynolan & @bhive01 for your most thorough and helpful reviews. 😺Great work all around!
To-dos:
- Transfer the repo to rOpenSci's "ropensci" GitHub organization under "Settings" in your repo. I have invited you to a team that should allow you to do so. You'll be made admin once you do.
- Add the rOpenSci footer to the bottom of your README
"[![ropensci_footer](https://ropensci.org/public_images/ropensci_footer.png)](https://ropensci.org)
" - Fix any links in badges for CI and coverage to point to the ropensci URL. We no longer transfer Appveyor projects to ropensci Appveyor account so after transfer of your repo to rOpenSci's "ropensci" GitHub organization the badge should be:
[![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/github/ropensci/MtreeRing?branch=master&svg=true)](https://ci.appveyor.com/project/JingningShi/MtreeRing)
Should you want to acknowledge your reviewers in your package DESCRIPTION, you can do so by making them "rev"
-type contributors in the Authors@R
field (with their consent). More info on this here. If you do you so so, remember to update the codemata.json
file too.
Welcome aboard! We'd also love a blog post about your package, either a short-form intro to it (https://ropensci.org/tech-notes/) or long-form post with more narrative about its development. (https://ropensci.org/blog/). If you are interested, @stefaniebutland will be in touch about content and timing.
We've started putting together a gitbook with our best practice and tips, this chapter starts the 3d section that's about guidance for after onboarding. Please tell us what could be improved, the corresponding repo is here.
Actually, sorry @JingningShi, I just picked up that the package is missing a NEWS.md
and that the package is still at version 1.2.
Tracking changes to the package is a requirement for an rOpenSci package. I also would expect that given the development and many improvements made to the package during review for the post-review package to have a higher version. The NEWS.md
is a great place to document all the changes and new features you have added.
Have a look at the chapter on releasing packages for more details and just reach out if you need any more help with this. Almost there!
Great thanks! @annakrystalli
I have transferred it over and add NEWS.md. But I find that the ropensci badge in README shows unknown
(https://badges.ropensci.org/287_status.svg). I am not sure if this is something which is still pending or not.
Excellent work @JingningShi! I've given you back admin rights and am looking into the badge situation. Will get back to you shortly.
Fixed! Many thanks again @JingningShi for your submission and engagement with the review process. As @rorynolan mentioned, this is just the start of your adventures as a package maintainer, but I've invited you to the rOpenSci slack. Feel free to ask questions there if you get stuck!
Thanks very much, @annakrystalli .Thanks also to @rorynolan and @bhive01 for such helpful and constructive reviews. This has been a fun and useful process. I have learned a lot from these comments. 😄