pyfar/pyfar

Crash when reading 'SimpleFreeFieldHRTF' v2.0 SOFA file

SDX-LV opened this issue · 6 comments

Hi Fabian,

Did some coding today and ran into an issue with the latest sofar 1.0.0 and pyfar.

If you use sofa_signals, sofa_sources, sofa_receivers = pf.io.read_sofa(sofa_path, verify=False)
on a HRTF file saved by recent Mesh2HRTF Python post processing with sofar 0.3.1 you get a crash:

...
  File "C:\Users\...\AppData\Local\Programs\Python\Python311\Lib\site-packages\sofar\utils.py", line 69, in _verify_convention_and_version
    raise ValueError((
ValueError: Version 2.0 does not exist for convention SimpleFreeFieldHRTF. Try to access the data with version='latest'

Basically 2 things:

  1. sofar 1.0.0 removed the SimpleFreeFieldHRTF_2.0.json file from sofar 0.3.1. But before all HRTF files were saved as convention 2.0. Now that causes a problem in _verify_convention_and_version, because v2.0 is no longer accepted.
  2. despite my pyfar code explicitly saying verify=False, the actual code to load SOFA file runs _verify_convention_and_version and there it dies :)

Hi, that error comes from the way the conventions were handled by the Matlab SOFAToolbox. They did not make it very clear, which conventions will be supported in the future and which will be deprecated. That convention once existed but was completely deleted later. I am already working on a work around my current idea is:

-sofar.read_sofa (which is used by pyfar.io.read_sofa) will always throw an error if a sofa file was written with a non-existing convention.

  • a new function sofar.read_netcdf will be able to read (almost) any NetCDF data (the format behind SOFA). This could be used to read deprecated data or data, which heavily violating the sofa standard.
  • The data could then be accesed. The violations could be fixed if desired and the data could be written in accordance with AES69.

I know this annoying for now. Starting with sofar 1.0.0, this wont happen again.

Hi, will this new sofar.read_netcdf be used when I call pyfar.io.read_sofa with verify=False option?

sofar.read_netcdf could make sofar confusing if there are 2 very similar sofa reading functions - it would force me to change to always use sofar.read_netcdf because maximum compatibility is very important. Otherwise I would have used verify=True option in my code.

No, pyfar.io.read_sofa will always call sofar.read_sofa. I would recommend the following:

Try to read data as before but with in a try ... catch statement. If the error occurs, either notify the user how to fix it or fix it directly:

file = "some/file.sofa"

sofa = sf.read_netcdf(file)
sofa.protected = False
sofa.GLOBAL_SOFAConventionsVersion = "1.0"
sofa.protected = True
sofa.verify()

And use pyfar.io.convert_sofa to obtain pyfar objects.

I already finished and tested the read_netcdf function but will wait for a code review before I make the release. Hopefully by end of next week.

mberz commented

This is not an issue with pyfar, but with sofar or rather the SOFA standard, right?
I'd like to close this issue then.

Can we leave it open until we released the new sofar version, that could read the data?