{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# OpenFLIM Ops" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Dependencies" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The FLIMJ ops live in `flimlib:flimj-ops`. This dependency has to be present in order to use the ops. You can either import the package from your maven local or the ImageJ central repository." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Added new repo: mvnLocal\n", "Added new repo: scijava.public\n" ] }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "", "version_major": 2, "version_minor": 0 }, "method": "display_data" }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "ebfac183-7777-48ba-a937-45c9babf3d04", "version_major": 2, "version_minor": 0 }, "method": "display_data" }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "", "version_major": 2, "version_minor": 0 }, "method": "display_data" }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "a0b4ce88-83f5-4dbd-9cf2-aab4b8409897", "version_major": 2, "version_minor": 0 }, "method": "display_data" }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "net.imagej.notebook.DefaultNotebookService [priority = 0.0]" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "// uncomment to import from local repo\n", "%classpath config resolver mvnLocal\n", "// import from ImageJ central repo\n", "%classpath config resolver scijava.public https://maven.scijava.org/content/groups/public\n", "// uncomment to import from ImageJ central repo\n", "%classpath add mvn flimlib flimj-ops 0.1.0-SNAPSHOT\n", "%classpath add mvn net.imagej imagej 2.0.0-rc-71\n", "\n", "import net.imagej.ImageJ\n", "\n", "ij = new ImageJ()\n", "op = ij.op()\n", "nb = ij.notebook()" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "null" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "// run this if dependency messed up\n", "// %classpath reset" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Utility Code" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Here is some utility code that helps display the multi-layer fitted images, no attention needed." ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "FancyDisplay@4c92b242" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import net.imglib2.type.numeric.ARGBType\n", "import net.imglib2.type.numeric.real.FloatType\n", "import net.imagej.display.ColorTables\n", "import net.imglib2.converter.Converters\n", "import net.imglib2.converter.RealLUTConverter\n", "\n", "class FancyDisplay {\n", " \n", " public channelAxis, op, nb\n", " \n", " public FancyDisplay(ij, channelAxis=3) {\n", " this.channelAxis = channelAxis\n", " this.op = ij.op()\n", " this.nb = ij.notebook()\n", " }\n", " \n", " public tableDisp(fitted, tMin=null, tMax=null, aMax=null, zMax=null) {\n", " def lifetimeAxis = fitted.ltAxis\n", " def fittedImg = fitted.paramMap\n", " def sampleZ = op.transform().hyperSliceView(fittedImg, lifetimeAxis, 0)\n", " def sampleA = []\n", " def sampleT = []\n", " for (int comp in 0..((fittedImg.dimension(lifetimeAxis) - 1) / 2 - 1)) {\n", " sampleA.push(op.transform().hyperSliceView(fittedImg, lifetimeAxis, comp * 2 + 1))\n", " sampleT.push(op.transform().hyperSliceView(fittedImg, lifetimeAxis, comp * 2 + 2))\n", " }\n", "\n", " println(\"Z min = \" + op.stats().min(sampleZ))\n", " println(\"Z max = \" + op.stats().max(sampleZ))\n", " for (int i in 0..sampleA.size() - 1) {\n", " println(\"A\" + (i + 1) + \" min = \" + op.stats().min(sampleA[i]))\n", " println(\"A\" + (i + 1) + \" max = \" + op.stats().max(sampleA[i]))\n", " println(\"Tau\" + (i + 1) + \" min = \" + op.stats().min(sampleT[i]))\n", " println(\"Tau\" + (i + 1) + \" max = \" + op.stats().max(sampleT[i]))\n", " }\n", " \n", " def pseudocolor = op.run(\"flim.showPseudocolor\", fitted, tMin, tMax, 0, aMax);\n", " \n", " // default values from img\n", " zMax = zMax == null ? op.stats().max(sampleZ) : new FloatType(zMax)\n", " aMax = aMax == null ? op.stats().max(sampleA[0]) : new FloatType(aMax)\n", " tMin = tMin == null ? op.stats().min(sampleT[0]) : new FloatType(tMin)\n", " tMax = tMax == null ? op.stats().max(sampleT[0]) : new FloatType(tMax)\n", " \n", " def labeled = [:]\n", " labeled[\"Z\"] = nb.display(sampleZ, 0, zMax.getRealFloat())\n", " \n", " for (int i in 0..sampleA.size() - 1) {\n", " labeled[\"A\" + (i + 1)] = nb.display(sampleA[i], 0, aMax.getRealFloat())\n", " labeled[\"Tau\" + (i + 1)] = nb.display(sampleT[i], tMin.getRealFloat(), tMax.getRealFloat())\n", " labeled[\"Pseudocolor\" + (i + 1)] = op.transform().hyperSliceView(pseudocolor, lifetimeAxis, i)\n", " }\n", " return [labeled]\n", " }\n", "}\n", "\n", "fcd = new FancyDisplay(ij)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Loading Dataset" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Here we use the [scifio](https://imagej.net/SCIFIO) [bio-formats](https://imagej.net/Bio-Formats) plugin to load time-resolved transient data from `input.sdt`." ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[INFO] Reading SDT header\r\n" ] }, { "data": { "text/html": [ "" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sdtPath = \"../test_files/input.sdt\"\n", "\n", "sdt = ij.scifio().datasetIO().open(sdtPath)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The acquired dataset is actually a 4-dimensional image as we will be shown bellow. It appears purely dark because the notebook by default displays the first layer it sees.
\n", "We now use the following snippet to \"chop up\" the dataset for demonstration. We also display the metadata for reference." ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "scrolled": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[INFO] Reading SDT header\n", "Dim #0: size: 128, type: X\n", "Dim #1: size: 128, type: Y\n", "Dim #2: size: 64, type: Lifetime\n", "Dim #3: size: 16, type: Spectra\n", "Time base: 12.500000, number of bins: 64\n" ] }, { "data": { "text/html": [ "
Channel1.0 ns1.2 ns1.4 ns1.6 ns1.8 ns2.0 ns2.1 ns2.3 ns2.5 ns2.7 ns2.9 ns3.1 ns
6
7
8
9
10
11
12
13
14
15
" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import io.scif.lifesci.SDTFormat\n", "\n", "sdtReader = new SDTFormat.Reader()\n", "sdtReader.setContext(ij.getContext())\n", "sdtReader.setSource(sdtPath)\n", "sdtMetadata = sdtReader.getMetadata()\n", "\n", "// display the axis type of each dimension\n", "for (d = 0; d < sdt.numDimensions(); d++) {\n", " printf(\"Dim #%d: size: %3d, type: %s\\n\", d, sdt.dimension(d), sdt.axis(d).type())\n", "}\n", "\n", "timeBase = sdtMetadata.getTimeBase()\n", "timeBins = sdtMetadata.getTimeBins()\n", "\n", "printf(\"Time base: %6f, number of bins: %d\\n\", timeBase, timeBins)\n", "\n", "cStart = 6\n", "cEnd = 15\n", "tStart = 5\n", "tEnd = 16\n", "\n", "table = []\n", "for (c in (cStart..cEnd)) {\n", " row = table[c - cStart] = [:]\n", " row.put(\"Channel\", c)\n", " cFixed = op.transform().hyperSliceView(sdt, 3, c)\n", " for (t in (tStart..tEnd)) {\n", " sample = op.transform().hyperSliceView(cFixed, 2, t)\n", " row.put(String.format(\"%.1f ns\", t * timeBase / timeBins), sample)\n", " }\n", "}\n", "ij.notebook().display(table)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Shown above are images from channel 6 through 15, time bin 5 through 16. For the rest of the demo, we choose channel 12 and perform the fit from time bin 9 to 20." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Hyperparameter Setup" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Prior to fitting, we set up some fitting parameters specifying how the fitting is done. All the settings are described below. The commented settings are optional and are set to default values." ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "xInc: 0.195313, interval: [-1, -1], intensity threshold: -1.000000, instr: null, noise: NOISE_POISSON_FIT, sig: null, param: null, paramFree: null, restrain: ECF_RESTRAIN_DEFAULT, fitFunc: flim.FitFuncNative@3b7b9f89, chisq_target: 1.000000, chisq_delta: 0.000100, chisq_percent: 95" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import flimlib.flimj.FitParams\n", "// import flimlib.flimj.FitFunc\n", "// import flimlib.flimj.NoiseType\n", "// import flimlib.flimj.RestrainType\n", "\n", "// create a new fitting parameter set\n", "param = new FitParams()\n", "// the dataset (3D image with coordinates (x, y, t)) we choose channel 12 in this case\n", "param.transMap = op.transform().hyperSliceView(sdt, 3, 12);\n", "// // the iterative fitting routine will stop when chi-squared improvement is less than param.chisq_delta\n", "// param.chisq_delta = 0.0001f\n", "// // the confidence interval when calculating the error axes (95% here)\n", "// param.chisq_percent = 95\n", "// // the routine will also stop when chi-squared < param.chisq_target\n", "// param.chisq_target = 1\n", "// when does the decay start and end?\n", "// param.fitStart = 9\n", "// param.fitEnd = 20\n", "// // the deacy model to use, in this case y(t) = Z + A * e^(-t / TAU)\n", "// param.fitFunc = FitFunc.GCI_MULTIEXP_TAU\n", "// // assume the data noise follows a Poisson distribution\n", "// param.noise = NoiseType.NOISE_GAUSSIAN_FIT\n", "// // the standard deviation at each data point in y\n", "// // NB: if NoiseType.NOISE_GIVEN is used, param.sig should be passed in\n", "// param.sig = null\n", "// // initial Z, A_i and TAU_i (i = 1, 2, ...)\n", "// param.param = [ 0, 0, 0, ... ]\n", "// all three parameters above will be fitted\n", "// param.paramFree = [ true, true, true ]\n", "// // use the default restrain type\n", "// param.restrain = RestrainType.ECF_RESTRAIN_DEFAULT\n", "// the time difference between two consecutive bins (ns)\n", "param.xInc = timeBase / timeBins\n", "// // generates the image of return code\n", "// param.getReturnCodeMap = false\n", "// // generates the image of parameters\n", "// param.getParamMap = true\n", "// // generates the image of fitted data\n", "// param.getFittedMap = false\n", "// // generates the image of residuals\n", "// param.getResidualsMap = false\n", "// // generates the image of chi-squared\n", "// param.getChisqMap = false\n", "// the index of the lifetime axis (from metadata)\n", "param.ltAxis = 2\n", "\n", "param" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "All of the fitting ops takes the same parameter, the fitting parameter (`params`) and the Lifetime axis index (`lifetimeAxis`). The rigion of interest (`roi`) is optional (see below)." ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Available operations:\n", "\t(FitResults out?) =\n", "\tflimlib.flimj.DefaultFitII$MLAFitII(\n", "\t\tFitResults out?,\n", "\t\tIterableInterval in,\n", "\t\tFitParams params)\n", "\t(FitResults out) =\n", "\tflimlib.flimj.DefaultFitRAI$MLASingleFitRAI(\n", "\t\tFitParams in,\n", "\t\tRealMask roi?,\n", "\t\tRandomAccessibleInterval kernel?)" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "op.help(\"flim.fitMLA\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Performing Image Fitting" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Once everything is set up, the fitting routine can be easily started. The op will generate an `FitResults` object with all the per-pixel results assembled into images. Specifically, `resutls.paramMap` will be the image of fitted parameters if `param.getParamMap` is set to `true` (which is by default), and `resutls.fittedMap`, `resutls.residualMap`, `resutls.chisqMap` will be those of fitted data ($\\tilde{y}$), residuals ($y-\\tilde{y}$) and $\\chi^2$ respectively if the corresponding `getXxMap` option is turned on.
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This images (`xxMap`) in `results` will be of the same size as the input dataset in X and Y directions. The result attributes (fitted parameters, $\\chi^2$, etc.) for that (x, y) coordinate will be layed along the Lifetime axis. E.g. `results.paramMap(x, y, 0)` will be the *Z* (constant term) for the transient at coordinate (x, y), while `results.fittedMap(x, y, 4)` will be the fitted data of the 4th time bin ($\\tilde{y}_4$) of the same pixel." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Here we demonstrate the most used ops:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Initial Parameter Estimation (RLD)" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "flimlib.flimj.FitResults@6f4c1a0f" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "// spin!\n", "rldRslt = op.run(\"flim.fitRLD\", param)" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Z min = -37.23078155517578\n", "Z max = 10.958125114440918\n", "A1 min = 0.0\n", "A1 max = 1728.772216796875\n", "Tau1 min = 0.0\n", "Tau1 max = 5.780399322509766\n", "brightness_max automatically set to 1081.4703\n" ] }, { "data": { "text/html": [ "
ZA1Tau1Pseudocolor1
" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "// showing tau from 0.15 to 0.4\n", "nb.display(fcd.tableDisp(rldRslt, 0.15, 0.4))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Refinement (Levenberg-Marquardt Algorithm)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Plaint LMA fit" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Z min = -288.048095703125\n", "Z max = 129.5683135986328\n", "A1 min = -129.72164916992188\n", "A1 max = 421.7679443359375\n", "Tau1 min = -2.19531955063383654E18\n", "Tau1 max = 1.628263575191552E15\n", "brightness_max automatically set to 358.49054\n" ] }, { "data": { "text/html": [ "
ZA1Tau1Pseudocolor1
" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "mlaRslt = op.run(\"flim.fitMLA\", param)\n", "\n", "// showing tau from 0.13 to 0.25\n", "nb.display(fcd.tableDisp(mlaRslt, 0.13, 0.25))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The plaint LMA fit starts with an arbitrary set of initial parameters $z=0, a_i=1, \\tau_i=1$. By design, the algorithm is only able to find values that locally minimizes the residuals and is therefore harder to converge compared to the following scheme:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### LMA fit with estimated initial values" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To set the initial parameters, either use `param.param` to set an array of global initial values:" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Z min = -137.22894287109375\n", "Z max = 459.2732238769531\n", "A1 min = -456.62646484375\n", "A1 max = 1088.8184814453125\n", "Tau1 min = -1.92399227597357056E17\n", "Tau1 max = 7.7091735513491046E17\n", "brightness_max automatically set to 921.78534\n" ] }, { "data": { "text/html": [ "
ZA1Tau1Pseudocolor1
" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "// Z = 0, A = 1000, Tau = 0.187\n", "param.param = [ 0, 1000, 0.18723493814468384 ]\n", "mlaRslt = op.run(\"flim.fitMLA\", param)\n", "// later fits shouldn't be affected\n", "param.param = null\n", "\n", "// showing tau from 0.13 to 0.25\n", "nb.display(fcd.tableDisp(mlaRslt, 0.13, 0.25))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "or use `param.paramMap` to set the per-pixel initial values from a previous fit:" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Z min = -0.3008432686328888\n", "Z max = 5.321786880493164\n", "A1 min = 0.0\n", "A1 max = 1088.684814453125\n", "Tau1 min = 0.0\n", "Tau1 max = 3.395394802093506\n", "brightness_max automatically set to 921.2601\n" ] }, { "data": { "text/html": [ "
ZA1Tau1Pseudocolor1
" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "// here we use the RLD's output as our estimation\n", "param.paramMap = rldRslt.paramMap\n", "mlaRslt = op.run(\"flim.fitMLA\", param)\n", "// later fits shouldn't be affected\n", "param.paramMap = null\n", "\n", "// showing tau from 0.13 to 0.25\n", "nb.display(fcd.tableDisp(mlaRslt, 0.13, 0.25))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "_Note: if both initial value settings are present, the global values will be overriden by the pixel-specific values._" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Global Analysis" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Z min = -16.0\n", "Z max = 5.352066993713379\n", "A1 min = 0.0\n", "A1 max = 1058.4622802734375\n", "Tau1 min = 0.18723493814468384\n", "Tau1 max = 0.18723493814468384\n", "brightness_max automatically set to 904.07117\n" ] }, { "data": { "text/html": [ "
ZA1Tau1Pseudocolor1
" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "globalRslt = op.run(\"flim.fitGlobal\", param)\n", "\n", "// showing tau from 0.13 to 0.25\n", "nb.display(fcd.tableDisp(globalRslt, 0.13, 0.25))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Multiple component fit" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For multi-exponential models ($I=\\sum_{i=1}^n a_i e^{-\\frac{t}{\\tau_i}}$), set `param.nComp` to the number of exponential components:" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Z min = -2.5444112E7\n", "Z max = 4695018.0\n", "A1 min = -15.217549324035645\n", "A1 max = 1086.9586181640625\n", "Tau1 min = -3.8798919808122356E19\n", "Tau1 max = 3.7239729106464054E27\n", "A2 min = -4695017.0\n", "A2 max = 2.5444112E7\n", "Tau2 min = -6.610360287203018E37\n", "Tau2 max = 5.267875201440915E37\n", "brightness_max automatically set to 885.0121\n" ] }, { "data": { "text/html": [ "
ZA1Tau1Pseudocolor1A2Tau2Pseudocolor2
" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "param.nComp = 2\n", "// again, we use the RLD's output as our estimation\n", "rldRslt = op.run(\"flim.fitRLD\", param)\n", "param.paramMap = rldRslt.paramMap\n", "mlaRslt = op.run(\"flim.fitMLA\", param)\n", "// later fits shouldn't be affected\n", "param.paramMap = null\n", "param.nComp = 1\n", "\n", "// showing tau from 0.13 to 0.25\n", "nb.display(fcd.tableDisp(mlaRslt, 0.13, 0.25))" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Z min = -16.0\n", "Z max = 3.0639078617095947\n", "A1 min = 0.0\n", "A1 max = 243.12957763671875\n", "Tau1 min = 1.1072466373443604\n", "Tau1 max = 1.1072466373443604\n", "A2 min = 0.0\n", "A2 max = 990.9171752929688\n", "Tau2 min = 0.1581559181213379\n", "Tau2 max = 0.1581559181213379\n", "A3 min = 0.0\n", "A3 max = 958.3338623046875\n", "Tau3 min = 0.15660516917705536\n", "Tau3 max = 0.15660516917705536\n", "brightness_max automatically set to 750.06635\n" ] }, { "data": { "text/html": [ "
ZA1Tau1Pseudocolor1A2Tau2Pseudocolor2A3Tau3Pseudocolor3
" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "// set # of exponential components\n", "param.nComp = 3\n", "globalRslt = op.run(\"flim.fitGlobal\", param)\n", "param.nComp = 1\n", "\n", "// showing tau from 0.13 to 0.25\n", "nb.display(fcd.tableDisp(globalRslt, 10, 10))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Phasor Analysis" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "flimlib.flimj.FitResults@19498cc4" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "// WIP\n", "param.paramMap = null\n", "phasorRslt = op.run(\"flim.fitPhasor\", param)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Other settings" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Region of Interest" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Sometimes, instead of the whole dataset, only part of the image (e.g. the region near the nucleus) are of our interest. By specifying the `roi` parameter, we neglect unwanted parts outside of it during fitting. This greatly improves the running time on large images." ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "net.imglib2.roi.geom.real.OpenWritableBox@1d29" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import net.imglib2.roi.geom.real.OpenWritableBox\n", "\n", "min = [ 20, 20 ]\n", "max = [ 100, 100 ]\n", "\n", "// define our region of interest, in this case [40, 87] * [40, 87]\n", "roi = new OpenWritableBox([ min[0] - 1, min[1] - 1 ] as double[], [ max[0] + 1, max[1] + 1 ] as double[])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We start the fitting routine the same way as before but with the `roi` parameter:" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Z min = -0.23343004286289215\n", "Z max = 5.321786880493164\n", "A1 min = 0.0\n", "A1 max = 1088.684814453125\n", "Tau1 min = 0.0\n", "Tau1 max = 3.1886990070343018\n", "brightness_max automatically set to 921.0847\n" ] }, { "data": { "text/html": [ "
ZA1Tau1Pseudocolor1
" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "// fitMLA with roi\n", "param.paramMap = rldRslt.paramMap\n", "mlaRslt = op.run(\"flim.fitMLA\", param, roi)\n", "nb.display(fcd.tableDisp(mlaRslt, 0.13, 0.25))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In the results above, all other regions outside the box is neglected." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Binning" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Binning settings are enabled by setting the binning kernel parameter. The kernel can be any image. Here we use the built-in `SQUARE_KERNEL_3`, a $3\\times3$ image with each pixel valued $\\frac{1}{9}$:" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import flimlib.flimj.FlimOps\n", "FlimOps.SQUARE_KERNEL_3" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Z min = -0.054822858422994614\n", "Z max = 3.1212329864501953\n", "A1 min = 0.0\n", "A1 max = 921.3705444335938\n", "Tau1 min = 0.0\n", "Tau1 max = 1.1913063526153564\n", "brightness_max automatically set to 817.89197\n" ] }, { "data": { "text/html": [ "
ZA1Tau1Pseudocolor1
" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import flimlib.flimj.FlimOps\n", "\n", "// spin!\n", "rldRslt = ij.op().run(\"flim.fitRLD\", param, roi, FlimOps.SQUARE_KERNEL_3)\n", "\n", "param.paramMap = rldRslt.paramMap\n", "mlaRslt = ij.op().run(\"flim.fitMLA\", param, roi, FlimOps.SQUARE_KERNEL_3)\n", "\n", "nb.display(fcd.tableDisp(mlaRslt, 0.13, 0.25))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Groovy", "language": "groovy", "name": "groovy" }, "language_info": { "codemirror_mode": "groovy", "file_extension": ".groovy", "mimetype": "", "name": "Groovy", "nbconverter_exporter": "", "version": "2.4.3" }, "toc": { "base_numbering": 1, "nav_menu": {}, "number_sections": false, "sideBar": false, "skip_h1_title": false, "title_cell": "Table of Contents", "title_sidebar": "Contents", "toc_cell": false, "toc_position": {}, "toc_section_display": false, "toc_window_display": false } }, "nbformat": 4, "nbformat_minor": 2 }