0% found this document useful (0 votes)
466 views7 pages

Convert TDMS

This MATLAB function converts Labview TDMS data files into MATLAB .mat files. It takes the TDMS file as input, reads the file tags and metadata to extract the data objects and properties. It then saves these to a new .mat file with the same name in the same directory.

Uploaded by

Bhanupriya Jain
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
466 views7 pages

Convert TDMS

This MATLAB function converts Labview TDMS data files into MATLAB .mat files. It takes the TDMS file as input, reads the file tags and metadata to extract the data objects and properties. It then saves these to a new .mat file with the same name in the same directory.

Uploaded by

Bhanupriya Jain
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 7

function [ob index]=convertTDMS(filename); %convertTDMS - function to convert Labview TDMS data files into .mat files.

% If called with no input, user selects from file open dialog box. A % .mat file with the same filename as the TDMS file is automatically % written to the same directory (warning - will over write .mat file of % the same name. % % TDMS format is based on information provided by National Instruments % at: http://zone.ni.com/devzone/cda/tut/p/id/5696 % % convertTDMS(filename) % % Inputs: % filename - filename to be converted. If not supplied, user % is provided dialog box to open file. Can be a cell array % of files for bulk conversion. % % Outputs: % ob - structure with all of the data objects % index - index of the information in ob % %--------------------------------------------%Brad Humphreys - v1.0 2008-04-23 %ZIN Technologies %--------------------------------------------conver='1.0'; %conversion version number

startingdir=cd; %Get the starting directory if nargin==0 %If file is not provided,prompt user [filename,pathname,filterindex] = uigetfile({'*.*', 'All Files (*.*)'},'Cho ose File'); filename=fullfile(pathname,filename); end %Create filelist if iscell(filename) %If it is a group of files numfiles=max(size(filename)); infilename=filename; else numfiles=1; %If only one file name is provided infilename{1}=filename; end

for fnum=1:numfiles disp([datestr(now,13) ' Begining conversion of: ' infilename{fnum}]) bytesInfile = dir(infilename{fnum}); estimation of variable size. filesize = bytesInfile.bytes; %Get size of file. Needed for later

%Initialize variables for each file conversion index.names=[]; ob=[];

firstRawData=1; segCnt=0; fid=fopen(infilename{fnum}); while ~feof(fid) %Look for TDM tag Ttag=fread(fid,1,'uint8'); Dtag=fread(fid,1,'uint8'); Stag=fread(fid,1,'uint8'); mtag=fread(fid,1,'uint8'); if Ttag==84 & Dtag==68 & Stag==83 & mtag==109 segCnt=segCnt+1; else if ~(isempty(Ttag) & isempty(Dtag) & isempty(Stag) & isempty(mtag)) %On last read, all will be empty error('Unexpected bit stream in file: %s at segment %d (dec: %d %d %d %d)',infilename{fnum}, segCnt+1, Ttag, Dtag, Stag, mtag); end end %ToC Field Toc=fread(fid,1,'uint32'); kTocMetaData=bitget(Toc,2); kTocNewObject=bitget(Toc,3); kTocRawData=bitget(Toc,4); %Segment vernum=fread(fid,1,'uint32'); segLength=fread(fid,1,'uint64'); metaRawLength=fread(fid,1,'uint64'); %% Process Meta Data if kTocMetaData ta in this segment numNewObjInSeg=fread(fid,1,'uint32'); for q=1:numNewObjInSeg obLength=fread(fid,1,'uint32'); he objects name obname=[fread(fid,obLength,'uint8=>char')]';%Get the objects nam e %Fix Object Name if strcmp(obname,'/') obname='Root'; else obname=fixcharformatlab(obname); end if ~isfield(ob,obname) %If the object do es not already exist, create it index.names{end+1}=obname; ob.(obname)=[]; obnum=max(size(index.names)); %Get the object number else %if it does exis t, get it's index and object number obnum=find(strcmp(index.names,obname)==1,1,'last'); %If there is meat da

%Get the length of t

end rawdataindex=fread(fid,1,'uint32'); a Index if rawdataindex==0 %No raw data ass igned to this object in this segment index.entry(obnum)=0; index.dataType(obnum)=1; index.arrayDim(obnum)=0; index.nValues(obnum)=0; index.byteSize(obnum)=0; elseif rawdataindex+1==2^32 %Objects raw dat a index matches previous index - no changes else %Get new object information index.entry(obnum)=rawdataindex; index.dataType(obnum)=fread(fid,1,'uint32'); index.arrayDim(obnum)=fread(fid,1,'uint32'); index.nValues(obnum)=fread(fid,1,'uint64'); if index.dataType(obnum)==32 %If the datatype is a string index.byteSize(obnum)=fread(fid,1,'uint64'); else index.byteSize(obnum)=0; end end numProps=fread(fid,1,'uint32'); for p=1:numProps propNameLength=fread(fid,1,'uint32'); propsName=[fread(fid,propNameLength,'uint8=>char')]'; propsDataType=fread(fid,1,'uint32'); propExists=isfield(ob.(obname),propsName); dataExists=isfield(ob.(obname),'data'); if dataExists %Get number of data samples for the object in this segment %nsamps=max(size(ob.(obname).data)); nsamps=ob.(cname).nsamples+1; else nsamps=0; estNumSeg=floor(filesize/(20+segLength)*1.2); %Estimate # of Segements. 20 is the number of bytes prior to the segLength Rea d end if propsDataType==32 %If the data type is a string propsValueLength=fread(fid,1,'uint32'); propsValue=fread(fid,propsValueLength,'uint8=>char'); if propExists cnt=ob.(obname).(propsName).cnt+1; ob.(obname).(propsName).cnt=cnt; ob.(obname).(propsName).value{cnt}=propsValue; ob.(obname).(propsName).samples(cnt)=nsamps; else %Get the raw dat

ob.(obname).(propsName).cnt=1; ob.(obname).(propsName).value{estNumSeg}=NaN; ob.(obname).(propsName).samples(estNumSeg)=0; ob.(obname).(propsName).value{1}=propsValue; ob.(obname).(propsName).samples(1)=nsamps; end else %Numeric Data type if propsDataType==68 %If the data type is a timestamp tsec=fread(fid,1,'uint64')/2^64+fread(fid,1,'uint64' ); %time since Jan-1-1904 in seconds propsValue=tsec/86400+695422-5/24; %/864000 convert to days; +695422 days from Jan-0-0000 to Jan-1-1904 else matType=LV2MatlabDataType(propsDataType); propsValue=fread(fid,1,matType); end if propExists cnt=ob.(obname).(propsName).cnt+1; ob.(obname).(propsName).cnt=cnt; ob.(obname).(propsName).value(cnt)=propsValue; ob.(obname).(propsName).samples(cnt)=nsamps; else ob.(obname).(propsName).cnt=1; ob.(obname).(propsName).value(estNumSeg)=NaN; ob.(obname).(propsName).samples(estNumSeg)=0; ob.(obname).(propsName).value(1)=propsValue; ob.(obname).(propsName).samples(1)=nsamps; end end end end end %% Process Raw Data if kTocRawData %Process Raw Data if firstRawData %If first raw data, preallocate data arrays firstRawData=0; estNumSeg=filesize/(20+segLength); %Estimate # of Segements. 20 is the number of bytes prior to the segLength Read for b=1:max(size(index.names)) cname=cell2mat(index.names(b)); nEstSamples=floor(1.2*estNumSeg*index.nValues(b)); if index.dataType(b)~=32 %If the data is numeric type ob.(cname).data(1:(nEstSamples),1)=NaN; else %If the data is string type ob.(cname).data{nEstSamples}=NaN; end ob.(cname).nsamples=0; end end

for r=1:max(size(index.names)) %Loop through the index nvals=index.nValues(r); if nvals>0 [data cnt]=fread(fid,nvals,LV2MatlabDataType(index.dataType( r))); cname=cell2mat(index.names(r)); ssamples=ob.(cname).nsamples; if index.dataType(r)~=32 %If the data is numeric type ob.(cname).data(ssamples+1:ssamples+cnt,1)=data; else %If the data is string type ob.(cname).data{ssamples+1:ssamples+cnt,1}=data; end ob.(cname).nsamples=ssamples+cnt; end end end end %% Clean up preallocated arrays (preallocation required for speed) for y=1:max(size(index.names)) cname=cell2mat(index.names(y)); nsamples=ob.(cname).nsamples; if nsamples>0 %Remove any excess from preallocation of data if index.dataType(y)~=32 ob.(cname).data=ob.(cname).data(1:nsamples,1); %If the data is numeric type else ob.(cname).data=ob.(cname).data{1:nsamples,1}; %If the data is string type end proplist=fieldnames(ob.(cname)); %Remove any excess from prealloc ation of properties for isaac=1:size(proplist,1) if isfield(ob.(cname).(proplist{isaac}),'cnt') cnt=ob.(cname).(proplist{isaac}).cnt; ob.(cname).(proplist{isaac}).value=ob.(cname).(proplist{isaa c}).value(1:cnt); ob.(cname).(proplist{isaac}).samples=ob.(cname).(proplist{is aac}).samples(1:cnt); ob.(cname).(proplist{isaac})=rmfield(ob.(cname).(proplist{is aac}),'cnt'); end end end end

%% Create Output filenames [pathstr,namestr]=fileparts(infilename{fnum}); namestr=fixcharformatlab(namestr); %savefilename=fullfile(pathstr,namestr); if ~isempty(pathstr)

cd(pathstr) end fclose(fid); %Save Output Data ob.index=index; ob.conver=conver; save(namestr,'-struct','ob') disp([datestr(now,13) ' Completed conversion of: ' infilename{fnum}]) end cd(startingdir); end function fixedtext=fixcharformatlab(textin) %Private Function to remove all text that is not MATLAB variable name %compatible textin=strrep(textin,'''',''); textin=strrep(textin,'/Untitled/',''); textin=strrep(textin,'/','.'); textin=strrep(textin,'-',''); textin=strrep(textin,'?',''); textin=strrep(textin,' ',''); textin=strrep(textin,'.',''); textin=strrep(textin,'[','_'); textin=strrep(textin,']',''); textin=strrep(textin,'%',''); textin=strrep(textin,'#',''); textin=strrep(textin,'(',''); textin=strrep(textin,')',''); fixedtext=textin; end function matType=LV2MatlabDataType(LVType) %Cross Refernce Labview TDMS Data type to MATLAB switch LVType case 1 %tdsTypeVoid matType=''; case 2 %tdsTypeI8 matType='int8'; case 3 %tdsTypeI16 matType='int32'; case 4 %tdsTypeI32 matType='int32'; case 5 %tdsTypeI64 matType='int64'; case 6 %tdsTypeU8 matType='uint8'; case 7 %tdsTypeU16 matType='uint16'; case 8 %tdsTypeU32 matType='uint32'; case 9 %tdsTypeU64 matType='uint64'; case 10 %tdsTypeSingleFloat

matType='float64'; case 11 %tdsTypeDoubleFloat matType='float64'; case 12 %tdsTypeExtendedFloat matType=''; case 32 %tdsTypeString matType='char'; case 33 %tdsTypeBoolean matType='bit1'; case 68 %tdsTypeTimeStamp matType='bit224'; otherwise matType=''; end end

You might also like