ropensci/software-review

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.

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:

Publication options

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 in inst/.
    • The package is deposited in a long-term repository with the DOI:
    • (Do not submit your package separately to JOSS)
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

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 the NAMESPACE and contents of the man/ folder using devtools::document(). At the minute there are no roxygen comments with the functions and the NAMESPACE and man/ 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 the DESCRIPTION file correctly to work. There are a number of other files that need similar attention (see results of goodpractice::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")

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:

  1. Generate the NAMESPACE and man/ files using devtools::document().
  2. Replace the images which throw up warnings with new image files.
    Sometimes the test will issue a warning libpng warning: iCCP: known incorrect sRGB profile. This happens because of changes in libpng version 1.6+, and will not affect the R function.
  3. Add a blank line at the end of DESCRIPTION file and R code files .
  4. Create a buildignore file using the command usethis::use_build_ignore(".travis.yml").
  5. Replace the "Depends" in DESCRIPTION with “Imports”.
  6. Remove sapply() as suggested by goodpractice.
  7. 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:

  1. Have you seen shinytest for testing shiny apps? This should allow to test the behaviour of the shinyapp.
  2. You could use mockery package to set the output of locator() 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:

  1. Use mock() and stub() to mock mouse cursor, and the test coverage reaches 97%.
  2. Create tests for the app using recordTest() and testApp(). I save these test scripts and results at a subdirectory of inst/ as suggested by this article.
  3. 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 and Maintainer (which may be autogenerated via Authors@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() and visualSelect(). 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() and calcRingWidth() 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 of magick?
  • 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 run devtools::test() the plots are produced but not when I run devtools::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() in nearPith() 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 rename imgInput() to img_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 build README.md. You should not edit README.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 and Maintainer (which may be autogenerated via Authors@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:

  1. 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?
  2. 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).

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

  1. Take installation instructions out of vignette, they belong in the README only.

Installation instructions have been removed.

  1. 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

  1. 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.

  1. 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

  1. 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.

  1. 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

  1. You need to run codemetar::write_codemeta().

The codemeta file has been added.

  1. 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
  1. 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.

  1. 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.

  1. 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

  1. 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')
  1. 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.

  1. 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.

  1. 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.

  1. 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

  1. 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.

  1. 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

  1. 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

  1. 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.

  1. 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.

  1. 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

  1. 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

  1. 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

  1. 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. 😄