Пиковое обнаружение измеренного сигнала

Мы используем карту сбора данных для считывания показаний с устройства, которое увеличивает его сигнал до пика, а затем возвращается к первоначальному значению. Чтобы найти пиковое значение, мы в настоящее время находим массив для наивысшего показания и используем индекс для определения времени пикового значения, которое используется в наших расчетах.

Это хорошо работает, если самое высокое значение – это пик, который мы ищем, но если устройство работает неправильно, мы можем видеть второй пик, который может быть выше начального пика. Мы берем 10 показаний в секунду из 16 устройств за 90 секунд.

Мои первоначальные мысли состоят в том, чтобы циклически проверять показания, чтобы увидеть, является ли предыдущая и следующая точки меньше текущего, чтобы найти пик и построить массив пиков. Возможно, мы должны смотреть на среднее количество точек с обеих сторон текущей позиции, чтобы обеспечить шум в системе. Это лучший способ продолжить или есть лучшие методы?


Мы используем LabVIEW, и я проверил форумы LAVA, и есть ряд интересных примеров. Это часть нашего тестового программного обеспечения, и мы стараемся избегать использования слишком большого количества нестандартных библиотек VI, поэтому я надеялся получить обратную связь о процессе / алгоритмах, а не о конкретном коде.

Вы можете попытаться усреднить сигнал, то есть для каждой точки, усреднить значение с близкими 3 или более точками. Если шум близок, то даже это может не помочь.

Я понимаю, что это язык не агностик, но, предполагая, что вы используете LabView, есть много предварительно упакованных ВП для обработки сигналов, которые поставляются с LabView, которые вы можете использовать для сглаживания и уменьшения шума. Форумы NI – отличное место, чтобы получить более специализированную помощь в этом.

Существует множество и множество classических методов обнаружения пиков, любой из которых может работать. Вам нужно будет увидеть, что, в частности, ограничивает качество ваших данных. Вот основные описания:

  1. Между любыми двумя точками ваших данных (x(0), y(0)) и (x(n), y(n)) , добавьте y(i + 1) - y(i) для 0 <= i < n и назовите это T («перемещение») и установите R («подъем») на y(n) - y(0) + k для подходящего малого k . T/R > 1 указывает на пик. Это работает нормально, если большое перемещение из-за шума маловероятно или если шум распределяется симметрично вокруг формы базовой кривой. Для вашего приложения принимайте самый ранний пик со счетом выше заданного порога или анализируйте кривую проезда на значения высоты для более интересных свойств.

  2. Используйте сопоставленные фильтры для оценки сходства с стандартной формой пика (по сути, используйте нормализованный точечный продукт против некоторой формы, чтобы получить косинус-метрику сходства)

  3. Deconvolve против стандартной формы пика и проверьте высокие значения (хотя я часто считаю, что 2 менее чувствителен к шуму для простого инструментального выхода).

  4. Разделите данные и проверьте триплеты одинаково разнесенных точек, где x0 < x1 < x2, y1 > 0.5 * (y0 + y2) или проверьте евклидовы расстояния следующим образом: D((x0, y0), (x1, y1)) + D((x1, y1), (x2, y2)) > D((x0, y0),(x2, y2)) , которая опирается на неравенство треугольника. Использование простых коэффициентов снова предоставит вам механизм подсчета очков.

  5. Примените к вашим данным очень простую модель с двумя гауссовыми смесями (например, Numericical Recipes имеет хороший готовый кусок кода). Возьмите более ранний пик. Это будет иметь дело с перекрывающимися пиками.

  6. Найдите наилучшее совпадение данных с простой кривой Гаусса, Коши, Пуассона или того, что у вас есть. Оцените эту кривую в широком диапазоне и вычтите ее из копии данных, отметив ее пиковое местоположение. Повторение. Возьмите самый ранний пик, параметры модели которого (возможно, стандартное отклонение, но некоторые приложения могут заботиться о эксцессах или других особенностях) соответствуют некоторому критерию. Следите за отсутствием артефактов, когда пики вычитаются из данных. Лучшее совпадение может быть определено путем подсчета очков, предложенного в № 2 выше.

Я сделал то, что вы делали раньше: находите пики в данных последовательности ДНК, находите пики в производных, оцененные по измеренным кривым, и находите пики на гистограммах.

Я призываю вас внимательно следить за надлежащей базой. Фильтрация Винера или другая фильтрация или простой анализ гистограммы часто являются легким способом базового уровня при наличии шума.

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

Эта проблема была изучена более подробно.

В classах TSpectrum* ROOT (инструмент анализа физики ядер / частиц) имеется набор очень современных реализаций. Код работает в одно-трехмерных данных.

Исходный код ROOT доступен, поэтому вы можете захватить эту реализацию, если хотите.

Из документации classа TSpectrum :

Алгоритмы, используемые в этом classе, опубликованы в следующих ссылках:

[1] M.Morhac et al .: методы устранения фона для многомерных совпадений спектров гамма-излучения. Ядерные приборы и методы в физических исследованиях 401 (1997) 113-132.

[2] M.Morhac et al .: эффективная одно- и двумерная деконволюция золота и ее применение к разложению спектров гамма-лучей. Ядерные приборы и методы в физических исследованиях A 401 (1997) 385-408.

[3] M.Morhac et al .: Идентификация пиков в многомерных совпадениях гамма-спектров. Ядерные приборы и методы в физике исследований A 443 (2000), 108-125.

