До запитання про стандартизацію методів спектрального аналізу кардіоінтервалограм.

Воробйов К.П. к.м.н, (лікар і дослідник), м.Луганськ, hbovorobyov@mail. ru
  Паламарчук Є.А. к.т.н, доцент, м. Вінниця, evgen@pallar.com.ua

Преамбула

    Оцінка варіабельності серцевого ритму (ВСР) відноситься до нових діагностичним технологій, яка почала активно виходити за межі наукових лабораторій. Цей метод діагностики стає одним із найважливіших клінічних тестів в оцінці, як вегетативного статусу організму, так і інтегральних характеристик функціонального стану.

    Будь якому досліднику хочеться мати перевірений і точний інструмент. В  клінічній практиці, при діагностиці різних станів необхідна повторюваність результатів функціональних досліджень і їх чітка метрологічна характеристика.

    Автор цих рядків дослідник і практик, який вже багато років використовує ВСР як інструмент пізнання, і як діагностичний тест оцінки ефективності гіпербаричної оксигенації.

    Спілкування з колегами, вивчення літератури і власні досліжнення вказують, що при аналізі ВСР існує багато невирішених проблем. Одна із них, найбільш важлива, – це стандартизація математичного апарату обчислення спектральних характеристик кардіоінтервалограм. З цього приводу розробники відповідного російського стандарту пишуть: «Порівнювальність записів і результатів аналізу ВСР означає можливість співставлення даних, що одержуються в різних клініках і установах за допомогою різних типів апаратури та різних програмних засобів» [Методические рекомендації по аналізу вариабельности сердечного ритма при использовании разных электрокардиографических систем (анализ “коротких” записей), с.20]

    Нас не задовільняють існуючі алгоритми обчислення спектральних характеристик. Більш правильно - пропонувати в стандартах не алгоритм високої математичної абстракції, а конкретну блок-схему обчислення спектру ВСР. Можливо, що це образить математичних гуру, але лікарю зараз необхідно мати інструмент і детальну інструкцію до нього.

    Ми розуміємо, що такий детальний опис математичного апарату спектрального аналізу може нанести важку втрату виробникам програм. Але й очевидно, що це не є головною бідою.Шановні пани комерсанти заробляють на самих приладах і зручних програмних оболонках. Окрім того, зараз головним стає не обрахування певного показника, а правильне і наочне його представлення в співставленні з іншими характеристиками. А це і є основна задача комерційних програмних комплексів аналізу ВСР.

    Прозорість математичного апарату оцінки спектру ВСР дозволить дослідникам говорити однією мовою, а лікарям - користуватись стандартними діагностичними методиками.

    Ці ідеі зріли вже давно і одержали більш чіткі риси під час першої Міжнародної конференції із ВСР (інститут геронтології, Київ, 26-27 жовтня) при обговоренні існуючих стандартів ВСР. Разом з математиком, одним із авторів діагностичних програм CARDIO (http://www.pallar.com.ua ) Є.А.Паламарчуком, ми в протягом майже місяця вели інтенсивну переписку по електронній пошті. Я вчився деяким поняттям математики, а Євген Анатолійович з подивом пізнавав, що деякі банальні математичні істини можуть бути не зрозумілі лікарю. Ми протестували різні програми, і в кожній із них знайшли помилки, покращили їх, створили тестові програми для перевірки існуючих. Перший етап цієї роботи завершено, і ми хочемо поділитись її результатами.

Загальні поняття спектрального аналізу кардіоінтервалограми

    Ми не будемо тут говорити про ази спектрального аналізу кардіоінтервалограм – це не є нашою метою. Цю інформацію ви зможете одержати із самих різних джерел, в яких немає обмежень. Поговоримо про інше. Про те, як зрозуміти, про що саме в цих джерелах не пишеться.

    Спектральний аналіз сигналів достатньо складна математична технологія, в якій поки що не поставлені всі крапки. Матеріали з цього запитання в керівництвах з аналізу ВСР пишуть частіше за все математики. Багато які речі для них є очевидними, а для лікаря - ні. Ми постараємось розібратись зі смисловим змістом спектру ВСР, розглянемо логіку одержання розрахункових характеристик спектру з масиву характеристик кардіоінтервалограми.

    Частіше за все для спектрального аналізу ВСР використовується швидке перетворювання Фур'є – так зване ШПФ. Після обробки кардіоінтервалограми утворюється ряд спектральних характеристик, які складаються із двох характеристик: частоти та амплітудного значення спектру. Частота вимірюється в герцах, амплітуда в мілісекундах. Ряд значень спектру дискретні, тобто вони характеризують не всі притаманні сигналу частоти, а тільки  вибірково, що є слабким місцем методу ШПФ.

    У відповідності із відомим міжнародним стандартом прийнята угода про розділення всього вимірюваного діапазону на чотири: ультранизькі частоти ( -<0,003 Гц), дуже низькі частоти (0,003-0,04 Гц), низькі частоти ( 0,04-0,15 Гц) і високі частоти ( 0,15-0,4 Гц). Клінічне значення визначено, в основному, для останніх трьох . Про них ми і поговоримо.

Типовий графік спектрального аналізу кардіоінтервалограми представлений на рис.1

Рис.1 Типове представлення спектрального аналізу кардіоінтервалограми.

    На цьому графіку трьома кольорами позначені характеристики відповідних трьох досліджуваних діапазонів. Для надання кривим графіку зручного для сприйняття вигляду іноді використовують спеціальні види обробки, які дозволяють одержати більш згладжений вигляд огинаючої кривої графіку.

Наші дослідження

    Від даного представлення спектру кардіоінтервалограми ми перейдемо до другого. У всіх наступних прикладах на малюнках будуть представлені : вихідна кардіоінтервалограма, її статистичні характеристики (максимальне, мінімальне, середнє значення і дисперсія ряду кардіоінтервалів), характеристики потужностей спектральних діапазонів і перші два десятки спектральних складових (номер спектрального діапазону, значення потужності в цьому діапазоні в мс 2 і частота, якій відповідає даний діапазон).

    Для подальшого опису спектру ми використовували спеціальну тестову вибірку кардіоінтервалів із заздалегідь відомими характеристиками, які вказані в підписах до малюнків. Тестові вибірки аналізувались спеціальною програмою, яку підготував автор для даних досліджень. Тестові вибірки створювались програмою, яку підготував Є.А.Паламарчук.

На рис. 2 наведені результати обробки тестової вибірки.

Рис.2 тестовий приклад з параметрами: VLF=600ms2 (f=0,015);LF=600 ms2 (f=0,06); LF=800 ms2 (f=0,2); При об'ємі вибірки 128 число дискретних складових спектру в діапазоні 0,003-0,4 = 51.

    На цьому графіку наведені результати аналізу вибірки із 128 кардіоінтервалів. Перше значення спектру відповідає 0,0077 Гц, що не дозволяє коректно охарактеризувати весь діапазон .

    Це значення відповідає часу, протягом якого виконувався набір цих 128 кардіоінтервалів (1/77Гц = 128,7 сек). Для характеристики більш низької частоти необхідні більш тривалі вибірки. На наступному графіку представлений аналіз тієї ж тестової кардіоінтервалограми, але із в два рази більшим за об'ємом вибірки (рис.3), тобто - 256 кардіоінтервалів.

image006.gif (16382 bytes)
Рис.3 Тестовий приклад з параметрами: VLF=600ms2 (f=0,015);LF=600 ms2 (f=0,06); LF=800 ms2 (f=0,2); При об'ємі вибірки 256 число дискретних складових спектру в діапазоні 0,003-0,4 = 102

    В цьому прикладі найбільш низька вимірювана частота дорівнює 0,0039 Гц, що відповідає (1/0,0039) 256,4 секундам тривалості досліджуваної вибірки. Але цього також недостатньо, щоб коректно охарактеризувати весь наднизькочастотний діапазон.

Обговорення результату дослідження

    Тепер давайте на останніх двох прикладах розберемось в деяких питаннях.

    Як рахується потужність відповідного діапазону?

    В міжнародному стандарті передбачений аналіз, п'ятихвилинних вибірок. П'ять хвилин складають 300 секунд. Тоді мінімальна аналізуєма частота буде відповідати 0,00333Гц. Тобто фактично відповідає самому низькочастотному діапазону (0,003 Гц). Передбачено, що досліджувані частоти збільшуються з інтервалом 0,003 Гц. Для того щоб досягнути частоти 0,4 Гц необхідно (0,4-0,003)/0,003=133 спектральних складових. Потужність відповідного частотного діапазону характеризується простою сумою спектральних потужностей в діапазонах з інтервалом 0,003 Гц. Це є класикою.

    Тепер давайте подивимось, як порушення класики впливає на точність результатів.

    В другому випадку (рис.3) ми проаналізували майже повну, таку, що відповідає класиці, вибірку. В першому (рис .2) - явно недостатню вибірку. Ми також зробили ще три експерименти на тестовій кардіоінтервалограмі з вибірками 64, 32 і 16 кардіоінтервалів. Порівняємо результати вимірювання спектральних потужностей в трьох діапазонах (табл.1)

Таблиця 1. Результати спектрального аналізу тестової кардіоінтервалограми при різних об'ємах вибірки

Вибірка (тривалість) Загальна потужність(мс2) VLF(мс2) LF (мс2) HF (мс2) К-сть частотних інтерв.
    600 600 800  
256 (256,4 сек) 1983 615 579 788 102
128 (128,7 сек) 1919 588 553 777 51
64 (64,1 сек) 1976 590 587 798 25
32 (32 сек) 1425 55 612 757 13
16 (16 сек) 1021 0 340 680 6

    Ми бачимо, що одержані результати дуже близькі до правильних. Похибка наших вимірювань склала до 8%, навіть для вибірки об'ємом 64 кардіоінтервали. Останній факт можна пояснити тим, що в діапазоні VLF була задана основна частота 0,015 Гц, що відповідає 66 секундам, тобто достатньо близько до першого частотному інтервалу вимірювання при тривалості вибірки 64 секунди.

    Відомо, що при аналізі коротких вибірок частіше за все вивчають характеристики LF і HF, тому для їх вивчення згідно нашим експериментам достатньо вибірок  довших кардіоінтервалівза 25 секунд (0,04 Гц). Правда треба врахувати, що із зменшенням тривалості вибірки падає точність вимірювання, через те, що кількість частотних інтервалів, на яких вимірюються потужності спектру зменшується пропорційно зниженню часу вибірки (див. лівий стовпчик табл.1). Продемонструємо останнє зауваження на реальній кардіоінтервалограмі (рис.4 і 5).

image008.gif (18026 bytes)
Рис.4 Реальна кардіоінтервалограма у хворої з початковими проявами діабетичної полінейропатії. При об'ємі вибірки 512 число дискретних діапазонів спектру від 0,003-0,4 = 178

 

Рис.5 Реальна кардіоінтервалограма у хворої з початковими  диабетическпроявленнямиой полінейропатії. При об'ємі вибірки 128 число дискретних діапазонів спектру від 0,003-0,4 = 46.

    Число дискретних вимірювань потужності спектру зменшилось в 4 рази при зменшенні об'єму вибірки з 512 до 128, але значення потужностей залишились спіставимими (треба врахувати, що в реальному запису наступні після 128 кардіоінтервали не можуть повторювати попередні, тобто відповідно не можуть співпадати потужності спектрів).

Заключення

    Ці експерименти були проведені за консультативної підтримки математика. Вони показують, що метод ШПФ дозволяє одержувати задовільні повторювані результати. Ми також сподіваємось, що для деяких колег читання цього матеріалу дозволить розібратись в деяких тонкощах розрахунку спектральних характеристик ВСР.

    Метод ШПФ по відношенню до кардіоінтервалограми має визначену математичну некоректність, через те, що по вісі абсцис відкладається не час, а номер наступного кардіоінтервалу. Цю неточність намагаються усунути російські колеги, пропонуючи в своєму проекті стандарту аналізувати методом ШПФ не кардіоінтервалограму, а функцію – x(t), яка будується із вхідної кардіоінтервалограми методом сплайнової кубичної інтерполяції, при квантуванні функції x(t) з інтервалом 250 мс.

    Ми пробували цей метод, але не одержали вагомих переваг. Можливо, що ми дещо зробили неточно. Але поки що автори стандарту не запропонували відповідні тестові приклади і більш детальний алгоритм розрахунку спектра, а тому й важко віддати перевагу їх вибору. А інструмент для лікаря-дослідника  вже необхідний сьогодні. Тому ми поки що пропонуємо використовувати перевірений метод, який дозволяє одержувати повторювані результати.

    Для того, щоб метод був дійсно повторюваним, необхідний детальний алгоритм розрахунку характеристик спектру. Цю роботу ласкаво погодився виконати фахівець, якому і надаємо слово.

Костянтин Петрович Воройьов, к.м.н., завідуючий відділенням гіпербаричної оксигенації Луганської обласної клінічної лікарні. 

29.11.02


    Дякую. Отже, давайте спочатку розберемось із часовим нормуванням. Запитання полягає в тому, скільки точок (або скільки RR-інтервалів) має бути у вхідному масиві? Виявляється, що не має значення їх кількість, а важливо, який вони утворюють час обстеження.

    В сумі цей час має складати біля 333 секунд. І ось чому. Нижня границя спектру VLF складає 0.003 Hz. Розрахуємо час зняття ритмограми, який буде відповідати цій частоті. Для цього поділимо 1sec/0.003 Hz = 333 sec. Треба відмітити також, що при спектральному перетворюванні  0.003 Hz ще буде відповідати і різниці частот між сусідніми точками спектру, тобто визначати частотний інтервал.

    Також відмітимо фізичну сторону першого елементу спектра. Це - постійна складова (нульова частота). Вона несе в собі інформацію про середню ЧСС за обстежуваний період. В розрахунках спектральної потужності її враховувати не треба.

    Тепер розрахуємо, якою має бути мінімальна розмірність спектрального масиву. В загальному випадку вона залежить від кількості серцевих скорочень за 333 сек, а також алгоритму, що був застосований в спектральному перетворенні.

    Наприклад, якщо вважати, що частота серцевих скорочень не буде перевищувати 90 скор.\хв., одержимо, що за 333 секунди відбудеться біля 333/60*90=~500 серцевих скорочень. Таким чином, розмірність вхідного масиву з RR-інтервалами має бути не менше за 500 точок.

    Будемо використовувати алгоритм швидкого перетворення Фур`є (ШПФ). Його особливістю є не тільки малий час перетворення, але й те, що розмірність спектрального масиву має бути кратним до ступені двійки. Таким чином, найближча розмірність в даному випадку складе 512 точок. Але при ШПФ завжди формується симетричний спектр, що складається з двох однакових, але дзеркально розташованих відносно нульової частоти спектральних частин. А це означає, що розмірність частотного масиву повинна бути в два рази більше за обрану. Тобто в цьому випадку - не менше 1024 точки. Невиконання цієї умови призведе до катастрофічного спотворення результатів перетворення.

    Тепер, враховуючи, що частотний інтервал ми розрахували і він склав 0.003 Hz, можна легко визначити, де в спектральному масиві будуть знаходитись частотні області VLF, LF і HF. Так,  для VLF-частинини спектру (0.003-0.04 Hz) їм будуть відповідати точки від  2 (Увага! В нашому випадку елементи нумеруються від 1. Тому 1-ій точці буде відповідати нульова частота) до 13-ой спектрального масиву, для LF-частини спектру (0.04-0.15 Hz) -від 14 до 50 точки, а HF-частини (0.15-0.4 Hz) - від 15 до 133 точки. Маючи розрахований спектр і границі частотних зон (VLF, LF, HF), легко одержати спектральні потужності, підрахувавши суму квадратів амплітуд спектральних складових в кожній частотній області (див. текст програмного модулю spec_lib нижче).

    Другою проблемою є амплітудне нормування обраного спектрального перетворення.Справа в тому, що різні алгоритми обчислення спектрів можуть давати різні передаточні коефіцієнти (не слід плутати із співвідношенням спектральних складових). Говорячи інакше, необхідно мати деякий коефіцієнт перетворення, який би забезпечував відповідність розрахованої потужності спектру з її реальним значенням.

    Спадає думка, що потрібен якийсь повірочний засіб-еталон, за допомогою якого можна було би верифікувати використовуємий алгоритм спектрального перетворення. Така задача вирішується досить просто, якщо врахувати, що спектральні перетворення - це лінійні перетворення, де справедливий принцип суперпозиції. Він означає, що будь-який сигнал може бути представлений певним набором гармонік (спектральних складових) або, навпаки, ці гармоніки однозначно можуть бути перетворені у вхідний сигнал.

    З цього витікає, що в якості повірочного засобу можна використовувати звичайні гармонічні коливання із заданою частотою та амплітудою (або їх суміш). Тобто, оцифрувавши, наприклад, гармоніку із заданою амплітудою і частотою 0.01 Hz, ми одержимо в спектрі спектральну складову з частотою 0.01 Hz і потужністю, що буде відповідати амплітуді вхідного сигналу. Всі останні гармоніки спектру будуть дорівнювати нулю. Середньоквадратична потужність (P) синусоїдального сигналу (гамоніки) пов`язана з її амплітудою (A) як P=A*A/2.

    Таким чином, якщо ми, оцифруємо дві гармоніки, то в спектральній області з`являться дві незалежні одна від однієї складові. Кожна із них буде мати потужність, що визначатиметься середньоквадратичною потужністю свого гармонічного сигналу. Із наведеного слідує, що ми маємо право оперувати сумою будь-якого числа гармонік, де кожна із них визначає свою спектральну складову. На справді будь-яка ритмограма і є набір гармонік із своїми амплітудами і фазовими співвідношеннями.

    Таким чином, використовуючи всього три гармоніки, що розташовані в частотних областях VLF, LF і HF, ми маємо можливість моделювати будь-які види частотних співвідношень для перевірки адекватності обраного матапарату частотного перетворення.

    Тут знаходиться програма-імітатор (HRV_Imit.EXE), яка реалізує наведений вище принцип. Вона дозволяє сформувати оцифровану суміш з трьох будь-яких частот в діапазоні (VLF..HF) з довільними потужностями і вивести її в текстовий файл export.rg. Структура файлу відповідає російському стандарту формату запису ритмограм, де в кожному рядку записується по одному RR-інтервалу в ASCII-форматі.Такий файл легко імпортувати в будь-яку верифікуєму програму.

    Нижче наведений код програмного модуля, що реалізує обробку ритмограми з використанням алгоритму ШПФ. Цей модуль використаний в тестовій програмі (checkFFT.EXE), яка обробляє текстовий файл ритмограми з описаною вище структурою. Програму checkFFT.EXE можна також використовувати для обробки ритмограм, експортованих з інших програм.

    Наприкінці хочу додати, що якщо говорити про використання медичного програмного забезпечення в наукових дослідженнях і практиці, то його обов'язковим критерієм має бути можливість імпорту\експорту біосигналів в загальнодоступному форматі (див. вище). Тільки тоді буде забезпечено можливість контролю правильності функціонування матапарату тих чи інших програм, а також проведення таких,  що можуть бути спіставлені, наукових і медичних досліджень на програмних продуктах від різних виробників.

Паламарчук Євген Анатолійович, к.т.н., доцент кафедри економічної кібернетики, Вінницького державного аграрного університету, директор фірми ПАЛЛАР Лтд.

 

 

 

unit spec_lib;

{модуль, що реалізує перетворення ритмограми на спектр і обрахунок спектральних параметрів }
{написаний мовою Turbo Pascal, (c) Borland Inc.}
{використаний в тестовій програмі CheckFFT.EXE}
{(c) Pallar Ltd. Co, 2002, +(380)-432-523-041 http://www.pallar.com.ua }

INTERFACE

uses dos;

const EndArray = 1024; {розмiрнiсть спектрального масиву}
      SpecWid : longint = 333000; {ширина спектру в мiлiсекундах}

var ECGArray : array [1..EndArray] of integer; {масив із вхідним сигналом}

VLF            : longint; {спектр. потужнiсть в дiапiзонi 0.003-0.04 Hz}
LF              : longint; {спектр. потужнiсть в дiапiзонi 0.04-0.15 Hz}
HF              : longint; {спектр. потужнiсть в дiапiзонi 0.15-0.4 Hz}
nuLF           : longint; {спектр. потужнiсть в дiапiзонi 0.04-0.15 Hz Normal Units}
nuHF           : longint; {спектр. потужнiсть в дiапiзонi 0.15-0.4 Hz Normal Units}
TotalSpecPower : longint; {загальна спектральна потужнiсть}
LF_HF          : real; {..........}
FL              : real; {частота з НЧ максимумом спектр. потужностi}
N333           : longint; {к-сть точок до iнтервалу 333 сек вiд початку запису}

type
   Complex = record re, im : real end;
   MyArr = Array [ 1..EndArray ] of Complex;

procedure FFT( A : pointer; Dimension,Expon : word; mode : shortint);
procedure GetRRSpectrum;
procedure ResizeRRArray;

IMPLEMENTATION

procedure FFT( A : pointer; Dimension,Expon : word; mode : shortint);
{--------------- процедура швидкого перетворення ФУР'Є ---------------------}
{
A - показчик на масив типу:

type complex=record re, im : real end;
myarr = array [ 1..Dimension ] of complex;

розмiрностi Dimension 2**Expon;
mode = 1 - пряме перетворювання
мode = -1 - зворотнє перетворювання
}


  function exp( expon : byte) : integer;
  begin exp := 2 shl (expon-1); end;

label 1;

var s,i,j,k,l,L1,L2,HalfOfDimension         : integer;
    SwapWord1,SwapWord2,v1,v2,w1,w2,my_phi  : real;
    A_                                       : ^myarr;
begin

A_ := A;

HalfOfDimension := Dimension div 2; j:=1;

for i:=1 to Dimension-1 do begin

if i >= j then k:=HalfOfDimension
else begin
  SwapWord1 := A_^[j].re;
  A_^[j].re := A_^[i].re;
  A_^[i].re := SwapWord1;

  SwapWord1 := A_^[j].im;
  A_^[j].im := A_^[i].im;
  A_^[i].im := SwapWord1;
  k := HalfOfDimension;
end; {if }

1: if (k<j) then begin
  j := j-k;
  k := k shr 1;
  goto 1;
end else j := j+k;

end; {do}


for l :=1 to Expon do begin
  L1:=exp(l);
  L2:=L1 shr 1;
  v1:=1;
  v2:=0;
  my_phi:=pi/L2;
  w1:=cos(my_phi);
  w2:=mode*sin(my_phi);

  for j:=1 to L2 do
   begin
    i:=j;
    repeat
      s:=i+L2;
      SwapWord1:=A_^[s].re*v1-v2*A_^[s].im;
      SwapWord2:=A_^[s].re*v2+v1*A_^[s].im;
      A_^[s].re:=A_^[i].re-SwapWord1;
      A_^[s].im:=A_^[i].im-SwapWord2;
      A_^[i].re:=A_^[i].re+SwapWord1;
      A_^[i].im:=A_^[i].im+SwapWord2;
      i:=i+L1;
    until i >= Dimension;
    SwapWord1:=v1*w1-w2*v2;
    v2:=v1*w2+v2*w1;
    v1:=SwapWord1;
  end; {for}
end; {for}
end; { FFT }


procedure GetRRSpectrum;
var p                         : pointer;
    SSS                       : ^myarr;
    NumPoint, i, k, repeater : integer;
    x, TimeStep, AmplMasht   : real;
begin

Mark(p); New(SSS);

for NumPoint := 1 to EndArray do begin
{перенесення сигналу з масиву ECGArray в масив SSS}
   SSS^[ NumPoint ].re := ECGArray[NumPoint];
{дійсна частина}
   SSS^[ NumPoint ].im := 0;                  
{неявна частина}
end; {for}

FFT(@SSS^, 1024, 10, 1);
{перетворення Фур`є, одержання спектру сигналу}

