Wednesday, February 24, 2010

textread and ignoring columns

okay, say you have a .csv file (comma separated variable, excel likes those) and for come reason you don't want to use csvread. i found textread to be more flexible.

roka collected some data that has 22 headerlines, and then 4 columns of data. i only care about the first column of data. so this is what i used to read in the file:

[kilograms] = textread(namestr,'%f %*f %*f %*f', 'delimiter', ',', 'headerlines',22);

namestr is set to the name of the file, e.g. '090512.csv'
%f indicates that the data are floating point numbers
the *s indicate that i am skipping the last three columns of floating point data
there are several options for the delimiter, in my case it is commas ','
there are 22 headerlines before the data starts. 

more data i/o, woo.

anyway, i just went to make the links to textread and matlab says that it recommends textscan over textread. oh well. 

Wednesday, February 17, 2010

break your plot. breakplot

there are several options on file exchange for putting a break in your plot axis if you have a region of uninteresting data.

for example if you have 12 subplots and 11 of them have the same y-bounds, but one of them has a very high value, you can put a break in that plot and standardize the rest of the axes bounds. got it?

breakplot

breakxaxis (you can modify it so it's the y-axis)

i haven't actually used these yet, so that's all i have to say about that. but i hope to in the near future.

Friday, February 12, 2010

fread: read binary data

probably the moment that i felt like the biggest matlab stud (although there are so many i cannot even count, haha JOKE), is when i finally decoded the binary data from the laser scanner my flume. the folks at SAFL had written the program to store the voluminous data in binary format, and ever since dec. 2006 i knew that one day i would have to figure out how to read it.

fread reads data from a binary file.

numsamples = fread(fid, 1, 'long','ieee-le');

first, you probably need to use fseek to move around in the file (to skip header info, etc.):

status = fseek(fid, 3000, 'bof');

i love the words bof, cof, and eof (beginning, current position, and end of file)

anyway, then you can read all the data and write it out to a matlab matrix

for i = 1:numsamples
    mirrorrev(i) = fread(fid, 1, 'double','ieee-le');
    drumrev(i) = fread(fid, 1, 'double','ieee-le');
    distance(i) = fread(fid, 1, 'single','ieee-le');
    laserstatus(i) = fread(fid, 1, 'uint16','ieee-le');
    ambient(i) = fread(fid, 1, 'int8','ieee-le');
    amplitude(i) = fread(fid, 1, 'int8','ieee-le');
end

data I/O is very important!

Tuesday, February 9, 2010

suplabel

this is one that i downloaded from matlab central file exchange: suplabel, places one x or y axis label on a bunch of subplots. Because sometimes redundancy is bad.

http://www.mathworks.com/matlabcentral/fileexchange/7772-suplabel

I changed the default supAxes to [.12 .12 .85 .85 ] so they wouldn't be chopped off. Download it to your path and off you go.

Places text as a title, xlabel, or ylabel on a group of subplots. Returns a handle to the label and a handle to the axis.

[ax,h]=suplabel(text,whichLabel,supAxes)

returns handles to both the axis and the label.

ax=suplabel(text,whichLabel,supAxes)

returns a handle to the axis only. suplabel(text) with one input argument assumes whichLabel='x'

whichLabel is any of 'x', 'y', or 't', specifying whether the text is to be the xlable, ylabel, or title respectively.

supAxes is an optional argument specifying the Position of the "super" axes surrounding the subplots. supAxes defaults to [.075 .075 .85 .85] specify supAxes if labels get chopped or overlay subplots

EXAMPLE:
subplot(2,2,1);ylabel('ylabel1');title('title1')
subplot(2,2,2);ylabel('ylabel2');title('title2')
subplot(2,2,3);ylabel('ylabel3');xlabel('xlabel3')
subplot(2,2,4);ylabel('ylabel4');xlabel('xlabel4')
[ax,h1]=suplabel('super X label', 'x');
[ax,h2]=suplabel('super Y label','y');
[ax,h3]=suplabel('super Title' ,'t');
set(h3,'FontSize',30)



the image doesn't match the example code. so kill me.

Monday, February 8, 2010

codecs and videos

you can make videos with matlab, usually i use avifile and addframe (usually in a loop) to make animations of my plots.

matlab will automatically use some kind of compression and this is where you might run into a problem where you aren't able to actually play the .avi on your computer. you might not have the correct codec (encoder/decoder).

These are the options given for the 'compression' parameter of avifile:
'Indeo3'
'Indeo5'
'Cinepak'
'MSVC'
'RLE'
'None'

Most of those are pretty old.

Also, if you want to enrage an open-source person you can start talking about proprietary codecs. I know very little about this stuff, but here's a list of open source codecs.

http://en.wikipedia.org/wiki/List_of_open_source_codecs

What I know is:

1. MATLAB defaults to Indeo5 on Windows, but this isn't part of the base Windows install now, so I had problems playing my own MATLAB generated .avi movies

2. 'Cinepak' seemed to work, but it loses some sharpness, especially in text

3. 'None' is fine but the files are much larger (duh)

4. Picasa will upload the default Indeo videos and play them, but degrade the quality, and mess up the timing

5. Another option is to write out .avis using 'None' compression, then using a third party software to compress.

6. Also some people have written stuff on the matlab file exchange such as mpgwrite, i haven't tried it yet though.

Man, MATLAB is so cool.

Saturday, February 6, 2010

making nice graphs

here's a much more comprehensive link on making nice graphs

http://blogs.mathworks.com/loren/2007/12/11/making-pretty-graphs/

covered (in well-written code):
  • line properties (both functional and aesthetic)
  • legends and labels
  • font and axes properties

Wednesday, February 3, 2010

serial port I/O and pause

i employed the help of yesdogs' friend to write this .m file to collect data from an instrument connected to my laptop's serial port:
http://seismo.berkeley.edu/~lhsu/help/get9830.m

instead of prostituting oneself for matlab code (figuratively, not literally), one could start here:

Serial Port I/O introduction
http://www.mathworks.com/access/helpdesk/help/techdoc/matlab_external/f105659.html

okay i'll paste the .m below. there's a lot to talk about. i don't understand it all. i think i had a version 2 of this that collected data for a set time, but i can't find it.

i think my favorite part is pause(0.25)
pause halts execution temporarily. as written above, it halts things for 0.25 sec. so data is collected at 4 Hz.

note: i have not yet used this data, but i wrote an abstract for a conference in 2011 that requires it.


% get9830.m 
%
% An example of how to get data from an instrument connected to a serial port.
% This was written specifically for an Interface 9830 Digital Indicator
% (connected to a load cell). Therefore some variables - espectially in the
% s = serial(....) line - may need to be adjusted for different systems.
% 
% pause(0.25) sets the frequency of data logging, units of seconds so 0.25
% is 4 Hz.
%
% finalized on 16 june 2008
% written by terry
%
% open serial port on COM1
s=serial('COM1','BaudRate',9600,'DataBits',8,'Parity','none','StopBits',1,'Terminator','CR');

fopen(s);

s.Status

disp('get9830.m');
disp('ctrl-C to end');
input('press enter to begin');
i = 1;

while(i)
    % send transmit on
    %fprintf(s,'data');
    fwrite(s,17,'uint8');  %send an XON
    fwrite(s,13,'uint8');  %send a  CR


    % get first 8 bytes
    %data = fread(s, s.BytesAvailable, 'uint8');
    if(s.BytesAvailable >= 8)
        data = fread(s, 8, 'uint8');
    
        %convert data into decimal
        reading = bitshift(data(3),24) + bitshift(data(4),16) + bitshift(data(5),8) + data(6);  %combine data bytes
        

        %handle negatives
        if(data(3)>127)
            reading = bitcmp(reading,32); % complement the bits
            reading = -1*(reading+1);
        end;

        %place decimal point
        reading = reading*10^-(5-data(7));
        
        %save in array
        output(i) = reading;
        pause(0.25); % I think the indicator makes 4 measurements per second
        i=i+1;
        
        % press ctrl-c to end
        
    end;
end;

fclose(s);
delete(s);
clear s;