You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

EEGLab pop_spectopo()报错:非整数段数问题求助

问题:处理8-10号受试者时Spectopo报错“非整数epochs”

我在从顶叶电极提取alpha功率,代码在1-7号受试者上运行正常,但处理8、9、10号受试者时触发如下报错。

主处理代码

baseDir  = 'my local folder'; %directory where everything is based

resultsFileName = [baseDir 'trialResultsAllSubjects.xlsx'];
allResultsTable = readmatrix(resultsFileName,'Basic',false); %load the matrix of trial timings

eeglabDir = 'C:\Users\hype2\Documents\MATLAB\eeglab2022.0'; %eeglab directory as we need some functions
addpath(genpath(eeglabDir)); %add folders and subfolders to path

channelsToPlot = [21 22 25 26 27]; 
channelsLabel = {'cp1', 'cp2', 'p3', 'pz', 'p4'}; % these are the electrodes names
doFig = 0; %if set to 1 then a time frequency figure for every trial will be plotted, this is 4s before and after the midpoint

for thisSubjectNum = 8 %the number of subject whose EEG is currently loaded
    subjectString = sprintf('%02d',thisSubjectNum);
    eegFileName  = [baseDir subjectString '\pilot_' subjectString '_filt_postICA_lowfilt_reref.set'];
    [ALLEEG, EEG, CURRENTSET, ALLCOM] = eeglab;
    EEG = pop_loadset('filename', eegFileName);
    [ALLEEG, EEG, CURRENTSET] = eeg_store(ALLEEG, EEG, 0);
    trialList = find(allResultsTable(:,1)==thisSubjectNum);
    for trialNum = trialList'

        timeMid = allResultsTable(trialNum,13);
        if doFig
            figure;
            out = pop_newtimef( EEG, 1, 26, [timeMid*1000-4000 timeMid*1000+4000], 0);
        end
        out = pop_spectopo( EEG, 1, [timeMid*1000-1000 timeMid*1000+1000],'EEG','freqrange',[2 35],'freqs',5);
        %get the average pwoer in the 8:12 Hz frequency band for the channels
        %of interest
        bandMus = mean(out(channelsToPlot,8:12),2);
        %copy to correct columns of results table
        allResultsTable(trialNum,7:11) = bandMus;
    end
end
%now save
writematrix(allResultsTable,'.\trialResultsAllSubjectsComplete.xlsx')

报错信息

Error using spectopo
Spectopo: non-integer number of epochs

Error in pop_spectopo (line 331)
                eval(com)

Error in getTfrFromMidPoint (line 32)
        out = pop_spectopo( EEG, 1, [timeMid*1000-1000 timeMid*1000+1000],'EEG','freqrange',[2 35],'freqs',5)

报错触发代码(来自spectopo函数)

epochs = round(size(data,2)/frames);
if frames*epochs ~= size(data,2)
   error('Spectopo: non-integer number of epochs');
end

时间同步表生成脚本(依赖代码)

%in the table (when loaded as a matrix):
%for each trial to understand which time point to extract from the EEG we
%need to find the mid point of the ball movement to the corner.
%this is 
% column 3 is overall trial number (including practice trials and isntruction screens)
% 4 is block number: 
% (1= practice1 instruction, 2= practice 1, 3= practice 2 instruction,...
% 4 = practice 2, 5 = block 1 instruction, 6= block 1, 7 = block 2
% instruction, 8 = block 2, 9 =  block 3 instruction, 10 = block 3)
%ballstart time is column 9
%estimated mid time (light off) is 10
%actual mid time is 11
%estimated end time is 12
%actual end time is 13 (but need to subtract 5s from this)
%15  is which corner the ball goes to (1=BL,2=BR,3=FL,4=FR)
%16 is movement speed of the ball.
eegVRTimeLags = [213.6 545.64 929.2 nan 469.87 200.84 320 710.8 573.6 774.5]; %when VR was time 0, EEG was this time in seconds

%in results table columns will be 
%1 = subjectnum
%2 = trialnumber (only real trials so 1:96)
%3 = end point of the ball (1=BL,2=BR,3=FL,4=FR)
%4 = speed of the ball (0.5, 1, 1.5 or 2)
%5 = the estiamted time length of ball travel
%6 = the actual time length of ball travel
%7 =  alpha power at 'cp1'
%8 =  'cp2' 
%9 = 'p3'
%10 = 'pz'
%11 = 'p4'
%12 = time point in eeg to extract in VR headset time
%13 = time point in EEG time to extract in EEG time

