BigDataViewer/BigDataServer: get an ImagePlus Image of the current slice

fiji
imageplus
bigdataviewer
bigdataserver

#1

Hi everybody,

I’m writing a plugin and I now have to deal with BigDataViewer. I fear I will ran into some difficulties, so I’m already asking for advice.

I have a dataset (3D, 3 channels, no multiview) hosted on a BigDataServer. I access this dataset from a client with BigDataViewer. What I want is to let the user choose the slice he’s interested in, and then retrieve/download a 2D full resolution multichannel ImagePlus of this slice (at least a reasonable sampling) .

How difficult is this gonna be ? I looked into the BigDataViewer documentation but I couldn’t find a template to start to solve this problem. My intent now is to look at the visualisation part of the BigDataViewer code in order to see how the rasterization is done. Is it the way to go ?

All advice is welcome!


#2

Hi @NicoKiaru,

I don’t think its worth you looking into the rasterization code unless you want to do something especially fancy.

If you have the ArrayList< SourceAndConverter<?> > e.g. after this section,
then you can just

ArrayList< SourceAndConverter<?> > sources = ...
source_index = ...
time_point = ...
level = ...

// pick a level that gets you a "reasonably sized" image
// keep in that levels likely downsample in z, not just x and y, 
// depending on how you generated the xfm/hdf5 pair
RandomAccessibleInterval rai = sources.get( source_index ).getSpimSource().getSource( time_point, level );

From the RandomAccessibleInterval, you can copy data into an ImagePlus if you like.
You can also wrap it into an ImagePlus - if you’d prefer it be virtual.

John


#3

Thanks a lot! I’ll continue to struggle with this tomorrow.
Just to be sure : what you suggest will return the current user slice (with potential XYZ rotations) ? Or the whole stack at a certain timepoint ? Should I expect a 2D RandomAccessibleInterval ?


#4

Ah, I did not give you the whole solution. There will be details depending on exactly what you want to do.

You mean the current view in the BigDataViewer window right?

Are you familiar with imglib2 by the way? I can add more details tomorrow if you need, but I’ll be brief for now. (We will indeed look at part of bdv’s rendering code)

In short - this code finds the current xyz rotation and applies it to a particular source. The resulting RandomAccessible (if you bound it to the range of [window_width,window_height,0], will give you what is visible in the bdv window.

John


#5

Learned it during my commute this morning. Super easy :wink:

No, I’ve worked a few times with it but I can’t do things easily.

Yes!

Okay, no problem, thanks a lot you for your time already. I will dig deeper and then come up with more specific questions (or maybe a solution!).


#6

I’ve made some progress (everything accessible in the repo https://github.com/NicoKiaru/BDVSlicer), but still not there yet.

Ok, so here’s what I did so far and - disclaimer - it’s mainly some copying/reshaping of existing code.:

  • One command OpenBDV to open a dataset from a bigdataserver

The problem I ran into is that I couldn’t find any public methods of BigDataViewer which allowed me to get the spim sources from an existing BigDataViewer object. I don’t know if that’s because I missed them or because they do not exist. If they do not exist, is there a good reason behind this choice ?

So I did:

  • a second Command OpenBDVCatchSources, which captures the spim sources before constructing the big data viewer object. I then store these sources into a container class SpimSources SpimSources by using an ObjectService here. That’s in order to reuse the spim sources into the third command:
  • SpimSourcesToImgPlus, which returns an ImagePlus from the spim sources, according to the example provided by @bogovicj.

This works and you can directly launch the main class of the SpimSourcesToImgPlus command with default parameters. It captures a small part of the fly dataset from mpi-cbg BigDataServer.

There’s hope I believe!

However: now, in order to get the data from a running BigDataViewer instance I need to be able to access the currently displayed sources / time point AND the current transform stored somewhere in the viewerStateobject here, as written in the previous post.

I’m not so sure I can access this state from the BigDataViewer object. Is there a public method for that ?

If you have read this long message, thanks!


#7

Hi @NicoKiaru,

Nice job. I read everything but havn’t digested it yet.
A quick question and some pointers.

Question

First, are you using bdv-vistools? or “vanilla” bigdataviewer-core?

ViewerState

getting a ViewerState is easy in both cases, since it’s easily gettable from a ViewerPanel

with vistools

BdvStackSource< T > bdvss = ...
ViewerState viewerState = bdvss.getBdvHandle().getViewerPanel().getState();

using bigdataviewer-core

BigDataViewer bdv = ...
ViewerState viewerState = bdv.getViewer().getState();

Sources

with vistools its easy to get sources

BdvStackSource< T > bdvss = BdvFunctions.show( source, "mySource" );

// to get a bdv.viewer.Source (not excatly a SpimSource )
// but you can get a RandomAccessibleInterval from it
sources = bdvss.getSources();

It’s not easily gettable from a BigDataViewer to my knowledge.
In that case, you may need to build you Sources yourself and hold on to references.
Not hard, just extra book keeping.

John


#8

You should be able to get the source from the ViewerState, e.g.

ViewerState viewerState = ...
int sourceIndex = ...
SourceState<?> sourceState = viewerState.getSources().get(sourceIndex);
Source<?> spimSource = sourceState.getSpimSource();

#9

Thanks to both of you, @hanslovsky and @bogovicj, I simplified a lot the command. See https://github.com/NicoKiaru/BDVSlicer

It’s now working smoothly:

Thank you very much!


#10

By the way, I declare this as a dependency:

<dependency>
	<groupId>sc.fiji</groupId>
	<artifactId>bigdataviewer_fiji</artifactId>
</dependency>

Is there something wrong with that ? Should I use bigdataviewer-core instead ?

Another small question:

  • Is there an easy way to retrieve a bigdataviewer instance for an ImageJ command? In my case, I had to create a command which stores the newly created bigdataviewer object into an object service. If I don’t do it, declaring
@Parameter
BigDataViewer bdv;

Do not return any object.

Best


#11

Cool, bigdataviewer_fiji depends on bigdataviewer-core, so that’s what you’re using.

Not to my knowledge, but maybe @imagejan knows otherwise.

The way I would do this is to start your BigDataViewer yourself from an ImagePlus (or whatever).
E.g. by copying the code from the BigDataViewer Fiji plugin, or by using bdv-vistools instead.

John