No BSD License  

Highlights from
PerkinElmer IR data file import tools

from PerkinElmer IR data file import tools by Ben Perston
Utilities to read PerkinElmer infrared spectroscopy and imaging files (.sp, .fsm, .lsc, .imp, .vis)

spload(filename)
function [data, xAxis, misc] = spload(filename)
% Reads in spectra from PerkinElmer block structured files.
% This version supports 'Spectrum' SP files.
% Note that earlier 'Data Manager' formats are not supported.
%
% [data, xAxis, misc] = spload(filename):
%   data:  1D array of doubles
%   xAxis: vector for abscissa (e.g. Wavenumbers).
%   misc: miscellanous information in name,value pairs

% Copyright (C)2007 PerkinElmer Life and Analytical Sciences
% Stephen Westlake, Seer Green
%
% History
% 2007-04-24 SW     Initial version

% Block IDs
DSet2DC1DIBlock               =  120;
HistoryRecordBlock            =  121;
InstrHdrHistoryRecordBlock    =  122;
InstrumentHeaderBlock         =  123;
IRInstrumentHeaderBlock       =  124;
UVInstrumentHeaderBlock       =  125;
FLInstrumentHeaderBlock       =  126;
% Data member IDs
DataSetDataTypeMember              =  -29839;
DataSetAbscissaRangeMember         =  -29838;
DataSetOrdinateRangeMember         =  -29837;
DataSetIntervalMember              =  -29836;
DataSetNumPointsMember             =  -29835;
DataSetSamplingMethodMember        =  -29834;
DataSetXAxisLabelMember            =  -29833;
DataSetYAxisLabelMember            =  -29832;
DataSetXAxisUnitTypeMember         =  -29831;
DataSetYAxisUnitTypeMember         =  -29830;
DataSetFileTypeMember              =  -29829;
DataSetDataMember                  =  -29828;
DataSetNameMember                  =  -29827;
DataSetChecksumMember              =  -29826;
DataSetHistoryRecordMember         =  -29825;
DataSetInvalidRegionMember         =  -29824;
DataSetAliasMember                 =  -29823;
DataSetVXIRAccyHdrMember           =  -29822;
DataSetVXIRQualHdrMember           =  -29821;
DataSetEventMarkersMember          =  -29820;
% Type code IDs
ShortType               = 29999;
UShortType              = 29998;
IntType                 = 29997;
UIntType                = 29996;
LongType                = 29995;
BoolType                = 29988;
CharType                = 29987;
CvCoOrdPointType        = 29986;
StdFontType             = 29985;
CvCoOrdDimensionType    = 29984;
CvCoOrdRectangleType    = 29983;
RGBColorType            = 29982;
CvCoOrdRangeType        = 29981;
DoubleType              = 29980;
CvCoOrdType             = 29979;
ULongType               = 29978;
PeakType                = 29977;
CoOrdType               = 29976;
RangeType               = 29975;
CvCoOrdArrayType        = 29974;
EnumType                = 29973;
LogFontType             = 29972;


fid = fopen(filename,'r');
if fid == -1
    error('Cannot open the file.');
    return
end

% Fixed file header of signature and description
signature = setstr(fread(fid, 4, 'uchar')');
if ~strcmp(signature, 'PEPE')
    
    error('This is not a PerkinElmer block structured file.');
    return
end
description = setstr(fread(fid, 40, 'uchar')');

% Initialize a variable so we can tell if we have read it.
xLen = int32(0);

% The rest of the file is a list of blocks
while ~feof(fid)
    blockID = fread(fid,1,'int16');
    blockSize = fread(fid,1,'int32');
    
    % feof does not go true until after the read has failed.
    if feof(fid)
        break
    end
    
    switch blockID
        case DSet2DC1DIBlock
        % Wrapper block.  Read nothing.

        case DataSetAbscissaRangeMember
            innerCode = fread(fid, 1, 'int16');
            %_ASSERTE(CvCoOrdRangeType == nInnerCode);
            x0 = fread(fid, 1, 'double');
            xEnd = fread(fid, 1, 'double');
                
        case DataSetIntervalMember
            innerCode = fread(fid, 1, 'int16');
            xDelta = fread(fid, 1, 'double');

        case DataSetNumPointsMember
            innerCode = fread(fid, 1, 'int16');
            xLen = fread(fid, 1, 'int32');

        case DataSetXAxisLabelMember
            innerCode = fread(fid, 1, 'int16');
            len = fread(fid, 1, 'int16');
            xLabel = setstr(fread(fid, len, 'uchar')');

        case DataSetYAxisLabelMember
            innerCode = fread(fid, 1, 'int16');
            len = fread(fid, 1, 'int16');
            yLabel = setstr(fread(fid, len, 'uchar')');
            
        case DataSetAliasMember
            innerCode = fread(fid, 1, 'int16');
            len = fread(fid, 1, 'int16');
            alias = setstr(fread(fid, len, 'uchar')');
          
        case DataSetNameMember
            innerCode = fread(fid, 1, 'int16');
            len = fread(fid, 1, 'int16');
            originalName = setstr(fread(fid, len, 'uchar')');
          
        case DataSetDataMember
            innerCode = fread(fid, 1, 'int16');
            len = fread(fid, 1, 'int32');
            % innerCode should be CvCoOrdArrayType
            % len should be xLen * 8
            if xLen == 0
                xLen = len / 8;
            end
            data = fread(fid, xLen, 'double');
 
        otherwise               % unknown block, just seek past it
            fseek(fid, blockSize, 'cof');
    end
end
fclose(fid);

if xLen == 0
    error('The file does not contain spectral data.');
    return
end

% Expand the axes specifications into vectors
xAxis = x0 : xDelta : xEnd;

% Return the other details as name,value pairs
misc(1,:) = {'xLabel', xLabel};
misc(2,:) = {'yLabel', yLabel};
misc(3,:) = {'alias', alias};
misc(4,:) = {'original name', originalName};

Contact us at files@mathworks.com