Giter Site home page Giter Site logo

bloodstream's Issues

Issue when json and tsv entries are not aligned

According to the PET BIDS specification for blood data, the time column is required to be in column 1. However, if the json entries and the tsv entries are not aligned, but are all there in each json and tsv, I get the following error:

bloodstream('/Users/martinnorgaard/Downloads/COX-1','/Users/martinnorgaard/Downloads/COX-1/code/config_2023-06-14_id-ZiU9.json')

processing file: template.rmd
|....... | 8% [subsetting]
Quitting from lines 83-114 [subsetting] (template.rmd)
Error in dplyr::filter():
ℹ In argument: extension == "json" || extension == "tsv".
Caused by error in extension == "json" || extension == "tsv":
! 'length = 56' in coercion to 'logical(1)'
Backtrace:

  1. bids_parse_files(params$studypath) %>% ...
  2. dplyr:::filter.data.frame(., extension == "json" || extension == "tsv")
  3. dplyr:::filter_rows(.data, dots, by)
  4. dplyr:::filter_eval(...)
  5. mask$eval_all_filter(dots, env_filter)
  6. dplyr (local) eval()

Quarto rendering

Due to issues with rendering the quarto output document in the derivatives folder, I've had to render the output using rmarkdown. I think this is an issue with quarto itself, so this has been left for now. But ideally it would be nice for everything to be in quarto at a later point to be able to take advantage of future developments on that front.

Issue running when derivatives directory is already created (from e.g. other tools)

Behavior:

processing file: template.rmd
|....... | 8% [subsetting]
Quitting from lines 83-114 [subsetting] (template.rmd)
Error in dplyr::filter():
ℹ In argument: extension == "json" || extension == "tsv".
Caused by error in extension == "json" || extension == "tsv":
! 'length = 56' in coercion to 'logical(1)'
Backtrace:

  1. bids_parse_files(params$studypath) %>% ...
  2. dplyr:::filter.data.frame(., extension == "json" || extension == "tsv")
  3. dplyr:::filter_rows(.data, dots, by)
  4. dplyr:::filter_eval(...)
  5. mask$eval_all_filter(dots, env_filter)
  6. dplyr (local) eval()
    Warning message:
    In dir.create(paste0(studypath, "/derivatives")) :
    '/Users/martinnorgaard/Downloads/COX-1analysisACL_defaced/derivatives' already exists

[ENH]: Make blood output units similar to as specified in the _pet.json

Currently, the output of the blood data is in Bq/mL which is in line with the PET-BIDS specification. However, on multiple occasions I have experienced the PET data being in kBq/mL and not Bq/mL. It would be nice if a check could be made with the _pet.json file "Units" to verify that PET data and blood data units are consistent. Ideally, the output of the blood data should be similar to the units in the PET data.

Issue using FengConv

I'm getting an error in aif-fengconv. Perhaps it's an environment issue? I'm using the container from PR #9.

Running bloodstream on ds004230 using the following config file:

{
  "Subsets": {
    "sub": [""],
    "ses": [""],
    "rec": [""],
    "task": [""],
    "run": [""],
    "TracerName": [""],
    "ModeOfAdministration": [""],
    "InstitutionName": [""],
    "PharmaceuticalName": [""]
  },
  "Model": {
    "ParentFraction": {
      "Method": ["Fit Hierarchically: HGAM"],
      "set_ppf0": [true],
      "starttime": [0],
      "endtime": ["Inf"],
      "gam_k": ["6"],
      "hgam_formula": ["s(time, k=8) + s(time, sub, bs='fs', k=5) + s(time, pet, bs='fs', k=5)"]
    },
    "BPR": {
      "Method": ["Fit Hierarchically: HGAM"],
      "starttime": [0],
      "endtime": ["Inf"],
      "gam_k": [6],
      "hgam_formula": ["s(time, k=8) + s(time, sub, bs='fs', k=5) + s(time, pet, bs='fs', k=5)"]
    },
    "AIF": {
      "Method": ["Fit Individually: FengConv"],
      "starttime": [0],
      "endtime": ["Inf"],
      "expdecay_props": ["NA", "NA"],
      "inftime": ["NA"],
      "spline_kb": [""],
      "spline_ka_m": [""],
      "spline_ka_a": [""]
    },
    "WholeBlood": {
      "Method": ["Interpolation"],
      "dispcor": [false],
      "starttime": [0],
      "endtime": ["Inf"],
      "spline_kb": [""],
      "spline_ka_m": [""],
      "spline_ka_a": [""]
    }
  }
}

