Skip to main content

High-Throughput Single-cell Imaging analysis.

Project description

PyPIPython build Issues
Downloads GNU License

logo

htsimaging

High-Throughput Single-cell Imaging analysis.
Examples · Explore the API

image

Examples

📈 Single-cell protein abundance and its normalization
📈 Single-cell protein abundance by marker localization
🖼️ Visualization of the images.
📈 Quantitative analysis of endocytosis.
📈 Single-particle tracking (SPT).
📈 Calculating the recovery rate from a bleach-chase data

Installation

pip install htsimaging              # with basic dependencies  

With additional dependencies as required:

pip install htsimaging[spt]         # for the analysis of the Single-Particle Tracking e.g. endocytosis.

How to cite?

  1. Using BibTeX:
@software{Dandage_htsimaging,
  title   = {htsimaging: High-Throughput Single-cell Imaging analysis in python},
  author  = {Dandage, Rohan},
  year    = {2023},
  url     = {https://zenodo.org/doi/10.5281/zenodo.3697134},
  version = {v1.0.5},
  note    = {The URL is a DOI link to the permanent archive of the software.},
}
  1. DOI link: DOI, or

  2. Using citation information from CITATION.CFF file.

Future directions, for which contributions are welcome

  • Command-line usage.

Similar projects

API

module htsimaging.bleach_chase

module htsimaging.bleach_chase.stat

Statistical analysis of the bleach-chase


function exp1

exp1(x, lag, amplitude, rate)

One-term exponential.

Parameters:

  • x (list): input vector
  • lag (float): lag
  • amplitude (float): amplitude
  • rate (float): rate

function get_scores

get_scores(df: DataFrame)  DataFrame

Calculate the rates other parameters.

Parameters:

  • df (pd.DataFrame): input table.

Returns:

  • pd.DataFrame: table with the parameters.

module htsimaging.endocytosis.io

Processing of the paths of input images to create configurations and metadata.


function make_project_cfg

make_project_cfg(
    prjd: str,
    output_dir_path: str,
    bright_fn_marker: str = None,
    segmented_fn_marker: str = None,
    magnification: int = None,
    image_ext: str = 'tif',
    cores: int = 1,
    test: bool = False,
    force: bool = False
)  dict

Make the confguration for the analysis run.

Args:

  • prjd (str): path to the directory with the images.
  • output_dir_path (str): output directory path.
  • bright_fn_marker (type): marker in the path of the bright field images.
  • segmented_fn_marker (type): marker in the path of the segmented images.
  • cores (int, optional): number of cores. Defaults to 1.
  • test (bool, optional): test-mode. Defaults to False.
  • force (bool, optional): over-write theoutputs. Defaults to False.

Returns:

  • dict: metadata

Notes:

Infer the magnification from the filenames: if 'T1C1' in cfg['bright_fn_marker']: cfg['magnification']=150 elif cfg['bright_fn_marker']=='_t': cfg['magnification']=100


function make_cell_cfg

make_cell_cfg(
    cfg: dict,
    frames: list,
    cells: list,
    trial: str,
    celli: int,
    cellbox: list,
    params_get_signal_summary_by_roi: dict = {'xy_center': None, 'width': 20, 'fun_summary_frame': 'min', 'fun_summary_frames': 'median'},
    filterby_centroid: bool = False,
    scale_signal_cytoplasm: float = 1.5,
    test: bool = False,
    force: bool = False
)  dict

Make the configuration for an individual cell.

Args:

  • cfg (dict): metadata.
  • frames (list): list of frames.
  • cells (list): list of cells.
  • trial (str): trial name.
  • celli (int): index of the cell.
  • cellbox (list): bounding box of the cell
  • params_get_signal_summary_by_roi (dict, optional): parameters for the aggregation of the values at the ROI. Defaults to {'xy_center':None,'width':20, 'fun_summary_frame':'min', 'fun_summary_frames':'median' }.
  • test (bool, optional): test-mode. Defaults to False.
  • force (bool, optional): over-write the output. Defaults to False.

Returns:

  • dict: metadata

module htsimaging.endocytosis

module htsimaging.endocytosis.vid

To make the video of the timelapse images.


function make_gif

make_gif(
    cellcfg=None,
    frames: list = None,
    t_cor: DataFrame = None,
    img_bright=None,
    outd: str = None,
    particle2color: dict = None,
    test: bool = False,
    force: bool = False
)

Make a .gif file out of frames.

module htsimaging.endocytosis.viz

Visualizations.


function plot_properties_cell

plot_properties_cell(cellcfg, df2, cols_colorby, colx='x', coly='y')

Plot properties of the cell.

Args:

  • cellcfg (type): config of a cell.
  • df2 (type): input dataframe.
  • cols_colorby (type): columns to color by.
  • colx (str, optional): column with the x values. Defaults to 'x'.
  • coly (str, optional): column with the y values. Defaults to 'y'.

function image_locate_particles

image_locate_particles(
    df1: DataFrame,
    frame,
    img_region,
    annotate_particles: str = False,
    fig=None,
    ax: Axes = None
)  Axes

Plot image with particles.

Args:

  • df1 (pd.DataFrame): input dataframe.
  • frame (type): image frame.
  • img_region (type): regions in the image.
  • annotate_particles (str, optional): annotate the paticles or not. Defaults to False.
  • fig (type, optional): figure object. Defaults to None.
  • ax (plt.Axes, optional): subplot object. Defaults to None.

Returns:

  • plt.Axes: description

function image_trajectories

image_trajectories(
    dtraj: DataFrame,
    img_gfp=None,
    img_bright=None,
    label: bool = True,
    fig=None,
    ax: Axes = None
)  Axes

Plot trajectories.

Args:

  • dtraj (pd.DataFrame): input dataframe with the trajectories.
  • img_gfp (type, optional): channel image e.g. GFP. Defaults to None.
  • img_bright (type, optional): segmentation image e.g. bright field. Defaults to None.
  • label (bool, optional): label. Defaults to True.
  • fig (type, optional): figure object. Defaults to None.
  • ax (plt.Axes, optional): subplot object. Defaults to None.

Returns:

  • plt.Axes: subplot

function plot_moving_particles

plot_moving_particles(
    t_cor: DataFrame,
    img_bright=None,
    frame=None,
    framei: int = 0,
    particle2color=None,
    test: bool = False,
    outd: str = None
)

Plot moving particles.

Args:

  • t_cor (pd.DataFrame): input table
  • img_bright (type, optional): segmentation raw image (e.g. bright field). Defaults to None.
  • frame (type, optional): image frame. Defaults to None.
  • framei (int, optional): image frame index. Defaults to 0.
  • particle2color (type, optional): particle-wise colors. Defaults to None.
  • test (bool, optional): test-mode. Defaults to False.
  • outd (str, optional): path to the output directory. Defaults to None.

module htsimaging.lib.io

I/O


function read_image

read_image(imp: str)

Read image.

Args:

  • imp (str): path to the image file.

Returns: np.array

TODOs: For a tiff file: from skimage.external import tifffile


function arr2vid

arr2vid(
    arr_list: list,
    regions: list,
    kins_mean: float,
    vid_fh: str,
    xpixels: list,
    ypixels: list,
    dpi: int = 100
)  str

From array to video.

Args:

  • arr_list (list): list of frames.
  • regions (list): regions
  • kins_mean (float): kinetics
  • vid_fh (str): video file path
  • xpixels (list): pixels allong x-axis.
  • ypixels (list): pixels allong y-axis.
  • dpi (int, optional): DPI resolution. Defaults to 100.

Returns:

  • str: path of the video

function makevid

makevid(
    gfp_list_stb: list,
    brf_list_stb: list,
    cmap_gfp: str,
    cmap_brf: str,
    vid_fh: str,
    conditionn: int = None,
    interval=None,
    dpi: int = 300
)  str

Convert to a video.

Args:

  • gfp_list_stb (list): channel (e.g. GFP) images.
  • brf_list_stb (list): segmented (e.g. bright-field) images.
  • cmap_gfp (str): colormap for the channel images.
  • cmap_brf (str): colormap for the segmented images.
  • vid_fh (str): path to the video file.
  • conditionn (int, optional): title. Defaults to None.
  • interval (type, optional): inerval of the frames. Defaults to None.
  • dpi (int, optional): DPI resolution. Defaults to 300.

Returns:

  • str: path to the video file.

function nd2arr_list

nd2arr_list(nd_dh: str = None, nd_fns: list = [], nd_fh: str = None)  list

Raw image to list of arrays.

Args:

  • nd_dh (str, optional): directory containing raw files e.g. nd2. Defaults to None.
  • nd_fns (list, optional): file names. Defaults to [].
  • nd_fh (str, optional): path to the files. Defaults to None.

Returns:

  • list: list of arrays

function to_csv

to_csv(
    fh_xls='../test/test.xlsx',
    nd2_dh='/media/Transcend/20160219_000356_267',
    cores=16
)

Convert nd2 files to csv using parallel processing.

Args:

  • fh_xls (str, optional): metadata file. Defaults to '../test/test.xlsx'.
  • nd2_dh (str, optional): path of the directory containing raw images. Defaults to "/media/Transcend/20160219_000356_267".
  • cores (int, optional): number of cores. Defaults to 16.

module htsimaging.lib

module htsimaging.lib.stat

Statistics.


function power

power(x, A, B)

power law equation.


function power_residuals

power_residuals(p, y, x)

Deviations of data from fitted 4PL curve


function power_peval

power_peval(x, p)

Evaluated value at x with current parameters.


function line

line(x, m, C)

power law equation.


function line_residuals

line_residuals(p, y, x)

Deviations of data from fitted 4PL curve


function line_peval

line_peval(x, p)

Evaluated value at x with current parameters.


function logistic4

logistic4(x, A, B, C, D)

function logistic4_residuals

logistic4_residuals(p, y, x)

Deviations of data from fitted 4PL curve


function logistic4_peval

logistic4_peval(x, p)

Evaluated value at x with current parameters.


function logistic5

logistic5(x, A, B, C, D, E)

function logistic5_residuals

logistic5_residuals(p, y, x)

Deviations of data from fitted 4PL curve


function logistic5_peval

logistic5_peval(x, p)

Evaluated value at x with current parameters.


function fit_power

fit_power(x, y, p0: list = [0, 1], plot: bool = False)

Fit power law.

Args:

  • x (vector-like): x values.
  • y (vector-like): y values.
  • p0 (list, optional): starting parameters. Defaults to [0, 1].
  • plot (bool, optional): to plot or not. Defaults to False.

Returns:

  • tuple: outputs.

function fit_line

fit_line(x, y, p0: list = [0, 1], plot: bool = False)  tuple

Fit power law.

Args:

  • x (vector-like): x values.
  • y (vector-like): y values.
  • p0 (list, optional): description. Defaults to [0, 1].
  • plot (bool, optional): description. Defaults to False.

Returns:

  • tuple: outputs

function get_slope

get_slope(df: DataFrame, ds: Series)  float

Get slope for a section of the line.

Args:

  • df (pd.DataFrame): input dataframe.
  • ds (pd.Series): section of the line.

Returns:

  • float: slope.

function get_inflection_point

get_inflection_point(df: DataFrame, threshold_slope: float = 0.25)  DataFrame

Get inflation point.

Args:

  • df (pd.DataFrame): input dataframe.
  • threshold_slope (float, optional): threshold on the slope. Defaults to 0.25.

Returns:

  • pd.DataFrame: output dataframe.

module htsimaging.lib.utils

Utilities for the image processing.


function filterframe

filterframe(frame, cutoff: float = 0)

Filter a frame.

Args:

  • frame (array-like): input frame.
  • cutoff (float, optional): cutoff on the values. Defaults to 0.

Returns:

  • array-like: filtered frame.

function filterframes

filterframes(frames: list, cutoff: float = 0)  list

Filter the frames.

Args:

  • frames (list): list of frames.
  • cutoff (float, optional): threshold on the values. Defaults to 0.

Returns:

  • list: list of frames.

function get_data_by_regions

get_data_by_regions(
    regions: list,
    img=None,
    prop_type: str = 'area'
)  DataFrame

Get properties by regions.

Args:

  • regions (list): list of the regions.
  • img (array-like, optional): input image. Defaults to None.
  • prop_type (str, optional): property type. Defaults to 'area'.

Returns:

  • pd.DataFrame: output dataframe.

function filter_regions

filter_regions(
    regions: list,
    kind='labeled',
    img=None,
    prop_type: str = 'area',
    mn: float = 0,
    mx: float = 0,
    test: bool = False,
    plotp: str = None
)  list

Filter regions.

Args:

  • regions (np.array): segmented image, labeled with measure.label(regions).
  • img (array-like, optional): image. Defaults to None.
  • prop_type (str, optional): property type. Defaults to 'area'.
  • mn (float, optional): minimum value. Defaults to 0.
  • mx (float, optional): maximum value. Defaults to 0.
  • test (bool, optional): test the filtering. Defaults to False.
  • plotp (str, optional): path to the plot. Defaults to None.

Raises:

  • ValueError: img is required if filtering is t be done by the intensity.

Returns:

  • list: list of the filtered regions.

Notes:

Prefer regionprops_table which is new in sklean's version 0.16.


function smoothen

smoothen(img)

Smoothen the image.

Args:

  • img (array-like): input image.

Returns:

  • array-like: output image

function smoothenframes

smoothenframes(frames: list)  list

Smoothen the images.

Args:

  • frames (list): list of frames.

Returns:

  • list: list of frames.

function get_regions

get_regions(img)

Get regions.

Args:

  • img (array-like): input image

function raw2phasecorr

raw2phasecorr(arr_list: list, clip: int = 0)  list

Correct for the relative translative offset by phase correlation between images.

Args:

  • arr_list (list): list of frames.
  • clip (int, optional): threshold. Defaults to 0.

Returns:

  • list: output frames.

function phasecorr_with

phasecorr_with(imlist: list, imlist2: list = None, clip: int = 0)

Correct for the relative translative offset by phase correlation with a set of given images.

Args:

  • imlist (list): test images
  • imlist2 (list, optional): reference images. Defaults to None.
  • clip (int, optional): threshold. Defaults to 0.

Returns:

  • list: corrected images.

function imlistcropper

imlistcropper(imlist: list, loci: int)  list

Crop a list of images.

Args:

  • imlist (list): list of images.
  • loci (int): locations.

Returns:

  • list: output images.

function imclipper

imclipper(im_stb, clip: float)

Crop an image.

Args:

  • im_stb (array-like): input image
  • clip (float): threshold.

function get_cellprops

get_cellprops(
    regions,
    intensity_imgtype2img,
    properties=['area', 'bbox_area', 'convex_area', 'eccentricity', 'equivalent_diameter', 'euler_number', 'extent', 'filled_area', 'label', 'major_axis_length', 'max_intensity', 'mean_intensity', 'min_intensity', 'minor_axis_length', 'orientation', 'perimeter', 'solidity', 'centroid']
)  DataFrame

Get cell properties.

Args:

  • regions (list): regions in a frame.
  • intensity_imgtype2img (type): intensities.
  • properties (list, optional): description. Defaults to ['area', 'bbox_area', 'convex_area', 'eccentricity', 'equivalent_diameter', 'euler_number', 'extent', 'filled_area', 'label', 'major_axis_length', 'max_intensity', 'mean_intensity', 'min_intensity', 'minor_axis_length', 'orientation', 'perimeter', 'solidity', 'centroid', ].

Returns:

  • pd.DataFrame: output dataframe.

function get_signal_summary_by_roi

get_signal_summary_by_roi(
    cellframes: list,
    xy_center: tuple = None,
    width: int = 20,
    fun_summary_frame: str = 'min',
    fun_summary_frames: str = 'median'
)

Place of the roi in the image is defined by

Args:

  • cellframes (list): list of frames.
  • xy_center (tuple, optional): position of the center. Defaults to None.
  • width (int, optional): width of the ROI. Defaults to 20.
  • fun_summary_frame (str, optional): function to summarise a frame. Defaults to 'min'.
  • fun_summary_frames (str, optional): function to summarise a list of frames. Defaults to 'median'.

Returns: summary value

module htsimaging.segment

module htsimaging.segment.region

Processing of the segmented regions.


function segmentation2cells

segmentation2cells(
    imsegp: str,
    kind: str = 'yeast',
    fiterby_border_thickness: int = None,
    magnification: int = 100,
    test: bool = False,
    **kws: dict
)  list

Segment the image to the single cells.

Args:

  • imsegp (str): description
  • fiterby_border_thickness (int, optional): description. Defaults to 100.
  • magnification (int, optional): description. Defaults to 100.
  • plotp (str, optional): description. Defaults to None.

Returns:

  • list: description

Examples:

  1. Parameters: prop_type='area',mn=100,mx=8000 at 1.5X prop_type='area',mn=1500,mx=12000

function get_cellboxes

get_cellboxes(
    regions: list,
    cellbox_width: int = 150,
    test: bool = False
)  list

Get the bounding boxes of the cells.

Args:

  • regions (list): regions.
  • cellbox_width (int, optional): width of the bounding box of the cell. Defaults to 150.
  • test (bool, optional): test-mode. Defaults to False.

Returns:

  • list: list of the bounding boxes for cells.

function arr_list2regions

arr_list2regions(arr_list: list, time_increment: int)  tuple

Parameterized cell-segmentation for the time lapse images.

Args:

  • arr_list (list): frames of images.
  • time_increment (int): time interval.

Returns:

  • tuple: regions and table with intensities.

module htsimaging.spt.io

I/O


function to_frames

to_frames(input_path: str, channeli=None)

Convert to frames.

Args:

  • input_path (str): path to the raw data.

Returns:

  • list: list of frames.

function expt_dh2expt_info

expt_dh2expt_info(expt_dh: str)  DataFrame

Make configuration using the directory structure for an experiment.

Args:

  • expt_dh (str): str

Returns:

  • pd.DataFrame: output dataframe.

function createinfo

createinfo(expt_dh: str)  str

Create information file.

Args:

  • expt_dh (str): path to the directory containing the raw data.

Returns: path to the file containing the metadata.

module htsimaging.spt

module htsimaging.spt.stat

Statistical analysis of the single particle tracking.


function test_locate_particles

test_locate_particles(
    cellcfg: dict,
    params_locate: dict,
    frame=None,
    force: bool = False,
    test: bool = False
)  bool

Test locating of the particles.

Args:

  • cellcfg (dict): the cell level configuration.
  • params_locate (dict): parameters provided for the location.
  • frame (np.array, optional): image frame. Defaults to None.
  • force (bool, optional): over-write the outputs. Defaults to False.
  • test (bool, optional): test mode. Defaults to False.

Returns: bool


function to_msd

to_msd(
    frames: list,
    coff_intesity_perc: float = 75,
    diameter=11,
    cores: int = 4,
    test: bool = False
)  tuple

MSD from the nd file.

Args:

  • frames (str): 2D frames.

Returns:

  • tuple: outputs.

function trim_returns

trim_returns(df1: DataFrame)  DataFrame

Trim images.

Args:

  • df1 (pd.DataFrame): input dataframe.

Returns:

  • pd.DataFrame: output dataframe.

function fill_frame_jumps

fill_frame_jumps(df1: DataFrame, jump_length)  DataFrame

Fill the frame jumps.

Args:

  • df1 (pd.DataFrame): input dataframe.
  • jump_length (type): length of the jump.

Returns:

  • pd.DataFrame: output dataframe.

function cellcfg2distances

cellcfg2distances(
    cellcfg: dict,
    params: dict,
    subtract_drift: bool = False,
    test: bool = False,
    force: bool = False
)

Calculate distances from cell configuration.

Args:

  • cellcfg (dict): configuration
  • params (type, optional): parameters. Defaults to { 'locate':{'diameter':11, # round to odd number 'noise_size':1, 'separation':15, 'threshold':4000, 'preprocess':True, 'invert':False, 'max_iterations':50, 'percentile':0, 'engine':'numba', }, 'link_df':{ 'search_range':5, 'memory':1, 'link_strategy':'drop',}, 'filter_stubs':{'threshold':4}, 'get_distance_from_centroid':{'center':[75,75]}, }.
  • force (bool, optional): over-write the outputs. Defaults to False.

function apply_cellcfgp2distances

apply_cellcfgp2distances(cellcfgp: str)

Wrapper around cellcfg2distances for multiprocessing.

Args:

  • cellcfgp (str): path to the configuration file.

function get_distance_from_centroid

get_distance_from_centroid(df1: DataFrame, center: list = [75, 75])  DataFrame

Get distance from the centroid.

Args:

  • df1 (pd.DataFrame): input dataframe.
  • center (list, optional): center point. Defaults to [75,75].

Returns:

  • pd.DataFrame: output dataframe.

function distance_effective

distance_effective(particle, frame1, frame2, t_cor: DataFrame)  float

Effective distance between frames.

Args:

  • particle : particle
  • frame1 (np.array): a frame.
  • frame2 (np.array): another frame.
  • t_cor (pd.DataFrame): t_cor.

Returns:

  • float: distance

function get_distance_travelled

get_distance_travelled(t_cor: DataFrame)  DataFrame

Distance travelled.

Args:

  • t_cor (pd.DataFrame): input dataframe.

Returns:

  • pd.DataFrame: output dataframe.

module htsimaging.viz.colors

GLobally used variables.

Global Variables

  • r
  • g
  • b
  • cmap_gfp_list

module htsimaging.viz.image

Visualization of the images.


function image_background

image_background(
    img_region=None,
    img=None,
    cmap: str = 'binary_r',
    alpha=1,
    linewidths=1,
    colors='cyan',
    kws_region={},
    show_scalebar=None,
    scalebar_color: str = 'w',
    show_cbar: bool = True,
    test=False,
    ax=None,
    **kws_img
)  Axes

Plot the image, to be used as a background to the annotations.

Args:

  • img_region (type, optional): segmentation image. Defaults to None.
  • img (type, optional): image with intensity values. Defaults to None.
  • cmap (str, optional): colormap name. Defaults to 'binary_r'.
  • alpha (int, optional): transparency. Defaults to 1.
  • linewidths (int, optional): segmentation contour line width. Defaults to 1.
  • colors (str, optional): color of the segmentation line. Defaults to 'cyan'.
  • kws_region (dict, optional): parameters provided to the segmentation plot. Defaults to {}.
  • show_scalebar (type, optional): show scale bar. Defaults to None.
  • scalebar_color (str, optional): color of the scale bar. Defaults to 'w'.
  • show_cbar (bool, optional): show colorbar. Defaults to True.
  • test (bool, optional): test-mode. Defaults to False.
  • ax (type, optional): subplot object. Defaults to None.

Keyword Args: parameters provided to the plt.imshow.

Returns: plt.Axes


function annot_cells

annot_cells(label_image, show_boxes: bool = False, ax: Axes = None)  Axes

Annotate the cells on an image.

Args:

  • label_image (type): image with the labeled regions
  • show_boxes (bool, optional): show boxes around regions. Defaults to False.
  • ax (plt.Axes, optional): plt.Axes. Defaults to None.

Returns: plt.Axes


function image_regions_annotated

image_regions_annotated(
    img_region,
    img,
    show_boxes: bool = False,
    **kws_img
)  Axes

Image with the annotated regions. Usage: for QC of the segmentation.

Args:

  • img_region (type): image with segmentated regions.
  • img (type): image with intensity.
  • show_boxes (bool, optional): whether to show the boxes around the regions. Defaults to False.

Keyword Args: parameters provided to the image_background function.

Returns: plt.Axes

module htsimaging.viz

module htsimaging.viz.stat

Visualization of the statistics.


function dist_signal

dist_signal(
    img,
    threshold: float = None,
    label_threshold: float = None,
    params_axvline: dict = {'color': 'r', 'linestyle': 'dashed'},
    ax: Axes = None,
    **kws
)  Axes

Plot the distribution of intensity.

Args:

  • img (type): inpput image
  • threshold (float, optional): threshold applied. Defaults to None.
  • label_threshold (float, optional): label of the threshold. Defaults to None.
  • params_axvline (type, optional): parameters provided to the vertical line plot. Defaults to {'color':'r','linestyle':'dashed'}.
  • ax (plt.Axes, optional): subplot object. Defaults to None.

Keyword Args: parameters provided to the hist function.

Returns: plt.Axes


function plot_summary_stats

plot_summary_stats(input_paths: list, ax: Axes = None)  Axes

Plot summary stats for a set of images e.g. time-lapse images.

Args:

  • input_paths (list): list of paths of the images.
  • ax (plt.Axes, optional): subplot object. Defaults to None.

Returns: plt.Axes

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

htsimaging-1.0.5.tar.gz (59.7 kB view hashes)

Uploaded Source

Built Distribution

htsimaging-1.0.5-py3-none-any.whl (50.8 kB view hashes)

Uploaded Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page