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

brukerconverter

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

brukerconverter - npm Package Compare versions

Comparing version 3.2.0 to 3.3.0

@@ -8,2 +8,11 @@ ## [3.1.0](https://github.com/cheminfo/brukerconverter/compare/v3.0.0...v3.1.0) (2021-03-06)

## [3.3.0](https://www.github.com/cheminfo/brukerconverter/compare/v3.2.0...v3.3.0) (2021-04-29)
### Features
* **keepZip:** add option to keep zip binary file per each spectrum ([b2554bf](https://www.github.com/cheminfo/brukerconverter/commit/b2554bf5b0b13624fb370c6c6b425ce0b7eb1e1c))
* one file one function and documentation ([#25](https://www.github.com/cheminfo/brukerconverter/issues/25)) ([0e09fad](https://www.github.com/cheminfo/brukerconverter/commit/0e09fad20c32182ac572458022eeec2e4df5fe5a))
* update dependencies ([67cb30e](https://www.github.com/cheminfo/brukerconverter/commit/67cb30e57dbf3f2fb63ba9b13da62a9332f992ab))
## [3.2.0](https://www.github.com/cheminfo/brukerconverter/compare/v3.1.1...v3.2.0) (2021-03-18)

@@ -10,0 +19,0 @@

@@ -5,8 +5,10 @@ 'use strict';

var JSZip$1 = require('jszip/dist/jszip');
var jcampconverter = require('jcampconverter');
var iobuffer = require('iobuffer');
var jcampconverter = require('jcampconverter');
var JSZip = require('jszip/dist/jszip');
var JSZip = require('jszip');
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
var JSZip__default$1 = /*#__PURE__*/_interopDefaultLegacy(JSZip$1);
var JSZip__default = /*#__PURE__*/_interopDefaultLegacy(JSZip);

@@ -28,3 +30,3 @@

for (let i = 0; i < ySize; i++) {
z[i] = new Array(xSize);
z[i] = new Float64Array(xSize);
for (let j = 0; j < xSize; j++) {

@@ -246,149 +248,176 @@ z[i][j] = spectra[i].data[j * 2 + 1];

const BINARY = 1;
const TEXT = 2;
function add2D(result, options) {
let zData = convertTo3DZ(result.spectra);
if (!options.noContours) {
result.contourLines = generateContourLines(zData);
}
result.minMax = zData;
}
function convertZip(zipFile, options = {}) {
const jsZip = new JSZip__default['default']();
function parseData(file, options) {
let { keepRecordsRegExp = /.*/ } = options;
let result = jcampconverter.convert(file, {
keepRecordsRegExp: keepRecordsRegExp,
});
return result.flatten.length === 0 ? {} : result.flatten[0];
}
return jsZip.loadAsync(zipFile, options).then((zip) => {
let files = {
ser: BINARY,
fid: BINARY,
acqus: TEXT,
acqu2s: TEXT,
procs: TEXT,
proc2s: TEXT,
'1r': BINARY,
'1i': BINARY,
'2rr': BINARY,
function ensureIOBuffer(data) {
if (data instanceof Array || data instanceof Uint8Array) {
data = new ArrayBuffer(data);
}
if (data instanceof ArrayBuffer) {
return new iobuffer.IOBuffer(data);
}
return data;
}
function setFIDSpectrumData(file, spectra) {
file = ensureIOBuffer(file);
let td = parseInt(spectra.meta.TD[0], 10);
let SW_H = parseFloat(spectra.meta.SW_h[0]);
let SF = parseFloat(spectra.meta.SFO1[0]);
spectra.meta.DATATYPE = 'NMR FID';
let DW = 1 / (2 * SW_H);
let AQ = td * DW;
let endian = parseInt(spectra.meta.BYTORDA, 10);
endian = endian ? 0 : 1;
if (endian) {
file.setLittleEndian();
} else {
file.setBigEndian();
}
let nbSubSpectra = spectra.meta.nbSubSpectra ? spectra.meta.nbSubSpectra : 1;
spectra.spectra = new Array(nbSubSpectra);
for (let j = 0; j < nbSubSpectra / 2; j++) {
let toSave = {
dataType: 'NMR FID',
dataTable: '(X++(R..R))',
nbPoints: td,
firstX: 0,
lastX: AQ,
nucleus: spectra.meta.NUC1,
xUnit: 'Sec',
yUnit: 'Arbitrary',
data: [new Float64Array(2 * td)],
isXYdata: true,
observeFrequency: SF,
title: spectra.meta.TITLE,
deltaX: DW,
};
let folders = zip.filter(function (relativePath) {
if (relativePath.match('__MACOSX')) return false;
if (
relativePath.endsWith('ser') ||
relativePath.endsWith('fid') ||
relativePath.endsWith('1r') ||
relativePath.endsWith('2rr')
) {
return true;
}
return false;
});
spectra.spectra[j * 2] = toSave;
let spectra = new Array(folders.length);
toSave = {
dataType: 'NMR FID',
dataTable: '(X++(I..I))',
nbPoints: td,
firstX: 0,
lastX: AQ,
nucleus: spectra.meta.NUC1,
xUnit: 'Sec',
yUnit: 'Arbitrary',
data: new Float64Array(2 * td),
isXYdata: true,
directFrequency: SF,
title: spectra.meta.TITLE,
deltaX: DW,
};
spectra.spectra[j * 2 + 1] = toSave;
for (let i = 0; i < folders.length; ++i) {
let promises = [];
let name = folders[i].name;
name = name.substr(0, name.lastIndexOf('/') + 1);
promises.push(name);
let currFolder = zip.folder(name);
let currFiles = currFolder.filter(function (relativePath) {
return files[relativePath] ? true : false;
});
if (name.indexOf('pdata') >= 0) {
promises.push('acqus');
promises.push(
zip.file(name.replace(/pdata\/[0-9]+\//, 'acqus')).async('string'),
);
let acqu2s = zip.file(name.replace(/pdata\/[0-9]+\//, 'acqu2s'));
if (acqu2s) {
promises.push('acqu2s');
promises.push(acqu2s.async('string'));
}
let i = 0;
let x = 0;
for (; file.available(8) && i < td; i++, x = i * DW) {
let y = file.readInt32();
if (y === null || isNaN(y)) {
y = 0;
}
for (let j = 0; j < currFiles.length; ++j) {
let idx = currFiles[j].name.lastIndexOf('/');
name = currFiles[j].name.substr(idx + 1);
promises.push(name);
if (files[name] === BINARY) {
promises.push(currFiles[j].async('arraybuffer'));
} else {
promises.push(currFiles[j].async('string'));
}
spectra.spectra[j * 2].data[2 * i + 1] = y;
spectra.spectra[j * 2].data[2 * i] = x;
y = file.readInt32();
if (y === null || isNaN(y)) {
y = 0;
}
spectra[i] = Promise.all(promises).then((result) => {
let brukerFiles = {};
for (let k = 1; k < result.length; k += 2) {
name = result[k];
brukerFiles[name] = result[k + 1];
}
return {
filename: result[0],
value: convertFolder(brukerFiles, options),
};
});
spectra.spectra[j * 2 + 1].data[2 * i + 1] = y;
spectra.spectra[j * 2 + 1].data[2 * i] = x;
}
return Promise.all(spectra);
});
}
function convertFolder(brukerFiles, options) {
options = options || {};
let start = new Date();
let result;
if (brukerFiles.ser || brukerFiles['2rr']) {
result = convert2D(brukerFiles, options);
} else if (brukerFiles['1r'] || brukerFiles['1i'] || brukerFiles.fid) {
result = convert1D(brukerFiles, options);
} else {
throw new RangeError('The current files are invalid');
}
//normalizing info
result.meta.DATE = parseFloat(result.meta.DATE);
if (result.meta.GRPDLY) {
result.meta.GRPDLY = parseFloat(result.meta.GRPDLY);
result.meta.DSPFVS = parseFloat(result.meta.DSPFVS);
result.meta.DECIM = parseFloat(result.meta.DECIM);
}
for (let key in result.meta) {
if (!Array.isArray(result.meta[key])) continue;
if (result.meta[key].length === 1) {
result.meta[key] = result.meta[key][0];
} else if (
typeof result.meta[key][0] === 'string' &&
result.meta[key][0].indexOf('(0..') > -1
) {
result.meta[key] = result.meta[key][0];
for (; i < td; i++, x = i * DW) {
spectra.spectra[j * 2].data[2 * i + 1] = 0;
spectra.spectra[j * 2].data[2 * i] = x;
spectra.spectra[j * 2 + 1].data[2 * i + 1] = 0;
spectra.spectra[j * 2 + 1].data[2 * i] = x;
}
}
}
if (result.twoD) {
add2D(result, options);
if (result.profiling) {
result.profiling.push({
action: 'Finished countour plot calculation',
time: new Date() - start,
});
}
if (!options.keepSpectra) {
delete result.spectra;
}
function setXYSpectrumData(file, spectra, real) {
file = ensureIOBuffer(file);
let td = parseInt(spectra.meta.SI, 10);
let swP = parseFloat(spectra.meta.SW_p);
let sf = parseFloat(spectra.meta.SF);
let bf = sf;
let offset = spectra.shiftOffsetVal || parseFloat(spectra.meta.OFFSET);
spectra.meta.observeFrequency = sf;
spectra.meta.brukerReference = bf;
spectra.meta.DATATYPE = 'NMR Spectrum';
let endian = parseInt(spectra.meta.BYTORDP, 10);
endian = endian ? 0 : 1;
let nbSubSpectra = spectra.meta.nbSubSpectra ? spectra.meta.nbSubSpectra : 1;
if (endian) {
file.setLittleEndian();
} else {
file.setBigEndian();
}
for (let i = 0; i < nbSubSpectra; i++) {
let toSave = {
dataType: 'NMR Spectrum',
dataTable: '(X++(R..R))',
nbPoints: td,
firstX: offset,
lastX: offset - swP / sf,
xUnit: 'PPM',
yUnit: 'Arbitrary',
data: new Float64Array(td * 2),
isXYdata: true,
observeFrequency: sf,
title: spectra.meta.TITLE,
deltaX: -(swP / sf) / (td - 1),
};
let spectra = result.spectra;
let x = offset;
let deltaX = toSave.deltaX;
if (options.xy && !!spectra) {
//the spectraData should not be a oneD array but an object with x and y
if (spectra.length > 0) {
for (let i = 0; i < spectra.length; i++) {
let spectrum = spectra[i];
if (spectrum.data.length) {
let data = spectrum.data;
let newData = {
x: new Array(data.length / 2),
y: new Array(data.length / 2),
};
for (let k = 0; k < data.length; k = k + 2) {
newData.x[k / 2] = data[k];
newData.y[k / 2] = data[k + 1];
}
spectrum.data = newData;
if (real) {
for (let k = 0; k < td; ++k) {
toSave.data[2 * k] = x;
toSave.data[2 * k + 1] = file.readInt32();
if (toSave.data[2 * k + 1] === null || isNaN(toSave.data[2 * k + 1])) {
toSave.data[2 * k + 1] = 0;
}
x += deltaX;
}
} else {
for (let k = 0; k < td; ++k) {
toSave.data[2 * k] = x;
toSave.data[2 * k + 1] = file.readInt32();
if (toSave.data[2 * k + 1] === null || isNaN(toSave.data[2 * k + 1])) {
toSave.data[2 * k + 1] = 0;
}
x += deltaX;
}
}
spectra.spectra.push(toSave);
}
return result;
}

@@ -399,3 +428,5 @@

let temp = parseData(files.acqus || '', options);
if (!Object.keys(result).length) result = temp;
if (!Object.keys(result).length) {
result = temp;
}

@@ -426,2 +457,16 @@ for (let key in result.meta) {

function mergeMetadata(main, complement) {
for (let key in complement.meta) {
if (main.meta[key]) {
if (!Array.isArray(main.meta[key])) {
main.meta[key] = [main.meta[key]];
}
main.meta[key].push(complement.meta[key]);
} else if (main.meta[key] === undefined) {
main.meta[key] = [complement.meta[key]];
}
}
return main;
}
function convert2D(files, options) {

@@ -440,3 +485,5 @@ let temp, temp2, result;

if (!result) result = temp;
if (!result) {
result = temp;
}
for (let key in temp.meta) {

@@ -458,5 +505,9 @@ if (result.meta[key] === undefined) {

// eslint-disable-next-line camelcase
if (!result.meta.SW_p) result.meta.SW_p = result.meta.SW_h;
if (!result.meta.SF) result.meta.SF = result.meta.SFO1;
if (!result.meta.SW_p) {
// eslint-disable-next-line camelcase
result.meta.SW_p = result.meta.SW_h;
}
if (!result.meta.SF) {
result.meta.SF = result.meta.SFO1;
}

@@ -510,194 +561,242 @@ let firstY, lastY, xOffset, yOffset;

function setXYSpectrumData(file, spectra, real) {
file = ensureIOBuffer(file);
let td = parseInt(spectra.meta.SI, 10);
let swP = parseFloat(spectra.meta.SW_p);
let sf = parseFloat(spectra.meta.SF);
let bf = sf;
let offset = spectra.shiftOffsetVal || parseFloat(spectra.meta.OFFSET);
/**
* Extract information and data from bruker files.
* @param {object} brukerFiles - Needed bruker files to parse raw data.
* @param {object} [options = {}] - options.
* @param {boolean} [options.xy] - if true, spectra data is a object with x and y
* @param {RegExp} [options.keepRecordsRegExp='\/.*\/'] - regular expresion to parse the metadata of the spectrum.
* @param {boolean} [options.noContours=false] - if true the contour data is not generated.
* @returns
*/
spectra.meta.observeFrequency = sf;
spectra.meta.brukerReference = bf;
spectra.meta.DATATYPE = 'NMR Spectrum';
function convertFolder(brukerFiles, options = {}) {
let start = new Date();
let result;
if (brukerFiles.ser || brukerFiles['2rr']) {
result = convert2D(brukerFiles, options);
} else if (brukerFiles['1r'] || brukerFiles['1i'] || brukerFiles.fid) {
result = convert1D(brukerFiles, options);
} else {
throw new RangeError('The current files are invalid');
}
//normalizing info
result.meta.DATE = parseFloat(result.meta.DATE);
if (result.meta.GRPDLY) {
result.meta.GRPDLY = parseFloat(result.meta.GRPDLY);
result.meta.DSPFVS = parseFloat(result.meta.DSPFVS);
result.meta.DECIM = parseFloat(result.meta.DECIM);
}
let endian = parseInt(spectra.meta.BYTORDP, 10);
endian = endian ? 0 : 1;
for (let key in result.meta) {
if (!Array.isArray(result.meta[key])) {
continue;
}
if (result.meta[key].length === 1) {
result.meta[key] = result.meta[key][0];
} else if (
typeof result.meta[key][0] === 'string' &&
result.meta[key][0].indexOf('(0..') > -1
) {
result.meta[key] = result.meta[key][0];
}
}
let nbSubSpectra = spectra.meta.nbSubSpectra ? spectra.meta.nbSubSpectra : 1;
if (endian) {
file.setLittleEndian();
} else {
file.setBigEndian();
if (result.twoD) {
add2D(result, options);
if (result.profiling) {
result.profiling.push({
action: 'Finished countour plot calculation',
time: new Date() - start,
});
}
if (!options.keepSpectra) {
delete result.spectra;
}
}
for (let i = 0; i < nbSubSpectra; i++) {
let toSave = {
dataType: 'NMR Spectrum',
dataTable: '(X++(R..R))',
nbPoints: td,
firstX: offset,
lastX: offset - swP / sf,
xUnit: 'PPM',
yUnit: 'Arbitrary',
data: new Array(td * 2),
isXYdata: true,
observeFrequency: sf,
title: spectra.meta.TITLE,
deltaX: -(swP / sf) / (td - 1),
};
let x = offset;
let deltaX = toSave.deltaX;
let spectra = result.spectra;
if (real) {
for (let k = 0; k < td; ++k) {
toSave.data[2 * k] = x;
toSave.data[2 * k + 1] = file.readInt32();
if (toSave.data[2 * k + 1] === null || isNaN(toSave.data[2 * k + 1])) {
toSave.data[2 * k + 1] = 0;
if (options.xy && !!spectra) {
//the spectraData should not be a oneD Array but an object with x and y
if (spectra.length > 0) {
for (let i = 0; i < spectra.length; i++) {
let spectrum = spectra[i];
if (spectrum.data.length) {
let data = spectrum.data;
let newData = {
x: new Float64Array(data.length / 2),
y: new Float64Array(data.length / 2),
};
for (let k = 0; k < data.length; k = k + 2) {
newData.x[k / 2] = data[k];
newData.y[k / 2] = data[k + 1];
}
spectrum.data = newData;
}
x += deltaX;
}
} else {
for (let k = 0; k < td; ++k) {
toSave.data[2 * k] = x;
toSave.data[2 * k + 1] = file.readInt32();
if (toSave.data[2 * k + 1] === null || isNaN(toSave.data[2 * k + 1])) {
toSave.data[2 * k + 1] = 0;
}
x += deltaX;
}
}
spectra.spectra.push(toSave);
}
}
const { file } = brukerFiles;
if (file) {
result.source = { file };
}
function parseData(file, options) {
let keepRecordsRegExp = /.*/;
if (options.keepRecordsRegExp) keepRecordsRegExp = options.keepRecordsRegExp;
let result = jcampconverter.convert(file, {
keepRecordsRegExp: keepRecordsRegExp,
});
return result.flatten.length === 0 ? {} : result.flatten[0];
return result;
}
function setFIDSpectrumData(file, spectra) {
file = ensureIOBuffer(file);
let td = parseInt(spectra.meta.TD[0], 10);
let SW_H = parseFloat(spectra.meta.SW_h[0]);
function extractFilePaths(pathSpectrum, options = {}) {
let { zipFiles } = options;
let SF = parseFloat(spectra.meta.SFO1[0]);
const expnoCheck = pathSpectrum.replace(
/([.*\w+/]*)([0-9]+\/)[pdata|fid|ser]\/*.*/,
'$1$2',
);
spectra.meta.DATATYPE = 'NMR FID';
const procnoCheck = pathSpectrum.match('pdata')
? pathSpectrum.replace(/([.*\w+/]*[0-9]+\/pdata\/[0-9]+\/)*.*/, '$1')
: null;
let DW = 1 / (2 * SW_H);
let AQ = td * DW;
let filePaths = [];
for (let file in zipFiles) {
if (
expnoCheck !== file.replace(/([.*/]*)((?<!pdata\/)[0-9]+\/).*/, '$1$2')
) {
continue;
}
let endian = parseInt(spectra.meta.BYTORDA, 10);
endian = endian ? 0 : 1;
if (file.match('pdata')) {
if (!procnoCheck) {
if (file.match(/[1|2]+[i|r]+[i|r]*/)) continue;
} else if (
procnoCheck !==
file.replace(
/([.*\w+/]*)(?<!pdata)([0-9]+\/)[pdata|fid|ser]*\/*.*/,
'$1$2',
)
) {
continue;
}
}
if (file.endsWith('/')) continue;
filePaths.push(file);
}
return filePaths;
}
if (endian) {
file.setLittleEndian();
} else {
file.setBigEndian();
async function extractSingleSpectrumZip(pathSpectrum, options = {}) {
let { zipFiles } = options;
const filePaths = extractFilePaths(pathSpectrum, { zipFiles });
let zipFolder = new JSZip__default['default']();
for (let file of filePaths) {
zipFolder.file(file, await zipFiles[file].async('arraybuffer'));
}
let nbSubSpectra = spectra.meta.nbSubSpectra ? spectra.meta.nbSubSpectra : 1;
spectra.spectra = new Array(nbSubSpectra);
return {
extension: 'zip',
name: pathSpectrum,
binary: await zipFolder.generateAsync({
type: 'uint8array',
compression: 'DEFLATE',
compressionOptions: { level: 9 },
}),
};
}
for (let j = 0; j < nbSubSpectra / 2; j++) {
let toSave = {
dataType: 'NMR FID',
dataTable: '(X++(R..R))',
nbPoints: td,
firstX: 0,
lastX: AQ,
nucleus: spectra.meta.NUC1,
xUnit: 'Sec',
yUnit: 'Arbitrary',
data: [new Array(2 * td)], // [{x:new Array(td),y:new Array(td)}],
isXYdata: true,
observeFrequency: SF,
title: spectra.meta.TITLE,
deltaX: DW,
};
spectra.spectra[j * 2] = toSave;
const BINARY = 1;
const TEXT = 2;
toSave = {
dataType: 'NMR FID',
dataTable: '(X++(I..I))',
nbPoints: td,
firstX: 0,
lastX: AQ,
nucleus: spectra.meta.NUC1,
xUnit: 'Sec',
yUnit: 'Arbitrary',
data: new Array(2 * td),
isXYdata: true,
directFrequency: SF,
title: spectra.meta.TITLE,
deltaX: DW,
/**
* Load a zip file using jszip and looking for folders contaning bruker files to parse.
* @param {*} zipFile - binary or base64 file of the bruker zip file.
* @param {object} [options={}] - options for jszip and convertFolder functions.
* @param {boolean} [options.keepOriginal=false] - options to keep a smaller zip file per spectrum.
* @returns {Promise} - Array of spectrum parsed from fid, ser, 2rr, 1r bruker files.
*/
function convertZip(zipFile, options = {}) {
const { keepOriginal = false } = options;
const jsZip = new JSZip__default$1['default']();
return jsZip.loadAsync(zipFile, options).then((zip) => {
let files = {
ser: BINARY,
fid: BINARY,
acqus: TEXT,
acqu2s: TEXT,
procs: TEXT,
proc2s: TEXT,
'1r': BINARY,
'1i': BINARY,
'2rr': BINARY,
};
spectra.spectra[j * 2 + 1] = toSave;
let folders = zip.filter(function (relativePath) {
if (relativePath.match('__MACOSX')) return false;
if (
relativePath.endsWith('ser') ||
relativePath.endsWith('fid') ||
relativePath.endsWith('1r') ||
relativePath.endsWith('2rr')
) {
return true;
}
return false;
});
let i = 0;
let x = 0;
for (; file.available(8) && i < td; i++, x = i * DW) {
let y = file.readInt32();
if (y === null || isNaN(y)) {
y = 0;
let spectra = new Array(folders.length);
for (let i = 0; i < folders.length; ++i) {
let promises = [];
let name = folders[i].name;
name = name.substr(0, name.lastIndexOf('/') + 1);
promises.push(name);
let currFolder = zip.folder(name);
let currFiles = currFolder.filter(function (relativePath) {
return files[relativePath] ? true : false;
});
if (name.indexOf('pdata') >= 0) {
promises.push('acqus');
promises.push(
zip.file(name.replace(/pdata\/[0-9]+\//, 'acqus')).async('string'),
);
let acqu2s = zip.file(name.replace(/pdata\/[0-9]+\//, 'acqu2s'));
if (acqu2s) {
promises.push('acqu2s');
promises.push(acqu2s.async('string'));
}
}
spectra.spectra[j * 2].data[2 * i + 1] = y;
spectra.spectra[j * 2].data[2 * i] = x;
y = file.readInt32();
if (y === null || isNaN(y)) {
y = 0;
for (let j = 0; j < currFiles.length; ++j) {
let idx = currFiles[j].name.lastIndexOf('/');
name = currFiles[j].name.substr(idx + 1);
promises.push(name);
if (files[name] === BINARY) {
promises.push(currFiles[j].async('arraybuffer'));
} else {
promises.push(currFiles[j].async('string'));
}
}
spectra.spectra[j * 2 + 1].data[2 * i + 1] = y;
spectra.spectra[j * 2 + 1].data[2 * i] = x;
}
if (keepOriginal) {
promises.push('file');
promises.push(
extractSingleSpectrumZip(folders[i].name, { zipFiles: zip.files }),
);
}
spectra[i] = Promise.all(promises).then((result) => {
let brukerFiles = {};
for (let k = 1; k < result.length; k += 2) {
name = result[k];
brukerFiles[name] = result[k + 1];
}
for (; i < td; i++, x = i * DW) {
spectra.spectra[j * 2].data[2 * i + 1] = 0;
spectra.spectra[j * 2].data[2 * i] = x;
spectra.spectra[j * 2 + 1].data[2 * i + 1] = 0;
spectra.spectra[j * 2 + 1].data[2 * i] = x;
return {
filename: result[0],
value: convertFolder(brukerFiles, options),
};
});
}
}
return Promise.all(spectra);
});
}
function add2D(result, options) {
let zData = convertTo3DZ(result.spectra);
if (!options.noContours) {
result.contourLines = generateContourLines(zData);
}
result.minMax = zData;
}
function ensureIOBuffer(data) {
if (data instanceof Array || data instanceof Uint8Array) {
data = new ArrayBuffer(data);
}
if (data instanceof ArrayBuffer) {
return new iobuffer.IOBuffer(data);
}
return data;
}
function mergeMetadata(main, complement) {
for (let key in complement.meta) {
if (main.meta[key]) {
if (!Array.isArray(main.meta[key])) {
main.meta[key] = [main.meta[key]];
}
main.meta[key].push(complement.meta[key]);
} else if (main.meta[key] === undefined) {
main.meta[key] = [complement.meta[key]];
}
}
return main;
}
exports.convertFolder = convertFolder;
exports.convertZip = convertZip;
{
"name": "brukerconverter",
"version": "3.2.0",
"version": "3.3.0",
"description": "Parse and convert Bruker raw data",

@@ -36,20 +36,20 @@ "main": "lib/index.js",

"@babel/plugin-transform-modules-commonjs": "^7.13.8",
"@types/jest": "^26.0.20",
"@types/jest": "^26.0.23",
"bruker-data-test": "0.1.0",
"cheminfo-build": "^1.1.10",
"eslint": "^7.21.0",
"eslint": "^7.25.0",
"eslint-config-cheminfo": "^5.2.3",
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-jest": "^24.1.5",
"eslint-plugin-prettier": "^3.3.1",
"eslint-plugin-jest": "^24.3.6",
"eslint-plugin-prettier": "^3.4.0",
"jest": "^26.6.3",
"npm-run-all": "^4.1.5",
"prettier": "^2.2.1",
"rollup": "^2.40.0"
"rollup": "^2.46.0"
},
"dependencies": {
"iobuffer": "^5.0.3",
"jcampconverter": "^7.7.0",
"jcampconverter": "^8.0.2",
"jszip": "^3.6.0"
}
}

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

import { IOBuffer } from 'iobuffer';
import { convert as convertJcamp } from 'jcampconverter';
import JSZip from 'jszip/dist/jszip';
import convertTo3DZ from './convertTo3DZ';
import generateContourLines from './generateContourLines';
const BINARY = 1;
const TEXT = 2;
export function convertZip(zipFile, options = {}) {
const jsZip = new JSZip();
return jsZip.loadAsync(zipFile, options).then((zip) => {
let files = {
ser: BINARY,
fid: BINARY,
acqus: TEXT,
acqu2s: TEXT,
procs: TEXT,
proc2s: TEXT,
'1r': BINARY,
'1i': BINARY,
'2rr': BINARY,
};
let folders = zip.filter(function (relativePath) {
if (relativePath.match('__MACOSX')) return false;
if (
relativePath.endsWith('ser') ||
relativePath.endsWith('fid') ||
relativePath.endsWith('1r') ||
relativePath.endsWith('2rr')
) {
return true;
}
return false;
});
let spectra = new Array(folders.length);
for (let i = 0; i < folders.length; ++i) {
let promises = [];
let name = folders[i].name;
name = name.substr(0, name.lastIndexOf('/') + 1);
promises.push(name);
let currFolder = zip.folder(name);
let currFiles = currFolder.filter(function (relativePath) {
return files[relativePath] ? true : false;
});
if (name.indexOf('pdata') >= 0) {
promises.push('acqus');
promises.push(
zip.file(name.replace(/pdata\/[0-9]+\//, 'acqus')).async('string'),
);
let acqu2s = zip.file(name.replace(/pdata\/[0-9]+\//, 'acqu2s'));
if (acqu2s) {
promises.push('acqu2s');
promises.push(acqu2s.async('string'));
}
}
for (let j = 0; j < currFiles.length; ++j) {
let idx = currFiles[j].name.lastIndexOf('/');
name = currFiles[j].name.substr(idx + 1);
promises.push(name);
if (files[name] === BINARY) {
promises.push(currFiles[j].async('arraybuffer'));
} else {
promises.push(currFiles[j].async('string'));
}
}
spectra[i] = Promise.all(promises).then((result) => {
let brukerFiles = {};
for (let k = 1; k < result.length; k += 2) {
name = result[k];
brukerFiles[name] = result[k + 1];
}
return {
filename: result[0],
value: convertFolder(brukerFiles, options),
};
});
}
return Promise.all(spectra);
});
}
export function convertFolder(brukerFiles, options) {
options = options || {};
let start = new Date();
let result;
if (brukerFiles.ser || brukerFiles['2rr']) {
result = convert2D(brukerFiles, options);
} else if (brukerFiles['1r'] || brukerFiles['1i'] || brukerFiles.fid) {
result = convert1D(brukerFiles, options);
} else {
throw new RangeError('The current files are invalid');
}
//normalizing info
result.meta.DATE = parseFloat(result.meta.DATE);
if (result.meta.GRPDLY) {
result.meta.GRPDLY = parseFloat(result.meta.GRPDLY);
result.meta.DSPFVS = parseFloat(result.meta.DSPFVS);
result.meta.DECIM = parseFloat(result.meta.DECIM);
}
for (let key in result.meta) {
if (!Array.isArray(result.meta[key])) continue;
if (result.meta[key].length === 1) {
result.meta[key] = result.meta[key][0];
} else if (
typeof result.meta[key][0] === 'string' &&
result.meta[key][0].indexOf('(0..') > -1
) {
result.meta[key] = result.meta[key][0];
}
}
if (result.twoD) {
add2D(result, options);
if (result.profiling) {
result.profiling.push({
action: 'Finished countour plot calculation',
time: new Date() - start,
});
}
if (!options.keepSpectra) {
delete result.spectra;
}
}
let spectra = result.spectra;
if (options.xy && !!spectra) {
//the spectraData should not be a oneD array but an object with x and y
if (spectra.length > 0) {
for (let i = 0; i < spectra.length; i++) {
let spectrum = spectra[i];
if (spectrum.data.length) {
let data = spectrum.data;
let newData = {
x: new Array(data.length / 2),
y: new Array(data.length / 2),
};
for (let k = 0; k < data.length; k = k + 2) {
newData.x[k / 2] = data[k];
newData.y[k / 2] = data[k + 1];
}
spectrum.data = newData;
}
}
}
}
return result;
}
function convert1D(files, options) {
let result = parseData(files.procs || '', options);
let temp = parseData(files.acqus || '', options);
if (!Object.keys(result).length) result = temp;
for (let key in result.meta) {
result.meta[key] = [result.meta[key]];
}
for (let currKey in temp.meta) {
if (result.meta[currKey] === undefined) {
result.meta[currKey] = [temp.meta[currKey]];
}
}
if (files['1r'] || files['1i']) {
if (files['1r']) {
setXYSpectrumData(files['1r'], result, true);
}
if (files['1i']) {
setXYSpectrumData(files['1i'], result, false);
}
} else if (files.fid) {
setFIDSpectrumData(files.fid, result);
}
return result;
}
function convert2D(files, options) {
let temp, temp2, result;
if (files.proc2s && files.procs) {
result = parseData(files.procs, options);
temp = parseData(files.proc2s, options);
result = mergeMetadata(result, temp);
}
temp = parseData(files.acqus, options);
temp2 = parseData(files.acqu2s, options);
temp = mergeMetadata(temp, temp2);
if (!result) result = temp;
for (let key in temp.meta) {
if (result.meta[key] === undefined) {
result.meta[key] = temp.meta[key];
}
}
for (let key in result.meta) {
if (!Array.isArray(result.meta[key])) {
result.meta[key] = [result.meta[key]];
}
}
result.meta.nbSubSpectra = files['2rr']
? parseInt(result.meta.SI[1], 10)
: parseInt(result.meta.TD[1], 10);
// eslint-disable-next-line camelcase
if (!result.meta.SW_p) result.meta.SW_p = result.meta.SW_h;
if (!result.meta.SF) result.meta.SF = result.meta.SFO1;
let firstY, lastY, xOffset, yOffset;
if (files['2rr']) {
let sf = parseFloat(result.meta.SF[1]);
let swP = parseFloat(result.meta.SW_p[1] || result.meta.SW[1]);
yOffset = parseFloat(result.meta.OFFSET[1]);
xOffset = parseFloat(result.meta.OFFSET[0]);
firstY = yOffset;
lastY = yOffset - swP / sf;
result.meta.firstY = firstY;
result.meta.lastY = lastY;
setXYSpectrumData(files['2rr'], result, true);
} else if (files.ser) {
firstY = 0;
lastY = result.meta.nbSubSpectra;
let xWindowSize = parseFloat(result.meta.SW[0]);
let yWindowSize = parseFloat(result.meta.SW[1]);
let xTransmitterFrequency = parseFloat(result.meta.SFO1[0]);
let yTransmitterFrequency = parseFloat(result.meta.SFO1[1]);
let xTransmitterFrequencyOffset = parseFloat(result.meta.O1[0]);
let yTransmitterFrequencyOffset = parseFloat(result.meta.O1[1]);
xOffset =
xTransmitterFrequencyOffset / xTransmitterFrequency + xWindowSize / 2;
yOffset =
yTransmitterFrequencyOffset / yTransmitterFrequency + yWindowSize / 2;
setFIDSpectrumData(files.ser, result);
}
let pageValue = firstY;
let nbSubSpectra = result.meta.nbSubSpectra;
let deltaY = (lastY - firstY) / (nbSubSpectra - 1);
for (let i = 0; i < nbSubSpectra; i++) {
pageValue += deltaY;
result.spectra[i].pageValue = pageValue;
}
let { NUC1: nuc1, AXNUC: axnuc, SF: sf } = result.meta;
const nucleus = axnuc ? axnuc : nuc1 ? nuc1 : [];
result.info['2D_Y_NUCLEUS'] = nucleus[1];
result.info['2D_X_NUCLEUS'] = nucleus[0];
result.info['2D_Y_FRECUENCY'] = sf[1];
result.info['2D_X_FRECUENCY'] = sf[0];
result.info['2D_Y_OFFSET'] = yOffset;
result.info['2D_X_OFFSET'] = xOffset;
result.info.twoD = result.twoD = true;
return result;
}
function setXYSpectrumData(file, spectra, real) {
file = ensureIOBuffer(file);
let td = parseInt(spectra.meta.SI, 10);
let swP = parseFloat(spectra.meta.SW_p);
let sf = parseFloat(spectra.meta.SF);
let bf = sf;
let offset = spectra.shiftOffsetVal || parseFloat(spectra.meta.OFFSET);
spectra.meta.observeFrequency = sf;
spectra.meta.brukerReference = bf;
spectra.meta.DATATYPE = 'NMR Spectrum';
let endian = parseInt(spectra.meta.BYTORDP, 10);
endian = endian ? 0 : 1;
let nbSubSpectra = spectra.meta.nbSubSpectra ? spectra.meta.nbSubSpectra : 1;
if (endian) {
file.setLittleEndian();
} else {
file.setBigEndian();
}
for (let i = 0; i < nbSubSpectra; i++) {
let toSave = {
dataType: 'NMR Spectrum',
dataTable: '(X++(R..R))',
nbPoints: td,
firstX: offset,
lastX: offset - swP / sf,
xUnit: 'PPM',
yUnit: 'Arbitrary',
data: new Array(td * 2),
isXYdata: true,
observeFrequency: sf,
title: spectra.meta.TITLE,
deltaX: -(swP / sf) / (td - 1),
};
let x = offset;
let deltaX = toSave.deltaX;
if (real) {
for (let k = 0; k < td; ++k) {
toSave.data[2 * k] = x;
toSave.data[2 * k + 1] = file.readInt32();
if (toSave.data[2 * k + 1] === null || isNaN(toSave.data[2 * k + 1])) {
toSave.data[2 * k + 1] = 0;
}
x += deltaX;
}
} else {
for (let k = 0; k < td; ++k) {
toSave.data[2 * k] = x;
toSave.data[2 * k + 1] = file.readInt32();
if (toSave.data[2 * k + 1] === null || isNaN(toSave.data[2 * k + 1])) {
toSave.data[2 * k + 1] = 0;
}
x += deltaX;
}
}
spectra.spectra.push(toSave);
}
}
function parseData(file, options) {
let keepRecordsRegExp = /.*/;
if (options.keepRecordsRegExp) keepRecordsRegExp = options.keepRecordsRegExp;
let result = convertJcamp(file, {
keepRecordsRegExp: keepRecordsRegExp,
});
return result.flatten.length === 0 ? {} : result.flatten[0];
}
function setFIDSpectrumData(file, spectra) {
file = ensureIOBuffer(file);
let td = parseInt(spectra.meta.TD[0], 10);
let SW_H = parseFloat(spectra.meta.SW_h[0]);
let SF = parseFloat(spectra.meta.SFO1[0]);
spectra.meta.DATATYPE = 'NMR FID';
let DW = 1 / (2 * SW_H);
let AQ = td * DW;
let endian = parseInt(spectra.meta.BYTORDA, 10);
endian = endian ? 0 : 1;
if (endian) {
file.setLittleEndian();
} else {
file.setBigEndian();
}
let nbSubSpectra = spectra.meta.nbSubSpectra ? spectra.meta.nbSubSpectra : 1;
spectra.spectra = new Array(nbSubSpectra);
for (let j = 0; j < nbSubSpectra / 2; j++) {
let toSave = {
dataType: 'NMR FID',
dataTable: '(X++(R..R))',
nbPoints: td,
firstX: 0,
lastX: AQ,
nucleus: spectra.meta.NUC1,
xUnit: 'Sec',
yUnit: 'Arbitrary',
data: [new Array(2 * td)], // [{x:new Array(td),y:new Array(td)}],
isXYdata: true,
observeFrequency: SF,
title: spectra.meta.TITLE,
deltaX: DW,
};
spectra.spectra[j * 2] = toSave;
toSave = {
dataType: 'NMR FID',
dataTable: '(X++(I..I))',
nbPoints: td,
firstX: 0,
lastX: AQ,
nucleus: spectra.meta.NUC1,
xUnit: 'Sec',
yUnit: 'Arbitrary',
data: new Array(2 * td),
isXYdata: true,
directFrequency: SF,
title: spectra.meta.TITLE,
deltaX: DW,
};
spectra.spectra[j * 2 + 1] = toSave;
let i = 0;
let x = 0;
for (; file.available(8) && i < td; i++, x = i * DW) {
let y = file.readInt32();
if (y === null || isNaN(y)) {
y = 0;
}
spectra.spectra[j * 2].data[2 * i + 1] = y;
spectra.spectra[j * 2].data[2 * i] = x;
y = file.readInt32();
if (y === null || isNaN(y)) {
y = 0;
}
spectra.spectra[j * 2 + 1].data[2 * i + 1] = y;
spectra.spectra[j * 2 + 1].data[2 * i] = x;
}
for (; i < td; i++, x = i * DW) {
spectra.spectra[j * 2].data[2 * i + 1] = 0;
spectra.spectra[j * 2].data[2 * i] = x;
spectra.spectra[j * 2 + 1].data[2 * i + 1] = 0;
spectra.spectra[j * 2 + 1].data[2 * i] = x;
}
}
}
function add2D(result, options) {
let zData = convertTo3DZ(result.spectra);
if (!options.noContours) {
result.contourLines = generateContourLines(zData);
}
result.minMax = zData;
}
function ensureIOBuffer(data) {
if (data instanceof Array || data instanceof Uint8Array) {
data = new ArrayBuffer(data);
}
if (data instanceof ArrayBuffer) {
return new IOBuffer(data);
}
return data;
}
function mergeMetadata(main, complement) {
for (let key in complement.meta) {
if (main.meta[key]) {
if (!Array.isArray(main.meta[key])) {
main.meta[key] = [main.meta[key]];
}
main.meta[key].push(complement.meta[key]);
} else if (main.meta[key] === undefined) {
main.meta[key] = [complement.meta[key]];
}
}
return main;
}
export { convertZip } from './convertZip';
export { convertFolder } from './convertFolder';