Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

multiplet-analysis

Package Overview
Dependencies
Maintainers
1
Versions
15
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

multiplet-analysis - npm Package Compare versions

Comparing version 0.0.3 to 0.1.0

History.md

385

lib/index.js

@@ -5,2 +5,5 @@ 'use strict';

function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
var maxY = _interopDefault(require('ml-array-xy-max-y'));
var fftJs = require('fft-js');

@@ -56,104 +59,2 @@

function symmetrize(y) {
for (let indi = 0; indi < y.length / 2; indi++) {
const average = (y[indi] + y[y.length - 1 - indi]) / 2;
y[indi] = average;
y[y.length - 1 - indi] = average;
}
return y;
}
function trigInterpolate(x, y, nextPowerTwo, addPhaseInterpolation) {
let sca = Array(nextPowerTwo);
let spe = Array(nextPowerTwo);
let scaIncrement = (x[x.length - 1] - x[0]) / (x.length - 1); // delta one pt
let scaPt = x[0] - scaIncrement / 2; // move to limit side - not middle of first point (half a pt left...)
let trueWidth = scaIncrement * x.length;
scaIncrement = trueWidth / nextPowerTwo;
scaPt += scaIncrement / 2; // move from limit side to middle of first pt
// set scale
for (let loop = 0; loop < nextPowerTwo; loop++) {
sca[loop] = scaPt;
scaPt += scaIncrement;
}
// interpolate spectrum
// prepare input for fft apply fftshift
let nextPowerTwoAn = Math.pow(
2,
Math.round(Math.log(y.length - 1) / Math.log(2.0) + 0.5),
);
let an = [...Array(nextPowerTwoAn)].map(() => Array(2).fill(0)); // n x 2 array
const halfNumPt = Math.floor(y.length / 2); // may ignore last pt... if odd number
const halfNumPtB = y.length - halfNumPt;
const shiftMult = nextPowerTwoAn - y.length;
for (let loop = 0; loop < halfNumPt; loop++) {
an[shiftMult + loop + halfNumPtB][0] = y[loop]; //Re
an[shiftMult + loop + halfNumPtB][1] = 0; //Im
}
for (let loop = 0; loop < halfNumPtB; loop++) {
an[loop][0] = y[loop + halfNumPt]; //Re
an[loop][1] = 0; //Im
}
let out = fftJs.ifft(an);
out[0][0] = out[0][0] / 2; // divide first point by 2 Re
out[0][1] = out[0][1] / 2; // divide first point by 2 Im
// move to larger array...
let an2 = [...Array(nextPowerTwo)].map(() => Array(2).fill(0)); // n x 2 array
for (let loop = 0; loop < halfNumPt; loop++) {
an2[loop][0] = out[loop][0]; //* Math.cos((phase / 180) * Math.PI) +
an2[loop][1] = out[loop][1]; //* Math.cos((phase / 180) * Math.PI) -
}
for (let loop = halfNumPt; loop < nextPowerTwo; loop++) {
// zero filling
an2[loop][0] = 0;
an2[loop][1] = 0;
}
let out2 = fftJs.fft(an2);
const halfNumPt2 = nextPowerTwo / 2;
// applies fftshift
let phase = addPhaseInterpolation;
for (let loop = 0; loop < halfNumPt2; loop++) {
//spe[loop] = out2[loop + halfNumPt2][0]; // only Re now...
spe[loop] =
out2[loop + halfNumPt2][0] * Math.cos((phase / 180) * Math.PI) +
out2[loop + halfNumPt2][1] * Math.sin((phase / 180) * Math.PI); // only Re now...
}
for (let loop = 0; loop < halfNumPt2; loop++) {
//spe[loop + halfNumPt2] = out2[loop][0]; // only Re now...
spe[loop + halfNumPt2] =
out2[loop][0] * Math.cos((phase / 180) * Math.PI) +
out2[loop][1] * Math.sin((phase / 180) * Math.PI); // only Re now...
}
return { spectrum: spe, scale: sca };
}
function scalarProduct(y1, y2, sens, incrementForSpeed) {
// sens = 1; crude scalar product
// sens =-1: flip spectrum first
let v11 = 0;
let v22 = 0;
let v12 = 0;
if (sens > 0) {
for (let index = 0; index < y1.length; index += incrementForSpeed) {
v12 += y1[index] * y2[index];
v11 += y1[index] * y1[index];
v22 += y2[index] * y2[index];
}
} else {
// Here as if flip left/right array
for (let index = 0; index < y1.length; index += incrementForSpeed) {
v12 += y1[index] * y2[y1.length - index - 1];
v11 += y1[index] * y1[index];
v22 += y2[index] * y2[index];
}
}
return v12 / Math.sqrt(v11 * v22);
}
/**

@@ -217,7 +118,30 @@ *

function scalarProduct(y1, y2, sens, incrementForSpeed) {
// sens = 1; crude scalar product
// sens =-1: flip spectrum first
let v11 = 0;
let v22 = 0;
let v12 = 0;
if (sens > 0) {
for (let index = 0; index < y1.length; index += incrementForSpeed) {
v12 += y1[index] * y2[index];
v11 += y1[index] * y1[index];
v22 += y2[index] * y2[index];
}
} else {
// Here as if flip left/right array
for (let index = 0; index < y1.length; index += incrementForSpeed) {
v12 += y1[index] * y2[y1.length - index - 1];
v11 += y1[index] * y1[index];
v22 += y2[index] * y2[index];
}
}
return v12 / Math.sqrt(v11 * v22);
}
function measureDeco(
y,
JStar,
sign,
chopTail,
y, // input vector
JStar, // tested value of J in pt
sign, // sign of the split 1: ++ -1: +-
chopTail, // 1: cut tail
multiplicity,

@@ -230,36 +154,36 @@ incrementForSpeed,

y2 = deco(y, JStar, sign, -1, chopTail, multiplicity); // dir right to left
return scalarProduct(y1, y2, 1, incrementForSpeed);
return sign * scalarProduct(y1, y2, 1, incrementForSpeed);
}
function measureSym(y) {
let spref;
let spnew;
function measureSymShift(y) {
let ScalarProductReference;
let ScalarProductNewValue;
let movedBy = 0;
spref = scalarProduct(y, y, -1, 1);
ScalarProductReference = scalarProduct(y, y, -1, 1);
// search left...
for (let indi = 1; indi < y.length / 2; indi++) {
spnew = scalarProduct(
y.slice(indi, y.length),
y.slice(indi, y.length),
for (let i = 1; i < y.length / 2; i++) {
ScalarProductNewValue = scalarProduct(
y.slice(i, y.length),
y.slice(i, y.length),
-1,
1,
);
if (spnew > spref) {
// console.log(`${spnew} > ${spref} size: ${y.length}`);
spref = spnew;
movedBy = indi;
if (ScalarProductNewValue > ScalarProductReference) {
// console.log(`${ScalarProductNewValue} > ${ScalarProductReference} size: ${y.length}`);
ScalarProductReference = ScalarProductNewValue;
movedBy = i;
}
}
if (movedBy === 0) {
for (let indi = 1; indi < y.length / 2; indi++) {
spnew = scalarProduct(
y.slice(0, y.length - indi),
y.slice(0, y.length - indi),
for (let i = 1; i < y.length / 2; i++) {
ScalarProductNewValue = scalarProduct(
y.slice(0, y.length - i),
y.slice(0, y.length - i),
-1,
1,
);
if (spnew > spref) {
// console.log(`${spnew} > ${spref} size: ${y.length}`);
spref = spnew;
movedBy = -indi;
if (ScalarProductNewValue > ScalarProductReference) {
// console.log(`${ScalarProductNewValue} > ${ScalarProductReference} size: ${y.length}`);
ScalarProductReference = ScalarProductNewValue;
movedBy = -i;
}

@@ -272,9 +196,173 @@ }

/**
* Analyse X / Y array and extract multiplicity
* @param {object} [data={}] An object containing properties x and y
* @param {object} [options={}] Options (default is empty object)
* @param {number} [options.frequency=400] Acquisition frequency, default is 400 MHz
*/
function symmetrize(y) {
for (let indi = 0; indi < y.length / 2; indi++) {
const average = (y[indi] + y[y.length - 1 - indi]) / 2;
y[indi] = average;
y[y.length - 1 - indi] = average;
}
return y;
}
function trigInterpolate(
x,
y,
numberOfPointOutput,
addPhaseInterpolation,
appliedPhaseCorrectionType,
) {
let sca = Array(numberOfPointOutput);
let spe = Array(numberOfPointOutput);
let scaIncrement = (x[x.length - 1] - x[0]) / (x.length - 1); // delta one pt
//let scaPt = x[0] - scaIncrement / 2; // move to limit side - not middle of first point (half a pt left...)
let scaPt = x[0]; // move to limit side - not middle of first point (half a pt left...)
let trueWidth = scaIncrement * x.length;
scaIncrement = trueWidth / numberOfPointOutput;
//scaPt += scaIncrement / 2; // move from limit side to middle of first pt
// set scale
for (let loop = 0; loop < numberOfPointOutput; loop++) {
sca[loop] = scaPt;
scaPt += scaIncrement;
}
// interpolate spectrum
// prepare input for fft apply fftshift
let nextPowerTwoInput = Math.pow(
2,
Math.round(Math.log(y.length - 1) / Math.log(2.0) + 0.5),
);
//nextPowerTwoAn = Math.pow(2, Math.ceil(Math.log(y.length) / Math.log(2)));
let an = [...Array(nextPowerTwoInput)].map(() => Array(2).fill(0)); // n x 2 array
const halfNumPt = Math.floor(y.length / 2); // may ignore last pt... if odd number
const halfNumPtB = y.length - halfNumPt;
const shiftMultiplet = nextPowerTwoInput - y.length;
for (let loop = 0; loop < halfNumPt; loop++) {
an[shiftMultiplet + loop + halfNumPtB][0] = y[loop]; //Re
an[shiftMultiplet + loop + halfNumPtB][1] = 0; //Im
}
for (let loop = 0; loop < halfNumPtB; loop++) {
an[loop][0] = y[loop + halfNumPt]; //Re
an[loop][1] = 0; //Im
}
let timeDomain = fftJs.ifft(an);
/*an = fft(out);
for (let loop = 0; loop < 2 * halfNumPt; loop++) {
an[loop][1] = 0; //* Math.cos((phase / 180) * Math.PI) -
}
out = ifft(an);*/
timeDomain[0][0] = timeDomain[0][0] / 2; // divide first point by 2 Re
timeDomain[0][1] = timeDomain[0][1] / 2; // divide first point by 2 Im
// move to larger array...
let timeDomainZeroFilled = [...Array(numberOfPointOutput)].map(() =>
Array(2).fill(0),
); // n x 2 array
for (let loop = 0; loop < halfNumPt; loop++) {
timeDomainZeroFilled[loop][0] = timeDomain[loop][0]; //* Math.cos((phase / 180) * Math.PI) +
timeDomainZeroFilled[loop][1] = timeDomain[loop][1]; //* Math.cos((phase / 180) * Math.PI) -
}
for (let loop = halfNumPt; loop < numberOfPointOutput; loop++) {
// zero filling
timeDomainZeroFilled[loop][0] = 0;
timeDomainZeroFilled[loop][1] = 0;
}
let interpolatedSpectrum = fftJs.fft(timeDomainZeroFilled);
const halfNumPt2 = Math.floor(numberOfPointOutput / 2);
let tmp;
// applies phase change
let phaseRad = ((addPhaseInterpolation + 0.0) / 180.0) * Math.PI; // this is for testing additional phases
if (phaseRad !== 0.0) {
for (let loop = 0; loop < 2 * halfNumPt2; loop++) {
tmp =
interpolatedSpectrum[loop][0] * Math.cos(phaseRad) +
interpolatedSpectrum[loop][1] * Math.sin(phaseRad); // only Re now...
interpolatedSpectrum[loop][1] =
-interpolatedSpectrum[loop][0] * Math.sin(phaseRad) +
interpolatedSpectrum[loop][1] * Math.cos(phaseRad); // only Re now...
interpolatedSpectrum[loop][0] = tmp;
}
}
let returnedPhase = 0;
if (appliedPhaseCorrectionType > 0) {
let localPhaseRad = 0;
let vectx;
let vecty;
let norm;
// let sumNorms;
for (let loo = 1; loo < 100; loo++) {
localPhaseRad = 0;
vectx = 0;
vecty = 0;
// sumNorms = 0;
if (appliedPhaseCorrectionType > 0) {
// if ( true ) {
for (let loop = 0; loop < 2 * halfNumPt2; loop++) {
if (interpolatedSpectrum[loop][0] !== 0) {
localPhaseRad = Math.atan(
interpolatedSpectrum[loop][1] / interpolatedSpectrum[loop][0],
);
} else {
localPhaseRad =
(Math.sign(interpolatedSpectrum[loop][1]) * Math.PI) / 2.0;
}
norm = Math.sqrt(
interpolatedSpectrum[loop][1] * interpolatedSpectrum[loop][1] +
interpolatedSpectrum[loop][0] * interpolatedSpectrum[loop][0],
);
vectx += Math.cos(localPhaseRad) * norm;
vecty += Math.sin(localPhaseRad) * norm;
// sumNorms += norm;
}
if (vectx !== 0) {
localPhaseRad = Math.atan(vecty / vectx);
} else {
localPhaseRad = (Math.sign(vecty) * Math.PI) / 2.0;
}
}
norm = Math.sqrt(vecty * vecty + vectx * vectx);
phaseRad = -(10.0 / (loo * loo)) * Math.sign(vecty);
returnedPhase -= (180.0 * phaseRad) / Math.PI;
// console.log('localPhase ' + (180.0 * localPhaseRad) / Math.PI);
//console.log('returnedPhase ' + returnedPhase);
if (phaseRad !== 0.0) {
for (let loop = 0; loop < 2 * halfNumPt2; loop++) {
tmp =
interpolatedSpectrum[loop][0] * Math.cos(phaseRad) +
interpolatedSpectrum[loop][1] * Math.sin(phaseRad); // only Re now...
interpolatedSpectrum[loop][1] =
-interpolatedSpectrum[loop][0] * Math.sin(phaseRad) +
interpolatedSpectrum[loop][1] * Math.cos(phaseRad); // only Re now...
interpolatedSpectrum[loop][0] = tmp;
}
}
}
}
// applies fftshift
for (let loop = 0; loop < halfNumPt2; loop++) {
spe[loop] = interpolatedSpectrum[loop + halfNumPt2][0]; // only Re now...
}
for (let loop = 0; loop < halfNumPt2; loop++) {
spe[loop + halfNumPt2] = interpolatedSpectrum[loop][0];
}
if (returnedPhase > 360.0) {
returnedPhase -= 360.0;
}
return {
spectrum: spe,
scale: sca,
phaseCorrectionOnMultipletInDeg: returnedPhase,
};
}
/* eslint-disable no-console */
/**

@@ -305,2 +393,3 @@ * Analyse a multiplet

forceFirstDeconvolutionToThisValue = 0,
appliedPhaseCorrectionType = 0,
} = options;

@@ -334,6 +423,11 @@

let topPosJ = 0;
if (resolutionHz > minimalResolution) {
// need increase resolution
let returned = trigInterpolate(x, y, nextPowerTwo, addPhaseInterpolation);
let returned = trigInterpolate(
x,
y,
nextPowerTwo,
addPhaseInterpolation,
appliedPhaseCorrectionType,
);
if (debug) console.log(`interpolating`);

@@ -343,2 +437,4 @@

sca = returned.scale;
result.phaseCorrectionOnMultipletInDeg =
returned.phaseCorrectionOnMultipletInDeg;
} else {

@@ -390,3 +486,3 @@ sca = x;

if (symmetrizeEachStep === true) {
movedBy = -measureSym(spe);
movedBy = -measureSymShift(spe);
if (movedBy > 0) {

@@ -539,7 +635,14 @@ spe = spe.slice(0, spe.length - movedBy);

if (sca.length !== spe.length) {
ErrorEvent('sts');// this is an ugly way to make sure to get an error when this occurs
throw Error('sts');
}
}
}
let curTop = -1000000000000000000.0;
// to be tested ...
let maxAmplitudePosition = maxY({ x: sca, y: spe });
result.chemShift = sca[maxAmplitudePosition.index];
// for non-javascript implementation
/*
let curTop = Number.NEGATIVE_INFINITY;
let curChemShift;

@@ -552,3 +655,4 @@ for (let i = 0; i < spe.length; i++) {

}
result.chemShift = curChemShift;
result.chemShift = curChemShift;*/
// end to be commented

