MapAcquisition.xaml.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423
  1. namespace OINA.Extender.WPF.Testharness
  2. {
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Collections.ObjectModel;
  6. using System.ComponentModel;
  7. using System.Linq;
  8. using System.Windows;
  9. using System.Windows.Controls;
  10. using System.Windows.Threading;
  11. using OINA.Extender.Acquisition;
  12. using OINA.Extender.Acquisition.Ed;
  13. using OINA.Extender.Data.Ed;
  14. using OINA.Extender.Data.Image;
  15. using OINA.Extender.Processing;
  16. using OINA.Extender.Processing.Ed;
  17. /// <summary>
  18. /// Interaction logic for MapAcquisition.xaml
  19. /// </summary>
  20. public partial class MapAcquisition : UserControl, INotifyPropertyChanged
  21. {
  22. private readonly List<DetectorEnableModel> enabledDetectors;
  23. private EdHardwareId primaryHardwareId;
  24. private List<DetectorEnableModel> secondaryHardwareIds;
  25. private IEdMapAcquisitionController controller;
  26. private IEdSpectrum spectrum;
  27. private ObservableCollection<IEdMap> acquiredMaps;
  28. private IEdMap selectedMap;
  29. private IReadOnlyList<IEdMapImage> elementMaps;
  30. private double progressPercentage;
  31. private IEdMapAcquisitionData mapData;
  32. private IEdMapProcessor mapProcessor;
  33. private IAutoIdSettings autoIdSettings;
  34. private IEdSpectrumProcessing spectrumProcessing;
  35. public MapAcquisition()
  36. {
  37. this.InitializeComponent();
  38. this.DataContext = this;
  39. this.autoIdSettings = ProcessingFactory.CreateAutoIdSettings();
  40. this.spectrumProcessing = ProcessingFactory.CreateSpectrumProcessing();
  41. this.Settings = AcquireFactory.CreateEdMapSettings();
  42. // pixel size is the number of data pixels in x
  43. double pixelSize = 1.0 / 128;
  44. this.Settings.ScanSettings.AcquisitionRegion.CreateFullFieldRegion(pixelSize);
  45. this.Settings.ScanSettings.FrameCount = 1;
  46. this.enabledDetectors = this.Settings.EdSettings.IsHardwareEnabled
  47. .Select(i => new DetectorEnableModel(i.Key, i.Value)).ToList();
  48. this.PrimaryHardwareId = this.Settings.EdSettings.PrimaryHardwareId;
  49. this.controller = AcquireFactory.CreateEdMapServer();
  50. this.controller.ExperimentStarted += this.OnExperimentStarted;
  51. this.controller.ExperimentFinished += this.OnExperimentFinished;
  52. this.acquiredMaps = new ObservableCollection<IEdMap>();
  53. }
  54. /// <summary>
  55. /// Event that notifies that the processing progress has changed
  56. /// </summary>
  57. public event PropertyChangedEventHandler PropertyChanged;
  58. private void RaisePropertyChanged(string propertyName)
  59. {
  60. this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
  61. }
  62. private void StartButton_Click(object sender, System.Windows.RoutedEventArgs e)
  63. {
  64. this.ElementMaps = null;
  65. this.ProgressPercentage = 0;
  66. var edSettings = this.Settings.EdSettings;
  67. var scanSettings = this.Settings.ScanSettings;
  68. foreach (var detectorEnabled in this.secondaryHardwareIds)
  69. {
  70. edSettings.EnableDevice(detectorEnabled.EdHardwareId, detectorEnabled.IsDetectorEnabled);
  71. }
  72. edSettings.PrimaryHardwareId = this.primaryHardwareId;
  73. edSettings.AcquisitionMode = EdAcquireMode.LiveTime;
  74. // 1ms pixel dwell time
  75. edSettings.AcquisitionTime = TimeSpan.FromMilliseconds(1);
  76. edSettings.TimeMode = EdTimeMode.Pixel;
  77. var results = this.Settings.Validate();
  78. if (!results.IsValid)
  79. {
  80. string errors = string.Join(Environment.NewLine, results.ValidationErrors);
  81. MessageBox.Show(errors, @"Invalid acquisition settings");
  82. return;
  83. }
  84. this.controller.StartAcquisition(this.Settings);
  85. }
  86. private void StopButton_Click(object sender, System.Windows.RoutedEventArgs e)
  87. {
  88. this.controller.StopAcquisition();
  89. }
  90. private void OnExperimentStarted(object sender, AcquisitionStartedEventArgs<IEdMapAcquisitionData> e)
  91. {
  92. this.Spectrum = e.Value.EdSpectrum;
  93. this.mapData = e.Value;
  94. }
  95. private void OnExperimentFinished(object sender, AcquisitionFinishedEventArgs<IEdMapAcquisitionData> e)
  96. {
  97. var edMap = e.Value?.EdMap;
  98. if (edMap != null)
  99. {
  100. this.Dispatcher.BeginInvoke(() =>
  101. {
  102. this.acquiredMaps.Add(edMap);
  103. this.SelectedMap = edMap;
  104. });
  105. }
  106. }
  107. public IEdSpectrum Spectrum
  108. {
  109. get
  110. {
  111. return this.spectrum;
  112. }
  113. set
  114. {
  115. this.spectrum = value;
  116. this.RaisePropertyChanged(nameof(this.Spectrum));
  117. }
  118. }
  119. public IEdMapSettings Settings { get; }
  120. public EdHardwareId PrimaryHardwareId
  121. {
  122. get
  123. {
  124. return this.primaryHardwareId;
  125. }
  126. set
  127. {
  128. if (this.primaryHardwareId == value)
  129. {
  130. return;
  131. }
  132. this.primaryHardwareId = value;
  133. this.RaisePropertyChanged(nameof(this.PrimaryHardwareId));
  134. this.SecondaryHardwareIds = this.enabledDetectors.Where(i => i.EdHardwareId != value).ToList();
  135. }
  136. }
  137. public IReadOnlyList<DetectorEnableModel> SecondaryHardwareIds
  138. {
  139. get
  140. {
  141. return this.secondaryHardwareIds;
  142. }
  143. set
  144. {
  145. this.secondaryHardwareIds = value.ToList();
  146. this.RaisePropertyChanged(nameof(this.SecondaryHardwareIds));
  147. }
  148. }
  149. /// <summary>
  150. /// Gets the acquired maps
  151. /// </summary>
  152. public ObservableCollection<IEdMap> AcquiredMaps
  153. {
  154. get
  155. {
  156. return this.acquiredMaps;
  157. }
  158. }
  159. /// <summary>
  160. /// Gets or sets the selected map
  161. /// </summary>
  162. public IEdMap SelectedMap
  163. {
  164. get
  165. {
  166. return this.selectedMap;
  167. }
  168. set
  169. {
  170. this.selectedMap = value;
  171. this.RaisePropertyChanged(nameof(this.SelectedMap));
  172. }
  173. }
  174. /// <summary>
  175. /// Deletes the selected map
  176. /// </summary>
  177. private void DeleteMapButton_Click(object sender, RoutedEventArgs e)
  178. {
  179. // Maps should be deleted when they are no longer required as the data is saved in the
  180. // AppData\Local\Oxford Instruments NanoAnalysis\Extender\TempProject folder of the current user
  181. // Note these projects cannot be used with AZtec.
  182. var edMap = this.selectedMap;
  183. if (edMap != null)
  184. {
  185. this.controller.Delete(edMap);
  186. edMap.Dispose();
  187. this.acquiredMaps.Remove(edMap);
  188. this.SelectedMap = this.acquiredMaps.LastOrDefault();
  189. }
  190. }
  191. #region FLS Processing
  192. /// <summary>
  193. /// Starts FLS map processing
  194. /// </summary>
  195. /// <param name="mapData">The map data</param>
  196. private void StartFLSProcessing(IEdMapAcquisitionData mapData)
  197. {
  198. this.PerformAutoId(mapData);
  199. var processor = ProcessingFactory.CreateEdMapFLSProcessor();
  200. var settings = ProcessingFactory.CreateEdMapFLSSettings();
  201. try
  202. {
  203. this.MapProcessor = processor;
  204. this.ElementMaps = processor.StartProcessing(mapData, settings);
  205. }
  206. catch (Exception ex)
  207. {
  208. MessageBox.Show(ex.Message, @"Error starting FLS processing");
  209. }
  210. }
  211. #endregion
  212. #region window integral processing
  213. /// <summary>
  214. /// Starts window integral map processing
  215. /// </summary>
  216. /// <param name="mapData">The map data</param>
  217. private void StartWindowIntegralProcessing(IEdMapAcquisitionData mapData)
  218. {
  219. this.PerformAutoId(mapData);
  220. var processor = ProcessingFactory.CreateEdMapWindowIntegralProcessor();
  221. var settings = ProcessingFactory.CreateEdMapWindowIntegralSettings();
  222. try
  223. {
  224. this.MapProcessor = processor;
  225. this.ElementMaps = processor.StartProcessing(mapData, settings);
  226. }
  227. catch (Exception ex)
  228. {
  229. MessageBox.Show(ex.Message, @"Error starting window integral processing");
  230. }
  231. }
  232. #endregion
  233. #region common map processing
  234. /// <summary>
  235. /// Gets or sets the Ed Map processor
  236. /// </summary>
  237. private IEdMapProcessor MapProcessor
  238. {
  239. get
  240. {
  241. return this.mapProcessor;
  242. }
  243. set
  244. {
  245. if (this.mapProcessor == value)
  246. {
  247. return;
  248. }
  249. var processor = this.mapProcessor;
  250. if (processor != null)
  251. {
  252. processor.CancelProcessing();
  253. processor.ProgressChanged -= this.OnProcessingProgressChanged;
  254. processor.Dispose();
  255. }
  256. this.mapProcessor = value;
  257. if (value != null)
  258. {
  259. value.ProgressChanged += this.OnProcessingProgressChanged;
  260. }
  261. }
  262. }
  263. private void OnProcessingProgressChanged(object sender, ProcessingProgressEventArgs e)
  264. {
  265. this.ProgressPercentage = e.ProgressPercentage;
  266. if (e.State == ProcessingProgressState.Completed)
  267. {
  268. this.elementMaps.ToList().ForEach(i => i.AutoBrightness());
  269. // calculate total counts in the first element map
  270. var elementMap = this.elementMaps.OfType<IEdMapImage>().FirstOrDefault();
  271. if (elementMap != null)
  272. {
  273. int pixels = elementMap.Height * elementMap.Width;
  274. float[] countsPerSecond = new float[pixels];
  275. elementMap.GetData(countsPerSecond);
  276. float[] liveTimes = new float[pixels];
  277. this.mapData.EdMap.GetLiveTimes(elementMap.BinFactor, liveTimes);
  278. double totalCounts = Enumerable.Range(0, pixels).Sum(i => countsPerSecond[i] * liveTimes[i]);
  279. }
  280. }
  281. }
  282. /// <summary>
  283. /// Gets or sets the processing percentage (0 - 100)
  284. /// </summary>
  285. public double ProgressPercentage
  286. {
  287. get
  288. {
  289. return this.progressPercentage;
  290. }
  291. set
  292. {
  293. this.progressPercentage = value;
  294. this.RaisePropertyChanged(nameof(this.ProgressPercentage));
  295. }
  296. }
  297. /// <summary>
  298. /// Gets or sets the element maps
  299. /// </summary>
  300. public IReadOnlyList<IEdMapImage> ElementMaps
  301. {
  302. get
  303. {
  304. return this.elementMaps;
  305. }
  306. set
  307. {
  308. if (this.elementMaps == value)
  309. {
  310. return;
  311. }
  312. var elementMaps = this.elementMaps;
  313. elementMaps?.ToList().ForEach(i => i.Dispose());
  314. this.elementMaps = value;
  315. this.RaisePropertyChanged(nameof(this.ElementMaps));
  316. }
  317. }
  318. private void PerformAutoId(IEdMapAcquisitionData mapData)
  319. {
  320. try
  321. {
  322. // Identify the elements in the sum spectrum
  323. var elements = this.spectrumProcessing.IdentifyElements(mapData.EdSpectrum, this.autoIdSettings);
  324. if (elements.Any())
  325. {
  326. // Update the identified elements in the map. Used to create the element maps.
  327. mapData.EdMap.ClearIdentifiedElements();
  328. mapData.EdMap.SetIdentifiedElements(elements, true);
  329. // Update the peak labels
  330. this.spectrumProcessing.UpdatePeakLabels(mapData.EdSpectrum, null);
  331. }
  332. }
  333. catch (Exception ex)
  334. {
  335. MessageBox.Show(ex.Message, @"Error processing spectrum");
  336. }
  337. }
  338. private void CancelButton_Click(object sender, RoutedEventArgs e)
  339. {
  340. this.MapProcessor?.CancelProcessing();
  341. }
  342. #endregion
  343. private void WindowIntegral_Click(object sender, RoutedEventArgs e)
  344. {
  345. if (this.mapData != null)
  346. {
  347. this.StartWindowIntegralProcessing(this.mapData);
  348. }
  349. }
  350. private void FLS_Click(object sender, RoutedEventArgs e)
  351. {
  352. if (this.mapData != null)
  353. {
  354. this.StartFLSProcessing(this.mapData);
  355. }
  356. }
  357. }
  358. }