images sequence at multiple positions

classic Classic list List threaded Threaded
9 messages Options
Reply | Threaded
Open this post in threaded view
|

images sequence at multiple positions

Cordelia Berz
Hi, 

we already use Micro-Manager to control our microscope. We'd like to move
the stage to multiple positions and to acquire an image at each position.
The camera is being triggered externally, but we'd like to only keep the
image it takes at specific positions. We've tried to run the script below. 

Although the stage moved (we checked this using
print(mmc.getXPosition(xy))), the program seemed to snap all images at the
beginning, before moving the stage. This would result in 4 identical images
taken at the same position. 

What's the reason for that? How to make sure that we only pull a single
frame from each position? 

Thank you, 

Cordelia​

script: 

//program moves stage to different XY positions, snaps an image at each
position,
//saves the entire stack at the end

//imports you need for creating grid of positions
import org.micromanager.MultiStagePosition;
import org.micromanager.PositionList;
import org.micromanager.StagePosition;

//imports you need for acquisition
import org.micromanager.data.Coords;
import org.micromanager.data.Image;
import org.micromanager.data.Datastore;
import org.micromanager.display.DisplayWindow;
import mmcorej.TaggedImage;

//define grid
nrGridPoints = 2; //# of grid points
distance = 100; //distance between individual grid points

PositionList pl = new PositionList();
xy = mmc.getXYStageDevice();
xPos = mmc.getXPosition(xy); //get current X-Position
yPos = mmc.getYPosition(xy);

//create grid of positions
for (int i =0; i < nrGridPoints; i++) {
for (int j=0; j < nrGridPoints; j++) {
MultiStagePosition msp = new MultiStagePosition();
StagePosition s = new StagePosition();
s.stageName = xy;
s.numAxes = 2;
s.x = xPos + i * distance;
s.y = yPos + j * distance;
msp.add(s);
msp.setLabel("Pos-" + i + "-" + j);
pl.addPosition(msp);
}
}

mm.positions().setPositionList(pl);
pl = mm.getPositionList();
n = pl.getNumberOfPositions();

camera = mmc.getCameraDevice();


// Create a Datastore for the images to be stored in, in RAM.
Datastore store = mm.data().createRAMDatastore();
// Create a display to show images as they are acquired.
DisplayWindow display = mm.displays().createDisplay(store);

builder = mm.data().getCoordsBuilder().z(0).channel(0).stagePosition(0);
int curFrame = 0;

for (i=0; i < n; i++) {

mp = pl.getPosition(i); //gets the ith position
mp.goToPosition(mp, mmc);
mmc.waitForDevice(xy);

mm.getCore().snapImage();
TaggedImage tagged = mm.getCore().getTaggedImage();
image = mm.data().convertTaggedImage(tagged,
builder.time(curFrame).build(),null);
store.putImage(image);

curFrame++;
mmc.waitForDevice(camera);

}

mm.displays().manage(store);

String savePath = "C:\\Users\\berz\\Desktop\\micromanager_data";
store.save(Datastore.SaveMode.MULTIPAGE_TIFF,savePath);



--
Sent from: http://micro-manager.3463995.n2.nabble.com/

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
micro-manager-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/micro-manager-general
Reply | Threaded
Open this post in threaded view
|

Re: images sequence at multiple positions

Vincent Maioli

Hello,

At first guess (and from what was happening with a stage I played with), it could be that mp.goToPosition(mp, mmc) is non-blocking, that is, the stage would answer True to mmc.waitForDevice(xy) even before finishing its move. When you say you checked the stage moved did you put the "print" just after the  mmc.waitForDevice(xy)?

If this is the problem there are a couple of ways to get around it, a simple one would be to run a loop checking the stage position until it is sufficiently close to where you want to get the image, another more hardware-based would be to check if your stage has a position-based trigger or move-based one that could send a trigger to the camera when the stage has finished moving (and put the camera in external trigger, i.e. acquisition start controlled by the trigger and not micro-manager)

Best regards,

--
Vincent

On 20/06/2018 12:11, Cordelia Berz wrote:
Hi, 

we already use Micro-Manager to control our microscope. We'd like to move
the stage to multiple positions and to acquire an image at each position.
The camera is being triggered externally, but we'd like to only keep the
image it takes at specific positions. We've tried to run the script below. 

Although the stage moved (we checked this using
print(mmc.getXPosition(xy))), the program seemed to snap all images at the
beginning, before moving the stage. This would result in 4 identical images
taken at the same position. 

What's the reason for that? How to make sure that we only pull a single
frame from each position? 

Thank you, 

Cordelia​

script: 

//program moves stage to different XY positions, snaps an image at each
position,
//saves the entire stack at the end

//imports you need for creating grid of positions
import org.micromanager.MultiStagePosition;
import org.micromanager.PositionList;
import org.micromanager.StagePosition;

//imports you need for acquisition
import org.micromanager.data.Coords;
import org.micromanager.data.Image;
import org.micromanager.data.Datastore;
import org.micromanager.display.DisplayWindow;
import mmcorej.TaggedImage;