{2 - коефiцiент втрати потужностi через симетричнiсть спектру }

{обрахунок спектральної потужності, що пропорційний сумі квадратів дійсної і неявної частин спектру}
AmplMasht := sqrt(2);
for NumPoint := 1 to EndArray do
   SSS^[ NumPoint ].re :=
       (sqr(SSS^[ NumPoint ].re/EndArray)+sqr(SSS^[ NumPoint ].im/EndArray))/AmplMasht;

{максимум спектру}
AmplMasht := SSS^[ 1 ].re;
for NumPoint := 2 to EndArray do if SSS^[ NumPoint ].re > AmplMasht then

AmplMasht := SSS^[ NumPoint ].re;
{нормування до 30000}
AmplMasht := AmplMasht + 0.0001;
AmplMasht := 30000/AmplMasht;
for NumPoint := 1 to EndArray do
    SSS^[ NumPoint ].re := SSS^[ NumPoint ].re * AmplMasht;

for NumPoint := 1 to EndArray do
ECGArray[NumPoint] := round(SSS^[ NumPoint ].re);

Release(p);

repeater := 333 div SpecWid; if repeater = 0 then repeater := 1;

ECGArray[1] := 0;
{обнулимо нульову частоту}

{приводимо масштаб спектру до амплiтуди вхiдного сигналу.
Через те, що спектр симетричний, то i масштабний коеф. визначається
як 1024/2,
експозицiя складає 333 сек. =>
верхня частота складає : - 1.5375 Hz
крок по частотi - 0.003 Hz }

