gtld2-diag-scripts/mask_func.js

163 lines
8.7 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

export function spec_model(spec, tol, color, visible) {
let result = {}; //результат
let model = spec.base; //исходный массив точек для построения упрощенной модели спектра
let imin = 0; //левая граница коридора
let imax = 0; //правая граница коридора
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 }; //проверяем выход границы за размер массива
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
if (visible == true) {
gtl.plot.add(
{
color: color,
name: result.name,
x: result.resolution,
y: model
}
);
};
return result;
}; //построение упрощенной модели спектра
export function mask(obj) {
let result = {}; //результат
let data = obj.src1.data; //массив точек спектра для сравнения с портретом
let mask = obj.src2.base; //исходный массив точек для построения портрета дефекта
let harms = obj.harms; //гармоник портрета
if (obj.freq * harms > obj.src2.frequency) { harms = Math.trunc(obj.src2.frequency / obj.freq) }; //проверяем максимальное кол-во гармоник в портрете
let df = 0; //отношение ширины фильтра частотному разрешению спектра
let dl = obj.lvl; //разность уровней гармонической и случайной составляющей вибрации
if (obj.filter != 0) {
df = obj.filter.width / obj.src2.resolution;
dl = 10 * Math.log10((obj.lvl ** 2) * df + 1);
};
let k = obj.coef; //коэффициент затухания
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;
};
//gtl.log.info("Корреляция гармоники:", X / (Math.sqrt(Y) * Math.sqrt(Z)));
return X / (Math.sqrt(Y) * Math.sqrt(Z));
};
let arr1 = [];
let arr2 = [];
switch (obj.type) {
case 0: //обычный ряд
for (let i = 1; i <= harms; i++) {
xmin = Math.round(i * (obj.freq - obj.freq * 0.5 * obj.tol / 100) / obj.src2.resolution); //определяем индекс левой границы коридора
xmax = Math.round(i * (obj.freq + obj.freq * 0.5 * obj.tol / 100) / obj.src2.resolution); //определяем индекс правой границы коридора
if (xmax > obj.src2.base.length) { xmax = obj.src2.base.length - 2 }; //проверяем выход границы за размер массива
for (let j = xmin; j <= xmax; j++) { mask[j] = obj.src2.base[j] + dl }; //записываем значение глубины модуляции для коридора
dl = dl - (k * dl); //снижаем глубину модуляции с коэффициентом затухания
for (let j = xmin - 2; j <= xmax + 2; j++) {
arr1.push(mask[j]);
arr2.push(data[j]);
}; //формируем массивы портретной гармоники и спектра (модели) под портретом
correlation += corr(arr1, arr2); //рассчитываем корреляцию данных из массивов
};
break;
case 1: //четные составляющие
for (let i = 1; i <= harms; i++) {
xmin = Math.round(i * (obj.freq - obj.freq * 0.5 * obj.tol / 100) / obj.src2.resolution); //определяем индекс левой границы коридора
xmax = Math.round(i * (obj.freq + obj.freq * 0.5 * obj.tol / 100) / obj.src2.resolution); //определяем индекс правой границы коридора
if (xmax > obj.src2.base.length) { xmax = obj.src2.base.length - 2 }; //проверяем выход границы за размер массива
if (i % 2 > 0) {
for (let j = xmin; j <= xmax; j++) { mask[j] = obj.src2.base[j] + k * dl }; //записываем значение глубины модуляции для коридора (нечетная гармоника)
} else {
for (let j = xmin; j <= xmax; j++) { mask[j] = obj.src2.base[j] + dl }; //записываем значение глубины модуляции для коридора (четная гармоника)
dl = dl - (k * dl); //снижаем глубину модуляции с коэффициентом затухания
};
for (let j = xmin - 2; j <= xmax + 2; j++) {
arr1.push(mask[j]);
arr2.push(data[j]);
}; //формируем массивы портретной гармоники и спектра (модели) под портретом
correlation += corr(arr1, arr2); //рассчитываем корреляцию данных из массивов
};
break;
default:
break;
};
//формируем результат
result["name"] = obj.name; //имя маски дефекта
result["corr"] = correlation / harms; //средняя корреляция
result["data"] = mask; //массив данных портрета
//отрисовка графика на plot
if (obj.visible == true) {
gtl.plot.add(
{
color: obj.color,
name: obj.name,
x: obj.src2.resolution,
y: mask
}
);
};
return result;
}; //построение портрета дефекта
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)));
};
corr = X / (Math.sqrt(Y) * Math.sqrt(Z));
result["corr"] = corr;
result["plot"] = plot;
return result;
}; //рассчет корреляции спектров