diff --git a/.gitignore b/.gitignore index bf678dd154daf5cd3c5fdf5b9c22738fed75066a..57f16fb67c1b1589981416b323d7a9debc728665 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,41 @@ -.idea/ +/build* +/workspace +setting.xml +release/ target/ -bin/ -.settings/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ +icy.log + +### IntelliJ IDEA ### +.idea/ +*.iws *.iml -.project +*.ipr + +### Eclipse ### +.apt_generated .classpath -SpotDetectorBlock.jar +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ + +### Mac OS ### +**/.DS_Store +Icon? \ No newline at end of file diff --git a/pom.xml b/pom.xml index 09473f6e1f70e7f03bcff948afb091559ba4754e..09d18711bba5f10926e702873342253475421082 100644 --- a/pom.xml +++ b/pom.xml @@ -7,13 +7,11 @@ <parent> <artifactId>pom-icy</artifactId> <groupId>org.bioimageanalysis.icy</groupId> - <version>2.1.2</version> + <version>3.0.0-a.1</version> </parent> <artifactId>spot-detector-block</artifactId> - <version>1.0.0</version> - - <packaging>jar</packaging> + <version>2.0.0-a.1</version> <name>Spot Detector block</name> <description> @@ -21,6 +19,14 @@ </description> <dependencies> + <dependency> + <groupId>org.bioimageanalysis.icy</groupId> + <artifactId>ezplug</artifactId> + </dependency> + <dependency> + <groupId>org.bioimageanalysis.icy</groupId> + <artifactId>protocols</artifactId> + </dependency> <dependency> <groupId>org.bioimageanalysis.icy</groupId> <artifactId>spot-detector</artifactId> @@ -30,7 +36,7 @@ <repositories> <repository> <id>icy</id> - <url>https://icy-nexus.pasteur.fr/repository/Icy/</url> + <url>https://nexus-icy.pasteur.cloud/repository/icy/</url> </repository> </repositories> </project> \ No newline at end of file diff --git a/src/main/java/plugins/fab/waveletspotdetectorblock/WaveletSpotDetectorBlock.java b/src/main/java/plugins/fab/waveletspotdetectorblock/WaveletSpotDetectorBlock.java index 2b51f70b230e50d5f823e484c5df8c594f33178a..fb6d307f01ae622b20b42f8b91050a14e0201f57 100644 --- a/src/main/java/plugins/fab/waveletspotdetectorblock/WaveletSpotDetectorBlock.java +++ b/src/main/java/plugins/fab/waveletspotdetectorblock/WaveletSpotDetectorBlock.java @@ -1,70 +1,91 @@ -package plugins.fab.waveletspotdetectorblock; +/* + * Copyright (c) 2010-2024. Institut Pasteur. + * + * This file is part of Icy. + * Icy is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Icy is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Icy. If not, see <https://www.gnu.org/licenses/>. + */ -import java.util.ArrayList; +package plugins.fab.waveletspotdetectorblock; -import icy.plugin.abstract_.Plugin; -import icy.roi.ROI; -import icy.roi.ROI2D; -import icy.sequence.Sequence; -import icy.sequence.SequenceUtil; -import icy.system.thread.ThreadUtil; +import org.bioimageanalysis.icy.extension.plugin.abstract_.Plugin; +import org.bioimageanalysis.icy.extension.plugin.annotation_.IcyPluginIcon; +import org.bioimageanalysis.icy.extension.plugin.annotation_.IcyPluginName; +import org.bioimageanalysis.icy.model.roi.ROI; +import org.bioimageanalysis.icy.model.roi.ROI2D; +import org.bioimageanalysis.icy.model.sequence.Sequence; +import org.bioimageanalysis.icy.model.sequence.SequenceUtil; +import org.bioimageanalysis.icy.system.logging.IcyLogger; +import org.bioimageanalysis.icy.system.thread.ThreadUtil; +import org.jetbrains.annotations.NotNull; import plugins.adufour.blocks.lang.Block; import plugins.adufour.blocks.util.VarList; -import plugins.adufour.vars.lang.VarBoolean; -import plugins.adufour.vars.lang.VarEnum; -import plugins.adufour.vars.lang.VarInteger; -import plugins.adufour.vars.lang.VarROIArray; -import plugins.adufour.vars.lang.VarSequence; +import plugins.adufour.vars.lang.*; import plugins.adufour.vars.util.VarException; import plugins.fab.spotDetector.DetectionSpot; import plugins.fab.spotDetector.detector.DetectionToROI; import plugins.fab.spotDetector.detector.UDWTScale; import plugins.fab.spotDetector.detector.UDWTWaveletCore; -public class WaveletSpotDetectorBlock extends Plugin implements Block -{ +import java.util.ArrayList; - enum detectionMethodEnum - { +@IcyPluginName("Wavelet Spot Detector") +@IcyPluginIcon(path = "/spot-detector-block.png") +public class WaveletSpotDetectorBlock extends Plugin implements Block { + enum detectionMethodEnum { BRIGHT_SPOT, DARK_SPOT } - VarSequence inputSequenceVar = new VarSequence("input Sequence", null); - VarEnum<detectionMethodEnum> detectionMethod = new VarEnum<detectionMethodEnum>("Spot to detect", - detectionMethodEnum.BRIGHT_SPOT); + VarSequence inputSequenceVar = new VarSequence("Input Sequence", null); + VarEnum<detectionMethodEnum> detectionMethod = new VarEnum<>("Spot to detect", detectionMethodEnum.BRIGHT_SPOT); VarBoolean computeWATConsideringROIBoolean = new VarBoolean("Compute WAT considering ROI", false); VarSequence inputSequenceROIVar = new VarSequence("ROIs from sequence for WAT", null); VarBoolean force2DWaveletVar = new VarBoolean("Force 2D Wavelets", false); VarROIArray inputROIForMask = new VarROIArray("ROIs for detection mask", null); - VarBoolean[] useScaleBoolean = {new VarBoolean("Scale 1", false), new VarBoolean("Scale 2", true), - new VarBoolean("Scale 3", false), new VarBoolean("Scale 4", false), new VarBoolean("Scale 5", false)}; - - VarInteger[] scaleParameter = {new VarInteger("Th. scale 1:", 100), new VarInteger("Th. scale 2:", 100), - new VarInteger("Th. scale 3:", 100), new VarInteger("Th. scale 4:", 100), new VarInteger("Th. scale 5:", 100)}; - - VarSequence outSequence = new VarSequence("output Sequence", null); - VarSequence denoisedSequence = new VarSequence("denoised Sequence", null); + VarBoolean[] useScaleBoolean = { + new VarBoolean("Scale 1", false), + new VarBoolean("Scale 2", true), + new VarBoolean("Scale 3", false), + new VarBoolean("Scale 4", false), + new VarBoolean("Scale 5", false) + }; + + VarInteger[] scaleParameter = { + new VarInteger("Th. scale 1:", 100), + new VarInteger("Th. scale 2:", 100), + new VarInteger("Th. scale 3:", 100), + new VarInteger("Th. scale 4:", 100), + new VarInteger("Th. scale 5:", 100) + }; + + //VarSequence outSequence = new VarSequence("output Sequence", null); + //VarSequence denoisedSequence = new VarSequence("denoised Sequence", null); VarSequence binarySpotSequence = new VarSequence("binary Spot Sequence", null); VarROIArray detectionAsROIOut = new VarROIArray("detection as ROIs", null); @Override - public void run() - { - + public void run() { // test if input sequence has only 1 channel. Sequence inputSequence = inputSequenceVar.getValue(); - if (inputSequence == null) - { - throw new VarException("The input sequence must be set"); + if (inputSequence == null) { + throw new VarException(inputSequenceVar, "The input sequence must be set"); } - if (inputSequence.getSizeC() != 1) - { - throw new VarException( - "The input sequence must contain only 1 channel. Please use 'Extract Channel' prior to the WaveletBlock"); + if (inputSequence.getSizeC() != 1) { + throw new VarException(inputSequenceVar, "The input sequence must contain only 1 channel. Please use 'Extract Channel' prior to the WaveletBlock"); } // inputChannelVar @@ -75,38 +96,26 @@ public class WaveletSpotDetectorBlock extends Plugin implements Block boolean detectNegative; - if (detectionMethod.getValue() == detectionMethodEnum.BRIGHT_SPOT) - { - detectNegative = false; - } - else - { - detectNegative = true; - } + detectNegative = detectionMethod.getValue() != detectionMethodEnum.BRIGHT_SPOT; boolean computeWATwithROI = computeWATConsideringROIBoolean.getValue(); // copy ROI from input sequence to the computation sequence Sequence inputComputationSequence; - try - { + try { inputComputationSequence = SequenceUtil.getCopy(inputSequence); } - catch (InterruptedException ex) - { + catch (InterruptedException ex) { // interrupt process return; } - if (inputSequenceROIVar.getValue() != null) - { - for (ROI2D roi : inputSequenceROIVar.getValue().getROI2Ds()) - { + if (inputSequenceROIVar.getValue() != null) { + for (ROI2D roi : inputSequenceROIVar.getValue().getROI2Ds()) { ROI2D roiCopy = (ROI2D) roi.getCopy(); - if (roiCopy != null) - { + if (roiCopy != null) { inputComputationSequence.addROI(roiCopy); } } @@ -116,73 +125,63 @@ public class WaveletSpotDetectorBlock extends Plugin implements Block // create UDWTScale Parameter list. - final ArrayList<UDWTScale> UDWTScaleArrayList = new ArrayList<UDWTScale>(); + final ArrayList<UDWTScale> UDWTScaleArrayList = new ArrayList<>(); // System.out.println("Block debug."); - ThreadUtil.invokeNow(new Runnable() - { - - @Override - public void run() - { - - for (int i = 0; i < 5; i++) - { - // System.out.println( "Scale enabled #" +i +" : " + useScaleBoolean[i].getValue() ); - UDWTScale scale = new UDWTScale(i + 1, useScaleBoolean[i].getValue(), scaleParameter[i].getValue()); - UDWTScaleArrayList.add(scale); - } + ThreadUtil.invokeNow(() -> { + for (int i = 0; i < 5; i++) { + // System.out.println( "Scale enabled #" +i +" : " + useScaleBoolean[i].getValue() ); + UDWTScale scale = new UDWTScale(i + 1, useScaleBoolean[i].getValue(), scaleParameter[i].getValue()); + UDWTScaleArrayList.add(scale); } }); // Perform detection. - try - { - ArrayList<DetectionSpot> detectionResult = waveletCore.computeDetection(true, UDWTScaleArrayList, inputComputationSequence, - detectNegative, computeWATwithROI, force2DWaveletVar.getValue()); + try { + ArrayList<DetectionSpot> detectionResult = waveletCore.computeDetection( + true, + UDWTScaleArrayList, + inputComputationSequence, + detectNegative, + computeWATwithROI, + force2DWaveletVar.getValue() + ); - // System.out.println( "ROI Mask : " + inputROIForMask.getValue() ); + // System.out.println( "ROI Mask : " + inputROIForMask.getValue() ); - // Filter spot with ROIs. - if (inputROIForMask.getValue().length != 0) - { - ArrayList<DetectionSpot> detectionResultCopy = new ArrayList<DetectionSpot>(detectionResult); + // Filter spot with ROIs. + if (inputROIForMask.getValue().length != 0) { + ArrayList<DetectionSpot> detectionResultCopy = new ArrayList<>(detectionResult); detectionList: - for (DetectionSpot spot : detectionResultCopy) - { + for (DetectionSpot spot : detectionResultCopy) { // Point2D spotCoordinates = new Point2D.Double( spot.getMassCenter().x , spot.getMassCenter().y ); // spot.getMassCenter() ROI detectionAsROI = null; - try - { - ArrayList<DetectionSpot> detectionList = new ArrayList<DetectionSpot>(); + try { + ArrayList<DetectionSpot> detectionList = new ArrayList<>(); detectionList.add(spot); - detectionAsROI = DetectionToROI.convertDetectionToROI(detectionList).get(0); + detectionAsROI = DetectionToROI.convertDetectionToROI(detectionList).getFirst(); } - catch (NullPointerException e) - { - System.err.println("Error in spot to ROI conversion"); + catch (NullPointerException e) { + IcyLogger.error(this.getClass(), "Error in spot to ROI conversion."); } - if (detectionAsROI == null) - { - System.err.println("Can't convert spot to ROI. spot=" + spot); + if (detectionAsROI == null) { + IcyLogger.error(this.getClass(), "Can't convert spot to ROI. spot=" + spot); continue; } // System.out.println( "spot as ROI to test: " + detectionAsROI.getBounds5D() ); - for (ROI roi : inputROIForMask.getValue()) - { + for (ROI roi : inputROIForMask.getValue()) { // System.out.println( "roi contenant: " + roi.getBounds5D() ); - if (roi.contains(detectionAsROI)) - { + if (roi.contains(detectionAsROI)) { // System.out.println("contains"); continue detectionList; } @@ -200,10 +199,8 @@ public class WaveletSpotDetectorBlock extends Plugin implements Block { Sequence binarySequence = waveletCore.getBinarySequence(); - if (inputSequenceROIVar.getValue() != null) - { - for (ROI2D roi : inputSequenceROIVar.getValue().getROI2Ds()) - { + if (inputSequenceROIVar.getValue() != null) { + for (ROI2D roi : inputSequenceROIVar.getValue().getROI2Ds()) { // System.out.println("roi:"+roi); String name = roi.getName(); @@ -221,52 +218,44 @@ public class WaveletSpotDetectorBlock extends Plugin implements Block // output detection as ROI { ArrayList<ROI> roiList = DetectionToROI.convertDetectionToROI(detectionResult); - ROI roi[] = new ROI[roiList.size()]; + ROI[] roi = new ROI[roiList.size()]; int i = 0; - for (ROI roiCandidate : roiList) - { + for (ROI roiCandidate : roiList) { roi[i] = roiCandidate; i++; } detectionAsROIOut.setValue(roi); } } - catch (InterruptedException e) - { + catch (InterruptedException e) { // protocols process interrupted Thread.currentThread().interrupt(); } } @Override - public void declareInput(VarList inputMap) - { - - inputMap.add(inputSequenceVar); - inputMap.add(detectionMethod); - inputMap.add("input Sequence ROIs", inputSequenceROIVar); - inputMap.add(computeWATConsideringROIBoolean); - inputMap.add(inputROIForMask); - - for (int i = 0; i < 5; i++) - { - inputMap.add(useScaleBoolean[i]); + public void declareInput(@NotNull VarList inputMap) { + inputMap.add("input-sequence", inputSequenceVar); + inputMap.add("detection-method", detectionMethod); + inputMap.add("input-sequence-rois", inputSequenceROIVar); + inputMap.add("compute-wat-considering-roi", computeWATConsideringROIBoolean); + inputMap.add("input-roi-for-mask", inputROIForMask); + + for (int i = 0; i < 5; i++) { + inputMap.add("use-scale-" + i, useScaleBoolean[i]); } - for (int i = 0; i < 5; i++) - { - inputMap.add(scaleParameter[i]); + for (int i = 0; i < 5; i++) { + inputMap.add("scale-value-" + i, scaleParameter[i]); } - inputMap.add(force2DWaveletVar); + inputMap.add("force-2d-wavelet", force2DWaveletVar); } @Override - public void declareOutput(VarList outputMap) - { - + public void declareOutput(@NotNull VarList outputMap) { // outputMap.add( outSequence ); // outputMap.add( denoisedSequence ); - outputMap.add(binarySpotSequence); - outputMap.add(detectionAsROIOut); + outputMap.add("Binary Spot Sequence", binarySpotSequence); + outputMap.add("Detection as ROI", detectionAsROIOut); } diff --git a/src/main/resources/spot-detector-block.png b/src/main/resources/spot-detector-block.png new file mode 100644 index 0000000000000000000000000000000000000000..fc0a7455a4c58ab68ab497d0e1ad058e45c28cc4 Binary files /dev/null and b/src/main/resources/spot-detector-block.png differ