TimeStep := 3.0/AmplMasht; {3.0 ms per point}
x := 0;
{0.003-0.04 Hz}
for NumPoint := 2 to 13 do x := x + abs(ECGArray[NumPoint]);
VLF := trunc( x * TimeStep ); {потужність VHF-частинини спектру}

{0.04-0.15 Hz}
x := 0;
for NumPoint := 14 to 50 do x := x + abs(ECGArray[NumPoint]);
LF := trunc( x * TimeStep ); {потужність LF-частинини спектру}

FL := 15; x := abs(ECGArray[NumPoint]);
for NumPoint := 14 to 50 do
if x < abs(ECGArray[NumPoint]) then begin
   x := abs(ECGArray[NumPoint]);
   FL := NumPoint;
end;
FL := (FL-1)*0.003;
{частота з НЧ максимумом спектр. потужностi }

{0.15-0.4 Hz}
x := 0;
for NumPoint := 51 to 133 do x := x + abs(ECGArray[NumPoint]); {!!! 51..133}
HF := trunc( x * TimeStep ); {потужність HF-частини спектру}

TotalSpecPower := VLF + LF + HF;
{Загальна потужність}

if TotalSpecPower <> 0 then begin
  nuLF := trunc(LF/(TotalSpecPower-VLF)*100);
{нормалізовані потужності}
  nuHF := trunc(HF/(TotalSpecPower-VLF)*100);
