gtld2-diag-scripts/getMask.js

171 lines
9.4 KiB
JavaScript
Raw Normal View History

2024-05-08 04:30:31 +03:00
2024-06-20 02:36:01 +03:00
export function specModel(spec, tol, color, canvas) {
let result = {}; //результат
2024-06-11 08:41:46 +03:00
let model = spec.base; //массив точек базовой линии для построения упрощенной модели спектра
let imin = 0; //левая граница коридора
let imax = 0; //правая граница коридора
2024-05-16 10:04:16 +03:00
for (let i = 0; i < spec.peaks.length; i++) {
let freq = spec.peaks[i].freq; //получаем значение частоты гармоники из массива обнаруженных гармоник
let level = spec.peaks[i].level; //получаем значение уровня гармоники из массива обнаруженных гармоник
imin = Math.round((freq - freq * 0.5 * tol / 100) / spec.resolution);
imax = Math.round((freq + freq * 0.5 * tol / 100) / spec.resolution);
if (imax > spec.base.length) { imax = spec.base.length - 1 }; //проверяем выход границы за размер массива
2024-05-16 10:04:16 +03:00
for (let j = imin; j <= imax; j++) { model[j] = spec.base[j] + level };
};
//формируем результат
result["name"] = "model_" + spec.name;
result["resolution"] = spec.resolution;
result["data"] = model;
//отрисовка графика на plot
2024-06-20 02:36:01 +03:00
if (canvas != undefined) {
canvas.add(
2024-05-21 05:42:23 +03:00
{
color: color,
name: result.name,
x: result.resolution,
y: model
}
);
};
2024-05-16 10:04:16 +03:00
return result;
2024-05-16 10:04:16 +03:00
}; //построение упрощенной модели спектра
2024-06-19 14:35:28 +03:00
export function getMask(options) {
let result = {}; //результат
2024-06-19 14:35:28 +03:00
let data = options.src1.data; //массив точек спектра для сравнения с портретом
let mask = options.src2.base; //массив точек базовой линии для построения портрета дефекта
let harms = options.harms; //кол-во гармоник портрета
if (options.freq * harms > options.src2.frequency) { harms = Math.trunc(options.src2.frequency / options.freq) }; //проверяем максимальное кол-во гармоник в портрете
2024-05-15 08:24:04 +03:00
let df = 0; //отношение ширины фильтра частотному разрешению спектра
2024-06-19 14:35:28 +03:00
let dl = options.lvl; //разность уровней гармонической и случайной составляющей вибрации
if (options.filter != 0) {
df = options.src2.frequency / options.filter.width;
dl = 10 * Math.log10((options.lvl ** 2) / df + 1);
2024-05-15 08:24:04 +03:00
};
2024-06-19 14:35:28 +03:00
let k = options.coef; //коэффициент затухания
2024-06-11 08:41:46 +03:00
let x = 0; //индекс элемента массива для гармоники
let dx = 0; //коридор индексов
2024-05-08 08:43:57 +03:00
let xmin = 0; //левая граница коридора
let xmax = 0; //правая граница коридора
let correlation = 0; //коэффициент корреляции
function corr(a, b) {
let a_sum = 0; //сумма значений массива 1
let b_sum = 0; //сумма значений массива 2
let X = 0; //аргумент 1
let Y = 0; //аргумент 2
let Z = 0; //аргумент 3
for (let i = 0; i < a.length; i++) { a_sum += a[i] };
for (let i = 0; i < b.length; i++) { b_sum += b[i] };
let a_avg = a_sum / a.length;
let b_avg = b_sum / b.length;
for (let i = 0; i < a.length; i++) {
X += (a[i] - a_avg) * (b[i] - b_avg);
Y += (a[i] - a_avg) ** 2;
Z += (b[i] - b_avg) ** 2;
};
2024-05-20 10:32:42 +03:00
//gtl.log.info("Корреляция гармоники:", X / (Math.sqrt(Y) * Math.sqrt(Z)));
return X / (Math.sqrt(Y) * Math.sqrt(Z));
};
2024-05-08 04:30:31 +03:00
2024-05-20 10:32:42 +03:00
let arr1 = [];
let arr2 = [];
2024-06-19 14:35:28 +03:00
switch (options.type) {
case 0: //обычный ряд
2024-05-15 08:21:54 +03:00
for (let i = 1; i <= harms; i++) {
2024-06-19 14:35:28 +03:00
x = Math.trunc(i * options.freq / options.src2.resolution); //определяем инднекс элемента массива для гармоники
dx = Math.trunc(i * (options.freq * options.tol / 100) / options.src2.resolution); //коридор индексов массива для гармоники
2024-06-11 08:41:46 +03:00
xmin = x - Math.round(dx / 2); //определяем индекс левой границы коридора
xmax = x + Math.round(dx / 2); //определяем индекс правой границы коридора
2024-06-19 14:35:28 +03:00
if (xmax > options.src2.base.length) { xmax = options.src2.base.length - 2 }; //проверяем выход границы за размер массива
for (let j = xmin; j <= xmax; j++) { mask[j] = options.src2.base[j] + dl }; //записываем значение глубины модуляции для коридора
2024-05-20 10:32:42 +03:00
dl = dl - (k * dl); //снижаем глубину модуляции с коэффициентом затухания
2024-05-21 05:42:23 +03:00
for (let j = xmin - 2; j <= xmax + 2; j++) {
arr1.push(mask[j]);
arr2.push(data[j]);
}; //формируем массивы портретной гармоники и спектра (модели) под портретом
correlation += corr(arr1, arr2); //рассчитываем корреляцию данных из массивов
2024-05-08 04:30:31 +03:00
};
break;
case 1: //четные составляющие
2024-05-20 10:32:42 +03:00
for (let i = 1; i <= harms; i++) {
2024-06-19 14:35:28 +03:00
x = Math.trunc(i * options.freq / options.src2.resolution); //инднекс элемента массива для гармоники
dx = Math.trunc(i * (options.freq * options.tol / 100) / options.src2.resolution); //коридор индексов массива для гармоники
2024-06-11 08:41:46 +03:00
xmin = x - Math.round(dx / 2); //определяем индекс левой границы коридора
xmax = x + Math.round(dx / 2); //определяем индекс правой границы коридора
2024-06-19 14:35:28 +03:00
if (xmax > options.src2.base.length) { xmax = options.src2.base.length - 2 }; //проверяем выход границы за размер массива
2024-05-08 08:43:57 +03:00
if (i % 2 > 0) {
2024-06-19 14:35:28 +03:00
for (let j = xmin; j <= xmax; j++) { mask[j] = options.src2.base[j] + k * dl }; //записываем значение глубины модуляции для коридора (нечетная гармоника)
2024-05-20 10:32:42 +03:00
} else {
2024-06-19 14:35:28 +03:00
for (let j = xmin; j <= xmax; j++) { mask[j] = options.src2.base[j] + dl }; //записываем значение глубины модуляции для коридора (четная гармоника)
2024-05-20 10:32:42 +03:00
dl = dl - (k * dl); //снижаем глубину модуляции с коэффициентом затухания
2024-05-08 08:43:57 +03:00
};
2024-05-20 10:32:42 +03:00
for (let j = xmin - 2; j <= xmax + 2; j++) {
arr1.push(mask[j]);
arr2.push(data[j]);
}; //формируем массивы портретной гармоники и спектра (модели) под портретом
correlation += corr(arr1, arr2); //рассчитываем корреляцию данных из массивов
2024-05-08 04:30:31 +03:00
};
break;
default:
break;
};
//формируем результат
2024-06-19 14:35:28 +03:00
result["name"] = options.name; //имя маски дефекта
result["corr"] = correlation / harms; //средняя корреляция
result["data"] = mask; //массив данных портрета
//отрисовка графика на plot
2024-06-20 02:36:01 +03:00
if (options.canvas != undefined) {
options.canvas.add(
2024-05-21 05:42:23 +03:00
{
2024-06-19 14:35:28 +03:00
color: options.color,
name: options.name + " (" + result.corr.toFixed(2) + ")",
x: options.src2.resolution,
2024-05-21 05:42:23 +03:00
y: mask
}
);
};
2024-05-08 04:30:31 +03:00
return result;
2024-05-08 04:30:31 +03:00
}; //построение портрета дефекта
2024-05-15 08:24:04 +03:00
export function corr(spec1, spec2) {
let result = {}; //результат
let plot = []; //массив значений корреляции для графика
let corr = 0; //коэффициент корреляции
let arr1 = spec1.data;
let arr2 = spec2.data;
let arr1_sum = 0; //сумма значений массива 1
let arr2_sum = 0; //сумма значений массива 2
let X = 0; //аргумент 1
let Y = 0; //аргумент 2
let Z = 0; //аргумент 3
for (let i = 0; i < arr1.length; i++) { arr1_sum += arr1[i] };
for (let i = 0; i < arr2.length; i++) { arr2_sum += arr2[i] };
let arr1_avg = arr1_sum / arr1.length;
let arr2_avg = arr2_sum / arr2.length;
for (let i = 0; i < arr1.length; i++) {
X += (arr1[i] - arr1_avg) * (arr2[i] - arr2_avg);
Y += (arr1[i] - arr1_avg) ** 2;
Z += (arr2[i] - arr2_avg) ** 2;
plot.push(X / (Math.sqrt(Y) * Math.sqrt(Z)));
};
2024-05-15 08:24:04 +03:00
corr = X / (Math.sqrt(Y) * Math.sqrt(Z));
result["corr"] = corr;
result["plot"] = plot;
2024-05-15 08:24:04 +03:00
return result;
}; //рассчет корреляции спектров