{
  "cells": [
    {
      "cell_type": "markdown",
      "source": [
        "# Detection of transmigration events with the *flowcatchR* package\n",
        "Federico Marini, 3 February 2015 \n",
        "-----------------------------\n",
        "\n",
        "## Background\n",
        "\n",
        "Platelets and leukocytes are known for playing essential roles in the development of inflammatory processes in blood vessels (http://www.nature.com/nm/journal/v17/n11/abs/nm.2515.html). The flow chamber system is an *in vitro* assay that allows for the investigation of biomolecular phenomena where the blood flow is simulated. \n",
        "\n",
        "The detection of candidate transmigration events for leukocytes occurs by mean of the detection of intensity changes of cells that, moving out of the focal plane of the microscope, are not anymore on the surface of the blood vessel.\n",
        "\n## The analysis backbone"
      ],
      "metadata": {}
    },
    {
      "cell_type": "code",
      "source": [
        "if (!requireNamespace(\"BiocManager\", quietly = TRUE))\n",
        "    install.packages(\"BiocManager\")\n",
        "BiocManager::install(\"flowcatchR\")\n",
        "library(\"flowcatchR\")"
      ],
      "outputs": [],
      "execution_count": null,
      "metadata": {
        "collapsed": false
      }
    },
    {
      "cell_type": "code",
      "source": [
        "# data loading\n",
        "kerstinImages <- \"/path/to/images/flowchambersystem/\"\n",
        "images <- list.files(kerstinImages,pattern = \"*.png\",full.names = T)"
      ],
      "outputs": [],
      "execution_count": null,
      "metadata": {
        "collapsed": false
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "### Helper functions\n",
        "Here I additionally define some helper functions, specific for this analysis."
      ],
      "metadata": {}
    },
    {
      "cell_type": "code",
      "source": [
        "particleFeatures_alongTraj <- function(trajectoryset,\n",
        "                                       particleset,\n",
        "                                       trajID,\n",
        "                                       ...)\n",
        "{\n",
        "  selectedTraj <- trajectoryset[[trajID]]$trajectory\n",
        "  objectsToPick <- selectedTraj$frameobjectID\n",
        "  framesToPick <- selectedTraj$frame\n",
        "  extendedTrajInfo <- selectedTraj\n",
        "  \n",
        "  tmp <- lapply(1:nrow(selectedTraj),\n",
        "         function(arg){\n",
        "           # arg is the index pro point in the trajectory\n",
        "           realFrame <- framesToPick[arg]\n",
        "           frameObj <- objectsToPick[arg]\n",
        "           objFeatures <- particleset[[ realFrame ]][frameObj,]\n",
        "           objFeatures\n",
        "         }\n",
        "        )\n",
        "  \n",
        "  trajObjFeatures <- do.call(rbind.data.frame,tmp)\n",
        "  trajFull <- data.frame(selectedTraj,trajObjFeatures)\n",
        "  trajFull$meanIntensity <- trajFull$cell.0.s.area * trajFull$cell.a.b.mean\n",
        "  return(trajFull)\n",
        "}"
      ],
      "outputs": [],
      "execution_count": null,
      "metadata": {
        "collapsed": false
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "# The analysis itself"
      ],
      "metadata": {}
    },
    {
      "cell_type": "code",
      "source": [
        "kjRaw <- read.Frames(images)\n",
        "inspect.Frames(kjRaw,nframes=9,display.method=\"raster\")\n",
        "kjProc <- preprocess.Frames(kjRaw)\n",
        "inspect.Frames(kjProc,nframes=9,display.method=\"raster\")\n",
        "kjParts <- particles(kjRaw,kjProc,channel = \"all\")\n",
        "kjParts\n",
        "kjTrajs <- trajectories(kjParts)\n",
        "kjTrajs\n",
        "plot2D.TrajectorySet(kjTrajs,kjRaw)"
      ],
      "outputs": [],
      "execution_count": null,
      "metadata": {
        "collapsed": false
      }
    },
    {
      "cell_type": "code",
      "source": [
        "trajID=4\n",
        "traj4Feats <- particleFeatures_alongTraj(kjTrajs,kjParts,4)\n",
        "framesToPick <- kjTrajs[[trajID]]$trajectory$frame\n",
        "plot(framesToPick,traj4Feats$meanIntensity)\n",
        "lines(spline(framesToPick,traj4Feats$meanIntensity),col = \"steelblue\")\n",
        "\n",
        "par(mfrow=c(4,5))\n",
        "for(i in 1:20)\n",
        "{\n",
        "  singleFullTraj <- particleFeatures_alongTraj(kjTrajs,kjParts,i)\n",
        "  framesToPick <- kjTrajs[[i]]$trajectory$frame\n",
        "  plot(framesToPick,singleFullTraj$meanIntensity,ylim=c(0,max(singleFullTraj$meanIntensity)))\n",
        "  lines(spline(framesToPick,singleFullTraj$meanIntensity),col = \"steelblue\")\n",
        "}\n"
      ],
      "outputs": [],
      "execution_count": null,
      "metadata": {
        "collapsed": false
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "### Alternative workflow with extra normalization step\n",
        "It is possible due to variation in the overall illumination that the image analysis is somehow encountering issues.\n",
        "We try to correct here by normalizing the images on their intensity - this should give a better estimation of the intensity of the particle, fundamental to inspect an eventual decreasing of it as an indicator for a possible transmigration event."
      ],
      "metadata": {}
    },
    {
      "cell_type": "code",
      "source": [
        "## slight modification by first normalizing the images in their intensity\n",
        "kjNorm <- normalizeFrames(kjRaw)\n",
        "kjProc_norm <- preprocess.Frames(kjNorm)\n",
        "kjParts_norm <- particles(kjNorm,kjProc_norm,channel = \"all\")\n",
        "kjTrajs_norm <- trajectories(kjParts_norm)\n",
        "kjTrajs_norm\n",
        "plot2D.TrajectorySet(kjTrajs_norm,kjNorm)\n"
      ],
      "outputs": [],
      "execution_count": null,
      "metadata": {
        "collapsed": false
      }
    },
    {
      "cell_type": "code",
      "source": [
        "## cfr on same trajectory: 4 for original data, 5 for normalized\n",
        "par(mfrow=c(1,2))\n",
        "trajID=4\n",
        "traj4Feats <- particleFeatures_alongTraj(kjTrajs,kjParts,4)\n",
        "framesToPick <- kjTrajs[[trajID]]$trajectory$frame\n",
        "plot(framesToPick,traj4Feats$meanIntensity)\n",
        "lines(spline(framesToPick,traj4Feats$meanIntensity),col = \"steelblue\")\n",
        "\n",
        "trajID=5\n",
        "traj5Feats_norm <- particleFeatures_alongTraj(kjTrajs_norm,kjParts_norm,5)\n",
        "framesToPick <- kjTrajs_norm[[trajID]]$trajectory$frame\n",
        "plot(framesToPick,traj5Feats_norm$meanIntensity)\n",
        "lines(spline(framesToPick,traj5Feats_norm$meanIntensity),col = \"steelblue\")\n"
      ],
      "outputs": [],
      "execution_count": null,
      "metadata": {
        "collapsed": false
      }
    },
    {
      "cell_type": "code",
      "source": [
        "# true negative: 5 for original,6 for normalized\n",
        "par(mfrow=c(1,2))\n",
        "trajID=5\n",
        "traj5Feats <- particleFeatures_alongTraj(kjTrajs,kjParts,5)\n",
        "framesToPick <- kjTrajs[[trajID]]$trajectory$frame\n",
        "plot(framesToPick,traj5Feats$meanIntensity)\n",
        "lines(spline(framesToPick,traj5Feats$meanIntensity),col = \"steelblue\")\n",
        "\n",
        "trajID=6\n",
        "traj6Feats_norm <- particleFeatures_alongTraj(kjTrajs_norm,kjParts_norm,6)\n",
        "framesToPick <- kjTrajs_norm[[trajID]]$trajectory$frame\n",
        "plot(framesToPick,traj6Feats_norm$meanIntensity)\n",
        "lines(spline(framesToPick,traj6Feats_norm$meanIntensity),col = \"steelblue\")\n"
      ],
      "outputs": [],
      "execution_count": null,
      "metadata": {
        "collapsed": false
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "It is possible by taking a closer look to this *brightness profiles* that a reasonable and meaningful threshold is set, in order to detect location candidates for transmigration processes, where the cell fades out of the focal plane. This preliminary automated step serves as a way to reduce the user labour for inspecting the full datasets, by channeling the attention to particular locations in the field of view, and delivering quantitative measurements related to phenomena such as transmigration events which are normally evaluated just on a subjective level."
      ],
      "metadata": {}
    },
    {
      "cell_type": "markdown",
      "source": [
        "## Supplementary information\n",
        "\n",
        "For more information on the method adapted for tracking cells, see Sbalzarini and Koumotsakos (2005).\n",
        "For additional details regarding the functions of *flowcatchR*, please consult the documentation or write an email to (marinif@uni-mainz.de). \n",
        "For requesting help (e.g., for extending one of these analysis templates) or a particular functionality/submitting a pull request, please use https://github.com/federicomarini/flowcatchR and/or write an email to (marinif@uni-mainz.de).\n",
        "\n",
        "## Acknowledgements\n",
        "This package was developed at the Institute of Medical Biostatistics, Epidemiology and Informatics at the University Medical Center, Mainz (Germany), with the financial support provided by the TRP-A15 Translational Research Project grant. \n",
        "\n",
        "*flowcatchR* incorporates suggestions and feedback from the wet-lab biology units operating at the Center for Thrombosis and Hemostasis (CTH), in particular Sven Jäckel and Kerstin Jurk. Sven Jäckel also provided us with the sample acquisition which is available in the package vignette.\n",
        "\n",
        "We would like to thank the members of the Biostatistics division for valuable discussions, and additionally Isabella Zwiener for contributing to the first ideas on the project.\n",
        "\n## Session Information"
      ],
      "metadata": {
        "collapsed": false
      }
    },
    {
      "cell_type": "code",
      "source": [
        "sessionInfo()"
      ],
      "outputs": [],
      "execution_count": null,
      "metadata": {
        "collapsed": true
      }
    }
  ],
  "metadata": {
    "kernelspec": {
      "name": "ir",
      "language": "R",
      "display_name": "R"
    },
    "language_info": {
      "name": "R",
      "codemirror_mode": "r",
      "pygments_lexer": "r",
      "mimetype": "text/x-r-source",
      "file_extension": ".r",
      "version": "3.5.0"
    },
    "kernel_info": {
      "name": "ir"
    },
    "nteract": {
      "version": "0.11.2"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}