All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jcamp.parser.FluorescenceJCAMPReader Maven / Gradle / Ivy

Go to download

The JCAMP-DX project is the reference implemention of the IUPAC JCAMP-DX spectroscopy data standard.

There is a newer version: 0.9.2
Show newest version
package org.jcamp.parser;
import java.util.Arrays;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jcamp.math.IArray1D;
import org.jcamp.math.IArray2D;
import org.jcamp.spectrum.ArrayData;
import org.jcamp.spectrum.Assignment;
import org.jcamp.spectrum.EquidistantData;
import org.jcamp.spectrum.Fluorescence2DSpectrum;
import org.jcamp.spectrum.FluorescenceSpectrum;
import org.jcamp.spectrum.IDataArray1D;
import org.jcamp.spectrum.IOrderedDataArray1D;
import org.jcamp.spectrum.ISpectrumIdentifier;
import org.jcamp.spectrum.OrderedArrayData;
import org.jcamp.spectrum.Pattern;
import org.jcamp.spectrum.Peak1D;
import org.jcamp.spectrum.Spectrum;
import org.jcamp.units.CommonUnit;
import org.jcamp.units.Unit;
/**
 * adapter between fluorescence spectrum class and JCAMPReader.
 * NON STANDARD
 * @author Thomas Weber
 */
public class FluorescenceJCAMPReader extends CommonSpectrumJCAMPReader implements ISpectrumJCAMPReader {
    private final static String CRLF = "\r\n";
    private static Log log = LogFactory.getLog(FluorescenceJCAMPReader.class);

    /**
     */
    protected FluorescenceJCAMPReader() {
        super();
    }

    /**
     * read Fluorescence full spectrum.
     * 
     * @return FluorescenceSpectrum
     * @param block JCAMPBlock
     */
    private FluorescenceSpectrum createFS(JCAMPBlock block) throws JCAMPException {
        FluorescenceSpectrum spectrum;
        Unit xUnit = getXUnits(block);
        if (xUnit == null)
            xUnit = CommonUnit.nanometerWavelength;
        Unit yUnit = getYUnits(block);
        if (yUnit == null)
            yUnit = CommonUnit.absorbance;
        double xFactor = getXFactor(block);
        double yFactor = getYFactor(block);
        int nPoints = getNPoints(block);
        if (block.getDataRecord("XYDATA") != null) {
            double firstX = getFirstX(block);
            double lastX = getLastX(block);
            double[] intensities = getXYData(block, firstX, lastX, nPoints, xFactor, yFactor);
            if (intensities.length != nPoints)
                throw new JCAMPException("incorrect ##NPOINTS= or bad ##XYDATA=");
            IOrderedDataArray1D x = new EquidistantData(firstX, lastX, nPoints, xUnit);
            IDataArray1D y = new ArrayData(intensities, yUnit);
            spectrum = new FluorescenceSpectrum(x, y, true);
        } else if (block.getDataRecord("XYPOINTS") != null) {
            double xy[][] = getXYPoints(block, nPoints, xFactor, yFactor);
            IOrderedDataArray1D x = new OrderedArrayData(xy[0], xUnit);
            IDataArray1D y = new ArrayData(xy[1], yUnit);
            spectrum = new FluorescenceSpectrum(x, y, false);
        } else
            throw new JCAMPException("missing data: ##XYDATA= or ##XYPOINTS= required.");
        setNotes(block, spectrum);
        return spectrum;
    }