%TODO need to think about how to save synchronsiation information
trialsToAnalyse = [12:43 45:76 78:109]; %this refers to row numbers in the data matrix loaded here
numSubjects = 10;
allResultsTable = nan(numSubjects*96,11);
 trialCounter = 1;
for subjectNum = 1:numSubjects


    thisSubFolder = ['C:\Users\ASUS\OneDrive - Goldsmiths College\Attachments\DISSERTATION\' sprintf('%02d',subjectNum),'\'];
    trialData = readmatrix([thisSubFolder 'trial_results.csv']);
   tempTrialCounter = 1;
    for trialNum = trialsToAnalyse
    allResultsTable(trialCounter,1) = subjectNum;
    allResultsTable(trialCounter,2) = trialCounter;
    allResultsTable(trialCounter,3) = trialData(trialNum,15);
    allResultsTable(trialCounter,4) = trialData(trialNum,16);
    allResultsTable(trialCounter,5) = trialData(trialNum,12)-trialData(trialNum,10);
    allResultsTable(trialCounter,6) = trialData(trialNum,13)-trialData(trialNum,11)-5;

    allResultsTable(trialCounter,12) = (trialData(trialNum,13)+trialData(trialNum,11)-5)/2;
    allResultsTable(trialCounter,13) = allResultsTable(trialCounter,12)+eegVRTimeLags(subjectNum);   
    tempTrialCounter = tempTrialCounter +1;
    trialCounter = trialCounter+1;
    end
    

end

writematrix(allResultsTable,'.\trialResultsAllSubjects.xlsx')

原因分析

  1. frames的含义:在EEGLAB的spectopo函数中,frames指的是频谱分析时使用的单段数据采样点数(即FFT窗口长度)。函数会把指定时间窗口内的EEG数据拆分成若干个frames长度的段(epochs)计算频谱,若总采样点数不是frames的整数倍,就会触发报错。
  2. 为何仅8-10号受试者报错:时间同步脚本里的eegVRTimeLags中,8-10号的时间偏移是710.8、573.6、774.5这类带小数的数值,计算出的timeMid(EEG时间,对应allResultsTable第13列)是带小数的浮点数。转换为毫秒后,对应的采样点范围不是整数边界,导致提取的总采样点数无法被frames整除。而1-7号的时间偏移计算后,timeMid对应的毫秒范围刚好匹配整数采样点,因此不会触发报错。

解决方案

方案1:用采样点索引替代毫秒时间范围(推荐)

直接基于EEG采样率计算窗口的起始/结束采样点,确保提取的总点数是整数且能被frames整除:

% 在循环内添加这段代码,替换原pop_spectopo调用
timeMid = allResultsTable(trialNum,13);
srate = EEG.srate; % 获取当前EEG数据的采样率
% 计算1秒前到1秒后的采样点索引(取整确保是整数)
win_start = round((timeMid - 1) * srate);
win_end = round((timeMid + 1) * srate);
% 调整窗口长度,确保是frames的整数倍(frames通常为256,或用round(srate * 0.25)取默认值)
frames = 256; 
win_length = win_end - win_start + 1;
adjusted_win_length = floor(win_length / frames) * frames;
win_end = win_start + adjusted_win_length - 1;
% 调用pop_spectopo,传入采样点范围
out = pop_spectopo(EEG, 1, [win_start win_end], 'EEG', 'freqrange', [2 35], 'freqs', 5);

方案2:对毫秒时间取整

如果不想调整采样点,可直接对timeMid*1000取整,确保时间窗口是整数毫秒,减少采样点计算误差:

timeMid = allResultsTable(trialNum,13);
timeMid_ms = round(timeMid * 1000); % 取整为整数毫秒
out = pop_spectopo( EEG, 1, [timeMid_ms-1000 timeMid_ms+1000],'EEG','freqrange',[2 35],'freqs',5);

方案3:检查EEG数据一致性

确认8-10号受试者的EEG数据采样率与1-7号是否一致:加载EEG后查看EEG.srate,若采样率不同,需统一处理或调整时间转换逻辑。


内容的提问来源于stack exchange,提问作者DerKeller

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 11:24:54