function [channelData,channelNames] = TDMS_readChannelOrGroup(TDMS_filename,group,channel,subset)
%TDMS_readChannelOrGroup Return data from a specific channel or group of channels
%
% Original Author: Preston K. Manwaring
% Last modified : 4/29/2011 JAH
%
% FORMAT 0: First call to examine file contents
% =======================================================================
% [tempStruct] = TDMS_readChannelOrGroup(TDMS_filename,1)
%
%
% NOTE: For FORMAT 1 & FORMAT 2, TDMS_filename can be replaced with
% the output from the FORMAT 0 call, tempStruct, to save on processing
% time
%
% FORMAT 1: To retrieve all channels in a group
% =======================================================================
% [channelData,channelNames] =
% TDMS_readChannelOrGroup(TDMS_filename,groupName,[],*subset)
%
% ALTERNATIVELY ...
%
% [...] = TDMS_readChannelOrGroup(tempStruct,groupName,[],*subset)
%
%
% FORMAT 2: To retrieve a specific channel from a group
% =======================================================================
% channelData = TDMS_readChannelOrGroup(TDMS_filename,groupName,channelName,*subset)
%
%
% Description: This file will read a channel out of a TDMS file and write
% the data to a local variable. It is a wrapper for TDMS_readTDMSfile.
%
% INPUTS:
% =======================================================================
% tempStruct : output from previous call to this function, see
% definition in OUTPUTS
% TDMS_filename : The name of the TDMS filename as a string
% (e.g.'C:\foo.tdms')
% groupName : The group name in which the channel data reside
% (e.g. 'data Group')
%
% OPTIONAL INPUTS
% =======================================================================
% channelName : (default []), if empty, retrieves all channels in a
% group, otherwise specify the channel name to retrieve
% (e.g. 'channel A')
% subset : A subset of the raw data to retrieve, format is:
% [starting sample , # of samples to retrieve]
% e.g. [100 50] would start retrieving data at the 100th
% index and would retrieve 50 samples, 100 through 149
%
% OUTPUTS:
% =======================================================================
% tempStruct : (structure array with fields)
% .tdmsStruct - main output of TDMS_readTDMSfile with no raw data
% retrieved
% .metaStruct - second output of TDMS_readTDMSfile
% .TDMS_filename - the filename that was passed in, this is used if
% this structure gets passed in as an input
% channelData : If requesting a single channel, channelData is the
% data from that channel. If requesting a group,
% channelData is a cell array, where each index holds the
% data for a specific channel
% channelNames : (cell array of strings) Name of each channel, used to
% match channelData to a channel name
%
% EXAMPLES
% ================================================================
% 1) Read 'myChannel' from 'myGroup', return all raw data
% channelData = TDMS_readChannelOrGroup('C:\myFile.tdms','myGroup','myChannel')
%
% 2) Retrieve all channels from myGroup, returning only the first 100 values
% channelData = TDMS_readChannelOrGroup('C:\myFile.tdms','myGroup',[],[1 100])
%
% See also:
% TDMS_readTDMSFile
if exist('subset','var')
SUBSET_GET = subset;
else
SUBSET_GET = [];
end
if ~exist('channel','var')
channel = [];
end
%This is a bit messy but it works ...
if isstruct(TDMS_filename)
%Unpack from previous call
tempStruct = TDMS_filename;
tdmsStruct = tempStruct.tdmsStruct;
metaStruct = tempStruct.metaStruct;
TDMS_filename = tempStruct.TDMS_filename;
else
% get the TDMS file name properties before trying to load a big file
[tdmsStruct,metaStruct] = TDMS_readTDMSFile(TDMS_filename,'GET_DATA_OPTION','getNone');
if isnumeric(group)
channelData = struct('tdmsStruct',tdmsStruct,'metaStruct',metaStruct,'TDMS_filename',TDMS_filename);
return
end
end
% check to see if the group name given is valid. If not, give alternatives.
I = find(strcmpi(group,tdmsStruct.groupNames),1);
if isempty(I)
fprintf(2,'Available group names are:\n');
disp(char(tdmsStruct.groupNames));
error('Specified group name: %s, not found in TDMS file.',group);
end
% check to see if the channel name is valid. If not, give alternatives.
if ~isempty(channel)
J = find(strcmpi(channel,tdmsStruct.chanNames{I}),1);
if isempty(J)
fprintf(2,'Available chan names are:\n');
disp(char(tdmsStruct.chanNames{I}));
disp('')
error('Specified channel name: %s, not found in TDMS file.',channel);
end
end
% Populate request structure
if ~isempty(channel)
indexOriginalPath = tdmsStruct.chanIndices{I}(J);
getStruct = struct(...
'fullPathsKeep',tdmsStruct.objectPathsOrig{indexOriginalPath});
else
getStruct = struct('groupsKeep',group);
end
%Retrieve data
tdmsStruct = TDMS_readTDMSFile(TDMS_filename,...
'META_STRUCT',metaStruct, ...
'GET_DATA_OPTION','getSubset',...
'OBJECTS_GET',getStruct, ...
'SUBSET_GET',SUBSET_GET);
%OUTPUT SETUP
%==============================
if ~isempty(channel)
channelData = tdmsStruct.data{indexOriginalPath};
channelNames = {channel};
else
nChans = length(tdmsStruct.chanNames{I});
channelData = cell(1,nChans);
chanIndices = tdmsStruct.chanIndices{I};
for iChan = 1:nChans
channelData(iChan) = tdmsStruct.data(chanIndices(iChan));
end
channelNames = tdmsStruct.chanNames{I};
end
end