namespace OINA.Extender.Testharness { using System; using System.Collections.Generic; using System.Collections.Specialized; using System.ComponentModel; using System.Drawing; using System.Drawing.Imaging; using System.Globalization; using System.IO; using System.Linq; using System.Runtime.Serialization; using System.Text; using System.Threading; using System.Windows.Forms; using OINA.Extender.Acquisition; using OINA.Extender.Acquisition.Ed; using OINA.Extender.Controls; using OINA.Extender.Controls.Common; using OINA.Extender.Controls.Image; using OINA.Extender.Controls.Spectrum; using OINA.Extender.Data; using OINA.Extender.Data.Ed; using OINA.Extender.Data.Image; using OINA.Extender.Processing; using OINA.Extender.Processing.Quant; using OINA.Extender.Testharness.Properties; using WindowsMedia = System.Windows.Media; /// /// MainForm Class /// public partial class MainForm : Form { /// /// List of EdSpectrum objects /// private readonly Dictionary edSpectrumList = new Dictionary(); /// /// List of ElectronImage objects /// private readonly List electronImageList = new List(); /// /// SpectrumViewer object /// private SpectrumViewer spectrumViewer; /// /// ElementCombo object for exclude element /// private ElementCombo excludeElementCombo; /// /// ElementCombo object for deconvolution element /// private ElementCombo deconvolutionElementCombo; /// /// The periodic table control /// private PeriodicTableControl periodicTableControl; /// /// imageViewer object /// private ImageViewer imageViewer; /// /// The comparison spectra /// private List comparisonSpectra; /// /// The periodic table control visual settings window /// private Form periodicTableVisualSettings; /// /// The element combo control visual settings window /// private Form elementComboVisualSettings; /// /// The spectrum viewer control visual settings window /// private Form spectrumViewerVisualSettings; /// /// The image viewer control visual settings window /// private Form imageViewVisualSettingsForm; /// /// The brightness/contrast dialog visual settings window /// private Form brightnessContrastDialogVisualSettings; /// /// The details dialog visual settings window /// private Form detailsDialogVisualSettingsForm; /// /// MainForm Constructor /// public MainForm() { this.InitializeComponent(); this.LoadComparisonSpectra(); this.cbCompareColor.DataSource = Enum.GetValues(typeof(KnownColor)); this.imageToolComboBox.DataSource = Enum.GetValues(typeof(ImageInteractionTool)); this.spectrumInteractionToolComboBox.DataSource = Enum.GetValues(typeof(InteractionTool)); // Binding spectrum acquisition controller events OIHelper.EdSpectrumAcquisitionController.ExperimentStarted += this.OnEdSpectrumExperimentStarted; OIHelper.EdSpectrumAcquisitionController.ExperimentFinished += this.OnEdSpectrumExperimentFinished; // Binding image acquisition controller events OIHelper.ImageAcquisitionController.ExperimentStarted += this.OnImageExperimentStarted; OIHelper.ImageAcquisitionController.ExperimentFinished += this.OnImageExperimentFinished; // Initial UI contents this.InitialSpectrumViewerElementHost(); this.InitialImageViewerElementHost(); this.InitialPeriodicTableElementHost(); this.InitialSpectrumSettingsContent(); this.InitialImageSettingsContent(); this.InitialTimers(); this.InitialProcessingSettingsContent(); this.InitializeEnabledElementsMenuItems(); this.cbCompareColor.SelectedItem = GetRandomColor(); this.spectrumInteractionToolComboBox.SelectedItem = this.spectrumViewer.InteractionTool; this.UpdateHighlightedElementInTable(); } /// /// Gets the random color. /// /// A random color private static KnownColor GetRandomColor() { Random randomGen = new Random(); KnownColor[] colors = Enum.GetValues(typeof(KnownColor)) as KnownColor[]; int index = randomGen.Next(colors.Length); return colors[index]; } /// /// Gets a value indicating whether this instance is acquiring. /// /// /// true if this instance is acquiring; otherwise, false. /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification = "n/a")] private bool IsAcquiring { get { return OIHelper.EdSpectrumAcquisitionController.IsAcquiring; } } #region Status Event Handlers /// /// OnAcquisitionStatusTimerTicked /// /// sender object /// EvenArgs private void OnAcquisitionStatusTimerTicked(object sender, EventArgs e) { if (OIHelper.EdSpectrumAcquisitionController.IsAcquiring || OIHelper.ImageAcquisitionController.IsAcquiring) { this.lblAcquisitionStatus.Visible = !this.lblAcquisitionStatus.Visible; } else { this.lblAcquisitionStatus.Visible = false; } } /// /// OnIdentifyTimerTicked /// /// sender object /// The instance containing the event data. private void OnIdentifyTimerTicked(object sender, EventArgs e) { this.DoAutoID(); } /// /// Called when [ed spectrum experiment started]. /// /// The sender. /// The instance containing the event data. private void OnEdSpectrumExperimentStarted(object sender, AcquisitionStartedEventArgs e) { var edSpectrum = e.Value; // execute on UI thread this.BeginInvoke((Action)delegate { this.spectrumViewer.Spectrum = edSpectrum; // Clear periodic table included and excluded elements this.periodicTableControl.ClearAll(); // Update Known Elements this.periodicTableControl.IncludeElements(OIHelper.AutoIdSettings.KnownElements.ToArray()); this.tmrIdentifyElements.Tick += this.OnIdentifyTimerTicked; this.tmrIdentifyElements.Enabled = true; }); edSpectrum.PropertyChanged += this.OnPropertyChanged; } /// /// Called when [image experiment started]. /// /// The sender. /// The instance containing the event data. private void OnImageExperimentStarted(object sender, AcquisitionStartedEventArgs e) { // execute on UI thread this.BeginInvoke((Action)delegate { this.imageViewer.DisplayImage = e.Value[0]; }); } /// /// OnExperimentFinished /// /// sender object /// The instance containing the event data. private void OnEdSpectrumExperimentFinished(object sender, AcquisitionFinishedEventArgs e) { e.Value.PropertyChanged -= this.OnPropertyChanged; this.tmrIdentifyElements.Tick -= this.OnIdentifyTimerTicked; this.tmrIdentifyElements.Enabled = false; // execute on UI thread this.BeginInvoke((Action)delegate { this.DoAutoID(); this.UpdatePeriodicTable(); this.DoQuant(); if (this.edSpectrumList.ContainsKey(e.Value)) { this.AcquisitionQueueListBox.Items.Remove(this.edSpectrumList[e.Value]); this.edSpectrumList.Remove(e.Value); } // *** If this is the last experiment, call EndMultipleAcquisition on the Acquisition // *** controller, to re-enable external scan switching if (!this.edSpectrumList.Any()) { OIHelper.EdSpectrumAcquisitionController.EndMultipleAcquisition(); } }); } /// /// Called when [image experiment finished]. /// /// The sender. /// The instance containing the event data. private void OnImageExperimentFinished(object sender, AcquisitionFinishedEventArgs e) { // execute on UI thread this.BeginInvoke((Action)delegate { e.Value.ToList().ForEach(i => { this.electronImageList.Remove(i); this.ImageAcquisitionQueueListBox.Items.Remove(i); }); }); } /// /// OnPropertyChanged /// /// Event source /// Event arguments private void OnPropertyChanged(object sender, PropertyChangedEventArgs e) { var edSpectrum = sender as IEdSpectrum; switch (e.PropertyName) { case "RealTimeSeconds": this.Invoke((MethodInvoker)delegate { this.textRealTimeSeconds.Text = edSpectrum.RealTimeSeconds.ToString(@"0.000", CultureInfo.InvariantCulture); }); break; case "LiveTimeSeconds": this.Invoke((MethodInvoker)delegate { this.textLiveTimeSeconds.Text = edSpectrum.LiveTimeSeconds.ToString(@"0.000", CultureInfo.InvariantCulture); }); break; case "OutputRate": this.Invoke((MethodInvoker)delegate { this.outputStatus.Text = OIHelper.MonitoringController.EdStatus.Values.Sum(status => status.OutputRate).ToString(CultureInfo.InvariantCulture) + @"cps"; }); break; case "DeadTime": this.Invoke((MethodInvoker)delegate { this.deadtimeStatus.Text = OIHelper.MonitoringController.EdStatus.Values.Max(status => status.DeadTime).ToString(CultureInfo.InvariantCulture) + @"%"; }); break; } } #endregion #region Update UI status /// /// InitialSpectrumSettingsContent /// private void InitialSpectrumSettingsContent() { if (OIHelper.EdSpectrumSettings.EdCapabilities.HasHardwareConnection) { this.textSpectrumLabel.Text = @"Spectrum 1"; this.cbAcquisitionMode.Items.Add(EdAcquireMode.LiveTime); this.cbAcquisitionMode.Items.Add(EdAcquireMode.RealTime); this.cbAcquisitionMode.SelectedIndex = 0; this.AcquisitionTimeNumericUpDown.Value = 10; this.cbProcessTime.DataSource = OIHelper.EdSpectrumSettings.EdCapabilities.AllowedProcessTimes; this.cbProcessTime.SelectedIndex = 3; this.cbEnergyRange.DataSource = OIHelper.EdSpectrumSettings.EdCapabilities.AllowedEnergyRanges; this.cbEnergyRange.SelectedIndex = 1; this.cbChannelNumber.DataSource = OIHelper.EdSpectrumSettings.EdCapabilities.AllowedNumberOfChannels; this.cbChannelNumber.SelectedIndex = 1; } } /// /// InitialImageSettingsContent /// private void InitialImageSettingsContent() { var settings = OIHelper.ImageSettings; if (settings.ImageCapabilities.HasHardwareConnection) { this.cbImageScanSize.DataSource = OIHelper.GetScanSizes( settings.ScanCapabilities.MinimumPixelSize, settings.ScanCapabilities.MaximumPixelSize); this.cbImageScanSize.SelectedIndex = this.cbImageScanSize.Items.Count > 4 ? 4 : this.cbImageScanSize.Items.Count - 1; this.cbInputSignal.DataSource = settings.ImageCapabilities.AllowedInputSources; this.cbInputSignal.SelectedIndex = 0; this.tbNumberOfFrames.Text = @"1"; this.tbDwellTime.Text = @"40"; } } /// /// Initial Timers /// private void InitialTimers() { this.tmrAcquisitionStatus.Enabled = true; this.tmrAcquisitionStatus.Interval = 1000; this.tmrAcquisitionStatus.Tick += this.OnAcquisitionStatusTimerTicked; this.tmrIdentifyElements.Enabled = false; this.tmrIdentifyElements.Interval = 1000; } /// /// InitialProcessingSettingsContent /// private void InitialProcessingSettingsContent() { this.rbAllElements.Checked = true; this.tbCombinedElement.Enabled = false; this.tbCombinedElement.Text = @"8"; this.tbNumberOfIons.Enabled = false; this.tbNumberOfIons.Text = @"3.0"; this.deconvolutionElementCombo = new ElementCombo(); this.ehDeconvolutionElement.Child = this.deconvolutionElementCombo; this.deconvolutionElementCombo.DisplayFormat = ElementComboDisplayFormat.ShowSymbol; foreach (int i in OIHelper.SEMQuantSettings.DeconvolutionElements) { this.tbDeconvolutionElementList.Text += i.ToString(CultureInfo.InvariantCulture) + System.Environment.NewLine; } this.cbThresholding.Checked = false; this.tbSigmaLevel.Enabled = false; this.tbSigmaLevel.Text = @"3.0"; this.cbIsCoated.Checked = OIHelper.SEMQuantSettings.SampleCoating.IsCoated; this.tbCoatingElement.Enabled = OIHelper.SEMQuantSettings.SampleCoating.IsCoated; this.tbCoatingElement.Text = OIHelper.SEMQuantSettings.SampleCoating.CoatingElement.ToString(CultureInfo.InvariantCulture); this.tbDensity.Enabled = OIHelper.SEMQuantSettings.SampleCoating.IsCoated; this.tbDensity.Text = OIHelper.SEMQuantSettings.SampleCoating.Density.ToString(CultureInfo.InvariantCulture); this.tbThickness.Enabled = OIHelper.SEMQuantSettings.SampleCoating.IsCoated; this.tbThickness.Text = OIHelper.SEMQuantSettings.SampleCoating.Thickness.ToString(CultureInfo.InvariantCulture); this.excludeElementCombo = new ElementCombo(); this.ehExcludeElement.Child = this.excludeElementCombo; this.excludeElementCombo.DisplayFormat = ElementComboDisplayFormat.ShowName; this.excludeElementCombo.PropertyChanged += this.ExcludeElementCombo_PropertyChanged; this.UpdateElementsList(this.periodicTableControl.ExcludedElements, this.tbExcludedElementList); this.UpdateElementsList(this.periodicTableControl.IncludedElements, this.tbIncludedElementList); this.UpdateElementsList(this.periodicTableControl.UnsetElements, this.tbUnsetElementList); } /// /// InitialSpectrumViewerElementHost /// private void InitialSpectrumViewerElementHost() { this.spectrumViewer = new SpectrumViewer(); this.ehSpectrumViewer.Child = this.spectrumViewer; this.spectrumViewer.IsXAxisAutoScaleEnabled = false; this.spectrumViewer.IsYAxisAutoScaleEnabled = true; } /// /// InitialImageViewerElementHost /// private void InitialImageViewerElementHost() { this.imageViewer = new ImageViewer(); this.ehImageViewer.Child = this.imageViewer; } /// /// Initials the periodic table element host. /// private void InitialPeriodicTableElementHost() { this.periodicTableControl = new PeriodicTableControl(); this.periodicTableElementHost.Child = this.periodicTableControl; // Set the Periodic Table BackColor (0xFF07366B) same as Spectrum Viewer this.periodicTableElementHost.BackColor = Color.FromArgb(255, 7, 54, 107); foreach (object knownColor in Enum.GetValues(typeof(System.Drawing.KnownColor))) { this.periodicTableBackgroundToolStripComboBox.Items.Add(knownColor); } ((INotifyCollectionChanged)this.periodicTableControl.ExcludedElements).CollectionChanged += this.PeriodicTableExcludedElements_CollectionChanged; ((INotifyCollectionChanged)this.periodicTableControl.IncludedElements).CollectionChanged += this.PeriodicTableIncludedElements_CollectionChanged; ((INotifyCollectionChanged)this.periodicTableControl.UnsetElements).CollectionChanged += this.PeriodicTableUnsetElements_CollectionChanged; } /// /// Update the Periodic Table content after acquisition finished /// private void UpdatePeriodicTable() { this.periodicTableControl.IncludeElements(this.spectrumViewer.Spectrum.IdentifiedElements.ToArray()); } /// /// Updates the elements list. /// /// The data. /// The list. [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification = "Ignore")] private void UpdateElementsList(IEnumerable data, TextBox list) { list.Clear(); foreach (int i in data.OrderBy(x => x).ToArray()) { list.Text += ElementProperties.GetElementName(i) + System.Environment.NewLine; } } #endregion #region Control acquisition from UI /// /// StartAcquisition button click handler /// /// sender object /// EventArgs private void StartAcquisitionButton_Click(object sender, EventArgs e) { this.spectrumViewer.ClearComparisonSpectra(); this.AcquireSpectrum(false); } /// /// ResumeAcquisition button click handler /// /// sender object /// EventArgs private void ResumeAcquisitionButton_Click(object sender, EventArgs e) { if (this.spectrumViewer.Spectrum != null && !this.IsAcquiring) { this.AcquireSpectrum(true); } } /// /// Start Acquire Spectrum Process /// /// true if is resume private void AcquireSpectrum(bool isResume) { IEdSpectrum edSpectrum = null; // Spectrum acquisition settings confirm var edSpectrumSettings = OIHelper.EdSpectrumSettings; var edSpectrumAcquisitionController = OIHelper.EdSpectrumAcquisitionController; edSpectrumSettings.EdSettings.AcquisitionMode = (EdAcquireMode)this.cbAcquisitionMode.SelectedItem; edSpectrumSettings.EdSettings.AcquisitionTime = TimeSpan.FromSeconds((int)this.AcquisitionTimeNumericUpDown.Value); edSpectrumSettings.EdSettings.ProcessTime = (int)this.cbProcessTime.SelectedValue; edSpectrumSettings.EdSettings.EnergyRange = (int)this.cbEnergyRange.SelectedValue; edSpectrumSettings.EdSettings.NumberOfChannels = (int)this.cbChannelNumber.SelectedValue; edSpectrumSettings.ScanSettings.AcquisitionRegion.CreateMicroscopeRegion(); // SpectrumViewer settings confirm this.spectrumViewer.MaximumEnergy = edSpectrumSettings.EdSettings.EnergyRange; // If Ed hardware is not ready, the software will crash. if (edSpectrumAcquisitionController.IsEdHardwareReady(edSpectrumSettings)) { // *** If this is the first acquisition, call BeginMultipleAcquisition // *** on the AcquisitionController to suppress external scan switching if (!this.edSpectrumList.Any()) { edSpectrumAcquisitionController.BeginMultipleAcquisition(); } if (!isResume) { // Start spectrum acquisition try { edSpectrum = edSpectrumAcquisitionController.StartAcquisition(edSpectrumSettings); edSpectrum.Label = string.Format(CultureInfo.CurrentCulture, @"{0} ({1:HH:mm:ss})", this.textSpectrumLabel.Text, DateTime.Now); this.edSpectrumList.Add(edSpectrum, new AcquisitionItem(edSpectrum, OIHelper.EdSpectrumSettings.EdSettings.AcquisitionMode, OIHelper.EdSpectrumSettings.EdSettings.AcquisitionTime.TotalMilliseconds, this.AcquisitionQueueListBox)); this.AcquisitionQueueListBox.Items.Add(this.edSpectrumList[edSpectrum]); } catch (InvalidSettingsException invalidSettingsException) { MessageBox.Show(invalidSettingsException.Message, Resources.CannotStartAcquisitionTitle, MessageBoxButtons.OK, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly); } catch (AcquisitionStartException acquisitionStartException) { MessageBox.Show(acquisitionStartException.Message, Resources.CannotStartAcquisitionTitle, MessageBoxButtons.OK, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly); } } else { edSpectrum = this.spectrumViewer.Spectrum; edSpectrumAcquisitionController.ResumeAcquisition(edSpectrumSettings, edSpectrum); this.edSpectrumList.Add(edSpectrum, new AcquisitionItem(edSpectrum, OIHelper.EdSpectrumSettings.EdSettings.AcquisitionMode, OIHelper.EdSpectrumSettings.EdSettings.AcquisitionTime.TotalMilliseconds, this.AcquisitionQueueListBox)); this.AcquisitionQueueListBox.Items.Add(this.edSpectrumList[edSpectrum]); } } } /// /// StopAcquisition button click handler /// /// sender object /// EventArgs private void StopAcquisitionButton_Click(object sender, EventArgs e) { if (OIHelper.EdSpectrumAcquisitionController.IsAcquiring == true) { OIHelper.EdSpectrumAcquisitionController.StopAcquisition(); } } /// /// Handles the Click event of Calculate button. /// /// The source of the event. /// The instance containing the event data. private void CalculateButton_Click(object sender, EventArgs e) { try { int atomicNum = ElementProperties.GetAtomicNumberByElementSymbol(this.tbIdentifiedElement.SelectedText); var peakParameters = OIHelper.EdSpectrumProcessing.CalculatePeakParameters(this.spectrumViewer.Spectrum, atomicNum); this.tbEnergy.Text = peakParameters.Centre.ToString(CultureInfo.InvariantCulture); this.tbFWHM.Text = peakParameters.FWHM.ToString(CultureInfo.InvariantCulture); } catch (NullReferenceException) { } catch (FormatException) { } catch (InvalidOperationException) { } } /// /// Handles the Click event of StartImageScan button. /// /// The source of the event. /// The instance containing the event data. private void StartImageScanButton_Click(object sender, EventArgs e) { var imageSettings = OIHelper.ImageSettings.ImageSettings; var imageCapabilities = OIHelper.ImageSettings.ImageCapabilities; var scanSettings = OIHelper.ImageSettings.ScanSettings; var imageAcquisitionController = OIHelper.ImageAcquisitionController; this.tbImageData.Text = string.Empty; this.tbPointX.Text = string.Empty; this.tbPointY.Text = string.Empty; var value = int.Parse(this.tbDwellTime.Text, CultureInfo.InvariantCulture); if (value > imageCapabilities.MaximumImageDwellMicroseconds) { imageSettings.DwellTimeMicroSeconds = imageCapabilities.MaximumImageDwellMicroseconds; } if (value < imageCapabilities.MinimumImageDwellMicroseconds) { imageSettings.DwellTimeMicroSeconds = imageCapabilities.MinimumImageDwellMicroseconds; } else { imageSettings.DwellTimeMicroSeconds = value; } // *** Disable all input sources before enabling the one that the user has chosen imageSettings.InputSources.ToList().ForEach(i => imageSettings.EnableInputSource(i.Key, false)); imageSettings.EnableInputSource((ImageInputSources)this.cbInputSignal.SelectedItem, true); scanSettings.FrameCount = int.Parse(this.tbNumberOfFrames.Text, CultureInfo.InvariantCulture); var pixelSize = 1d / double.Parse(this.cbImageScanSize.Text, CultureInfo.InvariantCulture); scanSettings.AcquisitionRegion.CreateFullFieldRegion(pixelSize); try { var images = imageAcquisitionController.StartAcquisition(OIHelper.ImageSettings).ToList(); images.ForEach(i => { i.Label = string.Format(CultureInfo.CurrentCulture, @"{0} ({1:HH:mm:ss})", @"ElectronImage", DateTime.Now); this.electronImageList.Add(i); this.ImageAcquisitionQueueListBox.Items.Add(i); }); } catch (InvalidSettingsException exception) { var sb = new StringBuilder(@"Invalid settings have been supplied:"); sb.AppendLine(); exception.ValidationResults.ValidationErrors .ToList() .ForEach(ve => sb.AppendFormat(CultureInfo.CurrentCulture, @"{0} {1}", Environment.NewLine, ve)); MessageBox.Show(sb.ToString(), @"Invalid settings", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } } /// /// Handles the Click event of StopImageScan button. /// /// The source of the event. /// The instance containing the event data. private void StopImageScanButton_Click(object sender, EventArgs e) { if (OIHelper.ImageAcquisitionController.IsAcquiring) { OIHelper.ImageAcquisitionController.StopAcquisition(); } } /// /// Handles the Click event of GetPixelData button. /// /// The source of the event. /// The instance containing the event data. private void GetPixelDataButton_Click(object sender, EventArgs e) { if ((!OIHelper.ImageAcquisitionController.IsAcquiring) & (this.imageViewer.DisplayImage != null)) { var electronImage = this.imageViewer.DisplayImage as IElectronImage; if (electronImage != null) { try { int x = int.Parse(this.tbPointX.Text, CultureInfo.InvariantCulture); int y = int.Parse(this.tbPointY.Text, CultureInfo.InvariantCulture); var stringBuilder = new StringBuilder(); stringBuilder.AppendFormat(CultureInfo.CurrentCulture, @" Point({0},{1}), Value: {2}", x, y, electronImage.GetData(new Point(x, y))); stringBuilder.Append(Environment.NewLine); this.tbImageData.Text = stringBuilder.ToString(); } catch (ArgumentOutOfRangeException) { //// stringBuilder - The length of the expanded string would exceed MaxCapacity. } catch (FormatException) { //// int.Parse - The x or y coordinates are not in the correct format. } } } } #endregion #region ToolStripMenuItem handlers /// /// Handles the Click event of the elementComboVisualSettingsToolStripMenuItem control. /// /// The source of the event. /// instance containing the event data. private void ExportSpectrumAsToolStripMenuItem_Click(object sender, EventArgs e) { string filter = @"Bitmap (*.bmp)|*.bmp|PNG (*.png)|*.png|TIFF (*.tif)|*.tif|JPEG (*.jpg)|*.jpg"; string title = @"Export Spectrum As..."; try { short width = (short)this.spectrumViewer.ActualWidth; short height = (short)this.spectrumViewer.ActualHeight; Bitmap bitmap = OIHelper.EdSpectrumProcessing.CreateBitmap(this.spectrumViewer.Spectrum, width, height); using (SaveFileDialog exportSpectrumDialog = new SaveFileDialog()) { exportSpectrumDialog.Filter = filter; exportSpectrumDialog.Title = title; exportSpectrumDialog.FilterIndex = 1; if (exportSpectrumDialog.ShowDialog() == DialogResult.OK) { switch (exportSpectrumDialog.FilterIndex) { case 1: bitmap.Save(exportSpectrumDialog.FileName, ImageFormat.Bmp); break; case 2: bitmap.Save(exportSpectrumDialog.FileName, ImageFormat.Png); break; case 3: bitmap.Save(exportSpectrumDialog.FileName, ImageFormat.Tiff); break; case 4: bitmap.Save(exportSpectrumDialog.FileName, ImageFormat.Jpeg); break; default: bitmap.Save(exportSpectrumDialog.FileName, ImageFormat.Bmp); break; } } } } catch (ArgumentException) { } } /// /// ExitToolStripMenuItem click handler /// /// sender object /// EventArgs private void ExitToolStripMenuItem_Click(object sender, EventArgs e) { Application.Exit(); } /// /// Detector Control Tool strip menu item click handler /// /// sender object /// EventArgs private void DetectorControlToolStripMenuItem_Click(object sender, EventArgs e) { Form detectorControlPanel = new DetectorControlPanel(OIHelper.EdDetectorControl); detectorControlPanel.Show(); } /// /// Microscope Control Tool strip menu item click handler /// /// sender object /// EventArgs private void MicroscopeControlToolStripMenuItem_Click(object sender, EventArgs e) { Form microscopeControlPanel = new MicroscopeControlPanel(); microscopeControlPanel.Show(); } /// /// Calibrate ToolStrip MenuItem Click event handler. /// /// sender /// e private void CalibrateToolStripMenuItem_Click(object sender, EventArgs e) { Form calibrate = new Calibrate(); calibrate.Show(); } /// /// Auto Id Settings Form /// /// sender /// EventArgs private void AutoIdSettingsToolStripMenuItem_Click(object sender, EventArgs e) { Form autoIDSettings = new AutoIdSettings(); autoIDSettings.Show(); } /// /// Handles the Click event of the periodicTableVisualSettingsToolStripMenuItem control. /// /// The source of the event. /// The instance containing the event data. private void PeriodicTableVisualSettingsToolStripMenuItem_Click(object sender, EventArgs e) { if (this.periodicTableVisualSettings == null || this.periodicTableVisualSettings.IsDisposed) { this.periodicTableVisualSettings = new PeriodicTableVisualSettings(); } this.periodicTableVisualSettings.Show(); this.periodicTableVisualSettings.BringToFront(); } /// /// Handles the Click event of the elementComboVisualSettingsToolStripMenuItem control. /// /// The source of the event. /// The instance containing the event data. private void ElementComboVisualSettingsToolStripMenuItem_Click(object sender, EventArgs e) { if (this.elementComboVisualSettings == null || this.elementComboVisualSettings.IsDisposed) { this.elementComboVisualSettings = new ElementComboVisualSettings(); } this.elementComboVisualSettings.Show(); this.elementComboVisualSettings.BringToFront(); } /// /// Handles the Click event of the SpectrumViewerVisualSettingsToolStripMenuItem control. /// /// The source of the event. /// The instance containing the event data. private void SpectrumViewerVisualSettingsToolStripMenuItem_Click(object sender, EventArgs e) { if (this.spectrumViewerVisualSettings == null || this.spectrumViewerVisualSettings.IsDisposed) { this.spectrumViewerVisualSettings = new SpectrumViewerVisualSettings(); } this.spectrumViewerVisualSettings.Show(); this.spectrumViewerVisualSettings.BringToFront(); } /// /// Handles the Click event of the ImageViewerVisualSetting control. /// /// The source of the event. /// The instance containing the event data. private void ImageViewerVisualSetting_Click(object sender, EventArgs e) { if (this.imageViewVisualSettingsForm == null || this.imageViewVisualSettingsForm.IsDisposed) { this.imageViewVisualSettingsForm = new ImageViewerVisualSettings(); } this.imageViewVisualSettingsForm.Show(); this.imageViewVisualSettingsForm.BringToFront(); } /// /// Handles the Click event of the BrightnessContractDialogVisualSettingsToolStripMenuItem control. /// /// The source of the event. /// The instance containing the event data. private void BrightnessContractDialogVisualSettingsToolStripMenuItem_Click(object sender, EventArgs e) { if (this.brightnessContrastDialogVisualSettings == null || this.brightnessContrastDialogVisualSettings.IsDisposed) { this.brightnessContrastDialogVisualSettings = new BCDialogVisualSettings(); } this.brightnessContrastDialogVisualSettings.Show(); this.brightnessContrastDialogVisualSettings.BringToFront(); } /// /// Called when [details visual settings menu item click]. /// /// The sender. /// The instance containing the event data. private void OnDetailsVisualSettingsMenuItemClick(object sender, EventArgs e) { if (this.detailsDialogVisualSettingsForm == null || this.detailsDialogVisualSettingsForm.IsDisposed) { this.detailsDialogVisualSettingsForm = new DetailDialogVisualSettings(); } this.detailsDialogVisualSettingsForm.Show(); this.detailsDialogVisualSettingsForm.BringToFront(); } /// /// Handles the Click event of the LoadSpectrumDataToolStripMenuItem_Click. /// /// The source of the event. /// The instance containing the event data. private void LoadSpectrumDataToolStripMenuItem_Click(object sender, EventArgs e) { try { using (var of_dlg = new OpenFileDialog()) { of_dlg.Title = @"Select a file"; of_dlg.Filter = @"Esd(*.esd)|*.esd|Iex(*.iex)|*.iex"; of_dlg.FilterIndex = 1; if (of_dlg.ShowDialog() == DialogResult.OK) { if (!File.Exists(of_dlg.FileName)) { throw new InvalidOperationException("File does not exists!"); } this.spectrumViewer.ClearComparisonSpectra(); switch (of_dlg.FilterIndex) { case 1: this.spectrumViewer.Spectrum = DataFactory.LoadEdSpectrum(OIHelper.FileToByteArray(of_dlg.FileName)); break; case 2: this.spectrumViewer.Spectrum = DataFactory.LoadEdSpectrumFromIex(of_dlg.FileName); break; } // Set Periodic Table control element state this.periodicTableControl.ClearAll(); this.periodicTableControl.IncludeElements(this.spectrumViewer.Spectrum.IdentifiedElements.ToArray()); } } } catch (SerializationException) { } } /// /// SaveSpectrumDataToolStripMenuItem_Click /// /// The source of the event. /// The instance containing the event data. private void SaveSpectrumDataToolStripMenuItem_Click(object sender, EventArgs e) { string filter = @"Esd(*.esd)|*.esd|Iex(*.iex)|*.iex"; string title = @"Save spectrum as"; var spectrum = this.spectrumViewer.Spectrum; if (spectrum != null) { try { using (var dialog = new SaveFileDialog()) { dialog.Filter = filter; dialog.Title = title; dialog.FilterIndex = 1; if (dialog.ShowDialog() == DialogResult.OK) { switch (dialog.FilterIndex) { case 1: byte[] spectrumData = spectrum.Save(); OIHelper.ByteArrayToFile(dialog.FileName, spectrumData); break; case 2: OIHelper.EdSpectrumProcessing.CreateIexSpectrum(dialog.FileName, spectrum); break; default: break; } } } } catch (ArgumentException) { } } } /// /// Handles the Click event of the LoadImageDataToolStripMenuItem_Click. /// /// The source of the event. /// The instance containing the event data. private void LoadImageDataToolStripMenuItem_Click(object sender, EventArgs e) { try { using (OpenFileDialog dialog = new OpenFileDialog()) { dialog.Title = @"Select a file"; dialog.Filter = @"Img(*.img)|*.img"; dialog.FilterIndex = 1; if (dialog.ShowDialog() == DialogResult.OK) { this.imageViewer.DisplayImage = null; if (!File.Exists(dialog.FileName)) { throw new System.InvalidOperationException("File does not exists!"); } this.imageViewer.DisplayImage = DataFactory.LoadElectronImage(OIHelper.FileToByteArray(dialog.FileName)); } } } catch (SerializationException) { } } /// /// SaveImageDataToolStripMenuItem_Click /// /// The source of the event. /// The instance containing the event data. private void SaveImageDataToolStripMenuItem_Click(object sender, EventArgs e) { string filter = @"Img(*.img)|*.img"; string title = @"Save image as"; if (this.imageViewer.DisplayImage != null) { try { var electronImage = this.imageViewer.DisplayImage; using (SaveFileDialog dialog = new SaveFileDialog()) { dialog.Filter = filter; dialog.Title = title; dialog.FilterIndex = 1; if (dialog.ShowDialog() == DialogResult.OK) { byte[] imageData = electronImage.Save(); OIHelper.ByteArrayToFile(dialog.FileName, imageData); } } } catch (ArgumentException) { } } } /// /// EDMapAcquisitionToolStripMenuItem_Click /// /// The source of the event. /// instance containing the event data. private void EDMapAcquisitionToolStripMenuItem_Click(object sender, EventArgs e) { #if ENABLE_MAP_ACQUIRE EdMapAcquisition edMapAcquisition = new EdMapAcquisition(); edMapAcquisition.Show(); #endif } #endregion #region Control Spectrum Processing #region Control AutoID /// /// Add element to excluded list /// /// sender object /// EventArgs private void AddExcludeButton_Click(object sender, EventArgs e) { int element = this.excludeElementCombo.CurrentElement; try { this.periodicTableControl.ExcludeElements(element); } catch (FormatException fe) { this.tbExcludedElementList.Text = fe.Message; } } /// /// Remove element from excluded list /// /// sender object /// EventArgs private void DeleteExcludeButton_Click(object sender, EventArgs e) { int element = this.excludeElementCombo.CurrentElement; try { this.periodicTableControl.Clear(element); } catch (FormatException fe) { this.tbExcludedElementList.Text = fe.Message; } } /// /// Do AutoID Button Click Handler /// /// sender object /// EventArgs private void DoAutoIDButton_Click(object sender, EventArgs e) { this.DoAutoID(); } /// /// Do AutoID /// private void DoAutoID() { var spectrum = this.spectrumViewer.Spectrum; if (spectrum != null) { this.tbIdentifiedElement.Clear(); IEnumerable elementList = OIHelper.EdSpectrumProcessing.IdentifyElements( spectrum, OIHelper.AutoIdSettings); foreach (int i in elementList) { this.tbIdentifiedElement.Text = this.tbIdentifiedElement.Text + ElementProperties.GetElementSymbol(i) + Environment.NewLine; } // Update spectrum peak label this.UpdateSpectrumPeakLabels(); } } /// /// Update current spectrum peak labels /// private void UpdateSpectrumPeakLabels() { try { OIHelper.EdSpectrumProcessing.UpdatePeakLabels(this.spectrumViewer.Spectrum, null); } catch (ArgumentNullException) { } catch (InvalidOperationException) { } } #endregion #region Control Quantitative Analysis /// /// Do quant button click handler /// /// sender object /// EventArgs private void DoQuantButton_Click(object sender, EventArgs e) { this.DoQuant(); } /// /// Do quantitative processing and display /// private void DoQuant() { switch (OIHelper.SEMQuantSettings.ProcessingOption) { case ProcessingOption.ElementByDifference: OIHelper.SEMQuantSettings.CombinedElement = int.Parse(this.tbCombinedElement.Text, CultureInfo.InvariantCulture); break; case ProcessingOption.ElementByStoichiometry: // While it is possible to choose other elements, Oxygen is the only supported element by stoichiometry. OIHelper.SEMQuantSettings.CombinedElement = 8; OIHelper.SEMQuantSettings.TypeOfIon = IonType.Anion; OIHelper.SEMQuantSettings.NumberOfIons = double.Parse(this.tbNumberOfIons.Text, CultureInfo.InvariantCulture); break; case ProcessingOption.AllElements: default: break; } if (this.cbIsCoated.Checked) { OIHelper.SEMQuantSettings.SampleCoating.IsCoated = true; OIHelper.SEMQuantSettings.SampleCoating.Thickness = double.Parse(this.tbThickness.Text, CultureInfo.InvariantCulture); OIHelper.SEMQuantSettings.SampleCoating.Density = double.Parse(this.tbDensity.Text, CultureInfo.InvariantCulture); OIHelper.SEMQuantSettings.SampleCoating.CoatingElement = int.Parse(this.tbCoatingElement.Text, CultureInfo.InvariantCulture); } else { OIHelper.SEMQuantSettings.SampleCoating.IsCoated = false; } if (this.cbThresholding.Checked) { OIHelper.SEMQuantSettings.Thresholding = true; OIHelper.SEMQuantSettings.SigmaLevel = double.Parse(this.tbSigmaLevel.Text, CultureInfo.InvariantCulture); } else { OIHelper.SEMQuantSettings.Thresholding = false; } OIHelper.SEMQuantSettings.Normalised = this.cbNormalised.Checked; this.dgQuantResult.Rows.Clear(); try { ISEMQuantStatus quantStatus = OIHelper.EdSpectrumProcessing.SEMQuantifySpectrum(this.spectrumViewer.Spectrum, OIHelper.SEMQuantSettings); this.tbQuantStatusMessage.Text = quantStatus.Status.ToString() + System.Environment.NewLine + quantStatus.StatusMessage; double totalWeightPercent = 0; double totalAtomicPercent = 0; foreach (ISEMQuantResult result in quantStatus.Results) { if (result.WeightPercent != 0) { this.dgQuantResult.Rows.Add(new object[] { ElementProperties.GetElementSymbol(result.AtomicNumber), result.LineType, Math.Round(result.WeightPercent, 2), Math.Round(result.WeightPercentSigma, 6), Math.Round(result.AtomicPercent, 2) }); } totalWeightPercent += result.WeightPercent; totalAtomicPercent += result.AtomicPercent; } this.dgQuantResult.Rows.Add(new object[] { @"Total", null, Math.Round(totalWeightPercent, 2), null, Math.Round(totalAtomicPercent, 2) }); this.spectrumViewer.SEMQuantify(OIHelper.SEMQuantSettings); } catch (QuantificationException ex) { MessageBox.Show(ex.Message, @"Quantification Error", MessageBoxButtons.OK, MessageBoxIcon.Warning); } catch (ArgumentNullException) { } } /// /// The last element set /// private int lastElementSet = -1; /// /// ExcludeElementCombo_PropertyChanged /// /// sender object /// PropertyChangedEventArgs private void ExcludeElementCombo_PropertyChanged(object sender, PropertyChangedEventArgs e) { if (e.PropertyName == @"CurrentElement") { this.UpdateHighlightedElementInTable(); } } /// /// Updates the highlighted element in table. /// private void UpdateHighlightedElementInTable() { if (this.lastElementSet != -1) { this.periodicTableControl.SetElementColor(this.lastElementSet, System.Windows.Media.Colors.Transparent); } System.Windows.Media.Color currentElementColor = System.Windows.Media.Color.FromArgb(255, 200, 255, 0); this.periodicTableControl.SetElementColor(this.excludeElementCombo.CurrentElement, currentElementColor); this.periodicTableControl.ShowElementColors = true; this.lastElementSet = this.excludeElementCombo.CurrentElement; } /// /// Add deconvolution element to list /// /// sender object /// EventArgs private void AddDeconvolutionButton_Click(object sender, EventArgs e) { this.tbDeconvolutionElementList.Clear(); int element = this.deconvolutionElementCombo.CurrentElement; try { OIHelper.SEMQuantSettings.SetDeconvolutionElement(element, true); foreach (int i in OIHelper.SEMQuantSettings.DeconvolutionElements) { this.tbDeconvolutionElementList.Text += i.ToString(CultureInfo.InvariantCulture) + System.Environment.NewLine; } } catch (FormatException fe) { this.tbDeconvolutionElementList.Text = fe.Message; } catch (ArgumentOutOfRangeException ae) { this.tbDeconvolutionElementList.Text = ae.Message; } } /// /// Remove element from deconvolution list /// /// sender object /// EventArgs private void DeleteDeconvolutionButton_Click(object sender, EventArgs e) { this.tbDeconvolutionElementList.Clear(); int element = this.deconvolutionElementCombo.CurrentElement; try { OIHelper.SEMQuantSettings.SetDeconvolutionElement(element, false); foreach (int i in OIHelper.SEMQuantSettings.DeconvolutionElements) { this.tbDeconvolutionElementList.Text += i.ToString(CultureInfo.InvariantCulture) + System.Environment.NewLine; } } catch (FormatException fe) { this.tbDeconvolutionElementList.Text = fe.Message; } } /// /// Clear deconvolution elements /// /// sender object /// EventArgs private void ClearListButton_Click(object sender, EventArgs e) { this.tbDeconvolutionElementList.Clear(); OIHelper.SEMQuantSettings.ClearDeconvolutionElements(); foreach (int i in OIHelper.SEMQuantSettings.DeconvolutionElements) { this.tbDeconvolutionElementList.Text += i.ToString(CultureInfo.InvariantCulture) + System.Environment.NewLine; } } /// /// Used when processing spectra from specimens in which all elements yield X-rays which can be readily detected. /// /// sender object /// EventArgs private void AllElementsRadiobutton_Click(object sender, EventArgs e) { OIHelper.SEMQuantSettings.ProcessingOption = ProcessingOption.AllElements; this.cbNormalised.Enabled = true; this.tbCombinedElement.Enabled = false; this.tbNumberOfIons.Enabled = false; } /// /// Calculated assuming that the difference between the analyzed total and 100% /// /// sender object /// EventArgs private void ElementByDifferenceRadioButton_Click(object sender, EventArgs e) { OIHelper.SEMQuantSettings.ProcessingOption = ProcessingOption.ElementByDifference; this.cbNormalised.Checked = false; this.cbNormalised.Enabled = false; this.tbCombinedElement.Enabled = true; this.tbNumberOfIons.Enabled = false; } /// /// Concentration of oxygen to be calculated. /// /// sender object /// EventArgs private void ElementByStoichiometryRadiobutton_Click(object sender, EventArgs e) { OIHelper.SEMQuantSettings.ProcessingOption = ProcessingOption.ElementByStoichiometry; this.cbNormalised.Enabled = true; this.tbCombinedElement.Enabled = false; this.tbNumberOfIons.Enabled = true; } /// /// ThresholdingCheckbox checked /// /// sender object /// EventArgs private void ThresholdingCheckbox_CheckedChanged(object sender, EventArgs e) { this.tbSigmaLevel.Enabled = this.cbThresholding.Checked; } /// /// IsCoatedCheckbox checked /// /// sender object /// EventArgs private void IsCoatedCheckbox_CheckedChanged(object sender, EventArgs e) { this.tbCoatingElement.Enabled = this.cbIsCoated.Checked; this.tbDensity.Enabled = this.cbIsCoated.Checked; this.tbThickness.Enabled = this.cbIsCoated.Checked; } #endregion #endregion #region Periodic Table /// /// Handles the CollectionChanged event of the PeriodicTableExcludedElements control. /// /// The source of the event. /// The instance containing the event data. private void PeriodicTableExcludedElements_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) { this.UpdateElementsList(this.periodicTableControl.ExcludedElements, this.tbExcludedElementList); } /// /// Handles the CollectionChanged event of the PeriodicTableIncludedElements control. /// /// The source of the event. /// The instance containing the event data. private void PeriodicTableIncludedElements_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) { this.UpdateElementsList(this.periodicTableControl.IncludedElements, this.tbIncludedElementList); var spectrum = this.spectrumViewer.Spectrum; if (spectrum != null) { switch (e.Action) { case NotifyCollectionChangedAction.Add: foreach (int i in e.NewItems.Cast()) { spectrum.SetIdentifiedElement(i, true); } break; case NotifyCollectionChangedAction.Remove: foreach (int i in e.OldItems.Cast()) { spectrum.SetIdentifiedElement(i, false); } break; default: break; } this.UpdateSpectrumPeakLabels(); } } /// /// Handles the CollectionChanged event of the PeriodicTableUnsetElements control. /// /// The source of the event. /// The instance containing the event data. private void PeriodicTableUnsetElements_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) { this.UpdateElementsList(this.periodicTableControl.UnsetElements, this.tbUnsetElementList); } /// /// Handles the CheckedChanged event of the EnableMultiselectToolStripMenuItem control. /// /// The source of the event. /// The instance containing the event data. private void EnableMultiselectToolStripMenuItem_CheckedChanged(object sender, EventArgs e) { this.periodicTableControl.SelectionMode = this.enableMultiselectToolStripMenuItem.Checked ? System.Windows.Controls.SelectionMode.Multiple : System.Windows.Controls.SelectionMode.Single; } /// /// Handles the SelectedIndexChanged event of the PeriodicTableBackgroundToolStripComboBox control. /// /// The source of the event. /// The instance containing the event data. private void PeriodicTableBackgroundToolStripComboBox_SelectedIndexChanged(object sender, EventArgs e) { if (this.periodicTableBackgroundToolStripComboBox.SelectedItem != null) { System.Drawing.Color selectedColor = System.Drawing.Color.FromKnownColor((System.Drawing.KnownColor)this.periodicTableBackgroundToolStripComboBox.SelectedItem); this.periodicTableElementHost.BackColor = selectedColor; this.periodicTableBackgroundToolStripComboBox.BackColor = selectedColor; this.periodicTableBackgroundToolStripComboBox.ForeColor = selectedColor.ToArgb() > (0xFFFFFFFF / 2) ? System.Drawing.Color.Black : System.Drawing.Color.LightGray; } } /// /// Initializes the enabled elements menu items. /// private void InitializeEnabledElementsMenuItems() { ToolStripMenuItem item; for (int element = 1; element <= 103; element++) { IPeriodicTableElement info = this.periodicTableControl.LookupElementInfo(element); if (info != null) { item = new ToolStripMenuItem(info.ElementName); item.CheckOnClick = true; item.Checked = true; item.Tag = element; item.CheckedChanged += this.ElementEnabled_CheckedChanged; this.enabledElementsMenuItem.DropDownItems.Add(item); } } } /// /// Handles the CheckedChanged event of the ElementEnabled control. /// /// The source of the event. /// The instance containing the event data. private void ElementEnabled_CheckedChanged(object sender, EventArgs e) { ToolStripMenuItem menuItem = sender as ToolStripMenuItem; if (menuItem != null) { int elementNo = (int)menuItem.Tag; this.periodicTableControl.EnableElements(menuItem.Checked, elementNo); } } #endregion /// /// Handles the SelectedIndexChanged event of the CbCompareColor control. /// /// The source of the event. /// The instance containing the event data. private void CbCompareColor_SelectedIndexChanged(object sender, EventArgs e) { this.addCompareSpectraButton.BackColor = Color.FromKnownColor((KnownColor)this.cbCompareColor.SelectedItem); } /// /// Called when [image tool ComboBox selected index changed]. /// /// The sender. /// The instance containing the event data. private void OnImageToolComboBoxSelectedIndexChanged(object sender, EventArgs e) { if (this.imageViewer != null) { this.imageViewer.InteractionTool = (ImageInteractionTool)this.imageToolComboBox.SelectedItem; } } /// /// Called when [spectrum tool ComboBox selected index changed]. /// /// The sender. /// The instance containing the event data. private void OnSpectrumToolComboBoxSelectedIndexChanged(object sender, EventArgs e) { if (this.spectrumViewer != null) { this.spectrumViewer.InteractionTool = (InteractionTool)this.spectrumInteractionToolComboBox.SelectedItem; } } /// /// Adds a spectrum for comparison. /// /// The sender. /// The instance containing the event data. private void OnAddCompareSpectraButtonClick(object sender, EventArgs e) { var spectrum = this.cbCompareSpectraComboBox.SelectedItem as IEdSpectrum; if (spectrum != null) { // Add Current Spectrum to Compare source WindowsMedia.Color spectrumColor = ColorConverter.Convert(this.addCompareSpectraButton.BackColor); this.spectrumViewer.AddComparisonSpectrum(spectrum, spectrumColor); this.cbCompareColor.SelectedItem = GetRandomColor(); } } /// /// Loads the comparison spectra. /// private void LoadComparisonSpectra() { byte[] data; this.comparisonSpectra = new List(); using (FileStream file = new FileStream(@"ComparisonSpectra\Nickel.spec", FileMode.Open)) { data = new byte[file.Length]; file.Read(data, 0, (int)file.Length); this.comparisonSpectra.Add(DataFactory.LoadEdSpectrum(data)); } using (FileStream file = new FileStream(@"ComparisonSpectra\Preview spectrum.spec", FileMode.Open)) { data = new byte[file.Length]; file.Read(data, 0, (int)file.Length); this.comparisonSpectra.Add(DataFactory.LoadEdSpectrum(data)); } using (FileStream file = new FileStream(@"ComparisonSpectra\Tungsten particle.spec", FileMode.Open)) { data = new byte[file.Length]; file.Read(data, 0, (int)file.Length); this.comparisonSpectra.Add(DataFactory.LoadEdSpectrum(data)); } this.cbCompareSpectraComboBox.DataSource = this.comparisonSpectra; this.cbCompareSpectraComboBox.DisplayMember = @"Label"; this.cbCompareSpectraComboBox.SelectedIndex = 0; } /// /// Called when [clear excluded list button clicked]. /// /// The sender. /// The instance containing the event data. private void OnClearExcludedListButtonClicked(object sender, EventArgs e) { foreach (int element in this.periodicTableControl.ExcludedElements) { this.periodicTableControl.Clear(element); } this.UpdateElementsList(this.periodicTableControl.ExcludedElements, this.tbExcludedElementList); } /// /// Called when [export tiff button clicked]. /// /// The sender. /// The instance containing the event data. private void OnExportTiffButtonClicked(object sender, EventArgs e) { // Export a tiff synchronously on the calling thread. var syncTiff = this.spectrumViewer.CreateImage(ExportImageType.Tiff); File.WriteAllBytes(Path.Combine(Path.GetTempPath(), @"zSpectrumSync.tiff"), syncTiff); // Export a tiff asynchronously on a background thread. // The thread must be created with an apartment state set to STA. // Calls to CreateImage() must be made on the same thread that created the viewer. var spectrum = this.spectrumViewer.Spectrum; var thread = new System.Threading.Thread(() => { // For optimum performance, create a single spectrum viewer and change the spectrum // and viewer settings where required for all spectra that you need images for. var backgroundViewer = new SpectrumViewer(); // A height and width must be set to provide the image dimensions in pixels. backgroundViewer.Width = 500; backgroundViewer.Height = 500; backgroundViewer.IsYAxisAutoScaleEnabled = true; backgroundViewer.YAxisType = ScaleType.Logarithmic; backgroundViewer.MaximumEnergy = 8; backgroundViewer.Spectrum = spectrum; var asyncTiff = backgroundViewer.CreateImage(ExportImageType.Tiff); File.WriteAllBytes(Path.Combine(Path.GetTempPath(), @"zSpectrumAsync.tiff"), asyncTiff); backgroundViewer.Dispatcher.InvokeShutdown(); }); thread.IsBackground = true; thread.SetApartmentState(ApartmentState.STA); thread.Start(); } } }