Skip to content

feat: visualize transform chains#298

Merged
jokasimr merged 11 commits intomainfrom
transform-visualize
Mar 2, 2026
Merged

feat: visualize transform chains#298
jokasimr merged 11 commits intomainfrom
transform-visualize

Conversation

@jokasimr
Copy link
Contributor

Fixes #292

@jokasimr
Copy link
Contributor Author

Screenshot from 2026-02-10 12-52-17

@nvaytet
Copy link
Member

nvaytet commented Feb 10, 2026

I think it would be useful to show the values as well? How many meters it was translated by in what direction?
Also degrees of rotation? (for rotations, maybe if we can see it's around a specific axis we can show that; otherwise, I am not sure showing the rotation matrix is so useful?)

Finally, I wonder if placing things at scale in the graph would be useful/possible for the translations? You could then build some sort of instrument layout with relative spacings between components?

@jokasimr
Copy link
Contributor Author

I added fields for the transformation vector and the magnitude.

Placing things at scale I think wouldn't be so useful here. I interpreted this to be a more abstract illustration to debug/understand transformations in a nexus file. It would be difficult to make it look good, because some translations might be tiny and other might be large, and it would only cover the translations anyway (since we can't rotate out of the screen).

@jokasimr
Copy link
Contributor Author

Examples

Screenshot from 2026-02-11 09-27-10 Screenshot from 2026-02-11 09-26-56

@SimonHeybrock
Copy link
Member

Finally, I wonder if placing things at scale in the graph would be useful/possible for the translations? You could then build some sort of instrument layout with relative spacings between components?

I think that would make it unusable in many cases. Let us not do that

@SimonHeybrock
Copy link
Member

I added fields for the transformation vector and the magnitude.

Can you also add add the others? No reason to omit anything, right?

f'{label}\\nvalue ∈ '
f'[{_fmt(np.nanmin(vals))} {unit}, '
f'{_fmt(np.nanmax(vals))} {unit}]'
)
Copy link
Member

Choose a reason for hiding this comment

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

Why all the duplication and why not use Scipp?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed now 👍

Comment on lines +287 to +290
if path in visited:
raise ValueError(
f'Circular depends_on chain detected: {[*visited, path]}'
)
Copy link
Member

Choose a reason for hiding this comment

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

Why not visualize this? The point of the visualization is to debug the chain. I don't see the need to raise here?

Comment on lines +347 to +351
except KeyError as e:
m = f'depends_on chain {depends_on} references missing node {e}'.replace(
'\n', ''
)
warnings.warn(UserWarning(m), stacklevel=2)
Copy link
Member

Choose a reason for hiding this comment

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

Why is this not included in the graph? Also not sure why we would want to warn here? Can that just be a warning color on the graph?

@jokasimr
Copy link
Contributor Author

Can you also add add the others? No reason to omit anything, right?

Including too much information in the graphviz boxes will make the visualization hard to read and understand. What fields are you thinking about specifically?

@jokasimr
Copy link
Contributor Author

Screenshot from 2026-02-11 16-29-03 Screenshot from 2026-02-11 16-28-53

dot.edge(prev, path, label='depends_on')
prev = path
depends_on = transform.depends_on
except KeyError:
Copy link
Member

Choose a reason for hiding this comment

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

This code is very long and deeply nested. And this try-except encompasses almost all of it. So it's difficult to understand how this works and what failures are supposed to trigger this fallback. Can you split this into smaller functions?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've moved the try-except to only cover the part of the code where it's relevant.
This makes the code less nested and easier to read.
I don't think it would benefit from being split into smaller functions at this point.

@jokasimr jokasimr requested a review from jl-wynen February 17, 2026 09:29
@SimonHeybrock
Copy link
Member

Can you also add add the others? No reason to omit anything, right?

Including too much information in the graphviz boxes will make the visualization hard to read and understand. What fields are you thinking about specifically?

All the values/attrs that are part of a transform. If you omit some it may be misinterpreted as a bug, and not seeing all of them means it is impossible to interpret what the transform does. There are not many, so I think including all should be perfectly feasible?

Copy link
Member

@SimonHeybrock SimonHeybrock left a comment

Choose a reason for hiding this comment

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

Thanks, code looks good. Can you share some screenshots of the latest state?

@jl-wynen Did you have more comments?

@jokasimr
Copy link
Contributor Author

jokasimr commented Mar 2, 2026

Screenshot from 2026-03-02 07-48-48 Screenshot from 2026-03-02 07-47-58 Screenshot from 2026-03-02 07-47-36

@jokasimr jokasimr merged commit 1ca907d into main Mar 2, 2026
5 checks passed
@jokasimr jokasimr deleted the transform-visualize branch March 2, 2026 08:21
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.

Add a graph visualisation to transformation chains

4 participants