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

Read events from c3d file #326

Closed IntiVanmechelen closed 2 months ago

IntiVanmechelen commented 2 months ago

Hello,

I'm a new ezc3d user (amazing tool, thank you for developing!) and a fairly new python user. I have a c3d file which has events in it, but I am failing to load the events when I load the file... When I load the c3d file I get the point_data and analog_data, which makes sense because those are defined in the readme file:

print(c['parameters']['POINT']['USED']['value'][0]);  # Print the number of points used
point_data = c['data']['points']
points_residuals = c['data']['meta_points']['residuals']
analog_data = c['data']['analogs']

I assume I have to add something like 'event_data' and describe it subsequently but I am totally failing to find the right configuration to get these added to the loaded variables...

Hoping someone can help me out here.

Thank you so much in advance!

pariterre commented 2 months ago

Dear @IntiVanmechelen C3D is kind of a weird format... The events are stored in the header, so if they are properly stored in the file, you should see them somewhere in c.headers

IntiVanmechelen commented 2 months ago

Aha thank you ofr that info! And how do I add the headers in that case?

I currently only have 'analog_data', 'point_data' and 'points_residuals' (and the c3d object which I cannot open) image Thanks!

pariterre commented 2 months ago

These are values from c.data, the c.header is one of the main category (alongside with c.parameters and c.data)

pariterre commented 2 months ago

Please note that c["header"] and c.header are strictly equivalent (as for c["data"] and c.data)

IntiVanmechelen commented 2 months ago

Hi Pariterre,

Thank you for your lightning quick reply!

I feel very very stupid now but whichever format I try ( c["header"] or c["data"] ) gives me a c3d object which I cannot open. I get the error: TypeError: cannot pickle 'SwigPyObject' object

I currently use following lines of code:

from ezc3d import c3d
c = c3d()
print(c['parameters']['POINT']['USED']['value'][0]);  # Print the number of points used
#print(c["data"])

# Import test c3d file
c = c3d('C:\DATA\DYS13 Gait 13.c3d')

point_data = c['data']['points']
points_residuals = c['data']['meta_points']['residuals']
analog_data = c['data']['analogs']

If I only do print(c["data"])

I get the c3d object I cannot open, and it seems like this might hold the headers?

image

Apologies in advance if I am missing something terribly obvious

pariterre commented 2 months ago

Hum.. weird.. this does not print the header section?

from ezc3d import c3d
c = c3d('C:\DATA\DYS13 Gait 13.c3d')
print(c.header)
IntiVanmechelen commented 2 months ago

No, only the c3d object unfortunately

(literally just kopied your lines above)

I will double-check this with another c3d file from an online repository. If that does work, we know the problem is in the structure of my own c3d file

pariterre commented 2 months ago

The following script does print the events from the header up here, please copy-paste the error you get!

from ezc3d import c3d
c = c3d("path_to_c3d/c3d_filename.c3d")
print(c.header["events"])
IntiVanmechelen commented 2 months ago

I do indeed get the events with the line above, but they are currently printed as zeros, while they should not be

{'size': 18, 'events_time': (0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), 'events_label': ('', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '')}

The error is mainly when I try to open the c3d object in the variable explorer. Then I get

TypeError: cannot pickle 'SwigPyObject' object

Which seems to be related to the fact that Spyder is not opened in the correct environment. Trying to figure out how I change that

pariterre commented 2 months ago

The error is mainly when I try to open the c3d object in the variable explorer

Unfortunately, you won't be able to open the object in a dynamic explorer. You have to pause your script after having loaded the C3D and navigate the file using the command line

I do indeed get the events with the line above, but they are currently printed as zeros, while they should not be

This means the event were not stored in the file as actual event. This depends on which system you used to create the C3D file (e.g. Nexus, Qualisys, etc.). They may be in the parameters then, I will unfortunately won't be able to help from that point on without accessing an actual c3d :S

IntiVanmechelen commented 2 months ago

I'm unable to attach one here, but this one downloaded from an open source repository: https://we.tl/t-tiZpOcZLK6

Event timings should be under EVENTS>TIMES in this case

Thank you for your help!

pariterre commented 2 months ago

The event are indeed stored in the parameters section in your c3d (which is a non-standard, but not an unexpected thing). To access them you can do:

from ezc3d import c3d
c = c3d("BWA_04.c3d")
c.parameters.EVENT.LABELS
c.parameters.EVENT.TIMES
c.parameters.EVENT.SUBJECTS
# There are more, you can print them using print(c.parameters["EVENT"].keys())
IntiVanmechelen commented 2 months ago

Amazing, thank you so much for your help!!