Skip to content

Commit

Permalink
Merge pull request #127 from Mailaender/mz5-perf
Browse files Browse the repository at this point in the history
Improved performance of the mz5 chromatogram reader
  • Loading branch information
eselmeister authored Aug 3, 2021
2 parents 4777c8f + ff6744c commit d2c8504
Show file tree
Hide file tree
Showing 10 changed files with 473 additions and 47 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*******************************************************************************
* Copyright (c) 2021 Lablicate GmbH.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Matthias Mailänder - initial API and implementation
*******************************************************************************/
package net.openchrom.msd.converter.supplier.mz5.internal.io;

import java.io.IOException;

import org.eclipse.core.runtime.IProgressMonitor;

import net.openchrom.msd.converter.supplier.mz5.io.IReaderProxy;
import net.openchrom.msd.converter.supplier.mz5.io.ReaderProxy;
import net.openchrom.msd.converter.supplier.mz5.io.support.IScanMarker;
import net.openchrom.msd.converter.supplier.mz5.model.IVendorScanProxy;

public class ProxyReader {

public void readMassSpectrum(double[] mzs, float[] spectrumIntensity, IScanMarker scanMarker, IVendorScanProxy massSpectrum, IProgressMonitor monitor) throws IOException {

IReaderProxy scanReaderProxy = new ReaderProxy();
scanReaderProxy.readMassSpectrum(mzs, spectrumIntensity, scanMarker, massSpectrum, monitor);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,20 +23,18 @@
import org.eclipse.chemclipse.converter.io.AbstractChromatogramReader;
import org.eclipse.chemclipse.logging.core.Logger;
import org.eclipse.chemclipse.model.core.IChromatogramOverview;
import org.eclipse.chemclipse.model.exceptions.AbundanceLimitExceededException;
import org.eclipse.chemclipse.msd.converter.io.IChromatogramMSDReader;
import org.eclipse.chemclipse.msd.model.core.IChromatogramMSD;
import org.eclipse.chemclipse.msd.model.core.IVendorMassSpectrum;
import org.eclipse.chemclipse.msd.model.exceptions.IonLimitExceededException;
import org.eclipse.chemclipse.msd.model.implementation.VendorMassSpectrum;
import org.eclipse.core.runtime.IProgressMonitor;

import net.openchrom.msd.converter.supplier.mz5.internal.model.CVParam;
import net.openchrom.msd.converter.supplier.mz5.internal.model.CVReference;
import net.openchrom.msd.converter.supplier.mz5.io.support.IScanMarker;
import net.openchrom.msd.converter.supplier.mz5.io.support.ScanMarker;
import net.openchrom.msd.converter.supplier.mz5.model.IVendorChromatogram;
import net.openchrom.msd.converter.supplier.mz5.model.IVendorIon;
import net.openchrom.msd.converter.supplier.mz5.model.IVendorScanProxy;
import net.openchrom.msd.converter.supplier.mz5.model.VendorChromatogram;
import net.openchrom.msd.converter.supplier.mz5.model.VendorIon;
import net.openchrom.msd.converter.supplier.mz5.model.VendorScanProxy;

import ch.systemsx.cisd.hdf5.HDF5Factory;
import ch.systemsx.cisd.hdf5.IHDF5SimpleReader;
Expand Down Expand Up @@ -81,57 +79,68 @@ public IChromatogramOverview readOverview(File file, IProgressMonitor monitor) t
public IChromatogramMSD read(File file, IProgressMonitor monitor) throws FileNotFoundException, FileIsNotReadableException, FileIsEmptyException, IOException {

IVendorChromatogram chromatogram = null;
try {
chromatogram = new VendorChromatogram();
IHDF5SimpleReader reader = HDF5Factory.openForReading(file);
CVReference[] cvReferences = reader.readCompoundArray("CVReference", CVReference.class);
int retentionTimeReference = 0;
for(int c = 0; c < cvReferences.length; c++) {
if(cvReferences[c].accession == 1000016 && cvReferences[c].name.equals("scan start time"))
retentionTimeReference = c;
chromatogram = new VendorChromatogram();
IHDF5SimpleReader reader = HDF5Factory.openForReading(file);
CVReference[] cvReferences = reader.readCompoundArray("CVReference", CVReference.class);
int retentionTimeReference = 0;
int spectrumTitleReference = 0;
int msLevelReference = 0;
for(int c = 0; c < cvReferences.length; c++) {
if(cvReferences[c].accession == 1000016 && cvReferences[c].name.equals("scan start time"))
retentionTimeReference = c;
if(cvReferences[c].accession == 1000796 && cvReferences[c].name.equals("spectrum title"))
spectrumTitleReference = c;
if(cvReferences[c].accession == 1000511 && cvReferences[c].name.equals("ms level"))
msLevelReference = c;
}
int[] spectrumIndex = reader.readIntArray("SpectrumIndex");
CVParam[] cvParams = reader.readCompoundArray("CVParam", CVParam.class);
int[] retentionTimes = new int[spectrumIndex.length];
String[] spectrumTitles = new String[spectrumIndex.length];
short[] msLevels = new short[spectrumIndex.length];
int p = 0;
for(CVParam cvParam : cvParams) {
if(cvParam.cvRefID == retentionTimeReference) {
int multiplicator = 1; // to milisecond
CVReference unit = cvReferences[cvParam.uRefID];
if(unit.accession == 10 && unit.name.equals("second"))
multiplicator = 1000;
if(unit.accession == 31 && unit.name.equals("minute"))
multiplicator = 60 * 1000;
retentionTimes[p] = Math.round(Float.parseFloat(cvParam.value) * multiplicator);
p++;
}
int[] spectrumIndex = reader.readIntArray("SpectrumIndex");
CVParam[] cvParams = reader.readCompoundArray("CVParam", CVParam.class);
int[] retentionTimes = new int[spectrumIndex.length];
int r = 0;
for(CVParam cvParam : cvParams) {
if(cvParam.cvRefID == retentionTimeReference) {
int multiplicator = 1; // to milisecond
CVReference unit = cvReferences[cvParam.uRefID];
if(unit.accession == 10 && unit.name.equals("second"))
multiplicator = 1000;
if(unit.accession == 31 && unit.name.equals("minute"))
multiplicator = 60 * 1000;
retentionTimes[r] = Math.round(Float.parseFloat(cvParam.value) * multiplicator);
r++;
}
if(cvParam.cvRefID == spectrumTitleReference) {
spectrumTitles[p] = cvParam.value;
}
float[] spectrumintensity = reader.readFloatArray("SpectrumIntensity");
if(cvParam.cvRefID == msLevelReference) {
msLevels[p] = Short.parseShort(cvParam.value);
}
}
try {
double[] mzs = reader.readDoubleArray("SpectrumMZ");
float[] spectrumIntensity = reader.readFloatArray("SpectrumIntensity");
int start = 0;
for(int i = 0; i < spectrumIndex.length; i++) {
IVendorMassSpectrum massSpectrum = new VendorMassSpectrum();
massSpectrum.setRetentionTime(retentionTimes[i]);
int offset = spectrumIndex[i];
double mz = 0;
IScanMarker scanMarker = new ScanMarker(start, offset);
IVendorScanProxy scanProxy = new VendorScanProxy(mzs, spectrumIntensity, scanMarker);
scanProxy.setScanNumber(i);
scanProxy.setIdentifier(spectrumTitles[i]);
scanProxy.setRetentionTime(retentionTimes[i]);
scanProxy.setMassSpectrometer(msLevels[i]);
float totalSignal = 0;
for(int o = start; o < offset; o++) {
float intensity = spectrumintensity[o];
if(intensity >= VendorIon.MIN_ABUNDANCE && intensity <= VendorIon.MAX_ABUNDANCE) {
mz += mzs[o]; // first m/z value and then deltas
IVendorIon ion = new VendorIon(mz, intensity);
massSpectrum.addIon(ion);
}
start = offset;
totalSignal = totalSignal + spectrumIntensity[o];
}
chromatogram.addScan(massSpectrum);
scanProxy.setTotalSignal(totalSignal);
chromatogram.addScan(scanProxy);
start = offset;
}
} catch(AbundanceLimitExceededException e) {
logger.warn(e);
} catch(IonLimitExceededException e) {
logger.warn(e);
chromatogram.setFile(file);
} catch(OutOfMemoryError e) {
logger.error(e);
}
chromatogram.setFile(file);
//
return chromatogram;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*******************************************************************************
* Copyright (c) 2021 Lablicate GmbH.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Matthias Mailänder - initial API and implementation
*******************************************************************************/
package net.openchrom.msd.converter.supplier.mz5.io;

import java.io.IOException;

import org.eclipse.core.runtime.IProgressMonitor;

import net.openchrom.msd.converter.supplier.mz5.io.support.IScanMarker;
import net.openchrom.msd.converter.supplier.mz5.model.IVendorScanProxy;

public interface IReaderProxy {

void readMassSpectrum(double[] mzs, float[] spectrumIntensity, IScanMarker scanMarker, IVendorScanProxy massSpectrum, IProgressMonitor monitor) throws IOException;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*******************************************************************************
* Copyright (c) 2021 Lablicate GmbH.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Matthias Mailänder - initial API and implementation
*******************************************************************************/
package net.openchrom.msd.converter.supplier.mz5.io;

import java.io.IOException;

import org.eclipse.chemclipse.logging.core.Logger;
import org.eclipse.chemclipse.model.exceptions.AbundanceLimitExceededException;
import org.eclipse.chemclipse.msd.model.exceptions.IonLimitExceededException;
import org.eclipse.core.runtime.IProgressMonitor;

import net.openchrom.msd.converter.supplier.mz5.io.support.IScanMarker;
import net.openchrom.msd.converter.supplier.mz5.model.IVendorIon;
import net.openchrom.msd.converter.supplier.mz5.model.IVendorScanProxy;
import net.openchrom.msd.converter.supplier.mz5.model.VendorIon;

public class ReaderProxy implements IReaderProxy {

private static final Logger logger = Logger.getLogger(ReaderProxy.class);

@Override
public void readMassSpectrum(double[] mzs, float[] spectrumIntensity, IScanMarker scanMarker, IVendorScanProxy massSpectrum, IProgressMonitor monitor) throws IOException {

try {
double mz = 0;
int start = scanMarker.getStart();
int offset = scanMarker.getOffset();
for(int o = start; o < offset; o++) {
float intensity = spectrumIntensity[o];
mz += mzs[o]; // first m/z value and then deltas
IVendorIon ion = new VendorIon(mz, intensity);
massSpectrum.addIon(ion);
}
} catch(OutOfMemoryError e) {
logger.error(e);
} catch(AbundanceLimitExceededException e) {
logger.warn(e);
} catch(IonLimitExceededException e) {
logger.warn(e);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*******************************************************************************
* Copyright (c) 2021 Lablicate GmbH.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Matthias Mailänder - initial API and implementation
*******************************************************************************/
package net.openchrom.msd.converter.supplier.mz5.io.support;

public interface IScanMarker {

int getStart();

void setStart(int start);

int getOffset();

void setOffset(int offset);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*******************************************************************************
* Copyright (c) 2021 Lablicate GmbH.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Matthias Mailänder - initial API and implementation
*******************************************************************************/
package net.openchrom.msd.converter.supplier.mz5.io.support;

public class ScanMarker implements IScanMarker {

private int start;
private int offset;

public ScanMarker(int start, int offset) {

this.start = start;
this.offset = offset;
}

@Override
public int getStart() {

return start;
}

@Override
public void setStart(int start) {

this.start = start;
}

@Override
public int getOffset() {

return offset;
}

@Override
public void setOffset(int offset) {

this.offset = offset;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*******************************************************************************
* Copyright (c) 2017, 2021 Lablicate GmbH.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Dr. Philip Wenig - initial API and implementation
*******************************************************************************/
package net.openchrom.msd.converter.supplier.mz5.model;

import org.eclipse.chemclipse.msd.model.core.IVendorMassSpectrumProxy;

public interface IVendorScanProxy extends IVendorScan, IVendorMassSpectrumProxy {
}
Loading

0 comments on commit d2c8504

Please sign in to comment.