Calculating the photon emittance rate from a single fluorophore

In this notebook we will develop code to estimate the number of collected photons from a single fluorophore for a given exposure time. To do this we will need to find the following parameters for our given experiment:

  • Illumination photon flux at sample
  • Fluorophore properties (absorption cross-section, \(\sigma\): quantum yield, Q)
  • Imaging optics properties

We will tackle each of these in turn.

Illumination Photon Flux.

Here we will estimate the photon flux on the fluorophore. It is important to note that the absorption cross-section is a strong function of wavelength and that whatever illumination source is also strongly wavelength dependent. Do we will have to make several assumptions:

  • Illumination power is not a strong function of wavelength.
  • Absorbtion is also relatively constant.

Alright, lets start with some code.

import numpy as np
import pylab as plt
from math import log,asin, pi, cos

Now lets calculate the photon flux at the sample.

For now, we are going to use the order of magnitude approximation from this pdf.

This source gives that the photon flux is about \(3.6 x 10^{20} \frac{photons}{cm^2}\)

# To Do: Need to make this more explicit. Probably several code blocks corresponding to broadband and led.
power_out = .22 # Watts, conservative estimate of total output of Spectra X in infrared.

illumination_area = 12.0e-6 # cm^2   This is a function of the viewing area and Numerical aperture of objective.

illumination_flux = power_out/illumination_area

wavelength = 380.0e-9 # meters

h = 6.626e-34  # Jouls/s

c = 2.998e8 # m/s

photon_flux = illumination_flux*wavelength/h/c

#photon_flux = 3.6e20        # photons / cm^2

print(photon_flux,'Photon Flux')
(3.5070501104099917e+22, 'Photon Flux')

Emitter Properties

You will generally see three different parameters describing a fluorophores performance:

  • Quantum Yield
  • Absorbtion Cross Section
  • Extinction Coefficient

The first, quantum yield, describes the percentage of photons absorbed that are actually emitted.

The second two are different methods of determining what percentage of a photon flux is absorbed by the molecule. The two are related by the expression

\[\sigma_{cs} = \frac{\epsilon_{coeff}}{N_{avag}}\]

where $ N_{avag} $ is Avagadro’s number. This is from the handbook of single molecule biophysics.

Great, now the number of photons emitted is given by the product of the photon flux, the absorbtion cross section, and the quantum yield.

\[B_{emit} = I_{p flux} Q \sigma_{cs}\]

First things first, we need to set some coefficients:

quantum_yield = 0.38       #This is a pretty good quantum yield

#ab_cross_section = 3.0e-16 #  cm^2

# Fluoroscene
quantum_yield = 0.8

ext_coeff = 76900.0 #1 / (M cm^2)

#ext_coeff = 45000.0   # 1/ M cm = 1000 cm^2 / mol
ab_cross_section = 1000.0 * log(10)* ext_coeff / 6.0221413e+23

print(ab_cross_section/100000000.0/100000000.0, 'Absorbtion cross section in Angstrom square')
(2.940296230698574e-32, 'Absorbtion cross section in Angstrom square')

Now we calculate the output photon flux

photon_emitt = photon_flux*ab_cross_section*quantum_yield # photons / second

print(photon_emitt,'photons/s')
(8249412.976407614, 'photons/s')

Collection Optics

Here we need to calculate what percentage of photons are actually making it to the camera.

The first thing we are going to consider is the solid angle that is actually collected.

\[\Omega = 2\pi \left (1 - \cos {\theta} \right)\,\mathrm{sr}\]

where theta is given by the numerical aperture (NA) of the objective.

\[\mathrm{NA} = n \sin \theta\]

Great, now we just need to calculate the percent collected.

NA = 1.4             # Numerical Aperture of Objective
n_medium = 1.52      # Index of Refraction of immersion media

theta = asin(NA/n_medium)

percent_collected = 2.0*pi*(1.0 - cos(theta) )/ (4.0*pi)

print(percent_collected , '%')
(0.30528093964541125, '%')

Finally, we need to take into account all of the photons lost in the transit to the camera. They can be lost for any number of reasons:

  • Fluorophore emittance is broad spectrum and gets cut off by long pass filter (70 - 90%)
  • Dichromatic mirrors are not perfectly efficient (80 - 85%)
  • Slight reflectance off each optical surface in optical train. (90 - 99%)
  • Poorly alligned optics
  • and so on...
percent_collected *= 0.85  # Dichroic Mirror
percent_collected *= 0.80  # Long pass filter
percent_collected *= 0.98**5  # Assume several surfaces, but that they have antireflective coating.

print(percent_collected,'%')
(0.18764585734425032, '%')

Great, now we just need to multiply this by the emitted photons and we have our photon rate.

photons_seen = photon_emitt*percent_collected  # photons/s

print(photons_seen, 'photons/s')
(1547968.1705447906, 'photons/s')

Image Quality

How does this affect image quality? Well, now that we know how many photons are reaching the camera we can start looking at how many are recorded per frame. This is affected, largely, by two parameters:

  • Exposure Time
  • Quantum Efficiency

Exposure time is fairly straight forward, how long a time does each pixel collect light. Quantum efficiency is the percentage chance that each photon will actually be recorded.

t_expose = 0.05
quantum_efficiency = 0.7

photons_counted = photons_seen*t_expose

print(photons_counted,'Photons counted')
(77398.40852723953, 'Photons counted')

Alternatively, we can specify a photon count and find the exposure time

photons_desired = 1000
quantum_efficiency = 0.7

t_expose = photons_desired/photons_seen

print(t_expose, 'Expsoure time needed to get num_photons')
(0.00064600811504287, 'Expsoure time needed to get num_photons')