pyomeca / ezc3d

Easy to use C3D reader/writer for C++, Python and Matlab
https://pyomeca.github.io/Documentation/ezc3d/index.html
MIT License
142 stars 44 forks source link

Writing C3D File using MATLAB: header and parameter values not modifiable? #292

Closed jagusto33 closed 1 year ago

jagusto33 commented 1 year ago

Hello,

I am trying to write some .c3d files that requires me to edit header values and parameter values from an existing, functioning .c3d template I have. However, when I run my scripts in MATLAB to edit the header and parameter values I am changing, the ezc3dWrite function seems to be changing all the values I manually edited.

Is there a way in MATLAB to be able to edit header and parameter values AND prevent the ezc3dWrite function from changing them? I can confirm that my manual changes are not working when I open the newly edited .c3d files in Visual 3d and look at my header and parameter data. My concern is that my changes using the MATLAB structure format (s.DATA = value) is somehow making the .c3d in a format that Visual 3D is not able to read or is required to change the base values.

As a point, can you clarify the importance of the IS_LOCKED parameter from 1 vs 0 and if I am making changes to values if I should be setting it to "1" or "0"? Thank you!

pariterre commented 1 year ago

Dear @jagusto33,

Thank you for using Ezc3d!

The header cannot be manually edited because it is fully determined by the parameters. Allowing manual editing of both could lead to a faulty C3D file with conflicting information between the header and the parameters. Therefore, to "edit" the header, you must edit the corresponding parameter that computes the relevant information.

It is indeed possible to add or edit parameters. The MATLAB section of the ReadMe (https://github.com/pyomeca/ezc3d#matlab) provides an MVP example on how to modify a C3D file (such as adding a point in that specific example). Please note that if you want to add a completely new parameter, you should use the ezc3dNewParam function, as it ensures the new parameter is valid by including all the necessary elements.

Visual3d will not open an invalid C3D file, such as one where the number of points in the data does not match the number of points declared in the parameters. If you want to generate a completely new C3D file, you must ensure its validity. Unfortunately, there is no easy way to check the integrity of a C3D file other than testing it.

Regarding the IS_LOCKED parameter, it is a legacy parameter. It exists so that software can prevent users from changing its value, for example, through a GUI. However, it is solely for informational purposes and does not affect the ability to change a value when ignored (which is the case in ezc3d). Therefore, I am keeping the value as it was in the original C3D file. If you believe it should be changed, you are welcome to modify it, but it won't have any impact when reading the file back into Visual3D.

jagusto33 commented 1 year ago

@pariterre

It might be best to provide some context to what it is I am trying to do and get your advice on what might be the "path of least resistance" for moving forward with our files, now that I have ezc3d working.

We have large repository of data (over 1200 .c3d files) that we are trying to import into Visual 3D so that I can have some students work with these files. Our files consist of the following:

  1. Trials that have only Motive-based motion capture data (i.e. tracked and labeled marker data) in a .c3d file format
  2. Trials that have only EMG-based data collected from Noraxon in a .c3d file format for BOTH simultaneous trials with Mocap trials (triggered via a "switch") and without Mocap trials (e.g., maximal voluntary isometric contraction tests done without the markers)
  3. Trials that have only EMG-based data from Noraxon but in a .mat Matlab file format (this is historical data that was exported to this format and the raw Noraxon files have been unfortunately lost)

My goal has been to combine our EMG data with the Mocap files within the Visual 3D environment using some of their built-in functions. This works great when bringing our .c3d EMG files into the same .c3d Mocap trials. However, it has been a major challenge configuring the .mat files to import correctly into the same .c3d Mocap trials. Part of the issue is that the .C3D files for the Mocap data is not "expecting" Analog data, and merging .mat --> .c3d data is having difficulty with assigning the correct parameters for the Analog data...

I have tried to use an existing .c3d file template of the EMG data to try and read / write my own custom .c3d file in MATLAB using the ezc3d functions. However, I have hit a roadblock for the best way to set this up. I see one of two options (below) and wanted to get your thoughts on what you think might be best practice, or offer an alternative option:

  1. I could work to generate "blank" .c3d files with the pre-requisite format to bring in both the mocap .c3d file AND the EMG data (either in the .c3d file format or .mat format). Then in Visual 3D I would use their custom functions to merge those files into the blank .c3d
  2. I could write a "complete" .c3d for each trial manually in MATLAB by adding all my EMG data (via the .mat files) directly into the c3d structure with the POINT data already included from the motion data and save those as new files.

Option 2 seems a little "daunting" to build the .c3d by manually adding in our EMG data...what do you think?

Thank you!

pariterre commented 1 year ago

Hi again!

I think the option 2 seems about right. If I undestood well, you would create a new c3d filled with the mocap/emg/trigger data ? If I were you, that would be my plan. If your data are standardized, it would be very easy to automatize this task and run it for all your files. Then you have c3d files that contains your data and you can move on.

The first option seems doom to be done by hand (unless there is an API that you can call from Matlab).

Part of the issue is that the .C3D files for the Mocap data is not "expecting" Analog data, and merging .mat

This should not be a problem. Please note, that there is no such thing as "updating" a c3d. When you use the "write" method to write a c3d, it has to generate it from scratch. Therefore, internally, ezc3d ensures that this new c3d will have the required structures by the c3d standard (even if the original is not fully compliant with it) including the ANALOG parameter.

My suggestion would be to generate a blank structure (using "ezc3dRead", but passing nothing as argument), then to populate the PARAMETER structure with what you need and fill the data!

jagusto33 commented 1 year ago

@pariterre after a night of revamping existing MATLAB scripts I developed, I was able to automate your suggestion to create our C3D files from scratch and was able to successfully get them into Visual 3D with everything straightened out. Thanks for all your help, a really great tool you have developed!