opensim-core icon indicating copy to clipboard operation
opensim-core copied to clipboard

C3DFileAdapter cannot handle files with more than 255 labels

Open mrrezaie opened this issue 1 year ago • 4 comments

Hi, C3DFileAdapter raises error when trying to read C3D files with more than 255 3D points or analog channels:

File F:\Python38\Lib\site-packages\opensim\common.py:24185 in read return _common.DataAdapter_read(self, dataSourceSpecification) RuntimeError: std::exception in 'OpenSim::DataAdapter::OutputTables OpenSim::DataAdapter::read(std::string const &) const': Invalid Argument. Number of labels does not match number of columns of dependent data. Thrown at DataTable.h:1231 in DataTable_().

According to the C3D documentation, additional parameters would be stored in POINT:LABELS2 and ANALOG:LABELS2. Perhaps "LABELS2" data must be added to marker_labels and analog_labels as well: https://github.com/opensim-org/opensim-core/blob/d0e1228f2c89c58d38acd396004990f41255964e/OpenSim/Common/C3DFileAdapter.cpp#L114-L116 https://github.com/opensim-org/opensim-core/blob/d0e1228f2c89c58d38acd396004990f41255964e/OpenSim/Common/C3DFileAdapter.cpp#L327-L329

Here is a C3D file for your test: https://github.com/mitkof6/opensim_automated_pipeline/blob/master/tutorial/experimental_data/task.c3d

Thank you in advance.

mrrezaie avatar Nov 10 '23 07:11 mrrezaie

Copying "LABELS2" contents into the main marker labels array is what I do in my Julia language C3D reading library.

Related, but somewhat off-topic, when I opened that example C3D file, a large number of those 3D points were unlabeled markers and Vicon IK results. Depending on how strictly the C3DFileAdapter is defining "markers", it might be a good idea to filter/remove 3D points that are not markers (and potentially unlabelled markers as well). All the point labels in the POINT:ANGLES, POINT:POWERS, POINT:FORCES, and POINT:MOMENTS C3D parameters are not actual markers.

halleysfifthinc avatar Nov 10 '23 17:11 halleysfifthinc

@pariterre Can you chime in on whether the file/format above is supported by EZC3D? Thanks

aymanhab avatar Nov 14 '23 18:11 aymanhab

Hi there!

According to the C3D documentation, additional parameters would be stored in POINT:LABELS2 and ANALOG:LABELS2.

ezc3d already deals with that. You can call ezc3d::c3d::pointNames() (https://github.com/pyomeca/ezc3d/blob/97c4c9254fd58a207f6c95ffe472779e11b7c8a5/src/ezc3d.cpp#L406). It will already return the merged LABELX together. Same thing if you want to write a new c3d file, you can but do not have to already break the labels into sublabels

All the point labels in the POINT:ANGLES, POINT:POWERS, POINT:FORCES, and POINT:MOMENTS C3D parameters are not actual markers.

These are workaround from Vicon and is not part of the c3d standard. I suggest to parse the names of the markers right after loading the point names to remove the non-points markers!

Hope this help

pariterre avatar Nov 14 '23 19:11 pariterre

I mean, I wouldn't call it a workaround, it is a standards compliant extension of C3D capabilities. Regardless, my point was that if it is desired to remove non-marker point data, the the POINT:ANGLES, POINT:POWERS, POINT:FORCES, and POINT:MOMENTS parameters are arrays of strings that give the names of the point data (i.e. items in POINT:LABELS) that are not markers. That would be a simpler approach with fewer assumptions than hard-coding point names that are known™ to be non-markers.

halleysfifthinc avatar Nov 15 '23 17:11 halleysfifthinc