PDA

View Full Version : Summary: Copying data between c3dfiles with C3Dserver in Matlab



jvanrenterghem29
07-06-2010, 01:27 AM
Dear Biomechanists,
Thanks for all those who responded. Solutions were created in Visual3D, in Matlab. Thanks in particular to Scott Selbie (C-Motion) and Sameer and Edmund (Motion Labs Systems). Communications were lengthy, so I will only repeat original question and outline solutions for Visual3D and Matlab below.
Regards,
Jos

Original question

Dear Biomechanists,

We have collected kinematic data, and after tracking the markers we added events in Visual3D software. We however wish to re-track the marker data, without loosing the events. My proposed strategy is to copy the events into the untracked C3D file using the c3dserver in Matlab.

I have tried to copy the parameter in which the events are stored (including values) from the tracked c3d file into the untracked c3d file using the C3Dserver in Matlab, but fail to do so. Apparently, it seems to have something to do with setting the dimensions of the parameter in the function AddParameter, but I fail to get it right using the available documentation.

I would very much appreciate it if you think you know how to fix this and could spare a moment to help fix this problem.

Kind regards and many thanks in advance,
Jos

Solution 1
Visual 3D pipeline: benefit is that the history of the events is retained.

Code for the v3s file:
Set_Pipeline_Parameter_To_List_Of_Tagged_Files
/PARAMETER_NAME=NewFiles
/TAG_NAME=EVENTS_new
! /GET_CURRENT_SELECTED_FILES=false
/USE_SHORT_FILENAMES=true
;

For_Each
/ITERATION_PARAMETER_NAME=NewFile
/ITEMS=::NewFiles
;

Set_Pipeline_Parameter
/PARAMETER_NAME=OldFile
/PARAMETER_VALUE=::NewFile
! /PARAMETER_VALUE_SEARCH_FOR=
! /PARAMETER_VALUE_REPLACE_WITH=
/PARAMETER_VALUE_PREFIX=x_
! /PARAMETER_VALUE_APPEND=
;

Select_Active_File
/FILE_NAME= C:\Users\pfiers\Desktop\KopiŽren_Events\PROBEERSEL export to C3D vanuit VISUAL 3D\&::OldFile
;

Set_Pipeline_Parameter_To_List_Of_Signal_Names
/PARAMETER_NAME=Events
/SIGNAL_TYPE=EVENT_LABEL
/SIGNAL_FOLDER=ORIGINAL
;

For_Each
/ITERATION_PARAMETER_NAME=Event
/ITEMS=::Events
;

Set_Pipeline_Parameter_To_Data_Value
/PARAMETER_NAME=Times
/SIGNAL_TYPES=EVENT_LABEL
/SIGNAL_NAMES=::Event
! /SIGNAL_FOLDER=ORIGINAL
! /SIGNAL_COMPONENTS=ALL_COMPONENTS
;

Select_Active_File
/FILE_NAME=C:\Users\pfiers\Desktop\Kopie QTM-Files\JD\C3D\&::NewFile
;

For_Each
/ITERATION_PARAMETER_NAME=Time
/ITEMS=::Times
;

Event_Explicit
/EVENT_NAME=::Event
! /FRAME=
/TIME=::Time
;

End_For_Each
/ITERATION_PARAMETER_NAME=Time
;

Select_Active_File
/FILE_NAME=C:\Users\pfiers\Desktop\KopiŽren_Events\ PROBEERSEL export to C3D vanuit VISUAL 3D\&::OldFile
;

End_For_Each
/ITERATION_PARAMETER_NAME=Event
;

End_For_Each
/ITERATION_PARAMETER_NAME=NewFile
;

Solution 2
Matlab: using the free c3d server (www.c3d.org).

