View Javadoc
1   package com.github.celldynamics.quimp.plugin.generatemask;
2   
3   import java.nio.file.Path;
4   import java.nio.file.Paths;
5   import java.util.List;
6   
7   import javax.swing.JOptionPane;
8   
9   import com.github.celldynamics.quimp.BOAState;
10  import com.github.celldynamics.quimp.Nest;
11  import com.github.celldynamics.quimp.QParamsQconf;
12  import com.github.celldynamics.quimp.QuimP;
13  import com.github.celldynamics.quimp.QuimpException;
14  import com.github.celldynamics.quimp.QuimpException.MessageSinkTypes;
15  import com.github.celldynamics.quimp.Snake;
16  import com.github.celldynamics.quimp.SnakeHandler;
17  import com.github.celldynamics.quimp.filesystem.FileExtensions;
18  import com.github.celldynamics.quimp.plugin.AbstractPluginQconf;
19  import com.github.celldynamics.quimp.plugin.QuimpPluginException;
20  import com.github.celldynamics.quimp.utils.QuimpToolsCollection;
21  
22  import ij.IJ;
23  import ij.ImagePlus;
24  import ij.ImageStack;
25  import ij.gui.NewImage;
26  import ij.gui.Roi;
27  import ij.process.ImageConverter;
28  import ij.process.ImageProcessor;
29  import ij.process.StackConverter;
30  
31  /**
32   * Convert QCONF files to BW masks.
33   * 
34   * <p>Use Snake data produced by BOA and stored in QCONF file. If run from macro it shows image and
35   * save it to folder where QCONF resides. If run as API it does not do any of these two actions, use
36   * {@link #getRes()} to obtain image.
37   * 
38   * @author p.baniukiewicz
39   *
40   */
41  public class GenerateMask_ extends AbstractPluginQconf {
42  
43    private static String thisPluginName = "Generate mask";
44  
45    /**
46     * Resulting image. (Not saved or shown if apiCall==true)
47     */
48    private ImagePlus res;
49  
50    /**
51     * Executed if plugin is run from IJ. Set apiCall to false and redirect exception to IJ.
52     */
53    public GenerateMask_() {
54      super(new GenerateMaskOptions(), thisPluginName);
55    }
56  
57    /**
58     * Constructor that allows to provide own parameters.
59     * 
60     * @param paramString it can be null to ask user for file or it can be parameters string like that
61     *        passed in macro.
62     * @throws QuimpPluginException on any error
63     */
64    public GenerateMask_(String paramString) throws QuimpPluginException {
65      super(paramString, new GenerateMaskOptions(), thisPluginName); // will parse and fill options
66    }
67  
68    /*
69     * (non-Javadoc)
70     * 
71     * @see com.github.celldynamics.quimp.plugin.PluginTemplate#run(java.lang.String)
72     */
73    @Override
74    public void run(String arg) {
75      super.run(arg);
76    }
77  
78    /*
79     * (non-Javadoc)
80     * 
81     * @see com.github.celldynamics.quimp.plugin.IQuimpPlugin#about()
82     */
83    @Override
84    public String about() {
85      return "Generate mask plugin.\n" + "Author: Piotr Baniukiewicz\n"
86              + "mail: p.baniukiewicz@warwick.ac.uk";
87    }
88  
89    /*
90     * (non-Javadoc)
91     * 
92     * @see com.github.celldynamics.quimp.plugin.PluginTemplate#runFromQCONF()
93     */
94    @Override
95    protected void runFromQconf() throws QuimpException {
96      GenerateMaskOptions/../../com/github/celldynamics/quimp/plugin/generatemask/GenerateMaskOptions.html#GenerateMaskOptions">GenerateMaskOptions opts = (GenerateMaskOptions) options;
97      BOAState bs = qconfLoader.getBOA();
98      Nest nest = bs.nest;
99      int currentColor;
100     // create output image
101     res = NewImage.createShortImage("test", bs.boap.getWidth(), bs.boap.getHeight(),
102             bs.boap.getFrames(), NewImage.FILL_BLACK);
103     // get stacks reference
104     ImageStack contourStack = res.getStack();
105     res.setSlice(1); // set for first
106     int frame; // frames counter (from 1)
107     Snake snake;
108     ImageProcessor contourIp; // processor taken from stack (ref)
109     for (frame = 1; frame <= bs.boap.getFrames(); frame++) { // iterate over frames
110       List<Integer> snakes = nest.getSnakesforFrame(frame); // find all SnakeHandlers on frame
111       contourIp = contourStack.getProcessor(frame); // get processor from stack for frame
112       currentColor = 1;
113       for (Integer snakeID : snakes) { // iterate over SnakeHandlers
114         SnakeHandler snakeH = nest.getHandlerofId(snakeID); // get SH of snakeID
115         if (snakeH != null) {
116           snake = snakeH.getStoredSnake(frame); // get snake from this handler and current frame
117           Roi roi = snake.asFloatRoi(); // convert to ROI
118           contourIp.setColor(currentColor++);
119           contourIp.fill(roi); // plot on current slice
120         }
121       }
122     }
123     if (opts.binary) {
124       for (int i = 1; i <= res.getImageStackSize(); i++) {
125         res.getStack().getProcessor(i).threshold(0);
126       }
127       ImageConverter.setDoScaling(false);
128       new StackConverter(res).convertToGray8();
129     }
130     if (!apiCall) { // do not show nor save if called from api
131       res.show();
132       // save in QCONF folder
133       QParamsQconf/../../../../../com/github/celldynamics/quimp/QParamsQconf.html#QParamsQconf">QParamsQconf qp = (QParamsQconf) qconfLoader.getQp();
134       Path filename = Paths.get(qp.getPath(), qp.getFileName() + FileExtensions.generateMaskSuffix);
135       IJ.saveAsTiff(res, filename.toString());
136       IJ.log("Saved in: " + filename.toString());
137       if (errorSink == MessageSinkTypes.GUI) { // run form IJ not from macro
138         JOptionPane.showMessageDialog(
139                 IJ.getInstance(), QuimpToolsCollection
140                         .stringWrap("Image saved! (" + filename.toString() + ")", QuimP.LINE_WRAP),
141                 "Saved!", JOptionPane.INFORMATION_MESSAGE);
142       } else {
143         IJ.log("Mask generated!");
144       }
145     }
146 
147   }
148 
149   /**
150    * Return image generated by plugin. Use with API calls.
151    * 
152    * <p>Return 16bit image if {@link GenerateMaskOptions#binary} is set to false with grayscale
153    * indexed objects.
154    * 
155    * @return the res Mask image generated from loaded Qconf.
156    */
157   public ImagePlus getRes() {
158     return res;
159   }
160 
161   @Override
162   protected void runFromPaqp() throws QuimpException {
163     throw new QuimpException("Old file format is not supported");
164   }
165 
166   /*
167    * (non-Javadoc)
168    * 
169    * @see com.github.celldynamics.quimp.plugin.PluginTemplate#showUi(boolean)
170    */
171   @Override
172   public void showUi(boolean val) throws Exception {
173     // this method is called when no options were provided to run, paramFile is empty or null
174     loadFile(options.paramFile); // if no options (run from menu) let qconfloader show file selector
175     // fill this for macro recorder
176     options.paramFile = qconfLoader.getQp().getParamFile().getAbsolutePath();
177   }
178 }