brukerconverter
Advanced tools
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 @@ |
693
lib/index.js
@@ -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" | ||
} | ||
} |
458
src/index.js
@@ -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'; |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
58345
21
1591
1
+ Addedcheminfo-types@0.9.1(transitive)
+ Addeddynamic-typing@0.1.3(transitive)
+ Addedjcampconverter@8.5.0(transitive)
+ Addedlodash@4.17.21(transitive)
+ Addedml-gsd@10.2.0(transitive)
+ Addedml-levenberg-marquardt@4.1.3(transitive)
+ Addedml-peak-shape-generator@4.1.4(transitive)
+ Addedml-savitzky-golay-generalized@4.0.1(transitive)
+ Addedml-spectra-fitting@3.0.4(transitive)
+ Addedml-spectra-processing@11.17.014.9.1(transitive)
+ Addedml-tree-set@0.1.1(transitive)
+ Addedml-xsadd@3.0.1(transitive)
+ Addednmr-correlation@2.3.3(transitive)
+ Addednmr-processing@7.4.3(transitive)
+ Addedspectrum-generator@8.0.12(transitive)
- Removedassign-deep@1.0.1(transitive)
- Removedassign-symbols@2.0.2(transitive)
- Removedcheminfo-types@0.5.0(transitive)
- Removedd3-random@2.2.2(transitive)
- Removedis-any-array@1.0.1(transitive)
- Removedjcampconverter@7.10.0(transitive)
- Removedml-array-standard-deviation@1.1.8(transitive)
- Removedml-array-variance@1.1.8(transitive)
- Removedml-gsd@6.9.2(transitive)
- Removedml-levenberg-marquardt@3.1.1(transitive)
- Removedml-peak-shape-generator@1.0.02.0.2(transitive)
- Removedml-savitzky-golay-generalized@2.0.3(transitive)
- Removedml-spectra-fitting@1.0.0(transitive)
- Removedml-spectra-processing@6.8.0(transitive)
- Removednmr-processing@1.5.2(transitive)
- Removedspectrum-generator@4.8.1(transitive)
Updatedjcampconverter@^8.0.2