R/setup_pl.R

Defines functions setup_pl

Documented in setup_pl

#' @title User friendly way to setup whole brain pipeline analysis
#' @description Asks user for setup information for wholebrain analysis.
#'   Generates a setup list of length 9 if the user is registering a partial
#'   brain or of length 18 if the user is mapping a whole brain. If a setup list
#'   already exists, calling this function will simply ask the user to verify
#'   setup info. Info can be changed if necessary. However, be conservative with
#'   changing setup parameters, especially if different users work on the same brain.
#' @param setup (optional) Allows the user to modify a setup list previously
#'   generated by this function.
#' @details
#' Descriptions of list elements for a **partial brain**.
#' 1)  Animal ID
#' 2)  User's Initials.
#' 3)  Registration channel image folder path (normally an autofluorescence
#' channel)
#' 4)  Segmentation channel image folder path (can be different than the
#' Registration channel)
#' 5)  Output folder to store data
#' 6)  All AP coordinates ranging from the first to last AP. User manually
#' entered.
#' 7)  All z image numbers matching element 6. User manually entered.
#' 8) Savepaths list containing paths to the data directories. Will be
#' NULL until [get_savepath()] is run.
#' 10) List of sorted image paths. Will be NULL until [im_sort()] is run.
#'
#' Descriptions of list elements for a **whole brain**.
#' 1)  Animal ID
#' 2)  User's Initials
#' 3)  Registration channel image folder path (normally an autofluorescence
#' channel)
#' 4)  Segmentation channel image folder path (can be the same as the
#' Registration channel)
#' 5)  Output folder to store data
#' 6)  Spacing between adjacent z images (mm)
#' 7)  Spacing between registrations
#' (mm). Default is 0.100, meaning registrations are performed every 100 um.
#' Recommended input is are multiples of 0.100. Beware! Larger spacing between
#' registrations means less manual work but less accurate mapping in the rostral
#' caudal axis.
#' 8)  Integer step size between z-images used for segmentation. Default is 1 (1
#' skips no images, 2 skips every other, etc.).
#' 9)  First AP coordinate
#' 10) First z image. Note: Keep all images of the stack together, even if the
#' first usable image isn't 1.
#' 11) Last AP coordinate
#' 12) Last z image
#' 13) AP coordinates of internal reference planes. Default coordinates are
#' 1.91, 1.10, -.42, -0.93 , -1.94 , -2.95, -3.96. They correspond to PFC, NAc,
#' antHyp, startHip, posHyp, VTA, PAG, respectively.
#' 14) z image numbers matching AP coordinates (14). Will be NULL until
#' [choice()] is run.
#' 15) All AP coordinates ranging from the first to last AP.
#'     Will be NULL until [interpolate()] is run.
#' 16) All z image numbers matching 16. Will be NULL until [interpolate()] is
#' run.
#' 17) Savepaths list containing paths to the data directories. Will be
#' NULL until [get_savepaths()] is run.
#' 18) List of sorted image paths. Will be NULL until [im_sort()] is run.
#' @return *setup* is a list of length 7 or length 16 with parameters for the pipeline analysis.
#' @export
#' @md

setup_pl <- function(setup = NULL) {

  # Setup user prompts for whole brain
  user_prompt <- vector(mode = "list", length = 13)
  user_prompt[[1]]  <- "1) Enter your Animal ID: \n"
  user_prompt[[2]]  <- "2) Enter your Initials: \n"
  user_prompt[[3]]  <- paste0("3) Enter the path to the registration channel folder: ",
                              "\n No need to enter quotes.\n")
  user_prompt[[4]]  <- paste0("4) Enter the path to the segmentation channel folder: ",
                              "\n No need to enter quotes.\n")
  user_prompt[[5]]  <- paste0("5) Enter the path to output folder. If it doesn't exist, please create it: ",
                              "\n No need to enter quotes.\n")
  user_prompt[[6]]  <- "6) What is your spacing (mm) between adjacent z images? \n"
  user_prompt[[7]]  <- "7) What is your spacing between registrations (mm) ?\n"
  user_prompt[[8]]  <- "8) What is your segmentation step size (integer)?\n"
  user_prompt[[9]] <- paste0("9) What is your most anterior AP coordinate (mm)? ",
                             "\nPlease enter at least 2 decimal digits.\n")
  user_prompt[[10]] <- paste0("10) What is the z image number corresponding to most anterior AP coordinate? ",
                              "\nPlease enter an integer number.\n")
  user_prompt[[11]] <- paste0("11) What is your most posterior AP coordinate (mm)? ",
                              "\nPlease enter at least 2 decimal digits.\n")
  user_prompt[[12]] <- paste0("12) What is the z image number corresponding to most posterior AP coordinate? ",
                              "\nPlease enter an integer number.\n")
  user_prompt[[13]] <- paste0("13) What are your internal reference coordinates? ",
                              "\nNOTE: The default coordinates are 1.91, 1.10, -0.42, -0.93 , -1.94 , -2.95, -3.96",
                              "\nThey correspond to PFC, NAc, antHyp, start of Hip, posHyp, VTA, PAG.\n")

  # Setup user prompts for partial brain
  user_prompt2 <- vector(mode = "list", length = 7)
  user_prompt2[[1]]  <- "1) Enter your Animal ID: \n"
  user_prompt2[[2]]  <- "2) Enter your Initials: \n"
  user_prompt2[[3]]  <- paste0("3) Enter the path to the registration channel folder: ",
                               "\n No need to enter quotes.\n")
  user_prompt2[[4]]  <- paste0("4) Enter the path to the segmentation channel folder: ",
                               "\n No need to enter quotes.\n")
  user_prompt2[[5]]  <- paste0("5) Enter the path to output folder. If it doesn't exist, please create it: ",
                               "\n No need to enter quotes.\n")
  user_prompt2[[6]]  <- paste0("6) Enter all known AP coordinates in order from anterior to posterior (mm): ",
                                "\nPlease enter at least 2 decimal digits per coordinate and separate values by a ','.\n")
  user_prompt2[[7]]  <- paste0("7) Enter all z image number in order corresponding to entered AP coordinates: ",
                               "\nPlease enter integer numbers and separate values by a ','.\n")

  # Create setup vector with defaults if it doesn't already exist. Then asks user for setup information.
  if (!exists(deparse(substitute(setup)))) {

    # Ask User to check over current setup parameters
    done <-FALSE
    while (!done) {
      inp <- readline(paste0("Do you want to register a partial brain (P) or a wholebrain (W): P/W? ",
                             "\nNote: partial brains must have KNOWN z and AP values!\n"))
      if (inp=="P" || inp=="p") {

        # Initializing setup for a partial brain analysis
        setup <- vector(mode = "list", length = 9)


        ## Ask for user input
        # 1)  Animal ID
        setup[[1]] <- readline(user_prompt2[[1]])
        # 2)  User's Initials
        setup[[2]] <- readline(user_prompt2[[2]])
        # 3)  Registration channel image folder path
        setup[[3]] <- convertpath(readline(user_prompt2[[3]]))
        # 4)  Segmentation channel image folder path
        setup[[4]] <- convertpath(readline(user_prompt2[[4]]))
        # 5)  Output folder path to store data
        setup[[5]] <- convertpath(readline(user_prompt2[[5]]))
        # 6) Vector to store known AP coordinates
        setup[[6]] <- readline(user_prompt2[[6]])
        setup[[6]] <- roundAP(as.numeric(unlist(strsplit(setup[[6]], ","))))
        # 7) Vector to store known z numbers
        setup[[7]] <- readline(user_prompt2[[7]])
        setup[[7]] <- round(as.numeric(unlist(strsplit(setup[[7]], ","))))

        ## Name the elements of the list
        names(setup)  <- c("anim_ID", "user_init","regi_channel", "seg_channel", "output",
                           "regi_AP", "regi_z", "savepaths", "image_paths")
        done <- TRUE

      } else if (inp=="W" || inp=="w") {

        # Initializing setup for a whole brain analysis
        setup <- vector(mode = "list", length = 18)

        ## Set defaults in the vector
        # 8) Spacing between registrations (mm). DEFAULT: 0.100
        setup [[7]] <- 0.100
        # 9)  Segmentation step (integer). DEFAULT: 1.
        setup [[8]] <- 1
        # 14) AP coordinates of internal reference planes.
        setup[[13]] <- roundAP(c( 1.91, 1.10, -0.42, -0.93 , -1.94 , -2.95, -3.96))

        ## Ask for user input
        # 1)  Animal ID
        setup[[1]] <- readline(user_prompt[[1]])
        # 2)  User's Initials
        setup[[2]] <- readline(user_prompt[[2]])
        # 3)  Registration channel image folder path
        setup[[3]] <- convertpath(readline(user_prompt[[3]]))
        # 4)  Segmentation channel image folder path
        setup[[4]] <- convertpath(readline(user_prompt[[4]]))
        # 5)  Output folder path to store data
        setup[[5]] <- convertpath(readline(user_prompt[[5]]))
        # 6) Spacing between adjacent z images
        setup[[6]] <- as.numeric(readline(user_prompt[[6]]))

        # 9) First AP coordinate
        setup[[9]] <- roundAP(as.numeric(readline(user_prompt[[9]])))
        # 10) First z image
        setup[[10]] <- as.numeric(readline(user_prompt[[10]]))
        # 11) Last AP coordinate
        setup[[11]] <- roundAP(as.numeric(readline(user_prompt[[11]])))
        # 12) Last z image
        setup[[12]] <- as.numeric(readline(user_prompt[[12]]))

        ## Name the elements of the list
        names(setup)  <- c("anim_ID", "user_init", "regi_channel",
                           "seg_channel", "output",
                           "z_space", "regi_step",
                           "seg_step", "first_AP", "first_z", "last_AP",
                           "last_z", "internal_ref_AP",
                           "internal_ref_z", "regi_AP", "regi_z", "savepaths", "image_paths")

        done <- TRUE
      }
    }
  }

  if (length(setup)==9){
    # IF PARTIAL BRAIN ANALYSIS
    # Ask User to check over current setup parameters
    change_done <-FALSE
    while (!change_done) {

      # Print relevant information
      cat("\nYour animal ID         : ", setup$anim_ID)
      cat("\nYour initials          : ", setup$user_init)
      cat("\nYour registration path : ", setup$regi_channel)
      cat("\nYour segmentation path : ", setup$seg_channel)
      cat("\nYour output path       : ", setup$output)
      cat("\nYour AP coordinates    : ", round(setup$regi_AP, digits = 2))
      cat("\nYour z numbers         : ", setup$regi_z)
      cat("\nPlease review your setup information above: ")
      inp <- readline("Do you want to change any settings: Y/N?" )
      if (inp=="Y" || inp=="y") {
        # change settings
        cat("\n1) Animal ID",
            "\n2) User's Initials",
            "\n3) Registration channel",
            "\n4) Segmentation channel",
            "\n5) Output folder",
            "\n6) AP coordinates (mm)",
            "\n7) z numbers\n")

        num_done <- FALSE
        while (!num_done) {
          pts <- readline("Enter the number(s) of the setting(s) you want to change: ")
          pts <- unlist(strsplit(pts,","))
          pts_col  <- grep(":", pts, value=TRUE)                # points with colon
          pts_sing <- grep(":", pts, value=TRUE, invert=TRUE)   # points without colon in string
          if (length(pts_col)!=0) {
            colvec <-  c()
            flag <- FALSE
            for (p in 1:length(pts_col)){
              suppressWarnings(curvec <- as.integer(unlist(strsplit(pts_col[p], ":"))))
              if (sum(is.na(curvec))> 0) {
                flag <- TRUE
                break                                            # break out of loop
              } else {
                colvec <- c(colvec, curvec[1]:curvec[2])
              }
            }
            pts_sing <- suppressWarnings(as.integer(pts_sing))    # Convert input from string into integer
            pts <- c(colvec, pts_sing)
            suppressWarnings(
              if(sum(is.na(pts)) == 0 & flag == FALSE){
                if (sum(pts>7 | pts < 1)<1) {
                  pts <- sort(pts)
                  num_done <- TRUE
                }
              })
          } else if (length(pts_sing)!=0) {
            pts <- suppressWarnings(as.integer(pts_sing))
            suppressWarnings(
              if(!sum(is.na(pts))){
                if (sum(pts>7 | pts < 1)<1) {
                  pts <- sort(pts)
                  num_done <- TRUE
                }
              })
          }
        }

        # Loop through and ask for settings
        for (s in pts ) {
          # Settings 1 through 5 should remain as strings.
          # Setting values should be parsed by ',' before converting to numeric.
          # Other input is converted to numeric.
          if (sum(s==1:2)>=1) {
            setup[[s]] <- readline(user_prompt2[[s]])
          } else if (sum(s==3:5)>=1) {
            setup[[s]] <- convertpath(readline(user_prompt2[[s]]))
          } else if (s==6) {
            setup[[s]] <- readline(user_prompt2[[s]])
            setup[[s]] <- roundAP(as.numeric(unlist(strsplit(setup[[s]], ","))))

          } else if (s==7) {
            setup[[s]] <- readline(user_prompt2[[s]])
            setup[[s]] <- round(as.numeric(unlist(strsplit(setup[[s]], ","))), digits=0)
          }
        }
      } else if ( inp=="N" || inp == "n") {
        # exit out of loop
        change_done  <- TRUE
      }
    }
  } else {
    # IF WHOLE BRAIN ANALYSIS
    # Ask User to check over current setup parameters
    change_done <-FALSE
    while (!change_done) {

      # Print relevant information
      cat("\nYour animal ID         : ", setup$anim_ID)
      cat("\nYour initials          : ", setup$user_init)
      cat("\nYour registration path : ", setup$regi_channel)
      cat("\nYour segmentation path : ", setup$seg_channel)
      cat("\nYour output path       : ", setup$output)
      cat("\nYour z spacing         : ", setup$z_space)
      cat("\nYour registration step : ", setup$regi_step)
      cat("\nYour segmentation step : ", setup$seg_step)
      cat("\nYour first AP          : ", round(setup$first_AP, digits = 2))
      cat("\nYour first z           : ", setup$first_z)
      cat("\nYour last AP           : ", round(setup$last_AP, digits = 2))
      cat("\nYour last z            : ", setup$last_z)
      cat("\nYour internal reference AP coordinates: ", round(setup$internal_ref_AP, digits = 2))

      cat("\nPlease review your setup information above: ")
      inp <- readline("Do you want to change any settings: Y/N?" )
      if (inp=="Y" || inp=="y") {

        # change settings
        cat("\n1) Animal ID",
            "\n2) User's Initials",
            "\n3) Registration channel",
            "\n4) Segmentation channel",
            "\n5) Output folder",
            "\n6) Z slice spacing (mm)",
            "\n7) Registration step size (mm)",
            "\n8) Segmentation step size (integer)",
            "\n9) First AP",
            "\n10) First z",
            "\n11) Last AP",
            "\n12) Last z",
            "\n13) Internal reference AP coordinates\n")

        num_done <- FALSE
        while (!num_done) {
          pts <- readline("Enter the number(s) of the setting(s) you want to change: ")
          pts <- unlist(strsplit(pts,","))
          pts_col  <- grep(":", pts, value=TRUE)                # points with colon
          pts_sing <- grep(":", pts, value=TRUE, invert=TRUE)   # points without colon in string
          if (length(pts_col)!=0) {
            colvec <-  c()
            flag <- FALSE
            for (p in 1:length(pts_col)){
              suppressWarnings(curvec <- as.integer(unlist(strsplit(pts_col[p], ":"))))
              if (sum(is.na(curvec))> 0) {
                flag <- TRUE
                break                                            # break out of loop
              } else {
                colvec <- c(colvec, curvec[1]:curvec[2])
              }
            }
            pts_sing <- suppressWarnings(as.integer(pts_sing))    # Convert input from string into integer
            pts <- c(colvec, pts_sing)
            suppressWarnings(
              if(sum(is.na(pts)) == 0 & flag == FALSE){
                if (sum(pts>13 | pts < 1)<1) {
                  pts <- sort(pts)
                  num_done <- TRUE
                }
              })
          } else if (length(pts_sing)!=0){
            pts <- suppressWarnings(as.integer(pts_sing))
            suppressWarnings(
              if(!sum(is.na(pts))){
                if (sum(pts>13 | pts < 1)<1) {
                  pts <- sort(pts)
                  num_done <- TRUE
                }
              })
          }
        }
        # Loop through and ask for settings
        for (s in pts ) {
          # Settings 1 through 5 should remain as strings.
          # Setting 13 values should be parsed by ',' before converting to numeric.
          # Other input is converted to numeric.
          if (sum(s==1:2)>=1) {
            setup[[s]] <- readline(user_prompt[[s]])
          } else if (sum(s==3:5)>=1) {
            setup[[s]] <- convertpath(readline(user_prompt[[s]]))
          } else if (s==9 | s==11){
            setup[[s]] <- roundAP(as.numeric(readline(user_prompt[[s]])))
          } else if (s==10 | s==12) {
            setup[[s]] <- round(as.numeric(readline(user_prompt[[s]])), digits=0)
          } else if (s==13) {
            setup[[s]] <- readline(user_prompt[[s]])
            setup[[s]] <- roundAP(sort(as.numeric(unlist(strsplit(setup[[s]], ","))), decreasing = TRUE))
          } else {
            setup[[s]] <- as.numeric(readline(user_prompt[[s]]))
          }
        }
      } else if ( inp=="N" || inp == "n") {
        # exit out of loop
        change_done  <- TRUE
      }
    }
  }
 setwd(setup$output)
 return(setup)
}
mjin1812/SMART documentation built on Oct. 30, 2021, 7:25 p.m.