Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
software:micro-manager [2019/09/20 17:18]
Jon Daniels [Scripting the 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 [[:docs:mm_dispim_plugin_user_guide|Micro-manager diSPIM Plugin User Guide]].  **Please see that manual for information about using the plugin.**  There is also a brief overview is on [[https://micro-manager.org/wiki/ASIdiSPIM_Plugin|its Micro-manager wiki page]]. Details about the plugin operation can be found in the manual section of this website in the [[:docs:mm_dispim_plugin_user_guide|Micro-manager diSPIM Plugin User Guide]].  **Please see that manual for information about using the plugin.**  There is also a brief overview is on [[https://micro-manager.org/wiki/ASIdiSPIM_Plugin|its Micro-manager wiki page]].
  
-Currently the diSPIM plugin is supported in 1.4.x only, although there have been some efforts to port it to 2.0.  At some point after the official release of Micro-manager 2.0development on the 1.4.x plugin will slow and eventually stop and at that point only 2.0 will be supported.  But that's all in the future as of early 2019 since 2.0 hasn't been released yet.+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 2.0 called [[https://github.com/micro-manager/LightSheetManager|LightSheetManager]] that will operate the diSPIM as well as other types of light sheet microscopes.  Contributions to the effort of making this new plugin are appreciated As of August 2023 this is in alpha testing by the first few bleeding edge adopters, and we expect that by end of 2023 it will be ready for more adopters and a full replacement in 2024.
  
-You can download the nightly builds of Micro-manager 1.4 for Windows [[http://valelab4.ucsf.edu/~MM/nightlyBuilds/1.4/Windows/|here]]; the date is encoded in the file name and the latest date is at the top of the page.  Make sure to get the appropriate 32bit or 64bit depending on your computer.+You can download the nightly builds of Micro-manager 1.4 for Windows [[https://download.micro-manager.org/nightly/1.4/Windows/|here]]; the date is encoded in the file name and the latest date is at the top of the page.  Make sure to get the appropriate 32bit or 64bit depending on your computer.
  
  
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://valelab.ucsf.edu/~MM/nightlyBuilds/1.4/Windows/|Windows]] and [[http://valelab.ucsf.edu/~MM/nightlyBuilds/1.4/Mac/|Mac]]). If your firmware is very old it wouldn't hurt to update it; instructions and firmware files are on this wiki filed under [[:hardware:controller#firmware | hardware > controller > firmware]]. 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://valelab.ucsf.edu/~MM/nightlyBuilds/1.4/Windows/|Windows]] and [[http://valelab.ucsf.edu/~MM/nightlyBuilds/1.4/Mac/|Mac]]). If your firmware is very old it wouldn't hurt to update it; instructions and firmware files are on this wiki filed under [[:hardware:controller#firmware | hardware > controller > firmware]].
  
-If the bug still happens, is helpful to generate a problem report using "Help" -> "Report Problem..." in the main Micro-Manager window. It will prompt you to reproduce the problem, for example if you are having a problem during diSPIM acquisition then run an acquisition and verify that the bug is manifest.  After clicking "Done" do not submit the report the usual way, instead click "View Report", save the text as a file, and then email that file directly to the plugin developers.  If you cannot reproduce the problem in order to generate a bug report, then an alternative is to enable debug logging in "Tools" -> "Options..." and then when the problem happens send the developers the core log file being written to at the time (find the logs in the Core Logs directory located inside the Micro-manager install directory, e.g. C:/Program Files/Micro-Manager-1.4/Core Logs and then log files named by the launch time).+If the bug still happens, is helpful to generate a problem report using "Help" -> "Report Problem..." in the main Micro-Manager window. It will prompt you to reproduce the problem, for example if you are having a problem during diSPIM acquisition then run an acquisition and verify that the bug is manifest.  After clicking "Done" do not submit the report the usual way, instead click "View Report", save the text as a file, and then email that file directly to the plugin developers. 
 + 
 +If you cannot reproduce the problem in order to generate a bug report, then an alternative is to enable debug logging in "Tools" -> "Options..." and then when the problem happens send the developers the core log file being written to at the time (find the logs in the Core Logs directory located inside the Micro-manager install directory, e.g. C:/Program Files/Micro-Manager-1.4/Core Logs and then log files named by the launch time), also noting the time that the error occurred.  Because the problem report file contains extra information, if it is possible to replicate the error on demand then it is better to use the problem report method.
  
 You can see recent changes to the plugin code by [[https://valelab.ucsf.edu/trac/micromanager/search?q=asidispim | searching the Micro-manager code timeline for ASIdiSPIM]].  Sometimes changes to the ASI Tiger device adapter also affect the plugin operation ([[https://valelab.ucsf.edu/trac/micromanager/search?q=asitiger | Micro-manager code timeline for ASITiger]]). You can see recent changes to the plugin code by [[https://valelab.ucsf.edu/trac/micromanager/search?q=asidispim | searching the Micro-manager code timeline for ASIdiSPIM]].  Sometimes changes to the ASI Tiger device adapter also affect the plugin operation ([[https://valelab.ucsf.edu/trac/micromanager/search?q=asitiger | Micro-manager code timeline for ASITiger]]).
Line 87: Line 89:
 ==== 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.  This allows users to orchestrate complex acquisitions and even use the plugin for adaptive microscopy where automated image analysis guides acquisition.  The best way to see what functionality is exposed via the API is to look at the [[https://valelab4.ucsf.edu/trac/micromanager/browser/plugins/ASIdiSPIM/src/org/micromanager/asidispim/api/ASIdiSPIMInterface.java|source code of the Java interface]] which defines the API.  The API includes are methods to get and set the most commonly changed settings within the plugin, launch acquisitions, move the microscope, and more.  The API can be augmented if needed but every effort is made not to change the documented functionality.  Furthermore there is support for Java RMI which allows the plugin API to be access from a completely separate Java VM.+The Micro-Manager plugin has an API that allows most of its functionality to be accessed via Beanshell scripts run from within Micro-Manager.  This allows users to orchestrate complex acquisitions and even use the plugin for adaptive microscopy where automated image analysis guides acquisition.  The best way to see what functionality is exposed via the API is to look at the [[https://github.com/micro-manager/micro-manager/blob/mm1/plugins/ASIdiSPIM/src/org/micromanager/asidispim/api/ASIdiSPIMInterface.java|source code of the Java interface]] which defines the API.  The API includes are methods to get and set the most commonly changed settings within the plugin, launch acquisitions, move the microscope, and more.  The API can be augmented if needed but every effort is made not to change the documented functionality.  Furthermore there is support for Java RMI which allows the plugin API to be access from a completely separate Java VM.
  
 Here is a bare-bones example script: Here is a bare-bones example script:
Line 341: Line 343:
 ==== Runnables in the plugin ==== ==== Runnables in the plugin ====
  
-As of July 2019 limited support for "runnables" has been added to the plugin.  A runnable is a snippet of user-specified code that is executed at a pre-defined moment.  Currently there are four times when runnables can be inserted:+Support for "runnables" was added to the plugin early July 2019 and extended November 2019.  A runnable is a snippet of user-specified code that is executed at a pre-defined sequence during the overall acquisition.  Runnables generally should not be used when exact timing matters because their exact execution time will be controlled by Micro-Manager and subject to the whims of the host computer and not done with exactly predictable timing (if you need exact timing, you can use the Tiger controller's flexible Programmable Logic Card (PLC) to implement). 
 + 
 +These runnables are normally defined in a Beanshell script executed from Micro-Manager's script window and "attached" to the plugin after the plugin has been invoked.  See the below example. 
 + 
 +Currently there are six times when runnables can be inserted: 
 +  - Start of acquisition 
 +  - End of acquisition
   - Start of timepoint   - Start of timepoint
   - End of timepoint   - End of timepoint
Line 347: Line 355:
   - End of position   - End of position
  
-Note that these would be called only once each for an acquisition without timepoints nor positions selected.  Recall that timepoints is always the "outer loop" relative to positions using the plugin (but to interchange the order you can write a script that uses positions as the outer loop).+Note that these would be called only once each for an acquisition without timepoints nor positions selected.  Recall that timepoints is always the "outer loop" relative to positions using the plugin (but to interchange the order you can write a script that uses positions as the outer loop).  The start/end acquisition runnables are only executed once even when the "separate viewer / file" option is enabled in the data saving settings.
  
-Here is an example adding a runnable to each of these possible invocation points:+Here is an example adding a runnable to each of these possible invocation points.  Note the use of global variables in the script so that state can be passed between runnables, as well as local variables within a runnable that cannot be changed by another runnable (e.g. reset at the start of the acquisition).
  
 <code java> <code java>
Line 360: Line 368:
 // note that the plugin must be launched for this to work // note that the plugin must be launched for this to work
 ASIdiSPIMInterface diSPIM = new ASIdiSPIMImplementation(); 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("started overall acquisition");
 + runnableTimepointCounter = 0;
 + runnablePositionCounter = 0;
 + }
 +};
 +
 +taskEndAcquisition = new Runnable() {
 + public void run() {
 + // test code which will raise dialog; should be replaced
 + gui.showError("ended entire acquisition");
 + }
 +};
 +
  
 taskStartPosition = new Runnable() { taskStartPosition = new Runnable() {
- int i = 0; 
  public void run() {  public void run() {
 + runnablePositionCounter++;
  // test code which will raise dialog; should be replaced  // test code which will raise dialog; should be replaced
- gui.showError("started position " + i)+ gui.showError("started position " + runnablePositionCounter);
- i++;+
  }  }
 }; };
  
 taskEndPosition = new Runnable() { taskEndPosition = new Runnable() {
 + int localCounter = 0;
  public void run() {  public void run() {
 + localCounter++;
  // test code which will raise dialog; should be replaced  // test code which will raise dialog; should be replaced
- gui.showError("ended position");+ gui.showError("ended position, which is call number " + localCounter + " to this runnable");
  }  }
 }; };
  
 taskStartTimepoint = new Runnable() { taskStartTimepoint = new Runnable() {
- int i = 0; 
  public void run() {  public void run() {
 + runnablePositionCounter = 0;
 + runnableTimepointCounter++;
  // test code which will raise dialog; should be replaced  // test code which will raise dialog; should be replaced
- gui.showError("started timepoint " + i)+ gui.showError("started timepoint " + runnableTimepointCounter );
- i++;+
  }  }
 }; };
  
 taskEndTimepoint = new Runnable() { taskEndTimepoint = new Runnable() {
 + int localCounter = 0;
  public void run() {  public void run() {
 + localCounter++;
  // test code which will raise dialog; should be replaced  // test code which will raise dialog; should be replaced
- gui.showError("ended timepoint");+ gui.showError("ended timepoint, which is call number " + localCounter + " to this runnable");
  }  }
 }; };
Line 395: Line 425:
 // add all run // add all run
 diSPIM.clearAllRunnables(); diSPIM.clearAllRunnables();
 +diSPIM.attachRunnable(taskStartAcquisition, RunnableType.ACQUISITION_START);
 +diSPIM.attachRunnable(taskEndAcquisition, RunnableType.ACQUISITION_END);
 diSPIM.attachRunnable(taskStartPosition, RunnableType.POSITION_START); diSPIM.attachRunnable(taskStartPosition, RunnableType.POSITION_START);
 diSPIM.attachRunnable(taskEndPosition, RunnableType.POSITION_END); diSPIM.attachRunnable(taskEndPosition, RunnableType.POSITION_END);
Line 400: Line 432:
 diSPIM.attachRunnable(taskEndTimepoint, RunnableType.TIMEPOINT_END); diSPIM.attachRunnable(taskEndTimepoint, RunnableType.TIMEPOINT_END);
  
-diSPIM.runAcquisition();+</code> 
 + 
 + 
 +Here is another example that runs autofocus periodically, in this case every 13 positions. 
 + 
 +<code> 
 + 
 +// 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() { 
 + //gui.showError("started position " + runnablePositionCounter); 
 + if ((runnablePositionCounter % counterPeriod)<1) { 
 + mmc.fullFocus();   // this is supposed to be a blocking call in the device adapter (should wait until focus is achieved) 
 +
 + runnablePositionCounter++; 
 +
 +}; 
 + 
 +  
 +// add the runnables to the diSPIM plugin's acquisition engine 
 +diSPIM.clearAllRunnables(); 
 +diSPIM.attachRunnable(taskStartAcquisition, RunnableType.ACQUISITION_START); 
 +diSPIM.attachRunnable(taskStartPosition, RunnableType.POSITION_START);