Skip to content

Conversation

@peterhollender
Copy link
Contributor

@peterhollender peterhollender commented Sep 3, 2025

This makes some substantial changes to the way we store transducer definitions on disk, and carries these changes throughout the codebase. Major updates include:

  1. A new TransducerArray class that explicitly holds multiple TransformedTransducers (also a new class - a thin wrapper for Transducers). This allows for per-module modification of module positioning and properties, with a simple to_transducer method that bakes array together into a single conventional Transducer.
  2. The addition of sensitivity and impulse_response attributes to Transducer, which propagate down to elements. The split of sensitivity means that impulse responses are no longer length-1 arrays when they mean to encode simple scaling, In both cases, these attributes also exist for Element, and are elegantly ignored when set to None. The to_dict and from_dict methods have been updated to exclude these attributes if they are None, since they will pick up the None on instantiation, and it would create confusing verbiosity in the .json files for users not actually specifying them for both Transducer and Element. The addition to Transducer has the benefit of making the json file shorter - if you determine that your array is less, sensitive, you don't need to change every element, just the overall sensivity.
  3. Compression of Element attributes (x,y,z becomes position, length,width becomes size, and az,el,roll become orientation.
  4. A module_invert attribute has been added to Transducer, which trickles through to register computation, allowing particular modules to invert their output to compensate for flipped polarity arrays
  5. The io module has been updated to handle the module_invert attribute
  6. Solution objects now carry around the Transducer that was used in their creation. This alleviates the need to separately carry around the Transducer for bringing it's module_invert attribute into LIFUInterface.set_solution
  7. DVC is updated with new example transducers.
  8. Updates some of the example scripts in notebooks
  9. Updates unit tests to account for these changes

@peterhollender peterhollender force-pushed the p/transducerdef_update branch 3 times, most recently from bb7c544 to 70b4c28 Compare September 4, 2025 14:24
@peterhollender peterhollender marked this pull request as ready for review September 4, 2025 19:52
@ebrahimebrahim ebrahimebrahim self-assigned this Sep 8, 2025
@ebrahimebrahim
Copy link
Collaborator

I think you forgot to dvc push

@ebrahimebrahim
Copy link
Collaborator

Heads up that I will start pushing to and potentially rebasing this branch as I work on upgrading SlicerOpenLIFU to it. I've reviewed much of the code and it looks good -- no changes will be requested from your end. It's in my hands now.

Couple of initial comments below on the DVC data.


Did you mean to add these users shown in green? I will remove them if not

image

The transducer openlifu_2x400_evt1_005 was not added to the transducers.json, so I will add it

@ebrahimebrahim
Copy link
Collaborator

There is a folder db_dvc/transducers/openlifu_2x400_evt1/openlifu_1x400_evt1 that I think wasn't supposed to be there. I will delete it

Comment on lines +78 to +79
if self.impulse_response.ndim != 1 or len(self.impulse_response)<2:
raise ValueError("Impulse response must be a 1-dimensional array.")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is raised when using the openlifu_2x400_evt1_005.json example, because len(self.impulse_response) is 1 in that example:

{
    "type": "TransducerArray",
    "id": "openlifu_2x400_evt1_005",
    "name": "OpenLIFU 2x 400kHz EVT1 S/N 005",
    "modules": [
        {
            ...,
            "impulse_response": [
                1350.0
            ],
            ...,
        },
        ...,
    ]
    ...,
}

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This issue is making it so that the transducer openlifu_2x400_evt1_005.json cannot be loaded into SlicerOpenLIFU. But I am not sure how to fix it unless I understand the intention behind enforcing len(self.impulse_response)<2.

Once way to see this error in the unit tests for quick debugging is to change impulse_response in tests/resources/example_db/transducers/example_transducer_array2/example_transducer_array2.json to a list of length 1 instead of 2 by deleting an element.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ooh maybe the re-uploaded dvc doesn't have the correct fixes...

@ebrahimebrahim
Copy link
Collaborator

ebrahimebrahim commented Sep 10, 2025

Note that there is no way to write a TransducerArray to database. If that's something we want to support we could open an issue.

EDIT: Correction -- you can use Database.write_transducer on a TransducerArray, and it should use TransducerArray's to_file, but for reasons I can't remember it did not work out for me. So in any case something has to be done if we want to support writing TransducerArray to database

peterhollender and others added 13 commits September 9, 2025 22:06
Reworking Transducer Def for #380 and #381

Minor fixes for inverting TX polarity.

Add module invert to logger printout

New TransducerArray

made TransformedTransducer subclass of Transducer

Update Elements format, database loading

add backwards compatibilty, database write

Update db_dvc.dvc

bugfix in transducer, upload test script

new tests

Fixes for Pytest

Update test_watertank.py

Update test_watertank_simulation.py

Update test_watertank.py

remove `module_invert` from LIFUInterface

the `module_invert` attribute of LIFUInterface had no function after instantiation, as it passed it's state through to `TxDevice`. `TxDevice` also passes `module_invert` through to the `TxRegisters`, but because we call `enum_tx_7332_devices()` at various points, which re-instantiates the `TxRegisters`, the `TxDevice` needs to (for now) hold that state.
The `impulse_response` attribute was getting a little complicated whether or not it was None, a single value, or an array, so I split it into a scaling `sensitivity` attribute and a unitless `impulse_response`.  This also comes with improvements to merging arrays with different sensitivities.
- remove extraneous users
- add missing transducer id to transducers.json
It was not being converted to a numpy array on read
- remove misplaced transducer folder and json
It was wrongly being converted to list
When the impulse response is global to the transducer array,
rather than per module, it is not converted to a numpy array when it
should be.
- Update standardization script, noting that writing of TransducerArray
  is not supported now.
- Fix Solutions in DVC data -- they had transducer_id rather than
  Transducer attribute in them
- Run standardization script on DVC data
"Smart transducer loading" means reading via Transducer or
TransducerArray's serializer depending on the "type" field in the json
file. This functionality was stuck inside of Databse, but we expose it
as a general utility to support its use in SlicerOpenLIFU.
Copy link
Collaborator

@ebrahimebrahim ebrahimebrahim left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alright, everything looks good now and I think it's all working in SlicerOpenLIFU branch here: OpenwaterHealth/SlicerOpenLIFU#478, with the exception that openlifu_2x400_evt1_005.json cannot be loaded in SlicerOpenLIFU as indicated in the comment. This is not part of any actual example session though, so no sessions are broken.

I think it just remains to fix the openlifu_2x400_evt1_005.json example if you want to, and if you don't then let me know and I will merge

Copy link
Collaborator

@ebrahimebrahim ebrahimebrahim left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for fixing the _005 definition -- it loads in SlicerOpenLIFU now!

Merging!

@ebrahimebrahim ebrahimebrahim enabled auto-merge (rebase) September 10, 2025 02:29
This was linked to issues Sep 10, 2025
@ebrahimebrahim ebrahimebrahim merged commit 93044cf into main Sep 10, 2025
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Transducer Calibration Need to specify polarity per-module

3 participants