4.83333

4.8 | 19 ratings Rate this file 51 Downloads (last 30 days) File Size: 2.63 KB File ID: #11224

Andor SIF image reader

by

 

30 May 2006 (Updated )

Read Andor SIF multi-channel image files.

| Watch this File

File Information
Description

Import the image data, background and reference from Andor SIF multi-channel image files to named structures in MATLAB. Besides the image data, most of the meta-information contained in the SIF file is also imported.

Note:

The file format was reverse engineered by identifying known information within the corresponding file. There are still non-identified regions left over but the current summary is available on request.

MATLAB release MATLAB 6.0 (R12)
Tags for This File   Please login to tag files.
Please login to add a comment or rating.
Comments and Ratings (34)
14 May 2014 Antonio Consoli

cannot paste the script here

14 May 2014 Antonio Consoli

I have changed the script for wavelength conversion from pixel number. the sif trace must be taken with wavelength calibatred horizontal axis. here the new version of the script :

13 May 2014 Antonio Consoli

i am using the script posted by Uli on 18 june 2012, it works great. Thank you a lot, Uli. To Deepak : if I understand , try typing func_ext_uli_sifread2('image1.sif', 1);

One question : is there a way to get the wavelength values ?? Thanks a lot to all contributors !

31 Mar 2014 Deepak

I am wondering if this code can be used to read the individual sif image files which were taken using Andor software.
My guess would be yes, if so, could anyone let me know how to use this function for that purpose. I tried the following while making sure that the image1 is placed in the same directory path..

>> sifread('image1.sif')

Error using sifread (line 44)
Could not open the file.

Cheers,

23 Jan 2014 Atefeh  
11 Oct 2013 Yinpeng

how to read the "Andor Technology Multi-Channel File"?

18 Jun 2012 Uli Kleßinger

Here is the script i currently use to read kinetic series from andor scmos, 11bit and 16bit and iXon. The reason why i'm not using the andor software is that my script takes 100ms to read 1 frame of a 1GB movie and the andor software takes up to 10seconds (on my computer). Take care, because i modified the output struct of the file and the name of its main function "func_ext_uli_sifread2(filename, framenumber)"!!

%Note:
%
% The file format was reverse engineered by identifying known
% information within the corresponding file. There are still
% non-identified regions left over but the current summary is
% available on request.
%

% Marcel Leutenegger © November 2006
%
function info=func_ext_uli_sifread2(filename, framenumber)

file = filename;
if nargin==1
currentFrameNumber = 0;
elseif nargin==2
currentFrameNumber = framenumber;
end
f=fopen(file,'r');
if f < 0
error('Could not open the file.');
end
if ~isequal(fgetl(f),'Andor Technology Multi-Channel File')
fclose(f);
error('Not an Andor SIF image file.');
end
skipLines(f,1);
[info]=readSection(f, currentFrameNumber);
fclose(f);
if currentFrameNumber > 0
pic_out = info.imageData;
%pic_plot_uint8 = uint8(pic_out/max(pic_out(:))*255);
pic_uint8 = uint8(round(pic_out/(2^info.currentBitDepth)*255));
%asdasd
%size(pic_uint8)
pic_uint8_rgb = zeros([size(pic_uint8), 3], 'uint8');
pic_uint8_rgb(:,:,1) = pic_uint8;
pic_uint8_rgb(:,:,2) = pic_uint8;
pic_uint8_rgb(:,:,3) = pic_uint8;

info.imageData_uint8_rgb = pic_uint8_rgb;
info.imageData_orig = NaN;
try
pic_rgb = zeros([size(pic_uint8), 3], 'double');
pic_rgb(:,:,1) = pic_out;
pic_rgb(:,:,2) = pic_out;
pic_rgb(:,:,3) = pic_out;
info.imageData_orig = pic_rgb;
catch
end
end

%figure
%imagesc(pic_uint8_rgb)

%Read a file section.
%
% f File handle
% info Section data
% next Flags if another section is available
%
function [info]=readSection(f, currentFrameNumber)

settingsline = fgetl(f);
settings_cell = regexp(settingsline, '(\S)+\s', 'match');
file_timestamp_utc_in_sec = sscanf(settings_cell{5}, '%f');
temperature1_in_celsius = sscanf(settings_cell{6}, '%f');
exposureTime_in_sec = sscanf(settings_cell{13}, '%f');
cycleTime = sscanf(settings_cell{14}, '%f');
accumulateCycleTime = sscanf(settings_cell{15}, '%f');
accumulateCycles = sscanf(settings_cell{16}, '%f');
stackCycleTime = sscanf(settings_cell{18}, '%f');
pixelReadoutTimeSec = sscanf(settings_cell{19}, '%f');
EMgain = sscanf(settings_cell{22}, '%f');
verticalShiftSpeed = sscanf(settings_cell{42}, '%f');
preAmpGain = sscanf(settings_cell{44}, '%f');
temperature2_in_celsius = sscanf(settings_cell{48}, '%f');
version1 = sscanf(settings_cell{55}, '%f');
version2 = sscanf(settings_cell{56}, '%f');
version3 = sscanf(settings_cell{57}, '%f');
version4 = sscanf(settings_cell{58}, '%f');

timestamp_utc_in_sec = file_timestamp_utc_in_sec; % o(5): UTC: seconds since 1970; ACHTUNG Kamera speichert in UTC OHNE Sommer/Winterzeit
timestamp_total_matlab_orig = datenum([1970 1 1 0 0 timestamp_utc_in_sec]); %umrechnen in die Matlab zeitrechnung
isDlST = isDaylightSavingTime(timestamp_total_matlab_orig); %nachschaun obs waehrend der sommerzeit war
additionalHourDueToDlST = 0;
if isDlST
additionalHourDueToDlST = 1;
end
additionalHourDueToTimezone = 1; %sind ja gmt+1!!
matlab_correction = additionalHourDueToTimezone/24 + additionalHourDueToDlST/24;
timestamp_total_matlab_corrected = timestamp_total_matlab_orig + matlab_correction;
timestamp_total_matlab_corrected_vec = datevec(timestamp_total_matlab_corrected);
timestamp_total_matlab_corrected_vec_day = [timestamp_total_matlab_corrected_vec(1:3) 0 0 0];
timestamp_rel_in_sec = etime(timestamp_total_matlab_corrected_vec, timestamp_total_matlab_corrected_vec_day);
timestamp_rel_in_ms = timestamp_rel_in_sec*1000;

%% Werte aus dem Sif file
info.date = datestr(timestamp_total_matlab_corrected);
info.filetype = 'andor-sif-file';
if temperature1_in_celsius~=-999
info.temperature = temperature1_in_celsius;
else
info.temperature = sprintf('%d UNSTABLE', temperature2_in_celsius);
end
info.accumulateCycles = accumulateCycles;
info.accumulateCycleTime = accumulateCycleTime;
info.cycleTime = cycleTime;
info.EMgain = EMgain;
info.exposureTime = exposureTime_in_sec;
info.pixelReadoutTimeSec = pixelReadoutTimeSec;
info.preAmpGain = preAmpGain;
info.stackCycleTime = stackCycleTime;
info.Version = sprintf('%d.%d.%d.%d', version1, version2, version3, version4);
info.verticalShiftSpeed = verticalShiftSpeed;

%% Daraus berechnete Werte
time_between_to_pics = info.stackCycleTime;

%% In die Ausgabe uebernehmen
info.framerate = 1/time_between_to_pics; %nicht sicher ob das stimmt
info.PixelReadoutRateHz=1/info.pixelReadoutTimeSec;
info.time_between_to_pics = time_between_to_pics;

%% Weitere Daten aus dem Sif file
info.detectorType=readLine(f);
if strcmp(info.detectorType, 'DU897_BV')
info.currentBitDepth = 14;
else
info.currentBitDepth = 11;
end

info.detectorSize=fscanf(f,'%d',[1 2]);
info.fileName=readString(f);
info.possibleBitDepth=fscanf(f,'%d',[1 2]);

current_line_text = '';
while isempty(strfind(current_line_text, 'Pixel number'))
current_line_text = fgetl(f);
end
skipLines(f,1)
imageArealine = fgetl(f);
frameArealine = fgetl(f);
imageAreaData=sscanf(imageArealine,'Pixel number%d %d %d %d %d %d %d %d %d');
frameAreaData=sscanf(frameArealine,'%d %d %d %d %d %d %d');
pixelPerImage = imageAreaData(9);
pixelInVideo = imageAreaData(8);
leftPixel = frameAreaData(2);
topPixel = frameAreaData(3);
rightPixel = frameAreaData(4);
bottomPixel = frameAreaData(5);
imageArea = [imageAreaData(2) imageAreaData(5) imageAreaData(7);imageAreaData(4) imageAreaData(3) imageAreaData(6)];
frameArea = [leftPixel bottomPixel; rightPixel topPixel]; %left, top, right, bottom!
vBin = frameAreaData(7); %vielleicht genau andersrum
hBin = frameAreaData(6); %vielleicht genau andersrum
frameBins = [vBin hBin]; %vielleicht genau andersrum

width = (rightPixel - leftPixel + 1)/hBin;
height = (topPixel - bottomPixel + 1)/vBin;

info.Width = width;
info.Height = height;
info.imageArea = imageArea;
info.frameArea = frameArea;
info.vBin = vBin;
info.hBin = hBin;
resolution=(1 + diff(info.frameArea))./frameBins;
NumFrames=1 + diff(info.imageArea(5:6));
info.NumFrames = NumFrames;
info.resolution = resolution;
info.pixelPerFrame = prod(resolution);

timestamps_from_siffile = fscanf(f,'%d\n', info.NumFrames); %sind aber angeblich auch nur berechnet
info.timestamps = timestamp_rel_in_ms + (1/info.framerate*(0:(info.NumFrames-1)))*1000;

if currentFrameNumber >0 && currentFrameNumber <= info.NumFrames

info.timestamp = info.timestamps(currentFrameNumber);
num_bytes_to_skip_for_curr_frame = 4 * ((currentFrameNumber-1) * info.pixelPerFrame);

fseek(f, num_bytes_to_skip_for_curr_frame, 'cof');
fseek(f, 2, 'cof'); %keine ahnung warum 2 byte offset..
if prod(resolution) ~= pixelPerImage || pixelPerImage*NumFrames ~= pixelInVideo
fclose(f)
error('Inconsistent image header.');
end

info.imageData=(reshape(fread(f,info.pixelPerFrame,'single=>single'), info.Width, info.Height ))';
end

%Read a character string.
%
% f File handle
% o String
%
function o=readString(f)
n=fscanf(f,'%d',1);
if isempty(n) || n < 0 || isequal(fgetl(f),-1)
fclose(f);
error('Inconsistent string.');
end
o=fread(f,[1 n],'uint8=>char');

%Read a line.
%
% f File handle
% o Read line
%
function o=readLine(f)
o=fgetl(f);
if isequal(o,-1)
fclose(f);
error('Inconsistent image header.');
end
o=deblank(o);

%Skip bytes.
%
% f File handle
% N Number of bytes to skip
%
function skipBytes(f,N)
[~,n]=fread(f,N,'uint8');
if n < N
fclose(f);
error('Inconsistent image header.');
end

%Skip lines.
%
% f File handle
% N Number of lines to skip
%
function skipLines(f,N)
for n=1:N
if isequal(fgetl(f),-1)
fclose(f);
error('Inconsistent image header.');
end
end

29 Mar 2012 Subhash

Dear .SIF user
I am very new in the community and new user of Matlab. I have recorded data and image files in .sif format using Andor CCD camera. Now I am facing problem in opening the files. I putted sifread file into the work folder of Matlab. Now what should I do inorder to open .fif file. Can anyone help me in step-by step manner.
Thanks in advance
with regards

17 Mar 2012 Todd Karin

I have modified this file to work with sif files from the Andor Newton CCD camera. You can download the files on my website:

http://students.washington.edu/tkarin/research.html

I also modified the script to allow for a variety of plotting options.

17 Mar 2012 Todd Karin  
14 Mar 2012 Eyal

I just wanted to warn people not to waste their time with the Andor software. It DOES NOT work! It is much easier to use the code posted here (with minor adjustments from the other users comments).

09 Feb 2012 Phillip

I am not having much luck with this stuff. Here are the things I have tried:

1) The folder in the Solis directory 'MatlabSIFReader' that came with my version of Solis (uses SDK version 2.92.32003.0)
2) The one pointed to by Phil from Andor above (SDK version 2.90.20000.2 - no idea why the version on the Andor site does not match the latest)
3) The really useful script put together here
4) The alteration to the script made by Uli Kleßinger above for the SCMOS, which is the camera I have.
5) The "Export As..." command to convert the .SIF file to an .AVI, which I could easily import into Matlab. When I try this, the Solis software crashes every time(!!).

This Andor camera is a nice piece of hardware, but the software is simply atrocious.

06 Feb 2012 Sven

Hello together,
I'm using this very handy script now for a few weeks without any problem. But today, for all my Andor files I measured today, I get this strange error:
Error using sifread>readString (line 136)
Inconsistent string.

Error in sifread>readSection (line 100)
info.dataType=readString(f);

Error in sifread (line 51)
[data,next]=readSection(f);

Error in nscs_01_sifread (line 13)
[data,back,ref]=sifread(filename)

Error in run (line 57)
evalin('caller', [s ';']);

I think it's most likely an error of the Andor software, because I didn't change the matlab code at all. However, the Andor software didn't change as well! Did anyone had a similar problem or knows which function can influence the error? The sif-files have the correct size and can be reopenend by the Andor software.
Would be happy about any comment.
Cheers
Sven

01 Apr 2011 Alexander

Dear Phil, I tried to use Matlab SIF Viewer, but it seems to work only under Windows. I need some solution (ideally official) for Matlab under Linux. Do you have any?

25 Mar 2011 Phil

Hello,

I am an employee of Andor Technology. Currently we offer on our website (via registration) a Matlab SIF viewer. This is updated with each release:

You can download the latest version of the Matlab SIF Viewer; Go the bottom of the page of the site (www.andor.com), click "Downloads". Then click on the "Log In" in the upper-right-hand corner, and register. An email will be sent to the email you used to register, click on the link inside the confirming email. You can find the latest version of the Matlab viewer among others in the "Software" folder on the left hand side of the screen (https://www.andor.com/download/).

If you ever have any questions, please give us a call or contact us via our website. We try to respond to all inquires as soon as possible.

Warm Regards,
Phil

20 Jan 2011 Matthew Diasio

We are also using an Andor iXon EMCCD and attempted to modify our code like Bradley Smith, replacing 'DV897_BV' with our model number, DU897_BV. We get the same error as Matt Baker does, namely

Error using ==> sifread>readString at 136
Inconsistent string.

Error in ==> sifread>readSection at 100
info.dataType=readString(f);

Error in ==> sifread at 51
[data,next]=readSection(f);

but we are just testing the program with a single .sif image, not the kinetic .sif images (although we would like to build up to that point in the future). Any suggestions on how to fix this, or why we should have an inconsistent string error in a single image?

10 Jan 2011 Uli Kleßinger

@ Matt and users for SCMOS

I used it to read the data from a cinetic Sif-File from an Andor SCMOS Camera. Therefore i had to change the readSection to the following:

function [info]=readSection(f, currentFrameNumber)
o=fscanf(f,'%d',6);
info.date=datestr(o(5)/86400 + 719529);
info.temperature=o(6);
skipBytes(f,10)
o=fscanf(f,'%f',5);
info.exposureTime=o(2);
info.cycleTime=o(3);
info.accumulateCycles=o(5);
info.accumulateCycleTime=o(4);
skipBytes(f,2)
o=fscanf(f,'%f',2);
info.stackCycleTime=o(1);
info.pixelReadoutTime=o(2);
o=fscanf(f,'%d',3);
info.gainDAC=o(3);
skipLines(f,1)
info.detectorType=readLine(f);
info.detectorSize=fscanf(f,'%d',[1 2]);
info.fileName=readString(f);
info.possibleBitDepth=fscanf(f,'%d',[1 2]);
skipLines(f,3)
skipBytes(f,14)
info.shutterTime=fscanf(f,'%f',[1 2]);
skipLines(f,18)

info.imageAxis=fscanf(f,'%s',3);
info.currentBitDepth = 11;
o=fscanf(f,'%d %d %d %d %d %d %d %d 65538 %d %d %d %d %d %d',14);
info.imageArea=[o(1) o(4) o(6);o(3) o(2) o(5)];
info.frameArea=[o(9) o(12);o(11) o(10)];
info.frameBins=[o(14) o(13)];
s=(1 + diff(info.frameArea))./info.frameBins;
z=1 + diff(info.imageArea(5:6));
info.numberOfFrames = z;
info.resolution = s;
info.pixelPerFrame = prod(s);

skipLines(f,1)
info.timeStamps = fscanf(f,'%d\n', info.numberOfFrames);

if currentFrameNumber <= info.numberOfFrames

info.timeStamp = info.timeStamps(currentFrameNumber);
num_bytes_to_skip_for_curr_frame = 4 * ((currentFrameNumber-1) * info.pixelPerFrame);

fseek(f, num_bytes_to_skip_for_curr_frame, 'cof');
fseek(f, 2, 'cof'); %keine ahnung warum 2 byte offset..
if prod(s) ~= o(8) || o(8)*z ~= o(7)
fclose(f)
error('Inconsistent image header.');
end

info.imageData=reshape(fread(f,info.pixelPerFrame,'single=>single'), info.resolution);
end

12 Nov 2010 Tomas Odstrcil

solution of Parker' problem:
add skipBytes(f,12) at 141 line of trusso version and skipBytes(f,25) at 121 line. It is not the corrected solution, but it works.

01 Nov 2010 Matt Baker

I have used sifread successfully to read single .sif images into matlab. I am interested now in loading in kinetic .sif images, that is, .sif files that have a 'stacked' set of many images (up to 5000 frames). Is this implementable? It is not clear to me how Andor break up the stacked images.

Running sifread on a test kinetic sif breaks down with the following error (when readstring is called as a function on line 101 - info.imageAxis=readString(f):

??? Error using ==> sifread>readString at 136
Inconsistent string.

Error in ==> sifread>readSection at 100
info.dataType=readString(f);

Error in ==> sifread at 51
[data,next]=readSection(f);

Does anyone know the details of the .sif kinetic format?

Thanks,

Matt.

08 Oct 2010 Benjamin

I have the same problem as Joshua.
Any ideas ?

22 Jun 2010 Joshua Parker

I'm attempting to input files created with an Andor iXon 897 EMCCD camera and I keep getting the following error:

??? Attempted to access o(1); index out of bounds because numel(o)=0.

Error in ==> sifread>readSection at 103
info.imageArea=[o(1) o(4) o(6);o(3) o(2) o(5)];

Error in ==> sifread at 51
[data,next]=readSection(f);

Any ideas?

12 May 2010 sebastiano trusso

I modified the original program by M. Leutenegger.
The modified program is able to read sif files generated by the Andor Solis program ver. 4.9.30004.0 (iCCD - iStar DH734 18mm 1024-1024).
Two info were added: info.timeGate and info.timeDelay, used by the gateable iStar camera.

%Read Andor SIF multi-channel image file.
%
%Synopsis:
%
% [data,back,ref]=sifread(file)
% Read the image data, background and reference from file.
% Return the image data, background and reference in named
% structures as follows:
%
% .temperature CCD temperature [°C]
% .exposureTime Exposure time [s]
% .cycleTime Time per full image take [s]
% .accumulateCycles Number of accumulation cycles
% .accumulateCycleTime Time per accumulated image [s]
% .stackCycleTime Interval in image series [s]
% .pixelReadoutTime Time per pixel readout [s]
% .detectorType CCD type
% .detectorSize Number of read CCD pixels [x,y]
% .fileName Original file name
% .shutterTime Time to open/close the shutter [s]
% .frameAxis Axis unit of CCD frame
% .dataType Type of image data
% .imageAxis Axis unit of image
% .imageArea Image limits [x1,y1,first image;
% x2,y2,last image]
% .frameArea Frame limits [x1,y1;x2,y2]
% .frameBins Binned pixels [x,y]
% .timeStamp Time stamp in image series
% .imageData Image data (x,y,t)

%Note:
%
% The file format was reverse engineered by identifying known
% information within the corresponding file. There are still
% non-identified regions left over but the current summary is
% available on request.
%

% Marcel Leutenegger © November 2006
%
%Note:
%
% The original program by M. Leutenegger was modified.
% The program is able to read sif files generated by the
% Andor Solis program ver. 4.9.30004.0
% (iCCD - iStar DH734 18mm)
%
% Sebastiano Trusso May 2010

function [data,back,ref]=sifread(file)
f=fopen(file,'r');
if f < 0
error('Could not open the file.');
end
if ~isequal(fgetl(f),'Andor Technology Multi-Channel File')
fclose(f);
error('Not an Andor SIF image file.');
end
skipLines(f,1);
[data,next]=readSection(f);
if nargout > 1 & next == 1
[back,next]=readSection(f);
if nargout > 2 & next == 1
ref=back;
back=readSection(f);
else
ref=struct([]);
end
else
back=struct([]);
ref=back;
end
fclose(f);

%Read a file section.
%
% f File handle
% info Section data
% next Flags if another section is available
%
function [info,next]=readSection(f)
o=fscanf(f,'%d',6);
info.temperature=o(6);
skipBytes(f,10);
o=fscanf(f,'%f',5);
info.exposureTime=o(2);
info.cycleTime=o(3);
info.accumulateCycles=o(5);
info.accumulateCycleTime=o(4);
skipBytes(f,2);
o=fscanf(f,'%f',2);
info.stackCycleTime=o(1);
info.pixelReadoutTime=o(2);
%% New info - [o(4) Delay] [o(5) Gate] S.T.
o=fscanf(f,'%d',5);% original by M.L. -> o=fscanf(f,'%d',3);
info.gainDAC=o(3);
info.timeDelay=o(4);
info.timeGate=o(5);

skipLines(f,1);
info.detectorType=readLine(f);
info.detectorSize=fscanf(f,'%d',[1 2]);
info.fileName=readString(f);
%% Modified by S.T.
skipLines(f,13);
%%

skipLines(f,3);

%% Commented by S.T.
%skipBytes(f,14);
%info.shutterTime=fscanf(f,'%f',[1 2])
%skipLines(f,8);
%if strmatch('Luc',info.detectorType)
% skipLines(f,2); % Andor Luca
%end
%%
info.frameAxis=readString(f);
info.dataType=readString(f);
info.imageAxis=readString(f);
o=fscanf(f,'65538 %d %d %d %d %d %d %d %d 65538 %d %d %d %d %d %d',14);
info.imageArea=[o(1) o(4) o(6);o(3) o(2) o(5)];
info.frameArea=[o(9) o(12);o(11) o(10)];
info.frameBins=[o(14) o(13)];
s=(1 + diff(info.frameArea))./info.frameBins;
z=1 + diff(info.imageArea(5:6));
if prod(s) ~= o(8) | o(8)*z ~= o(7);
fclose(f);
error('Inconsistent image header.');
end
%% Commented by S.T.
%for n=1:z
% o=readString(f);
%if numel(o)
% fprintf('%s\n',o); % comments
%end
%end
%%
info.timeStamp=fread(f,1,'uint16');
info.imageData=reshape(fread(f,prod(s)*z,'single=>single'),[s z]);

%% Commented by S.T.
%o=readString(f) % ???
%if numel(o)
% fprintf('%s\n',o); % ???
%end

next=fscanf(f,'%d',1);

%Read a character string.
%
% f File handle
% o String
%
function o=readString(f)
n=fscanf(f,'%d',1);
if isempty(n) | n < 0 | isequal(fgetl(f),-1)
fclose(f);
error('Inconsistent string.');
end
o=fread(f,[1 n],'uint8=>char');

%Read a line.
%
% f File handle
% o Read line
%
function o=readLine(f)
o=fgetl(f);
if isequal(o,-1)
fclose(f);
error('Inconsistent image header.');
end
o=deblank(o);

%Skip bytes.
%
% f File handle
% N Number of bytes to skip
%
function skipBytes(f,N)
[s,n]=fread(f,N,'uint8');
if n < N
fclose(f);
error('Inconsistent image header.');
end

%Skip lines.
%
% f File handle
% N Number of lines to skip
%
function skipLines(f,N)
for n=1:N
if isequal(fgetl(f),-1)
fclose(f);
error('Inconsistent image header.');
end
end

24 Sep 2009 Woosub

I'm Luca user. But when I downloaded the file, there are some dim-mismatch. so, I corrected it a little to my Luca. I checked with Hex editor and new Andor SOLIS. Now, I`m processing more than 100,000 images with this program. Thank you Marcel Leutenegger.

function [data,back,ref]=sifread(file)
f=fopen(file,'r');
if f < 0
error('Could not open the file.');
end
if ~isequal(fgetl(f),'Andor Technology Multi-Channel File')
fclose(f);
error('Not an Andor SIF image file.');
end
skipLines(f,1);
[data,next]=readSection(f);
if nargout > 1 & next == 1
[back,next]=readSection(f);
if nargout > 2 & next == 1
ref=back;
back=readSection(f);
else
ref=struct([]);
end
else
back=struct([]);
ref=back;
end
fclose(f);

%Read a file section.
%
% f File handle
% info Section data
% next Flags if another section is available
%
function [info,next]=readSection(f)
o=fscanf(f,'%f',6);
info.temperature=o(6);
skipBytes(f,10);
o=fscanf(f,'%f',5);
info.exposureTime=o(2);
info.cycleTime=o(3);
info.accumulateCycles=o(5);
info.accumulateCycleTime=o(4);
skipBytes(f,2);
o=fscanf(f,'%f',2);
info.stackCycleTime=o(1);
info.pixelReadoutTime=o(2);
o=fscanf(f,'%f',3);
info.gainDAC=o(3);
skipLines(f,1);
info.detectorType=readLine(f);
info.detectorSize=fscanf(f,'%f',[1 2]);
info.fileName=readString(f);
skipLines(f,3);
skipBytes(f,14);
info.shutterTime=fscanf(f,'%f',[1 2]);
skipLines(f,8);
if strmatch('Luc',info.detectorType)
skipLines(f,9); % Andor Luca
end
info.frameAxis=readString(f);
info.dataType=readString(f);
info.imageAxis=readString(f);
o=fscanf(f,'65538 %d %d %d %d %d %d %d %d 65538 %d %d %d %d %d %d',14);
info.imageArea=[o(1) o(4) o(6);o(3) o(2) o(5)];
info.frameArea=[o(9) o(12);o(11) o(10)];
info.frameBins=[o(14) o(13)];
s=(1 + diff(info.frameArea))./info.frameBins;
z=1 + diff(info.imageArea(5:6));
if prod(s) ~= o(8) | o(8)*z ~= o(7)
fclose(f);
error('Inconsistent image header.');
end
for n=1:z
o=readString(f);
if numel(o)
fprintf('%s\n',o); % comments
end
end
info.timeStamp=fread(f,1,'uint16');
skipLines(f,1);
info.imageData=reshape(fread(f,prod(s)*z,'single=>single'),[s z]);
next=fscanf(f,'%d',1);

%Read a character string.
%
% f File handle
% o String
%
function o=readString(f)
n=fscanf(f,'%d',1);
if isempty(n) | n < 0 | isequal(fgetl(f),-1)
fclose(f);
error('Inconsistent string.');
end
o=fread(f,[1 n],'uint8=>char');

%Read a line.
%
% f File handle
% o Read line
%
function o=readLine(f)
o=fgetl(f);
if isequal(o,-1)
fclose(f);
error('Inconsistent image header.');
end
o=deblank(o);

%Skip bytes.
%
% f File handle
% N Number of bytes to skip
%
function skipBytes(f,N)
[s,n]=fread(f,N,'uint8');
if n < N
fclose(f);
error('Inconsistent image header.');
end

%Skip lines.
%
% f File handle
% N Number of lines to skip
%
function skipLines(f,N)
for n=1:N
if isequal(fgetl(f),-1)
fclose(f);
error('Inconsistent image header.');
end
end

10 Dec 2008 Marcel Leutenegger

Dear all,

thanks for the comments. It seems the SIF reader is of interest to quite a number of people :-)

Meanwhile, I got a few more feedbacks concerning compatibility issues. The SIF format typically changes a bit with new Andor SOLIS releases. That is it would be more robust to check for the file version than the detector type. If none of the comments above helps, you may try the following:

After 129: info.shutterTime=fscanf(f,'%f',[1 2]);
130: skipLines(f,13);
131..133: comment out

147: for n=0:z % one more comment?

155: % skipBytes(f,2); % no time-stamp?

Otherwise, open a small SIF file with an ASCII/Hex editor and compare with the program.

30 Oct 2008 rajiv bharadwaj

never mind got it, my bad, works great!

30 Oct 2008 rajiv bharadwaj

I am a little confused. I can run the script fine but how do I access the data in the individual frames? The variable imageData seems to have the info. but not sure how to, say, plot the intensity profile of each frame...

29 Apr 2008 Ralph Ernstorfer

Excellent, thanks to Marcel and Chad & Co! Regarding the detector.Type: as it seems to work with any Andor sif file, the if condition (lines 96 and 98) can be removed.

05 Apr 2008 Asger Krüger

Very nice program! Also I had to change line 96 according to Bradley Smith and Chad Lieber's comments. Unfortunately though I have some very big files where the data matrix do not seem to be processable with fread, causing a crash on the subsequent dim mismatch.

24 Mar 2008 Andy Pascall

Chad Lieber's comments helped me out.

Great work. Saved me a bunch of time manually converting files to AVI in SOLIS.

14 Mar 2008 Chad Lieber

As per Bradley Smith's comments, I also needed to change the detectorType string match to get it to work properly. Easily done by first examing the info.detectorType read on line 89, then changing line 96 to match appropriately. Easy change, and very appreciated.

06 Mar 2008 Bradley Steel

Excellent. I was tearing my hair out trying to get image data from multiple sif files into MATLAB quickly.

Thanks.

13 Feb 2008 Bradley Smith

We found that with our Andor iXon EMCCD we needed to change line 96 from:
if strmatch('Luc',info.detectorType)
to
if strcmp('Luc',info.detectorType) ||... strcmp('DV897_BV',info.detectorType)
otherwise great. Thanks Marcel.

04 Dec 2007 Roland Vulliamy  
08 Jan 2007 Felix Wong

I'm just in need of this.thanks to Marcel:)

Updates
29 Jun 2006

Fixed an offset bug when reading kinetic series or single/multi-track images. The field "timeStamps" was renamed to "timeStamp" now containing a single integer value per image or track, respectively.

Contact us