//define grid
nrGridPoints = 2; //# of grid points
distance = 100; //distance between individual grid points

PositionList pl = new PositionList();
xy = mmc.getXYStageDevice();
xPos = mmc.getXPosition(xy); //get current X-Position
yPos = mmc.getYPosition(xy);

//create grid of positions
for (int i =0; i < nrGridPoints; i++) {
for (int j=0; j < nrGridPoints; j++) {
MultiStagePosition msp = new MultiStagePosition();
StagePosition s = new StagePosition();
s.stageName = xy;
s.numAxes = 2;
s.x = xPos + i * distance;
s.y = yPos + j * distance;
msp.add(s);
msp.setLabel("Pos-" + i + "-" + j);
pl.addPosition(msp);
}
}

mm.positions().setPositionList(pl);
pl = mm.getPositionList();
n = pl.getNumberOfPositions();

camera = mmc.getCameraDevice();


// Create a Datastore for the images to be stored in, in RAM.
Datastore store = mm.data().createRAMDatastore();
// Create a display to show images as they are acquired.
DisplayWindow display = mm.displays().createDisplay(store);

builder = mm.data().getCoordsBuilder().z(0).channel(0).stagePosition(0);
int curFrame = 0;

for (i=0; i < n; i++) {

mp = pl.getPosition(i); //gets the ith position
mp.goToPosition(mp, mmc);
mmc.waitForDevice(xy);

mm.getCore().snapImage();
TaggedImage tagged = mm.getCore().getTaggedImage();
image = mm.data().convertTaggedImage(tagged,
builder.time(curFrame).build(),null);
store.putImage(image);

curFrame++;
mmc.waitForDevice(camera);

}

mm.displays().manage(store);

String savePath = "C:\\Users\\berz\\Desktop\\micromanager_data";
store.save(Datastore.SaveMode.MULTIPAGE_TIFF,savePath);



--
Sent from: http://micro-manager.3463995.n2.nabble.com/

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
micro-manager-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/micro-manager-general


------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
micro-manager-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/micro-manager-general
Reply | Threaded
Open this post in threaded view
|

Re: images sequence at multiple positions

Cordelia Berz
Hello Vincent, 

thank you very much for you reply and your suggestions!

Exactly, we put the print statement right after the mmc.waitForDevice(xy).
The device position updated. 

On https://micro-manager.org/wiki/Micro-Manager_Programming_Guide in the
section "Synchronization" I've found the following piece of code: 

// wait until Z stage stops moving
core.waitForDevice("Z");
core.snapImage();

// move to new XY position
core.SetPosition("X", 1230);
core.setPosition("Y", 330);

I've therefore assumed that the same would apply to mp.goToPosition(mp, mmc)
i.e. that it is blocking. I will check this and keep you updated. 

Best wishes, 
Cordelia 



--
Sent from: http://micro-manager.3463995.n2.nabble.com/

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
micro-manager-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/micro-manager-general
Reply | Threaded
Open this post in threaded view
|

Re: images sequence at multiple positions

JonD
Administrator
I believe goToPosition() is blocking.  At least it was in version 1.4.