    /**
     * read Fluorescence full spectrum.
     * 
     * @return Fluorescence2DSpectrum
     * @param block JCAMPBlock
     */
    private Fluorescence2DSpectrum createFS2D(JCAMPBlock block) throws JCAMPException {
        Fluorescence2DSpectrum spectrum;
        JCAMPNTuple ntuple = block.getNTuple();
        JCAMPVariable[] vars = block.getVariables();
        int nPages = ntuple.numPages();
        int emissionIndex = -1;
        int excitationIndex = -1;
        int intensityIndex = -1;
        for (int i = 0; i < vars.length; i++) {
            String name = vars[i].getName().toUpperCase();
            if ("INTENSITY".equalsIgnoreCase(name))
                intensityIndex = i;
            else if ("EMISSION".equalsIgnoreCase(name))
                emissionIndex = i;
            else if ("EXCITATION".equalsIgnoreCase(name))
                excitationIndex = i;
            else if ("PAGE".equals(name));
            else
                log.warn("unknown fluorescence variable: " + name);
        }
        for (int i = 0; i < vars.length; i++) {
            if (intensityIndex < 0 && vars[i].getType().equals(JCAMPVariable.Type.DEPENDENT)) {
                log.warn("intensity variable could not be recognized: using dependend variable at column " + (i + 1));
                intensityIndex = i;
            }
            if (emissionIndex < 0 && vars[i].getType().equals(JCAMPVariable.Type.INDEPENDENT)) {
                log.warn("emission variable could not be recognized: using independend variable at column " + (i + 1));
                emissionIndex = i;
            }
            if (excitationIndex < 0 && vars[i].getType().equals(JCAMPVariable.Type.INDEPENDENT)) {
                log.warn(
                    "excitation variable could not be recognized: using independend variable at column " + (i + 1));
                excitationIndex = i;
            }
        }
        if (emissionIndex < 0)
            throw new JCAMPException("missing emission variable");
        if (excitationIndex < 0)
            throw new JCAMPException("missing excitation variable");
        if (intensityIndex < 0)
            throw new JCAMPException("missing intensity variable");
        Double emissionFirst = vars[emissionIndex].getFirst();
        if (emissionFirst == null)
            throw new JCAMPException("missing ##FIRST= for emission");
        double mFirst = emissionFirst.doubleValue();
        Double emissionLast = vars[emissionIndex].getLast();
        if (emissionLast == null)
            throw new JCAMPException("missing ##LAST= for emission");
        double mLast = emissionLast.doubleValue();
        Integer emissionDim = vars[emissionIndex].getDimension();
        if (emissionDim == null)
            throw new JCAMPException("missing ##VARDIM= for emission");
        int mDim = emissionDim.intValue();
        Double excitationFirst = vars[excitationIndex].getFirst();
        if (excitationFirst == null)
            throw new JCAMPException("missing ##FIRST= for excitation");
        double xFirst = excitationFirst.doubleValue();
        Double excitationLast = vars[excitationIndex].getLast();
        if (excitationLast == null)
            throw new JCAMPException("missing ##LAST= for excitation");
        double xLast = excitationLast.doubleValue();
        Integer excitationDim = vars[excitationIndex].getDimension();
        if (excitationDim == null)
            throw new JCAMPException("missing ##VARDIM= for excitation");
        int xDim = excitationDim.intValue();
        JCAMPNTuplePage firstPage = block.getNTuple().getPage(0);
        boolean excitationIsX = true;
        if (firstPage.getPageVariableSymbols()[0].equals(vars[excitationIndex].getSymbol()))
            excitationIsX = false;

        Unit emissionUnit = vars[emissionIndex].getUnit();
        if (emissionUnit == null)
            emissionUnit = CommonUnit.nanometerWavelength;
        Unit excitationUnit = vars[excitationIndex].getUnit();
        if (excitationUnit == null)
            excitationUnit = CommonUnit.nanometerWavelength;
        Unit intensityUnit = vars[intensityIndex].getUnit();
        if (intensityUnit == null)
            intensityUnit = CommonUnit.absorbance;
        Double emissionFactor = vars[emissionIndex].getFactor();
        double mFactor = (emissionFactor == null ? 1.0 : emissionFactor.doubleValue());
        Double excitationFactor = vars[excitationIndex].getFactor();
        double xFactor = (excitationFactor == null ? 1.0 : excitationFactor.doubleValue());
        Double intensityFactor = vars[intensityIndex].getFactor();
        double iFactor = (intensityFactor == null ? 1.0 : intensityFactor.doubleValue());

        IOrderedDataArray1D x;
        IOrderedDataArray1D y;
        double[] intensities;
        if (excitationIsX) {
            x = new EquidistantData(xFirst, xLast, xDim, excitationUnit);
            x.setLabel("Excitation [" + excitationUnit + "]");
            y = new EquidistantData(mFirst, mLast, mDim, emissionUnit);
            y.setLabel("Emission [" + emissionUnit + "]");
            intensities = new double[x.getLength() * y.getLength()];
            if (nPages != emissionDim.intValue())
                log.warn("number of pages != emission dimension, possible missing values");
            for (int i = 0; i < nPages; i++) {
                JCAMPNTuplePage page = block.getNTuple().getPage(i);
                IArray2D data = page.getXYData();
                String emissionStr = page.getPageVariableValue(vars[emissionIndex].getSymbol());
                int index;
                if (emissionStr == null) {
                    index = i * x.getLength();
                    log.warn("missing ##PAGE= emission entry, assuming ordered pages");
                } else { // calculate index
                    double emission = Double.parseDouble(emissionStr);
                    index = y.indexAt(emission);
                    index *= x.getLength();
                }
                IArray1D iArr = data.getYArray();
                for (int j = 0; j < x.getLength(); j++)
                    intensities[index + j] = iArr.pointAt(j);
            }
        } else {
            x = new EquidistantData(mFirst, mLast, mDim, emissionUnit);
            x.setLabel("Emission [" + emissionUnit + "]");
            y = new EquidistantData(xFirst, xLast, xDim, excitationUnit);
            y.setLabel("Excitation [" + excitationUnit + "]");
            intensities = new double[x.getLength() * y.getLength()];
            if (nPages != excitationDim.intValue())
                log.warn("number of pages != excitation dimension, possible missing values");
            for (int i = 0; i < nPages; i++) {
                JCAMPNTuplePage page = block.getNTuple().getPage(i);
                IArray2D data = page.getXYData();
                int index;
                String excitationStr = page.getPageVariableValue(vars[excitationIndex].getSymbol());
                if (excitationStr == null) {
                    index = i * x.getLength();
                    log.warn("missing ##PAGE= excitation entry, assuming ordered pages");
                } else { // calculate index
                    double excitation = Double.parseDouble(excitationStr);
                    index = y.indexAt(excitation);
                    index *= x.getLength();
                }
                IArray1D iArr = data.getYArray();
                for (int j = 0; j < x.getLength(); j++)
                    intensities[index + j] = iArr.pointAt(j);
            }
        }
        spectrum = new Fluorescence2DSpectrum(x, y, new ArrayData(intensities, intensityUnit));

        setNotes(block, spectrum);
        return spectrum;
    }

    /**
     * create Fluorescence peak table (peak spectrum) from JCAMPBlock.
     * 
     * @return FluorescenceSpectrum
     * @param block JCAMPBlock
     * @exception JCAMPException exception thrown if parsing fails.
     */
    private FluorescenceSpectrum createPeakTable(JCAMPBlock block) throws JCAMPException {
        FluorescenceSpectrum spectrum = null;
        Unit xUnit = getXUnits(block);
        if (xUnit == null)
            xUnit = CommonUnit.nanometerWavelength;
        Unit yUnit = getYUnits(block);
        if (yUnit == null)
            yUnit = CommonUnit.intensity;
        double xFactor = getXFactor(block);
        double yFactor = getYFactor(block);
        int nPoints = getNPoints(block);
        Object[] tables = getPeaktable(block, nPoints, xFactor, yFactor);
        Peak1D[] peaks = (Peak1D[]) tables[0];
        if (nPoints != peaks.length) {
            block.getErrorHandler().error(
                "incorrect ##NPOINTS=: expected "
                    + Integer.toString(nPoints)
                    + " but got "
                    + Integer.toString(peaks.length));
            nPoints = peaks.length;
        }
        Arrays.sort(peaks);
        double[] px = new double[nPoints];
        double[] py = new double[nPoints];
        for (int i = 0; i < nPoints; i++) {
            px[i] = peaks[i].getPosition()[0];
            py[i] = peaks[i].getHeight();
        }
        IOrderedDataArray1D x = new OrderedArrayData(px, xUnit);
        IDataArray1D y = new ArrayData(py, yUnit);
        spectrum = new FluorescenceSpectrum(x, y, false);
        spectrum.setPeakTable(peaks);
        if (tables.length > 1) {
            spectrum.setPatternTable((Pattern[]) tables[1]);
            if (tables.length > 2)
                spectrum.setAssignments((Assignment[]) tables[2]);
        }
        setNotes(block, spectrum);
        return spectrum;
    }

    /**
     * createSpectrum method comment.
     */
    public Spectrum createSpectrum(JCAMPBlock block) throws JCAMPException {
        if (block.getSpectrumID() != ISpectrumIdentifier.FLUORESCENCE)
            block.getErrorHandler().fatal("JCAMP reader adapter missmatch");
        if (block.isNTupleBlock()) { // 2D
            Fluorescence2DSpectrum spectrum = createFS2D(block);
            //        setNotes(block, spectrum);
            return spectrum;
        }
        FluorescenceSpectrum spectrum = null;
        JCAMPDataRecord ldrDataType = block.getDataRecord("DATATYPE");
        String dataType = ldrDataType.getContent().toUpperCase();
        JCAMPBlock.Type type = block.getType();
        if (type.equals(JCAMPBlock.Type.FULLSPECTRUM))
            spectrum = createFS(block);
        else if (type.equals(JCAMPBlock.Type.PEAKTABLE))
            spectrum = createPeakTable(block);
        else if (type.equals(JCAMPBlock.Type.ASSIGNMENT))
            spectrum = createPeakTable(block);
        else // never reached
            block.getErrorHandler().fatal("illegal block type");
        return spectrum;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy