read only 4 bits at a time?

I have a binary file that I need to read in a bitwise fashion.
It is a TCSPC file where some data is stored using only 4 bits (see below).
Is there a way to read only the first four bits of a U32 in IGOR?


Here is a section Matlab code that I would like to be able to do in IGOR - I can do it all except the Bitshift part:

for i=1:Records

T3Record = fread(fid, 1, 'ubit32'); % all 32 bits:

% +-------------------------------+ +-------------------------------+
% |x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x| |x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|
% +-------------------------------+ +-------------------------------+

nsync = bitand(T3Record,65535); % the lowest 16 bits:

% +-------------------------------+ +-------------------------------+
% | | | | | | | | | | | | | | | | | |x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|
% +-------------------------------+ +-------------------------------+

chan = bitand(bitshift(T3Record,-28),15); % the upper 4 bits:

% +-------------------------------+ +-------------------------------+
% |x|x|x|x| | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
% +-------------------------------+ +-------------------------------+

fprintf(fpout,'\n%7u %08x %6.0f %2u ',i,T3Record,nsync,chan);

dtime=0;

switch chan;

% if chan = 1,2,3 or 4, then these bits contain the dtime:
% +-------------------------------+ +-------------------------------+
% | | | | |x|x|x|x|x|x|x|x|x|x|x|x| | | | | | | | | | | | | | | | | |
% +-------------------------------+ +-------------------------------+

Several routines for reading TCSPC data from a number of devices have been discussed on the Igor mailing list. It might be easier to get more specific help by mentioning the kind of hardware you're using.

To extract only certain bits from a number you'll want to use the bitwise 'AND' operator, & (see https://secure.wikimedia.org/wikipedia/en/wiki/Bitwise_operation#AND). Simply AND your number with a constant in which only those bits you're interested in are set.

For instance, to get the four highest bits, use the following
variable fourHighest = myNum & 0xF0 // 0xF0 is hexadecimal notation for the number 11110000


Usually you'll want to shift the resulting value to the right by four bits, so that it's no longer "offset from zero". Igor doesn't have a built-in operator for bitwise shifting, so you can divide or multiply by factors of two instead. To right-shift by four places, divide the number by 2^4. Example:
variable yourNumber = 231 // 1110 0111 in binary
yourNumber = 231 & 0xF0 // yourNumber is now 1110 0000
yourNumber /= 2^4 // yourNumber is now 0000 1110
In Igor, bitwise AND uses the & operator (and comment is like C++, //)
nsync = T3Record & 65535        // the lowest 16 bits:

As 741 says, there is no shift operator, so just divide by powers of 2:
chan = (T3Record/2^28) & 15 // the upper 4 bits

But really, for efficiency, you should not use literally 2^28, but instead pre-compute 268435456 and use that. Igor's compiler doesn't optimize things like that for you.

John Weeks
WaveMetrics, Inc.
support@wavemetrics.com