{"metadata":{"kernelspec":{"name":"ir","display_name":"R","language":"R"},"language_info":{"name":"R","codemirror_mode":"r","pygments_lexer":"r","mimetype":"text/x-r-source","file_extension":".r","version":"3.6.3"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"---\n#title: 'Loading big .tiff files on R notebooks/ Guide to use Python on R notebooks '\n\n---","metadata":{}},{"cell_type":"markdown","source":"THe python tifffile can be downloaded [here. ](https://pypi.org/project/tifffile/#modal-close )\nIn order to make it ready to import from kaggle notebooks, we need to upload it as dataset, so\nwe can run the notebook offline  ( requirement to make a valid submission)\nFirst we will need some packages, reticulate included:","metadata":{}},{"cell_type":"code","source":"library(tensorflow)\nlibrary(keras)\nlibrary(tfdatasets)\nlibrary(tidyverse)\nlibrary(reticulate)\nlibrary(dplyr)\n","metadata":{"execution":{"iopub.status.busy":"2021-07-13T23:16:21.110423Z","iopub.execute_input":"2021-07-13T23:16:21.112332Z","iopub.status.idle":"2021-07-13T23:16:23.46005Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"The tifffile module can be loaded using a nice function from reticulate\nThe option `convert =F` is important to keep object in the efficient python version[](http://)","metadata":{}},{"cell_type":"code","source":"#py_install(c(\"imagecodecs\", \"tifffile\"))\nff<- list.files(\"../input/hubmap-datasets\",full.names=T )   \npy_install(ff)\nTEST<- file.path(\"../input/hubmap-kidney-segmentation/test\")\nBASE<-file.path(\"../input/hubmap-kidney-segmentation/\")\ntiff<- import(\"tifffile\", convert = F)\n","metadata":{"execution":{"iopub.status.busy":"2021-07-13T23:16:23.462267Z","iopub.execute_input":"2021-07-13T23:16:23.493139Z","iopub.status.idle":"2021-07-13T23:16:28.642508Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Now, lets choose a large .tiff file\n","metadata":{}},{"cell_type":"code","source":"SIZE = 2^7\nbaseid<-list.files(TEST, full.names = F,pattern = \"*.tiff\") %>% gsub(pattern = \".tiff\",replacement =  \"\")\nb<- tibble(baseid=baseid, size = list.files(TEST, full.names = T,pattern = \"*.tiff\") %>% file.info %>% .$size, k = 1: length(baseid))\nb","metadata":{"execution":{"iopub.status.busy":"2021-07-13T23:16:48.142849Z","iopub.execute_input":"2021-07-13T23:16:48.145749Z","iopub.status.idle":"2021-07-13T23:16:48.186479Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Now, here the reticulate package do a great job. It reads the `.tiff` file and return a object in uint8, what is way more memory efficient. ( a numpy array)","metadata":{}},{"cell_type":"markdown","source":"* Lets get rid of extra dimensions and convert to a tensorflow object","metadata":{}},{"cell_type":"code","source":"impath<-file.path(TEST,paste0(baseid[1],\".tiff\"))","metadata":{"execution":{"iopub.status.busy":"2021-07-13T23:16:50.690668Z","iopub.execute_input":"2021-07-13T23:16:50.692304Z","iopub.status.idle":"2021-07-13T23:16:50.704695Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"im <- tiff$imread(impath)  \nnp <- import(\"numpy\", convert=F )\nim<- np$squeeze(im)\nim$shape","metadata":{"execution":{"iopub.status.busy":"2021-07-13T23:16:52.821694Z","iopub.execute_input":"2021-07-13T23:16:52.826587Z","iopub.status.idle":"2021-07-13T23:17:04.705103Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"It is interesting to note that, this kind of object is like native for tensorflow( python native) and keras \nand can be converted direct to a tensorflow object, so that we can manipulate it in R:","metadata":{}},{"cell_type":"markdown","source":"A better way doing this is using python : ( i really should learn more python )\n","metadata":{}},{"cell_type":"code","source":"im <-  tf$constant(im)\nim","metadata":{"execution":{"iopub.status.busy":"2021-07-13T23:17:08.654848Z","iopub.execute_input":"2021-07-13T23:17:08.65672Z","iopub.status.idle":"2021-07-13T23:17:17.651302Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Now, the object is in uint8 format( integers from 0 to 255). If we try to convert to float32 mapped to (0,1) range,\nit will overlow the system memory ( all 32GB on my system. )\nBut we can convert to flat32 to manipulate small chuncks to make predicitions and to train any tensorflow/machine learning codes:\n","metadata":{}},{"cell_type":"code","source":"to_tensorflow<-function(i,j,im=im){\n  #im:  dim[1]= high, dim[2]= width \n  #dest<- paste0(512,\"x\",512, \"+\",i, \"+\", j)\n  #imx<- image_crop(im,dest) %>% .[[1]] %>% as.numeric %>% #array(dim=c (1,SIZE,SIZE,3)) %>%\n  shape<- dim(im)\n  \n  if(shape[1]==3){\n  imx<-im[,(i+1):(i+512),(j+1):(j+512)] %>%\n    k_permute_dimensions(c(2,3,1)) %>%\n    tf$image$convert_image_dtype(.,tf$float32)\n  }else\n  {imx<-im[(i+1):(i+512),(j+1):(j+512),] %>%\n    tf$image$convert_image_dtype(.,tf$float32) \n    \n  }\n  \n imx<- imx  %>%\n  tf$image$resize( size = shape(SIZE,SIZE)) %>% k_expand_dims(axis=1)\n imx\n}","metadata":{"execution":{"iopub.status.busy":"2021-07-13T23:17:20.619245Z","iopub.execute_input":"2021-07-13T23:17:20.621193Z","iopub.status.idle":"2021-07-13T23:17:20.635684Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"i=floor(dim(im)[1]/2)\nj= floor( dim(im)[2]/2 )\nimg<- to_tensorflow(i,j,im)\nimg","metadata":{"execution":{"iopub.status.busy":"2021-07-13T23:17:22.47739Z","iopub.execute_input":"2021-07-13T23:17:22.479329Z","iopub.status.idle":"2021-07-13T23:17:22.800857Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"\nA window 128x128 in shape (1,128,128,3) in tf$float32 that we can process as we see fit.\nfor expample, we can plot to take a look:\n","metadata":{}},{"cell_type":"code","source":"library(imager)\nlibrary(magick)\nimg %>% .[1,,,] %>%k_expand_dims(3)%>% as.array %>% as.cimg(.) %>% plot  #( imager transpose/rotates images 90 degrees because it gets the firt dimention as width, not height  before print/save)\n#or\nimg %>% .[1,,,] %>% as.array %>% as.raster %>% plot\n#or\nimg %>% .[1,,,] %>% as.array %>% image_read %>% plot","metadata":{"execution":{"iopub.status.busy":"2021-07-13T23:17:25.777648Z","iopub.execute_input":"2021-07-13T23:17:25.779384Z","iopub.status.idle":"2021-07-13T23:17:27.438285Z"},"trusted":true},"execution_count":null,"outputs":[]}]}