-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: cdf loader for gcms added (#290)
* feat: cdf loader for gcms added * feat: add cdfLoader in the app * test: add direct link to the test files HPLC and GC/MS * chore: specify the return value of loaders * chore: fixing missing importt * chore: suggestions implemented * fix: style issues fixed * fix: return full experiment as measurement * chore: fix the code Co-authored-by: Luc Patiny <luc@patiny.com>
- Loading branch information
Showing
10 changed files
with
155 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import { expect, test } from 'vitest'; | ||
|
||
import { getGCMSMeasurement } from './getGCMSMeasurement'; | ||
|
||
test('getGCMSMeasurement', async () => { | ||
const result = await getGCMSMeasurement(); | ||
expect(result).toHaveLength(1); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import { join } from 'path'; | ||
|
||
import { fileCollectionFromPath } from 'filelist-utils'; | ||
|
||
import { getEmptyDataState } from '../DataState'; | ||
import { append } from '../append'; | ||
import { cdfLoader } from '../loaders/cdfLoader'; | ||
|
||
export async function getGCMSMeasurement() { | ||
const dataState = getEmptyDataState(); | ||
|
||
const filteredFileCollection = ( | ||
await fileCollectionFromPath(join(__dirname, 'data/cdf/')) | ||
).filter((file) => file.name === 'agilent-gcms.cdf'); | ||
|
||
const gcmsEntry = ( | ||
await append(filteredFileCollection, dataState, { loaders: [cdfLoader] }) | ||
).dataState.measurements.gclcms.entries; | ||
return gcmsEntry; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
import { v4 } from '@lukeed/uuid'; | ||
import type { FileCollection } from 'filelist-utils'; | ||
import { NetCDFReader } from 'netcdfjs'; | ||
|
||
import { | ||
MeasurementKind, | ||
Loader, | ||
Measurements, | ||
getEmptyMeasurements, | ||
} from '../DataState'; | ||
|
||
export const cdfLoader: Loader = async function cdfLoader( | ||
fileCollection: FileCollection, | ||
): Promise<Measurements> { | ||
const newMeasurements: Measurements = getEmptyMeasurements(); | ||
for (const file of fileCollection) { | ||
if (file.name.match(/(?:\.cdf)$/i)) { | ||
const reader = new NetCDFReader(await file.arrayBuffer(), { meta: true }); | ||
if ( | ||
!reader.dataVariableExists('mass_values') || | ||
!reader.dataVariableExists('time_values') | ||
) { | ||
return newMeasurements; | ||
} | ||
|
||
const kind: MeasurementKind = 'gclcms'; | ||
|
||
const times = reader.getDataVariable('scan_acquisition_time'); | ||
const tics = reader.getDataVariable('total_intensity'); | ||
const pointCount = reader.getDataVariable('point_count'); | ||
const massValues = reader.getDataVariable('mass_values'); | ||
const intensityValues = reader.getDataVariable('intensity_values'); | ||
addMeta(reader, reader.globalAttributes); | ||
|
||
let index = 0; | ||
const allMasses: Float64Array[] = []; | ||
const allIntensities: Float64Array[] = []; | ||
for (let size of pointCount) { | ||
// Taken from: https://github.com/cheminfo/netcdf-gcms | ||
const masses = new Float64Array(size); | ||
const intensities = new Float64Array(size); | ||
for (let j = 0; j < size; j++) { | ||
masses[j] = massValues[index]; | ||
intensities[j] = intensityValues[index++]; | ||
} | ||
allIntensities.push(intensities); | ||
allMasses.push(masses); | ||
} | ||
newMeasurements[kind].entries.push({ | ||
id: v4(), | ||
meta: reader.header.meta, | ||
filename: file.name, | ||
path: file.relativePath || '', | ||
info: {}, | ||
title: reader.getAttribute('experiment_title'), | ||
data: normalizeChromatogram(times, allMasses, allIntensities, tics), | ||
}); | ||
} | ||
} | ||
return newMeasurements; | ||
}; | ||
|
||
function normalizeChromatogram(time, masses, intensities, tics) { | ||
let data: any = []; | ||
for (let i = 0; i < time.length; i++) { | ||
data.push({ | ||
meta: {}, | ||
info: { | ||
time: { value: time[i], units: 's' }, | ||
tic: tics[i], | ||
}, | ||
variables: { | ||
x: { | ||
symbol: 'X', | ||
label: 'm/z', | ||
units: '', | ||
data: masses[i] || [], | ||
}, | ||
y: { | ||
symbol: 'Y', | ||
label: 'relative intensity', | ||
units: '', | ||
data: intensities[i] || [], | ||
}, | ||
}, | ||
}); | ||
} | ||
return data; | ||
} | ||
|
||
function addMeta(reader, globalAttributes) { | ||
reader.header.meta = {}; | ||
for (const item of globalAttributes) { | ||
reader.header.meta[item.name] = item.value; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters