Issue Accessing .vital File Data via vitaldb Python Library #707

Ary Serpa Neto (2025-04-20 14:55) · 21 view(s)

Hello,

I’m a researcher using Vital Recorder to collect intraoperative and ICU data. I have several `.vital` files that I'm reading with Vital Recorder 1.15.5, and I can view all waveform and numerical signals correctly within the software.

However, when using the `vitaldb` Python library (as described in your documentation), none of the tracks returned by `VitalFile(...).get_track_names()` or `VitalFile(...).trks` have `.samples()`, `.trend()`, or `.get_samples()` methods available.

I’ve tried using both R (via reticulate) and native Python, including the latest PyPI version of `vitaldb`, but none of them can extract the signal data programmatically.

The CLI tool `vital_recs.exe` works, but it only returns a single value per interval (e.g., `-m` for mean), and I specifically need to extract **mean, max, and min within each 30-second block** from the raw signal data — which requires access to the full-resolution signal series.

Could you please advise if there is an updated version of the `vitaldb` library that supports `.vital` files recorded with the current Vital Recorder version? Or is there another method to extract the complete underlying data from `.vital` files in batch?

Thank you very much for your help. Python code below:

import os
import pandas as pd
from vitaldb import VitalFile

input_dir = "input_vitals"
output_dir = "output_csv"

os.makedirs(output_dir, exist_ok=True)

def flatten_columns(df):
    df.columns = ['{}_{}'.format(col, stat) for col, stat in df.columns]
    return df

vital_files = [f for f in os.listdir(input_dir) if f.endswith(".vital")]

for file in vital_files:
    file_path = os.path.join(input_dir, file)
    try:
        vf = VitalFile(file_path)
        print(f"[INFO] Processando: {file}")
        
        track_names = vf.get_track_names()
        dataframes = []

        for name in track_names:
            try:
                trk = vf.find_track(name)
                samples = trk.get_samples()
                if len(samples) == 0:
                    continue
                times, values = zip(*samples)
                df = pd.DataFrame({'time': times, name: values})
                df['time'] = pd.to_datetime(df['time'], unit='s', origin=vf.dtstart)
                df.set_index('time', inplace=True)
                dataframes.append(df)
            except Exception as e:
                print(f"  [ERRO] {name}: {e}")
                continue

        if not dataframes:
            print(f"[AVISO] Nenhum sinal válido em: {file}")
            continue

        df_all = pd.concat(dataframes, axis=1)
        df_agg = df_all.resample('30S').agg(['mean', 'max', 'min'])
        df_agg = flatten_columns(df_agg)
        df_agg.index.name = 'moment'

        output_file = os.path.join(output_dir, file.replace(".vital", ".csv"))
        df_agg.to_csv(output_file)
        print(f"[SUCESSO] {file}")
    except Exception as e:
        print(f"[FALHA GERAL] {file} — {e}")