Code m-file (sorry but indentation fell away in email):
% jvsC3DInsertEvents
%
% code to insert events from one file into other file
% INPUT
% X_filename.c3d = file with events
% filename.c3d = file in which events are to be copied
% OUTPUT
% N_filename.c3d = file with events from X_filename.c3d
% with rest of parameters and data from filename.c3d
% SUB-ROUTINES
% (1) check for events in filename.c3d
% (2) if no events, copy events from X_filename.c3d to filename.c3d
%+++++++++++++++++++++++++++++++++++++++++++++++++ ++
%
% Acknowledgements:
% Sameer K. and Edmund Cramp (Motion Lab Systems)
% Tim Dorn (University of Melbourne)
%
%+++++++++++++++++++++++++++++++++++++++++++++++++ ++

% (1) Define directory
myDir = uigetdir;
cd(myDir); % change directory
myFileNames = dir('X_*.c3d');
itf = c3dserver(); %start c3d server to access c3d files
SuccessCount = 0;

% (2) Loop through all files to copy events from X_filename.c3d
% into filename.c3d in same directory
for k=1:length(myFileNames)

% (2.1) open X_file.C3D
myX_File = myFileNames(k).name;
myFile = myX_File(3:end);
openc3d(itf,0,myX_File);

% (2.2) load event data from X_file.c3d
myX_IndexLabels = itf.GetParameterIndex('EVENT','LABELS');
myX_LabelsNumDim = itf.GetParameterNumberDim(myX_IndexLabels);
for i = 0:myX_LabelsNumDim-1
myX_LabelsDimension(i+1) = itf.GetParameterDimension(myX_IndexLabels,i) +1;
end
myX_LengthLabels = itf.GetParameterLength(myX_IndexLabels);
myX_IndexTimes = itf.GetParameterIndex('EVENT','TIMES');
for ii = 0:myX_LengthLabels-1
myX_Labels{ii+1} = itf.GetParameterValue(myX_IndexLabels,ii);
myX_Times(ii+1) = itf.GetParameterValue(myX_IndexTimes,ii);
end
closec3d(itf);

% (2.3) open file.c3d
openc3d(itf,0,myFile);

% (2.4) check if events exist in filename.c3d
my_IndexLabels = itf.GetParameterIndex('EVENT','LABELS');
if my_IndexLabels ~= -1
% add action if needed when events exist in filename.c3d
else
% Add new group EVENT with parameters LABELS and TIMES
itf.AddGroup(0,'EVENT','Events','0');
itf.AddParameter('USED','Number of events used','EVENT',char(0),2,0,int16([1,0]), {});
itf.AddParameter('LABELS','Labels','EVENT',char(0) ,-1,2,int16([32,0]), {});
itf.AddParameter('TIMES','Times','EVENT',char(0), 4, 2, int16([2,0]), {});
% Add Existing events to new group EVENT
for ii = 0:myX_LengthLabels-1
% Change number used events
index1 = itf.GetParameterIndex('EVENT', 'USED');
oldnumEvents = itf.GetParameterValue(index1, 0);
itf.SetParameterValue(index1, 0, oldnumEvents+1);
% Add label to LABELS
index2 = itf.GetParameterIndex('EVENT', 'LABELS');
itf.AddParameterData(index2, 1);
itf.SetParameterValue(index2, oldnumEvents, myX_Labels{ii+1});
% Add time to Times
index3 = itf.GetParameterIndex('EVENT', 'TIMES');
itf.AddParameterData(index3, 1);
myTimesLength = itf.GetParameterLength(index3);
itf.SetParameterValue(index3, myTimesLength-1, myX_Times(ii+1));
end
if nSuccess ~= -1 %replacement parameters was successful
fprintf('\n file %s has events added. \n\n', myFile)
SuccessCount = SuccessCount + 1;
end
end

% (2.5) save file.C3D as new file N_file.c3d
myN_File = ['N_' myFile];
itf.SaveFile(myN_File,-1);
closec3d(itf);
end

fprintf('\n %g files out of %g were replaced successfully \n', SuccessCount, length(myFileNames))