Comparing version 2.1.0 to 2.2.0
490
lib/index.js
@@ -5,10 +5,108 @@ 'use strict'; | ||
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } | ||
var arraybufferXmlParser = require('arraybuffer-xml-parser'); | ||
var pako = require('pako'); | ||
var uint8Base64 = require('uint8-base64'); | ||
var camelCase = require('camelcase'); | ||
var fastXmlParser = require('fast-xml-parser'); | ||
var base64Js = require('base64-js'); | ||
var camelCase = _interopDefault(require('camelcase')); | ||
var pako = _interopDefault(require('pako')); | ||
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } | ||
function parseCvParam(cvParam) { | ||
var pako__default = /*#__PURE__*/_interopDefaultLegacy(pako); | ||
var camelCase__default = /*#__PURE__*/_interopDefaultLegacy(camelCase); | ||
function decodeBase64(base64, options = {}) { | ||
let { | ||
endian = 'little', | ||
precision, | ||
float = true, | ||
compression = '', | ||
ontologies, | ||
} = options; | ||
if (ontologies) { | ||
if (ontologies.includes('MS:1000519')) { | ||
precision = 32; | ||
float = false; | ||
} | ||
if (ontologies.includes('MS:1000520')) precision = 16; | ||
if (ontologies.includes('MS:1000521')) precision = 32; | ||
if (ontologies.includes('MS:1000522')) { | ||
float = false; | ||
precision = 64; | ||
} | ||
if (ontologies.includes('MS:1000523')) precision = 64; | ||
if (ontologies.includes('MS:1000574')) compression = 'zlib'; | ||
} | ||
let uint8Array = uint8Base64.decode(base64); | ||
switch (compression.toLowerCase()) { | ||
case 'zlib': | ||
uint8Array = pako__default['default'].inflate(uint8Array); | ||
break; | ||
case '': | ||
case 'none': | ||
break; | ||
default: | ||
throw new Error(`Unknow compression algorithm: ${compression}`); | ||
} | ||
switch (endian.toLowerCase()) { | ||
case 'little': | ||
break; | ||
case 'network': | ||
case 'big': | ||
{ | ||
// we will invert in place the data | ||
let step; | ||
switch (precision) { | ||
case 32: | ||
step = 4; | ||
break; | ||
case 64: | ||
step = 8; | ||
break; | ||
default: | ||
throw new Error('Can not process bigendian file'); | ||
} | ||
for ( | ||
let i = 0; | ||
i < uint8Array.length - (uint8Array.length % step); | ||
i += step | ||
) { | ||
for (let j = 0; j < step / 2; j++) { | ||
const temp = uint8Array[i + j]; | ||
uint8Array[i + j] = uint8Array[i + step - 1 - j]; | ||
uint8Array[i + step - 1 - j] = temp; | ||
} | ||
} | ||
} | ||
break; | ||
default: | ||
throw new TypeError(`Attributes endian not correct: ${endian}`); | ||
} | ||
/* | ||
We should take care that the length of the Uint8Array is correct but the buffer | ||
may be a little bit bigger because when decoding base 64 it may end with = or == | ||
and we plan the size in the buffer. | ||
*/ | ||
if (float) { | ||
switch (precision) { | ||
case 32: | ||
return new Float32Array(uint8Array.buffer, 0, uint8Array.length / 4); | ||
case 64: | ||
return new Float64Array(uint8Array.buffer, 0, uint8Array.length / 8); | ||
default: | ||
throw new TypeError(`Incorrect precision: ${precision}`); | ||
} | ||
} else { | ||
switch (precision) { | ||
case 32: | ||
return new Int32Array(uint8Array.buffer, 0, uint8Array.length / 4); | ||
default: | ||
throw new TypeError(`Incorrect precision: ${precision}`); | ||
} | ||
} | ||
} | ||
function parseCvParam$1(cvParam) { | ||
let result = {}; | ||
@@ -23,9 +121,9 @@ if (!cvParam) return result; | ||
for (let param of cvParams) { | ||
let attr = param._attr; | ||
if (attr.name) { | ||
result[attr.name.toLowerCase()] = { | ||
accession: attr.accession, | ||
cvLabel: attr.cvLabel, | ||
value: attr.value, | ||
name: attr.name, | ||
let attributes = param.attributes; | ||
if (attributes.name) { | ||
result[attributes.name.toLowerCase()] = { | ||
accession: attributes.accession, | ||
cvLabel: attributes.cvLabel, | ||
value: attributes.value, | ||
name: attributes.name, | ||
}; | ||
@@ -50,3 +148,3 @@ } | ||
let analyzer = instrument.analyzerList.analyzer; | ||
let cvParam = parseCvParam(analyzer.cvParam); | ||
let cvParam = parseCvParam$1(analyzer.cvParam); | ||
if (cvParam.analyzertype) { | ||
@@ -58,3 +156,3 @@ metadata.analyzer = cvParam.analyzertype.value; | ||
let detector = instrument.detector; | ||
let cvParam = parseCvParam(detector.cvParam); | ||
let cvParam = parseCvParam$1(detector.cvParam); | ||
if (cvParam.detectortype) { | ||
@@ -67,34 +165,14 @@ metadata.detector = cvParam.detectortype.value; | ||
function decodeData(node) { | ||
let data = node._data; | ||
let attr = node._attr; | ||
if (!data || !attr) return []; | ||
let buffer = base64Js.toByteArray(data); | ||
if (attr.endian !== 'little') { | ||
throw new Error(`endian not recognized: ${attr.endian}`); | ||
} | ||
switch (attr.precision) { | ||
case 32: | ||
return new Float32Array(buffer.buffer); | ||
case 64: | ||
return new Float64Array(buffer.buffer); | ||
default: | ||
throw new Error(`unknown precision in decoder: ${attr.precision}`); | ||
} | ||
} | ||
function processSpectrumList(parsed, times, msData) { | ||
function processSpectrumList$2(parsed, times, msData) { | ||
if (!parsed || !parsed.spectrumList || !parsed.spectrumList.spectrum) return; | ||
let spectrumList = parsed.spectrumList.spectrum; | ||
for (let spectrum of spectrumList) { | ||
let info = parseCvParam( | ||
let info = parseCvParam$1( | ||
spectrum.spectrumDesc.spectrumSettings.spectrumInstrument.cvParam, | ||
); | ||
// info.scanmode; | ||
// info.polarity; | ||
times.push(info.timeinminutes.value); | ||
let mzArray = decodeData(spectrum.mzArrayBinary.data); | ||
let intensity = decodeData(spectrum.intenArrayBinary.data); | ||
let mzArray = spectrum.mzArrayBinary.data['#text'] || []; | ||
let intensity = spectrum.intenArrayBinary.data['#text'] || []; | ||
msData.push([mzArray, intensity]); | ||
@@ -104,8 +182,31 @@ } | ||
function processMZData(topLevel, result) { | ||
processMetadata(topLevel, result.metadata); | ||
processSpectrumList(topLevel, result.times, result.series.ms.data); | ||
const decoder$3 = new TextDecoder(); | ||
function parseMzData(arrayBuffer) { | ||
const result = { | ||
metadata: {}, | ||
times: [], | ||
series: { | ||
ms: { | ||
data: [], | ||
}, | ||
}, | ||
}; | ||
let parsed = arraybufferXmlParser.parse(arrayBuffer, { | ||
attributeNamePrefix: '', | ||
attributesNodeName: 'attributes', | ||
tagValueProcessor: (value, node) => { | ||
if (node.tagName !== 'data') return decoder$3.decode(value); | ||
return decodeBase64(node.value, node.attributes); | ||
}, | ||
}); | ||
processMetadata(parsed.mzData, result.metadata); | ||
processSpectrumList$2(parsed.mzData, result.times, result.series.ms.data); | ||
return result; | ||
} | ||
function parseCvParam$1(cvParam) { | ||
function parseCvParam(cvParam) { | ||
let result = {}; | ||
@@ -119,10 +220,12 @@ if (!cvParam) return result; | ||
} | ||
for (let param of cvParams) { | ||
let attr = param._attr; | ||
if (attr.name) { | ||
result[camelCase(attr.name.toLowerCase().replace(/[^ a-z0-9]/g, ''))] = { | ||
accession: attr.accession, | ||
cvLabel: attr.cvLabel, | ||
value: attr.value, | ||
name: attr.name, | ||
for (let parameter of cvParams) { | ||
let attribute = parameter.attributes; | ||
if (attribute.name) { | ||
result[ | ||
camelCase__default['default'](attribute.name.toLowerCase().replace(/[^ a-z0-9]/g, '')) | ||
] = { | ||
accession: attribute.accession, | ||
cvLabel: attribute.cvLabel, | ||
value: attribute.value, | ||
name: attribute.name, | ||
}; | ||
@@ -134,39 +237,2 @@ } | ||
function parseBinaryDataArray(node) { | ||
let data = node.binary; | ||
let attr = node._attr; | ||
let cvParam = parseCvParam$1(node.cvParam); | ||
if (!data || !attr) return []; | ||
let buffer = decoder(data, cvParam); | ||
let kind = ''; | ||
if (cvParam.mzArray) { | ||
kind = 'mz'; | ||
} else if (cvParam.intensityArray) { | ||
kind = 'intensity'; | ||
} else { | ||
throw new Error('unknown binary data type'); | ||
} | ||
if (cvParam['64BitFloat']) { | ||
let result = {}; | ||
result[kind] = new Float64Array(buffer.buffer); | ||
return result; | ||
} else if (cvParam['32BitFloat']) { | ||
let result = {}; | ||
result[kind] = new Float32Array(buffer.buffer); | ||
return result; | ||
} | ||
throw new Error(`unknown precision in decoder: ${attr.precision}`); | ||
} | ||
function decoder(base64Encoded, cvParams = {}) { | ||
if (cvParams.zlibCompression) { | ||
return pako.inflate(base64Js.toByteArray(base64Encoded)); | ||
} else { | ||
return base64Js.toByteArray(base64Encoded); | ||
} | ||
} | ||
function processSpectrumList$1(parsed, times, msData) { | ||
@@ -184,2 +250,3 @@ if ( | ||
for (let spectrum of spectrumList) { | ||
if (!spectrum.binaryDataArrayList) continue; | ||
let scanList = spectrum.scanList; | ||
@@ -194,6 +261,6 @@ if (Array.isArray(scanList)) throw new Error('Unsupported scanList'); | ||
} | ||
let cvParam = parseCvParam$1(scan.cvParam); | ||
const cvParam = parseCvParam(scan.cvParam); | ||
times.push(cvParam.scanStartTime.value); | ||
let dataArrayList = spectrum.binaryDataArrayList.binaryDataArray; | ||
const dataArrayList = spectrum.binaryDataArrayList.binaryDataArray; | ||
if (dataArrayList.length !== 2) { | ||
@@ -203,80 +270,54 @@ throw new Error('Can not decodeData because length !== 2'); | ||
let first = parseBinaryDataArray(dataArrayList[0]); | ||
let second = parseBinaryDataArray(dataArrayList[1]); | ||
const first = dataArrayList[0]; | ||
const firstCVParams = parseCvParam(first.cvParam); | ||
const second = dataArrayList[1]; | ||
const secondCVParams = parseCvParam(second.cvParam); | ||
msData.push([first.mz || second.mz, second.intensity || first.intensity]); | ||
if (firstCVParams.mzArray && secondCVParams.intensityArray) { | ||
msData.push([first.binary, second.binary]); | ||
} | ||
if (firstCVParams.intensityArray && secondCVParams.mzArray) { | ||
msData.push([second.binary, first.binary]); | ||
} | ||
} | ||
} | ||
function processMZML(topLevel, result) { | ||
//processMetadata(topLevel, result.metadata) | ||
processSpectrumList$1(topLevel, result.times, result.series.ms.data); | ||
} | ||
const decoder$2 = new TextDecoder(); | ||
function parseCvParam$2(cvParam) { | ||
let result = {}; | ||
if (!cvParam) return result; | ||
let cvParams; | ||
if (Array.isArray(cvParam)) { | ||
cvParams = cvParam; | ||
} else { | ||
cvParams = [cvParam]; | ||
} | ||
for (let param of cvParams) { | ||
if (param.precision) { | ||
result = { | ||
precision: param.precision, | ||
byteOrder: param.byteOrder, | ||
contentType: param.contentType, | ||
pairOrder: param.pairOrder, | ||
}; | ||
} | ||
} | ||
return result; | ||
} | ||
function parseMzML(arrayBuffer) { | ||
const result = { | ||
metadata: {}, | ||
times: [], | ||
series: { | ||
ms: { | ||
data: [], | ||
}, | ||
}, | ||
}; | ||
function parseBinaryDataArray$1(node) { | ||
let data = node.peaks; | ||
let attr = node._attr; | ||
let cvParam = parseCvParam$2(data._attr); | ||
if (!data || !attr) return []; | ||
let buffer = decoder$1(data._data, cvParam); | ||
let kind = ''; | ||
if (cvParam.contentType) { | ||
kind = cvParam.contentType; | ||
} else if (cvParam.pairOrder) { | ||
kind = cvParam.pairOrder; | ||
} else { | ||
throw new Error('unknown binary data type'); | ||
} | ||
// console.log(buffer) | ||
if (cvParam.precision === 64) { | ||
let result = {}; | ||
result.data = new Float64Array(buffer.buffer); | ||
result.kind = kind; | ||
return result; | ||
} else if (cvParam.precision === 32) { | ||
let result = {}; | ||
result.data = new Float32Array(buffer); | ||
result.kind = kind; | ||
return result; | ||
} | ||
throw new Error(`unknown precision in decoder: ${attr.precision}`); | ||
} | ||
let parsed = arraybufferXmlParser.parse(arrayBuffer, { | ||
attributeNamePrefix: '', | ||
attributesNodeName: 'attributes', | ||
tagValueProcessor: (value, node) => { | ||
if (node.tagName !== 'binary') return decoder$2.decode(value); | ||
const ontologies = node.parent.children.cvParam.map( | ||
(entry) => entry.attributes.accession, | ||
); | ||
function decoder$1(base64Encoded, cvParams = {}) { | ||
if (cvParams.compressionType === 'zlib') { | ||
return pako.inflate(base64Js.toByteArray(base64Encoded)); | ||
} else { | ||
return base64Js.toByteArray(base64Encoded); | ||
} | ||
return decodeBase64(node.value, { ontologies }); | ||
}, | ||
}); | ||
const mzML = parsed.mzML || parsed.indexedmzML.mzML; | ||
processSpectrumList$1(mzML, result.times, result.series.ms.data); | ||
return result; | ||
} | ||
function processSpectrumList$2(parsed, msData) { | ||
function processSpectrumList(parsed, times, msData) { | ||
if (!parsed.msRun.scan) return; | ||
let scanList = parsed.msRun.scan; | ||
if (Array.isArray(scanList) === false) scanList = [scanList]; | ||
if (scanList[0]._attr) { | ||
msData.info = []; | ||
} | ||
if (scanList[0].attributes) msData.info = []; | ||
for (let scan of scanList) { | ||
@@ -287,56 +328,52 @@ if (typeof scan !== 'object') continue; | ||
} | ||
let dataArray = parseBinaryDataArray$1(scan); | ||
let first = new Float64Array(dataArray.data.length / 2); | ||
let second = new Float64Array(dataArray.data.length / 2); | ||
for (let i = 0; i < dataArray.data.length / 2; i++) { | ||
first[i] = dataArray.data[i * 2]; | ||
second[i] = dataArray.data[i * 2 + 1]; | ||
const dataArray = scan.peaks['#text']; | ||
let length = dataArray.length / 2; | ||
let first = new Float64Array(length); | ||
let second = new Float64Array(length); | ||
for (let i = 0; i < length; i++) { | ||
first[i] = dataArray[i * 2]; | ||
second[i] = dataArray[i * 2 + 1]; | ||
} | ||
msData.data.push([first, second]); | ||
msData.info.push(scan._attr); | ||
msData.info.push(scan.attributes); | ||
times.push( | ||
parseFloat( | ||
scan.attributes.retentionTime.replace(/(?:P*)(?:T*)(?:S*)/gi, ''), | ||
), | ||
); | ||
} | ||
} | ||
function processMZXML(topLevel, result) { | ||
processSpectrumList$2(topLevel, result.series.ms); | ||
let offset = topLevel.index.offset; | ||
for (let i = 0; i < offset.length; i++) { | ||
let index = offset[i]._attr.id; | ||
let data = offset[i]._data; | ||
result.times[index - 1] = data; | ||
} | ||
result.metadata = { | ||
msManufacturer: topLevel.msRun.msInstrument.msManufacturer._attr, | ||
msModel: topLevel.msRun.msInstrument.msModel._attr, | ||
msIonisation: topLevel.msRun.msInstrument.msIonisation._attr, | ||
msMassAnalyzer: topLevel.msRun.msInstrument.msMassAnalyzer._attr, | ||
msDetector: topLevel.msRun.msInstrument.msDetector._attr, | ||
software: topLevel.msRun.msInstrument.software._attr, | ||
const decoder$1 = new TextDecoder(); | ||
function parseMzXML(arrayBuffer) { | ||
const result = { | ||
metadata: {}, | ||
times: [], | ||
series: { | ||
ms: { | ||
data: [], | ||
}, | ||
}, | ||
}; | ||
} | ||
let parsed = arraybufferXmlParser.parse(arrayBuffer, { | ||
attributeNamePrefix: '', | ||
attributesNodeName: 'attributes', | ||
tagValueProcessor: (value, node) => { | ||
if (node.tagName !== 'peaks') return decoder$1.decode(value); | ||
return decodeBase64(node.value, { | ||
precision: node.attributes.precision, | ||
endian: node.attributes.byteOrder, | ||
compression: node.attributes.compressionType, | ||
}); | ||
}, | ||
}); | ||
function ensureText(data, options = {}) { | ||
const { encoding = 'utf8' } = options; | ||
if (typeof Buffer !== 'undefined' && data instanceof Buffer) { | ||
return data.toString(encoding); | ||
} | ||
if (typeof ArrayBuffer !== 'undefined' && data instanceof ArrayBuffer) { | ||
return new TextDecoder(encoding).decode(data); | ||
} | ||
return data; | ||
} | ||
processSpectrumList(parsed.mzXML, result.times, result.series.ms); | ||
function searchObjectKey(object, searchKey) { | ||
for (let key in object) { | ||
if (key.match(searchKey)) { | ||
let result = {}; | ||
result[key.toLowerCase()] = object[key]; | ||
return result; | ||
} else if (typeof object[key] === 'object' && !Array.isArray(object[key])) { | ||
let result = searchObjectKey(object[key], searchKey); | ||
if (result) return result; | ||
} | ||
} | ||
return result; | ||
} | ||
const decoder = new TextDecoder(); | ||
/** | ||
@@ -348,46 +385,15 @@ * Reads a mzData v1.05 file | ||
function parseMZ(xml) { | ||
xml = ensureText(xml); | ||
const header = decoder.decode(xml.subarray(0, 200)); | ||
if (typeof xml !== 'string') throw new TypeError('xml must be a string'); | ||
let parsed = fastXmlParser.parse(xml, { | ||
textNodeName: '_data', | ||
attributeNamePrefix: '', | ||
parseAttributeValue: true, | ||
attrNodeName: '_attr', | ||
ignoreAttributes: false, | ||
}); | ||
let topLevel = searchObjectKey(parsed, /^(mzdata|mzml|mzxml)$/i); | ||
if (!topLevel) { | ||
throw new Error('MZ parser: can not find tag mzdata, mzml or mzxml'); | ||
if (header.includes('mzData')) { | ||
return parseMzData(xml); | ||
} else if (header.includes('mzML')) { | ||
return parseMzML(xml); | ||
} else if (header.includes('mzXML')) { | ||
return parseMzXML(xml); | ||
} else { | ||
throw new Error(`MZ parser: unknown format`); | ||
} | ||
let result = { | ||
metadata: {}, | ||
times: [], | ||
series: { | ||
ms: { | ||
data: [], | ||
}, | ||
}, | ||
}; | ||
switch (Object.keys(topLevel)[0]) { | ||
case 'mzdata': | ||
processMZData(topLevel.mzdata, result); | ||
break; | ||
case 'mzml': | ||
processMZML(topLevel.mzml, result); | ||
break; | ||
case 'mzxml': | ||
processMZXML(topLevel.mzxml, result); | ||
break; | ||
default: | ||
throw new Error(`MZ parser: unknown format: ${Object.keys(topLevel)[0]}`); | ||
} | ||
return result; | ||
} | ||
exports.parseMZ = parseMZ; |
{ | ||
"name": "mzdata", | ||
"version": "2.1.0", | ||
"version": "2.2.0", | ||
"description": "Read and explore mzData v1.05 files", | ||
@@ -12,5 +12,6 @@ "main": "lib/index.js", | ||
"scripts": { | ||
"build": "cheminfo-build --entry src/index.js --root MZ", | ||
"eslint": "eslint src", | ||
"eslint-fix": "npm run eslint -- --fix", | ||
"prepublishOnly": "rollup -c", | ||
"prepack": "rollup -c", | ||
"test-travis": "npm run test", | ||
@@ -36,22 +37,23 @@ "test": "npm run test-coverage && npm run eslint", | ||
"devDependencies": { | ||
"@babel/plugin-transform-modules-commonjs": "^7.8.3", | ||
"@babel/plugin-transform-modules-commonjs": "^7.15.4", | ||
"cheminfo-build": "^1.1.11", | ||
"cheminfo-tools": "^1.23.3", | ||
"codecov": "^3.6.5", | ||
"eslint": "^6.8.0", | ||
"eslint-config-cheminfo": "^2.0.4", | ||
"eslint-plugin-import": "^2.20.1", | ||
"eslint-plugin-jest": "^23.8.0", | ||
"eslint-plugin-no-only-tests": "^2.4.0", | ||
"eslint-plugin-prettier": "^3.1.2", | ||
"jest": "^25.1.0", | ||
"prettier": "^1.19.1", | ||
"rollup": "^1.32.0" | ||
"codecov": "^3.8.3", | ||
"eslint": "^7.32.0", | ||
"eslint-config-cheminfo": "^5.3.0", | ||
"eslint-plugin-import": "^2.24.2", | ||
"eslint-plugin-jest": "^24.4.0", | ||
"eslint-plugin-no-only-tests": "^2.6.0", | ||
"eslint-plugin-prettier": "^4.0.0", | ||
"jest": "^27.1.0", | ||
"prettier": "^2.3.2", | ||
"rollup": "^2.56.3" | ||
}, | ||
"dependencies": { | ||
"base64-arraybuffer": "^0.2.0", | ||
"base64-js": "^1.3.1", | ||
"camelcase": "^5.3.1", | ||
"fast-xml-parser": "^3.16.0", | ||
"pako": "^1.0.11" | ||
"arraybuffer-xml-parser": "^0.3.0", | ||
"base64-arraybuffer": "^1.0.1", | ||
"camelcase": "^6.2.0", | ||
"pako": "^2.0.4", | ||
"uint8-base64": "^0.1.1" | ||
} | ||
} |
@@ -11,2 +11,3 @@ # mzData | ||
This includes: | ||
- mzData | ||
@@ -30,2 +31,6 @@ - mzML | ||
## Ontology | ||
[Ontology](./ontology.md) | ||
## More examples | ||
@@ -32,0 +37,0 @@ |
@@ -1,8 +0,6 @@ | ||
import { parse } from 'fast-xml-parser'; | ||
import { parseMzData } from './mzdata/parseMzData'; | ||
import { parseMzML } from './mzml/parseMzML'; | ||
import { parseMzXML } from './mzxml/parseMzXML'; | ||
import { processMZData } from './mzdata/process'; | ||
import { processMZML } from './mzml/process'; | ||
import { processMZXML } from './mzxml/process'; | ||
import { ensureText } from './util/ensureText'; | ||
import { searchObjectKey } from './util/searchObjectKey'; | ||
const decoder = new TextDecoder(); | ||
@@ -15,44 +13,13 @@ /** | ||
export function parseMZ(xml) { | ||
xml = ensureText(xml); | ||
const header = decoder.decode(xml.subarray(0, 200)); | ||
if (typeof xml !== 'string') throw new TypeError('xml must be a string'); | ||
let parsed = parse(xml, { | ||
textNodeName: '_data', | ||
attributeNamePrefix: '', | ||
parseAttributeValue: true, | ||
attrNodeName: '_attr', | ||
ignoreAttributes: false, | ||
}); | ||
let topLevel = searchObjectKey(parsed, /^(mzdata|mzml|mzxml)$/i); | ||
if (!topLevel) { | ||
throw new Error('MZ parser: can not find tag mzdata, mzml or mzxml'); | ||
if (header.includes('mzData')) { | ||
return parseMzData(xml); | ||
} else if (header.includes('mzML')) { | ||
return parseMzML(xml); | ||
} else if (header.includes('mzXML')) { | ||
return parseMzXML(xml); | ||
} else { | ||
throw new Error(`MZ parser: unknown format`); | ||
} | ||
let result = { | ||
metadata: {}, | ||
times: [], | ||
series: { | ||
ms: { | ||
data: [], | ||
}, | ||
}, | ||
}; | ||
switch (Object.keys(topLevel)[0]) { | ||
case 'mzdata': | ||
processMZData(topLevel.mzdata, result); | ||
break; | ||
case 'mzml': | ||
processMZML(topLevel.mzml, result); | ||
break; | ||
case 'mzxml': | ||
processMZXML(topLevel.mzxml, result); | ||
break; | ||
default: | ||
throw new Error(`MZ parser: unknown format: ${Object.keys(topLevel)[0]}`); | ||
} | ||
return result; | ||
} |
@@ -11,9 +11,9 @@ export function parseCvParam(cvParam) { | ||
for (let param of cvParams) { | ||
let attr = param._attr; | ||
if (attr.name) { | ||
result[attr.name.toLowerCase()] = { | ||
accession: attr.accession, | ||
cvLabel: attr.cvLabel, | ||
value: attr.value, | ||
name: attr.name, | ||
let attributes = param.attributes; | ||
if (attributes.name) { | ||
result[attributes.name.toLowerCase()] = { | ||
accession: attributes.accession, | ||
cvLabel: attributes.cvLabel, | ||
value: attributes.value, | ||
name: attributes.name, | ||
}; | ||
@@ -20,0 +20,0 @@ } |
import { parseCvParam } from './parseCvParam'; | ||
import { decodeData } from './decodeData'; | ||
@@ -11,9 +10,9 @@ export function processSpectrumList(parsed, times, msData) { | ||
); | ||
// info.scanmode; | ||
// info.polarity; | ||
times.push(info.timeinminutes.value); | ||
let mzArray = decodeData(spectrum.mzArrayBinary.data); | ||
let intensity = decodeData(spectrum.intenArrayBinary.data); | ||
let mzArray = spectrum.mzArrayBinary.data['#text'] || []; | ||
let intensity = spectrum.intenArrayBinary.data['#text'] || []; | ||
msData.push([mzArray, intensity]); | ||
} | ||
} |
@@ -12,10 +12,12 @@ import camelCase from 'camelcase'; | ||
} | ||
for (let param of cvParams) { | ||
let attr = param._attr; | ||
if (attr.name) { | ||
result[camelCase(attr.name.toLowerCase().replace(/[^ a-z0-9]/g, ''))] = { | ||
accession: attr.accession, | ||
cvLabel: attr.cvLabel, | ||
value: attr.value, | ||
name: attr.name, | ||
for (let parameter of cvParams) { | ||
let attribute = parameter.attributes; | ||
if (attribute.name) { | ||
result[ | ||
camelCase(attribute.name.toLowerCase().replace(/[^ a-z0-9]/g, '')) | ||
] = { | ||
accession: attribute.accession, | ||
cvLabel: attribute.cvLabel, | ||
value: attribute.value, | ||
name: attribute.name, | ||
}; | ||
@@ -22,0 +24,0 @@ } |
import { parseCvParam } from './parseCvParam'; | ||
import { parseBinaryDataArray } from './parseBinaryDataArray'; | ||
@@ -16,2 +15,3 @@ export function processSpectrumList(parsed, times, msData) { | ||
for (let spectrum of spectrumList) { | ||
if (!spectrum.binaryDataArrayList) continue; | ||
let scanList = spectrum.scanList; | ||
@@ -26,6 +26,6 @@ if (Array.isArray(scanList)) throw new Error('Unsupported scanList'); | ||
} | ||
let cvParam = parseCvParam(scan.cvParam); | ||
const cvParam = parseCvParam(scan.cvParam); | ||
times.push(cvParam.scanStartTime.value); | ||
let dataArrayList = spectrum.binaryDataArrayList.binaryDataArray; | ||
const dataArrayList = spectrum.binaryDataArrayList.binaryDataArray; | ||
if (dataArrayList.length !== 2) { | ||
@@ -35,7 +35,14 @@ throw new Error('Can not decodeData because length !== 2'); | ||
let first = parseBinaryDataArray(dataArrayList[0]); | ||
let second = parseBinaryDataArray(dataArrayList[1]); | ||
const first = dataArrayList[0]; | ||
const firstCVParams = parseCvParam(first.cvParam); | ||
const second = dataArrayList[1]; | ||
const secondCVParams = parseCvParam(second.cvParam); | ||
msData.push([first.mz || second.mz, second.intensity || first.intensity]); | ||
if (firstCVParams.mzArray && secondCVParams.intensityArray) { | ||
msData.push([first.binary, second.binary]); | ||
} | ||
if (firstCVParams.intensityArray && secondCVParams.mzArray) { | ||
msData.push([second.binary, first.binary]); | ||
} | ||
} | ||
} |
@@ -0,3 +1,3 @@ | ||
import { decode } from 'base64-arraybuffer'; | ||
import pako from 'pako'; | ||
import { decode } from 'base64-arraybuffer'; | ||
@@ -4,0 +4,0 @@ export function decoder(base64Encoded, options = {}) { |
@@ -17,2 +17,3 @@ export function parseCvParam(cvParam) { | ||
pairOrder: param.pairOrder, | ||
compressionType: param.compressionType, | ||
}; | ||
@@ -19,0 +20,0 @@ } |
@@ -1,10 +0,6 @@ | ||
import { parseBinaryDataArray } from './parseBinaryDataArray'; | ||
export function processSpectrumList(parsed, msData) { | ||
export function processSpectrumList(parsed, times, msData) { | ||
if (!parsed.msRun.scan) return; | ||
let scanList = parsed.msRun.scan; | ||
if (Array.isArray(scanList) === false) scanList = [scanList]; | ||
if (scanList[0]._attr) { | ||
msData.info = []; | ||
} | ||
if (scanList[0].attributes) msData.info = []; | ||
for (let scan of scanList) { | ||
@@ -15,12 +11,18 @@ if (typeof scan !== 'object') continue; | ||
} | ||
let dataArray = parseBinaryDataArray(scan); | ||
let first = new Float64Array(dataArray.data.length / 2); | ||
let second = new Float64Array(dataArray.data.length / 2); | ||
for (let i = 0; i < dataArray.data.length / 2; i++) { | ||
first[i] = dataArray.data[i * 2]; | ||
second[i] = dataArray.data[i * 2 + 1]; | ||
const dataArray = scan.peaks['#text']; | ||
let length = dataArray.length / 2; | ||
let first = new Float64Array(length); | ||
let second = new Float64Array(length); | ||
for (let i = 0; i < length; i++) { | ||
first[i] = dataArray[i * 2]; | ||
second[i] = dataArray[i * 2 + 1]; | ||
} | ||
msData.data.push([first, second]); | ||
msData.info.push(scan._attr); | ||
msData.info.push(scan.attributes); | ||
times.push( | ||
parseFloat( | ||
scan.attributes.retentionTime.replace(/(?:P*)(?:T*)(?:S*)/gi, ''), | ||
), | ||
); | ||
} | ||
} |
@@ -0,3 +1,3 @@ | ||
import { decode } from 'base64-arraybuffer'; | ||
import pako from 'pako'; | ||
import { decode } from 'base64-arraybuffer'; | ||
@@ -4,0 +4,0 @@ export function decoder(base64Encoded, options = {}) { |
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
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
54
0
28790
13
19
813
1
+ Addeduint8-base64@^0.1.1
+ Addedarraybuffer-xml-parser@0.3.0(transitive)
+ Addedbase64-arraybuffer@1.0.2(transitive)
+ Addedcamelcase@6.3.0(transitive)
+ Addeddynamic-typing@0.1.3(transitive)
+ Addedpako@2.1.0(transitive)
+ Addeduint8-base64@0.1.1(transitive)
- Removedbase64-js@^1.3.1
- Removedfast-xml-parser@^3.16.0
- Removedbase64-arraybuffer@0.2.0(transitive)
- Removedbase64-js@1.5.1(transitive)
- Removedcamelcase@5.3.1(transitive)
- Removedfast-xml-parser@3.21.1(transitive)
- Removedpako@1.0.11(transitive)
- Removedstrnum@1.0.5(transitive)
Updatedbase64-arraybuffer@^1.0.1
Updatedcamelcase@^6.2.0
Updatedpako@^2.0.4