[Micro-manager] MDA doesn't use updated PositionList during acquisition

Hello,

While running my MDA, I’m changing the 1DPosition of the positions using a script (cf below). The positions are properly updated in the PositionList GUI, but the MDA doesn’t take the modifications into account and snaps at the original PositionList positions. Is there something particular to do so the MDA always look at the new PositionList? Is this the role of changeListener. If so, how to use it?

My script:

posList = mm.positions().getPositionList();
list = posList.getPositions();
	
//Apply the z-offset to the positions of the list
for (msp : list) {
	sp = msp.get(zStageFocus);
	sp.set1DPosition(zStageFocus, sp.get1DPosition()  -15);
};
posList.setPositions(list);
mm.positions().setPositionList(posList);

Thank you!

Sounds like a bug. I’ll look into it soon.

1 Like

I just tested this with the Demo configuration, and it works as expected. After running the script, I see the positions in the list updated. When I then run the MDA, I see the z position in the metadata as expected (i.e. at -15 after running the script once, -30 after running it twice).

Are you using a recent nightly build? There have been some modifications to the code structuring the info for the MDA about a month ago or so.

Thank you @nicost for your answer.
Yes I’m using the very last build.

However, my problem occurs DURING the MDA, ie while the MDA is running.
Steps:

  1. I launch the MDA (let’s say 3 positions - 2 timepoints spaced by 10 seconds) with Z=0 for all my positions.
  2. After the first timepoint and before the second, I change de Z of the positions using the script (while the MDA is still running), to Z=15.
  3. The Z is updated in the position list GUI (I see Z=15 for all my pos)
  4. The MDA keeps going to Z=0 for the timepoint_2

However, editing the position manually (instead of with the script) during the MDA seems to work and be taken into account, so maybe the problems is my script.
Besides, I tried with the demo configuration, and the problem remains (in the meta file, the Z remains =0 for all timepoints), so it doesn’t come from my config.

Thanks

1 Like

Ah, that makes sense! When the MDA starts, it takes the then current position list, and works with that. In the script, we are setting a new position list, however the MDA is not aware that there is a new list.

This api design is defensive, i.e. it makes the position list immutable, so that no bad things can happen ( for instance by multiple threads changing it simultaneously). Nevertheless, your use case is a very good one and we may need to go beyond the api and into the internals (like the PositionLIstDialog does) to make this happen. I’ll look at it soon.

1 Like

Ok, but then how come that when I edit a position manually during the MDA (using the Replace button), the modification is taken into account for the subsequent timepoints?
This means there must be a way to bypass the restriction using PositionListDlg from the script, no?

Thank you!

This turned out to be a difficult problem! The API design basically does not allow for what you need to do. The reasons are good, but there clearly should be a way to make this happen. I explained the background here: API does not allow updating positions in the current positionList · Issue #1090 · micro-manager/micro-manager · GitHub.

For the time being, I created a “backdoor” to let you get the current PositionList rather than a copy. This is the one the Acquisition Engine is using, so changes in it should result in changes in the actual positions (I did not test, but it should do the same thing as changes made in the PositionListDlg). The script with that in place looks like:

zStageFocus = "Z";
posList = mm.uiManager().getPositionList();
list = posList.getPositions();
	
//Apply the z-offset to the positions of the list
for (msp : list) {
	sp = msp.get(zStageFocus);
	sp.set1DPosition(zStageFocus, sp.get1DPosition()  -15);
};
posList.setPositions(list);
// only here to keep the display up to date
mm.positions().setPositionList(posList);

You will need the latest nightly build to make this work. I just started a build (20210128), which should b ready around 10.30 am PST.

1 Like

Fantastic, thanks @nicost !
Will try this out as soon as the nightly build is released and keep you posted.

From your github issue:

Clearly, giving direct access to the PositionList is not desirable, but it will also be difficult to convince (and likely undesirable) to convince the acquisition engine that there is a new position list (for instance, what should it do when the names of the positions, or the number of positions changes?). One solution may be to have the API provide a mostly immutable version of the current PositionList, that does allow to change the actual stage positions, but nothing else.

I think this is the best option. The number of positions and their name must remain the same to avoid naming conflicts and unexpected outcomes.
The StagePositions is the only parameter one might need to edit during the MDA.

Sorry, build ran into some issues but is ready now.
And yes, I agree, (with the addition that 2D StagePositions should also be changeable). It will need a bit of thinking and organizing to do that cleanly.

1 Like

No problem @nicost.
I just tested your workaround and it is now working as intended! Awesome :slight_smile: :slight_smile: :slight_smile:

Thanks a lot.

1 Like