@@ -675,3 +779,4 @@ return result;

title(['J(' num2str(main_j_loop) ')=' num2str(symj(top_pos)*hz_per_pt_interp,3) ' Hz'])
nbpt=symj(top_pos);
=symj(top_pos);
[v1, v2]=deco(segment_int',nbpt);

@@ -678,0 +783,0 @@ segment_int=(v1*0.5+0.5*v2)';

{
"name": "multiplet-analysis",
"version": "0.0.3",
"description": "",
"main": "lib/index.js",
"module": "src/index.js",
"files": [
"lib",
"src"
],
"scripts": {
"eslint": "eslint src",
"eslint-fix": "npm run eslint -- --fix",
"prepublishOnly": "rollup -c",
"test": "npm run test-coverage && npm run eslint",
"test-coverage": "jest --coverage",
"test-only": "jest"
},
"repository": {
"type": "git",
"url": "git+https://github.com/cheminfo/multiplet-analysis.git"
},
"keywords": [],
"author": "Luc Patiny",
"license": "MIT",
"bugs": {
"url": "https://github.com/cheminfo/multiplet-analysis/issues"
},
"homepage": "https://github.com/cheminfo/multiplet-analysis#readme",
"jest": {
"testEnvironment": "node"
},
"prettier": {
"arrowParens": "always",
"semi": true,
"singleQuote": true,
"tabWidth": 2,
"trailingComma": "all"
},
"devDependencies": {
"@babel/plugin-transform-modules-commonjs": "^7.7.5",
"eslint": "^6.8.0",
"eslint-config-cheminfo": "^2.0.4",
"eslint-plugin-import": "^2.20.0",
"eslint-plugin-jest": "^23.4.0",
"eslint-plugin-prettier": "^3.1.2",
"esm": "^3.2.25",
"jest": "^24.9.0",
"nmr-simulation": "^1.0.19",
"prettier": "^1.19.1",
"rollup": "^1.29.0"
},
"dependencies": {
"fft-js": "0.0.12",
"ml-fft": "^1.3.5"
}
"name": "multiplet-analysis",
"version": "0.1.0",
"description": "",
"main": "lib/index.js",
"module": "src/index.js",
"files": [
"lib",
"src"
],
"scripts": {
"eslint": "eslint src",
"eslint-fix": "npm run eslint -- --fix",
"prepublishOnly": "rollup -c",
"test": "npm run test-coverage && npm run eslint",
"test-coverage": "jest --coverage",
"test-only": "jest"
},
"repository": {
"type": "git",
"url": "git+https://github.com/cheminfo/multiplet-analysis.git"
},
"keywords": [],
"author": "Luc Patiny",
"license": "MIT",
"bugs": {
"url": "https://github.com/cheminfo/multiplet-analysis/issues"
},
"homepage": "https://github.com/cheminfo/multiplet-analysis#readme",
"jest": {
"testEnvironment": "node"
},
"prettier": {
"arrowParens": "always",
"semi": true,
"singleQuote": true,
"tabWidth": 2,
"trailingComma": "all"
},
"devDependencies": {
"@babel/plugin-transform-modules-commonjs": "^7.9.0",
"eslint": "^6.8.0",
"eslint-config-cheminfo": "^3.0.0",
"eslint-plugin-import": "^2.20.2",
"eslint-plugin-jest": "^23.8.2",
"eslint-plugin-prettier": "^3.1.2",
"esm": "^3.2.25",
"jest": "^25.2.3",
"nmr-simulation": "^1.0.19",
"prettier": "^2.0.2",
"rollup": "^2.2.0"
},
"dependencies": {
"fft-js": "0.0.12",
"ml-array-xy-max-y": "^1.0.1",
"ml-fft": "^1.3.5"
}
}

@@ -27,2 +27,3 @@ # multiplet-analysis

`node -r esm examples/simulate.js` to simulate from a user-defined spin system
`node -r esm examples/dd-exp.js` to simulate from a user-defined spin system

@@ -29,0 +30,0 @@

@@ -1,2 +0,1 @@

/**

@@ -3,0 +2,0 @@ *

@@ -0,1 +1,2 @@

/* eslint-disable no-console */
/**

@@ -8,8 +9,10 @@ * Analyse X / Y array and extract multiplicity

import maxY from 'ml-array-xy-max-y';
import { appendDebug } from './appendDebug';
import { deco } from './deco';
import { measureDeco } from './measureDeco';
import { measureSymShift } from './measureSymShift';
import { symmetrize } from './symmetrize';
import { trigInterpolate } from './trigInterpolate';
import { measureDeco } from './measureDeco';
import { deco } from './deco';
import { measureSym } from './measureSym';

@@ -41,2 +44,3 @@ /**

forceFirstDeconvolutionToThisValue = 0,
appliedPhaseCorrectionType = 0,
} = options;

@@ -70,6 +74,11 @@

let topPosJ = 0;
if (resolutionHz > minimalResolution) {
// need increase resolution
let returned = trigInterpolate(x, y, nextPowerTwo, addPhaseInterpolation);
let returned = trigInterpolate(
x,
y,
nextPowerTwo,
addPhaseInterpolation,
appliedPhaseCorrectionType,
);
if (debug) console.log(`interpolating`);

@@ -79,2 +88,4 @@

sca = returned.scale;
result.phaseCorrectionOnMultipletInDeg =
returned.phaseCorrectionOnMultipletInDeg;
} else {

@@ -126,3 +137,3 @@ sca = x;

if (symmetrizeEachStep === true) {
movedBy = -measureSym(spe);
movedBy = -measureSymShift(spe);
if (movedBy > 0) {

@@ -275,7 +286,14 @@ spe = spe.slice(0, spe.length - movedBy);

if (sca.length !== spe.length) {
ErrorEvent('sts');// this is an ugly way to make sure to get an error when this occurs
throw Error('sts');
}
}
}
let curTop = -1000000000000000000.0;
// to be tested ...
let maxAmplitudePosition = maxY({ x: sca, y: spe });
result.chemShift = sca[maxAmplitudePosition.index];
// for non-javascript implementation
/*
let curTop = Number.NEGATIVE_INFINITY;
let curChemShift;

@@ -288,3 +306,4 @@ for (let i = 0; i < spe.length; i++) {

}
result.chemShift = curChemShift;
result.chemShift = curChemShift;*/
// end to be commented

@@ -411,3 +430,4 @@ return result;

title(['J(' num2str(main_j_loop) ')=' num2str(symj(top_pos)*hz_per_pt_interp,3) ' Hz'])
nbpt=symj(top_pos);
=symj(top_pos);
[v1, v2]=deco(segment_int',nbpt);

@@ -414,0 +434,0 @@ segment_int=(v1*0.5+0.5*v2)';

@@ -0,9 +1,9 @@

import { deco } from './deco';
import { scalarProduct } from './scalarProduct';
import { deco } from './deco';
export function measureDeco(
y,
JStar,
sign,
chopTail,
y, // input vector
JStar, // tested value of J in pt
sign, // sign of the split 1: ++ -1: +-
chopTail, // 1: cut tail
multiplicity,

@@ -16,3 +16,3 @@ incrementForSpeed,

y2 = deco(y, JStar, sign, -1, chopTail, multiplicity); // dir right to left
return scalarProduct(y1, y2, 1, incrementForSpeed);
}
return sign * scalarProduct(y1, y2, 1, incrementForSpeed);
}

@@ -8,2 +8,2 @@ export function symmetrize(y) {

return y;
}
}
import { fft, ifft } from 'fft-js';
export function trigInterpolate(x, y, nextPowerTwo, addPhaseInterpolation) {
let sca = Array(nextPowerTwo);
let spe = Array(nextPowerTwo);
export function trigInterpolate(
x,
y,
numberOfPointOutput,
addPhaseInterpolation,
appliedPhaseCorrectionType,
) {
let sca = Array(numberOfPointOutput);
let spe = Array(numberOfPointOutput);
let scaIncrement = (x[x.length - 1] - x[0]) / (x.length - 1); // delta one pt
let scaPt = x[0] - scaIncrement / 2; // move to limit side - not middle of first point (half a pt left...)
//let scaPt = x[0] - scaIncrement / 2; // move to limit side - not middle of first point (half a pt left...)
let scaPt = x[0]; // move to limit side - not middle of first point (half a pt left...)
let trueWidth = scaIncrement * x.length;
scaIncrement = trueWidth / nextPowerTwo;
scaPt += scaIncrement / 2; // move from limit side to middle of first pt
scaIncrement = trueWidth / numberOfPointOutput;
//scaPt += scaIncrement / 2; // move from limit side to middle of first pt
// set scale
for (let loop = 0; loop < nextPowerTwo; loop++) {
for (let loop = 0; loop < numberOfPointOutput; loop++) {
sca[loop] = scaPt;

@@ -21,13 +28,14 @@ scaPt += scaIncrement;

// prepare input for fft apply fftshift
let nextPowerTwoAn = Math.pow(
let nextPowerTwoInput = Math.pow(
2,
Math.round(Math.log(y.length - 1) / Math.log(2.0) + 0.5),
);
let an = [...Array(nextPowerTwoAn)].map(() => Array(2).fill(0)); // n x 2 array
//nextPowerTwoAn = Math.pow(2, Math.ceil(Math.log(y.length) / Math.log(2)));
let an = [...Array(nextPowerTwoInput)].map(() => Array(2).fill(0)); // n x 2 array
const halfNumPt = Math.floor(y.length / 2); // may ignore last pt... if odd number
const halfNumPtB = y.length - halfNumPt;
const shiftMult = nextPowerTwoAn - y.length;
const shiftMultiplet = nextPowerTwoInput - y.length;
for (let loop = 0; loop < halfNumPt; loop++) {
an[shiftMult + loop + halfNumPtB][0] = y[loop]; //Re
an[shiftMult + loop + halfNumPtB][1] = 0; //Im
an[shiftMultiplet + loop + halfNumPtB][0] = y[loop]; //Re
an[shiftMultiplet + loop + halfNumPtB][1] = 0; //Im
}

@@ -39,35 +47,117 @@ for (let loop = 0; loop < halfNumPtB; loop++) {

let out = ifft(an);
let timeDomain = ifft(an);
/*an = fft(out);
for (let loop = 0; loop < 2 * halfNumPt; loop++) {
an[loop][1] = 0; //* Math.cos((phase / 180) * Math.PI) -
}
out = ifft(an);*/
out[0][0] = out[0][0] / 2; // divide first point by 2 Re
out[0][1] = out[0][1] / 2; // divide first point by 2 Im
timeDomain[0][0] = timeDomain[0][0] / 2; // divide first point by 2 Re
timeDomain[0][1] = timeDomain[0][1] / 2; // divide first point by 2 Im
// move to larger array...
let an2 = [...Array(nextPowerTwo)].map(() => Array(2).fill(0)); // n x 2 array
let timeDomainZeroFilled = [...Array(numberOfPointOutput)].map(() =>
Array(2).fill(0),
); // n x 2 array
for (let loop = 0; loop < halfNumPt; loop++) {
an2[loop][0] = out[loop][0]; //* Math.cos((phase / 180) * Math.PI) +
an2[loop][1] = out[loop][1]; //* Math.cos((phase / 180) * Math.PI) -
timeDomainZeroFilled[loop][0] = timeDomain[loop][0]; //* Math.cos((phase / 180) * Math.PI) +
timeDomainZeroFilled[loop][1] = timeDomain[loop][1]; //* Math.cos((phase / 180) * Math.PI) -
}
for (let loop = halfNumPt; loop < nextPowerTwo; loop++) {
for (let loop = halfNumPt; loop < numberOfPointOutput; loop++) {
// zero filling
an2[loop][0] = 0;
an2[loop][1] = 0;
timeDomainZeroFilled[loop][0] = 0;
timeDomainZeroFilled[loop][1] = 0;
}
let out2 = fft(an2);
const halfNumPt2 = nextPowerTwo / 2;
let interpolatedSpectrum = fft(timeDomainZeroFilled);
const halfNumPt2 = Math.floor(numberOfPointOutput / 2);
let tmp;
// applies phase change
let phaseRad = ((addPhaseInterpolation + 0.0) / 180.0) * Math.PI; // this is for testing additional phases
if (phaseRad !== 0.0) {
for (let loop = 0; loop < 2 * halfNumPt2; loop++) {
tmp =
interpolatedSpectrum[loop][0] * Math.cos(phaseRad) +
interpolatedSpectrum[loop][1] * Math.sin(phaseRad); // only Re now...
interpolatedSpectrum[loop][1] =
-interpolatedSpectrum[loop][0] * Math.sin(phaseRad) +
interpolatedSpectrum[loop][1] * Math.cos(phaseRad); // only Re now...
interpolatedSpectrum[loop][0] = tmp;
}
}
let returnedPhase = 0;
if (appliedPhaseCorrectionType > 0) {
let localPhaseRad = 0;
let vectx;
let vecty;
let norm;
// let sumNorms;
for (let loo = 1; loo < 100; loo++) {
localPhaseRad = 0;
vectx = 0;
vecty = 0;
// sumNorms = 0;
if (appliedPhaseCorrectionType > 0) {
// if ( true ) {
for (let loop = 0; loop < 2 * halfNumPt2; loop++) {
if (interpolatedSpectrum[loop][0] !== 0) {
localPhaseRad = Math.atan(
interpolatedSpectrum[loop][1] / interpolatedSpectrum[loop][0],
);
} else {
localPhaseRad =
(Math.sign(interpolatedSpectrum[loop][1]) * Math.PI) / 2.0;
}
norm = Math.sqrt(
interpolatedSpectrum[loop][1] * interpolatedSpectrum[loop][1] +
interpolatedSpectrum[loop][0] * interpolatedSpectrum[loop][0],
);
vectx += Math.cos(localPhaseRad) * norm;
vecty += Math.sin(localPhaseRad) * norm;
// sumNorms += norm;
}
if (vectx !== 0) {
localPhaseRad = Math.atan(vecty / vectx);
} else {
localPhaseRad = (Math.sign(vecty) * Math.PI) / 2.0;
}
}
norm = Math.sqrt(vecty * vecty + vectx * vectx);
phaseRad = -(10.0 / (loo * loo)) * Math.sign(vecty);
returnedPhase -= (180.0 * phaseRad) / Math.PI;
// console.log('localPhase ' + (180.0 * localPhaseRad) / Math.PI);
//console.log('returnedPhase ' + returnedPhase);
if (phaseRad !== 0.0) {
for (let loop = 0; loop < 2 * halfNumPt2; loop++) {
tmp =
interpolatedSpectrum[loop][0] * Math.cos(phaseRad) +
interpolatedSpectrum[loop][1] * Math.sin(phaseRad); // only Re now...
interpolatedSpectrum[loop][1] =
-interpolatedSpectrum[loop][0] * Math.sin(phaseRad) +
interpolatedSpectrum[loop][1] * Math.cos(phaseRad); // only Re now...
interpolatedSpectrum[loop][0] = tmp;
}
}
}
}
// applies fftshift
let phase = addPhaseInterpolation;
for (let loop = 0; loop < halfNumPt2; loop++) {
//spe[loop] = out2[loop + halfNumPt2][0]; // only Re now...
spe[loop] =
out2[loop + halfNumPt2][0] * Math.cos((phase / 180) * Math.PI) +
out2[loop + halfNumPt2][1] * Math.sin((phase / 180) * Math.PI); // only Re now...
spe[loop] = interpolatedSpectrum[loop + halfNumPt2][0]; // only Re now...
}
for (let loop = 0; loop < halfNumPt2; loop++) {
//spe[loop + halfNumPt2] = out2[loop][0]; // only Re now...
spe[loop + halfNumPt2] =
out2[loop][0] * Math.cos((phase / 180) * Math.PI) +
out2[loop][1] * Math.sin((phase / 180) * Math.PI); // only Re now...
spe[loop + halfNumPt2] = interpolatedSpectrum[loop][0];
}
return { spectrum: spe, scale: sca };
if (returnedPhase > 360.0) {
returnedPhase -= 360.0;
}
return {
spectrum: spe,
scale: sca,
phaseCorrectionOnMultipletInDeg: returnedPhase,
};
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc