4747import java .util .concurrent .atomic .AtomicReference ;
4848import java .util .function .BiConsumer ;
4949import java .util .function .Function ;
50+ import java .util .function .IntPredicate ;
5051import java .util .logging .Logger ;
5152import java .util .stream .IntStream ;
5253import uk .ac .sussex .gdsc .core .ij .BufferedTextWindow ;
@@ -96,12 +97,16 @@ public class FociNeighbourAnalysis_PlugIn implements ExtendedPlugInFilter, Dialo
9697 * Contains the settings that are the re-usable state of the plugin.
9798 */
9899 private static class Settings {
100+ static final String [] LABEL_OPTIONS = {"None" , "Neighbours" , "All" };
101+ static final int LABEL_NEIGHBOURS = 1 ;
102+ static final int LABEL_ALL = 2 ;
99103 private static final String SETTING_PR_CHANNEL = "gdsc.foci.neighbours.primaryChannel" ;
100104 private static final String SETTING_SE_CHANNEL = "gdsc.foci.neighbours.secondaryChannel" ;
101105 private static final String SETTING_DISTANCE = "gdsc.foci.neighbours.distance" ;
102106 private static final String SETTING_RESULT_DIR = "gdsc.foci.neighbours.resultsDirectory" ;
103107 private static final String SETTING_PROCESSOR = "gdsc.foci.neighbours.processor" ;
104108 private static final String SETTING_DIGITS = "gdsc.foci.neighbours.digits" ;
109+ private static final String SETTING_LABEL_OPTION = "gdsc.foci.neighbours.labelOption" ;
105110
106111 /** The last settings used by the plugin. This should be updated after plugin execution. */
107112 private static final AtomicReference <Settings > lastSettings =
@@ -113,6 +118,7 @@ private static class Settings {
113118 String resultsDirectory ;
114119 private final Int2ObjectOpenHashMap <FindFociProcessorOptions > options ;
115120 int digits ;
121+ int labelOption ;
116122
117123 /**
118124 * Default constructor.
@@ -123,7 +129,8 @@ private static class Settings {
123129 distance = Prefs .get (SETTING_DISTANCE , 1 );
124130 resultsDirectory = Prefs .get (SETTING_RESULT_DIR , "" );
125131 options = new Int2ObjectOpenHashMap <>();
126- digits = 4 ;
132+ digits = (int ) Prefs .get (SETTING_DIGITS , 4 );
133+ labelOption = (int ) Prefs .get (SETTING_LABEL_OPTION , LABEL_NEIGHBOURS );
127134
128135 // Convert chars to boolean
129136 final String se = Prefs .get (SETTING_SE_CHANNEL , "" );
@@ -145,6 +152,7 @@ private Settings(Settings source) {
145152 resultsDirectory = source .resultsDirectory ;
146153 options = source .options .clone ();
147154 digits = source .digits ;
155+ labelOption = source .labelOption ;
148156 }
149157
150158 /**
@@ -187,6 +195,7 @@ void saveAnalysisOptions() {
187195 Prefs .set (SETTING_DISTANCE , distance );
188196 Prefs .set (SETTING_RESULT_DIR , resultsDirectory );
189197 Prefs .set (SETTING_DIGITS , digits );
198+ Prefs .set (SETTING_LABEL_OPTION , labelOption );
190199 }
191200
192201 FindFociProcessorOptions getOptions (int channel ) {
@@ -323,6 +332,7 @@ public int showDialog(ImagePlus imp, String command, PlugInFilterRunner pfr) {
323332 gd .addNumericField ("Distance" , settings .distance , 2 , 6 , cal .scaled () ? cal .getUnit () : "px" );
324333 gd .addDirectoryField ("Results_directory" , settings .resultsDirectory );
325334 gd .addSlider ("Table_Digits" , 2 , 10 , settings .digits );
335+ gd .addChoice ("Label_option" , Settings .LABEL_OPTIONS , settings .labelOption );
326336
327337 // Add dialogs to control FindFoci settings for each channel
328338 addFindFociSettings (gd , settings .primaryChannel );
@@ -455,6 +465,7 @@ public boolean dialogItemChanged(GenericDialog gd, AWTEvent event) {
455465 settings .distance = gd .getNextNumber ();
456466 settings .resultsDirectory = gd .getNextString ();
457467 settings .digits = (int ) gd .getNextNumber ();
468+ settings .labelOption = gd .getNextChoiceIndex ();
458469 settings .saveAnalysisOptions ();
459470 return settings .distance > 0 ;
460471 }
@@ -609,13 +620,17 @@ private String createHeader() {
609620
610621 private void overlayResults (FindFociResults pResults ,
611622 List <Int2ObjectOpenHashMap <List <FindFociResult >>> allNeighbours ) {
623+ IntPredicate display = createMatchPredicate (allNeighbours );
624+ if (display == null ) {
625+ return ;
626+ }
612627 final int [] x = new int [pResults .results .size ()];
613628 final int [] y = new int [x .length ];
614629 final int [] id = new int [x .length ];
615630 int c = 0 ;
616631 for (final FindFociResult r : pResults .results ) {
617- // Check for any neighbours
618- if (allNeighbours . stream (). anyMatch ( m -> m . containsKey ( r .id ) )) {
632+ // Check for display
633+ if (display . test ( r .id )) {
619634 x [c ] = r .x ;
620635 y [c ] = r .y ;
621636 id [c ] = r .id ;
@@ -627,4 +642,15 @@ private void overlayResults(FindFociResults pResults,
627642 roi .setShowLabels (true );
628643 imp .setRoi (roi );
629644 }
645+
646+ private IntPredicate
647+ createMatchPredicate (List <Int2ObjectOpenHashMap <List <FindFociResult >>> allNeighbours ) {
648+ if (settings .labelOption == Settings .LABEL_ALL ) {
649+ return i -> true ;
650+ }
651+ if (settings .labelOption == Settings .LABEL_NEIGHBOURS ) {
652+ return i -> allNeighbours .stream ().anyMatch (m -> m .containsKey (i ));
653+ }
654+ return null ;
655+ }
630656}
0 commit comments