Source code for mesofield.datakit.sources.analysis.mesoscope

"""Mesoscope mean fluorescence analysis data source.

This module translates CSV exports from the mesoscope processing pipeline into
time-indexed :class:`~datakit.datamodel.LoadedStream` objects.  Each record in the
table represents one slice/ROI with derived dF/F traces, ready for alignment
against other experiment timelines.
"""

import pandas as pd
import numpy as np
from pathlib import Path

from mesofield.datakit.sources.register import LoadContext, TimeseriesSource, document


[docs] class MesoMeanSource(TimeseriesSource): """Load mean fluorescence CSV. The CSV is expected to contain at least ``Slice`` and ``Mean`` columns. """ tag = "meso" patterns = ("**/*_meso-mean-trace.csv",) camera_tag = "meso_metadata" # Bind to meso camera required_columns = ("Mean") assumed_frame_rate_hz = 50.0 normalization_baseline = "min"
[docs] def build_timeseries( self, path: Path, *, context: LoadContext | None = None, ) -> tuple[np.ndarray, pd.DataFrame, dict]: """Read a mesoscope CSV and return a normalized table.""" df = pd.read_csv(path) #remove the "Slice" column df = df.drop(columns=["Slice"]) n_frames = len(df) t = np.arange(n_frames, dtype=np.float64) / float(self.assumed_frame_rate_hz) df = df.copy() return t, df, {"source_file": str(path), "n_slices": len(df)}
[docs] class MesoDFFSource(TimeseriesSource): """Load DFF fluorescence CSV. The CSV is expected to contain at least ``Slice`` and ``Mean`` columns. """ tag = "meso" patterns = ("**/*_meso-collapse_first-trace.csv",) camera_tag = "meso_metadata" # Bind to meso camera required_columns = ("Mean") assumed_frame_rate_hz = 50.0 normalization_baseline = "min"
[docs] def build_timeseries( self, path: Path, *, context: LoadContext | None = None, ) -> tuple[np.ndarray, pd.DataFrame, dict]: """Read a mesoscope CSV and return a normalized table.""" df = pd.read_csv(path) #remove the "Slice" column df = df.drop(columns=["Slice"]) #rename the "Mean" column to "dF_F" df = df.rename(columns={"Mean": "dF_F"}) n_frames = len(df) t = np.arange(n_frames, dtype=np.float64) / float(self.assumed_frame_rate_hz) df = df.copy() return t, df, {"source_file": str(path), "n_slices": len(df)}