Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ribbon Observables #27

Open
anton083 opened this issue May 16, 2024 · 2 comments
Open

Ribbon Observables #27

anton083 opened this issue May 16, 2024 · 2 comments

Comments

@anton083
Copy link
Member

anton083 commented May 16, 2024

It would be nice if the ribbon would re-render every time the backbone coordinates of the chains changed. Oxygen atoms and secondary structure would have to be re-assigned.

Here's my attempt at implementing it:

function Makie.plot!(ribbon::Ribbon{Tuple{Vector{Protein.Chain}}})
    coords_observables = [Observable(chain.backbone.coords) for chain in ribbon[1][]]

    function update_plot(coords_observables...)
        chains = deepcopy(ribbon[1][])
        Protein.assign_oxygens!.(chains)
        _assign_secondary_structure!(chains)
        isnothing(ribbon.colors[]) && (ribbon.colors = [LinRange(0, 1, length(chain)) for chain in chains])
        empty!(ribbon.plots)
        render!(ribbon, chains)
    end

    Makie.Observables.onany(update_plot, coords_observables...)

    update_plot(coords_observables...)

    return ribbon
end

This doesn't work because Observables doesn't detect mutation of coords, and the user can also not reach inside to update coords_observables and trigger update_plot. We can wrap coords in whatever, but the user will never have access to that thing, and Observables doesn't listen to mutations, I think -- only to e.g. obs = Observable(0); obs[] = 1.

Alternatively we could instead define Makie.plot!(ribbon::Ribbon{Tuple{Observable{Vector{Protein.Chain}}}}) such that the user could update a passed observable. The user wouldn't necessarily need to pass an observable if we define a convert_arguments for this.

@timholy
Copy link
Contributor

timholy commented May 20, 2024

Is this possibly related to animated visualizations? I'm working on something similar from a different angle, see https://github.com/HolyLab/FlyThroughPaths.jl (just created yesterday). There will be more modes added, and thankfully one of the Makie developers has gotten involved (see HolyLab/FlyThroughPaths.jl#6).

If you look at the implementation, you'll see there's even an action field which can be a callback (not yet documented). I'm planning on using this to adjust things like chain and residue transparency, so that as one flies around the protein one can gradually emphasize structural points that you want to highlight.

@asinghvi17
Copy link

asinghvi17 commented May 21, 2024

In this case I don't think you're using the Observables right. ribbon[1] is an Observable, so you want to create either one observable (@lift([chains.backbone.coords for chain in $(ribbon[1])])) or lift on ribbon[1] and update multiple pre-created observables. With the first approach, you don't need to splat which is nice.

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

No branches or pull requests

3 participants