BioGTK  6.7.0
A .NET library & program for annotating, editing various microscopy imaging formats using Bioformats supported images. Including whole slide, pyramidal, and series.
Loading...
Searching...
No Matches
ChannelsTool.cs
1using AForge;
2using Gtk;
3using System;
4using System.Collections.Generic;
5using System.IO;
6using System.Linq;
7using System.Threading;
8using System.Threading.Tasks;
9
10
11namespace BioGTK
12{
13 public class ChannelsTool : Gtk.Window
14 {
15 #region Properties
16
18 private Builder _builder;
19
20#pragma warning disable 649
21 [Builder.Object]
22 private Button applyBut;
23 [Builder.Object]
24 private Button resetBut;
25 [Builder.Object]
26 private ComboBox channelsBox;
27 [Builder.Object]
28 private SpinButton sampleBox;
29 [Builder.Object]
30 private ComboBox maxUintBox;
31 [Builder.Object]
32 private SpinButton minBox;
33 [Builder.Object]
34 private SpinButton maxBox;
35 [Builder.Object]
36 private Button setMinAllBut;
37 [Builder.Object]
38 private Button setMaxAllBut;
39 [Builder.Object]
40 private Entry fluorBox;
41 [Builder.Object]
42 private SpinButton emissionBox;
43 [Builder.Object]
44 private SpinButton excitationBox;
45 [Builder.Object]
46 private SpinButton binBox;
47 [Builder.Object]
48 private SpinButton graphMinBox;
49 [Builder.Object]
50 private SpinButton graphMax;
51 [Builder.Object]
52 private ComboBox maxUintBox2;
53 [Builder.Object]
54 private CheckButton meanStackBox;
55#pragma warning restore 649
56
57 #endregion
58
59 #region Constructors / Destructors
60 public static ChannelsTool Create()
61 {
62 string s = System.IO.Path.GetDirectoryName(Environment.ProcessPath).Replace("\\", "/") + "/" + "Glade/ChannelsTool.glade";
63 Builder builder = new Builder(new FileStream(s, FileMode.Open));
64 return new ChannelsTool(builder, builder.GetObject("chanTool").Handle);
65 }
66 /* Creating a new window and populating it with the values from the channels. */
67 protected ChannelsTool(Builder builder, IntPtr handle) : base(handle)
68 {
69 _builder = builder;
70 builder.Autoconnect(this);
71 App.channelsTool = this;
72 var store = new ListStore(typeof(string));
73 foreach (Channel item in Channels)
74 {
75 // Add items to the ListStore
76 store.AppendValues(item.ToString());
77 channelsBox.Active = 0;
78 }
79 channelsBox.Model = store;
80 // Set the text column to display
81 var renderer = new CellRendererText();
82 channelsBox.PackStart(renderer, false);
83 channelsBox.AddAttribute(renderer, "text", 0);
84
85 UpdateGUI();
86
87 GetChannelLimits(Channels[0], 0, out int initialMin, out int initialMax);
88 minBox.Value = initialMin;
89 maxBox.Value = initialMax;
90 binBox.Value = 1;
91 binBox.Adjustment = new Adjustment(1, 1, 255, 1, 1, 1);
92 hist = HistogramControl.Create(Channels[0]);
93 int initialGraphMaximum = GetObservedHistogramMaximum();
94 hist.GraphMax = initialGraphMaximum;
95 graphMax.Value = initialGraphMaximum;
96 hist.Show();
97 _ = LoadMissingZarrStatisticsAsync();
98
99 minBox.ButtonPressEvent += minBox_ValueChanged;
100 //meanStackBox.Clicked += MeanStackBox_Clicked;
101 setMinAllBut.ButtonPressEvent += setMinAllBut_Click;
102 setMaxAllBut.ButtonPressEvent += setMaxAllBut_Click;
103 minBox.ValueChanged+= minBox_ValueChanged;
104 maxBox.ValueChanged+= maxBox_ValueChanged;
105 fluorBox.Changed += fluorBox_TextChanged;
106 emissionBox.ValueChanged += emissionBox_ValueChanged;
107 excitationBox.ValueChanged += excitationBox_ValueChanged;
108 binBox.ValueChanged += binBox_ValueChanged;
109 graphMinBox.ValueChanged += minGraphBox_ValueChanged;
110 graphMax.ValueChanged += maxGraphBox_ValueChanged;
111 applyBut.ButtonPressEvent += applyBut_Click;
112 resetBut.ButtonPressEvent += ResetButton_ButtonPressEvent;
113 this.ButtonPressEvent += ChannelsTool_MouseDown;
114 this.FocusActivated += ChannelsTool_Activated;
115 channelsBox.Changed += ChannelsBox_Changed;
116 sampleBox.Changed += SampleBox_Changed;
117 meanStackBox.Clicked += MeanStackBox_Clicked;
118
119 maxUintBox.Changed += MaxUintBox_Changed;
120 maxUintBox2.Changed += MaxUintBox2_Changed;
121
122 var st = new ListStore(typeof(string));
123 st.AppendValues(ushort.MaxValue.ToString());
124 st.AppendValues(16383);
125 st.AppendValues(4096);
126 st.AppendValues(1023);
127 st.AppendValues(byte.MaxValue.ToString());
128 maxUintBox.Model = st;
129 maxUintBox2.Model = st;
130 // Set the text column to display
131 var rend = new CellRendererText();
132 maxUintBox.PackStart(rend, false);
133 maxUintBox.AddAttribute(rend, "text", 0);
134 var rend2 = new CellRendererText();
135 maxUintBox2.PackStart(rend2, false);
136 maxUintBox2.AddAttribute(rend2, "text", 0);
137 ShowAll();
138 App.ApplyStyles(this);
139 }
140
145 private void SampleBox_Changed(object sender, EventArgs e)
146 {
147 UpdateValues();
148 }
149
155 private void MeanStackBox_Clicked(object sender, EventArgs e)
156 {
157 hist.StackHistogram = meanStackBox.Active;
158 }
159
165 private void MaxUintBox2_Changed(object sender, EventArgs e)
166 {
167 int selectedIndex = maxUintBox2.Active;
168 TreeIter iter;
169 if (maxUintBox2.Model.GetIterFromString(out iter, selectedIndex.ToString()))
170 {
171 string selectedValue = (string)maxUintBox2.Model.GetValue(iter, 0);
172 // Your code to handle the selected value
173 int i = int.Parse(selectedValue);
174 graphMax.Value = i;
175 }
176 }
177
183 private void MaxUintBox_Changed(object sender, EventArgs e)
184 {
185 int selectedIndex = maxUintBox.Active;
186 TreeIter iter;
187 if (maxUintBox.Model.GetIterFromString(out iter, selectedIndex.ToString()))
188 {
189 string selectedValue = (string)maxUintBox.Model.GetValue(iter, 0);
190 // Your code to handle the selected value
191 int i = int.Parse(selectedValue);
192 maxBox.Value = i;
193 }
194 }
195
200 private void ChannelsBox_Changed(object sender, EventArgs e)
201 {
202 UpdateValues();
203 }
204
208 private void UpdateValues()
209 {
210 if (channelsBox.Active == -1)
211 return;
212 sampleBox.Adjustment.Upper = SelectedChannel.range.Length - 1;
213 if (minBox.Adjustment.Upper < SelectedChannel.range[(int)sampleBox.Value].Min || maxBox.Adjustment.Upper < SelectedChannel.range[(int)sampleBox.Value].Max)
214 {
215 minBox.Value = 0;
216 maxBox.Value = ushort.MaxValue;
217 }
218 else
219 {
220 minBox.Value = Channels[channelsBox.Active].range[(int)sampleBox.Value].Min;
221 maxBox.Value = Channels[channelsBox.Active].range[(int)sampleBox.Value].Max;
222 }
223 if (hist != null)
224 {
225 //hist.Statistics = Channels[channelsBox.Active].statistics;
226 hist.UpdateChannel(SelectedChannel);
227 hist.UpdateView();
228 }
229 float max = float.MinValue;
230 float min = float.MaxValue;
231 foreach (Channel c in Channels)
232 {
233 for (int i = 0; i < c.SamplesPerPixel; i++)
234 {
235 if (max < c.range[i].Max)
236 max = c.range[i].Max;
237 if (min > c.range[i].Min)
238 min = c.range[i].Min;
239 }
240 }
241 int observedMaximum = GetObservedHistogramMaximum();
242 graphMax.Value = observedMaximum;
243 if (hist != null)
244 hist.GraphMax = observedMaximum;
245 graphMinBox.Value = min;
246 fluorBox.Text = SelectedChannel.Fluor;
247 emissionBox.Value = SelectedChannel.Emission;
248 excitationBox.Value = SelectedChannel.Excitation;
249 }
250
252 private void UpdateGUI()
253 {
254 if (SelectedChannel.BitsPerPixel > 8)
255 {
256 minBox.Adjustment.Upper = ushort.MaxValue;
257 minBox.Adjustment.StepIncrement = 1;
258 minBox.Adjustment.PageIncrement = 10;
259 maxBox.Adjustment.Upper = ushort.MaxValue;
260 maxBox.Adjustment.StepIncrement = 1;
261 maxBox.Adjustment.PageIncrement = 10;
262 graphMax.Adjustment.Upper = ushort.MaxValue;
263 graphMax.Adjustment.StepIncrement = 1;
264 graphMax.Adjustment.PageIncrement = 10;
265 graphMinBox.Adjustment.Upper = ushort.MaxValue;
266 graphMinBox.Adjustment.StepIncrement = 1;
267 graphMinBox.Adjustment.PageIncrement = 10;
268 }
269 else
270 {
271 minBox.Adjustment.Upper = byte.MaxValue;
272 minBox.Adjustment.StepIncrement = 1;
273 minBox.Adjustment.PageIncrement = 10;
274 maxBox.Adjustment.Upper = byte.MaxValue;
275 maxBox.Adjustment.StepIncrement = 1;
276 maxBox.Adjustment.PageIncrement = 10;
277 graphMax.Adjustment.Upper = byte.MaxValue;
278 graphMax.Adjustment.StepIncrement = 1;
279 graphMax.Adjustment.PageIncrement = 10;
280 graphMinBox.Adjustment.Upper = byte.MaxValue;
281 graphMinBox.Adjustment.StepIncrement = 1;
282 graphMinBox.Adjustment.PageIncrement = 10;
283 }
284 GetChannelLimits(SelectedChannel, (int)sampleBox.Value,
285 out int selectedMin, out int selectedMax);
286 minBox.Value = selectedMin;
287 maxBox.Value = selectedMax;
288 emissionBox.Value =
289
290 emissionBox.Adjustment.Upper = 1000;
291 emissionBox.Adjustment.StepIncrement = 1;
292 emissionBox.Adjustment.PageIncrement = 10;
293 excitationBox.Adjustment.Upper = 1000;
294 excitationBox.Adjustment.StepIncrement = 1;
295 excitationBox.Adjustment.PageIncrement = 10;
296 binBox.Adjustment.Upper = 1000;
297 binBox.Adjustment.StepIncrement = 1;
298 binBox.Adjustment.PageIncrement = 10;
299 sampleBox.Adjustment.Upper = SelectedChannel.SamplesPerPixel-1;
300 sampleBox.Adjustment.StepIncrement = 1;
301 sampleBox.Adjustment.PageIncrement = 1;
302 }
303
310 private void ResetButton_ButtonPressEvent(object o, ButtonPressEventArgs args)
311 {
312 if (ImageView.SelectedImage.bitsPerPixel > 8)
313 ImageView.SelectedImage.StackThreshold(true);
314 else
315 ImageView.SelectedImage.StackThreshold(false);
316 App.viewer.RefreshPyramidalTiles();
317 App.viewer.UpdateView();
318 }
319 /*
320 private void View_ScrollEvent(object o, ScrollEventArgs args)
321 {
322 int i = 100;
323 if (maxGraphBox.Value < 255)
324 i = 10;
325 if (e.Delta > 0)
326 {
327 if (graphMax.Value + i < graphMax.Adjustment.Upper)
328 {
329 graphMax.Value += i;
330 graphMax.QueueDraw();
331 return;
332 }
333 }
334 else
335 if (graphMax.Value - i > graphMax.Adjustment.Upper)
336 {
337 graphMax.Value -= i;
338 graphMax.QueueDraw();
339 return;
340 }
341 }
342 */
343 #endregion
344
345 private HistogramControl hist = null;
346 private readonly SemaphoreSlim _statisticsRefreshGate = new(1, 1);
347 private int _statisticsRefreshVersion;
348
349 private async Task LoadMissingZarrStatisticsAsync()
350 {
351 if (ImageView.SelectedImage?.IsZarrSource != true ||
352 Channels.All(HasPopulatedStatistics))
353 return;
354
355 BioImage image = ImageView.SelectedImage;
356 int version = Interlocked.Increment(ref _statisticsRefreshVersion);
357 await RefreshZarrStatisticsAsync(image, image.Coordinate, version, debounce: false);
358 }
359
360 public void RefreshStatisticsForCoordinate(BioImage image, ZCT coordinate)
361 {
362 if (image == null)
363 return;
364
365 int version = Interlocked.Increment(ref _statisticsRefreshVersion);
366 if (!image.IsZarrSource)
367 {
368 UpdateValues();
369 hist?.UpdateChannel(SelectedChannel);
370 hist?.UpdateView();
371 hist?.QueueDraw();
372 return;
373 }
374
375 _ = RefreshZarrStatisticsAsync(image, coordinate, version, debounce: true);
376 }
377
378 private async Task RefreshZarrStatisticsAsync(
379 BioImage image,
380 ZCT coordinate,
381 int version,
382 bool debounce)
383 {
384 if (debounce)
385 await Task.Delay(150).ConfigureAwait(false);
386
387 if (version != Volatile.Read(ref _statisticsRefreshVersion) ||
388 !ReferenceEquals(image, ImageView.SelectedImage) ||
389 image.Coordinate != coordinate)
390 return;
391
392 try
393 {
394 if (App.viewer == null)
395 return;
396
397 await _statisticsRefreshGate.WaitAsync().ConfigureAwait(false);
398 bool populated;
399 try
400 {
401 if (version != Volatile.Read(ref _statisticsRefreshVersion) ||
402 !ReferenceEquals(image, ImageView.SelectedImage) ||
403 image.Coordinate != coordinate)
404 return;
405
406 populated = await App.viewer.PopulateSelectedZarrStatisticsAsync().ConfigureAwait(false);
407 }
408 finally
409 {
410 _statisticsRefreshGate.Release();
411 }
412
413 if (!populated)
414 {
415 AppLog.Append("Zarr statistics loading returned no usable samples.");
416 return;
417 }
418
419 if (version != Volatile.Read(ref _statisticsRefreshVersion) ||
420 !ReferenceEquals(image, ImageView.SelectedImage) ||
421 image.Coordinate != coordinate)
422 return;
423
424 Gtk.Application.Invoke((s, e) =>
425 {
426 if (version != Volatile.Read(ref _statisticsRefreshVersion) ||
427 !ReferenceEquals(image, ImageView.SelectedImage) ||
428 image.Coordinate != coordinate)
429 return;
430
431 UpdateGUI();
432 UpdateValues();
433 hist?.UpdateChannel(SelectedChannel);
434 hist?.UpdateView();
435 hist?.QueueDraw();
436 });
437 }
438 catch (OperationCanceledException)
439 {
440 }
441 catch (Exception ex)
442 {
443 AppLog.Append($"Zarr statistics loading failed: {ex}");
444 Console.WriteLine($"Zarr statistics loading failed: {ex.Message}");
445 }
446 }
447
448 private static bool HasPopulatedStatistics(Channel channel)
449 {
450 return channel?.stats != null &&
451 channel.stats.Length > 0 &&
452 channel.stats.All(statistics =>
453 statistics?.StackValues != null && statistics.StackValues.Length > 0);
454 }
455
456 private static bool TryGetStatistics(Channel channel, int sample, out Statistics statistics)
457 {
458 statistics = null;
459 if (channel?.stats == null || channel.stats.Length == 0)
460 return false;
461
462 int index = Math.Clamp(sample, 0, channel.stats.Length - 1);
463 statistics = channel.stats[index];
464 return statistics != null;
465 }
466
467 private static void GetChannelLimits(Channel channel, int sample, out int min, out int max)
468 {
469 if (TryGetStatistics(channel, sample, out Statistics statistics))
470 {
471 min = (int)statistics.StackMin;
472 max = (int)statistics.StackMax;
473 return;
474 }
475
476 if (channel?.range != null && channel.range.Length > 0)
477 {
478 int index = Math.Clamp(sample, 0, channel.range.Length - 1);
479 min = channel.range[index].Min;
480 max = channel.range[index].Max;
481 return;
482 }
483
484 min = 0;
485 max = channel?.BitsPerPixel > 8 ? ushort.MaxValue : byte.MaxValue;
486 }
487
488 private int GetObservedHistogramMaximum()
489 {
490 float observedMaximum = 0;
491 foreach (Channel imageChannel in Channels)
492 {
493 if (imageChannel?.stats == null)
494 continue;
495
496 foreach (Statistics statistics in imageChannel.stats)
497 {
498 if (statistics != null && statistics.StackMax > observedMaximum)
499 observedMaximum = statistics.StackMax;
500 }
501 }
502
503 if (observedMaximum > 0)
504 return Math.Max(1, (int)Math.Ceiling(observedMaximum));
505
506 int fallbackMaximum = 0;
507 foreach (Channel imageChannel in Channels)
508 {
509 if (imageChannel?.range == null)
510 continue;
511 foreach (IntRange range in imageChannel.range)
512 fallbackMaximum = Math.Max(fallbackMaximum, range.Max);
513 }
514
515 if (fallbackMaximum > 0)
516 return fallbackMaximum;
517 return SelectedChannel?.BitsPerPixel > 8 ? ushort.MaxValue : byte.MaxValue;
518 }
519
520 private bool TryGetSelectedStatistics(out Statistics statistics)
521 {
522 return TryGetStatistics(SelectedChannel, SelectedSample, out statistics);
523 }
524
525 public List<Channel> Channels
526 {
527 get
528 {
529 return ImageView.SelectedImage.Channels;
530 }
531 }
532 public Channel SelectedChannel
533 {
534 get
535 {
536 if (channelsBox.Active != -1)
537 return Channels[channelsBox.Active];
538 else
539 return Channels[0];
540 }
541 }
542 public int SelectedSample
543 {
544 get
545 {
546 return (int)sampleBox.Value;
547 }
548 set
549 {
550 sampleBox.Value = value;
551 }
552 }
554 public void UpdateItems()
555 {
556 channelsBox.Model = null;
557 var store = new ListStore(typeof(string));
558 // Add items to the ListStore
559 foreach (Channel item in Channels)
560 {
561 store.AppendValues(item.Name);
562 }
563 // Set the model for the ComboBox
564 channelsBox.Model = store;
565 // Set the text column to display
566 var renderer = new CellRendererText();
567 channelsBox.PackStart(renderer, false);
568 channelsBox.AddAttribute(renderer, "text", 0);
569
570 }
571
579 private void minBox_ValueChanged(object sender, EventArgs e)
580 {
581 if (channelsBox.Active == -1)
582 return;
583 if (hist != null)
584 {
585 hist.UpdateChannel(Channels[channelsBox.Active]);
586 hist.UpdateView();
587 hist.Min = (int)minBox.Value;
588 }
589 SelectedChannel.range[(int)sampleBox.Value].Min = (int)minBox.Value;
590 App.viewer.RefreshPyramidalTiles();
591 App.viewer.UpdateImage();
592 App.viewer.UpdateView();
593 }
601 private void maxBox_ValueChanged(object sender, EventArgs e)
602 {
603 if (channelsBox.Active == -1)
604 return;
605 if (hist != null)
606 {
607 hist.UpdateChannel(Channels[channelsBox.Active]);
608 hist.QueueDraw();
609 hist.Max = (int)maxBox.Value;
610 }
611 SelectedChannel.range[(int)sampleBox.Value].Max = (int)maxBox.Value;
612 App.viewer.RefreshPyramidalTiles();
613 App.viewer.UpdateImage();
614 App.viewer.UpdateView();
615 }
621 private void maxUintBox_ActiveChanged(object sender, EventArgs e)
622 {
623 TreeIter it;
624 maxUintBox.GetActiveIter(out it);
625 var selectedItem = (string)maxUintBox.Model.GetValue(it, 0);
626
627 int i = int.Parse((string)selectedItem, System.Globalization.CultureInfo.InvariantCulture);
628 if(i<=maxBox.Adjustment.Upper)
629 maxBox.Value = i;
630
631 }
632
638 private void setMaxAllBut_Click(object o, ButtonPressEventArgs args)
639 {
640 foreach (Channel c in Channels)
641 {
642 for (int i = 0; i < c.range.Length; i++)
643 {
644 c.range[i].Max = (int)maxBox.Value;
645 }
646 }
647 App.viewer.RefreshPyramidalTiles();
648 App.viewer.UpdateView();
649 }
650
656 private void setMinAllBut_Click(object o, ButtonPressEventArgs args)
657 {
658 foreach (Channel c in Channels)
659 {
660 for (int i = 0; i < c.range.Length; i++)
661 {
662 c.range[i].Min = (int)minBox.Value;
663 }
664 }
665 App.viewer.RefreshPyramidalTiles();
666 App.viewer.UpdateView();
667 }
668
675 private void ChannelsTool_Activated(object? sender, EventArgs e)
676 {
677 sampleBox.Adjustment.Upper = SelectedChannel.SamplesPerPixel - 1;
678 for (int i = 0; i < SelectedChannel.range.Length; i++)
679 {
680 SelectedChannel.range[i].Min = (int)minBox.Value;
681 }
682 minBox.Value = SelectedChannel.range[(int)sampleBox.Value].Min;
683 maxBox.Value = SelectedChannel.range[(int)sampleBox.Value].Max;
684 UpdateItems();
685 App.viewer.RefreshPyramidalTiles();
686 hist.UpdateView();
687
688 }
689
695 private void maxUintBox2_ActiveChanged(object sender, EventArgs e)
696 {
697 TreeIter it;
698 maxUintBox.GetActiveIter(out it);
699 var selectedItem = (string)maxUintBox.Model.GetValue(it, 0);
700 int i = int.Parse((string)selectedItem, System.Globalization.CultureInfo.InvariantCulture);
701 if(i <= graphMax.Adjustment.Upper)
702 graphMax.Value = i;
703 if (i == 255)
704 {
705 graphMax.Value = 255;
706 binBox.Value = 1;
707 }
708 }
709
715 private void minGraphBox_ValueChanged(object sender, EventArgs e)
716 {
717 if (hist != null)
718 {
719 hist.GraphMin = (int)graphMinBox.Value;
720 hist.UpdateView();
721 }
722 }
723
729 private void maxGraphBox_ValueChanged(object sender, EventArgs e)
730 {
731 if (hist != null)
732 {
733 hist.GraphMax = (int)graphMax.Value;
734 hist.UpdateView();
735 }
736 }
742 private void binBox_ValueChanged(object sender, EventArgs e)
743 {
744 if (hist != null)
745 {
746 hist.Bin = (int)binBox.Value;
747 hist.UpdateView();
748 }
749 }
750
755 private void ChannelsTool_MouseDown(object sender, ButtonPressEventArgs e)
756 {
757
758 }
765 private void setMinToolStripMenuItem_Click(object o, ButtonPressEventArgs args)
766 {
767 minBox.Value = (int)hist.MouseValX;
768 }
769
776 private void setMaxToolStripMenuItem_Click(object o, ButtonPressEventArgs args)
777 {
778 maxBox.Value = (int)hist.MouseValX;
779 }
780
785 private void applyBut_Click(object o, ButtonPressEventArgs args)
786 {
787 ImageView.SelectedImage.Bake(ImageView.SelectedImage.RChannel.RangeR, ImageView.SelectedImage.GChannel.RangeG, ImageView.SelectedImage.BChannel.RangeB);
788 }
789
797 private void minToolStripMenuItem_Click(object o, ButtonPressEventArgs args)
798 {
799 if (TryGetSelectedStatistics(out Statistics statistics))
800 minBox.Value = statistics.StackMin;
801 }
802
809 private void maxToolStripMenuItem_Click(object o, ButtonPressEventArgs args)
810 {
811 if (TryGetSelectedStatistics(out Statistics statistics))
812 minBox.Value = statistics.StackMax;
813 }
814
822 private void medianToolStripMenuItem_Click(object o, ButtonPressEventArgs args)
823 {
824 if (TryGetSelectedStatistics(out Statistics statistics))
825 minBox.Value = statistics.StackMedian;
826 }
827
834 private void meanToolStripMenuItem_Click(object o, ButtonPressEventArgs args)
835 {
836 if (TryGetSelectedStatistics(out Statistics statistics))
837 minBox.Value = statistics.StackMean;
838 }
839
846 private void toolStripMenuItem1_Click(object o, ButtonPressEventArgs args)
847 {
848 if (TryGetSelectedStatistics(out Statistics statistics))
849 maxBox.Value = statistics.StackMin;
850 }
851
858 private void toolStripMenuItem2_Click(object o, ButtonPressEventArgs args)
859 {
860 if (TryGetSelectedStatistics(out Statistics statistics))
861 maxBox.Value = statistics.StackMax;
862 }
869 private void toolStripMenuItem3_Click(object o, ButtonPressEventArgs args)
870 {
871 if (TryGetSelectedStatistics(out Statistics statistics))
872 maxBox.Value = statistics.StackMedian;
873 }
880 private void toolStripMenuItem4_Click(object o, ButtonPressEventArgs args)
881 {
882 if (TryGetSelectedStatistics(out Statistics statistics))
883 maxBox.Value = statistics.StackMean;
884 }
885
891 private void updateBut_Click(object o, ButtonPressEventArgs args)
892 {
893 if (ImageView.SelectedImage.bitsPerPixel > 8)
894 {
895 ImageView.SelectedImage.StackThreshold(true);
896 GetChannelLimits(SelectedChannel, SelectedSample,
897 out int thresholdMin, out int thresholdMax);
898 maxBox.Value = thresholdMax;
899 minBox.Value = thresholdMin;
900 }
901 else
902 {
903 ImageView.SelectedImage.StackThreshold(false);
904 }
905 App.viewer.RefreshPyramidalTiles();
906 App.viewer.UpdateImage();
907 }
908
914 private void sampleBox_ValueChanged(object sender, EventArgs e)
915 {
916 if (channelsBox.Active == -1)
917 channelsBox.Active = 0;
918 UpdateValues();
919 if (hist != null)
920 {
921 //hist.Statistics = Channels[channelsBox.Active].statistics;
922 hist.UpdateChannel(SelectedChannel);
923 hist.QueueDraw();
924 }
925 App.viewer.RefreshPyramidalTiles();
926 App.viewer.UpdateView();
927 }
928
934 private void excitationBox_ValueChanged(object sender, EventArgs e)
935 {
936 SelectedChannel.Excitation = (int)excitationBox.Value;
937 }
938
944 private void emissionBox_ValueChanged(object sender, EventArgs e)
945 {
946 SelectedChannel.Emission = (int)emissionBox.Value;
947 }
948
954 private void fluorBox_TextChanged(object sender, EventArgs e)
955 {
956 SelectedChannel.Fluor = fluorBox.Text;
957 }
958 }
959}
void UpdateItems()
It takes the list of channels and adds them to the ComboBox.
void UpdateChannel(Channel c)
Definition ML.cs:17