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

xy-parser

Package Overview
Dependencies
Maintainers
2
Versions
19
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

xy-parser - npm Package Compare versions

Comparing version 3.0.0 to 3.1.0

src/__tests__/mass.test.js

12

History.md

@@ -0,1 +1,13 @@

## [3.1.0](https://github.com/cheminfo/xy-parser/compare/v3.0.0...v3.1.0) (2021-03-19)
### Features
* add bestGuess and numberColumns options ([3bf5f86](https://github.com/cheminfo/xy-parser/commit/3bf5f8687d67b5c34921a11f184214d056ba4383))
### Bug Fixes
* improve readme ([0889efc](https://github.com/cheminfo/xy-parser/commit/0889efce4a4ef27ab58bd685442066a9fe8ef449))
0.0.0 / HEAD

@@ -2,0 +14,0 @@ ============

689

lib/index.js

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

const toString$1 = Object.prototype.toString;
function isAnyArray(object) {
return toString$1.call(object).endsWith('Array]');
}
function max(input) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
if (!isAnyArray(input)) {
throw new TypeError('input must be an array');
}
if (input.length === 0) {
throw new TypeError('input must not be empty');
}
var _options$fromIndex = options.fromIndex,
fromIndex = _options$fromIndex === void 0 ? 0 : _options$fromIndex,
_options$toIndex = options.toIndex,
toIndex = _options$toIndex === void 0 ? input.length : _options$toIndex;
if (fromIndex < 0 || fromIndex >= input.length || !Number.isInteger(fromIndex)) {
throw new Error('fromIndex must be a positive integer smaller than length');
}
if (toIndex <= fromIndex || toIndex > input.length || !Number.isInteger(toIndex)) {
throw new Error('toIndex must be an integer greater than fromIndex and at most equal to length');
}
var maxValue = input[fromIndex];
for (var i = fromIndex + 1; i < toIndex; i++) {
if (input[i] > maxValue) maxValue = input[i];
}
return maxValue;
}
/**

@@ -40,3 +79,586 @@ * In place modification of the 2 arrays to make X unique and sum the Y if X has the same value

var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
function createCommonjsModule(fn, module) {
return module = { exports: {} }, fn(module, module.exports), module.exports;
}
createCommonjsModule(function (module) {
(function(){function a(d){for(var e=0,f=d.length-1,g=void 0,h=void 0,i=void 0,j=c(e,f);!0;){if(f<=e)return d[j];if(f==e+1)return d[e]>d[f]&&b(d,e,f),d[j];for(g=c(e,f),d[g]>d[f]&&b(d,g,f),d[e]>d[f]&&b(d,e,f),d[g]>d[e]&&b(d,g,e),b(d,g,e+1),h=e+1,i=f;!0;){do h++;while(d[e]>d[h]);do i--;while(d[i]>d[e]);if(i<h)break;b(d,h,i);}b(d,e,i),i<=j&&(e=h),i>=j&&(f=i-1);}}var b=function b(d,e,f){var _ref;return _ref=[d[f],d[e]],d[e]=_ref[0],d[f]=_ref[1],_ref},c=function c(d,e){return ~~((d+e)/2)};module.exports?module.exports=a:window.median=a;})();
});
/**
* Returns true if x is monotone
* @param {Array} array
* @return {boolean}
*/
function xIsMonotone(array) {
if (array.length <= 2) {
return true;
}
if (array[0] === array[1]) {
// maybe a constant series
for (let i = 1; i < array.length - 1; i++) {
if (array[i] !== array[i + 1]) return false;
}
return true;
}
if (array[0] < array[array.length - 1]) {
for (let i = 0; i < array.length - 1; i++) {
if (array[i] >= array[i + 1]) return false;
}
} else {
for (let i = 0; i < array.length - 1; i++) {
if (array[i] <= array[i + 1]) return false;
}
}
return true;
}
createCommonjsModule(function (module, exports) {
(function (global, factory) {
factory(exports) ;
}(commonjsGlobal, function (exports) {
function ascending(a, b) {
return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;
}
function bisector(compare) {
if (compare.length === 1) compare = ascendingComparator(compare);
return {
left: function(a, x, lo, hi) {
if (lo == null) lo = 0;
if (hi == null) hi = a.length;
while (lo < hi) {
var mid = lo + hi >>> 1;
if (compare(a[mid], x) < 0) lo = mid + 1;
else hi = mid;
}
return lo;
},
right: function(a, x, lo, hi) {
if (lo == null) lo = 0;
if (hi == null) hi = a.length;
while (lo < hi) {
var mid = lo + hi >>> 1;
if (compare(a[mid], x) > 0) hi = mid;
else lo = mid + 1;
}
return lo;
}
};
}
function ascendingComparator(f) {
return function(d, x) {
return ascending(f(d), x);
};
}
var ascendingBisect = bisector(ascending);
var bisectRight = ascendingBisect.right;
var bisectLeft = ascendingBisect.left;
function descending(a, b) {
return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN;
}
function number$1(x) {
return x === null ? NaN : +x;
}
function variance(array, f) {
var n = array.length,
m = 0,
a,
d,
s = 0,
i = -1,
j = 0;
if (f == null) {
while (++i < n) {
if (!isNaN(a = number$1(array[i]))) {
d = a - m;
m += d / ++j;
s += d * (a - m);
}
}
}
else {
while (++i < n) {
if (!isNaN(a = number$1(f(array[i], i, array)))) {
d = a - m;
m += d / ++j;
s += d * (a - m);
}
}
}
if (j > 1) return s / (j - 1);
}
function deviation(array, f) {
var v = variance(array, f);
return v ? Math.sqrt(v) : v;
}
function extent(array, f) {
var i = -1,
n = array.length,
a,
b,
c;
if (f == null) {
while (++i < n) if ((b = array[i]) != null && b >= b) { a = c = b; break; }
while (++i < n) if ((b = array[i]) != null) {
if (a > b) a = b;
if (c < b) c = b;
}
}
else {
while (++i < n) if ((b = f(array[i], i, array)) != null && b >= b) { a = c = b; break; }
while (++i < n) if ((b = f(array[i], i, array)) != null) {
if (a > b) a = b;
if (c < b) c = b;
}
}
return [a, c];
}
function constant(x) {
return function() {
return x;
};
}
function identity(x) {
return x;
}
function range(start, stop, step) {
start = +start, stop = +stop, step = (n = arguments.length) < 2 ? (stop = start, start = 0, 1) : n < 3 ? 1 : +step;
var i = -1,
n = Math.max(0, Math.ceil((stop - start) / step)) | 0,
range = new Array(n);
while (++i < n) {
range[i] = start + i * step;
}
return range;
}
var e10 = Math.sqrt(50);
var e5 = Math.sqrt(10);
var e2 = Math.sqrt(2);
function ticks(start, stop, count) {
var step = tickStep(start, stop, count);
return range(
Math.ceil(start / step) * step,
Math.floor(stop / step) * step + step / 2, // inclusive
step
);
}
function tickStep(start, stop, count) {
var step0 = Math.abs(stop - start) / Math.max(0, count),
step1 = Math.pow(10, Math.floor(Math.log(step0) / Math.LN10)),
error = step0 / step1;
if (error >= e10) step1 *= 10;
else if (error >= e5) step1 *= 5;
else if (error >= e2) step1 *= 2;
return stop < start ? -step1 : step1;
}
function sturges(values) {
return Math.ceil(Math.log(values.length) / Math.LN2) + 1;
}
function number(x) {
return +x;
}
function histogram() {
var value = identity,
domain = extent,
threshold = sturges;
function histogram(data) {
var i,
n = data.length,
x,
values = new Array(n);
// Coerce values to numbers.
for (i = 0; i < n; ++i) {
values[i] = +value(data[i], i, data);
}
var xz = domain(values),
x0 = +xz[0],
x1 = +xz[1],
tz = threshold(values, x0, x1);
// Convert number of thresholds into uniform thresholds.
if (!Array.isArray(tz)) tz = ticks(x0, x1, +tz);
// Coerce thresholds to numbers, ignoring any outside the domain.
var m = tz.length;
for (i = 0; i < m; ++i) tz[i] = +tz[i];
while (tz[0] <= x0) tz.shift(), --m;
while (tz[m - 1] >= x1) tz.pop(), --m;
var bins = new Array(m + 1),
bin;
// Initialize bins.
for (i = 0; i <= m; ++i) {
bin = bins[i] = [];
bin.x0 = i > 0 ? tz[i - 1] : x0;
bin.x1 = i < m ? tz[i] : x1;
}
// Assign data to bins by value, ignoring any outside the domain.
for (i = 0; i < n; ++i) {
x = values[i];
if (x0 <= x && x <= x1) {
bins[bisectRight(tz, x, 0, m)].push(data[i]);
}
}
return bins;
}
histogram.value = function(_) {
return arguments.length ? (value = typeof _ === "function" ? _ : constant(+_), histogram) : value;
};
histogram.domain = function(_) {
return arguments.length ? (domain = typeof _ === "function" ? _ : constant([+_[0], +_[1]]), histogram) : domain;
};
histogram.thresholds = function(_) {
if (!arguments.length) return threshold;
threshold = typeof _ === "function" ? _
: Array.isArray(_) ? constant(Array.prototype.map.call(_, number))
: constant(+_);
return histogram;
};
return histogram;
}
function quantile(array, p, f) {
if (f == null) f = number$1;
if (!(n = array.length)) return;
if ((p = +p) <= 0 || n < 2) return +f(array[0], 0, array);
if (p >= 1) return +f(array[n - 1], n - 1, array);
var n,
h = (n - 1) * p,
i = Math.floor(h),
a = +f(array[i], i, array),
b = +f(array[i + 1], i + 1, array);
return a + (b - a) * (h - i);
}
function freedmanDiaconis(values, min, max) {
values.sort(ascending);
return Math.ceil((max - min) / (2 * (quantile(values, 0.75) - quantile(values, 0.25)) * Math.pow(values.length, -1 / 3)));
}
function scott(values, min, max) {
return Math.ceil((max - min) / (3.5 * deviation(values) * Math.pow(values.length, -1 / 3)));
}
function max(array, f) {
var i = -1,
n = array.length,
a,
b;
if (f == null) {
while (++i < n) if ((b = array[i]) != null && b >= b) { a = b; break; }
while (++i < n) if ((b = array[i]) != null && b > a) a = b;
}
else {
while (++i < n) if ((b = f(array[i], i, array)) != null && b >= b) { a = b; break; }
while (++i < n) if ((b = f(array[i], i, array)) != null && b > a) a = b;
}
return a;
}
function mean(array, f) {
var s = 0,
n = array.length,
a,
i = -1,
j = n;
if (f == null) {
while (++i < n) if (!isNaN(a = number$1(array[i]))) s += a; else --j;
}
else {
while (++i < n) if (!isNaN(a = number$1(f(array[i], i, array)))) s += a; else --j;
}
if (j) return s / j;
}
function median(array, f) {
var numbers = [],
n = array.length,
a,
i = -1;
if (f == null) {
while (++i < n) if (!isNaN(a = number$1(array[i]))) numbers.push(a);
}
else {
while (++i < n) if (!isNaN(a = number$1(f(array[i], i, array)))) numbers.push(a);
}
return quantile(numbers.sort(ascending), 0.5);
}
function merge(arrays) {
var n = arrays.length,
m,
i = -1,
j = 0,
merged,
array;
while (++i < n) j += arrays[i].length;
merged = new Array(j);
while (--n >= 0) {
array = arrays[n];
m = array.length;
while (--m >= 0) {
merged[--j] = array[m];
}
}
return merged;
}
function min(array, f) {
var i = -1,
n = array.length,
a,
b;
if (f == null) {
while (++i < n) if ((b = array[i]) != null && b >= b) { a = b; break; }
while (++i < n) if ((b = array[i]) != null && a > b) a = b;
}
else {
while (++i < n) if ((b = f(array[i], i, array)) != null && b >= b) { a = b; break; }
while (++i < n) if ((b = f(array[i], i, array)) != null && a > b) a = b;
}
return a;
}
function pairs(array) {
var i = 0, n = array.length - 1, p = array[0], pairs = new Array(n < 0 ? 0 : n);
while (i < n) pairs[i] = [p, p = array[++i]];
return pairs;
}
function permute(array, indexes) {
var i = indexes.length, permutes = new Array(i);
while (i--) permutes[i] = array[indexes[i]];
return permutes;
}
function scan(array, compare) {
if (!(n = array.length)) return;
var i = 0,
n,
j = 0,
xi,
xj = array[j];
if (!compare) compare = ascending;
while (++i < n) if (compare(xi = array[i], xj) < 0 || compare(xj, xj) !== 0) xj = xi, j = i;
if (compare(xj, xj) === 0) return j;
}
function shuffle(array, i0, i1) {
var m = (i1 == null ? array.length : i1) - (i0 = i0 == null ? 0 : +i0),
t,
i;
while (m) {
i = Math.random() * m-- | 0;
t = array[m + i0];
array[m + i0] = array[i + i0];
array[i + i0] = t;
}
return array;
}
function sum(array, f) {
var s = 0,
n = array.length,
a,
i = -1;
if (f == null) {
while (++i < n) if (a = +array[i]) s += a; // Note: zero and null are equivalent.
}
else {
while (++i < n) if (a = +f(array[i], i, array)) s += a;
}
return s;
}
function transpose(matrix) {
if (!(n = matrix.length)) return [];
for (var i = -1, m = min(matrix, length), transpose = new Array(m); ++i < m;) {
for (var j = -1, n, row = transpose[i] = new Array(n); ++j < n;) {
row[j] = matrix[j][i];
}
}
return transpose;
}
function length(d) {
return d.length;
}
function zip() {
return transpose(arguments);
}
var version = "0.7.1";
exports.version = version;
exports.bisect = bisectRight;
exports.bisectRight = bisectRight;
exports.bisectLeft = bisectLeft;
exports.ascending = ascending;
exports.bisector = bisector;
exports.descending = descending;
exports.deviation = deviation;
exports.extent = extent;
exports.histogram = histogram;
exports.thresholdFreedmanDiaconis = freedmanDiaconis;
exports.thresholdScott = scott;
exports.thresholdSturges = sturges;
exports.max = max;
exports.mean = mean;
exports.median = median;
exports.merge = merge;
exports.min = min;
exports.pairs = pairs;
exports.permute = permute;
exports.quantile = quantile;
exports.range = range;
exports.scan = scan;
exports.shuffle = shuffle;
exports.sum = sum;
exports.ticks = ticks;
exports.tickStep = tickStep;
exports.transpose = transpose;
exports.variance = variance;
exports.zip = zip;
}));
});
/*!
* assign-symbols <https://github.com/jonschlinkert/assign-symbols>
*
* Copyright (c) 2015-present, Jon Schlinkert.
* Licensed under the MIT License.
*/
const toString = Object.prototype.toString;
const isEnumerable = Object.prototype.propertyIsEnumerable;
const getSymbols = Object.getOwnPropertySymbols;
var assignSymbols = (target, ...args) => {
if (!isObject(target)) {
throw new TypeError('expected the first argument to be an object');
}
if (args.length === 0 || typeof Symbol !== 'function' || typeof getSymbols !== 'function') {
return target;
}
for (let arg of args) {
let names = getSymbols(arg);
for (let key of names) {
if (isEnumerable.call(arg, key)) {
target[key] = arg[key];
}
}
}
return target;
};
function isObject(val) {
return typeof val === 'function' || toString.call(val) === '[object Object]' || Array.isArray(val);
}
createCommonjsModule(function (module) {
const toString = Object.prototype.toString;
const isValidKey = key => {
return key !== '__proto__' && key !== 'constructor' && key !== 'prototype';
};
const assign = module.exports = (target, ...args) => {
let i = 0;
if (isPrimitive(target)) target = args[i++];
if (!target) target = {};
for (; i < args.length; i++) {
if (isObject(args[i])) {
for (const key of Object.keys(args[i])) {
if (isValidKey(key)) {
if (isObject(target[key]) && isObject(args[i][key])) {
assign(target[key], args[i][key]);
} else {
target[key] = args[i][key];
}
}
}
assignSymbols(target, args[i]);
}
}
return target;
};
function isObject(val) {
return typeof val === 'function' || toString.call(val) === '[object Object]';
}
function isPrimitive(val) {
return typeof val === 'object' ? val === null : typeof val !== 'function';
}
});
/**
* Parse a text-file and convert it to an array of XY points

@@ -49,2 +671,4 @@ * @param {string} text - csv or tsv strings

* @param {number} [options.yColumn = 1] - A number that specifies the y column
* @param {boolean} [options.bestGuess=false] Will try to guess which columns are the best
* @param {number} [options.numberColumns=Number.MAX_SAFE_INTEGER] If the file has 10 columns and you specify here 2 it will reflow the file
* @param {number} [options.maxNumberColumns = (Math.max(xColumn, yColumn)+1)] - A number that specifies the maximum number of y columns

@@ -62,2 +686,4 @@ * @param {number} [options.minNumberColumns = (Math.min(xColumn, yColumn)+1)] - A number that specifies the minimum number of y columns

keepInfo = false,
bestGuess = false,
numberColumns = Number.MAX_SAFE_INTEGER,
maxNumberColumns = Number.MAX_SAFE_INTEGER,

@@ -72,5 +698,5 @@ minNumberColumns = 2,

let maxY = Number.MIN_VALUE;
let result = { x: [], y: [] };
let matrix = [];
let info = [];
let position = 0;
for (let l = 0; l < lines.length; l++) {

@@ -86,17 +712,59 @@ let line = lines[l].trim();

fields &&
fields.length >= minNumberColumns &&
fields.length >= minNumberColumns && // we filter lines that have not enough or too many columns
fields.length <= maxNumberColumns
) {
let x = parseFloat(fields[xColumn].replace(',', '.'));
let y = parseFloat(fields[yColumn].replace(',', '.'));
if (y > maxY) maxY = y;
result.x.push(x);
result.y.push(y);
matrix.push(fields.map((value) => parseFloat(value.replace(',', '.'))));
position++;
}
} else if (line) {
info.push({ position: result.x.length, value: line });
info.push({ position, value: line });
}
}
if (bestGuess) {
if (
matrix[0] &&
matrix[0].length === 3 &&
options.xColumn === undefined &&
options.yColumn === undefined
) {
// is the first column a seuqnetial number ?
let skipFirstColumn = true;
for (let i = 0; i < matrix.length - 1; i++) {
if (Math.abs(matrix[i][0] - matrix[i + 1][0]) !== 1) {
skipFirstColumn = false;
}
}
if (skipFirstColumn) {
xColumn = 1;
yColumn = 2;
}
}
if (matrix[0] && matrix[0].length > 3) {
let xs = [];
for (let row of matrix) {
for (let i = xColumn; i < row.length; i += 2) {
xs.push(row[i]);
}
}
if (xIsMonotone(xs)) {
numberColumns = 2;
}
}
}
if (numberColumns) {
const newMatrix = [];
for (const row of matrix) {
for (let i = 0; i < row.length; i += numberColumns) {
newMatrix.push(row.slice(i, i + numberColumns));
}
}
matrix = newMatrix;
}
const result = {
x: matrix.map((row) => row[xColumn]),
y: matrix.map((row) => row[yColumn]),
};
if (uniqueX$1) {

@@ -107,2 +775,3 @@ uniqueX(result);

if (rescale) {
let maxY = max(result.y);
for (let i = 0; i < result.y.length; i++) {

@@ -109,0 +778,0 @@ result.y[i] /= maxY;

35

package.json
{
"name": "xy-parser",
"version": "3.0.0",
"version": "3.1.0",
"description": "Parse a text-file and convert it to an array of XY points",

@@ -23,3 +23,3 @@ "main": "lib/index.js",

"type": "git",
"url": "git+https://github.com/cheminfo-js/xy-parser.git"
"url": "git+https://github.com/cheminfo/xy-parser.git"
},

@@ -33,5 +33,5 @@ "keywords": [

"bugs": {
"url": "https://github.com/cheminfo-js/xy-parser/issues"
"url": "https://github.com/cheminfo/xy-parser/issues"
},
"homepage": "https://github.com/cheminfo-js/xy-parser#readme",
"homepage": "https://github.com/cheminfo/xy-parser#readme",
"jest": {

@@ -41,15 +41,16 @@ "testEnvironment": "node"

"devDependencies": {
"@types/jest": "^26.0.21",
"babel-plugin-transform-es2015-modules-commonjs": "^6.26.2",
"cheminfo-build": "^1.0.3",
"cheminfo-build": "^1.1.10",
"cheminfo-tools": "^1.23.3",
"codecov": "^3.6.1",
"eslint": "^6.5.1",
"eslint-config-cheminfo": "^2.0.3",
"eslint-plugin-import": "^2.18.2",
"eslint-plugin-jest": "^22.17.0",
"eslint-plugin-no-only-tests": "^2.3.1",
"eslint-plugin-prettier": "^3.1.1",
"jest": "^24.9.0",
"prettier": "^1.18.2",
"rollup": "^1.23.1",
"codecov": "^3.8.1",
"eslint": "^7.22.0",
"eslint-config-cheminfo": "^5.2.3",
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-jest": "^24.3.2",
"eslint-plugin-no-only-tests": "^2.4.0",
"eslint-plugin-prettier": "^3.3.1",
"jest": "^26.6.3",
"prettier": "^2.2.1",
"rollup": "^2.42.0",
"rollup-plugin-commonjs": "^10.1.0",

@@ -59,4 +60,6 @@ "rollup-plugin-node-resolve": "^5.2.0"

"dependencies": {
"ml-arrayxy-uniquex": "1.0.1"
"ml-array-max": "^1.2.2",
"ml-arrayxy-uniquex": "1.0.2",
"ml-spectra-processing": "^5.8.0"
}
}
# xy-parser
[![NPM version][npm-image]][npm-url]
[![build status][travis-image]][travis-url]
[![Test coverage][codecov-image]][codecov-url]
[![npm download][download-image]][download-url]
[![NPM version][npm-image]][npm-url]
[![build status][travis-image]][travis-url]
[![Test coverage][codecov-image]][codecov-url]
[![npm download][download-image]][download-url]

@@ -15,5 +15,7 @@ Parse a text-file and convert it to an array of XY points.

## Usage
```js
import {parseXY} from 'xy-parser';
const data = `1 2
import { parseXY } from "xy-parser";
const data = `My file
1 2
3 4

@@ -24,22 +26,43 @@ 5 6

/* result ->
{
x: [1, 3, 5, 7],
y: [2, 4, 6, 8]
{
x: [1, 3, 5, 7],
y: [2, 4, 6, 8]
}
}
*/
const result2 = parseXY(data, { keepInfo: true });
/* result2 ->
data: {
x: [1, 3, 5, 7],
y: [2, 4, 6, 8]
},
info: [
'My file'
]
}
*/
```
## [API Documentation](https://cheminfo-js.github.io/xy-parser/)
The `bestGuess` option will try to determine which columns should be used.
If there are 3 columns and the first column is a sequential number starting at '1' it looks
like this is a line number, we will ignore it.
If there are many columns maybe we have a format like X1, Y1, X2, Y2, ... in this cases if one
column on two is a monotone series we will parse it correctly.
## [API Documentation](https://cheminfo.github.io/xy-parser/)
## License
[MIT](./LICENSE)
[MIT](./LICENSE)
[npm-image]: https://img.shields.io/npm/v/xy-parser.svg?style=flat-square
[npm-url]: https://www.npmjs.com/package/xy-parser
[travis-image]: https://img.shields.io/travis/cheminfo-js/xy-parser/master.svg?style=flat-square
[travis-url]: https://travis-ci.org/cheminfo-js/xy-parser
[codecov-image]: https://img.shields.io/codecov/c/github/cheminfo-js/xy-parser.svg?style=flat-square
[codecov-url]: https://codecov.io/gh/cheminfo-js/xy-parser
[travis-image]: https://img.shields.io/travis/cheminfo/xy-parser/master.svg?style=flat-square
[travis-url]: https://travis-ci.org/cheminfo/xy-parser
[codecov-image]: https://img.shields.io/codecov/c/github/cheminfo/xy-parser.svg?style=flat-square
[codecov-url]: https://codecov.io/gh/cheminfo/xy-parser
[download-image]: https://img.shields.io/npm/dm/xy-parser.svg?style=flat-square
[download-url]: https://www.npmjs.com/package/xy-parser

@@ -40,3 +40,3 @@ import { readFileSync } from 'fs';

test('Test with some spaces', () => {
test('with some spaces', () => {
let filename = 'text4.txt';

@@ -52,3 +52,3 @@ let data = readFileSync(path + filename).toString();

test('Test with some spaces and taking second and third column', () => {
test('with some spaces and taking second and third column', () => {
let filename = 'text5.txt';

@@ -63,3 +63,3 @@ let data = readFileSync(path + filename).toString();

test('Test with some non numeric lines', () => {
test('with some non numeric lines', () => {
let filename = 'text6.txt';

@@ -71,3 +71,3 @@ let data = readFileSync(path + filename).toString();

test('Test with some non numeric lines and keeping info', () => {
test('with some non numeric lines and keeping info', () => {
let filename = 'text6.txt';

@@ -88,3 +88,3 @@ let data = readFileSync(path + filename).toString();

test('Test with comma as decimal delimiter', () => {
test('with comma as decimal delimiter', () => {
let filename = 'text7.txt';

@@ -96,3 +96,3 @@ let data = readFileSync(path + filename).toString();

test('Test with scientific notation', () => {
test('with scientific notation', () => {
let filename = 'text8.txt';

@@ -109,3 +109,3 @@ let data = readFileSync(path + filename).toString();

test('Test large IV scientific notation file', () => {
test('large IV scientific notation file', () => {
let filename = 'text9.txt';

@@ -112,0 +112,0 @@ let data = readFileSync(path + filename).toString();

@@ -0,3 +1,4 @@

import mlArrayMax from 'ml-array-max';
import uniqueXFunction from 'ml-arrayxy-uniquex';
import { xIsMonotone } from 'ml-spectra-processing';
/**

@@ -11,2 +12,4 @@ * Parse a text-file and convert it to an array of XY points

* @param {number} [options.yColumn = 1] - A number that specifies the y column
* @param {boolean} [options.bestGuess=false] Will try to guess which columns are the best
* @param {number} [options.numberColumns=Number.MAX_SAFE_INTEGER] If the file has 10 columns and you specify here 2 it will reflow the file
* @param {number} [options.maxNumberColumns = (Math.max(xColumn, yColumn)+1)] - A number that specifies the maximum number of y columns

@@ -24,2 +27,4 @@ * @param {number} [options.minNumberColumns = (Math.min(xColumn, yColumn)+1)] - A number that specifies the minimum number of y columns

keepInfo = false,
bestGuess = false,
numberColumns = Number.MAX_SAFE_INTEGER,
maxNumberColumns = Number.MAX_SAFE_INTEGER,

@@ -34,5 +39,5 @@ minNumberColumns = 2,

let maxY = Number.MIN_VALUE;
let result = { x: [], y: [] };
let matrix = [];
let info = [];
let position = 0;
for (let l = 0; l < lines.length; l++) {

@@ -48,17 +53,59 @@ let line = lines[l].trim();

fields &&
fields.length >= minNumberColumns &&
fields.length >= minNumberColumns && // we filter lines that have not enough or too many columns
fields.length <= maxNumberColumns
) {
let x = parseFloat(fields[xColumn].replace(',', '.'));
let y = parseFloat(fields[yColumn].replace(',', '.'));
if (y > maxY) maxY = y;
result.x.push(x);
result.y.push(y);
matrix.push(fields.map((value) => parseFloat(value.replace(',', '.'))));
position++;
}
} else if (line) {
info.push({ position: result.x.length, value: line });
info.push({ position, value: line });
}
}
if (bestGuess) {
if (
matrix[0] &&
matrix[0].length === 3 &&
options.xColumn === undefined &&
options.yColumn === undefined
) {
// is the first column a seuqnetial number ?
let skipFirstColumn = true;
for (let i = 0; i < matrix.length - 1; i++) {
if (Math.abs(matrix[i][0] - matrix[i + 1][0]) !== 1) {
skipFirstColumn = false;
}
}
if (skipFirstColumn) {
xColumn = 1;
yColumn = 2;
}
}
if (matrix[0] && matrix[0].length > 3) {
let xs = [];
for (let row of matrix) {
for (let i = xColumn; i < row.length; i += 2) {
xs.push(row[i]);
}
}
if (xIsMonotone(xs)) {
numberColumns = 2;
}
}
}
if (numberColumns) {
const newMatrix = [];
for (const row of matrix) {
for (let i = 0; i < row.length; i += numberColumns) {
newMatrix.push(row.slice(i, i + numberColumns));
}
}
matrix = newMatrix;
}
const result = {
x: matrix.map((row) => row[xColumn]),
y: matrix.map((row) => row[yColumn]),
};
if (uniqueX) {

@@ -69,2 +116,3 @@ uniqueXFunction(result);

if (rescale) {
let maxY = mlArrayMax(result.y);
for (let i = 0; i < result.y.length; i++) {

@@ -71,0 +119,0 @@ result.y[i] /= maxY;

Sorry, the diff of this file is not supported yet

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