Generates the following error:

Quitting from lines 1054-1110 [aif-fengconv] (template.rmd)

Error in `mutate()`:
ℹ In argument: `aif_fit = map(aif, ~blmod_fengconv(time = .x$time, activity = .x$aif, Method = .x$Method))`.
Caused by error in `map()`:
ℹ In index: 1.
Caused by error in `if (startpars$t0 < 0) ...`:
! missing value where TRUE/FALSE needed
Traceback:

1. bloodstream(studypath = studypath, configpath = configfile)
2. rmarkdown::render(input = paste0(system.file(package = "bloodstream"), 
 .     "/rmd/template.rmd"), output_file = paste0(studypath, "/derivatives/bloodstream", 
 .     config_suffix, "/", "bloodstream_report_config", ifelse(stringr::str_length(config_suffix) > 
 .         0, yes = "-", no = ""), config_suffix, ".html"), params = list(configpath = configpath, 
 .     studypath = studypath), knit_root_dir = studypath)
3. knitr::knit(knit_input, knit_output, envir = envir, quiet = quiet)
4. process_file(text, output)
5. withCallingHandlers(withCallingHandlers(if (tangle) process_tangle(group) else process_group(group), 
 .     error = function(e) if (xfun::pkg_available("rlang", "1.0.0")) rlang::entrace(e)), 
 .     error = function(e) {
 .         setwd(wd)
 .         write_utf8(res, output %n% stdout())
 .         message("\nQuitting from lines ", paste(current_lines(i), 
 .             collapse = "-"), if (labels[i] != "") 
 .             sprintf(" [%s]", labels[i]), sprintf(" (%s)", knit_concord$get("infile")))
 .     })
6. withCallingHandlers(if (tangle) process_tangle(group) else process_group(group), 
 .     error = function(e) if (xfun::pkg_available("rlang", "1.0.0")) rlang::entrace(e))
7. process_group(group)
8. process_group.block(group)
9. call_block(x)
10. block_exec(params)
11. eng_r(options)
12. in_input_dir(evaluate(code, envir = env, new_device = FALSE, 
  .     keep_warning = if (is.numeric(options$warning)) TRUE else options$warning, 
  .     keep_message = if (is.numeric(options$message)) TRUE else options$message, 
  .     stop_on_error = if (is.numeric(options$error)) options$error else {
  .         if (options$error && options$include) 
  .             0L
  .         else 2L
  .     }, output_handler = knit_handlers(options$render, options)))
13. in_dir(input_dir(), expr)
14. evaluate(code, envir = env, new_device = FALSE, keep_warning = if (is.numeric(options$warning)) TRUE else options$warning, 
  .     keep_message = if (is.numeric(options$message)) TRUE else options$message, 
  .     stop_on_error = if (is.numeric(options$error)) options$error else {
  .         if (options$error && options$include) 
  .             0L
  .         else 2L
  .     }, output_handler = knit_handlers(options$render, options))
15. evaluate::evaluate(...)
16. evaluate_call(expr, parsed$src[[i]], envir = envir, enclos = enclos, 
  .     debug = debug, last = i == length(out), use_try = stop_on_error != 
  .         2L, keep_warning = keep_warning, keep_message = keep_message, 
  .     log_echo = log_echo, log_warning = log_warning, output_handler = output_handler, 
  .     include_timing = include_timing)
17. timing_fn(handle(ev <- withCallingHandlers(withVisible(eval_with_user_handlers(expr, 
  .     envir, enclos, user_handlers)), warning = wHandler, error = eHandler, 
  .     message = mHandler)))
18. handle(ev <- withCallingHandlers(withVisible(eval_with_user_handlers(expr, 
  .     envir, enclos, user_handlers)), warning = wHandler, error = eHandler, 
  .     message = mHandler))
19. withCallingHandlers(withVisible(eval_with_user_handlers(expr, 
  .     envir, enclos, user_handlers)), warning = wHandler, error = eHandler, 
  .     message = mHandler)
20. withVisible(eval_with_user_handlers(expr, envir, enclos, user_handlers))
21. eval_with_user_handlers(expr, envir, enclos, user_handlers)
22. eval(expr, envir, enclos)
23. eval(expr, envir, enclos)
24. aif_data %>% mutate(aif_fit = map(aif, ~blmod_fengconv(time = .x$time, 
  .     activity = .x$aif, Method = .x$Method)))   # at line 20-22 of file <text>
25. mutate(., aif_fit = map(aif, ~blmod_fengconv(time = .x$time, 
  .     activity = .x$aif, Method = .x$Method)))
26. mutate.data.frame(., aif_fit = map(aif, ~blmod_fengconv(time = .x$time, 
  .     activity = .x$aif, Method = .x$Method)))
27. mutate_cols(.data, dplyr_quosures(...), by)
28. withCallingHandlers(for (i in seq_along(dots)) {
  .     poke_error_context(dots, i, mask = mask)
  .     context_poke("column", old_current_column)
  .     new_columns <- mutate_col(dots[[i]], data, mask, new_columns)
  . }, error = dplyr_error_handler(dots = dots, mask = mask, bullets = mutate_bullets, 
  .     error_call = error_call, error_class = "dplyr:::mutate_error"), 
  .     warning = dplyr_warning_handler(state = warnings_state, mask = mask, 
  .         error_call = error_call))
29. mutate_col(dots[[i]], data, mask, new_columns)
30. mask$eval_all_mutate(quo)
31. eval()
32. map(aif, ~blmod_fengconv(time = .x$time, activity = .x$aif, Method = .x$Method))
33. map_("list", .x, .f, ..., .progress = .progress)
34. with_indexed_errors(i = i, names = names, error_call = .purrr_error_call, 
  .     call_with_cleanup(map_impl, environment(), .type, .progress, 
  .         n, names, i))
35. withCallingHandlers(expr, error = function(cnd) {
  .     if (i == 0L) {
  .     }
  .     else {
  .         message <- c(i = "In index: {i}.")
  .         if (!is.null(names) && !is.na(names[[i]]) && names[[i]] != 
  .             "") {
  .             name <- names[[i]]
  .             message <- c(message, i = "With name: {name}.")
  .         }
  .         else {
  .             name <- NULL
  .         }
  .         cli::cli_abort(message, location = i, name = name, parent = cnd, 
  .             call = error_call, class = "purrr_error_indexed")
  .     }
  . })
36. call_with_cleanup(map_impl, environment(), .type, .progress, 
  .     n, names, i)
37. .f(.x[[i]], ...)
38. blmod_fengconv(time = .x$time, activity = .x$aif, Method = .x$Method)
39. blmod_feng_startpars(time, activity, expdecay_props)
40. .handleSimpleError(function (cnd) 
  . {
  .     if (i == 0L) {
  .     }
  .     else {
  .         message <- c(i = "In index: {i}.")
  .         if (!is.null(names) && !is.na(names[[i]]) && names[[i]] != 
  .             "") {
  .             name <- names[[i]]
  .             message <- c(message, i = "With name: {name}.")
  .         }
  .         else {
  .             name <- NULL
  .         }
  .         cli::cli_abort(message, location = i, name = name, parent = cnd, 
  .             call = error_call, class = "purrr_error_indexed")
  .     }
  . }, "missing value where TRUE/FALSE needed", base::quote(if (startpars$t0 < 
  .     0) {
  .     bloodrise <- bloodrise[blood$activity >= 0.1 * startpars$peakval, 
  .         ]
  .     rise_lm <- lm(activity ~ time, data = bloodrise)
  .     rise_coef <- coef(rise_lm)
  .     startpars$t0 <- as.numeric(-1 * (rise_coef[1]/rise_coef[2]))
  . }))
41. h(simpleError(msg, call))
42. cli::cli_abort(message, location = i, name = name, parent = cnd, 
  .     call = error_call, class = "purrr_error_indexed")
43. rlang::abort(message, ..., call = call, use_cli_format = TRUE, 
  .     .frame = .frame)
44. signal_abort(cnd, .file)
45. signalCondition(cnd)
46. (function (cnd) 
  . {
  .     local_error_context(dots, i = frame[[i_sym]], mask = mask)
  .     if (inherits(cnd, "dplyr:::internal_error")) {
  .         parent <- error_cnd(message = bullets(cnd))
  .     }
  .     else {
  .         parent <- cnd
  .     }
  .     message <- c(cnd_bullet_header(action), i = if (has_active_group_context(mask)) cnd_bullet_cur_group_label())
  .     abort(message, class = error_class, parent = parent, call = error_call)
  . })(structure(list(message = c(i = "In index: 1."), trace = structure(list(
  .     call = list(aif_data %>% mutate(aif_fit = map(aif, ~blmod_fengconv(time = .x$time, 
  .         activity = .x$aif, Method = .x$Method))), mutate(., aif_fit = map(aif, 
  .         ~blmod_fengconv(time = .x$time, activity = .x$aif, Method = .x$Method))), 
  .         mutate.data.frame(., aif_fit = map(aif, ~blmod_fengconv(time = .x$time, 
  .             activity = .x$aif, Method = .x$Method))), mutate_cols(.data, 
  .             dplyr_quosures(...), by), withCallingHandlers(for (i in seq_along(dots)) {
  .             poke_error_context(dots, i, mask = mask)
  .             context_poke("column", old_current_column)
  .             new_columns <- mutate_col(dots[[i]], data, mask, 
  .                 new_columns)
  .         }, error = dplyr_error_handler(dots = dots, mask = mask, 
  .             bullets = mutate_bullets, error_call = error_call, 
  .             error_class = "dplyr:::mutate_error"), warning = dplyr_warning_handler(state = warnings_state, 
  .             mask = mask, error_call = error_call)), mutate_col(dots[[i]], 
  .             data, mask, new_columns), mask$eval_all_mutate(quo), 
  .         eval(), map(aif, ~blmod_fengconv(time = .x$time, activity = .x$aif, 
  .             Method = .x$Method)), map_("list", .x, .f, ..., .progress = .progress), 
  .         with_indexed_errors(i = i, names = names, error_call = .purrr_error_call, 
  .             call_with_cleanup(map_impl, environment(), .type, 
  .                 .progress, n, names, i)), withCallingHandlers(expr, 
  .             error = function(cnd) {
  .                 if (i == 0L) {
  .                 }
  .                 else {
  .                   message <- c(i = "In index: {i}.")
  .                   if (!is.null(names) && !is.na(names[[i]]) && 
  .                     names[[i]] != "") {
  .                     name <- names[[i]]
  .                     message <- c(message, i = "With name: {name}.")
  .                   }
  .                   else {
  .                     name <- NULL
  .                   }
  .                   cli::cli_abort(message, location = i, name = name, 
  .                     parent = cnd, call = error_call, class = "purrr_error_indexed")
  .                 }
  .             }), call_with_cleanup(map_impl, environment(), .type, 
  .             .progress, n, names, i), .f(.x[[i]], ...), blmod_fengconv(time = .x$time, 
  .             activity = .x$aif, Method = .x$Method), blmod_feng_startpars(time, 
  .             activity, expdecay_props), .handleSimpleError(`<fn>`, 
  .             "missing value where TRUE/FALSE needed", base::quote(if (startpars$t0 < 
  .                 0) {
  .                 bloodrise <- bloodrise[blood$activity >= 0.1 * 
  .                   startpars$peakval, ]
  .                 rise_lm <- lm(activity ~ time, data = bloodrise)
  .                 rise_coef <- coef(rise_lm)
  .                 startpars$t0 <- as.numeric(-1 * (rise_coef[1]/rise_coef[2]))
  .             })), h(simpleError(msg, call)), cli::cli_abort(message, 
  .             location = i, name = name, parent = cnd, call = error_call, 
  .             class = "purrr_error_indexed"), rlang::abort(message, 
  .             ..., call = call, use_cli_format = TRUE, .frame = .frame)), 
  .     parent = c(0L, 0L, 0L, 3L, 4L, 4L, 6L, 7L, 0L, 9L, 10L, 11L, 
  .     10L, 10L, 14L, 15L, 0L, 17L, 18L, 19L), visible = c(TRUE, 
  .     TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, 
  .     TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE), 
  .     namespace = c(NA, "dplyr", "dplyr", "dplyr", "base", "dplyr", 
  .     NA, "dplyr", "purrr", "purrr", "purrr", "base", "purrr", 
  .     "bloodstream", "kinfitr", "kinfitr", "base", "purrr", "cli", 
  .     "rlang"), scope = c(NA, "::", ":::", ":::", "::", ":::", 
  .     NA, "local", "::", ":::", ":::", "::", ":::", "local", "::", 
  .     "::", "::", "local", "::", "::"), error_frame = c(FALSE, 
  .     FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, 
  .     FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
  .     FALSE)), row.names = c(NA, -20L), version = 2L, class = c("rlang_trace", 
  . "rlib_trace", "tbl", "data.frame")), parent = structure(list(
  .     message = "missing value where TRUE/FALSE needed", call = if (startpars$t0 < 
  .         0) {
  .         bloodrise <- bloodrise[blood$activity >= 0.1 * startpars$peakval, 
  .             ]
  .         rise_lm <- lm(activity ~ time, data = bloodrise)
  .         rise_coef <- coef(rise_lm)
  .         startpars$t0 <- as.numeric(-1 * (rise_coef[1]/rise_coef[2]))
  .     }), class = c("simpleError", "error", "condition")), location = 1L, 
  .     name = NULL, rlang = list(inherit = TRUE), call = map(aif, 
  .         ~blmod_fengconv(time = .x$time, activity = .x$aif, Method = .x$Method)), 
  .     use_cli_format = TRUE), class = c("purrr_error_indexed", 
  . "rlang_error", "error", "condition")))
47. abort(message, class = error_class, parent = parent, call = error_call)
48. signal_abort(cnd, .file)

Testing

Currently there are no tests. Developing a set of good tests should include tests for the individual functions, but should also include a mini fake dataset which can be parsed and read.

Docker functionality for config file flexibility

I want to add the possibility of including no config file at all, or including a named config file. This is not currently possible in the docker container. It should be a very easy fix, but I just need to make sure that the dockerfile doesn't error out on the command in which the config file is included.

Issues with Institution parsing

When there are multiple Institution tags, bloodstream's parsing seems to pick all of them up and complains about multiple matches. Example in the MC1 data. The institutional tags are from dcm2niix and not part of default BIDS, but it's worthwhile fixing this so that the parser is more robust.

Better outputs

Some ideas to improve the outputs

  • Remove the unused parameters from the output configuration files (e.g. gam basis dimension if an NLS was run).
  • Provide table of the parameters in the report. This allows spotting commonalities in ti values from FengConv for instance.
  • Include parent fraction and BPR parameters in the output configs too.

Unable to Run Docker Version as User

When running bloodstream in docker with the following on ubuntu 22 LTS:

docker run -v $HOME/ds004869:/data/ --user $(id -u):$(id -g) bloodstream

I get the following:

156/157 [sessioninfo]                
157/157                              
Error in file(con, "w") : cannot open the connection
Calls: bloodstream ... <Anonymous> -> <Anonymous> -> write_utf8 -> writeLines -> file
In addition: Warning message:
In file(con, "w") : cannot open file 'template.knit.md': Permission denied

Documentation

The documentations is a bit of a mess. It ought to be fixed up for if users wish to use the functions as standalones, and also to remember what all the pieces do when debugging..

Add weights

Blood modelling weights are important for some models or some tracers. I need to add the option to have weights in both the web app, as well as in the kinfitr functions.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.