/** * PHD 类型 */ export const PHD_DATA_TYPE = { QCPHD: 'QCPHD', DETBKPHD: 'DETBKPHD', SAMPLEPHD: 'SAMPLEPHD', GASBKPHD: 'GASBKPHD' } /** * 判断是不是sample * @param {*} dataType * @returns */ export const isSample = dataType => { return ['SAMPLEPHD', 'SPHDP', 'SPHDF'].includes(dataType) } export class PHDParser { /** * 根据Block解析出的结果集 */ blocks = { baseInfo: [] } /** * 数据类型 */ dataType = '' /** * 类型 B G 等 */ fileType = '' /** * 质量 FULL 等 */ qualify = '' /** * 生存时间 */ liveTime = '' /** * sample 谱的文件名 */ sampleFilePrefix = '' /** * 其他文件名 */ otherFilePrefixes = [] /** * 该文件是不是sample */ isSample = false /** * 构造函数 * @param {string} text */ constructor(text) { this.splitByBlock(text) this.dataType = this.getBaseInfoByTag('DATA_TYPE')[0] this.isSample = isSample(this.dataType) const headerInfo = this.getBlockInfo('Header') const headerInfoLine1 = this.splitLineText(headerInfo[0]) this.fileType = headerInfoLine1[2] this.qualify = headerInfoLine1[4] const liveTime = parseFloat(this.getBlockStr('Acquisition', 0, 3)).toFixed(1) this.liveTime = liveTime.indexOf('.0') == -1 ? liveTime : liveTime.slice(0, -2) // 如果解析的是sample 文件,则解析相关联的文件 if (this.isSample) { if (this.fileType == 'B') { const filePrefixes = this.getFilePrefixes(headerInfo[2]) this.sampleFilePrefix = filePrefixes.splice(0, 1)[0] this.otherFilePrefixes = filePrefixes } else { this.sampleFilePrefix = this.getGammaFilePrefix(headerInfo[2]) } } } /** * 根据块类型分割 * @param {string} text */ splitByBlock(text) { const lines = (text = text.replace(/\r{0,1}\n/g, '\n').split('\n')) let blockType = 'baseInfo' for (const line of lines) { // 如果以#开头 if (line.startsWith('#')) { blockType = line.slice(1) if (blockType.startsWith('Header')) { blockType = 'Header' } this.blocks[blockType] = [] continue } this.blocks[blockType].push(line.trim()) } } /** * 根据块名拿到块内容 * @param {string} blockName * @returns {Array} */ getBlockInfo(blockName) { return this.blocks[blockName] } /** * 在baseInfo中根据tag查找值 * @param {*} tag * @returns {Array} */ getBaseInfoByTag(tag) { const baseInfo = this.getBlockInfo('baseInfo') const map = new Map() baseInfo.forEach(line => { if (line.startsWith(tag)) { map.set(tag, this.getOnymousData(line)) } }) return map.get(tag) } /** * 根据行号和位置在block中查找字符 * @param {string} blockName * @param {number} lineNum * @param {number} index * @returns {string} */ getBlockStr(blockName, lineNum, index) { const blockInfo = this.getBlockInfo(blockName) const lineText = blockInfo[lineNum] const splited = this.splitLineText(lineText) return splited[index] } /** * 获取 具名 行的数据 * @param {string} text * @example DATA_TYPE SAMPLEPHD 返回['SAMPLEPHD'] * @returns {string[]} */ getOnymousData(text) { return text.split(' ').slice(1) } /** * 将一行中的文本按空格切割 * @param {string} text */ splitLineText(text) { return text.replace(/\s+/g, ',').split(',') } /** * 获取全部文件名前缀 * @param {string} text */ getFilePrefixes(text) { const unHandledfilePrefixes = this.splitLineText(text) const filePrefixes = unHandledfilePrefixes .filter(filePrefix => filePrefix) .map(filePrefix => { filePrefix = filePrefix.replace(/(\d{4})\/(\d{2})\/(\d{2})-(\d{2}):(\d{2})(:\d{2}\.\d)?/, '$1$2$3_$4$5') return filePrefix + '_' }) return filePrefixes } /** * 获取gamma的文件名前缀 * @param {string} text */ getGammaFilePrefix(text) { const regExp = /[A-Z]{1,}\d{1,}_\d{1,}-\d{4}\/\d{2}\/\d{2}[-\s]\d{2}:\d{2}/ const result = text.match(regExp) const regExpDate = /(\d{4})\/(\d{2})\/(\d{2})[ -](\d{2}):(\d{2})/ return result[0].replace(regExpDate, '$1$2$3_$4$5') + '_' } }