Документы связаны с документацией classов для тех из вас, у кого нет онлайн-подписки NIM.


Короткий вариант того, что делается, состоит в том, что гистограмма сглаживается для устранения шума, а затем локальные максимумы обнаруживаются грубой силой в сплющенной гистограмме.

Я хотел бы внести в этот stream алгоритм, который я разработал сам :

Он основан на принципе дисперсии : если новый datapoint является заданным x числом стандартных отклонений от некоторого движущегося среднего, алгоритм сигнализирует (также называемый z-балл ). Алгоритм очень надежный, поскольку он создает отдельное движущееся среднее и отклонение, так что сигналы не повреждают порог. Таким образом, будущие сигналы идентифицируются с примерно одинаковой точностью, независимо от количества предыдущих сигналов. Алгоритм принимает 3 входа: lag = the lag of the moving window , threshold = the z-score at which the algorithm signals и influence = the influence (between 0 and 1) of new signals on the mean and standard deviation . Например, lag в 5 будет использовать последние 5 наблюдений для сглаживания данных. threshold в 3.5 будет сигнализировать, если значение datapoint равно 3,5 стандартным отклонениям от движущегося среднего. И influence 0,5 дает сигналы о половине влияния, которое имеют обычные данные. Аналогично, influence 0 полностью игнорирует сигналы для пересчета нового порога: поэтому влияние 0 является наиболее надежным вариантом.

Он работает следующим образом:

ПСЕВДОКОД

 # Let y be a vector of timeseries data of at least length lag+2 # Let mean() be a function that calculates the mean # Let std() be a function that calculates the standard deviaton # Let absolute() be the absolute value function # Settings (the ones below are examples: choose what is best for your data) set lag to 5; # lag 5 for the smoothing functions set threshold to 3.5; # 3.5 standard deviations for signal set influence to 0.5; # between 0 and 1, where 1 is normal influence, 0.5 is half # Initialise variables set signals to vector 0,...,0 of length of y; # Initialise signal results set filteredY to y(1,...,lag) # Initialise filtered series set avgFilter to null; # Initialise average filter set stdFilter to null; # Initialise std. filter set avgFilter(lag) to mean(y(1,...,lag)); # Initialise first value set stdFilter(lag) to std(y(1,...,lag)); # Initialise first value for i=lag+1,...,t do if absolute(y(i) - avgFilter(i-1)) > threshold*stdFilter(i-1) then if y(i) > avgFilter(i-1) set signals(i) to +1; # Positive signal else set signals(i) to -1; # Negative signal end # Adjust the filters set filteredY(i) to influence*y(i) + (1-influence)*filteredY(i-1); set avgFilter(i) to mean(filteredY(i-lag,i),lag); set stdFilter(i) to std(filteredY(i-lag,i),lag); else set signals(i) to 0; # No signal # Adjust the filters set filteredY(i) to y(i); set avgFilter(i) to mean(filteredY(i-lag,i),lag); set stdFilter(i) to std(filteredY(i-lag,i),lag); end end 

демонстрация

Демонстрация надежного алгоритма порогового значения

> Оригинальный ответ

Этот метод в основном состоит из книги Дэвида Марра «Видение»,

Гауссов размывает ваш сигнал с ожидаемой шириной ваших пиков. это избавляет от шумовых шипов, и ваши фазовые данные не повреждены.

Тогда обнаружение края (LOG сделает)

Тогда ваши края были краями функций (например, пиками). посмотрите между краями для пиков, сортируйте пики по размеру, и все готово.

Я использовал вариации на этом, и они работают очень хорошо.

Я думаю, вы хотите переквалифицировать свой сигнал с ожидаемым, образцовым сигналом. Но это было так долго, так как я изучал обработку сигналов, и даже тогда я не обращал особого внимания.

Вы можете применить стандартное отклонение к своей логике и обратить внимание на пики над x%.

Я не очень разбираюсь в инструментах, поэтому это может быть совершенно непрактично, но опять же это может быть полезным другим направлением. Если вы знаете, как показания могут потерпеть неудачу, и существует определенный интервал между пиками при таких сбоях, почему бы не сделать gradleиентный спуск на каждом интервале. Если спуск возвращает вас в область, которую вы искали раньше, вы можете отказаться от нее. В зависимости от формы отбираемой поверхности это также может помочь вам найти пики быстрее, чем поиск.

Существует ли качественное различие между желаемым пиком и нежелательным вторым пиком? Если оба пика являются «острыми», то есть короткими по длительности – при просмотре сигнала в частотной области (делая FFT) вы получите энергию в большинстве диапазонов. Но если «хороший» пик надежно имеет энергию, присутствующую на частотах, не существующих в «плохом» пике, или наоборот, вы можете автоматически их дифференцировать таким образом.

  • Роллинг-срединный алгоритм в C
  • как обеспечить функцию подкачки для моего classа?
  • Эффективный выбор набора случайных элементов из связанного списка
  • как найти самую длинную палиндромную подпоследовательность?
  • Как работают тригонометрические функции?
  • Самый элегантный способ генерации простых чисел
  • Интервью: Объединение двух отсортированных односвязных списков
  • Найти дубликаты в массиве
  • Правильность алгоритма Сакамото, чтобы найти день недели
  • Побитовое и вместо оператора модуля
  • Случайный взвешенный выбор
  • Давайте будем гением компьютера.