Differential imaging of averaged iSCAT frames
The static version of tutorial documents are presented here. Once the installation of PiSCAT on your local computer is completed, the dynamic version of the tutorial files can be found in the local PiSCAT directory located at "./Tutorials/JupyterFiles/"
. Based on the number of available CPU cores for parallel
processing, this tutorial needs 5-7 GB of computer memory (RAM) to run.
Previously on PiSCAT tutorials…
In the last tutorial, we set up the PiSCAT modules and downloaded a demo iSCAT video, did some basic checks on the acquisition process, suppressed the temporal instability of the laser light and used some of the basic data visualization tools provided in PiSCAT for inspection of the iSCAT videos.
# Only to ignore warnings
import warnings
warnings.filterwarnings('ignore')
# Setting up the path to the PiSCAT modules
import os
import sys
current_path = os.path.abspath(os.path.join('..'))
dir_path = os.path.dirname(current_path)
module_path = os.path.join(dir_path)
if module_path not in sys.path:
sys.path.append(module_path)
# Downloading a control video for this tutorial
from piscat.InputOutput import download_tutorial_data
download_tutorial_data('control_video')
# Examining the status line in a loaded/downloaded video and removing the line
from piscat.InputOutput import reading_videos
from piscat.Visualization import JupyterDisplay
from piscat.InputOutput import read_status_line
from piscat.Preproccessing import normalization
import numpy as np
data_path = os.path.join(dir_path, 'Tutorials', 'Demo data')#The path to the demo data
df_video = reading_videos.DirectoryType(data_path, type_file='raw').return_df()
paths = df_video['Directory'].tolist()
video_names = df_video['File'].tolist()
demo_video_path = os.path.join(paths[0], video_names[0])#Selecting the first entry in the list
video = reading_videos.video_reader(file_name=demo_video_path, type='binary', img_width=128, img_height=128,
image_type=np.dtype('<u2'), s_frame=0, e_frame=-1)#Loading the video
status_ = read_status_line.StatusLine(video)#Reading the status line
video_remove_status, status_information = status_.find_status_line()#Examining the status line & removing it
# Normalization of the power in the frames of a video
video_pn, _ = normalization.Normalization(video=video_remove_status).power_normalized()
The directory with the name Demo data already exists in the following path: PiSCAT\Tutorials
The data file named Control already exists in the following path: PiSCAT\Tutorials\Demo data
---Status line detected in column---
start power_normalized without parallel loop---> Done
Frame averaging to boost SNR of imaged proteins, followed by visualization of their signal via differential imaging
The illumination profile and imaged speckles from the coverglass are among static features in iSCAT videos that can be removed by subtracting two subsequent frames to obtain a differential image which will only include dynamic features. As illustrated in the figure below, these features are new relative to the reference image, which is itself being rolled forward. In the calculation of the differential image, each image is the mean frame of a batch of $L$ number of camera frames. In order to apply Differential Rolling Average (DRA), an object of the class Differential_Rolling_Average is instantiated and deployed [1].
#For Jupyter notebooks only:
%matplotlib inline
from piscat.BackgroundCorrection import DifferentialRollingAverage
DRA_PN = DifferentialRollingAverage(video=video_pn, batchSize=200)
RVideo_PN, _ = DRA_PN.differential_rolling(FFT_flag=False)
from piscat.Visualization import JupyterDisplay
JupyterDisplay(RVideo_PN, median_filter_flag=False, color='gray', imgSizex=5, imgSizey=5, IntSlider_width='500px', step=100)
--- start DRA ---
100%|#########| 4598/4598 [00:00<?, ?it/s]
The effect of power normalization on the detection limit
Here, we perform a quantitative analysis of the influence of the laser power fluctuations on the sensitivity limit of our scheme using noise_floor class to analyze the noise floor trend as a function of the batch size [1].
# Noise floor analysis
from piscat.BackgroundCorrection import NoiseFloor
l_range = list(range(30, 200, 30))
noise_floor_DRA = NoiseFloor(video_remove_status, list_range=l_range)
noise_floor_DRA_pn = NoiseFloor(video_pn, list_range=l_range)
import matplotlib.pyplot as plt
%matplotlib inline
plt.plot(l_range, noise_floor_DRA.mean, label='DRA')
plt.plot(l_range, noise_floor_DRA_pn.mean, label='PN+DRA')
plt.ticklabel_format(style='sci', axis='y', scilimits=(0, 0))
plt.xlabel("Batch size", fontsize=18)
plt.ylabel("Noise floor", fontsize=18)
plt.legend()
plt.show()
We see about 10% improvement in our detection limit with performing power normalization on top of the differential rolling averaging with the best results obtained when the batch size corresponds to 120 frames.