Differences
This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
software:micro-manager [2019/03/07 01:19] Jon Daniels [Micro-manager diSPIM Plugin] |
software:micro-manager [2024/05/21 23:52] (current) Jon Daniels [Runnables in the plugin] |
||
---|---|---|---|
Line 5: | Line 5: | ||
Details about the plugin operation can be found in the manual section of this website in the [[: | Details about the plugin operation can be found in the manual section of this website in the [[: | ||
- | Currently the diSPIM plugin is supported in 1.4.x only, although | + | Currently the diSPIM plugin is supported in 1.4.x only. In 2023 there have been efforts to create a new plugin in Micro-Manager |
- | You can download the nightly builds of Micro-manager 1.4 for Windows [[http://valelab4.ucsf.edu/~MM/ | + | You can download the nightly builds of Micro-manager 1.4 for Windows [[https://download.micro-manager.org/nightly/ |
Line 66: | Line 66: | ||
The first step is to check and see if your problem has already been fixed by using a recent nightly build of Micro-Manager ([[http:// | The first step is to check and see if your problem has already been fixed by using a recent nightly build of Micro-Manager ([[http:// | ||
- | If the bug still happens, is helpful to generate a problem report using " | + | If the bug still happens, is helpful to generate a problem report using " |
+ | |||
+ | If you cannot reproduce the problem in order to generate a bug report, then an alternative is to enable debug logging in " | ||
You can see recent changes to the plugin code by [[https:// | You can see recent changes to the plugin code by [[https:// | ||
Line 72: | Line 74: | ||
==== Launching the plugin on startup ==== | ==== Launching the plugin on startup ==== | ||
- | Add the following lines to your MMStartup.bsh script (or create the file if it doesn' | + | Add the following lines to your MMStartup.bsh script (or create the file if it doesn' |
- | < | + | < |
import org.micromanager.asidispim.ASIdiSPIM; | import org.micromanager.asidispim.ASIdiSPIM; | ||
- | ASIdiSPIM plugin = new ASIdiSPIM(); | + | import org.micromanager.asidispim.Utils.MyDialogUtils; |
- | plugin.setApp(gui); | + | |
+ | // the if statement and closing brace can be removed if you want the plugin to always load regardless | ||
+ | if (MyDialogUtils.getConfirmDialogResult(" | ||
+ | | ||
+ | plugin.setApp(gui); | ||
+ | } | ||
</ | </ | ||
==== Scripting the plugin ==== | ==== Scripting the plugin ==== | ||
- | The Micro-Manager plugin has an API that allows most of its functionality to be accessed via Beanshell scripts run from within Micro-Manager. | + | The Micro-Manager plugin has an API that allows most of its functionality to be accessed via Beanshell scripts run from within Micro-Manager. |
Here is a bare-bones example script: | Here is a bare-bones example script: | ||
- | < | + | < |
// required imports | // required imports | ||
import org.micromanager.asidispim.api.ASIdiSPIMInterface; | import org.micromanager.asidispim.api.ASIdiSPIMInterface; | ||
Line 103: | Line 110: | ||
Here are some example scripts: | Here are some example scripts: | ||
- | < | + | < |
// This script changes channels in the middle of a multi-timepoint acquistion. | // This script changes channels in the middle of a multi-timepoint acquistion. | ||
Line 148: | Line 155: | ||
- | < | + | < |
// This script runs a multi-timepoint acquisition at multiple positions, collecting all time points at a single position | // This script runs a multi-timepoint acquisition at multiple positions, collecting all time points at a single position | ||
// before moving to the next position (reversing the time/ | // before moving to the next position (reversing the time/ | ||
Line 190: | Line 197: | ||
</ | </ | ||
+ | |||
+ | <code java> | ||
+ | // This script runs a " | ||
+ | // in a separate acquisition on disk. | ||
+ | |||
+ | // required imports | ||
+ | import org.micromanager.asidispim.api.*; | ||
+ | import org.micromanager.api.PositionList; | ||
+ | import org.micromanager.api.MultiStagePosition; | ||
+ | import org.micromanager.asidispim.utils.MyDialogUtils; | ||
+ | import java.text.DecimalFormat; | ||
+ | |||
+ | // get reference to plugin (requires plugin to be open) | ||
+ | ASIdiSPIMInterface diSPIM = new ASIdiSPIMImplementation(); | ||
+ | |||
+ | // get MM's position list (should have positions set there already before running script) | ||
+ | PositionList pl = gui.getPositionList(); | ||
+ | int numPositions = pl.getNumberOfPositions(); | ||
+ | |||
+ | // make sure plugin is set _not_ to use positions after caching old value | ||
+ | boolean multiXY = diSPIM.getMultiplePositionsEnabled(); | ||
+ | diSPIM.setMultiplePositionsEnabled(false); | ||
+ | |||
+ | // get value of post-move delay from plugin | ||
+ | double postMoveDelayMs = diSPIM.getMultiplePositionsDelay(); | ||
+ | |||
+ | // save original name prefix for file saving | ||
+ | String basePrefix = diSPIM.getSavingNamePrefix(); | ||
+ | |||
+ | // set up formatting with leading 0s | ||
+ | DecimalFormat df = new DecimalFormat(" | ||
+ | |||
+ | // setup for closing finished acquisition windows | ||
+ | // instead of leaving every window open want to close when done | ||
+ | // found that call to closeAcquisitionWindow() can come before writing is finished and cause problems | ||
+ | // so let there be 2 open windows but prevent opening more | ||
+ | String lastAcqName = ""; | ||
+ | String lastLastAcqName = ""; | ||
+ | |||
+ | |||
+ | // loop over all positions in position list | ||
+ | try { | ||
+ | for(int i=1; i< | ||
+ | MultiStagePosition.goToPosition(pl.getPosition(i-1), | ||
+ | Thread.sleep(Math.round(postMoveDelayMs)); | ||
+ | diSPIM.setSavingNamePrefix(basePrefix + " | ||
+ | try { | ||
+ | diSPIM.closeAcquisitionWindow(lastLastAcqName); | ||
+ | } catch (Exception ex) { | ||
+ | // do nothing | ||
+ | } | ||
+ | diSPIM.runAcquisitionBlocking() | ||
+ | lastLastAcqName = lastAcqName; | ||
+ | lastAcqName = diSPIM.getLastAcquisitionName(); | ||
+ | } | ||
+ | } catch (Exception ex) { | ||
+ | MyDialogUtils.showError(ex, | ||
+ | } finally { | ||
+ | // restore prefix and multi-XY value | ||
+ | diSPIM.setSavingNamePrefix(basePrefix); | ||
+ | diSPIM.setMultiplePositionsEnabled(multiXY); | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | |||
+ | <code java> | ||
+ | |||
+ | // This script runs a " | ||
+ | // to save each position in a separate file on disk. | ||
+ | // Positions are the "outer loop", channels are the "inner loop" | ||
+ | // Channels are not necessarily in the order specified in the plugin but should be the same order every time. | ||
+ | // User should put the plugin " | ||
+ | |||
+ | |||
+ | // required imports | ||
+ | import org.micromanager.asidispim.api.*; | ||
+ | import org.micromanager.api.PositionList; | ||
+ | import org.micromanager.api.MultiStagePosition; | ||
+ | import org.micromanager.asidispim.utils.MyDialogUtils; | ||
+ | import java.text.DecimalFormat; | ||
+ | |||
+ | // get reference to plugin (requires plugin to be open) | ||
+ | ASIdiSPIMInterface diSPIM = new ASIdiSPIMImplementation(); | ||
+ | |||
+ | // get MM's position list (should have positions set there already before running script) | ||
+ | PositionList pl = gui.getPositionList(); | ||
+ | int numPositions = pl.getNumberOfPositions(); | ||
+ | |||
+ | // make sure plugin is set _not_ to use positions after caching old value | ||
+ | boolean multiXY = diSPIM.getMultiplePositionsEnabled(); | ||
+ | diSPIM.setMultiplePositionsEnabled(false); | ||
+ | |||
+ | // get value of post-move delay from plugin | ||
+ | double postMoveDelayMs = diSPIM.getMultiplePositionsDelay(); | ||
+ | |||
+ | // save original name prefix for file saving | ||
+ | String basePrefix = diSPIM.getSavingNamePrefix(); | ||
+ | |||
+ | // set up formatting with leading 0s | ||
+ | DecimalFormat df = new DecimalFormat(" | ||
+ | |||
+ | // setup for closing finished acquisition windows | ||
+ | // instead of leaving every window open want to close when done | ||
+ | // found that call to closeAcquisitionWindow() can come before writing is finished and cause problems | ||
+ | // so let there be 2 open windows but prevent opening more | ||
+ | String lastAcqName = ""; | ||
+ | String lastLastAcqName = ""; | ||
+ | |||
+ | // figure out which channels we are using | ||
+ | boolean channelsEnabled = diSPIM.getChannelsEnabled(); | ||
+ | String [] allChannels = diSPIM.getAvailableChannels(); | ||
+ | |||
+ | try { | ||
+ | // loop over all positions in position list | ||
+ | for( int i=1; i< | ||
+ | MultiStagePosition.goToPosition(pl.getPosition(i-1), | ||
+ | Thread.sleep(Math.round(postMoveDelayMs)); | ||
+ | |||
+ | for( s : allChannels) { | ||
+ | if (!diSPIM.getChannelEnabled(s)) | ||
+ | continue; | ||
+ | diSPIM.setSavingNamePrefix(basePrefix + " | ||
+ | try { | ||
+ | diSPIM.closeAcquisitionWindow(lastLastAcqName); | ||
+ | } catch (Exception ex) { | ||
+ | // do nothing | ||
+ | } | ||
+ | diSPIM.runAcquisitionBlocking() | ||
+ | lastLastAcqName = lastAcqName; | ||
+ | lastAcqName = diSPIM.getLastAcquisitionName(); | ||
+ | } | ||
+ | } | ||
+ | } catch (Exception ex) { | ||
+ | MyDialogUtils.showError(ex, | ||
+ | } finally { | ||
+ | // restore prefix and multi-XY value | ||
+ | diSPIM.setSavingNamePrefix(basePrefix); | ||
+ | diSPIM.setMultiplePositionsEnabled(multiXY); | ||
+ | diSPIM.setChannelsEnabled(channelsEnabled); | ||
+ | } | ||
+ | |||
+ | </ | ||
+ | |||
+ | |||
+ | ==== Runnables in the plugin ==== | ||
+ | |||
+ | Support for " | ||
+ | |||
+ | These runnables are normally defined in a Beanshell script executed from Micro-Manager' | ||
+ | |||
+ | Currently there are six times when runnables can be inserted: | ||
+ | - Start of acquisition | ||
+ | - End of acquisition | ||
+ | - Start of timepoint | ||
+ | - End of timepoint | ||
+ | - Start of position | ||
+ | - End of position | ||
+ | |||
+ | Note that these would be called only once each for an acquisition without timepoints nor positions selected. | ||
+ | |||
+ | Here is an example adding a runnable to each of these possible invocation points. | ||
+ | |||
+ | <code java> | ||
+ | // required imports | ||
+ | import org.micromanager.asidispim.api.*; | ||
+ | |||
+ | // get a reference to the plugin; use this to call the plugin' | ||
+ | // API documented in ASIdiSPIMInterface.java in source code | ||
+ | // | ||
+ | // note that the plugin must be launched for this to work | ||
+ | ASIdiSPIMInterface diSPIM = new ASIdiSPIMImplementation(); | ||
+ | int runnableTimepointCounter; | ||
+ | int runnablePositionCounter; | ||
+ | |||
+ | taskStartAcquisition = new Runnable() { | ||
+ | public void run() { | ||
+ | // test code which will raise dialog; should be replaced | ||
+ | gui.showError(" | ||
+ | runnableTimepointCounter = 0; | ||
+ | runnablePositionCounter = 0; | ||
+ | } | ||
+ | }; | ||
+ | |||
+ | taskEndAcquisition = new Runnable() { | ||
+ | public void run() { | ||
+ | // test code which will raise dialog; should be replaced | ||
+ | gui.showError(" | ||
+ | } | ||
+ | }; | ||
+ | |||
+ | |||
+ | taskStartPosition = new Runnable() { | ||
+ | public void run() { | ||
+ | runnablePositionCounter++; | ||
+ | // test code which will raise dialog; should be replaced | ||
+ | gui.showError(" | ||
+ | } | ||
+ | }; | ||
+ | |||
+ | taskEndPosition = new Runnable() { | ||
+ | int localCounter = 0; | ||
+ | public void run() { | ||
+ | localCounter++; | ||
+ | // test code which will raise dialog; should be replaced | ||
+ | gui.showError(" | ||
+ | } | ||
+ | }; | ||
+ | |||
+ | taskStartTimepoint = new Runnable() { | ||
+ | public void run() { | ||
+ | runnablePositionCounter = 0; | ||
+ | runnableTimepointCounter++; | ||
+ | // test code which will raise dialog; should be replaced | ||
+ | gui.showError(" | ||
+ | } | ||
+ | }; | ||
+ | |||
+ | taskEndTimepoint = new Runnable() { | ||
+ | int localCounter = 0; | ||
+ | public void run() { | ||
+ | localCounter++; | ||
+ | // test code which will raise dialog; should be replaced | ||
+ | gui.showError(" | ||
+ | } | ||
+ | }; | ||
+ | |||
+ | // add all run | ||
+ | diSPIM.clearAllRunnables(); | ||
+ | diSPIM.attachRunnable(taskStartAcquisition, | ||
+ | diSPIM.attachRunnable(taskEndAcquisition, | ||
+ | diSPIM.attachRunnable(taskStartPosition, | ||
+ | diSPIM.attachRunnable(taskEndPosition, | ||
+ | diSPIM.attachRunnable(taskStartTimepoint, | ||
+ | diSPIM.attachRunnable(taskEndTimepoint, | ||
+ | |||
+ | </ | ||
+ | |||
+ | |||
+ | Here is another example that runs autofocus periodically, | ||
+ | |||
+ | < | ||
+ | |||
+ | // runs autofocus once on the first position and periodically afterwards based on period set in script (currently every 13th position) | ||
+ | // script assumes that CRISP is already set up and is the default focus device | ||
+ | // run this script after launching the plugin and before beginning the acquisition | ||
+ | |||
+ | // required imports | ||
+ | import org.micromanager.asidispim.api.*; | ||
+ | |||
+ | // get a reference to the plugin; use this to call the plugins API methods | ||
+ | ASIdiSPIMInterface diSPIM = new ASIdiSPIMImplementation(); | ||
+ | |||
+ | // local variables | ||
+ | int runnablePositionCounter; | ||
+ | int counterPeriod = 13; | ||
+ | |||
+ | // initialize the counter when the acquisition begins | ||
+ | taskStartAcquisition = new Runnable() { | ||
+ | public void run() { | ||
+ | runnablePositionCounter = 0; | ||
+ | } | ||
+ | }; | ||
+ | |||
+ | // at each position see if it's time to run autofocus, plus also increment the counter | ||
+ | taskStartPosition = new Runnable() { | ||
+ | public void run() { | ||
+ | // | ||
+ | if ((runnablePositionCounter % counterPeriod)< | ||
+ | mmc.fullFocus(); | ||
+ | } | ||
+ | runnablePositionCounter++; | ||
+ | } | ||
+ | }; | ||
+ | |||
+ | |||
+ | // add the runnables to the diSPIM plugin' | ||
+ | diSPIM.clearAllRunnables(); | ||
+ | diSPIM.attachRunnable(taskStartAcquisition, | ||
+ | diSPIM.attachRunnable(taskStartPosition, | ||
+ | |||
+ | |||
+ | </ | ||
/* | /* |