pyomeca / ezc3d

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

[Feature Request] recompute forceplate data #346

Closed mrrezaie closed 1 month ago

mrrezaie commented 1 month ago

Hi, the idea is to let users modify the forceplate parameters before extracting the forceplate data (force, COP, and Tz).

In my workflow, I need to process the forceplate analogs before computing COP. So, I read the c3d file, got the analogs, processed them, overwrote the analogs, and wrote to a new c3d file. Then I read the new c3d file and extracted the forceplate data.

It would be great if there is a method such as recompute_forceplate_data(), so the last writing, re-reading, and re-extracting steps would be omitted, and makes it more convenient.

(hope I explained it properly) I'm looking forward to this new feature, and thank you in advance.

pariterre commented 1 month ago

Hi there!

It would be great if there is a method such as recompute_forceplate_data(), so the last writing, re-reading, and re-extracting steps would be omitted, and makes it more convenient.

This would be a major change in the ezc3d core as the writting and reading process do important checks and updates to the internal structure of the data. If the method recompute_forceplate_data was implemented, it would only be a frontend to writing a new temporary c3d and reading it back and deleting it, which would be a pretty useless method to provide (as it is litterally 3 lines of code)

mrrezaie commented 1 month ago

Thanks @pariterre for your response. Updating the force, moment, COP, and Tz values in the c3d object after invoking recompute_forceplate_data actually sounds pretty useful. This is what I'm suggesting:

import ezc3d
c3d = ezc3d.c3d(file1, extract_forceplat_data=True)

analogs = c3d['data']['analogs']
... # process the analogs
c3d['data']['analogs'] = analogs

corners = c3d['parameters']['FORCE_PLATFORM']['CORNERS']['value']
... # or adjusting forceplate parameters
c3d['parameters']['FORCE_PLATFORM']['CORNERS']['value'] = corners

c3d.recompute_forceplate_data()
c3d['data']['platform'][0]['center_of_pressure']

Does it make sense?

If this is a tedious development, please ignore this. Thank you.

pariterre commented 1 month ago

c3d.recompute_forceplate_data() would not be tedious as it would be:

def recompute_forceplate_data(self):
    self.write("tp.c3d")
    self.read("tp.c3d")
    os.delete("tp.c3d")

This would not be sophisticated at all as there is no other way to access something meaningful from the Python interface. But this would be pretty slow as a method to provide to the user. That said, you have the snippet to do it now (simply replace the self by c3d) ;)

mrrezaie commented 1 month ago

Thanks, Yes, I had done similar thing.