RGLab / flowWorkspace

flowWorkspace
GNU Affero General Public License v3.0
44 stars 21 forks source link

Replacing markernames of cytoset exits prematurely in some cases #358

Closed DillonHammill closed 3 years ago

DillonHammill commented 3 years ago

Hi @mikejiang,

I have got quite a complicated issue with replacing markernames of a cytoset that I have spent many hours debugging. I was hoping that you may be able to take a look if you have time.

Everything works fine if I try and replace markernames as below:

library(flowWorkspace)
library(CytoExploreRData)

# define cytoset
cs <- flowSet_to_cytoset(Activation)

# define markers (same as cs - just for demo)
channels <- colnames(cs)
markers <- c(rep("", 6),
              "CD8",
              "Va2",
              "",
              "CD69",
              "",
              "Hoechst-405",
              "Hoechst-430",
              "",
              "CD44",
              "CD4",
              "CD11c",
              "")
names(markers) <- channels

# update markers
markernames(cs) <- markers
markernames(cs)

Now within CytoExploreR I provide an interactive way to modify marker assignments through use of my DataEditR package. If we pass the markers to DataEditR for editing and simply hit the DONE button in the top right corner, the marker assignments are exactly the same as above. In fact I have confirmed this using identical(markers, markers_new) as below. Replacing markernames with markers_new works as expected.

# install DataEditR from CRAN
install.packages("DataEditR")
library(DataEditR)

# create data.frame to edit
markers_edit <- cbind("channel" = channels, "marker" = markers)
markers_edit <- as.data.frame(markers_edit)

# edit markers - (just hit DONE button in top right - no values edited)
markers_edit <- data_edit(markers_edit)

# format result to match that required by markernames
markers_new <- markers_edit$marker
names(markers_new) <- markers_edit$channel

# check that it matches markers defined in previous chunk
identical(markers, markers_new) # TRUE

# update markers
markernames(cs) <- markers_new

From the above code chunks it is clear that both methods work to update the markernames of the cytoset. However, when I try to wrap both methods in a function (called edit_markers()) ONLY THE FIRST METHOD works despite the re-assignments being identical. The second method just terminates early without an error. I have spent ages debugging this and this is what I found. The markernames replacement method for cytoset simply loops through each cytoframe (by sampleName) and calls the markernames replacement method for cytoframe, where the marker assignments are updated. If I print out the sampleNames as we loop through them in the cytoset markernames replacement method, I see that the loop terminates early at around the ninth or tenth sample. So I suspect that the problem is coming from [[ used to extract each cytoframe prior to passing it to the cytoframe markernames replacement method. Please have a look at the example below, where the second method terminates early and the cytoset is not returned by edit_markers(). I added some print statements to illustrate this point, if method 2 works it should print "Method 2 works!" to the console.

edit_markers <- function(x) {
  # METHOD 1 - WORKS
  channels <- colnames(cs)
  markers <- c(rep("", 6),
               "CD8",
               "Va2",
               "",
               "CD69",
               "",
               "Hoechst-405",
               "Hoechst-430",
               "",
               "CD44",
               "CD4",
               "CD11c",
               "")
  names(markers) <- channels
  markernames(x) <- markers

 print("Method 1 works!")

  # METHOD 2 - EXITS EARLY
  markers_edit <- cbind("channel" = channels, "marker" = markers)
  markers_edit <- as.data.frame(markers_edit)
  markers_edit <- data_edit(markers_edit)
  markers_new <- markers_edit$marker
  names(markers_new) <- markers_edit$channel
  markernames(x) <- markers_new

 print("Method 2 works!")

  # CHECK MARKER ASSIGNMENTS MATCH
  identical(markers, markers_new) # TRUE

 # CYTOSET
  return(x)
}
edit_markers(cs)

Sorry for bugging you with this issue @mikejiang, I have spent many hours on this and I am reasonably confident that the issue is not due to something on my end. Please disregard this issue if you cannot reproduce it on your end. I just don't understand why the loop through sampleNames in the cytoset markernames replacement method terminates early without error in certain cases.

Thanks again for all your help!

Dillon

mikejiang commented 3 years ago

I've verified it is not cytolib issue


edit_markers <- function() {

  markers_edit <- cbind("channel" = 1:10, "marker" = 1:10)
  markers_edit <- as.data.frame(markers_edit)
  markers_edit <- data_edit(markers_edit)

  for(i in 1:30)
  {
    fr = new("ExpressionSet")
    print(i)

  }
  print("Method 2 works!")
}
edit_markers()

Listening on http://127.0.0.1:6456
[1] 1
[1] 2
[1] 3
[1] 4

so it's rather the DataEditR issue, which I don't have clue about.

DillonHammill commented 3 years ago

Thanks @mikejiang, I appreciate you taking the time to look into this. I am still baffled by this one, but at least now I can narrow down the list of places to search for the problem. As always, I really appreciate your help!

DillonHammill commented 3 years ago

Thanks again @mikejiang, with your help I managed to track down the problem. Turns out if you run a shiny application in diaolgViewer() and close the application it terminates all active processes. This doesn't happen immediately and that's why the loop was exiting at different stages. In case you ever encounter this issue, the only available solution is to use paneViewer() or browserViewer() and open a different viewer instead.

mikejiang commented 3 years ago

Good to know, Thanks!