.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "auto_examples/flim/plot_tutorial_python.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code .. rst-class:: sphx-glr-example-title .. _sphx_glr_auto_examples_flim_plot_tutorial_python.py: ============================ Tutorial: Image construction ============================ Below, using a few lines of python code it is outlined how CLSM images can be constructed. For productive uses ``tttrlib`` provides a set of functions to create images based on CLSM TTTR data implemented in C/C++. To describe how this is actually implemented, it is outlined below in Python only using basic the basic functionality of ``tttrlib``. The presented outline presented below may serve to understand how the image construction in CLSM work and is not intended for productive use. For any productive applications it is recommended to use the built-in ``tttrlib`` CLSM functions. .. GENERATED FROM PYTHON SOURCE LINES 18-42 .. code-block:: Python import tttrlib import numpy as np import pylab as p import numba as nb @nb.jit(nopython=True) def count_marker(channels, event_types, marker, event_type): n = 0 for i, ci in enumerate(channels): if (ci == marker) and (event_types[i] == event_type): n += 1 return n @nb.jit(nopython=True) def find_marker(channels, event_types, maker, event_type=1): r = list() for i, ci in enumerate(channels): if (ci == maker) and (event_types[i] == event_type): r.append(i) return np.array(r) .. GENERATED FROM PYTHON SOURCE LINES 43-69 In the example above, first the number of frames are counted. Next, the number of start line events are counted. In the example, there are overall 41 frames are present in the file each having 256 lines. As the last frame is often incomplete (see Figure above) the last frame is neglected (41 - 1 = 40). With the script above, the number of frames ``n_frames`` and the number of lines per frame ``n_lines_per_frame`` is determined. Next, the number of pixel per line ``n_pixel`` can be freely defined. Based on the time the laser spends in each line, the duration per pixel (the laser is constantly scanning) needs to be calculated. Here, there are two options: 1) either the total time from the beginning of each new line (line start) to the beginning of the next line is considered as a line or 2) the time between the line start and the line stop is considered as the time base to calculate the pixel duration. In the first case, the back movement of the laser to the line start can be visualized in the image. In the later case, only the *valid* region where the laser scans over the sample is visualized. For most applications the later approach is useful. To understand the microscope laser scanner the former approach is more useful. Above, ``line_duration_valid`` is the time the laser spends in every of the lines in a valid region and ``line_duration_total`` is the total time the laser spends in a line including the rewind to the line beginning. Above, ``n_pixel`` is the freely defined number of pixels per line and ``pixel_duration`` is the duration of every pixel. With the number of frames ``n_frames``, the number of pixels ``n_pixel``, and the number of lines ``n_lines_per_frame`` it is clear how much the memory for an image needs to be can be allocated and with the defined number of pixels per line the duration for the pixel can be calculated for all the lines of the frames. With these numbers an image for a certain set of detector channels ``detector_channels`` can be calculated. Below this is by the function ``make_image``. .. GENERATED FROM PYTHON SOURCE LINES 69-133 .. code-block:: Python @nb.jit(nopython=True) def make_image( c, m, t, e, n_frames, n_lines, pixel_duration, channels, frame_marker=4, line_start=1, line_stop=2, n_pixel=None, tac_coarsening=32, n_tac_max=2**15): if n_pixel is None: n_pixel = n_lines # assume squared image n_tac = int(n_tac_max // tac_coarsening) image = np.zeros( (int(n_frames), int(n_lines), int(n_pixel), int(n_tac)), dtype=np.uint16 ) # iterate through all photons in a line and add to image frame = -1 current_line = 0 time_start_line = 0 invalid_range = True mask_invalid = True for i in range(len(c)): ci, mi, ti, ei = c[i], m[i], t[i], e[i] if ei == 1: # marker if ci == frame_marker: frame += 1 current_line = 0 if frame < n_frames: continue else: break elif ci == line_start: time_start_line = ti invalid_range = False continue elif ci == line_stop: invalid_range = True current_line += 1 continue elif ei == 0: # photon in_channels = False for v in channels: if v == ci: in_channels = True if in_channels and (not invalid_range or not mask_invalid): pixel = int((ti - time_start_line) // pixel_duration[current_line]) if pixel < n_pixel: tac = mi // tac_coarsening image[frame, current_line, pixel, tac] += 1 return image events = tttrlib.TTTR('../../tttr-data/imaging/pq/ht3/pq_ht3_clsm.ht3', 1) e = events.get_event_type() c = events.get_routing_channel() t = events.get_macro_times() m = events.get_micro_times() .. GENERATED FROM PYTHON SOURCE LINES 134-155 Before creating an image the channel numbers of the frame and the line markers need to be determined. For the example that is shown above the frame, line start, and line stop markers are 4, 1, and 2, respectively. Next, the TTTR data needs to be loaded into memory, the number of frames, and the number of lines need to be determined in order to allocate memory for the image. In CLSM the number of pixels per line can be arbitrarily defined, as the laser beam is continuously displaced and the fluorescence of the sample is continuously recorded. Hence, the main experimental determinants of the image size in memory are the number of frames and the number of line scans per frame. Usually, the number of line scans per frame is constant within a TTTR file. The number of frames can be determined by counting extracting and counting the number of frame markers as shown below. .. note:: The channel number of the frame makers (here 4) depends on the experimental setup. Moreover, some setup configurations use "photons" event types to record special events. Different microscopes may use different markers. For common microscopes such as the Leica SP5 and Leica SP8 ready-to-use image processing routines are provided. .. GENERATED FROM PYTHON SOURCE LINES 155-177 .. code-block:: Python frame_marker_list = find_marker(c, e, 4) line_start_marker_list = find_marker(c, e, 1) line_stop_marker_list = find_marker(c, e, 2) n_frames = len(frame_marker_list) - 1 # 41 n_line_start_marker = len(line_start_marker_list) # 10246 n_lines = n_line_start_marker // n_frames # 256 line_duration_valid = t[line_stop_marker_list] - t[line_start_marker_list] line_duration_total = t[line_start_marker_list[1:]] - t[line_start_marker_list[0:-1]] n_pixel = 256 pixel_duration = line_duration_valid // n_pixel line_duration_valid = t[line_stop_marker_list] - t[line_start_marker_list] image = make_image( c, m, t, e, n_frames, n_lines, pixel_duration, channels=np.array([0, 1]), tac_coarsening=256 ) .. GENERATED FROM PYTHON SOURCE LINES 178-181 In the example function ``make_image`` the an 3D array is created that contains in every pixel a histogram of the micro times. An histogram of the micro time can be displayed by the code shown below: .. GENERATED FROM PYTHON SOURCE LINES 181-186 .. code-block:: Python fig, ax = p.subplots(1, 2) ax[0].imshow(image.sum(axis=(0, 3)), cmap='inferno') ax[1].semilogy(image.sum(axis=(0, 1))[128]) p.show() .. image-sg:: /auto_examples/flim/images/sphx_glr_plot_tutorial_python_001.png :alt: plot tutorial python :srcset: /auto_examples/flim/images/sphx_glr_plot_tutorial_python_001.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 5.085 seconds) .. _sphx_glr_download_auto_examples_flim_plot_tutorial_python.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_tutorial_python.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_tutorial_python.py ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_