|
4 | 4 | "cell_type": "markdown", |
5 | 5 | "metadata": {}, |
6 | 6 | "source": [ |
7 | | - "\n# Multidimensional phasor approach\n\nSimultaneous phasor analysis of lifetime and spectral data.\n\nMultidimensional phasor analysis enables the correlation and classification\nof pixels based on multiple fluorescence characteristics simultaneously.\nThis approach combines phasor coordinates from different measurement domains\nto provide enhanced discrimination and identification of molecular species\nor cellular components that may appear similar in single-domain analysis.\n\nPhasor coordinates in one dimension can be mapped to other dimensions by masks\n(or cursors) that define regions of interest in the phasor space. The dimension\nwhere cursors are defined serves as the \"main\" dimension, controlling the\nclassification that is then applied to correlate with other dimensions.\n\nThis analysis method is demonstrated using a dataset combining fluorescence\nlifetime imaging microscopy (FLIM) and hyperspectral imaging (HSI) of LAURDAN\nfluorescence as presented in:\n\n Malacrida L, Jameson D, and Gratton E.\n A multidimensional phasor approach reveals LAURDAN photophysics in NIH-3T3\n cell membranes.\n *Sci Rep*, 7: 9215 (2017). https://doi.org/10.1038/s41598-017-08564-z\n\nThe dataset is available at https://zenodo.org/records/16894639.\n\nThe multidimensional analysis correlates FLIM phasor coordinates from two\ndetection channels with spectral phasor coordinates, enabling enhanced\nclassification of cellular regions based on both lifetime and spectral\nproperties of LAURDAN fluorescence.\n" |
| 7 | + "\n# Multidimensional phasor approach\n\nSimultaneous phasor analysis of lifetime and spectral data.\n\nMultidimensional phasor analysis enables the correlation and classification\nof pixels based on multiple fluorescence characteristics simultaneously.\nThis approach combines phasor coordinates from different measurement domains\nto provide enhanced discrimination and identification of molecular species\nor cellular components that may appear similar in single-domain analysis.\n\nPhasor coordinates in one dimension can be mapped to other dimensions by masks\n(or cursors) that define regions of interest in the phasor space. The dimension\nwhere cursors are defined serves as the \"main\" dimension, controlling the\nclassification that is then applied to correlate with other dimensions.\n\nThis analysis method is demonstrated using a dataset combining fluorescence\nlifetime imaging microscopy (FLIM) and hyperspectral imaging (HSI) of LAURDAN\nfluorescence as presented in:\n\n Malacrida L, Jameson D, and Gratton E.\n [A multidimensional phasor approach reveals LAURDAN photophysics in NIH-3T3\n cell membranes](https://doi.org/10.1038/s41598-017-08564-z).\n *Sci Rep*, 7: 9215 (2017).\n\nThe dataset is available at https://zenodo.org/records/16894639.\n\nThe multidimensional analysis correlates FLIM phasor coordinates from two\ndetection channels with spectral phasor coordinates, enabling enhanced\nclassification of cellular regions based on both lifetime and spectral\nproperties of LAURDAN fluorescence.\n" |
8 | 8 | ] |
9 | 9 | }, |
10 | 10 | { |
|
40 | 40 | }, |
41 | 41 | "outputs": [], |
42 | 42 | "source": [ |
43 | | - "spectral_signal = signal_from_lsm(fetch('04 NIH3T3LAURDAN8meanspectra.lsm'))\n\nflim_signal = signal_from_fbd(\n fetch('04NIH3T3_LAURDAN_000$CC0Z.fbd'),\n frame=-1, # integrate all frames\n channel=None, # load all channels\n laser_factor=0.99168, # override incorrect metadata in FBD file\n)\n\nreference_signal = numpy.stack(\n [\n signal_from_fbd(\n fetch(f'cumarinech{ch}_780LAURDAN_000$CC0Z.fbd'),\n frame=-1,\n channel=ch - 1,\n laser_factor=0.99168,\n )\n for ch in (1, 2)\n ],\n)\n\nfrequency = flim_signal.attrs['frequency'] * flim_signal.attrs['harmonic']" |
| 43 | + "spectral_signal = signal_from_lsm(fetch('04 NIH3T3LAURDAN8meanspectra.lsm'))\n\nflim_signal = signal_from_fbd(\n fetch('04NIH3T3_LAURDAN_000$CC0Z.fbd'),\n frame=-1, # integrate all frames\n channel=None, # load all channels\n laser_factor=0.99168, # override incorrect metadata in FBD file\n)\n\nreference_signal = numpy.stack(\n [\n signal_from_fbd(\n fetch(f'cumarinech{ch + 1}_780LAURDAN_000$CC0Z.fbd'),\n frame=-1,\n channel=ch,\n laser_factor=0.99168,\n )\n for ch in (0, 1)\n ],\n)\n\nfrequency = flim_signal.attrs['frequency'] * flim_signal.attrs['harmonic']" |
44 | 44 | ] |
45 | 45 | }, |
46 | 46 | { |
|
94 | 94 | }, |
95 | 95 | "outputs": [], |
96 | 96 | "source": [ |
97 | | - "plot_phasor(\n spectral_real,\n spectral_imag,\n xlim=(-0.5, 1.05),\n ylim=(-0.1, 1.05),\n allquadrants=True,\n title='Spectral phasor coordinates',\n)" |
| 97 | + "plot_phasor(\n spectral_real,\n spectral_imag,\n xlim=(-0.5, 1.05),\n ylim=(-0.1, 1.05),\n allquadrants=True,\n title='Spectral phasor',\n)" |
98 | 98 | ] |
99 | 99 | }, |
100 | 100 | { |
|
112 | 112 | }, |
113 | 113 | "outputs": [], |
114 | 114 | "source": [ |
115 | | - "plot = PhasorPlot(frequency=frequency, title='FLIM phasor coordinates')\nplot.hist2d(flim_real[0], flim_imag[0], cmap='Blues')\nplot.hist2d(flim_real[1], flim_imag[1], cmap='Oranges', alpha=0.5)\nplot.show()" |
| 115 | + "fig, axs = pyplot.subplots(2, 1, figsize=(6.4, 9))\nfig.suptitle('FLIM phasor')\nfor ch in (0, 1):\n plot = PhasorPlot(\n ax=axs[ch], frequency=frequency, title=f'Channel {ch + 1}'\n )\n plot.hist2d(flim_real[ch], flim_imag[ch])\nfig.tight_layout()\nplot.show()" |
116 | 116 | ] |
117 | 117 | }, |
118 | 118 | { |
|
130 | 130 | }, |
131 | 131 | "outputs": [], |
132 | 132 | "source": [ |
133 | | - "spectral_cursor_real = [0.04, 0.24, 0.14]\nspectral_cursor_imag = [0.74, 0.70, 0.72]\nspectral_cursor_radius = 0.05\n\nspectral_masks = mask_from_circular_cursor(\n spectral_real,\n spectral_imag,\n spectral_cursor_real,\n spectral_cursor_imag,\n radius=spectral_cursor_radius,\n)" |
| 133 | + "spectral_cursor_real = [0.04, 0.24, 0.14]\nspectral_cursor_imag = [0.74, 0.70, 0.72]\nspectral_cursor_radius = 0.05\n\nspectral_mask = mask_from_circular_cursor(\n spectral_real,\n spectral_imag,\n spectral_cursor_real,\n spectral_cursor_imag,\n radius=spectral_cursor_radius,\n)" |
134 | 134 | ] |
135 | 135 | }, |
136 | 136 | { |
|
148 | 148 | }, |
149 | 149 | "outputs": [], |
150 | 150 | "source": [ |
151 | | - "plot = PhasorPlot(\n xlim=(-0.5, 1.05),\n ylim=(-0.1, 1.05),\n xticks=None,\n yticks=None,\n allquadrants=True,\n title='Spectral phasor and cursors',\n)\nplot.hist2d(\n spectral_real,\n spectral_imag,\n cmap='Grays',\n bins=200,\n)\nplot.cursor(\n spectral_cursor_real,\n spectral_cursor_imag,\n radius=spectral_cursor_radius,\n color=CATEGORICAL[:3],\n linestyle='-',\n linewidth=2,\n)\nplot.show()" |
| 151 | + "plot = PhasorPlot(\n xlim=(-0.5, 1.05),\n ylim=(-0.1, 1.05),\n xticks=None,\n yticks=None,\n allquadrants=True,\n title='Spectral phasor and cursors',\n)\nplot.hist2d(\n spectral_real,\n spectral_imag,\n cmap='Grays',\n bins=200,\n)\nplot.cursor(\n spectral_cursor_real,\n spectral_cursor_imag,\n radius=spectral_cursor_radius,\n color=CATEGORICAL[:3],\n linewidth=2,\n)\nplot.show()" |
152 | 152 | ] |
153 | 153 | }, |
154 | 154 | { |
|
166 | 166 | }, |
167 | 167 | "outputs": [], |
168 | 168 | "source": [ |
169 | | - "spectral_pseudo_color = pseudo_color(*spectral_masks)\nplot_image(spectral_pseudo_color, title='Spectral pseudo-color image')" |
| 169 | + "spectral_pseudo_color = pseudo_color(*spectral_mask)\nplot_image(spectral_pseudo_color, title='Spectral pseudo-color image')" |
170 | 170 | ] |
171 | 171 | }, |
172 | 172 | { |
|
184 | 184 | }, |
185 | 185 | "outputs": [], |
186 | 186 | "source": [ |
187 | | - "fig, axs = pyplot.subplots(2, 1, figsize=(6.4, 8))\nfig.suptitle('Spectral classified FLIM phasor')\n\nfor ch in range(2):\n plot = PhasorPlot(\n ax=axs[ch], frequency=frequency, title=f'Channel {ch + 1}'\n )\n for i in range(spectral_masks.shape[0]):\n plot.plot(\n flim_real[ch][spectral_masks[i]],\n flim_imag[ch][spectral_masks[i]],\n color=CATEGORICAL[i],\n alpha=0.05,\n markersize=0.5,\n )\nfig.tight_layout()\nplot.show()" |
| 187 | + "fig, axs = pyplot.subplots(2, 1, figsize=(6.4, 9))\nfig.suptitle('Spectral classified FLIM phasor')\n\nfor ch in (0, 1):\n plot = PhasorPlot(\n ax=axs[ch], frequency=frequency, title=f'Channel {ch + 1}'\n )\n for i in range(spectral_mask.shape[0]):\n plot.plot(\n flim_real[ch][spectral_mask[i]],\n flim_imag[ch][spectral_mask[i]],\n color=CATEGORICAL[i],\n alpha=0.05,\n markersize=0.5,\n )\nfig.tight_layout()\nplot.show()" |
188 | 188 | ] |
189 | 189 | }, |
190 | 190 | { |
|
202 | 202 | }, |
203 | 203 | "outputs": [], |
204 | 204 | "source": [ |
205 | | - "flim_cursor_real = [0.35, 0.19, 0.27]\nflim_cursor_imag = [0.44, 0.38, 0.41]\nflim_cursor_radius = 0.05\n\nflim_ch1_masks = mask_from_circular_cursor(\n flim_real[0],\n flim_imag[0],\n flim_cursor_real,\n flim_cursor_imag,\n radius=flim_cursor_radius,\n)" |
| 205 | + "flim_cursor_real = [0.35, 0.19, 0.27]\nflim_cursor_imag = [0.44, 0.38, 0.41]\nflim_cursor_radius = 0.05\n\nflim_mask = mask_from_circular_cursor(\n flim_real[0],\n flim_imag[0],\n flim_cursor_real,\n flim_cursor_imag,\n radius=flim_cursor_radius,\n)" |
206 | 206 | ] |
207 | 207 | }, |
208 | 208 | { |
|
220 | 220 | }, |
221 | 221 | "outputs": [], |
222 | 222 | "source": [ |
223 | | - "plot = PhasorPlot(\n frequency=frequency,\n title='FLIM phasor and cursors (first channel)',\n)\nplot.hist2d(flim_real[0], flim_imag[0], cmap='Grays', bins=200)\nplot.cursor(\n flim_cursor_real,\n flim_cursor_imag,\n radius=flim_cursor_radius,\n color=CATEGORICAL[:3],\n linestyle='-',\n linewidth=2,\n)\nplot.show()" |
| 223 | + "plot = PhasorPlot(\n frequency=frequency,\n title='FLIM phasor and cursors (first channel)',\n)\nplot.hist2d(flim_real[0], flim_imag[0], cmap='Grays', bins=200)\nplot.cursor(\n flim_cursor_real,\n flim_cursor_imag,\n radius=flim_cursor_radius,\n color=CATEGORICAL[:3],\n linewidth=2,\n)\nplot.show()" |
224 | 224 | ] |
225 | 225 | }, |
226 | 226 | { |
|
238 | 238 | }, |
239 | 239 | "outputs": [], |
240 | 240 | "source": [ |
241 | | - "plot_image(\n pseudo_color(*flim_ch1_masks),\n title='FLIM pseudo-color image (first channel)',\n)" |
| 241 | + "plot_image(\n pseudo_color(*flim_mask), title='FLIM pseudo-color image (first channel)'\n)" |
242 | 242 | ] |
243 | 243 | }, |
244 | 244 | { |
|
256 | 256 | }, |
257 | 257 | "outputs": [], |
258 | 258 | "source": [ |
259 | | - "plot = PhasorPlot(\n xlim=(-0.5, 1.05),\n ylim=(-0.1, 1.05),\n allquadrants=True,\n title='FLIM classified spectral phasor',\n)\n\nfor i in range(flim_ch1_masks.shape[0]):\n plot.plot(\n spectral_real[flim_ch1_masks[i]],\n spectral_imag[flim_ch1_masks[i]],\n color=CATEGORICAL[i],\n alpha=0.05,\n markersize=1,\n )\n\nplot.show()" |
| 259 | + "plot = PhasorPlot(\n xlim=(-0.5, 1.05),\n ylim=(-0.1, 1.05),\n allquadrants=True,\n title='FLIM classified spectral phasor',\n)\n\nfor i in range(flim_mask.shape[0]):\n plot.plot(\n spectral_real[flim_mask[i]],\n spectral_imag[flim_mask[i]],\n color=CATEGORICAL[i],\n alpha=0.05,\n markersize=1,\n )\n\nplot.show()" |
260 | 260 | ] |
261 | 261 | }, |
262 | 262 | { |
|
0 commit comments