### Report sofar and SOFA standard versions with sf.version() Source: https://context7.com/pyfar/sofar/llms.txt Returns a string identifying the installed sofar version and the SOFA standard version it implements. ```python import sofar as sf print(sf.version()) # sofar v1.2.3 implementing SOFA standard AES69-2022 ``` -------------------------------- ### `sf.version()` Source: https://context7.com/pyfar/sofar/llms.txt Returns a string identifying the installed sofar version and the SOFA standard version it implements. ```APIDOC ## `sf.version()` ### Description Returns a string identifying the installed sofar version and the SOFA standard version it implements. ### Method `version` is a function within the `sofar` module. ### Returns - **string**: A string indicating the sofar version and the SOFA standard version it implements. ### Usage ```python import sofar as sf print(sf.version()) ``` ``` -------------------------------- ### Install Sofar Package Source: https://github.com/pyfar/sofar/blob/main/README.md Use pip to install the sofar package. Requires Python version 3.8 or higher. ```bash pip install sofar ``` -------------------------------- ### Set Up Development Environment with Conda Source: https://github.com/pyfar/sofar/blob/main/CONTRIBUTING.rst Create and activate a conda virtual environment named 'sofar', then install the project in editable mode with development dependencies. This prepares the environment for making and testing changes. ```shell $ conda create --name sofar python $ conda activate sofar $ pip install -e ".[dev]" ``` -------------------------------- ### Download latest SOFA conventions with sf.update_conventions() Source: https://context7.com/pyfar/sofar/llms.txt Fetches the latest convention CSV files from sofaconventions.org, compares them to the locally installed ones, reports any additions or updates, and compiles them into internal JSON files. Use `assume_yes=True` for non-interactive scripting. ```python import sofar as sf # Interactive update — prompts "y/n" before applying changes sf.update_conventions() # Reading SOFA conventions from https://www.sofaconventions.org/conventions/ ... # - update convention: SimpleFreeFieldHRIR_1.0 # Do you want to update the conventions above? (y/n) # Non-interactive update (e.g., in CI pipelines) sf.update_conventions(assume_yes=True) # ... done. # Already up to date: # sf.update_conventions(assume_yes=True) # ... conventions already up to date. ``` -------------------------------- ### `sf.update_conventions()` Source: https://context7.com/pyfar/sofar/llms.txt Fetches the latest convention CSV files from sofaconventions.org, compares them to the locally installed ones, reports any additions or updates, and compiles them into the JSON files used internally by sofar. ```APIDOC ## `sf.update_conventions(assume_yes=False)` ### Description Fetches the latest convention CSV files from `sofaconventions.org`, compares them to the locally installed ones, reports any additions or updates, and (after user confirmation) compiles them into the JSON files used internally by sofar. Use `assume_yes=True` for non-interactive scripting. ### Parameters - **assume_yes** (boolean, optional) - If True, automatically confirms any prompts to update conventions, useful for non-interactive use. Defaults to False. ### Usage ```python import sofar as sf # Interactive update sf.update_conventions() # Non-interactive update sf.update_conventions(assume_yes=True) ``` ``` -------------------------------- ### Clone and Set Up sofar Repository Source: https://github.com/pyfar/sofar/blob/main/CONTRIBUTING.rst Clone the sofar repository recursively and navigate into the directory. This is the first step for local development. ```shell $ git clone --recursive https://github.com/YOUR_USERNAME/sofar.git $ cd sofar ``` -------------------------------- ### Create New SOFA Object with `sf.Sofa()` Source: https://context7.com/pyfar/sofar/llms.txt Instantiate a new SOFA object using a specified convention. All mandatory and optional fields are created with default values. Verification against the standard occurs by default. Use `mandatory=True` to reduce memory footprint or `version` to pin to a specific convention version. ```python import sofar as sf import numpy as np # Create a SimpleFreeFieldHRIR object (the most common HRIR convention) sofa = sf.Sofa("SimpleFreeFieldHRIR") print(sofa) # sofar.SOFA object: SimpleFreeFieldHRIR 1.0 # Populate with measurement data: # M=2 measurements, R=2 receivers (ears), N=128 samples sofa.Data_IR = np.zeros((2, 2, 128)) sofa.Data_SamplingRate = 48000 # Source positions (azimuth, elevation, radius) for 2 measurements sofa.SourcePosition = np.array([[0, 0, 1.0], [90, 0, 1.0]]) sofa.SourcePosition_Type = "spherical" sofa.SourcePosition_Units = "degree, degree, metre" # List all available dimensions and their sizes sofa.list_dimensions # M = 2 measurements (set by SourcePosition of dimension MCI) # N = 128 samples (set by Data_IR of dimension MRN) # R = 2 receiver (set by ReceiverPosition of dimension RCI) # E = 1 emitter ... # C = 3 coordinate dimensions, fixed # I = 1 single dimension, fixed # Only create with mandatory fields to reduce memory footprint sofa_min = sf.Sofa("SimpleFreeFieldHRIR", mandatory=True) # Pin to a specific convention version sofa_v1 = sf.Sofa("SimpleFreeFieldHRIR", version="1.0") ``` -------------------------------- ### Commit and Push Changes Source: https://github.com/pyfar/sofar/blob/main/CONTRIBUTING.rst Stage all changes, commit them with a descriptive message, and push the branch to your GitHub fork. This prepares your changes for a pull request. ```shell $ git add . $ git commit -m "Your detailed description of your changes." $ git push origin name-of-your-bugfix-or-feature ``` -------------------------------- ### Write SOFA Object to Disk with `sf.write_sofa()` Source: https://context7.com/pyfar/sofar/llms.txt Serializes a `Sofa` object to a `.sofa` file. The `.sofa` extension is added automatically if missing. Verification is performed before writing. Trailing dimensions are appended automatically, and compression is configurable (0-9, default 4). ```python import sofar as sf import numpy as np sofa = sf.Sofa("SimpleFreeFieldHRIR") sofa.Data_IR = np.random.randn(10, 2, 256) sofa.Data_SamplingRate = 44100 sofa.SourcePosition = np.column_stack([ np.linspace(0, 360, 10, endpoint=False), np.zeros(10), np.ones(10) ]) sofa.SourcePosition_Type = "spherical" sofa.SourcePosition_Units = "degree, degree, metre" sofa.GLOBAL_Title = "Example HRIR measurement" # Write with default compression (level 4) sf.write_sofa("/tmp/my_hrir.sofa", sofa) # Write without compression for faster read/write on local storage sf.write_sofa("/tmp/my_hrir_uncompressed.sofa", sofa, compression=0) ``` -------------------------------- ### List available SOFA conventions with sf.list_conventions() Source: https://context7.com/pyfar/sofar/llms.txt Prints all SOFA conventions currently bundled with sofar, including deprecated ones. Conventions define the required and optional variables for a specific data type. ```python import sofar as sf sf.list_conventions() # Available SOFA conventions: # FreeFieldDirectivityTF (Version 1.0) # GeneralFIR (Version 1.0) # GeneralFIR-E (Version 2.0) # GeneralSOS (Version 1.0) # GeneralTF (Version 1.0) # GeneralTF-E (Version 1.0) # SimpleFreeFieldHRIR (Version 1.0) # SimpleFreeFieldHRSOS (Version 1.0) # SimpleFreeFieldHRTF (Version 1.0) # SimpleHeadphoneIR (Version 1.0) # SingleRoomMIMOSRIR (Version 1.0) # SingleRoomSRIR (Version 1.0) # ... ``` -------------------------------- ### `sf.list_conventions()` Source: https://context7.com/pyfar/sofar/llms.txt Prints all SOFA conventions currently bundled with sofar, including deprecated ones. Conventions define the required and optional variables for a specific data type. ```APIDOC ## `sf.list_conventions()` ### Description Prints all SOFA conventions currently bundled with sofar, including deprecated ones. Conventions define the required and optional variables for a specific data type (e.g., HRIRs, transfer functions, directivity). ### Method `list_conventions` is a function within the `sofar` module. ### Usage ```python import sofar as sf sf.list_conventions() ``` ``` -------------------------------- ### sf.Sofa(convention) Source: https://context7.com/pyfar/sofar/llms.txt Instantiates a new SOFA object pre-populated with default values defined by the specified convention. The object is verified against the standard upon creation unless verification is explicitly disabled. ```APIDOC ## `sf.Sofa(convention)` — Create a new SOFA object Instantiates a new SOFA object pre-populated with the default values defined by the named convention. The `convention` argument selects the SOFA data type (e.g., `"SimpleFreeFieldHRIR"`, `"GeneralTF"`, `"FreeFieldDirectivityTF"`). All mandatory and optional fields are created as object attributes. The object is verified against the standard immediately unless `verify=False` is passed. ```python import sofar as sf import numpy as np # Create a SimpleFreeFieldHRIR object (the most common HRIR convention) sofa = sf.Sofa("SimpleFreeFieldHRIR") print(sofa) # sofar.SOFA object: SimpleFreeFieldHRIR 1.0 # Populate with measurement data: # M=2 measurements, R=2 receivers (ears), N=128 samples sofa.Data_IR = np.zeros((2, 2, 128)) sofa.Data_SamplingRate = 48000 # Source positions (azimuth, elevation, radius) for 2 measurements sofa.SourcePosition = np.array([[0, 0, 1.0], [90, 0, 1.0]]) sofa.SourcePosition_Type = "spherical" sofa.SourcePosition_Units = "degree, degree, metre" # List all available dimensions and their sizes sofa.list_dimensions # M = 2 measurements (set by SourcePosition of dimension MCI) # N = 128 samples (set by Data_IR of dimension MRN) # R = 2 receiver (set by ReceiverPosition of dimension RCI) # E = 1 emitter ... # C = 3 coordinate dimensions, fixed # I = 1 single dimension, fixed # Only create with mandatory fields to reduce memory footprint sofa_min = sf.Sofa("SimpleFreeFieldHRIR", mandatory=True) # Pin to a specific convention version sofa_v1 = sf.Sofa("SimpleFreeFieldHRIR", version="1.0") ``` ``` -------------------------------- ### Upgrade SOFA Convention with upgrade_convention() Source: https://context7.com/pyfar/sofar/llms.txt Check for and upgrade deprecated SOFA convention versions using `upgrade_convention()`. Without arguments, it lists available upgrade targets. With a `target` string, it performs the upgrade in-place, showing each transformation step. Custom entries are preserved. ```python import sofar as sf # Read a file using an older convention version sofa = sf.read_sofa("/path/to/old_hrir.sofa", verify=False) print(sofa.GLOBAL_SOFAConventions, sofa.GLOBAL_SOFAConventionsVersion) # SimpleFreeFieldHRIR 0.6 # Discover available upgrade targets targets = sofa.upgrade_convention() # SimpleFreeFieldHRIR v0.6 can be upgraded to: # - SimpleFreeFieldHRIR v1.0 # Perform the upgrade sofa.upgrade_convention(target="SimpleFreeFieldHRIR_1.0") # Upgrading SimpleFreeFieldHRIR v0.6 to SimpleFreeFieldHRIR v1.0 ... # - Moving Data_IR to Data_IR. Moving axis ... # - No data to remove # Save the upgraded file sf.write_sofa("/path/to/upgraded_hrir.sofa", sofa) ``` -------------------------------- ### Update and Commit Submodule Changes Source: https://github.com/pyfar/sofar/blob/main/CONTRIBUTING.rst Update the submodule containing conventions and verification rules, then commit any changes. This ensures the project uses the latest rules. ```bash $ git submodule update --init --recursive $ git submodule update --recursive --remote ``` -------------------------------- ### Sofa.inspect() Source: https://context7.com/pyfar/sofar/llms.txt Prints a human-readable summary of a SOFA object's attributes and variables, including shapes and values for small arrays. The output can also be saved to a text file. ```APIDOC ## `Sofa.inspect()` — Inspect data content of a SOFA object Prints a human-readable summary of all attributes (values) and all numeric/string variables (shape with named dimensions). Arrays with six or fewer elements also have their values printed. Output can be saved to a plain-text file. ```python import sofar as sf import numpy as np sofa = sf.Sofa("SimpleFreeFieldHRIR") sofa.Data_IR = np.zeros((3, 2, 64)) sofa.Data_SamplingRate = 48000 sofa.SourcePosition = np.array([[0, 0, 1.0], [45, 0, 1.0], [90, 0, 1.0]]) sofa.SourcePosition_Type = "spherical" sofa.SourcePosition_Units = "degree, degree, metre" # Print to console sofa.inspect() # SimpleFreeFieldHRIR 1.0 (SOFA version 2.1) # ------------------------------------------- # GLOBAL_Conventions : SOFA # GLOBAL_Version : 2.1 # ... # Data_IR : (M=3, R=2, N=64) # Data_SamplingRate : 48000.0 # SourcePosition : (M=3, C=3) # [[ 0. 0. 1.] # [45. 0. 1.] # [90. 0. 1.]] # Save to file sofa.inspect(file="/tmp/sofa_info.txt") ``` ``` -------------------------------- ### Check Code Quality and Run Tests Source: https://github.com/pyfar/sofar/blob/main/CONTRIBUTING.rst Before committing, ensure your changes pass linting with ruff and all tests with pytest. Ruff checks should pass without warnings for the specified directories. ```shell $ ruff check $ pytest ``` -------------------------------- ### Read SOFA File from Disk with `sf.read_sofa()` Source: https://context7.com/pyfar/sofar/llms.txt Reads a `.sofa` file and returns a `Sofa` object. Numeric arrays are NumPy floats, masked arrays are used for fill values. Singleton trailing dimensions are removed, and scalar arrays with one element become Python scalars. Custom variables/attributes are loaded and reported unless `verbose=False`. ```python import sofar as sf # Standard read with automatic verification sofa = sf.read_sofa("/tmp/my_hrir.sofa") print(sofa) # sofar.SOFA object: SimpleFreeFieldHRIR 1.0 print(sofa.Data_IR.shape) # (10, 2, 256) print(sofa.Data_SamplingRate) # 44100.0 (scalar) print(sofa.SourcePosition.shape) # (10, 3) # Read without verification (useful for debugging corrupted files) sofa_unverified = sf.read_sofa("/tmp/my_hrir.sofa", verify=False) # Suppress reporting of custom entries sofa_quiet = sf.read_sofa("/tmp/my_hrir.sofa", verbose=False) ``` -------------------------------- ### Create a New Branch for Development Source: https://github.com/pyfar/sofar/blob/main/CONTRIBUTING.rst Create a new branch for your bug fix or feature development. Naming the branch descriptively, like 'feature/branch-name' or 'bugfix/branch-name', is recommended. ```shell $ git checkout -b name-of-your-bugfix-or-feature ``` -------------------------------- ### sf.read_sofa(filename) Source: https://context7.com/pyfar/sofar/llms.txt Reads a `.sofa` file from disk and returns a `Sofa` object. Numeric arrays are returned as NumPy arrays, and masked arrays are used for fill values. Singleton trailing dimensions are discarded, and scalar arrays with one element are converted to Python scalars. Custom variables and attributes are loaded and reported. ```APIDOC ## `sf.read_sofa(filename)` — Read a SOFA file from disk Reads a `.sofa` file and returns a fully populated `Sofa` object. Numeric arrays are returned as NumPy float arrays; masked arrays are returned where data contains fill values. Singleton trailing dimensions are discarded (e.g., stored shape `(M, R, 1)` → returned shape `(M, R)`). Scalar arrays with one element are converted to Python scalars (e.g., `Data_SamplingRate`). Custom variables and attributes not defined by the convention are loaded and reported. ```python import sofar as sf # Standard read with automatic verification sofa = sf.read_sofa("/tmp/my_hrir.sofa") print(sofa) # sofar.SOFA object: SimpleFreeFieldHRIR 1.0 print(sofa.Data_IR.shape) # (10, 2, 256) print(sofa.Data_SamplingRate) # 44100.0 (scalar) print(sofa.SourcePosition.shape) # (10, 3) # Read without verification (useful for debugging corrupted files) sofa_unverified = sf.read_sofa("/tmp/my_hrir.sofa", verify=False) # Suppress reporting of custom entries sofa_quiet = sf.read_sofa("/tmp/my_hrir.sofa", verbose=False) ``` ``` -------------------------------- ### sf.write_sofa(filename, sofa) Source: https://context7.com/pyfar/sofar/llms.txt Serializes a `Sofa` object to a NetCDF4-based `.sofa` file. The file is automatically verified before writing, and missing trailing dimensions are appended. Compression level can be configured. ```APIDOC ## `sf.write_sofa(filename, sofa)` — Write a SOFA object to disk Serializes a `Sofa` object to a NetCDF4-based `.sofa` file. The `.sofa` extension is appended automatically if omitted. Full verification is run before writing. Missing trailing dimensions are automatically appended (e.g., a `Data_IR` array of shape `(M, R)` is stored as `(M, R, 1)`). Compression level is configurable from 0 (none) to 9 (maximum); the default of 4 balances file size and I/O speed. ```python import sofar as sf import numpy as np sofa = sf.Sofa("SimpleFreeFieldHRIR") sofa.Data_IR = np.random.randn(10, 2, 256) sofa.Data_SamplingRate = 44100 sofa.SourcePosition = np.column_stack([ np.linspace(0, 360, 10, endpoint=False), np.zeros(10), np.ones(10) ]) sofa.SourcePosition_Type = "spherical" sofa.SourcePosition_Units = "degree, degree, metre" sofa.GLOBAL_Title = "Example HRIR measurement" # Write with default compression (level 4) sf.write_sofa("/tmp/my_hrir.sofa", sofa) # Write without compression for faster read/write on local storage sf.write_sofa("/tmp/my_hrir_uncompressed.sofa", sofa, compression=0) ``` ``` -------------------------------- ### SofaStream Source: https://context7.com/pyfar/sofar/llms.txt Provides memory-efficient streaming access to SOFA files, keeping the file on disk and reading variables on demand. Ideal for large datasets where loading everything into RAM is impractical. ```APIDOC ## `SofaStream` — Memory-efficient streaming access Context-manager class that keeps the SOFA file on disk and reads only the requested variables on demand via NetCDF4 lazy access. Returned numeric variables are `netCDF4.Variable` objects that must be sliced to retrieve values. Ideal for large HRIR databases (millions of measurements) where loading everything into RAM is impractical. ```python import sofar as sf filename = "/path/to/large_hrir_dataset.sofa" with sf.SofaStream(filename) as stream: # Read a scalar global attribute (returned as a Python string) room_type = stream.GLOBAL_RoomType print(room_type) # free field # Access variable metadata without loading data ir_var = stream.Data_IR print(ir_var) # # float64 Data.IR(M, R, N) # current shape = (11950, 2, 256) # Slice to retrieve actual values all_irs = stream.Data_IR[:] left_ear = stream.Data_IR[:, 0, :] first_ir = stream.Data_IR[0, :, :] # Check dimensions without loading data stream.list_dimensions # M = 11950 measurements # N = 256 samples # R = 2 receiver n_measurements = stream.get_dimension("M") n_samples = stream.get_dimension("N") ``` ``` -------------------------------- ### Update Git Submodules Source: https://github.com/pyfar/sofar/blob/main/CONTRIBUTING.rst If the submodule directory is empty after cloning, use this command to initialize and update submodules. This ensures all necessary convention and verification rule files are present. ```shell $ git submodule update --init ``` -------------------------------- ### Read Corrupted SOFA Data with Fallback Source: https://context7.com/pyfar/sofar/llms.txt Use `sf.read_sofa_as_netcdf` as a last resort to load raw NetCDF4 content from files that fail standard SOFA reading and verification. The returned object may require manual data correction. ```python import sofar as sf # Escalating recovery strategy for a problematic file filename = "/tmp/broken.sofa" try: sofa = sf.read_sofa(filename) except Exception: try: sofa = sf.read_sofa(filename, verify=False) sofa.verify() # inspect the specific errors except Exception: # Last resort: raw NetCDF load sofa = sf.read_sofa_as_netcdf(filename) print("Loaded raw content — inspect and fix manually") sofa.inspect(issue_handling="ignore") ``` -------------------------------- ### sf.read_sofa_as_netcdf(filename) Source: https://context7.com/pyfar/sofar/llms.txt A fallback reader for corrupted SOFA files that bypasses convention checks and loads raw NetCDF4 content. This is a last resort when standard reading methods fail. ```APIDOC ## `sf.read_sofa_as_netcdf(filename)` — Read corrupted SOFA data Fallback reader that bypasses SOFA convention checks entirely and loads the raw NetCDF4 content into a minimal `Sofa` object. Intended for recovering data from files that fail both `read_sofa(..., verify=True)` and `read_sofa(..., verify=False)`. The returned object may not behave correctly until the underlying data errors are fixed manually. ```python import sofar as sf # Escalating recovery strategy for a problematic file filename = "/tmp/broken.sofa" try: sofa = sf.read_sofa(filename) except Exception: try: sofa = sf.read_sofa(filename, verify=False) sofa.verify() # inspect the specific errors except Exception: # Last resort: raw NetCDF load sofa = sf.read_sofa_as_netcdf(filename) print("Loaded raw content — inspect and fix manually") sofa.inspect(issue_handling="ignore") ``` ``` -------------------------------- ### Sofa.verify() Source: https://context7.com/pyfar/sofar/llms.txt Validates a SOFA object against the AES69-2022 standard, checking for mandatory fields, correct data types, consistent shapes, and valid attributes. It can raise exceptions, print issues, or return them as a string. ```APIDOC ## `Sofa.verify()` — Validate a SOFA object against AES69-2022 Runs the complete set of SOFA standard checks: mandatory fields present, correct data types, consistent variable shapes, valid attribute values, unit format compliance, and deprecation detection. Called automatically on object creation, read, and write. The `issue_handling` parameter controls whether problems raise exceptions, print to console, or are returned as a string. ```python import sofar as sf import numpy as np sofa = sf.Sofa("GeneralTF", verify=False) sofa.Data_Real = np.ones((5, 2, 128)) sofa.Data_Imag = np.zeros((5, 2, 128)) # Default: raise ValueError on any errors try: sofa.verify() except ValueError as e: print(e) # Print issues without raising exceptions sofa.verify(issue_handling="print") # Return issues as a string for programmatic handling issues = sofa.verify(issue_handling="return") if issues is None: print("SOFA object is valid") else: print(f"Issues detected:\n{issues}") # Use 'read' mode to allow uppercase units (as stored in older files) sofa.verify(mode="read") ``` ``` -------------------------------- ### Upgrading SOFA Convention Source: https://context7.com/pyfar/sofar/llms.txt Detects and upgrades outdated SOFA convention versions by renaming or reorganizing variables to match a target convention. Without arguments, it lists available upgrade targets. With a `target` string, it performs the upgrade in-place. ```APIDOC ## `Sofa.upgrade_convention()` — Upgrade outdated SOFA data Detects whether a SOFA object uses a deprecated convention version and upgrades it by renaming/reorganizing variables to match the target convention. Without arguments, lists the available upgrade targets. With a `target` string, performs the upgrade in-place, printing each transformation step. ### Usage ```python import sofar as sf # Read a file using an older convention version sofa = sf.read_sofa("/path/to/old_hrir.sofa", verify=False) print(sofa.GLOBAL_SOFAConventions, sofa.GLOBAL_SOFAConventionsVersion) # Discover available upgrade targets targets = sofa.upgrade_convention() # Perform the upgrade sofa.upgrade_convention(target="SimpleFreeFieldHRIR_1.0") # Save the upgraded file sf.write_sofa("/path/to/upgraded_hrir.sofa", sofa) ``` ### Output Example ``` SimpleFreeFieldHRIR 0.6 SimpleFreeFieldHRIR v0.6 can be upgraded to: - SimpleFreeFieldHRIR v1.0 Upgrading SimpleFreeFieldHRIR v0.6 to SimpleFreeFieldHRIR v1.0 ... - Moving Data_IR to Data_IR. Moving axis ... - No data to remove ``` ``` -------------------------------- ### Compare two SOFA objects with sf.equals() Source: https://context7.com/pyfar/sofar/llms.txt Performs element-wise comparison of all attributes and variables in two SOFA objects. Numeric arrays are compared with numpy.testing.assert_allclose; string arrays with exact equality. Returns True if identical, False otherwise, with optional console output of differences. Fields can be selectively excluded (global metadata, date fields, or all attributes). ```python import sofar as sf sofa_a = sf.read_sofa("/tmp/my_hrir.sofa") # Round-trip test: write and read back, then compare ignoring dates sf.write_sofa("/tmp/copy.sofa", sofa_a) sofa_b = sf.read_sofa("/tmp/copy.sofa") # Full comparison identical = sf.equals(sofa_a, sofa_b) print(identical) # True # Compare only data, ignoring all metadata attributes identical_data = sf.equals(sofa_a, sofa_b, exclude="ATTR") # Compare ignoring auto-updated date fields (DateCreated, DateModified) identical_no_dates = sf.equals(sofa_a, sofa_b, exclude="DATE") # Silent comparison (no warnings printed for differences) result = sf.equals(sofa_a, sofa_b, verbose=False) ``` -------------------------------- ### Memory-Efficient SOFA Streaming with SofaStream Source: https://context7.com/pyfar/sofar/llms.txt Utilize `SofaStream` for large SOFA files to access data on demand without loading the entire file into memory. This is ideal for HRIR databases. Returned variables are `netCDF4.Variable` objects that require slicing to retrieve values. ```python import sofar as sf filename = "/path/to/large_hrir_dataset.sofa" with sf.SofaStream(filename) as stream: # Read a scalar global attribute (returned as a Python string) room_type = stream.GLOBAL_RoomType print(room_type) # free field # Access variable metadata without loading data ir_var = stream.Data_IR print(ir_var) # # float64 Data.IR(M, R, N) # current shape = (11950, 2, 256) # Slice to retrieve actual values all_irs = stream.Data_IR[:] # shape (11950, 2, 256) left_ear = stream.Data_IR[:, 0, :] # shape (11950, 256) — left channel only first_ir = stream.Data_IR[0, :, :] # shape (2, 256) — first measurement # Check dimensions without loading data stream.list_dimensions # M = 11950 measurements # N = 256 samples # R = 2 receiver n_measurements = stream.get_dimension("M") # 11950 n_samples = stream.get_dimension("N") # 256 ``` -------------------------------- ### Querying SOFA Dimensions Source: https://context7.com/pyfar/sofar/llms.txt Retrieve the integer size of named SOFA dimensions or list all dimensions with their semantic meaning. Dimensions are inferred from the shapes of the data currently stored in the object. ```APIDOC ## `Sofa.get_dimension()` and `Sofa.list_dimensions` — Query SOFA dimensions Retrieve the integer size of a named SOFA dimension (`M`, `N`, `R`, `E`, `C`, `I`, `S`) or print a full listing of all dimensions with their semantic meaning. Dimensions are inferred from the shapes of the data currently stored in the object. ### Usage ```python import sofar as sf import numpy as np sofa = sf.Sofa("SimpleFreeFieldHRIR") sofa.Data_IR = np.zeros((100, 2, 512)) sofa.Data_SamplingRate = 48000 sofa.SourcePosition = np.zeros((100, 3)) sofa.SourcePosition_Type = "spherical" sofa.SourcePosition_Units = "degree, degree, metre" # Get individual dimension sizes M = sofa.get_dimension("M") # 100 — number of measurements R = sofa.get_dimension("R") # 2 — number of receivers N = sofa.get_dimension("N") # 512 — number of samples print(f"Dataset: {M} measurements, {R} receivers, {N} samples") # Print all dimensions with descriptions sofa.list_dimensions ``` ### Output Example ``` Dataset: 100 measurements, 2 receivers, 512 samples # M = 100 measurements (set by SourcePosition of dimension MCI) # N = 512 samples (set by Data_IR of dimension MRN) # R = 2 receiver (set by ReceiverPosition of dimension RCI) # E = 1 emitter ... # S = 0 maximum string length # C = 3 coordinate dimensions, fixed # I = 1 single dimension, fixed ``` ``` -------------------------------- ### `Sofa.copy()` Source: https://context7.com/pyfar/sofar/llms.txt Returns a fully independent deep copy of the SOFA object, including all data arrays, custom entries, and internal API metadata. Useful for creating modified variants without altering the original. ```APIDOC ## `Sofa.copy()` ### Description Returns a fully independent deep copy of the SOFA object, including all data arrays, custom entries, and internal API metadata. Useful for creating modified variants without altering the original. ### Method Instance method of the `Sofa` object. ### Usage ```python import sofar as sf sofa_original = sf.read_sofa("path/to/your/sofa.sofa") sofa_copy = sofa_original.copy() ``` ``` -------------------------------- ### Deep copy a SOFA object with Sofa.copy() Source: https://context7.com/pyfar/sofar/llms.txt Returns a fully independent deep copy of the SOFA object. Useful for creating modified variants without altering the original. Ensure data arrays, custom entries, and internal API metadata are included. ```python import sofar as sf import numpy as np sofa = sf.read_sofa("/tmp/my_hrir.sofa") # Make a copy and apply gain to the IR data sofa_boosted = sofa.copy() sofa_boosted.Data_IR = sofa_boosted.Data_IR * 2.0 # Originals are unaffected print(np.allclose(sofa.Data_IR * 2, sofa_boosted.Data_IR)) # True print(sofa.Data_IR is sofa_boosted.Data_IR) # False ``` -------------------------------- ### Add Custom Variables and Attributes with add_variable() and add_attribute() Source: https://context7.com/pyfar/sofar/llms.txt Extend SOFA objects with custom numeric or string variables using `add_variable()`, specifying dimensions and data type. Use `add_attribute()` to add string metadata, including documenting custom variables or adding global information. Both methods enforce SOFA naming rules and preserve custom entries through write/read operations. ```python import sofar as sf import numpy as np sofa = sf.Sofa("GeneralTF") sofa.Data_Real = np.ones((5, 2, 64)) sofa.Data_Imag = np.zeros((5, 2, 64)) # Add a numeric variable: temperature at each of 5 measurements # Dimensions: M=measurements, I=single (scalar per measurement) sofa.add_variable("Temperature", np.array([22.1, 22.3, 22.0, 21.9, 22.2]), dtype="double", dimensions="MI") # Add an attribute documenting the new variable's units sofa.add_attribute("Temperature_Units", "degree Celsius") # Add a global metadata attribute sofa.add_attribute("GLOBAL_DateMeasured", "2024-07-15") # Add a string variable: comment per measurement sofa.add_variable("Comment", np.array(["dry run", "with diffuser", "with panel", "no panel", "final"]), dtype="string", dimensions="MS") # Verify the complete object including custom entries sofa.verify() # Write to disk — custom entries are preserved sf.write_sofa("/tmp/custom_tf.sofa", sofa) # Read back and confirm custom entries are present sofa2 = sf.read_sofa("/tmp/custom_tf.sofa") print(sofa2.Temperature) # [22.1 22.3 22.0 21.9 22.2] print(sofa2.Temperature_Units) # degree Celsius ``` -------------------------------- ### Adding Custom Data Source: https://context7.com/pyfar/sofar/llms.txt Extend a SOFA object with custom numeric or string variables and string metadata attributes. Both methods enforce SOFA naming rules and preserve custom entries through write/read round-trips. ```APIDOC ## `Sofa.add_variable()` and `Sofa.add_attribute()` — Add custom data Extend a SOFA object with data beyond what the convention defines. Custom variables store numeric or string arrays with explicit dimension strings; custom attributes store string metadata. Both methods enforce SOFA naming rules (e.g., attributes must follow `Variable_Attribute` form). Custom entries are preserved through write/read round-trips. ### Usage ```python import sofar as sf import numpy as np sofa = sf.Sofa("GeneralTF") sofa.Data_Real = np.ones((5, 2, 64)) sofa.Data_Imag = np.zeros((5, 2, 64)) # Add a numeric variable: temperature at each of 5 measurements # Dimensions: M=measurements, I=single (scalar per measurement) sofa.add_variable("Temperature", np.array([22.1, 22.3, 22.0, 21.9, 22.2]), dtype="double", dimensions="MI") # Add an attribute documenting the new variable's units sofa.add_attribute("Temperature_Units", "degree Celsius") # Add a global metadata attribute sofa.add_attribute("GLOBAL_DateMeasured", "2024-07-15") # Add a string variable: comment per measurement sofa.add_variable("Comment", np.array(["dry run", "with diffuser", "with panel", "no panel", "final"]), dtype="string", dimensions="MS") # Verify the complete object including custom entries sofa.verify() # Write to disk — custom entries are preserved sf.write_sofa("/tmp/custom_tf.sofa", sofa) # Read back and confirm custom entries are present sofa2 = sf.read_sofa("/tmp/custom_tf.sofa") print(sofa2.Temperature) print(sofa2.Temperature_Units) ``` ### Output Example ``` [22.1 22.3 22.0 21.9 22.2] degree Celsius ``` ``` -------------------------------- ### `sf.equals(sofa_a, sofa_b)` Source: https://context7.com/pyfar/sofar/llms.txt Performs element-wise comparison of all attributes and variables in two SOFA objects. Numeric arrays are compared with `numpy.testing.assert_allclose`; string arrays with exact equality. Returns `True` if identical, `False` otherwise, with optional console output of differences. Fields can be selectively excluded. ```APIDOC ## `sf.equals(sofa_a, sofa_b, exclude=None, verbose=True)` ### Description Performs element-wise comparison of all attributes and variables in two SOFA objects. Numeric arrays are compared with `numpy.testing.assert_allclose`; string arrays with exact equality. Returns `True` if identical, `False` otherwise, with optional console output of differences. Fields can be selectively excluded (global metadata, date fields, or all attributes). ### Parameters - **sofa_a** (`Sofa` object) - The first SOFA object to compare. - **sofa_b** (`Sofa` object) - The second SOFA object to compare. - **exclude** (string, optional) - Specifies fields to exclude from comparison. Can be 'ATTR' (all attributes), 'DATE' (date fields), or a comma-separated string of specific fields. Defaults to None (no exclusions). - **verbose** (boolean, optional) - If True, prints differences to the console. Defaults to True. ### Returns - **boolean**: True if the SOFA objects are identical based on the comparison criteria, False otherwise. ### Usage ```python import sofar as sf sofa_a = sf.read_sofa("path/to/sofa_a.sofa") sofa_b = sf.read_sofa("path/to/sofa_b.sofa") # Full comparison identical = sf.equals(sofa_a, sofa_b) # Compare only data, ignoring all metadata attributes identical_data = sf.equals(sofa_a, sofa_b, exclude="ATTR") # Compare ignoring auto-updated date fields identical_no_dates = sf.equals(sofa_a, sofa_b, exclude="DATE") # Silent comparison result = sf.equals(sofa_a, sofa_b, verbose=False) ``` ``` -------------------------------- ### Query SOFA Dimensions with get_dimension() and list_dimensions Source: https://context7.com/pyfar/sofar/llms.txt Use `get_dimension()` to retrieve the integer size of specific SOFA dimensions (M, N, R, E, C, I, S). Call `list_dimensions` to see all dimensions with their meanings, inferred from the data shapes. ```python import sofar as sf import numpy as np sofa = sf.Sofa("SimpleFreeFieldHRIR") sofa.Data_IR = np.zeros((100, 2, 512)) sofa.Data_SamplingRate = 48000 sofa.SourcePosition = np.zeros((100, 3)) sofa.SourcePosition_Type = "spherical" sofa.SourcePosition_Units = "degree, degree, metre" # Get individual dimension sizes M = sofa.get_dimension("M") # 100 — number of measurements R = sofa.get_dimension("R") # 2 — number of receivers N = sofa.get_dimension("N") # 512 — number of samples print(f"Dataset: {M} measurements, {R} receivers, {N} samples") # Dataset: 100 measurements, 2 receivers, 512 samples # Print all dimensions with descriptions sofa.list_dimensions # M = 100 measurements (set by SourcePosition of dimension MCI) # N = 512 samples (set by Data_IR of dimension MRN) # R = 2 receiver (set by ReceiverPosition of dimension RCI) # E = 1 emitter ... # S = 0 maximum string length # C = 3 coordinate dimensions, fixed # I = 1 single dimension, fixed ``` -------------------------------- ### Verify SOFA Object Compliance with `Sofa.verify()` Source: https://context7.com/pyfar/sofar/llms.txt Use `sofa.verify()` to validate a SOFA object against the AES69-2022 standard. It checks for mandatory fields, correct data types, consistent shapes, and valid attributes. The `issue_handling` parameter controls error reporting (exceptions, print, or return string). ```python import sofar as sf import numpy as np sofa = sf.Sofa("GeneralTF", verify=False) sofa.Data_Real = np.ones((5, 2, 128)) sofa.Data_Imag = np.zeros((5, 2, 128)) # Default: raise ValueError on any errors try: sofa.verify() except ValueError as e: print(e) # Print issues without raising exceptions sofa.verify(issue_handling="print") # Return issues as a string for programmatic handling issues = sofa.verify(issue_handling="return") if issues is None: print("SOFA object is valid") else: print(f"Issues detected:\n{issues}") # Use 'read' mode to allow uppercase units (as stored in older files) sofa.verify(mode="read") ``` -------------------------------- ### Inspect SOFA Object Content with `Sofa.inspect()` Source: https://context7.com/pyfar/sofar/llms.txt Employ `sofa.inspect()` to generate a human-readable summary of a SOFA object's attributes and variables. It displays shapes and values (for small arrays) and can save the output to a text file. This is useful for understanding the structure and content of SOFA data. ```python import sofar as sf import numpy as np sofa = sf.Sofa("SimpleFreeFieldHRIR") sofa.Data_IR = np.zeros((3, 2, 64)) sofa.Data_SamplingRate = 48000 sofa.SourcePosition = np.array([[0, 0, 1.0], [45, 0, 1.0], [90, 0, 1.0]]) sofa.SourcePosition_Type = "spherical" sofa.SourcePosition_Units = "degree, degree, metre" # Print to console sofa.inspect() # SimpleFreeFieldHRIR 1.0 (SOFA version 2.1) # ------------------------------------------- # GLOBAL_Conventions : SOFA # GLOBAL_Version : 2.1 # ... # Data_IR : (M=3, R=2, N=64) # Data_SamplingRate : 48000.0 # SourcePosition : (M=3, C=3) # [[ 0. 0. 1.] # [45. 0. 1.] # [90. 0. 1.]] # Save to file sofa.inspect(file="/tmp/sofa_info.txt") ``` -------------------------------- ### Delete Optional Fields with delete() Source: https://context7.com/pyfar/sofar/llms.txt Remove optional variables or attributes from a SOFA object using `delete()`. Mandatory fields cannot be deleted and will raise a `TypeError`. This is useful for reducing file size by trimming unnecessary optional data before writing. ```python import sofar as sf sofa = sf.Sofa("SimpleFreeFieldHRIR") # includes many optional fields # Remove optional fields not needed for this dataset sofa.delete("GLOBAL_Comment") sofa.delete("GLOBAL_Origin") # Attempting to delete a mandatory field raises TypeError try: sofa.delete("Data_IR") except TypeError as e: print(e) # Data_IR is a mandatory attribute that can not be deleted ``` -------------------------------- ### Deleting Optional Data Source: https://context7.com/pyfar/sofar/llms.txt Remove optional variables or attributes from a SOFA object. Mandatory fields cannot be deleted and will raise a `TypeError`. This is useful for trimming optional fields before writing to reduce file size. ```APIDOC ## `Sofa.delete()` — Remove optional variables or attributes Deletes an optional variable or attribute from a SOFA object. Mandatory fields cannot be deleted; attempting to do so raises a `TypeError`. This is useful for trimming optional fields before writing to reduce file size. ### Usage ```python import sofar as sf sofa = sf.Sofa("SimpleFreeFieldHRIR") # includes many optional fields # Remove optional fields not needed for this dataset sofa.delete("GLOBAL_Comment") sofa.delete("GLOBAL_Origin") # Attempting to delete a mandatory field raises TypeError try: sofa.delete("Data_IR") except TypeError as e: print(e) ``` ### Output Example ``` Data_IR is a mandatory attribute that can not be deleted ``` ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.