end else begin
nuLF := 0;
nuHF := 0;
end;

if HF > 0 then LF_HF := LF/HF
{співвідношення LF/HF}
else LF_HF := 0;

end; {getrrspectrum}

procedure ResizeRRArray;
{процедура часового нормування (розтягування\стискування)первинного масиву до розмiрностi 1024}
{приведемо RR-масив до 333 точок, має вiдповiдати 5-хвилиннiй експозицiї}
var HorScaleStep : real;
i, CurrPoint : integer;
TmpArray : array [1..EndArray] of integer;
begin
HorScaleStep := EndArray / N333;

for i := 1 to EndArray do TmpArray[ i] := 0;

TmpArray[ 1] := ECGArray[1];
for i := 2 to N333 do begin
   CurrPoint := trunc(i*HorScaleStep);
   if CurrPoint <= EndArray then TmpArray[CurrPoint] := ECGArray[i];
end;

{заповнимо пропущенi елементи масиву ...}
i := 0;
repeat
   inc(i);
until ( i >= EndArray ) or (TmpArray[i] <> 0);
TmpArray[1] := TmpArray[i];

for i := 2 to EndArray do
   if TmpArray[i] = 0 then TmpArray[i] := TmpArray[i-1];

{приберемо постiйну складову}
CurrPoint := TmpArray[1];
for i := 2 to EndArray do if CurrPoint > TmpArray[i] then CurrPoint := TmpArray[i];
for i := 1 to EndArray do begin
   ECGArray[i] := TmpArray[i] - CurrPoint;
end;

end; {resizeRRarray}

END.