Is it possible that your stage doesn't correctly report its busy status?
waitForDevice() polls the device adapter's Busy() method until it returns
false (or until the core's timeout value is exceeded).  If the stage doesn't
have a way of reporting whether it's moving or not then maybe the device
adapter just returns false every time.  You can check the device adapter's
code to find out.

-------------------------------------------
Jon Daniels
Applied Scientific Instrumentation
29391 West Enid Rd, Eugene, OR 97402
Phone: (541) 461-8181 x118
-------------------------------------------



--
Sent from: http://micro-manager.3463995.n2.nabble.com/

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
micro-manager-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/micro-manager-general
Reply | Threaded
Open this post in threaded view
|

Re: images sequence at multiple positions

julou
In reply to this post by Cordelia Berz
Hi Cordelia,

Maybe this comment is not relevant, but I was wondering why you dont want to
use the multidimensional acquisition engine of micro-manager. I already
comes with position control builtin (and you can easily create a grid from
the position window). Also you can add custom actions using "runnables"…

but maybe you're heading for an application where you need full control over
the acquisition process…
Best,

Thomas



-----
Thomas Julou  |  Computational & Systems Biology  |  Biozentrum – University of Basel  |  Klingelbergstrasse 50/70 CH-4056 Basel  |  +41 (0)61 267 16 21

--
Sent from: http://micro-manager.3463995.n2.nabble.com/

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
micro-manager-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/micro-manager-general
Thomas Julou  |  Computational & Systems Biology  |  Biozentrum – University of Basel  |  Klingelbergstrasse 50/70 CH-4056 Basel  |  +41 (0)61 267 16 21
Reply | Threaded
Open this post in threaded view
|

Re: images sequence at multiple positions

Cordelia Berz
Hi Jon and Thomas, 

thank you very much for your replies!

I've checked the device adapter's code and you're absolutely right. Busy()
is set to false in the beginning of the program and doesn't get updated
afterwards. 

I can try checking whether the stage is within a certain distance of the
target instead, or just use sleep() to give the stage time to move. 

I am aware that there is a position list that can be defined within the
MultiD Acquisition, but I'd like to be able to customize the acquisition a
bit more. Do you know which functions are used for going through a position
list within MultiD Acq? In particular how does the program ensure that the
stage stopped moving before acquiring the next image? 

Thank you, 

Cordelia





--
Sent from: http://micro-manager.3463995.n2.nabble.com/

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
micro-manager-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/micro-manager-general
Reply | Threaded
Open this post in threaded view
|

Re: images sequence at multiple positions

JonD
Administrator
Hi Cordelia,

The best thing to do would be to update the device adapter.  Second-best you
could add a delay to your script.

You can estimate the time to move knowing the distance and speed plus a bit
of extra time for acceleration and deceleration (consider treating X/Y axes
separately).  The DemoCamera device adapter's implementation of Busy() uses
a simplified version of this so it returns true for a while after initiating
the move and false again afterwards.  As you suggested, another way would be
to poll the stage position and see if it's "close enough" to the target.
Both these techniques could be used in either the device adapter (seems
better) or your script (probably easier since you don't have to build the
device adapter code).  As a fallback, you could add a fixed delay to your
script which is longer than the pre-determined longest-possible move time.

IIRC the MultiDAcq code uses goToPosition()... you could dig through the
code to verify.  goToPosition() should have built-in waitForDevice() calls
to the moved devices so that it blocks until everything has finished moving.
In other words, Micro-Manager relies on the device's Busy() method to
determine whether the stage has stopped moving, and this functionality seems
not to be implemented for your stage :(

Jon



--
Sent from: http://micro-manager.3463995.n2.nabble.com/

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
micro-manager-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/micro-manager-general
Reply | Threaded
Open this post in threaded view
|

Re: images sequence at multiple positions

julou
In reply to this post by Cordelia Berz
Cordelia Berz wrote
> Do you know which functions are used for going through a position
> list within MultiD Acq? In particular how does the program ensure that the
> stage stopped moving before acquiring the next image? 

Not directly answering but the simple way to achieve that using the MDA
engine would be to add a delay to your stage device directly in the config
(last step of the config wizard if I remember well).

alternatively, you could attach a runnable to each position where you would
set a delay e.g. with sleep()



-----
Thomas Julou  |  Computational & Systems Biology  |  Biozentrum – University of Basel  |  Klingelbergstrasse 50/70 CH-4056 Basel  |  +41 (0)61 267 16 21

--
Sent from: http://micro-manager.3463995.n2.nabble.com/

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
micro-manager-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/micro-manager-general
Thomas Julou  |  Computational & Systems Biology  |  Biozentrum – University of Basel  |  Klingelbergstrasse 50/70 CH-4056 Basel  |  +41 (0)61 267 16 21
Reply | Threaded
Open this post in threaded view
|

Re: images sequence at multiple positions

Cordelia Berz
Hi Jon and Thomas,

Thank you again for your replies!

I’d like to add that our camera is triggered externally as we think this
might actually be another reason (besides that busy() doesn’t work for our
stage) why the camera seems to acquire all images at the beginning. We’ve
run a couple of tests.

1) We tried to use the MultD Acq to acquire 4 images on a grid. Although the
stage did move, 4 identical images were displayed. Is MultiD Acq supposed to
work if the camera is triggered externally?

2) We tested a script in which an image is snapped at one position, the
stage is moved, the program waits before another image is snapped. (The code
is attached below and is based on a script available on the MicroManager
website (https://micro-manager.org/wiki/Version_2.0_API_How_do_I) . The
result remained the same: identical images.

3) Finally, we run a script where we start a new acquisition every time the
stage is moved (mmc.startSequenceAcquisition and
mmc.stopSequenceAcquisition). For this script we received different images.
(Script attached below) So we achieved the desired result.

We’re thus wondering why the 3rd script worked whereas the 1st and the 2nd
one didn’t. The problem seems to be that images do not get reloaded. This
suggested to us that the problem might be connected to the camera being
triggered externally (i.e. the camera receives triggers at constant time
intervals throughout the acquisition (see also sketch)). We therefore think
that the camera acquires all images at the beginning and thus essentially
provides us with an old image after the stage moved.
How can we ensure that we pull a single image at a specific time point (but
keeping external triggering)?
As the 3rd script seemed to function, is there something that gets updated
between acquisitions that doesn’t get updated during acquisition? (We tried
to clear the circular buffer in the past without any effect though.)

Thanks a lot,

Cordelia

<http://micro-manager.3463995.n2.nabble.com/file/t397179/sketch.jpg>
script2.bsh
<http://micro-manager.3463995.n2.nabble.com/file/t397179/script2.bsh>  
script3.bsh
<http://micro-manager.3463995.n2.nabble.com/file/t397179/script3.bsh>  



--
Sent from: http://micro-manager.3463995.n2.nabble.com/

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
micro-manager-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/micro-manager-general